Add Support for a Macro
Steps
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 page describes, which makes supporting a macro a matter of adding one file. This How-to adds a framed box for the box macro.
- 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 says what each of them produces. box is not among them, so an export writes the box's content out and drops the box.
{{box title="A note"}} Boxed **content**. {{/box}}\begin{varwidth}[t]{\linewidth} \begin{varwidth}[t]{\linewidth} A note \end{varwidth}Boxed \textbf{content}. \end{varwidth}The directory on GitHub is the complete list, release by release.
- 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 documents the rest of what is in scope.
#set ($macroBlock = $latex.block) #if (!$macroBlock.isInline()) \begin{mdframed} #set ($discard = $latex.tool.getStack('isInContainerAcceptingStandalone').push(true)) ## Skip the macro's own GroupBlock: its varwidth environment is not wanted inside the frame. $latex.processor.process($macroBlock.children.get(0).children) #set ($discard = $latex.tool.getStack('isInContainerAcceptingStandalone').pop()) \end{mdframed}## #else \fbox{$latex.processor.process($macroBlock.getChildren())}## #endThe 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.
- 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. 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 is a jar holding that one file.
macro-formula-latex-14.8.jar templates/latex/default/macros/formulaA 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.
- 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.
\begin{mdframed} \begin{varwidth}[t]{\linewidth} A note \end{varwidth}Boxed \textbf{content}. \end{mdframed}
FAQ
My template is ignored
The file name has to be the macro id exactly, case included: the shipped template of the putFootnotes macro is named putFootnotes. A name that matches no macro is never reported — the macro simply keeps exporting as its content.
How do I know what blocks I am wrapping?
Export the page once with no template for the macro: what comes out is what $latex.processor.process($latex.block.getChildren()) produces, so it is the structure your template has to wrap. For a macro whose content is not wiki syntax, leave the children alone and write $latex.block.getContent() out instead.