Package org.rascalmpl.uri

Source Code of org.rascalmpl.uri.LinkifiedString

package org.rascalmpl.uri;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class LinkifiedString {
 
  private List<Integer> linkOffsets;
  private List<Integer> linkLengths;
  private List<String> linkTargets;
  private String linkedString;
 
 
  public String getString() {
    return linkedString;
  }
 
  public boolean containsLinks() {
    return linkOffsets != null && linkOffsets.size() > 0;
  }
 
  public int linkCount() {
    return linkOffsets == null ? 0 : linkOffsets.size();
  }
 
  public int linkOffset(int index) {
    if (linkOffsets == null) {
      throw new IllegalStateException("There are no links");
    }
    return linkOffsets.get(index)
  }
 
  public int linkLength(int index) {
    if (linkLengths == null) {
      throw new IllegalStateException("There are no links");
    }
    return linkLengths.get(index)
  }
  public String linkTarget(int index) {
    if (linkTargets == null) {
      throw new IllegalStateException("There are no links");
    }
    return linkTargets.get(index)
  }
 

  // scan for both \uE007 + [Title](url) and all |loc|'s
  private static final Pattern findLinks = Pattern.compile(
      "(?:\\uE007" // first alternative, Markdown
        + "\\[([^\\]]*)\\]" // [Title]
        + "\\(([^\\)]*)\\)" // (link)
      + ")"
      + "|"
      + "(" // or the other alternative, any rascal location
        + "\\|[^\\t-\\n\\r\\s\\|]*://[^\\t-\\n\\r\\s\\|]*\\|" // |location|
        + "(?:\\([^\\)]*\\))?" // (optional offset)
      + ")");
 
  public LinkifiedString(String input) {
    linkedString = input;
   
    StringBuffer sb = null;
    Matcher m = findLinks.matcher(input);
    while (m.find()) {
      if (linkOffsets == null) {
        linkOffsets = new ArrayList<Integer>();
        linkLengths = new ArrayList<Integer>();
        linkTargets = new ArrayList<String>();
      }
      if (m.group(3) == null) {
        if (sb == null) {
          // first link found, so we have to recut the string
          sb = new StringBuffer(input.length());
        }
        // markdown link
        String name =  "\u261E " + m.group(1) ;
        String url = m.group(2);
        linkTargets.add(url);
        m.appendReplacement(sb, escapeReplacement(name));
        linkOffsets.add((sb.length() - name.length()) + 1);
        linkLengths.add(name.length());
      }
      else {
        // source location
        String loc = m.group(3);
        linkTargets.add(loc);
        if (sb != null) {
          // we are re-appending
          m.appendReplacement(sb, escapeReplacement(loc));
          linkOffsets.add((sb.length() - loc.length()) + 1);
        }
        else {
          linkOffsets.add(m.start() + 1);
        }
        linkLengths.add(loc.length());
      }
    }
    if (sb != null) {
      // we have a new string
      m.appendTail(sb);
      linkedString = sb.toString();
    }
  }
 
  private static String escapeReplacement(String replacement) {
    // the $ char should be escaped when we append it as a replacement,
    // since it is used by the regular expression engine to reference a group
    // the \ also needs to be escape, since it is used for escaping in the replacement string
    if (replacement.length() < 20) {
      return replacement.replace("\\", "\\\\").replace("$", "\\$");
    }
    else {
      // okay, "larger" string, lets avoid double loop
      int stringLength = replacement.length();
      StringBuilder sb = new StringBuilder(stringLength);
      for (int currentChar = 0; currentChar < stringLength; currentChar++) {
        char c = replacement.charAt(currentChar);
        if (c == '\\')
          sb.append('\\');
        else if (c == '$' )
          sb.append('\\');
        sb.append(c);
      }
      return sb.toString();
    }
  }
}
TOP

Related Classes of org.rascalmpl.uri.LinkifiedString

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.