When writing this answer I came into trouble trying to calculate total horizontal margins for contents of a cell in the right way. The first part of the problem is that both CellMargins
and CellFrameMargins
can be explicitly specified in two ways:
Possible settings are:
dist
the same margins on all sides{{left,right},{bottom,top}}
different margins on different sides
With the first specification I have to double the value of the option, with the second I have to take the first element of the list and then sum up the values. Of course I can write a function which will handle both situations separately, but may be there is an elegant way to avoid this?
The second part of the problem is that the value of CellFrameMargins
is used only if the corresponding value of CellFrame
is True
or a numeric nonzero. And all the numeric values are allowed to be negative. Here is a simple setup for playing with these options:
cell = Notebook[{Cell[StringJoin[Table["abcd ", {20}]]]},
PageWidth -> 600,
CellMargins -> {{200, 200}, {10, 10}},
CellFrame -> {{True, True}, {True, True}},
CellFrameMargins -> {{20, 20}, {10, 10}}];
Rasterize[cell, "Image"]
% // ImageDimensions
{200, 84}
Currently the best I come up with is the following:
margins = Total[Replace[
Switch[CurrentValue[{CellFrame, 1}],
True | {True, True}, {CurrentValue[{CellMargins, 1}], CurrentValue[{CellFrameMargins, 1}]},
_?NumericQ | {_?NumericQ, _?NumericQ}, {CurrentValue[{CellMargins, 1}], CurrentValue[{CellFrameMargins, 1}]*Sign[Abs[CurrentValue[{CellFrame, 1}]]], CurrentValue[{CellFrame, 1}]},
_, {CurrentValue[{CellMargins, 1}]}], {x_?NumericQ :> 2 x, l_List :> Total[l]}, {1}]]
This solution is already ugly and complicated but still doesn't handle correctly mixed specifications like CellFrame -> {{1, True}, {1, 1}}
. And my final intention is to use it in Dynamic
where the above simple forms of CurrentValue
should be replaced with CurrentValue[EvaluationNotebook[], {StyleDefinitions, "Input", CellFrame}]
etc.
Is there a better way to get the complete margins?