/*******************************************************************************
* Copyright (c) 2007, 2011 David Green 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:
* David Green - initial API and implementation
*******************************************************************************/
package org.eclipse.mylyn.wikitext.twiki;
import java.text.MessageFormat;
import java.util.List;
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.phrase.HtmlEndTagPhraseModifier;
import org.eclipse.mylyn.wikitext.parser.markup.phrase.HtmlStartTagPhraseModifier;
import org.eclipse.mylyn.wikitext.parser.markup.token.EntityReferenceReplacementToken;
import org.eclipse.mylyn.wikitext.parser.markup.token.ImpliedHyperlinkReplacementToken;
import org.eclipse.mylyn.wikitext.twiki.internal.block.DefinitionListBlock;
import org.eclipse.mylyn.wikitext.twiki.internal.block.HeadingBlock;
import org.eclipse.mylyn.wikitext.twiki.internal.block.HorizontalRuleBlock;
import org.eclipse.mylyn.wikitext.twiki.internal.block.ListBlock;
import org.eclipse.mylyn.wikitext.twiki.internal.block.LiteralBlock;
import org.eclipse.mylyn.wikitext.twiki.internal.block.ParagraphBlock;
import org.eclipse.mylyn.wikitext.twiki.internal.block.TableOfContentsBlock;
import org.eclipse.mylyn.wikitext.twiki.internal.block.VerbatimBlock;
import org.eclipse.mylyn.wikitext.twiki.internal.phrase.AutoLinkSwitchPhraseModifier;
import org.eclipse.mylyn.wikitext.twiki.internal.phrase.SimplePhraseModifier;
import org.eclipse.mylyn.wikitext.twiki.internal.token.IconReplacementToken;
import org.eclipse.mylyn.wikitext.twiki.internal.token.ImpliedEmailLinkReplacementToken;
import org.eclipse.mylyn.wikitext.twiki.internal.token.LinkReplacementToken;
import org.eclipse.mylyn.wikitext.twiki.internal.token.WikiWordReplacementToken;
/**
* a markup language implementing TWiki syntax. See
* <a href="http://wikix.ilog.fr/wiki/bin/view/TWiki/TextFormattingRules">TWiki Formatting Rules</a> for details.
*
* @author David Green
* @since 3.0
*/
public class TWikiLanguage extends AbstractMarkupLanguage {
private final PatternBasedSyntax literalTokenSyntax = new PatternBasedSyntax();
private final PatternBasedSyntax literalPhraseModifierSyntax = new PatternBasedSyntax();
private boolean literalMode;
private boolean isAutoLinking = true;
private String iconPattern = "TWikiDocGraphics/{0}.gif"; // FIXME find out if this is correct //$NON-NLS-1$
public TWikiLanguage() {
setName("TWiki"); //$NON-NLS-1$
setInternalLinkPattern("/cgi-bin/view/{0}/{1}"); //$NON-NLS-1$
}
@Override
protected PatternBasedSyntax getPhraseModifierSyntax() {
return literalMode ? literalPhraseModifierSyntax : phraseModifierSyntax;
}
@Override
protected PatternBasedSyntax getReplacementTokenSyntax() {
return literalMode ? literalTokenSyntax : tokenSyntax;
}
@Override
protected void clearLanguageSyntax() {
super.clearLanguageSyntax();
literalTokenSyntax.clear();
literalPhraseModifierSyntax.clear();
}
private Block paragraphBreakingBlock(Block block) {
paragraphBreakingBlocks.add(block);
return block;
}
/**
* for the purpose of converting wiki words into links, determine if the wiki word exists.
*
* @see WikiWordReplacementToken
*/
public boolean computeInternalLinkExists(String link) {
return true;
}
/**
* Convert a page name to an href to the page.
*
* @param pageName
* the name of the page to target, usually a WikiWord with whitespace removed
* @return the href to access the page
* @see #getInternalPageHrefPrefix()
*/
public String toInternalHref(String pageName) {
String[] parts = pageName.split("\\."); //$NON-NLS-1$
if (parts.length == 1) {
parts = new String[] { "Main", parts[0] }; //$NON-NLS-1$
}
return MessageFormat.format(super.internalLinkPattern, (Object[]) parts);
}
public String toIconUrl(String iconType) {
return MessageFormat.format(getIconPattern(), iconType);
}
/**
* indicate if we're currently processing a literal block
*
* @see LiteralBlock
*/
public boolean isLiteralMode() {
return literalMode;
}
/**
* indicate if we're currently processing a literal block
*
* @see LiteralBlock
*/
public void setLiteralMode(boolean literalMode) {
this.literalMode = literalMode;
}
/**
* the pattern to use when generating icon image urls.
*/
public void setIconPattern(String iconPattern) {
this.iconPattern = iconPattern;
}
/**
* the pattern to use when generating icon image urls.
*/
public String getIconPattern() {
return iconPattern;
}
public boolean isAutoLinking() {
return isAutoLinking;
}
public void setAutoLinking(boolean isAutoLinking) {
this.isAutoLinking = isAutoLinking;
}
@Override
protected void addStandardBlocks(List<Block> blocks, List<Block> paragraphBreakingBlocks) {
// IMPORTANT NOTE: Most items below have order dependencies. DO NOT REORDER ITEMS BELOW!!
blocks.add(paragraphBreakingBlock(new VerbatimBlock()));
blocks.add(paragraphBreakingBlock(new LiteralBlock()));
blocks.add(paragraphBreakingBlock(new HorizontalRuleBlock()));
blocks.add(paragraphBreakingBlock(new HeadingBlock()));
blocks.add(paragraphBreakingBlock(new DefinitionListBlock()));
blocks.add(paragraphBreakingBlock(new TableOfContentsBlock()));
blocks.add(paragraphBreakingBlock(new ListBlock()));
}
@Override
protected void addStandardPhraseModifiers(PatternBasedSyntax phraseModifierSyntax) {
// IMPORTANT NOTE: Most items below have order dependencies. DO NOT REORDER ITEMS BELOW!!
boolean escapingHtml = configuration == null ? false : configuration.isEscapingHtmlAndXml();
phraseModifierSyntax.add(new AutoLinkSwitchPhraseModifier());
if (!escapingHtml) {
phraseModifierSyntax.add(new HtmlStartTagPhraseModifier());
phraseModifierSyntax.add(new HtmlEndTagPhraseModifier());
}
phraseModifierSyntax.beginGroup("(?:(?<=[\\s\\.,\\\"'?!;:\\)\\(\\{\\}\\[\\]])|^)(?:", 0); //$NON-NLS-1$
phraseModifierSyntax.add(new SimplePhraseModifier("*", SpanType.BOLD)); //$NON-NLS-1$
phraseModifierSyntax.add(new SimplePhraseModifier("__", new SpanType[] { SpanType.BOLD, SpanType.ITALIC })); //$NON-NLS-1$
phraseModifierSyntax.add(new SimplePhraseModifier("_", SpanType.ITALIC)); //$NON-NLS-1$
phraseModifierSyntax.add(new SimplePhraseModifier("==", new SpanType[] { SpanType.BOLD, SpanType.MONOSPACE })); //$NON-NLS-1$
phraseModifierSyntax.add(new SimplePhraseModifier("=", SpanType.MONOSPACE)); //$NON-NLS-1$
phraseModifierSyntax.endGroup(")(?=\\W|$)", 0); //$NON-NLS-1$
literalPhraseModifierSyntax.add(new HtmlStartTagPhraseModifier());
literalPhraseModifierSyntax.add(new HtmlEndTagPhraseModifier());
}
@Override
protected void addStandardTokens(PatternBasedSyntax tokenSyntax) {
// IMPORTANT NOTE: Most items below have order dependencies. DO NOT REORDER ITEMS BELOW!!
tokenSyntax.add(new EntityReferenceReplacementToken("(tm)", "#8482")); //$NON-NLS-1$ //$NON-NLS-2$
tokenSyntax.add(new EntityReferenceReplacementToken("(TM)", "#8482")); //$NON-NLS-1$ //$NON-NLS-2$
tokenSyntax.add(new EntityReferenceReplacementToken("(c)", "#169")); //$NON-NLS-1$ //$NON-NLS-2$
tokenSyntax.add(new EntityReferenceReplacementToken("(C)", "#169")); //$NON-NLS-1$ //$NON-NLS-2$
tokenSyntax.add(new EntityReferenceReplacementToken("(r)", "#174")); //$NON-NLS-1$ //$NON-NLS-2$
tokenSyntax.add(new EntityReferenceReplacementToken("(R)", "#174")); //$NON-NLS-1$ //$NON-NLS-2$
tokenSyntax.add(new LinkReplacementToken());
tokenSyntax.add(new ImpliedHyperlinkReplacementToken());
tokenSyntax.add(new ImpliedEmailLinkReplacementToken());
tokenSyntax.add(new WikiWordReplacementToken());
tokenSyntax.add(new IconReplacementToken());
literalTokenSyntax.add(new ImpliedHyperlinkReplacementToken());
}
@Override
protected Block createParagraphBlock() {
return new ParagraphBlock();
}
}