4

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.

QuantumDot
  • 19,601
  • 7
  • 45
  • 121

1 Answers1

6

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.

Carl Woll
  • 130,679
  • 6
  • 243
  • 355
  • Could you forward this issue somewhere? That is either is should accept RuleDelayed or the documentation of TemplateBox should stress that out. Currently the second example uses RuleDelayed for the DisplayFunction. – Kuba Aug 09 '17 at 11:03