The Code Macro renders its content as is but pretty printed according to the language passed as parameter. Supporting
escaping Radeox, Velocity and Groovy wasn't trivial. Here's how it's currently implemented (waiting for a better
implementation):
- The first renderer to execute is the MacroMappingRenderer. That's because it's registered first in
DefaultXWikiRenderingEngine.DefaultXWikiRenderingEngine(com.xpn.xwiki.XWiki, com.xpn.xwiki.XWikiContext)
}.
The code macro is registered in the macros.txt file used by the MacroMappingRenderer and thus it is processed
by the macro mapping feature. Since it recognizes it's a radeox macro, it calls the Radeox Renderer's
XWikiRadeoxRenderer.convertMultiLine(String, String, String, String, com.xpn.xwiki.render.XWikiVirtualMacro, com.xpn.xwiki.XWikiContext)
method. This method has a hack and verifies if the macro to render is the code macro. If so it escapes Velocity
and Groovy special characters ($, #, <% and %>) so that when the Velocity and Radeox renderers execute they do
not process its content.
- We also don't want the Radeox renderer to render the code macro's content. We do this by having a special Radeox
Filter (
CodeRemoveFilter
that is defined before all other filters in
the META-INF/services/com.xpn.xwiki.render.filter.XWikiFilter
file and that removes the content of
the code macro. The other filters then execute. The last but one defined filter is
CodeRestoreFilter
which puts back the content of the code macro and the last
filter is the CodeFilter
filter which calls this macro.