| /******************************************************************************* |
| * Copyright (c) 2007, 2010 David Green and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * David Green - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.mylyn.wikitext.twiki.internal.token; |
| |
| import java.util.regex.Matcher; |
| import java.util.regex.Pattern; |
| |
| import org.eclipse.mylyn.wikitext.parser.markup.PatternBasedElement; |
| import org.eclipse.mylyn.wikitext.parser.markup.PatternBasedElementProcessor; |
| import org.eclipse.mylyn.wikitext.twiki.TWikiLanguage; |
| |
| /** |
| * Tokens that represent links, as follows: <code>[[link]]</code> |
| * |
| * @author David Green |
| */ |
| public class LinkReplacementToken extends PatternBasedElement { |
| |
| private static final Pattern replacementPattern = Pattern.compile("\\W"); //$NON-NLS-1$ |
| |
| private static final Pattern wordBoundaryPattern = Pattern.compile("\\W\\w"); //$NON-NLS-1$ |
| |
| @Override |
| protected String getPattern(int groupOffset) { |
| return "(!)?(\\[\\[([^\\]]+)(?:(\\]\\[)([^\\]]*))?\\]\\])"; //$NON-NLS-1$ |
| } |
| |
| @Override |
| protected int getPatternGroupCount() { |
| return 5; |
| } |
| |
| @Override |
| protected PatternBasedElementProcessor newProcessor() { |
| return new LinkProcessor(); |
| } |
| |
| private static class LinkProcessor extends PatternBasedElementProcessor { |
| @Override |
| public void emit() { |
| String escaped = group(1); |
| if (escaped != null) { |
| String escapedText = group(2); |
| builder.characters(escapedText); |
| } else { |
| String link = group(3); |
| String text = group(5); |
| if (text == null || text.trim().length() == 0) { |
| text = link; |
| } |
| boolean looksLikeEmail = link.indexOf('@') != -1; |
| if (link.indexOf('/') != -1 || link.indexOf('#') != -1 || looksLikeEmail) { |
| if (looksLikeEmail) { |
| text = text.replaceFirst("\\s*mailto:", ""); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| // url link |
| builder.link(link, text); |
| } else { |
| // wiki link |
| link = camelCaseWordBoundaries(link); |
| String target = replacementPattern.matcher(link).replaceAll(""); //$NON-NLS-1$ |
| TWikiLanguage twikiLanguage = (TWikiLanguage) markupLanguage; |
| boolean exists = twikiLanguage.computeInternalLinkExists(target); |
| |
| String internalHref = twikiLanguage.toInternalHref(target); |
| if (!exists) { |
| builder.characters(text); |
| builder.link(internalHref, "?"); //$NON-NLS-1$ |
| } else { |
| builder.link(internalHref, text); |
| } |
| } |
| } |
| } |
| |
| private String camelCaseWordBoundaries(String text) { |
| Matcher matcher = wordBoundaryPattern.matcher(text); |
| String newText = Character.toString(Character.toUpperCase(text.charAt(0))); |
| int start = 1; |
| while (matcher.find()) { |
| int offset = matcher.start(); |
| newText += text.substring(start, offset); |
| |
| newText += Character.toUpperCase(text.charAt(offset + 1)); |
| |
| start = offset + 2; |
| } |
| if (start < text.length()) { |
| newText += text.substring(start); |
| } |
| return newText; |
| } |
| } |
| |
| } |