Adding a new Syntax
You have 2 possibilities:
- You might want to add the ability to write page content using a new input Syntax. In this case you'll need to write a Parser.
- or you might want to be able to render page content in a new output Syntax. In this case you'll need to write a Renderer.
Adding a Parser
To add a Parser, simply implement the Parser interface and register it as a component against the Component Manager.
Example:
public class MyParser implements Parser
{
private static final Syntax SYNTAX = new Syntax(new SyntaxType("mysyntax", "My Syntax"), "1.0");
public Syntax getSyntax()
{
return SYNTAX;
}
public XDOM parse(Reader source) throws ParseException
{
XDOM xdom = new XDOM(Collections.singletonList(new WordBlock("amazing")));
return xdom;
}
}
In practice the easiest is to look at existing parser implementations. Specifically several parsers are implemented using JavaCC grammars.
Adding a Renderer
TODO: Add tutorial
You have to implement the Renderer interface.
Examples of Renderer source code:
Adding Tests
You'll need to write tests to verify that your Parser/Renderer work fine.
There are 2 Rendering test frameworks you can use (they're both located in the org.xwiki.rendering:xwiki-rendering-test module):
Adding a new Macro
Follow the Macro Tutorial.
To create a Transformation, create a Component implementing the org.xwiki.rendering.transformation.Transformation interface. To make it even easier you can simply extend org.xwiki.rendering.transformation.AbstractTransformation.
Example:
@Component("wikiword")
public class WikiWordTransformation extends AbstractTransformation
{
/**
* Regex Pattern to recognize a WikiWord.
*/
private static final Pattern WIKIWORD_PATTERN = Pattern.compile(
"\\p{javaUpperCase}+\\p{javaLowerCase}+(\\p{javaUpperCase}\\p{javaLowerCase}*)+");
/**
* {@inheritDoc}
* @see AbstractTransformation#transform(Block, TransformationContext)
*/
public void transform(Block block, TransformationContext transformationContext) throws TransformationException
{
// Find all Word blocks and for each of them check if they're a wiki word or not
for (WordBlock wordBlock : block.getChildrenByType(WordBlock.class, true)) {
Matcher matcher = WIKIWORD_PATTERN.matcher(wordBlock.getWord());
if (matcher.matches()) {
ResourceReference linkReference = new DocumentResourceReference(wordBlock.getWord());
wordBlock.getParent().replaceChild(new LinkBlock(wordBlock.getChildren(), linkReference, false),
wordBlock);
}
}
}
}
Check out the full code with tests
Adding a new Link Type
When using the XWiki Syntax 2.1, it's possible to extend the link syntax. The generic link syntax is: [[label>>referenceType:referencePath]] and it's possible to add new referenceType. This is a several step process:
- Implement a component with the org.xwiki.rendering.parser.ResourceReferenceTypeParser role.
- Implement a component with the org.xwiki.rendering.internal.renderer.xhtml.link.XHTMLLinkTypeRenderer role.