Wiki source code of Template Script Bindings
Last modified by Vincent Massol on 2026/08/30 20:43
Show last authors
| author | version | line-number | content |
|---|---|---|---|
| 1 | A LaTeX template is a Velocity script, so it has the standard bindings any wiki script has, ##$services## and the Velocity tools among them. On top of those the renderer adds ##$latex##, which is the whole of the LaTeX rendering API, and ##$SP##. | ||
| 2 | |||
| 3 | |=Binding|=What it gives | ||
| 4 | |##$latex.block##|The Block being rendered. | ||
| 5 | |##$latex.processor##|Renders other Blocks, and other templates. | ||
| 6 | |##$latex.tool##|Escaping, the document language, Block tests and the shared stacks. | ||
| 7 | |##$latex.properties##|The options the export was started with. | ||
| 8 | |##$latex.resourceConverter##|Puts attachments and generated files into the exported package. | ||
| 9 | |##$latex.includes##|The page files already written to that package. | ||
| 10 | |##$SP##|One space character. | ||
| 11 | |||
| 12 | The last four belong to an export. A template rendered outside one still finds them, and the FAQ below says what they hold there. | ||
| 13 | |||
| 14 | == $latex.block == | ||
| 15 | |||
| 16 | The ##org.xwiki.rendering.block.Block## the template was chosen for, with its own API: ##getChildren()##, ##getParameter($name)##, ##isInline()##, ##getParent()##, and whatever its class adds on top — ##getWord()## on a ##WordBlock##, ##getLevel()## on a ##HeaderBlock##. It is set again for every Block, so a template always sees its own. | ||
| 17 | |||
| 18 | Handing its children back to the processor is the line almost every template contains: | ||
| 19 | |||
| 20 | {{code language="velocity"}} | ||
| 21 | $latex.processor.process($latex.block.getChildren()) | ||
| 22 | {{/code}} | ||
| 23 | |||
| 24 | == $latex.processor == | ||
| 25 | |||
| 26 | |=Call|=Returns | ||
| 27 | |##process($blocks)##|The LaTeX for a collection of Blocks, each rendered through its own template. | ||
| 28 | |##render($name)##|The LaTeX the named template produces. | ||
| 29 | |##getTemplate($name)##|That template, or nothing when it exists on neither lookup path. | ||
| 30 | |##render($template)##|The LaTeX a template already in hand produces, which is how an [[override>>doc:documentation.extensions.dev.latex.override-template.WebHome]] renders the default it has just modified. | ||
| 31 | |||
| 32 | A name here is relative and carries no ##latex/## prefix — ##Preamble##, ##macros/code## — and goes through the [[same two-path lookup>>doc:documentation.extensions.dev.latex.template-mechanism.WebHome]] as a Block's own template. ##getTemplate## is how a template checks that another one is there before rendering it. | ||
| 33 | |||
| 34 | == $latex.tool == | ||
| 35 | |||
| 36 | |=Call|=Returns | ||
| 37 | |##escape($text)##|The text with LaTeX's special characters replaced by their escaped forms. | ||
| 38 | |##normalizeLabel($text)##|The text with the characters a ##\label## cannot hold removed. | ||
| 39 | |##language##|The document language spelled the way ##babel## wants it, lowercase: ##english##, ##french##. | ||
| 40 | |##getStack($id)##|A stack shared by every template of the export, created empty on first use. | ||
| 41 | |##getSiblings($block)##|The Blocks following the one passed, under the same parent. | ||
| 42 | |##getParentBlock($block)##|Its parent, skipping the ##MacroMarkerBlock## wrappers. | ||
| 43 | |##isTableCell($block)##|True for a table cell, header cells included. | ||
| 44 | |##isFigure($block)##|True for a ##FigureBlock##. | ||
| 45 | |##isIdBlockInline($idBlock)##|True when an ##id## macro sits inside a paragraph rather than on its own. | ||
| 46 | |##previousSiblingsContainsOnlyIdMacros($block)##|True when nothing but ##id## macros precedes the Block under its parent. | ||
| 47 | |##getInlineDescendants($block)##|The descendants of the Block that can be rendered as inline content. | ||
| 48 | |##getDescendantMetaDataBlockWithParameterName($block, $name)##|The first ##MetaDataBlock## below it carrying that ##parameter-name##, or nothing. | ||
| 49 | |##figureTool##|The figure helpers below. | ||
| 50 | |||
| 51 | A template that writes text cannot do without ##escape##: these ten characters mean something to LaTeX and have to be neutralised first. | ||
| 52 | |||
| 53 | {{code language="none"}} | ||
| 54 | \ { } # $ % & ^ _ ~ | ||
| 55 | {{/code}} | ||
| 56 | |||
| 57 | ##normalizeLabel## is the variant for a ##\label##, which refuses seven of them outright rather than accepting an escape; it drops those and keeps ##&##, ##^## and ##_##. | ||
| 58 | |||
| 59 | === Figure Helpers === | ||
| 60 | |||
| 61 | ##$latex.tool.figureTool## holds what the ##FigureBlock## and ##FigureCaptionBlock## templates need. | ||
| 62 | |||
| 63 | |=Call|=Returns | ||
| 64 | |##isTable($figureBlock)##|True when the figure holds a table. | ||
| 65 | |##getFigureEnvironment($figureBlock)##|The environment to open for it, ##table## or ##figure##. | ||
| 66 | |##getFigureEnvironmentParameter($figureBlock)##|The Block written as that environment's placement option, ##h## unless the figure overrides it. | ||
| 67 | |##isFigureCaptionLast($captionBlock)##|True when the caption comes after the figure content rather than before it. | ||
| 68 | |##displayFigureCaption($captionBlock)##|Whether the caption should be written at all. | ||
| 69 | |||
| 70 | == $latex.properties == | ||
| 71 | |||
| 72 | The options the export was started with. They are the eleven fields of the export form, and [[Export Options>>doc:documentation.extensions.user.latex.export-page.export-options.WebHome]] says what each one does. | ||
| 73 | |||
| 74 | |=Property|=Type | ||
| 75 | |##$latex.properties.documentClass##|String | ||
| 76 | |##$latex.properties.coverPage##|Boolean | ||
| 77 | |##$latex.properties.coverPageImage##|String | ||
| 78 | |##$latex.properties.pageNumbering##|Boolean | ||
| 79 | |##$latex.properties.toc##|Boolean | ||
| 80 | |##$latex.properties.listOfFigures##|Boolean | ||
| 81 | |##$latex.properties.listOfTables##|Boolean | ||
| 82 | |##$latex.properties.title##|String | ||
| 83 | |##$latex.properties.subtitle##|String | ||
| 84 | |##$latex.properties.author##|String | ||
| 85 | |##$latex.properties.date##|Date | ||
| 86 | |||
| 87 | The [[index template>>doc:documentation.extensions.dev.latex.export-package.index-template.WebHome]] is where they are read, one guard per option: | ||
| 88 | |||
| 89 | {{code language="tex"}} | ||
| 90 | #if ($latex.properties.toc) | ||
| 91 | \setcounter{tocdepth}{3} | ||
| 92 | \tableofcontents | ||
| 93 | #end | ||
| 94 | {{/code}} | ||
| 95 | |||
| 96 | == $latex.resourceConverter == | ||
| 97 | |||
| 98 | |=Call|=Returns | ||
| 99 | |##convert($linkBlock)##, ##convert($imageBlock)##|The Block's reference, rewritten to the copy the converter has just added to the package. | ||
| 100 | |##convert($reference, $forceDownload)##|The same for a bare ##ResourceReference##; with ##true##, external URLs are downloaded so that they become local files too. | ||
| 101 | |##convert($reference, $baseReference, $forceDownload)##|The same again, resolving a relative reference against the base reference passed. | ||
| 102 | |##store($path, $stream)##|Adds content to the package at that path, and returns nothing. | ||
| 103 | |||
| 104 | The shipped ##ImageBlock## template shows the pattern: convert first, write the reference the converter hands back, escape it like any other text. | ||
| 105 | |||
| 106 | {{code language="tex"}} | ||
| 107 | #set ($resourceReference = $latex.resourceConverter.convert($imageBlock)) | ||
| 108 | \includegraphics{$latex.tool.escape($resourceReference.reference)} | ||
| 109 | {{/code}} | ||
| 110 | |||
| 111 | Its Java interface is [[LaTeXResourceConverter>>https://github.com/xwiki-contrib/latex/blob/master/latex-syntax/src/main/java/org/xwiki/contrib/latex/internal/LaTeXResourceConverter.java]]. | ||
| 112 | |||
| 113 | == $latex.includes == | ||
| 114 | |||
| 115 | The paths of the page files written to the package so far, in the order they were added. The index template is what loops over them to pull each page into the document. Outside an export nothing writes page files, so the list is empty. | ||
| 116 | |||
| 117 | == $SP == | ||
| 118 | |||
| 119 | Leading whitespace is stripped from every line of a template before it runs, so that a template can be indented for reading without leaking that indentation into the LaTeX. A line whose output really has to begin with spaces asks for them with ##$SP##: | ||
| 120 | |||
| 121 | {{code language="tex"}} | ||
| 122 | \newcommand{\xwikititle}[1]{ | ||
| 123 | ${SP}${SP}\title{#1}} | ||
| 124 | {{/code}} |