porting in progress
diff --git a/src/prettify/CombinePrefixPattern.java b/src/prettify/CombinePrefixPattern.java
index e75500b..bf05efe 100644
--- a/src/prettify/CombinePrefixPattern.java
+++ b/src/prettify/CombinePrefixPattern.java
@@ -75,7 +75,7 @@
escapeCharToCodeUnit.put('r', 0xf);
}
- public static int decodeEscape(String charsetPart) {
+ protected static int decodeEscape(String charsetPart) {
Integer cc0 = charsetPart.codePointAt(0);
if (cc0 != 92 /* \\ */) {
return cc0;
@@ -93,7 +93,7 @@
}
}
- public static String encodeEscape(int charCode) {
+ protected static String encodeEscape(int charCode) {
if (charCode < 0x20) {
return (charCode < 0x10 ? "\\x0" : "\\x") + Integer.toString(charCode, 16);
}
@@ -103,7 +103,7 @@
? "\\" + ch : ch;
}
- public static String caseFoldCharset(String charSet) {
+ protected static String caseFoldCharset(String charSet) {
String[] charsetParts = Util.match(Pattern.compile("\\\\u[0-9A-Fa-f]{4}"
+ "|\\\\x[0-9A-Fa-f]{2}"
+ "|\\\\[0-3][0-7]{0,2}"
@@ -185,7 +185,7 @@
return Util.join(out);
}
- public String allowAnywhereFoldCaseAndRenumberGroups(Pattern regex) {
+ protected String allowAnywhereFoldCaseAndRenumberGroups(Pattern regex) {
// Split into character sets, escape sequences, punctuation strings
// like ('(', '(?:', ')', '^'), and runs of characters that do not
// include any of the above.
diff --git a/src/prettify/JTextComponentRowHeader.java b/src/prettify/JTextComponentRowHeader.java
index 1f98259..26a7671 100644
--- a/src/prettify/JTextComponentRowHeader.java
+++ b/src/prettify/JTextComponentRowHeader.java
@@ -48,7 +48,7 @@
protected final static boolean debug;
static {
- String debugMode = System.getProperty("SyntaxHighlighterDebugMode");
+ String debugMode = System.getProperty("PrettifyDebugMode");
debug = debugMode == null || !debugMode.equals("true") ? false : true;
}
private static final long serialVersionUID = 1L;
diff --git a/src/prettify/Job.java b/src/prettify/Job.java
index cc3d37f..05ff68f 100644
--- a/src/prettify/Job.java
+++ b/src/prettify/Job.java
@@ -26,6 +26,11 @@
decorations = new ArrayList<Object>();
}
+ public Job(int basePos, String sourceCode) {
+ this.basePos = basePos;
+ this.sourceCode = sourceCode;
+ }
+
public int getBasePos() {
return basePos;
}
diff --git a/src/prettify/Lang.java b/src/prettify/Lang.java
new file mode 100644
index 0000000..d4565dc
--- /dev/null
+++ b/src/prettify/Lang.java
@@ -0,0 +1,69 @@
+package prettify;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Lang {
+
+ protected List<List<Object>> shortcutStylePatterns;
+ protected List<List<Object>> fallthroughStylePatterns;
+ protected List<Lang> extendedLangs;
+
+ public Lang() {
+ shortcutStylePatterns = new ArrayList<List<Object>>();
+ fallthroughStylePatterns = new ArrayList<List<Object>>();
+ extendedLangs = new ArrayList<Lang>();
+ }
+
+ public static List<String> getFileExtensions() {
+ return new ArrayList<String>();
+ }
+
+ public List<List<Object>> getShortcutStylePatterns() {
+ List<List<Object>> returnList = new ArrayList<List<Object>>();
+ for (List<Object> shortcutStylePattern : shortcutStylePatterns) {
+ returnList.add(new ArrayList<Object>(shortcutStylePattern));
+ }
+ return returnList;
+ }
+
+ public void setShortcutStylePatterns(List<List<Object>> shortcutStylePatterns) {
+ if (shortcutStylePatterns == null) {
+ this.shortcutStylePatterns = new ArrayList<List<Object>>();
+ return;
+ }
+ List<List<Object>> cloneList = new ArrayList<List<Object>>();
+ for (List<Object> shortcutStylePattern : shortcutStylePatterns) {
+ cloneList.add(new ArrayList<Object>(shortcutStylePattern));
+ }
+ this.shortcutStylePatterns = cloneList;
+ }
+
+ public List<List<Object>> getFallthroughStylePatterns() {
+ List<List<Object>> returnList = new ArrayList<List<Object>>();
+ for (List<Object> fallthroughStylePattern : fallthroughStylePatterns) {
+ returnList.add(new ArrayList<Object>(fallthroughStylePattern));
+ }
+ return returnList;
+ }
+
+ public void setFallthroughStylePatterns(List<List<Object>> fallthroughStylePatterns) {
+ if (fallthroughStylePatterns == null) {
+ this.fallthroughStylePatterns = new ArrayList<List<Object>>();
+ return;
+ }
+ List<List<Object>> cloneList = new ArrayList<List<Object>>();
+ for (List<Object> fallthroughStylePattern : fallthroughStylePatterns) {
+ cloneList.add(new ArrayList<Object>(fallthroughStylePattern));
+ }
+ this.fallthroughStylePatterns = cloneList;
+ }
+
+ public List<Lang> getExtendedLangs() {
+ return new ArrayList<Lang>(extendedLangs);
+ }
+
+ public void setExtendedLangs(List<Lang> extendedLangs) {
+ this.extendedLangs = new ArrayList<Lang>(extendedLangs);
+ }
+}
diff --git a/src/prettify/Prettify.java b/src/prettify/Prettify.java
index cf7ddfb..58c4eb7 100644
--- a/src/prettify/Prettify.java
+++ b/src/prettify/Prettify.java
@@ -13,15 +13,25 @@
// limitations under the License.
package prettify;
+import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.TreeMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
+import prettify.lang.LangAppollo;
+import prettify.lang.LangClj;
+import prettify.lang.LangCss;
+import prettify.lang.LangGo;
+import prettify.lang.LangProto;
+import prettify.lang.LangScala;
+import prettify.lang.LangSql;
+import prettify.lang.LangVb;
+import prettify.lang.LangWiki;
+import prettify.lang.LangYaml;
/**
* @fileoverview
@@ -62,6 +72,15 @@
*/
public class Prettify {
+ /**
+ * 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;
+ }
// Keyword lists for various languages.
public static final String FLOW_CONTROL_KEYWORDS = "break,continue,do,else,for,if,return,while";
public static final String C_KEYWORDS = FLOW_CONTROL_KEYWORDS + "," + "auto,case,char,const,default,"
@@ -192,8 +211,10 @@
decorateSourceMap.put("regexLiterals", true);
registerLangHandler(sourceDecorator(decorateSourceMap), Arrays.asList(new String[]{"default-code"}));
- List<List<Object>> shortcutStylePatterns = new ArrayList<List<Object>>();
- List<List<Object>> fallthroughStylePatterns = new ArrayList<List<Object>>();
+ List<List<Object>> shortcutStylePatterns, fallthroughStylePatterns;
+
+ shortcutStylePatterns = new ArrayList<List<Object>>();
+ fallthroughStylePatterns = new ArrayList<List<Object>>();
fallthroughStylePatterns.add(Arrays.asList(new Object[]{PR_PLAIN, Pattern.compile("^[^<?]+")}));
fallthroughStylePatterns.add(Arrays.asList(new Object[]{PR_DECLARATION, Pattern.compile("^<!\\w[^>]*(?:>|$)")}));
fallthroughStylePatterns.add(Arrays.asList(new Object[]{PR_COMMENT, Pattern.compile("^<\\!--[\\s\\S]*?(?:-\\->|$)")}));
@@ -300,6 +321,17 @@
fallthroughStylePatterns = new ArrayList<List<Object>>();
fallthroughStylePatterns.add(Arrays.asList(new Object[]{PR_STRING, Pattern.compile("^[\\s\\S]+")}));
registerLangHandler(new CreateSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns), Arrays.asList(new String[]{"regex"}));
+
+ register(LangAppollo.class);
+ register(LangClj.class);
+ register(LangCss.class);
+ register(LangGo.class);
+ register(LangProto.class);
+ register(LangScala.class);
+ register(LangSql.class);
+ register(LangVb.class);
+ register(LangWiki.class);
+ register(LangYaml.class);
} catch (Exception ex) {
Logger.getLogger(Prettify.class.getName()).log(Level.SEVERE, null, ex);
}
@@ -311,7 +343,7 @@
* @param basePos the index of sourceCode within the chunk of source
* whose decorations are already present on out.
*/
- public static void appendDecorations(int basePos, String sourceCode, CreateSimpleLexer langHandler, List<Object> out) {
+ protected static void appendDecorations(int basePos, String sourceCode, CreateSimpleLexer langHandler, List<Object> out) {
if (sourceCode == null) {
throw new NullPointerException("argument 'sourceCode' cannot be null");
}
@@ -372,7 +404,7 @@
* @param fallthroughStylePatterns patterns that will be tried in
* order if the shortcut ones fail. May have shortcuts.
*/
- public CreateSimpleLexer(List<List<Object>> shortcutStylePatterns, List<List<Object>> fallthroughStylePatterns) throws Exception {
+ protected CreateSimpleLexer(List<List<Object>> shortcutStylePatterns, List<List<Object>> fallthroughStylePatterns) throws Exception {
this.fallthroughStylePatterns = fallthroughStylePatterns;
List<List<Object>> allPatterns = new ArrayList<List<Object>>(shortcutStylePatterns);
@@ -497,25 +529,7 @@
}
}
- List<Object> newDecorations = new ArrayList<Object>();
-
- // use TreeMap to remove entrys with same pos
- Map<Integer, String> posToStyleMap = new TreeMap<Integer, String>();
- for (int i = 0, iEnd = decorations.size(); i < iEnd;) {
- posToStyleMap.put((Integer) decorations.get(i++), (String) decorations.get(i++));
- }
- // remove adjacent style
- String previousStyle = null;
- for (Integer _pos : posToStyleMap.keySet()) {
- if (previousStyle != null && previousStyle.equals(posToStyleMap.get(_pos))) {
- continue;
- }
- newDecorations.add(_pos);
- newDecorations.add(posToStyleMap.get(_pos));
- previousStyle = posToStyleMap.get(_pos);
- }
-
- job.setDecorations(newDecorations);
+ job.setDecorations(Util.removeDuplicates(decorations));
}
}
@@ -534,7 +548,7 @@
* @return a function that examines the source code
* in the input job and builds the decoration list.
*/
- public CreateSimpleLexer sourceDecorator(Map<String, Object> options) throws Exception {
+ protected CreateSimpleLexer sourceDecorator(Map<String, Object> options) throws Exception {
List<List<Object>> shortcutStylePatterns = new ArrayList<List<Object>>();
List<List<Object>> fallthroughStylePatterns = new ArrayList<List<Object>>();
if (options.get("tripleQuotedStrings") != null) {
@@ -634,7 +648,7 @@
shortcutStylePatterns.add(Arrays.asList(new Object[]{PR_PLAIN,
Pattern.compile("^\\s+"),
null,
- " \r\n\t\\xA0"
+ " \r\n\t" + Character.toString((char) 0xA0)
}));
// TODO(mikesamuel): recognize non-latin letters and numerals in idents
@@ -671,7 +685,7 @@
return new CreateSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns);
}
/** Maps language-specific file extensions to handlers. */
- protected Map<String, CreateSimpleLexer> langHandlerRegistry = new HashMap<String, CreateSimpleLexer>();
+ protected Map<String, Object> langHandlerRegistry = new HashMap<String, Object>();
/** Register a language handler for the given file extensions.
* @param handler a function from source code to a list
@@ -689,7 +703,7 @@
* } }
* @param fileExtensions
*/
- public void registerLangHandler(CreateSimpleLexer handler, List<String> fileExtensions) throws Exception {
+ protected void registerLangHandler(CreateSimpleLexer handler, List<String> fileExtensions) throws Exception {
for (int i = fileExtensions.size(); --i >= 0;) {
String ext = fileExtensions.get(i);
if (langHandlerRegistry.get(ext) == null) {
@@ -700,6 +714,34 @@
}
}
+ /**
+ * Register language handler. The clazz will not be instantiated
+ * @param clazz the class of the language
+ * @throws Exception cannot instantiate the object using the class,
+ * or language handler with specified extension exist already
+ */
+ public void register(Class<? extends Lang> clazz) throws Exception {
+ if (clazz == null) {
+ throw new NullPointerException("argument 'clazz' cannot be null");
+ }
+ Method getExtensionsMethod = clazz.getMethod("getFileExtensions", (Class<?>[]) null);
+ List<String> fileExtensions = (List<String>) getExtensionsMethod.invoke(null, null);
+ for (int i = fileExtensions.size(); --i >= 0;) {
+ String ext = fileExtensions.get(i);
+ if (langHandlerRegistry.get(ext) == null) {
+ langHandlerRegistry.put(ext, clazz);
+ } else {
+ throw new Exception("cannot override language handler " + ext);
+ }
+ }
+ }
+
+ /**
+ * Get the parser for the extension specified.
+ * @param extension the file extension, if null, default parser will be returned
+ * @param source the source code
+ * @return the parser
+ */
public CreateSimpleLexer langHandlerForExtension(String extension, String source) {
if (!(extension != null && langHandlerRegistry.get(extension) != null)) {
// Treat it as markup if the first non whitespace character is a < and
@@ -708,6 +750,34 @@
? "default-markup"
: "default-code";
}
- return langHandlerRegistry.get(extension);
+
+ Object handler = langHandlerRegistry.get(extension);
+ if (handler instanceof CreateSimpleLexer) {
+ return (CreateSimpleLexer) handler;
+ } else {
+ Lang _lang;
+ CreateSimpleLexer _simpleLexer;
+ try {
+ _lang = ((Class<Lang>) handler).newInstance();
+ _simpleLexer = new CreateSimpleLexer(_lang.getShortcutStylePatterns(), _lang.getFallthroughStylePatterns());
+
+ List<Lang> extendedLangs = _lang.getExtendedLangs();
+ for (Lang _extendedLang : extendedLangs) {
+ register(_extendedLang.getClass());
+ }
+ } catch (Exception ex) {
+ if (debug) {
+ Logger.getLogger(Prettify.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ return null;
+ }
+
+ List<String> fileExtensions = _lang.getFileExtensions();
+ for (String _extension : fileExtensions) {
+ langHandlerRegistry.put(_extension, _simpleLexer);
+ }
+
+ return _simpleLexer;
+ }
}
}
diff --git a/src/prettify/SyntaxHighlighter.java b/src/prettify/SyntaxHighlighter.java
new file mode 100644
index 0000000..a53cf26
--- /dev/null
+++ b/src/prettify/SyntaxHighlighter.java
@@ -0,0 +1,260 @@
+/**
+ * This is part of the Java Prettify.
+ *
+ * It is distributed under MIT license. See the file 'readme.txt' for
+ * information on usage and redistribution of this file, and for a
+ * DISCLAIMER OF ALL WARRANTIES.
+ *
+ * @author Chan Wai Shing <cws1989@gmail.com>
+ */
+package prettify;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.List;
+import javax.swing.BorderFactory;
+import javax.swing.JScrollPane;
+
+/**
+ * The syntax highlighter.
+ * @author Chan Wai Shing <cws1989@gmail.com>
+ */
+public class SyntaxHighlighter extends JScrollPane {
+
+ static {
+ // set debug mode
+ System.setProperty("PrettifyDebugMode", "false");
+ }
+ private static final long serialVersionUID = 1L;
+ /**
+ * The script text panel.
+ */
+ protected SyntaxHighlighterPane highlighter;
+ /**
+ * The gutter panel (line number).
+ */
+ protected JTextComponentRowHeader highlighterRowHeader;
+ /**
+ * The theme.
+ */
+ protected Theme theme;
+ /**
+ * The content of the syntax highlighter, null if there is no content so far.
+ */
+ protected String content;
+
+ /**
+ * Constructor.
+ * @param theme the theme for the syntax highlighter
+ */
+ public SyntaxHighlighter(Theme theme) {
+ this(theme, new SyntaxHighlighterPane());
+ }
+
+ /**
+ * Constructor.
+ * @param theme the theme for the syntax highlighter
+ * @param highlighterPane the script text pane of the syntax highlighter
+ */
+ public SyntaxHighlighter(Theme theme, SyntaxHighlighterPane highlighterPane) {
+ super();
+
+ if (theme == null) {
+ throw new NullPointerException("argument 'theme' cannot be null");
+ }
+ if (highlighterPane == null) {
+ throw new NullPointerException("argument 'highlighterPane' cannot be null");
+ }
+
+ this.theme = theme;
+
+ setBorder(null);
+
+ highlighter = highlighterPane;
+ highlighter.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0));
+ highlighter.setTheme(theme);
+ setViewportView(highlighter);
+
+ highlighterRowHeader = new JTextComponentRowHeader(this, highlighter);
+ theme.setTheme(highlighterRowHeader);
+ setRowHeaderView(highlighterRowHeader);
+ }
+
+ /**
+ * Re-render the script text pane. Invoke this when any change of setting that affect the rendering was made.
+ * This will re-parse the content and set the style.
+ */
+ protected void render() {
+// if (content != null) {
+// Parser parser = new Parser();
+// // stop the change listener on the row header to speed up rendering
+// highlighterRowHeader.setListenToDocumentUpdate(false);
+// highlighter.setStyle(parser.parse(brush, htmlScript, content.toCharArray(), 0, content.length()));
+// // resume the change listener on the row header
+// highlighterRowHeader.setListenToDocumentUpdate(true);
+// // notify the row header to update its information related to the SyntaxHighlighterPane
+// // need to call this because we have stopped the change listener of the row header in previous code
+// highlighterRowHeader.checkPanelSize();
+// }
+ }
+
+ /**
+ * Get the SyntaxHighlighterPane (the script text panel).
+ * <p><b>Note: Normally should not operate on the SyntaxHighlighterPane directly.</b></p>
+ * @return the SyntaxHighlighterPane
+ */
+ public SyntaxHighlighterPane getHighlighter() {
+ return highlighter;
+ }
+
+ /**
+ * Get the JTextComponentRowHeader, the line number panel.
+ * <p><b>Note: Normally should not operate on the JTextComponentRowHeader directly.</b></p>
+ * @return the JTextComponentRowHeader
+ */
+ public JTextComponentRowHeader getHighlighterRowHeader() {
+ return highlighterRowHeader;
+ }
+
+ /**
+ * Get current theme.
+ * @return the current theme
+ */
+ public Theme getTheme() {
+ return theme;
+ }
+
+ /**
+ * Set the theme.
+ * <p>
+ * Setting the theme will not re-parse the content, but will clear and apply the new theme on the script text pane.
+ * </p>
+ * @param theme the theme
+ */
+ public void setTheme(Theme theme) {
+ if (theme == null) {
+ throw new NullPointerException("argument 'theme' cannot be null");
+ }
+ if (!this.theme.equals(theme)) {
+ this.theme = theme;
+ highlighter.setTheme(theme);
+ theme.setTheme(highlighterRowHeader);
+ }
+ }
+
+ /**
+ * Set the line number of the first line. E.g. if set 10, the line number will start count from 10 instead of 1.
+ * @param firstLine the line number of the first line
+ */
+ public void setFirstLine(int firstLine) {
+ highlighterRowHeader.setLineNumberOffset(firstLine - 1);
+ highlighter.setLineNumberOffset(firstLine - 1);
+ }
+
+ /**
+ * Get the list of highlighted lines.
+ * @return a copy of the list
+ */
+ public List<Integer> getHighlightedLineList() {
+ return highlighter.getHighlightedLineList();
+ }
+
+ /**
+ * Set highlighted lines. Note that this will clear all previous recorded highlighted lines.
+ * @param highlightedLineList the list that contain the highlighted lines
+ */
+ public void setHighlightedLineList(List<Integer> highlightedLineList) {
+ highlighterRowHeader.setHighlightedLineList(highlightedLineList);
+ highlighter.setHighlightedLineList(highlightedLineList);
+ }
+
+ /**
+ * Add highlighted line.
+ * @param lineNumber the line number to highlight
+ */
+ public void addHighlightedLine(int lineNumber) {
+ highlighterRowHeader.addHighlightedLine(lineNumber);
+ highlighter.addHighlightedLine(lineNumber);
+ }
+
+ /**
+ * Get the visibility of the gutter.
+ * @return true if the gutter is visible, false if not
+ */
+ public boolean isGutterVisible() {
+ return getRowHeader() != null && getRowHeader().getView() != null;
+ }
+
+ /**
+ * Set the visibility of the gutter.
+ * @param visible true to make visible, false to hide it
+ */
+ public void setGutterVisible(boolean visible) {
+ if (visible) {
+ setRowHeaderView(highlighterRowHeader);
+ highlighter.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0));
+ } else {
+ setRowHeaderView(null);
+ highlighter.setBorder(null);
+ }
+ }
+
+ /**
+ * Get the status of the mouse-over highlight effect. Default is on.
+ * @return true if turned on, false if turned off
+ */
+ public boolean isHighlightOnMouseOver() {
+ return highlighter.isHighlightOnMouseOver();
+ }
+
+ /**
+ * Set turn on the mouse-over highlight effect or not.
+ * If set true, there will be a highlight effect on the line that the mouse cursor currently is pointing on (on the script text panel only, not on the line number panel).
+ * @param highlightWhenMouseOver true to turn on, false to turn off
+ */
+ public void setHighlightOnMouseOver(boolean highlightWhenMouseOver) {
+ highlighter.setHighlightOnMouseOver(highlightWhenMouseOver);
+ }
+
+ /**
+ * Set the content of the syntax highlighter. Better set it last after setting all other settings.
+ * @param file the file to read
+ */
+ public void setContent(File file) throws IOException {
+ setContent(readFile(file));
+ }
+
+ /**
+ * Set the content of the syntax highlighter. It is better to set other settings first and set this the last.
+ * @param content the content to set
+ */
+ public void setContent(String content) {
+ this.content = content;
+ highlighter.setContent(content);
+ render();
+ }
+
+ /**
+ * Get the string content of a file.
+ * @param file the file to retrieve the content from
+ * @return the string content
+ * @throws IOException error occured, either it is not a valid file or failed to read the file
+ */
+ protected static String readFile(File file) throws IOException {
+ if (file == null) {
+ throw new IOException("argument 'file' cannot be null");
+ }
+ if (!file.isFile()) {
+ throw new IOException("It is not a file.");
+ }
+
+ byte[] buffer = new byte[(int) file.length()];
+
+ FileInputStream fileIn = new FileInputStream(file);
+ fileIn.read(buffer);
+ fileIn.close();
+
+ return new String(buffer);
+ }
+}
diff --git a/src/prettify/SyntaxHighlighterPane.java b/src/prettify/SyntaxHighlighterPane.java
new file mode 100644
index 0000000..82059ec
--- /dev/null
+++ b/src/prettify/SyntaxHighlighterPane.java
@@ -0,0 +1,502 @@
+/**
+ * This is part of the Java Prettify.
+ *
+ * It is distributed under MIT license. See the file 'readme.txt' for
+ * information on usage and redistribution of this file, and for a
+ * DISCLAIMER OF ALL WARRANTIES.
+ *
+ * @author Chan Wai Shing <cws1989@gmail.com>
+ */
+package prettify;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.event.MouseAdapter;
+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;
+import javax.swing.text.AbstractDocument;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.BoxView;
+import javax.swing.text.ComponentView;
+import javax.swing.text.DefaultStyledDocument;
+import javax.swing.text.Element;
+import javax.swing.text.Highlighter;
+import javax.swing.text.IconView;
+import javax.swing.text.JTextComponent;
+import javax.swing.text.LabelView;
+import javax.swing.text.ParagraphView;
+import javax.swing.text.SimpleAttributeSet;
+import javax.swing.text.StyleConstants;
+import javax.swing.text.StyledEditorKit;
+import javax.swing.text.View;
+import javax.swing.text.ViewFactory;
+
+/**
+ * The text pane for displaying the script text.
+ * @author Chan Wai Shing <cws1989@gmail.com>
+ */
+public class SyntaxHighlighterPane extends JTextPane {
+
+ /**
+ * 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;
+ }
+ private static final long serialVersionUID = 1L;
+ /**
+ * The line number offset. E.g. set offset to 9 will make the first line number to appear at line 1 + 9 = 10
+ */
+ private int lineNumberOffset;
+ /**
+ * The background color of the highlighted line. Default is black.
+ */
+ private Color highlightedBackground;
+ /**
+ * Indicator that indicate to turn on the mouse-over highlight effect or not. See {@link #setHighlightOnMouseOver(boolean)}.
+ */
+ private boolean highlightWhenMouseOver;
+ /**
+ * The list of line numbers that indicate which lines are needed to be highlighted.
+ */
+ protected final List<Integer> highlightedLineList;
+ /**
+ * The highlighter painter used to do the highlight line effect.
+ */
+ protected Highlighter.HighlightPainter highlightPainter;
+ /**
+ * The theme.
+ */
+ protected Theme theme;
+ /**
+ * The style list. see {@link #setStyle(java.util.Map)}.
+ */
+ protected Map<String, List<Object>> styleList;
+ /**
+ * Record the mouse cursor is currently pointing at which line of the document. -1 means not any line.
+ * It is used internally.
+ */
+ protected int mouseOnLine;
+
+ public SyntaxHighlighterPane() {
+ super();
+
+ setEditable(false);
+ //<editor-fold defaultstate="collapsed" desc="editor kit">
+ setEditorKit(new StyledEditorKit() {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public ViewFactory getViewFactory() {
+ return new ViewFactory() {
+
+ @Override
+ public View create(Element elem) {
+ String kind = elem.getName();
+ if (kind != null) {
+ if (kind.equals(AbstractDocument.ContentElementName)) {
+ return new LabelView(elem) {
+
+ @Override
+ public int getBreakWeight(int axis, float pos, float len) {
+ return 0;
+ }
+ };
+ } else if (kind.equals(AbstractDocument.ParagraphElementName)) {
+ return new ParagraphView(elem) {
+
+ @Override
+ public int getBreakWeight(int axis, float pos, float len) {
+ return 0;
+ }
+ };
+ } else if (kind.equals(AbstractDocument.SectionElementName)) {
+ return new BoxView(elem, View.Y_AXIS);
+ } else if (kind.equals(StyleConstants.ComponentElementName)) {
+ return new ComponentView(elem) {
+
+ @Override
+ public int getBreakWeight(int axis, float pos, float len) {
+ return 0;
+ }
+ };
+ } else if (kind.equals(StyleConstants.IconElementName)) {
+ return new IconView(elem);
+ }
+ }
+ return new LabelView(elem) {
+
+ @Override
+ public int getBreakWeight(int axis, float pos, float len) {
+ return 0;
+ }
+ };
+ }
+ };
+ }
+ });
+ //</editor-fold>
+
+ lineNumberOffset = 0;
+
+ //<editor-fold defaultstate="collapsed" desc="highlighter painter">
+ highlightedBackground = Color.black;
+ highlightWhenMouseOver = true;
+ highlightedLineList = new ArrayList<Integer>();
+
+ highlightPainter = new Highlighter.HighlightPainter() {
+
+ @Override
+ public void paint(Graphics g, int p0, int p1, Shape bounds, JTextComponent c) {
+ if (c.getParent() == null) {
+ return;
+ }
+
+ // get the Y-axis value of the visible area of the text component
+ int startY = Math.abs(c.getY());
+ int endY = startY + c.getParent().getHeight();
+
+ FontMetrics textPaneFontMetrics = g.getFontMetrics(getFont());
+ int textPaneFontHeight = textPaneFontMetrics.getHeight();
+
+ int largerestLineNumber = c.getDocument().getDefaultRootElement().getElementCount();
+
+ g.setColor(highlightedBackground);
+
+ // draw the highlight background to the highlighted line
+ synchronized (highlightedLineList) {
+ for (Integer lineNumber : highlightedLineList) {
+ if (lineNumber > largerestLineNumber + lineNumberOffset) {
+ // skip those line number that out of range
+ continue;
+ }
+ // get the Y-axis value of this highlighted line
+ int _y = Math.max(0, textPaneFontHeight * (lineNumber - lineNumberOffset - 1));
+ if (_y > endY || _y + textPaneFontHeight < startY) {
+ // this line is out of visible area, skip it
+ continue;
+ }
+ // draw the highlighted background
+ g.fillRect(0, _y, c.getWidth(), textPaneFontHeight);
+ }
+ }
+
+ // draw the mouse-over-highlight effect
+ if (mouseOnLine != -1) {
+ if (mouseOnLine <= largerestLineNumber + lineNumberOffset) {
+ int _y = Math.max(0, textPaneFontHeight * (mouseOnLine - lineNumberOffset - 1));
+ if (_y < endY && _y + textPaneFontHeight > startY) {
+ // the line is within the range of visible area
+ g.fillRect(0, _y, c.getWidth(), textPaneFontHeight);
+ }
+ }
+ }
+ }
+ };
+ try {
+ getHighlighter().addHighlight(0, 0, highlightPainter);
+ } catch (BadLocationException ex) {
+ if (debug) {
+ Logger.getLogger(SyntaxHighlighterPane.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+ //</editor-fold>
+
+ mouseOnLine = -1;
+
+ //<editor-fold defaultstate="collapsed" desc="mouse listener">
+ addMouseListener(new MouseAdapter() {
+
+ @Override
+ public void mouseExited(MouseEvent e) {
+ if (!highlightWhenMouseOver) {
+ return;
+ }
+ mouseOnLine = -1;
+ repaint();
+ }
+ });
+ addMouseMotionListener(new MouseMotionListener() {
+
+ @Override
+ public void mouseDragged(MouseEvent e) {
+ }
+
+ @Override
+ public void mouseMoved(MouseEvent e) {
+ if (!highlightWhenMouseOver) {
+ return;
+ }
+
+ Element defaultRootElement = getDocument().getDefaultRootElement();
+ // get the position of the document the mouse cursor is pointing
+ int documentOffsetStart = viewToModel(e.getPoint());
+
+ // the line number that the mouse cursor is currently pointing
+ int lineNumber = documentOffsetStart == -1 ? -1 : defaultRootElement.getElementIndex(documentOffsetStart) + 1 + lineNumberOffset;
+ if (lineNumber == defaultRootElement.getElementCount()) {
+ // if the line number got is the last line, check if the cursor is actually on the line or already below the line
+ try {
+ Rectangle rectangle = modelToView(documentOffsetStart);
+ if (e.getY() > rectangle.y + rectangle.height) {
+ lineNumber = -1;
+ }
+ } catch (BadLocationException ex) {
+ if (debug) {
+ Logger.getLogger(SyntaxHighlighterPane.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+ }
+
+ // only repaint when the line number changed
+ if (mouseOnLine != lineNumber) {
+ mouseOnLine = lineNumber;
+ repaint();
+ }
+ }
+ });
+ //</editor-fold>
+ }
+
+ @Override
+ public void setHighlighter(Highlighter highlighter) {
+ if (highlightPainter != null) {
+ getHighlighter().removeHighlight(highlightPainter);
+ try {
+ highlighter.addHighlight(0, 0, highlightPainter);
+ } catch (BadLocationException ex) {
+ if (debug) {
+ Logger.getLogger(SyntaxHighlighterPane.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+ }
+ super.setHighlighter(highlighter);
+ }
+
+ /**
+ * Set the content of the syntax highlighter. It is better to set other settings first and set this the last.
+ * @param content the content to set
+ */
+ public void setContent(String content) {
+ String newContent = content == null ? "" : content;
+ DefaultStyledDocument document = (DefaultStyledDocument) getDocument();
+
+ try {
+ document.remove(0, document.getLength());
+ if (theme != null) {
+ document.insertString(0, newContent, theme.getPlain().getAttributeSet());
+ } else {
+ document.insertString(0, newContent, new SimpleAttributeSet());
+ }
+ } catch (BadLocationException ex) {
+ if (debug) {
+ Logger.getLogger(SyntaxHighlighterPane.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+
+ setCaretPosition(0);
+
+ // clear the style list
+ styleList = null;
+ }
+
+ /**
+ * Apply the list of style to the script text pane.
+ * @param styleList the style list
+ */
+ public void setStyle(Map<String, List<Object>> styleList) {
+ if (styleList == null) {
+ this.styleList = new HashMap<String, List<Object>>();
+ return;
+ }
+ // not a deep copy
+ this.styleList = new HashMap<String, List<Object>>(styleList);
+
+ if (theme == null) {
+ return;
+ }
+
+ DefaultStyledDocument document = (DefaultStyledDocument) getDocument();
+ // clear all the existing style
+ document.setCharacterAttributes(0, document.getLength(), theme.getPlain().getAttributeSet(), true);
+
+// // apply style according to the style list
+// for (String key : styleList.keySet()) {
+// List<Object> posList = styleList.get(key);
+//
+// AttributeSet attributeSet = theme.getStyle(key).getAttributeSet();
+// for (Object pos : posList) {
+// document.setCharacterAttributes(pos.getOffset(), pos.getLength(), attributeSet, true);
+// }
+// }
+
+ repaint();
+ }
+
+ /**
+ * Get current theme.
+ * @return the current theme
+ */
+ public Theme getTheme() {
+ return theme;
+ }
+
+ /**
+ * Set the theme.
+ * @param theme the theme
+ */
+ public void setTheme(Theme theme) {
+ if (theme == null) {
+ throw new NullPointerException("argument 'theme' cannot be null");
+ }
+ this.theme = theme;
+
+ setFont(theme.getFont());
+ setBackground(theme.getBackground());
+ setHighlightedBackground(theme.getHighlightedBackground());
+
+ if (styleList != null) {
+ setStyle(styleList);
+ }
+ }
+
+ /**
+ * Get the line number offset. E.g. set offset to 9 will make the first line number to appear at line 1 + 9 = 10
+ * @return the offset
+ */
+ public int getLineNumberOffset() {
+ return lineNumberOffset;
+ }
+
+ /**
+ * Set the line number offset. E.g. set offset to 9 will make the first line number to appear at line 1 + 9 = 10
+ * @param offset the offset
+ */
+ public void setLineNumberOffset(int offset) {
+ lineNumberOffset = Math.max(lineNumberOffset, offset);
+ repaint();
+ }
+
+ /**
+ * Get the color of the highlighted background. Default is black.
+ * @return the color
+ */
+ public Color getHighlightedBackground() {
+ return highlightedBackground;
+ }
+
+ /**
+ * Set the color of the highlighted background. Default is black.
+ * @param highlightedBackground the color
+ */
+ public void setHighlightedBackground(Color highlightedBackground) {
+ if (highlightedBackground == null) {
+ throw new NullPointerException("argument 'highlightedBackground' cannot be null");
+ }
+ this.highlightedBackground = highlightedBackground;
+ repaint();
+ }
+
+ /**
+ * Get the status of the mouse-over highlight effect. Default is on.
+ * @return true if turned on, false if turned off
+ */
+ public boolean isHighlightOnMouseOver() {
+ return highlightWhenMouseOver;
+ }
+
+ /**
+ * Set turn on the mouse-over highlight effect or not. Default is on.
+ * If set true, there will be a highlight effect on the line that the mouse cursor currently is pointing on (on the script text panel only, not on the line number panel).
+ * @param highlightWhenMouseOver true to turn on, false to turn off
+ */
+ public void setHighlightOnMouseOver(boolean highlightWhenMouseOver) {
+ this.highlightWhenMouseOver = highlightWhenMouseOver;
+ if (!highlightWhenMouseOver) {
+ mouseOnLine = -1;
+ }
+ repaint();
+ }
+
+ /**
+ * Get the list of highlighted lines.
+ * @return a copy of the list
+ */
+ public List<Integer> getHighlightedLineList() {
+ List<Integer> returnList;
+ synchronized (highlightedLineList) {
+ returnList = new ArrayList<Integer>(highlightedLineList);
+ }
+ return returnList;
+ }
+
+ /**
+ * Set highlighted lines. Note that this will clear all previous recorded highlighted lines.
+ * @param highlightedLineList the list that contain the highlighted lines
+ */
+ public void setHighlightedLineList(List<Integer> highlightedLineList) {
+ synchronized (this.highlightedLineList) {
+ this.highlightedLineList.clear();
+ if (highlightedLineList != null) {
+ this.highlightedLineList.addAll(highlightedLineList);
+ }
+ }
+ repaint();
+ }
+
+ /**
+ * Add highlighted line.
+ * @param lineNumber the line number to highlight
+ */
+ public void addHighlightedLine(int lineNumber) {
+ highlightedLineList.add(lineNumber);
+ repaint();
+ }
+
+ /**
+ * Set the <code>font</code> according to <code>bold</code> and <code>italic</code>.
+ * @param font the font to set
+ * @param bold true to set bold, false not
+ * @param italic true to set italic, false not
+ * @return the font with bold and italic changed, or null if the input <code>font</code> is null
+ */
+ protected static Font setFont(Font font, boolean bold, boolean italic) {
+ if (font == null) {
+ return null;
+ }
+ if ((font.getStyle() & Font.ITALIC) != 0) {
+ if (!bold) {
+ return font.deriveFont(font.getStyle() ^ Font.BOLD);
+ }
+ } else {
+ if (bold) {
+ return font.deriveFont(font.getStyle() | Font.BOLD);
+ }
+ }
+ if ((font.getStyle() & Font.ITALIC) != 0) {
+ if (!italic) {
+ return font.deriveFont(font.getStyle() ^ Font.ITALIC);
+ }
+ } else {
+ if (italic) {
+ return font.deriveFont(font.getStyle() | Font.ITALIC);
+ }
+ }
+ return font;
+ }
+}
diff --git a/src/prettify/Theme.java b/src/prettify/Theme.java
new file mode 100644
index 0000000..cf60dbc
--- /dev/null
+++ b/src/prettify/Theme.java
@@ -0,0 +1,771 @@
+/**
+ * This is part of the Java Prettify.
+ *
+ * It is distributed under MIT license. See the file 'readme.txt' for
+ * information on usage and redistribution of this file, and for a
+ * DISCLAIMER OF ALL WARRANTIES.
+ *
+ * @author Chan Wai Shing <cws1989@gmail.com>
+ */
+package prettify;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.text.SimpleAttributeSet;
+import javax.swing.text.StyleConstants;
+
+/**
+ * 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.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("pub")) {
+ 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.
+ */
+ public Font getFont() {
+ return font;
+ }
+
+ /**
+ * The font of the script text.
+ */
+ 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.
+ */
+ public Color getBackground() {
+ return background;
+ }
+
+ /**
+ * The background color of the script text area.
+ */
+ 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.
+ */
+ public Color getHighlightedBackground() {
+ return highlightedBackground;
+ }
+
+ /**
+ * The background color of the highlighted line of script text.
+ */
+ 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.
+ */
+ public Color getGutterText() {
+ return gutterText;
+ }
+
+ /**
+ * The color of the gutter text.
+ */
+ 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.
+ */
+ public Color getGutterBorderColor() {
+ return gutterBorderColor;
+ }
+
+ /**
+ * The color of the border that joint the gutter and the script text panel.
+ */
+ 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.
+ */
+ public int getGutterBorderWidth() {
+ return gutterBorderWidth;
+ }
+
+ /**
+ * The width of the border that joint the gutter and the script text panel.
+ */
+ public void setGutterBorderWidth(int gutterBorderWidth) {
+ this.gutterBorderWidth = gutterBorderWidth;
+ }
+
+ /**
+ * The font of the gutter text.
+ */
+ public Font getGutterTextFont() {
+ return gutterTextFont;
+ }
+
+ /**
+ * The font of the gutter text.
+ */
+ 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'.
+ */
+ public int getGutterTextPaddingLeft() {
+ return gutterTextPaddingLeft;
+ }
+
+ /**
+ * The minimum padding from 'the leftmost of the line number text' to 'the left margin'.
+ */
+ 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).
+ */
+ 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).
+ */
+ public void setGutterTextPaddingRight(int gutterTextPaddingRight) {
+ this.gutterTextPaddingRight = gutterTextPaddingRight;
+ }
+
+ public Style getString() {
+ return string;
+ }
+
+ public void setString(Style string) {
+ this.string = string;
+ }
+
+ public Style getKeyword() {
+ return keyword;
+ }
+
+ public void setKeyword(Style keyword) {
+ this.keyword = keyword;
+ }
+
+ public Style getComment() {
+ return comment;
+ }
+
+ public void setComment(Style comment) {
+ this.comment = comment;
+ }
+
+ public Style getType() {
+ return type;
+ }
+
+ public void setType(Style type) {
+ this.type = type;
+ }
+
+ public Style getLiteral() {
+ return literal;
+ }
+
+ public void setLiteral(Style literal) {
+ this.literal = literal;
+ }
+
+ public Style getPunctuation() {
+ return punctuation;
+ }
+
+ public void setPunctuation(Style punctuation) {
+ this.punctuation = punctuation;
+ }
+
+ public Style getPlain() {
+ return plain;
+ }
+
+ public void setPlain(Style plain) {
+ this.plain = plain;
+ }
+
+ public Style getTag() {
+ return tag;
+ }
+
+ public void setTag(Style tag) {
+ this.tag = tag;
+ }
+
+ public Style getDeclaration() {
+ return declaration;
+ }
+
+ public void setDeclaration(Style declaration) {
+ this.declaration = declaration;
+ }
+
+ public Style getSource() {
+ return source;
+ }
+
+ public void setSource(Style source) {
+ this.source = source;
+ }
+
+ public Style getAttributeName() {
+ return attributeName;
+ }
+
+ public void setAttributeName(Style attributeName) {
+ this.attributeName = attributeName;
+ }
+
+ public Style getAttributeValue() {
+ return attributeValue;
+ }
+
+ public void setAttributeValue(Style attributeValue) {
+ this.attributeValue = attributeValue;
+ }
+
+ public Style getNoCode() {
+ return noCode;
+ }
+
+ public void setNoCode(Style noCode) {
+ this.noCode = noCode;
+ }
+
+ public Style getOpenBracket() {
+ return openBracket;
+ }
+
+ public void setOpenBracket(Style openBracket) {
+ this.openBracket = openBracket;
+ }
+
+ public Style getCloseBracket() {
+ return closeBracket;
+ }
+
+ public void setCloseBracket(Style closeBracket) {
+ this.closeBracket = closeBracket;
+ }
+
+ public Style getVariable() {
+ return variable;
+ }
+
+ public void setVariable(Style variable) {
+ this.variable = variable;
+ }
+
+ public Style getFunction() {
+ return function;
+ }
+
+ public void setFunction(Style function) {
+ 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();
+ }
+
+ /**
+ * The style used by {@link prettify.theme} as those of CSS styles.
+ */
+ public static class Style {
+
+ protected boolean bold;
+ protected Color color;
+ /**
+ * The background color, null means no background color is set.
+ */
+ protected Color background;
+ protected boolean underline;
+ protected boolean italic;
+
+ /**
+ * Constructor.
+ * <p>
+ * <b>Default values:</b><br />
+ * <ul>
+ * <li>bold: false;</li>
+ * <li>color: black;</li>
+ * <li>background: null;</li>
+ * <li>underline: false;</li>
+ * <li>italic: false;</li>
+ * </ul>
+ * </p>
+ */
+ public Style() {
+ bold = false;
+ color = Color.black;
+ background = null;
+ underline = false;
+ italic = false;
+ }
+
+ /**
+ * 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);
+ }
+ StyleConstants.setUnderline(attributeSet, underline);
+ StyleConstants.setItalic(attributeSet, italic);
+ return attributeSet;
+ }
+
+ /**
+ * Get the background color.
+ * @return the background color or null if no color is set
+ */
+ public Color getBackground() {
+ return background;
+ }
+
+ /**
+ * Set the background color.
+ * @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");
+ }
+ this.background = background;
+ }
+
+ public boolean isBold() {
+ return bold;
+ }
+
+ public void setBold(boolean bold) {
+ this.bold = bold;
+ }
+
+ public Color getColor() {
+ return color;
+ }
+
+ public void setColor(Color color) {
+ if (color == null) {
+ throw new NullPointerException("argument 'color' cannot be null");
+ }
+ this.color = color;
+ }
+
+ public boolean isItalic() {
+ return italic;
+ }
+
+ public void setItalic(boolean italic) {
+ this.italic = italic;
+ }
+
+ public boolean isUnderline() {
+ return underline;
+ }
+
+ public void setUnderline(boolean underline) {
+ this.underline = underline;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null || !(obj instanceof Style)) {
+ return false;
+ }
+ if (obj == this) {
+ return true;
+ }
+ Style _object = (Style) obj;
+ return _object.bold == bold && _object.color.equals(color) && _object.background.equals(background)
+ && _object.underline == underline && _object.italic == italic;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Style clone() {
+ 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;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append(getClass().getName());
+ sb.append(": ");
+ sb.append("bold: ").append(bold);
+ sb.append(", ");
+ sb.append("color: ").append(color);
+ sb.append(", ");
+ sb.append("bg: ").append(background);
+ sb.append(", ");
+ sb.append("underline: ").append(underline);
+ sb.append(", ");
+ sb.append("italic: ").append(italic);
+
+ return sb.toString();
+ }
+ }
+}
diff --git a/src/prettify/Util.java b/src/prettify/Util.java
index d4afa9c..b8c69e9 100644
--- a/src/prettify/Util.java
+++ b/src/prettify/Util.java
@@ -2,6 +2,8 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -48,4 +50,27 @@
}
return sb.toString();
}
+
+ public static List<Object> removeDuplicates(List<Object> decorations) {
+ // use TreeMap to remove entrys with same pos
+ Map<Integer, Object> orderedMap = new TreeMap<Integer, Object>();
+ for (int i = 0, iEnd = decorations.size(); i < iEnd; i++) {
+ orderedMap.put((Integer) decorations.get(i), decorations.get(i + 1));
+ i++;
+ }
+
+ // remove adjacent style
+ List<Object> returnList = new ArrayList<Object>(orderedMap.size() + 1);
+ String previousStyle = null;
+ for (Integer _pos : orderedMap.keySet()) {
+ if (previousStyle != null && previousStyle.equals(orderedMap.get(_pos))) {
+ continue;
+ }
+ returnList.add(_pos);
+ returnList.add(orderedMap.get(_pos));
+ previousStyle = (String) orderedMap.get(_pos);
+ }
+
+ return returnList;
+ }
}
diff --git a/src/prettify/lang/LangAppollo.java b/src/prettify/lang/LangAppollo.java
new file mode 100644
index 0000000..15ac802
--- /dev/null
+++ b/src/prettify/lang/LangAppollo.java
@@ -0,0 +1,63 @@
+// Copyright (C) 2009 Onno Hommes.
+//
+// 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.lang;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.regex.Pattern;
+import prettify.Lang;
+import prettify.Prettify;
+
+/**
+ * @fileoverview
+ * Registers a language handler for the AGC/AEA Assembly Language as described
+ * at http://virtualagc.googlecode.com
+ * <p>
+ * This file could be used by goodle code to allow syntax highlight for
+ * Virtual AGC SVN repository or if you don't want to commonize
+ * the header for the agc/aea html assembly listing.
+ *
+ * @author ohommes@alumni.cmu.edu
+ */
+public class LangAppollo extends Lang {
+
+ public LangAppollo() {
+ List<List<Object>> _shortcutStylePatterns = new ArrayList<List<Object>>();
+ List<List<Object>> _fallthroughStylePatterns = new ArrayList<List<Object>>();
+
+ // A line comment that starts with ;
+ _shortcutStylePatterns.add(Arrays.asList(new Object[]{Prettify.PR_COMMENT, Pattern.compile("^#[^\r\n]*"), null, "#"}));
+ // Whitespace
+ _shortcutStylePatterns.add(Arrays.asList(new Object[]{Prettify.PR_PLAIN, Pattern.compile("^[\t\n\r \\xA0]+"), null, "\t\n\r " + Character.toString((char) 0xA0)}));
+ // A double quoted, possibly multi-line, string.
+ _shortcutStylePatterns.add(Arrays.asList(new Object[]{Prettify.PR_STRING, Pattern.compile("^\\\"(?:[^\\\"\\\\]|\\\\[\\s\\S])*(?:\\\"|$)"), null, "\""}));
+ _fallthroughStylePatterns.add(Arrays.asList(new Object[]{Prettify.PR_KEYWORD, Pattern.compile("^(?:ADS|AD|AUG|BZF|BZMF|CAE|CAF|CA|CCS|COM|CS|DAS|DCA|DCOM|DCS|DDOUBL|DIM|DOUBLE|DTCB|DTCF|DV|DXCH|EDRUPT|EXTEND|INCR|INDEX|NDX|INHINT|LXCH|MASK|MSK|MP|MSU|NOOP|OVSK|QXCH|RAND|READ|RELINT|RESUME|RETURN|ROR|RXOR|SQUARE|SU|TCR|TCAA|OVSK|TCF|TC|TS|WAND|WOR|WRITE|XCH|XLQ|XXALQ|ZL|ZQ|ADD|ADZ|SUB|SUZ|MPY|MPR|MPZ|DVP|COM|ABS|CLA|CLZ|LDQ|STO|STQ|ALS|LLS|LRS|TRA|TSQ|TMI|TOV|AXT|TIX|DLY|INP|OUT)\\s"), null}));
+ _fallthroughStylePatterns.add(Arrays.asList(new Object[]{Prettify.PR_TYPE, Pattern.compile("^(?:-?GENADR|=MINUS|2BCADR|VN|BOF|MM|-?2CADR|-?[1-6]DNADR|ADRES|BBCON|[SE]?BANK\\=?|BLOCK|BNKSUM|E?CADR|COUNT\\*?|2?DEC\\*?|-?DNCHAN|-?DNPTR|EQUALS|ERASE|MEMORY|2?OCT|REMADR|SETLOC|SUBRO|ORG|BSS|BES|SYN|EQU|DEFINE|END)\\s"), null}));
+ // A single quote possibly followed by a word that optionally ends with
+ // = ! or ?.
+ _fallthroughStylePatterns.add(Arrays.asList(new Object[]{Prettify.PR_LITERAL, Pattern.compile("^\\'(?:-*(?:\\w|\\\\[\\x21-\\x7e])(?:[\\w-]*|\\\\[\\x21-\\x7e])[=!?]?)?")}));
+ // Any word including labels that optionally ends with = ! or ?.
+ _fallthroughStylePatterns.add(Arrays.asList(new Object[]{Prettify.PR_PLAIN, Pattern.compile("^-*(?:[!-z_]|\\\\[\\x21-\\x7e])(?:[\\w-]*|\\\\[\\x21-\\x7e])[=!?]?", Pattern.CASE_INSENSITIVE)}));
+ // A printable non-space non-special character
+ _fallthroughStylePatterns.add(Arrays.asList(new Object[]{Prettify.PR_PUNCTUATION, Pattern.compile("^[^\\w\\t\\n\\r \\xA0()\\\"\\\\\\';]+")}));
+
+ setShortcutStylePatterns(_shortcutStylePatterns);
+ setFallthroughStylePatterns(_fallthroughStylePatterns);
+ }
+
+ public static List<String> getExtensions() {
+ return Arrays.asList(new String[]{"apollo", "agc", "aea"});
+ }
+}
diff --git a/src/prettify/lang/LangClj.java b/src/prettify/lang/LangClj.java
new file mode 100644
index 0000000..8765cf0
--- /dev/null
+++ b/src/prettify/lang/LangClj.java
@@ -0,0 +1,79 @@
+/**
+ * @license Copyright (C) 2011 Google Inc.
+ *
+ * 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.lang;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.regex.Pattern;
+import prettify.Lang;
+import prettify.Prettify;
+
+/**
+ * @fileoverview
+ * Registers a language handler for Clojure.
+ *
+ *
+ * To use, include prettify.js and this file in your HTML page.
+ * Then put your code in an HTML tag like
+ * <pre class="prettyprint lang-lisp">(my lisp code)</pre>
+ * The lang-cl class identifies the language as common lisp.
+ * This file supports the following language extensions:
+ * lang-clj - Clojure
+ *
+ *
+ * I used lang-lisp.js as the basis for this adding the clojure specific
+ * keywords and syntax.
+ *
+ * "Name" = 'Clojure'
+ * "Author" = 'Rich Hickey'
+ * "Version" = '1.2'
+ * "About" = 'Clojure is a lisp for the jvm with concurrency primitives and a richer set of types.'
+ *
+ *
+ * I used <a href="http://clojure.org/Reference">Clojure.org Reference</a> as
+ * the basis for the reserved word list.
+ *
+ *
+ * @author jwall@google.com
+ */
+public class LangClj extends Lang {
+
+ public LangClj() {
+ List<List<Object>> _shortcutStylePatterns = new ArrayList<List<Object>>();
+ List<List<Object>> _fallthroughStylePatterns = new ArrayList<List<Object>>();
+
+ // clojure has more paren types than minimal lisp.
+ _shortcutStylePatterns.add(Arrays.asList(new Object[]{"opn", Pattern.compile("^[\\(\\{\\[]+"), null, "([{"}));
+ _shortcutStylePatterns.add(Arrays.asList(new Object[]{"clo", Pattern.compile("^[\\)\\}\\]]+"), null, ")]}"}));
+ // A line comment that starts with ;
+ _shortcutStylePatterns.add(Arrays.asList(new Object[]{Prettify.PR_COMMENT, Pattern.compile("^;[^\r\n]*"), null, ";"}));
+ // Whitespace
+ _shortcutStylePatterns.add(Arrays.asList(new Object[]{Prettify.PR_PLAIN, Pattern.compile("^[\t\n\r \\xA0]+"), null, "\t\n\r " + Character.toString((char) 0xA0)}));
+ // A double quoted, possibly multi-line, string.
+ _shortcutStylePatterns.add(Arrays.asList(new Object[]{Prettify.PR_STRING, Pattern.compile("^\\\"(?:[^\\\"\\\\]|\\\\[\\s\\S])*(?:\\\"|$)"), null, "\""}));
+ // clojure has a much larger set of keywords
+ _fallthroughStylePatterns.add(Arrays.asList(new Object[]{Prettify.PR_KEYWORD, Pattern.compile("^(?:def|if|do|let|quote|var|fn|loop|recur|throw|try|monitor-enter|monitor-exit|defmacro|defn|defn-|macroexpand|macroexpand-1|for|doseq|dosync|dotimes|and|or|when|not|assert|doto|proxy|defstruct|first|rest|cons|defprotocol|deftype|defrecord|reify|defmulti|defmethod|meta|with-meta|ns|in-ns|create-ns|import|intern|refer|alias|namespace|resolve|ref|deref|refset|new|set!|memfn|to-array|into-array|aset|gen-class|reduce|map|filter|find|nil?|empty?|hash-map|hash-set|vec|vector|seq|flatten|reverse|assoc|dissoc|list|list?|disj|get|union|difference|intersection|extend|extend-type|extend-protocol|prn)\\b"), null}));
+ _fallthroughStylePatterns.add(Arrays.asList(new Object[]{Prettify.PR_TYPE, Pattern.compile("^:[0-9a-zA-Z\\-]+")}));
+
+ setShortcutStylePatterns(_shortcutStylePatterns);
+ setFallthroughStylePatterns(_fallthroughStylePatterns);
+ }
+
+ public static List<String> getExtensions() {
+ return Arrays.asList(new String[]{"clj"});
+ }
+}
diff --git a/src/prettify/lang/LangCss.java b/src/prettify/lang/LangCss.java
new file mode 100644
index 0000000..d39c668
--- /dev/null
+++ b/src/prettify/lang/LangCss.java
@@ -0,0 +1,109 @@
+// Copyright (C) 2009 Google Inc.
+//
+// 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.lang;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.regex.Pattern;
+import prettify.Lang;
+import prettify.Prettify;
+
+/**
+ * @fileoverview
+ * Registers a language handler for CSS.
+ *
+ *
+ * To use, include prettify.js and this file in your HTML page.
+ * Then put your code in an HTML tag like
+ * <pre class="prettyprint lang-css"></pre>
+ *
+ *
+ * http://www.w3.org/TR/CSS21/grammar.html Section G2 defines the lexical
+ * grammar. This scheme does not recognize keywords containing escapes.
+ *
+ * @author mikesamuel@gmail.com
+ */
+public class LangCss extends Lang {
+
+ public LangCss() {
+ List<List<Object>> _shortcutStylePatterns = new ArrayList<List<Object>>();
+ List<List<Object>> _fallthroughStylePatterns = new ArrayList<List<Object>>();
+
+ // The space production <s>
+ _shortcutStylePatterns.add(Arrays.asList(new Object[]{Prettify.PR_PLAIN, Pattern.compile("^[ \t\r\n\f]+"), null, " \t\r\n\f"}));
+ // Quoted strings. <string1> and <string2>
+ _fallthroughStylePatterns.add(Arrays.asList(new Object[]{Prettify.PR_STRING, Pattern.compile("^\\\"(?:[^\n\r\f\\\\\\\"]|\\\\(?:\r\n?|\n|\f)|\\\\[\\s\\S])*\\\""), null}));
+ _fallthroughStylePatterns.add(Arrays.asList(new Object[]{Prettify.PR_STRING, Pattern.compile("^\\'(?:[^\n\r\f\\\\\\']|\\\\(?:\r\n?|\n|\f)|\\\\[\\s\\S])*\\'"), null}));
+ _fallthroughStylePatterns.add(Arrays.asList(new Object[]{"lang-css-str", Pattern.compile("^url\\(([^\\)\\\"\\']*)\\)", Pattern.CASE_INSENSITIVE)}));
+ _fallthroughStylePatterns.add(Arrays.asList(new Object[]{Prettify.PR_KEYWORD, Pattern.compile("^(?:url|rgb|\\!important|@import|@page|@media|@charset|inherit)(?=[^\\-\\w]|$)", Pattern.CASE_INSENSITIVE), null}));
+ // A property name -- an identifier followed by a colon.
+ _fallthroughStylePatterns.add(Arrays.asList(new Object[]{"lang-css-kw", Pattern.compile("^(-?(?:[_a-z]|(?:\\\\[0-9a-f]+ ?))(?:[_a-z0-9\\-]|\\\\(?:\\\\[0-9a-f]+ ?))*)\\s*:", Pattern.CASE_INSENSITIVE)}));
+ // A C style block comment. The <comment> production.
+ _fallthroughStylePatterns.add(Arrays.asList(new Object[]{Prettify.PR_COMMENT, Pattern.compile("^\\/\\*[^*]*\\*+(?:[^\\/*][^*]*\\*+)*\\/")}));
+ // Escaping text spans
+ _fallthroughStylePatterns.add(Arrays.asList(new Object[]{Prettify.PR_COMMENT, Pattern.compile("^(?:<!--|-->)/")}));
+ // A number possibly containing a suffix.
+ _fallthroughStylePatterns.add(Arrays.asList(new Object[]{Prettify.PR_LITERAL, Pattern.compile("^(?:\\d+|\\d*\\.\\d+)(?:%|[a-z]+)?", Pattern.CASE_INSENSITIVE)}));
+ // A hex color
+ _fallthroughStylePatterns.add(Arrays.asList(new Object[]{Prettify.PR_LITERAL, Pattern.compile("^#(?:[0-9a-f]{3}){1,2}", Pattern.CASE_INSENSITIVE)}));
+ // An identifier
+ _fallthroughStylePatterns.add(Arrays.asList(new Object[]{Prettify.PR_PLAIN, Pattern.compile("^-?(?:[_a-z]|(?:\\\\[\\da-f]+ ?))(?:[_a-z\\d\\-]|\\\\(?:\\\\[\\da-f]+ ?))*", Pattern.CASE_INSENSITIVE)}));
+ // A run of punctuation
+ _fallthroughStylePatterns.add(Arrays.asList(new Object[]{Prettify.PR_PUNCTUATION, Pattern.compile("^[^\\s\\w\\'\\\"]+", Pattern.CASE_INSENSITIVE)}));
+
+ setShortcutStylePatterns(_shortcutStylePatterns);
+ setFallthroughStylePatterns(_fallthroughStylePatterns);
+
+ setExtendedLangs(Arrays.asList(new Lang[]{new LangCssKeyword(), new LangCssString()}));
+ }
+
+ public static List<String> getExtensions() {
+ return Arrays.asList(new String[]{"css"});
+ }
+
+ protected static class LangCssKeyword extends Lang {
+
+ public LangCssKeyword() {
+ List<List<Object>> _shortcutStylePatterns = new ArrayList<List<Object>>();
+ List<List<Object>> _fallthroughStylePatterns = new ArrayList<List<Object>>();
+
+ _fallthroughStylePatterns.add(Arrays.asList(new Object[]{Prettify.PR_KEYWORD, Pattern.compile("^-?(?:[_a-z]|(?:\\\\[\\da-f]+ ?))(?:[_a-z\\d\\-]|\\\\(?:\\\\[\\da-f]+ ?))*", Pattern.CASE_INSENSITIVE)}));
+
+ setShortcutStylePatterns(_shortcutStylePatterns);
+ setFallthroughStylePatterns(_fallthroughStylePatterns);
+ }
+
+ public static List<String> getExtensions() {
+ return Arrays.asList(new String[]{"css-kw"});
+ }
+ }
+
+ protected static class LangCssString extends Lang {
+
+ public LangCssString() {
+ List<List<Object>> _shortcutStylePatterns = new ArrayList<List<Object>>();
+ List<List<Object>> _fallthroughStylePatterns = new ArrayList<List<Object>>();
+
+ _fallthroughStylePatterns.add(Arrays.asList(new Object[]{Prettify.PR_STRING, Pattern.compile("^[^\\)\\\"\\']+")}));
+
+ setShortcutStylePatterns(_shortcutStylePatterns);
+ setFallthroughStylePatterns(_fallthroughStylePatterns);
+ }
+
+ public static List<String> getExtensions() {
+ return Arrays.asList(new String[]{"css-str"});
+ }
+ }
+}
diff --git a/src/prettify/lang/LangGo.java b/src/prettify/lang/LangGo.java
new file mode 100644
index 0000000..05bfa2f
--- /dev/null
+++ b/src/prettify/lang/LangGo.java
@@ -0,0 +1,15 @@
+package prettify.lang;
+
+import java.util.Arrays;
+import java.util.List;
+import prettify.Lang;
+
+public class LangGo extends Lang {
+
+ public LangGo() {
+ }
+
+ public static List<String> getExtensions() {
+ return Arrays.asList(new String[]{});
+ }
+}
diff --git a/src/prettify/lang/LangProto.java b/src/prettify/lang/LangProto.java
new file mode 100644
index 0000000..8941ec8
--- /dev/null
+++ b/src/prettify/lang/LangProto.java
@@ -0,0 +1,15 @@
+package prettify.lang;
+
+import java.util.Arrays;
+import java.util.List;
+import prettify.Lang;
+
+public class LangProto extends Lang {
+
+ public LangProto() {
+ }
+
+ public static List<String> getExtensions() {
+ return Arrays.asList(new String[]{});
+ }
+}
diff --git a/src/prettify/lang/LangScala.java b/src/prettify/lang/LangScala.java
new file mode 100644
index 0000000..6622694
--- /dev/null
+++ b/src/prettify/lang/LangScala.java
@@ -0,0 +1,15 @@
+package prettify.lang;
+
+import java.util.Arrays;
+import java.util.List;
+import prettify.Lang;
+
+public class LangScala extends Lang {
+
+ public LangScala() {
+ }
+
+ public static List<String> getExtensions() {
+ return Arrays.asList(new String[]{});
+ }
+}
diff --git a/src/prettify/lang/LangSql.java b/src/prettify/lang/LangSql.java
new file mode 100644
index 0000000..59f06af
--- /dev/null
+++ b/src/prettify/lang/LangSql.java
@@ -0,0 +1,15 @@
+package prettify.lang;
+
+import java.util.Arrays;
+import java.util.List;
+import prettify.Lang;
+
+public class LangSql extends Lang {
+
+ public LangSql() {
+ }
+
+ public static List<String> getExtensions() {
+ return Arrays.asList(new String[]{});
+ }
+}
diff --git a/src/prettify/lang/LangVb.java b/src/prettify/lang/LangVb.java
new file mode 100644
index 0000000..8e39256
--- /dev/null
+++ b/src/prettify/lang/LangVb.java
@@ -0,0 +1,70 @@
+// Copyright (C) 2009 Google Inc.
+//
+// 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.lang;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.regex.Pattern;
+import prettify.Lang;
+import prettify.Prettify;
+
+/**
+ * @fileoverview
+ * Registers a language handler for various flavors of basic.
+ *
+ *
+ * To use, include prettify.js and this file in your HTML page.
+ * Then put your code in an HTML tag like
+ * <pre class="prettyprint lang-vb"></pre>
+ *
+ *
+ * http://msdn.microsoft.com/en-us/library/aa711638(VS.71).aspx defines the
+ * visual basic grammar lexical grammar.
+ *
+ * @author mikesamuel@gmail.com
+ */
+public class LangVb extends Lang {
+
+ public LangVb() {
+ List<List<Object>> _shortcutStylePatterns = new ArrayList<List<Object>>();
+ List<List<Object>> _fallthroughStylePatterns = new ArrayList<List<Object>>();
+
+ // Whitespace
+ _shortcutStylePatterns.add(Arrays.asList(new Object[]{Prettify.PR_COMMENT, Pattern.compile("^[\\t\\n\\r \\xA0\\u2028\\u2029]+"), null, "\t\n\r " + Character.toString((char) 0xA0) + "\u2028\u2029"}));
+ // A double quoted string with quotes escaped by doubling them.
+ // A single character can be suffixed with C.
+ _shortcutStylePatterns.add(Arrays.asList(new Object[]{Prettify.PR_STRING, Pattern.compile("^(?:[\\\"\\u201C\\u201D](?:[^\\\"\\u201C\\u201D]|[\\\"\\u201C\\u201D]{2})(?:[\\\"\\u201C\\u201D]c|$)|[\\\"\\u201C\\u201D](?:[^\\\"\\u201C\\u201D]|[\\\"\\u201C\\u201D]{2})*(?:[\\\"\\u201C\\u201D]|$))", Pattern.CASE_INSENSITIVE), null, "\"\u201C\u201D"}));
+ // A comment starts with a single quote and runs until the end of the line.
+ _shortcutStylePatterns.add(Arrays.asList(new Object[]{Prettify.PR_COMMENT, Pattern.compile("^[\\'\\u2018\\u2019][^\\r\\n\\u2028\\u2029]*"), null, "'\u2018\u2019"}));
+ _fallthroughStylePatterns.add(Arrays.asList(new Object[]{Prettify.PR_KEYWORD, Pattern.compile("^(?:AddHandler|AddressOf|Alias|And|AndAlso|Ansi|As|Assembly|Auto|Boolean|ByRef|Byte|ByVal|Call|Case|Catch|CBool|CByte|CChar|CDate|CDbl|CDec|Char|CInt|Class|CLng|CObj|Const|CShort|CSng|CStr|CType|Date|Decimal|Declare|Default|Delegate|Dim|DirectCast|Do|Double|Each|Else|ElseIf|End|EndIf|Enum|Erase|Error|Event|Exit|Finally|For|Friend|Function|Get|GetType|GoSub|GoTo|Handles|If|Implements|Imports|In|Inherits|Integer|Interface|Is|Let|Lib|Like|Long|Loop|Me|Mod|Module|MustInherit|MustOverride|MyBase|MyClass|Namespace|New|Next|Not|NotInheritable|NotOverridable|Object|On|Option|Optional|Or|OrElse|Overloads|Overridable|Overrides|ParamArray|Preserve|Private|Property|Protected|Public|RaiseEvent|ReadOnly|ReDim|RemoveHandler|Resume|Return|Select|Set|Shadows|Shared|Short|Single|Static|Step|Stop|String|Structure|Sub|SyncLock|Then|Throw|To|Try|TypeOf|Unicode|Until|Variant|Wend|When|While|With|WithEvents|WriteOnly|Xor|EndIf|GoSub|Let|Variant|Wend)\\b", Pattern.CASE_INSENSITIVE), null}));
+ // A second comment form
+ _fallthroughStylePatterns.add(Arrays.asList(new Object[]{Prettify.PR_COMMENT, Pattern.compile("^REM[^\\r\\n\\u2028\\u2029]*", Pattern.CASE_INSENSITIVE)}));
+ // A boolean, numeric, or date literal.
+ _fallthroughStylePatterns.add(Arrays.asList(new Object[]{Prettify.PR_LITERAL, Pattern.compile("^(?:True\\b|False\\b|Nothing\\b|\\d+(?:E[+\\-]?\\d+[FRD]?|[FRDSIL])?|(?:&H[0-9A-F]+|&O[0-7]+)[SIL]?|\\d*\\.\\d+(?:E[+\\-]?\\d+)?[FRD]?|#\\s+(?:\\d+[\\-\\/]\\d+[\\-\\/]\\d+(?:\\s+\\d+:\\d+(?::\\d+)?(\\s*(?:AM|PM))?)?|\\d+:\\d+(?::\\d+)?(\\s*(?:AM|PM))?)\\s+#)", Pattern.CASE_INSENSITIVE)}));
+ // An identifier?
+ _fallthroughStylePatterns.add(Arrays.asList(new Object[]{Prettify.PR_PLAIN, Pattern.compile("^(?:(?:[a-z]|_\\w)\\w*|\\[(?:[a-z]|_\\w)\\w*\\])", Pattern.CASE_INSENSITIVE)}));
+ // A run of punctuation
+ _fallthroughStylePatterns.add(Arrays.asList(new Object[]{Prettify.PR_PUNCTUATION, Pattern.compile("^[^\\w\\t\\n\\r \\\"\\'\\[\\]\\xA0\\u2018\\u2019\\u201C\\u201D\\u2028\\u2029]+")}));
+ // Square brackets
+ _fallthroughStylePatterns.add(Arrays.asList(new Object[]{Prettify.PR_PUNCTUATION, Pattern.compile("^(?:\\[|\\])")}));
+
+ setShortcutStylePatterns(_shortcutStylePatterns);
+ setFallthroughStylePatterns(_fallthroughStylePatterns);
+ }
+
+ public static List<String> getExtensions() {
+ return Arrays.asList(new String[]{"vb", "vbs"});
+ }
+}
diff --git a/src/prettify/lang/LangWiki.java b/src/prettify/lang/LangWiki.java
new file mode 100644
index 0000000..d878351
--- /dev/null
+++ b/src/prettify/lang/LangWiki.java
@@ -0,0 +1,15 @@
+package prettify.lang;
+
+import java.util.Arrays;
+import java.util.List;
+import prettify.Lang;
+
+public class LangWiki extends Lang {
+
+ public LangWiki() {
+ }
+
+ public static List<String> getExtensions() {
+ return Arrays.asList(new String[]{});
+ }
+}
diff --git a/src/prettify/lang/LangYaml.java b/src/prettify/lang/LangYaml.java
new file mode 100644
index 0000000..7e78937
--- /dev/null
+++ b/src/prettify/lang/LangYaml.java
@@ -0,0 +1,15 @@
+package prettify.lang;
+
+import java.util.Arrays;
+import java.util.List;
+import prettify.Lang;
+
+public class LangYaml extends Lang {
+
+ public LangYaml() {
+ }
+
+ public static List<String> getExtensions() {
+ return Arrays.asList(new String[]{});
+ }
+}
diff --git a/src/prettify/theme/ThemeDefault.java b/src/prettify/theme/ThemeDefault.java
new file mode 100644
index 0000000..43cdceb
--- /dev/null
+++ b/src/prettify/theme/ThemeDefault.java
@@ -0,0 +1,89 @@
+package prettify.theme;
+
+import java.awt.Color;
+import java.awt.Font;
+import prettify.Theme;
+
+/**
+ * Default theme.
+ */
+public class ThemeDefault extends Theme {
+
+ public ThemeDefault() {
+ super();
+
+ setFont(new Font("Consolas", Font.PLAIN, 12));
+ setBackground(Color.white);
+
+ setHighlightedBackground(Color.decode("0xeee"));
+
+ setGutterText(Color.decode("0x000"));
+ setGutterBorderColor(Color.decode("0xeee"));
+ setGutterBorderWidth(3);
+ setGutterTextFont(new Font("Verdana", Font.PLAIN, 11));
+ setGutterTextPaddingLeft(7);
+ setGutterTextPaddingRight(7);
+
+ Style plainStyle = new Style();
+ plainStyle.setColor(Color.decode("0x000"));
+ setPlain(plainStyle);
+
+ Style style;
+
+ style = new Style();
+ style.setColor(Color.decode("0x080"));
+ setString(style);
+
+ style = new Style();
+ style.setColor(Color.decode("0x008"));
+ setKeyword(style);
+
+ style = new Style();
+ style.setColor(Color.decode("0x800"));
+ setComment(style);
+
+ style = new Style();
+ style.setColor(Color.decode("0x606"));
+ setType(style);
+
+ style = new Style();
+ style.setColor(Color.decode("0x066"));
+ setLiteral(style);
+
+ style = new Style();
+ style.setColor(Color.decode("0x660"));
+ setPunctuation(style);
+
+ style = new Style();
+ style.setColor(Color.decode("0x008"));
+ setTag(style);
+
+ setDeclaration(plainStyle);
+
+ style = new Style();
+ style.setColor(Color.decode("0x606"));
+ setAttributeName(style);
+
+ style = new Style();
+ style.setColor(Color.decode("0x080"));
+ setAttributeValue(style);
+
+ setNoCode(plainStyle);
+
+ style = new Style();
+ style.setColor(Color.decode("0x660"));
+ setOpenBracket(style);
+
+ style = new Style();
+ style.setColor(Color.decode("0x660"));
+ setCloseBracket(style);
+
+ style = new Style();
+ style.setColor(Color.decode("0x606"));
+ setVariable(style);
+
+ style = new Style();
+ style.setColor(Color.red);
+ setFunction(style);
+ }
+}
diff --git a/src/prettify/theme/ThemeDesert.java b/src/prettify/theme/ThemeDesert.java
new file mode 100644
index 0000000..70398d0
--- /dev/null
+++ b/src/prettify/theme/ThemeDesert.java
@@ -0,0 +1,91 @@
+package prettify.theme;
+
+import java.awt.Color;
+import java.awt.Font;
+import prettify.Theme;
+
+/**
+ * Desert theme.
+ */
+public class ThemeDesert extends Theme {
+
+ public ThemeDesert() {
+ super();
+
+ /* desert scheme ported from vim to google prettify */
+
+ setFont(new Font("Consolas", Font.PLAIN, 12));
+ setBackground(Color.decode("0x000"));
+
+ setHighlightedBackground(Color.decode("0x111"));
+
+ setGutterText(Color.decode("0xfff"));
+ setGutterBorderColor(Color.decode("0x111"));
+ setGutterBorderWidth(3);
+ setGutterTextFont(new Font("Verdana", Font.PLAIN, 11));
+ setGutterTextPaddingLeft(7);
+ setGutterTextPaddingRight(7);
+
+ Style plainStyle = new Style();
+ plainStyle.setColor(Color.decode("0xfff"));
+ setPlain(plainStyle);
+
+ Style style;
+
+ style = new Style();
+ style.setColor(Color.decode("0xffa0a0")); /* string - pink */
+ setString(style);
+
+ style = new Style();
+ style.setColor(Color.decode("0xf0e68c"));
+ style.setBold(true);
+ setKeyword(style);
+
+ style = new Style();
+ style.setColor(Color.decode("0x87ceeb")); /* comment - skyblue */
+ setComment(style);
+
+ style = new Style();
+ style.setColor(Color.decode("0x98fb98")); /* type - lightgreen */
+ setType(style);
+
+ style = new Style();
+ style.setColor(Color.decode("0xcd5c5c")); /* literal - darkred */
+ setLiteral(style);
+
+ style = new Style();
+ style.setColor(Color.decode("0xfff"));
+ setPunctuation(style);
+
+ style = new Style();
+ style.setColor(Color.decode("0xf0e68c"));/* html/xml tag - lightyellow */
+ style.setBold(true);
+ setTag(style);
+
+ style = new Style();
+ style.setColor(Color.decode("0x98fb98")); /* decimal - lightgreen */
+ setDeclaration(style);
+
+ style = new Style();
+ style.setColor(Color.decode("0xbdb76b")); /* attribute name - khaki */
+ style.setBold(true);
+ setAttributeName(style);
+
+ style = new Style();
+ style.setColor(Color.decode("0xffa0a0")); /* attribute value - pink */
+ style.setBold(true);
+ setAttributeValue(style);
+
+ style = new Style();
+ style.setColor(Color.decode("0x333"));
+ setNoCode(style);
+
+ setOpenBracket(plainStyle);
+
+ setCloseBracket(plainStyle);
+
+ setVariable(plainStyle);
+
+ setFunction(plainStyle);
+ }
+}
diff --git a/src/prettify/theme/ThemeSonsOfObsidian.java b/src/prettify/theme/ThemeSonsOfObsidian.java
new file mode 100644
index 0000000..08920bb
--- /dev/null
+++ b/src/prettify/theme/ThemeSonsOfObsidian.java
@@ -0,0 +1,91 @@
+package prettify.theme;
+
+import java.awt.Color;
+import java.awt.Font;
+import prettify.Theme;
+
+/**
+ * Son of Obsidian theme.
+ * @author Alex Ford
+ */
+public class ThemeSonsOfObsidian extends Theme {
+
+ public ThemeSonsOfObsidian() {
+ super();
+
+ /*
+ * Derived from einaros's Sons of Obsidian theme at
+ * http://studiostyl.es/schemes/son-of-obsidian by
+ * Alex Ford of CodeTunnel:
+ * http://CodeTunnel.com/blog/post/71/google-code-prettify-obsidian-theme
+ */
+
+ setFont(new Font("Consolas", Font.PLAIN, 12));
+ setBackground(Color.white);
+
+ setHighlightedBackground(Color.decode("0x111"));
+
+ setGutterText(Color.decode("0xF1F2F3"));
+ setGutterBorderColor(Color.decode("0x111"));
+ setGutterBorderWidth(3);
+ setGutterTextFont(new Font("Verdana", Font.PLAIN, 11));
+ setGutterTextPaddingLeft(7);
+ setGutterTextPaddingRight(7);
+
+ Style plainStyle = new Style();
+ plainStyle.setColor(Color.decode("0xF1F2F3"));
+ setPlain(plainStyle);
+
+ Style style;
+
+ style = new Style();
+ style.setColor(Color.decode("0xEC7600"));
+ setString(style);
+
+ style = new Style();
+ style.setColor(Color.decode("0x93C763"));
+ setKeyword(style);
+
+ style = new Style();
+ style.setColor(Color.decode("0x66747B"));
+ setComment(style);
+
+ style = new Style();
+ style.setColor(Color.decode("0x678CB1"));
+ setType(style);
+
+ style = new Style();
+ style.setColor(Color.decode("0xFACD22"));
+ setLiteral(style);
+
+ style = new Style();
+ style.setColor(Color.decode("0xF1F2F3"));
+ setPunctuation(style);
+
+ style = new Style();
+ style.setColor(Color.decode("0x8AC763"));
+ setTag(style);
+
+ style = new Style();
+ style.setColor(Color.decode("0x800080"));
+ setDeclaration(style);
+
+ style = new Style();
+ style.setColor(Color.decode("0xE0E2E4"));
+ setAttributeName(style);
+
+ style = new Style();
+ style.setColor(Color.decode("0xEC7600"));
+ setAttributeValue(style);
+
+ setNoCode(plainStyle);
+
+ setOpenBracket(plainStyle);
+
+ setCloseBracket(plainStyle);
+
+ setVariable(plainStyle);
+
+ setFunction(plainStyle);
+ }
+}
diff --git a/src/prettify/theme/ThemeSunburst.java b/src/prettify/theme/ThemeSunburst.java
new file mode 100644
index 0000000..ef75c80
--- /dev/null
+++ b/src/prettify/theme/ThemeSunburst.java
@@ -0,0 +1,88 @@
+package prettify.theme;
+
+import java.awt.Color;
+import java.awt.Font;
+import prettify.Theme;
+
+/**
+ * Sunbrust theme.
+ * Vim sunburst theme by David Leibovic.
+ * @author David Leibovic
+ */
+public class ThemeSunburst extends Theme {
+
+ public ThemeSunburst() {
+ super();
+
+ /* Vim sunburst theme by David Leibovic */
+
+ setFont(new Font("Consolas", Font.PLAIN, 12));
+ setBackground(Color.black);
+
+ setHighlightedBackground(Color.decode("0xAEAEAE"));
+
+ setGutterText(Color.decode("0xfff"));
+ setGutterBorderColor(Color.decode("0xAEAEAE"));
+ setGutterBorderWidth(3);
+ setGutterTextFont(new Font("Verdana", Font.PLAIN, 11));
+ setGutterTextPaddingLeft(7);
+ setGutterTextPaddingRight(7);
+
+ Style plainStyle = new Style();
+ plainStyle.setColor(Color.decode("0xfff"));
+ setPlain(plainStyle);
+
+ Style style;
+
+ style = new Style();
+ style.setColor(Color.decode("0x65B042")); /* string - green */
+ setString(style);
+
+ style = new Style();
+ style.setColor(Color.decode("0xE28964")); /* keyword - dark pink */
+ setKeyword(style);
+
+ style = new Style();
+ style.setColor(Color.decode("0xAEAEAE")); /* comment - gray */
+ style.setItalic(true);
+ setComment(style);
+
+ style = new Style();
+ style.setColor(Color.decode("0x89bdff")); /* type - light blue */
+ setType(style);
+
+ style = new Style();
+ style.setColor(Color.decode("0x3387CC")); /* literal - blue */
+ setLiteral(style);
+
+ style = new Style();
+ style.setColor(Color.decode("0xfff")); /* punctuation - white */
+ setPunctuation(style);
+
+ style = new Style();
+ style.setColor(Color.decode("0x89bdff")); /* html/xml tag - light blue */
+ setTag(style);
+
+ style = new Style();
+ style.setColor(Color.decode("0x3387CC")); /* decimal - blue */
+ setDeclaration(style);
+
+ style = new Style();
+ style.setColor(Color.decode("0xbdb76b")); /* html/xml attribute name - khaki */
+ setAttributeName(style);
+
+ style = new Style();
+ style.setColor(Color.decode("0x65B042")); /* html/xml attribute value - green */
+ setAttributeValue(style);
+
+ setNoCode(plainStyle);
+
+ setOpenBracket(plainStyle);
+
+ setCloseBracket(plainStyle);
+
+ setVariable(plainStyle);
+
+ setFunction(plainStyle);
+ }
+}
diff --git a/test/prettify/PrettifyTest.java b/test/prettify/PrettifyTest.java
index 8d4cf42..89c9c52 100644
--- a/test/prettify/PrettifyTest.java
+++ b/test/prettify/PrettifyTest.java
@@ -13,8 +13,6 @@
// limitations under the License.
package prettify;
-import java.util.Map;
-import java.util.TreeMap;
import java.util.ListIterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -70,116 +68,78 @@
List<Object> decorations, compare;
source = new String(readFile(new File(packagePath + "source/bash.txt")));
- job = new Job();
- job.setBasePos(0);
- job.setSourceCode(source);
- prettify.langHandlerForExtension(null, source).decorate(job);
+ prettify.langHandlerForExtension(null, source).decorate(job = new Job(0, source));
decorations = job.getDecorations();
compare = readResult(new String(readFile(new File(packagePath + "result/bash.txt"))));
assertArrayEquals("bash", decorations.toArray(), compare.toArray());
source = new String(readFile(new File(packagePath + "source/bash_lang.txt")));
- job = new Job();
- job.setBasePos(0);
- job.setSourceCode(source);
- prettify.langHandlerForExtension("sh", source).decorate(job);
+ prettify.langHandlerForExtension("sh", source).decorate(job = new Job(0, source));
decorations = removeNewLine(job.getDecorations(), source);
compare = readResult(new String(readFile(new File(packagePath + "result/bash_lang.txt"))), true);
assertArrayEquals("bash_lang", decorations.toArray(), compare.toArray());
source = new String(readFile(new File(packagePath + "source/java.txt")));
- job = new Job();
- job.setBasePos(0);
- job.setSourceCode(source);
- prettify.langHandlerForExtension(null, source).decorate(job);
+ prettify.langHandlerForExtension(null, source).decorate(job = new Job(0, source));
decorations = job.getDecorations();
compare = readResult(new String(readFile(new File(packagePath + "result/java.txt"))));
assertArrayEquals("java", decorations.toArray(), compare.toArray());
-
source = new String(readFile(new File(packagePath + "source/java_lang.txt")));
- job = new Job();
- job.setBasePos(0);
- job.setSourceCode(source);
- prettify.langHandlerForExtension("java", source).decorate(job);
+ prettify.langHandlerForExtension("java", source).decorate(job = new Job(0, source));
decorations = removeNewLine(job.getDecorations(), source);
compare = readResult(new String(readFile(new File(packagePath + "result/java_lang.txt"))), true);
assertArrayEquals("java_lang", decorations.toArray(), compare.toArray());
source = new String(readFile(new File(packagePath + "source/C.txt")));
- job = new Job();
- job.setBasePos(0);
- job.setSourceCode(source);
- prettify.langHandlerForExtension(null, source).decorate(job);
+ prettify.langHandlerForExtension(null, source).decorate(job = new Job(0, source));
decorations = job.getDecorations();
compare = readResult(new String(readFile(new File(packagePath + "result/C.txt"))));
assertArrayEquals("C", decorations.toArray(), compare.toArray());
-
source = new String(readFile(new File(packagePath + "source/C_lang.txt")));
- job = new Job();
- job.setBasePos(0);
- job.setSourceCode(source);
- prettify.langHandlerForExtension("c", source).decorate(job);
+ prettify.langHandlerForExtension("c", source).decorate(job = new Job(0, source));
decorations = removeNewLine(job.getDecorations(), source);
compare = readResult(new String(readFile(new File(packagePath + "result/C_lang.txt"))), true);
assertArrayEquals("C_lang", decorations.toArray(), compare.toArray());
source = new String(readFile(new File(packagePath + "source/Cpp.txt")));
- job = new Job();
- job.setBasePos(0);
- job.setSourceCode(source);
- prettify.langHandlerForExtension(null, source).decorate(job);
+ prettify.langHandlerForExtension(null, source).decorate(job = new Job(0, source));
decorations = job.getDecorations();
compare = readResult(new String(readFile(new File(packagePath + "result/Cpp.txt"))));
assertArrayEquals("Cpp", decorations.toArray(), compare.toArray());
source = new String(readFile(new File(packagePath + "source/Cpp_lang.txt")));
- job = new Job();
- job.setBasePos(0);
- job.setSourceCode(source);
- prettify.langHandlerForExtension("cpp", source).decorate(job);
+ prettify.langHandlerForExtension("cpp", source).decorate(job = new Job(0, source));
decorations = removeNewLine(job.getDecorations(), source);
compare = readResult(new String(readFile(new File(packagePath + "result/Cpp_lang.txt"))), true);
assertArrayEquals("Cpp_lang", decorations.toArray(), compare.toArray());
source = new String(readFile(new File(packagePath + "source/javascript.txt")));
- job = new Job();
- job.setBasePos(0);
- job.setSourceCode(source);
- prettify.langHandlerForExtension(null, source).decorate(job);
+ prettify.langHandlerForExtension(null, source).decorate(job = new Job(0, source));
decorations = job.getDecorations();
compare = readResult(new String(readFile(new File(packagePath + "result/javascript.txt"))));
assertArrayEquals("javascript", decorations.toArray(), compare.toArray());
source = new String(readFile(new File(packagePath + "source/perl.txt")));
- job = new Job();
- job.setBasePos(0);
- job.setSourceCode(source);
- prettify.langHandlerForExtension(null, source).decorate(job);
+ prettify.langHandlerForExtension(null, source).decorate(job = new Job(0, source));
decorations = job.getDecorations();
compare = readResult(new String(readFile(new File(packagePath + "result/perl.txt"))));
assertArrayEquals("perl", decorations.toArray(), compare.toArray());
-
source = new String(readFile(new File(packagePath + "source/python.txt")));
- job = new Job();
- job.setBasePos(0);
- job.setSourceCode(source);
- prettify.langHandlerForExtension(null, source).decorate(job);
+ prettify.langHandlerForExtension(null, source).decorate(job = new Job(0, source));
decorations = job.getDecorations();
compare = readResult(new String(readFile(new File(packagePath + "result/python.txt"))));
assertArrayEquals("python", decorations.toArray(), compare.toArray());
source = new String(readFile(new File(packagePath + "source/python_lang.txt")));
- job = new Job();
- job.setBasePos(0);
- job.setSourceCode(source);
- prettify.langHandlerForExtension("py", source).decorate(job);
+ prettify.langHandlerForExtension("py", source).decorate(job = new Job(0, source));
decorations = removeNewLine(job.getDecorations(), source);
compare = readResult(new String(readFile(new File(packagePath + "result/python_lang.txt"))), true);
assertArrayEquals("python_lang", decorations.toArray(), compare.toArray());
+ // porting in progress
}
/**
@@ -241,25 +201,7 @@
}
// matcher.appendTail(sb);
- // use TreeMap to remove entrys with same pos
- Map<Integer, Object> orderedMap = new TreeMap<Integer, Object>();
- for (int i = 0, iEnd = decorations.size(); i < iEnd; i++) {
- orderedMap.put((Integer) decorations.get(i), decorations.get(i + 1));
- i++;
- }
- // remove adjacent style
- List<Object> returnList = new ArrayList<Object>(orderedMap.size() + 1);
- String previousStyle = null;
- for (Integer _pos : orderedMap.keySet()) {
- if (previousStyle != null && previousStyle.equals(orderedMap.get(_pos))) {
- continue;
- }
- returnList.add(_pos);
- returnList.add(orderedMap.get(_pos));
- previousStyle = (String) orderedMap.get(_pos);
- }
-
- return returnList;
+ return Util.removeDuplicates(decorations);
}
public static List<Object> readResult(String result) {
@@ -291,41 +233,25 @@
}
}
- StringBuffer sb = new StringBuffer();
+ StringBuffer sb = new StringBuffer(); // for debug
Pattern pattern = Pattern.compile("`([A-Z]{3})([^`]*?)`END", Pattern.MULTILINE | Pattern.DOTALL);
Matcher matcher = pattern.matcher(result);
while (matcher.find()) {
- matcher.appendReplacement(sb, "");
- sb.append(matcher.group(2));
+ matcher.appendReplacement(sb, ""); // for debug
+ sb.append(matcher.group(2)); // for debug
returnList.add(count);
returnList.add(matcher.group(1).toLowerCase());
count += matcher.group(2).length();
}
matcher.appendTail(sb);
- String plainCode = sb.toString();
+ String plainCode = sb.toString(); // for debug
if (removeNewLine) {
- // use TreeMap to remove entrys with same pos
- Map<Integer, Object> orderedMap = new TreeMap<Integer, Object>();
- for (int i = 0, iEnd = returnList.size(); i < iEnd; i++) {
- orderedMap.put((Integer) returnList.get(i), returnList.get(i + 1));
- i++;
- }
- // remove adjacent style
- List<Object> _returnList = new ArrayList<Object>(orderedMap.size() + 1);
- String previousStyle = null;
- for (Integer _pos : orderedMap.keySet()) {
- if (previousStyle != null && previousStyle.equals(orderedMap.get(_pos))) {
- continue;
- }
- _returnList.add(_pos);
- _returnList.add(orderedMap.get(_pos));
- previousStyle = (String) orderedMap.get(_pos);
- }
- returnList = _returnList;
+ returnList = Util.removeDuplicates(returnList);
}
+ // for debug
// System.out.println(plainCode);
for (int i = 0, iEnd = returnList.size(); i < iEnd; i++) {
int end = i + 2 < iEnd ? (Integer) returnList.get(i + 2) : plainCode.length();