blob: b15ad4d8ea98b56fd6f47a9125a3d53d24222ca4 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010, 2012, 2015 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.internal.wikitext.mediawiki.core;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.MessageFormat;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.mylyn.wikitext.core.parser.MarkupParser;
import org.eclipse.mylyn.wikitext.core.parser.markup.AbstractMarkupLanguage;
import org.eclipse.mylyn.wikitext.core.parser.markup.MarkupLanguage;
import org.eclipse.mylyn.wikitext.mediawiki.core.Template;
import org.eclipse.mylyn.wikitext.mediawiki.core.TemplateResolver;
/**
* @author David Green
*/
public abstract class AbstractMediaWikiLanguage extends AbstractMarkupLanguage {
private static final String CATEGORY_PREFIX = ":"; //$NON-NLS-1$
private static final Pattern STANDARD_EXTERNAL_LINK_FORMAT = Pattern.compile(".*?/([^/]+)/(\\{\\d+\\})"); //$NON-NLS-1$
private static final Pattern QUALIFIED_INTERNAL_LINK = Pattern.compile("([^/]+)/(.+)"); //$NON-NLS-1$
private PageMapping pageMapping;
private Map<String, String> imageMapping;
protected String mapPageNameToHref(String pageName) {
if (pageMapping != null) {
String mapping = pageMapping.mapPageNameToHref(pageName);
if (mapping != null) {
return mapping;
}
}
String pageId;
int anchorIndex = pageName.indexOf("#"); //$NON-NLS-1$
if (anchorIndex < 0) {
pageId = pageName;
} else {
String encodedAnchor = MediaWikiIdGenerationStrategy.headingTextToId(pageName.substring(anchorIndex + 1));
pageId = pageName.substring(0, anchorIndex) + "#" + encodedAnchor; //$NON-NLS-1$
}
if (pageId.startsWith(CATEGORY_PREFIX) && pageId.length() > CATEGORY_PREFIX.length()) { // category
return pageId.substring(CATEGORY_PREFIX.length());
} else if (pageId.startsWith("#")) { //$NON-NLS-1$
// internal anchor
return pageId;
}
if (internalLinkPattern.contains("index.php?")) { //$NON-NLS-1$
try {
pageId = URLEncoder.encode(pageId, "UTF-8"); //$NON-NLS-1$
} catch (UnsupportedEncodingException e) {
throw new IllegalStateException(MessageFormat.format(
Messages.getString("AbstractMediaWikiLanguage_cannotComputeUrl"), pageId), e); //$NON-NLS-1$
}
}
if (QUALIFIED_INTERNAL_LINK.matcher(pageId).matches()) {
Matcher matcher = STANDARD_EXTERNAL_LINK_FORMAT.matcher(internalLinkPattern);
if (matcher.matches()) {
String prefix = matcher.group(1);
if (pageId.startsWith(prefix + '/')) {
return internalLinkPattern.substring(0, matcher.start(1)) + pageId;
} else {
return internalLinkPattern.substring(0, matcher.start(2)) + pageId;
}
}
}
return MessageFormat.format(super.internalLinkPattern, pageId);
}
public PageMapping getPageMapping() {
return pageMapping;
}
public void setPageMapping(PageMapping pageMapping) {
this.pageMapping = pageMapping;
}
@Override
public void processContent(MarkupParser parser, String markupContent, boolean asDocument) {
if (isEnableMacros()) {
markupContent = preprocessContent(markupContent);
}
super.processContent(parser, markupContent, asDocument);
}
/**
* preprocess content, which involves template substitution.
*/
private String preprocessContent(String markupContent) {
return new TemplateProcessor(this).processTemplates(markupContent);
}
public abstract List<Template> getTemplates();
public abstract List<TemplateResolver> getTemplateProviders();
public abstract String getTemplateExcludes();
public Set<String> getImageNames() {
if (imageMapping == null) {
return Collections.emptySet();
}
return Collections.unmodifiableSet(new HashSet<String>(imageMapping.values()));
}
public void setImageNames(Set<String> imageNames) {
if (imageMapping == null) {
imageMapping = new HashMap<String, String>();
} else {
imageMapping.clear();
}
for (String name : imageNames) {
imageMapping.put(name.toLowerCase(), name);
}
}
public String mapImageName(String imageName) {
String substitute = imageMapping == null ? null : imageMapping.get(imageName.toLowerCase());
if (substitute != null) {
imageName = substitute;
}
return imageName;
}
@Override
public MarkupLanguage clone() {
AbstractMediaWikiLanguage copy = (AbstractMediaWikiLanguage) super.clone();
copy.imageMapping = this.imageMapping;
copy.pageMapping = this.pageMapping;
return copy;
}
}