Wiki source code of Add Support for a Macro

Last modified by Vincent Massol on 2026/08/30 20:43

Hide last authors
Vincent Massol 2.1 1 A macro is exported with a LaTeX form of its own only where a template exists for it. Every other macro is exported as the blocks it renders to, so a structural macro loses its structure and keeps only its text. A macro template is found by macro id, through the lookup the [[Template Mechanism>>doc:documentation.extensions.dev.latex.template-mechanism.WebHome]] page describes, which makes supporting a macro a matter of adding one file. This How-to adds a framed box for the ##box## macro.
2
3 1. Check whether the macro is handled already. The templates that ship with the extension are in its jar under ##templates/latex/default/macros/##, one file per macro id, and [[Macro Support>>doc:documentation.extensions.user.latex.macro-support.WebHome]] says what each of them produces. ##box## is not among them, so an export writes the box's content out and drops the box.(((
4 {{code language="none"}}
5 {{box title="A note"}}
6 Boxed **content**.
7 {{/box}}
8 {{/code}}
9
10 {{code language="tex"}}
11 \begin{varwidth}[t]{\linewidth}
12 \begin{varwidth}[t]{\linewidth}
13 A note
14 \end{varwidth}Boxed \textbf{content}.
15 \end{varwidth}
16 {{/code}}
17
18 [[The directory on GitHub>>https://github.com/xwiki-contrib/latex/tree/master/latex-syntax/src/main/resources/templates/latex/default/macros]] is the complete list, release by release.
19 )))
20 1. Write the template. Its name is the macro id, and ##$latex.block## is the macro's ##MacroMarkerBlock##: its children are the blocks the macro rendered to, and ##getContent()## returns the macro's own unparsed content, which is what a macro like ##formula## works from instead. [[Template Script Bindings>>doc:documentation.extensions.dev.latex.template-bindings.WebHome]] documents the rest of what is in scope.(((
21 {{code language="tex"}}
22 #set ($macroBlock = $latex.block)
23 #if (!$macroBlock.isInline())
24
25
26 \begin{mdframed}
27 #set ($discard = $latex.tool.getStack('isInContainerAcceptingStandalone').push(true))
28 ## Skip the macro's own GroupBlock: its varwidth environment is not wanted inside the frame.
29 $latex.processor.process($macroBlock.children.get(0).children)
30 #set ($discard = $latex.tool.getStack('isInContainerAcceptingStandalone').pop())
31 \end{mdframed}##
32 #else
33 \fbox{$latex.processor.process($macroBlock.getChildren())}##
34 #end
35 {{/code}}
36
37 The preamble already loads ##mdframed## for the message macros, so nothing has to be added to it. Pushing ##isInContainerAcceptingStandalone## tells the first block inside the frame not to open with the blank line it would otherwise add. The ##isInline()## branch is needed because ##box## can also be used inside a sentence, where a framed environment cannot go.
38 )))
39 1. Install the template at ##latex/macros/box##. On one wiki that is a Skin File Override object on the skin, [[the way any template is installed>>doc:documentation.extensions.dev.latex.override-template.WebHome]]. To give it to other wikis, ship it in a JAR extension instead, under ##templates/latex/default/macros/##: the ##default/## slot is the one the extension's own templates use, and it leaves ##latex/macros/box## free for a wiki that wants to override yours in turn. Such an extension needs nothing else — the [[LaTeX template of the Formula macro>>doc:extensions:Extension.Formula.Formula LaTeX Template.WebHome]] is a jar holding that one file.(((
40 {{code language="none"}}
41 macro-formula-latex-14.8.jar
42 templates/latex/default/macros/formula
43 {{/code}}
44
Vincent Massol 5.1 45 A template for a macro the LaTeX extension does not own belongs in an extension of its own, next to the macro it serves. That is the rule the ##reference## macro's template and the ##formula## one both left the LaTeX extension for.
Vincent Massol 2.1 46 )))
47 1. Export a page holding the macro and open its page file in the package. The box is a frame in the exported source, and a PDF export compiles it as one.(((
48 {{code language="tex"}}
49 \begin{mdframed}
50 \begin{varwidth}[t]{\linewidth}
51 A note
52 \end{varwidth}Boxed \textbf{content}.
53 \end{mdframed}
54 {{/code}}
55 )))

Get Connected