If I define the TraditionalForm formatting of myFunction without TemplateBox, then TeXForm works properly:
ClearAll[myFunction]
myFunction /: HoldPattern[MakeBoxes[myFunction[a_, b_, c_], TraditionalForm]] :=
SubsuperscriptBox[ToBoxes[a], ToBoxes[b], ToBoxes[c]]
myFunction[h, 1, 2] // TeXForm
(* h_1^2 *)
But if I try to define it using TemplateBox,
ClearAll[myFunction]
myFunction /: HoldPattern[MakeBoxes[myFunction[a_, b_, c_], TraditionalForm]] :=
TemplateBox[
{ToBoxes[a], ToBoxes[b], ToBoxes[c]}, "myFunctionTag",
DisplayFunction :> (SubsuperscriptBox[#1, #2, #3] &)
];
TraditionalForm works correctly,
myFunction[h, 1, 2] // TraditionalForm
(* $h_1^2$ *)
but TeXForm does not return code to format the expression as in TraditionalForm:
myFunction[h, 1, 2] // TeXForm
(* \text{myFunctionTag}[h,1,2] *)
Instead, it is just replacing the head of the function with the tag of TemplateBox. What is the correct way to make TeXForm generate code out of a TemplateBox? I'm looking for a solution that can be programmed into a package.
Answer
The internal function used by TeXForm to process boxes is System`Convert`CommonDump`ExpandTemplateBoxes. This function is expecting the DisplayFunction option of a TemplateBox to use Rule, not RuleDelayed. Compare:
System`Convert`CommonDump`ExpandTemplateBoxes @ TemplateBox[
{"a"},
"FOO",
DisplayFunction :> (#&)
]
System`Convert`CommonDump`ExpandTemplateBoxes @ TemplateBox[
{"a"},
"FOO",
DisplayFunction -> (#&)
]
RowBox[{"FOO", "[", RowBox[{"a"}], "]"}]
"a"
When RuleDelayed is used, the box structure generated by the DisplayFunction is ignored. So, modify your TemplateBox format to use Rule:
ClearAll[myFunction]
myFunction /: MakeBoxes[myFunction[a_, b_, c_], TraditionalForm] :=
TemplateBox[
{ToBoxes[a], ToBoxes[b], ToBoxes[c]}, "myFunctionTag",
DisplayFunction -> (SubsuperscriptBox[#1, #2, #3] &)
]
myFunction[h, 1, 2] // TeXForm
h_1^2
Note that I removed a superfluous HoldPattern in your definition.
Comments
Post a Comment