/*******************************************************************************
* Copyright (c) 2007, 2014 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
* Jeremie Bresson - Bug 396545
*******************************************************************************/
package org.eclipse.mylyn.wikitext.mediawiki;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.mylyn.wikitext.mediawiki.internal.AbstractMediaWikiLanguage;
import org.eclipse.mylyn.wikitext.mediawiki.internal.BuiltInTemplateResolver;
import org.eclipse.mylyn.wikitext.mediawiki.internal.MediaWikiIdGenerationStrategy;
import org.eclipse.mylyn.wikitext.mediawiki.internal.block.BehaviorSwitchBlock;
import org.eclipse.mylyn.wikitext.mediawiki.internal.block.CommentBlock;
import org.eclipse.mylyn.wikitext.mediawiki.internal.block.EscapeBlock;
import org.eclipse.mylyn.wikitext.mediawiki.internal.block.HeadingBlock;
import org.eclipse.mylyn.wikitext.mediawiki.internal.block.ListBlock;
import org.eclipse.mylyn.wikitext.mediawiki.internal.block.ParagraphBlock;
import org.eclipse.mylyn.wikitext.mediawiki.internal.block.PreformattedBlock;
import org.eclipse.mylyn.wikitext.mediawiki.internal.block.SourceBlock;
import org.eclipse.mylyn.wikitext.mediawiki.internal.block.TableBlock;
import org.eclipse.mylyn.wikitext.mediawiki.internal.block.TableOfContentsBlock;
import org.eclipse.mylyn.wikitext.mediawiki.internal.phrase.EscapePhraseModifier;
import org.eclipse.mylyn.wikitext.mediawiki.internal.phrase.SimplePhraseModifier;
import org.eclipse.mylyn.wikitext.mediawiki.internal.token.HyperlinkExternalReplacementToken;
import org.eclipse.mylyn.wikitext.mediawiki.internal.token.HyperlinkInternalReplacementToken;
import org.eclipse.mylyn.wikitext.mediawiki.internal.token.ImageReplacementToken;
import org.eclipse.mylyn.wikitext.mediawiki.internal.token.LineBreakToken;
import org.eclipse.mylyn.wikitext.parser.DocumentBuilder.SpanType;
import org.eclipse.mylyn.wikitext.parser.markup.Block;
import org.eclipse.mylyn.wikitext.parser.markup.IdGenerationStrategy;
import org.eclipse.mylyn.wikitext.parser.markup.MarkupLanguage;
import org.eclipse.mylyn.wikitext.parser.markup.phrase.HtmlCommentPhraseModifier;
import org.eclipse.mylyn.wikitext.parser.markup.phrase.LimitedHtmlEndTagPhraseModifier;
import org.eclipse.mylyn.wikitext.parser.markup.phrase.LimitedHtmlStartTagPhraseModifier;
import org.eclipse.mylyn.wikitext.parser.markup.token.EntityReferenceReplacementToken;
import org.eclipse.mylyn.wikitext.parser.markup.token.ImpliedHyperlinkReplacementToken;
import org.eclipse.mylyn.wikitext.parser.markup.token.PatternLiteralReplacementToken;
/**
* A markup language for <a href="http://www.mediawiki.org">MediaWiki</a>
* <a href="http://en.wikipedia.org/wiki/Wikitext">Wikitext markup</a>, which is the wiki format used by <a href=
* "http://www.wikipedia.org>WikiPedia</a> and <a href="http://www.wikimedia.org/">several other major sites</a>.
*
* @author David Green
* @since 3.0
*/
public class MediaWikiLanguage extends AbstractMediaWikiLanguage {
private List<Template> templates = new ArrayList<Template>();
private List<TemplateResolver> templateProviders = new ArrayList<TemplateResolver>();
private String templateExcludes;
public MediaWikiLanguage() {
setName("MediaWiki"); //$NON-NLS-1$
setInternalLinkPattern("/wiki/{0}"); //$NON-NLS-1$
templateProviders.add(new BuiltInTemplateResolver());
}
/**
* Convert a page name to an href to the page.
*
* @param pageName
* the name of the page to target
* @return the href to access the page
* @see MarkupLanguage#getInternalLinkPattern()
*/
public String toInternalHref(String pageName) {
return super.mapPageNameToHref(pageName);
}
@Override
public IdGenerationStrategy getIdGenerationStrategy() {
return new MediaWikiIdGenerationStrategy();
}
@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(new HeadingBlock());
blocks.add(new ListBlock());
blocks.add(new TableBlock());
if (hasPreformattedBlock()) {
// preformatted blocks are lines that start with a single space, and thus are non-optimal for
// repository usage.
blocks.add(new PreformattedBlock());
}
blocks.add(new SourceBlock());
blocks.add(new TableOfContentsBlock());
blocks.add(new EscapeBlock());
blocks.add(new CommentBlock());
blocks.add(new BehaviorSwitchBlock());
for (Block block : blocks) {
if (block instanceof ParagraphBlock || block instanceof CommentBlock) {
continue;
}
paragraphBreakingBlocks.add(block);
}
}
private boolean hasPreformattedBlock() {
return configuration == null ? true : !configuration.isOptimizeForRepositoryUsage();
}
@Override
protected void addStandardPhraseModifiers(PatternBasedSyntax phraseModifierSyntax) {
phraseModifierSyntax.add(new EscapePhraseModifier());
phraseModifierSyntax.beginGroup("(?:(?<=[\\s\\.,\\\"'?!;:\\)\\(\\{\\}\\[\\]=>])|^)(?:", 0); //$NON-NLS-1$
phraseModifierSyntax.add(new SimplePhraseModifier("'''''", new SpanType[] { SpanType.BOLD, SpanType.ITALIC }, //$NON-NLS-1$
true));
phraseModifierSyntax.add(new SimplePhraseModifier("'''", SpanType.BOLD, true)); //$NON-NLS-1$
phraseModifierSyntax.add(new SimplePhraseModifier("''", SpanType.ITALIC, true)); //$NON-NLS-1$
phraseModifierSyntax.endGroup(")", 0); //$NON-NLS-1$
boolean escapingHtml = configuration == null ? false : configuration.isEscapingHtmlAndXml();
if (!escapingHtml) {
String[] allowedHtmlTags = new String[] { // HANDLED BY LineBreakToken "<br>",
// HANDLED BY LineBreakToken "<br/>",
"b", "big", "blockquote", "caption", "center", "cite", "code", "dd", "del", "div", "dl", "dt", "em", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$//$NON-NLS-5$//$NON-NLS-6$//$NON-NLS-7$//$NON-NLS-8$//$NON-NLS-9$//$NON-NLS-10$//$NON-NLS-11$//$NON-NLS-12$//$NON-NLS-13$
"font", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "i", "ins", "li", "ol", "p", "pre", "rb", "rp", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$//$NON-NLS-5$//$NON-NLS-6$//$NON-NLS-7$//$NON-NLS-8$//$NON-NLS-9$//$NON-NLS-10$//$NON-NLS-11$//$NON-NLS-12$//$NON-NLS-13$//$NON-NLS-14$//$NON-NLS-15$//$NON-NLS-16$
"rt", "ruby", "s", "small", "span", "strike", "strong", "sub", "sup", "table", "td", "th", "tr", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$//$NON-NLS-5$//$NON-NLS-6$//$NON-NLS-7$//$NON-NLS-8$//$NON-NLS-9$//$NON-NLS-10$//$NON-NLS-11$//$NON-NLS-12$//$NON-NLS-13$
"tt", "u", "ul", "var" }; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
phraseModifierSyntax.add(new LimitedHtmlEndTagPhraseModifier(allowedHtmlTags));
phraseModifierSyntax.add(new LimitedHtmlStartTagPhraseModifier(allowedHtmlTags));
phraseModifierSyntax.add(new HtmlCommentPhraseModifier());
}
}
@Override
protected void addStandardTokens(PatternBasedSyntax tokenSyntax) {
tokenSyntax.add(new LineBreakToken());
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 ImageReplacementToken());
tokenSyntax.add(new HyperlinkInternalReplacementToken());
tokenSyntax.add(new HyperlinkExternalReplacementToken());
tokenSyntax.add(new ImpliedHyperlinkReplacementToken());
tokenSyntax.add(new PatternLiteralReplacementToken("(?:(?<=^|\\w\\s)(----)(?=$|\\s\\w))", "<hr/>")); // horizontal rule //$NON-NLS-1$ //$NON-NLS-2$
tokenSyntax.add(new org.eclipse.mylyn.wikitext.mediawiki.internal.token.EntityReferenceReplacementToken());
}
@Override
protected Block createParagraphBlock() {
ParagraphBlock paragraphBlock = new ParagraphBlock(hasPreformattedBlock());
if (configuration != null && configuration.isNewlinesMustCauseLineBreak()) {
paragraphBlock.setNewlinesCauseLineBreak(true);
}
return paragraphBlock;
}
/**
*
*/
@Override
public List<Template> getTemplates() {
return templates;
}
/**
*
*/
public void setTemplates(List<Template> templates) {
if (templates == null) {
throw new IllegalArgumentException();
}
this.templates = templates;
}
/**
*
*/
@Override
public List<TemplateResolver> getTemplateProviders() {
return templateProviders;
}
/**
*
*/
public void setTemplateProviders(List<TemplateResolver> templateProviders) {
if (templateProviders == null) {
throw new IllegalArgumentException();
}
this.templateProviders = templateProviders;
}
@Override
public MarkupLanguage clone() {
MediaWikiLanguage copy = (MediaWikiLanguage) super.clone();
copy.templates = new ArrayList<Template>(templates);
copy.templateProviders = new ArrayList<TemplateResolver>(templateProviders);
copy.templateExcludes = templateExcludes;
return copy;
}
/**
* Indicate template names to exclude.
*
* @param templateExcludes
* a comma-delimited list of names, may include '*' wildcards
*/
public void setTemplateExcludes(String templateExcludes) {
this.templateExcludes = templateExcludes;
}
/**
* Indicate template names to exclude.
*
* @return a comma-delimited list of names, may include '*' wildcards, or null if none are to be excluded
*/
@Override
public String getTemplateExcludes() {
return templateExcludes;
}
}