Changes:
1. Refractor the structure, isolate those reuseable/generic part out of the SyntaxHighlighter
diff --git a/src/prettify/PrettifyParser.java b/src/prettify/PrettifyParser.java
new file mode 100644
index 0000000..041189a
--- /dev/null
+++ b/src/prettify/PrettifyParser.java
@@ -0,0 +1,41 @@
+package prettify;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import prettify.parser.Job;
+import prettify.parser.Prettify;
+import syntaxhighlight.ParseResult;
+import syntaxhighlight.Parser;
+
+/**
+ * @author Chan Wai Shing <cws1989@gmail.com>
+ */
+public class PrettifyParser implements Parser {
+
+ protected Prettify prettify;
+
+ public PrettifyParser() {
+ prettify = new Prettify();
+ }
+
+ @Override
+ public List<ParseResult> parse(String fileExtension, String content) {
+ Job job = new Job(0, content);
+ prettify.langHandlerForExtension(fileExtension, content).decorate(job);
+ List<Object> decorations = job.getDecorations();
+
+
+ List<ParseResult> returnList = new ArrayList<ParseResult>();
+
+ Integer startPos = 0, endPos = 0;
+ // apply style according to the style list
+ for (int i = 0, iEnd = decorations.size(); i < iEnd; i += 2) {
+ endPos = i + 2 < iEnd ? (Integer) decorations.get(i + 2) : content.length();
+ startPos = (Integer) decorations.get(i);
+ returnList.add(new ParseResult(startPos, endPos - startPos, Arrays.asList(new String[]{(String) decorations.get(i + 1)})));
+ }
+
+ return returnList;
+ }
+}
diff --git a/src/prettify/example/Example.java b/src/prettify/example/Example.java
index 366f217..33f4df3 100644
--- a/src/prettify/example/Example.java
+++ b/src/prettify/example/Example.java
@@ -22,8 +22,10 @@
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
-import prettify.SyntaxHighlighter;
+import prettify.PrettifyParser;
import prettify.theme.ThemeDefault;
+import syntaxhighlight.Parser;
+import syntaxhighlight.SyntaxHighlighter;
/**
* Usage example. This will just cover some of the functions. To know other
@@ -88,8 +90,10 @@
long start, end;
start = System.currentTimeMillis();
+ // initialize the parser
+ Parser parser = new PrettifyParser();
// use Default theme
- SyntaxHighlighter highlighter = new SyntaxHighlighter(new ThemeDefault());
+ SyntaxHighlighter highlighter = new SyntaxHighlighter(parser, new ThemeDefault());
// set the line number count from 10 instead of 1
highlighter.setFirstLine(10);
// set to highlight line 13, 27, 28, 38, 42, 43 and 53
diff --git a/src/prettify/gui/package-info.java b/src/prettify/gui/package-info.java
deleted file mode 100644
index cdbe674..0000000
--- a/src/prettify/gui/package-info.java
+++ /dev/null
@@ -1,4 +0,0 @@
-/**
- * GUI.
- */
-package prettify.gui;
\ No newline at end of file
diff --git a/src/prettify/theme/Theme.java b/src/prettify/theme/Theme.java
deleted file mode 100644
index fc34eda..0000000
--- a/src/prettify/theme/Theme.java
+++ /dev/null
@@ -1,676 +0,0 @@
-// Copyright (C) 2011 Chan Wai Shing
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-package prettify.theme;
-
-import java.awt.Color;
-import java.awt.Font;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import prettify.gui.JTextComponentRowHeader;
-
-/**
- * Theme for the Java Prettify.
- * <p>To make a new theme, either extending this class of initiate this class
- * and set the parameter by the setter. For the default value, please refer to
- * the constructor.</p>
- * @author Chan Wai Shing <cws1989@gmail.com>
- */
-public class Theme {
-
- /**
- * Indicate whether it is in debug mode or not.
- */
- protected final static boolean debug;
-
- static {
- String debugMode = System.getProperty("PrettifyDebugMode");
- debug = debugMode == null || !debugMode.equals("true") ? false : true;
- }
- /**
- * The font of the script text.
- */
- protected Font font;
- /**
- * The background color of the script text area.
- */
- protected Color background;
- /**
- * The background color of the highlighted line of script text.
- */
- protected Color highlightedBackground;
- /**
- * Gutter (line number column on the left)
- */
- /**
- * The color of the gutter text.
- */
- protected Color gutterText;
- /**
- * The color of the border that joint the gutter and the script text panel.
- */
- protected Color gutterBorderColor;
- /**
- * The width of the border that joint the gutter and the script text panel.
- */
- protected int gutterBorderWidth;
- /**
- * The font of the gutter text.
- */
- protected Font gutterTextFont;
- /**
- * The minimum padding from 'the leftmost of the line number text' to
- * 'the left margin'.
- */
- protected int gutterTextPaddingLeft;
- /**
- * The minimum padding from 'the rightmost of the line number text' to
- * 'the right margin' (not to the gutter border).
- */
- protected int gutterTextPaddingRight;
- protected Style string;
- protected Style keyword;
- protected Style comment;
- protected Style type;
- protected Style literal;
- protected Style punctuation;
- protected Style plain;
- protected Style tag;
- protected Style declaration;
- protected Style source;
- protected Style attributeName;
- protected Style attributeValue;
- protected Style noCode;
- protected Style openBracket;
- protected Style closeBracket;
- protected Style variable;
- protected Style function;
-
- /**
- * Constructor.<br />
- * <p>
- * <b>Default value:</b><br />
- * <ul>
- * <li>font: Consolas 12pt</li>
- * <li>background: white</li>
- * <li>gutter text: black</li>
- * <li>gutter border: R: 184, G: 184, B: 184</li>
- * <li>gutter border width: 3px</li>
- * <li>gutter text font: Consolas 12pt</li>
- * <li>gutter text padding-left: 7px</li>
- * <li>gutter text padding-right: 7px</li>
- * <li>plain, comments, string, keyword, preprocessor, variable, value,
- * functions, constants, script, scriptBackground, color1, color2, color3:
- * no style set</li>
- * </ul>
- * </p>
- */
- public Theme() {
- font = new Font("Consolas", Font.PLAIN, 12);
- background = Color.white;
-
- highlightedBackground = Color.gray;
-
- gutterText = Color.black;
- gutterBorderColor = new Color(184, 184, 184);
- gutterBorderWidth = 3;
- gutterTextFont = new Font("Consolas", Font.PLAIN, 12);
- gutterTextPaddingLeft = 7;
- gutterTextPaddingRight = 7;
-
- string = new Style();
- keyword = new Style();
- comment = new Style();
- type = new Style();
- literal = new Style();
- punctuation = new Style();
- plain = new Style();
- tag = new Style();
- declaration = new Style();
- source = new Style();
- attributeName = new Style();
- attributeValue = new Style();
- noCode = new Style();
- openBracket = new Style();
- closeBracket = new Style();
- variable = new Style();
- function = new Style();
- }
-
- /**
- * Apply the theme to the row header panel.
- * @param rowHeader the row header to apply theme on
- */
- public void setTheme(JTextComponentRowHeader rowHeader) {
- rowHeader.setBackground(background);
- rowHeader.setHighlightedColor(background);
-
- rowHeader.setForeground(gutterText);
- rowHeader.setBorderColor(gutterBorderColor);
- rowHeader.setBorderWidth(gutterBorderWidth);
- rowHeader.setFont(gutterTextFont);
- rowHeader.setPaddingLeft(gutterTextPaddingLeft);
- rowHeader.setPaddingRight(gutterTextPaddingRight);
- }
-
- /**
- * Get the {@link prettify.theme.Style} by keyword.
- * @param key the keyword, possible values: plain, comments, string, keyword,
- * preprocessor, variable, value, functions, constants, script,
- * scriptBackground, color1, color2 or color3
- * @return the {@link prettify.theme.Style} related to the {@code key}; if
- * the style related to the <code>key</code> not exist, the style of 'plain'
- * will return.
- */
- public Style getStyle(String key) {
- if (key == null) {
- return plain;
- }
- if (key.equals("str")) {
- return string;
- } else if (key.equals("kwd")) {
- return keyword;
- } else if (key.equals("com")) {
- return comment;
- } else if (key.equals("typ")) {
- return type;
- } else if (key.equals("lit")) {
- return literal;
- } else if (key.equals("pun")) {
- return punctuation;
- } else if (key.equals("pln")) {
- return plain;
- } else if (key.equals("tag")) {
- return tag;
- } else if (key.equals("dec")) {
- return declaration;
- } else if (key.equals("src")) {
- return source;
- } else if (key.equals("atn")) {
- return attributeName;
- } else if (key.equals("atv")) {
- return attributeValue;
- } else if (key.equals("nocode")) {
- return noCode;
- } else if (key.equals("opn")) {
- return openBracket;
- } else if (key.equals("clo")) {
- return closeBracket;
- } else if (key.equals("var")) {
- return variable;
- } else if (key.equals("fun")) {
- return function;
- } else {
- // key not exist
- return plain;
- }
- }
-
- /**
- * The font of the script text.
- * @return the font
- */
- public Font getFont() {
- return font;
- }
-
- /**
- * The font of the script text.
- * @param font the font
- */
- public void setFont(Font font) {
- if (font == null) {
- throw new NullPointerException("argument 'font' cannot be null");
- }
- this.font = font;
- }
-
- /**
- * The background color of the script text area.
- * @return the color
- */
- public Color getBackground() {
- return background;
- }
-
- /**
- * The background color of the script text area.
- * @param background the color
- */
- public void setBackground(Color background) {
- if (background == null) {
- throw new NullPointerException("argument 'background' cannot be null");
- }
- this.background = background;
- }
-
- /**
- * The background color of the highlighted line of script text.
- * @return the color
- */
- public Color getHighlightedBackground() {
- return highlightedBackground;
- }
-
- /**
- * The background color of the highlighted line of script text.
- * @param highlightedBackground the color
- */
- public void setHighlightedBackground(Color highlightedBackground) {
- if (highlightedBackground == null) {
- throw new NullPointerException("argument 'highlightedBackground' cannot be null");
- }
- this.highlightedBackground = highlightedBackground;
- }
-
- /**
- * The color of the gutter text.
- * @return the color
- */
- public Color getGutterText() {
- return gutterText;
- }
-
- /**
- * The color of the gutter text.
- * @param gutterText the color
- */
- public void setGutterText(Color gutterText) {
- if (gutterText == null) {
- throw new NullPointerException("argument 'gutterText' cannot be null");
- }
- this.gutterText = gutterText;
- }
-
- /**
- * The color of the border that joint the gutter and the script text panel.
- * @return the color
- */
- public Color getGutterBorderColor() {
- return gutterBorderColor;
- }
-
- /**
- * The color of the border that joint the gutter and the script text panel.
- * @param gutterBorderColor the color
- */
- public void setGutterBorderColor(Color gutterBorderColor) {
- if (gutterBorderColor == null) {
- throw new NullPointerException("argument 'gutterBorderColor' cannot be null");
- }
- this.gutterBorderColor = gutterBorderColor;
- }
-
- /**
- * The width of the border that joint the gutter and the script text panel.
- * @return the width in pixel
- */
- public int getGutterBorderWidth() {
- return gutterBorderWidth;
- }
-
- /**
- * The width of the border that joint the gutter and the script text panel.
- * @param gutterBorderWidth in pixel
- */
- public void setGutterBorderWidth(int gutterBorderWidth) {
- this.gutterBorderWidth = gutterBorderWidth;
- }
-
- /**
- * The font of the gutter text.
- * @return the font
- */
- public Font getGutterTextFont() {
- return gutterTextFont;
- }
-
- /**
- * The font of the gutter text.
- * @param gutterTextFont the font
- */
- public void setGutterTextFont(Font gutterTextFont) {
- if (gutterTextFont == null) {
- throw new NullPointerException("argument 'gutterTextFont' cannot be null");
- }
- this.gutterTextFont = gutterTextFont;
- }
-
- /**
- * The minimum padding from 'the leftmost of the line number text' to 'the left margin'.
- * @return the padding in pixel
- */
- public int getGutterTextPaddingLeft() {
- return gutterTextPaddingLeft;
- }
-
- /**
- * The minimum padding from 'the leftmost of the line number text' to
- * 'the left margin'.
- * @param gutterTextPaddingLeft in pixel
- */
- public void setGutterTextPaddingLeft(int gutterTextPaddingLeft) {
- this.gutterTextPaddingLeft = gutterTextPaddingLeft;
- }
-
- /**
- * The minimum padding from 'the rightmost of the line number text' to
- * 'the right margin' (not to the gutter border).
- * @return the padding in pixel
- */
- public int getGutterTextPaddingRight() {
- return gutterTextPaddingRight;
- }
-
- /**
- * The minimum padding from 'the rightmost of the line number text' to
- * 'the right margin' (not to the gutter border).
- * @param gutterTextPaddingRight in pixel
- */
- public void setGutterTextPaddingRight(int gutterTextPaddingRight) {
- this.gutterTextPaddingRight = gutterTextPaddingRight;
- }
-
- public Style getString() {
- return string;
- }
-
- public void setString(Style string) {
- if (string == null) {
- throw new NullPointerException("argument 'string' cannot be null");
- }
- this.string = string;
- }
-
- public Style getKeyword() {
- return keyword;
- }
-
- public void setKeyword(Style keyword) {
- if (keyword == null) {
- throw new NullPointerException("argument 'keyword' cannot be null");
- }
- this.keyword = keyword;
- }
-
- public Style getComment() {
- return comment;
- }
-
- public void setComment(Style comment) {
- if (comment == null) {
- throw new NullPointerException("argument 'comment' cannot be null");
- }
- this.comment = comment;
- }
-
- public Style getType() {
- return type;
- }
-
- public void setType(Style type) {
- if (type == null) {
- throw new NullPointerException("argument 'type' cannot be null");
- }
- this.type = type;
- }
-
- public Style getLiteral() {
- return literal;
- }
-
- public void setLiteral(Style literal) {
- if (literal == null) {
- throw new NullPointerException("argument 'literal' cannot be null");
- }
- this.literal = literal;
- }
-
- public Style getPunctuation() {
- return punctuation;
- }
-
- public void setPunctuation(Style punctuation) {
- if (punctuation == null) {
- throw new NullPointerException("argument 'punctuation' cannot be null");
- }
- this.punctuation = punctuation;
- }
-
- public Style getPlain() {
- return plain;
- }
-
- public void setPlain(Style plain) {
- if (plain == null) {
- throw new NullPointerException("argument 'plain' cannot be null");
- }
- this.plain = plain;
- }
-
- public Style getTag() {
- return tag;
- }
-
- public void setTag(Style tag) {
- if (tag == null) {
- throw new NullPointerException("argument 'tag' cannot be null");
- }
- this.tag = tag;
- }
-
- public Style getDeclaration() {
- return declaration;
- }
-
- public void setDeclaration(Style declaration) {
- if (declaration == null) {
- throw new NullPointerException("argument 'declaration' cannot be null");
- }
- this.declaration = declaration;
- }
-
- public Style getSource() {
- return source;
- }
-
- public void setSource(Style source) {
- if (source == null) {
- throw new NullPointerException("argument 'source' cannot be null");
- }
- this.source = source;
- }
-
- public Style getAttributeName() {
- return attributeName;
- }
-
- public void setAttributeName(Style attributeName) {
- if (attributeName == null) {
- throw new NullPointerException("argument 'attributeName' cannot be null");
- }
- this.attributeName = attributeName;
- }
-
- public Style getAttributeValue() {
- return attributeValue;
- }
-
- public void setAttributeValue(Style attributeValue) {
- if (attributeValue == null) {
- throw new NullPointerException("argument 'attributeValue' cannot be null");
- }
- this.attributeValue = attributeValue;
- }
-
- public Style getNoCode() {
- return noCode;
- }
-
- public void setNoCode(Style noCode) {
- if (noCode == null) {
- throw new NullPointerException("argument 'noCode' cannot be null");
- }
- this.noCode = noCode;
- }
-
- public Style getOpenBracket() {
- return openBracket;
- }
-
- public void setOpenBracket(Style openBracket) {
- if (openBracket == null) {
- throw new NullPointerException("argument 'openBracket' cannot be null");
- }
- this.openBracket = openBracket;
- }
-
- public Style getCloseBracket() {
- return closeBracket;
- }
-
- public void setCloseBracket(Style closeBracket) {
- if (closeBracket == null) {
- throw new NullPointerException("argument 'closeBracket' cannot be null");
- }
- this.closeBracket = closeBracket;
- }
-
- public Style getVariable() {
- return variable;
- }
-
- public void setVariable(Style variable) {
- if (variable == null) {
- throw new NullPointerException("argument 'variable' cannot be null");
- }
- this.variable = variable;
- }
-
- public Style getFunction() {
- return function;
- }
-
- public void setFunction(Style function) {
- if (function == null) {
- throw new NullPointerException("argument 'function' cannot be null");
- }
- this.function = function;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public Theme clone() {
- Theme object = null;
- try {
- object = (Theme) super.clone();
- object.font = font;
- object.background = background;
- object.highlightedBackground = highlightedBackground;
- object.gutterText = gutterText;
- object.gutterBorderColor = gutterBorderColor;
- object.gutterBorderWidth = gutterBorderWidth;
- object.gutterTextFont = gutterTextFont;
- object.gutterTextPaddingLeft = gutterTextPaddingLeft;
- object.gutterTextPaddingRight = gutterTextPaddingRight;
- object.string = string.clone();
- object.keyword = keyword.clone();
- object.comment = comment.clone();
- object.type = type.clone();
- object.literal = literal.clone();
- object.punctuation = punctuation.clone();
- object.plain = plain.clone();
- object.tag = tag.clone();
- object.declaration = declaration.clone();
- object.source = source.clone();
- object.attributeName = attributeName.clone();
- object.attributeValue = attributeValue.clone();
- object.noCode = noCode.clone();
- object.openBracket = openBracket.clone();
- object.closeBracket = closeBracket.clone();
- object.variable = variable.clone();
- object.function = function.clone();
- } catch (CloneNotSupportedException ex) {
- if (debug) {
- Logger.getLogger(Theme.class.getName()).log(Level.WARNING, null, ex);
- }
- }
- return object;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
-
- sb.append(getClass().getName());
- sb.append(": ");
- sb.append("font: ").append(getFont());
- sb.append(", ");
- sb.append("background: ").append(getBackground());
- sb.append(", ");
- sb.append("highlightedBackground: ").append(getHighlightedBackground());
- sb.append(", ");
- sb.append("gutterText: ").append(getGutterText());
- sb.append(", ");
- sb.append("gutterBorderColor: ").append(getGutterBorderColor());
- sb.append(", ");
- sb.append("gutterBorderWidth: ").append(getGutterBorderWidth());
- sb.append(", ");
- sb.append("gutterTextFont: ").append(getGutterTextFont());
- sb.append(", ");
- sb.append("gutterTextPaddingLeft: ").append(getGutterTextPaddingLeft());
- sb.append(", ");
- sb.append("gutterTextPaddingRight: ").append(getGutterTextPaddingRight());
- sb.append(", ");
- sb.append("string: ").append(getString());
- sb.append(", ");
- sb.append("keyword: ").append(getKeyword());
- sb.append(", ");
- sb.append("comment: ").append(getComment());
- sb.append(", ");
- sb.append("type: ").append(getType());
- sb.append(", ");
- sb.append("literal: ").append(getLiteral());
- sb.append(", ");
- sb.append("punctuation: ").append(getPunctuation());
- sb.append(", ");
- sb.append("plain: ").append(getPlain());
- sb.append(", ");
- sb.append("tag: ").append(getTag());
- sb.append(", ");
- sb.append("declaration: ").append(getDeclaration());
- sb.append(", ");
- sb.append("source: ").append(getSource());
- sb.append(", ");
- sb.append("attributeName: ").append(getAttributeName());
- sb.append(", ");
- sb.append("attributeValue: ").append(getAttributeValue());
- sb.append(", ");
- sb.append("noCode: ").append(getNoCode());
- sb.append(", ");
- sb.append("openBracket: ").append(getOpenBracket());
- sb.append(", ");
- sb.append("closeBracket: ").append(getCloseBracket());
- sb.append(", ");
- sb.append("variable: ").append(getVariable());
- sb.append(", ");
- sb.append("function: ").append(getFunction());
-
- return sb.toString();
- }
-}
diff --git a/src/prettify/theme/ThemeDefault.java b/src/prettify/theme/ThemeDefault.java
index 8a903a5..c57f1d9 100644
--- a/src/prettify/theme/ThemeDefault.java
+++ b/src/prettify/theme/ThemeDefault.java
@@ -15,6 +15,8 @@
import java.awt.Color;
import java.awt.Font;
+import syntaxhighlight.Style;
+import syntaxhighlight.Theme;
/**
* Default theme.
@@ -38,64 +40,65 @@
Style plainStyle = new Style();
plainStyle.setColor(Color.decode("0x000000"));
+ addStyle("pln", plainStyle);
setPlain(plainStyle);
Style style;
style = new Style();
style.setColor(Color.decode("0x008800"));
- setString(style);
+ addStyle("str", style);
style = new Style();
style.setColor(Color.decode("0x000088"));
- setKeyword(style);
+ addStyle("kwd", style);
style = new Style();
style.setColor(Color.decode("0x880000"));
- setComment(style);
+ addStyle("com", style);
style = new Style();
style.setColor(Color.decode("0x660066"));
- setType(style);
+ addStyle("typ", style);
style = new Style();
style.setColor(Color.decode("0x006666"));
- setLiteral(style);
+ addStyle("lit", style);
style = new Style();
style.setColor(Color.decode("0x666600"));
- setPunctuation(style);
+ addStyle("pun", style);
style = new Style();
style.setColor(Color.decode("0x000088"));
- setTag(style);
+ addStyle("tag", style);
- setDeclaration(plainStyle);
+ addStyle("dec", plainStyle);
style = new Style();
style.setColor(Color.decode("0x660066"));
- setAttributeName(style);
+ addStyle("atn", style);
style = new Style();
style.setColor(Color.decode("0x008800"));
- setAttributeValue(style);
+ addStyle("atv", style);
- setNoCode(plainStyle);
+ addStyle("nocode", plainStyle);
style = new Style();
style.setColor(Color.decode("0x666600"));
- setOpenBracket(style);
+ addStyle("opn", style);
style = new Style();
style.setColor(Color.decode("0x666600"));
- setCloseBracket(style);
+ addStyle("clo", style);
style = new Style();
style.setColor(Color.decode("0x660066"));
- setVariable(style);
+ addStyle("var", style);
style = new Style();
style.setColor(Color.red);
- setFunction(style);
+ addStyle("fun", style);
}
}
diff --git a/src/prettify/theme/ThemeDesert.java b/src/prettify/theme/ThemeDesert.java
index 77149ea..ff1ffda 100644
--- a/src/prettify/theme/ThemeDesert.java
+++ b/src/prettify/theme/ThemeDesert.java
@@ -15,6 +15,8 @@
import java.awt.Color;
import java.awt.Font;
+import syntaxhighlight.Style;
+import syntaxhighlight.Theme;
/**
* Desert theme.
@@ -40,64 +42,65 @@
Style plainStyle = new Style();
plainStyle.setColor(Color.decode("0xffffff"));
+ addStyle("pln", plainStyle);
setPlain(plainStyle);
Style style;
style = new Style();
style.setColor(Color.decode("0xffa0a0")); /* string - pink */
- setString(style);
+ addStyle("str", style);
style = new Style();
style.setColor(Color.decode("0xf0e68c"));
style.setBold(true);
- setKeyword(style);
+ addStyle("kwd", style);
style = new Style();
style.setColor(Color.decode("0x87ceeb")); /* comment - skyblue */
- setComment(style);
+ addStyle("com", style);
style = new Style();
style.setColor(Color.decode("0x98fb98")); /* type - lightgreen */
- setType(style);
+ addStyle("typ", style);
style = new Style();
style.setColor(Color.decode("0xcd5c5c")); /* literal - darkred */
- setLiteral(style);
+ addStyle("lit", style);
style = new Style();
style.setColor(Color.decode("0xffffff"));
- setPunctuation(style);
+ addStyle("pun", style);
style = new Style();
style.setColor(Color.decode("0xf0e68c"));/* html/xml tag - lightyellow */
style.setBold(true);
- setTag(style);
+ addStyle("tag", style);
style = new Style();
style.setColor(Color.decode("0x98fb98")); /* decimal - lightgreen */
- setDeclaration(style);
+ addStyle("dec", style);
style = new Style();
style.setColor(Color.decode("0xbdb76b")); /* attribute name - khaki */
style.setBold(true);
- setAttributeName(style);
+ addStyle("atn", style);
style = new Style();
style.setColor(Color.decode("0xffa0a0")); /* attribute value - pink */
style.setBold(true);
- setAttributeValue(style);
+ addStyle("atv", style);
style = new Style();
style.setColor(Color.decode("0x333333"));
- setNoCode(style);
+ addStyle("nocode", style);
- setOpenBracket(plainStyle);
+ addStyle("opn", plainStyle);
- setCloseBracket(plainStyle);
+ addStyle("clo", plainStyle);
- setVariable(plainStyle);
+ addStyle("var", plainStyle);
- setFunction(plainStyle);
+ addStyle("fun", plainStyle);
}
}
diff --git a/src/prettify/theme/ThemeSonsOfObsidian.java b/src/prettify/theme/ThemeSonsOfObsidian.java
index 6faa494..1d87dac 100644
--- a/src/prettify/theme/ThemeSonsOfObsidian.java
+++ b/src/prettify/theme/ThemeSonsOfObsidian.java
@@ -15,6 +15,8 @@
import java.awt.Color;
import java.awt.Font;
+import syntaxhighlight.Style;
+import syntaxhighlight.Theme;
/**
* Son of Obsidian theme.
@@ -47,58 +49,59 @@
Style plainStyle = new Style();
plainStyle.setColor(Color.decode("0xF1F2F3"));
+ addStyle("pln", plainStyle);
setPlain(plainStyle);
Style style;
style = new Style();
style.setColor(Color.decode("0xEC7600"));
- setString(style);
+ addStyle("str", style);
style = new Style();
style.setColor(Color.decode("0x93C763"));
- setKeyword(style);
+ addStyle("kwd", style);
style = new Style();
style.setColor(Color.decode("0x66747B"));
- setComment(style);
+ addStyle("com", style);
style = new Style();
style.setColor(Color.decode("0x678CB1"));
- setType(style);
+ addStyle("typ", style);
style = new Style();
style.setColor(Color.decode("0xFACD22"));
- setLiteral(style);
+ addStyle("lit", style);
style = new Style();
style.setColor(Color.decode("0xF1F2F3"));
- setPunctuation(style);
+ addStyle("pun", style);
style = new Style();
style.setColor(Color.decode("0x8AC763"));
- setTag(style);
+ addStyle("tag", style);
style = new Style();
style.setColor(Color.decode("0x800080"));
- setDeclaration(style);
+ addStyle("dec", style);
style = new Style();
style.setColor(Color.decode("0xE0E2E4"));
- setAttributeName(style);
+ addStyle("atn", style);
style = new Style();
style.setColor(Color.decode("0xEC7600"));
- setAttributeValue(style);
+ addStyle("atv", style);
- setNoCode(plainStyle);
+ addStyle("nocode", plainStyle);
- setOpenBracket(plainStyle);
+ addStyle("opn", plainStyle);
- setCloseBracket(plainStyle);
+ addStyle("clo", plainStyle);
- setVariable(plainStyle);
+ addStyle("var", plainStyle);
- setFunction(plainStyle);
+ addStyle("fun", plainStyle);
}
}
diff --git a/src/prettify/theme/ThemeSunburst.java b/src/prettify/theme/ThemeSunburst.java
index 435bf7c..6160ac0 100644
--- a/src/prettify/theme/ThemeSunburst.java
+++ b/src/prettify/theme/ThemeSunburst.java
@@ -15,6 +15,8 @@
import java.awt.Color;
import java.awt.Font;
+import syntaxhighlight.Style;
+import syntaxhighlight.Theme;
/**
* Sunbrust theme.
@@ -43,59 +45,60 @@
Style plainStyle = new Style();
plainStyle.setColor(Color.decode("0xffffff"));
+ addStyle("pln", plainStyle);
setPlain(plainStyle);
Style style;
style = new Style();
style.setColor(Color.decode("0x65B042")); /* string - green */
- setString(style);
+ addStyle("str", style);
style = new Style();
style.setColor(Color.decode("0xE28964")); /* keyword - dark pink */
- setKeyword(style);
+ addStyle("kwd", style);
style = new Style();
style.setColor(Color.decode("0xAEAEAE")); /* comment - gray */
style.setItalic(true);
- setComment(style);
+ addStyle("com", style);
style = new Style();
style.setColor(Color.decode("0x89bdff")); /* type - light blue */
- setType(style);
+ addStyle("typ", style);
style = new Style();
style.setColor(Color.decode("0x3387CC")); /* literal - blue */
- setLiteral(style);
+ addStyle("lit", style);
style = new Style();
style.setColor(Color.decode("0xffffff")); /* punctuation - white */
- setPunctuation(style);
+ addStyle("pun", style);
style = new Style();
style.setColor(Color.decode("0x89bdff")); /* html/xml tag - light blue */
- setTag(style);
+ addStyle("tag", style);
style = new Style();
style.setColor(Color.decode("0x3387CC")); /* decimal - blue */
- setDeclaration(style);
+ addStyle("dec", style);
style = new Style();
style.setColor(Color.decode("0xbdb76b")); /* html/xml attribute name - khaki */
- setAttributeName(style);
+ addStyle("atn", style);
style = new Style();
style.setColor(Color.decode("0x65B042")); /* html/xml attribute value - green */
- setAttributeValue(style);
+ addStyle("atv", style);
- setNoCode(plainStyle);
+ addStyle("nocode", plainStyle);
- setOpenBracket(plainStyle);
+ addStyle("opn", plainStyle);
- setCloseBracket(plainStyle);
+ addStyle("clo", plainStyle);
- setVariable(plainStyle);
+ addStyle("var", plainStyle);
- setFunction(plainStyle);
+ addStyle("fun", plainStyle);
}
}
diff --git a/src/prettify/gui/JTextComponentRowHeader.java b/src/syntaxhighlight/JTextComponentRowHeader.java
similarity index 99%
rename from src/prettify/gui/JTextComponentRowHeader.java
rename to src/syntaxhighlight/JTextComponentRowHeader.java
index 711febe..2e76e8e 100644
--- a/src/prettify/gui/JTextComponentRowHeader.java
+++ b/src/syntaxhighlight/JTextComponentRowHeader.java
@@ -11,7 +11,7 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
-package prettify.gui;
+package syntaxhighlight;
import java.awt.Color;
import java.awt.Container;
diff --git a/src/syntaxhighlight/ParseResult.java b/src/syntaxhighlight/ParseResult.java
new file mode 100644
index 0000000..a731c73
--- /dev/null
+++ b/src/syntaxhighlight/ParseResult.java
@@ -0,0 +1,148 @@
+// Copyright (c) 2011 Chan Wai Shing
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+package syntaxhighlight;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Matched result, it will be generated when parsing the content.
+ *
+ * @author Chan Wai Shing <cws1989@gmail.com>
+ */
+public class ParseResult {
+
+ /**
+ * The start position in the document for this matched result.
+ */
+ protected int offset;
+ /**
+ * The length of the matched result.
+ */
+ protected int length;
+ /**
+ * The style key for this matched result, see {@link syntaxhighlighter.theme}.
+ */
+ protected List<String> styleKeys;
+
+ /**
+ * Constructor.
+ *
+ * @param offset the position in the document for this matched result
+ * @param length the length of the matched result.
+ * @param styleKeys the style key for this matched result, cannot be null, see
+ * {@link syntaxhighlighter.theme}
+ */
+ public ParseResult(int offset, int length, List<String> styleKeys) {
+ this.offset = offset;
+ this.length = length;
+ this.styleKeys = new ArrayList<String>(styleKeys);
+ }
+
+ /**
+ * The position in the document for this matched result.
+ * @return the offset in the document
+ */
+ public int getOffset() {
+ return offset;
+ }
+
+ /**
+ * The position in the document for this matched result.
+ * @param offset the offset in the document
+ */
+ public void setOffset(int offset) {
+ this.offset = offset;
+ }
+
+ /**
+ * The length of the matched result.
+ * @return the length
+ */
+ public int getLength() {
+ return length;
+ }
+
+ /**
+ * The length of the matched result.
+ * @param length the length
+ */
+ public void setLength(int length) {
+ this.length = length;
+ }
+
+ public String getStyleKeysString() {
+ StringBuilder sb = new StringBuilder(10);
+ for (int i = 0, iEnd = styleKeys.size(); i < iEnd; i++) {
+ if (i != 0) {
+ sb.append(" ");
+ }
+ sb.append(styleKeys.get(i));
+ }
+ return sb.toString();
+ }
+
+ public void setStyleKeys(List<String> styleKeys) {
+ this.styleKeys = new ArrayList<String>(styleKeys);
+ }
+
+ public boolean addStyleKey(String styleKey) {
+ return styleKeys.add(styleKey);
+ }
+
+ public boolean removeStyleKey(String styleKey) {
+ return styleKeys.remove(styleKey);
+ }
+
+ public void clearStyleKeys() {
+ styleKeys.clear();
+ }
+
+ /**
+ * The style keys for this matched result, see {@link syntaxhighlighter.theme}.
+ * @return the style keys
+ */
+ public List<String> getStyleKeys() {
+ return new ArrayList<String>(styleKeys);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append("[");
+ sb.append(offset);
+ sb.append("; ");
+ sb.append(length);
+ sb.append("; ");
+ for (int i = 0, iEnd = styleKeys.size(); i < iEnd; i++) {
+ if (i != 0) {
+ sb.append(", ");
+ }
+ sb.append(styleKeys.get(i));
+ }
+ sb.append("]");
+
+ return sb.toString();
+ }
+}
\ No newline at end of file
diff --git a/src/syntaxhighlight/Parser.java b/src/syntaxhighlight/Parser.java
new file mode 100644
index 0000000..41eee05
--- /dev/null
+++ b/src/syntaxhighlight/Parser.java
@@ -0,0 +1,19 @@
+package syntaxhighlight;
+
+import java.util.List;
+
+/**
+ * The parser interface for syntax highlight.
+ *
+ * @author Chan Wai Shing <cws1989@gmail.com>
+ */
+public interface Parser {
+
+ /**
+ * Parse the {@code content} and return the parsed result.
+ * @param fileExtension the file extension of the content, null means not provided
+ * @param content the content
+ * @return the parsed result
+ */
+ List<ParseResult> parse(String fileExtension, String content);
+}
diff --git a/src/prettify/theme/Style.java b/src/syntaxhighlight/Style.java
similarity index 67%
rename from src/prettify/theme/Style.java
rename to src/syntaxhighlight/Style.java
index a29f3ab..88f4531 100644
--- a/src/prettify/theme/Style.java
+++ b/src/syntaxhighlight/Style.java
@@ -1,4 +1,4 @@
-// Copyright (C) 2011 Chan Wai Shing
+// Copyright (C) 2012 Chan Wai Shing
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -11,19 +11,22 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
-package prettify.theme;
+package syntaxhighlight;
import java.awt.Color;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
/**
- * The style used by {@link prettify.theme} as those of CSS styles.
+ * The style used by {@link syntaxhiglight.Theme} as those of CSS styles.
*
* @author Chan Wai Shing <cws1989@gmail.com>
*/
-public class Style {
+public class Style implements Cloneable {
+ protected boolean changed;
+ protected SimpleAttributeSet attributeSet;
+ //
protected boolean bold;
protected Color color;
/**
@@ -47,6 +50,9 @@
* </p>
*/
public Style() {
+ changed = true;
+ attributeSet = null;
+
bold = false;
color = Color.black;
background = null;
@@ -55,38 +61,21 @@
}
/**
- * Apply the style to the AttributeSet.
- * Note that the AttributeSet should only be set by this function once or some unexpected style may appear.
- * @param attributeSet the AttributeSet to set the style on
- */
- public void setAttributeSet(SimpleAttributeSet attributeSet) {
- if (attributeSet == null) {
- return;
- }
- StyleConstants.setBold(attributeSet, bold);
- StyleConstants.setForeground(attributeSet, color);
- if (background != null) {
- StyleConstants.setBackground(attributeSet, background);
- } else {
- attributeSet.removeAttribute(StyleConstants.Background);
- }
- StyleConstants.setUnderline(attributeSet, underline);
- StyleConstants.setItalic(attributeSet, italic);
- }
-
- /**
* Get the AttributeSet from this style.
* @return the AttributeSet
*/
public SimpleAttributeSet getAttributeSet() {
- SimpleAttributeSet attributeSet = new SimpleAttributeSet();
- StyleConstants.setBold(attributeSet, bold);
- StyleConstants.setForeground(attributeSet, color);
- if (background != null) {
- StyleConstants.setBackground(attributeSet, background);
+ if (changed) {
+ attributeSet = new SimpleAttributeSet();
+ StyleConstants.setBold(attributeSet, bold);
+ StyleConstants.setForeground(attributeSet, color);
+ if (background != null) {
+ StyleConstants.setBackground(attributeSet, background);
+ }
+ StyleConstants.setUnderline(attributeSet, underline);
+ StyleConstants.setItalic(attributeSet, italic);
+ changed = false;
}
- StyleConstants.setUnderline(attributeSet, underline);
- StyleConstants.setItalic(attributeSet, italic);
return attributeSet;
}
@@ -103,9 +92,7 @@
* @param background input null means do not set the background
*/
public void setBackground(Color background) {
- if (background == null) {
- throw new NullPointerException("argument 'background' cannot be null");
- }
+ changed = true;
this.background = background;
}
@@ -114,6 +101,7 @@
}
public void setBold(boolean bold) {
+ changed = true;
this.bold = bold;
}
@@ -125,6 +113,7 @@
if (color == null) {
throw new NullPointerException("argument 'color' cannot be null");
}
+ changed = true;
this.color = color;
}
@@ -133,6 +122,7 @@
}
public void setItalic(boolean italic) {
+ changed = true;
this.italic = italic;
}
@@ -141,6 +131,7 @@
}
public void setUnderline(boolean underline) {
+ changed = true;
this.underline = underline;
}
@@ -149,12 +140,12 @@
*/
@Override
public int hashCode() {
- int hash = 5;
- hash = 59 * hash + (this.bold ? 1 : 0);
- hash = 59 * hash + (this.color != null ? this.color.hashCode() : 0);
- hash = 59 * hash + (this.background != null ? this.background.hashCode() : 0);
- hash = 59 * hash + (this.underline ? 1 : 0);
- hash = 59 * hash + (this.italic ? 1 : 0);
+ int hash = 7;
+ hash = 97 * hash + (this.bold ? 1 : 0);
+ hash = 97 * hash + (this.color != null ? this.color.hashCode() : 0);
+ hash = 97 * hash + (this.background != null ? this.background.hashCode() : 0);
+ hash = 97 * hash + (this.underline ? 1 : 0);
+ hash = 97 * hash + (this.italic ? 1 : 0);
return hash;
}
@@ -182,11 +173,6 @@
Style object = null;
try {
object = (Style) super.clone();
- object.bold = bold;
- object.color = color;
- object.background = background;
- object.underline = underline;
- object.italic = italic;
} catch (CloneNotSupportedException ex) {
}
return object;
@@ -199,6 +185,7 @@
public String toString() {
StringBuilder sb = new StringBuilder();
+ sb.append("[");
sb.append(getClass().getName());
sb.append(": ");
sb.append("bold: ").append(bold);
@@ -210,7 +197,8 @@
sb.append("underline: ").append(underline);
sb.append(", ");
sb.append("italic: ").append(italic);
+ sb.append("]");
return sb.toString();
}
-}
\ No newline at end of file
+}
diff --git a/src/prettify/SyntaxHighlighter.java b/src/syntaxhighlight/SyntaxHighlighter.java
similarity index 92%
rename from src/prettify/SyntaxHighlighter.java
rename to src/syntaxhighlight/SyntaxHighlighter.java
index c0dd605..df9638a 100644
--- a/src/prettify/SyntaxHighlighter.java
+++ b/src/syntaxhighlight/SyntaxHighlighter.java
@@ -11,13 +11,8 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
-package prettify;
+package syntaxhighlight;
-import prettify.parser.Job;
-import prettify.parser.Prettify;
-import prettify.gui.SyntaxHighlighterPane;
-import prettify.gui.JTextComponentRowHeader;
-import prettify.theme.Theme;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
@@ -48,7 +43,7 @@
/**
* The Prettify object.
*/
- protected Prettify prettify;
+ protected Parser parser;
/**
* The content of the syntax highlighter, null if there is no content so far.
*/
@@ -57,19 +52,21 @@
/**
* Constructor.
*
+ * @param parser
* @param theme the theme for the syntax highlighter
*/
- public SyntaxHighlighter(Theme theme) {
- this(theme, new SyntaxHighlighterPane());
+ public SyntaxHighlighter(Parser parser, Theme theme) {
+ this(parser, theme, new SyntaxHighlighterPane());
}
/**
* Constructor.
*
+ * @param parser
* @param theme the theme for the syntax highlighter
* @param highlighterPane the script text pane of the syntax highlighter
*/
- public SyntaxHighlighter(Theme theme, SyntaxHighlighterPane highlighterPane) {
+ public SyntaxHighlighter(Parser parser, Theme theme, SyntaxHighlighterPane highlighterPane) {
super();
if (theme == null) {
@@ -80,7 +77,7 @@
}
this.theme = theme;
- prettify = new Prettify();
+ this.parser = parser;
setBorder(null);
@@ -103,9 +100,7 @@
if (content != null) {
// stop the change listener on the row header to speed up rendering
highlighterRowHeader.setListenToDocumentUpdate(false);
- Job job = new Job(0, content);
- prettify.langHandlerForExtension(null, content).decorate(job);
- highlighter.setStyle(job.getDecorations());
+ highlighter.setStyle(parser.parse(null, content));
// resume the change listener on the row header
highlighterRowHeader.setListenToDocumentUpdate(true);
// notify the row header to update its information related to the SyntaxHighlighterPane
diff --git a/src/prettify/gui/SyntaxHighlighterPane.java b/src/syntaxhighlight/SyntaxHighlighterPane.java
similarity index 84%
rename from src/prettify/gui/SyntaxHighlighterPane.java
rename to src/syntaxhighlight/SyntaxHighlighterPane.java
index d3c0dd0..482b87f 100644
--- a/src/prettify/gui/SyntaxHighlighterPane.java
+++ b/src/syntaxhighlight/SyntaxHighlighterPane.java
@@ -1,19 +1,25 @@
-// Copyright (C) 2011 Chan Wai Shing
+// Copyright (c) 2011 Chan Wai Shing
//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
//
-// http://www.apache.org/licenses/LICENSE-2.0
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-package prettify.gui;
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+package syntaxhighlight;
-import prettify.theme.Theme;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
@@ -24,7 +30,9 @@
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JTextPane;
@@ -83,7 +91,7 @@
/**
* The style list.
*/
- protected List<Object> styleList;
+ protected Map<String, List<ParseResult>> styleList;
/**
* Record the mouse cursor is currently pointing at which line of the
* document. -1 means not any line.
@@ -311,19 +319,32 @@
styleList = null;
}
- /**
- * Apply the list of style to the script text pane.
- *
- * @param styleList the style list
- */
- public void setStyle(List<Object> styleList) {
+ public void setStyle(List<ParseResult> styleList) {
if (styleList == null) {
- this.styleList = new ArrayList<Object>();
- return;
+ throw new NullPointerException("argumenst 'styleList' cannot be null");
}
- this.styleList = new ArrayList<Object>(styleList);
- if (theme == null) {
+ this.styleList = new HashMap<String, List<ParseResult>>();
+
+ for (ParseResult parseResult : styleList) {
+ String styleKeysString = parseResult.getStyleKeysString();
+ List<ParseResult> _styleList = this.styleList.get(styleKeysString);
+ if (_styleList == null) {
+ _styleList = new ArrayList<ParseResult>();
+ this.styleList.put(styleKeysString, _styleList);
+ }
+ _styleList.add(parseResult);
+ }
+
+ applyStyle();
+ }
+
+ /**
+ * Apply the list of style to the script text pane. See
+ * {@link syntaxhighlighter.parser.Parser#parse(syntaxhighlighter.brush.Brush, boolean, char[], int, int)}.
+ */
+ protected void applyStyle() {
+ if (theme == null || styleList == null) {
return;
}
@@ -331,13 +352,14 @@
// clear all the existing style
document.setCharacterAttributes(0, document.getLength(), theme.getPlain().getAttributeSet(), true);
- Integer startPos = 0, endPos = 0;
// apply style according to the style list
- for (int i = 0, iEnd = styleList.size(); i < iEnd; i += 2) {
- SimpleAttributeSet attributeSet = theme.getStyle((String) styleList.get(i + 1)).getAttributeSet();
- endPos = i + 2 < iEnd ? (Integer) styleList.get(i + 2) : document.getLength();
- startPos = (Integer) styleList.get(i);
- document.setCharacterAttributes(startPos, endPos - startPos, attributeSet, true);
+ for (String key : styleList.keySet()) {
+ List<ParseResult> posList = styleList.get(key);
+
+ SimpleAttributeSet attributeSet = theme.getStyle(key).getAttributeSet();
+ for (ParseResult pos : posList) {
+ document.setCharacterAttributes(pos.getOffset(), pos.getLength(), attributeSet, true);
+ }
}
repaint();
@@ -368,7 +390,7 @@
setHighlightedBackground(theme.getHighlightedBackground());
if (styleList != null) {
- setStyle(styleList);
+ applyStyle();
}
}
@@ -456,11 +478,12 @@
* @param highlightedLineList the list that contain the highlighted lines
*/
public void setHighlightedLineList(List<Integer> highlightedLineList) {
+ if (highlightedLineList == null) {
+ throw new NullPointerException("argument 'highlightedLineList' cannot be null");
+ }
synchronized (this.highlightedLineList) {
this.highlightedLineList.clear();
- if (highlightedLineList != null) {
- this.highlightedLineList.addAll(highlightedLineList);
- }
+ this.highlightedLineList.addAll(highlightedLineList);
}
repaint();
}
diff --git a/src/syntaxhighlight/Theme.java b/src/syntaxhighlight/Theme.java
new file mode 100644
index 0000000..0449e15
--- /dev/null
+++ b/src/syntaxhighlight/Theme.java
@@ -0,0 +1,401 @@
+// Copyright (c) 2011 Chan Wai Shing
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+package syntaxhighlight;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Logger;
+import javax.swing.text.SimpleAttributeSet;
+
+/**
+ * Theme for the syntax highlighter.
+ * To make a new theme, either extending this class of initiate this class
+ * and set the parameter by the setter. For the default value, please refer to
+ * the constructor.
+ *
+ * @author Chan Wai Shing <cws1989@gmail.com>
+ */
+public class Theme {
+
+ private static final Logger LOG = Logger.getLogger(Theme.class.getName());
+ /**
+ * The font of the script text.
+ */
+ protected Font font;
+ /**
+ * The background color of the script text area.
+ */
+ protected Color background;
+ /**
+ * The background color of the highlighted line of script text.
+ */
+ protected Color highlightedBackground;
+ /**
+ * Gutter (line number column on the left)
+ */
+ /**
+ * The color of the gutter text.
+ */
+ protected Color gutterText;
+ /**
+ * The color of the border that joint the gutter and the script text panel.
+ */
+ protected Color gutterBorderColor;
+ /**
+ * The width of the border that joint the gutter and the script text panel.
+ */
+ protected int gutterBorderWidth;
+ /**
+ * The font of the gutter text.
+ */
+ protected Font gutterTextFont;
+ /**
+ * The minimum padding from 'the leftmost of the line number text' to
+ * 'the left margin'.
+ */
+ protected int gutterTextPaddingLeft;
+ /**
+ * The minimum padding from 'the rightmost of the line number text' to
+ * 'the right margin' (not to the gutter border).
+ */
+ protected int gutterTextPaddingRight;
+ protected Style plain;
+ protected Map<String, Style> styles;
+
+ /**
+ * Constructor.<br />
+ * <p>
+ * <b>Default value:</b><br />
+ * <ul>
+ * <li>font: Consolas 12pt</li>
+ * <li>background: white</li>
+ * <li>gutter text: black</li>
+ * <li>gutter border: R: 184, G: 184, B: 184</li>
+ * <li>gutter border width: 3px</li>
+ * <li>gutter text font: Consolas 12pt</li>
+ * <li>gutter text padding-left: 7px</li>
+ * <li>gutter text padding-right: 7px</li>
+ * </ul>
+ * </p>
+ */
+ public Theme() {
+ font = new Font("Consolas", Font.PLAIN, 12);
+ background = Color.white;
+
+ highlightedBackground = Color.gray;
+
+ gutterText = Color.black;
+ gutterBorderColor = new Color(184, 184, 184);
+ gutterBorderWidth = 3;
+ gutterTextFont = new Font("Consolas", Font.PLAIN, 12);
+ gutterTextPaddingLeft = 7;
+ gutterTextPaddingRight = 7;
+
+ plain = new Style();
+
+ styles = new HashMap<String, Style>();
+ }
+
+ /**
+ * Apply the theme to the row header panel.
+ * @param rowHeader the row header to apply theme on
+ */
+ public void setTheme(JTextComponentRowHeader rowHeader) {
+ rowHeader.setBackground(background);
+ rowHeader.setHighlightedColor(background);
+
+ rowHeader.setForeground(gutterText);
+ rowHeader.setBorderColor(gutterBorderColor);
+ rowHeader.setBorderWidth(gutterBorderWidth);
+ rowHeader.setFont(gutterTextFont);
+ rowHeader.setPaddingLeft(gutterTextPaddingLeft);
+ rowHeader.setPaddingRight(gutterTextPaddingRight);
+ }
+
+ public void setPlain(Style plain) {
+ if (plain == null) {
+ throw new NullPointerException("argument 'plain' cannot be null");
+ }
+ this.plain = plain;
+ }
+
+ public Style getPlain() {
+ return plain;
+ }
+
+ public SimpleAttributeSet getStyleAttributeSet(String styleKeys) {
+ if (styleKeys.indexOf(' ') != -1) {
+ SimpleAttributeSet returnAttributeSet = new SimpleAttributeSet();
+ String[] keys = styleKeys.split(" ");
+ for (String _key : keys) {
+ returnAttributeSet.addAttributes(getStyle(_key).getAttributeSet());
+ }
+ return returnAttributeSet;
+ } else {
+ return getStyle(styleKeys).getAttributeSet();
+ }
+ }
+
+ public Style addStyle(String styleKey, Style style) {
+ return styles.put(styleKey, style);
+ }
+
+ public Style removeStyle(String styleKey) {
+ return styles.remove(styleKey);
+ }
+
+ /**
+ * Get the {@link syntaxhighlighter.theme.Style} by keyword.
+ *
+ * @param key the keyword
+ *
+ * @return the {@link syntaxhighlighter.theme.Style} related to the
+ * {@code key}; if the style related to the <code>key</code> not exist,
+ * the style of 'plain' will return.
+ */
+ public Style getStyle(String key) {
+ Style returnStyle = styles.get(key);
+ return returnStyle != null ? returnStyle : plain;
+ }
+
+ public Map<String, Style> getStyles() {
+ return new HashMap<String, Style>(styles);
+ }
+
+ public void clearStyles() {
+ styles.clear();
+ }
+
+ /**
+ * The font of the script text.
+ * @return the font
+ */
+ public Font getFont() {
+ return font;
+ }
+
+ /**
+ * The font of the script text.
+ * @param font the font
+ */
+ public void setFont(Font font) {
+ if (font == null) {
+ throw new NullPointerException("argument 'font' cannot be null");
+ }
+ this.font = font;
+ }
+
+ /**
+ * The background color of the script text area.
+ * @return the color
+ */
+ public Color getBackground() {
+ return background;
+ }
+
+ /**
+ * The background color of the script text area.
+ * @param background the color
+ */
+ public void setBackground(Color background) {
+ if (background == null) {
+ throw new NullPointerException("argument 'background' cannot be null");
+ }
+ this.background = background;
+ }
+
+ /**
+ * The background color of the highlighted line of script text.
+ * @return the color
+ */
+ public Color getHighlightedBackground() {
+ return highlightedBackground;
+ }
+
+ /**
+ * The background color of the highlighted line of script text.
+ * @param highlightedBackground the color
+ */
+ public void setHighlightedBackground(Color highlightedBackground) {
+ if (highlightedBackground == null) {
+ throw new NullPointerException("argument 'highlightedBackground' cannot be null");
+ }
+ this.highlightedBackground = highlightedBackground;
+ }
+
+ /**
+ * The color of the gutter text.
+ * @return the color
+ */
+ public Color getGutterText() {
+ return gutterText;
+ }
+
+ /**
+ * The color of the gutter text.
+ * @param gutterText the color
+ */
+ public void setGutterText(Color gutterText) {
+ if (gutterText == null) {
+ throw new NullPointerException("argument 'gutterText' cannot be null");
+ }
+ this.gutterText = gutterText;
+ }
+
+ /**
+ * The color of the border that joint the gutter and the script text panel.
+ * @return the color
+ */
+ public Color getGutterBorderColor() {
+ return gutterBorderColor;
+ }
+
+ /**
+ * The color of the border that joint the gutter and the script text panel.
+ * @param gutterBorderColor the color
+ */
+ public void setGutterBorderColor(Color gutterBorderColor) {
+ if (gutterBorderColor == null) {
+ throw new NullPointerException("argument 'gutterBorderColor' cannot be null");
+ }
+ this.gutterBorderColor = gutterBorderColor;
+ }
+
+ /**
+ * The width of the border that joint the gutter and the script text panel.
+ * @return the width in pixel
+ */
+ public int getGutterBorderWidth() {
+ return gutterBorderWidth;
+ }
+
+ /**
+ * The width of the border that joint the gutter and the script text panel.
+ * @param gutterBorderWidth in pixel
+ */
+ public void setGutterBorderWidth(int gutterBorderWidth) {
+ this.gutterBorderWidth = gutterBorderWidth;
+ }
+
+ /**
+ * The font of the gutter text.
+ * @return the font
+ */
+ public Font getGutterTextFont() {
+ return gutterTextFont;
+ }
+
+ /**
+ * The font of the gutter text.
+ * @param gutterTextFont the font
+ */
+ public void setGutterTextFont(Font gutterTextFont) {
+ if (gutterTextFont == null) {
+ throw new NullPointerException("argument 'gutterTextFont' cannot be null");
+ }
+ this.gutterTextFont = gutterTextFont;
+ }
+
+ /**
+ * The minimum padding from 'the leftmost of the line number text' to
+ * 'the left margin'.
+ * @return the padding in pixel
+ */
+ public int getGutterTextPaddingLeft() {
+ return gutterTextPaddingLeft;
+ }
+
+ /**
+ * The minimum padding from 'the leftmost of the line number text' to
+ * 'the left margin'.
+ * @param gutterTextPaddingLeft in pixel
+ */
+ public void setGutterTextPaddingLeft(int gutterTextPaddingLeft) {
+ this.gutterTextPaddingLeft = gutterTextPaddingLeft;
+ }
+
+ /**
+ * The minimum padding from 'the rightmost of the line number text' to
+ * 'the right margin' (not to the gutter border).
+ * @return the padding in pixel
+ */
+ public int getGutterTextPaddingRight() {
+ return gutterTextPaddingRight;
+ }
+
+ /**
+ * The minimum padding from 'the rightmost of the line number text' to
+ * 'the right margin' (not to the gutter border).
+ * @param gutterTextPaddingRight in pixel
+ */
+ public void setGutterTextPaddingRight(int gutterTextPaddingRight) {
+ this.gutterTextPaddingRight = gutterTextPaddingRight;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Theme clone() {
+ Theme object = null;
+ try {
+ object = (Theme) super.clone();
+ object.styles = new HashMap<String, Style>();
+ for (String key : styles.keySet()) {
+ object.styles.put(key, styles.get(key).clone());
+ }
+ } catch (CloneNotSupportedException ex) {
+ }
+ return object;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append(getClass().getName());
+ sb.append(": ");
+ sb.append("font: ").append(getFont());
+ sb.append(", ");
+ sb.append("background: ").append(getBackground());
+ sb.append(", ");
+ sb.append("highlightedBackground: ").append(getHighlightedBackground());
+ sb.append(", ");
+ sb.append("gutterText: ").append(getGutterText());
+ sb.append(", ");
+ sb.append("gutterBorderColor: ").append(getGutterBorderColor());
+ sb.append(", ");
+ sb.append("gutterBorderWidth: ").append(getGutterBorderWidth());
+ sb.append(", ");
+ sb.append("gutterTextFont: ").append(getGutterTextFont());
+ sb.append(", ");
+ sb.append("gutterTextPaddingLeft: ").append(getGutterTextPaddingLeft());
+ sb.append(", ");
+ sb.append("gutterTextPaddingRight: ").append(getGutterTextPaddingRight());
+
+ return sb.toString();
+ }
+}