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(); + } +}