How to build a TemplateBox with dynamic length GridBox?
Thanks to jkuczm for an idea: https://mathematica.stackexchange.com/a/159407/5478:
MakeBoxes[ActuarialSurvivalProbability[x_, t_], StandardForm] :=
With[{row = Table[Slot[i], {i, 2, Length[x] + 1}]} (*Key point,
row of slots generated*),
TemplateBox[
Prepend[MakeBoxes /@ Unevaluated@x,
MakeBoxes[t]] ,
"ActuarialSurvivalProbability",
InterpretationFunction -> (RowBox[{"ActuarialSurvivalProbability",
"[", RowBox[{RowBox[{"{", RowBox[Riffle[{##2}, ","]], "}"}],
",", #}], "]"}] &),
DisplayFunction :> (RowBox[{SubscriptBox["",
TagBox[GridBox[{{#}}, GridBoxDividers -> {}], "Grid"]],
SubscriptBox["p",
RowBox[{"",
TagBox[GridBox[{row},
GridBoxDividers -> {"ColumnsIndexed" -> {},
"RowsIndexed" -> {1 -> Thickness[1]}}], "Grid"]}]]}] &),
Tooltip ->
"probability that atleast one of live(s) aged " <> ToString[x] <>
" survives for " <> ToString[t] <> " year(s)"]]
You can use TemplateSlotSequence
for variable length TemplateBox
arguments:
MakeBoxes[ActuarialSurvivalProbability[x_, t_], StandardForm] := TemplateBox[
Prepend[MakeBoxes[t]] @ BoxForm`ListMakeBoxes[x, StandardForm],
"ActuarialSurvivalProbability",
InterpretationFunction -> (
RowBox[{
"ActuarialSurvivalProbability",
"[",
RowBox[{
RowBox[{"{", RowBox[{TemplateSlotSequence[2, ","]}], "}"}],
",",
#1
}],
"]"
}]&
),
DisplayFunction -> (
RowBox[{
SubscriptBox["", #1],
SubscriptBox[
"p",
RowBox[{
"",
GridBox[
{{TemplateSlotSequence[2]}},
GridBoxDividers->{"RowsIndexed"->{1->Thickness[1]}}
]
}]
]
}]&
),
Tooltip->"probability that at least one of live(s) aged "<>ToString[x]<>
" survives for "<>ToString[t]<>" year(s)"
]
Then:
ActuarialSurvivalProbability[{x, y, z}, t]
The advantage of using a TemplateSlotSequence
solution is that the DisplayFunction
/InterpretationFunction
can be defined in a stylesheet.
A brief comment on TemplateSlotSequence
I think since the pure functions used in DisplayFunction
and InterpretationFunction
do not evaluate in the Wolfram Language kernel, TemplateSlotSequence
was introduced as a way to enhance the creation of box structures. When the front end constructs the box expression using the DisplayFunction
/InterpretationFunction
, TemplateSlotSequence
objects are interpreted as:
TemplateSlotSequence[1] -> Sequence[#1, #2, ...]
TemplateSlotSequence[2, ","] -> Sequence[#2, ",", #3, ",", ...]
TemplateSlotSequence[{3, 5}, " "] -> Sequence[#3, " ", #4, " ", #5]
Note that the above is not documented, and as with all undocumented functionality, it is subject to change.