/******************************************************************************* * Copyright (c) 2012, 2016 Stefan Seelmann and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Stefan Seelmann - initial API and implementation * Max Rydahl Andersen - Bug 474084 * Patrik Suzzi <psuzzi@gmail.com> - Bug 481670, 474084 * Jeremie Bresson - Bug 488246 *******************************************************************************/ package org.eclipse.mylyn.wikitext.asciidoc; import java.io.Writer; import java.util.List; import java.util.Map; import org.eclipse.mylyn.wikitext.asciidoc.internal.AsciiDocContentState; import org.eclipse.mylyn.wikitext.asciidoc.internal.AsciiDocDocumentBuilder; import org.eclipse.mylyn.wikitext.asciidoc.internal.AsciiDocIdGenerationStrategy; import org.eclipse.mylyn.wikitext.asciidoc.internal.block.AttributeDefinitionBlock; import org.eclipse.mylyn.wikitext.asciidoc.internal.block.CodeBlock; import org.eclipse.mylyn.wikitext.asciidoc.internal.block.CommentBlock; import org.eclipse.mylyn.wikitext.asciidoc.internal.block.HeadingBlock; import org.eclipse.mylyn.wikitext.asciidoc.internal.block.HorizontalRuleBlock; import org.eclipse.mylyn.wikitext.asciidoc.internal.block.ListBlock; import org.eclipse.mylyn.wikitext.asciidoc.internal.block.ParagraphBlock; import org.eclipse.mylyn.wikitext.asciidoc.internal.block.PreformattedBlock; import org.eclipse.mylyn.wikitext.asciidoc.internal.block.PropertiesLineBlock; import org.eclipse.mylyn.wikitext.asciidoc.internal.block.TableBlock; import org.eclipse.mylyn.wikitext.asciidoc.internal.block.TitleLineBlock; import org.eclipse.mylyn.wikitext.asciidoc.internal.block.UnderlinedHeadingBlock; import org.eclipse.mylyn.wikitext.asciidoc.internal.phrase.BackslashEscapePhraseModifier; import org.eclipse.mylyn.wikitext.asciidoc.internal.phrase.SimplePhraseModifier; import org.eclipse.mylyn.wikitext.asciidoc.internal.phrase.SimplePhraseModifier.Mode; import org.eclipse.mylyn.wikitext.asciidoc.internal.token.AnchorLinkMacroReplacementToken; import org.eclipse.mylyn.wikitext.asciidoc.internal.token.AnchorLinkReplacementToken; import org.eclipse.mylyn.wikitext.asciidoc.internal.token.EmailLinkReplacementToken; import org.eclipse.mylyn.wikitext.asciidoc.internal.token.ExplicitLinkReplacementToken; import org.eclipse.mylyn.wikitext.asciidoc.internal.token.ImplicitFormattedLinkReplacementToken; import org.eclipse.mylyn.wikitext.asciidoc.internal.token.ImplicitLinkReplacementToken; import org.eclipse.mylyn.wikitext.asciidoc.internal.token.InlineAttributeReplacementToken; import org.eclipse.mylyn.wikitext.asciidoc.internal.token.InlineCommentReplacementToken; import org.eclipse.mylyn.wikitext.asciidoc.internal.token.InlineEscapedAttributeReplacementToken; import org.eclipse.mylyn.wikitext.asciidoc.internal.token.InlineImageReplacementToken; import org.eclipse.mylyn.wikitext.asciidoc.internal.token.PreserverHtmlEntityToken; import org.eclipse.mylyn.wikitext.asciidoc.internal.token.XrefMacroReplacementToken; import org.eclipse.mylyn.wikitext.asciidoc.internal.token.XrefReplacementToken; import org.eclipse.mylyn.wikitext.asciidoc.internal.util.ReadAheadDispatcher; import org.eclipse.mylyn.wikitext.parser.DocumentBuilder; import org.eclipse.mylyn.wikitext.parser.DocumentBuilder.SpanType; import org.eclipse.mylyn.wikitext.parser.markup.AbstractMarkupLanguage; import org.eclipse.mylyn.wikitext.parser.markup.Block; import org.eclipse.mylyn.wikitext.parser.markup.ContentState; import org.eclipse.mylyn.wikitext.parser.markup.IdGenerationStrategy; import org.eclipse.mylyn.wikitext.parser.markup.token.PatternLineBreakReplacementToken; /** * A markup language implementing Asciidoc syntax. * * @author Stefan Seelmann * @author Max Rydahl Andersen * @since 3.0 */ public class AsciiDocLanguage extends AbstractMarkupLanguage { public AsciiDocLanguage() { setName("AsciiDoc"); //$NON-NLS-1$ } @Override protected ContentState createState() { AsciiDocContentState state = new AsciiDocContentState(); putInitialAttributes(state); if (configuration instanceof AsciiDocMarkupLanguageConfiguration) { Map<String, String> initialAttributes = ((AsciiDocMarkupLanguageConfiguration) configuration) .getInitialAttributes(); if (initialAttributes != null) { for (Map.Entry<String, String> e : initialAttributes.entrySet()) { state.putAttribute(e.getKey(), e.getValue()); } } } return state; } private void putInitialAttributes(AsciiDocContentState state) { state.putAttribute(AsciiDocContentState.ATTRIBUTE_IDPREFIX, AsciiDocContentState.IDPREFIX_DEFAULT_VALUE); state.putAttribute(AsciiDocContentState.ATTRIBUTE_IDSEPARATOR, AsciiDocContentState.IDSEPARATOR_DEFAULT_VALUE); state.putAttribute(AsciiDocContentState.ATTRIBUTE_IMAGESDIR, ""); //$NON-NLS-1$ } @Override public IdGenerationStrategy getIdGenerationStrategy() { return new AsciiDocIdGenerationStrategy(); } @Override protected void addStandardTokens(PatternBasedSyntax tokenSyntax) { // HTML entities are preserved tokenSyntax.add(new PreserverHtmlEntityToken()); // line ending with a + will cause a line Break tokenSyntax.add(new PatternLineBreakReplacementToken("(\\s\\+)\\s*$")); //$NON-NLS-1$ } @Override protected void addStandardPhraseModifiers(PatternBasedSyntax phraseModifierSyntax) { // attribute phraseModifierSyntax.add(new InlineAttributeReplacementToken()); phraseModifierSyntax.add(new InlineEscapedAttributeReplacementToken()); // comments phraseModifierSyntax.add(new InlineCommentReplacementToken()); // links phraseModifierSyntax.add(new EmailLinkReplacementToken()); phraseModifierSyntax.add(new ExplicitLinkReplacementToken()); phraseModifierSyntax.add(new ImplicitFormattedLinkReplacementToken()); phraseModifierSyntax.add(new ImplicitLinkReplacementToken()); phraseModifierSyntax.add(new AnchorLinkReplacementToken()); phraseModifierSyntax.add(new AnchorLinkMacroReplacementToken()); phraseModifierSyntax.add(new XrefReplacementToken()); phraseModifierSyntax.add(new XrefMacroReplacementToken()); // backslash escaped span elements phraseModifierSyntax.add(new BackslashEscapePhraseModifier("++")); //$NON-NLS-1$ phraseModifierSyntax.add(new BackslashEscapePhraseModifier("**")); //$NON-NLS-1$ phraseModifierSyntax.add(new BackslashEscapePhraseModifier("__")); //$NON-NLS-1$ phraseModifierSyntax.add(new BackslashEscapePhraseModifier("+")); //$NON-NLS-1$ phraseModifierSyntax.add(new BackslashEscapePhraseModifier("*")); //$NON-NLS-1$ phraseModifierSyntax.add(new BackslashEscapePhraseModifier("_")); //$NON-NLS-1$ phraseModifierSyntax.add(new InlineImageReplacementToken()); // pass-through phraseModifierSyntax.add(new SimplePhraseModifier("+++", SpanType.SPAN, Mode.SPECIAL)); // emphasis span elements phraseModifierSyntax.add(new SimplePhraseModifier("``", SpanType.CODE, Mode.NESTING)); //$NON-NLS-1$ phraseModifierSyntax.add(new SimplePhraseModifier("++", SpanType.SPAN, Mode.NORMAL)); //$NON-NLS-1$ phraseModifierSyntax.add(new SimplePhraseModifier("**", SpanType.STRONG, Mode.NESTING)); //$NON-NLS-1$ phraseModifierSyntax.add(new SimplePhraseModifier("__", SpanType.EMPHASIS, Mode.NESTING)); //$NON-NLS-1$ // emphasis span elements on word boundaries phraseModifierSyntax.beginGroup("(?:(?<=\\W)|^)(?:", 0); phraseModifierSyntax.add(new SimplePhraseModifier("*", SpanType.STRONG, Mode.NESTING)); //$NON-NLS-1$ phraseModifierSyntax.add(new SimplePhraseModifier("_", SpanType.EMPHASIS, Mode.NESTING)); //$NON-NLS-1$ phraseModifierSyntax.add(new SimplePhraseModifier("`", SpanType.CODE, Mode.NESTING)); //$NON-NLS-1$ phraseModifierSyntax.add(new SimplePhraseModifier("+", SpanType.SPAN, Mode.NORMAL)); //$NON-NLS-1$ phraseModifierSyntax.endGroup(")(?:(?=\\W)|$)", 0); phraseModifierSyntax.add(new SimplePhraseModifier("^", SpanType.SUPERSCRIPT, Mode.NESTING)); phraseModifierSyntax.add(new SimplePhraseModifier("~", SpanType.SUBSCRIPT, Mode.NESTING)); } @Override protected void addStandardBlocks(List<Block> blocks, List<Block> paragraphBreakingBlocks) { ListBlock listBlock = new ListBlock(); blocks.add(listBlock); paragraphBreakingBlocks.add(listBlock); AttributeDefinitionBlock attributeDefinition = new AttributeDefinitionBlock(); TitleLineBlock titleLineBlock = new TitleLineBlock(); PropertiesLineBlock propertiesLineBlock = new PropertiesLineBlock(); TableBlock tableBlock = new TableBlock(); PreformattedBlock preformattedBlock = new PreformattedBlock(); CommentBlock commentBlock = new CommentBlock(); HeadingBlock headingBlock = new HeadingBlock(); CodeBlock codeBlock = new CodeBlock(); HorizontalRuleBlock hrBlock = new HorizontalRuleBlock(); blocks.add(attributeDefinition); blocks.add(titleLineBlock); blocks.add(propertiesLineBlock); blocks.add(tableBlock); blocks.add(preformattedBlock); blocks.add(headingBlock); blocks.add(codeBlock); blocks.add(commentBlock); blocks.add(hrBlock); paragraphBreakingBlocks.add(codeBlock); paragraphBreakingBlocks.add(commentBlock); paragraphBreakingBlocks.add(preformattedBlock); } @Override protected Block createParagraphBlock() { ParagraphBlock paragraphBlock = new ParagraphBlock(); UnderlinedHeadingBlock headingBlock = new UnderlinedHeadingBlock(); ReadAheadDispatcher readAheadBlock = new ReadAheadDispatcher(headingBlock, paragraphBlock); return readAheadBlock; } @Override public DocumentBuilder createDocumentBuilder(Writer out, boolean formatting) { return new AsciiDocDocumentBuilder(out); } }