Renderer API
Reference
Two components turn an XDOM into LaTeX, and both are an org.xwiki.rendering.renderer.BlockRenderer: you pick one by its role hint, hand it a Block and a printer, and read the LaTeX back off the printer.
| Role hint | Produces |
|---|---|
| latex/1.0 | A complete document: the preamble, \begin{document}, the content, \end{document}. |
| latex+fragment/1.0 | The content alone, with no document wrapper and no leading blank lines, to embed in a document produced elsewhere. |
They ship with the latex-syntax module, and the fragment renderer delegates to latex/1.0, so the two produce the same LaTeX for the same content.
From Java
@Inject
@Named("xwiki/2.1")
private Parser parser;
@Inject
@Named("latex/1.0")
private BlockRenderer latexRenderer;
public String toLaTeX(String content) throws ParseException
{
XDOM xdom = this.parser.parse(new StringReader(content));
WikiPrinter printer = new DefaultWikiPrinter();
this.latexRenderer.render(xdom, printer);
return printer.toString();
}Render the XDOM itself, not its children. The document wrapper is the XDOM Block's own template, so render(xdom.getChildren(), printer) returns the content with no preamble around it and two blank lines in front of it. Injecting latex+fragment/1.0 is the supported way to get a fragment, and the only change the code above needs.
From a Wiki Page
$services.rendering does the same two steps and takes the same two role hints:
{{velocity}}
#set ($xdom = $services.rendering.parse('hello **world**', 'xwiki/2.1'))
{{{$services.rendering.render($xdom, 'latex+fragment/1.0')}}}
{{/velocity}}That prints hello \textbf{world}. The verbatim block around the call keeps the produced LaTeX away from the wiki parser, which would otherwise read part of it as syntax of its own.
What the Renderer Is Not
It is a BlockRenderer and nothing else. The extension registers no LaTeX parser and no PrintRendererFactory, so LaTeX is not among the syntaxes $services.rendering.getAvailableRendererSyntaxes() returns, it cannot be chosen as the syntax a page is written in, and the two role hints above are the only way to reach it.
FAQ
The macros in my content produced nothing
parse leaves a macro as a MacroBlock, which has neither a template nor children, so the renderer writes nothing for it and reports no error. Transform the XDOM first, which needs programming rights:
#set ($tc = $services.rendering.createTransformationContext())
#set ($discard = $tc.setXDOM($xdom))
#set ($discard = $tc.setSyntax($services.rendering.resolveSyntax('xwiki/2.1')))
#set ($discard = $services.rendering.transform($xdom, $tc))Can I render a single Block?
Yes, any Block is accepted. Only an XDOM brings the document wrapper with it, so a paragraph rendered through latex/1.0 comes back as a fragment anyway.