Commits

J. Ryan Stinnett  committed 77be5bf

Added JavaScript support, currently disabled because ctags doesn't look instead JS module defs

  • Participants
  • Parent commits 22dac9f

Comments (0)

Files changed (3)

File freemarker-support

 # HG changeset patch
 # User J. Ryan Stinnett <jryans@gmail.com>
-# Date 1295246315 21600
+# Date 1295439996 21600
 # Node ID 3d24e2d206cf5d240bbe9f833d4f9ffea7cfec61
-# Parent 7c1cb073eaf72577e22d2612750eaa74eee8d3f5
+# Parent a6fe2b4139e56faa9af54859b8b9cfb54691ea2c
 Adds support for FreeMarker files
 
 diff --git a/build.xml b/build.xml
 new file mode 100644
 --- /dev/null
 +++ b/src/org/opensolaris/opengrok/analysis/freemarker/FreeMarkerXref.lex
-@@ -0,0 +1,274 @@
+@@ -0,0 +1,270 @@
 +/*
 + * CDDL HEADER START
 + *
 +%ignorecase
 +%int
 +%{
-+    /* Must match WhiteSpace regex */
-+    private final static String WHITE_SPACE = "[ \t]+";
-+
 +    private Stack<Integer> state = new Stack<Integer>();
 +
 +    private void enterState(int newState) {
 +    protected void setLineNumber(int x) { yyline = x; }
 +%}
 +
-+/* Must match WHITE_SPACE constant */
 +WhiteSpace                  = [ \t]+
 +EOL                         = \r|\n|\r\n
 +
 +
 +URIChar                     = [\?\+\%\&\:\/\.\@\_\;\=\$\,\-\!\~\*\\]
 +FNameChar                   = [a-zA-Z0-9_\-\.]
-+File                        = [a-zA-Z]{FNameChar}* "." ("java"|"properties"|"props"|"xml"|"conf"|"txt"|"htm"|"html"|"ini"|"jnlp"|"jad"|"diff"|"patch")
++File                        = {FNameChar}+ "." ([a-zA-Z]+) {FNameChar}*
 +Path                        = "/"? [a-zA-Z]{FNameChar}* ("/" [a-zA-Z]{FNameChar}*[a-zA-Z0-9])+
 +
 +Number                      = (0[xX][0-9a-fA-F]+|[0-9]+\.[0-9]+|[0-9]+)(([eE][+-]?[0-9]+)?[ufdlUFDL]*)?

File javascript-support

+# HG changeset patch
+# Parent ef20fb132409077264f4e33c90d292115365253c
+# User J. Ryan Stinnett <jryans@gmail.com>
+# Date 1295515047 21600
+
+Adds support for JavaScript files
+
+diff --git a/build.xml b/build.xml
+--- a/build.xml
++++ b/build.xml
+@@ -143,7 +143,7 @@
+     <taskdef classname="JFlex.anttask.JFlexTask" name="jflex" classpathref="lib.search.path"/>    
+     <target name="jflex" depends="init">
+         <mkdir dir="${src.generatedsrc.dir}"/>
+-	    <jflex file="${src.dir}/org/opensolaris/opengrok/analysis/plain/PlainXref.lex" destdir="${src.generatedsrc.dir}"/>
++        <jflex file="${src.dir}/org/opensolaris/opengrok/analysis/plain/PlainXref.lex" destdir="${src.generatedsrc.dir}"/>
+         <jflex file="${src.dir}/org/opensolaris/opengrok/analysis/c/CSymbolTokenizer.lex" destdir="${src.generatedsrc.dir}"/>
+         <jflex file="${src.dir}/org/opensolaris/opengrok/analysis/c/CXref.lex" destdir="${src.generatedsrc.dir}"/>
+         <jflex file="${src.dir}/org/opensolaris/opengrok/analysis/c/CxxSymbolTokenizer.lex" destdir="${src.generatedsrc.dir}"/>
+@@ -154,12 +154,14 @@
+         <jflex file="${src.dir}/org/opensolaris/opengrok/analysis/freemarker/FreeMarkerXref.lex" destdir="${src.generatedsrc.dir}"/>
+         <jflex file="${src.dir}/org/opensolaris/opengrok/analysis/java/JavaSymbolTokenizer.lex" destdir="${src.generatedsrc.dir}"/>
+         <jflex file="${src.dir}/org/opensolaris/opengrok/analysis/java/JavaXref.lex" destdir="${src.generatedsrc.dir}"/>
++        <jflex file="${src.dir}/org/opensolaris/opengrok/analysis/javascript/JavaScriptSymbolTokenizer.lex" destdir="${src.generatedsrc.dir}"/>
++        <jflex file="${src.dir}/org/opensolaris/opengrok/analysis/javascript/JavaScriptXref.lex" destdir="${src.generatedsrc.dir}"/>
+         <jflex file="${src.dir}/org/opensolaris/opengrok/analysis/python/PythonSymbolTokenizer.lex" destdir="${src.generatedsrc.dir}"/>
+         <jflex file="${src.dir}/org/opensolaris/opengrok/analysis/python/PythonXref.lex" destdir="${src.generatedsrc.dir}"/>
+         <jflex file="${src.dir}/org/opensolaris/opengrok/analysis/perl/PerlSymbolTokenizer.lex" destdir="${src.generatedsrc.dir}"/>
+         <jflex file="${src.dir}/org/opensolaris/opengrok/analysis/perl/PerlXref.lex" destdir="${src.generatedsrc.dir}"/>
+-	<jflex file="${src.dir}/org/opensolaris/opengrok/analysis/php/PhpSymbolTokenizer.lex" destdir="${src.generatedsrc.dir}"/>
+-	<jflex file="${src.dir}/org/opensolaris/opengrok/analysis/php/PhpXref.lex" destdir="${src.generatedsrc.dir}"/>
++        <jflex file="${src.dir}/org/opensolaris/opengrok/analysis/php/PhpSymbolTokenizer.lex" destdir="${src.generatedsrc.dir}"/>
++        <jflex file="${src.dir}/org/opensolaris/opengrok/analysis/php/PhpXref.lex" destdir="${src.generatedsrc.dir}"/>
+         <jflex file="${src.dir}/org/opensolaris/opengrok/analysis/lisp/LispSymbolTokenizer.lex" destdir="${src.generatedsrc.dir}"/>
+         <jflex file="${src.dir}/org/opensolaris/opengrok/analysis/lisp/LispXref.lex" destdir="${src.generatedsrc.dir}"/>
+         <jflex file="${src.dir}/org/opensolaris/opengrok/analysis/tcl/TclSymbolTokenizer.lex" destdir="${src.generatedsrc.dir}"/>
+diff --git a/src/org/opensolaris/opengrok/analysis/AnalyzerGuru.java b/src/org/opensolaris/opengrok/analysis/AnalyzerGuru.java
+--- a/src/org/opensolaris/opengrok/analysis/AnalyzerGuru.java
++++ b/src/org/opensolaris/opengrok/analysis/AnalyzerGuru.java
+@@ -42,6 +42,7 @@
+ import org.opensolaris.opengrok.analysis.fortran.FortranAnalyzerFactory;
+ import org.opensolaris.opengrok.analysis.freemarker.FreeMarkerAnalyzerFactory;
+ import org.opensolaris.opengrok.analysis.java.JavaAnalyzerFactory;
++import org.opensolaris.opengrok.analysis.javascript.JavaScriptAnalyzerFactory;
+ import org.opensolaris.opengrok.analysis.lisp.LispAnalyzerFactory;
+ import org.opensolaris.opengrok.analysis.perl.PerlAnalyzerFactory;
+ import org.opensolaris.opengrok.analysis.php.PhpAnalyzerFactory;
+@@ -139,7 +140,8 @@
+             new TclAnalyzerFactory(),
+             new SQLAnalyzerFactory(),
+             new FortranAnalyzerFactory(),
+-            new FreeMarkerAnalyzerFactory()
++            new FreeMarkerAnalyzerFactory(),
++            new JavaScriptAnalyzerFactory()
+         };
+ 
+         for (FileAnalyzerFactory analyzer : analyzers) {
+diff --git a/src/org/opensolaris/opengrok/analysis/JFlexXref.java b/src/org/opensolaris/opengrok/analysis/JFlexXref.java
+--- a/src/org/opensolaris/opengrok/analysis/JFlexXref.java
++++ b/src/org/opensolaris/opengrok/analysis/JFlexXref.java
+@@ -81,6 +81,7 @@
+         {"union",      "xu",   null},
+         {"field",      "xfld", null},
+         {"member",     "xmb",  null},
++        {"property",   "xpr",  null},
+         {"function",   "xf",   "Function"},
+         {"method",     "xmt",  "Method"},
+         {"subroutine", "xsr",  "Subroutine"},
+diff --git a/src/org/opensolaris/opengrok/analysis/java/JavaXref.lex b/src/org/opensolaris/opengrok/analysis/java/JavaXref.lex
+--- a/src/org/opensolaris/opengrok/analysis/java/JavaXref.lex
++++ b/src/org/opensolaris/opengrok/analysis/java/JavaXref.lex
+@@ -154,7 +154,7 @@
+  .      { writeUnicodeChar(yycharat(0)); }
+ }
+ 
+-<STRING, COMMENT, SCOMMENT, STRING, QSTRING, JAVADOC> {
++<STRING, COMMENT, SCOMMENT, QSTRING, JAVADOC> {
+ {Path}
+         { out.write(Util.breadcrumbPath(urlPrefix+"path=",yytext(),'/'));}
+ 
+diff --git a/src/org/opensolaris/opengrok/analysis/freemarker/Consts.java b/src/org/opensolaris/opengrok/analysis/javascript/Consts.java
+copy from src/org/opensolaris/opengrok/analysis/freemarker/Consts.java
+copy to src/org/opensolaris/opengrok/analysis/javascript/Consts.java
+--- a/src/org/opensolaris/opengrok/analysis/freemarker/Consts.java
++++ b/src/org/opensolaris/opengrok/analysis/javascript/Consts.java
+@@ -21,61 +21,75 @@
+  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+  * Use is subject to license terms.
+  */
+-package org.opensolaris.opengrok.analysis.freemarker;
++package org.opensolaris.opengrok.analysis.javascript;
+ 
+ import java.util.HashSet;
+ import java.util.Set;
+ 
+ /**
+-  * Holds static hash set containing the FreeMarker keywords
+-  */
++ * Holds static hash set containing the JavaScript keywords
++ * @see <a href="https://developer.mozilla.org/en/JavaScript/Reference/Reserved_Words">Reserved Words</a>
++ */
+ public class Consts {
+     public static final Set<String> kwd = new HashSet<String>() ;
+     static {
+-        kwd.add( "assign" );
+-        kwd.add( "attempt" );
++        kwd.add( "abstract" );
++        kwd.add( "boolean" );
+         kwd.add( "break" );
+-        kwd.add( "call" );
++        kwd.add( "byte" );
+         kwd.add( "case" );
+-        kwd.add( "comment" );
+-        kwd.add( "compress" );
++        kwd.add( "catch" );
++        kwd.add( "char" );
++        kwd.add( "class" );
++        kwd.add( "const" );
++        kwd.add( "continue" );
++        kwd.add( "debugger" );
+         kwd.add( "default" );
++        kwd.add( "delete" );
++        kwd.add( "do" );
++        kwd.add( "double" );
+         kwd.add( "else" );
+-        kwd.add( "elseif" );
+-        kwd.add( "embed" );
+-        kwd.add( "escape" );
+-        kwd.add( "fallback" );
+-        kwd.add( "flush" );
+-        kwd.add( "foreach" );
++        kwd.add( "enum" );
++        kwd.add( "export" );
++        kwd.add( "extends" );
++        kwd.add( "false" );
++        kwd.add( "final" );
++        kwd.add( "finally" );
++        kwd.add( "float" );
++        kwd.add( "for" );
+         kwd.add( "function" );
+-        kwd.add( "global" );
++        kwd.add( "goto" );
+         kwd.add( "if" );
++        kwd.add( "implements" );
+         kwd.add( "import" );
+-        kwd.add( "include" );
+-        kwd.add( "list" );
+-        kwd.add( "local" );
+-        kwd.add( "lt" );
+-        kwd.add( "lt_lines" );
+-        kwd.add( "macro" );
+-        kwd.add( "nested" );
+-        kwd.add( "noparse" );
+-        kwd.add( "param" );
+-        kwd.add( "noescape" );
+-        kwd.add( "nt" );
+-        kwd.add( "nt_lines" );
+-        kwd.add( "recover" );
+-        kwd.add( "recurse" );
++        kwd.add( "in" );
++        kwd.add( "instanceof" );
++        kwd.add( "int" );
++        kwd.add( "interface" );
++        kwd.add( "long" );
++        kwd.add( "native" );
++        kwd.add( "new" );
++        kwd.add( "package" );
++        kwd.add( "private" );
++        kwd.add( "protected" );
++        kwd.add( "public" );
+         kwd.add( "return" );
+-        kwd.add( "rt" );
+-        kwd.add( "rt_lines" );
+-        kwd.add( "set" );
+-        kwd.add( "setting" );
+-        kwd.add( "stop" );
++        kwd.add( "short" );
++        kwd.add( "static" );
++        kwd.add( "super" );
++        kwd.add( "synchronized" );
+         kwd.add( "switch" );
+-        kwd.add( "transform" );
+-        kwd.add( "t" );
+-        kwd.add( "t_lines" );
++        kwd.add( "this" );
++        kwd.add( "throw" );
++        kwd.add( "throws" );
++        kwd.add( "true" );
++        kwd.add( "transient" );
++        kwd.add( "try" );
++        kwd.add( "typeof" );
+         kwd.add( "var" );
+-        kwd.add( "visit" );
++        kwd.add( "void" );
++        kwd.add( "volatile" );
++        kwd.add( "while" );
++        kwd.add( "with" );
+     }
+ }
+diff --git a/src/org/opensolaris/opengrok/analysis/java/JavaAnalyzer.java b/src/org/opensolaris/opengrok/analysis/javascript/JavaScriptAnalyzer.java
+copy from src/org/opensolaris/opengrok/analysis/java/JavaAnalyzer.java
+copy to src/org/opensolaris/opengrok/analysis/javascript/JavaScriptAnalyzer.java
+--- a/src/org/opensolaris/opengrok/analysis/java/JavaAnalyzer.java
++++ b/src/org/opensolaris/opengrok/analysis/javascript/JavaScriptAnalyzer.java
+@@ -20,12 +20,7 @@
+ /*
+  * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+  */
+-package org.opensolaris.opengrok.analysis.java;
+-
+-import java.io.IOException;
+-import java.io.Reader;
+-import java.io.StringReader;
+-import java.io.Writer;
++package org.opensolaris.opengrok.analysis.javascript;
+ 
+ import org.apache.lucene.analysis.TokenStream;
+ import org.apache.lucene.document.Document;
+@@ -36,21 +31,26 @@
+ import org.opensolaris.opengrok.configuration.Project;
+ import org.opensolaris.opengrok.history.Annotation;
+ 
++import java.io.IOException;
++import java.io.Reader;
++import java.io.StringReader;
++import java.io.Writer;
++
+ /**
+  *
+  * @author martin
+  */
+-public class JavaAnalyzer extends PlainAnalyzer {
++public class JavaScriptAnalyzer extends PlainAnalyzer {
+ 
+-    JavaSymbolTokenizer cref;
+-    JavaXref xref;
++    JavaScriptSymbolTokenizer cref;
++    JavaScriptXref xref;
+     Reader dummy = new StringReader("");
+ 
+     /** Creates a new instance of JavaAnalyzer */
+-    protected JavaAnalyzer(FileAnalyzerFactory factory) {
++    protected JavaScriptAnalyzer(FileAnalyzerFactory factory) {
+         super(factory);
+-        cref = new JavaSymbolTokenizer(dummy);
+-        xref = new JavaXref(dummy);
++        cref = new JavaScriptSymbolTokenizer(dummy);
++        xref = new JavaScriptXref(dummy);
+     }
+ 
+     @Override
+@@ -86,7 +86,7 @@
+      * @param annotation annotation for the file (could be null)
+      */
+     static void writeXref(Reader in, Writer out, Definitions defs, Annotation annotation, Project project) throws IOException {
+-        JavaXref xref = new JavaXref(in);
++        JavaScriptXref xref = new JavaScriptXref(in);
+         xref.annotation = annotation;
+         xref.project = project;
+         xref.setDefs(defs);
+diff --git a/src/org/opensolaris/opengrok/analysis/java/JavaAnalyzerFactory.java b/src/org/opensolaris/opengrok/analysis/javascript/JavaScriptAnalyzerFactory.java
+copy from src/org/opensolaris/opengrok/analysis/java/JavaAnalyzerFactory.java
+copy to src/org/opensolaris/opengrok/analysis/javascript/JavaScriptAnalyzerFactory.java
+--- a/src/org/opensolaris/opengrok/analysis/java/JavaAnalyzerFactory.java
++++ b/src/org/opensolaris/opengrok/analysis/javascript/JavaScriptAnalyzerFactory.java
+@@ -21,11 +21,8 @@
+  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+  */
+ 
+-package org.opensolaris.opengrok.analysis.java;
++package org.opensolaris.opengrok.analysis.javascript;
+ 
+-import java.io.IOException;
+-import java.io.Reader;
+-import java.io.Writer;
+ import org.opensolaris.opengrok.analysis.Definitions;
+ import org.opensolaris.opengrok.analysis.FileAnalyzer;
+ import org.opensolaris.opengrok.analysis.FileAnalyzer.Genre;
+@@ -33,27 +30,28 @@
+ import org.opensolaris.opengrok.configuration.Project;
+ import org.opensolaris.opengrok.history.Annotation;
+ 
+-public class JavaAnalyzerFactory extends FileAnalyzerFactory {
++import java.io.IOException;
++import java.io.Reader;
++import java.io.Writer;
++
++public class JavaScriptAnalyzerFactory extends FileAnalyzerFactory {
++
+     private static final String[] SUFFIXES = {
+-        "JAVA"
++        "JS"
+     };
+ 
+-    private static final String[] MAGICS = {
+-        "/*"
+-    };
+-
+-    public JavaAnalyzerFactory() {
+-        super(null, SUFFIXES, MAGICS, null, "text/plain", Genre.PLAIN);
++    public JavaScriptAnalyzerFactory() {
++        super(null, SUFFIXES, null, null, "text/plain", Genre.PLAIN);
+     }
+ 
+     @Override
+     protected FileAnalyzer newAnalyzer() {
+-        return new JavaAnalyzer(this);
++        return new JavaScriptAnalyzer(this);
+     }
+ 
+     @Override
+     public void writeXref(Reader in, Writer out, Definitions defs, Annotation annotation, Project project)
+         throws IOException {
+-        JavaAnalyzer.writeXref(in, out, defs, annotation, project);
++        JavaScriptAnalyzer.writeXref(in, out, defs, annotation, project);
+     }
+ }
+diff --git a/src/org/opensolaris/opengrok/analysis/java/JavaSymbolTokenizer.lex b/src/org/opensolaris/opengrok/analysis/javascript/JavaScriptSymbolTokenizer.lex
+copy from src/org/opensolaris/opengrok/analysis/java/JavaSymbolTokenizer.lex
+copy to src/org/opensolaris/opengrok/analysis/javascript/JavaScriptSymbolTokenizer.lex
+--- a/src/org/opensolaris/opengrok/analysis/java/JavaSymbolTokenizer.lex
++++ b/src/org/opensolaris/opengrok/analysis/javascript/JavaScriptSymbolTokenizer.lex
+@@ -21,18 +21,18 @@
+  * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+  */
+ 
+-/*
+- * Gets Java symbols - ignores comments, strings, keywords
++/**
++ * Gets JavaScript symbols - ignores comments, strings, keywords
+  */
+ 
+-package org.opensolaris.opengrok.analysis.java;
++package org.opensolaris.opengrok.analysis.javascript;
+ import java.io.IOException;
+ import java.io.Reader;
+ import org.opensolaris.opengrok.analysis.JFlexTokenizer;
+ 
+ %%
+ %public
+-%class JavaSymbolTokenizer
++%class JavaScriptSymbolTokenizer
+ %extends JFlexTokenizer
+ %unicode
+ %type boolean
+@@ -48,35 +48,55 @@
+ %%
+ 
+ <YYINITIAL> {
+-{Identifier} {String id = yytext();
+-                if(!Consts.kwd.contains(id)){
+-                        setAttribs(id, yychar, yychar + yylength());
+-                        return true; }
+-              }
+- \"     { yybegin(STRING); }
+- \'     { yybegin(QSTRING); }
+- "/*"   { yybegin(COMMENT); }
+- "//"   { yybegin(SCOMMENT); }
++    {Identifier} {
++        String id = yytext();
++        if(!Consts.kwd.contains(id)) {
++            setAttribs(id, yychar, yychar + yylength());
++            return true;
++        }
++    }
++    \" {
++        yybegin(STRING);
++    }
++    \' {
++        yybegin(QSTRING);
++    }
++    "/*" {
++        yybegin(COMMENT);
++    }
++    "//" {
++        yybegin(SCOMMENT);
++    }
+ }
+ 
+ <STRING> {
+- \"     { yybegin(YYINITIAL); }
+-\\\\ | \\\"     {}
++    \" {
++        yybegin(YYINITIAL);
++    }
++    \\\\ | \\\" {}
+ }
+ 
+ <QSTRING> {
+- \'     { yybegin(YYINITIAL); }
++    \' {
++        yybegin(YYINITIAL);
++    }
+ }
+ 
+ <COMMENT> {
+-"*/"    { yybegin(YYINITIAL);}
++    "*/" {
++        yybegin(YYINITIAL);
++    }
+ }
+ 
+ <SCOMMENT> {
+-\n      { yybegin(YYINITIAL);}
++    \n { 
++        yybegin(YYINITIAL);
++    }
+ }
+ 
+ <YYINITIAL, STRING, COMMENT, SCOMMENT, QSTRING> {
+-<<EOF>>   { return false;}
+-.|\n    {}
++    <<EOF>> {
++        return false;
++    }
++    .|\n {}
+ }
+diff --git a/src/org/opensolaris/opengrok/analysis/java/JavaXref.lex b/src/org/opensolaris/opengrok/analysis/javascript/JavaScriptXref.lex
+copy from src/org/opensolaris/opengrok/analysis/java/JavaXref.lex
+copy to src/org/opensolaris/opengrok/analysis/javascript/JavaScriptXref.lex
+--- a/src/org/opensolaris/opengrok/analysis/java/JavaXref.lex
++++ b/src/org/opensolaris/opengrok/analysis/javascript/JavaScriptXref.lex
+@@ -21,11 +21,12 @@
+  * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+  */
+ 
+-/*
+- * Cross reference a Java file
++/**
++ * Cross reference a JavaScript file
++ * @author J. Ryan Stinnett
+  */
+ 
+-package org.opensolaris.opengrok.analysis.java;
++package org.opensolaris.opengrok.analysis.javascript;
+ import org.opensolaris.opengrok.analysis.JFlexXref;
+ import java.io.IOException;
+ import java.io.Writer;
+@@ -34,149 +35,169 @@
+ 
+ %%
+ %public
+-%class JavaXref
++%class JavaScriptXref
+ %extends JFlexXref
+ %unicode
+ %ignorecase
+ %int
+ %{
+-  /* Must match WhiteSpace regex */
+-  private final static String WHITE_SPACE = "[ \t\f\r]+";
+-
+-  // TODO move this into an include file when bug #16053 is fixed
+-  @Override
+-  protected int getLineNumber() { return yyline; }
+-  @Override
+-  protected void setLineNumber(int x) { yyline = x; }
++    // TODO move this into an include file when bug #16053 is fixed
++    @Override
++    protected int getLineNumber() { return yyline; }
++    @Override
++    protected void setLineNumber(int x) { yyline = x; }
+ %}
+ 
+-/* Must match WHITE_SPACE constant */
+-WhiteSpace     = [ \t\f]+
+-EOL = \r|\n|\r\n
+-Identifier = [a-zA-Z_] [a-zA-Z0-9_]+
++WhiteSpace                  = [ \t]+
++EOL                         = \r|\n|\r\n
++Identifier                  = [a-zA-Z_] [a-zA-Z0-9_]+
+ 
+-URIChar = [\?\+\%\&\:\/\.\@\_\;\=\$\,\-\!\~\*\\]
+-FNameChar = [a-zA-Z0-9_\-\.]
+-File = [a-zA-Z]{FNameChar}* "." ("java"|"properties"|"props"|"xml"|"conf"|"txt"|"htm"|"html"|"ini"|"jnlp"|"jad"|"diff"|"patch")
+-Path = "/"? [a-zA-Z]{FNameChar}* ("/" [a-zA-Z]{FNameChar}*[a-zA-Z0-9])+
++URIChar                     = [\?\+\%\&\:\/\.\@\_\;\=\$\,\-\!\~\*\\]
++FNameChar                   = [a-zA-Z0-9_\-\.]
++File                        = {FNameChar}+ "." ([a-zA-Z]+) {FNameChar}*
++Path                        = "/"? [a-zA-Z]{FNameChar}* ("/" [a-zA-Z]{FNameChar}*[a-zA-Z0-9])+
+ 
+-Number = (0[xX][0-9a-fA-F]+|[0-9]+\.[0-9]+|[0-9]+)(([eE][+-]?[0-9]+)?[ufdlUFDL]*)?
++Number                      = (0[xX][0-9a-fA-F]+|[0-9]+\.[0-9]+|[0-9]+)(([eE][+-]?[0-9]+)?)?
+ 
+-JavadocWithClassArg = "@throws" | "@exception"
+-JavadocWithParamNameArg = "@param"
++/* ClassName                = ({Identifier} ".")* {Identifier}
++ParamName                   = {Identifier} | "<" {Identifier} ">" */
+ 
+-ClassName = ({Identifier} ".")* {Identifier}
+-ParamName = {Identifier} | "<" {Identifier} ">"
+-
+-%state  STRING COMMENT SCOMMENT QSTRING JAVADOC
++%state STRING COMMENT SCOMMENT QSTRING
+ 
+ %%
++
+ <YYINITIAL>{
+-
+-{Identifier} {
+-    String id = yytext();
+-    writeSymbol(id, Consts.kwd, yyline);
+-}
+-
+-"<" ({File}|{Path}) ">" {
++    {Identifier} {
++        String id = yytext();
++        writeSymbol(id, Consts.kwd, yyline);
++    }
++    "<" ({File}|{Path}) ">" {
+         out.write("&lt;");
+         String path = yytext();
+         path = path.substring(1, path.length() - 1);
+-        out.write("<a href=\""+urlPrefix+"path=");
++        out.write("<a href=\"" + urlPrefix + "path=");
+         out.write(path);
+         appendProject();
+         out.write("\">");
+         out.write(path);
+         out.write("</a>");
+         out.write("&gt;");
+-}
+-
+-/*{Hier}
+-        { out.write(Util.breadcrumbPath(urlPrefix+"defs=",yytext(),'.'));}
+-*/
+-{Number}        { out.write("<span class=\"n\">"); out.write(yytext()); out.write("</span>"); }
+-
+- \"     { yybegin(STRING);out.write("<span class=\"s\">\"");}
+- \'     { yybegin(QSTRING);out.write("<span class=\"s\">\'");}
+- "/**"  { yybegin(JAVADOC);out.write("<span class=\"c\">/**");}
+- "/*"   { yybegin(COMMENT);out.write("<span class=\"c\">/*");}
+- "//"   { yybegin(SCOMMENT);out.write("<span class=\"c\">//");}
++    }
++    {Number} {
++        out.write("<span class=\"n\">");
++        out.write(yytext());
++        out.write("</span>");
++    }
++    \" {
++        yybegin(STRING);
++        out.write("<span class=\"s\">\"");
++    }
++    \' {
++        yybegin(QSTRING);
++        out.write("<span class=\"s\">\'");
++    }
++    "/*" {
++        yybegin(COMMENT);
++        out.write("<span class=\"c\">/*");
++    }
++    "//" {
++        yybegin(SCOMMENT);
++        out.write("<span class=\"c\">//");
++    }
+ }
+ 
+ <STRING> {
+- \" {WhiteSpace} \"  { out.write(yytext());}
+- \"     { yybegin(YYINITIAL); out.write("\"</span>"); }
+- \\\\   { out.write("\\\\"); }
+- \\\"   { out.write("\\\""); }
++    \" {WhiteSpace} \" {
++        out.write(yytext());
++    }
++    \" {
++        yybegin(YYINITIAL);
++        out.write("\"</span>");
++    }
++    \\\\ {
++        out.write("\\\\");
++    }
++    \\\" {
++        out.write("\\\"");
++    }
+ }
+ 
+ <QSTRING> {
+- "\\\\" { out.write("\\\\"); }
+- "\\\'" { out.write("\\\'"); }
+- \' {WhiteSpace} \' { out.write(yytext()); }
+- \'     { yybegin(YYINITIAL); out.write("'</span>"); }
++    "\\\\" {
++        out.write("\\\\");
++    }
++    "\\\'" {
++        out.write("\\\'");
++    }
++    \' {WhiteSpace} \' {
++        out.write(yytext());
++    }
++    \' {
++        yybegin(YYINITIAL);
++        out.write("'</span>");
++    }
+ }
+ 
+-<COMMENT, JAVADOC> {
+-"*/"    { yybegin(YYINITIAL); out.write("*/</span>"); }
+-}
+-
+-<JAVADOC> {
+-  {JavadocWithParamNameArg} {WhiteSpace} {ParamName} |
+-  {JavadocWithClassArg} {WhiteSpace} {ClassName} {
+-    String text = yytext();
+-    String[] tokens = text.split(WHITE_SPACE, 2);
+-    out.append("<strong>").append(tokens[0]).append("</strong>")
+-      .append(text.substring(tokens[0].length(),
+-                             text.length() - tokens[1].length()))
+-      .append("<em>").append(tokens[1]).append("</em>");
+-  }
+-  "@" {Identifier} {
+-    out.append("<strong>").append(yytext()).append("</strong>");
+-  }
++<COMMENT> {
++    "*/" {
++        yybegin(YYINITIAL);
++        out.write("*/</span>");
++    }
+ }
+ 
+ <SCOMMENT> {
+-  {WhiteSpace}*{EOL} {
+-    yybegin(YYINITIAL); out.write("</span>");
+-    startNewLine();
+-  }
++    {WhiteSpace}*{EOL} {
++        yybegin(YYINITIAL);
++        out.write("</span>");
++        startNewLine();
++    }
+ }
+ 
+ 
+-<YYINITIAL, STRING, COMMENT, SCOMMENT, QSTRING, JAVADOC> {
+-"&"     {out.write( "&amp;");}
+-"<"     {out.write( "&lt;");}
+-">"     {out.write( "&gt;");}
+-{WhiteSpace}*{EOL}      { startNewLine(); }
+- {WhiteSpace}   { out.write(yytext()); }
+- [!-~]  { out.write(yycharat(0)); }
+- .      { writeUnicodeChar(yycharat(0)); }
++<YYINITIAL, STRING, COMMENT, SCOMMENT, QSTRING> {
++    "&" {
++        out.write("&amp;");
++    }
++    "<" {
++        out.write("&lt;");
++    }
++    ">" {
++        out.write("&gt;");
++    }
++    {WhiteSpace}*{EOL} {
++        startNewLine();
++    }
++    {WhiteSpace} {
++        out.write(yytext());
++    }
++    [!-~] {
++        out.write(yycharat(0));
++    }
++    . {
++        writeUnicodeChar(yycharat(0));
++    }
+ }
+ 
+-<STRING, COMMENT, SCOMMENT, STRING, QSTRING, JAVADOC> {
+-{Path}
+-        { out.write(Util.breadcrumbPath(urlPrefix+"path=",yytext(),'/'));}
+-
+-{File}
+-        {
++<STRING, COMMENT, SCOMMENT, QSTRING> {
++    {Path} {
++        out.write(Util.breadcrumbPath(urlPrefix + "path=", yytext(), '/'));
++    }
++    {File} {
+         String path = yytext();
+-        out.write("<a href=\""+urlPrefix+"path=");
++        out.write("<a href=\"" + urlPrefix + "path=");
+         out.write(path);
+         appendProject();
+         out.write("\">");
+         out.write(path);
+-        out.write("</a>");}
+-
+-("http" | "https" | "ftp" ) "://" ({FNameChar}|{URIChar})+[a-zA-Z0-9/]
+-        {
+-         String url = yytext();
+-         out.write("<a href=\"");
+-         out.write(url);out.write("\">");
+-         out.write(url);out.write("</a>");}
+-
+-{FNameChar}+ "@" {FNameChar}+ "." {FNameChar}+
+-        {
+-          writeEMailAddress(yytext());
+-        }
+-}
++        out.write("</a>");
++    }
++    ("http" | "https" | "ftp" ) "://" ({FNameChar}|{URIChar})+[a-zA-Z0-9/] {
++        String url = yytext();
++        out.write("<a href=\"");
++        out.write(url);out.write("\">");
++        out.write(url);out.write("</a>");
++    }
++    {FNameChar}+ "@" {FNameChar}+ "." {FNameChar}+ {
++        writeEMailAddress(yytext());
++    }
++}
+\ No newline at end of file
+diff --git a/web/default/style.css b/web/default/style.css
+--- a/web/default/style.css
++++ b/web/default/style.css
+@@ -175,6 +175,7 @@
+ 
+ a.xfld {color:#090; font-weight:bold; text-decoration:none;} /* field */
+ a.xmb {color:#090; font-weight:bold; text-decoration:none;} /* member */
++a.xpr {color:#090; font-weight:bold; text-decoration:none;} /* property */
+ 
+ a.xf {color:#00f; font-weight:bold; text-decoration:none;} /* function */
+ a.xmt {color:#00f; font-weight:bold; text-decoration:none;} /* method */
 escape-markup
 freemarker-support
 enhanced-xml-support
+javascript-support #+testing
 tabular-xref
 xref-line-highlight
 check-js-symbol-list