diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..433f78b2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,18 @@ +# temporary files +*~ +*.swp +.DS_Store + +# package managers +/node_modules/ +/bower_components/ +npm-debug.log +.bower.json + +# generated files +#/src/prettify.js +#/src/run_prettify.js +#/loader/*.js +#/loader/*.css +#/loader/skins/*.css +#/distrib/*.zip diff --git a/CHANGES.html b/CHANGES.html deleted file mode 100644 index 32665d77..00000000 --- a/CHANGES.html +++ /dev/null @@ -1,162 +0,0 @@ - - - - Change Log - - - README - -

Known Issues

- - -

Change Log

-

29 March 2007

- -

4 Jul 2008

- -

5 Jul 2008

- -

14 Jul 2008

- -

6 Jan 2009

- -

21 May 2009

- -

14 August 2009

- -

3 October 2009

- -

19 July 2010

- -

7 September 2010

- -

4 March 2011

- -

29 March 2011

- -

4 February 2013

- - - diff --git a/CHANGES.md b/CHANGES.md new file mode 100644 index 00000000..7371e7c8 --- /dev/null +++ b/CHANGES.md @@ -0,0 +1,137 @@ +# Known Issues + + * Perl formatting is really crappy. Partly because the author is lazy and partly + because Perl is [hard](http://www.perlmonks.org/?node_id=663393) to parse. + * On some browsers, `` elements with newlines in the text which use CSS + to specify `white-space:pre` will have the newlines improperly stripped if + the element is not attached to the document at the time the stripping is done. + Also, on IE6, all newlines will be stripped from `` elements because + of the way IE6 produces `innerHTML`. Workaround: use `
` for code with
+   newlines.
+
+# Change Log
+
+## 29 March 2007
+
+ * Added [tests](https://raw.githack.com/google/code-prettify/master/tests/prettify_test.html#php)
+   for PHP support to address issue [#3](https://github.com/google/code-prettify/issues/3).
+ * Fixed bug [#6](https://github.com/google/code-prettify/issues/6): `prettyPrintOne`
+   was not halting. This was not reachable through the normal entry point.
+ * Fixed bug [#4](https://github.com/google/code-prettify/issues/4): recursing into a
+   script block or PHP tag that was not properly closed would not silently drop the content.
+   ([test](https://raw.githack.com/google/code-prettify/master/tests/prettify_test.html#js_script))
+ * Fixed bug [#8](https://github.com/google/code-prettify/issues/8): was eating tabs
+   ([test](https://raw.githack.com/google/code-prettify/master/tests/prettify_test.html#issue8))
+ * Fixed entity handling so that the caveat
+
+   > Caveats: please properly escape less-thans. `x<y` instead of `x and use `"` instead of `"` for string delimiters.
+
+   is no longer applicable.
+ * Added *noisefree*'s C# patch [#7](https://github.com/google/code-prettify/issues/7)
+ * Added a [distribution](http://google-code-prettify.googlecode.com/files/prettify-small.zip)
+   that has comments and whitespace removed to reduce download size from 45.5kB
+   to 12.8kB.
+
+## 4 Jul 2008
+
+ * Added [#17](https://github.com/google/code-prettify/issues/17) language specific
+   formatters that are triggered by the presence of a `lang-`
+ * Fixed bug [#29](https://github.com/google/code-prettify/issues/29): python
+   handling of `'''string'''`
+ * Fixed bug: `/` in regex `[charsets] should not end regex`
+
+## 5 Jul 2008
+
+ * Defined language extensions for Lisp and Lua
+
+## 14 Jul 2008
+
+ * Language handlers for F#, OCAML, SQL
+ * Support for `nocode` spans to allow embedding of line numbers and code
+   annotations which should not be styled or otherwise affect the tokenization
+   of prettified code. See the issue [#22](https://github.com/google/code-prettify/issues/22)
+   [testcase](https://raw.githack.com/google/code-prettify/master/tests/prettify_test.html#issue22).
+
+## 6 Jan 2009
+
+ * Language handlers for Visual Basic, Haskell, CSS, and WikiText
+ * Added `.mxml` extension to the markup style handler for
+   Flex [MXML files](http://en.wikipedia.org/wiki/MXML).
+   See issue [#37](https://github.com/google/code-prettify/issues/37).
+ * Added `.m` extension to the C style handler so that Objective C source files
+   properly highlight. See issue [#58](https://github.com/google/code-prettify/issues/58).
+ * Changed HTML lexer to use the same embedded source mechanism as the wiki
+   language handler, and changed to use the registered CSS handler for STYLE
+   element content.
+
+## 21 May 2009
+
+ * Rewrote to improve performance on large files.
+   See [benchmarks](http://mikesamuel.blogspot.com/2009/05/efficient-parsing-in-javascript.html).
+ * Fixed bugs with highlighting of Haskell line comments, Lisp number literals,
+   Lua strings, C preprocessor directives, newlines in Wiki code on Windows, and
+   newlines in IE6.
+
+## 14 August 2009
+
+ * Fixed prettifying of `` blocks with embedded newlines.
+
+## 3 October 2009
+
+ * Fixed prettifying of XML/HTML tags that contain uppercase letters.
+
+## 19 July 2010
+
+ * Added support for line numbers. Bug [#22](https://github.com/google/code-prettify/issues/22)
+ * Added YAML support. Bug [#123](https://github.com/google/code-prettify/issues/123)
+ * Added VHDL support courtesy *Le Poussin*.
+ * IE performance improvements. Bug [#102](https://github.com/google/code-prettify/issues/102)
+   courtesy *jacobly*.
+ * A variety of markup formatting fixes courtesy *smain* and *thezbyg*.
+ * Fixed copy and paste in IE 6, 7, 8.
+ * Changed output to use ` ` instead of ` ` so that the output works
+   when embedded in XML. Bug [#108](https://github.com/google/code-prettify/issues/108).
+
+## 7 September 2010
+
+ * Added support for coffeescript courtesy *Cezary Bartoszuk*.
+
+## 4 March 2011
+
+ * Added a [themes gallery](https://raw.githack.com/google/code-prettify/master/styles/index.html)
+   to showcase contributed styles.
+ * Added support for XQuery courtesy *Patrick Wied*, Nemerle courtesy *Zimin A.V.*,
+   and Latex support courtesy *Martin S*.
+
+## 29 March 2011
+
+ * Fixed IE newline issues, and copying/pasting of prettified source code from IE.
+   This required significant internal changes but involves no API changes.
+   **Caveat**: `prettyPrintOne` injects the HTML passed to it into a `
` element.
+   If the HTML comes from a trusted source, this may allow XSS. Do not do this.
+   This should not be a problem for existing apps since the standard usage is to
+   rewrite the HTML and then inject it, so anyone doing that with untrusted HTML
+   already has an XSS vulnerability. If you sanitize and prettify HTML from an
+   untrusted source, sanitize first.
+
+## 4 February 2013
+
+ * Language handlers for Dart, Erlang, Mumps, TCL, R, S., and others
+ * Bug fix: VB REM style comments.
+ * Bug fix: CSS color literals / ID selector confusion.
+ * Bug fix: IE8 line breaks.
+
+## 24 February 2013
+
+ * Added a one script autoload&run mechanism and a way to embed hints in
+   processing instructions/comments. See
+   [example](https://raw.githack.com/google/code-prettify/master/examples/quine.html).
+
+## 4 March 2013
+
+ * Matlab language handler courtesy *Amro³*
+
+## 28 Apr 2015
+
+ * Migrated to Github
diff --git a/Gruntfile.js b/Gruntfile.js
new file mode 100644
index 00000000..918a6b05
--- /dev/null
+++ b/Gruntfile.js
@@ -0,0 +1,263 @@
+/**
+ * google-code-prettify
+ * https://github.com/google/code-prettify
+ *
+ * Copyright (C) 2017 Google Inc.
+ * Licensed under Apache 2.0 license.
+ */
+
+module.exports = function (grunt) {
+  'use strict';
+
+  // project configuration
+  grunt.initConfig({
+    // metadata
+    pkg: grunt.file.readJSON('package.json'),
+
+    // grunt-preprocess
+    preprocess: {
+      // https://github.com/jsoverson/preprocess#optionstype
+      options: {
+        // renders @include directives (similar to SSI server-side includes)
+        // where JS files are resolved relative to this directory
+        srcDir: 'js-modules',
+        type: 'js'
+      },
+      prettify: {
+        src: 'js-modules/prettify.js',
+        dest: 'src/prettify.js'
+      },
+      runprettify: {
+        options: {
+          context: {
+            // to control where defs.js is included (top level)
+            RUN_PRETTIFY: true
+          }
+        },
+        src: 'js-modules/run_prettify.js',
+        dest: 'src/run_prettify.js'
+      },
+      nodeprettify: {
+        options: {
+          context: {
+            RUN_PRETTIFY: true
+          }
+        },
+        src: 'js-modules/node_prettify.js',
+        dest: 'src/node_prettify.js'
+      }
+    },
+
+    // grunt-contrib-copy
+    copy: {
+      prettify: {
+        options: {
+          process: function (content) {
+            // trim trailing whitespaces in blank lines added by preprocess
+            return content.replace(/[ \f\t\v]+$/gm, '');
+          }
+        },
+        files: [
+          {src: 'src/prettify.js', dest: 'src/prettify.js'},
+          {src: 'src/run_prettify.js', dest: 'src/run_prettify.js'},
+          {src: 'src/node_prettify.js', dest: 'src/node_prettify.js'}
+        ]
+      },
+      langs: {
+        options: {
+          process: function (content) {
+            // replace PR.PR_* token names with inlined strings
+            return content
+              .replace(/\bPR\.PR_ATTRIB_NAME\b/g,  '"atn"')
+              .replace(/\bPR\.PR_ATTRIB_VALUE\b/g, '"atv"')
+              .replace(/\bPR\.PR_COMMENT\b/g,      '"com"')
+              .replace(/\bPR\.PR_DECLARATION\b/g,  '"dec"')
+              .replace(/\bPR\.PR_KEYWORD\b/g,      '"kwd"')
+              .replace(/\bPR\.PR_LITERAL\b/g,      '"lit"')
+              .replace(/\bPR\.PR_NOCODE\b/g,       '"nocode"')
+              .replace(/\bPR\.PR_PLAIN\b/g,        '"pln"')
+              .replace(/\bPR\.PR_PUNCTUATION\b/g,  '"pun"')
+              .replace(/\bPR\.PR_SOURCE\b/g,       '"src"')
+              .replace(/\bPR\.PR_STRING\b/g,       '"str"')
+              .replace(/\bPR\.PR_TAG\b/g,          '"tag"')
+              .replace(/\bPR\.PR_TYPE\b/g,         '"typ"');
+          }
+        },
+        files: [{
+          expand: true,
+          cwd: 'loader/',
+          src: ['lang-*.js'],
+          dest: 'loader/'
+        }]
+      }
+    },
+
+    // ./tasks/aliases.js
+    aliases: {
+      langs: {
+        src: 'loader/lang-*.js',
+        filter: function (src) {
+          // skip files that are themselves aliases created in previous runs
+          return grunt.file.exists(src.replace(/^loader/, 'src'));
+        }
+      }
+    },
+
+    // grunt-contrib-uglify
+    uglify: {
+      // https://github.com/mishoo/UglifyJS2#usage
+      options: {
+        report: 'gzip',
+        ASCIIOnly: true,
+        maxLineLen: 500,
+        screwIE8: false
+      },
+      prettify: {
+        options: {
+          compress: {
+            global_defs: {'IN_GLOBAL_SCOPE': true}
+          },
+          wrap: true
+        },
+        src: 'src/prettify.js',
+        dest: 'loader/prettify.js'
+      },
+      runprettify: {
+        options: {
+          compress: {
+            global_defs: {'IN_GLOBAL_SCOPE': false}
+          },
+          wrap: true
+        },
+        src: 'src/run_prettify.js',
+        dest: 'loader/run_prettify.js'
+      },
+      langs: {
+        files: [{
+          expand: true,
+          cwd: 'src/',
+          src: ['lang-*.js'],
+          dest: 'loader/',
+          ext: '.js'
+        }]
+      }
+    },
+
+    // google-closure-compiler
+    'closure-compiler': {
+      // https://github.com/google/closure-compiler/wiki
+      options: {
+        // Don't specify --charset=UTF-8.  If we do, then non-ascii
+        // codepoints that do not correspond to line terminators are
+        // converted to UTF-8 sequences instead of being emitted as
+        // ASCII. This makes the resulting JavaScript less portable.
+        warning_level: 'VERBOSE',
+        language_in: 'ECMASCRIPT5',
+        compilation_level: 'ADVANCED',
+        charset: 'US-ASCII'
+      },
+      prettify: {
+        options: {
+          externs: 'tools/closure-compiler/amd-externs.js',
+          define: 'IN_GLOBAL_SCOPE=true',
+          output_wrapper: '!function(){%output%}()'
+        },
+        src: '<%= uglify.prettify.src %>',
+        dest: '<%= uglify.prettify.dest %>'
+      },
+      runprettify: {
+        options: {
+          externs: 'tools/closure-compiler/amd-externs.js',
+          define: 'IN_GLOBAL_SCOPE=false',
+          output_wrapper: '!function(){%output%}()'
+        },
+        src: '<%= uglify.runprettify.src %>',
+        dest: '<%= uglify.runprettify.dest %>'
+      },
+      langs: {
+        options: {
+          externs: 'js-modules/externs.js'
+        },
+        files: '<%= uglify.langs.files %>'
+      }
+    },
+
+    // ./tasks/gcc.js
+    gcc: {
+      // same as 'closure-compiler:langs'
+      langs: {
+        options: {
+          externs: 'js-modules/externs.js'
+        },
+        files: '<%= uglify.langs.files %>'
+      }
+    },
+
+    // grunt-contrib-cssmin
+    cssmin: {
+      // https://github.com/jakubpawlowicz/clean-css#how-to-use-clean-css-api
+      options: {
+        report: 'gzip'
+      },
+      prettify: {
+        src: 'src/prettify.css',
+        dest: 'loader/prettify.css'
+      },
+      skins: {
+        files: [{
+          expand: true,
+          cwd: 'styles/',
+          src: ['*.css'],
+          dest: 'loader/skins/',
+          ext: '.css'
+        }]
+      }
+    },
+
+    // grunt-contrib-compress
+    compress: {
+      zip: {
+        options: {
+          archive: 'distrib/prettify-small.zip',
+          mode: 'zip',
+          level: 9
+        },
+        files: [{
+          expand: true,
+          cwd: 'loader/',
+          src: ['*.js', '*.css', 'skins/*.css'],
+          dest: 'google-code-prettify/'
+        }]
+      }
+    },
+
+    // grunt-contrib-clean
+    clean: {
+      js: ['src/prettify.js', 'src/run_prettify.js', 'loader/*.js'],
+      css: ['loader/*.css', 'loader/skins/*.css'],
+      zip: ['distrib/*.zip']
+    }
+  });
+
+  // load plugins that provide tasks
+  require('google-closure-compiler').grunt(grunt);
+  grunt.loadTasks('./tasks');
+  grunt.loadNpmTasks('grunt-preprocess');
+  grunt.loadNpmTasks('grunt-contrib-copy');
+  grunt.loadNpmTasks('grunt-contrib-uglify');
+  grunt.loadNpmTasks('grunt-contrib-cssmin');
+  grunt.loadNpmTasks('grunt-contrib-compress');
+  grunt.loadNpmTasks('grunt-contrib-clean');
+
+  // register task aliases
+  grunt.registerTask('default', [
+    //'clean',
+    'preprocess',
+    'copy:prettify',
+    'gcc',
+    'copy:langs',
+    'aliases',
+    'cssmin',
+    'compress'
+  ]);
+};
diff --git a/Makefile b/Makefile
deleted file mode 100644
index a1c7f62e..00000000
--- a/Makefile
+++ /dev/null
@@ -1,97 +0,0 @@
-SHELL := /bin/bash
-
-CLOSURE_COMPILER=java -jar closure-compiler/compiler.jar \
-	      --warning_level VERBOSE \
-	      --language_in ECMASCRIPT5 \
-	      --compilation_level ADVANCED_OPTIMIZATIONS
-# Don't specify --charset=UTF-8.  If we do, then non-ascii codepoints
-# that do not correspond to line terminators are converted
-# to UTF-8 sequences instead of being emitted as ASCII.
-# This makes the resulting JavaScript less portable.
-
-YUI_COMPRESSOR=java -jar yui-compressor/yuicompressor-2.4.4.jar \
-	      --charset UTF-8
-
-TAR_ROOT=distrib/google-code-prettify
-
-all: distrib
-
-clean:
-	rm -rf distrib.tstamp distrib src/prettify.js src/run_prettify.js
-
-src/prettify.js: js-modules/*.js js-modules/*.pl
-	@if [ -e "$@" ]; then chmod +w "$@"; fi
-	@perl js-modules/js_include.pl "$$(basename $@)" > "$@"
-	@if [ -e "$@" ]; then chmod -w "$@"; fi
-
-src/run_prettify.js: js-modules/*.js js-modules/*.pl
-	@if [ -e "$@" ]; then chmod +w "$@"; fi
-	@perl js-modules/js_include.pl "$$(basename $@)" > "$@"
-	@if [ -e "$@" ]; then chmod -w "$@"; fi
-
-distrib: distrib.tstamp distrib/prettify-small.tgz distrib/prettify-small.zip distrib/prettify-small.tar.bz2
-	@wc -c distrib/prettify-small.{tar.bz2,tgz,zip} \
-	    | grep -v total
-
-distrib.tstamp: src/prettify.js src/run_prettify.js src/*.js src/*.css
-	@echo Compiling
-	@mkdir -p $(TAR_ROOT)
-	@for f in src/*.css; do \
-	  $(YUI_COMPRESSOR) --type css $$f \
-	      > $(TAR_ROOT)/$$(basename $$f); \
-	  wc -c $$f $(TAR_ROOT)/$$(basename $$f) \
-	      | grep -v total; \
-	done
-	@$(CLOSURE_COMPILER) --js src/prettify.js \
-	    --externs closure-compiler/console-externs.js \
-	    --externs closure-compiler/amd-externs.js \
-	    --define IN_GLOBAL_SCOPE=true \
-	    --output_wrapper='!function(){%output%}()' \
-	    > $(TAR_ROOT)/prettify.js
-	@wc -c src/prettify.js $(TAR_ROOT)/prettify.js \
-	    | grep -v total
-	@$(CLOSURE_COMPILER) --js src/run_prettify.js \
-	    --externs closure-compiler/console-externs.js \
-	    --externs closure-compiler/amd-externs.js \
-	    --define IN_GLOBAL_SCOPE=false \
-	    --output_wrapper='!function(){%output%}()' \
-	    > $(TAR_ROOT)/run_prettify.js
-	@wc -c src/run_prettify.js $(TAR_ROOT)/run_prettify.js \
-	    | grep -v total
-	@for f in src/lang*.js; do \
-	  if [ $$f -nt $(TAR_ROOT)/$$(basename $$f) ]; then \
-	    $(CLOSURE_COMPILER) --js $$f --externs js-modules/externs.js \
-	        | perl -pe 's/\bPR\.PR_ATTRIB_NAME\b/"atn"/g; \
-			    s/\bPR\.PR_ATTRIB_VALUE\b/"atv"/g; \
-			    s/\bPR\.PR_COMMENT\b/"com"/g; \
-			    s/\bPR\.PR_DECLARATION\b/"dec"/g; \
-			    s/\bPR\.PR_KEYWORD\b/"kwd"/g; \
-			    s/\bPR\.PR_LITERAL\b/"lit"/g; \
-			    s/\bPR\.PR_PLAIN\b/"pln"/g; \
-			    s/\bPR\.PR_PUNCTUATION\b/"pun"/g; \
-			    s/\bPR\.PR_STRING\b/"str"/g; \
-			    s/\bPR\.PR_TAG\b/"tag"/g; \
-			    s/\bPR\.PR_TYPE\b/"typ"/g;' \
-	        > $(TAR_ROOT)/$$(basename $$f); \
-	    wc -c $$f $(TAR_ROOT)/$$(basename $$f) \
-	        | grep -v total; \
-	  fi \
-	done
-	@touch distrib.tstamp
-
-%.tgz: %.tar
-	@gzip -c -9 $^ > $@
-
-%.tar.bz2: %.tar
-	@bzip2 -9f $^
-
-distrib/prettify-small.tar: distrib.tstamp
-	@pushd distrib >& /dev/null; \
-	tar cf ../$@ google-code-prettify; \
-	popd >& /dev/null
-
-distrib/prettify-small.zip: distrib.tstamp
-	@pushd distrib >& /dev/null; \
-	rm -f ../$@; \
-	zip -q -9 -r ../$@ google-code-prettify; \
-	popd >& /dev/null
diff --git a/README-zh-Hans.html b/README-zh-Hans.html
deleted file mode 100644
index 69bf7aed..00000000
--- a/README-zh-Hans.html
+++ /dev/null
@@ -1,143 +0,0 @@
-
-
-
-  
-    
-    Javascript code prettifier
-
-    
-
-    
-
-    
-  
-
-  
-    

Javascript code prettifier

-

Javascript 代码美容师

-

安装使用

-
    -
  1. 下载 文件 -
  2. 在你的文件中包含这儿的脚本和样式表(你要保证这儿的 css 和 js 文件按在你的服务器上, 并且调整在 scriptlink标签中的路径) -
    -<link href="prettify.css" type="text/css" rel="stylesheet" />
    -<script type="text/javascript" src="prettify.js"></script>
    -
  3. 添加onload="prettyPrint()" 到你的文件的 body 标签中. -
  4. 修改样式表,使用你自己喜欢的颜色.
  5. -
- -

使用方法

-

在 - <pre class="prettyprint">...</pre><code class="prettyprint">...</code> - 中间放上代码片段,它就会自动被美化了. - - - - -
The original - Prettier -
class Voila {
-public:
-  // Voila
-  static const string VOILA = "Voila";
-
-  // will not interfere with embedded tags.
-}
- -
class Voila {
-public:
-  // Voila
-  static const string VOILA = "Voila";
-
-  // will not interfere with embedded tags.
-}
-
- - -

常见问题

-

它是为什么语言工作的?

-

prettify.js中的注释是权威的,但是它的语法分析程序可以在很多语言中使用,包括 C , - Java, Python, Bash, SQL, HTML, XML, CSS, Javascript, 和 Makefiles. - 它在 Ruby, PHP, VB, 和 Awk 中还算可以,而且也可以在 Perl 和 Ruby的合适子集中起作用,但是, 因为注释的约定,它对 - Smalltalk, 或 CAML类似的语言起作用.

- - -

LISP系列的语言可以使用一个拓展lang-lisp.js.

对于 CSS, - Haskell, - Lua, - OCAML, SML, F#, - Visual Basic, - SQL, - Protocol Buffers, 和 - WikiText..也是类似的

如果你想给你喜欢的语言写个拓展版本, 请参阅src/lang-lisp.js ,并写一个包括你的语言的拓展的 发布 和一个测试用例.

- -

如何指定我的代码在哪种语言里?

-

你不需要指定语言环境,因为 prettyprint() - 会对此进行猜测. 你可以使用 prettyprint 这个类通过指定语言的拓展名来指定语言,就像这样:

-
<pre class="prettyprint lang-html">
-  The lang-* class specifies the language file extensions.
-  File extensions supported by default include
-    "bsh", "c", "cc", "cpp", "cs", "csh", "cyc", "cv", "htm", "html",
-    "java", "js", "m", "mxml", "perl", "pl", "pm", "py", "rb", "sh",
-    "xhtml", "xml", "xsl".
-</pre>
- -

它在混淆代码例子上不起作用吗?

-

是的. 美化混淆代码就像给小猪涂口红,也就是不在这个工具的范围内.

- -

它可以在那些浏览器上工作?

-

这个工具已经在 IE 6, Firefox 1.5 & 2, 和 Safari 2.0.4 上测试通过. 打开 测试页面 ,看看它能不能在你的浏览器上起作用.

- -

有什么改变?

-

查看 变化日志

- -

 为什么Prettyprinting 对WordPress中的字符串没用?

-

很显然,wordpress 在 "smart quoting" 时会改变关闭符号. - 这使得关闭符号跟开始符号不配套. -

这和复制粘贴代码一样,破坏了美化作用. 去 - WordPress's help center 查看更多关于如何关闭插入代码段时的"smart quoting"的信息.

- -

如何在我的代码中加入行号? (Out of date -- see English version)

-

你可以使用 nocode 类来标记 span 标记不是代码. -

<pre class=prettyprint>
-<span class="nocode">1:</span> /* This is line 1 of my code
-<span class="nocode">2:</span>  * and here's line 2 */
-<span class="nocode">3:</span> print("I'm line number 3");
-</pre>
得到 -
-1: /* This is line 1 of my code
-2:  * and here's line 2 */
-3: print("I'm line number 3");
-
- -

查看一个更完整的例子: issue22 - testcase.

- -

我得到了这样一条错误信息 "a is not a function" 或 "opt_whenDone is not a function"

-

如果你通过事件句柄条用 prettyPrint , 把它隐藏到一个函数中.

不要这么写 -

- addEventListener('load', prettyPrint, false); -
而要这么写 -
- addEventListener('load', function (event) { prettyPrint() }, false); -
这样的话,浏览器就不会把时间对象传递给 prettyPrint ,事件对象会让它困惑的. - -


- - - - diff --git a/README.html b/README.html deleted file mode 100644 index 3049a43a..00000000 --- a/README.html +++ /dev/null @@ -1,235 +0,0 @@ - - - - - Javascript code prettifier - - - - - - - - - - Languages : CH -

Javascript code prettifier

- -

Setup

-
    -
  1. Download a distribution -
  2. Include the script and stylesheets in your document - (you will need to make sure the css and js file are on your server, and - adjust the paths in the script and link tag) -
    -<link href="prettify.css" type="text/css" rel="stylesheet" />
    -<script type="text/javascript" src="prettify.js"></script>
    -
  3. Add onload="prettyPrint()" to your - document's body tag. -
  4. Modify the stylesheet to get the coloring you prefer
  5. -
- -

Usage

-

Put code snippets in - <pre class="prettyprint">...</pre> - or <code class="prettyprint">...</code> - and it will automatically be pretty printed. - - - - -
The original - Prettier -
class Voila {
-public:
-  // Voila
-  static const string VOILA = "Voila";
-
-  // will not interfere with embedded tags.
-}
- -
class Voila {
-public:
-  // Voila
-  static const string VOILA = "Voila";
-
-  // will not interfere with embedded tags.
-}
-
- -

FAQ

-

For which languages does it work?

-

The comments in prettify.js are authoritative but 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, VB, and Awk and a decent subset of Perl - and Ruby, but, because of commenting conventions, doesn't work on - Smalltalk, or CAML-like languages.

- -

LISPy languages are supported via an extension: - lang-lisp.js.

-

And similarly for - Clojure, - CSS, - Erlang, - Go, - Haskell, - Lua, - OCAML, SML, F#, - Nemerle, - Protocol Buffers, - Scala, - SQL, - TeX, LaTeX, - VHDL, - Visual Basic, - WikiText, - XQuery, and - YAML. - -

If you'd like to add an extension for your favorite language, please - look at src/lang-lisp.js and file an - issue including your language extension, and a testcase.

- -

How do I specify the language of my code?

-

You don't need to specify the language since prettyprint() - will guess. You can specify a language by specifying the language extension - along with the prettyprint class like so:

-
<pre class="prettyprint lang-html">
-  The lang-* class specifies the language file extensions.
-  File extensions supported by default include
-    "bsh", "c", "cc", "cpp", "cs", "csh", "cyc", "cv", "htm", "html",
-    "java", "js", "m", "mxml", "perl", "pl", "pm", "py", "rb", "sh",
-    "xhtml", "xml", "xsl".
-</pre>
- -

You may also use the - HTML 5 convention of embedding a code element inside the - PRE and using language-java style classes. - E.g.

<pre class="prettyprint"><code class="language-java">...</code></pre> - -

It doesn't work on <obfuscated code sample>?

-

Yes. Prettifying obfuscated code is like putting lipstick on a pig - — i.e. outside the scope of this tool.

- -

Which browsers does it work with?

-

It's been tested with IE 6, Firefox 1.5 & 2, and Safari 2.0.4. - Look at the test page to see if it - works in your browser.

- -

What's changed?

-

See the change log

- -

Why doesn't Prettyprinting of strings work on WordPress?

-

Apparently wordpress does "smart quoting" which changes close quotes. - This causes end quotes to not match up with open quotes. -

This breaks prettifying as well as copying and pasting of code samples. - See - WordPress's help center for info on how to stop smart quoting of code - snippets.

- -

How do I put line numbers in my code?

-

You can use the linenums class to turn on line - numbering. If your code doesn't start at line number 1, you can - add a colon and a line number to the end of that class as in - linenums:52. - -

For example -

<pre class="prettyprint linenums:4"
->// This is line 4.
-foo();
-bar();
-baz();
-boo();
-far();
-faz();
-<pre>
- produces -
// This is line 4.
-foo();
-bar();
-baz();
-boo();
-far();
-faz();
-
- -

How do I prevent a portion of markup from being marked as code?

-

You can use the nocode class to identify a span of markup - that is not code. -

<pre class=prettyprint>
-int x = foo();  /* This is a comment  <span class="nocode">This is not code</span>
-  Continuation of comment */
-int y = bar();
-</pre>
-produces -
-int x = foo();  /* This is a comment  This is not code
-  Continuation of comment */
-int y = bar();
-
- -

For a more complete example see the issue22 - testcase.

- -

I get an error message "a is not a function" or "opt_whenDone is not a function"

-

If you are calling prettyPrint via an event handler, wrap it in a function. - Instead of doing -

- addEventListener('load', prettyPrint, false); -
- wrap it in a closure like -
- addEventListener('load', function (event) { prettyPrint() }, false); -
- so that the browser does not pass an event object to prettyPrint which - will confuse it. - -

How can I customize the colors and styles of my code?

-

- Prettify adds <span> with classes describing - the kind of code. You can create CSS styles to matches these - classes. - See the - - theme gallery for examples. -

- -


- - - - diff --git a/README.md b/README.md new file mode 100644 index 00000000..41cd727e --- /dev/null +++ b/README.md @@ -0,0 +1,248 @@ +# Status: Archived + +![status: inactive](https://img.shields.io/badge/status-inactive-red.svg) + +This repository has been archived and is no longer maintained. + +--- + +# JavaScript code prettifier + +Announcement: [**Action required** *rawgit.com* is going away](https://groups.google.com/forum/#!topic/js-code-prettifier/IFHev_kLm30). + +An embeddable script that makes source-code snippets in HTML prettier. + +* Works on HTML pages. +* Works even if code contains embedded links, line numbers, etc. +* Simple API: include some JS & CSS and add an onload handler. +* Lightweights: small download and does not block page from loading while + running. +* Customizable styles via CSS. See the [themes gallery][1]. +* Supports all C-like, Bash-like, and XML-like languages. No need to specify + the language. +* Extensible language handlers for other languages. You can specify the + language. +* Widely used with good cross-browser support. Powers https://code.google.com/ + and http://stackoverflow.com/ + +[See an example][2]. + +## Setup + + * Include the script tag below in your document: +```HTML + +``` + * See [Getting Started](docs/getting_started.md) to configure that URL with + options you need. + * Look at the [skin gallery][1] and pick styles that suit you. + +## Usage + +Put code snippets in `
...
` or +`...` and it will automatically be +pretty-printed. + +```HTML +
class Voila {
+public:
+  // Voila
+  static const string VOILA = "Voila";
+
+  // will not interfere with embedded tags.
+}
+``` + +## FAQ + +### For which languages does it work? + +The comments in `prettify.js` are authoritative but the lexer should work on a +number of languages including C and friends, Java, Python, Bash, SQL, HTML, +XML, CSS, JavaScript, Makefile, and Rust. + +It works passably on Ruby, PHP, VB, and Awk and a decent subset of Perl and +Ruby, but because of commenting conventions, doesn't work on Smalltalk, OCaml, +etc. without a language extension. + +Other languages are supported via extensions: + +[Apollo](src/lang-apollo.js); +[Basic](src/lang-basic.js); +[Clojure](src/lang-clj.js); +[CSS](src/lang-css.js); +[Dart](src/lang-dart.js); +[Erlang](src/lang-erlang.js); +[Go](src/lang-go.js); +[Haskell](src/lang-hs.js); +[Lasso](src/lang-lasso.js); +[Lisp, Scheme](src/lang-lisp.js); +[LLVM](src/lang-llvm.js); +[Logtalk](src/lang-logtalk.js); +[Lua](src/lang-lua.js); +[MATLAB](src/lang-matlab.js); +[MLs: F#, Ocaml,SML](src/lang-ml.js); +[Mumps](src/lang-mumps.js); +[Nemerle](src/lang-n.js); +[Pascal](src/lang-pascal.js); +[Protocol buffers](src/lang-proto.js); +[R, S](src/lang-r.js); +[RD](src/lang-rd.js); +[Rust](src/lang-rust.js); +[Scala](src/lang-scala.js); +[SQL](src/lang-sql.js); +[Swift](src/lang-swift.js); +[TCL](src/lang-tcl.js); +[LaTeX](src/lang-tex.js); +[Visual Basic](src/lang-vb.js); +[VHDL](src/lang-vhdl.js); +[Wiki](src/lang-wiki.js); +[XQ](src/lang-xq.js); +[YAML](src/lang-yaml.js) + +If you'd like to add an extension for your favorite language, please look at +`src/lang-lisp.js` and submit a pull request. + +### How do I specify the language of my code? + +You don't need to specify the language since `PR.prettyPrint()` will guess. +You can specify a language by specifying the language extension along with the +`prettyprint` class: + +```HTML +
+  The lang-* class specifies the language file extensions.
+  File extensions supported by default include:
+    "bsh", "c", "cc", "cpp", "cs", "csh", "cyc", "cv", "htm", "html", "java",
+    "js", "m", "mxml", "perl", "pl", "pm", "py", "rb", "sh", "xhtml", "xml",
+    "xsl".
+
+``` + +You may also use the [HTML 5][3] convention of embedding a `` element +inside the `
` and using `language-java` style classes:
+
+```HTML
+
...
+``` + +### It doesn't work on "obfuscated code sample"? + +Yes. Prettifying obfuscated code is like putting lipstick on a pig — +i.e. outside the scope of this tool. + +### Which browsers does it work with? + +It's been tested with IE 6, Firefox 1.5 & 2, and Safari 2.0.4. Look at +[the tests][4] to see if it works in your browser. + +### What's changed? + +See the [changelog](CHANGES.md). + +### Why doesn't Prettyprinting of strings work on WordPress? + +Apparently wordpress does "smart quoting" which changes close quotes. This +causes end quotes to not match up with open quotes. + +This breaks prettifying as well as copying and pasting of code samples. See +[WordPress's help center][5] for info on how to stop smart quoting of code +snippets. + +### How do I put line numbers in my code? + +You can use the `linenums` class to turn on line numbering. If your code +doesn't start at line number `1`, you can add a colon and a line number to the +end of that class as in `linenums:52`. For example: + +```HTML +
// This is line 4.
+foo();
+bar();
+baz();
+boo();
+far();
+faz();
+
+``` + +### How do I prevent a portion of markup from being marked as code? + +You can use the `nocode` class to identify a span of markup that is not code: + +```HTML +
+int x = foo();  /* This is a comment  This is not code
+  Continuation of comment */
+int y = bar();
+
+``` + +For a more complete example see the [issue #22 testcase][6]. + +### I get an error message "a is not a function" or "opt_whenDone is not a function" + +If you are calling `prettyPrint` via an event handler, wrap it in a function. +Instead of doing: + +```JavaScript +addEventListener('load', PR.prettyPrint, false); +``` + +wrap it in a closure like: + +```JavaScript +addEventListener('load', function(event) { PR.prettyPrint(); }, false); +``` + +so that the browser does not pass an event object to `PR.prettyPrint` +which will confuse it. + +### How can I customize the colors and styles of my code? + +Prettify adds `` with `class`es describing the kind of code. You can +create CSS styles to matches these classes. + +See the [theme gallery][1] for examples. + +### I can't add classes to my code (because it comes from Markdown, etc.) + +Instead of `
` you can use a comment or processing
+instructions that survives processing instructions: `` works
+as explained in [Getting Started](docs/getting_started.md).
+
+### How can I put line numbers on every line instead of just every fifth line?
+
+Prettify puts lines into an HTML list element so that line numbers aren't
+caught by copy/paste, and the line numbering is controlled by CSS in the
+default stylesheet, `prettify.css`.
+
+The following should turn line numbering back on for the other lines:
+
+```HTML
+
+```
+
+## Discussion
+
+Please use the official [support group][7] for discussions, suggestions, and
+general feedback.
+
+## License
+
+[Apache License 2.0](COPYING)
+
+
+[1]: https://raw.githack.com/google/code-prettify/master/styles/index.html
+[2]: https://raw.githack.com/google/code-prettify/master/examples/quine.html
+[3]: http://dev.w3.org/html5/spec-author-view/the-code-element.html#the-code-element
+[4]: https://raw.githack.com/google/code-prettify/master/tests/prettify_test.html
+[5]: http://wordpress.org/support/topic/125038
+[6]: https://raw.githack.com/google/code-prettify/master/tests/prettify_test.html#issue22
+[7]: http://groups.google.com/group/js-code-prettifier
diff --git a/bower.json b/bower.json
new file mode 100644
index 00000000..27b13817
--- /dev/null
+++ b/bower.json
@@ -0,0 +1,40 @@
+{
+  "name": "code-prettify",
+  "description": "Google Code Prettify",
+  "authors": [
+    "Google"
+  ],
+  "license": "Apache-2.0",
+  "homepage": "https://github.com/google/code-prettify",
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/google/code-prettify.git"
+  },
+  "keywords": [
+    "syntax",
+    "highlight",
+    "highlighting",
+    "source",
+    "code",
+    "prettify",
+    "google"
+  ],
+  "main": [
+    "src/prettify.js",
+    "src/prettify.css"
+  ],
+  "moduleType": [
+    "globals",
+    "amd"
+  ],
+  "ignore": [
+    "**/.*",
+    "node_modules",
+    "bower_components",
+    "distrib",
+    "js-modules",
+    "tasks",
+    "tests",
+    "tools"
+  ]
+}
diff --git a/closure-compiler/COPYING b/closure-compiler/COPYING
deleted file mode 100644
index d6456956..00000000
--- a/closure-compiler/COPYING
+++ /dev/null
@@ -1,202 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   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.
diff --git a/closure-compiler/README b/closure-compiler/README
deleted file mode 100644
index dfffa7f9..00000000
--- a/closure-compiler/README
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Copyright 2009 The Closure Compiler Authors.
- *
- * 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.
- */
-
-//
-// Contents
-//
-
-The Closure Compiler performs checking, instrumentation, and
-optimizations on JavaScript code. The purpose of this README is to
-explain how to build and run the Closure Compiler.
-
-The Closure Compiler requires Java 6 or higher.
-http://www.java.com/
-
-
-//
-// Building The Closure Compiler
-//
-
-There are three ways to get a Closure Compiler executable.
-
-1) Use one we built for you.
-
-Pre-built Closure binaries can be found at
-http://code.google.com/p/closure-compiler/downloads/list
-
-
-2) Check out the source and build it with Apache Ant.
-
-First, check out the full source tree of the Closure Compiler. There
-are instructions on how to do this at the project site.
-http://code.google.com/p/closure-compiler/source/checkout
-
-Apache Ant is a cross-platform build tool.
-http://ant.apache.org/
-
-At the root of the source tree, there is an Ant file named
-build.xml. To use it, navigate to the same directory and type the
-command
-
-ant jar
-
-This will produce a jar file called "build/compiler.jar".
-
-
-3) Check out the source and build it with Eclipse.
-
-Eclipse is a cross-platform IDE.
-http://www.eclipse.org/
-
-Under Eclipse's File menu, click "New > Project ..." and create a
-"Java Project."  You will see an options screen. Give the project a
-name, select "Create project from existing source," and choose the
-root of the checked-out source tree as the existing directory. Verify
-that you are using JRE version 6 or higher.
-
-Eclipse can use the build.xml file to discover rules. When you
-navigate to the build.xml file, you will see all the build rules in
-the "Outline" pane. Run the "jar" rule to build the compiler in
-build/compiler.jar.
-
-
-//
-// Running The Closure Compiler
-//
-
-Once you have the jar binary, running the Closure Compiler is straightforward.
-
-On the command line, type
-
-java -jar compiler.jar
-
-This starts the compiler in interactive mode. Type
-
-var x = 17 + 25;
-
-then hit "Enter", then hit "Ctrl-Z" (on Windows) or "Ctrl-D" (on Mac or Linux)
-and "Enter" again. The Compiler will respond:
-
-var x=42;
-
-The Closure Compiler has many options for reading input from a file,
-writing output to a file, checking your code, and running
-optimizations. To learn more, type
-
-java -jar compiler.jar --help
-
-You can read more detailed documentation about the many flags at
-http://code.google.com/closure/compiler/docs/gettingstarted_app.html
-
-
-//
-// Compiling Multiple Scripts
-//
-
-If you have multiple scripts, you should compile them all together with
-one compile command.
-
-java -jar compiler.jar --js=in1.js --js=in2.js ... --js_output_file=out.js
-
-The Closure Compiler will concatenate the files in the order they're
-passed at the command line.
-
-If you need to compile many, many scripts together, you may start to
-run into problems with managing dependencies between scripts. You
-should check out the Closure Library. It contains functions for
-enforcing dependencies between scripts, and a tool called calcdeps.py
-that knows how to give scripts to the Closure Compiler in the right
-order.
-
-http://code.google.com/p/closure-library/
-
-//
-// Licensing
-//
-
-Unless otherwise stated, all source files are licensed under
-the Apache License, Version 2.0.
-
-
------
-Code under:
-src/com/google/javascript/rhino
-test/com/google/javascript/rhino
-
-URL: http://www.mozilla.org/rhino
-Version:  1.5R3, with heavy modifications
-License:  Netscape Public License and MPL / GPL dual license
-
-Description: A partial copy of Mozilla Rhino. Mozilla Rhino is an
-implementation of JavaScript for the JVM.  The JavaScript parser and
-the parse tree data structures were extracted and modified
-significantly for use by Google's JavaScript compiler.
-
-Local Modifications: The packages have been renamespaced. All code not
-relavant to parsing has been removed. A JSDoc parser and static typing
-system have been added.
-
-
------
-Code in:
-lib/libtrunk_rhino_parser_jarjared.jar
-
-Rhino
-URL: http://www.mozilla.org/rhino
-Version:  Trunk
-License:  Netscape Public License and MPL / GPL dual license
-
-Description: Mozilla Rhino is an implementation of JavaScript for the JVM.
-
-Local Modifications: None. We've used JarJar to renamespace the code
-post-compilation. See:
-http://code.google.com/p/jarjar/
-
-
------
-Code in:
-lib/args4j.jar
-
-Args4j
-URL: https://args4j.dev.java.net/
-Version: 2.0.12
-License: MIT
-
-Description:
-args4j is a small Java class library that makes it easy to parse command line
-options/arguments in your CUI application.
-
-Local Modifications: None.
-
-
------
-Code in:
-lib/guava.jar
-
-Guava Libraries
-URL: http://code.google.com/p/guava-libraries/
-Version:  R7
-License: Apache License 2.0
-
-Description: Google's core Java libraries.
-
-Local Modifications: None.
-
-
------
-Code in:
-lib/jsr305.jar
-
-Annotations for software defect detection
-URL: http://code.google.com/p/jsr-305/
-Version: svn revision 47
-License: BSD License
-
-Description: Annotations for software defect detection.
-
-Local Modifications: None.
-
-
-----
-Code in:
-lib/junit.jar
-
-JUnit
-URL:  http://sourceforge.net/projects/junit/
-Version:  4.8.2
-License:  Common Public License 1.0
-
-Description: A framework for writing and running automated tests in Java.
-
-Local Modifications: None.
-
-
----
-Code in:
-lib/protobuf-java.jar
-
-Protocol Buffers
-URL: http://code.google.com/p/protobuf/
-Version: 2.3.0
-License: New BSD License
-
-Description: Supporting libraries for protocol buffers,
-an encoding of structured data.
-
-Local Modifications: None
-
-
----
-Code in:
-lib/ant.jar
-lib/ant-launcher.jar
-
-URL: http://ant.apache.org/bindownload.cgi
-Version: 1.8.1
-License: Apache License 2.0
-Description:
-  Ant is a Java based build tool. In theory it is kind of like "make"
-  without make's wrinkles and with the full portability of pure java code.
-
-Local Modifications: None
-
-
----
-Code in:
-lib/json.jar
-URL: http://json.org/java/index.html
-Version: JSON version 20090211
-License: MIT license
-Description:
-JSON is a set of java files for use in transmitting data in JSON format.
-
-Local Modifications: None
-
----
-Code in:
-tools/maven-ant-tasks-2.1.1.jar
-URL: http://maven.apache.org
-Version 2.1.1
-License: Apache License 2.0
-Description:
-  Maven Ant tasks are used to manage dependencies and to install/deploy to
-  maven repositories.
-
-Local Modifications: None
diff --git a/closure-compiler/compiler.jar b/closure-compiler/compiler.jar
deleted file mode 100644
index 10516dc7..00000000
Binary files a/closure-compiler/compiler.jar and /dev/null differ
diff --git a/cut-release.sh b/cut-release.sh
deleted file mode 100755
index 5e339a6e..00000000
--- a/cut-release.sh
+++ /dev/null
@@ -1,194 +0,0 @@
-#!/bin/bash
-
-function help_and_exit() {
-    echo "Usage: $0 [-go] [-verbose] [-force]"
-    echo
-    echo "Moves minified CSS and JS to distribution directories and"
-    echo "creates a branch in SVN."
-    echo
-    echo "  -go:      Run commands instead of just echoing them."
-    echo "  -verbose: More verbose logging."
-    echo "  -force:   Ignore sanity checks for testing."
-    echo "            Incompatible with -go."
-    exit "$1"
-}
-
-# 1 for verbose logging
-export VERBOSE="0"
-# 1 if commands that have side-effects should actually be run instead of logged
-export EFFECT="0"
-# 1 to not exit on panic.
-export NO_PANIC="0"
-
-function panic() {
-    echo "PANIC: $*"
-
-    if ! (( $NO_PANIC )); then
-        exit -1
-    fi
-}
-
-function command() {
-    if (( $VERBOSE )) || ! (( $EFFECT )); then
-        echo '$' "$*"
-    fi
-    if (( $EFFECT )); then
-        "$@" || panic "command failed: $@"
-    fi
-}
-
-function mime_for_file() {
-    local path="$1"
-    case "${path##*.}" in
-        js)   echo -n "text/javascript;charset=UTF-8";;
-        css)  echo -n "text/css;charset=UTF-8";;
-        html) echo -n "text/html;charset=UTF-8";;
-        *)    panic "unrecognized extension for $path";;
-    esac
-}
-
-for var in "$@"; do
-  case "$var" in
-      -verbose)
-          VERBOSE="1"
-          ;;
-      -go)
-          EFFECT="1"
-          ;;
-      -force)
-          NO_PANIC="1"
-          ;;
-      -h)
-          help_and_exit 0
-          ;;
-      *)
-          echo "Unrecognized variable $var"
-          help_and_exit -1
-          ;;
-  esac
-done
-
-if (( $NO_PANIC )) && (( $EFFECT )); then
-    NO_PANIC="0"
-    panic "-force is incompatible with -go"
-fi
-
-# Find svn root
-export VERSION_BASE="$(
-  pushd "$(dirname "$0")/.." > /dev/null; pwd; popd > /dev/null)"
-
-if [ -z "$VERSION_BASE" ] || ! [ -d "$VERSION_BASE" ]; then
-    panic "unknown VERSION_BASE"
-fi
-if ! [ -d "$VERSION_BASE/trunk" ]; then
-    panic "missing trunk in $VERSION_BASE"
-fi
-if ! [ -d "$VERSION_BASE/loader" ]; then
-    panic "missing loader in $VERSION_BASE"
-fi
-if ! [ -d "$VERSION_BASE/branches" ]; then
-    panic "missing branches in $VERSION_BASE"
-fi
-
-if (( $VERBOSE )); then
-    echo "VERSION_BASE=$VERSION_BASE"
-fi
-
-# Choose a release label
-export RELEASE_LABEL="$(date -u +release-%e-%b-%Y)"
-
-if (( $VERBOSE )); then
-    echo "RELEASE_LABEL=$RELEASE_LABEL"
-fi
-
-if [ -e "$VERSION_BASE/branches/$RELEASE_LABEL" ]; then
-    panic "duplicate release $VERSION_BASE/branches/$RELEASE_LABEL"
-fi
-
-
-# Make the distribution
-function build() {
-  pushd "$VERSION_BASE/trunk" > /dev/null
-  make distrib
-  local status=$?
-  popd > /dev/null
-  (($status))
-}
-if build; then
-  panic "Make failed"
-fi
-
-if [ -n "$(svn stat "$VERSION_BASE/trunk")" ]; then
-  svn stat "$VERSION_BASE/trunk"
-  panic "Uncommitted changes"
-fi
-
-function sync() {
-    local action="$1"
-    local src_dir="$2"
-    local dest_dir="$3"
-    shift 3
-    local exts=$@
-    local ext
-    local src_file
-    local dest_file
-    (
-        shopt -s nullglob
-        for ext in $exts; do
-            for src_file in "$src_dir"/*."$ext"; do
-                dest_file="$dest_dir"/"$(basename "$src_file")"
-                if ! [ -e "$dest_file" ] || \
-                    diff -q "$src_file" "$dest_file"; then
-                    "$action" "$src_file" "$dest_file"
-                fi
-            done
-            for dest_file in "$dest_dir"/*."$ext"; do
-                src_file="$src_dir"/"$(basename "$dest_file")"
-                if ! [ -e "$src_file" ]; then
-                    "$action" "$src_file" "$dest_file"
-                fi
-            done
-        done
-    )
-}
-
-function svn_sync() {
-    local src_file="$1"
-    local dest_file="$2"
-    if ! [ -e "$src_file" ]; then
-        command svn delete "$dest_file"
-    else
-        if [ -e "$dest_file" ]; then
-            command cp "$src_file" "$dest_file"
-        else
-            command cp "$src_file" "$dest_file"
-            command svn add "$dest_file"
-            command svn propset svn:mime-type "$(mime_for_file "$src_file")" \
-                "$dest_file"
-        fi
-    fi
-}
-
-# Deploy the current compiled source to /loader
-sync svn_sync "$VERSION_BASE/trunk/distrib/google-code-prettify" \
-    "$VERSION_BASE/loader" js css
-sync svn_sync "$VERSION_BASE/trunk/styles" \
-    "$VERSION_BASE/loader/skins" css
-
-# Cut branch
-command svn copy "$VERSION_BASE/trunk" "$VERSION_BASE/branches/$RELEASE_LABEL"
-
-# Dump final instructions for caller.
-echo
-if (( $EFFECT )); then
-    echo "Finally run"
-    echo "    $ svn commit -m 'Release $RELEASE_LABEL'"
-    echo "to commit the new release then upload"
-    echo "    $VERSION_BASE/trunk/distrib/prettify-small.*"
-    echo "to"
-    echo "    http://code.google.com/p/google-code-prettify/downloads/list"
-else
-   echo "Rerun with -go flag to actually execute these commands."
-fi
-
-exit 0
diff --git a/distrib/prettify-small.zip b/distrib/prettify-small.zip
new file mode 100644
index 00000000..c63da471
Binary files /dev/null and b/distrib/prettify-small.zip differ
diff --git a/docs/getting_started.md b/docs/getting_started.md
new file mode 100644
index 00000000..81221bfe
--- /dev/null
+++ b/docs/getting_started.md
@@ -0,0 +1,138 @@
+# Getting Started
+
+You can load the Prettify script to highlight code in your web pages.
+
+It adds styles to code snippets so that token boundaries stand out and your
+readers can get the gist of your code without having to mentally perform a
+left-to-right parse.
+
+## Marking code sections
+
+The prettyprinter looks for `
`, ``, or `` elements with the
+*prettyprint* class, and adds `<span>`s to colorize keywords, strings,
+comments, and other token types.
+
+```HTML
+<pre class="prettyprint">
+source code here
+</pre>
+```
+
+If you're using Markdown or some other HTML generator that does not add
+classes, you can alternatively ask the prettifier to target your code by
+preceding it with a processing instruction thus:
+
+```HTML
+<?prettify?>
+<pre class="prettyprint">
+code here
+</pre>
+```
+
+[Larger example](https://raw.githack.com/google/code-prettify/master/examples/quine.html)
+
+## Auto-Loader
+
+You can load the JavaScript and CSS for prettify via one URL:
+
+```HTML
+<script src="https://cdn.jsdelivr.net/gh/google/code-prettify@master/loader/run_prettify.js"></script>
+```
+
+This will load the entire system and schedule the prettifier to run on page
+load.  There are a variety of additional options you can specify (as CGI
+arguments) to configure the runner.
+
+| CGI parameter         | default | meaning                        |
+| --------------------- | ------- | ------------------------------ |
+| autorun=(true, false) | true    | run automatically on page load |
+| lang=...              | none    | Loads the language handler for the given language which is usually the file extension for source files for that language.  See the [index of language handlers](../src).  If specified multiple times (`?lang=css&lang=ml`) then all are loaded. |
+| skin=...              | none    | See the [skin gallery](https://raw.githack.com/google/code-prettify/master/styles/index.html).  If specified multiple times, the first one to successfully load is used. |
+| callback=js_ident     |         | `window.exports["js_ident"]` will be called when prettyprinting finishes.  If specified multiple times, all are called. |
+
+For example:
+
+```HTML
+<script src="https://cdn.jsdelivr.net/gh/google/code-prettify@master/loader/run_prettify.js?lang=css&amp;skin=sunburst"></script>
+```
+
+The above specifies the `lang` parameter to also load the CSS language
+extension and the `skin` parameter to load the
+[*sunburst*](https://raw.githack.com/google/code-prettify/master/styles/index.html#sunburst)
+skin.
+
+## Serving your own JS & CSS
+
+You can
+[download](https://github.com/google/code-prettify/raw/master/distrib/prettify-small.zip)
+the scripts and styles and serve them yourself.  Make sure to include both the
+script and a stylesheet:
+
+```HTML
+<link rel="stylesheet" type="text/css" href="prettify.css">
+<script type="text/javascript" src="prettify.js"></script>
+```
+
+Then run the `PR.prettyPrint()` function once your page has finished loading.
+One way to do this is via the `onload` handler thus:
+
+```HTML
+<body onload="PR.prettyPrint()">
+```
+
+## Styling
+
+The prettifier only adds `class`es; it does not specify exact colors or fonts,
+so you can swap in a different stylesheet to change the way code is
+prettified.
+
+The easiest way to create your own stylesheet is by starting with one from the
+[style gallery](https://raw.githack.com/google/code-prettify/master/styles/index.html)
+and tweaking it.
+
+You can use CSS `@media` rules to specify styles that work well with printers
+(for example, dark text on a white background) when someone tries to print it.
+
+## Language Hints
+
+Prettify makes a best effort to guess the language but works best with C-like
+and HTML-like languages.  For others, there are special language handlers that
+are chosen based on language hints.
+
+For example, set the `lang-scm` hint to specify that the code is Scheme code:
+
+```HTML
+<pre class="prettyprint lang-scm">(friends 'of '(parentheses))</pre>
+```
+
+It can also be specified as:
+
+```HTML
+<?prettify lang=scm?>
+<pre>(friends 'of '(parentheses))</pre>
+```
+
+## Line Numbering
+
+```HTML
+<pre class="prettyprint linenums">
+Many
+lines
+of
+code
+</pre>
+```
+
+The `linenums` class in the above code tells the prettyprinter to insert an
+`<ol>` element and `<li>` elements around each line so that you get line
+numbers.
+
+Most stylesheets then hide the line numbers except for every fifth line.
+
+The class `linenums:40` makes line numbering start at line 40 if you're
+excerpting a larger chunk of code.  The following also works:
+
+```HTML
+<?prettify linenums=40?>
+<pre>lots of code</pre>
+```
diff --git a/examples/quine.html b/examples/quine.html
new file mode 100644
index 00000000..d43eb11e
--- /dev/null
+++ b/examples/quine.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8" />
+<title>Making Quines Prettier</title>
+<!-- The defer attribute is not necessary for autoloading, but is necessary
+     for the script at the bottom to work as a Quine. -->
+<script src="https://cdn.jsdelivr.net/gh/google/code-prettify@master/loader/run_prettify.js?autoload=true&amp;skin=sunburst&amp;lang=css" defer></script>
+<style type="text/css">
+.operative { font-weight: bold; border: 1px solid yellow; }
+#quine { border: 4px solid #88c; }
+</style>
+</head>
+
+<body>
+<h1>Making Quines Prettier</h1>
+
+<p>
+Below is the content of this page prettified.  The <code>&lt;pre&gt;</code>
+element is prettified because it has <code>class="prettyprint"</code> and
+because the sourced script loads a JavaScript library that styles source
+code.
+</p>
+
+<p>
+The line numbers to the left appear because the preceding comment
+<code>&lt;?prettify lang=html linenums=true?&gt;</code> turns on
+line-numbering and the
+<a href="https://raw.githack.com/google/code-prettify/master/styles/index.html">stylesheet</a>
+(see <code>skin=sunburst</code> in the <code>&lt;script src&gt;</code>)
+specifies that every fifth line should be numbered.
+</p>
+
+<!-- Language hints can be put in XML application directive style comments. -->
+<?prettify lang=html linenums=true?>
+<pre class="prettyprint" id="quine"></pre>
+
+<script type="text/javascript">//<![CDATA[
+(function () {
+  function htmlEscape(s) {
+    return s
+      .replace(/&/g, '&amp;')
+      .replace(/</g, '&lt;')
+      .replace(/>/g, '&gt;');
+  }
+
+  // this page's own source code
+  var quineHtml = htmlEscape(
+    '<!DOCTYPE html>\n<html>\n' +
+    document.documentElement.innerHTML +
+    '\n<\/html>\n');
+
+  // Highlight the operative parts:
+  quineHtml = quineHtml.replace(
+    /&lt;script src[\s\S]*?&gt;&lt;\/script&gt;|&lt;!--\?[\s\S]*?--&gt;|&lt;pre\b[\s\S]*?&lt;\/pre&gt;/g,
+    '<span class="operative">$&<\/span>');
+
+  // insert into PRE
+  document.getElementById("quine").innerHTML = quineHtml;
+})();
+//]]>
+</script>
+
+</body>
+</html>
diff --git a/js-modules/defs.js b/js-modules/defs.js
new file mode 100644
index 00000000..18f3e4aa
--- /dev/null
+++ b/js-modules/defs.js
@@ -0,0 +1,55 @@
+/**
+ * @typedef {!Array.<number|string>}
+ * Alternating indices and the decorations that should be inserted there.
+ * The indices are monotonically increasing.
+ */
+var DecorationsT;
+
+/**
+ * @typedef {!{
+ *   sourceNode: !Element,
+ *   pre: !(number|boolean),
+ *   langExtension: ?string,
+ *   numberLines: ?(number|boolean),
+ *   sourceCode: ?string,
+ *   spans: ?(Array.<number|Node>),
+ *   basePos: ?number,
+ *   decorations: ?DecorationsT
+ * }}
+ * <dl>
+ *  <dt>sourceNode<dd>the element containing the source
+ *  <dt>sourceCode<dd>source as plain text
+ *  <dt>pre<dd>truthy if white-space in text nodes
+ *     should be considered significant.
+ *  <dt>spans<dd> alternating span start indices into source
+ *     and the text node or element (e.g. {@code <BR>}) corresponding to that
+ *     span.
+ *  <dt>decorations<dd>an array of style classes preceded
+ *     by the position at which they start in job.sourceCode in order
+ *  <dt>basePos<dd>integer position of this.sourceCode in the larger chunk of
+ *     source.
+ * </dl>
+ */
+var JobT;
+
+/**
+ * @typedef {!{
+ *   sourceCode: string,
+ *   spans: !(Array.<number|Node>)
+ * }}
+ * <dl>
+ *  <dt>sourceCode<dd>source as plain text
+ *  <dt>spans<dd> alternating span start indices into source
+ *     and the text node or element (e.g. {@code <BR>}) corresponding to that
+ *     span.
+ * </dl>
+ */
+var SourceSpansT;
+
+/** @define {boolean} */
+/* @ifndef RUN_PRETTIFY */
+var IN_GLOBAL_SCOPE = true;
+/* @endif */
+/* @ifdef RUN_PRETTIFY */
+var IN_GLOBAL_SCOPE = false;
+/* @endif */
diff --git a/js-modules/externs.js b/js-modules/externs.js
index e920098b..d962f53c 100644
--- a/js-modules/externs.js
+++ b/js-modules/externs.js
@@ -1,3 +1,30 @@
+/**
+ * @license
+ * Copyright (C) 2015 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.
+ */
+
+
+/**
+ *
+ * @fileoverview
+ * This file allows separate compilation of language handlers and the
+ * core library.
+ * @externs 
+ */
+
+
 var PR = {};
 
 /**
@@ -35,3 +62,4 @@ PR.PR_SOURCE = 'src';
 PR.PR_STRING = 'str';
 PR.PR_TAG = 'tag';
 PR.PR_TYPE = 'typ';
+
diff --git a/js-modules/extractSourceSpans.js b/js-modules/extractSourceSpans.js
index 5654cef5..220ae0f2 100644
--- a/js-modules/extractSourceSpans.js
+++ b/js-modules/extractSourceSpans.js
@@ -39,9 +39,9 @@
  * </p>
  *
  * @param {Node} node an HTML DOM subtree containing source-code.
- * @param {boolean} isPreformatted true if white-space in text nodes should
- *    be considered significant.
- * @return {Object} source code and the text nodes in which they occur.
+ * @param {boolean|number} isPreformatted truthy if white-space in
+ *    text nodes should be considered significant.
+ * @return {SourceSpansT} source code and the nodes in which they occur.
  */
 function extractSourceSpans(node, isPreformatted) {
   var nocode = /(?:^|\s)nocode(?:\s|$)/;
diff --git a/js-modules/extractSourceSpans_test.html b/js-modules/extractSourceSpans_test.html
deleted file mode 100644
index 090f6e2b..00000000
--- a/js-modules/extractSourceSpans_test.html
+++ /dev/null
@@ -1,129 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html> <head>
-<title>Extract Source Spans Test</title>
-<script src="extractSourceSpans.js"></script>
-<script src="http://github.com/douglascrockford/JSON-js/raw/master/json2.js"></script>
-<style>
-.ok { background: #dfd }
-.error, .failure { background: #fdd }
-td { font-family: monospace }
-.actual { white-space: pre }
-tr { vertical-align: top }
-.break { padding-left: 2px; border-right-style: dotted !important }
-.odd, .even { border-style: solid; border-width: 1px }
-.even { background: #fff; border-color: #888 }
-.odd { background: #ddd; border-color: #000 }
-</style>
-</head>
-
-<body>
-<h1>Extract Source Spans Test</h1>
-
-<table border=1 cellpadding=2 cellspacing=0>
-  <tr><th colspan=3>Test space preserved in PRE</th></tr>
-  <tr>
-    <td><pre class="testinput"><b>print </b>'Hello '<br>  + '&lt;World&gt;';</pre></td>
-    <td class="golden"><pre>^print ^'Hello '^\n^  + '&lt;World&gt;';^</pre></td>
-  </tr>
-  <tr><th colspan=3>Test class="nocode"</th></tr>
-  <tr>
-    <td><pre class="testinput"><span class=nocode>1. </span><b>print </b>'Hello '<br><span class=nocode>2. </span>  + '&lt;World&gt;';</pre></td>
-    <td class="golden"><pre>^print ^'Hello '^\n^  + '&lt;World&gt;';^</pre></td>
-  </tr>
-  <tr><th colspan=3>Test whitespace normalized in code</th></tr>
-  <tr>
-    <td><code class="testinput"><b>print </b>'Hello '
-  + '&lt;World&gt;';</pre></td>
-    <td class="golden"><pre>^print ^'Hello ' + '&lt;World&gt;';^</pre></td>
-  </tr>
-  <tr><th colspan=3>Test XMP</th></tr>
-  <tr>
-    <td><xmp class="testinput">print 'Hello '
-  + '<World>';
-    
^print 'Hello '\n  + '<World>';^
- - Test tabs - -
print 'Hello '
-	+ '<World>';
-
^print 'Hello '\n\t+ '<World>';^
- - Test number lines output - -
  • print 'Hello '
  • + '<World>';
-
^print ^'Hello '^\n^  + '<World>';^^
- - - - - -
-
- Last modified: Tue Mar 29 16:38:23 PDT 2011 - diff --git a/js-modules/js_include.pl b/js-modules/js_include.pl deleted file mode 100644 index 8d3b6238..00000000 --- a/js-modules/js_include.pl +++ /dev/null @@ -1,76 +0,0 @@ -#!/usr/bin/perl - -# Given a JS file looks for lines like -# include("path/to/file/to/include"); -# and replaces them with the quoted file relative to the js-modules directory. -# If the included file ends with ".pl" then it is treated as a perl file to -# execute and the stdout is used as the JS to include. - -use strict; - -# Closure Compiler @define annotations that need to be pulled out of included -# files because @defines need to be top-level vars. -my $global_defs = ""; - -# Find @defines at the top of a JS file by pulling off comments and looking for -# comments containing @define followed by a var declaration. -sub extractGlobalDefs($) { - my @headerComments; - my $s = shift; - while ($s) { - last unless $s =~ m#^\s*(?://[^\r\n]*|/\*.*?\*/[ \t]*)[\r\n]*#s; - my $comment = $&; - $s = $'; - if ($comment =~ /[\@]define/ && $s =~ /^\s*var\s+[^;]+;[ \t]*[\r\n]*/) { - my $global = $&; - $s = $'; - $global =~ s/(var\s*IN_GLOBAL_SCOPE\s*=\s*)true\b/$1false/; - $global_defs .= "$comment$global"; - } else { - push(@headerComments, $comment); - } - } - return (join "", @headerComments) . $s; -} - -# readInclude(whiteSpacePrefix, path) returns the JS content at path -# (with the ".pl" adjustment above) and prepends each line with the -# whitespace in whiteSpacePrefix to produce a chunk of JS that matches the -# indentation of the including file. -# @defines are extracted so that they can all appear globally at the top of -# the file. -sub readInclude($$) { - my $prefix = shift; - my $name = "js-modules/" . (shift); - my $in; - if ($name =~ /\.pl$/) { - open($in, "perl $name|") or die "$name: $!"; - } else { - open($in, "<$name") or die "$name: $!"; - } - my $buf = ""; - while (<$in>) { - if (m/(\s*)include\("([^"]+)"\);\s*$/) { - my $inc = extractGlobalDefs(readInclude("$prefix$1", $2)); - $buf .= $inc; - } else { - $buf .= "$prefix$_"; - } - } - close($in); - return $buf; -} - -my $target = shift; -my $inc = readInclude("", $target); -my $header = ""; -# Put descriptive top level comments above the grouped @defines. -if ($inc =~ s#^(?://[^\r\n]*|/\*.*?\*/|\s)+##s) { - $header = $&; -} -my $globals = $global_defs; -# Un-indent @defines. -$globals =~ s#^[ \t]*##gm; -$globals .= "\n" unless $globals eq ""; - -print "$header$globals$inc"; diff --git a/js-modules/node_prettify.js b/js-modules/node_prettify.js new file mode 100644 index 00000000..7262a48e --- /dev/null +++ b/js-modules/node_prettify.js @@ -0,0 +1,16 @@ + +var IN_GLOBAL_SCOPE = false; + +/* @include prettify.js */ + +var path = require('path'); + +module.exports = { + prettyPrint: prettyPrint, + prettyPrintOne: prettyPrintOne, + // include paths for css preprocessor support + includePaths: [ + __dirname, + path.resolve(__dirname, '../styles') + ] +}; diff --git a/js-modules/numberLines.js b/js-modules/numberLines.js index 840fe0be..e7ee3a42 100644 --- a/js-modules/numberLines.js +++ b/js-modules/numberLines.js @@ -6,10 +6,14 @@ * HTMLOListElement, and each line is moved into a separate list item. * This requires cloning elements, so the input might not have unique * IDs after numbering. + * @param {number|null|boolean} startLineNum + * If truthy, coerced to an integer which is the 1-indexed line number + * of the first line of code. The number of the first line will be + * attached to the list. * @param {boolean} isPreformatted true iff white-space in text nodes should * be treated as significant. */ -function numberLines(node, opt_startLineNum, isPreformatted) { +function numberLines(node, startLineNum, isPreformatted) { var nocode = /(?:^|\s)nocode(?:\s|$)/; var lineBreak = /\r\n?|\n/; @@ -26,7 +30,7 @@ function numberLines(node, opt_startLineNum, isPreformatted) { function walk(node) { var type = node.nodeType; if (type == 1 && !nocode.test(node.className)) { // Element - if ('br' === node.nodeName) { + if ('br' === node.nodeName.toLowerCase()) { breakAfter(node); // Discard the
since it is now flush against a . if (node.parentNode) { @@ -110,13 +114,13 @@ function numberLines(node, opt_startLineNum, isPreformatted) { } // Make sure numeric indices show correctly. - if (opt_startLineNum === (opt_startLineNum|0)) { - listItems[0].setAttribute('value', opt_startLineNum); + if (startLineNum === (startLineNum|0)) { + listItems[0].setAttribute('value', startLineNum); } var ol = document.createElement('ol'); ol.className = 'linenums'; - var offset = Math.max(0, ((opt_startLineNum - 1 /* zero index */)) | 0) || 0; + var offset = Math.max(0, ((startLineNum - 1 /* zero index */)) | 0) || 0; for (var i = 0, n = listItems.length; i < n; ++i) { li = listItems[i]; // Stick a class on the LIs so that stylesheets can @@ -130,4 +134,4 @@ function numberLines(node, opt_startLineNum, isPreformatted) { } node.appendChild(ol); -} \ No newline at end of file +} diff --git a/js-modules/numberLines_test.html b/js-modules/numberLines_test.html deleted file mode 100644 index a074e014..00000000 --- a/js-modules/numberLines_test.html +++ /dev/null @@ -1,119 +0,0 @@ - - -Number Lines Test - - - - - - -

Number Lines Test

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Test Nothing to Split
Hello, World!
  1. Hello, World!
Test Normalized Spaces
Hello, World!
  1. Hello, World!
Test BR
Hello,
World!
  1. Hello,
  2. World!
Test line breaks
Hello,
there
World!
  1. Hello,
  2. there
  3. World!
Test line breaks with followers
Hello,
there
World!
  1. Hello,
  2. there
  3. World!
Test nocode
Hello,
there
World!
  1. Hello,
  2. there World!
Test link
Hello,
there
World!
  1. Hello,
  2. there
  3. World!
Test blank lines
One

Three
  1. One
  2.  
  3. Three
- - - -
-
- Last modified: Tue Mar 29 16:44:05 PDT 2011 - diff --git a/js-modules/prettify.js b/js-modules/prettify.js index 7c45c4be..872c44b7 100644 --- a/js-modules/prettify.js +++ b/js-modules/prettify.js @@ -1,17 +1,19 @@ -// 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. - +/** + * @license + * 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. + */ /** * @fileoverview @@ -19,7 +21,7 @@ * *

* For a fairly comprehensive set of languages see the - * README + * README * 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 @@ -55,15 +57,44 @@ // JSLint declarations /*global console, document, navigator, setTimeout, window, define */ -/** @define {boolean} */ -var IN_GLOBAL_SCOPE = true; +/* @ifndef RUN_PRETTIFY */ +/* @include defs.js */ +/* @endif */ + +/** + * {@type !{ + * 'createSimpleLexer': function (Array, Array): (function (JobT)), + * 'registerLangHandler': function (function (JobT), Array.), + * 'PR_ATTRIB_NAME': string, + * 'PR_ATTRIB_NAME': string, + * 'PR_ATTRIB_VALUE': string, + * 'PR_COMMENT': string, + * 'PR_DECLARATION': string, + * 'PR_KEYWORD': string, + * 'PR_LITERAL': string, + * 'PR_NOCODE': string, + * 'PR_PLAIN': string, + * 'PR_PUNCTUATION': string, + * 'PR_SOURCE': string, + * 'PR_STRING': string, + * 'PR_TAG': string, + * 'PR_TYPE': string, + * 'prettyPrintOne': function (string, string, number|boolean), + * 'prettyPrint': function (?function, ?(HTMLElement|HTMLDocument)) + * }} + * @const + */ +var PR; /** * Split {@code prettyPrint} into multiple timeouts so as not to interfere with * UI events. * If set to {@code false}, {@code prettyPrint()} is synchronous. */ -window['PR_SHOULD_USE_CONTINUATION'] = true; +var PR_SHOULD_USE_CONTINUATION = true +if (typeof window !== 'undefined') { + window['PR_SHOULD_USE_CONTINUATION'] = PR_SHOULD_USE_CONTINUATION; +} /** * Pretty print a chunk of code. @@ -88,37 +119,38 @@ var prettyPrint; (function () { - var win = window; + var win = (typeof window !== 'undefined') ? window : {}; // Keyword lists for various languages. // We use things that coerce to strings to make them compact when minified // and to defeat aggressive optimizers that fold large string constants. var FLOW_CONTROL_KEYWORDS = ["break,continue,do,else,for,if,return,while"]; - var C_KEYWORDS = [FLOW_CONTROL_KEYWORDS,"auto,case,char,const,default," + - "double,enum,extern,float,goto,inline,int,long,register,short,signed," + + var C_KEYWORDS = [FLOW_CONTROL_KEYWORDS,"auto,case,char,const,default," + + "double,enum,extern,float,goto,inline,int,long,register,restrict,short,signed," + "sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"]; var COMMON_KEYWORDS = [C_KEYWORDS,"catch,class,delete,false,import," + "new,operator,private,protected,public,this,throw,true,try,typeof"]; - var CPP_KEYWORDS = [COMMON_KEYWORDS,"alignof,align_union,asm,axiom,bool," + + var CPP_KEYWORDS = [COMMON_KEYWORDS,"alignas,alignof,align_union,asm,axiom,bool," + "concept,concept_map,const_cast,constexpr,decltype,delegate," + "dynamic_cast,explicit,export,friend,generic,late_check," + - "mutable,namespace,nullptr,property,reinterpret_cast,static_assert," + + "mutable,namespace,noexcept,noreturn,nullptr,property,reinterpret_cast,static_assert," + "static_cast,template,typeid,typename,using,virtual,where"]; var JAVA_KEYWORDS = [COMMON_KEYWORDS, - "abstract,assert,boolean,byte,extends,final,finally,implements,import," + + "abstract,assert,boolean,byte,extends,finally,final,implements,import," + "instanceof,interface,null,native,package,strictfp,super,synchronized," + "throws,transient"]; - var CSHARP_KEYWORDS = [JAVA_KEYWORDS, - "as,base,by,checked,decimal,delegate,descending,dynamic,event," + - "fixed,foreach,from,group,implicit,in,internal,into,is,let," + - "lock,object,out,override,orderby,params,partial,readonly,ref,sbyte," + - "sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort," + - "var,virtual,where"]; + var CSHARP_KEYWORDS = [COMMON_KEYWORDS, + "abstract,add,alias,as,ascending,async,await,base,bool,by,byte,checked,decimal,delegate,descending," + + "dynamic,event,finally,fixed,foreach,from,get,global,group,implicit,in,interface," + + "internal,into,is,join,let,lock,null,object,out,override,orderby,params," + + "partial,readonly,ref,remove,sbyte,sealed,select,set,stackalloc,string,select,uint,ulong," + + "unchecked,unsafe,ushort,value,var,virtual,where,yield"]; var 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," + "throw,true,try,unless,until,when,while,yes"; var JSCRIPT_KEYWORDS = [COMMON_KEYWORDS, - "debugger,eval,export,function,get,null,set,undefined,var,with," + - "Infinity,NaN"]; + "abstract,async,await,constructor,debugger,enum,eval,export,from,function," + + "get,import,implements,instanceof,interface,let,null,of,set,undefined," + + "var,with,yield,Infinity,NaN"]; var 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"; @@ -130,15 +162,12 @@ var prettyPrint; "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"]; - var RUST_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "as,assert,const,copy,drop," + - "enum,extern,fail,false,fn,impl,let,log,loop,match,mod,move,mut,priv," + - "pub,pure,ref,self,static,struct,true,trait,type,unsafe,use"]; var SH_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "case,done,elif,esac,eval,fi," + "function,in,local,set,then,until"]; var ALL_KEYWORDS = [ - CPP_KEYWORDS, CSHARP_KEYWORDS, JSCRIPT_KEYWORDS, PERL_KEYWORDS, - PYTHON_KEYWORDS, RUBY_KEYWORDS, SH_KEYWORDS]; - var C_TYPES = /^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)\b/; + CPP_KEYWORDS, CSHARP_KEYWORDS, JAVA_KEYWORDS, JSCRIPT_KEYWORDS, + PERL_KEYWORDS, PYTHON_KEYWORDS, RUBY_KEYWORDS, SH_KEYWORDS]; + var C_TYPES = /^(DIR|FILE|array|vector|(de|priority_)?queue|(forward_)?list|stack|(const_)?(reverse_)?iterator|(unordered_)?(multi)?(set|map)|bitset|u?(int|float)\d*)\b/; // token style names. correspond to css classes /** @@ -210,23 +239,35 @@ var prettyPrint; */ var PR_NOCODE = 'nocode'; - include("regexpPrecederPatterns.pl"); + /* @include regexpPrecederPatterns.js */ - include("combinePrefixPatterns.js"); + /* @include combinePrefixPatterns.js */ - include("extractSourceSpans.js"); + /* @include extractSourceSpans.js */ /** * Apply the given language handler to sourceCode and add the resulting * decorations to out. + * @param {!Element} sourceNode * @param {number} basePos the index of sourceCode within the chunk of source * whose decorations are already present on out. + * @param {string} sourceCode + * @param {function(JobT)} langHandler + * @param {DecorationsT} out */ - function appendDecorations(basePos, sourceCode, langHandler, out) { + function appendDecorations( + sourceNode, basePos, sourceCode, langHandler, out) { if (!sourceCode) { return; } + /** @type {JobT} */ var job = { + sourceNode: sourceNode, + pre: 1, + langExtension: null, + numberLines: null, sourceCode: sourceCode, - basePos: basePos + spans: null, + basePos: basePos, + decorations: null }; langHandler(job); out.push.apply(out, job.decorations); @@ -301,8 +342,8 @@ var prettyPrint; * @param {Array} fallthroughStylePatterns patterns that will be tried in * order if the shortcut ones fail. May have shortcuts. * - * @return {function (Object)} a - * function that takes source code and returns a list of decorations. + * @return {function (JobT)} a function that takes an undecorated job and + * attaches a list of decorations. */ function createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns) { var shortcuts = {}; @@ -333,22 +374,19 @@ var prettyPrint; var nPatterns = fallthroughStylePatterns.length; /** - * Lexes job.sourceCode and produces an output array job.decorations of + * Lexes job.sourceCode and attaches an output array job.decorations of * style classes preceded by the position at which they start in * job.sourceCode in order. * - * @param {Object} job an object like

{
-     *    sourceCode: {string} sourceText plain text,
-     *    basePos: {int} position of job.sourceCode in the larger chunk of
-     *        sourceCode.
-     * }
+ * @type{function (JobT)} */ var decorate = function (job) { var sourceCode = job.sourceCode, basePos = job.basePos; + var sourceNode = job.sourceNode; /** 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.} + * @type {DecorationsT} */ var decorations = [basePos, PR_PLAIN]; var pos = 0; // index into sourceCode @@ -411,17 +449,20 @@ var prettyPrint; var lang = style.substring(5); // Decorate the left of the embedded source appendDecorations( + sourceNode, basePos + tokenStart, token.substring(0, embeddedSourceStart), decorate, decorations); // Decorate the embedded source appendDecorations( + sourceNode, basePos + tokenStart + embeddedSourceStart, embeddedSource, langHandlerForExtension(lang, embeddedSource), decorations); // Decorate the right of the embedded section appendDecorations( + sourceNode, basePos + tokenStart + embeddedSourceEnd, token.substring(embeddedSourceEnd), decorate, decorations); @@ -444,8 +485,9 @@ var prettyPrint; * It recognizes C, C++, and shell style comments. * * @param {Object} options a set of optional parameters. - * @return {function (Object)} a function that examines the source code - * in the input job and builds the decoration list. + * @return {function (JobT)} a function that examines the source code + * in the input job and builds a decoration list which it attaches to + * the job. */ function sourceDecorator(options) { var shortcutStylePatterns = [], fallthroughStylePatterns = []; @@ -497,7 +539,18 @@ var prettyPrint; fallthroughStylePatterns.push( [PR_COMMENT, /^\/\*[\s\S]*?(?:\*\/|$)/, null]); } - if (options['regexLiterals']) { + var regexLiterals = options['regexLiterals']; + if (regexLiterals) { + /** + * @const + */ + var regexExcls = regexLiterals > 1 + ? '' // Multiline regex literals + : '\n\r'; + /** + * @const + */ + var regexAny = regexExcls ? '.' : '[\\S\\s]'; /** * @const */ @@ -505,18 +558,19 @@ var prettyPrint; // A regular expression literal starts with a slash that is // not followed by * or / so that it is not confused with // comments. - '/(?=[^/*])' + '/(?=[^/*' + regexExcls + '])' // and then contains any number of raw characters, - + '(?:[^/\\x5B\\x5C]' + + '(?:[^/\\x5B\\x5C' + regexExcls + ']' // escape sequences (\x5C), - + '|\\x5C[\\s\\S]' + + '|\\x5C' + regexAny // or non-nesting character sets (\x5B\x5D); - + '|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+' + + '|\\x5B(?:[^\\x5C\\x5D' + regexExcls + ']' + + '|\\x5C' + regexAny + ')*(?:\\x5D|$))+' // finally closed by a /. + '/'); fallthroughStylePatterns.push( ['lang-regex', - new RegExp('^' + REGEXP_PRECEDER_PATTERN + '(' + REGEX_LITERAL + ')') + RegExp('^' + REGEXP_PRECEDER_PATTERN + '(' + REGEX_LITERAL + ')') ]); } @@ -543,7 +597,7 @@ var prettyPrint; // which are the following plus space, tab, and newline: { } // | & $ ; < > // ... - + // A word beginning with # causes that word and all remaining // characters on that line to be ignored. @@ -571,7 +625,10 @@ var prettyPrint; // If that does turn out to be a problem, we should change the below // when hc is truthy to include # in the run of punctuation characters // only when not followint [|&;<>]. - /^.[^\s\w\.$@\'\"\`\/\\]*/; + '^.[^\\s\\w.$@\'"`/\\\\]*'; + if (options['regexLiterals']) { + punctuation += '(?!\s*\/)'; + } fallthroughStylePatterns.push( // TODO(mikesamuel): recognize non-latin letters and numerals in idents @@ -591,9 +648,10 @@ var prettyPrint; // with an optional modifier like UL for unsigned long + '[a-z]*', 'i'), null, '0123456789'], - // Don't treat escaped quotes in bash as starting strings. See issue 144. + // Don't treat escaped quotes in bash as starting strings. + // See issue 144. [PR_PLAIN, /^\\[\s\S]?/, null], - [PR_PUNCTUATION, punctuation, null]); + [PR_PUNCTUATION, new RegExp(punctuation), null]); return createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns); } @@ -606,26 +664,16 @@ var prettyPrint; 'regexLiterals': true }); - include("numberLines.js"); + /* @include numberLines.js */ - include("recombineTagsAndDecorations.js"); + /* @include recombineTagsAndDecorations.js */ /** Maps language-specific file extensions to handlers. */ var langHandlerRegistry = {}; /** Register a language handler for the given file extensions. - * @param {function (Object)} handler a function from source code to a list + * @param {function (JobT)} 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.} 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. - * } } + * state of the computation and attaches the decorations to it. * @param {Array.} fileExtensions */ function registerLangHandler(handler, fileExtensions) { @@ -724,7 +772,7 @@ var prettyPrint; 'keywords': PERL_KEYWORDS, 'hashComments': true, 'multiLineStrings': true, - 'regexLiterals': true + 'regexLiterals': 2 // multiline regex literals }), ['perl', 'pl', 'pm']); registerLangHandler(sourceDecorator({ 'keywords': RUBY_KEYWORDS, @@ -736,7 +784,7 @@ var prettyPrint; 'keywords': JSCRIPT_KEYWORDS, 'cStyleComments': true, 'regexLiterals': true - }), ['javascript', 'js']); + }), ['javascript', 'js', 'ts', 'typescript']); registerLangHandler(sourceDecorator({ 'keywords': COFFEE_KEYWORDS, 'hashComments': 3, // ### style block comments @@ -745,14 +793,10 @@ var prettyPrint; 'tripleQuotedStrings': true, 'regexLiterals': true }), ['coffee']); - registerLangHandler(sourceDecorator({ - 'keywords': RUST_KEYWORDS, - 'cStyleComments': true, - 'multilineStrings': true - }), ['rc', 'rs', 'rust']); registerLangHandler( createSimpleLexer([], [[PR_STRING, /^[\s\S]+/]]), ['regex']); + /** @param {JobT} job */ function applyDecorator(job) { var opt_langExtension = job.langExtension; @@ -773,7 +817,7 @@ var prettyPrint; recombineTagsAndDecorations(job); } catch (e) { if (win['console']) { - console['log'](e && e['stack'] ? e['stack'] : e); + console['log'](e && e['stack'] || e); } } } @@ -787,6 +831,11 @@ var prettyPrint; * or the 1-indexed number of the first line in sourceCodeHtml. */ function $prettyPrintOne(sourceCodeHtml, opt_langExtension, opt_numberLines) { + /** @type{number|boolean} */ + var nl = opt_numberLines || false; + /** @type{string|null} */ + var langExtension = opt_langExtension || null; + /** @type{!Element} */ var container = document.createElement('div'); // This could cause images to load and onload listeners to fire. // E.g. . @@ -796,16 +845,21 @@ var prettyPrint; // http://stackoverflow.com/questions/451486/pre-tag-loses-line-breaks-when-setting-innerhtml-in-ie // http://stackoverflow.com/questions/195363/inserting-a-newline-into-a-pre-tag-ie-javascript container.innerHTML = '
' + sourceCodeHtml + '
'; - container = container.firstChild; - if (opt_numberLines) { - numberLines(container, opt_numberLines, true); + container = /** @type{!Element} */(container.firstChild); + if (nl) { + numberLines(container, nl, true); } + /** @type{JobT} */ var job = { - langExtension: opt_langExtension, - numberLines: opt_numberLines, + langExtension: langExtension, + numberLines: nl, sourceNode: container, - pre: 1 + pre: 1, + sourceCode: null, + basePos: null, + spans: null, + decorations: null }; applyDecorator(job); return container.innerHTML; @@ -842,7 +896,6 @@ var prettyPrint; // The loop is broken into a series of continuations to make sure that we // don't make the browser unresponsive when rewriting a large page. var k = 0; - var prettyPrintingJob; var langExtensionRe = /\blang(?:uage)?-([\w.]+)(?!\S)/; var prettyPrintRe = /\bprettyprint\b/; @@ -850,6 +903,7 @@ var prettyPrint; var preformattedTagNameRe = /pre|xmp/i; var codeRe = /^code$/i; var preCodeXmpRe = /^(?:pre|code|xmp)$/i; + var EMPTY = {}; function doWork() { var endTime = (win['PR_SHOULD_USE_CONTINUATION'] ? @@ -857,8 +911,34 @@ var prettyPrint; Infinity); for (; k < elements.length && clock['now']() < endTime; k++) { var cs = elements[k]; + + // Look for a preceding comment like + // + var attrs = EMPTY; + { + for (var preceder = cs; (preceder = preceder.previousSibling);) { + var nt = preceder.nodeType; + // is parsed by HTML 5 to a comment node (8) + // like , but in XML is a processing instruction + var value = (nt === 7 || nt === 8) && preceder.nodeValue; + if (value + ? !/^\??prettify\b/.test(value) + : (nt !== 3 || /\S/.test(preceder.nodeValue))) { + // Skip over white-space text nodes but not others. + break; + } + if (value) { + attrs = {}; + value.replace( + /\b(\w+)=([\w:.%+-]+)/g, + function (_, name, value) { attrs[name] = value; }); + break; + } + } + } + var className = cs.className; - if (prettyPrintRe.test(className) + if ((attrs !== EMPTY || prettyPrintRe.test(className)) // Don't redo this if we've already done it. // This allows recalling pretty print to just prettyprint elements // that have been added to the page since last call. @@ -887,15 +967,18 @@ var prettyPrint; // HTML5 recommends that a language be specified using "language-" // as the prefix instead. Google Code Prettify supports both. // http://dev.w3.org/html5/spec-author-view/the-code-element.html - var langExtension = className.match(langExtensionRe); - // Support

-            var wrapper;
-            if (!langExtension && (wrapper = childContentWrapper(cs))
-                && codeRe.test(wrapper.tagName)) {
-              langExtension = wrapper.className.match(langExtensionRe);
-            }
+            var langExtension = attrs['lang'];
+            if (!langExtension) {
+              langExtension = className.match(langExtensionRe);
+              // Support 

+              var wrapper;
+              if (!langExtension && (wrapper = childContentWrapper(cs))
+                  && codeRe.test(wrapper.tagName)) {
+                langExtension = wrapper.className.match(langExtensionRe);
+              }
 
-            if (langExtension) { langExtension = langExtension[1]; }
+              if (langExtension) { langExtension = langExtension[1]; }
+            }
 
             var preformatted;
             if (preformattedTagNameRe.test(cs.tagName)) {
@@ -917,18 +1000,27 @@ var prettyPrint;
 
             // Look for a class like linenums or linenums: where  is the
             // 1-indexed number of the first line.
-            var lineNums = cs.className.match(/\blinenums\b(?::(\d+))?/);
-            lineNums = lineNums
-                ? lineNums[1] && lineNums[1].length ? +lineNums[1] : true
+            var lineNums = attrs['linenums'];
+            if (!(lineNums = lineNums === 'true' || +lineNums)) {
+              lineNums = className.match(/\blinenums\b(?::(\d+))?/);
+              lineNums =
+                lineNums
+                ? lineNums[1] && lineNums[1].length
+                  ? +lineNums[1] : true
                 : false;
+            }
             if (lineNums) { numberLines(cs, lineNums, preformatted); }
 
             // do the pretty printing
-            prettyPrintingJob = {
+            var prettyPrintingJob = {
               langExtension: langExtension,
               sourceNode: cs,
               numberLines: lineNums,
-              pre: preformatted
+              pre: preformatted,
+              sourceCode: null,
+              basePos: null,
+              spans: null,
+              decorations: null
             };
             applyDecorator(prettyPrintingJob);
           }
@@ -936,7 +1028,7 @@ var prettyPrint;
       }
       if (k < elements.length) {
         // finish up in a continuation
-        setTimeout(doWork, 250);
+        win.setTimeout(doWork, 250);
       } else if ('function' === typeof opt_whenDone) {
         opt_whenDone();
       }
@@ -970,7 +1062,7 @@ var prettyPrint;
            IN_GLOBAL_SCOPE
              ? (win['prettyPrintOne'] = $prettyPrintOne)
              : (prettyPrintOne = $prettyPrintOne),
-        'prettyPrint': prettyPrint =
+        'prettyPrint':
            IN_GLOBAL_SCOPE
              ? (win['prettyPrint'] = $prettyPrint)
              : (prettyPrint = $prettyPrint)
@@ -988,9 +1080,10 @@ var prettyPrint;
   // whose value is an object. This helps avoid conflict with any
   // other existing JavaScript code that could have defined a define()
   // function that does not conform to the AMD API.
+  var define = win['define'];
   if (typeof define === "function" && define['amd']) {
     define("google-code-prettify", [], function () {
-      return PR; 
+      return PR;
     });
   }
 })();
diff --git a/js-modules/recombineTagsAndDecorations.js b/js-modules/recombineTagsAndDecorations.js
index 33a8fb3f..69b1a8f0 100644
--- a/js-modules/recombineTagsAndDecorations.js
+++ b/js-modules/recombineTagsAndDecorations.js
@@ -1,14 +1,7 @@
 /**
  * Breaks {@code job.sourceCode} around style boundaries in
  * {@code job.decorations} and modifies {@code job.sourceNode} in place.
- * @param {Object} job like 
{
- *    sourceCode: {string} source as plain text,
- *    spans: {Array.} alternating span start indices into source
- *       and the text node or element (e.g. {@code 
}) corresponding to that - * span. - * decorations: {Array. + * @param {JobT} job * @private */ function recombineTagsAndDecorations(job) { @@ -62,7 +55,7 @@ function recombineTagsAndDecorations(job) { nDecorations = decorations.length = decPos; var sourceNode = job.sourceNode; - var oldDisplay; + var oldDisplay = ""; if (sourceNode) { oldDisplay = sourceNode.style.display; sourceNode.style.display = 'none'; @@ -71,13 +64,14 @@ function recombineTagsAndDecorations(job) { var decoration = null; while (spanIndex < nSpans) { var spanStart = spans[spanIndex]; - var spanEnd = spans[spanIndex + 2] || sourceLength; + var spanEnd = /** @type{number} */ (spans[spanIndex + 2]) + || sourceLength; var decEnd = decorations[decorationIndex + 2] || sourceLength; var end = Math.min(spanEnd, decEnd); - var textNode = spans[spanIndex + 1]; + var textNode = /** @type{Node} */ (spans[spanIndex + 1]); var styledText; if (textNode.nodeType !== 1 // Don't muck with
s or
  • s // Don't introduce spans around empty text nodes. diff --git a/js-modules/recombineTagsAndDecorations_test.html b/js-modules/recombineTagsAndDecorations_test.html deleted file mode 100644 index 555ee3c6..00000000 --- a/js-modules/recombineTagsAndDecorations_test.html +++ /dev/null @@ -1,98 +0,0 @@ - - -Recombine Tags And Decorations - - - - - - - - - -

    Recombine Tags And Decorations

    - - - - - - - - - - - - - - - - - - - - -
    Test Single Decoration
    "Hello, World!"[0, 'str']"Hello, World!"
    Test Single Span
    print "Hello, <World>!";[0, 'kwd', 5, 'pln', 6, 'str', 14, 'tag', 21, 'str', 23, 'pun']print "Hello, <World>!";
    Test Interleaved
    print "Hello, <World>!";[0, 'kwd', 5, 'pln', 6, 'str', 14, 'tag', 21, 'str', 23, 'pun']print "Hello, <World>!";
    - - - -
    -
    - Last modified: Tue Mar 29 10:41:34 PDT 2011 - diff --git a/js-modules/regexpPrecederPatterns.js b/js-modules/regexpPrecederPatterns.js new file mode 100644 index 00000000..65d3de53 --- /dev/null +++ b/js-modules/regexpPrecederPatterns.js @@ -0,0 +1,30 @@ + +// Regex pattern below is automatically generated by regexpPrecederPatterns.pl +// Do not modify, your changes will be erased. + +// 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. + +/** + * 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. + * + * 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. + * + * 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 + * @const + */ +var REGEXP_PRECEDER_PATTERN = '(?:^^\\.?|[+-]|[!=]=?=?|\\#|%=?|&&?=?|\\(|\\*=?|[+\\-]=|->|\\/=?|::?|<>?>?=?|,|;|\\?|@|\\[|~|{|\\^\\^?=?|\\|\\|?=?|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*'; diff --git a/js-modules/regexpPrecederPatterns.pl b/js-modules/regexpPrecederPatterns.pl index 488dbd68..0f1e1d59 100644 --- a/js-modules/regexpPrecederPatterns.pl +++ b/js-modules/regexpPrecederPatterns.pl @@ -1,6 +1,14 @@ use strict; print " +// Regex pattern below is automatically generated by regexpPrecederPatterns.pl +// Do not modify, your changes will be erased. + +// 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. /** * A set of tokens that can precede a regular expression literal in @@ -9,12 +17,12 @@ * has the full list, but I've removed ones that might be problematic when * seen in languages that don't support regular expression literals. * - *

    Specifically, I've removed any keywords that can't precede a regexp + * 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. * - *

    The link above does not accurately describe EcmaScript rules since + * 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. * @@ -34,7 +42,7 @@ "->", "\\/=?", # "/", "/=", "::?", # ":", "::", - "<>?>?=?", # ">", ">=", ">>", ">>=", ">>>", ">>>=", ",", ";", # ";" @@ -58,11 +66,3 @@ $pattern .= ")\\\\s*'"; # matches at end, and matches empty string print "$pattern;\n"; - -print " -// 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. -"; diff --git a/js-modules/run_prettify.js b/js-modules/run_prettify.js index 1a283186..faae9897 100644 --- a/js-modules/run_prettify.js +++ b/js-modules/run_prettify.js @@ -1,64 +1,69 @@ -// Copyright (C) 2013 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. - - -// Looks at query parameters to decide which language handlers and style-sheets -// to load. - -// Query Parameter Format Effect Default -// +------------------+---------------+------------------------------+--------+ -// | autorun= | true | false | If true then prettyPrint() | "true" | -// | | | is called on page load. | | -// +------------------+---------------+------------------------------+--------+ -// | lang= | language name | Loads the language handler | Can | -// | | | named "lang-.js". | appear | -// | | | See available handlers at | many | -// | | | http://code.google.com/p/ | times. | -// | | | google-code-prettify/source/ | | -// | | | browse/trunk/src | | -// +------------------+---------------+------------------------------+--------+ -// | skin= | skin name | Loads the skin stylesheet | none. | -// | | | named ".css". | | -// | | | http://code.google.com/p/ | | -// | | | google-code-prettify/source/ | | -// | | | browse/trunk/styles | | -// +------------------+---------------+------------------------------+--------+ -// | namespace= | dotted ident | Attaches prettyPrint and | none | -// | | | related functions to the | | -// | | | global object at that path | | -// | | | so they are accessible to | | -// | | | client code. | | -// +------------------+---------------+------------------------------+--------+ -// | callback= | JS identifier | When "prettyPrint" finishes | none | -// | | | window.exports[js_ident] is | | -// | | | called. | | -// | | | The callback must be under | | -// | | | exports to reduce the risk | | -// | | | of XSS via query parameter | | -// | | | injection. | | -// +------------------+---------------+------------------------------+--------+ - -// Exmaples -// .../prettify.js?lang=css&skin=sunburst -// 1. Loads the CSS language handler which can be used to prettify CSS -// stylesheets, HTML - - + - -

    + + +
    +<!doctype html>
    +<html>
    +<head>
    +<title>HTML Test</title>
     <script type="text/javascript">
     // Say hello world until the user starts questioning
     // the meaningfulness of their existence.
    @@ -51,11 +94,18 @@
       }
     }
     </script>
    -<style>
    +<style type="text/css">
     p { color: pink }
     b { color: blue }
     u { color: "umber" }
     </style>
    +</head>
    +<body>
    +<h1>Hello world!</h1>
    +</body>
    +</html>
     
    - + + + diff --git a/styles/doxy.css b/styles/doxy.css index b0e89161..f328738a 100644 --- a/styles/doxy.css +++ b/styles/doxy.css @@ -51,7 +51,7 @@ li.L1,li.L3,li.L5,li.L7,li.L9 { } pre.prettyprint, code.prettyprint { background-color: #fff; } pre .str, code .str { color: #088; } pre .kwd, code .kwd { color: #006; font-weight: bold; } - pre .com, code .com { color: #oc3; font-style: italic; } + pre .com, code .com { color: #0c3; font-style: italic; } pre .typ, code .typ { color: #404; font-weight: bold; } pre .lit, code .lit { color: #044; } pre .pun, code .pun { color: #440; } diff --git a/styles/index.html b/styles/index.html index abd6ef52..ba171df7 100644 --- a/styles/index.html +++ b/styles/index.html @@ -1,39 +1,73 @@ - - + + + Prettify Themes Gallery - @@ -42,48 +76,28 @@

    Gallery of themes for -code prettify

    +code prettify

    Click on a theme name for a link to the file in revision control. Print preview this page to see how the themes work on the printed page.

    - +})(); + - + + diff --git a/styles/sunburst.css b/styles/sunburst.css index 011d33e2..ae06306a 100644 --- a/styles/sunburst.css +++ b/styles/sunburst.css @@ -15,11 +15,6 @@ pre .dec, code .dec { color: #3387CC; } /* decimal - blue */ pre.prettyprint, code.prettyprint { background-color: #000; - -moz-border-radius: 8px; - -webkit-border-radius: 8px; - -o-border-radius: 8px; - -ms-border-radius: 8px; - -khtml-border-radius: 8px; border-radius: 8px; } diff --git a/tasks/aliases.js b/tasks/aliases.js new file mode 100644 index 00000000..e67aadf9 --- /dev/null +++ b/tasks/aliases.js @@ -0,0 +1,72 @@ +/** + * google-code-prettify + * https://github.com/google/code-prettify + * + * @author Amro + * @license Apache-2.0 + */ + +module.exports = function (grunt) { + 'use strict'; + + var fs = require('fs'); + var runLanguageHandler = require('./lib/lang-aliases'); + + /** + * Copy timestamp from source to destination file. + * @param {string} src + * @param {string} dest + * @param {boolean} timestamp + */ + function syncTimestamp(src, dest, timestamp) { + if (timestamp) { + var stat = fs.lstatSync(src); + var fd = fs.openSync(dest, process.platform === 'win32' ? 'r+' : 'r'); + fs.futimesSync(fd, stat.atime, stat.mtime); + fs.closeSync(fd); + } + } + + /** + * Copy file mode from source to destination. + * @param {string} src + * @param {string} dest + * @param {boolean|number} mode + */ + function syncMod(src, dest, mode) { + if (mode !== false) { + fs.chmodSync(dest, (mode === true) ? fs.lstatSync(src).mode : mode); + } + } + + // Create copies of language handler files under all registered aliases + grunt.registerMultiTask('aliases', 'Create language aliases', function () { + var opts = this.options({ + timestamp: false, + mode: false + }); + + var count = 0; + this.filesSrc.forEach(function (src) { + // run language handler in sandbox + grunt.verbose.subhead('Running ' + src.cyan + ' in sandbox...'); + var exts = runLanguageHandler(src); + grunt.verbose.ok(); + + // go over collected extensions + exts.forEach(function (ext) { + // copy file + var dest = src.replace(/\blang-\w+\b/, 'lang-' + ext); + grunt.verbose.writeln('Copying ' + src.cyan + ' -> ' + dest.cyan); + grunt.file.copy(src, dest); + + // sync timestamp and file mode + syncTimestamp(src, dest, opts.timestamp); + syncMod(src, dest, opts.mode); + count++; + }); + }); + grunt.log.ok('Copied ' + count.toString().cyan + + grunt.util.pluralize(count, ' file/ files')); + }); +}; diff --git a/tasks/gcc.js b/tasks/gcc.js new file mode 100644 index 00000000..cd64d29f --- /dev/null +++ b/tasks/gcc.js @@ -0,0 +1,49 @@ +/** + * google-code-prettify + * https://github.com/google/code-prettify + * + * @author Amro + * @license Apache-2.0 + */ + +module.exports = function (grunt) { + 'use strict'; + + /* + * HACK: Custom task to override "closure-compiler:langs" since all lang-* + * files are compiled in parallel, launching too many Java processes at once + * which easily runs out of memory! This task programmatically creates + * separate targets (one file per target) so that lang files are compiled + * sequentially (sync) instead of in parallel (async). + */ + grunt.registerMultiTask('gcc', 'Override closure-compiler', function () { + // closure-compiler:langs + var task = 'closure-compiler'; + var target = this.target; + if (!grunt.task.exists(task)) { + grunt.fail.warn(grunt.util.error('Require task "' + task + '".')); + } + + // create new targets for each file (one file per target) + var count = 0; + var opts = this.options(); + this.files.forEach(function (file, idx) { + // simple target config with only: src, dest, and options + delete file.orig; + file.options = opts; + + // configure new target + grunt.config.set([task, target + idx], file); + grunt.verbose.writeln('New target ' + (task + ':' + target + idx).cyan); + count++; + }); + grunt.log.ok('Configured ' + count.toString().cyan + ' lang targets'); + + // remove original multi-file target + grunt.config.set([task, target], {}); + + // enqueue modified task to run + //console.log(grunt.config.get(task)); + grunt.task.run(task); + }); +}; diff --git a/tasks/lib/lang-aliases.js b/tasks/lib/lang-aliases.js new file mode 100644 index 00000000..7272e829 --- /dev/null +++ b/tasks/lib/lang-aliases.js @@ -0,0 +1,92 @@ +/** + * google-code-prettify + * https://github.com/google/code-prettify + * + * @author Amro + * @license Apache-2.0 + */ + +var fs = require('fs'); +var path = require('path'); +var vm = require('vm'); + +/** + * Returns a mock object PR of the prettify API. This is used to collect + * registered language file extensions. + * + * @return {Object} PR object with an additional `extensions` property. + */ +function createSandbox() { + // collect registered language extensions + var sandbox = {}; + sandbox.extensions = []; + // mock prettify.js API + sandbox.window = {}; + sandbox.window.PR = sandbox.PR = { + registerLangHandler: function (handler, exts) { + sandbox.extensions = sandbox.extensions.concat(exts); + }, + createSimpleLexer: function (sPatterns, fPatterns) { + return function (job) {}; + }, + sourceDecorator: function (options) { + return function (job) {}; + }, + prettyPrintOne: function (src, lang, ln) { + return src; + }, + prettyPrint: function (done, root) {}, + PR_ATTRIB_NAME: 'atn', + PR_ATTRIB_VALUE: 'atv', + PR_COMMENT: 'com', + PR_DECLARATION: 'dec', + PR_KEYWORD: 'kwd', + PR_LITERAL: 'lit', + PR_NOCODE: 'nocode', + PR_PLAIN: 'pln', + PR_PUNCTUATION: 'pun', + PR_SOURCE: 'src', + PR_STRING: 'str', + PR_TAG: 'tag', + PR_TYPE: 'typ' + }; + return sandbox; +} + +/** + * Runs a language handler file under VM to collect extensions. + * + * Given a lang-*.js file, runs the language handler in a fake context where + * PR.registerLangHandler collects handler names without doing anything else. + * This is later used to makes copies of the JS extension under all its + * registered language names lang-.js + * + * @param {string} src path to lang-xxx.js language handler + * @return {Array} registered file extensions + */ +function runLanguageHandler(src) { + // execute source code in an isolated sandbox with a mock PR object + var sandbox = createSandbox(); + vm.runInNewContext(fs.readFileSync(src), sandbox, { + filename: src + }); + + // language name + var lang = path.basename(src, path.extname(src)).replace(/^lang-/, ''); + + // collect and filter extensions + var exts = sandbox.extensions.map(function (ext) { + // case-insensitive names + return ext.toLowerCase(); + }).filter(function (ext) { + // skip self, and internal names like foo-bar-baz or lang.foo + return ext !== lang && !/\W/.test(ext); + }); + exts = exts.filter(function (ext, pos) { + // remove duplicates + return exts.indexOf(ext) === pos; + }); + return exts; +} + +module.exports = runLanguageHandler; diff --git a/tests/debug-ie-compat-matrix.html b/tests/debug-ie-compat-matrix.html index 78125192..caa58ae4 100644 --- a/tests/debug-ie-compat-matrix.html +++ b/tests/debug-ie-compat-matrix.html @@ -1,8 +1,20 @@ - + + + + +

    IE Standard/Quirks Modes Test

    one short line, @@ -22,89 +34,100 @@
    -

    +

    Results

    +
    +

    +

    +
    - + if ('boolean' !== typeof quirksMode) { + throw new Error(quirksMode); + } else if ('number' !== typeof ieVersion || + !table.quirks.hasOwnProperty(+ieVersion)) { + throw new Error(ieVersion); + } + return table[quirksMode ? 'quirks' : 'standards'][ieVersion]; +} - - + + + diff --git a/tests/extractSourceSpans_test.html b/tests/extractSourceSpans_test.html new file mode 100644 index 00000000..60fa520b --- /dev/null +++ b/tests/extractSourceSpans_test.html @@ -0,0 +1,146 @@ + + + + +extractSourceSpans + + + + + + + +

    Extract Source Spans Test

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Test space preserved in PRE
    print 'Hello '
    + '<World>';
    ^print ^'Hello '^\n^  + '<World>';^
    Test class="nocode"
    1. print 'Hello '
    2. + '<World>';
    ^print ^'Hello '^\n^  + '<World>';^
    Test whitespace normalized in code
    print 'Hello ' + + '<World>';
    ^print ^'Hello ' + '<World>';^
    Test XMP
    print 'Hello ' + + '<World>';
    ^print 'Hello '\n  + '<World>';^
    Test tabs
    print 'Hello '
    +	+ '<World>';
    ^print 'Hello '\n\t+ '<World>';^
    Test number lines output
    • print 'Hello '
    • + '<World>';
    ^print ^'Hello '^\n^  + '<World>';^^
    + +
    +

    Log

    +
    + + + + + diff --git a/tests/ie-newline-copy-paste.html b/tests/ie-newline-copy-paste.html index 40c9adca..bfd601de 100644 --- a/tests/ie-newline-copy-paste.html +++ b/tests/ie-newline-copy-paste.html @@ -1,119 +1,124 @@ + + + + IE Newline Copy/Paste Info Gathering + + + +

    IE newline copy/paste

    +

    -I'm trying to squash, once and for all, the problems with newlines in -<PRE>s in IE. I can't run 3 versions of IE, so I'd +I'm trying to squash, once and for all, the problems with newlines in +<PRE>s in IE. I can't run all versions of IE, so I'd really appreciate any help from people who have IE open and running. +See bugs #20, +#104, and +#128 for +reference.

    -Please copy from START through END below and paste it into the -textarea below. -Then hit Ctrl-A, Ctrl-C to copy the textarea contents, and paste that -into an email. -Please also copy and paste the RESULTS section below and include it in -the email response as well and send it -to me or respond to the -discussion list. +Please copy from START through END below +and paste it into the TEXTAREA below. Then hit +Ctrl-A, Ctrl-C to copy the textarea contents, and paste +that into an email. Please also copy and paste the RESULTS +section below and include it in the email response as well and send it to +me or respond to the discussion +list.

    -In case you're interested, there are two problems: choosing a way to -split lines that doesn't introduce too few or extra newlines, and a -way to make sure that the resulting code can be copy-pasted into a -plain text editors such as the textarea below. This is my attempt to -gather information on both issues by IE version. +In case you're interested, there are two problems: choosing a way to split +lines that doesn't introduce too few or extra newlines, and a way to make sure +that the resulting code can be copy-pasted into a plain text editors such as +the textarea below. This is my attempt to gather information on both issues +by IE version.

    -cheers. - - - - -

    START

    - - - - - - - - - - - - - - - - - - - - - - - - +

    Cheers.

    - +
    - +

    == START ==

    - +
    - - - - - - - - - - - +
    before
    +[manual CR]
    +after
    - +
    before
    [manual BR]
    after
    - +
    before
    +[manual CR+BR]
    +after
    - +
    before
    +
    [manual BR+CR] +
    after
    - +

    == END ==

    -
    before
    -[Not generated via innerHTML CR]
    +
    before
    +[text]
     after
    -
    before
    [Not generated via innerHTML BR]
    after
    +
    -
    before
    -[Not generated via innerHTML CR + BR]
    -after
    +

    RESULTS

    -
    before
    -
    [Not generated via innerHTML BR + CR] -
    after
    +
    -

    END

    +
    -
    one
    -two
    -three
    +

    TEXTAREA

    + -

    RESULTS

    - + logger('User Agent = ' + navigator.userAgent); + logger('Ok = ' + ok); + logger('Bad = ' + bad); +})(); + -

    TEXTAREA

    - + + diff --git a/tests/large_input_test.html b/tests/large_input_test.html index 7e40b898..5c4ff30c 100644 --- a/tests/large_input_test.html +++ b/tests/large_input_test.html @@ -1,120 +1,201 @@ - + + Tests of Prettifier w/ large data files - - - + + + - -
    -
    + +

    Benchmarks

    +
    +
    +

    Results

    +
    - diff --git a/tests/numberLines_test.html b/tests/numberLines_test.html new file mode 100644 index 00000000..317333f9 --- /dev/null +++ b/tests/numberLines_test.html @@ -0,0 +1,135 @@ + + + + +numberLines + + + + + + +

    Number Lines Test

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Test Nothing to Split
    Hello, World!
    1. Hello, World!
    Test Normalized Spaces
    Hello, World!
    1. Hello, World!
    Test BR
    Hello,
    World!
    1. Hello,
    2. World!
    Test line breaks
    Hello,
    there
    World!
    1. Hello,
    2. there
    3. World!
    Test line breaks with followers
    Hello,
    there
    World!
    
    1. Hello,
    2. there
    3. World!
    Test nocode
    Hello,
    there
    World!
    1. Hello,
    2. there World!
    Test link
    Hello,
    there
    World!
    1. Hello,
    2. there
    3. World!
    Test blank lines
    One
    
    Three
    1. One
    2.  
    3. Three
    + +
    +

    Log

    +
    + + + + + diff --git a/tests/prettify_test.html b/tests/prettify_test.html index e02e5393..04f55f22 100644 --- a/tests/prettify_test.html +++ b/tests/prettify_test.html @@ -1,52 +1,76 @@ - + + Code Prettifier - + + + - - - - -
    -
    + +

    Test Results

    +
    + +

    Bash

    #!/bin/bash
    @@ -88,14 +112,14 @@ 

    Bash w/ language specified

    fib | /usr/bin/*head -10 | tail -1
    -

    Issue 165

    +

    Bash special characters

    +

    Issue #165

    # Comment
     local $x = ${#x[@]}  # Previous is not a comment
     # A comment

    C

    - -
    +
     #include <stdio.h>
     
     /* the n-th fibonacci number.
    @@ -103,7 +127,7 @@ 

    C

    unsigned int fib(unsigned int n) { unsigned int a = 1, b = 1; unsigned int tmp; - while (--n >= 0) { + while (--n >= 0) { tmp = a; a += b; b = tmp; @@ -117,15 +141,14 @@

    C

    C w/ language specified

    - -
    +
     #include <stdio.h>
     
     /* the nth fibonacci number. */
     uint32 fib(unsigned int n) {
       uint32 a = 1, b = 1;
       uint32 tmp;
    -  while (--n >= 0) {
    +  while (--n >= 0) {
         tmp = a;
         a += b;
         b = tmp;
    @@ -142,8 +165,9 @@ 

    C w/ language specified

    #define ZERO 0 /* a multiline comment */
    +

    C++

    -
    +
     #include <iostream>
     
     using namespace std;
    @@ -152,7 +176,7 @@ 

    C++

    //! \param n an index into the fibonacci series //! \param fib0 element 0 of the series //! \return the nth element of the fibonacci series -template <class T> +template <class T> T fib(unsigned int n, const T& fib0) { T a(fib0), b(fib0); for (; n; --n) { @@ -169,7 +193,7 @@

    C++

    C++ w/ language specified

    -
    +
     #include <iostream>
     
     using namespace std;
    @@ -178,10 +202,10 @@ 

    C++ w/ language specified

    //! \param n an index into the fibonacci series //! \param fib0 element 0 of the series //! \return the nth element of the fibonacci series -template <class T> +template <class T> T fib(int n, const T& fib0) { T a(fib0), b(fib0); - while (--n >= 0) { + while (--n >= 0) { T tmp(a); a += b; b = tmp; @@ -203,13 +227,13 @@

    Java

    /** * the fibonacci series implemented as an Iterable. */ -public final class Fibonacci implements Iterable<Integer> { +public final class Fibonacci implements Iterable<Integer> { /** the next and previous members of the series. */ private int a = 1, b = 1; @Override - public Iterator<Integer> iterator() { - return new Iterator<Integer>() { + public Iterator<Integer> iterator() { + return new Iterator<Integer>() { /** the series is infinite. */ public boolean hasNext() { return true; } public Integer next() { @@ -223,14 +247,14 @@

    Java

    } /** - * the n<sup>th</sup> element of the given series. + * the n<sup>th</sup> element of the given series. * @throws NoSuchElementException if there are less than n elements in the * given Iterable's {@link Iterable#iterator iterator}. */ - public static <T> - T nth(int n, Iterable<T> iterable) { - Iterator<? extends T> it = iterable.iterator(); - while (--n > 0) { + public static <T> + T nth(int n, Iterable<T> iterable) { + Iterator<? extends T> it = iterable.iterator(); + while (--n > 0) { it.next(); } return it.next(); @@ -242,7 +266,8 @@

    Java

    }
    -

    Java w/ language specified(first line shown is line 12)

    +

    Java w/ language specified

    +

    (first line shown is line 12)

     package foo;
     
    @@ -251,13 +276,13 @@ 

    Java w/ language specified(first line shown is line 12)

    /** * the fibonacci series implemented as an Iterable. */ -public final class Fibonacci implements Iterable<Integer> { +public final class Fibonacci implements Iterable<Integer> { /** the next and previous members of the series. */ private int a = 1, b = 1; @Override - public Iterator<Integer> iterator() { - return new Iterator<Integer>() { + public Iterator<Integer> iterator() { + return new Iterator<Integer>() { /** the series is infinite. */ public boolean hasNext() { return true; } public Integer next() { @@ -271,14 +296,14 @@

    Java w/ language specified(first line shown is line 12)

    } /** - * the n<sup>th</sup> element of the given series. + * the n<sup>th</sup> element of the given series. * @throws NoSuchElementException if there are less than n elements in the * given Iterable's {@link Iterable#iterator iterator}. */ - public static <T> - T nth(int n, Iterable<T> iterable) { - Iterator<? extends T> in = iterable.iterator(); - while (--n > 0) { + public static <T> + T nth(int n, Iterable<T> iterable) { + Iterator<? extends T> in = iterable.iterator(); + while (--n > 0) { in.next(); } return in.next(); @@ -293,17 +318,17 @@

    Java w/ language specified(first line shown is line 12)

    # not keywords: static_cast and namespace
    -

    Javascript

    +

    JavaScript

     /**
      * nth element in the fibonacci series.
    - * @param n >= 0
    - * @return the nth element, >= 0.
    + * @param n >= 0
    + * @return the nth element, >= 0.
      */
     function fib(n) {
       var a = 1, b = 1;
       var tmp;
    -  while (--n >= 0) {
    +  while (--n >= 0) {
         tmp = a;
         a += b;
         b = tmp;
    @@ -314,8 +339,9 @@ 

    Javascript

    document.write(fib(10));
    -

    Issue 12 - Javascript Regular Expressions

    -
    +

    JavaScript Regular Expressions

    +

    Issue #12

    +
     /foo/;  // a slash starting a line treated as a regexp beginning
     "foo".match(/fo+$/);
     // this line comment not treated as a regular expressions
    @@ -352,14 +378,15 @@ 

    Issue 12 - Javascript Regular Expressions

    return /a regexp/; division = notreturn / not_a_regexp / 2; // keyword suffix does not match -// & not used as prefix operator in javascript but this should still work -&/foo/; +// & not used as prefix operator in javascript but this should still work +&/foo/; extends = /extends/;
    -

    Issue 12 - Javascript Regular Expressions w/ language specified

    -
    +

    JavaScript Regular Expressions w/ language specified

    +

    Issue #12

    +
     /foo/;  // a slash starting a line treated as a regexp beginning
     "foo".match(/fo+$/);
     // this line comment not treated as a regular expressions
    @@ -396,19 +423,19 @@ 

    Issue 12 - Javascript Regular Expressions w/ language specified

    return /a regexp/; division = notreturn / not_a_regexp / 2; // keyword suffix does not match -// & not used as prefix operator in javascript but this should still work -&/foo/; +// & not used as prefix operator in javascript but this should still work +&/foo/; extends = /extends/;
    -

    Coffee

    +

    CoffeeScript

     class Animal
    -  constructor: (@name) ->
    -  move: (meters, loc) ->
    +  constructor: (@name) ->
    +  move: (meters, loc) ->
         alert @name + " moved " + meters + "m."
    -  travel: (path...) ->
    +  travel: (path...) ->
         for place in path
           @move place.distance, place.location
     
    @@ -417,17 +444,17 @@ 

    Coffee

    @param name Horse name @param jumper Jumping ability ### - constructor: (name, jumper) -> + constructor: (name, jumper) -> super name @capable = jumper - step: -> + step: -> alert ''' Step, step... ''' - jump: -> + jump: -> @capable - move: (meters, where) -> + move: (meters, where) -> switch where when "ground" @step() @@ -461,11 +488,11 @@

    Perl

    use integer; # the nth element of the fibonacci series -# param n - an int >= 0 -# return an int >= 0 +# param n - an int >= 0 +# return an int >= 0 sub fib($) { my $n = shift, $a = 1, $b = 1; - ($a, $b) = ($a + $b, $a) until (--$n < 0); + ($a, $b) = ($a + $b, $a) until (--$n < 0); return $a; } @@ -495,7 +522,7 @@

    Python

    for x in series: n = n - 1 - if n <= 0: return x + if n <= 0: return x print nth(fib(), 10)
    @@ -523,14 +550,14 @@

    Python w/ language specified

    for x in series: n -= 1 - if n <= 0: return x + if n <= 0: return x print nth(fib(), 10) /* not a comment and not keywords: null char true */
    -

    SQL w/ language specified

    +

    SQL

     /* A multi-line
      * comment */
    @@ -547,7 +574,7 @@ 

    XML

     <!DOCTYPE series PUBLIC "fibonacci numbers">
     
    -<series.root base="1" step="s(n-2) + s(n-1)">
    +<series.root base="1" step="s(n-2) + s(n-1)">
       <element i="0">1</element>
       <element i="1">1</element>
       <element i="2">2</element>
    @@ -561,13 +588,13 @@ 

    XML

    HTML

     <html>
    -  <head>
    +  <head>
         <title>Fibonacci number</title>
         <style><!-- BODY { text-decoration: blink } --></style>
         <script src="foo.js"></script>
         <script src="bar.js"></script>
       </head>
    -  <body>
    +  <body>
         <noscript>
           <dl>
             <dt>Fibonacci numbers</dt>
    @@ -581,11 +608,11 @@ 

    HTML

    </dl> </noscript> - <script type="text/javascript"><!-- + <script type="text/javascript"><!-- function fib(n) { var a = 1, b = 1; var tmp; - while (--n >= 0) { + while (--n >= 0) { tmp = a; a += b; b = tmp; @@ -595,7 +622,7 @@

    HTML

    document.writeln(fib(10)); // --> - </script> + </script> </body> </html>
    @@ -617,11 +644,11 @@

    HTML w/ language specified

    </dl> </noscript> -<script type="text/javascript"><!-- +<script type="text/javascript"><!-- function fib(n) { var a = 1, b = 1; var tmp; - while (--n >= 0) { + while (--n >= 0) { tmp = a; a += b; b = tmp; @@ -631,12 +658,11 @@

    HTML w/ language specified

    document.writeln(fib(10)); // --> -</script> +</script>
    - -

    HTML using XMP

    -HTML using &lt;XMP&gt;</h1> +<xmp class="prettyprint" id="html_xmp" ><html> <head> <title>Fibonacci number</title> @@ -680,7 +706,7 @@ <h1>XHTML</h1> &lt;head&gt; &lt;title&gt;Fibonacci number&lt;/title&gt; &lt;/head&gt; - &lt;body onload="alert(fib(10))"> + &lt;body onload="alert(fib(10))"&gt; &lt;script type="text/javascript"&gt;&lt;![CDATA[ function fib(n) { var a = 1, b = 1; @@ -699,10 +725,10 @@ <h1>XHTML</h1> </pre> <h1>PHP</h1> -<pre class="prettyprint" id="PHP"> -&lt;html> - &lt;head> - &lt;title>&lt;?= 'Fibonacci numbers' ?>&lt;/title> +<pre class="prettyprint" id="php"> +&lt;html&gt; + &lt;head&gt; + &lt;title&gt;&lt;?= 'Fibonacci numbers' ?&gt;&lt;/title&gt; &lt;?php // PHP has a plethora of comment types @@ -712,22 +738,23 @@ <h1>PHP</h1> # I don't know. $a = 1; $b = 1; - while (--$n >= 0) { + while (--$n &gt;= 0) { echo "$a\n"; $tmp = $a; $a += $b; $b = $tmp; } } - ?> - &lt;/head> - &lt;body> - &lt;?= fib(10) ?> - &lt;/body> -&lt;/html> + ?&gt; + &lt;/head&gt; + &lt;body&gt; + &lt;?= fib(10) ?&gt; + &lt;/body&gt; +&lt;/html&gt; </pre> -<h1>XSL (Issue 19)</h1> +<h1>XSL</h1> +<p><a href="https://github.com/google/code-prettify/issues/19">Issue #19</a></p> <pre class="prettyprint" id="xsl"> &lt;!-- Test elements and attributes with namespaces --&gt; @@ -739,17 +766,20 @@ <h1>XSL (Issue 19)</h1> </pre> <h1>Whitespace</h1> -<pre class=prettyprint id="whitespace"></pre> +<pre class="prettyprint" id="whitespace"></pre> <h1>Misc</h1> -<pre class=prettyprint id="misc1">// ends with line comment token +<pre class="prettyprint" id="misc1">// ends with line comment token //</pre> -<h1>User submitted testcase for Bug 4</h1> +<h1>JavaScript inside HTML &lt;SCRIPT&gt;</h1> <p> -Javascript Snippets wrapped in HTML SCRIPT tags hides/destroys inner content +<a href="https://github.com/google/code-prettify/issues/4">Issue #4</a>: +JavaScript Snippets wrapped in HTML SCRIPT tags hides/destroys inner content </p> -<pre class=prettyprint id="issue4"> +<p>The fact that the script tag was not closed properly was causing +<em>PR_splitSourceNodes</em> to end without emitting the script contents.</p> +<pre class="prettyprint" id="js_script"> &lt;script type="text/javascript"&gt; var savedTarget=null; // The target layer (effectively vidPane) var orgCursor=null; // The original mouse style so we can restore it @@ -761,70 +791,72 @@ <h1>User submitted testcase for Bug 4</h1> vidPaneID.style.left='75px'; // Starting location verticle &lt;script&gt; </pre> -<p>The fact that the script tag was not closed properly was causing -PR_splitSourceNodes to end without emitting the script contents.</p> -<h1>Bug 8 - tabs mangled</h1> -<p>If tabs are used to indent code inside &lt;pre> IE6 and 7 won't honor them -after the script runs. - -Code indented with tabs will be shown aligned to the left margin instead of -the proper indenting shown in Firefox. - -I'm using Revision 20 of prettify.js, IE 6.0.29.00 in English and IE -7.0.5730.11 in Spanish. -</p> -<pre class=prettyprint id="issue8"> +<h1>Tabs mangled</h1> +<p><a href="https://github.com/google/code-prettify/issues/8">Issue #8</a>: +If tabs are used to indent code inside &lt;pre&gt;, IE6 and 7 won't honor them +after the script runs.</p> +<p>Code indented with tabs will be shown aligned to the left margin instead of +the proper indenting shown in Firefox.</p> +<p>I'm using Revision 20 of prettify.js, IE 6.0.29.00 in English and IE +7.0.5730.11 in Spanish.</p> +<pre class="prettyprint" id="issue8"> <b>one</b>&#9;<b>Two</b>&#9;<b>three</b>&#9;Four&#9;<b>five</b>&#9;| Six&#9;<b>seven</b>&#9;Eight&#9;nine&#9;Ten&#9;| <b>eleven</b>&#9;Twelve&#9;<b>thirteen</b>&#9;Fourteen&#9;fifteen&#9;| </pre> -<h1>Bug 14a - does not recognize <code>&lt;br&gt;</code> as newline</h1> +<h1>Does not recognize <code>&lt;br&gt;</code> as newline</h1> +<p><a href="https://github.com/google/code-prettify/issues/14">Issue #14</a></p> <pre class="prettyprint" id="issue14a" >//comment<br />int main(int argc, char **argv) {}</pre> -<h1>Bug 14b - comments not ignored</h1> +<h1>Comments not ignored</h1> +<p><a href="https://github.com/google/code-prettify/issues/14">Issue #14</a></p> <pre class="prettyprint" id="issue14b" >&lt;!-- There's an <!-- BOO!! --><acronym title="tag soup">HTML</acronym> comment in my comment --&gt; &lt;p&gt;And another one inside the end tag&lt;/p<!-- GOTCHA!! -->&gt; </pre> -<h1>Bug 20 - missing blank lines</h1> +<h1>Missing blank lines</h1> +<p><a href="https://github.com/google/code-prettify/issues/20">Issue #20</a></p> <pre class="prettyprint" id="issue20" >&lt;html&gt; &lt;head&gt;</pre> -<h1>Bug 21 - code doesn't copy and paste well in IE</h1> +<h1>Code doesn't copy and paste well in IE</h1> +<p><a href="https://github.com/google/code-prettify/issues/21">Issue #21</a>: +To test this bug, disable overriding of <em>_pr_isIE6</em> in test_base.js +by putting <em>#testcopypaste</em> on the end of the URL and reloading the +page, then copy and paste the above into Notepad.</p> <pre class="prettyprint" id="issue21" >&lt;html&gt; &lt;head&gt; &lt;title&gt;Test&lt;/title&gt; &lt;/head&gt; &lt;/html&gt;</pre> -<p>To test this bug, disable overriding of _pr_isIE6 in test_base.js -by putting #testcopypaste on the end of the URL and reloading the -page, then copy and paste the above into Notepad.</p> -<h1>Bug 22 - Line numbers and other non-code spans in code</h1> -<pre class="prettyprint" id="issue22" -><span class=nocode>01: </span>// This is a line of code -<span class=nocode>02: </span>/* Multiline comments can -<span class=nocode>03: </span> * span over and around -<span class=nocode>04: </span> * line markers +<h1>Line numbers and other non-code spans in code</h1> +<p><a href="https://github.com/google/code-prettify/issues/22">Issue #22</a></p> +<pre class="prettyprint lang-java" id="issue22" +><span class="nocode">01: </span>// This is a line of code +<span class="nocode">02: </span>/* Multiline comments can +<span class="nocode">03: </span> * span over and around +<span class="nocode">04: </span> * line markers <span class="nocode annot">And can even be interrupted</span> <span class="nocode annot">by inline code annotations</span> -<span class=nocode>05: </span> */ -<span class=nocode>06: </span>class MyClass extends Foo { -<span class=nocode>07: </span> public static void main(String... argv) { -<span class=nocode>08: </span> System.out.print("Hello World"); -<span class=nocode>09: </span> } -<span class=nocode>10: </span>}</pre> - -<h1>Bug 24 - Lua Syntax Highlighting</h1> -<pre class="prettyprint lang-lua" id="issue24"> +<span class="nocode">05: </span> */ +<span class="nocode">06: </span>class MyClass extends Foo { +<span class="nocode">07: </span> public static void main(String... argv) { +<span class="nocode">08: </span> System.out.print("Hello World"); +<span class="nocode">09: </span> } +<span class="nocode">10: </span>}</pre> + +<h1>Lua</h1> +<p><a href="https://github.com/google/code-prettify/issues/24">Issue #24</a></p> +<pre class="prettyprint lang-lua" id="lua"> os=require("os") math=require("math") @@ -869,16 +901,17 @@ <h1>Bug 24 - Lua Syntax Highlighting</h1> function shellsort(t, before, n) n = n or #t - if not before or before == "<" then return ssup(t, n) - elseif before == ">" then return ssdown(t, n) + if not before or before == "&lt;" then return ssup(t, n) + elseif before == "&gt;" then return ssdown(t, n) else return ssgeneral(t, n, before) end end return shellsort end</pre> -<h1>Bug 27 - VBScript w/ language specified</h1> -<pre class="prettyprint lang-vb" id="issue27"> +<h1>VBScript</h1> +<p><a href="https://github.com/google/code-prettify/issues/27">Issue #27</a></p> +<pre class="prettyprint lang-vb" id="vbs"> Imports System Class [class] @@ -930,8 +963,9 @@ <h1>Bug 27 - VBScript w/ language specified</h1> i = (0, 123, 45L, &amp;HA0I, &amp;O177S) </pre> -<h1>Bug 30 - Haskell w/ language specified</h1> -<pre class="prettyprint lang-hs" id="issue30"> +<h1>Haskell</h1> +<p><a href="https://github.com/google/code-prettify/issues/30">Issue #30</a></p> +<pre class="prettyprint lang-hs" id="haskell"> -- A comment Not(--"a comment&quot;) Also.not(--(A.comment)) @@ -947,9 +981,9 @@ <h1>Bug 30 - Haskell w/ language specified</h1> instance Thingy Foo where a = b -data Foo :: (* -> * -> *) -&gt; * > * -> * where +data Foo :: (* -&gt; * -&gt; *) -&gt; * &gt; * -&gt; * where Nil :: Foo a b c - Cons :: a b c -> Foo abc -> Foo a b c + Cons :: a b c -&gt; Foo abc -&gt; Foo a b c str = &quot;Foo\\Bar" char = 'x' @@ -960,8 +994,10 @@ <h1>Bug 30 - Haskell w/ language specified</h1> (0, 12, 0x45, 0xA7, 0o177, 0O377, 0.1, 1.0, 1e3, 0.5E-3, 1.0E+45) </pre> -<h1>Bug 33 - OCaml and F#</h1> -<pre class="prettyprint lang-ml" id="issue33"> +<h1>OCaml and F#</h1> +<p><a href="https://github.com/google/code-prettify/issues/33">Issue #33</a></p> +<p>TODO: handle nested <code>(* (* comments *) *)</code> properly.</p> +<pre class="prettyprint lang-ml" id="ml"> (* * Print the 10th fibonacci number *) @@ -972,8 +1008,8 @@ <h1>Bug 33 - OCaml and F#</h1> #if fibby let - rec fib = function (0, a, _) -> a - | (n, a, b) -> fib(n - 1, a + b, a) + rec fib = function (0, a, _) -&gt; a + | (n, a, b) -&gt; fib(n - 1, a + b, a) in print_int(fib(10, 1, 1));; #endif @@ -982,10 +1018,10 @@ <h1>Bug 33 - OCaml and F#</h1> let f' x' = x' + 1 </pre> -<p>Still TODO: handle nested <code>(* (* comments *) *)</code> properly.</p> -<h1>Bug 42 - Lisp Syntax Highlighting</h1> -<pre class="prettyprint lang-el" id="issue42" +<h1>Lisp</h1> +<p><a href="https://github.com/google/code-prettify/issues/42">Issue #42</a></p> +<pre class="prettyprint lang-el" id="lisp" >; -*- mode: lisp -*- (defun back-six-lines () (interactive) (forward-line -6)) @@ -1027,7 +1063,8 @@ <h1>Bug 42 - Lisp Syntax Highlighting</h1> (define (sqt x) (sqrt-iter 1.0 2.0 x)) </pre> -<h1>Bug 45 - Square brackets in strings</h1> +<h1>Square brackets in strings</h1> +<p><a href="https://github.com/google/code-prettify/issues/45">Issue #45</a></p> <pre class="prettyprint" id="issue45"> throw new RuntimeException("Element [" + element.getName() + "] missing attribute."); @@ -1052,7 +1089,7 @@ <h1>Protocol Buffers</h1> optional Corpus corpus = 4 [default = UNIVERSAL]; }</pre> -<h1>Wiki syntax w/ language specified</h1> +<h1>Wiki Syntax</h1> <pre class="prettyprint lang-wiki" id="wiki"> #summary hello world #labels HelloWorld WikiWord Hiya @@ -1105,9 +1142,10 @@ <h1>CSS w/ language specified</h1> --&gt; </pre> -<h1>Issue 79 CSS highlighting</h1> -<pre class="prettyprint" id="issue79"> -&lt;style type='text/css'> +<h1>CSS inside HTML &lt;STYLE&gt;</h1> +<p><a href="https://github.com/google/code-prettify/issues/79">Issue #79</a></p> +<pre class="prettyprint" id="css_style"> +&lt;style type='text/css'&gt; /* desert scheme ported from vim to google prettify */ code.prettyprint { display: block; padding: 2px; border: 1px solid #888; background-color: #333; } @@ -1122,27 +1160,36 @@ <h1>Issue 79 CSS highlighting</h1> .atn { color: #bdb76b; font-weight: bold; } /* attribute name - khaki*/ .atv { color: #ffa0a0; } /* attribute value - pink */ .dec { color: #98fb98; } /* decimal - lightgreen */ -&lt;/style> +&lt;/style&gt; </pre> -<h1>Issue 84 NBSPs</h1> +<h1>NBSPs</h1> +<p><a href="https://github.com/google/code-prettify/issues/84">Issue #84</a></p> <pre class="prettyprint lang-java" id="issue84">super("&amp;nbsp;");</pre> -<h1>Issue 86</h1> +<h1>Line breaks and preformatted style</h1> +<p><a href="https://github.com/google/code-prettify/issues/86">Issue #86</a></p> +<p>CODE tag</p> <p><code class="prettyprint" id="issue86_0">#One Two words</code></p> +<p>CODE tag with preformatted style</p> <p><code class="prettyprint known_ie6_failure" id="issue86_1" style="white-space: pre">#One Two lines</code></p> +<p>PRE tag</p> <pre class="prettyprint" id="issue86_2">#One Two lines</pre> +<p>PRE+CODE tag</p> <pre><code class="prettyprint known_ie6_failure" id="issue86_3">#One Two lines</code></pre> +<p>XMP tag</p> <xmp class="prettyprint" id="issue86_4">#One Two lines +

    CODE tag with BR line break

    #One
    Two lines

    -

    Issue 92 -- capital letters in tag names

    +

    Capital letters in tag names

    +

    Issue #92

     <?xml version="1.0" encoding="UTF-8"?>
     <kml xmlns="http://www.opengis.net/kml/2.2">
    @@ -1157,15 +1204,16 @@ 

    Issue 92 -- capital letters in tag names

    </kml>
    -

    Issue 93 -- C# verbatim strings

    -
    +

    C# verbatim strings

    +

    Issue #93

    +
     // The normal string syntax
     string a = "C:\\";
     // is equivalent to a verbatim string
     string b = @"C:\";
     
    -

    VHDL mode

    +

    VHDL

     library ieee;
     use ieee.std_logic_1164.all;
    @@ -1196,7 +1244,7 @@ 

    VHDL mode

    dummy_p : process (clk_i) begin if b_i = 1 then - c_o <= (others => '0'); + c_o <= (others => '0'); elsif rising_edge(clk_i) then c_o <= "1011" & bar_s(1 downto 0); end if; @@ -1205,7 +1253,7 @@

    VHDL mode

    end architecture foo_architecture;
    -

    YAML mode

    +

    YAML

     application: mirah-lang
     version: 1
    @@ -1231,6 +1279,8 @@ 

    YAML mode

    init_params: logType: special
    + +

    YAML

     %YAML 1.1
     ---
    @@ -1249,7 +1299,7 @@ 

    YAML mode

    : !!str "value" }
    -

    Scala mode

    +

    Scala

     /* comment 1 */
     /*
    @@ -1295,12 +1345,12 @@ 

    Scala mode

    var pongCount = 0 loop { react { - case Ping => + case Ping => if (pongCount % 1000 == 0) Console.println("Pong: ping "+pongCount) sender ! Pong pongCount = pongCount + 1 - case Stop => + case Stop => Console.println("Pong: stop") exit() } @@ -1308,7 +1358,7 @@

    Scala mode

    }
    -

    Go mode

    +

    Go

     package main  /* Package of which this program is part. */
     
    @@ -1323,7 +1373,7 @@ 

    Go mode

    /* ` */ `foo /* ` /*/ */
    -

    Erlang mode

    +

    Erlang

     % Sample comment
     
    @@ -1337,1718 +1387,52 @@ 

    Erlang mode

    -define(my_macro, Variable). %% @doc My function -test(Variables, MoreVariables) -> +test(Variables, MoreVariables) -> % Inline comment {ok,Scanned,_} = my_lib:do_stuff(), - Variable = fun(V) -> {ok, V} end, + Variable = fun(V) -> {ok, V} end, try ?my_macro({value, test}) of - {value, Result, _} -> + {value, Result, _} -> {ok, Result} catch - Type:Error -> + Type:Error -> {'error', Type, Error} end.
    -Test IE by copy/pasting content here. - - +

    Rust

    +
    +// Single line comment
    +/* Multi-line (nesting not highlighted properly, sorry)
    +comment */
     
    -
    +#![feature(code_prettification)]
    +
    +use std::io::{self, Write};
    +
    +impl<'a, T: 'a + ?Sized> Foo<'a, 'static> for Bar<'b>
    +where T: Iterator<Item = Box<Fn() -> u32>> {
    +    fn something(&mut self) -> u32 {
    +        if let Some(ref x) = self.foo("multi li\ne
    +s\tring") {
    +            panic!(r"\things is going wrong!");
    +            panic!(r#"Things is "really" goig\n wront!"#);
    +            panic!(r##"Raw strings are #"#fancy#"#"##);
    +        }
    +    }
    +}
     
    +pub type CowString<'a> = std::cow::Cow<'a, str>;
    +
    +fn main() {
    +    let (i, r) = (1u8, 'c');
    +    let s = r#"Take a raw egg,
    +        "break" it (or the line),
    +        and beat it"#;
    +}
    +
    + + diff --git a/tests/prettify_test.js b/tests/prettify_test.js new file mode 100644 index 00000000..9d40aa7b --- /dev/null +++ b/tests/prettify_test.js @@ -0,0 +1,1782 @@ +/** + * maps ids of rewritten code to the expected output. + * For brevity, has been changed to `FOO + * and < /span> has been changed to `END. + */ +var goldens = { + bash: ( + '`COM#!/bin/bash`END`PLN\n' + + '\n' + + '`END`COM# Fibonacci numbers`END`PLN\n' + + '`END`COM# Writes an infinite series to stdout, one entry per line`END' + + '`PLN\n' + + '`END`KWDfunction`END`PLN fib`END`PUN()`END`PLN `END`PUN{`END`PLN\n' + + ' `END`KWDlocal`END`PLN a`END`PUN=`END`LIT1`END`PLN\n' + + ' `END`KWDlocal`END`PLN b`END`PUN=`END`LIT1`END`PLN\n' + + ' `END`KWDwhile`END`PLN `END`KWDtrue`END`PLN `END`PUN;`END' + + '`PLN `END`KWDdo`END`PLN\n' + + ' echo $a\n' + + ' `END`KWDlocal`END`PLN tmp`END`PUN=`END`PLN$a\n' + + ' a`END`PUN=`END`PLN$`END`PUN((`END`PLN $a `END`PUN+`END' + + '`PLN $b `END`PUN))`END`PLN\n' + + ' b`END`PUN=`END`PLN$tmp\n' + + ' `END`KWDdone`END`PLN\n' + + '`END`PUN}`END`PLN\n' + + '\n' + + '`END`COM# output the 10th element of the series and halt`END`PLN\n' + + 'fib `END`PUN|`END`PLN head `END`PUN-`END`LIT10`END`PLN `END`PUN|`END' + + '`PLN tail `END`PUN-`END`LIT1`END' + ), + bash_lang: ( + '
      `#`COM#!/bin/bash`END' + + '`#1`PLN `END' + + '`#2`COM# Fibonacci numbers`END' + + '`#3`COM# Writes an infinite series to stdout, one entry per line`END' + + '`#4`KWDfunction`END`PLN fib`END`PUN()`END`PLN `END`PUN{`END' + + '`#5`PLN `END`KWDlocal`END`PLN a`END`PUN=`END`LIT1`END' + + '`#6`PLN `END`KWDlocal`END`PLN b`END`PUN=`END`LIT1`END' + + '`#7`PLN `END`KWDwhile`END`PLN true `END`PUN;`END' + + '`PLN `END`KWDdo`END' + + '`#8`PLN echo $a`END' + + '`#9`PLN `END`KWDlocal`END`PLN tmp`END`PUN=`END`PLN$a`END' + + '`#0`PLN a`END`PUN=`END`PLN$`END`PUN((`END`PLN $a `END`PUN+`END' + + '`PLN $b `END`PUN))`END' + + '`#1`PLN b`END`PUN=`END`PLN$tmp`END' + + '`#2`PLN `END`KWDdone`END' + + '`#3`PUN}`END' + + '`#4`PLN `END' + + '`#5`COM# output the 10th element of the series and halt`END' + + '`#6`PLNfib `END`PUN|`END`PLN `END`PUN/`END`PLNusr`END`PUN/`END`PLNbin`END' + + '`PUN/*`END`PLNhead `END`PUN-`END`LIT10`END`PLN `END`PUN|`END' + + '`PLN tail `END`PUN-`END`LIT1`END
    ' + ), + issue_165: ( + '`COM# Comment`END`PLN\n' + + '`END`KWDlocal`END`PLN $x `END`PUN=`END`PLN $`END`PUN{#`END`PLNx`END`PUN[@]}`END`PLN `END' + + '`COM# Previous is not a comment`END`PLN\n' + + '`END`COM# A comment`END' + ), + c: ( + '`COM#include`END`PLN `END`STR<stdio.h>`END`PLN\n' + + '\n' + + '`END`COM/* the n-th fibonacci number.\n' + + ' *\/`END`PLN\n' + + '`END`KWDunsigned`END`PLN `END`KWDint`END`PLN fib`END`PUN(`END' + + '`KWDunsigned`END`PLN `END`KWDint`END`PLN n`END`PUN)`END`PLN `END' + + '`PUN{`END`PLN\n' + + ' `END`KWDunsigned`END`PLN `END`KWDint`END`PLN a `END`PUN=`END' + + '`PLN `END`LIT1`END`PUN,`END`PLN b `END`PUN=`END`PLN `END`LIT1`END' + + '`PUN;`END`PLN\n' + + ' `END`KWDunsigned`END`PLN `END`KWDint`END`PLN tmp`END`PUN;`END' + + '`PLN\n' + + ' `END`KWDwhile`END`PLN `END`PUN(--`END`PLNn `END`PUN>=`END' + + '`PLN `END`LIT0`END`PUN)`END`PLN `END`PUN{`END`PLN\n' + + ' tmp `END`PUN=`END`PLN a`END`PUN;`END`PLN\n' + + ' a `END`PUN+=`END`PLN b`END`PUN;`END`PLN\n' + + ' b `END`PUN=`END`PLN tmp`END`PUN;`END`PLN\n' + + ' `END`PUN}`END`PLN\n' + + ' `END`KWDreturn`END`PLN a`END`PUN;`END`PLN\n' + + '`END`PUN}`END`PLN\n' + + '\n' + + 'main`END`PUN()`END`PLN `END`PUN{`END`PLN\n' + + ' printf`END`PUN(`END`STR"%u"`END`PUN,`END`PLN fib`END`PUN(`END' + + '`LIT10`END`PUN));`END`PLN\n' + + '`END`PUN}`END' + ), + c_lang: ( + '`COM#include`END`PLN `END`STR<stdio.h>`END`PLN\n' + + '\n' + + '`END`COM/* the n`END`COMth`END<\/sup>`COM fibonacci number. *\/`END`PLN\n' + + '`END`TYPuint32`END`PLN fib`END`PUN(`END' + + '`KWDunsigned`END`PLN `END`TYPint`END`PLN n`END`PUN)`END`PLN `END' + + '`PUN{`END`PLN\n' + + ' `END`TYPuint32`END`PLN a `END`PUN=`END`PLN `END`LIT1`END`PUN,`END' + + '`PLN b `END`PUN=`END`PLN `END`LIT1`END`PUN;`END`PLN\n' + + ' `END`TYPuint32`END`PLN tmp`END`PUN;`END`PLN\n' + + ' `END`KWDwhile`END`PLN `END`PUN(--`END`PLNn `END`PUN>=`END' + + '`PLN `END`LIT0`END`PUN)`END`PLN `END`PUN{`END`PLN\n' + + ' tmp `END`PUN=`END`PLN a`END`PUN;`END`PLN\n' + + ' a `END`PUN+=`END`PLN b`END`PUN;`END`PLN\n' + + ' b `END`PUN=`END`PLN tmp`END`PUN;`END`PLN\n' + + ' `END`PUN}`END`PLN\n' + + ' `END`KWDreturn`END`PLN a`END`PUN;`END`PLN\n' + + '`END`PUN}`END`PLN\n' + + '\n' + + '`END`KWDvoid`END`PLN main`END`PUN()`END`PLN `END`PUN{`END`PLN\n' + + ' `END`TYPsize_t`END`PLN size `END`PUN=`END`PLN `END`KWDsizeof`END' + + '`PUN(`END`TYPwchar_t`END`PUN);`END`PLN\n' + + ' ASSERT_EQ`END`PUN(`END`PLNsize`END`PUN,`END`PLN `END`LIT1`END' + + '`PUN);`END`PLN\n' + + ' printf`END`PUN(`END`STR"%u"`END`PUN,`END`PLN fib`END`PUN(`END' + + '`LIT10`END`PUN));`END`PLN\n' + + '`END`PUN}`END`PLN\n' + + '\n' + + '`END`COM#define`END`PLN ZERO `END`LIT0`END`PLN `END`COM/* a\n' + + ' multiline comment *\/`END' + ), + cpp: ( + '`COM#include`END`PLN `END`STR<iostream>`END`PLN\n' + + '\n' + + '`END`KWDusing`END`PLN `END`KWDnamespace`END`PLN std`END`PUN;`END' + + '`PLN\n' + + '\n' + + '`END`COM//! fibonacci numbers with gratuitous use of templates.`END' + + '`PLN\n' + + '`END`COM//! \\param n an index into the fibonacci series`END`PLN\n' + + '`END`COM//! \\param fib0 element 0 of the series`END`PLN\n' + + '`END`COM//! \\return the nth element of the fibonacci series`END' + + '`PLN\n' + + '`END`KWDtemplate`END`PLN `END`PUN<`END`KWDclass`END`PLN T`END' + + '`PUN>`END`PLN\n' + + 'T fib`END`PUN(`END`KWDunsigned`END`PLN `END`KWDint`END`PLN n`END' + + '`PUN,`END`PLN `END`KWDconst`END`PLN T`END`PUN&`END`PLN fib0' + + '`END`PUN)`END`PLN `END`PUN{`END`PLN\n' + + ' T a`END`PUN(`END`PLNfib0`END`PUN),`END`PLN b`END`PUN(`END' + + '`PLNfib0`END`PUN);`END`PLN\n' + + ' `END`KWDfor`END`PLN `END`PUN(;`END`PLN n`END`PUN;`END' + + '`PLN `END`PUN--`END`PLNn`END`PUN)`END`PLN `END`PUN{`END`PLN\n' + + ' T tmp`END`PUN(`END`PLNa`END`PUN);`END`PLN\n' + + ' a `END`PUN+=`END`PLN b`END`PUN;`END`PLN\n' + + ' b `END`PUN=`END`PLN tmp`END`PUN;`END`PLN\n' + + ' `END`PUN}`END`PLN\n' + + ' `END`KWDreturn`END`PLN a`END`PUN;`END`PLN\n' + + '`END`PUN}`END`PLN\n' + + '\n' + + '`END`KWDint`END`PLN main`END`PUN(`END`KWDint`END`PLN argc`END' + + '`PUN,`END`PLN `END`KWDchar`END`PLN `END`PUN**`END`PLNargv`END' + + '`PUN)`END`PLN `END`PUN{`END`PLN\n' + + ' cout `END`PUN<<`END`PLN fib`END`PUN(`END`LIT10`END' + + '`PUN,`END`PLN `END`LIT1U`END`PUN);`END`PLN\n' + + '`END`PUN}`END' + ), + cpp_lang: ( + '`COM#include`END`PLN `END`STR<iostream>`END`PLN\n' + + '\n' + + '`END`KWDusing`END`PLN `END`KWDnamespace`END`PLN std`END`PUN;`END' + + '`PLN\n' + + '\n' + + '`END`COM//! fibonacci numbers with gratuitous use of templates.`END' + + '`PLN\n' + + '`END`COM//! \\param n an index into the fibonacci series`END`PLN\n' + + '`END`COM//! \\param fib0 element 0 of the series`END`PLN\n' + + '`END`COM//! \\return the nth element of the fibonacci series`END' + + '`PLN\n' + + '`END`KWDtemplate`END`PLN `END`PUN<`END`KWDclass`END`PLN T`END' + + '`PUN>`END`PLN\n' + + 'T fib`END`PUN(`END`TYPint`END`PLN n`END' + + '`PUN,`END`PLN `END`KWDconst`END`PLN T`END`PUN&`END`PLN fib0' + + '`END`PUN)`END`PLN `END`PUN{`END`PLN\n' + + ' T a`END`PUN(`END`PLNfib0`END`PUN),`END`PLN b`END`PUN(`END' + + '`PLNfib0`END`PUN);`END`PLN\n' + + ' `END`KWDwhile`END`PLN `END`PUN(--`END`PLNn `END`PUN>=`END' + + '`PLN `END`LIT0`END`PUN)`END`PLN `END`PUN{`END`PLN\n' + + ' T tmp`END`PUN(`END`PLNa`END`PUN);`END`PLN\n' + + ' a `END`PUN+=`END`PLN b`END`PUN;`END`PLN\n' + + ' b `END`PUN=`END`PLN tmp`END`PUN;`END`PLN\n' + + ' `END`PUN}`END`PLN\n' + + ' `END`KWDreturn`END`PLN a`END`PUN;`END`PLN\n' + + '`END`PUN}`END`PLN\n' + + '\n' + + '`END`TYPint`END`PLN main`END`PUN(`END`TYPint`END`PLN argc`END' + + '`PUN,`END`PLN `END`KWDchar`END`PLN `END`PUN**`END`PLNargv`END' + + '`PUN)`END`PLN `END`PUN{`END`PLN\n' + + ' cout `END`PUN<<`END`PLN fib`END`PUN(`END`LIT10`END' + + '`PUN,`END`PLN `END`LIT1U`END`PUN);`END`PLN\n' + + '`END`PUN}`END' + ), + java: ( + '`KWDpackage`END`PLN foo`END`PUN;`END`PLN\n' + + '\n' + + '`END`KWDimport`END`PLN java`END`PUN.`END`PLNutil`END`PUN.`END' + + '`TYPIterator`END`PUN;`END`PLN\n' + + '\n' + + '`END`COM/**\n' + + ' * the fibonacci series implemented as an Iterable.\n' + + ' *\/`END`PLN\n' + + '`END`KWDpublic`END`PLN `END`KWDfinal`END`PLN `END`KWDclass`END' + + '`PLN `END`TYPFibonacci`END`PLN `END`KWDimplements`END`PLN `END' + + '`TYPIterable`END`PUN<`END`TYPInteger`END`PUN>`END`PLN `END`' + + 'PUN{`END`PLN\n' + + ' `END' + + '`COM/** the next and previous members of the series. *\/`END' + + '`PLN\n' + + ' `END`KWDprivate`END`PLN `END`KWDint`END`PLN a `END`PUN=`END' + + '`PLN `END`LIT1`END`PUN,`END`PLN b `END`PUN=`END`PLN `END`LIT1`END' + + '`PUN;`END`PLN\n' + + '\n' + + ' `END`LIT@Override`END`PLN\n' + + ' `END`KWDpublic`END`PLN `END`TYPIterator`END`PUN<`END' + + '`TYPInteger`END`PUN>`END`PLN iterator`END`PUN()`END`PLN `END' + + '`PUN{`END`PLN\n' + + ' `END`KWDreturn`END`PLN `END`KWDnew`END`PLN `END' + + '`TYPIterator`END`PUN<`END`TYPInteger`END`PUN>()`END`PLN `END' + + '`PUN{`END`PLN\n' + + ' `END`COM/** the series is infinite. *\/`END' + + '`PLN\n' + + ' `END`KWDpublic`END`PLN `END`KWDboolean`END' + + '`PLN hasNext`END`PUN()`END`PLN `END`PUN{`END`PLN `END' + + '`KWDreturn`END`PLN `END`KWDtrue`END`PUN;`END`PLN `END`PUN}`END' + + '`PLN\n' + + ' `END`KWDpublic`END`PLN `END`TYPInteger`END' + + '`PLN `END`KWDnext`END`PUN()`END`PLN `END`PUN{`END`PLN\n' + + ' `END`KWDint`END`PLN tmp `END`PUN=`END' + + '`PLN a`END`PUN;`END`PLN\n' + + ' a `END`PUN+=`END`PLN b`END`PUN;`END' + + '`PLN\n' + + ' b `END`PUN=`END`PLN tmp`END`PUN;`END' + + '`PLN\n' + + ' `END`KWDreturn`END`PLN a`END`PUN;`END' + + '`PLN\n' + + ' `END`PUN}`END`PLN\n' + + ' `END`KWDpublic`END`PLN `END`KWDvoid`END' + + '`PLN `END`KWDremove`END`PUN()`END`PLN `END`PUN{`END`PLN `END`KWDthrow`END' + + '`PLN `END`KWDnew`END`PLN `END' + + '`TYPUnsupportedOperationException`END`PUN();`END`PLN `END' + + '`PUN}`END`PLN\n' + + ' `END`PUN};`END`PLN\n' + + ' `END`PUN}`END`PLN\n' + + '\n' + + ' `END`COM/**\n' + + ' * the n<sup>th</sup> element of the given ' + + 'series.\n' + + ' * @throws NoSuchElementException if there are less than ' + + 'n elements in the\n' + + ' * given Iterable\'s {@link Iterable#iterator ' + + 'iterator}.\n' + + ' *\/`END`PLN\n' + + ' `END`KWDpublic`END`PLN `END`KWDstatic`END`PLN `END' + + '`PUN<`END`PLNT`END`PUN>`END`PLN\n' + + ' T nth`END`PUN(`END`KWDint`END`PLN n`END`PUN,`END`PLN `END' + + '`TYPIterable`END`PUN<`END`PLNT`END`PUN>`END' + + '`PLN iterable`END`PUN)`END`PLN `END`PUN{`END`PLN\n' + + ' `END`TYPIterator`END`PUN<?`END`PLN ' + + '`END`KWDextends`END`PLN T`END`PUN>`END`PLN it `END`PUN=`END' + + '`PLN iterable`END`PUN.`END`PLNiterator`END`PUN();`END`PLN\n' + + ' `END`KWDwhile`END`PLN `END`PUN(--`END`PLNn `END' + + '`PUN>`END`PLN `END`LIT0`END`PUN)`END`PLN `END`PUN{`END`PLN\n' + + ' it`END`PUN.`END`KWDnext`END`PUN();`END`PLN\n' + + ' `END`PUN}`END`PLN\n' + + ' `END`KWDreturn`END`PLN it`END`PUN.`END`KWDnext`END' + + '`PUN();`END`PLN\n' + + ' `END`PUN}`END`PLN\n' + + '\n' + + ' `END`KWDpublic`END`PLN `END`KWDstatic`END`PLN `END`KWDvoid`END' + + '`PLN main`END`PUN(`END`TYPString`END`PUN[]`END`PLN args`END' + + '`PUN)`END`PLN `END`PUN{`END`PLN\n' + + ' `END`TYPSystem`END`PUN.`END`KWDout`END`PUN.`END' + + '`KWDprint`END`PUN(`END`PLNnth`END`PUN(`END`LIT10`END`PUN,`END' + + '`PLN `END`KWDnew`END`PLN `END`TYPFibonacci`END`PUN()));`END' + + '`PLN\n' + + ' `END`PUN}`END`PLN\n' + + '`END`PUN}`END' + ), + java_lang: ( + '
    1. ' + + '`KWDpackage`END`PLN foo`END`PUN;`END' + + '`#2`PLN `END' + + '`#3`KWDimport`END`PLN java`END`PUN.`END`PLNutil`END`PUN.`END' + + '`TYPIterator`END`PUN;`END' + + '`#4`PLN `END' + + '`#5`COM/**`END' + + '`#6`COM * the fibonacci series implemented as an Iterable.`END' + + '`#7`COM *\/`END' + + '`#8`KWDpublic`END`PLN `END`KWDfinal`END`PLN `END`KWDclass`END' + + '`PLN `END`TYPFibonacci`END`PLN `END`KWDimplements`END`PLN `END' + + '`TYPIterable`END`PUN<`END`TYPInteger`END`PUN>`END`PLN `END`' + + 'PUN{`END' + + '`#9`PLN `END' + + '`COM/** the next and previous members of the series. *\/`END' + + '' + + '`#0`PLN `END`KWDprivate`END`PLN `END`KWDint`END`PLN a `END`PUN=`END' + + '`PLN `END`LIT1`END`PUN,`END`PLN b `END`PUN=`END`PLN `END`LIT1`END' + + '`PUN;`END' + + '`#1`PLN `END' + + '`#2`PLN `END`LIT@Override`END' + + '`#3`PLN `END`KWDpublic`END`PLN `END`TYPIterator`END`PUN<`END' + + '`TYPInteger`END`PUN>`END`PLN iterator`END`PUN()`END`PLN `END' + + '`PUN{`END' + + '`#4`PLN `END`KWDreturn`END`PLN `END`KWDnew`END`PLN `END' + + '`TYPIterator`END`PUN<`END`TYPInteger`END`PUN>()`END`PLN `END' + + '`PUN{`END' + + '`#5`PLN `END`COM/** the series is infinite. *\/`END' + + '' + + '`#6`PLN `END`KWDpublic`END`PLN `END`KWDboolean`END' + + '`PLN hasNext`END`PUN()`END`PLN `END`PUN{`END`PLN `END' + + '`KWDreturn`END`PLN `END`KWDtrue`END`PUN;`END`PLN `END`PUN}`END' + + '' + + '`#7`PLN `END`KWDpublic`END`PLN `END`TYPInteger`END' + + '`PLN next`END`PUN()`END`PLN `END`PUN{`END' + + '`#8`PLN `END`KWDint`END`PLN tmp `END`PUN=`END' + + '`PLN a`END`PUN;`END' + + '`#9`PLN a `END`PUN+=`END`PLN b`END`PUN;`END' + + '' + + '`#0`PLN b `END`PUN=`END`PLN tmp`END`PUN;`END' + + '' + + '`#1`PLN `END`KWDreturn`END`PLN a`END`PUN;`END' + + '' + + '`#2`PLN `END`PUN}`END' + + '`#3`PLN `END`KWDpublic`END`PLN `END`KWDvoid`END' + + '`PLN remove`END`PUN()`END`PLN `END`PUN{`END`PLN `END`KWDthrow`END' + + '`PLN `END`KWDnew`END`PLN `END' + + '`TYPUnsupportedOperationException`END`PUN();`END`PLN `END' + + '`PUN}`END' + + '`#4`PLN `END`PUN};`END' + + '`#5`PLN `END`PUN}`END' + + '`#6`PLN `END' + + '`#7`PLN `END`COM/**`END' + + '`#8`COM * the n<sup>th</sup> element of the given ' + + 'series.`END' + + '`#9`COM * @throws NoSuchElementException if there are less than ' + + 'n elements in the`END' + + '`#0`COM * given Iterable\'s {@link Iterable#iterator ' + + 'iterator}.`END' + + '`#1`COM *\/`END' + + '`#2`PLN `END`KWDpublic`END`PLN `END`KWDstatic`END`PLN `END' + + '`PUN<`END`PLNT`END`PUN>`END' + + '`#3`PLN T nth`END`PUN(`END`KWDint`END`PLN n`END`PUN,`END`PLN `END' + + '`TYPIterable`END`PUN<`END`PLNT`END`PUN>`END' + + '`PLN iterable`END`PUN)`END`PLN `END`PUN{`END' + + '`#4`PLN `END`TYPIterator`END`PUN<?`END`PLN `END' + + '`KWDextends`END`PLN T`END`PUN>`END`PLN in `END`PUN=`END' + + '`PLN iterable`END`PUN.`END`PLNiterator`END`PUN();`END' + + '`#5`PLN `END`KWDwhile`END`PLN `END`PUN(--`END`PLNn `END' + + '`PUN>`END`PLN `END`LIT0`END`PUN)`END`PLN `END`PUN{`END' + + '`#6`PLN in`END`PUN.`END`PLNnext`END`PUN();`END' + + '`#7`PLN `END`PUN}`END' + + '`#8`PLN `END`KWDreturn`END`PLN in`END`PUN.`END`PLNnext`END' + + '`PUN();`END' + + '`#9`PLN `END`PUN}`END' + + '`#0`PLN `END' + + '`#1`PLN `END`KWDpublic`END`PLN `END`KWDstatic`END`PLN `END`KWDvoid`END' + + '`PLN main`END`PUN(`END`TYPString`END`PUN[]`END`PLN args`END' + + '`PUN)`END`PLN `END`PUN{`END' + + '`#2`PLN `END`TYPSystem`END`PUN.`END`PLNout`END`PUN.`END' + + '`PLNprint`END`PUN(`END`PLNnth`END`PUN(`END`LIT10`END`PUN,`END' + + '`PLN `END`KWDnew`END`PLN `END`TYPFibonacci`END`PUN()));`END' + + '' + + '`#3`PLN `END`PUN}`END' + + '`#4`PUN}`END' + + '`#5`PLN `END' + + '`#6`PUN#`END`PLN not a java comment`END' + + '`#7`PUN#`END`PLN not keywords`END`PUN:`END' + + '`PLN static_cast and namespace`END
    ' + ), + javascript: ( + '`COM/**\n' + + ' * nth element in the fibonacci series.\n' + + ' * @param n >= 0\n' + + ' * @return the nth element, >= 0.\n' + + ' *\/`END`PLN\n' + + '`END`KWDfunction`END`PLN fib`END`PUN(`END`PLNn`END`PUN)`END`PLN `END' + + '`PUN{`END`PLN\n' + + ' `END`KWDvar`END`PLN a `END`PUN=`END`PLN `END`LIT1`END`PUN,`END' + + '`PLN b `END`PUN=`END`PLN `END`LIT1`END`PUN;`END`PLN\n' + + ' `END`KWDvar`END`PLN tmp`END`PUN;`END`PLN\n' + + ' `END`KWDwhile`END`PLN `END`PUN(--`END`PLNn `END`PUN>=`END' + + '`PLN `END`LIT0`END`PUN)`END`PLN `END`PUN{`END`PLN\n' + + ' tmp `END`PUN=`END`PLN a`END`PUN;`END`PLN\n' + + ' a `END`PUN+=`END`PLN b`END`PUN;`END`PLN\n' + + ' b `END`PUN=`END`PLN tmp`END`PUN;`END`PLN\n' + + ' `END`PUN}`END`PLN\n' + + ' `END`KWDreturn`END`PLN a`END`PUN;`END`PLN\n' + + '`END`PUN}`END`PLN\n' + + '\n' + + 'document`END`PUN.`END`PLNwrite`END`PUN(`END`PLNfib`END`PUN(`END' + + '`LIT10`END`PUN));`END' + ), + perl: ( + '`COM#!/usr/bin/perl`END`PLN\n' + + '\n' + + '`END`KWDuse`END`PLN strict`END`PUN;`END`PLN\n' + + '`END`KWDuse`END`PLN integer`END`PUN;`END`PLN\n' + + '\n' + + '`END`COM# the nth element of the fibonacci series`END`PLN\n' + + '`END`COM# param n - an int >= 0`END`PLN\n' + + '`END`COM# return an int >= 0`END`PLN\n' + + '`END`KWDsub`END`PLN fib`END`PUN(`END`PLN$`END`PUN)`END`PLN `END' + + '`PUN{`END`PLN\n' + + ' `END`KWDmy`END`PLN $n `END`PUN=`END`PLN shift`END`PUN,`END`PLN ' + + '$a `END`PUN=`END`PLN `END`LIT1`END`PUN,`END`PLN $b `END' + + '`PUN=`END`PLN `END`LIT1`END`PUN;`END`PLN\n' + + ' `END`PUN(`END`PLN$a`END`PUN,`END`PLN $b`END`PUN)`END' + + '`PLN `END`PUN=`END`PLN `END`PUN(`END`PLN$a `END`PUN+`END' + + '`PLN $b`END`PUN,`END`PLN $a`END`PUN)`END`PLN `END`KWDuntil`END' + + '`PLN `END`PUN(--`END`PLN$n `END`PUN<`END`PLN `END`LIT0`END' + + '`PUN);`END`PLN\n' + + ' `END`KWDreturn`END`PLN $a`END`PUN;`END`PLN\n' + + '`END`PUN}`END`PLN\n' + + '\n' + + '`END`KWDprint`END`PLN fib`END`PUN(`END`LIT10`END`PUN);`END' + ), + python: ( + '`COM#!/usr/bin/python2.4`END`PLN\n' + + '\n' + + '`END`KWDdef`END`PLN fib`END`PUN():`END`PLN\n' + + ' `END`STR\'\'\'\n' + + ' a generator that produces the elements of the fibonacci series' + + '\n' + + ' \'\'\'`END`PLN\n' + + '\n' + + ' a `END`PUN=`END`PLN `END`LIT1`END`PLN\n' + + ' b `END`PUN=`END`PLN `END`LIT1`END`PLN\n' + + ' `END`KWDwhile`END`PLN `END`KWDTrue`END`PUN:`END`PLN\n' + + ' a`END`PUN,`END`PLN b `END`PUN=`END`PLN a `END`PUN+`END' + + '`PLN b`END`PUN,`END`PLN a\n' + + ' `END`KWDyield`END`PLN a\n' + + '\n' + + '`END`KWDdef`END`PLN nth`END`PUN(`END`PLNseries`END`PUN,`END`PLN n`END' + + '`PUN):`END`PLN\n' + + ' `END`STR\'\'\'\n' + + ' returns the nth element of a series,\n' + + ' consuming the earlier elements of the series\n' + + ' \'\'\'`END`PLN\n' + + '\n' + + ' `END`KWDfor`END`PLN x `END`KWDin`END`PLN series`END`PUN:`END' + + '`PLN\n' + + ' n `END`PUN=`END`PLN n `END`PUN-`END`PLN `END`LIT1`END' + + '`PLN\n' + + ' `END`KWDif`END`PLN n `END`PUN<=`END`PLN `END' + + '`LIT0`END`PUN:`END`PLN `END`KWDreturn`END`PLN x\n' + + '\n' + + '`END`KWDprint`END`PLN nth`END`PUN(`END`PLNfib`END`PUN(),`END`PLN `END' + + '`LIT10`END`PUN)`END' + ), + python_lang: ( + '`COM#!/usr/bin/python2.4`END`PLN\n' + + '\n' + + '`END`KWDdef`END`PLN fib`END`PUN():`END`PLN\n' + + ' `END`STR\'\'\'\n' + + ' a generator that produces the fibonacci series\'s elements' + + '\n' + + ' \'\'\'`END`PLN\n' + + '\n' + + ' a `END`PUN=`END`PLN `END`LIT1`END`PLN\n' + + ' b `END`PUN=`END`PLN `END`LIT1`END`PLN\n' + + ' `END`KWDwhile`END`PLN `END`KWDTrue`END`PUN:`END`PLN\n' + + ' a`END`PUN,`END`PLN b `END`PUN=`END`PLN a `END`PUN+`END' + + '`PLN b`END`PUN,`END`PLN a\n' + + ' `END`KWDyield`END`PLN a\n' + + '\n' + + '`END`KWDdef`END`PLN nth`END`PUN(`END`PLNseries`END`PUN,`END`PLN n`END' + + '`PUN):`END`PLN\n' + + ' `END`STR\'\'\'\n' + + ' returns the nth element of a series,\n' + + ' consuming the series\' earlier elements.\n' + + ' \'\'\'`END`PLN\n' + + '\n' + + ' `END`KWDfor`END`PLN x `END`KWDin`END`PLN series`END`PUN:`END' + + '`PLN\n' + + ' n `END`PUN-=`END`PLN `END`LIT1`END' + + '`PLN\n' + + ' `END`KWDif`END`PLN n `END`PUN<=`END`PLN `END' + + '`LIT0`END`PUN:`END`PLN `END`KWDreturn`END`PLN x\n' + + '\n' + + '`END`KWDprint`END`PLN nth`END`PUN(`END`PLNfib`END`PUN(),`END`PLN `END' + + '`LIT10`END`PUN)`END`PLN\n' + + '\n' + + '`END`PUN/*`END`PLN `END`KWDnot`END`PLN a comment `END`KWDand`END' + + '`PLN `END`KWDnot`END`PLN keywords`END`PUN:`END' + + '`PLN null char true `END`PUN*\/`END' + ), + sql_lang: ( + '`COM/* A multi-line\n' + + ' * comment *\/`END`PLN\n' + + '`END`STR\'Another string /* Isn\\\'t a comment\'`END`PUN,`END`PLN\n' + + '`END`STR"A string *\/"`END`PLN\n' + + '`END`COM-- A line comment`END`PLN\n' + + '`END`KWDSELECT`END`PLN `END`PUN*`END`PLN `END`KWDFROM`END' + + '`PLN users `END`KWDWHERE`END`PLN id `END`KWDIN`END`PLN `END' + + '`PUN(`END`LIT1`END`PUN,`END`PLN `END`LIT2.0`END`PUN,`END`PLN `END' + + '`LIT+30e-1`END`PUN);`END`PLN\n' + + '`END`COM-- keywords are case-insensitive.`END`PLN\n' + + '`END`COM-- Note: user-table is a single identifier, not a pair of' + + ' keywords`END`PLN\n' + + '`END`KWDselect`END`PLN `END`PUN*`END`PLN `END`KWDfrom`END' + + '`PLN user-table `END`KWDwhere`END`PLN id `END`KWDin`END`PLN `END' + + '`PUN(`END`PLNx`END`PUN,`END`PLN y`END`PUN,`END`PLN z`END`PUN);`END' + ), + xml: ( + '`DEC<!DOCTYPE series PUBLIC "fibonacci numbers">`END`PLN\n' + + '\n' + + '`END`TAG<series.root`END`PLN `END`ATNbase`END`PUN=`END' + + '`ATV"1"`END`PLN `END' + + '`ATNstep`END`PUN=`END`ATV"s(n-2) + s(n-1)"`END`TAG>`END' + + '`PLN\n' + + ' `END`TAG<element`END`PLN `END`ATNi`END`PUN=`END' + + '`ATV"0"`END' + + '`TAG>`END`PLN1`END`TAG</element>`END' + + '`PLN\n' + + ' `END`TAG<element`END`PLN `END`ATNi`END`PUN=`END' + + '`ATV"1"`END' + + '`TAG>`END`PLN1`END`TAG</element>`END' + + '`PLN\n' + + ' `END`TAG<element`END`PLN `END`ATNi`END`PUN=`END' + + '`ATV"2"`END' + + '`TAG>`END`PLN2`END`TAG</element>`END' + + '`PLN\n' + + ' `END`TAG<element`END`PLN `END`ATNi`END`PUN=`END' + + '`ATV"3"`END' + + '`TAG>`END`PLN3`END`TAG</element>`END' + + '`PLN\n' + + ' `END`TAG<element`END`PLN `END`ATNi`END`PUN=`END' + + '`ATV"4"`END' + + '`TAG>`END`PLN5`END`TAG</element>`END' + + '`PLN\n' + + ' `END`TAG<element`END`PLN `END`ATNi`END`PUN=`END' + + '`ATV"5"`END' + + '`TAG>`END`PLN8`END`TAG</element>`END' + + '`PLN\n' + + ' ...\n' + + '`END`TAG</series.root>`END' + ), + html: ( + '`TAG<html>`END`PLN\n' + + ' `END`TAG<head>`END`PLN\n' + + ' `END`TAG<title>`END`PLNFibonacci number`END' + + '`TAG</title>`END`PLN\n' + + ' `END`TAG<style>`END`COM<!--`END' + + '`PLN BODY `END`PUN{`END`PLN `END`KWDtext-decoration`END`PUN:`END' + + '`PLN blink `END`PUN}`END`PLN `END`COM-->`END`TAG</' + + 'style>`END`PLN\n' + + ' `END`TAG<script`END`PLN `END`ATNsrc`END`PUN=`END' + + '`ATV"foo.js"`END`TAG></script>`END`PLN\n' + + ' `END`TAG<script`END`PLN `END`ATNsrc`END`PUN=`END' + + '`ATV"bar.js"`END`TAG></script>`END`PLN\n' + + ' `END`TAG</head>`END`PLN\n' + + ' `END`TAG<body>`END`PLN\n' + + ' `END`TAG<noscript>`END`PLN\n' + + ' `END`TAG<dl>`END`PLN\n' + + ' `END`TAG<dt>`END' + + '`PLNFibonacci numbers`END`TAG</dt>`END' + + '`PLN\n' + + ' `END`TAG<dd>`END`PLN1`END' + + '`TAG</dd>`END`PLN\n' + + ' `END`TAG<dd>`END`PLN1`END' + + '`TAG</dd>`END`PLN\n' + + ' `END`TAG<dd>`END`PLN2`END' + + '`TAG</dd>`END`PLN\n' + + ' `END`TAG<dd>`END`PLN3`END' + + '`TAG</dd>`END`PLN\n' + + ' `END`TAG<dd>`END`PLN5`END' + + '`TAG</dd>`END`PLN\n' + + ' `END`TAG<dd>`END`PLN8`END' + + '`TAG</dd>`END`PLN\n' + + ' &hellip;\n' + + ' `END`TAG</dl>`END`PLN\n' + + ' `END`TAG</noscript>`END`PLN\n' + + '\n' + + ' `END`TAG<script`END`PLN `END`ATNtype`END`PUN=`END' + + '`ATV"text/javascript"`END`TAG>`END`PUN<!--`END`PLN\n' + + '`END`KWDfunction`END`PLN fib`END`PUN(`END`PLNn`END`PUN)`END`PLN `END' + + '`PUN{`END`PLN\n' + + ' `END`KWDvar`END`PLN a `END`PUN=`END`PLN `END`LIT1`END`PUN,`END' + + '`PLN b `END`PUN=`END`PLN `END`LIT1`END`PUN;`END`PLN\n' + + ' `END`KWDvar`END`PLN tmp`END`PUN;`END`PLN\n' + + ' `END`KWDwhile`END`PLN `END`PUN(--`END`PLNn `END`PUN>=`END' + + '`PLN `END`LIT0`END`PUN)`END`PLN `END`PUN{`END`PLN\n' + + ' tmp `END`PUN=`END`PLN a`END`PUN;`END`PLN\n' + + ' a `END`PUN+=`END`PLN b`END`PUN;`END`PLN\n' + + ' b `END`PUN=`END`PLN tmp`END`PUN;`END`PLN\n' + + ' `END`PUN}`END`PLN\n' + + ' `END`KWDreturn`END`PLN a`END`PUN;`END`PLN\n' + + '`END`PUN}`END`PLN\n' + + '\n' + + 'document`END`PUN.`END`PLNwriteln`END`PUN(`END`PLNfib`END`PUN(`END' + + '`LIT10`END`PUN));`END`PLN\n' + + '`END`COM// -->`END`PLN\n' + + ' `END`TAG</script>`END`PLN\n' + + ' `END`TAG</body>`END`PLN\n' + + '`END`TAG</html>`END' + ), + html_lang: ( + '`PLNFibonacci Numbers\n' + + '\n' + + '`END`TAG<noscript>`END`PLN\n' + + ' `END`TAG<dl`END`PLN `END`ATNstyle`END`PUN=`END' + + '`ATV"`END`KWDlist-style`END`PUN:`END`PLN disc`END`ATV"`END' + + '`TAG>`END`PLN\n' + + ' `END`TAG<dt>`END' + + '`PLNFibonacci numbers`END`TAG</dt>`END`PLN\n' + + ' `END`TAG<dd>`END`PLN1`END`TAG</dd>`END' + + '`PLN\n' + + ' `END`TAG<dd>`END`PLN1`END`TAG</dd>`END' + + '`PLN\n' + + ' `END`TAG<dd>`END`PLN2`END`TAG</dd>`END' + + '`PLN\n' + + ' `END`TAG<dd>`END`PLN3`END`TAG</dd>`END' + + '`PLN\n' + + ' `END`TAG<dd>`END`PLN5`END`TAG</dd>`END' + + '`PLN\n' + + ' `END`TAG<dd>`END`PLN8`END`TAG</dd>`END' + + '`PLN\n' + + ' &hellip;\n' + + ' `END`TAG</dl>`END`PLN\n' + + '`END`TAG</noscript>`END`PLN\n' + + '\n' + + '`END`TAG<script`END`PLN `END`ATNtype`END`PUN=`END' + + '`ATV"text/javascript"`END`TAG>`END`PUN<!--`END`PLN\n' + + '`END`KWDfunction`END`PLN fib`END`PUN(`END`PLNn`END`PUN)`END`PLN `END' + + '`PUN{`END`PLN\n' + + ' `END`KWDvar`END`PLN a `END`PUN=`END`PLN `END`LIT1`END`PUN,`END' + + '`PLN b `END`PUN=`END`PLN `END`LIT1`END`PUN;`END`PLN\n' + + ' `END`KWDvar`END`PLN tmp`END`PUN;`END`PLN\n' + + ' `END`KWDwhile`END`PLN `END`PUN(--`END`PLNn `END`PUN>=`END' + + '`PLN `END`LIT0`END`PUN)`END`PLN `END`PUN{`END`PLN\n' + + ' tmp `END`PUN=`END`PLN a`END`PUN;`END`PLN\n' + + ' a `END`PUN+=`END`PLN b`END`PUN;`END`PLN\n' + + ' b `END`PUN=`END`PLN tmp`END`PUN;`END`PLN\n' + + ' `END`PUN}`END`PLN\n' + + ' `END`KWDreturn`END`PLN a`END`PUN;`END`PLN\n' + + '`END`PUN}`END`PLN\n' + + '\n' + + 'document`END`PUN.`END`PLNwriteln`END`PUN(`END`PLNfib`END`PUN(`END' + + '`LIT10`END`PUN));`END`PLN\n' + + '`END`COM// -->`END`PLN\n' + + '`END`TAG</script>`END' + ), + html_xmp: ( + '`TAG<html>`END`PLN\n' + + ' `END`TAG<head>`END`PLN\n' + + ' `END`TAG<title>`END`PLNFibonacci number`END' + + '`TAG</title>`END`PLN\n' + + ' `END`TAG</head>`END`PLN\n' + + ' `END`TAG<body>`END`PLN\n' + + ' `END`TAG<noscript>`END`PLN\n' + + ' `END`TAG<dl>`END`PLN\n' + + ' `END`TAG<dt>`END' + + '`PLNFibonacci numbers`END`TAG</dt>`END`PLN\n' + + ' `END`TAG<dd>`END`PLN1`END' + + '`TAG</dd>`END`PLN\n' + + ' `END`TAG<dd>`END`PLN1`END' + + '`TAG</dd>`END`PLN\n' + + ' `END`TAG<dd>`END`PLN2`END' + + '`TAG</dd>`END`PLN\n' + + ' `END`TAG<dd>`END`PLN3`END' + + '`TAG</dd>`END`PLN\n' + + ' `END`TAG<dd>`END`PLN5`END' + + '`TAG</dd>`END`PLN\n' + + ' `END`TAG<dd>`END`PLN8`END' + + '`TAG</dd>`END`PLN\n' + + ' &hellip;\n' + + ' `END`TAG</dl>`END`PLN\n' + + ' `END`TAG</noscript>`END`PLN\n' + + '\n' + + ' `END`TAG<script`END`PLN `END`ATNtype`END`PUN=`END' + + '`ATV"text/javascript"`END`TAG>`END`PUN<!--`END`PLN\n' + + '`END`KWDfunction`END`PLN fib`END`PUN(`END`PLNn`END`PUN)`END`PLN `END' + + '`PUN{`END`PLN\n' + + ' `END`KWDvar`END`PLN a `END`PUN=`END`PLN `END`LIT1`END`PUN,`END' + + '`PLN b `END`PUN=`END`PLN `END`LIT1`END`PUN;`END`PLN\n' + + ' `END`KWDvar`END`PLN tmp`END`PUN;`END`PLN\n' + + ' `END`KWDwhile`END`PLN `END`PUN(--`END`PLNn `END`PUN>=`END' + + '`PLN `END`LIT0`END`PUN)`END`PLN `END`PUN{`END`PLN\n' + + ' tmp `END`PUN=`END`PLN a`END`PUN;`END`PLN\n' + + ' a `END`PUN+=`END`PLN b`END`PUN;`END`PLN\n' + + ' b `END`PUN=`END`PLN tmp`END`PUN;`END`PLN\n' + + ' `END`PUN}`END`PLN\n' + + ' `END`KWDreturn`END`PLN a`END`PUN;`END`PLN\n' + + '`END`PUN}`END`PLN\n' + + '\n' + + 'document`END`PUN.`END`PLNwriteln`END`PUN(`END`PLNfib`END`PUN(`END' + + '`LIT10`END`PUN));`END`PLN\n' + + '`END`COM// -->`END`PLN\n' + + ' `END`TAG</script>`END`PLN\n' + + ' `END`TAG</body>`END`PLN\n' + + '`END`TAG</html>`END' + ), + xhtml: ( + '`TAG<xhtml>`END`PLN\n' + + ' `END`TAG<head>`END`PLN\n' + + ' `END`TAG<title>`END' + + '`PLNFibonacci number`END`TAG</title>`END' + + '`PLN\n' + + ' `END`TAG</head>`END`PLN\n' + + ' `END`TAG<body`END`PLN `END`ATNonload`END`PUN=`END' + + '`ATV"`END`PLNalert`END`PUN(`END`PLNfib`END`PUN(`END`LIT10`END' + + '`PUN))`END`ATV"`END`TAG>`END`PLN\n' + + ' `END`TAG<script`END`PLN `END`ATNtype`END' + + '`PUN=`END`ATV"text/javascript"`END`TAG>`END' + + '`PUN<![`END`PLNCDATA`END`PUN[`END`PLN\n' + + '`END`KWDfunction`END`PLN fib`END`PUN(`END`PLNn`END`PUN)`END`PLN `END' + + '`PUN{`END`PLN\n' + + ' `END`KWDvar`END`PLN a `END`PUN=`END`PLN `END`LIT1`END`PUN,`END' + + '`PLN b `END`PUN=`END`PLN `END`LIT1`END`PUN;`END`PLN\n' + + ' `END`KWDvar`END`PLN tmp`END`PUN;`END`PLN\n' + + ' `END`KWDwhile`END`PLN `END`PUN(--`END`PLNn `END`PUN>=`END' + + '`PLN `END`LIT0`END`PUN)`END`PLN `END`PUN{`END`PLN\n' + + ' tmp `END`PUN=`END`PLN a`END`PUN;`END`PLN\n' + + ' a `END`PUN+=`END`PLN b`END`PUN;`END`PLN\n' + + ' b `END`PUN=`END`PLN tmp`END`PUN;`END`PLN\n' + + ' `END`PUN}`END`PLN\n' + + ' `END`KWDreturn`END`PLN a`END`PUN;`END`PLN\n' + + '`END`PUN}`END`PLN\n' + + '`END`PUN]]>`END`PLN\n' + + ' `END`TAG</script>`END`PLN\n' + + ' `END`TAG</body>`END`PLN\n' + + '`END`TAG</xhtml>`END' + ), + php: ( + '`TAG<html>`END`PLN\n' + + ' `END`TAG<head>`END`PLN\n' + + ' `END`TAG<title>`END`PUN<?=`END' + + '`PLN `END' + + '`STR\'Fibonacci numbers\'`END`PLN `END' + + '`PUN?>`END`TAG</title>`END`PLN\n' + + '\n' + + ' `END`PUN<?`END`PLNphp\n' + + ' `END`COM// PHP has a plethora of comment types' + + '`END`PLN\n' + + ' `END`COM\/* What is a\n' + + ' "plethora"? *\/`END`PLN\n' + + ' `END`KWDfunction`END`PLN fib`END`PUN(`END' + + '`PLN$n`END`PUN)`END`PLN `END`PUN{`END`PLN\n' + + ' `END`COM# I don\'t know.`END`PLN\n' + + ' $a `END`PUN=`END`PLN `END`LIT1`END' + + '`PUN;`END`PLN\n' + + ' $b `END`PUN=`END`PLN `END`LIT1`END' + + '`PUN;`END`PLN\n' + + ' `END`KWDwhile`END`PLN `END`PUN(--`END' + + '`PLN$n `END`PUN>=`END`PLN `END`LIT0`END`PUN)`END`PLN `END' + + '`PUN{`END`PLN\n' + + ' echo `END`STR"$a\\n"`END`PUN;`END' + + '`PLN\n' + + ' $tmp `END`PUN=`END`PLN $a`END' + + '`PUN;`END`PLN\n' + + ' $a `END`PUN+=`END`PLN $b`END' + + '`PUN;`END`PLN\n' + + ' $b `END`PUN=`END`PLN $tmp`END' + + '`PUN;`END`PLN\n' + + ' `END`PUN}`END`PLN\n' + + ' `END`PUN}`END`PLN\n' + + ' `END`PUN?>`END`PLN\n' + + ' `END`TAG</head>`END`PLN\n' + + ' `END`TAG<body>`END`PLN\n' + + ' `END`PUN<?=`END`PLN fib`END' + + '`PUN(`END`LIT10`END`PUN)`END`PLN `END`PUN?>`END`PLN\n' + + ' `END`TAG</body>`END`PLN\n' + + '`END`TAG</html>`END' + ), + xsl: ( + '`COM<!-- Test elements and attributes with namespaces -->' + + '`END`PLN\n' + + '\n' + + '`END`TAG<xsl:stylesheet`END`PLN `END`ATNxml:lang`END' + + '`PUN=`END`ATV"en"`END`TAG>`END`PLN\n' + + ' `END`TAG<xsl:template`END' + + '`PLN `END`ATNmatch`END`PUN=`END`ATV"."`END' + + '`TAG>`END`PLN\n' + + ' `END`TAG<xsl:text>`END' + + '`PLNHello World`END' + + '`TAG</xsl:text>`END`PLN\n' + + ' `END`TAG</xsl:template>`END`PLN\n' + + '`END`TAG</xsl:stylesheet>`END' + ), + whitespace: '', + misc1: ( + '`COM// ends with line comment token`END`PLN\n' + + '`END`COM//`END' + ), + js_script: ( + '`TAG<script`END`PLN `END' + + '`ATNtype`END`PUN=`END`ATV"text/javascript"`END' + + '`TAG>`END`PLN\n' + + ' var savedTarget=null' + + '; ' + + ' // The target ' + + 'layer (effectively vidPane)\n' + + ' var orgCursor=null' + + '; ' + + ' // The ' + + 'original mouse style so we can restore it\n' + + ' var dragOK=false' + + '; ' + + ' ' + + '// True if we\'re allowed to move the element under mouse' + + '\n' + + ' var dragXoffset=0' + + '; ' + + ' ' + + '// How much we\'ve moved the element on the horozontal' + + '\n' + + ' var dragYoffset=0' + + '; ' + + ' ' + + '// How much we\'ve moved the element on the verticle' + + '\n' + + ' vidPaneID = document.' + + 'getElementById(\'vidPane\');' + + ' // Our movable layer\n' + + ' vidPaneID.style.top' + + '=\'75px\'; ' + + ' // ' + + 'Starting location horozontal\n' + + ' vidPaneID.style.left' + + '=\'75px\'; ' + + ' // ' + + 'Starting location verticle\n' + + '`END`TAG<script>`END' + ), + issue8: ( + '`PLNone`END`PLN\t`END`TYPTwo`END`PLN' + + '\t`END`PLNthree`END`PLN\t`END`TYPFour' + + '`END`PLN\t`END`PLNfive`END`PLN\t' + + '`END`PUN|`END`PLN\n' + + '`END`TYPSix`END`PLN\t`END`PLNseven`END`PLN\t' + + '`END`TYPEight`END`PLN\tnine\t`END`TYPTen`END' + + '`PLN\t`END`PUN|`END`PLN\n' + + '`END`PLNeleven`END`PLN\t`END`TYPTwelve`END`PLN\t`END' + + '`PLNthirteen`END`PLN\t`END' + + '`TYPFourteen`END`PLN\tfifteen\t`END`' + + 'PUN|`END' + ), + js_regexp: ( + '`STR/foo/`END`PUN;`END`PLN `END`COM// a slash starting a line ' + + 'treated as a regexp beginning`END`PLN\n' + + '`END`STR"foo"`END`PUN.`END`PLNmatch`END`PUN(`END`STR/fo+$/`END' + + '`PUN);`END`PLN\n' + + '`END`COM// this line comment not treated as a regular expressions`END' + + '`PLN\n' + + '`END`STR"foo /bar/"`END`PUN.`END`PLNtest`END`PUN(`END`STR/"baz"/`END' + + '`PUN);`END`PLN `END`COM// test string and regexp boundaries' + + '`END`PLN\n' + + '`END`KWDvar`END`PLN division `END`PUN=`END`PLN `END' + + '`STR/\\b\\d+\\/\\d+/`END`PLNg`END`PUN;`END`PLN `END' + + '`COM// test char sets and escaping of specials`END`PLN\n' + + '`END`KWDvar`END`PLN allSpecials `END`PUN=`END`PLN `END' + + '`STR/([^\\(\\)\\[\\]\\{\\}\\-\\?\\+\\*\\.\\^\\$\\/]+)\\\\/`END' + + '`PUN;`END`PLN\n' + + '`END`KWDvar`END`PLN slashInCharset `END`PUN=`END`PLN `END' + + '`STR/[^/]/`END`PLNg`END`PUN,`END`PLN notCloseSq `END`PUN=`END' + + '`PLN `END`STR/[^\\]]/`END`PUN;`END`PLN\n' + + '\n' + + '`END`COM// test that slash used in numeric context treated as an ' + + 'operator`END`PLN\n' + + '`END`LIT1`END`PLN `END`PUN/`END`PLN `END`LIT2`END`PUN;`END`PLN\n' + + '`END`LIT1.`END`PLN `END`PUN/`END`PLN x`END`PUN;`END`PLN\n' + + 'x `END`PUN/`END`PLN y`END`PUN;`END`PLN\n' + + '`END`PUN(`END`PLNx`END`PUN)`END`PLN `END`PUN/`END`PLN y`END`PUN;`END' + + '`PLN\n' + + '`END`LIT1`END`PLN `END`COM/* foo *\/`END`PLN `END`PUN/`END`PLN `END' + + '`LIT2`END`PUN;`END`PLN\n' + + '`END`LIT1`END`PLN `END`COM/* foo *\/`END`PUN/`END`PLN `END`LIT2`END' + + '`PUN;`END`PLN\n' + + '`END`LIT1`END`PUN/`END`LIT2`END`PUN;`END`PLN\n' + + '`END`LIT1.`END`PUN/`END`PLNx`END`PUN;`END`PLN\n' + + 'x`END`PUN/`END`PLNy`END`PUN;`END`PLN\n' + + '`END`PUN(`END`PLNx`END`PUN)/`END`PLNy`END`PUN;`END`PLN\n' + + '\n' + + '`END`COM// test split over two lines. line comment should not ' + + 'fool it`END`PLN\n' + + '`END`LIT1`END`COM//`END`PLN\n' + + '`END`PUN/`END`LIT2`END`PUN;`END`PLN\n' + + '\n' + + 'x`END`PUN++/`END`PLNy`END`PUN;`END`PLN\n' + + 'x`END`PUN--/`END`PLNy`END`PUN;`END`PLN\n' + + 'x`END`PUN[`END`PLNy`END`PUN]`END`PLN `END`PUN/`END`PLN z`END`PUN;`END' + + '`PLN\n' + + 'f`END`PUN()`END`PLN `END`PUN/`END`PLN n`END`PUN;`END`PLN\n' + + '\n' + + '`END`COM// test that slash after non postfix operator is start of ' + + 'regexp`END`PLN\n' + + 'log`END`PUN(`END`STR\'matches = \'`END`PLN `END`PUN+`END`PLN `END' + + '`STR/foo/`END`PUN.`END`PLNtest`END`PUN(`END`PLNfoo`END`PUN));`END' + + '`PLN\n' + + '\n' + + '`END`COM// test keyword preceders`END`PLN\n' + + '`END`KWDreturn`END`PLN `END`STR/a regexp/`END`PUN;`END`PLN\n' + + 'division `END`PUN=`END`PLN notreturn `END`PUN/`END`PLN not_a_regexp ' + + '`END`PUN/`END`PLN `END`LIT2`END`PUN;`END`PLN `END`COM// ' + + 'keyword suffix does not match`END`PLN\n' + + '\n' + + '`END`COM// & not used as prefix operator in javascript but this ' + + 'should still work`END`PLN\n' + + '`END`PUN&`END`STR/foo/`END`PUN;`END`PLN\n' + + '\n' + + '`END`KWDextends`END`PLN `END`PUN=`END`PLN `END`STR/extends/`END' + + '`PUN;`END' + ), + js_regexp_lang: ( + '`STR/foo/`END`PUN;`END`PLN `END`COM// a slash starting a line ' + + 'treated as a regexp beginning`END`PLN\n' + + '`END`STR"foo"`END`PUN.`END`PLNmatch`END`PUN(`END`STR/fo+$/`END' + + '`PUN);`END`PLN\n' + + '`END`COM// this line comment not treated as a regular expressions`END' + + '`PLN\n' + + '`END`STR"foo /bar/"`END`PUN.`END`PLNtest`END`PUN(`END`STR/"baz"/`END' + + '`PUN);`END`PLN `END`COM// test string and regexp boundaries' + + '`END`PLN\n' + + '`END`KWDvar`END`PLN division `END`PUN=`END`PLN `END' + + '`STR/\\b\\d+\\/\\d+/`END`PLNg`END`PUN;`END`PLN `END' + + '`COM// test char sets and escaping of specials`END`PLN\n' + + '`END`KWDvar`END`PLN allSpecials `END`PUN=`END`PLN `END' + + '`STR/([^\\(\\)\\[\\]\\{\\}\\-\\?\\+\\*\\.\\^\\$\\/]+)\\\\/`END' + + '`PUN;`END`PLN\n' + + '`END`KWDvar`END`PLN slashInCharset `END`PUN=`END`PLN `END' + + '`STR/[^/]/`END`PLNg`END`PUN,`END`PLN notCloseSq `END`PUN=`END' + + '`PLN `END`STR/[^\\]]/`END`PUN;`END`PLN\n' + + '\n' + + '`END`COM// test that slash used in numeric context treated as an ' + + 'operator`END`PLN\n' + + '`END`LIT1`END`PLN `END`PUN/`END`PLN `END`LIT2`END`PUN;`END`PLN\n' + + '`END`LIT1.`END`PLN `END`PUN/`END`PLN x`END`PUN;`END`PLN\n' + + 'x `END`PUN/`END`PLN y`END`PUN;`END`PLN\n' + + '`END`PUN(`END`PLNx`END`PUN)`END`PLN `END`PUN/`END`PLN y`END`PUN;`END' + + '`PLN\n' + + '`END`LIT1`END`PLN `END`COM/* foo *\/`END`PLN `END`PUN/`END`PLN `END' + + '`LIT2`END`PUN;`END`PLN\n' + + '`END`LIT1`END`PLN `END`COM/* foo *\/`END`PUN/`END`PLN `END`LIT2`END' + + '`PUN;`END`PLN\n' + + '`END`LIT1`END`PUN/`END`LIT2`END`PUN;`END`PLN\n' + + '`END`LIT1.`END`PUN/`END`PLNx`END`PUN;`END`PLN\n' + + 'x`END`PUN/`END`PLNy`END`PUN;`END`PLN\n' + + '`END`PUN(`END`PLNx`END`PUN)/`END`PLNy`END`PUN;`END`PLN\n' + + '\n' + + '`END`COM// test split over two lines. line comment should not ' + + 'fool it`END`PLN\n' + + '`END`LIT1`END`COM//`END`PLN\n' + + '`END`PUN/`END`LIT2`END`PUN;`END`PLN\n' + + '\n' + + 'x`END`PUN++/`END`PLNy`END`PUN;`END`PLN\n' + + 'x`END`PUN--/`END`PLNy`END`PUN;`END`PLN\n' + + 'x`END`PUN[`END`PLNy`END`PUN]`END`PLN `END`PUN/`END`PLN z`END`PUN;`END' + + '`PLN\n' + + 'f`END`PUN()`END`PLN `END`PUN/`END`PLN n`END`PUN;`END`PLN\n' + + '\n' + + '`END`COM// test that slash after non postfix operator is start of ' + + 'regexp`END`PLN\n' + + 'log`END`PUN(`END`STR\'matches = \'`END`PLN `END`PUN+`END`PLN `END' + + '`STR/foo/`END`PUN.`END`PLNtest`END`PUN(`END`PLNfoo`END`PUN));`END' + + '`PLN\n' + + '\n' + + '`END`COM// test keyword preceders`END`PLN\n' + + '`END`KWDreturn`END`PLN `END`STR/a regexp/`END`PUN;`END`PLN\n' + + 'division `END`PUN=`END`PLN notreturn `END`PUN/`END`PLN not_a_regexp ' + + '`END`PUN/`END`PLN `END`LIT2`END`PUN;`END`PLN `END`COM// ' + + 'keyword suffix does not match`END`PLN\n' + + '\n' + + '`END`COM// & not used as prefix operator in javascript but this ' + + 'should still work`END`PLN\n' + + '`END`PUN&`END`STR/foo/`END`PUN;`END`PLN\n' + + '\n' + + 'extends `END`PUN=`END`PLN `END`STR/extends/`END`PUN;`END' + ), + coffee: ( + '`KWDclass`END`PLN `END`TYPAnimal`END`PLN\n' + + ' constructor`END`PUN:`END`PLN `END`PUN(`END`LIT@name`END`PUN)`END`PLN `END`PUN->`END`PLN\n' + + ' move`END`PUN:`END`PLN `END`PUN(`END`PLNmeters`END`PUN,`END`PLN loc`END`PUN)`END`PLN `END`PUN->`END`PLN\n' + + ' alert `END`LIT@name`END`PLN `END`PUN+`END`PLN `END`STR" moved "`END`PLN `END`PUN+`END`PLN meters `END`PUN+`END`PLN `END`STR"m."`END`PLN\n' + + ' travel`END`PUN:`END`PLN `END`PUN(`END`PLNpath`END`PUN...)`END`PLN `END`PUN->`END`PLN\n' + + ' `END`KWDfor`END`PLN place `END`KWDin`END`PLN path\n' + + ' `END`LIT@move`END`PLN place`END`PUN.`END`PLNdistance`END`PUN,`END`PLN place`END`PUN.`END`PLNlocation\n' + + '\n' + + '`END`KWDclass`END`PLN `END`TYPHorse`END`PLN `END`KWDextends`END`PLN `END`TYPAnimal`END`PLN\n' + + ' `END`COM###\n' + + ' @param name Horse name\n' + + ' @param jumper Jumping ability\n' + + ' ###`END`PLN\n' + + ' constructor`END`PUN:`END`PLN `END`PUN(`END`PLNname`END`PUN,`END`PLN jumper`END`PUN)`END`PLN `END`PUN->`END`PLN\n' + + ' `END`KWDsuper`END`PLN name\n' + + ' `END`LIT@capable`END`PLN `END`PUN=`END`PLN jumper\n' + + ' step`END`PUN:`END`PLN `END`PUN->`END`PLN\n' + + ' alert `END`STR\'\'\'\n' + + ' Step,\n' + + ' step...\n' + + ' \'\'\'`END`PLN\n' + + ' jump`END`PUN:`END`PLN `END`PUN->`END`PLN\n' + + ' `END`LIT@capable`END`PLN\n' + + ' move`END`PUN:`END`PLN `END`PUN(`END`PLNmeters`END`PUN,`END`PLN where`END`PUN)`END`PLN `END`PUN->`END`PLN\n' + + ' switch where\n' + + ' `END`KWDwhen`END`PLN `END`STR"ground"`END`PLN\n' + + ' `END`LIT@step`END`PUN()`END`PLN\n' + + ' `END`KWDsuper`END`PLN meters\n' + + ' `END`KWDwhen`END`PLN `END`STR"hurdle"`END`PLN\n' + + ' `END`KWDsuper`END`PLN meters `END`KWDif`END`PLN `END`LIT@jump`END`PUN()`END`PLN\n' + + '\n' + + '`END`COM# Create horse`END`PLN\n' + + 'tom `END`PUN=`END`PLN `END`KWDnew`END`PLN `END`TYPHorse`END`PLN `END`STR"Tommy"`END`PUN,`END`PLN `END`KWDyes`END`PLN\n' + + '\n' + + 'street `END`PUN=`END`PLN\n' + + ' location`END`PUN:`END`PLN `END`STR"ground"`END`PLN\n' + + ' distance`END`PUN:`END`PLN `END`LIT12`END`PLN\n' + + 'car `END`PUN=`END`PLN\n' + + ' location`END`PUN:`END`PLN `END`STR"hurdle"`END`PLN\n' + + ' distance`END`PUN:`END`PLN `END`LIT2`END`PLN\n' + + '\n' + + '`END`COM###\n' + + 'Tell him to travel:\n' + + '1. through the street\n' + + '2. over the car\n' + + '###`END`PLN\n' + + 'tom`END`PUN.`END`PLNtravel street`END`PUN,`END`PLN car`END' + ), + issue14a: ( + '`COM//comment`END
    ' + + '`KWDint`END`PLN main`END`PUN(`END`KWDint`END`PLN argc`END`PUN,`END' + + '`PLN `END`KWDchar`END`PLN `END`PUN**`END`PLNargv`END`PUN)`END' + + '`PLN\n' + + '`END`PUN{}`END' + ), + issue14b: ( + '`COM<!-- There\'s an `END`COMHTML`END' + + '`COM comment in my comment -->`END`PLN\n' + + '`END`TAG<p>`END' + + '`PLNAnd another one inside the end tag`END' + + '`TAG</p`END`TAG>`END' + ), + issue20: ( + '`TAG<html>`END`PLN\n' + + '\n' + + '`END`TAG<head>`END' + ), + issue21: ( + '`TAG<html>`END`PLN\n' + + ' `END`TAG<head>`END`PLN\n' + + ' `END`TAG<title>`END`PLNTest`END' + + '`TAG</title>`END`PLN\n' + + ' `END`TAG</head>`END`PLN\n' + + '`END`TAG</html>`END' + ), + issue22: ( + '01: `END`COM// This is a line of code`END`PLN\n' + + '`END02: `END`COM/* Multiline comments can\n' + + '`END03: `END`COM * span over and around\n' + + '`END04: `END`COM * line markers\n' + + '`ENDAnd can even be interrupted`END`COM\n' + + '`ENDby inline code annotations`END`COM\n' + + '`END05: `END`COM *\/`END`PLN\n' + + '`END06: `END`KWDclass`END`PLN `END`TYPMyClass`END' + + '`PLN `END`KWDextends`END`PLN `END`TYPFoo`END`PLN `END`PUN{`END' + + '`PLN\n' + + '`END07: `END`PLN `END`KWDpublic`END' + + '`PLN `END`KWDstatic`END`PLN `END`KWDvoid`END`PLN main`END`PUN(`END' + + '`TYPString`END`PUN...`END`PLN argv`END`PUN)`END`PLN `END`PUN{`END' + + '`PLN\n' + + '`END08: `END`PLN `END`TYPSystem`END' + + '`PUN.`END`PLNout`END`PUN.`END`PLNprint`END`PUN(`END' + + '`STR"Hello World"`END`PUN);`END`PLN\n' + + '`END09: `END`PLN `END`PUN}`END`PLN\n' + + '`END10: `END`PUN}`END' + ), + lua: ( + '`PLNos`END`PUN=`END`PLNrequire`END`PUN(`END`STR"os"`END`PUN)`END`PLN\n' + + 'math`END`PUN=`END`PLNrequire`END`PUN(`END`STR"math"`END`PUN)`END`PLN\n' + + '\n' + + '`END`COM-- Examples from the language reference`END`PLN\n' + + ' a `END`PUN=`END`PLN `END`STR\'alo\\n123"\'`END' + + '`PLN\n' + + ' a `END`PUN=`END`PLN `END`STR"alo\\n123\\""`END' + + '`PLN\n' + + ' a `END`PUN=`END`PLN `END' + + '`STR\'\\97lo\\10\\04923"\'`END`PLN\n' + + ' a `END`PUN=`END`PLN `END`STR[[alo\n' + + ' 123"]]`END`PLN\n' + + ' a `END`PUN=`END`PLN `END`STR[==[\n' + + ' alo\n' + + ' 123"]==]`END`PLN\n' + + '\n' + + '`END`LIT3`END`PLN `END`LIT3.0`END`PLN `END`LIT3.1416`END' + + '`PLN `END`LIT314.16e-2`END`PLN `END`LIT0.31416E1`END' + + '`PLN `END`LIT0xff`END`PLN `END`LIT0x56`END`PLN\n' + + '\n' + + '`END`COM-- Some comments that demonstrate long brackets`END`PLN\n' + + 'double_quoted `END`PUN=`END`PLN `END`STR"Not a long bracket [=["`END' + + '`PLN\n' + + '`END`COM--[=[ quoting out\n' + + ' [[ foo ]]\n' + + ' [==[does not end comment either]==]\n' + + ']=]`END`PLN\n' + + 'past_end_of_comment\n' + + '`END`COM--]=]`END`PLN\n' + + '\n' + + '`END`COM-- Example code courtesy Joseph Harmbruster`END`PLN\n' + + '`END`PUN#`END`PLN\n' + + '`END`KWDdo`END`PLN\n' + + ' `END`KWDlocal`END`PLN `END`KWDfunction`END`PLN ssgeneral`END' + + '`PUN(`END`PLNt`END`PUN,`END`PLN n`END`PUN,`END`PLN before`END' + + '`PUN)`END`PLN\n' + + ' `END`KWDfor`END`PLN _`END`PUN,`END`PLN h `END`KWDin`END' + + '`PLN ipairs`END`PUN(`END`PLNincs`END`PUN)`END`PLN `END`KWDdo`END' + + '`PLN\n' + + ' `END`KWDfor`END`PLN i `END`PUN=`END`PLN h `END' + + '`PUN+`END`PLN `END`LIT1`END`PUN,`END`PLN n `END`KWDdo`END`PLN\n' + + ' `END`KWDlocal`END`PLN v `END`PUN=`END' + + '`PLN t`END`PUN[`END`PLNi`END`PUN]`END`PLN\n' + + ' `END`KWDfor`END`PLN j `END`PUN=`END' + + '`PLN i `END`PUN-`END`PLN h`END`PUN,`END`PLN `END`LIT1`END`PUN,`END' + + '`PLN `END`PUN-`END`PLNh `END`KWDdo`END`PLN\n' + + ' `END`KWDlocal`END`PLN testval `END' + + '`PUN=`END`PLN t`END`PUN[`END`PLNj`END`PUN]`END`PLN\n' + + ' `END`KWDif`END`PLN `END`KWDnot`END' + + '`PLN before`END`PUN(`END`PLNv`END`PUN,`END`PLN testval`END' + + '`PUN)`END`PLN `END`KWDthen`END`PLN `END`KWDbreak`END`PLN `END' + + '`KWDend`END`PLN\n' + + ' t`END`PUN[`END`PLNi`END`PUN]`END' + + '`PLN `END`PUN=`END`PLN testval`END`PUN;`END`PLN i `END`PUN=`END' + + '`PLN j\n' + + ' `END`KWDend`END`PLN\n' + + ' t`END`PUN[`END`PLNi`END`PUN]`END`PLN `END' + + '`PUN=`END`PLN v\n' + + ' `END`KWDend`END`PLN \n' + + ' `END`KWDend`END`PLN\n' + + ' `END`KWDreturn`END`PLN t\n' + + ' `END`KWDend`END`PLN\n' + + '\n' + + ' `END`KWDfunction`END`PLN shellsort`END`PUN(`END`PLNt`END' + + '`PUN,`END`PLN before`END`PUN,`END`PLN n`END`PUN)`END`PLN\n' + + ' n `END`PUN=`END`PLN n `END`KWDor`END`PLN `END`PUN#`END' + + '`PLNt\n' + + ' `END`KWDif`END`PLN `END`KWDnot`END`PLN before `END' + + '`KWDor`END`PLN before `END`PUN==`END`PLN `END`STR"<"`END' + + '`PLN `END`KWDthen`END`PLN `END`KWDreturn`END`PLN ssup`END`PUN(`END' + + '`PLNt`END`PUN,`END`PLN n`END`PUN)`END`PLN\n' + + ' `END`KWDelseif`END`PLN before `END`PUN==`END`PLN `END' + + '`STR">"`END`PLN `END`KWDthen`END`PLN `END`KWDreturn`END' + + '`PLN ssdown`END`PUN(`END`PLNt`END`PUN,`END`PLN n`END`PUN)`END' + + '`PLN\n' + + ' `END`KWDelse`END`PLN `END`KWDreturn`END' + + '`PLN ssgeneral`END`PUN(`END`PLNt`END`PUN,`END`PLN n`END`PUN,`END' + + '`PLN before`END`PUN)`END`PLN\n' + + ' `END`KWDend`END`PLN\n' + + ' `END`KWDend`END`PLN\n' + + ' `END`KWDreturn`END`PLN shellsort\n' + + '`END`KWDend`END' + ), + vbs: ( + '`KWDImports`END`PLN System\n' + + '\n' + + '`END`KWDClass`END`PLN [class]\n' + + ' `END`KWDShared`END`PLN `END`KWDSub`END`PLN [shared]`END' + + '`PUN(`END`KWDByVal`END`PLN [boolean] `END`KWDAs`END`PLN `END' + + '`KWDBoolean`END`PUN)`END`PLN\n' + + ' `END`KWDIf`END`PLN [boolean] `END' + + '`KWDThen`END`PLN\n' + + ' Console`END`PUN.`END' + + '`PLNWriteLine`END`PUN(`END`STR"true"`END`PUN)`END`PLN\n' + + ' `END`KWDElse`END`PLN\n' + + ' Console`END`PUN.`END' + + '`PLNWriteLine`END`PUN(`END`STR"false"`END`PUN)`END`PLN\n' + + ' `END`KWDEnd`END`PLN `END`KWDIf`END' + + '`PLN\n' + + ' `END`KWDEnd`END`PLN `END`KWDSub`END`PLN\n' + + '`END`KWDEnd`END`PLN `END`KWDClass`END`PLN\n' + + '\n' + + '`END`COM\' Comment`END`PLN\n' + + '`END`COM\u2018 Second Line comment with a smart quote _\n' + + ' continued line using VB6 syntax.`END`PLN\n' + + '`END`KWDModule`END`PLN [module]\n' + + ' `END`KWDSub`END`PLN Main`END`PUN()`END`PLN\n' + + ' [class]`END`PUN.`END`PLN[shared]`END' + + '`PUN(`END`LITTrue`END`PUN)`END`PLN\n' + + '\n' + + ' `END`COM\' This prints out: \".`END' + + '`PLN\n' + + ' Console`END`PUN.`END`PLNWriteLine`END' + + '`PUN(`END`STR""""`END`PUN)`END`PLN\n' + + '\n' + + ' `END`COM\' This prints out: a"b.`END' + + '`PLN\n' + + ' Console`END`PUN.`END`PLNWriteLine`END' + + '`PUN(`END`STR"a""b"`END`PUN)`END`PLN\n' + + '\n' + + ' `END`COM\' This prints out: a.`END' + + '`PLN\n' + + ' Console`END`PUN.`END`PLNWriteLine`END' + + '`PUN(`END`STR"a"c`END`PUN)`END`PLN\n' + + '\n' + + ' `END`COM\' This prints out: ".`END' + + '`PLN\n' + + ' Console`END`PUN.`END`PLNWriteLine`END' + + '`PUN(`END`STR""""c`END`PUN)`END`PLN\n' + + '\n' + + ' `END`COMREM an old-style comment`END`PLN\n' + + ' REMOVE`END`PUN(`END`PLNnot_a_comment`END`PUN)`END`PLN\n' + + ' `END`KWDEnd`END`PLN `END`KWDSub`END`PLN\n' + + '`END`KWDEnd`END`PLN `END`KWDModule`END`PLN\n' + + '\n' + + '`END`KWDDim`END`PLN d `END`KWDAs`END`PLN `END`KWDDate`END`PLN\n' + + 'd `END`PUN=`END`PLN `END`LIT# 8/23/1970 3:45:39AM #`END`PLN\n' + + 'd `END`PUN=`END`PLN `END`LIT# 8/23/1970 #`END`PLN\n' + + 'd `END`PUN=`END`PLN `END`LIT# 3:45:39AM #`END`PLN\n' + + 'd `END`PUN=`END`PLN `END`LIT# 3:45:39 #`END`PLN\n' + + 'd `END`PUN=`END`PLN `END`LIT# 13:45:39 #`END`PLN\n' + + 'd `END`PUN=`END`PLN `END`LIT# 13:45:39PM #`END`PLN\n' + + '\n' + + '`END`KWDDim`END`PLN n `END`KWDAs`END`PLN Float\n' + + 'n `END`PUN=`END`PLN `END`PUN(`END`LIT0.0`END`PUN,`END`PLN `END' + + '`LIT.99F`END`PUN,`END`PLN `END`LIT1.0E-2D`END`PUN,`END`PLN `END' + + '`LIT1.0E+3D`END`PUN,`END`PLN `END`LIT.5E4`END`PUN,`END`PLN `END' + + '`LIT1E3R`END`PUN,`END`PLN `END`LIT4D`END`PUN)`END`PLN\n' + + '\n' + + '`END`KWDDim`END`PLN i `END`KWDAs`END`PLN `END`KWDInteger`END`PLN\n' + + 'i `END`PUN=`END`PLN `END`PUN(`END`LIT0`END`PUN,`END`PLN `END' + + '`LIT123`END`PUN,`END`PLN `END`LIT45L`END`PUN,`END`PLN `END' + + '`LIT&HA0I`END`PUN,`END`PLN `END`LIT&O177S`END`PUN)`END' + ), + haskell: ( + '`COM-- A comment`END`PLN\n' + + 'Not`END`PUN(--`END`STR"a comment"`END`PUN)`END`PLN\n' + + 'Also.not`END`PUN(--(`END`PLNA.comment`END`PUN))`END`PLN\n' + + '\n' + + '`END`KWDmodule`END`PLN Foo`END`PUN(`END`PLNbar`END`PUN)`END`PLN `END' + + '`KWDwhere`END`PLN\n' + + '`END`KWDimport`END`PLN Blah\n' + + '`END`KWDimport`END`PLN BlahBlah`END`PUN(`END`PLNblah`END`PUN)`END' + + '`PLN\n' + + '`END`KWDimport`END`PLN Monads`END`PUN(`END`PLNException`END' + + '`PUN(..),`END`PLN FIO`END`PUN(..),`END`PLNunFIO`END`PUN,`END' + + '`PLNhandle`END`PUN,`END`PLNrunFIO`END`PUN,`END`PLNfixFIO`END' + + '`PUN,`END`PLNfio`END`PUN,`END`PLN\n' + + ' write`END`PUN,`END' + + '`PLNwriteln`END`PUN,`END`PLNHasNext`END`PUN(..),`END' + + '`PLNHasOutput`END`PUN(..))`END`PLN\n' + + '\n' + + '`END`COM{- nested comments\n' + + ' - don\'t work {-yet-}`END`PLN `END`PUN-}`END`PLN\n' + + '`END`KWDinstance`END`PLN Thingy Foo `END`KWDwhere`END`PLN\n' + + ' a `END`PUN=`END`PLN b\n' + + '\n' + + '`END`KWDdata`END`PLN Foo `END`PUN::`END`PLN `END`PUN(*`END`PLN `END' + + '`PUN->`END`PLN `END`PUN*`END`PLN `END`PUN->`END`PLN `END' + + '`PUN*)`END`PLN `END`PUN->`END`PLN `END`PUN*`END`PLN `END' + + '`PUN>`END`PLN `END`PUN*`END`PLN `END`PUN->`END`PLN `END' + + '`PUN*`END`PLN `END`KWDwhere`END`PLN\n' + + ' Nil `END`PUN::`END`PLN Foo a b c\n' + + ' Cons `END`PUN::`END`PLN a b c `END`PUN->`END' + + '`PLN Foo abc `END`PUN->`END`PLN Foo a b c\n' + + '\n' + + 'str `END`PUN=`END`PLN `END`STR"Foo\\\\Bar"`END`PLN\n' + + 'char `END`PUN=`END`PLN `END`STR\'x\'`END`PLN\n' + + 'Not.A.Char `END`PUN=`END`PLN `END`STR\'t`END`PLNoo long\' `END' + + '`COM-- Don\'t barf. Show that \'t is a lexical error.`END' + + '`PLN\n' + + '\n' + + '`END`PUN(`END`PLNident`END`PUN,`END`PLN ident\'`END`PUN,`END' + + '`PLN Fo\'\'o.b\'ar`END`PUN)`END`PLN\n' + + '\n' + + '`END`PUN(`END`LIT0`END`PUN,`END`PLN `END`LIT12`END`PUN,`END`PLN `END' + + '`LIT0x45`END`PUN,`END`PLN `END`LIT0xA7`END`PUN,`END`PLN `END' + + '`LIT0o177`END`PUN,`END`PLN `END`LIT0O377`END`PUN,`END`PLN `END' + + '`LIT0.1`END`PUN,`END`PLN `END`LIT1.0`END`PUN,`END`PLN `END' + + '`LIT1e3`END`PUN,`END`PLN `END`LIT0.5E-3`END`PUN,`END`PLN `END' + + '`LIT1.0E+45`END`PUN)`END' + ), + ml: ( + '`COM(*\n' + + ' * Print the 10th fibonacci number\n' + + ' *)`END`PLN\n' + + '\n' + + '`END`COM//// A line comment`END`PLN\n' + + '`END`STR"A string"`END`PUN;;`END`PLN\n' + + '`END`PUN(`END`LIT0`END`PUN,`END`PLN `END`LIT125`END`PUN,`END' + + '`PLN `END`LIT0xa0`END`PUN,`END`PLN `END`LIT-1.0`END`PUN,`END' + + '`PLN `END`LIT1e6`END`PUN,`END`PLN `END`LIT1.2e-3`END`PUN);;`END' + + '`PLN `END`COM// number literals`END`PLN\n' + + '\n' + + '`END`COM#if fibby`END`PLN\n' + + ' `END`KWDlet`END`PLN\n' + + ' `END`KWDrec`END`PLN fib `END`PUN=`END`PLN `END' + + '`KWDfunction`END`PLN `END`PUN(`END`LIT0`END`PUN,`END`PLN a`END' + + '`PUN,`END`PLN _`END`PUN)`END`PLN `END`PUN->`END`PLN a\n' + + ' ' + + ' `END`PUN|`END`PLN `END`PUN(`END`PLNn`END`PUN,`END`PLN a`END' + + '`PUN,`END`PLN b`END`PUN)`END`PLN `END`PUN->`END`PLN fib`END' + + '`PUN(`END`PLNn `END`PUN-`END`PLN `END`LIT1`END`PUN,`END' + + '`PLN a `END`PUN+`END`PLN b`END`PUN,`END`PLN a`END`PUN)`END' + + '`PLN\n' + + ' `END`KWDin`END`PLN\n' + + ' print_int`END`PUN(`END`PLNfib`END`PUN(`END`LIT10`END' + + '`PUN,`END`PLN `END`LIT1`END`PUN,`END`PLN `END`LIT1`END' + + '`PUN));;`END`PLN\n' + + '`END`COM#endif`END`PLN\n' + + '\n' + + '`END`KWDlet`END`PLN zed `END`PUN=`END`PLN `END`STR\'z\'`END`PLN\n' + + '\n' + + '`END`KWDlet`END`PLN f\' x\' `END`PUN=`END`PLN x\' `END`PUN+`END`PLN `END`LIT1`END' + ), + lisp: ( + '`COM; -*- mode: lisp -*-`END`PLN\n' + + '\n' + + '`END`OPN(`END`KWDdefun`END`PLN back-six-lines `END`OPN(`END`CLO)`END' + + '`PLN `END`OPN(`END`PLNinteractive`END`CLO)`END`PLN `END`OPN(`END' + + '`PLNforward-line `END`LIT-6`END`CLO))`END`PLN\n' + + '`END`OPN(`END`KWDdefun`END`PLN forward-six-lines `END`OPN(`END' + + '`CLO)`END`PLN `END`OPN(`END`PLNinteractive`END`CLO)`END`PLN `END' + + '`OPN(`END`PLNforward-line `END`LIT6`END`CLO))`END`PLN\n' + + '\n' + + '`END`OPN(`END`PLNglobal-set-key `END`STR"\\M-l"`END`PLN `END' + + '`LIT\'goto-line`END`CLO)`END`PLN\n' + + '`END`OPN(`END`PLNglobal-set-key `END`STR"\\C-z"`END`PLN `END' + + '`LIT\'advertised-undo`END`CLO)`END`PLN\n' + + '`END`OPN(`END`PLNglobal-set-key `END`PUN[`END`PLNC-insert`END' + + '`PUN]`END`PLN `END`LIT\'clipboard-kill-ring-save`END`CLO)`END' + + '`PLN\n' + + '`END`OPN(`END`PLNglobal-set-key `END`PUN[`END`PLNS-insert`END`PUN]`END' + + '`PLN `END`LIT\'clipboard-yank`END`CLO)`END`PLN\n' + + '`END`OPN(`END`PLNglobal-set-key `END`PUN[`END`PLNC-up`END`PUN]`END' + + '`PLN `END`LIT\'back-six-lines`END`CLO)`END`PLN\n' + + '`END`OPN(`END`PLNglobal-set-key `END`PUN[`END`PLNC-down`END`PUN]`END' + + '`PLN `END`LIT\'forward-six-lines`END`CLO)`END`PLN\n' + + '\n' + + '`END`OPN(`END`KWDsetq`END`PLN visible-bell `END`KWDt`END`CLO)`END' + + '`PLN\n' + + '`END`OPN(`END`KWDsetq`END`PLN user-mail-address `END' + + '`STR"foo@bar.com"`END`CLO)`END`PLN\n' + + '`END`OPN(`END`KWDsetq`END`PLN default-major-mode `END' + + '`LIT\'text-mode`END`CLO)`END`PLN\n' + + '\n' + + '`END`OPN(`END`PLNsetenv `END`STR"TERM"`END`PLN `END' + + '`STR"emacs"`END`CLO)`END`PLN\n' + + '`END`OPN(`END`PLNc-set-offset `END`LIT\'case-label`END`PLN `END' + + '`LIT2`END`CLO)`END`PLN\n' + + '`END`OPN(`END`KWDsetq`END`PLN c-basic-offset `END`LIT2`END`CLO)`END' + + '`PLN\n' + + '`END`OPN(`END`KWDsetq`END`PLN perl-indent-level `END`LIT0x2`END`CLO)`END' + + '`PLN\n' + + '`END`OPN(`END`KWDsetq`END`PLN delete-key-deletes-forward `END`KWDt`END' + + '`CLO)`END`PLN\n' + + '`END`OPN(`END`KWDsetq`END`PLN indent-tabs-mode `END`KWDnil`END' + + '`CLO)`END`PLN\n' + + '\n' + + '`END`COM;; Text mode`END`PLN\n' + + '`END`OPN(`END`PLNadd-hook `END`LIT\'text-mode-hook`END`PLN \n' + + ' `END`LIT\'`END`OPN(`END`KWDlambda`END`PLN `END`OPN(`END' + + '`CLO)`END`PLN\n' + + ' `END`OPN(`END`PLNturn-on-auto-fill`END`CLO)`END' + + '`PLN\n' + + ' `END`CLO)`END`PLN\n' + + '`END`CLO)`END`PLN\n' + + '\n' + + '`END`COM;; Fundamental mode`END`PLN\n' + + '`END`OPN(`END`PLNadd-hook `END`LIT\'fundamental-mode-hook`END' + + '`PLN \n' + + ' `END`LIT\'`END`OPN(`END`KWDlambda`END`PLN `END`OPN(`END' + + '`CLO)`END`PLN\n' + + ' `END`OPN(`END`PLNturn-on-auto-fill`END' + + '`CLO)`END`PLN\n' + + ' `END`CLO)`END`PLN\n' + + '`END`CLO)`END`PLN\n' + + '\n' + + '`END`COM;; Define and cond are keywords in scheme`END`PLN\n' + + '`END`OPN(`END`KWDdefine`END`PLN `END`OPN(`END`PLNsqt x`END`CLO)`END' + + '`PLN `END`OPN(`END`PLNsqrt-iter `END`LIT1.0`END`PLN `END' + + '`LIT2.0`END`PLN x`END`CLO))`END' + ), + issue45: ( + '`KWDthrow`END`PLN `END`KWDnew`END`PLN `END`TYPRuntimeException`END' + + '`PUN(`END`STR"Element ["`END`PLN `END`PUN+`END`PLN element`END' + + '`PUN.`END`PLNgetName`END`PUN()`END`PLN `END`PUN+`END`PLN \n' + + ' `END`STR"] missing attribute."`END`PUN);`END`PLN\n' + + 'variable`END`PUN++;`END' + ), + proto: ( + '`KWDmessage`END`PLN `END`TYPSearchRequest`END`PLN `END`PUN{`END' + + '`PLN\n' + + ' `END`KWDrequired`END`PLN `END`TYPstring`END`PLN query `END' + + '`PUN=`END`PLN `END`LIT1`END`PUN;`END`PLN\n' + + ' `END`KWDoptional`END`PLN `END`TYPint32`END`PLN page_number `END' + + '`PUN=`END`PLN `END`LIT2`END`PUN;`END`PLN\n' + + ' `END`KWDoptional`END`PLN `END`TYPint32`END' + + '`PLN result_per_page `END`PUN=`END`PLN `END`LIT3`END`PLN `END' + + '`PUN[`END`KWDdefault`END`PLN `END`PUN=`END`PLN `END`LIT10`END' + + '`PUN];`END`PLN\n' + + ' `END`KWDenum`END`PLN `END`TYPCorpus`END`PLN `END`PUN{`END' + + '`PLN\n' + + ' UNIVERSAL `END`PUN=`END`PLN `END`LIT0`END`PUN;`END' + + '`PLN\n' + + ' WEB `END`PUN=`END`PLN `END`LIT1`END`PUN;`END`PLN\n' + + ' IMAGES `END`PUN=`END`PLN `END`LIT2`END`PUN;`END`PLN\n' + + ' LOCAL `END`PUN=`END`PLN `END`LIT3`END`PUN;`END`PLN\n' + + ' NEWS `END`PUN=`END`PLN `END`LIT4`END`PUN;`END`PLN\n' + + ' PRODUCTS `END`PUN=`END`PLN `END`LIT5`END`PUN;`END' + + '`PLN\n' + + ' VIDEO `END`PUN=`END`PLN `END`LIT6`END`PUN;`END`PLN\n' + + ' `END`PUN}`END`PLN\n' + + ' `END`KWDoptional`END`PLN `END`TYPCorpus`END`PLN corpus `END' + + '`PUN=`END`PLN `END`LIT4`END`PLN `END`PUN[`END`KWDdefault`END' + + '`PLN `END`PUN=`END`PLN UNIVERSAL`END`PUN];`END`PLN\n' + + '`END`PUN}`END' + ), + wiki: ( + '`KWD#summary`END`PLN hello world\n' + + '`END`KWD#labels`END`PLN `END`LITHelloWorld`END`PLN `END' + + '`LITWikiWord`END`PLN Hiya\n' + + '\n' + + '`END`PUN[`END' + + '`STRhttp://www.google.com/?q=WikiSyntax+site:code.google.com`END' + + '`PLN `END`LITWikiSyntax`END`PUN]`END`PLN\n' + + '\n' + + 'Lorem Ipsum ``END`KWDwhile`END`PLN `END`PUN(`END`LIT1`END' + + '`PUN)`END`PLN `END`KWDprint`END`PUN(`END`STR"blah blah"`END' + + '`PUN);`END`PLN`\n' + + '\n' + + ' `END`PUN*`END`PLN Bullet\n' + + ' `END`PUN*`END`PLN Points\n' + + ' `END`PUN*`END`PLN `END`LITNestedBullet`END' + + '`PLN\n' + + '\n' + + '`END`PUN==`END`LITDroningOnAndOn`END`PUN==`END`PLN\n' + + '{{{\n' + + ' `END`COM// Some EmbeddedSourceCode`END`PLN\n' + + ' `END`KWDvoid`END`PLN main`END`PUN()`END`PLN `END`PUN{`END' + + '`PLN\n' + + ' `END`TYPPrint`END`PUN(`END`STR\'hello world\'`END' + + '`PUN);`END`PLN\n' + + ' `END`PUN}`END`PLN\n' + + '}}}\n' + + '\n' + + '{{{\n' + + ' `END`COM<!-- Embedded XML -->`END`PLN\n' + + ' `END`TAG<foo`END`PLN `END`ATNbar`END`PUN=`END' + + '`ATV"baz"`END`TAG><boo`END`PLN `END' + + '`TAG/><foo>`END`PLN\n' + + '}}}`END' + ), + css: ( + '`COM<!--`END`PLN\n' + + '`END`KWD@charset`END`PUN(`END`STR\'UTF-8\'`END`PUN);`END`PLN\n' + + '\n' + + '`END`COM/** A url that is not quoted. *\/`END`PLN\n' + + '`END`KWD@import`END`PUN(`END`KWDurl`END`PUN(`END`STR/more-styles.css`END' + + '`PUN));`END`PLN\n' + + '\n' + + 'HTML `END`PUN{`END`PLN `END`KWDcontent-before`END`PUN:`END`PLN `END' + + '`STR\'hello\\20\'`END`PUN;`END`PLN `END`KWDcontent-after`END' + + '`PUN:`END`PLN `END`STR\'w\\6f rld\'`END`PUN;`END`PLN\n' + + ' `END`KWD-moz-spiff`END`PUN:`END`PLN `END' + + '`KWDinherit`END`PLN `END`KWD!important`END`PLN `END`PUN}`END' + + '`PLN\n' + + '\n' + + '`END`COM/* Test units on numbers. *\/`END`PLN\n' + + 'BODY `END`PUN{`END`PLN `END`KWDmargin-bottom`END`PUN:`END`PLN `END' + + '`LIT4px`END`PUN;`END`PLN `END`KWDmargin-left`END`PUN:`END' + + '`PLN `END`LIT3in`END`PUN;`END`PLN `END`KWDmargin-bottom`END' + + '`PUN:`END`PLN `END`LIT0`END`PUN;`END`PLN `END`KWDmargin-top`END' + + '`PUN:`END`PLN `END`LIT5%`END`PLN `END`PUN}`END`PLN\n' + + '\n' + + '`END`COM/** Test number literals and quoted values. *\/`END`PLN\n' + + 'TABLE`END`PUN.`END`PLNfoo TR`END`PUN.`END`PLNbar A`END`PUN#`END' + + '`PLNvisited `END`PUN{`END`PLN `END`KWDcolor`END`PUN:`END`PLN `END' + + '`LIT#001123`END`PUN;`END`PLN `END`KWDfont-family`END`PUN:`END' + + '`PLN `END`STR"monospace"`END`PLN `END`PUN}`END`PLN\n' + + '`END`COM/** bolder is not a name, so should be plain. ' + + ' !IMPORTANT is a keyword\n' + + ' * regardless of case.\n' + + ' *\/`END`PLN\n' + + 'blink `END`PUN{`END`PLN `END`KWDtext-decoration`END`PUN:`END' + + '`PLN BLINK `END`KWD!IMPORTANT`END`PUN;`END`PLN `END' + + '`KWDfont-weight`END`PUN:`END`PLN bolder `END`PUN}`END`PLN\n' + + '`END`COM/* Empty url() was causing infinite recursion */`END`PLN\n' + + 'a `END`PUN{`END`PLN `END`KWDbackground-image`END`PUN:`END`PLN ' + + '`END`KWDurl`END`PUN();`END`PLN `END`PUN}`END`PLN\n' + + 'p`END`PUN#`END`PLNfeatured`END`PUN{`END`KWDbackground`END`PUN:`END`LIT#fea`END`PUN}`END`PLN\n' + + '`END`COM-->`END' + ), + css_style: ( + '`TAG<style`END`PLN `END`ATNtype`END`PUN=`END`ATV\'text/css\'`END' + + '`TAG>`END`PLN\n' + + '`END`COM/* desert scheme ported from vim to google prettify */`END' + + '`PLN\n' + + 'code`END`PUN.`END`PLNprettyprint `END`PUN{`END`PLN `END' + + '`KWDdisplay`END`PUN:`END`PLN block`END`PUN;`END`PLN `END' + + '`KWDpadding`END`PUN:`END`PLN `END`LIT2px`END`PUN;`END`PLN `END' + + '`KWDborder`END`PUN:`END`PLN `END`LIT1px`END`PLN solid `END' + + '`LIT#888`END`PUN;`END`PLN\n' + + '`END`KWDbackground-color`END`PUN:`END`PLN `END`LIT#333`END`PUN;`END' + + '`PLN `END`PUN}`END`PLN\n' + + '`END`PUN.`END`PLNstr `END`PUN{`END`PLN `END`KWDcolor`END`PUN:`END' + + '`PLN `END`LIT#ffa0a0`END`PUN;`END`PLN `END`PUN}`END`PLN `END' + + '`COM/* string - pink */`END`PLN\n' + + '`END`PUN.`END`PLNkwd `END`PUN{`END`PLN `END`KWDcolor`END`PUN:`END' + + '`PLN `END`LIT#f0e68c`END`PUN;`END`PLN `END`KWDfont-weight`END' + + '`PUN:`END`PLN bold`END`PUN;`END`PLN `END`PUN}`END`PLN\n' + + '`END`PUN.`END`PLNcom `END`PUN{`END`PLN `END`KWDcolor`END`PUN:`END' + + '`PLN `END`LIT#87ceeb`END`PUN;`END`PLN `END`PUN}`END`PLN `END' + + '`COM/* comment - skyblue */`END`PLN\n' + + '`END`PUN.`END`PLNtyp `END`PUN{`END`PLN `END`KWDcolor`END`PUN:`END' + + '`PLN `END`LIT#98fb98`END`PUN;`END`PLN `END`PUN}`END`PLN `END' + + '`COM/* type - lightgreen */`END`PLN\n' + + '`END`PUN.`END`PLNlit `END`PUN{`END`PLN `END`KWDcolor`END`PUN:`END' + + '`PLN `END`LIT#cd5c5c`END`PUN;`END`PLN `END`PUN}`END`PLN `END' + + '`COM/* literal - darkred */`END`PLN\n' + + '`END`PUN.`END`PLNpun `END`PUN{`END`PLN `END`KWDcolor`END`PUN:`END' + + '`PLN `END`LIT#fff`END`PUN;`END`PLN `END`PUN}`END`PLN `END' + + '`COM/* punctuation */`END`PLN\n' + + '`END`PUN.`END`PLNpln `END`PUN{`END`PLN `END`KWDcolor`END`PUN:`END' + + '`PLN `END`LIT#fff`END`PUN;`END`PLN `END`PUN}`END`PLN `END' + + '`COM/* plaintext */`END`PLN\n' + + '`END`PUN.`END`PLNtag `END`PUN{`END`PLN `END`KWDcolor`END`PUN:`END' + + '`PLN `END`LIT#f0e68c`END`PUN;`END`PLN `END`KWDfont-weight`END' + + '`PUN:`END`PLN bold`END`PUN;`END`PLN `END`PUN}`END`PLN `END' + + '`COM/* html/xml tag - lightyellow*/`END`PLN\n' + + '`END`PUN.`END`PLNatn `END`PUN{`END`PLN `END`KWDcolor`END`PUN:`END' + + '`PLN `END`LIT#bdb76b`END`PUN;`END`PLN `END`KWDfont-weight`END' + + '`PUN:`END`PLN bold`END`PUN;`END`PLN `END`PUN}`END`PLN `END' + + '`COM/* attribute name - khaki*/`END`PLN\n' + + '`END`PUN.`END`PLNatv `END`PUN{`END`PLN `END`KWDcolor`END`PUN:`END' + + '`PLN `END`LIT#ffa0a0`END`PUN;`END`PLN `END`PUN}`END`PLN `END' + + '`COM/* attribute value - pink */`END`PLN\n' + + '`END`PUN.`END`PLNdec `END`PUN{`END`PLN `END`KWDcolor`END`PUN:`END' + + '`PLN `END`LIT#98fb98`END`PUN;`END`PLN `END`PUN}`END`PLN `END' + + '`COM/* decimal - lightgreen */`END`PLN\n' + + '`END`TAG</style>`END' + ), + issue84: '`KWDsuper`END`PUN(`END`STR"&nbsp;"`END`PUN);`END', + issue86_0: '`COM#One Two words`END', + issue86_1: ( + '`COM#One`END`PLN\n' + + '`END`TYPTwo`END`PLN lines`END' + ), + issue86_2: ( + '`COM#One`END`PLN\n' + + '`END`TYPTwo`END`PLN lines`END' + ), + issue86_3: ( + '`COM#One`END`PLN\n' + + '`END`TYPTwo`END`PLN lines`END' + ), + issue86_4: ( + '`COM#One`END`PLN\n' + + '`END`TYPTwo`END`PLN lines`END' + ), + issue86_5: ( + '`COM#One`END
    `PLN ' + + '`END`TYPTwo`END`PLN lines`END' + ), + issue92: ( + '`PUN<?`END`PLNxml version`END`PUN=`END`STR"1.0"`END`PLN encoding`END`PUN=`END' + + '`STR"UTF-8"`END`PUN?>`END`PLN\n' + + '`END`TAG<kml`END`PLN `END`ATNxmlns`END`PUN=`END`ATV"http://www.opengis.net/kml/2.2"`END' + + '`TAG>`END`PLN\n' + + ' `END`TAG<Placemark>`END`PLN\n' + + ' `END`TAG<name>`END`PLNSimple placemark`END`TAG</name>`END`PLN\n' + + ' `END`TAG<description`END' + + '`PLN `END`ATNLang`END`PUN=`END`ATV"en"`END`TAG>`END' + + '`PLNAttached to the ground.' + + ' Intelligently places itself \n' + + ' at the height of the underlying terrain.`END' + + '`TAG</description>`END`PLN\n' + + ' `END`TAG<Point>`END`PLN\n' + + ' `END`TAG<coordinates>`END' + + '`PLN-122.0822035425683,37.42228990140251,0`END`TAG</coordinates>`END`PLN\n' + + ' `END`TAG</Point>`END`PLN\n' + + ' `END`TAG</Placemark>`END`PLN\n' + + '`END`TAG</kml>`END' + ), + cs_verbatim: ( + '`COM// The normal string syntax`END`PLN\n' + + '`END`KWDstring`END`PLN a `END`PUN=`END`PLN `END`STR"C:\\\\"`END`PUN;`END`PLN\n' + + '`END`COM// is equivalent to a verbatim string`END`PLN\n' + + '`END`KWDstring`END`PLN b `END`PUN=`END`PLN `END`STR@"C:\\"`END`PUN;`END' + ), + vhdl: ( + '`KWDlibrary`END`PLN ieee`END`PUN;`END`PLN\n' + + '`END`KWDuse`END`PLN ieee`END`PUN.`END`PLNstd_logic_1164`END`PUN.`END`KWDall`END`PUN;`END`PLN\n' + + '`END`KWDuse`END`PLN ieee`END`PUN.`END`PLNnumeric_std`END`PUN.`END`KWDall`END`PUN;`END`PLN\n' + + '\n' + + '`END`COM-- A line comment`END`PLN\n' + + '`END`KWDentity`END`PLN foo_entity `END`KWDis`END`PLN\n' + + '\n' + + ' `END`KWDgeneric`END`PLN `END`PUN(`END`COM-- comment after punc`END`PLN\n' + + ' a `END`PUN:`END`PLN `END`TYPnatural`END`PLN `END`PUN:=`END' + + '`PLN `END`LIT42`END`PUN;`END`PLN\n' + + ' x `END`PUN:`END`PLN `END`TYPreal`END`PLN `END' + + '`PUN:=`END`PLN `END`LIT16#ab.cd#-3`END`PLN\n' + + ' `END`PUN);`END`PLN\n' + + ' `END`KWDport`END`PLN `END`PUN(`END`PLN\n' + + ' clk_i `END`PUN:`END`PLN `END`KWDin`END`PLN `END`TYPstd_logic`END`PUN;`END`PLN\n' + + ' b_i `END`PUN:`END`PLN `END`KWDin`END`PLN `END`TYPnatural`END`PLN `END`KWDrange`END`PLN `END`LIT0`END`PLN `END`KWDto`END`PLN `END`LIT100`END`PUN;`END`PLN\n' + + ' c_o `END`PUN:`END`PLN `END`KWDout`END`PLN `END`TYPstd_logic_vector`END`PUN(`END`LIT5`END`PLN `END`KWDdownto`END`PLN `END`LIT0`END`PUN);`END`PLN\n' + + ' \\a "name"\\ `END`PUN:`END`PLN `END`KWDout`END`PLN `END`TYPinteger`END`PLN `END`COM-- extended identifier`END`PLN\n' + + ' `END`PUN);`END`PLN\n' + + '\n' + + '`END`KWDend`END`PLN `END`KWDentity`END`PLN foo_entity`END`PUN;`END`PLN\n' + + '\n' + + '`END`KWDarchitecture`END`PLN foo_architecture `END`KWDof`END`PLN foo_entity `END`KWDis`END`PLN\n' + + ' `END`KWDsignal`END`PLN bar_s `END`PUN:`END`PLN `END`TYPstd_logic_vector`END`PUN(`END`LIT2`END`PLN `END`KWDdownto`END`PLN `END`LIT0`END`PUN);`END`PLN\n' + + '`END`KWDbegin`END`PLN\n' + + ' \n' + + ' bar_s `END`PUN<=`END`PLN `END`STRb"101"`END`PUN;`END`PLN\n' + + '\n' + + ' dummy_p `END`PUN:`END`PLN `END`KWDprocess`END`PLN `END`PUN(`END`PLNclk_i`END`PUN)`END`PLN\n' + + ' `END`KWDbegin`END`PLN\n' + + ' `END`KWDif`END`PLN b_i `END`PUN=`END`PLN `END`LIT1`END`PLN `END`KWDthen`END`PLN\n' + + ' c_o `END`PUN<=`END`PLN `END`PUN(`END`KWDothers`END`PLN `END`PUN=>`END`PLN `END`STR\'0\'`END`PUN);`END`PLN\n' + + ' `END`KWDelsif`END`PLN rising_edge`END`PUN(`END`PLNclk_i`END`PUN)`END`PLN `END`KWDthen`END`PLN\n' + + ' c_o `END`PUN<=`END`PLN `END`STR"1011"`END`PLN `END`PUN&`END`PLN bar_s`END`PUN(`END`LIT1`END`PLN `END`KWDdownto`END`PLN `END`LIT0`END`PUN);`END`PLN\n' + + ' `END`KWDend`END`PLN `END`KWDif`END`PUN;`END`PLN\n' + + ' `END`KWDend`END`PLN `END`KWDprocess`END`PLN dummy_p`END`PUN;`END`PLN\n' + + '\n' + + '`END`KWDend`END`PLN `END`KWDarchitecture`END`PLN foo_architecture`END`PUN;`END' + ), + yaml1: ( + '`KWDapplication: `END`PLNmirah`END`PUN-`END`PLNlang\n' + + '`END`KWDversion: `END`PLN1\n' + + '\n' + + '`END`COM# Here\'s a comment`END`PLN\n' + + '`END`KWDhandlers:\n' + + '`END`PLN `END`PUN-`END`PLN `END`KWDurl: `END`PLN/red/*\n' + + ' `END`KWDservlet: `END`PLNmysite.server.TeamServlet\n' + + ' `END`KWDinit_params:\n' + + '`END`PLN `END`KWDteamColor: `END`PLNred\n' + + ' `END`KWDbgColor: `END`STR"#CC0000"`END`PLN\n' + + ' `END`KWDname: `END`PLNredteam\n' + + ' `END`PUN-`END`PLN `END`KWDurl: `END`PLN/blue/*\n' + + ' `END`KWDservlet: `END`PLNmysite.server.TeamServlet\n' + + ' `END`KWDinit_params:\n' + + '`END`PLN `END`KWDteamColor: `END`PLNblue\n' + + ' `END`KWDbgColor: `END`STR"#0000CC"`END`PLN\n' + + ' `END`KWDname: `END`PLNblueteam\n' + + ' `END`PUN-`END`PLN `END`KWDurl: `END`PLN/register/*\n' + + ' `END`KWDjsp: `END`PLN/register/start.jsp\n' + + ' `END`PUN-`END`PLN `END`KWDurl: `END`PLN*.special\n' + + ' `END`KWDfilter: `END`PLNmysite.server.LogFilterImpl\n' + + ' `END`KWDinit_params:\n' + + '`END`PLN `END`KWDlogType: `END`PLNspecial\n' + + ' `END' + ), + yaml2: ( + '`DEC%YAML 1.1`END`PLN\n' + + '`END`DEC---\n' + + '`END`TYP!!map`END`PLN {\n' + + ' `END`PUN?`END`PLN `END`TYP!!str`END`PLN `END`STR""`END`PLN\n' + + ' `END`PUN:`END`PLN `END`TYP!!str`END`PLN `END`STR"value"`END`PLN,\n' + + ' `END`PUN?`END`PLN `END`TYP!!str`END`PLN `END`STR"explicit key"`END`PLN\n' + + ' `END`PUN:`END`PLN `END`TYP!!str`END`PLN `END`STR"value"`END`PLN,\n' + + ' `END`PUN?`END`PLN `END`TYP!!str`END`PLN `END`STR"simple key"`END`PLN\n' + + ' `END`PUN:`END`PLN `END`TYP!!str`END`PLN `END`STR"value"`END`PLN,\n' + + ' `END`PUN?`END`PLN `END`TYP!!seq`END`PLN [\n' + + ' `END`TYP!!str`END`PLN `END`STR"collection"`END`PLN,\n' + + ' `END`TYP!!str`END`PLN `END`STR"simple"`END`PLN,\n' + + ' `END`TYP!!str`END`PLN `END`STR"key"`END`PLN\n' + + ' ]\n' + + ' `END`PUN:`END`PLN `END`TYP!!str`END`PLN `END`STR"value"`END`PLN\n' + + '}`END' + ), + scala: ( + '`COM/* comment 1 *\/`END`PLN\n' + + '`END`COM/*\n' + + 'comment 2\n' + + '*\/`END`PLN\n' + + '`END`COM/* comment / * comment 3 **\/`END`PLN\n' + + '`END`COM// strings`END`PLN\n' + + '`END`STR"Hello, World!"`END`PUN,`END`PLN `END`STR"\\n"`END`PUN,`END`PLN\n' + + '`END`LIT`an-identifier``END`PUN,`END`PLN `END`LIT`\\n``END`PUN,`END`PLN\n' + + '`END`STR\'A\'`END`PUN,`END`PLN `END`STR\'\\n\'`END`PUN,`END`PLN\n' + + '`END`LIT\'aSymbol`END`PUN,`END`PLN\n' + + '`END`STR"""Hello,\n' + + 'World"""`END`PUN,`END`PLN `END`STR"""Hello,\\nWorld"""`END`PUN,`END`PLN\n' + + '`END`STR"""Hello, "World"!"""`END`PUN,`END`PLN\n' + + '`END`STR"""Hello, \\"World\\""""`END`PLN\n' + + '\n' + + '`END`COM// Numbers`END`PLN\n' + + '`END`LIT0`END`PLN\n' + + '`END`LIT0123`END`PLN\n' + + '`END`LIT0xa0`END`PLN\n' + + '`END`LIT0XA0L`END`PLN\n' + + '`END`LIT123`END`PLN\n' + + '`END`LIT123.45`END`PLN\n' + + '`END`LIT1.50F`END`PLN\n' + + '`END`LIT0.50`END`PLN\n' + + '`END`PUN.`END`LIT50`END`PLN\n' + + '`END`LIT123e-1`END`PLN\n' + + '`END`LIT123.45e+1`END`PLN\n' + + '`END`LIT1.50e2`END`PLN\n' + + '`END`LIT0.50e-6`END`PLN\n' + + '`END`PUN.`END`LIT50e+42f`END`PLN\n' + + '\n' + + '`END`COM// Values`END`PLN\n' + + '`END`LITfalse`END`PUN,`END`PLN `END`LITtrue`END`PUN,`END`PLN `END`LITnull`END`PUN,`END`PLN `END`LITthis`END`PUN;`END`PLN\n' + + '\n' + + '`END`COM// Keywords`END`PLN\n' + + '`END`KWDclass`END`PLN `END`TYPMyClass`END`PUN;`END`PLN\n' + + '`END`KWDimport`END`PLN foo`END`PUN.`END`PLNbar`END`PUN;`END`PLN\n' + + '`END`KWDpackage`END`PLN baz`END`PUN;`END`PLN\n' + + '\n' + + '`END`COM// From scala-lang.org/node/242`END`PLN\n' + + '`END`KWDdef`END`PLN act`END`PUN()`END`PLN `END`PUN{`END`PLN\n' + + ' `END`KWDvar`END`PLN pongCount `END`PUN=`END`PLN `END`LIT0`END`PLN\n' + + ' loop `END`PUN{`END`PLN\n' + + ' react `END`PUN{`END`PLN\n' + + ' `END`KWDcase`END`PLN `END`TYPPing`END`PLN `END`PUN=>`END`PLN\n' + + ' `END`KWDif`END`PLN `END`PUN(`END`PLNpongCount `END`PUN%`END`PLN `END`LIT1000`END`PLN `END`PUN==`END`PLN `END`LIT0`END`PUN)`END`PLN\n' + + ' `END`TYPConsole`END`PUN.`END`PLNprintln`END`PUN(`END`STR"Pong: ping "`END`PUN+`END`PLNpongCount`END`PUN)`END`PLN\n' + + ' sender `END`PUN!`END`PLN `END`TYPPong`END`PLN\n' + + ' pongCount `END`PUN=`END`PLN pongCount `END`PUN+`END`PLN `END`LIT1`END`PLN\n' + + ' `END`KWDcase`END`PLN `END`TYPStop`END`PLN `END`PUN=>`END`PLN\n' + + ' `END`TYPConsole`END`PUN.`END`PLNprintln`END`PUN(`END`STR"Pong: stop"`END`PUN)`END`PLN\n' + + ' exit`END`PUN()`END`PLN\n' + + ' `END`PUN}`END`PLN\n' + + ' `END`PUN}`END`PLN\n' + + '`END`PUN}`END' + ), + go: ( + '`PLNpackage main `END`COM/* Package of which this program is part. *\/`END`PLN\n' + + '\n' + + 'import fmt "fmt" `END`COM// Package implementing formatted I/O.`END`PLN\n' + + '\n' + + '\n' + + 'func main() {\n' + + ' fmt.Printf("Hello, world; or \u039a\u03b1\u03bb\u03b7\u03bc\u03ad\u03c1\u03b1 \u03ba\u03cc\u03c3\u03bc\u03b5; or \u3053\u3093\u306b\u3061\u306f \u4e16\u754c\\n") `END`COM// Semicolon inserted here`END`PLN\n' + + '}\n' + + '\n' + + '`END`COM/* " *\/`END`PLN "foo /* " `END`COM/*\/ *\/`END`PLN\n' + + '`END`COM/* ` *\/`END`PLN `foo /* ` `END`COM/*\/ *\/`END' + ), + erlang: ( + '`COM% Sample comment`END`PLN\n' + + '\n' + + '`END`KWD-module`END`PLN(my_test)`END`PUN.`END`PLN\n' + + '`END`KWD-include_lib`END`PLN(`END`STR"my_sample_lib.hrl"`END`PLN)`END`PUN.`END`PLN\n' + + '`END`KWD-export`END`PLN([\n' + + ' test/`END`LIT2`END`PLN\n' + + '])`END`PUN.`END`PLN\n' + + '\n' + + '`END`COM%% @doc Define a macro`END`PLN\n' + + '`END`KWD-define`END`PLN(my_macro`END`PUN,`END`PLN `END`TYPVariable`END`PLN)`END`PUN.`END`PLN\n' + + '\n' + + '`END`COM%% @doc My function`END`PLN\n' + + 'test(`END`TYPVariables`END`PUN,`END`PLN `END`TYPMoreVariables`END`PLN) ->\n' + + ' `END`COM% Inline comment`END`PLN\n' + + ' {ok`END`PUN,`END`TYPScanned`END`PUN,`END`TYP_`END`PLN} = my_lib:do_stuff()`END`PUN,`END`PLN\n' + + '\n' + + ' `END`TYPVariable`END`PLN = `END`KWDfun`END`PLN(`END`TYPV`END`PLN) -> {ok`END`PUN,`END`PLN `END`TYPV`END`PLN} `END`KWDend`END`PUN,`END`PLN\n' + + '\n' + + ' `END`KWDtry`END`PLN `END`LIT?my_macro`END`PLN({value`END`PUN,`END`PLN test}) `END`KWDof`END`PLN\n' + + ' {value`END`PUN,`END`PLN `END`TYPResult`END`PUN,`END`PLN `END`TYP_`END`PLN} ->\n' + + ' {ok`END`PUN,`END`PLN `END`TYPResult`END`PLN}\n' + + ' `END`KWDcatch`END`PLN\n' + + ' `END`TYPType`END`PLN:`END`TYPError`END`PLN ->\n' + + ' {`END`LIT\'error\'`END`PUN,`END`PLN `END`TYPType`END`PUN,`END`PLN `END`TYPError`END`PLN}\n' + + ' `END`KWDend`END`PUN.`END' + ), + rust: ( + '`COM// Single line comment`END`PLN\n' + + '`END`COM/* Multi-line (nesting not highlighted properly, sorry)\n' + + 'comment */`END`PLN\n' + + '\n' + + '`END`ATV#![feature(code_prettification)]`END`PLN\n' + + '\n' + + '`END`KWDuse`END`PLN std`END`PUN::`END`PLNio`END`PUN::{`END`LITself`END`PUN,`END`PLN Write`END`PUN};`END`PLN\n' + + '\n' + + '`END`KWDimpl`END`PUN<`END`TAG\'a`END`PUN,`END`PLN T`END`PUN:`END`PLN `END`TAG\'a`END`PLN `END`PUN+`END`PLN `END`PUN?`END`TYPSized`END`PUN>`END`PLN Foo`END`PUN<`END`TAG\'a`END`PUN,`END`PLN `END`TAG\'static`END`PUN>`END`PLN `END`KWDfor`END`PLN Bar`END`PUN<`END`TAG\'b`END`PUN>`END`PLN\n' + + '`END`KWDwhere`END`PLN T`END`PUN:`END`PLN `END`TYPIterator`END`PUN<`END`PLNItem `END`PUN=`END`PLN `END`TYPBox`END`PUN<`END`TYPFn`END`PUN()`END`PLN `END`PUN->`END`PLN `END`TYPu32`END`PUN>>`END`PLN `END`PUN{`END`PLN\n' + + ' `END`KWDfn`END`PLN something`END`PUN(&`END`KWDmut`END`PLN `END`LITself`END`PUN)`END`PLN `END`PUN->`END`PLN `END`TYPu32`END`PLN `END`PUN{`END`PLN\n' + + ' `END`KWDif`END`PLN `END`KWDlet`END`PLN `END`TYPSome`END`PUN(`END`KWDref`END`PLN x`END`PUN)`END`PLN `END`PUN=`END`PLN `END`LITself`END`PUN.`END`PLNfoo`END`PUN(`END`STR"multi li\\ne\n' + + 's\\tring"`END`PUN)`END`PLN `END`PUN{`END`PLN\n' + + ' `END`ATNpanic!`END`PUN(`END`STRr"\\things is going wrong!"`END`PUN);`END`PLN\n' + + ' `END`ATNpanic!`END`PUN(`END`STRr#"Things is "really" goig\\n wront!"#`END`PUN);`END`PLN\n' + + ' `END`ATNpanic!`END`PUN(`END`STRr##"Raw strings are #"#fancy#"#"##`END`PUN);`END`PLN\n' + + ' `END`PUN}`END`PLN\n' + + ' `END`PUN}`END`PLN\n' + + '`END`PUN}`END`PLN\n' + + '\n' + + '`END`KWDpub`END`PLN `END`KWDtype`END`PLN CowString`END`PUN<`END`TAG\'a`END`PUN>`END`PLN `END`PUN=`END`PLN std`END`PUN::`END`PLNcow`END`PUN::`END`PLNCow`END`PUN<`END`TAG\'a`END`PUN,`END`PLN `END`TYPstr`END`PUN>;`END`PLN\n' + + '\n' + + '`END`KWDfn`END`PLN main`END`PUN()`END`PLN `END`PUN{`END`PLN\n' + + ' `END`KWDlet`END`PLN `END`PUN(`END`PLNi`END`PUN,`END`PLN r`END`PUN)`END`PLN `END`PUN=`END`PLN `END`PUN(`END`LIT1u8`END`PUN,`END`PLN `END`STR\'c\'`END`PUN);`END`PLN\n' + + ' `END`KWDlet`END`PLN s `END`PUN=`END`PLN `END`STRr#"Take a raw egg,\n' + + ' "break" it (or the line),\n' + + ' and beat it"#`END`PUN;`END`PLN\n' + + '`END`PUN}`END' + ) +}; diff --git a/tests/prettify_test_2.html b/tests/prettify_test_2.html index bcba9798..c62e032b 100644 --- a/tests/prettify_test_2.html +++ b/tests/prettify_test_2.html @@ -1,53 +1,80 @@ - + + Code Prettifier - + + + - - - - -
    -
    + +

    Test Results

    +
    -

    XQuery mode

    -From http://www.patrick-wied.at/static/xquery/prettify/ +
    + +

    XQuery

    +

    From http://www.patrick-wied.at/static/xquery/prettify/

     (: 
     	Took some of Mike Brevoort's xquery code samples because they are nice and show common xquery syntax 
    @@ -382,8 +409,8 @@ 

    XQuery mode

    (: -------- :)
    -

    Nemerle code

    -
    +

    Nemerle

    +
     class Set ['a]
     {
       mutable storage : list ['a] = [];
    @@ -408,8 +435,8 @@ 

    Nemerle code

    assert (s2.Contains ("foo"));
    -

    Tex support

    -
    % resume.tex
    +

    LaTeX

    +
    % resume.tex
     % vim:set ft=tex spell:
     \documentclass[10pt,letterpaper]{article}
     \usepackage[letterpaper,margin=0.8in]{geometry}
    @@ -420,9 +447,9 @@ 

    Tex support

    \setlength{\tabcolsep}{0em}
    -

    Issue 144

    -Escaped quotes in bash. -
    +

    Escaped quotes in Bash

    +

    Issue #144

    +
     #! /bin/bash
     # toascii.sh
     for i in $(echo $* | fold -w 1);do
    @@ -431,8 +458,9 @@ 

    Issue 144

    echo
    -

    Issue 145

    -
    +

    Regular expression in <SCRIPT> body

    +

    Issue #145

    +
     <script type="text/javascript">
     <!--
             var target = $$.css('backgroundImage').replace(/^url[\(\)'"]/g, '');
    @@ -443,14 +471,14 @@ 

    Issue 145

    </script>
    -

    Clojure Syntax Highlighting

    +

    Clojure

     ; Clojure test comment
     (ns test
      (:gen-class))
     
     (def foo "bar")
    -(defn bar [arg1 arg2 & args]
    +(defn bar [arg1 arg2 & args]
       "sample function"
       (for [arg args]
         (prn arg)))
    @@ -458,20 +486,19 @@ 

    Clojure Syntax Highlighting

    (bar "foo" "bar" "blah" :baz)
    -

    HTML 5 language on code

    -

    -The text is specified to be lisp by the class attribute. +

    HTML5 language on CODE

    +

    The text is specified to be lisp by the class attribute. Semicolon is normally a valid punctuation character but in lisp it is a comment so should be colored as a comment if the className is being properly parsed.

    ; foo -

    HTML 5 language on nested code element

    +

    HTML5 language on nested CODE element

    The language is attached to a CODE element inside a PRE.

    ; foo
    -

    HTML 5 language on nested code element not foiled by space

    +

    HTML5 language on nested CODE element not foiled by space

    The language is attached to a CODE element inside a PRE and there is space between the PRE element's tags and CODE element's tags.

    @@ -480,7 +507,7 @@ 

    HTML 5 language on nested code element not foiled by space

    -

    HTML 5 nested code element language ignored if not only content

    +

    HTML5 nested CODE element language ignored if not only content

    The below is not treated as lisp despite there being a lisp language specifier on the contained CODE element, the CODE element does not wrap all non-space content.

    @@ -489,18 +516,45 @@

    HTML 5 nested code element language ignored if not only content

    ; foo
    -

    Issues 185 and 261: Don't reprettify prettified content

    +

    Language using XML processing instrution

    +

    The language is attached to an HTML5 comment that looks like an XML +processing instruction.

    + +
    ; foo
    + +

    Language and line numbers using HTML comment

    +

    The language is attached to a regular HTML5 comment that looks like an XML +processing instruction.

    + +
    ; foo
    + +

    Language and line numbers using HTML comment

    +

    The language is attached to a regular HTML5 comment that looks like an XML +processing instruction.

    + +
    ; foo
    + +

    Language and line numbers using HTML comment

    +

    The language is attached to a regular HTML5 comment that looks like an XML +processing instruction.

    + +
    ; foo
    + +

    Don't reprettify prettified content

    +

    Issue #185

    "No tag backs." +

    Issue #261

    1. "No tag backs."
    -

    Issue 201: C type not full word

    +

    C type not full word

    +

    Issue #201

    static Persistent<String> listeners_symbol; -

    Pascal w/ language specified

    +

    Pascal

     (* some comment here *)
     PROCEDURE TestCase.AssertEquals(msg:String; expect, act:Longint);
    @@ -525,7 +579,7 @@ 

    Pascal w/ language specified

    END;
    -

    BASIC w/ language specified

    +

    BASIC

     200 REM ----- method teardown
     210 PRINT "green"
    @@ -538,9 +592,7 @@ 

    BASIC w/ language specified

    1000 DATA "one", 1, 0
    - - -

    Dart language handler

    +

    Dart

     part of myLib;
     
    @@ -585,12 +637,12 @@ 

    Dart language handler

    }
    -

    TCL_lang

    +

    TCL

    #!/bin/tclsh
     proc fib {n} {
         set a 0
         set b 1
    -    while {$n > 0} {
    +    while {$n > 0} {
             set tmp $a
             set a [expr $a + $b]
             set b $tmp
    @@ -600,21 +652,21 @@ 

    TCL_lang

    }
    -

    R, S language support

    +

    R, S

     ### Example R script for syntax highlighting
     
     # This is a comment
     
     ## Valid names
    -abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV0123456789._a <- NULL
    -.foo_ <- NULL
    -._foo <- NULL
    +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV0123456789._a <- NULL
    +.foo_ <- NULL
    +._foo <- NULL
     
     ## Invalid names
    -0abc <- NULL
    -.0abc <- NULL
    -abc+cde <- NULL
    +0abc <- NULL
    +.0abc <- NULL
    +abc+cde <- NULL
     
     ## Reserved Words
     NA
    @@ -626,10 +678,10 @@ 

    R, S language support

    NaN Inf ## Not reserved -NULLa <- NULL -NULL1 <- NULL -NULL. <- NULL -NA_foo_ <- NULL +NULLa <- NULL +NULL1 <- NULL +NULL. <- NULL +NA_foo_ <- NULL ## Numbers 12345678901 @@ -662,7 +714,7 @@

    R, S language support

    1 %in% 1:10 diag(2) %o% diag(2) diag(2) %x% diag(2) -`%foo bar%` <- function(x, y) x + y +`%foo bar%` <- function(x, y) x + y 1 %foo bar% 2 ## Control Structures (3.2) and Function @@ -673,40 +725,40 @@

    R, S language support

    print(i) } ## While, break -i <- 1 +i <- 1 while (TRUE) { - i <- i + 1 - if (i > 3) break + i <- i + 1 + if (i > 3) break } ## Repeat repeat {1+1} ## Switch -x <- 3 +x <- 3 switch(x, 2+2, mean(1:10), rnorm(5)) ## Function, dot-dot-dot, return -foo <- function(...) { +foo <- function(...) { return(sum(...)) } # Not keywords -functiona <- 2 + 2 -function. <- 2 + 2 -function1 <- 2 + 2 +functiona <- 2 + 2 +function. <- 2 + 2 +function1 <- 2 + 2 ## Grouping Tokens 10.3.7 ## Parentheses 1 + (2 + 3) ## brackets -foo <- function(a) { +foo <- function(a) { a + 1 } ## Indexing 10.3.8 ## [] -bar <- 1:10 +bar <- 1:10 bar[3] ## [[]] -foo <- list(a=1, b=2, c=3) +foo <- list(a=1, b=2, c=3) foo[["a"]] ## $ foo$a @@ -722,38 +774,38 @@

    R, S language support

    2 * 2 2 / 2 2^2 -2 < 2 -2 > 2 +2 < 2 +2 > 2 2 == 2 -2 >= 2 -2 <= 2 +2 >= 2 +2 <= 2 2 != 2 -TRUE & FALSE -TRUE && FALSE +TRUE & FALSE +TRUE && FALSE TRUE | FALSE TRUE || FALSE -foo <- 2 + 2 +foo <- 2 + 2 foo = 2 + 2 -2 + 2 -> foo -foo <<- 2 + 2 -2 + 2 ->> foo +2 + 2 -> foo +foo <<- 2 + 2 +2 + 2 ->> foo base:::sum base::sum ## Strings -foo <- "hello, world!" -foo <- 'hello, world!' -foo <- "Hello, 'world!" -foo <- 'Hello, "world!' -foo <- 'Hello, \'world!\'' -foo <- "Hello, \"world!\"" -foo <- "Hello, +foo <- "hello, world!" +foo <- 'hello, world!' +foo <- "Hello, 'world!" +foo <- 'Hello, "world!' +foo <- 'Hello, \'world!\'' +foo <- "Hello, \"world!\"" +foo <- "Hello, world!" -foo <- 'Hello, +foo <- 'Hello, world!' ## Backtick strings -`foo123 +!"bar'baz` <- 2 + 2 +`foo123 +!"bar'baz` <- 2 + 2

    MUMPS

    @@ -771,696 +823,383 @@

    MUMPS

    I $E(IOST,1,2)="C-" W $C(13) D IOXY^VALM4(30,0) ; -- position cursor W $J("",((VALMWD-80)/2)),$$HTE^XLFDT($H,1),$J("",10+((VALMWD-80)/2)),"Page: ",$J(VALMPGE,4)," of ",$J($$PAGE^VALM4(VALMCNT,VALM("LINES")),4)_$S($D(VALMORE):"+",1:" ") ; -- prt rest of hdr W:VALMCC IOUOFF I $E(IOST,1,2)="C-" D IOXY^VALM4(0,0) ; -- turn off undln - F I=1:1:VALM("TM")-3 W !,$S('$D(VALMHDR(I)):"",$L(VALMHDR(I))>(VALMWD-1):$$EXTRACT^VALM4($G(VALMHDR(I))),1:VALMHDR(I)) ; -- prt hdr + F I=1:1:VALM("TM")-3 W !,$S('$D(VALMHDR(I)):"",$L(VALMHDR(I))>(VALMWD-1):$$EXTRACT^VALM4($G(VALMHDR(I))),1:VALMHDR(I)) ; -- prt hdr Q
    - +typealias SomeNumber = Int + +val number: Long = 1_000L +var float: Float = 12.34f +0xFF_FF +3.14 + +314e-2 +0.314e1 + +protected override fun ifBoolean(condition: Boolean? = null) {} + +::ifBoolean + +constructor() : super() + +"\"true\"" +'a' + +""" +aaaaaaaaaaa +""" + +loop@ for() + +break @loop + +enum class `true` + +data class Person(val name: String) + +enum class Size { + BIG, MEDIUM, SMALL +} + +class Ball(val color: String, val size: Size) { + companion object {} + + fun isBig() = size == Size.BIG + + val isMedium: Boolean + get() = size == Size.MEDIUM +} + +fun Boolean?.isNull(): Boolean = this == null + +fun Boolean?.getOrThrow(): Boolean = this ?: throw Exception() +
    + diff --git a/tests/prettify_test_2.js b/tests/prettify_test_2.js new file mode 100644 index 00000000..03e29f5a --- /dev/null +++ b/tests/prettify_test_2.js @@ -0,0 +1,1072 @@ +/** + * maps ids of rewritten code to the expected output. + * For brevity, has been changed to `FOO + * and < /span> has been changed to `END. + */ +var goldens = { + xquery: ( + '`COM(: \n' + + '\tTook some of Mike Brevoort\'s xquery code samples because they are nice and show common xquery syntax \n' + + ':)`END`PLN\n' + + ' \n' + + ' `END`COM(:~\n' + + ' : Given a sequence of version URIs, publish all of these versions of each document\n' + + ' : If there is a version of the same document already published, unpublish it 1st\n' + + ' :\n' + + ' : When "publish" is referred to, we mean that it is put into the PUBLISHED collection\n' + + ' : unpublish removes content from this collection\n' + + ' : @param $version_uris - sequence of uris of versions of managed documents to publish\n' + + ' :)`END`PLN\n' + + ' `END`KWDdeclare`END`PLN `END`KWDfunction`END`PLN comoms-dls:publish(`END$version_uris`END`PLN `END`KWDas`END`PLN `END`KWDitem`END`PLN()*) {\n' + + ' `END`KWDfor`END`PLN `END$uri`END`PLN `END`KWDin`END`PLN `END$version_uris`END`PLN\n' + + ' `END`KWDlet`END`PLN `END$doc`END`PLN := `ENDfn:doc`END`PLN(`END$uri`END`PLN)\n' + + ' `END`KWDlet`END`PLN `END$managed_base_uri`END`PLN := `END$doc`END`PLN/`END`KWDnode`END`PLN()/property::dls:version/dls:document-uri/`END`KWDtext`END`PLN()\n' + + ' `END`KWDlet`END`PLN `END$existing`END`PLN := comoms-dls:publishedDoc(`END$managed_base_uri`END`PLN)\n' + + ' `END`KWDlet`END`PLN `END$unpublishExisting`END`PLN := `END`KWDif`END`PLN(`END$existing`END`PLN) `END`KWDthen`END`PLN comoms-dls:unpublishVersion((`ENDxdmp:node-uri`END`PLN(`END$existing`END`PLN))) `END`KWDelse`END`PLN ()\n' + + ' `END`KWDlet`END`PLN `END$addPermissions`END`PLN := `ENDdls:document-add-permissions`END`PLN(`END$uri`END`PLN, (`ENDxdmp:permission`END`PLN(`END`STR\'mkp-anon\'`END`PLN, `END`STR\'read\'`END`PLN)))\n' + + ' `END`KWDreturn`END`PLN\n' + + ' `ENDdls:document-add-collections`END`PLN(`END$uri`END`PLN, (`END`STR"PUBLISHED"`END`PLN)) \n' + + ' };\n' + + ' \n' + + ' `END`KWDdeclare`END`PLN `END`KWDfunction`END`PLN comoms-dls:publishLatest(`END$uri`END`PLN) {\n' + + ' `END`COM(: TODO check if it\'s in the draft collection probably :)`END`PLN\n' + + ' \n' + + ' `END`KWDlet`END`PLN `END$latest_version_uri`END`PLN := comoms-dls:latestVersionUri(`END$uri`END`PLN)\n' + + ' `END`KWDlet`END`PLN `END$log`END`PLN:= `ENDxdmp:log`END`PLN(`ENDfn:concat`END`PLN(`END`STR"latest: "`END`PLN, `END$latest_version_uri`END`PLN)) \n' + + ' `END`KWDlet`END`PLN `END$log`END`PLN:= `ENDxdmp:log`END`PLN(`ENDfn:concat`END`PLN(`END`STR"uri: "`END`PLN, `END$uri`END`PLN)) \n' + + ' `END`KWDreturn`END`PLN comoms-dls:publish(`END$latest_version_uri`END`PLN) \n' + + ' \n' + + ' };\n' + + ' \n' + + ' `END`KWDdeclare`END`PLN `END`KWDfunction`END`PLN comoms-dls:latestVersionUri(`END$uri`END`PLN) {\n' + + ' `END`KWDlet`END`PLN `END$latest_version_num`END`PLN :=\n' + + ' (\n' + + ' `END`KWDfor`END`PLN `END$version`END`PLN `END`KWDin`END`PLN `ENDdls:document-history`END`PLN(`END$uri`END`PLN)/dls:version\n' + + ' `END`KWDorder`END`PLN `END`KWDby`END`PLN `ENDfn:number`END`PLN(`END$version`END`PLN//dls:version-id/`END`KWDtext`END`PLN()) `END`KWDdescending`END`PLN\n' + + ' `END`KWDreturn`END`PLN `END$version`END`PLN//dls:version-id/`END`KWDtext`END`PLN()\n' + + ' )[1]\n' + + ' \n' + + ' \n' + + ' `END`KWDreturn`END`PLN `ENDdls:document-version-uri`END`PLN(`END$uri`END`PLN, `END$latest_version_num`END`PLN)\n' + + ' };\n' + + ' \n' + + ' `END`KWDdeclare`END`PLN `END`KWDfunction`END`PLN comoms-dls:unpublish(`END$uris`END`PLN `END`KWDas`END`PLN `END`KWDitem`END`PLN()*) {\n' + + ' `END`KWDfor`END`PLN `END$uri`END`PLN `END`KWDin`END`PLN `END$uris`END`PLN\n' + + ' `END`KWDreturn`END`PLN\n' + + ' `END`KWDlet`END`PLN `END$published_doc`END`PLN := comoms-dls:publishedDoc(`END$uri`END`PLN)\n' + + ' `END`KWDreturn`END`PLN\n' + + ' `END`KWDif`END`PLN(`END$published_doc`END`PLN) `END`KWDthen`END`PLN\n' + + ' `END`KWDlet`END`PLN `END$published_version_uri`END`PLN := `ENDxdmp:node-uri`END`PLN(`END$published_doc`END`PLN)\n' + + ' `END`KWDreturn`END`PLN comoms-dls:unpublishVersion(`END$published_version_uri`END`PLN) \n' + + ' `END`KWDelse`END`PLN\n' + + ' ()\n' + + ' };\n' + + ' \n' + + ' `END`KWDdeclare`END`PLN `END`KWDfunction`END`PLN comoms-dls:latestPublishedDocAuthor(`END$uri`END`PLN) {\n' + + ' `END`KWDlet`END`PLN `END$author_id`END`PLN := `ENDdoc`END`PLN(`END$uri`END`PLN)/property::dls:version/dls:author/`END`KWDtext`END`PLN()\n' + + ' `END`KWDreturn`END`PLN\n' + + ' `END`KWDif`END`PLN(`END$author_id`END`PLN) `END`KWDthen`END`PLN\n' + + ' comoms-user:getUsername(`END$author_id`END`PLN)\n' + + ' `END`KWDelse`END`PLN\n' + + ' ()\n' + + ' \n' + + ' };\n' + + ' \n' + + ' `END`COM(:~\n' + + ' : Given a sequence of version URIs, unpublish all of these versions of each document\n' + + ' :)`END`PLN\n' + + ' `END`KWDdeclare`END`PLN `END`KWDfunction`END`PLN comoms-dls:unpublishVersion(`END$version_uris`END`PLN `END`KWDas`END`PLN `END`KWDitem`END`PLN()*) {\n' + + ' `END`KWDfor`END`PLN `END$uri`END`PLN `END`KWDin`END`PLN `END$version_uris`END`PLN\n' + + ' `END`KWDreturn`END`PLN\n' + + ' `END`KWDlet`END`PLN `END$removePermissions`END`PLN := `ENDdls:document-remove-permissions`END`PLN(`END$uri`END`PLN, (`ENDxdmp:permission`END`PLN(`END`STR\'mkp-anon\'`END`PLN, `END`STR\'read\'`END`PLN)))\n' + + ' `END`KWDreturn`END`PLN `ENDdls:document-remove-collections`END`PLN(`END$uri`END`PLN, (`END`STR"PUBLISHED"`END`PLN)) \n' + + ' };\n' + + ' \n' + + ' `END`COM(:~\n' + + ' : Given the base URI of a managed piece of content, return the document of the node\n' + + ' : of the version that is published\n' + + ' :)`END`PLN\n' + + ' `END`KWDdeclare`END`PLN `END`KWDfunction`END`PLN comoms-dls:publishedDoc(`END$uri`END`PLN) {\n' + + ' `ENDfn:collection`END`PLN(`END`STR"PUBLISHED"`END`PLN)[property::dls:version/dls:document-uri = `END$uri`END`PLN]\n' + + ' };\n' + + ' \n' + + ' \n' + + ' `END`COM(:~\n' + + ' : Test if any version of the managed document is published\n' + + ' :)`END`PLN\n' + + ' `END`KWDdeclare`END`PLN `END`KWDfunction`END`PLN comoms-dls:isPublished(`END$uri`END`PLN) {\n' + + ' `END`KWDif`END`PLN( comoms-dls:publishedDoc(`END$uri`END`PLN)) `END`KWDthen`END`PLN\n' + + ' `ENDfn:true`END`PLN()\n' + + ' `END`KWDelse`END`PLN\n' + + ' `ENDfn:false`END`PLN()\n' + + ' };\n' + + ' \n' + + ' \n' + + ' `END`KWDdeclare`END`PLN `END`KWDfunction`END`PLN comoms-dls:publishedState(`END$uri`END`PLN) {\n' + + ' `END`KWDlet`END`PLN `END$doc`END`PLN := comoms-dls:publishedDoc(`END$uri`END`PLN)\n' + + ' `END`KWDlet`END`PLN `END$published_uri`END`PLN := `END`KWDif`END`PLN(`END$doc`END`PLN) `END`KWDthen`END`PLN `ENDxdmp:node-uri`END`PLN(`END$doc`END`PLN) `END`KWDelse`END`PLN ()\n' + + ' `END`KWDlet`END`PLN `END$latest`END`PLN := comoms-dls:latestVersionUri(`END$uri`END`PLN)\n' + + ' `END`KWDreturn`END`PLN\n' + + ' `END`KWDif`END`PLN(`END$doc`END`PLN) `END`KWDthen`END`PLN\n' + + ' `END`KWDif`END`PLN(`END$latest`END`PLN ne `END$published_uri`END`PLN) `END`KWDthen`END`PLN\n' + + ' `END`STR"stale"`END`PLN\n' + + ' `END`KWDelse`END`PLN\n' + + ' `END`STR"published"`END`PLN\n' + + ' `END`KWDelse`END`PLN\n' + + ' `END`STR"unpublished"`END`PLN\n' + + ' };\n' + + ' \n' + + ' \n' + + ' `END`KWDdeclare`END`PLN `END`KWDfunction`END`PLN comoms-dls:getManagedDocUri(`END$uri`END`PLN) {\n' + + ' `END`KWDlet`END`PLN `END$doc`END`PLN := `ENDfn:doc`END`PLN(`END$uri`END`PLN)\n' + + ' `END`KWDlet`END`PLN `END$managed_uri`END`PLN := `END$doc`END`PLN/property::dls:version/dls:document-uri/`END`KWDtext`END`PLN()\n' + + ' `END`KWDlet`END`PLN `END$managed_uri`END`PLN := `END`KWDif`END`PLN(`END$managed_uri`END`PLN) `END`KWDthen`END`PLN `END$managed_uri`END`PLN `END`KWDelse`END`PLN `END$uri`END`PLN\n' + + ' `END`KWDreturn`END`PLN `END$managed_uri`END`PLN\n' + + ' };\n' + + ' \n' + + ' `END`COM(:~\n' + + ' : Given a manage content url (e.g. /content/123456.xml) return the appropriate\n' + + ' : version of the document based on what stage collection is being viewed and\n' + + ' : what\'s published\n' + + ' :\n' + + ' : @param $uri a manage content url (e.g. /content/123456.xml) - NOT A VERSIONED URI\n' + + ' :)`END`PLN\n' + + ' `END`KWDdeclare`END`PLN `END`KWDfunction`END`PLN comoms-dls:doc(`END$uri`END`PLN) {\n' + + ' `END`KWDlet`END`PLN `END$doc`END`PLN := `ENDfn:root`END`PLN(comoms-dls:collection()[property::dls:version/dls:document-uri = `END$uri`END`PLN][1])\n' + + ' `END`KWDreturn`END`PLN\n' + + ' `END`KWDif`END`PLN(`END$doc`END`PLN) `END`KWDthen`END`PLN\n' + + ' `END$doc`END`PLN\n' + + ' `END`KWDelse`END`PLN\n' + + ' `END`KWDlet`END`PLN `END$managedDocInCollection`END`PLN := comoms-dls:collection-name() = `ENDxdmp:document-get-collections`END`PLN(`END$uri`END`PLN)\n' + + ' `END`KWDreturn`END`PLN\n' + + ' `END`KWDif`END`PLN(`END$managedDocInCollection`END`PLN) `END`KWDthen`END`PLN\n' + + ' `ENDfn:doc`END`PLN(`END$uri`END`PLN)\n' + + ' `END`KWDelse`END`PLN\n' + + ' ()\n' + + ' };\n' + + ' \n' + + ' `END`COM(:~\n' + + ' : Get the collection to be used when querying for content\n' + + ' : THIS or comoms-dls:collection-name() SHOULD BE USED WHEN BUILDING ANY QUERY FOR MANAGED CONTENT\n' + + ' :)`END`PLN\n' + + ' `END`KWDdeclare`END`PLN `END`KWDfunction`END`PLN comoms-dls:collection() {\n' + + ' `ENDfn:collection`END`PLN( comoms-dls:collection-name() )\n' + + ' };\n' + + ' \n' + + ' `END`COM(:~\n' + + ' : Get the collection nameto be used when querying for content\n' + + ' : THIS or comoms-dls:collection() SHOULD BE USED WHEN BUILDING ANY QUERY FOR MANAGED CONTENT\n' + + ' :)`END`PLN\n' + + ' `END`KWDdeclare`END`PLN `END`KWDfunction`END`PLN comoms-dls:collection-name() `END`KWDas`END`PLN `END`TYPxs:string`END`PLN {\n' + + ' `END`KWDlet`END`PLN `END$default_collection`END`PLN := `END`STR"PUBLISHED"`END`PLN\n' + + ' `END`KWDreturn`END`PLN\n' + + ' `END`KWDif`END`PLN(comoms-user:isAdmin()) `END`KWDthen`END`PLN\n' + + ' `END`KWDlet`END`PLN `END$pub_stage_collection_cookie`END`PLN := comoms-util:getCookie(`END`STR"COMOMS_COLLECTION"`END`PLN)\n' + + ' `END`KWDreturn`END`PLN\n' + + ' `END`KWDif`END`PLN(`END$pub_stage_collection_cookie`END`PLN) `END`KWDthen`END`PLN\n' + + ' `END$pub_stage_collection_cookie`END`PLN\n' + + ' `END`KWDelse`END`PLN\n' + + ' `END$default_collection`END`PLN\n' + + ' `END`KWDelse`END`PLN\n' + + ' `END$default_collection`END`PLN\n' + + ' };\n' + + ' \n' + + ' `END`COM(:~\n' + + ' : Check if the published collection is being viewed\n' + + ' :)`END`PLN\n' + + ' `END`KWDdeclare`END`PLN `END`KWDfunction`END`PLN comoms-dls:isViewingPublished() {\n' + + ' `END`KWDif`END`PLN(comoms-dls:collection-name() = `END`STR"PUBLISHED"`END`PLN) `END`KWDthen`END`PLN\n' + + ' `ENDfn:true`END`PLN()\n' + + ' `END`KWDelse`END`PLN\n' + + ' `ENDfn:false`END`PLN()\n' + + ' };\n' + + ' \n' + + ' `END`COM(:~\n' + + ' : Get the best URL for the content URI.\n' + + ' : This is either the default URI based on detail type or should also take\n' + + ' : into account friendly urls and navigation structures to figure out the\n' + + ' : best choice\n' + + ' :)`END`PLN\n' + + ' `END`KWDdeclare`END`PLN `END`KWDfunction`END`PLN comoms-dls:contentUrl(`END$uri`END`PLN) {\n' + + ' \n' + + ' `END`COM(: TODO: add friendly URL and nav structure logic 1st :)`END`PLN\n' + + ' \n' + + ' `END`KWDlet`END`PLN `END$doc`END`PLN := `ENDfn:doc`END`PLN(`END$uri`END`PLN)\n' + + ' `END`KWDlet`END`PLN `END$managedDocUri`END`PLN := `END$doc`END`PLN/property::dls:version/dls:document-uri\n' + + ' `END`KWDlet`END`PLN `END$uri`END`PLN := `END`KWDif`END`PLN(`END$managedDocUri`END`PLN) `END`KWDthen`END`PLN `END$managedDocUri`END`PLN `END`KWDelse`END`PLN `END$uri`END`PLN\n' + + ' `END`KWDlet`END`PLN `END$type`END`PLN := `END$doc`END`PLN/`END`KWDnode`END`PLN()/`ENDfn:name`END`PLN()\n' + + ' `END`KWDlet`END`PLN `END$content_id`END`PLN := `ENDfn:tokenize`END`PLN( `ENDfn:tokenize`END`PLN(`END$uri`END`PLN, `END`STR"/"`END`PLN)[3], `END`STR"\\."`END`PLN)[1]\n' + + ' `END`KWDreturn`END`PLN\n' + + ' `ENDfn:concat`END`PLN(`END`STR"/"`END`PLN, `END$type`END`PLN, `END`STR"/"`END`PLN, `END$content_id`END`PLN)\n' + + ' };\n' + + ' \n' + + ' `END`COM(:\n' + + ' :\n' + + ' : gets list of doc versions and uri.\n' + + ' :\n' + + ' :)`END`PLN\n' + + ' `END`KWDdeclare`END`PLN `END`KWDfunction`END`PLN comoms-dls:versionHistory(`END$uri`END`PLN) {\n' + + ' `END`KWDlet`END`PLN `END$published_doc`END`PLN := comoms-dls:publishedDoc(`END$uri`END`PLN)\n' + + ' `END`KWDlet`END`PLN `END$published_uri`END`PLN := `END`KWDif`END`PLN(`END$published_doc`END`PLN) `END`KWDthen`END`PLN `ENDxdmp:node-uri`END`PLN(`END$published_doc`END`PLN) `END`KWDelse`END`PLN ()\n' + + ' `END`KWDreturn`END`PLN\n' + + ' `END`TAG<versions>`END`PLN\n' + + ' {\n' + + ' `END`KWDfor`END`PLN `END$version`END`PLN `END`KWDin`END`PLN `ENDdls:document-history`END`PLN(`END$uri`END`PLN)/dls:version\n' + + ' `END`KWDlet`END`PLN `END$version_num`END`PLN := `END$version`END`PLN/dls:version-id/`END`KWDtext`END`PLN()\n' + + ' `END`KWDlet`END`PLN `END$created`END`PLN := `END$version`END`PLN/dls:created/`END`KWDtext`END`PLN()\n' + + ' `END`KWDlet`END`PLN `END$author_id`END`PLN := `END$version`END`PLN/dls:author/`END`KWDtext`END`PLN()\n' + + ' `END`KWDlet`END`PLN `END$author`END`PLN := comoms-user:getUsername(`END$author_id`END`PLN)\n' + + ' \n' + + ' \n' + + ' `END`KWDlet`END`PLN `END$note`END`PLN := `END$version`END`PLN/dls:annotation/`END`KWDtext`END`PLN()\n' + + ' `END`KWDlet`END`PLN `END$version_uri`END`PLN := `ENDxdmp:node-uri`END`PLN(`ENDdls:document-version`END`PLN(`END$uri`END`PLN, `END$version_num`END`PLN))\n' + + ' `END`KWDlet`END`PLN `END$published`END`PLN := `END$published_uri`END`PLN `END`KWDeq`END`PLN `END$version_uri`END`PLN\n' + + ' `END`KWDreturn`END`PLN\n' + + ' `END`TAG<version>`END`PLN\n' + + ' `END`TAG<version-number>`END`PLN{`END$version_num`END`PLN}`END`TAG</version-number>`END`PLN\n' + + ' `END`TAG<created>`END`PLN{`END$created`END`PLN}`END`TAG</created>`END`PLN \n' + + ' `END`TAG<author>`END`PLN{`END$author`END`PLN}`END`TAG</author>`END`PLN\n' + + ' `END`TAG<published>`END`PLN{`END$published`END`PLN}`END`TAG</published>`END`PLN\n' + + ' `END`TAG<version-uri>`END`PLN{`END$version_uri`END`PLN}`END`TAG</version-uri>`END`PLN\n' + + ' `END`TAG</version>`END`PLN \n' + + ' } \n' + + ' `END`TAG</versions>`END`PLN\n' + + ' };\n' + + ' \n' + + ' \n' + + ' \n' + + ' \n' + + ' \n' + + ' \n' + + ' `END`COM(: ########################################################################### :)`END`PLN\n' + + ' `END`COM(: PRIVATE FUNCTIONS :)`END`PLN\n' + + ' `END`COM(: ########################################################################### :)`END`PLN\n' + + ' \n' + + ' `END`KWDdeclare`END`PLN `END`KWDfunction`END`PLN comoms-dls:_import() {\n' + + ' `END`STR"xquery version \'1.0-ml\';\n' + + ' import module namespace dls = \'http://marklogic.com/xdmp/dls\' at \'/MarkLogic/dls.xqy\'; "`END`PLN\n' + + ' }; \n' + + ' \n' + + '`END`COM(: ----\n' + + '---- :)`END`PLN\n' + + '`END`KWDxquery`END`PLN `END`KWDversion`END`PLN `END`STR\'1.0-ml\'`END`PLN;\n' + + '`END`KWDdeclare`END`PLN `END`KWDvariable`END`PLN `END$URI`END`PLN `END`KWDas`END`PLN `END`TYPxs:string`END`PLN `END`KWDexternal`END`PLN;\n' + + ' \n' + + '`END`KWDdeclare`END`PLN `END`KWDfunction`END`PLN local:document-move-forest(`END$uri`END`PLN `END`KWDas`END`PLN `END`TYPxs:string`END`PLN, `END$forest-ids`END`PLN `END`KWDas`END`PLN `END`TYPxs:unsignedLong`END`PLN*)\n' + + '{\n' + + ' `ENDxdmp:document-insert`END`PLN(\n' + + ' `END$uri`END`PLN,\n' + + ' `ENDfn:doc`END`PLN(`END$uri`END`PLN),\n' + + ' `ENDxdmp:document-get-permissions`END`PLN(`END$uri`END`PLN),\n' + + ' `ENDxdmp:document-get-collections`END`PLN(`END$uri`END`PLN),\n' + + ' `ENDxdmp:document-get-quality`END`PLN(`END$uri`END`PLN),\n' + + ' `END$forest-ids`END`PLN\n' + + ' )\n' + + '};\n' + + ' \n' + + '`END`KWDlet`END`PLN `END$xml`END`PLN :=\n' + + ' `END`TAG<xml`END`PLN att=`END`STR"blah"`END`PLN att2=`END`STR"blah"`END`TAG>`END`PLN\n' + + ' sdasd`END`TAG<b>`END`PLNasdasd`END`TAG</b>`END`PLN\n' + + ' `END`TAG</xml>`END`PLN\n' + + '`END`COM(: -------- :)`END`PLN\n' + + '`END`KWDfor`END`PLN `END$d`END`PLN `END`KWDin`END`PLN `ENDfn:doc`END`PLN(`END`STR"depts.xml"`END`PLN)/depts/deptno\n' + + '`END`KWDlet`END`PLN `END$e`END`PLN := `ENDfn:doc`END`PLN(`END`STR"emps.xml"`END`PLN)/emps/emp[deptno = `END$d`END`PLN]\n' + + '`END`KWDwhere`END`PLN `ENDfn:count`END`PLN(`END$e`END`PLN) >= 10\n' + + '`END`KWDorder`END`PLN `END`KWDby`END`PLN `ENDfn:avg`END`PLN(`END$e`END`PLN/salary) `END`KWDdescending`END`PLN\n' + + '`END`KWDreturn`END`PLN\n' + + ' `END`TAG<big-dept>`END`PLN\n' + + ' {\n' + + ' `END$d`END`PLN,\n' + + ' `END`TAG<headcount>`END`PLN{`ENDfn:count`END`PLN(`END$e`END`PLN)}`END`TAG</headcount>`END`PLN,\n' + + ' `END`TAG<avgsal>`END`PLN{`ENDfn:avg`END`PLN(`END$e`END`PLN/salary)}`END`TAG</avgsal>`END`PLN\n' + + ' }\n' + + ' `END`TAG</big-dept>`END`PLN\n' + + '`END`COM(: -------- :)`END`PLN\n' + + '`END`KWDdeclare`END`PLN `END`KWDfunction`END`PLN local:depth(`END$e`END`PLN `END`KWDas`END`PLN `END`KWDnode`END`PLN()) `END`KWDas`END`PLN `END`TYPxs:integer`END`PLN\n' + + '{\n' + + ' `END`COM(: A node with no children has depth 1 :)`END`PLN\n' + + ' `END`COM(: Otherwise, add 1 to max depth of children :)`END`PLN\n' + + ' `END`KWDif`END`PLN (`ENDfn:empty`END`PLN(`END$e`END`PLN/*)) `END`KWDthen`END`PLN 1\n' + + ' `END`KWDelse`END`PLN `ENDfn:max`END`PLN(`END`KWDfor`END`PLN `END$c`END`PLN `END`KWDin`END`PLN `END$e`END`PLN/* `END`KWDreturn`END`PLN local:depth(`END$c`END`PLN)) + 1\n' + + '};\n' + + ' \n' + + 'local:depth(`ENDfn:doc`END`PLN(`END`STR"partlist.xml"`END`PLN))\n' + + ' \n' + + '`END`COM(: -------- :)`END`PLN\n' + + '`END`TAG<html><head`END`PLN/`END`TAG><body>`END`PLN\n' + + '{\n' + + ' `END`KWDfor`END`PLN `END$act`END`PLN `END`KWDin`END`PLN `ENDdoc`END`PLN(`END`STR"hamlet.xml"`END`PLN)//ACT\n' + + ' `END`KWDlet`END`PLN `END$speakers`END`PLN := `ENDdistinct-values`END`PLN(`END$act`END`PLN//SPEAKER)\n' + + ' `END`KWDreturn`END`PLN\n' + + ' `END`TAG<div>`END`PLN{ `ENDstring`END`PLN(`END$act`END`PLN/TITLE) }`END`TAG</h1>`END`PLN\n' + + ' `END`TAG<ul>`END`PLN\n' + + ' {\n' + + ' `END`KWDfor`END`PLN `END$speaker`END`PLN `END`KWDin`END`PLN `END$speakers`END`PLN\n' + + ' `END`KWDreturn`END`PLN `END`TAG<li>`END`PLN{ `END$speaker`END`PLN }`END`TAG</li>`END`PLN\n' + + ' }\n' + + ' `END`TAG</ul>`END`PLN\n' + + ' `END`TAG</div>`END`PLN\n' + + '}\n' + + '`END`TAG</body></html>`END`PLN\n' + + '`END`COM(: -------- :)`END`PLN\n' + + '{\n' + + '\t`END`KWDfor`END`PLN `END$book`END`PLN `END`KWDin`END`PLN `ENDdoc`END`PLN(`END`STR"books.xml"`END`PLN)//book\n' + + ' `END`KWDreturn`END`PLN\n' + + '\t`END`KWDif`END`PLN (`ENDcontains`END`PLN(`END$book`END`PLN/author/`END`KWDtext`END`PLN(),`END`STR"Herbert"`END`PLN) `END`KWDor`END`PLN `ENDcontains`END`PLN(`END$book`END`PLN/author/`END`KWDtext`END`PLN(),`END`STR"Asimov"`END`PLN))\n' + + '\t\t`END`KWDthen`END`PLN `END$book`END`PLN\n' + + '\t`END`KWDelse`END`PLN `END$book`END`PLN/`END`KWDtext`END`PLN()\n' + + '\t\n' + + '\t`END`KWDlet`END`PLN `END$let`END`PLN := `END`TAG<x>`END`STR"test"`END`TAG</x>`END`PLN\n' + + '\t`END`KWDreturn`END`PLN `END`KWDelement`END`PLN `END`KWDelement`END`PLN {\n' + + '\t`END`KWDattribute`END`PLN `END`KWDattribute`END`PLN { 1 },\n' + + '\t`END`KWDelement`END`PLN test { `END`STR\'a\'`END`PLN },\n' + + '\t`END`KWDattribute`END`PLN foo { `END`STR"bar"`END`PLN },\n' + + '\t`ENDfn:doc`END`PLN()[ foo/`END`LIT@bar`END`PLN `END`KWDeq`END`PLN `END$let`END`PLN ],\n' + + '\t//x }\n' + + '}\n' + + '`END`COM(: -------- :)`END`PLN\n' + + '`END`TAG<bib>`END`PLN\n' + + ' {\n' + + ' `END`KWDfor`END`PLN `END$b`END`PLN `END`KWDin`END`PLN `ENDdoc`END`PLN(`END`STR"http://bstore1.example.com/bib.xml"`END`PLN)/bib/book\n' + + ' `END`KWDwhere`END`PLN `END$b`END`PLN/publisher = `END`STR"Addison-Wesley"`END`PLN `END`KWDand`END`PLN `END$b`END`PLN/`END`LIT@year`END`PLN > 1991\n' + + ' `END`KWDreturn`END`PLN\n' + + ' `END`TAG<book`END`PLN year=`END`STR"`END`PLN{ `END$b`END`PLN/`END`LIT@year`END`PLN }`END`STR"`END`TAG>`END`PLN\n' + + ' { `END$b`END`PLN/title }\n' + + ' `END`TAG</book>`END`PLN\n' + + ' }\n' + + '`END`TAG</bib>`END`PLN\n' + + '`END`COM(: -------- :)`END' + ), + nemerle: ( + '`KWDclass`END`PLN Set `END`PUN[`END`PLN\'a`END`PUN]`END`PLN\n' + + '`END`PUN{`END`PLN\n' + + ' `END`KWDmutable`END`PLN storage `END`PUN:`END`PLN `END`TYPlist`END`PLN `END`PUN[`END`PLN\'a`END`PUN]`END`PLN `END`PUN=`END`PLN `END`PUN[];`END`PLN\n' + + ' `END`KWDpublic`END`PLN Add `END`PUN(`END`PLNe `END`PUN:`END`PLN \'a`END`PUN)`END`PLN `END`PUN:`END`PLN `END`TYPvoid`END`PLN\n' + + ' `END`PUN{`END`PLN\n' + + ' `END`KWDwhen`END`PLN `END`PUN(!`END`PLN Contains `END`PUN(`END`PLNe`END`PUN))`END`PLN\n' + + ' storage `END`PUN::=`END`PLN e`END`PUN;`END`PLN\n' + + ' `END`PUN}`END`PLN\n' + + ' `END`KWDpublic`END`PLN Contains `END`PUN(`END`PLNe `END`PUN:`END`PLN \'a`END`PUN)`END`PLN `END`PUN:`END`PLN `END`TYPbool`END`PLN\n' + + ' `END`PUN{`END`PLN\n' + + ' storage`END`PUN.`END`PLNContains `END`PUN(`END`PLNe`END`PUN)`END`PLN\n' + + ' `END`PUN}`END`PLN\n' + + '`END`PUN}`END`PLN\n' + + ' \n' + + '`END`KWDdef`END`PLN s1 `END`PUN=`END`PLN Set `END`PUN();`END`PLN\n' + + 's1`END`PUN.`END`PLNAdd `END`PUN(`END`LIT3`END`PUN);`END`PLN\n' + + 's1`END`PUN.`END`PLNAdd `END`PUN(`END`LIT42`END`PUN);`END`PLN\n' + + '`END`KWDassert`END`PLN `END`PUN(`END`PLNs1`END`PUN.`END`PLNContains `END`PUN(`END`LIT3`END`PUN));`END`PLN\n' + + '`END`COM// s1.Add ("foo"); // error here!`END`PLN\n' + + '`END`KWDdef`END`PLN s2 `END`PUN=`END`PLN Set `END`PUN();`END`PLN\n' + + 's2`END`PUN.`END`PLNAdd `END`PUN(`END`STR"foo"`END`PUN);`END`PLN\n' + + '`END`KWDassert`END`PLN `END`PUN(`END`PLNs2`END`PUN.`END`PLNContains `END`PUN(`END`STR"foo"`END`PUN));`END' + ), + latex: ( + '`COM% resume.tex`END`PLN\n' + + '`END`COM% vim:set ft=tex spell:`END`PLN\n' + + '`END`KWD\\documentclass`END`PUN[`END`LIT10pt`END`PLN,letterpaper`END`PUN]{`END`PLNarticle`END`PUN}`END`PLN\n' + + '`END`KWD\\usepackage`END`PUN[`END`PLNletterpaper,margin`END`PUN=`END`LIT0.8in`END`PUN]{`END`PLNgeometry`END`PUN}`END`PLN\n' + + '`END`KWD\\usepackage`END`PUN{`END`PLNmdwlist`END`PUN}`END`PLN\n' + + '`END`KWD\\usepackage`END`PUN[`END`PLNT1`END`PUN]{`END`PLNfontenc`END`PUN}`END`PLN\n' + + '`END`KWD\\usepackage`END`PUN{`END`PLNtextcomp`END`PUN}`END`PLN\n' + + '`END`KWD\\pagestyle`END`PUN{`END`PLNempty`END`PUN}`END`PLN\n' + + '`END`KWD\\setlength`END`PUN{`END`KWD\\tabcolsep`END`PUN}{`END`LIT0em`END`PUN}`END' + ), + issue144: ( + '`COM#! /bin/bash`END`PLN\n' + + '`END`COM# toascii.sh`END`PLN\n' + + '`END`KWDfor`END`PLN i `END`KWDin`END`PLN $`END`PUN(`END`PLNecho $`END`PUN*' + + '`END`PLN `END`PUN|`END`PLN fold `END`PUN-`END`PLNw `END`LIT1`END`PUN);`END' + + '`KWDdo`END`PLN\n' + + ' printf `END`STR"%x "`END`PLN \\\'$i`END`PUN;`END`PLN\n' + + '`END`KWDdone`END`PUN;`END`PLN\n' + + 'echo`END' + ), + issue145: ( + '`TAG<script`END`PLN `END`ATNtype`END`PUN=`END`ATV"text/javascript"`END`TAG>`END`PLN\n' + + '`END`PUN<!--`END`PLN\n' + + ' `END`KWDvar`END`PLN target `END`PUN=`END`PLN $$`END`PUN.`END`PLNcss`END`PUN(`END`STR\'backgroundImage\'`END`PUN).`END`PLNreplace`END`PUN(`END`STR/^url[\\(\\)\'"]/`END`PLNg`END`PUN,`END`PLN `END`STR\'\'`END`PUN);`END`PLN\n' + + '\n' + + ' `END`COM// nice long chain: wrap img element in span`END`PLN\n' + + ' $$`END`PUN.`END`PLNwrap`END`PUN(`END`STR\'<span style="position: relative;"></span>\'`END`PUN)`END`PLN\n' + + '`END`PUN-->`END`PLN\n' + + '`END`TAG</script>`END' + ), + clojure: ( + '`COM; Clojure test comment`END`PLN\n' + + '`END`OPN(`END`KWDns`END`PLN test\n' + + ' `END`OPN(`END`TYP:gen-class`END`CLO))`END`PLN\n' + + '\n' + + '`END`OPN(`END`KWDdef`END`PLN foo `END`STR"bar"`END`CLO)`END`PLN\n' + + '`END`OPN(`END`KWDdefn`END`PLN bar `END`OPN[`END`PLNarg1 arg2 & args`END`CLO]`END`PLN\n' + + ' `END`STR"sample function"`END`PLN\n' + + ' `END`OPN(`END`KWDfor`END`PLN `END`OPN[`END`PLNarg args`END`CLO]`END`PLN\n' + + ' `END`OPN(`END`KWDprn`END`PLN arg`END`CLO)))`END`PLN\n' + + '\n' + + '`END`OPN(`END`PLNbar `END`STR"foo"`END`PLN `END`STR"bar"`END`PLN `END`STR"blah"`END`PLN `END`TYP:baz`END`CLO)`END' + ), + html5conv1: '`COM; foo`END', + html5conv2: '`COM; foo`END', + html5conv3: ( + '`PLN\n' + + '`END`COM; foo`END`PLN\n' + + '`END\n' + ), + html5conv4: ( + '`PLNbefore CODE\n' + + '`END`PUN;`END`PLN foo`END\n' + ), + procinstr1: '`COM; foo`END', + procinstr2: '
    1. `COM; foo`END
    ', + procinstr3: '
    1. `COM; foo`END
    ', + procinstr4: '`COM; foo`END', + issue185: '`STR"No tag backs."`END', + issue261: '
    1. `STR"No tag backs."`END
    ', + issue201: ( + '`KWDstatic`END`PLN `END`TYPPersistent`END' + + '`PUN<`END`TYPString`END`PUN>`END`PLN listeners_symbol`END`PUN;`END' + ), + dart: ( + '`KWDpart of`END`PLN myLib`END`PUN;`END`PLN\n' + + '\n' + + '`END`KWDpart`END`PLN `END`STR\'something.dart\'`END`PUN;`END`PLN\n' + + '\n' + + '`END`KWDimport`END`PLN `END`STR\'dart:math\'`END`PLN `END' + + '`KWDas`END`PLN test `END`KWDshow`END`PLN foo`END`PUN,`END`PLN bar`END`PUN;`END' + + '`PLN\n' + + '\n' + + '`END`KWDclass`END`PLN `END`TYPPoint`END`PLN `END`PUN{`END`PLN\n' + + ' `END`KWDfinal`END`PLN `END`TYPnum`END`PLN x`END`PUN,`END`PLN y`END`PUN;`END`PLN\n' + + '\n' + + ' `END`TYPPoint`END`PUN(`END`KWDthis`END`PUN.`END`PLNx`END' + + '`PUN,`END`PLN `END`KWDthis`END`PUN.`END`PLNy`END`PUN);`END`PLN\n' + + ' `END`TYPPoint`END`PUN.`END`PLNzero`END`PUN()`END`PLN `END' + + '`PUN:`END`PLN x `END`PUN=`END`PLN `END`LIT0`END`PUN,`END' + + '`PLN y `END`PUN=`END`PLN `END`LIT0`END`PUN;`END`PLN `END' + + '`COM// Named constructor`END`PLN\n' + + ' `END' + + '`COM// with an initializer list.`END`PLN\n' + + '\n' + + ' `END`TYPnum`END`PLN distanceTo`END`PUN(`END`TYPPoint`END`PLN other`END' + + '`PUN)`END`PLN `END`PUN{`END`PLN\n' + + ' `END`KWDvar`END`PLN dx `END`PUN=`END`PLN x `END`PUN-`END' + + '`PLN other`END`PUN.`END`PLNx`END`PUN;`END`PLN\n' + + ' `END`KWDvar`END`PLN dy `END`PUN=`END`PLN y `END`PUN-`END' + + '`PLN other`END`PUN.`END`PLNy`END`PUN;`END`PLN\n' + + ' `END`KWDreturn`END`PLN sqrt`END`PUN(`END`PLNdx `END`PUN*`END' + + '`PLN dx `END`PUN+`END`PLN dy `END`PUN*`END`PLN dy`END`PUN);`END' + + '`PLN\n' + + ' `END`PUN}`END`PLN\n' + + '`END`PUN}`END`PLN\n' + + '\n' + + '`END`COM// This is a single-line comment.`END`PLN\n' + + '\n' + + '`END`COM/*\n' + + 'This is a\n' + + 'multiline comment.\n' + + '*/`END`PLN\n' + + '\n' + + 'main`END`PUN()`END`PLN `END`PUN{`END`PLN\n' + + ' `END`TYPPoint`END`PLN p `END`PUN=`END`PLN `END`KWDnew`END' + + '`PLN `END`TYPPoint`END`PUN(`END`LIT7`END`PUN,`END`PLN `END' + + '`LIT12`END`PUN);`END`PLN\n' + + ' `END`TYPString`END`PLN thing `END`PUN=`END`PLN `END' + + '`STR\'It\\\'s awesome!\'`END`PUN;`END`PLN\n' + + ' `END`TYPString`END`PLN thing2 `END`PUN=`END`PLN `END' + + '`STR\'\'\'\n' + + 'This is a test! \\\'\'\'\n' + + 'This is the end of the test\'\'\'`END`PUN;`END`PLN\n' + + ' `END`TYPString`END`PLN thing3 `END`PUN=`END`PLN `END' + + '`STRr\"\"\"\n' + + 'This is a raw\n' + + 'multiline string!\"\"\"`END`PUN;`END`PLN\n' + + ' `END`TYPnum`END`PLN x `END`PUN=`END`PLN `END`LIT0x123ABC`END`PUN;`END`PLN\n' + + ' `END`TYPnum`END`PLN y `END`PUN=`END`PLN `END`LIT1.8e-12`END`PUN;`END`PLN\n' + + ' `END`TYPbool`END`PLN flag `END`PUN=`END`PLN `END`KWDfalse`END' + + '`PUN;`END`PLN\n' + + ' `END`TYPString`END`PLN raw `END`PUN=`END`PLN `END' + + '`STRr\"This is a raw string, where \\n doesn\'t matter\"`END' + + '`PUN;`END`PLN\n' + + '`END`PUN}`END' + ), + tcl_lang: ( + '`COM#!/bin/tclsh`END`PLN\n' + + '`END`KWDproc`END`PLN fib `END`OPN{`END`PLNn`END`CLO}`END`PLN `END`OPN{`END`PLN\n' + + ' `END`KWDset`END`PLN a `END`LIT0`END`PLN\n' + + ' `END`KWDset`END`PLN b `END`LIT1`END`PLN\n' + + ' `END`KWDwhile`END`PLN `END`OPN{`END`PUN$`END`PLNn `END`PUN>`END`PLN `END`LIT0`END`CLO}`END`PLN `END`OPN{`END`PLN\n' + + ' `END`KWDset`END`PLN tmp `END`PUN$`END`PLNa\n' + + ' `END`KWDset`END`PLN a `END`PUN[`END`KWDexpr`END`PLN `END`PUN$`END`PLNa `END`PUN+`END`PLN `END`PUN$`END`PLNb`END`PUN]`END`PLN\n' + + ' `END`KWDset`END`PLN b `END`PUN$`END`PLNtmp\n' + + ' `END`KWDincr`END`PLN n `END`LIT-1`END`PLN\n' + + ' `END`CLO}`END`PLN\n' + + ' `END`KWDreturn`END`PLN `END`PUN$`END`PLNa\n' + + '`END`CLO}`END' + ), + r_lang: ( + '`COM### Example R script for syntax highlighting`END`PLN\n' + + '\n' + + '`END`COM# This is a comment`END`PLN\n' + + '\n' + + '`END`COM## Valid names`END`PLN\n' + + 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV0123456789._a `END`PUN<-`END`PLN `END`LITNULL`END`PLN\n' + + '.foo_ `END`PUN<-`END`PLN `END`LITNULL`END`PLN\n' + + '._foo `END`PUN<-`END`PLN `END`LITNULL`END`PLN\n' + + '\n' + + '`END`COM## Invalid names`END`PLN\n' + + '`END`LIT0`END`PLNabc `END`PUN<-`END`PLN `END`LITNULL`END`PLN\n' + + '`END`LIT.0`END`PLNabc `END`PUN<-`END`PLN `END`LITNULL`END`PLN\n' + + 'abc`END`PUN+`END`PLNcde `END`PUN<-`END`PLN `END`LITNULL`END`PLN\n' + + '\n' + + '`END`COM## Reserved Words`END`PLN\n' + + '`END`LITNA`END`PLN\n' + + '`END`LITNA_integer_`END`PLN\n' + + '`END`LITNA_real_`END`PLN\n' + + '`END`LITNA_character_`END`PLN\n' + + '`END`LITNA_complex_`END`PLN\n' + + '`END`LITNULL`END`PLN\n' + + '`END`LITNaN`END`PLN\n' + + '`END`LITInf`END`PLN\n' + + '`END`COM## Not reserved`END`PLN\n' + + 'NULLa `END`PUN<-`END`PLN `END`LITNULL`END`PLN\n' + + 'NULL1 `END`PUN<-`END`PLN `END`LITNULL`END`PLN\n' + + 'NULL. `END`PUN<-`END`PLN `END`LITNULL`END`PLN\n' + + 'NA_foo_ `END`PUN<-`END`PLN `END`LITNULL`END`PLN\n' + + '\n' + + '`END`COM## Numbers`END`PLN\n' + + '`END`LIT12345678901`END`PLN\n' + + '`END`LIT123456.78901`END`PLN\n' + + '`END`LIT123e3`END`PLN\n' + + '`END`LIT123E3`END`PLN\n' + + '`END`LIT1.23e-3`END`PLN\n' + + '`END`LIT1.23e3`END`PLN\n' + + '`END`LIT1.23e-3`END`PLN\n' + + '`END`COM## integer constants`END`PLN\n' + + '`END`LIT123L`END`PLN\n' + + '`END`LIT1.23L`END`PLN\n' + + '`END`COM## imaginary numbers`END`PLN\n' + + '`END`LIT123i`END`PLN\n' + + '`END`LIT-123i`END`PLN\n' + + '`END`LIT123e4i`END`PLN\n' + + '`END`LIT123e-4i`END`PLN\n' + + '`END`COM## Hex numbers`END`PLN\n' + + '`END`LIT0xabcdefABCDEF01234`END`PLN\n' + + '`END`LIT0xabcp123`END`PLN\n' + + '`END`LIT0xabcP123`END`PLN\n' + + '`END`COM## Not hex`END`PLN\n' + + '`END`LIT0`END`PLNxg\n' + + '\n' + + '`END`COM## Special operators %xyz%`END`PLN\n' + + '`END`COM## %xyz%`END`PLN\n' + + '`END`LIT1`END`PLN `END`PUN%%`END`PLN `END`LIT2`END`PLN\n' + + 'diag`END`PUN(`END`LIT2`END`PUN)`END`PLN `END`PUN%*%`END`PLN diag`END`PUN(`END`LIT2`END`PUN)`END`PLN\n' + + '`END`LIT1`END`PLN `END`PUN%/%`END`PLN `END`LIT2`END`PLN\n' + + '`END`LIT1`END`PLN `END`PUN%in%`END`PLN `END`LIT1`END`PUN:`END`LIT10`END`PLN\n' + + 'diag`END`PUN(`END`LIT2`END`PUN)`END`PLN `END`PUN%o%`END`PLN diag`END`PUN(`END`LIT2`END`PUN)`END`PLN\n' + + 'diag`END`PUN(`END`LIT2`END`PUN)`END`PLN `END`PUN%x%`END`PLN diag`END`PUN(`END`LIT2`END`PUN)`END`PLN\n' + + '`END`STR`%foo bar%``END`PLN `END`PUN<-`END`PLN `END`KWDfunction`END`PUN(`END`PLNx`END`PUN,`END`PLN y`END`PUN)`END`PLN x `END`PUN+`END`PLN y\n' + + '`END`LIT1`END`PLN `END`PUN%foo bar%`END`PLN `END`LIT2`END`PLN\n' + + '\n' + + '`END`COM## Control Structures (3.2) and Function`END`PLN\n' + + '`END`COM## if, else`END`PLN\n' + + '`END`KWDif`END`PLN `END`PUN(`END`LITTRUE`END`PUN)`END`PLN print`END`PUN(`END`STR"foo"`END`PUN)`END`PLN `END`KWDelse`END`PLN print`END`PUN(`END`STR"bar"`END`PUN)`END`PLN\n' + + '`END`COM## For, in`END`PLN\n' + + '`END`KWDfor`END`PUN(`END`PLNi `END`KWDin`END`PLN `END`LIT1`END`PUN:`END`LIT5`END`PUN)`END`PLN `END`PUN{`END`PLN\n' + + ' print`END`PUN(`END`PLNi`END`PUN)`END`PLN\n' + + '`END`PUN}`END`PLN\n' + + '`END`COM## While, break`END`PLN\n' + + 'i `END`PUN<-`END`PLN `END`LIT1`END`PLN\n' + + '`END`KWDwhile`END`PLN `END`PUN(`END`LITTRUE`END`PUN)`END`PLN `END`PUN{`END`PLN\n' + + ' i `END`PUN<-`END`PLN i `END`PUN+`END`PLN `END`LIT1`END`PLN\n' + + ' `END`KWDif`END`PLN `END`PUN(`END`PLNi `END`PUN>`END`PLN `END`LIT3`END`PUN)`END`PLN `END`KWDbreak`END`PLN\n' + + '`END`PUN}`END`PLN\n' + + '`END`COM## Repeat`END`PLN\n' + + '`END`KWDrepeat`END`PLN `END`PUN{`END`LIT1+1`END`PUN}`END`PLN\n' + + '`END`COM## Switch`END`PLN\n' + + 'x `END`PUN<-`END`PLN `END`LIT3`END`PLN\n' + + '`END`KWDswitch`END`PUN(`END`PLNx`END`PUN,`END`PLN `END`LIT2+2`END`PUN,`END`PLN mean`END`PUN(`END`LIT1`END`PUN:`END`LIT10`END`PUN),`END`PLN rnorm`END`PUN(`END`LIT5`END`PUN))`END`PLN\n' + + '`END`COM## Function, dot-dot-dot, return`END`PLN\n' + + 'foo `END`PUN<-`END`PLN `END`KWDfunction`END`PUN(`END`LIT...`END`PUN)`END`PLN `END`PUN{`END`PLN\n' + + ' `END`KWDreturn`END`PUN(`END`PLNsum`END`PUN(`END`LIT...`END`PUN))`END`PLN\n' + + '`END`PUN}`END`PLN\n' + + '`END`COM# Not keywords`END`PLN\n' + + 'functiona `END`PUN<-`END`PLN `END`LIT2`END`PLN `END`PUN+`END`PLN `END`LIT2`END`PLN\n' + + 'function. `END`PUN<-`END`PLN `END`LIT2`END`PLN `END`PUN+`END`PLN `END`LIT2`END`PLN\n' + + 'function1 `END`PUN<-`END`PLN `END`LIT2`END`PLN `END`PUN+`END`PLN `END`LIT2`END`PLN\n' + + '\n' + + '\n' + + '`END`COM## Grouping Tokens 10.3.7`END`PLN\n' + + '`END`COM## Parentheses`END`PLN\n' + + '`END`LIT1`END`PLN `END`PUN+`END`PLN `END`PUN(`END`LIT2`END`PLN `END`PUN+`END`PLN `END`LIT3`END`PUN)`END`PLN\n' + + '`END`COM## brackets`END`PLN\n' + + 'foo `END`PUN<-`END`PLN `END`KWDfunction`END`PUN(`END`PLNa`END`PUN)`END`PLN `END`PUN{`END`PLN\n' + + ' a `END`PUN+`END`PLN `END`LIT1`END`PLN\n' + + '`END`PUN}`END`PLN\n' + + '\n' + + '`END`COM## Indexing 10.3.8`END`PLN\n' + + '`END`COM## []`END`PLN\n' + + 'bar `END`PUN<-`END`PLN `END`LIT1`END`PUN:`END`LIT10`END`PLN\n' + + 'bar`END`PUN[`END`LIT3`END`PUN]`END`PLN\n' + + '`END`COM## [[]]`END`PLN\n' + + 'foo `END`PUN<-`END`PLN list`END`PUN(`END`PLNa`END`PUN=`END`LIT1`END`PUN,`END`PLN b`END`PUN=`END`LIT2`END`PUN,`END`PLN c`END`PUN=`END`LIT3`END`PUN)`END`PLN\n' + + 'foo`END`PUN[[`END`STR"a"`END`PUN]]`END`PLN\n' + + '`END`COM## $`END`PLN\n' + + 'foo`END`PUN$`END`PLNa\n' + + 'foo`END`PUN$`END`STR"a"`END`PLN\n' + + '\n' + + '`END`COM## Operators`END`PLN\n' + + '`END`LIT2`END`PLN `END`PUN-`END`PLN `END`LIT2`END`PLN\n' + + '`END`LIT2`END`PLN `END`PUN+`END`PLN `END`LIT2`END`PLN\n' + + '`END`LIT2`END`PLN `END`PUN~`END`PLN `END`LIT2`END`PLN\n' + + '`END`PUN!`END`PLN `END`LITTRUE`END`PLN\n' + + '`END`PUN?`END`STR"help"`END`PLN\n' + + '`END`LIT1`END`PUN:`END`LIT2`END`PLN\n' + + '`END`LIT2`END`PLN `END`PUN*`END`PLN `END`LIT2`END`PLN\n' + + '`END`LIT2`END`PLN `END`PUN/`END`PLN `END`LIT2`END`PLN\n' + + '`END`LIT2`END`PUN^`END`LIT2`END`PLN\n' + + '`END`LIT2`END`PLN `END`PUN<`END`PLN `END`LIT2`END`PLN\n' + + '`END`LIT2`END`PLN `END`PUN>`END`PLN `END`LIT2`END`PLN\n' + + '`END`LIT2`END`PLN `END`PUN==`END`PLN `END`LIT2`END`PLN\n' + + '`END`LIT2`END`PLN `END`PUN>=`END`PLN `END`LIT2`END`PLN\n' + + '`END`LIT2`END`PLN `END`PUN<=`END`PLN `END`LIT2`END`PLN\n' + + '`END`LIT2`END`PLN `END`PUN!=`END`PLN `END`LIT2`END`PLN\n' + + '`END`LITTRUE`END`PLN `END`PUN&`END`PLN `END`LITFALSE`END`PLN\n' + + '`END`LITTRUE`END`PLN `END`PUN&&`END`PLN `END`LITFALSE`END`PLN\n' + + '`END`LITTRUE`END`PLN `END`PUN|`END`PLN `END`LITFALSE`END`PLN\n' + + '`END`LITTRUE`END`PLN `END`PUN||`END`PLN `END`LITFALSE`END`PLN\n' + + 'foo `END`PUN<-`END`PLN `END`LIT2`END`PLN `END`PUN+`END`PLN `END`LIT2`END`PLN\n' + + 'foo `END`PUN=`END`PLN `END`LIT2`END`PLN `END`PUN+`END`PLN `END`LIT2`END`PLN\n' + + '`END`LIT2`END`PLN `END`PUN+`END`PLN `END`LIT2`END`PLN `END`PUN->`END`PLN foo\n' + + 'foo `END`PUN<<-`END`PLN `END`LIT2`END`PLN `END`PUN+`END`PLN `END`LIT2`END`PLN\n' + + '`END`LIT2`END`PLN `END`PUN+`END`PLN `END`LIT2`END`PLN `END`PUN->>`END`PLN foo\n' + + 'base`END`PUN:::`END`PLNsum\n' + + 'base`END`PUN::`END`PLNsum\n' + + '\n' + + '`END`COM## Strings`END`PLN\n' + + 'foo `END`PUN<-`END`PLN `END`STR"hello, world!"`END`PLN\n' + + 'foo `END`PUN<-`END`PLN `END`STR\'hello, world!\'`END`PLN\n' + + 'foo `END`PUN<-`END`PLN `END`STR"Hello, \'world!"`END`PLN\n' + + 'foo `END`PUN<-`END`PLN `END`STR\'Hello, "world!\'`END`PLN\n' + + 'foo `END`PUN<-`END`PLN `END`STR\'Hello, \\\'world!\\\'\'`END`PLN\n' + + 'foo `END`PUN<-`END`PLN `END`STR"Hello, \\"world!\\""`END`PLN\n' + + 'foo `END`PUN<-`END`PLN `END`STR"Hello,\n' + + 'world!"`END`PLN\n' + + 'foo `END`PUN<-`END`PLN `END`STR\'Hello,\n' + + 'world!\'`END`PLN\n' + + '\n' + + '`END`COM## Backtick strings`END`PLN\n' + + '`END`STR`foo123 +!"bar\'baz``END`PLN `END`PUN<-`END`PLN `END`LIT2`END`PLN `END`PUN+`END`PLN `END`LIT2`END' + ), + mumps: ( + '`PLNHDR `END`COM; -- prt/display header`END`PLN\n' + + ' `END`KWDN`END`PLN `END`KWDX`END`PUN,`END`KWDI`END`PLN\n' + + ' `END`KWDI`END`PLN `END`PUN\'`END`DEC$D`END`PUN(`END`PLNVALMHDR`END`PUN)`END`PLN `END`KWDX`END`PUN:`END`DEC$G`END`PUN(`END`PLNVALM`END`PUN(`END`STR"HDR"`END`PUN))]`END`STR""`END`PLN VALM`END`PUN(`END`STR"HDR"`END`PUN)`END`PLN\n' + + ' `END`COM; -- prt hdr line`END`PLN\n' + + ' `END`KWDW`END`PUN:\'`END`DEC$D`END`PUN(`END`PLNVALMPG1`END`PUN)`END`PLN `END`PUN@`END`PLNIOF `END`KWDK`END`PLN VALMPG1\n' + + ' `END`KWDW`END`PUN:`END`PLNVALMCC `END`DEC$C`END`PUN(`END`LIT13`END`PUN)_`END`PLNIOUON`END`PUN_`END`DEC$C`END`PUN(`END`LIT13`END`PUN)_`END`PLNIOINHI`END`PUN_`END`DEC$C`END`PUN(`END`LIT13`END`PUN)`END`PLN `END`COM; -- turn on undln/hi`END`PLN\n' + + ' `END`KWDI`END`PLN `END`DEC$E`END`PUN(`END`PLNIOST`END`PUN,`END`LIT1`END`PUN,`END`LIT2`END`PUN)=`END`STR"C-"`END`PLN `END`KWDD`END`PLN IOXY^VALM4`END`PUN(`END`LIT0`END`PUN,`END`LIT0`END`PUN)`END`PLN `END`COM; -- position cursor`END`PLN\n' + + ' `END`KWDW`END`PLN `END`DEC$E`END`PUN(`END`PLNVALM`END`PUN(`END`STR"TITLE"`END`PUN),`END`LIT1`END`PUN,`END`LIT30`END`PUN)`END`PLN `END`COM; -- prt title`END`PLN\n' + + ' `END`KWDW`END`PUN:`END`PLNVALMCC IOINORM`END`PUN,`END`PLNIOUON `END`COM; -- turn off hi`END`PLN\n' + + ' `END`KWDW`END`PLN `END`DEC$J`END`PUN(`END`STR""`END`PUN,`END`LIT30`END`PUN-`END`DEC$L`END`PUN(`END`PLNVALM`END`PUN(`END`STR"TITLE"`END`PUN)))`END`PLN `END`COM; -- fill in w/blanks`END`PLN\n' + + ' `END`KWDI`END`PLN `END`DEC$E`END`PUN(`END`PLNIOST`END`PUN,`END`LIT1`END`PUN,`END`LIT2`END`PUN)=`END`STR"C-"`END`PLN `END`KWDW`END`PLN `END`DEC$C`END`PUN(`END`LIT13`END`PUN)`END`PLN `END`KWDD`END`PLN IOXY^VALM4`END`PUN(`END`LIT30`END`PUN,`END`LIT0`END`PUN)`END`PLN `END`COM; -- position cursor`END`PLN\n' + + ' `END`KWDW`END`PLN `END`DEC$J`END`PUN(`END`STR""`END`PUN,((`END`PLNVALMWD`END`LIT-80`END`PUN)/`END`LIT2`END`PUN)),`END`PLN$$HTE^XLFDT`END`PUN(`END`DEC$H`END`PUN,`END`LIT1`END`PUN),`END`DEC$J`END`PUN(`END`STR""`END`PUN,`END`LIT10`END`PUN+((`END`PLNVALMWD`END`LIT-80`END`PUN)/`END`LIT2`END`PUN)),`END`STR"Page: "`END`PUN,`END`DEC$J`END`PUN(`END`PLNVALMPGE`END`PUN,`END`LIT4`END`PUN),`END`STR" of "`END`PUN,`END`DEC$J`END`PUN(`END`PLN$$PAGE^VALM4`END`PUN(`END`PLNVALMCNT`END`PUN,`END`PLNVALM`END`PUN(`END`STR"LINES"`END`PUN)),`END`LIT4`END`PUN)_`END`DEC$S`END`PUN(`END`DEC$D`END`PUN(`END`PLNVALMORE`END`PUN):`END`STR"+"`END`PUN,`END`LIT1`END`PUN:`END`STR" "`END`PUN)`END`PLN `END`COM; -- prt rest of hdr`END`PLN\n' + + ' `END`KWDW`END`PUN:`END`PLNVALMCC IOUOFF `END`KWDI`END`PLN `END`DEC$E`END`PUN(`END`PLNIOST`END`PUN,`END`LIT1`END`PUN,`END`LIT2`END`PUN)=`END`STR"C-"`END`PLN `END`KWDD`END`PLN IOXY^VALM4`END`PUN(`END`LIT0`END`PUN,`END`LIT0`END`PUN)`END`PLN `END`COM; -- turn off undln`END`PLN\n' + + ' `END`KWDF`END`PLN `END`KWDI`END`PUN=`END`LIT1`END`PUN:`END`LIT1`END`PUN:`END`PLNVALM`END`PUN(`END`STR"TM"`END`PUN)`END`LIT-3`END`PLN `END`KWDW`END`PLN `END`PUN!,`END`DEC$S`END`PUN(\'`END`DEC$D`END`PUN(`END`PLNVALMHDR`END`PUN(`END`KWDI`END`PUN)):`END`STR""`END`PUN,`END`DEC$L`END`PUN(`END`PLNVALMHDR`END`PUN(`END`KWDI`END`PUN))>(`END`PLNVALMWD`END`LIT-1`END`PUN):`END`PLN$`END`DEC$EXTRACT`END`PLN^VALM4`END`PUN(`END`DEC$G`END`PUN(`END`PLNVALMHDR`END`PUN(`END`KWDI`END`PUN))),`END`LIT1`END`PUN:`END`PLNVALMHDR`END`PUN(`END`KWDI`END`PUN))`END`PLN `END`COM; -- prt hdr`END`PLN\n' + + ' `END`KWDQ`END' + ), + basic_lang: ( + '`LIT200`END`PLN `END`COMREM ----- method teardown`END`PLN\n' + + '`END`LIT210`END`PLN `END`KWDPRINT`END`PLN `END`STR"green"`END`PLN\n' + + '`END`LIT220`END`PLN `END`KWDRETURN`END`PLN\n' + + '`END`LIT470`END`PLN `END`KWDIF`END`PLN af`END`PUN=`END`LIT0`END`PLN `END`KWDTHEN`END`PLN `END`KWDGOTO`END`PLN `END`LIT520`END`PLN\n' + + '`END`LIT480`END`PLN `END`KWDFOR`END`PLN j`END`PUN=`END`LIT1`END`PLN `END`KWDTO`END`PLN af\n' + + '`END`LIT500`END`PLN ac`END`PUN=`END`PLNpf`END`PUN(`END`PLNj`END`PUN)`END`PLN `END`PUN:`END`PLN me$`END`PUN=`END`PLNSTR$`END`PUN(`END`PLNj`END`PUN)+`END`STR". factor"`END`PLN `END`PUN:`END`PLN `END`KWDGOSUB`END`PLN `END`LIT100`END`PLN\n' + + '`END`LIT510`END`PLN `END`KWDNEXT`END`PLN\n' + + '`END`LIT530`END`PLN `END`KWDRETURN`END`PLN\n' + + '`END`LIT1000`END`PLN `END`KWDDATA`END`PLN `END`STR"one"`END`PUN,`END`PLN `END`LIT1`END`PUN,`END`PLN `END`LIT0`END' + ), + pascal_lang: ( + '`COM(* some comment here *)`END`PLN\n' + + '`END`KWDPROCEDURE`END`PLN TestCase`END`PUN.`END`PLNAssertEquals`END`PUN(`END`PLNmsg`END`PUN:`END`PLNString`END`PUN;`END`PLN expect`END`PUN,`END`PLN act`END`PUN:`END`PLNLongint`END`PUN);`END`PLN\n' + + '`END`KWDVAR`END`PLN ex`END`PUN,`END`PLN ac`END`PUN:`END`PLNString`END`PUN;`END`PLN\n' + + '`END`KWDBEGIN`END`PLN\n' + + ' `END`KWDIF`END`PLN expect `END`PUN<>`END`PLN act `END`KWDTHEN`END`PLN\n' + + ' `END`KWDBEGIN`END`PLN\n' + + ' Str`END`PUN(`END`PLNexpect`END`PUN,`END`PLN ex`END`PUN);`END`PLN\n' + + ' Fail`END`PUN(`END`PLNConcat`END`PUN(`END`PLNmsg`END`PUN,`END`STR\' expected \'`END`PUN,`END`PLNex`END`PUN,`END`STR\' but was \'`END`PUN,`END`PLNac`END`PUN));`END`PLN\n' + + ' `END`KWDEND`END`PUN;`END`PLN\n' + + '\n' + + ' factors `END`PUN:=`END`PLN new`END`PUN(`END`PLNArrayListPtr`END`PUN,`END`PLN Init`END`PUN);`END`PLN\n' + + '\n' + + ' `END`KWDFOR`END`PLN candidate `END`PUN:=`END`PLN `END`LIT2`END`PLN `END`KWDTO`END`PLN i `END`KWDDO`END`PLN\n' + + ' `END`KWDBEGIN`END`PLN\n' + + ' `END`KWDWHILE`END`PLN i `END`KWDMOD`END`PLN candidate `END`PUN=`END`PLN `END`LIT0`END`PLN `END`KWDDO`END`PLN\n' + + ' `END`KWDBEGIN`END`PLN\n' + + ' factors`END`PUN^.`END`PLNAdd`END`PUN(`END`PLNcandidate`END`PUN);`END`PLN\n' + + ' i `END`PUN:=`END`PLN i `END`KWDDIV`END`PLN candidate`END`PUN;`END`PLN\n' + + ' `END`KWDEND`END`PUN;`END`PLN\n' + + ' `END`KWDEND`END`PUN;`END`PLN\n' + + '`END`KWDEND`END`PUN;`END' + ), + kotlin: ( + '`KWDpackage`END`PLN test`END`PUN;`END`PLN\n' + + '\n' + + '`END`KWDimport`END`PLN kotlin`END`PUN.`END`TYPInt`END`PLN\n' + + '\n' + + '`END`COM// Single line comment`END`PLN\n' + + '`END`COM/*\n' + + ' * Multiline\n' + + ' * comment\n' + + ' */`END`PLN\n' + + '\n' + + '`END`KWDtypealias`END`PLN `END`TYPSomeNumber`END`PLN `END`PUN=`END`PLN `END`TYPInt`END`PLN\n' + + '\n' + + '`END`KWDval`END`PLN number`END`PUN:`END`PLN `END`TYPLong`END`PLN `END`PUN=`END`PLN `END`LIT1_000L`END`PLN\n' + + '`END`KWDvar`END`PLN float`END`PUN:`END`PLN `END`TYPFloat`END`PLN `END`PUN=`END`PLN `END`LIT12.34f`END`PLN\n' + + '`END`LIT0xFF_FF`END`PLN\n' + + '`END`LIT3.14`END`PLN\n' + + '\n' + + '`END`LIT314e-2`END`PLN\n' + + '`END`LIT0.314e1`END`PLN\n' + + '\n' + + '`END`KWDprotected`END`PLN `END`KWDoverride`END`PLN `END`KWDfun`END`PLN ifBoolean`END`PUN(`END`PLNcondition`END`PUN:`END`PLN `END`TYPBoolean`END`PUN?`END`PLN `END`PUN=`END`PLN `END`LITnull`END`PUN)`END' + + '`PLN `END`PUN{}`END`PLN\n' + + '\n' + + '`END`PUN::`END`PLNifBoolean\n' + + '\n' + + '`END`KWDconstructor`END`PUN()`END`PLN `END`PUN:`END`PLN `END`KWDsuper`END`PUN()`END`PLN\n' + + '\n' + + '`END`STR"\\\"true\\\""`END`PLN\n' + + '`END`STR\'a\'`END`PLN\n' + + '\n' + + '`END`STR"""\n' + + 'aaaaaaaaaaa\n' + + '"""`END`PLN\n' + + '\n' + + '`END`LITloop@`END`PLN `END`KWDfor`END`PUN()`END`PLN\n' + + '\n' + + '`END`KWDbreak`END`PLN `END`LIT@loop`END`PLN\n' + + '\n' + + '`END`KWDenum class`END`PLN `END`TYP\`true\``END`PLN\n' + + '\n' + + '`END`KWDdata class`END`PLN `END`TYPPerson`END`PUN(`END`KWDval`END`PLN name`END`PUN:`END`PLN `END`TYPString`END`PUN)`END`PLN\n' + + '\n' + + '`END`KWDenum class`END`PLN `END`TYPSize`END`PLN `END`PUN{`END`PLN\n' + + ' BIG`END`PUN,`END`PLN MEDIUM`END`PUN,`END`PLN SMALL\n' + + '`END`PUN}`END`PLN\n' + + '\n' + + '`END`KWDclass`END`PLN `END`TYPBall`END`PUN(`END`KWDval`END`PLN color`END`PUN:`END`PLN `END`TYPString`END`PUN,`END`PLN `END`KWDval`END`PLN size`END`PUN:`END`PLN `END`TYPSize`END`PUN)`END`PLN `END`PUN{`END`PLN\n' + + ' `END`KWDcompanion object`END`PLN `END`PUN{}`END`PLN\n' + + '\n' + + ' `END`KWDfun`END`PLN isBig`END`PUN()`END`PLN `END`PUN=`END`PLN size `END`PUN==`END`PLN `END`TYPSize`END`PUN.`END`PLNBIG\n' + + '\n' + + ' `END`KWDval`END`PLN isMedium`END`PUN:`END`PLN `END`TYPBoolean`END`PLN\n' + + ' `END`KWDget`END`PUN()`END`PLN `END`PUN=`END`PLN size `END`PUN==`END`PLN `END`TYPSize`END`PUN.`END`PLNMEDIUM\n' + + '`END`PUN}`END`PLN\n' + + '\n' + + '`END`KWDfun`END`PLN `END`TYPBoolean`END`PUN?.`END`PLNisNull`END`PUN():`END`PLN `END`TYPBoolean`END`PLN `END`PUN=`END`PLN `END`KWDthis`END`PLN `END`PUN==`END`PLN `END`LITnull`END`PLN\n' + + '\n' + + '`END`KWDfun`END`PLN `END`TYPBoolean`END`PUN?.`END`PLNgetOrThrow`END`PUN():`END`PLN `END`TYPBoolean`END`PLN `END`PUN=`END`PLN `END`KWDthis`END`PLN `END`PUN?:`END`PLN `END`KWDthrow`END`PLN `END`TYPException`END`PUN()`END' + ), + llvm: ( + '`COM; Declare the string constant as a global constant.`END`PLN\n' + + '@.str `END`PUN=`END`PLN `END`KWDprivate`END`PLN `END`KWDunnamed_addr`END`PLN `END`KWDconstant`END`PLN `END`PUN[`END`LIT13`END`PLN `END`KWDx`END`PLN `END`KWDi8`END`PUN]`END`PLN `END`KWDc`END`STR"hello world\\0A\\00"`END`PLN\n' + + '\n' + + '`END`COM; External declaration of the puts function`END`PLN\n' + + '`END`KWDdeclare`END`PLN `END`KWDi32`END`PLN @puts`END`PUN(`END`KWDi8`END`PUN*`END`PLN `END`KWDnocapture`END`PUN)`END`PLN `END`KWDnounwind`END`PLN\n' + + '\n' + + '`END`COM; Definition of main function`END`PLN\n' + + '`END`KWDdefine`END`PLN `END`KWDi32`END`PLN @main`END`PUN()`END`PLN `END`PUN{`END`PLN `END`COM; i32()*`END`PLN\n' + + ' `END`COM; Convert [13 x i8]* to i8 *...`END`PLN\n' + + ' %cast210 `END`PUN=`END`PLN `END`KWDgetelementptr`END`PLN `END`PUN[`END`LIT13`END`PLN `END`KWDx`END`PLN `END`KWDi8`END`PUN]*`END`PLN @.str`END`PUN,`END`PLN `END`KWDi64`END`PLN `END`LIT0`END`PUN,`END`PLN `END`KWDi64`END`PLN `END`LIT0`END`PLN\n' + + '\n' + + ' `END`COM; Call puts function to write out the string to stdout.`END`PLN\n' + + ' `END`KWDcall`END`PLN `END`KWDi32`END`PLN @puts`END`PUN(`END`KWDi8`END`PUN*`END`PLN %cast210`END`PUN)`END`PLN\n' + + ' `END`KWDret`END`PLN `END`KWDi32`END`PLN `END`LIT0`END`PLN\n' + + '`END`PUN}`END`PLN\n' + + '\n' + + '`END`COM; Named metadata`END`PLN\n' + + '!1 `END`PUN=`END`PLN `END`KWDmetadata`END`PLN !`END`PUN{`END`KWDi32`END`PLN `END`LIT42`END`PUN}`END`PLN\n' + + '!foo `END`PUN=`END`PLN !`END`PUN{`END`PLN!1`END`PUN,`END`PLN `END`KWDnull`END`PUN}`END' + ), + issue217: ( + '`KWDif`END`PUN(!`END`STR/^https?:\\/\\//`END`PLNi`END`PUN.`END`PLNtest`END`PUN(`END`PLNval`END`PUN)`END`PLN `END`PUN&&`END`PLN foo `END`PUN==`END`PLN `END`STR\'bar\'`END`PUN)`END`PLN `END`PUN{`END`PLN\n' + + ' val `END`PUN=`END`PLN `END`STR\'http://\'`END`PLN `END`PUN+`END`PLN val`END`PUN;`END`PLN\n' + + '`END`PUN}`END' + ), + matlab: ( + '`COM%%%%%%%%%%%%%%%%%% DATA TYPES %%%%%%%%%%%%%%%%%%`END`PLN\n' + + '\n' + + '`ENDv`END`PLN `END`PUN=`END`PLN `END`TAG[`END`LIT1`END`PUN,`END`LIT2`END`PUN,`END`LIT3`END`PUN;`END`LIT4`END`PUN,`END`LIT5`END`PUN,`END`LIT6`END`TAG]`END`PUN;`END`PLN\n' + + '`ENDv`END`TAG(`ENDv`END`PUN>`END`LIT4`END`TAG)`END`PLN `END`PUN=`END`PLN `END`LIT0`END`PUN;`END`PLN\n' + + '\n' + + '`ENDs`END`PLN `END`PUN=`END`PLN `END`TYPstruct`END`TAG(`END`STR\'key\'`END`PUN,`END`LIT1`END`PUN,`END`PLN `END`STR\'key2\'`END`PUN,`END`STR\'string\'`END`TAG)`END`PUN;`END`PLN\n' + + '`ENDs.key`END`PLN `END`PUN=`END`PLN `END`LIT2`END`PUN;`END`PLN\n' + + '\n' + + '`ENDC`END`PLN `END`PUN=`END`PLN `END`TYPcell`END`TAG(`END`LIT1`END`PUN,`END`LIT2`END`TAG)`END`PUN;`END`PLN\n' + + '`ENDC`END`TAG{`END`LIT1`END`PUN,`END`LIT1`END`TAG}`END`PLN `END`PUN=`END`PLN `END`LIT0`END`PUN:`END`LIT9`END`PUN;`END`PLN\n' + + '\n' + + '`END`TYPdouble`END`TAG(`END`LIT1`END`TAG)`END`PLN\n' + + '`END`TYPsingle`END`TAG(`END`LIT1`END`TAG)`END`PLN\n' + + '`END`TYPuint8`END`TAG(`END`LIT1`END`TAG)`END`PLN\n' + + '`END`TYPint8`END`TAG(`END`LIT1`END`TAG)`END`PLN\n' + + '\n' + + '`END`COM%%%%%%%%%%%%%%%%%% STRINGS & TRANSPOSE %%%%%%%%%%%%%%%%%%`END`PLN\n' + + '\n' + + '`END`FUNplot`END`TAG(`ENDdata`END\'`END`TAG)`END`PUN;`END`PLN\n' + + '`END`FUNlegend`END`TAG(`ENDlabels`END`TAG)`END`PLN\n' + + '\n' + + '`ENDstr`END`PLN `END`PUN=`END`PLN `END`STR\'asdasd\'`END`PUN;`END`PLN `END`COM% this is a string`END`PLN\n' + + '`ENDstr`END`PLN `END`PUN=`END`PLN `END`STR\'asdas\'`END`PUN;`END`PLN\n' + + '`ENDstr`END`PLN `END`PUN=`END`PLN `END`STR\'sdasd\'\'sdasd\'`END`PUN;`END`PLN\n' + + '\n' + + '`ENDstr`END`PLN `END`PUN=`END`PLN `END`TAG[`END`STR\'one\'`END`PLN `END`STR\'two\'`END`PLN `END`STR\'three\'`END`TAG]`END`PUN;`END`PLN\n' + + '`ENDstr`END`PLN `END`PUN=`END`PLN `END`FUNstrcat`END`TAG(`END`STR\'one\'`END`PUN,`END`PLN `END`STR\'two\'`END`PUN,`END`PLN `END`STR\'three\'`END`TAG)`END`PUN;`END`PLN\n' + + '\n' + + '`END`COM% matrix transpose`END`PLN\n' + + '`ENDM`END`PLN `END`PUN=`END`PLN `END`FUNrand`END`TAG(`END`LIT3`END`PUN,`END`LIT3`END`TAG)`END\'`END`PUN;`END`PLN\n' + + '`ENDx`END`PLN `END`PUN=`END`PLN `ENDM`END`PUN.`END\'`END`PUN;`END`PLN\n' + + '`ENDx`END`PLN `END`PUN=`END`PLN `END`TAG[`END`LIT10`END`PLN `END`LIT20`END`PUN;`END`PLN `END`LIT30`END`PUN,`END`PLN `END`LIT40`END`TAG]`END\'`END`PUN;`END`PLN\n' + + '`END`FUNdisp`END`TAG(`ENDx`END\'`END`TAG)`END`PLN\n' + + '`END`FUNfprintf`END`TAG(`END`STR\'%d\\n\'`END`PUN,`END`PLN `ENDx`END`TAG(`END`PUN:`END`TAG)`END\'`END`TAG)`END`PLN `END`COM% with comment`END`PLN\n' + + '`END`TAG{`END`LIT1`END`PUN,`END`LIT2`END`TAG}`END\'`END`PLN `END`COM% another comment`END`PLN\n' + + '\n' + + '`END`COM%%%%%%%%%%%%%%%%%% LINE CONTINUATION %%%%%%%%%%%%%%%%%%`END`PLN\n' + + '\n' + + '`END`TAG[`END`LIT1`END`PLN `END`LIT20`END`PUN;`END`PLN `END...\n' + + '`END`LIT30`END`PLN `END`LIT4`END`TAG]`END`PLN\n' + + '\n' + + '`END`TAG[`END`STR\'gdgsd\'`END...\n' + + '`END`STR\'sdfs\'`END`TAG]`END`PLN\n' + + '\n' + + '`END`TAG{`END...\n' + + '`END`STR\'sdasd\'`END`PLN `END`PUN;`END`PLN\n' + + '`END`STR\'asdsad\'`END`TAG}`END`PLN\n' + + '\n' + + '`END`COM%%%%%%%%%%%%%%%%%% SYSTEM COMMANDS %%%%%%%%%%%%%%%%%%`END`PLN\n' + + '\n' + + '`END!touch file.txt`END`PLN\n' + + '\n' + + '`END`COM%%%%%%%%%%%%%%%%%% COMMAND OUTPUT %%%%%%%%%%%%%%%%%%`END`PLN\n' + + '\n' + + '`END>> `END`LIT1+1`END`PLN\n' + + '`ENDans`END`PLN `END`PUN=`END`PLN\n' + + ' `END`LIT2`END`PLN\n' + + '\n' + + '`END>> `END`LIT1+1`END`PLN\n' + + '\n' + + '`ENDans`END`PLN `END`PUN=`END`PLN\n' + + '\n' + + ' `END`LIT2`END`PLN\n' + + '\n' + + '`END`COM%%%%%%%%%%%%%%%%%% KEYWORDS %%%%%%%%%%%%%%%%%%`END`PLN\n' + + '\n' + + '`END`KWDfunction`END`PLN `ENDret`END`PLN `END`PUN=`END`PLN `ENDfcn`END`TAG(`ENDin`END`TAG)`END`PLN\n' + + ' `ENDret`END`PLN `END`PUN=`END`PLN `END`FUNsum`END`TAG(`ENDin`END`PUN.^`END`LIT2`END`TAG)`END`PUN;`END`PLN\n' + + '`END`KWDend`END`PLN\n' + + '\n' + + '`END`KWDclassdef`END`PLN `ENDCC`END`PLN `END`PUN<`END`PLN `END`FUNhandle`END`PLN\n' + + ' `ENDproperties`END`PLN `END`TAG(`ENDSetAccess`END`PLN `END`PUN=`END`PLN `ENDpublic`END`TAG)`END`PLN\n' + + ' `ENDx`END`PLN `END`PUN=`END`PLN `END`LIT0`END`PUN;`END`PLN\n' + + ' `END`KWDend`END`PLN\n' + + ' `END`FUNmethods`END`PLN\n' + + ' `END`KWDfunction`END`PLN `ENDthis`END`PLN `END`PUN=`END`PLN `ENDCC`END`TAG(`ENDvarargin`END`TAG)`END`PLN\n' + + ' `ENDthis.x`END`PLN `END`PUN=`END`PLN `END`LIT9`END`PUN;`END`PLN\n' + + ' `END`KWDend`END`PLN\n' + + ' `END`KWDend`END`PLN\n' + + '`END`KWDend`END`PLN\n' + + '\n' + + '`ENDx`END`PLN `END`PUN=`END`PLN `END`TAG[]`END`PUN;`END`PLN\n' + + '`END`KWDparfor`END`PLN `ENDi`END`PUN=`END`LIT1`END`PUN:`END`LIT10`END`PLN\n' + + ' `ENDx`END`TAG[`ENDi`END`TAG]`END`PLN `END`PUN=`END`PLN `ENDi`END`PUN;`END`PLN\n' + + '`END`KWDend`END`PLN\n' + + '\n' + + '`ENDtrue`END`PLN `END`PUN~=`END`PLN `ENDfalse`END`PLN\n' + + '\n' + + '`END`KWDif`END`PLN `ENDx`END`PUN==`END`LIT1`END`PLN\n' + + ' `ENDtrue`END`PLN\n' + + '`END`KWDelseif`END`PLN\n' + + ' `ENDfalse`END`PLN\n' + + '`END`KWDelse`END`PLN\n' + + ' `END`KWDreturn`END`PLN\n' + + '`END`KWDend`END`PLN\n' + + '\n' + + '`END`KWDwhile`END`PLN `ENDtrue`END`PLN\n' + + ' `END`KWDcontinue`END`PLN\n' + + ' `END`KWDbreak`END`PLN\n' + + '`END`KWDend`END`PLN\n' + + '\n' + + '`END`KWDtry`END`PLN\n' + + ' `END`FUNerror`END`TAG(`END`STR\'aa:aa\'`END`PUN,`END`PLN `END`STR\'asdasd\'`END`TAG)`END`PLN\n' + + '`END`KWDcatch`END`PLN `ENDME`END`PLN\n' + + ' `END`FUNwarning`END`TAG(`ENDME`END`TAG)`END`PLN\n' + + '`END`KWDend`END`PLN\n' + + '\n' + + '`END`KWDswitch`END`PLN `ENDx`END`PLN\n' + + ' `END`KWDcase`END`PLN `END`LIT1`END`PLN\n' + + ' `END`FUNdisp`END`TAG(`END`LIT1`END`TAG)`END`PLN\n' + + ' `END`KWDotherwise`END`PLN\n' + + ' `END`LIT0`END`PLN\n' + + '`END`KWDend`END`PLN\n' + + '\n' + + '`END`COM%%%%%%%%%%%%%%%%%% NUM LITERALS %%%%%%%%%%%%%%%%%%`END`PLN\n' + + '\n' + + '`END`LIT1`END`PLN\n' + + '`END`LIT1.`END`PLN\n' + + '`END`LIT.1`END`PLN\n' + + '`END`LIT1.0`END`PLN\n' + + '`END`LIT-1`END`PLN\n' + + '`END`LIT-1.`END`PLN\n' + + '`END`LIT-.1`END`PLN\n' + + '`END`LIT-1.0`END`PLN\n' + + '`END`LIT+10`END`PLN\n' + + '`END`LIT+01.`END`PLN\n' + + '`END`LIT+.1`END`PLN\n' + + '`END`LIT+1.0`END`PLN\n' + + '`END`LIT1e1`END`PLN\n' + + '`END`LIT1e-1`END`PLN\n' + + '`END`LIT1.e1`END`PLN\n' + + '`END`LIT1.e-1`END`PLN\n' + + '`END`LIT1.0e1`END`PLN\n' + + '`END`LIT1.0e-1`END`PLN\n' + + '`END`LIT.1e1`END`PLN\n' + + '`END`LIT.1e-1`END`PLN\n' + + '`END`LIT-.1e+1`END`PLN\n' + + '`END`LIT+1.e-1`END`PLN\n' + + '\n' + + '`END`LIT1i`END`PLN\n' + + '`END`LIT.10j`END`PLN\n' + + '`END`LIT-1.001i`END`PLN\n' + + '`END`LIT+1e-100j`END`PLN\n' + + '`END`LIT-.10e-01i`END`PLN\n' + + '\n' + + '`END`COM% unary vs binary operators`END`PLN\n' + + '`END`LIT1+1`END`PLN\n' + + '`END`LIT1`END`PUN+`END`PLN `END`LIT1`END`PLN\n' + + '`END`LIT1`END`PLN `END`LIT+1`END`PLN\n' + + '`END`LIT1`END`PLN `END`PUN+`END`PLN `END`LIT1`END`PLN\n' + + '`END`LIT+1+1`END`PLN\n' + + '`END`LIT+1`END`PUN+`END`PLN `END`LIT1`END`PLN\n' + + '`END`LIT+1`END`PLN `END`LIT+1`END`PLN\n' + + '`END`LIT+1`END`PLN `END`PUN+`END`PLN `END`LIT1`END`PLN\n' + + '\n' + + '`END`COM%%%%%%%%%%%%%%%%%% COMMENTS %%%%%%%%%%%%%%%%%%`END`PLN\n' + + '\n' + + '`END`COM% % comment % %`END`PLN\n' + + ' `END`COM% comment`END`PLN\n' + + '`END`COM% comment`END`PLN\n' + + '`END`COM%# comment`END`PLN\n' + + '`END`COM%% comment`END`PLN\n' + + '`END`COM%#x = sum(x);`END`PLN\n' + + '\n' + + '`END`COM%{\n' + + 'block comment\n' + + '%}`END`PLN\n' + + '\n' + + '`END`COM%{\n' + + '%}`END`PLN\n' + + '\n' + + '`END`COM%{\n' + + '\n' + + '%}`END`PLN\n' + + '\n' + + '`END`COM%{\n' + + '1\n' + + '2\n' + + '%}`END`PLN\n' + + '\n' + + '`END`COM%{\n' + + '% sdf {}\n' + + 'sdf\n' + + '%asda{}\n' + + 'sfds\n' + + '%}`END`PLN\n' + + '\n' + + ' `END`COM%{\n' + + 'dsf\n' + + ' %}`END`PLN\n' + + '\n' + + '`END`COM%{%}`END`PLN\n' + + '\n' + + '`END`COM%{ zzz=10; %}`END`PLN\n' + + '\n' + + '`END`COM%{%x=10;%}`END`PLN\n' + + '\n' + + '`END`COM%{ x\n' + + 'a=10;\n' + + '%}`END`PLN\n' + + '\n' + + '`END`COM%{\n' + + '%a=10;\n' + + '%}`END`PLN `ENDx`END`PLN\n' + + '\n' + + '`END`COM% nested block comments fail`END`PLN\n' + + '`END`COM%{\n' + + 'dfsdf\n' + + '%{\n' + + 'xxx\n' + + '%}`END`PLN\n' + + '`ENDdfsdf`END`PLN\n' + + '`END`COM%}`END`PLN\n' + + '\n' + + '`END`COM% fails here!`END`PLN\n' + + '`END`COM%{\n' + + 'x=10;\n' + + '%%{\n' + + '%%}`END`PLN\n' + + '`ENDy`END`PUN=`END`LIT20`END`PUN;`END`PLN\n' + + '`END`COM%}`END' + ), + elixir: ('`KWDdefmodule`END`PLN `END`TYPFoo`END`PUN.`END`TYPBar`END`PLN `END`KWDdo`END`PLN\n' + +' `END`ATN@moduledoc`END`PLN `END`STR"""\n' + +' Tests syntax highlighting for Elixir\n' + +' """`END`PLN\n' + +'\n' + +' `END`KWDuse`END`PLN `END`TYPBitwise`END`PLN\n' + +' `END`KWDrequire`END`PLN `END`TYPLogger`END`PLN\n' + +' `END`KWDalias`END`PLN `END`ATN__MODULE__`END`PUN,`END`PLN `END`LITas:`END`PLN `END`TYPThis`END`PLN\n' + +'\n' + +' `END`ATN@default_token_length`END`PLN `END`LIT10_000`END`PLN\n' + +'\n' + +'\n' + +' `END`ATN@spec`END`PLN token`END`PUN(`END`PLNlength `END`PUN::`END`PLN integer`END`PUN)`END`PLN `END`PUN::`END`PLN `END`TYPString`END`PUN.`END`PLNt\n' + +'\n' + +' `END`KWDdef`END`PLN token`END`PUN(`END`PLNlength `END`PUN\\\\`END`PLN `END`ATN@default_token_length`END`PUN),`END`PLN `END`KWDdo`END`PUN:`END`PLN `END`TYPString`END`PUN.`END`PLNduplicate`END`PUN(`END`STR"x"`END`PUN,`END`PLN length`END`PUN)`END`PLN\n' + +'\n' + +'\n' + +' `END`KWDdefp`END`PLN `END`COM_not_exported`END`PUN(),`END`PLN `END`KWDdo`END`PUN:`END`PLN `END`LIT0xFF`END`PLN `END`PUN+`END`PLN `END`LIT0xF_F`END`PLN `END`PUN-`END`PLN `END`LIT0xff`END`PLN\n' + +'\n' + +'\n' + +' `END`KWDdef`END`PLN other`END`PUN(`END`PLNfoo`END`PUN,`END`PLN bar`END`PUN)`END`PLN `END`KWDdo`END`PLN\n' + +' fun `END`PUN=`END`PLN `END`KWDfn`END`PUN{`END`COM_a`END`PUN,`END`PLN b`END`PUN}`END`PLN `END`PUN->`END`PLN b `END`PUN+`END`PLN `END`LIT1_3.1_4`END`PLN `END`KWDend`END`PLN\n' + +' fun`END`PUN.(`END`LIT1.0e+20`END`PUN)`END`PLN\n' + +' `END`COM_str`END`PLN `END`PUN=`END`PLN `END`STR"string without #{inspect(42)} interpolation"`END`PLN `END`PUN<>`END`PLN `END`STR" some more\n' + +' with newlines \\\n' + +' and newlines"`END`PLN\n' + +' charlist `END`PUN=`END`PLN `END`LIT\'some\\\'chars\n' + +' with newlines \\\n' + +' and newlines\'`END`PLN\n' + +' `END`PUN<<`END`PLNx`END`PUN::`END`PLNutf8`END`PUN,`END`PLN `END`COM_y`END`PUN::`END`PLNsize`END`PUN(`END`LIT8`END`PUN),`END`PLN data`END`PUN::`END`PLNbinary`END`PUN>>`END`PLN `END`PUN=`END`PLN `END`STR"fooo"`END`PLN\n' + +' ls `END`PUN=`END`PLN `END`PUN[`END`LIT1`END`PLN `END`PUN|`END`PLN `END`PUN[`END`LIT2`END`PUN,`END`PLN `END`LIT3`END`PUN]]`END`PLN\n' + +' map `END`PUN=`END`PLN `END`PUN%{`END`STR"baz"`END`PLN `END`PUN=>`END`PLN `END`STR"ban"`END`PUN}`END`PLN\n' + +' map `END`PUN=`END`PLN `END`PUN%{`END`LITfoo:`END`PLN `END`LIT:bar`END`PUN,`END`PLN `END`LIT"yes, this compiles":`END`PLN `END`LIT:"also an atom"`END`PUN}`END`PLN\n' + +' `END`LIT:erlang`END`PUN.`END`PLNtime`END`PUN()`END`PLN\n' + +' `END`KWDcase`END`PLN `END`PUN{`END`PLNfoo`END`PUN,`END`PLN bar`END`PUN}`END`PLN `END`KWDdo`END`PLN\n' + +' `END`PUN{`END`LIT1`END`PUN,`END`PLN `END`LIT2`END`PUN}`END`PLN `END`PUN->`END`PLN `END`LIT3`END`PLN\n' + +' `END`COM_something_else`END`PLN `END`PUN->`END`PLN `END`LIT:error`END`PLN\n' + +' `END`COM_`END`PLN `END`PUN->`END`PLN `END`LIT:"this won\'t match"`END`PLN\n' + +' `END`KWDend`END`PLN\n' + +' r `END`PUN=`END`PLN `END`LIT2`END`PLN\n' + +' `END`COM_bitwise_not`END`PLN `END`PUN=`END`PLN `END`PUN~~~`END`PLNr\n' + +'\n' + +' `END`ATV~r/foo/iu`END`PLN `END`COM# regex sigils are treated as normal ones`END`PLN\n' + +' `END`ATV~S|we have "quotes" and \'quotes\' and|`END`PLN `END`PUN<>`END`PLN `END`STR" more string"`END`PLN\n' + +' `END`ATV~c"custom sigil char \\"is\\" fine too"`END`PLN\n' + +' `END`ATV~r\'hello\'`END`PLN\n' + +' `END`ATV~w[hell\\] #o]`END`PLN `END`COM#sigil does not expand to the comment`END`PLN\n' + +' `END`ATV~w{hello}`END`PLN\n' + +' `END`ATV~C<hello>`END`PLN\n' + +' `END`KWDend`END`PLN\n' + +'\n' + +'`END`KWDend`END') +}; diff --git a/tests/recombineTagsAndDecorations_test.html b/tests/recombineTagsAndDecorations_test.html new file mode 100644 index 00000000..f6997230 --- /dev/null +++ b/tests/recombineTagsAndDecorations_test.html @@ -0,0 +1,119 @@ + + + + +recombineTagsAndDecorations + + + + + + + + +

    Recombine Tags And Decorations Test

    + + + + + + + + + + + + + + + + + + + + + + + +
    Test Single Decoration
    "Hello, World!"[0, 'str']"Hello, World!"
    Test Single Span
    print "Hello, <World>!";[0, 'kwd', 5, 'pln', 6, 'str', 14, 'tag', 21, 'str', 23, 'pun']print "Hello, <World>!";
    Test Interleaved
    print "Hello, <World>!";[0, 'kwd', 5, 'pln', 6, 'str', 14, 'tag', 21, 'str', 23, 'pun']print "Hello, <World>!";
    + +
    +

    Log

    +
    + + + + + diff --git a/tests/run_prettify_test.html b/tests/run_prettify_test.html index e4fb052d..e71370e6 100644 --- a/tests/run_prettify_test.html +++ b/tests/run_prettify_test.html @@ -1,58 +1,78 @@ - + - - Run_Prettify Test - + + +Run_Prettify Test + + +// load run_prettify +(function () { + function injectJS(url) { + var script = document.createElement('script'); + script.type = 'text/javascript'; + script.src = url; + document.getElementsByTagName('head')[0].appendChild(script); + } + var srcDir = /[&?]loader\b/.test(location.search) ? '../loader/' : '../src/'; + injectJS(srcDir + 'run_prettify.js' + + '?lang=css' + + '&callback=print_done' + + '&skin=sunburst' + + '&callback=dump_globals'); +})(); + + - - - -
    +
    +
    +

    run_prettify test

    +

    Note: try appending ?loader to this page URL to test the +minified version instead.

    + +

    Test

    +
     <div style="color: #f00">
    -  Hello, World!
    +  Hello, World!
     </div>
     
    - + +

    Log

    +
    + + diff --git a/tests/shims.js b/tests/shims.js new file mode 100644 index 00000000..77cb9dc9 --- /dev/null +++ b/tests/shims.js @@ -0,0 +1,105 @@ +/** + * Shim for ES5 Date.now + * for older browsers (IE < 9, FF < 3, etc.) + * + * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/now#Polyfill + */ +(function () { + if (!Date.now) { + Date.now = function now() { + return new Date().getTime(); + }; + } +})(); + +/** + * Shim for HTML5 getElementsByClassName + * for older browsers (IE < 9, FF < 3, etc.) + */ +(function () { + if (!document.getElementsByClassName) { + document.getElementsByClassName = function (className) { + className = className.replace(/\s+/g, ' ').replace(/^\s*|\s*$/g, ' '); + var results = []; + function walk(node) { + if (node.nodeType !== 1) { return; } + // This test should be order-insensitive. + if ((' ' + node.className + ' ').indexOf(className) >= 0) { + results[results.length] = node; + } + for (var child = node.firstChild; child; child = child.nextSibling) { + walk(child); + } + } + walk(document.body); + return results; + }; + } +})(); + +/** + * Shim for "fixing" IE's lack of support (IE < 9) for applying slice + * on host objects like NamedNodeMap, NodeList, and HTMLCollection + * (technically, since host objects have been implementation-dependent, + * at least before ES2015, IE hasn't needed to work this way). + * Also works on strings, fixes IE < 9 to allow an explicit undefined + * for the 2nd argument (as in Firefox), and prevents errors when + * called on other DOM objects. + * + * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice#Streamlining_cross-browser_behavior + */ +(function () { + 'use strict'; + var _slice = Array.prototype.slice; + + try { + // Can't be used with DOM elements in IE < 9 + _slice.call(document.documentElement); + } catch (e) { // Fails in IE < 9 + // This will work for genuine arrays, array-like objects, + // NamedNodeMap (attributes, entities, notations), + // NodeList (e.g., getElementsByTagName), HTMLCollection (e.g., childNodes), + // and will not fail on other DOM objects (as do DOM elements in IE < 9) + Array.prototype.slice = function(begin, end) { + // IE < 9 gets unhappy with an undefined end argument + end = (typeof end !== 'undefined') ? end : this.length; + + // For native Array objects, we use the native slice function + if (Object.prototype.toString.call(this) === '[object Array]') { + return _slice.call(this, begin, end); + } + + // For array like object we handle it ourselves. + var i, cloned = [], + size, len = this.length; + + // Handle negative value for "begin" + var start = begin || 0; + start = (start >= 0) ? start : Math.max(0, len + start); + + // Handle negative value for "end" + var upTo = (typeof end === 'number') ? Math.min(end, len) : len; + if (end < 0) { + upTo = len + end; + } + + // Actual expected size of the slice + size = upTo - start; + + if (size > 0) { + cloned = new Array(size); + if (this.charAt) { + for (i = 0; i < size; i++) { + cloned[i] = this.charAt(start + i); + } + } else { + for (i = 0; i < size; i++) { + cloned[i] = this[start + i]; + } + } + } + + return cloned; + }; + } +}()); diff --git a/tests/test_base.js b/tests/test_base.js index 31820cb9..6590c6a3 100644 --- a/tests/test_base.js +++ b/tests/test_base.js @@ -1,20 +1,206 @@ -// get accurate timing. -// This file must be loaded after prettify.js for this to work. -PR_SHOULD_USE_CONTINUATION = false; +/** + * @license + * Copyright (C) 2015 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. + */ + +/** + * Dynamically load script + * + * @param {string} url JavaScript file + * @param {Function=} opt_func onload callback + */ +function injectJS(url, opt_func) { + var el = document.createElement('script'); + if (typeof opt_func === 'function') { + el.onload = el.onerror = el.onreadystatechange = function () { + if (el && (!el.readyState || /loaded|complete/.test(el.readyState))) { + el.onerror = el.onload = el.onreadystatechange = null; + el = null; + opt_func(); + } + }; + } + el.type = 'text/javascript'; + el.src = url; + document.getElementsByTagName('head')[0].appendChild(el); +} + +/** + * Dynamically load stylesheet + * + * @param {string} url CSS file + */ +function injectCSS(url) { + var el = document.createElement('link'); + el.rel = 'stylesheet'; + el.type = 'text/css'; + el.href = url; + document.getElementsByTagName('head')[0].appendChild(el); +} + +/** + * Perform syntax highlighting and execute tests to verify results. + * + * @param {Object} goldens a mapping from IDs of prettyprinted + * chunks to an abbreviated form of the expected output. See "var goldens" + * in prettify_test.html and prettify_test_2.html for examples. + */ +function runTests(goldens) { + // Regexp literals defined here so that the interpreter doesn't have to + // compile them each time the function containing them is called. + /** @const {RegExp} */ + var ampRe = /&/g; + /** @const {RegExp} */ + var ltRe = //g; + /** @const {RegExp} */ + var quotRe = /\"/g; + /** @const {RegExp} */ + var nbspRe = /\xa0/g; + /** @const {RegExp} */ + var newlineRe = /[\r\n]/g; + /** @const {RegExp} */ + var voidElemsRe = /^(?:br|hr|link|img)$/; + + /** @type {?boolean} */ + var innerHtmlWorks = null; -var attribToHtml, textToHtml; + /** + * Get timestamp in milliseconds unit. + * + * @return {number} + */ + function now() { + return (Date.now ? Date.now() : (new Date()).getTime()); + } -var getInnerHtml; + /** + * Escapes HTML special characters to HTML. + * + * @param {string} str the HTML to escape + * @return {string} output escaped HTML + */ + function textToHtml(str) { + return str + .replace(ampRe, '&') + .replace(ltRe, '<') + .replace(gtRe, '>'); + } -(function () { - /** is the given node's innerHTML normally unescaped? */ - function isRawContent(node) { - return 'XMP' === node.tagName; + /** + * Like {@link textToHtml} but escapes double quotes to be attribute safe. + * + * @param {string} str the HTML to escape + * @return {string} output escaped HTML + */ + function attribToHtml(str) { + return textToHtml(str).replace(quotRe, '"'); + } + + /** + * convert a plain text string to HTML by escaping HTML special chars. + * + * @param {string} plainText + * @return {string} + */ + function htmlEscape(plainText) { + return attribToHtml(plainText).replace(nbspRe, ' '); + } + + /** + * Traverse node and manually build `innerHTML`. + * + * @param {Node} node DOM node + * @param {string} out HTML content + * @param {boolean=} opt_sortAttrs if attributes should be sorted + */ + function normalizedHtml(node, out, opt_sortAttrs) { + switch (node.nodeType) { + case 1: // ELEMENT_NODE + // start-tag + var name = node.tagName.toLowerCase(); + out.push('<', name); + // attributes + var attrs = node.attributes; + var n = attrs.length; + if (n) { + if (opt_sortAttrs) { + // sort attributes by name + var sortedAttrs = []; + for (var i = n; --i >= 0;) { sortedAttrs[i] = attrs[i]; } + sortedAttrs.sort(function (a, b) { + return (a.name < b.name) ? -1 : (a.name === b.name ? 0 : 1); + }); + attrs = sortedAttrs; + } + for (var i = 0; i < n; ++i) { + var attr = attrs[i]; + // specified: vs. + if (!attr.specified) { continue; } + out.push(' ', attr.name.toLowerCase(), + '="', attribToHtml(attr.value), '"'); + } + } + out.push('>'); + // children + for (var child = node.firstChild; child; child = child.nextSibling) { + normalizedHtml(child, out, opt_sortAttrs); + } + // end-tag + if (node.firstChild || !voidElemsRe.test(name)) { + out.push('<\/', name, '>'); + } + break; + case 3: // TEXT_NODE + case 4: // CDATA_SECTION_NODE + out.push(textToHtml(node.nodeValue)); + break; + } } - var newlineRe = /[\r\n]/g; /** - * Are newlines and adjacent spaces significant in the given node's innerHTML? + * get normalized markup. innerHTML varies enough across browsers that we + * can't use it. + * + * @param {Node} node + * @return {string} + */ + function normalizedInnerHtml(node) { + // manually build innerHTML with sorted attributes + var out = []; + for (var child = node.firstChild; child; child = child.nextSibling) { + normalizedHtml(child, out, true); + } + out = out.join(''); + + // more normalization to work around problems with non-ascii chars in + // regexps in Safari + for (var i = 0; (i = out.indexOf('\xa0')) >= 0;) { + out = out.substring(0, i) + ' ' + out.substring(i + 1); + } + return out.replace(/\r\n?/g, '\n'); + } + + /** + * Are newlines and adjacent spaces significant in the given node's + * `innerHTML`? + * + * @param {Node} node DOM node + * @param {string} content its HTML content + * @return {boolean} is it preformatted */ function isPreformatted(node, content) { // PRE means preformatted, and is a very common case, so don't create @@ -33,113 +219,49 @@ var getInnerHtml; return !whitespace || whitespace === 'pre'; } - // Define regexps here so that the interpreter doesn't have to create an - // object each time the function containing them is called. - // The language spec requires a new object created even if you don't access - // the $1 members. - var pr_amp = /&/g; - var pr_lt = //g; - var pr_quot = /\"/g; - - /** escapest html special characters to html. */ - textToHtml = function (str) { - return str.replace(pr_amp, '&') - .replace(pr_lt, '<') - .replace(pr_gt, '>'); - }; - - /** like textToHtml but escapes double quotes to be attribute safe. */ - attribToHtml = function (str) { - return str.replace(pr_amp, '&') - .replace(pr_lt, '<') - .replace(pr_gt, '>') - .replace(pr_quot, '"'); - }; - - var PR_innerHtmlWorks = null; - getInnerHtml = function (node) { - // inner html is hopelessly broken in Safari 2.0.4 when the content is - // an html description of well formed XML and the containing tag is a PRE + /** + * Get `innerHTML` of a node + * + * @param {Node} node DOM node + * @return {string} HTML content + */ + function getInnerHtml(node) { + // innerHTML is hopelessly broken in Safari 2.0.4 when the content is + // an HTML description of well formed XML and the containing tag is a PRE // tag, so we detect that case and emulate innerHTML. - if (null === PR_innerHtmlWorks) { - var testNode = document.createElement('PRE'); + if (null === innerHtmlWorks) { + var testNode = document.createElement('pre'); testNode.appendChild( - document.createTextNode('\n')); - PR_innerHtmlWorks = !/\n')); + innerHtmlWorks = !/)[\r\n]+/g, '$1') - .replace(/(?:[\r\n]+[ \t]*)+/g, ' '); + .replace(/(?:[\r\n]+[ \t]*)+/g, ' '); } return content; - } - - var out = []; - for (var child = node.firstChild; child; child = child.nextSibling) { - normalizedHtml(child, out); - } - return out.join(''); - }; -})(); - -function normalizedHtml(node, out, opt_sortAttrs) { - switch (node.nodeType) { - case 1: // an element - var name = node.tagName.toLowerCase(); - - out.push('<', name); - var attrs = node.attributes; - var n = attrs.length; - if (n) { - if (opt_sortAttrs) { - var sortedAttrs = []; - for (var i = n; --i >= 0;) { sortedAttrs[i] = attrs[i]; } - sortedAttrs.sort(function (a, b) { - return (a.name < b.name) ? -1 : a.name === b.name ? 0 : 1; - }); - attrs = sortedAttrs; - } - for (var i = 0; i < n; ++i) { - var attr = attrs[i]; - if (!attr.specified) { continue; } - out.push(' ', attr.name.toLowerCase(), - '="', attribToHtml(attr.value), '"'); - } - } - out.push('>'); + } else { + var out = []; for (var child = node.firstChild; child; child = child.nextSibling) { - normalizedHtml(child, out, opt_sortAttrs); - } - if (node.firstChild || !/^(?:br|link|img)$/.test(name)) { - out.push('<\/', name, '>'); + normalizedHtml(child, out); } - break; - case 3: case 4: // text - out.push(textToHtml(node.nodeValue)); - break; + return out.join(''); + } } -} - - -/** - * @param golden a mapping from IDs of prettyprinted chunks to an abbreviated - * form of the expected output. See "var goldens" in prettify_test.html - * for an example. - */ -function go(goldens) { - startClock(); - prettyPrint(function () { stopClock(); runTests(goldens); }); -} -function runTests(goldens) { - /** number of characters in common at the end up to max. */ + /** + * number of characters in common from the beginning. + * + * @param {string} a + * @param {string} b + * @return {number} + */ function commonPrefix(a, b) { var n = Math.min(a.length, b.length); var i; @@ -149,7 +271,14 @@ function runTests(goldens) { return i; } - /** number of characters in common at the end up to max. */ + /** + * number of characters in common at the end up to max. + * + * @param {string} a + * @param {string} b + * @param {number} max + * @return {number} + */ function commonSuffix(a, b, max) { var n = Math.min(a.length - max, b.length - max); var i; @@ -159,93 +288,125 @@ function runTests(goldens) { return i; } - /** convert a plain text string to html by escaping html special chars. */ - function html(plainText) { - return attribToHtml(plainText).replace(/\xa0/g, ' '); + /** + * Replace whitespace characters with printable graphical representations. + * + * @param {string} txt + * @return {string} + */ + function showAllCharacters(txt) { + // space = \xb7, \u02f0, \u2219, \u2423, \u2420 + // htab = \xbb, \u21e5, \u25b8, \u2409 + // newline = \xac, \xb6, \u21b5, \u2424 + // vtab = \u240B + // ffeed = \u240C + return txt + .replace(/ /g, '\xb7') + .replace(/(\r?\n)/g, '\u21b5$1') + .replace(/\t/g, '\u25b8') + .replace(/\v/g, '\u240B') + .replace(/\f/g, '\u240C'); } /** - * get normalized markup. innerHTML varies enough across browsers that we - * can't use it. + * Find differences between two texts, and return an HTML report. + * + * @param {string} golden text + * @param {string} actual text + * @return {string} HTML representation */ - function normalizedInnerHtml(node) { - var out = []; - for (var child = node.firstChild; child; child = child.nextSibling) { - normalizedHtml(child, out, true); - } - out = out.join(''); - // more normalization to work around problems with non-ascii chars in - // regexps in Safari - for (var i = 0; (i = out.indexOf('\xa0')) >= 0;) { - out = out.substring(0, i) + ' ' + out.substring(i + 1); + function diffTexts(golden, actual) { + if (true) { + golden = showAllCharacters(golden); + actual = showAllCharacters(actual); } - return out.replace(/\r\n?/g, '\n'); + var npre = commonPrefix(golden, actual); + var npost = commonSuffix(golden, actual, npre); + return ( + '
    Golden<\/th>' + + htmlEscape(golden.substring(0, npre)) + + '»' + + htmlEscape(golden.substring(npre, golden.length - npost)) + + '<\/span>«' + + htmlEscape(golden.substring(golden.length - npost)) + + '<\/code><\/td><\/tr>
    Actual<\/th>' + + htmlEscape(actual.substring(0, npre)) + + '»' + + htmlEscape(actual.substring(npre, actual.length - npost)) + + '<\/span>«' + + htmlEscape(actual.substring(actual.length - npost)) + + '<\/code><\/td><\/tr><\/table>' + ); } - var htmlOut = []; - var failures = 0; - document.getElementById('errorReport').innerHTML = - '

    Running tests…<\/h1>'; - htmlOut.push('

    Test results<\/h1>'); - for (var lang in goldens) { - var container = document.getElementById(lang); - // Convert abbreviations that start with `. - var golden = goldens[lang].replace(/`([A-Z]{3})/g, function (_, lbl) { - return (lbl == 'END' - ? '<\/span>' - : ''); + /** + * Convert golden from abbreviated form back to original text + * + * @param {string} golden + * @return {string} + */ + function expandGolden(golden) { + return golden.replace(/`([A-Z]{3})/g, function (_, lbl) { + // convert abbreviations that start with ` + return (lbl === 'END' ? '<\/span>' : + ''); }) - // Line numbers + // line numbers .replace(/`#(?![0-9])/, '
  • ') - .replace(/`#([0-9])/g, '
  • '); - var actual = normalizedInnerHtml(container); - if (golden !== actual) { // test failed - // write out - var pre = commonPrefix(golden, actual); - var post = commonSuffix(golden, actual, pre); - - ++failures; - htmlOut.push( - '

    ' - + html(lang) + '<\/a> Failed<\/h2>'); - htmlOut.push( - '' + html(golden.substring(0, pre)) + - '»' + - html(golden.substring(pre, golden.length - post)) + - '<\/span>«' + - html(golden.substring(golden.length - post)) + - - '
    !==
    ' + - - html(actual.substring(0, pre)) + - '»' + - html(actual.substring(pre, actual.length - post)) + - '<\/span>«' + - html(actual.substring(actual.length - post)) + '<\/tt>'); - } else { - htmlOut.push( - '

    ' + html(lang) + '<\/a> OK<\/h2>'); + .replace(/`#([0-9])/g, '<\/li>
  • '); + } + + /** + * Compare tests results against expected outcomes. + * + * @param {Object} goldens + * @return {{html: Array, pass: integer, fail: integer}} HTML report + */ + function runComparison(goldens) { + var out = []; + var npass = 0; + var nfail = 0; + for (var id in goldens) { + // compare actual against expexted + var golden = expandGolden(goldens[id]); + var actual = normalizedInnerHtml(document.getElementById(id)); + var diff = golden !== actual; + out.push('
    ' + (diff ? 'FAIL' : 'PASS') + + ': ' + id + '<\/a><\/div>'); + if (diff) { + ++nfail; + // write out difference + out.push( + diffTexts(golden, actual).replace(/<br>/g, '<br>\n')); + } else { + ++npass; + } } + out.unshift( + '

    \u2714 ' + npass + ' passing<\/p>', + '

    \u2718 ' + nfail + ' failing<\/p>'); + out.push('

    Tests ' + + (nfail ? 'failed' : 'passed') + '<\/h3>'); + return { + html: out, + pass: npass, + fail: nfail + }; } - var summary = ( - failures - ? (failures + ' test' + (failures === 1 ? '' : 's') + ' failed') - : 'Tests Passed'); - var summaryStr = '

    ' + summary + '<\/h2>'; - htmlOut.push(summaryStr); - htmlOut.splice(0, 0, summaryStr); - document.title += ' \u2014 ' + summary; - document.getElementById('errorReport').innerHTML = - htmlOut.join('').replace(/<br>/g, '<br>\n'); -} -var startTime = null; -function startClock() { - startTime = (new Date).getTime(); -} + // for more accurate timing, no continuation. + // This file must be loaded after prettify.js for this to work. + window.PR_SHOULD_USE_CONTINUATION = false; + + // time syntax highlighting + var t = now(); // tic + PR.prettyPrint(function () { + t = now() - t; // toc -function stopClock() { - var delta = (new Date).getTime() - startTime; - startTime = null; - document.getElementById('timing').innerHTML = 'Took ' + delta + ' ms'; + // verify results against golden and write HTML report + var report = runComparison(goldens); + document.title += (' \u2014 ' + (report.fail ? 'FAIL' : 'PASS')); + report.html.unshift('

    Took ' + t + ' ms<\/p>'); + document.getElementById('report').innerHTML = report.html.join('\n'); + }); } diff --git a/tests/test_in_node b/tests/test_in_node new file mode 100755 index 00000000..1cd5c625 --- /dev/null +++ b/tests/test_in_node @@ -0,0 +1,89 @@ +#!/usr/bin/env node + +var path = require('path'); +var Browser = require('zombie'); +var htmlToText = require('html-to-text'); + +var optsZombie = { + debug: false, + silent: false, + waitDuration: '10s', + runScripts: true +}; +var optsHTT = { + wordwrap: 80, // process.stdout.columns + tables: true, + ignoreHref: true, + preserveNewlines: true, + singleNewLineParagraphs: true +}; + +var jobs = process.argv.slice(2); +var returnCode = 0; +var browser = null; + +// start processing pages +startBrowser(); + +function startBrowser() { + // close any previous browser sessions + if (browser) { + //browser.window.close(); + browser.destroy(); + } + + // next URL + var url = jobs.shift(); + if (url === undefined) { + console.log('>> Complete'); + process.exit(returnCode); + return; + } else if (!/^(?:https?|ftp):/.test(url)) { + // rewrite local path as a file:// URL + url = encodeURI('file://' + path.resolve(url).replace(/\\/g, '/')); + } + + // load page + console.log('>> Loading %s ...', url); + browser = new Browser(optsZombie); + if (optsZombie.debug) { browser.debug(); } + browser.visit(url).then(checkCb).catch(problemCb); +} + +function problemCb(err) { + // log error, and process next page + console.warn('>> ' + err); + returnCode = 1; + startBrowser(); +} + +function checkCb() { + var done = false; + + // check for errors + function onProb(err) { + console.warn('>> ' + err); + returnCode = 1; + done = true; + } + (browser.errors || []).forEach(onProb); + (browser.document.errors || []).forEach(onProb); + + // retrieve and log results + var report = browser.html('#report'); + if (report && report.length) { + done = true; + //console.log(browser.text('#report')); + console.log(htmlToText.fromString( + // HACK: replace

    tags with

    + // https://github.com/werk85/node-html-to-text/issues/71 + report.replace(/(<\/?)div/ig, '$1p'), optsHTT)); + } + + // process next page if done, otherwise wait for page to complete loading + if (done) { + startBrowser(); + } else { + browser.wait().then(checkCb).catch(problemCb); + } +} diff --git a/tests/test_modules.css b/tests/test_modules.css new file mode 100644 index 00000000..ecc8141e --- /dev/null +++ b/tests/test_modules.css @@ -0,0 +1,90 @@ +/* tests table */ +table { + border-collapse: collapse; + border-spacing: 0; +} +table, th, td { + border: 1px solid black; +} +td, th { + padding: 2px; +} +tr { + vertical-align: top; +} +th { + background-color: #FFD; +} +td { + font-family: monospace; +} + +/* tests */ +.input, .golden, .actual, .decorations { + white-space: pre; +} + +/* results */ +.ok { + background-color: #DFD; +} +.failure, .error { + background-color: #FDD; +} +.ok:after { + color: green; + content: '\a[PASS]'; + font-weight: bold; +} +.failure:after { + color: red; + content: '\a[FAIL]'; + font-weight: bold; +} +.error:after { + color: #AF7817; + content: '\a[ERROR]'; + font-weight: bold; +} + +/* used in extractSourceSpans_test.html */ +.break { + padding-left: 2px; + border-right-style: dotted !important; +} +.odd, .even { + border-style: solid; + border-width: 1px; +} +.even { + background-color: #fff; + border-color: #888; +} +.odd { + background-color: #ddd; + border-color: #000; +} + +/* log */ +#report { + margin-left: 1em; +} +.pass { + color: green; +} +.fail, .err { + color: red; +} + +/* diff tables */ +table.diff { + table-layout: fixed; + max-width: 100%; +} +.diff th { + width: 50px; +} +.diff td { + white-space: pre-wrap; + word-wrap: break-word; +} diff --git a/tests/test_styles.css b/tests/test_styles.css index 23c59465..47e4b369 100644 --- a/tests/test_styles.css +++ b/tests/test_styles.css @@ -1,5 +1,61 @@ -/* Used by error reporting code in test_base.js */ -.mismatch { background: #fee; font-weight: bold } -span.annot { margin:2px 2px 2px 3em; border:1px dotted #88f; background:#eef; - padding: 0 2px 0 2px } -.nocode { background: #f8f8f8 } +/** + * @license + * Copyright (C) 2015 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. + */ + +/* used by test_base.js */ +#report { + margin-left: 1em; +} +.pass { + color: green; +} +.fail { + color: red; +} +.mismatch { + background-color: #faa; + font-weight: bold; +} + +/* diff tables */ +table.diff { + border-collapse: collapse; + border-spacing: 0; + table-layout: fixed; + width: 100%; +} +.diff th, .diff td { + border: 1px solid black; +} +.diff th { + background-color: #FFD; + width: 50px; +} +.diff td { + white-space: pre-wrap; + word-wrap: break-word; +} + +/* used in prettify_test.html issue 22 */ +.annot { + background-color: #eef; + border: 1px dotted #88f; + margin: 2px 2px 2px 3em; + padding: 0 2px 0 2px; +} +.nocode { + background-color: #f8f8f8; +} diff --git a/closure-compiler/amd-externs.js b/tools/closure-compiler/amd-externs.js similarity index 100% rename from closure-compiler/amd-externs.js rename to tools/closure-compiler/amd-externs.js diff --git a/closure-compiler/console-externs.js b/tools/closure-compiler/console-externs.js similarity index 100% rename from closure-compiler/console-externs.js rename to tools/closure-compiler/console-externs.js diff --git a/yui-compressor/LICENSE.TXT b/yui-compressor/LICENSE.TXT deleted file mode 100644 index fc34134a..00000000 --- a/yui-compressor/LICENSE.TXT +++ /dev/null @@ -1,54 +0,0 @@ -YUI Compressor Copyright License Agreement (BSD License) - -Copyright (c) 2009, Yahoo! Inc. -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the following -conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of Yahoo! Inc. nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of Yahoo! Inc. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -This software also requires access to software from the following sources: - -The Jarg Library v 1.0 ( http://jargs.sourceforge.net/ ) is available -under a BSD License Copyright (c) 2001-2003 Steve Purcell, -Copyright (c) 2002 Vidar Holen, Copyright (c) 2002 Michal Ceresna and -Copyright (c) 2005 Ewan Mellor. - -The Rhino Library ( http://www.mozilla.org/rhino/ ) is dually available -under an MPL 1.1/GPL 2.0 license, with portions subject to a BSD license. - -Additionally, this software contains modified versions of the following -component files from the Rhino Library: - -[org/mozilla/javascript/Decompiler.java] -[org/mozilla/javascript/Parser.java] -[org/mozilla/javascript/Token.java] -[org/mozilla/javascript/TokenStream.java] - -The modified versions of these files are distributed under the MPL v 1.1 -( http://www.mozilla.org/MPL/MPL-1.1.html ) diff --git a/yui-compressor/README b/yui-compressor/README deleted file mode 100644 index c2b5751c..00000000 --- a/yui-compressor/README +++ /dev/null @@ -1,145 +0,0 @@ -============================================================================== -YUI Compressor -============================================================================== - -NAME - - YUI Compressor - The Yahoo! JavaScript and CSS Compressor - -SYNOPSIS - - Usage: java -jar yuicompressor-x.y.z.jar [options] [input file] - - Global Options - -h, --help Displays this information - --type Specifies the type of the input file - --charset Read the input file using - --line-break Insert a line break after the specified column number - -v, --verbose Display informational messages and warnings - -o Place the output into or a file pattern. - Defaults to stdout. - - JavaScript Options - --nomunge Minify only, do not obfuscate - --preserve-semi Preserve all semicolons - --disable-optimizations Disable all micro optimizations - -DESCRIPTION - - The YUI Compressor is a JavaScript compressor which, in addition to removing - comments and white-spaces, obfuscates local variables using the smallest - possible variable name. This obfuscation is safe, even when using constructs - such as 'eval' or 'with' (although the compression is not optimal is those - cases) Compared to jsmin, the average savings is around 20%. - - The YUI Compressor is also able to safely compress CSS files. The decision - on which compressor is being used is made on the file extension (js or css) - -GLOBAL OPTIONS - - -h, --help - Prints help on how to use the YUI Compressor - - --line-break - Some source control tools don't like files containing lines longer than, - say 8000 characters. The linebreak option is used in that case to split - long lines after a specific column. It can also be used to make the code - more readable, easier to debug (especially with the MS Script Debugger) - Specify 0 to get a line break after each semi-colon in JavaScript, and - after each rule in CSS. - - --type js|css - The type of compressor (JavaScript or CSS) is chosen based on the - extension of the input file name (.js or .css) This option is required - if no input file has been specified. Otherwise, this option is only - required if the input file extension is neither 'js' nor 'css'. - - --charset character-set - If a supported character set is specified, the YUI Compressor will use it - to read the input file. Otherwise, it will assume that the platform's - default character set is being used. The output file is encoded using - the same character set. - - -o outfile - - Place output in file outfile. If not specified, the YUI Compressor will - default to the standard output, which you can redirect to a file. - Supports a filter syntax for expressing the output pattern when there are - multiple input files. ex: - java -jar yuicompressor.jar -o '.css$:-min.css' *.css - ... will minify all .css files and save them as -min.css - - -v, --verbose - Display informational messages and warnings. - -JAVASCRIPT ONLY OPTIONS - - --nomunge - Minify only. Do not obfuscate local symbols. - - --preserve-semi - Preserve unnecessary semicolons (such as right before a '}') This option - is useful when compressed code has to be run through JSLint (which is the - case of YUI for example) - - --disable-optimizations - Disable all the built-in micro optimizations. - -NOTES - - + If no input file is specified, it defaults to stdin. - - + Supports wildcards for specifying multiple input files. - - + The YUI Compressor requires Java version >= 1.4. - - + It is possible to prevent a local variable, nested function or function - argument from being obfuscated by using "hints". A hint is a string that - is located at the very beginning of a function body like so: - - function fn (arg1, arg2, arg3) { - "arg2:nomunge, localVar:nomunge, nestedFn:nomunge"; - - ... - var localVar; - ... - - function nestedFn () { - .... - } - - ... - } - - The hint itself disappears from the compressed file. - - + C-style comments starting with /*! are preserved. This is useful with - comments containing copyright/license information. For example: - - /*! - * TERMS OF USE - EASING EQUATIONS - * Open source under the BSD License. - * Copyright 2001 Robert Penner All rights reserved. - */ - - becomes: - - /* - * TERMS OF USE - EASING EQUATIONS - * Open source under the BSD License. - * Copyright 2001 Robert Penner All rights reserved. - */ - -MODIFIED RHINO FILES - - YUI Compressor uses a modified version of the Rhino library - (http://www.mozilla.org/rhino/) The changes were made to support - JScript conditional comments, preserved comments, unescaped slash - characters in regular expressions, and to allow for the optimization - of escaped quotes in string literals. - -COPYRIGHT AND LICENSE - - Copyright (c) 2010 Yahoo! Inc. All rights reserved. - The copyrights embodied in the content of this file are licensed - by Yahoo! Inc. under the BSD (revised) open source license. diff --git a/yui-compressor/yuicompressor-2.4.4.jar b/yui-compressor/yuicompressor-2.4.4.jar deleted file mode 100644 index 05ccc054..00000000 Binary files a/yui-compressor/yuicompressor-2.4.4.jar and /dev/null differ