porting in progress
diff --git a/nbproject/build-impl.xml b/nbproject/build-impl.xml
new file mode 100644
index 0000000..e30d0ee
--- /dev/null
+++ b/nbproject/build-impl.xml
@@ -0,0 +1,1042 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT ***
+*** EDIT ../build.xml INSTEAD ***
+
+For the purpose of easier reading the script
+is divided into following sections:
+
+ - initialization
+ - compilation
+ - jar
+ - execution
+ - debugging
+ - javadoc
+ - junit compilation
+ - junit execution
+ - junit debugging
+ - applet
+ - cleanup
+
+ -->
+<project xmlns:j2seproject1="http://www.netbeans.org/ns/j2se-project/1" xmlns:j2seproject3="http://www.netbeans.org/ns/j2se-project/3" xmlns:jaxrpc="http://www.netbeans.org/ns/j2se-project/jax-rpc" basedir=".." default="default" name="Prettify-impl">
+ <fail message="Please build using Ant 1.7.1 or higher.">
+ <condition>
+ <not>
+ <antversion atleast="1.7.1"/>
+ </not>
+ </condition>
+ </fail>
+ <target depends="test,jar,javadoc" description="Build and test whole project." name="default"/>
+ <!--
+ ======================
+ INITIALIZATION SECTION
+ ======================
+ -->
+ <target name="-pre-init">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target depends="-pre-init" name="-init-private">
+ <property file="nbproject/private/config.properties"/>
+ <property file="nbproject/private/configs/${config}.properties"/>
+ <property file="nbproject/private/private.properties"/>
+ </target>
+ <target depends="-pre-init,-init-private" name="-init-user">
+ <property file="${user.properties.file}"/>
+ <!-- The two properties below are usually overridden -->
+ <!-- by the active platform. Just a fallback. -->
+ <property name="default.javac.source" value="1.4"/>
+ <property name="default.javac.target" value="1.4"/>
+ </target>
+ <target depends="-pre-init,-init-private,-init-user" name="-init-project">
+ <property file="nbproject/configs/${config}.properties"/>
+ <property file="nbproject/project.properties"/>
+ </target>
+ <target depends="-pre-init,-init-private,-init-user,-init-project,-init-macrodef-property" name="-do-init">
+ <available file="${manifest.file}" property="manifest.available"/>
+ <condition property="splashscreen.available">
+ <and>
+ <not>
+ <equals arg1="${application.splash}" arg2="" trim="true"/>
+ </not>
+ <available file="${application.splash}"/>
+ </and>
+ </condition>
+ <condition property="main.class.available">
+ <and>
+ <isset property="main.class"/>
+ <not>
+ <equals arg1="${main.class}" arg2="" trim="true"/>
+ </not>
+ </and>
+ </condition>
+ <condition property="manifest.available+main.class">
+ <and>
+ <isset property="manifest.available"/>
+ <isset property="main.class.available"/>
+ </and>
+ </condition>
+ <condition property="do.archive">
+ <not>
+ <istrue value="${jar.archive.disabled}"/>
+ </not>
+ </condition>
+ <condition property="do.mkdist">
+ <and>
+ <isset property="do.archive"/>
+ <isset property="libs.CopyLibs.classpath"/>
+ <not>
+ <istrue value="${mkdist.disabled}"/>
+ </not>
+ </and>
+ </condition>
+ <condition property="manifest.available+main.class+mkdist.available">
+ <and>
+ <istrue value="${manifest.available+main.class}"/>
+ <isset property="do.mkdist"/>
+ </and>
+ </condition>
+ <condition property="do.archive+manifest.available">
+ <and>
+ <isset property="manifest.available"/>
+ <istrue value="${do.archive}"/>
+ </and>
+ </condition>
+ <condition property="do.archive+main.class.available">
+ <and>
+ <isset property="main.class.available"/>
+ <istrue value="${do.archive}"/>
+ </and>
+ </condition>
+ <condition property="do.archive+splashscreen.available">
+ <and>
+ <isset property="splashscreen.available"/>
+ <istrue value="${do.archive}"/>
+ </and>
+ </condition>
+ <condition property="do.archive+manifest.available+main.class">
+ <and>
+ <istrue value="${manifest.available+main.class}"/>
+ <istrue value="${do.archive}"/>
+ </and>
+ </condition>
+ <condition property="manifest.available-mkdist.available">
+ <or>
+ <istrue value="${manifest.available}"/>
+ <isset property="do.mkdist"/>
+ </or>
+ </condition>
+ <condition property="manifest.available+main.class-mkdist.available">
+ <or>
+ <istrue value="${manifest.available+main.class}"/>
+ <isset property="do.mkdist"/>
+ </or>
+ </condition>
+ <condition property="have.tests">
+ <or>
+ <available file="${test.src.dir}"/>
+ </or>
+ </condition>
+ <condition property="have.sources">
+ <or>
+ <available file="${src.dir}"/>
+ </or>
+ </condition>
+ <condition property="netbeans.home+have.tests">
+ <and>
+ <isset property="netbeans.home"/>
+ <isset property="have.tests"/>
+ </and>
+ </condition>
+ <condition property="no.javadoc.preview">
+ <and>
+ <isset property="javadoc.preview"/>
+ <isfalse value="${javadoc.preview}"/>
+ </and>
+ </condition>
+ <property name="run.jvmargs" value=""/>
+ <property name="javac.compilerargs" value=""/>
+ <property name="work.dir" value="${basedir}"/>
+ <condition property="no.deps">
+ <and>
+ <istrue value="${no.dependencies}"/>
+ </and>
+ </condition>
+ <property name="javac.debug" value="true"/>
+ <property name="javadoc.preview" value="true"/>
+ <property name="application.args" value=""/>
+ <property name="source.encoding" value="${file.encoding}"/>
+ <property name="runtime.encoding" value="${source.encoding}"/>
+ <condition property="javadoc.encoding.used" value="${javadoc.encoding}">
+ <and>
+ <isset property="javadoc.encoding"/>
+ <not>
+ <equals arg1="${javadoc.encoding}" arg2=""/>
+ </not>
+ </and>
+ </condition>
+ <property name="javadoc.encoding.used" value="${source.encoding}"/>
+ <property name="includes" value="**"/>
+ <property name="excludes" value=""/>
+ <property name="do.depend" value="false"/>
+ <condition property="do.depend.true">
+ <istrue value="${do.depend}"/>
+ </condition>
+ <path id="endorsed.classpath.path" path="${endorsed.classpath}"/>
+ <condition else="" property="endorsed.classpath.cmd.line.arg" value="-Xbootclasspath/p:'${toString:endorsed.classpath.path}'">
+ <length length="0" string="${endorsed.classpath}" when="greater"/>
+ </condition>
+ <condition else="false" property="jdkBug6558476">
+ <and>
+ <matches pattern="1\.[56]" string="${java.specification.version}"/>
+ <not>
+ <os family="unix"/>
+ </not>
+ </and>
+ </condition>
+ <property name="javac.fork" value="${jdkBug6558476}"/>
+ <property name="jar.index" value="false"/>
+ <property name="jar.index.metainf" value="${jar.index}"/>
+ <available file="${meta.inf.dir}/persistence.xml" property="has.persistence.xml"/>
+ </target>
+ <target name="-post-init">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target depends="-pre-init,-init-private,-init-user,-init-project,-do-init" name="-init-check">
+ <fail unless="src.dir">Must set src.dir</fail>
+ <fail unless="test.src.dir">Must set test.src.dir</fail>
+ <fail unless="build.dir">Must set build.dir</fail>
+ <fail unless="dist.dir">Must set dist.dir</fail>
+ <fail unless="build.classes.dir">Must set build.classes.dir</fail>
+ <fail unless="dist.javadoc.dir">Must set dist.javadoc.dir</fail>
+ <fail unless="build.test.classes.dir">Must set build.test.classes.dir</fail>
+ <fail unless="build.test.results.dir">Must set build.test.results.dir</fail>
+ <fail unless="build.classes.excludes">Must set build.classes.excludes</fail>
+ <fail unless="dist.jar">Must set dist.jar</fail>
+ </target>
+ <target name="-init-macrodef-property">
+ <macrodef name="property" uri="http://www.netbeans.org/ns/j2se-project/1">
+ <attribute name="name"/>
+ <attribute name="value"/>
+ <sequential>
+ <property name="@{name}" value="${@{value}}"/>
+ </sequential>
+ </macrodef>
+ </target>
+ <target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-macrodef-javac-with-processors">
+ <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
+ <attribute default="${src.dir}" name="srcdir"/>
+ <attribute default="${build.classes.dir}" name="destdir"/>
+ <attribute default="${javac.classpath}" name="classpath"/>
+ <attribute default="${javac.processorpath}" name="processorpath"/>
+ <attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/>
+ <attribute default="${includes}" name="includes"/>
+ <attribute default="${excludes}" name="excludes"/>
+ <attribute default="${javac.debug}" name="debug"/>
+ <attribute default="${empty.dir}" name="sourcepath"/>
+ <attribute default="${empty.dir}" name="gensrcdir"/>
+ <element name="customize" optional="true"/>
+ <sequential>
+ <property location="${build.dir}/empty" name="empty.dir"/>
+ <mkdir dir="${empty.dir}"/>
+ <mkdir dir="@{apgeneratedsrcdir}"/>
+ <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" fork="${javac.fork}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}">
+ <src>
+ <dirset dir="@{gensrcdir}" erroronmissingdir="false">
+ <include name="*"/>
+ </dirset>
+ </src>
+ <classpath>
+ <path path="@{classpath}"/>
+ </classpath>
+ <compilerarg line="${endorsed.classpath.cmd.line.arg}"/>
+ <compilerarg line="${javac.compilerargs}"/>
+ <compilerarg value="-processorpath"/>
+ <compilerarg path="@{processorpath}:${empty.dir}"/>
+ <compilerarg line="${ap.processors.internal}"/>
+ <compilerarg line="${annotation.processing.processor.options}"/>
+ <compilerarg value="-s"/>
+ <compilerarg path="@{apgeneratedsrcdir}"/>
+ <compilerarg line="${ap.proc.none.internal}"/>
+ <customize/>
+ </javac>
+ </sequential>
+ </macrodef>
+ </target>
+ <target depends="-init-ap-cmdline-properties" name="-init-macrodef-javac-without-processors" unless="ap.supported.internal">
+ <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
+ <attribute default="${src.dir}" name="srcdir"/>
+ <attribute default="${build.classes.dir}" name="destdir"/>
+ <attribute default="${javac.classpath}" name="classpath"/>
+ <attribute default="${javac.processorpath}" name="processorpath"/>
+ <attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/>
+ <attribute default="${includes}" name="includes"/>
+ <attribute default="${excludes}" name="excludes"/>
+ <attribute default="${javac.debug}" name="debug"/>
+ <attribute default="${empty.dir}" name="sourcepath"/>
+ <attribute default="${empty.dir}" name="gensrcdir"/>
+ <element name="customize" optional="true"/>
+ <sequential>
+ <property location="${build.dir}/empty" name="empty.dir"/>
+ <mkdir dir="${empty.dir}"/>
+ <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" fork="${javac.fork}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}">
+ <src>
+ <dirset dir="@{gensrcdir}" erroronmissingdir="false">
+ <include name="*"/>
+ </dirset>
+ </src>
+ <classpath>
+ <path path="@{classpath}"/>
+ </classpath>
+ <compilerarg line="${endorsed.classpath.cmd.line.arg}"/>
+ <compilerarg line="${javac.compilerargs}"/>
+ <customize/>
+ </javac>
+ </sequential>
+ </macrodef>
+ </target>
+ <target depends="-init-macrodef-javac-with-processors,-init-macrodef-javac-without-processors" name="-init-macrodef-javac">
+ <macrodef name="depend" uri="http://www.netbeans.org/ns/j2se-project/3">
+ <attribute default="${src.dir}" name="srcdir"/>
+ <attribute default="${build.classes.dir}" name="destdir"/>
+ <attribute default="${javac.classpath}" name="classpath"/>
+ <sequential>
+ <depend cache="${build.dir}/depcache" destdir="@{destdir}" excludes="${excludes}" includes="${includes}" srcdir="@{srcdir}">
+ <classpath>
+ <path path="@{classpath}"/>
+ </classpath>
+ </depend>
+ </sequential>
+ </macrodef>
+ <macrodef name="force-recompile" uri="http://www.netbeans.org/ns/j2se-project/3">
+ <attribute default="${build.classes.dir}" name="destdir"/>
+ <sequential>
+ <fail unless="javac.includes">Must set javac.includes</fail>
+ <pathconvert pathsep="${line.separator}" property="javac.includes.binary">
+ <path>
+ <filelist dir="@{destdir}" files="${javac.includes}"/>
+ </path>
+ <globmapper from="*.java" to="*.class"/>
+ </pathconvert>
+ <tempfile deleteonexit="true" property="javac.includesfile.binary"/>
+ <echo file="${javac.includesfile.binary}" message="${javac.includes.binary}"/>
+ <delete>
+ <files includesfile="${javac.includesfile.binary}"/>
+ </delete>
+ <delete>
+ <fileset file="${javac.includesfile.binary}"/>
+ </delete>
+ </sequential>
+ </macrodef>
+ </target>
+ <target name="-init-macrodef-junit">
+ <macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">
+ <attribute default="${includes}" name="includes"/>
+ <attribute default="${excludes}" name="excludes"/>
+ <attribute default="**" name="testincludes"/>
+ <sequential>
+ <property name="junit.forkmode" value="perTest"/>
+ <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">
+ <batchtest todir="${build.test.results.dir}">
+ <fileset dir="${test.src.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
+ <filename name="@{testincludes}"/>
+ </fileset>
+ </batchtest>
+ <classpath>
+ <path path="${run.test.classpath}"/>
+ </classpath>
+ <syspropertyset>
+ <propertyref prefix="test-sys-prop."/>
+ <mapper from="test-sys-prop.*" to="*" type="glob"/>
+ </syspropertyset>
+ <formatter type="brief" usefile="false"/>
+ <formatter type="xml"/>
+ <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+ <jvmarg value="-ea"/>
+ <jvmarg line="${run.jvmargs}"/>
+ </junit>
+ </sequential>
+ </macrodef>
+ </target>
+ <target depends="-profile-pre-init, init, -profile-post-init, -profile-init-macrodef-profile, -profile-init-check" name="profile-init"/>
+ <target name="-profile-pre-init">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target name="-profile-post-init">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target name="-profile-init-macrodef-profile">
+ <macrodef name="resolve">
+ <attribute name="name"/>
+ <attribute name="value"/>
+ <sequential>
+ <property name="@{name}" value="${env.@{value}}"/>
+ </sequential>
+ </macrodef>
+ <macrodef name="profile">
+ <attribute default="${main.class}" name="classname"/>
+ <element name="customize" optional="true"/>
+ <sequential>
+ <property environment="env"/>
+ <resolve name="profiler.current.path" value="${profiler.info.pathvar}"/>
+ <java classname="@{classname}" dir="${profiler.info.dir}" fork="true" jvm="${profiler.info.jvm}">
+ <jvmarg value="${profiler.info.jvmargs.agent}"/>
+ <jvmarg line="${profiler.info.jvmargs}"/>
+ <env key="${profiler.info.pathvar}" path="${profiler.info.agentpath}:${profiler.current.path}"/>
+ <arg line="${application.args}"/>
+ <classpath>
+ <path path="${run.classpath}"/>
+ </classpath>
+ <syspropertyset>
+ <propertyref prefix="run-sys-prop."/>
+ <mapper from="run-sys-prop.*" to="*" type="glob"/>
+ </syspropertyset>
+ <customize/>
+ </java>
+ </sequential>
+ </macrodef>
+ </target>
+ <target depends="-profile-pre-init, init, -profile-post-init, -profile-init-macrodef-profile" name="-profile-init-check">
+ <fail unless="profiler.info.jvm">Must set JVM to use for profiling in profiler.info.jvm</fail>
+ <fail unless="profiler.info.jvmargs.agent">Must set profiler agent JVM arguments in profiler.info.jvmargs.agent</fail>
+ </target>
+ <target depends="-init-debug-args" name="-init-macrodef-nbjpda">
+ <macrodef name="nbjpdastart" uri="http://www.netbeans.org/ns/j2se-project/1">
+ <attribute default="${main.class}" name="name"/>
+ <attribute default="${debug.classpath}" name="classpath"/>
+ <attribute default="" name="stopclassname"/>
+ <sequential>
+ <nbjpdastart addressproperty="jpda.address" name="@{name}" stopclassname="@{stopclassname}" transport="${debug-transport}">
+ <classpath>
+ <path path="@{classpath}"/>
+ </classpath>
+ </nbjpdastart>
+ </sequential>
+ </macrodef>
+ <macrodef name="nbjpdareload" uri="http://www.netbeans.org/ns/j2se-project/1">
+ <attribute default="${build.classes.dir}" name="dir"/>
+ <sequential>
+ <nbjpdareload>
+ <fileset dir="@{dir}" includes="${fix.classes}">
+ <include name="${fix.includes}*.class"/>
+ </fileset>
+ </nbjpdareload>
+ </sequential>
+ </macrodef>
+ </target>
+ <target name="-init-debug-args">
+ <property name="version-output" value="java version "${ant.java.version}"/>
+ <condition property="have-jdk-older-than-1.4">
+ <or>
+ <contains string="${version-output}" substring="java version "1.0"/>
+ <contains string="${version-output}" substring="java version "1.1"/>
+ <contains string="${version-output}" substring="java version "1.2"/>
+ <contains string="${version-output}" substring="java version "1.3"/>
+ </or>
+ </condition>
+ <condition else="-Xdebug" property="debug-args-line" value="-Xdebug -Xnoagent -Djava.compiler=none">
+ <istrue value="${have-jdk-older-than-1.4}"/>
+ </condition>
+ <condition else="dt_socket" property="debug-transport-by-os" value="dt_shmem">
+ <os family="windows"/>
+ </condition>
+ <condition else="${debug-transport-by-os}" property="debug-transport" value="${debug.transport}">
+ <isset property="debug.transport"/>
+ </condition>
+ </target>
+ <target depends="-init-debug-args" name="-init-macrodef-debug">
+ <macrodef name="debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+ <attribute default="${main.class}" name="classname"/>
+ <attribute default="${debug.classpath}" name="classpath"/>
+ <element name="customize" optional="true"/>
+ <sequential>
+ <java classname="@{classname}" dir="${work.dir}" fork="true">
+ <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+ <jvmarg line="${debug-args-line}"/>
+ <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
+ <jvmarg value="-Dfile.encoding=${runtime.encoding}"/>
+ <redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/>
+ <jvmarg line="${run.jvmargs}"/>
+ <classpath>
+ <path path="@{classpath}"/>
+ </classpath>
+ <syspropertyset>
+ <propertyref prefix="run-sys-prop."/>
+ <mapper from="run-sys-prop.*" to="*" type="glob"/>
+ </syspropertyset>
+ <customize/>
+ </java>
+ </sequential>
+ </macrodef>
+ </target>
+ <target name="-init-macrodef-java">
+ <macrodef name="java" uri="http://www.netbeans.org/ns/j2se-project/1">
+ <attribute default="${main.class}" name="classname"/>
+ <attribute default="${run.classpath}" name="classpath"/>
+ <element name="customize" optional="true"/>
+ <sequential>
+ <java classname="@{classname}" dir="${work.dir}" fork="true">
+ <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+ <jvmarg value="-Dfile.encoding=${runtime.encoding}"/>
+ <redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/>
+ <jvmarg line="${run.jvmargs}"/>
+ <classpath>
+ <path path="@{classpath}"/>
+ </classpath>
+ <syspropertyset>
+ <propertyref prefix="run-sys-prop."/>
+ <mapper from="run-sys-prop.*" to="*" type="glob"/>
+ </syspropertyset>
+ <customize/>
+ </java>
+ </sequential>
+ </macrodef>
+ </target>
+ <target name="-init-macrodef-copylibs">
+ <macrodef name="copylibs" uri="http://www.netbeans.org/ns/j2se-project/3">
+ <attribute default="${manifest.file}" name="manifest"/>
+ <element name="customize" optional="true"/>
+ <sequential>
+ <property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
+ <pathconvert property="run.classpath.without.build.classes.dir">
+ <path path="${run.classpath}"/>
+ <map from="${build.classes.dir.resolved}" to=""/>
+ </pathconvert>
+ <pathconvert pathsep=" " property="jar.classpath">
+ <path path="${run.classpath.without.build.classes.dir}"/>
+ <chainedmapper>
+ <flattenmapper/>
+ <globmapper from="*" to="lib/*"/>
+ </chainedmapper>
+ </pathconvert>
+ <taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/>
+ <copylibs compress="${jar.compress}" index="${jar.index}" indexMetaInf="${jar.index.metainf}" jarfile="${dist.jar}" manifest="@{manifest}" runtimeclasspath="${run.classpath.without.build.classes.dir}">
+ <fileset dir="${build.classes.dir}"/>
+ <manifest>
+ <attribute name="Class-Path" value="${jar.classpath}"/>
+ <customize/>
+ </manifest>
+ </copylibs>
+ </sequential>
+ </macrodef>
+ </target>
+ <target name="-init-presetdef-jar">
+ <presetdef name="jar" uri="http://www.netbeans.org/ns/j2se-project/1">
+ <jar compress="${jar.compress}" index="${jar.index}" jarfile="${dist.jar}">
+ <j2seproject1:fileset dir="${build.classes.dir}"/>
+ </jar>
+ </presetdef>
+ </target>
+ <target name="-init-ap-cmdline-properties">
+ <property name="annotation.processing.enabled" value="true"/>
+ <property name="annotation.processing.processors.list" value=""/>
+ <property name="annotation.processing.processor.options" value=""/>
+ <property name="annotation.processing.run.all.processors" value="true"/>
+ <property name="javac.processorpath" value="${javac.classpath}"/>
+ <property name="javac.test.processorpath" value="${javac.test.classpath}"/>
+ <condition property="ap.supported.internal" value="true">
+ <not>
+ <matches pattern="1\.[0-5](\..*)?" string="${javac.source}"/>
+ </not>
+ </condition>
+ </target>
+ <target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-ap-cmdline-supported">
+ <condition else="" property="ap.processors.internal" value="-processor ${annotation.processing.processors.list}">
+ <isfalse value="${annotation.processing.run.all.processors}"/>
+ </condition>
+ <condition else="" property="ap.proc.none.internal" value="-proc:none">
+ <isfalse value="${annotation.processing.enabled}"/>
+ </condition>
+ </target>
+ <target depends="-init-ap-cmdline-properties,-init-ap-cmdline-supported" name="-init-ap-cmdline">
+ <property name="ap.cmd.line.internal" value=""/>
+ </target>
+ <target depends="-pre-init,-init-private,-init-user,-init-project,-do-init,-post-init,-init-check,-init-macrodef-property,-init-macrodef-javac,-init-macrodef-junit,-init-macrodef-nbjpda,-init-macrodef-debug,-init-macrodef-java,-init-presetdef-jar,-init-ap-cmdline" name="init"/>
+ <!--
+ ===================
+ COMPILATION SECTION
+ ===================
+ -->
+ <target name="-deps-jar-init" unless="built-jar.properties">
+ <property location="${build.dir}/built-jar.properties" name="built-jar.properties"/>
+ <delete file="${built-jar.properties}" quiet="true"/>
+ </target>
+ <target if="already.built.jar.${basedir}" name="-warn-already-built-jar">
+ <echo level="warn" message="Cycle detected: Prettify was already built"/>
+ </target>
+ <target depends="init,-deps-jar-init" name="deps-jar" unless="no.deps">
+ <mkdir dir="${build.dir}"/>
+ <touch file="${built-jar.properties}" verbose="false"/>
+ <property file="${built-jar.properties}" prefix="already.built.jar."/>
+ <antcall target="-warn-already-built-jar"/>
+ <propertyfile file="${built-jar.properties}">
+ <entry key="${basedir}" value=""/>
+ </propertyfile>
+ </target>
+ <target depends="init,-check-automatic-build,-clean-after-automatic-build" name="-verify-automatic-build"/>
+ <target depends="init" name="-check-automatic-build">
+ <available file="${build.classes.dir}/.netbeans_automatic_build" property="netbeans.automatic.build"/>
+ </target>
+ <target depends="init" if="netbeans.automatic.build" name="-clean-after-automatic-build">
+ <antcall target="clean"/>
+ </target>
+ <target depends="init,deps-jar" name="-pre-pre-compile">
+ <mkdir dir="${build.classes.dir}"/>
+ </target>
+ <target name="-pre-compile">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target if="do.depend.true" name="-compile-depend">
+ <pathconvert property="build.generated.subdirs">
+ <dirset dir="${build.generated.sources.dir}" erroronmissingdir="false">
+ <include name="*"/>
+ </dirset>
+ </pathconvert>
+ <j2seproject3:depend srcdir="${src.dir}:${build.generated.subdirs}"/>
+ </target>
+ <target depends="init,deps-jar,-pre-pre-compile,-pre-compile, -copy-persistence-xml,-compile-depend" if="have.sources" name="-do-compile">
+ <j2seproject3:javac gensrcdir="${build.generated.sources.dir}"/>
+ <copy todir="${build.classes.dir}">
+ <fileset dir="${src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
+ </copy>
+ </target>
+ <target if="has.persistence.xml" name="-copy-persistence-xml">
+ <mkdir dir="${build.classes.dir}/META-INF"/>
+ <copy todir="${build.classes.dir}/META-INF">
+ <fileset dir="${meta.inf.dir}" includes="persistence.xml"/>
+ </copy>
+ </target>
+ <target name="-post-compile">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile,-do-compile,-post-compile" description="Compile project." name="compile"/>
+ <target name="-pre-compile-single">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target depends="init,deps-jar,-pre-pre-compile" name="-do-compile-single">
+ <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
+ <j2seproject3:force-recompile/>
+ <j2seproject3:javac excludes="" gensrcdir="${build.generated.sources.dir}" includes="${javac.includes}" sourcepath="${src.dir}"/>
+ </target>
+ <target name="-post-compile-single">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile-single,-do-compile-single,-post-compile-single" name="compile-single"/>
+ <!--
+ ====================
+ JAR BUILDING SECTION
+ ====================
+ -->
+ <target depends="init" name="-pre-pre-jar">
+ <dirname file="${dist.jar}" property="dist.jar.dir"/>
+ <mkdir dir="${dist.jar.dir}"/>
+ </target>
+ <target name="-pre-jar">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target depends="init,compile,-pre-pre-jar,-pre-jar" if="do.archive" name="-do-jar-without-manifest" unless="manifest.available-mkdist.available">
+ <j2seproject1:jar/>
+ </target>
+ <target depends="init,compile,-pre-pre-jar,-pre-jar" if="do.archive+manifest.available" name="-do-jar-with-manifest" unless="manifest.available+main.class-mkdist.available">
+ <j2seproject1:jar manifest="${manifest.file}"/>
+ </target>
+ <target depends="init,compile,-pre-pre-jar,-pre-jar" if="do.archive+manifest.available+main.class" name="-do-jar-with-mainclass" unless="manifest.available+main.class+mkdist.available">
+ <j2seproject1:jar manifest="${manifest.file}">
+ <j2seproject1:manifest>
+ <j2seproject1:attribute name="Main-Class" value="${main.class}"/>
+ </j2seproject1:manifest>
+ </j2seproject1:jar>
+ <echo level="info">To run this application from the command line without Ant, try:</echo>
+ <property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
+ <property location="${dist.jar}" name="dist.jar.resolved"/>
+ <pathconvert property="run.classpath.with.dist.jar">
+ <path path="${run.classpath}"/>
+ <map from="${build.classes.dir.resolved}" to="${dist.jar.resolved}"/>
+ </pathconvert>
+ <echo level="info">java -cp "${run.classpath.with.dist.jar}" ${main.class}</echo>
+ </target>
+ <target depends="init" if="do.archive" name="-do-jar-with-libraries-create-manifest" unless="manifest.available">
+ <tempfile deleteonexit="true" destdir="${build.dir}" property="tmp.manifest.file"/>
+ <touch file="${tmp.manifest.file}" verbose="false"/>
+ </target>
+ <target depends="init" if="do.archive+manifest.available" name="-do-jar-with-libraries-copy-manifest">
+ <tempfile deleteonexit="true" destdir="${build.dir}" property="tmp.manifest.file"/>
+ <copy file="${manifest.file}" tofile="${tmp.manifest.file}"/>
+ </target>
+ <target depends="init,-do-jar-with-libraries-create-manifest,-do-jar-with-libraries-copy-manifest" if="do.archive+main.class.available" name="-do-jar-with-libraries-set-main">
+ <manifest file="${tmp.manifest.file}" mode="update">
+ <attribute name="Main-Class" value="${main.class}"/>
+ </manifest>
+ </target>
+ <target depends="init,-do-jar-with-libraries-create-manifest,-do-jar-with-libraries-copy-manifest" if="do.archive+splashscreen.available" name="-do-jar-with-libraries-set-splashscreen">
+ <basename file="${application.splash}" property="splashscreen.basename"/>
+ <mkdir dir="${build.classes.dir}/META-INF"/>
+ <copy failonerror="false" file="${application.splash}" todir="${build.classes.dir}/META-INF"/>
+ <manifest file="${tmp.manifest.file}" mode="update">
+ <attribute name="SplashScreen-Image" value="META-INF/${splashscreen.basename}"/>
+ </manifest>
+ </target>
+ <target depends="init,-init-macrodef-copylibs,compile,-pre-pre-jar,-pre-jar,-do-jar-with-libraries-create-manifest,-do-jar-with-libraries-copy-manifest,-do-jar-with-libraries-set-main,-do-jar-with-libraries-set-splashscreen" if="do.mkdist" name="-do-jar-with-libraries-pack">
+ <j2seproject3:copylibs manifest="${tmp.manifest.file}"/>
+ <echo level="info">To run this application from the command line without Ant, try:</echo>
+ <property location="${dist.jar}" name="dist.jar.resolved"/>
+ <echo level="info">java -jar "${dist.jar.resolved}"</echo>
+ </target>
+ <target depends="-do-jar-with-libraries-pack" if="do.archive" name="-do-jar-with-libraries-delete-manifest">
+ <delete>
+ <fileset file="${tmp.manifest.file}"/>
+ </delete>
+ </target>
+ <target depends="init,compile,-pre-pre-jar,-pre-jar,-do-jar-with-libraries-create-manifest,-do-jar-with-libraries-copy-manifest,-do-jar-with-libraries-set-main,-do-jar-with-libraries-set-splashscreen,-do-jar-with-libraries-pack,-do-jar-with-libraries-delete-manifest" name="-do-jar-with-libraries"/>
+ <target name="-post-jar">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target depends="init,compile,-pre-jar,-do-jar-with-manifest,-do-jar-without-manifest,-do-jar-with-mainclass,-do-jar-with-libraries,-post-jar" description="Build JAR." name="jar"/>
+ <!--
+ =================
+ EXECUTION SECTION
+ =================
+ -->
+ <target depends="init,compile" description="Run a main class." name="run">
+ <j2seproject1:java>
+ <customize>
+ <arg line="${application.args}"/>
+ </customize>
+ </j2seproject1:java>
+ </target>
+ <target name="-do-not-recompile">
+ <property name="javac.includes.binary" value=""/>
+ </target>
+ <target depends="init,compile-single" name="run-single">
+ <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
+ <j2seproject1:java classname="${run.class}"/>
+ </target>
+ <target depends="init,compile-test-single" name="run-test-with-main">
+ <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
+ <j2seproject1:java classname="${run.class}" classpath="${run.test.classpath}"/>
+ </target>
+ <!--
+ =================
+ DEBUGGING SECTION
+ =================
+ -->
+ <target depends="init" if="netbeans.home" name="-debug-start-debugger">
+ <j2seproject1:nbjpdastart name="${debug.class}"/>
+ </target>
+ <target depends="init" if="netbeans.home" name="-debug-start-debugger-main-test">
+ <j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${debug.class}"/>
+ </target>
+ <target depends="init,compile" name="-debug-start-debuggee">
+ <j2seproject3:debug>
+ <customize>
+ <arg line="${application.args}"/>
+ </customize>
+ </j2seproject3:debug>
+ </target>
+ <target depends="init,compile,-debug-start-debugger,-debug-start-debuggee" description="Debug project in IDE." if="netbeans.home" name="debug"/>
+ <target depends="init" if="netbeans.home" name="-debug-start-debugger-stepinto">
+ <j2seproject1:nbjpdastart stopclassname="${main.class}"/>
+ </target>
+ <target depends="init,compile,-debug-start-debugger-stepinto,-debug-start-debuggee" if="netbeans.home" name="debug-stepinto"/>
+ <target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-single">
+ <fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
+ <j2seproject3:debug classname="${debug.class}"/>
+ </target>
+ <target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-single" if="netbeans.home" name="debug-single"/>
+ <target depends="init,compile-test-single" if="netbeans.home" name="-debug-start-debuggee-main-test">
+ <fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
+ <j2seproject3:debug classname="${debug.class}" classpath="${debug.test.classpath}"/>
+ </target>
+ <target depends="init,compile-test-single,-debug-start-debugger-main-test,-debug-start-debuggee-main-test" if="netbeans.home" name="debug-test-with-main"/>
+ <target depends="init" name="-pre-debug-fix">
+ <fail unless="fix.includes">Must set fix.includes</fail>
+ <property name="javac.includes" value="${fix.includes}.java"/>
+ </target>
+ <target depends="init,-pre-debug-fix,compile-single" if="netbeans.home" name="-do-debug-fix">
+ <j2seproject1:nbjpdareload/>
+ </target>
+ <target depends="init,-pre-debug-fix,-do-debug-fix" if="netbeans.home" name="debug-fix"/>
+ <!--
+ =================
+ PROFILING SECTION
+ =================
+ -->
+ <target depends="profile-init,compile" description="Profile a project in the IDE." if="netbeans.home" name="profile">
+ <nbprofiledirect>
+ <classpath>
+ <path path="${run.classpath}"/>
+ </classpath>
+ </nbprofiledirect>
+ <profile/>
+ </target>
+ <target depends="profile-init,compile-single" description="Profile a selected class in the IDE." if="netbeans.home" name="profile-single">
+ <fail unless="profile.class">Must select one file in the IDE or set profile.class</fail>
+ <nbprofiledirect>
+ <classpath>
+ <path path="${run.classpath}"/>
+ </classpath>
+ </nbprofiledirect>
+ <profile classname="${profile.class}"/>
+ </target>
+ <!--
+ =========================
+ APPLET PROFILING SECTION
+ =========================
+ -->
+ <target depends="profile-init,compile-single" if="netbeans.home" name="profile-applet">
+ <nbprofiledirect>
+ <classpath>
+ <path path="${run.classpath}"/>
+ </classpath>
+ </nbprofiledirect>
+ <profile classname="sun.applet.AppletViewer">
+ <customize>
+ <arg value="${applet.url}"/>
+ </customize>
+ </profile>
+ </target>
+ <!--
+ =========================
+ TESTS PROFILING SECTION
+ =========================
+ -->
+ <target depends="profile-init,compile-test-single" if="netbeans.home" name="profile-test-single">
+ <nbprofiledirect>
+ <classpath>
+ <path path="${run.test.classpath}"/>
+ </classpath>
+ </nbprofiledirect>
+ <junit dir="${profiler.info.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" jvm="${profiler.info.jvm}" showoutput="true">
+ <env key="${profiler.info.pathvar}" path="${profiler.info.agentpath}:${profiler.current.path}"/>
+ <jvmarg value="${profiler.info.jvmargs.agent}"/>
+ <jvmarg line="${profiler.info.jvmargs}"/>
+ <test name="${profile.class}"/>
+ <classpath>
+ <path path="${run.test.classpath}"/>
+ </classpath>
+ <syspropertyset>
+ <propertyref prefix="test-sys-prop."/>
+ <mapper from="test-sys-prop.*" to="*" type="glob"/>
+ </syspropertyset>
+ <formatter type="brief" usefile="false"/>
+ <formatter type="xml"/>
+ </junit>
+ </target>
+ <!--
+ ===============
+ JAVADOC SECTION
+ ===============
+ -->
+ <target depends="init" if="have.sources" name="-javadoc-build">
+ <mkdir dir="${dist.javadoc.dir}"/>
+ <javadoc additionalparam="${javadoc.additionalparam}" author="${javadoc.author}" charset="UTF-8" destdir="${dist.javadoc.dir}" docencoding="UTF-8" encoding="${javadoc.encoding.used}" failonerror="true" noindex="${javadoc.noindex}" nonavbar="${javadoc.nonavbar}" notree="${javadoc.notree}" private="${javadoc.private}" source="${javac.source}" splitindex="${javadoc.splitindex}" use="${javadoc.use}" useexternalfile="true" version="${javadoc.version}" windowtitle="${javadoc.windowtitle}">
+ <classpath>
+ <path path="${javac.classpath}"/>
+ </classpath>
+ <fileset dir="${src.dir}" excludes="*.java,${excludes}" includes="${includes}">
+ <filename name="**/*.java"/>
+ </fileset>
+ <fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
+ <include name="**/*.java"/>
+ <exclude name="*.java"/>
+ </fileset>
+ </javadoc>
+ <copy todir="${dist.javadoc.dir}">
+ <fileset dir="${src.dir}" excludes="${excludes}" includes="${includes}">
+ <filename name="**/doc-files/**"/>
+ </fileset>
+ <fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
+ <include name="**/doc-files/**"/>
+ </fileset>
+ </copy>
+ </target>
+ <target depends="init,-javadoc-build" if="netbeans.home" name="-javadoc-browse" unless="no.javadoc.preview">
+ <nbbrowse file="${dist.javadoc.dir}/index.html"/>
+ </target>
+ <target depends="init,-javadoc-build,-javadoc-browse" description="Build Javadoc." name="javadoc"/>
+ <!--
+ =========================
+ JUNIT COMPILATION SECTION
+ =========================
+ -->
+ <target depends="init,compile" if="have.tests" name="-pre-pre-compile-test">
+ <mkdir dir="${build.test.classes.dir}"/>
+ </target>
+ <target name="-pre-compile-test">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target if="do.depend.true" name="-compile-test-depend">
+ <j2seproject3:depend classpath="${javac.test.classpath}" destdir="${build.test.classes.dir}" srcdir="${test.src.dir}"/>
+ </target>
+ <target depends="init,deps-jar,compile,-pre-pre-compile-test,-pre-compile-test,-compile-test-depend" if="have.tests" name="-do-compile-test">
+ <j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" processorpath="${javac.test.processorpath}" srcdir="${test.src.dir}"/>
+ <copy todir="${build.test.classes.dir}">
+ <fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
+ </copy>
+ </target>
+ <target name="-post-compile-test">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-do-compile-test,-post-compile-test" name="compile-test"/>
+ <target name="-pre-compile-test-single">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target depends="init,deps-jar,compile,-pre-pre-compile-test,-pre-compile-test-single" if="have.tests" name="-do-compile-test-single">
+ <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
+ <j2seproject3:force-recompile destdir="${build.test.classes.dir}"/>
+ <j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" excludes="" includes="${javac.includes}" processorpath="${javac.test.processorpath}" sourcepath="${test.src.dir}" srcdir="${test.src.dir}"/>
+ <copy todir="${build.test.classes.dir}">
+ <fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
+ </copy>
+ </target>
+ <target name="-post-compile-test-single">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single,-do-compile-test-single,-post-compile-test-single" name="compile-test-single"/>
+ <!--
+ =======================
+ JUNIT EXECUTION SECTION
+ =======================
+ -->
+ <target depends="init" if="have.tests" name="-pre-test-run">
+ <mkdir dir="${build.test.results.dir}"/>
+ </target>
+ <target depends="init,compile-test,-pre-test-run" if="have.tests" name="-do-test-run">
+ <j2seproject3:junit testincludes="**/*Test.java"/>
+ </target>
+ <target depends="init,compile-test,-pre-test-run,-do-test-run" if="have.tests" name="-post-test-run">
+ <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
+ </target>
+ <target depends="init" if="have.tests" name="test-report"/>
+ <target depends="init" if="netbeans.home+have.tests" name="-test-browse"/>
+ <target depends="init,compile-test,-pre-test-run,-do-test-run,test-report,-post-test-run,-test-browse" description="Run unit tests." name="test"/>
+ <target depends="init" if="have.tests" name="-pre-test-run-single">
+ <mkdir dir="${build.test.results.dir}"/>
+ </target>
+ <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single">
+ <fail unless="test.includes">Must select some files in the IDE or set test.includes</fail>
+ <j2seproject3:junit excludes="" includes="${test.includes}"/>
+ </target>
+ <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single" if="have.tests" name="-post-test-run-single">
+ <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
+ </target>
+ <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single,-post-test-run-single" description="Run single unit test." name="test-single"/>
+ <!--
+ =======================
+ JUNIT DEBUGGING SECTION
+ =======================
+ -->
+ <target depends="init,compile-test" if="have.tests" name="-debug-start-debuggee-test">
+ <fail unless="test.class">Must select one file in the IDE or set test.class</fail>
+ <property location="${build.test.results.dir}/TEST-${test.class}.xml" name="test.report.file"/>
+ <delete file="${test.report.file}"/>
+ <mkdir dir="${build.test.results.dir}"/>
+ <j2seproject3:debug classname="org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner" classpath="${ant.home}/lib/ant.jar:${ant.home}/lib/ant-junit.jar:${debug.test.classpath}">
+ <customize>
+ <syspropertyset>
+ <propertyref prefix="test-sys-prop."/>
+ <mapper from="test-sys-prop.*" to="*" type="glob"/>
+ </syspropertyset>
+ <arg value="${test.class}"/>
+ <arg value="showoutput=true"/>
+ <arg value="formatter=org.apache.tools.ant.taskdefs.optional.junit.BriefJUnitResultFormatter"/>
+ <arg value="formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter,${test.report.file}"/>
+ </customize>
+ </j2seproject3:debug>
+ </target>
+ <target depends="init,compile-test" if="netbeans.home+have.tests" name="-debug-start-debugger-test">
+ <j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${test.class}"/>
+ </target>
+ <target depends="init,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test" name="debug-test"/>
+ <target depends="init,-pre-debug-fix,compile-test-single" if="netbeans.home" name="-do-debug-fix-test">
+ <j2seproject1:nbjpdareload dir="${build.test.classes.dir}"/>
+ </target>
+ <target depends="init,-pre-debug-fix,-do-debug-fix-test" if="netbeans.home" name="debug-fix-test"/>
+ <!--
+ =========================
+ APPLET EXECUTION SECTION
+ =========================
+ -->
+ <target depends="init,compile-single" name="run-applet">
+ <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
+ <j2seproject1:java classname="sun.applet.AppletViewer">
+ <customize>
+ <arg value="${applet.url}"/>
+ </customize>
+ </j2seproject1:java>
+ </target>
+ <!--
+ =========================
+ APPLET DEBUGGING SECTION
+ =========================
+ -->
+ <target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-applet">
+ <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
+ <j2seproject3:debug classname="sun.applet.AppletViewer">
+ <customize>
+ <arg value="${applet.url}"/>
+ </customize>
+ </j2seproject3:debug>
+ </target>
+ <target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-applet" if="netbeans.home" name="debug-applet"/>
+ <!--
+ ===============
+ CLEANUP SECTION
+ ===============
+ -->
+ <target name="-deps-clean-init" unless="built-clean.properties">
+ <property location="${build.dir}/built-clean.properties" name="built-clean.properties"/>
+ <delete file="${built-clean.properties}" quiet="true"/>
+ </target>
+ <target if="already.built.clean.${basedir}" name="-warn-already-built-clean">
+ <echo level="warn" message="Cycle detected: Prettify was already built"/>
+ </target>
+ <target depends="init,-deps-clean-init" name="deps-clean" unless="no.deps">
+ <mkdir dir="${build.dir}"/>
+ <touch file="${built-clean.properties}" verbose="false"/>
+ <property file="${built-clean.properties}" prefix="already.built.clean."/>
+ <antcall target="-warn-already-built-clean"/>
+ <propertyfile file="${built-clean.properties}">
+ <entry key="${basedir}" value=""/>
+ </propertyfile>
+ </target>
+ <target depends="init" name="-do-clean">
+ <delete dir="${build.dir}"/>
+ <delete dir="${dist.dir}" followsymlinks="false" includeemptydirs="true"/>
+ </target>
+ <target name="-post-clean">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target depends="init,deps-clean,-do-clean,-post-clean" description="Clean build products." name="clean"/>
+ <target name="-check-call-dep">
+ <property file="${call.built.properties}" prefix="already.built."/>
+ <condition property="should.call.dep">
+ <not>
+ <isset property="already.built.${call.subproject}"/>
+ </not>
+ </condition>
+ </target>
+ <target depends="-check-call-dep" if="should.call.dep" name="-maybe-call-dep">
+ <ant antfile="${call.script}" inheritall="false" target="${call.target}">
+ <propertyset>
+ <propertyref prefix="transfer."/>
+ <mapper from="transfer.*" to="*" type="glob"/>
+ </propertyset>
+ </ant>
+ </target>
+</project>
diff --git a/nbproject/genfiles.properties b/nbproject/genfiles.properties
new file mode 100644
index 0000000..cde3213
--- /dev/null
+++ b/nbproject/genfiles.properties
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=4d2699c2
+build.xml.script.CRC32=fd9caa3f
+build.xml.stylesheet.CRC32=28e38971@1.44.1.45
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=4d2699c2
+nbproject/build-impl.xml.script.CRC32=95d36cae
+nbproject/build-impl.xml.stylesheet.CRC32=0ae3a408@1.44.1.45
diff --git a/nbproject/project.properties b/nbproject/project.properties
new file mode 100644
index 0000000..f4a767d
--- /dev/null
+++ b/nbproject/project.properties
@@ -0,0 +1,71 @@
+annotation.processing.enabled=true
+annotation.processing.enabled.in.editor=false
+annotation.processing.processor.options=
+annotation.processing.processors.list=
+annotation.processing.run.all.processors=true
+annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
+build.classes.dir=${build.dir}/classes
+build.classes.excludes=**/*.java,**/*.form
+# This directory is removed when the project is cleaned:
+build.dir=build
+build.generated.dir=${build.dir}/generated
+build.generated.sources.dir=${build.dir}/generated-sources
+# Only compile against the classpath explicitly listed here:
+build.sysclasspath=ignore
+build.test.classes.dir=${build.dir}/test/classes
+build.test.results.dir=${build.dir}/test/results
+# Uncomment to specify the preferred debugger connection transport:
+#debug.transport=dt_socket
+debug.classpath=\
+ ${run.classpath}
+debug.test.classpath=\
+ ${run.test.classpath}
+# This directory is removed when the project is cleaned:
+dist.dir=dist
+dist.jar=${dist.dir}/Prettify.jar
+dist.javadoc.dir=${dist.dir}/javadoc
+excludes=
+includes=**
+jar.compress=false
+javac.classpath=
+# Space-separated list of extra javac options
+javac.compilerargs=
+javac.deprecation=false
+javac.processorpath=\
+ ${javac.classpath}
+javac.source=1.6
+javac.target=1.6
+javac.test.classpath=\
+ ${javac.classpath}:\
+ ${build.classes.dir}
+javac.test.processorpath=\
+ ${javac.test.classpath}
+javadoc.additionalparam=
+javadoc.author=false
+javadoc.encoding=${source.encoding}
+javadoc.noindex=false
+javadoc.nonavbar=false
+javadoc.notree=false
+javadoc.private=false
+javadoc.splitindex=true
+javadoc.use=true
+javadoc.version=false
+javadoc.windowtitle=
+main.class=
+manifest.file=manifest.mf
+meta.inf.dir=${src.dir}/META-INF
+mkdist.disabled=false
+platform.active=default_platform
+run.classpath=\
+ ${javac.classpath}:\
+ ${build.classes.dir}
+# Space-separated list of JVM arguments used when running the project
+# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value
+# or test-sys-prop.name=value to set system properties for unit tests):
+run.jvmargs=
+run.test.classpath=\
+ ${javac.test.classpath}:\
+ ${build.test.classes.dir}
+source.encoding=UTF-8
+src.dir=src
+test.src.dir=test
diff --git a/nbproject/project.xml b/nbproject/project.xml
new file mode 100644
index 0000000..80e5298
--- /dev/null
+++ b/nbproject/project.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.java.j2seproject</type>
+ <configuration>
+ <data xmlns="http://www.netbeans.org/ns/j2se-project/3">
+ <name>Prettify</name>
+ <source-roots>
+ <root id="src.dir"/>
+ </source-roots>
+ <test-roots>
+ <root id="test.src.dir"/>
+ </test-roots>
+ </data>
+ </configuration>
+</project>
diff --git a/src/prettify/CombinePrefixPattern.java b/src/prettify/CombinePrefixPattern.java
new file mode 100644
index 0000000..d9348d3
--- /dev/null
+++ b/src/prettify/CombinePrefixPattern.java
@@ -0,0 +1,289 @@
+// Copyright (C) 2006 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;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class CombinePrefixPattern {
+
+ protected int capturedGroupIndex = 0;
+ protected boolean needToFoldCase = false;
+
+ public CombinePrefixPattern() {
+ }
+
+ /**
+ * Given a group of {@link java.util.regex.Pattern}s, returns a {@code RegExp} that globally
+ * matches the union of the sets of strings matched by the input RegExp.
+ * Since it matches globally, if the input strings have a start-of-input
+ * anchor (/^.../), it is ignored for the purposes of unioning.
+ * @param regexs non multiline, non-global regexs.
+ * @return Pattern a global regex.
+ */
+ public Pattern combinePrefixPattern(List<Pattern> regexs) throws Exception {
+ boolean ignoreCase = false;
+
+ for (int i = 0, n = regexs.size(); i < n; ++i) {
+ Pattern regex = regexs.get(i);
+ if ((regex.flags() & Pattern.CASE_INSENSITIVE) != 0) {
+ ignoreCase = true;
+ } else if (regex.pattern().replaceAll("(?i)\\\\u[0-9a-f]{4}|\\\\x[0-9a-f]{2}|\\\\[^ux]", "").matches("(?i)[a-z]")) {
+ needToFoldCase = true;
+ ignoreCase = false;
+ break;
+ }
+ }
+
+ List<String> rewritten = new ArrayList<String>();
+ for (int i = 0, n = regexs.size(); i < n; ++i) {
+ Pattern regex = regexs.get(i);
+ if ((regex.flags() & Pattern.MULTILINE) != 0) {
+ throw new Exception(regex.pattern());
+ }
+ rewritten.add("(?:" + allowAnywhereFoldCaseAndRenumberGroups(regex) + ")");
+ }
+
+ return ignoreCase ? Pattern.compile(Util.join(rewritten, "|"), Pattern.CASE_INSENSITIVE) : Pattern.compile(Util.join(rewritten, "|"));
+ }
+ protected static final Map<Character, Integer> escapeCharToCodeUnit = new HashMap<Character, Integer>();
+
+ static {
+ escapeCharToCodeUnit.put('b', 8);
+ escapeCharToCodeUnit.put('t', 9);
+ escapeCharToCodeUnit.put('n', 0xa);
+ escapeCharToCodeUnit.put('v', 0xb);
+ escapeCharToCodeUnit.put('f', 0xc);
+ escapeCharToCodeUnit.put('r', 0xf);
+ }
+
+ public static int decodeEscape(String charsetPart) {
+ Integer cc0 = charsetPart.codePointAt(0);
+ if (cc0 != 92 /* \\ */) {
+ return cc0;
+ }
+ char c1 = charsetPart.charAt(1);
+ cc0 = escapeCharToCodeUnit.get(c1);
+ if (cc0 != null) {
+ return cc0;
+ } else if ('0' <= c1 && c1 <= '7') {
+ return Integer.parseInt(charsetPart.substring(1), 8);
+ } else if (c1 == 'u' || c1 == 'x') {
+ return Integer.parseInt(charsetPart.substring(2), 16);
+ } else {
+ return charsetPart.codePointAt(1);
+ }
+ }
+
+ public static String encodeEscape(int charCode) {
+ if (charCode < 0x20) {
+ return (charCode < 0x10 ? "\\x0" : "\\x") + Integer.toString(charCode, 16);
+ }
+
+ String ch = new String(Character.toChars(charCode));
+ return (charCode == '\\' || charCode == '-' || charCode == ']' || charCode == '^')
+ ? "\\" + ch : ch;
+ }
+
+ public 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}"
+ + "|\\\\[0-7]{1,2}"
+ + "|\\\\[\\s\\S]"
+ + "|-"
+ + "|[^-\\\\]"), charSet.substring(1, charSet.length() - 1));
+ List<List<Integer>> ranges = new ArrayList<List<Integer>>();
+ boolean inverse = charsetParts[0] != null && charsetParts[0].equals("^");
+
+ List<String> out = new ArrayList<String>(Arrays.asList(new String[]{"["}));
+ if (inverse) {
+ out.add("^");
+ }
+
+ for (int i = inverse ? 1 : 0, n = charsetParts.length; i < n; ++i) {
+ String p = charsetParts[i];
+ if (p.matches("(?i)\\\\[bdsw]")) { // Don't muck with named groups.
+ out.add(p);
+ } else {
+ int start = decodeEscape(p);
+ int end;
+ if (i + 2 < n && "-".equals(charsetParts[i + 1])) {
+ end = decodeEscape(charsetParts[i + 2]);
+ i += 2;
+ } else {
+ end = start;
+ }
+ ranges.add(Arrays.asList(new Integer[]{start, end}));
+ // If the range might intersect letters, then expand it.
+ // This case handling is too simplistic.
+ // It does not deal with non-latin case folding.
+ // It works for latin source code identifiers though.
+ if (!(end < 65 || start > 122)) {
+ if (!(end < 65 || start > 90)) {
+ ranges.add(Arrays.asList(new Integer[]{Math.max(65, start) | 32, Math.min(end, 90) | 32}));
+ }
+ if (!(end < 97 || start > 122)) {
+ ranges.add(Arrays.asList(new Integer[]{Math.max(97, start) & ~32, Math.min(end, 122) & ~32}));
+ }
+ }
+ }
+ }
+
+ // [[1, 10], [3, 4], [8, 12], [14, 14], [16, 16], [17, 17]]
+ // -> [[1, 12], [14, 14], [16, 17]]
+ Collections.sort(ranges, new Comparator<List<Integer>>() {
+
+ @Override
+ public int compare(List<Integer> a, List<Integer> b) {
+ return a.get(0) != b.get(0) ? (a.get(0) - b.get(0)) : (b.get(1) - a.get(1));
+ }
+ });
+ List<List<Integer>> consolidatedRanges = new ArrayList<List<Integer>>();
+ Map<Integer, Integer> lastRange = new HashMap<Integer, Integer>();
+ for (int i = 0; i < ranges.size(); ++i) {
+ List<Integer> range = ranges.get(i);
+ if (lastRange.get(1) != null && range.get(0) <= lastRange.get(1) + 1) {
+ lastRange.put(1, Math.max(lastRange.get(1), range.get(1)));
+ } else {
+ consolidatedRanges.add(range);
+ lastRange.put(0, range.get(0));
+ lastRange.put(1, range.get(1));
+ }
+ }
+
+ for (int i = 0; i < consolidatedRanges.size(); ++i) {
+ List<Integer> range = consolidatedRanges.get(i);
+ out.add(encodeEscape((int) range.get(0)));
+ if (range.get(1) > range.get(0)) {
+ if (range.get(1) + 1 > range.get(0)) {
+ out.add("-");
+ }
+ out.add(encodeEscape((int) range.get(1)));
+ }
+ }
+ out.add("]");
+
+ return Util.join(out);
+ }
+
+ public 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.
+ String[] parts = Util.match(Pattern.compile("(?:"
+ + "\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]" // a character set
+ + "|\\\\u[A-Fa-f0-9]{4}" // a unicode escape
+ + "|\\\\x[A-Fa-f0-9]{2}" // a hex escape
+ + "|\\\\[0-9]+" // a back-reference or octal escape
+ + "|\\\\[^ux0-9]" // other escape sequence
+ + "|\\(\\?[:!=]" // start of a non-capturing group
+ + "|[\\(\\)\\^]" // start/end of a group, or line start
+ + "|[^\\x5B\\x5C\\(\\)\\^]+" // run of other characters
+ + ")"), regex.pattern());
+ int n = parts.length;
+
+ // Maps captured group numbers to the number they will occupy in
+ // the output or to -1 if that has not been determined, or to
+ // undefined if they need not be capturing in the output.
+ Map<Integer, Integer> capturedGroups = new HashMap<Integer, Integer>();
+
+ // Walk over and identify back references to build the capturedGroups
+ // mapping.
+ for (int i = 0, groupIndex = 0; i < n; ++i) {
+ String p = parts[i];
+ if (p.equals("(")) {
+ // groups are 1-indexed, so max group index is count of '('
+ ++groupIndex;
+ } else if ('\\' == p.charAt(0)) {
+ try {
+ int decimalValue = Math.abs(Integer.parseInt(p.substring(1)));
+ if (decimalValue <= groupIndex) {
+ capturedGroups.put(decimalValue, -1);
+ } else {
+ // Replace with an unambiguous escape sequence so that
+ // an octal escape sequence does not turn into a backreference
+ // to a capturing group from an earlier regex.
+ parts[i] = encodeEscape(decimalValue);
+ }
+ } catch (NumberFormatException ex) {
+ }
+ }
+ }
+
+ // Renumber groups and reduce capturing groups to non-capturing groups
+ // where possible.
+ for (int i : capturedGroups.keySet()) {
+ if (-1 == capturedGroups.get(i)) {
+ capturedGroups.put(i, ++capturedGroupIndex);
+ }
+ }
+ for (int i = 0, groupIndex = 0; i < n; ++i) {
+ String p = parts[i];
+ if (p.equals("(")) {
+ ++groupIndex;
+ if (capturedGroups.get(groupIndex) == null) {
+ parts[i] = "(?:";
+ }
+ } else if ('\\' == p.charAt(0)) {
+ try {
+ int decimalValue = Math.abs(Integer.parseInt(p.substring(1)));
+ if (decimalValue <= groupIndex) {
+ parts[i] = "\\" + capturedGroups.get(decimalValue);
+ }
+ } catch (NumberFormatException ex) {
+ }
+ }
+ }
+
+ // Remove any prefix anchors so that the output will match anywhere.
+ // ^^ really does mean an anchored match though.
+ for (int i = 0; i < n; ++i) {
+ if ("^".equals(parts[i]) && !"^".equals(parts[i + 1])) {
+ parts[i] = "";
+ }
+ }
+
+ // Expand letters to groups to handle mixing of case-sensitive and
+ // case-insensitive patterns if necessary.
+ if ((regex.flags() & Pattern.CASE_INSENSITIVE) != 0 && needToFoldCase) {
+ for (int i = 0; i < n; ++i) {
+ String p = parts[i];
+ char ch0 = p.charAt(0);
+ if (p.length() >= 2 && ch0 == '[') {
+ parts[i] = caseFoldCharset(p);
+ } else if (ch0 == '\\') {
+ // TODO: handle letters in numeric escapes.
+ StringBuffer sb = new StringBuffer();
+ Matcher _matcher = Pattern.compile("[a-zA-Z]").matcher(p);
+ while (_matcher.find()) {
+ int cc = _matcher.group(0).codePointAt(0);
+ _matcher.appendReplacement(sb, "[" + Character.toString((char) (cc & ~32)) + Character.toString((char) (cc | 32)) + "]");
+ }
+ _matcher.appendTail(sb);
+ parts[i] = sb.toString();
+ }
+ }
+ }
+
+ return Util.join(parts);
+ }
+}
diff --git a/src/prettify/JTextComponentRowHeader.java b/src/prettify/JTextComponentRowHeader.java
new file mode 100644
index 0000000..1f98259
--- /dev/null
+++ b/src/prettify/JTextComponentRowHeader.java
@@ -0,0 +1,515 @@
+/**
+ * This is part of the Java SyntaxHighlighter.
+ *
+ * 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.Container;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Point;
+import java.awt.RenderingHints;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JViewport;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Document;
+import javax.swing.text.Element;
+import javax.swing.text.JTextComponent;
+
+/**
+ * A row header panel for JScrollPane.
+ * It is used with JTextComponent for line number displaying.<br />
+ * Currently it only accept fixed-height line.<br />
+ * <b>The usage is not limited to this syntax highlighter, it can be used on all JTextComponent.</b>
+ * @author Chan Wai Shing <cws1989@gmail.com>
+ */
+public class JTextComponentRowHeader extends JPanel {
+
+ /**
+ * Indicate whether it is in debug mode or not.
+ */
+ protected final static boolean debug;
+
+ static {
+ String debugMode = System.getProperty("SyntaxHighlighterDebugMode");
+ debug = debugMode == null || !debugMode.equals("true") ? false : true;
+ }
+ private static final long serialVersionUID = 1L;
+ /**
+ * The anti-aliasing setting of the line number text. See {@link java.awt.RenderingHints}.
+ */
+ private Object textAntiAliasing = RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT;
+ /**
+ * The color of the border that joint the gutter and the script text panel.
+ */
+ private Color borderColor = new Color(184, 184, 184);
+ /**
+ * The background of the row when it is highlighted.
+ */
+ private Color highlightedColor = Color.black;
+ /**
+ * The minimum padding from 'the leftmost of the line number text' to 'the left margin'.
+ */
+ private int paddingLeft = 7;
+ /**
+ * The minimum padding from 'the rightmost of the line number text' to 'the right margin' (not to the gutter border).
+ */
+ private int paddingRight = 2;
+ /**
+ * The width of the border that joint the gutter and the script text panel.
+ */
+ private int borderWidth = 1;
+ /**
+ * The JScrollPane that it be added into.
+ */
+ protected JScrollPane scrollPane;
+ /**
+ * The text component to listen the change events on.
+ */
+ protected JTextComponent textComponent;
+ /**
+ * The document of the text component.
+ */
+ protected Document document;
+ /**
+ * The document listener for {@link #document}.
+ */
+ protected DocumentListener documentListener;
+ /**
+ * The cached panel width.
+ */
+ protected int panelWidth;
+ /**
+ * The cached largest row number (for determine panel width {@link #panelWidth}).
+ */
+ protected int largestRowNumber;
+ /**
+ * The cached text component height, for determine panel height.
+ */
+ protected int textComponentHeight;
+ /**
+ * 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 list of line numbers that indicate which lines are needed to be highlighted.
+ */
+ private final List<Integer> highlightedLineList;
+ /**
+ * Indicator indicate whether it is listening to the document change events or not.
+ */
+ private boolean listenToDocumentUpdate;
+
+ /**
+ * Constructor.
+ * @param scrollPane the JScrollPane that it be added into
+ * @param textComponent the text component to listen the change events on
+ */
+ public JTextComponentRowHeader(JScrollPane scrollPane, JTextComponent textComponent) {
+ super();
+
+ if (scrollPane == null) {
+ throw new NullPointerException("argument 'scrollPane' cannot be null");
+ }
+ if (textComponent == null) {
+ throw new NullPointerException("argument 'textComponent' cannot be null");
+ }
+
+ setFont(new Font("Verdana", Font.PLAIN, 10));
+ setForeground(Color.black);
+ setBackground(new Color(233, 232, 226));
+
+ this.scrollPane = scrollPane;
+ this.textComponent = textComponent;
+
+ panelWidth = 0;
+ largestRowNumber = 1;
+ textComponentHeight = 0;
+
+ lineNumberOffset = 0;
+ highlightedLineList = Collections.synchronizedList(new ArrayList<Integer>());
+
+ listenToDocumentUpdate = true;
+
+ document = textComponent.getDocument();
+ documentListener = new DocumentListener() {
+
+ @Override
+ public void insertUpdate(DocumentEvent e) {
+ handleEvent(e);
+ }
+
+ @Override
+ public void removeUpdate(DocumentEvent e) {
+ handleEvent(e);
+ }
+
+ @Override
+ public void changedUpdate(DocumentEvent e) {
+ handleEvent(e);
+ }
+
+ public void handleEvent(DocumentEvent e) {
+ if (!listenToDocumentUpdate) {
+ return;
+ }
+ Document _document = e.getDocument();
+ if (document == _document) {
+ checkPanelSize();
+ } else {
+ _document.removeDocumentListener(this);
+ }
+ }
+ };
+
+ document.addDocumentListener(documentListener);
+
+ checkPanelSize();
+ }
+
+ /**
+ * Check if the 'document of the textComponent' has changed to another document or not.
+ */
+ protected void validateTextComponentDocument() {
+ Document _currentDocument = textComponent.getDocument();
+ if (document != _currentDocument) {
+ document.removeDocumentListener(documentListener);
+ document = _currentDocument;
+ _currentDocument.addDocumentListener(documentListener);
+ }
+ }
+
+ /**
+ * Check whether the height of the row header panel match with the height of the text component or not.
+ * If not, it will invoke {@link #updatePanelSize()}.
+ */
+ protected void checkPanelSize() {
+ validateTextComponentDocument();
+ int _largestRowNumber = document.getDefaultRootElement().getElementCount() + lineNumberOffset;
+ int _panelWidth = getFontMetrics(getFont()).stringWidth(Integer.toString(_largestRowNumber)) + paddingLeft + paddingRight;
+ if (panelWidth != _panelWidth || largestRowNumber != _largestRowNumber) {
+ panelWidth = _panelWidth;
+ largestRowNumber = _largestRowNumber;
+ updatePanelSize();
+ }
+ }
+
+ /**
+ * Update the panel size.
+ */
+ protected void updatePanelSize() {
+ Container parent = getParent();
+ if (parent != null) {
+ parent.doLayout();
+ scrollPane.doLayout();
+ parent.repaint();
+ }
+ }
+
+ /**
+ * The font of the line number.
+ */
+ @Override
+ public void setFont(Font font) {
+ super.setFont(font);
+ }
+
+ /**
+ * The color of the line number.
+ */
+ @Override
+ public void setForeground(Color foreground) {
+ super.setForeground(foreground);
+ }
+
+ /**
+ * The background of the panel.
+ */
+ @Override
+ public void setBackground(Color background) {
+ super.setBackground(background);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Dimension getPreferredSize() {
+ textComponentHeight = textComponent.getPreferredSize().height;
+ return new Dimension(panelWidth, textComponentHeight);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void paint(Graphics g) {
+ super.paint(g);
+
+ // check whether the height of this panel matches the height of the text component or not
+ Dimension textComponentPreferredSize = textComponent.getPreferredSize();
+ if (textComponentHeight != textComponentPreferredSize.height) {
+ textComponentHeight = textComponentPreferredSize.height;
+ updatePanelSize();
+ }
+
+ JViewport viewport = scrollPane.getViewport();
+ Point viewPosition = viewport.getViewPosition();
+ Dimension viewportSize = viewport.getSize();
+
+ validateTextComponentDocument();
+ Element defaultRootElement = document.getDefaultRootElement();
+
+
+ // maybe able to get the value when font changed and cache them
+ // however i'm not sure if there is any condition which will make the java.awt.FontMetrics get by getFontMetrics() from java.awt.Graphics is different from getFontMetrics() from java.awt.Component
+ FontMetrics fontMetrics = g.getFontMetrics(getFont());
+ int fontHeight = fontMetrics.getHeight();
+ int fontAscent = fontMetrics.getAscent();
+ int fontLeading = fontMetrics.getLeading();
+
+ FontMetrics textPaneFontMetrics = g.getFontMetrics(textComponent.getFont());
+ int textPaneFontHeight = textPaneFontMetrics.getHeight();
+
+
+ // get the location of the document of the left top and right bottom point of the visible part of the text component
+ int documentOffsetStart = textComponent.viewToModel(viewPosition);
+ int documentOffsetEnd = textComponent.viewToModel(new Point(viewPosition.x + viewportSize.width, viewPosition.y + viewportSize.height));
+
+ // convert the location to line number
+ int startLine = defaultRootElement.getElementIndex(documentOffsetStart) + 1 + lineNumberOffset;
+ int endLine = defaultRootElement.getElementIndex(documentOffsetEnd) + 1 + lineNumberOffset;
+
+
+ // draw right border
+ g.setColor(borderColor);
+ g.fillRect(panelWidth - borderWidth, viewPosition.y, borderWidth, viewportSize.height);
+
+ // draw line number
+ int startY = -1, baselineOffset = -1;
+ try {
+ startY = textComponent.modelToView(documentOffsetStart).y;
+ baselineOffset = (textPaneFontHeight / 2) + fontAscent - (fontHeight / 2) + fontLeading;
+ } catch (BadLocationException ex) {
+ if (debug) {
+ Logger.getLogger(JTextComponentRowHeader.class.getName()).log(Level.WARNING, null, ex);
+ }
+ return;
+ }
+
+ // text anti-aliasing
+ ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, textAntiAliasing);
+ // preserve the foreground color (for recover the color after highlighing the line)
+ Color foregroundColor = getForeground();
+
+ g.setColor(foregroundColor);
+ g.setFont(getFont());
+
+ for (int i = startLine, y = startY + baselineOffset; i <= endLine; y += textPaneFontHeight, i++) {
+ boolean highlighted = false;
+ if (highlightedLineList.indexOf((Integer) i) != -1) {
+ // highlight this line
+ g.setColor(borderColor);
+ g.fillRect(0, y - baselineOffset, panelWidth - borderWidth, textPaneFontHeight);
+ g.setColor(highlightedColor);
+ highlighted = true;
+ }
+
+ // draw the line number
+ String lineNumberString = Integer.toString(i);
+ int lineNumberStringWidth = fontMetrics.stringWidth(lineNumberString);
+ g.drawString(lineNumberString, panelWidth - lineNumberStringWidth - paddingRight, y);
+
+ // restore the line number text color
+ if (highlighted) {
+ g.setColor(foregroundColor);
+ }
+ }
+ }
+
+ /**
+ * The anti-aliasing setting of the line number text. See {@link java.awt.RenderingHints}.
+ */
+ public Object getTextAntiAliasing() {
+ return textAntiAliasing;
+ }
+
+ /**
+ * The anti-aliasing setting of the line number text. See {@link java.awt.RenderingHints}.
+ */
+ public void setTextAntiAliasing(Object textAntiAliasing) {
+ if (textAntiAliasing == null) {
+ throw new NullPointerException("argument 'textAntiAliasing' cannot be null");
+ }
+ this.textAntiAliasing = textAntiAliasing;
+ repaint();
+ }
+
+ /**
+ * The color of the border that joint the gutter and the script text panel.
+ */
+ public Color getBorderColor() {
+ return borderColor;
+ }
+
+ /**
+ * The color of the border that joint the gutter and the script text panel.
+ */
+ public void setBorderColor(Color borderColor) {
+ if (borderColor == null) {
+ throw new NullPointerException("argument 'borderColor' cannot be null");
+ }
+ this.borderColor = borderColor;
+ repaint();
+ }
+
+ /**
+ * The background of the highlighted row.
+ */
+ public Color getHighlightedColor() {
+ return highlightedColor;
+ }
+
+ /**
+ * The background of the highlighted row.
+ */
+ public void setHighlightedColor(Color highlightedColor) {
+ if (highlightedColor == null) {
+ throw new NullPointerException("argument 'highlightedColor' cannot be null");
+ }
+ this.highlightedColor = highlightedColor;
+ repaint();
+ }
+
+ /**
+ * The minimum padding from the 'leftmost of the line number text' to the 'left margin'.
+ */
+ public int getPaddingLeft() {
+ return paddingLeft;
+ }
+
+ /**
+ * The minimum padding from 'the leftmost of the line number text' to the 'left margin'.
+ */
+ public void setPaddingLeft(int paddingLeft) {
+ this.paddingLeft = paddingLeft;
+ checkPanelSize();
+ }
+
+ /**
+ * The minimum padding from the 'rightmost of the line number text' to the 'right margin' (not to the gutter border).
+ */
+ public int getPaddingRight() {
+ return paddingRight;
+ }
+
+ /**
+ * The minimum padding from the 'rightmost of the line number text' to the 'right margin' (not to the gutter border).
+ */
+ public void setPaddingRight(int paddingRight) {
+ this.paddingRight = paddingRight;
+ checkPanelSize();
+ }
+
+ /**
+ * The width of the border that joint the gutter and the script text panel.
+ */
+ public int getBorderWidth() {
+ return borderWidth;
+ }
+
+ /**
+ * The width of the border that joint the gutter and the script text panel.
+ */
+ public void setBorderWidth(int borderWidth) {
+ this.borderWidth = borderWidth;
+ repaint();
+ }
+
+ /**
+ * Get the line number offset
+ * @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);
+ checkPanelSize();
+ 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();
+ }
+
+ /**
+ * Check if it is listening to the document change events.
+ * @return true if it is listening, false if not
+ */
+ public boolean isListenToDocumentUpdate() {
+ return listenToDocumentUpdate;
+ }
+
+ /**
+ * Set to listen to document change events or not. It is useful when a number of updates are needed to be done to the text component.
+ * May invoke {@link #updatePanelSize()}.
+ * @param listenToDocumentUpdate true to listen on document change, false not
+ */
+ public void setListenToDocumentUpdate(boolean listenToDocumentUpdate) {
+ this.listenToDocumentUpdate = listenToDocumentUpdate;
+ }
+}
diff --git a/src/prettify/Job.java b/src/prettify/Job.java
new file mode 100644
index 0000000..cc3d37f
--- /dev/null
+++ b/src/prettify/Job.java
@@ -0,0 +1,56 @@
+// Copyright (C) 2006 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;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Job {
+
+ protected int basePos;
+ protected String sourceCode;
+ protected List<Object> decorations;
+
+ public Job() {
+ decorations = new ArrayList<Object>();
+ }
+
+ public int getBasePos() {
+ return basePos;
+ }
+
+ public void setBasePos(int basePos) {
+ this.basePos = basePos;
+ }
+
+ public String getSourceCode() {
+ return sourceCode;
+ }
+
+ public void setSourceCode(String sourceCode) {
+ this.sourceCode = sourceCode;
+ }
+
+ public List<Object> getDecorations() {
+ return new ArrayList<Object>(decorations);
+ }
+
+ public void setDecorations(List<Object> decorations) {
+ if (decorations == null) {
+ this.decorations = new ArrayList<Object>();
+ return;
+ }
+ this.decorations = new ArrayList<Object>(decorations);
+ }
+}
diff --git a/src/prettify/Prettify.java b/src/prettify/Prettify.java
new file mode 100644
index 0000000..5e50f7a
--- /dev/null
+++ b/src/prettify/Prettify.java
@@ -0,0 +1,703 @@
+// Copyright (C) 2006 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;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.regex.Pattern;
+
+/**
+ * @fileoverview
+ * some functions for browser-side pretty printing of code contained in html.
+ *
+ * <p>
+ * For a fairly comprehensive set of languages see the
+ * <a href="http://google-code-prettify.googlecode.com/svn/trunk/README.html#langs">README</a>
+ * file that came with this source. At a minimum, the lexer should work on a
+ * number of languages including C and friends, Java, Python, Bash, SQL, HTML,
+ * XML, CSS, Javascript, and Makefiles. It works passably on Ruby, PHP and Awk
+ * and a subset of Perl, but, because of commenting conventions, doesn't work on
+ * Smalltalk, Lisp-like, or CAML-like languages without an explicit lang class.
+ * <p>
+ * Usage: <ol>
+ * <li> include this source file in an html page via
+ * {@code <script type="text/javascript" src="/path/to/prettify.js"></script>}
+ * <li> define style rules. See the example page for examples.
+ * <li> mark the {@code <pre>} and {@code <code>} tags in your source with
+ * {@code class=prettyprint.}
+ * You can also use the (html deprecated) {@code <xmp>} tag, but the pretty
+ * printer needs to do more substantial DOM manipulations to support that, so
+ * some css styles may not be preserved.
+ * </ol>
+ * That's it. I wanted to keep the API as simple as possible, so there's no
+ * need to specify which language the code is in, but if you wish, you can add
+ * another class to the {@code <pre>} or {@code <code>} element to specify the
+ * language, as in {@code <pre class="prettyprint lang-java">}. Any class that
+ * starts with "lang-" followed by a file extension, specifies the file type.
+ * See the "lang-*.js" files in this directory for code that implements
+ * per-language file handlers.
+ * <p>
+ * Change log:<br>
+ * cbeust, 2006/08/22
+ * <blockquote>
+ * Java annotations (start with "@") are now captured as literals ("lit")
+ * </blockquote>
+ */
+public class Prettify {
+
+ // 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,"
+ + "double,enum,extern,float,goto,int,long,register,short,signed,sizeof,"
+ + "static,struct,switch,typedef,union,unsigned,void,volatile";
+ public static final String COMMON_KEYWORDS = C_KEYWORDS + "," + "catch,class,delete,false,import,"
+ + "new,operator,private,protected,public,this,throw,true,try,typeof";
+ public static final String CPP_KEYWORDS = COMMON_KEYWORDS + "," + "alignof,align_union,asm,axiom,bool,"
+ + "concept,concept_map,const_cast,constexpr,decltype,"
+ + "dynamic_cast,explicit,export,friend,inline,late_check,"
+ + "mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,"
+ + "template,typeid,typename,using,virtual,where";
+ public static final String JAVA_KEYWORDS = COMMON_KEYWORDS + ","
+ + "abstract,boolean,byte,extends,final,finally,implements,import,"
+ + "instanceof,null,native,package,strictfp,super,synchronized,throws,"
+ + "transient";
+ public static final String CSHARP_KEYWORDS = JAVA_KEYWORDS + ","
+ + "as,base,by,checked,decimal,delegate,descending,dynamic,event,"
+ + "fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,"
+ + "object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,"
+ + "stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var";
+ public static final String COFFEE_KEYWORDS = "all,and,by,catch,class,else,extends,false,finally,"
+ + "for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,"
+ + "true,try,unless,until,when,while,yes";
+ public static final String JSCRIPT_KEYWORDS = COMMON_KEYWORDS + ","
+ + "debugger,eval,export,function,get,null,set,undefined,var,with,"
+ + "Infinity,NaN";
+ public static final String PERL_KEYWORDS = "caller,delete,die,do,dump,elsif,eval,exit,foreach,for,"
+ + "goto,if,import,last,local,my,next,no,our,print,package,redo,require,"
+ + "sub,undef,unless,until,use,wantarray,while,BEGIN,END";
+ public static final String PYTHON_KEYWORDS = FLOW_CONTROL_KEYWORDS + "," + "and,as,assert,class,def,del,"
+ + "elif,except,exec,finally,from,global,import,in,is,lambda,"
+ + "nonlocal,not,or,pass,print,raise,try,with,yield,"
+ + "False,True,None";
+ public static final String RUBY_KEYWORDS = FLOW_CONTROL_KEYWORDS + "," + "alias,and,begin,case,class,"
+ + "def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,"
+ + "rescue,retry,self,super,then,true,undef,unless,until,when,yield,"
+ + "BEGIN,END";
+ public static final String SH_KEYWORDS = FLOW_CONTROL_KEYWORDS + "," + "case,done,elif,esac,eval,fi,"
+ + "function,in,local,set,then,until";
+ public static final String ALL_KEYWORDS = CPP_KEYWORDS + "," + CSHARP_KEYWORDS + "," + JSCRIPT_KEYWORDS + "," + PERL_KEYWORDS + ","
+ + PYTHON_KEYWORDS + "," + RUBY_KEYWORDS + "," + SH_KEYWORDS;
+ public static final Pattern C_TYPES = Pattern.compile("^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\\d*)");
+ // token style names. correspond to css classes
+ /**
+ * token style for a string literal
+ */
+ public static final String PR_STRING = "str";
+ /**
+ * token style for a keyword
+ */
+ public static final String PR_KEYWORD = "kwd";
+ /**
+ * token style for a comment
+ */
+ public static final String PR_COMMENT = "com";
+ /**
+ * token style for a type
+ */
+ public static final String PR_TYPE = "';";
+ /**
+ * token style for a literal value. e.g. 1, null, true.
+ */
+ public static final String PR_LITERAL = "lit";
+ /**
+ * token style for a punctuation string.
+ */
+ public static final String PR_PUNCTUATION = "pun";
+ /**
+ * token style for a plain text.
+ */
+ public static final String PR_PLAIN = "pln";
+ /**
+ * token style for an sgml tag.
+ */
+ public static final String PR_TAG = "tag";
+ /**
+ * token style for a markup declaration such as a DOCTYPE.
+ */
+ public static final String PR_DECLARATION = "dec";
+ /**
+ * token style for embedded source.
+ */
+ public static final String PR_SOURCE = "src";
+ /**
+ * token style for an sgml attribute name.
+ */
+ public static final String PR_ATTRIB_NAME = "atn";
+ /**
+ * token style for an sgml attribute value.
+ */
+ public static final String PR_ATTRIB_VALUE = "atv";
+ /**
+ * A class that indicates a section of markup that is not code, e.g. to allow
+ * embedding of line numbers within code listings.
+ */
+ public static final String PR_NOCODE = "nocode";
+ /**
+ * A set of tokens that can precede a regular expression literal in
+ * javascript
+ * http://web.archive.org/web/20070717142515/http://www.mozilla.org/js/language/js20/rationale/syntax.html
+ * has the full list, but I've removed ones that might be problematic when
+ * seen in languages that don't support regular expression literals.
+ *
+ * <p>Specifically, I've removed any keywords that can't precede a regexp
+ * literal in a syntactically legal javascript program, and I've removed the
+ * "in" keyword since it's not a keyword in many languages, and might be used
+ * as a count of inches.
+ *
+ * <p>The link above does not accurately describe EcmaScript rules since
+ * it fails to distinguish between (a=++/b/i) and (a++/b/i) but it works
+ * very well in practice.
+ */
+ private static final String REGEXP_PRECEDER_PATTERN = "(?:^^\\.?|[+-]|[!=]=?=?|\\#|%=?|&&?=?|\\(|\\*=?|[+\\-]=|->|\\/=?|::?|<<?=?|>>?>?=?|,|;|\\?|@|\\[|~|\\{|\\^\\^?=?|\\|\\|?=?|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";
+ // CAVEAT: this does not properly handle the case where a regular
+ // expression immediately follows another since a regular expression may
+ // have flags for case-sensitivity and the like. Having regexp tokens
+ // adjacent is not valid in any language I'm aware of, so I'm punting.
+ // TODO: maybe style special characters inside a regexp as punctuation.
+
+ public Prettify() {
+ try {
+ Map<String, Object> decorateSourceMap = new HashMap<String, Object>();
+ decorateSourceMap.put("keywords", ALL_KEYWORDS);
+ decorateSourceMap.put("hashComments", true);
+ decorateSourceMap.put("cStyleComments", true);
+ decorateSourceMap.put("multiLineStrings", true);
+ 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>>();
+ 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]*?(?:-\\->|$)")}));
+ // Unescaped content in an unknown language
+ fallthroughStylePatterns.add(Arrays.asList(new Object[]{"lang-", Pattern.compile("^<\\?([\\s\\S]+?)(?:\\?>|$)")}));
+ fallthroughStylePatterns.add(Arrays.asList(new Object[]{"lang-", Pattern.compile("^<%([\\s\\S]+?)(?:%>|$)")}));
+ fallthroughStylePatterns.add(Arrays.asList(new Object[]{PR_PUNCTUATION, Pattern.compile("^(?:<[%?]|[%?]>)")}));
+ fallthroughStylePatterns.add(Arrays.asList(new Object[]{"lang-", Pattern.compile("^<xmp\\b[^>]*>([\\s\\S]+?)<\\/xmp\\b[^>]*>", Pattern.CASE_INSENSITIVE)}));
+ // Unescaped content in javascript. (Or possibly vbscript).
+ fallthroughStylePatterns.add(Arrays.asList(new Object[]{"lang-js", Pattern.compile("^<script\\b[^>]*>([\\s\\S]*?)(<\\/script\\b[^>]*>)", Pattern.CASE_INSENSITIVE)}));
+ // Contains unescaped stylesheet content
+ fallthroughStylePatterns.add(Arrays.asList(new Object[]{"lang-css", Pattern.compile("^<style\\b[^>]*>([\\s\\S]*?)(<\\/style\\b[^>]*>)", Pattern.CASE_INSENSITIVE)}));
+ fallthroughStylePatterns.add(Arrays.asList(new Object[]{"lang-in.tag", Pattern.compile("^(<\\/?[a-z][^<>]*>)", Pattern.CASE_INSENSITIVE)}));
+ registerLangHandler(new CreateSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns), Arrays.asList(new String[]{"default-markup", "htm", "html", "mxml", "xhtml", "xml", "xsl"}));
+
+ shortcutStylePatterns = new ArrayList<List<Object>>();
+ fallthroughStylePatterns = new ArrayList<List<Object>>();
+ shortcutStylePatterns.add(Arrays.asList(new Object[]{PR_PLAIN, Pattern.compile("^[\\s]+"), null, " \t\r\n"}));
+ shortcutStylePatterns.add(Arrays.asList(new Object[]{PR_ATTRIB_VALUE, Pattern.compile("^(?:\\\"[^\\\"]*\\\"?|\\'[^\\']*\\'?)"), null, " \t\r\n"}));
+ fallthroughStylePatterns.add(Arrays.asList(new Object[]{"lang-uq.val", Pattern.compile("^^<\\/?[a-z](?:[\\w.:-]*\\w)?|\\/?>$", Pattern.CASE_INSENSITIVE)}));
+ fallthroughStylePatterns.add(Arrays.asList(new Object[]{PR_PUNCTUATION, Pattern.compile("^[=<>\\/]+")}));
+ fallthroughStylePatterns.add(Arrays.asList(new Object[]{"lang-js", Pattern.compile("^on\\w+\\s*=\\s*\\\"([^\\\"]+)\\\"", Pattern.CASE_INSENSITIVE)}));
+ fallthroughStylePatterns.add(Arrays.asList(new Object[]{"lang-js", Pattern.compile("^on\\w+\\s*=\\s*\\'([^\\']+)\\'", Pattern.CASE_INSENSITIVE)}));
+ fallthroughStylePatterns.add(Arrays.asList(new Object[]{"lang-js", Pattern.compile("^on\\w+\\s*=\\s*([^\\\"\\'>\\s]+)", Pattern.CASE_INSENSITIVE)}));
+ fallthroughStylePatterns.add(Arrays.asList(new Object[]{"lang-css", Pattern.compile("^style\\s*=\\s*\\\"([^\\\"]+)\\\"", Pattern.CASE_INSENSITIVE)}));
+ fallthroughStylePatterns.add(Arrays.asList(new Object[]{"lang-css", Pattern.compile("^style\\s*=\\s*\\'([^\\']+)\\'", Pattern.CASE_INSENSITIVE)}));
+ fallthroughStylePatterns.add(Arrays.asList(new Object[]{"lang-css", Pattern.compile("^style\\s*=\\s\\*([^\\\"\\'>\\s]+)", Pattern.CASE_INSENSITIVE)}));
+ registerLangHandler(new CreateSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns), Arrays.asList(new String[]{"in.tag"}));
+
+ shortcutStylePatterns = new ArrayList<List<Object>>();
+ fallthroughStylePatterns = new ArrayList<List<Object>>();
+ fallthroughStylePatterns.add(Arrays.asList(new Object[]{PR_ATTRIB_VALUE, Pattern.compile("^[\\s\\S]+")}));
+ registerLangHandler(new CreateSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns), Arrays.asList(new String[]{"uq.val"}));
+
+ decorateSourceMap = new HashMap<String, Object>();
+ decorateSourceMap.put("keywords", CPP_KEYWORDS);
+ decorateSourceMap.put("hashComments", true);
+ decorateSourceMap.put("cStyleComments", true);
+ decorateSourceMap.put("types", C_TYPES);
+ registerLangHandler(sourceDecorator(decorateSourceMap), Arrays.asList(new String[]{"c", "cc", "cpp", "cxx", "cyc", "m"}));
+
+ decorateSourceMap = new HashMap<String, Object>();
+ decorateSourceMap.put("keywords", "null,true,false");
+ registerLangHandler(sourceDecorator(decorateSourceMap), Arrays.asList(new String[]{"json"}));
+
+ decorateSourceMap = new HashMap<String, Object>();
+ decorateSourceMap.put("keywords", CSHARP_KEYWORDS);
+ decorateSourceMap.put("hashComments", true);
+ decorateSourceMap.put("cStyleComments", true);
+ decorateSourceMap.put("verbatimStrings", true);
+ decorateSourceMap.put("types", C_TYPES);
+ registerLangHandler(sourceDecorator(decorateSourceMap), Arrays.asList(new String[]{"cs"}));
+
+ decorateSourceMap = new HashMap<String, Object>();
+ decorateSourceMap.put("keywords", JAVA_KEYWORDS);
+ decorateSourceMap.put("cStyleComments", true);
+ registerLangHandler(sourceDecorator(decorateSourceMap), Arrays.asList(new String[]{"java"}));
+
+ decorateSourceMap = new HashMap<String, Object>();
+ decorateSourceMap.put("keywords", SH_KEYWORDS);
+ decorateSourceMap.put("hashComments", true);
+ decorateSourceMap.put("multiLineStrings", true);
+ registerLangHandler(sourceDecorator(decorateSourceMap), Arrays.asList(new String[]{"bsh", "csh", "sh"}));
+
+ decorateSourceMap = new HashMap<String, Object>();
+ decorateSourceMap.put("keywords", PYTHON_KEYWORDS);
+ decorateSourceMap.put("hashComments", true);
+ decorateSourceMap.put("multiLineStrings", true);
+ decorateSourceMap.put("tripleQuotedStrings", true);
+ registerLangHandler(sourceDecorator(decorateSourceMap), Arrays.asList(new String[]{"cv", "py"}));
+
+ decorateSourceMap = new HashMap<String, Object>();
+ decorateSourceMap.put("keywords", PERL_KEYWORDS);
+ decorateSourceMap.put("hashComments", true);
+ decorateSourceMap.put("multiLineStrings", true);
+ decorateSourceMap.put("regexLiterals", true);
+ registerLangHandler(sourceDecorator(decorateSourceMap), Arrays.asList(new String[]{"perl", "pl", "pm"}));
+
+ decorateSourceMap = new HashMap<String, Object>();
+ decorateSourceMap.put("keywords", RUBY_KEYWORDS);
+ decorateSourceMap.put("hashComments", true);
+ decorateSourceMap.put("multiLineStrings", true);
+ decorateSourceMap.put("regexLiterals", true);
+ registerLangHandler(sourceDecorator(decorateSourceMap), Arrays.asList(new String[]{"rb"}));
+
+ decorateSourceMap = new HashMap<String, Object>();
+ decorateSourceMap.put("keywords", JSCRIPT_KEYWORDS);
+ decorateSourceMap.put("cStyleComments", true);
+ decorateSourceMap.put("regexLiterals", true);
+ registerLangHandler(sourceDecorator(decorateSourceMap), Arrays.asList(new String[]{"js"}));
+
+ decorateSourceMap = new HashMap<String, Object>();
+ decorateSourceMap.put("keywords", COFFEE_KEYWORDS);
+ decorateSourceMap.put("hashComments", 3); // ### style block comments
+ decorateSourceMap.put("cStyleComments", true);
+ decorateSourceMap.put("multilineStrings", true);
+ decorateSourceMap.put("tripleQuotedStrings", true);
+ decorateSourceMap.put("regexLiterals", true);
+ registerLangHandler(sourceDecorator(decorateSourceMap), Arrays.asList(new String[]{"coffee"}));
+
+ shortcutStylePatterns = new ArrayList<List<Object>>();
+ 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"}));
+ } catch (Exception ex) {
+ Logger.getLogger(Prettify.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+
+ /**
+ * Apply the given language handler to sourceCode and add the resulting
+ * decorations to out.
+ * @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) {
+ if (sourceCode == null) {
+ throw new NullPointerException("argument 'sourceCode' cannot be null");
+ }
+ Job job = new Job();
+ job.setSourceCode(sourceCode);
+ job.setBasePos(basePos);
+ langHandler.decorate(job);
+ out.addAll(job.getDecorations());
+ }
+
+ public class CreateSimpleLexer {
+
+ protected List<List<Object>> fallthroughStylePatterns;
+ protected Map<Character, List<Object>> shortcuts = new HashMap<Character, List<Object>>();
+ protected Pattern tokenizer;
+ protected int nPatterns;
+
+ /** Given triples of [style, pattern, context] returns a lexing function,
+ * The lexing function interprets the patterns to find token boundaries and
+ * returns a decoration list of the form
+ * [index_0, style_0, index_1, style_1, ..., index_n, style_n]
+ * where index_n is an index into the sourceCode, and style_n is a style
+ * constant like PR_PLAIN. index_n-1 <= index_n, and style_n-1 applies to
+ * all characters in sourceCode[index_n-1:index_n].
+ *
+ * The stylePatterns is a list whose elements have the form
+ * [style : string, pattern : RegExp, DEPRECATED, shortcut : string].
+ *
+ * Style is a style constant like PR_PLAIN, or can be a string of the
+ * form 'lang-FOO', where FOO is a language extension describing the
+ * language of the portion of the token in $1 after pattern executes.
+ * E.g., if style is 'lang-lisp', and group 1 contains the text
+ * '(hello (world))', then that portion of the token will be passed to the
+ * registered lisp handler for formatting.
+ * The text before and after group 1 will be restyled using this decorator
+ * so decorators should take care that this doesn't result in infinite
+ * recursion. For example, the HTML lexer rule for SCRIPT elements looks
+ * something like ['lang-js', /<[s]cript>(.+?)<\/script>/]. This may match
+ * '<script>foo()<\/script>', which would cause the current decorator to
+ * be called with '<script>' which would not match the same rule since
+ * group 1 must not be empty, so it would be instead styled as PR_TAG by
+ * the generic tag rule. The handler registered for the 'js' extension would
+ * then be called with 'foo()', and finally, the current decorator would
+ * be called with '<\/script>' which would not match the original rule and
+ * so the generic tag rule would identify it as a tag.
+ *
+ * Pattern must only match prefixes, and if it matches a prefix, then that
+ * match is considered a token with the same style.
+ *
+ * Context is applied to the last non-whitespace, non-comment token
+ * recognized.
+ *
+ * Shortcut is an optional string of characters, any of which, if the first
+ * character, gurantee that this pattern and only this pattern matches.
+ *
+ * @param shortcutStylePatterns patterns that always start with
+ * a known character. Must have a shortcut string.
+ * @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 {
+ this.fallthroughStylePatterns = fallthroughStylePatterns;
+
+ List<List<Object>> allPatterns = new ArrayList<List<Object>>(shortcutStylePatterns);
+ allPatterns.addAll(fallthroughStylePatterns);
+ List<Pattern> allRegexs = new ArrayList<Pattern>();
+ Map<String, Object> regexKeys = new HashMap<String, Object>();
+ for (int i = 0, n = allPatterns.size(); i < n; ++i) {
+ List<Object> patternParts = allPatterns.get(i);
+ String shortcutChars = patternParts.size() > 4 ? (String) patternParts.get(3) : null;
+ if (shortcutChars != null) {
+ for (int c = shortcutChars.length(); --c >= 0;) {
+ shortcuts.put(shortcutChars.charAt(c), patternParts);
+ }
+ }
+ Pattern regex = (Pattern) patternParts.get(1);
+ String k = regex.pattern();
+ if (regexKeys.get(k) == null) {
+ allRegexs.add(regex);
+ regexKeys.put(k, new Object());
+ }
+ }
+ allRegexs.add(Pattern.compile("[\0-\\uffff]"));
+ tokenizer = new CombinePrefixPattern().combinePrefixPattern(allRegexs);
+
+ nPatterns = fallthroughStylePatterns.size();
+ }
+
+ /**
+ * Lexes job.sourceCode and produces an output array job.decorations of
+ * style classes preceded by the position at which they start in
+ * job.sourceCode in order.
+ *
+ * @param job an object like <pre>{
+ * sourceCode: {string} sourceText plain text,
+ * basePos: {int} position of job.sourceCode in the larger chunk of
+ * sourceCode.
+ * }</pre>
+ */
+ public void decorate(Job job) {
+ String sourceCode = job.getSourceCode();
+ int basePos = job.getBasePos();
+ /** Even entries are positions in source in ascending order. Odd enties
+ * are style markers (e.g., PR_COMMENT) that run from that position until
+ * the end.
+ * @type {Array.<number|string>}
+ */
+ List<Object> decorations = new ArrayList<Object>(Arrays.asList(new Object[]{basePos, PR_PLAIN}));
+ int pos = 0; // index into sourceCode
+ String[] tokens = Util.match(tokenizer, sourceCode);
+ Map<String, String> styleCache = new HashMap<String, String>();
+
+ for (int ti = 0, nTokens = tokens.length; ti < nTokens; ++ti) {
+ String token = tokens[ti];
+ String style = styleCache.get(token);
+ String[] match = null;
+
+ boolean isEmbedded;
+ if (style != null) {
+ isEmbedded = false;
+ } else {
+ List<Object> patternParts = shortcuts.get(token.charAt(0));
+ if (patternParts != null) {
+ match = Util.match((Pattern) patternParts.get(1), token);
+ style = (String) patternParts.get(0);
+ } else {
+ for (int i = 0; i < nPatterns; ++i) {
+ patternParts = fallthroughStylePatterns.get(i);
+ match = Util.match((Pattern) patternParts.get(1), token);
+ if (match.length != 0) {
+ style = (String) patternParts.get(0);
+ break;
+ }
+ }
+
+ if (match.length == 0) { // make sure that we make progress
+ style = PR_PLAIN;
+ }
+ }
+
+ isEmbedded = style != null && style.length() >= 5 && style.startsWith("lang-");
+ if (isEmbedded && !(match.length > 1)) {
+ isEmbedded = false;
+ style = PR_SOURCE;
+ }
+
+ if (!isEmbedded) {
+ styleCache.put(token, style);
+ }
+ }
+
+ int tokenStart = pos;
+ pos += token.length();
+
+ if (!isEmbedded) {
+ decorations.add(basePos + tokenStart);
+ decorations.add(style);
+ } else { // Treat group 1 as an embedded block of source code.
+ String embeddedSource = match[1];
+ int embeddedSourceStart = token.indexOf(embeddedSource);
+ int embeddedSourceEnd = embeddedSourceStart + embeddedSource.length();
+ if (match.length > 2) {
+ // If embeddedSource can be blank, then it would match at the
+ // beginning which would cause us to infinitely recurse on the
+ // entire token, so we catch the right context in match[2].
+ embeddedSourceEnd = token.length() - match[2].length();
+ embeddedSourceStart = embeddedSourceEnd = embeddedSource.length();
+ }
+ String lang = style.substring(5);
+ // Decorate the left of the embedded source
+ appendDecorations(basePos + tokenStart,
+ token.substring(0, embeddedSourceStart),
+ this, decorations);
+ // Decorate the embedded source
+ appendDecorations(basePos + tokenStart + embeddedSourceStart,
+ embeddedSource,
+ langHandlerForExtension(lang, embeddedSource),
+ decorations);
+ // Decorate the right of the embedded section
+ appendDecorations(basePos + tokenStart + embeddedSourceEnd,
+ token.substring(embeddedSourceEnd),
+ this, decorations);
+ }
+ }
+
+ job.setDecorations(decorations);
+ }
+ }
+
+ /** returns a function that produces a list of decorations from source text.
+ *
+ * This code treats ", ', and ` as string delimiters, and \ as a string
+ * escape. It does not recognize perl's qq() style strings.
+ * It has no special handling for double delimiter escapes as in basic, or
+ * the tripled delimiters used in python, but should work on those regardless
+ * although in those cases a single string literal may be broken up into
+ * multiple adjacent string literals.
+ *
+ * It recognizes C, C++, and shell style comments.
+ *
+ * @param options a set of optional parameters.
+ * @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 {
+ List<List<Object>> shortcutStylePatterns = new ArrayList<List<Object>>();
+ List<List<Object>> fallthroughStylePatterns = new ArrayList<List<Object>>();
+ if (options.get("tripleQuotedStrings") != null) {
+ // '''multi-line-string''', 'single-line-string', and double-quoted
+ shortcutStylePatterns.add(Arrays.asList(new Object[]{PR_STRING,
+ Pattern.compile("^(?:\\'\\'\\'(?:[^\\'\\\\]|\\\\[\\s\\S]|\\'{1,2}(?=[^\\']))*(?:\\'\\'\\'|$)|\\\"\\\"\\\"(?:[^\\\"\\\\]|\\\\[\\s\\S]|\\\"{1,2}(?=[^\\\"]))*(?:\\\"\\\"\\\"|$)|\\'(?:[^\\\\\\']|\\\\[\\s\\S])*(?:\\'|$)|\\\"(?:[^\\\\\\\"]|\\\\[\\s\\S])*(?:\\\"|$))"),
+ null,
+ "'\""}));
+ } else if (options.get("multiLineStrings") != null) {
+ // 'multi-line-string', "multi-line-string"
+ shortcutStylePatterns.add(Arrays.asList(new Object[]{PR_STRING,
+ Pattern.compile("^(?:\\'(?:[^\\\\\\']|\\\\[\\s\\S])*(?:\\'|$)|\\\"(?:[^\\\\\\\"]|\\\\[\\s\\S])*(?:\\\"|$)|\\`(?:[^\\\\\\`]|\\\\[\\s\\S])*(?:\\`|$))"),
+ null,
+ "'\"`"}));
+ } else {
+ // 'single-line-string', "single-line-string"
+ shortcutStylePatterns.add(Arrays.asList(new Object[]{PR_STRING,
+ Pattern.compile("^(?:\\'(?:[^\\\\\\'\r\n]|\\\\.)*(?:\\'|$)|\\\"(?:[^\\\\\\\"\r\n]|\\\\.)*(?:\\\"|$))"),
+ null,
+ "\"'"}));
+ }
+ if (options.get("verbatinStrings") != null) {
+ // verbatim-string-literal production from the C# grammar. See issue 93.
+ fallthroughStylePatterns.add(Arrays.asList(new Object[]{PR_STRING,
+ Pattern.compile("^@\\\"(?:[^\\\"]|\\\"\\\")*(?:\\\"|$)"),
+ null}));
+ }
+ Object hc = options.get("hashComments");
+ if (hc != null) {
+ if (options.get("cStyleComments") != null) {
+ if ((hc instanceof Integer) && (Integer) hc > 1) { // multiline hash comments
+ shortcutStylePatterns.add(Arrays.asList(new Object[]{PR_COMMENT,
+ Pattern.compile("^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)"),
+ null,
+ "#"}));
+ } else {
+ // Stop C preprocessor declarations at an unclosed open comment
+ shortcutStylePatterns.add(Arrays.asList(new Object[]{PR_COMMENT,
+ Pattern.compile("^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\\b|[^\r\n]*)"),
+ null,
+ "#"}));
+ }
+ fallthroughStylePatterns.add(Arrays.asList(new Object[]{PR_STRING,
+ Pattern.compile("^<(?:(?:(?:\\.\\.\\/)*|\\/?)(?:[\\w-]+(?:\\/[\\w-]+)+)?[\\w-]+\\.h|[a-z]\\w*)>"),
+ null}));
+ } else {
+ shortcutStylePatterns.add(Arrays.asList(new Object[]{PR_COMMENT,
+ Pattern.compile("^#[^\r\n]*"),
+ null,
+ "#"}));
+ }
+ }
+ if (options.get("cStyleComments") != null) {
+ fallthroughStylePatterns.add(Arrays.asList(new Object[]{PR_COMMENT,
+ Pattern.compile("^\\/\\/[^\r\n]*"),
+ null}));
+
+ fallthroughStylePatterns.add(Arrays.asList(new Object[]{PR_COMMENT,
+ Pattern.compile("^\\/\\*[\\s\\S]*?(?:\\*\\/|$)"),
+ null}));
+ }
+ if (options.get("regexLiterals") != null) {
+ /**
+ * @const
+ */
+ String REGEX_LITERAL =
+ // A regular expression literal starts with a slash that is
+ // not followed by * or / so that it is not confused with
+ // comments.
+ "/(?=[^/*])"
+ // and then contains any number of raw characters,
+ + "(?:[^/\\x5B\\x5C]"
+ // escape sequences (\x5C),
+ + "|\\x5C[\\s\\S]"
+ // or non-nesting character sets (\x5B\x5D);
+ + "|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+"
+ // finally closed by a /.
+ + "/";
+ fallthroughStylePatterns.add(Arrays.asList(new Object[]{"lang-regex",
+ Pattern.compile("^" + REGEXP_PRECEDER_PATTERN + "(" + REGEX_LITERAL + ")")}));
+ }
+
+ Pattern types = (Pattern) options.get("types");
+ if (types != null) {
+ fallthroughStylePatterns.add(Arrays.asList(new Object[]{PR_TYPE, types}));
+ }
+
+ if (options.get("keywords") != null) {
+ String keywords = ((String) options.get("keywords")).replaceAll("^ | $", "");
+ if (keywords.length() != 0) {
+ fallthroughStylePatterns.add(Arrays.asList(new Object[]{PR_KEYWORD,
+ Pattern.compile("^(?:" + keywords.replaceAll("[\\s,]+", "|") + ")\\b"),
+ null}));
+ }
+ }
+
+ shortcutStylePatterns.add(Arrays.asList(new Object[]{PR_PLAIN,
+ Pattern.compile("^\\s+"),
+ null,
+ " \r\n\t\\xA0"
+ }));
+
+ // TODO(mikesamuel): recognize non-latin letters and numerals in idents
+ fallthroughStylePatterns.add(Arrays.asList(new Object[]{PR_LITERAL,
+ Pattern.compile("^@[a-z_$][a-z_$@0-9]*", Pattern.CASE_INSENSITIVE),
+ null}));
+ fallthroughStylePatterns.add(Arrays.asList(new Object[]{PR_TYPE,
+ Pattern.compile("^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\\w+_t\\b)"),
+ null}));
+ fallthroughStylePatterns.add(Arrays.asList(new Object[]{PR_PLAIN,
+ Pattern.compile("^[a-z_$][a-z_$@0-9]*", Pattern.CASE_INSENSITIVE),
+ null}));
+ fallthroughStylePatterns.add(Arrays.asList(new Object[]{PR_LITERAL,
+ Pattern.compile("^(?:"
+ // A hex number
+ + "0x[a-f0-9]+"
+ // or an octal or decimal number,
+ + "|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)"
+ // possibly in scientific notation
+ + "(?:e[+\\-]?\\d+)?"
+ + ')'
+ // with an optional modifier like UL for unsigned long
+ + "[a-z]*", Pattern.CASE_INSENSITIVE),
+ null,
+ "0123456789"}));
+ // Don't treat escaped quotes in bash as starting strings. See issue 144.
+ fallthroughStylePatterns.add(Arrays.asList(new Object[]{PR_PLAIN,
+ Pattern.compile("^\\\\[\\s\\S]?"),
+ null}));
+ fallthroughStylePatterns.add(Arrays.asList(new Object[]{PR_PUNCTUATION,
+ Pattern.compile("^.[^\\s\\w\\.$@\\'\\\"\\`\\/\\#\\\\]*"),
+ null}));
+
+ return new CreateSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns);
+ }
+ /** Maps language-specific file extensions to handlers. */
+ protected Map<String, CreateSimpleLexer> langHandlerRegistry = new HashMap<String, CreateSimpleLexer>();
+
+ /** Register a language handler for the given file extensions.
+ * @param handler a function from source code to a list
+ * of decorations. Takes a single argument job which describes the
+ * state of the computation. The single parameter has the form
+ * {@code {
+ * sourceCode: {string} as plain text.
+ * decorations: {Array.<number|string>} an array of style classes
+ * preceded by the position at which they start in
+ * job.sourceCode in order.
+ * The language handler should assigned this field.
+ * basePos: {int} the position of source in the larger source chunk.
+ * All positions in the output decorations array are relative
+ * to the larger source chunk.
+ * } }
+ * @param fileExtensions
+ */
+ public 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) {
+ langHandlerRegistry.put(ext, handler);
+ } else {
+ throw new Exception("cannot override language handler " + ext);
+ }
+ }
+ }
+
+ 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
+ // the last non-whitespace character is a >.
+ extension = source.matches("^\\s&<")
+ ? "default-markup"
+ : "default-code";
+ }
+ return langHandlerRegistry.get(extension);
+ }
+
+ public static void main(String[] args) throws IOException {
+ Job job = new Job();
+ job.setBasePos(0);
+ job.setSourceCode(new String(Util.readResourceFile("/prettify/example.html")));
+ Prettify prettify = new Prettify();
+ prettify.langHandlerRegistry.get("html").decorate(job);
+ List<Object> decorations = job.getDecorations();
+ System.out.println(decorations);
+ }
+}
diff --git a/src/prettify/Util.java b/src/prettify/Util.java
new file mode 100644
index 0000000..3f53f93
--- /dev/null
+++ b/src/prettify/Util.java
@@ -0,0 +1,86 @@
+package prettify;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @author Chan Wai Shing <cws1989@gmail.com>
+ */
+public class Util {
+
+ /**
+ * Read the resource file from the jar.
+ * @param path the resource path
+ * @return the content of the resource file in byte array
+ * @throws IOException error occurred when reading the content from the file
+ */
+ public static byte[] readResourceFile(String path) throws IOException {
+ if (path == null) {
+ throw new NullPointerException("argument 'path' cannot be null");
+ }
+
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ InputStream in = null;
+ try {
+ in = Util.class.getResourceAsStream(path);
+ if (in == null) {
+ throw new IOException("Resources not found: " + path);
+ }
+
+ int byteRead = 0;
+ byte[] b = new byte[8096];
+
+ while ((byteRead = in.read(b)) != -1) {
+ bout.write(b, 0, byteRead);
+ }
+ } finally {
+ if (in != null) {
+ try {
+ in.close();
+ } catch (IOException ex) {
+ }
+ }
+ }
+
+ return bout.toByteArray();
+ }
+
+ public static String[] match(Pattern pattern, String string) {
+ List<String> matchesList = new ArrayList<String>();
+
+ Matcher matcher = pattern.matcher(string);
+ while (matcher.find()) {
+ matchesList.add(matcher.group(0));
+ }
+
+ return matchesList.toArray(new String[matchesList.size()]);
+ }
+
+ public static String join(List<String> strings) {
+ return join(strings.toArray(new String[strings.size()]));
+ }
+
+ public static String join(List<String> strings, String delimiter) {
+ return join(strings.toArray(new String[strings.size()]), delimiter);
+ }
+
+ public static String join(String[] strings) {
+ return join(strings, null);
+ }
+
+ public static String join(String[] strings, String delimiter) {
+ StringBuilder sb = new StringBuilder();
+ for (String string : strings) {
+ if (delimiter != null && sb.length() != 0) {
+ sb.append(delimiter);
+ }
+ sb.append(string);
+ }
+ return sb.toString();
+ }
+}
diff --git a/src/prettify/example.html b/src/prettify/example.html
new file mode 100644
index 0000000..1ef22ae
--- /dev/null
+++ b/src/prettify/example.html
@@ -0,0 +1,47 @@
+<html>
+<head>
+ <title> HTML Script Example </title>
+ <style type="text/css">
+ body {
+ font-family: Helvetica, Geneva, Arial, sans-serif;
+ font-size: 1em;
+ margin: 4em 15em 4em 4em;
+ }
+ body.with_sponsor { margin-right: 410px; }
+ a.external {
+ background: url(../images/external.png) right 50% no-repeat;
+ padding-right: 12px;
+ }
+ code, pre, .file-list {
+ font-family: Consolas, Monaco, "Bitstream Vera Sans Mono", "Courier New", Courier, monospace;
+ }
+ </style>
+ <script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-XXXXX-XX']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script>
+</head>
+<body>
+
+<div style="font-weight: bold"><?= str_replace("\n", "<br/>", $var) ?></div>
+<?php
+ /***********************************
+ ** Multiline block comments
+ **********************************/
+
+ $stringWithUrl = "http://alexgorbatchev.com";
+ $stringWithUrl = 'http://alexgorbatchev.com';
+
+ ob_start("parseOutputBuffer"); // Start Code Buffering
+ session_start();
+?>
+
+</body>
+</html>
\ No newline at end of file