/* * Scute * * Homepage: http://hyperdata.org/scute * * License : http://www.apache.org/licenses/LICENSE-2.0 * See also license.txt or http://hyperdata.org/wiki/Scute:License * * Danny Ayers 2011 */ package org.hyperdata.scute.syntax; import java.awt.Color; import java.awt.Graphics; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import java.util.SortedMap; import java.util.TreeMap; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.swing.text.*; /** * The Class HighlighterView. * * contains methods - subclasses contain pattern constants * */ public abstract class HighlighterView extends ScalableView implements PatternMap { private static HashMap<Pattern, Color> patternMap; /** * Instantiates a new turtle view. * * @param element * the element */ public HighlighterView(Element element) { super(element); // Set tabsize to 4 (instead of the default 8) getDocument().putProperty(PlainDocument.tabSizeAttribute, 4); } /* (non-Javadoc) * @see javax.swing.text.PlainView#drawUnselectedText(java.awt.Graphics, int, int, int, int) */ @Override protected int drawUnselectedText(Graphics graphics, int x, int y, int p0, int p1) throws BadLocationException { final Document doc = getDocument(); final String text = doc.getText(p0, p1 - p0); final Segment segment = getLineBuffer(); final SortedMap<Integer, Integer> blockMap = new TreeMap<Integer, Integer>(); final SortedMap<Integer, Color> colorMap = new TreeMap<Integer, Color>(); // Match all regexes on this snippet, store positions for (final Map.Entry<Pattern, Color> entry : getPatternMap().entrySet()) { // System.out.println(); final Matcher matcher = entry.getKey().matcher(text); MatcherLoop: while (matcher.find()) { // System.out.println(matcher.start(1) + " -> " +matcher.end()); // System.out.println(matcher.group()); // remove blocks nested inside - redundant? for(int i = matcher.start(1);i<matcher.end();i++){ if(blockMap.get(i) != null){ if(blockMap.get(i) < matcher.end()){ blockMap.remove(i); } } } // don't insert if this will be inside a larger match for(int i = 0;i<matcher.start(1);i++){ if(blockMap.get(i) != null){ if(blockMap.get(i) > matcher.end()){ // System.out.println("don't include inner "+i+" -> "+matcher.end()); // System.out.println("-----------------------"); break MatcherLoop; } } } blockMap.put(matcher.start(1), matcher.end()); colorMap.put(matcher.start(1), entry.getValue()); } } // Colour the parts int i = 0; for (final Map.Entry<Integer, Integer> entry : blockMap.entrySet()) { final int start = entry.getKey(); final int end = entry.getValue(); if (i < start) { graphics.setColor(Color.black); doc.getText(p0 + i, start - i, segment); x = Utilities.drawTabbedText(segment, x, y, graphics, this, i); } graphics.setColor(colorMap.get(start)); i = end; doc.getText(p0 + start, i - start, segment); x = Utilities.drawTabbedText(segment, x, y, graphics, this, start); } // Paint possible remaining text black if (i < text.length()) { graphics.setColor(Color.black); doc.getText(p0 + i, text.length() - i, segment); x = Utilities.drawTabbedText(segment, x, y, graphics, this, i); } return x; // x is end of block } }