From f2c7155bbd361681d893e6e8c2c1f86689c6d183 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Thu, 15 Dec 2011 08:25:41 +0000 Subject: [PATCH] upgraded google-code-prettify and made relevant changes to the code viewer --- codepot/src/codepot/views/code_blame.php | 20 +- codepot/src/codepot/views/code_file.php | 38 +- codepot/src/js/prettify/lang-apollo.js | 20 +- codepot/src/js/prettify/lang-clj.js | 64 + codepot/src/js/prettify/lang-css.js | 36 +- codepot/src/js/prettify/lang-go.js | 58 + codepot/src/js/prettify/lang-hs.js | 20 +- codepot/src/js/prettify/lang-lisp.js | 26 +- codepot/src/js/prettify/lang-lua.js | 20 +- codepot/src/js/prettify/lang-ml.js | 22 +- codepot/src/js/prettify/lang-n.js | 62 + codepot/src/js/prettify/lang-proto.js | 16 +- codepot/src/js/prettify/lang-scala.js | 54 + codepot/src/js/prettify/lang-sql.js | 18 +- codepot/src/js/prettify/lang-tex.js | 46 + codepot/src/js/prettify/lang-vb.js | 22 +- codepot/src/js/prettify/lang-vhdl.js | 34 + codepot/src/js/prettify/lang-wiki.js | 18 +- codepot/src/js/prettify/lang-xq.js | 67 ++ codepot/src/js/prettify/lang-yaml.js | 27 + codepot/src/js/prettify/prettify.css | 70 +- codepot/src/js/prettify/prettify.js | 1369 +++++++++++----------- 22 files changed, 1267 insertions(+), 860 deletions(-) create mode 100644 codepot/src/js/prettify/lang-clj.js create mode 100644 codepot/src/js/prettify/lang-go.js create mode 100644 codepot/src/js/prettify/lang-n.js create mode 100644 codepot/src/js/prettify/lang-scala.js create mode 100644 codepot/src/js/prettify/lang-tex.js create mode 100644 codepot/src/js/prettify/lang-vhdl.js create mode 100644 codepot/src/js/prettify/lang-xq.js create mode 100644 codepot/src/js/prettify/lang-yaml.js diff --git a/codepot/src/codepot/views/code_blame.php b/codepot/src/codepot/views/code_blame.php index cd8328ee..03e485e8 100644 --- a/codepot/src/codepot/views/code_blame.php +++ b/codepot/src/codepot/views/code_blame.php @@ -169,11 +169,15 @@ else
code_hide_line_num == 'Y') $prettyprint_linenums = ''; ?> -
+
 {$rev_padded}";
 		print "{$author_padded}";
 
-		if ($login['settings'] != NULL && $login['settings']->code_hide_line_num == 'Y')
-		{
-			/* do nothing */
-		}
-		else
-		{
-			print "{$lineno_padded}";
-		}
-
 		print htmlspecialchars ($line['line']);
 		print "\n";
 	}
diff --git a/codepot/src/codepot/views/code_file.php b/codepot/src/codepot/views/code_file.php
index 5cf60160..8e6100f4 100644
--- a/codepot/src/codepot/views/code_file.php
+++ b/codepot/src/codepot/views/code_file.php
@@ -171,41 +171,17 @@ $this->load->view (
 
 code_hide_line_num == 'Y') $prettyprint_linenums = '';
 ?>
 
-
-code_hide_line_num == 'Y')
-	{
-		print htmlspecialchars($file['content']);
-	}
-	else
-	{
-		$pos = 0; $lineno = 0; $len = strlen($file['content']);
-		while ($pos < $len)
-		{
-			$lineno_padded = str_pad (++$lineno, 6, ' ', STR_PAD_LEFT);
-			$npos = strpos ($file['content'], "\n", $pos);
-			if ($npos === FALSE)
-			{
-				print '' . $lineno_padded . '  ';
-				print substr ($file['content'], $pos, $len - $pos);
-				print "\n";
-				break;
-			}
-
-			print '' . $lineno_padded . '  ';
-			print htmlspecialchars (substr ($file['content'], $pos, $npos - $pos));
-			print "\n";
-
-			$pos = $npos + 1;
-		}
-	}
-?>
+
+
 
-
lang->line('CODE_COMMIT') ?>
lang->line('CODE_MSG_COMMITTED_BY_ON'), $file['last_author'], $file['time']); ?> diff --git a/codepot/src/js/prettify/lang-apollo.js b/codepot/src/js/prettify/lang-apollo.js index c2182100..9fa1d24c 100644 --- a/codepot/src/js/prettify/lang-apollo.js +++ b/codepot/src/js/prettify/lang-apollo.js @@ -25,27 +25,27 @@ * @author ohommes@alumni.cmu.edu */ -PR.registerLangHandler( - PR.createSimpleLexer( +PR['registerLangHandler']( + PR['createSimpleLexer']( [ // A line comment that starts with ; - [PR.PR_COMMENT, /^#[^\r\n]*/, null, '#'], + [PR['PR_COMMENT'], /^#[^\r\n]*/, null, '#'], // Whitespace - [PR.PR_PLAIN, /^[\t\n\r \xA0]+/, null, '\t\n\r \xA0'], + [PR['PR_PLAIN'], /^[\t\n\r \xA0]+/, null, '\t\n\r \xA0'], // A double quoted, possibly multi-line, string. - [PR.PR_STRING, /^\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)/, null, '"'] + [PR['PR_STRING'], /^\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)/, null, '"'] ], [ - [PR.PR_KEYWORD, /^(?:ADS|AD|AUG|BZF|BZMF|CAE|CAF|CA|CCS|COM|CS|DAS|DCA|DCOM|DCS|DDOUBL|DIM|DOUBLE|DTCB|DTCF|DV|DXCH|EDRUPT|EXTEND|INCR|INDEX|NDX|INHINT|LXCH|MASK|MSK|MP|MSU|NOOP|OVSK|QXCH|RAND|READ|RELINT|RESUME|RETURN|ROR|RXOR|SQUARE|SU|TCR|TCAA|OVSK|TCF|TC|TS|WAND|WOR|WRITE|XCH|XLQ|XXALQ|ZL|ZQ|ADD|ADZ|SUB|SUZ|MPY|MPR|MPZ|DVP|COM|ABS|CLA|CLZ|LDQ|STO|STQ|ALS|LLS|LRS|TRA|TSQ|TMI|TOV|AXT|TIX|DLY|INP|OUT)\s/,null], - [PR.PR_TYPE, /^(?:-?GENADR|=MINUS|2BCADR|VN|BOF|MM|-?2CADR|-?[1-6]DNADR|ADRES|BBCON|[SE]?BANK\=?|BLOCK|BNKSUM|E?CADR|COUNT\*?|2?DEC\*?|-?DNCHAN|-?DNPTR|EQUALS|ERASE|MEMORY|2?OCT|REMADR|SETLOC|SUBRO|ORG|BSS|BES|SYN|EQU|DEFINE|END)\s/,null], + [PR['PR_KEYWORD'], /^(?:ADS|AD|AUG|BZF|BZMF|CAE|CAF|CA|CCS|COM|CS|DAS|DCA|DCOM|DCS|DDOUBL|DIM|DOUBLE|DTCB|DTCF|DV|DXCH|EDRUPT|EXTEND|INCR|INDEX|NDX|INHINT|LXCH|MASK|MSK|MP|MSU|NOOP|OVSK|QXCH|RAND|READ|RELINT|RESUME|RETURN|ROR|RXOR|SQUARE|SU|TCR|TCAA|OVSK|TCF|TC|TS|WAND|WOR|WRITE|XCH|XLQ|XXALQ|ZL|ZQ|ADD|ADZ|SUB|SUZ|MPY|MPR|MPZ|DVP|COM|ABS|CLA|CLZ|LDQ|STO|STQ|ALS|LLS|LRS|TRA|TSQ|TMI|TOV|AXT|TIX|DLY|INP|OUT)\s/,null], + [PR['PR_TYPE'], /^(?:-?GENADR|=MINUS|2BCADR|VN|BOF|MM|-?2CADR|-?[1-6]DNADR|ADRES|BBCON|[SE]?BANK\=?|BLOCK|BNKSUM|E?CADR|COUNT\*?|2?DEC\*?|-?DNCHAN|-?DNPTR|EQUALS|ERASE|MEMORY|2?OCT|REMADR|SETLOC|SUBRO|ORG|BSS|BES|SYN|EQU|DEFINE|END)\s/,null], // A single quote possibly followed by a word that optionally ends with // = ! or ?. - [PR.PR_LITERAL, + [PR['PR_LITERAL'], /^\'(?:-*(?:\w|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?)?/], // Any word including labels that optionally ends with = ! or ?. - [PR.PR_PLAIN, + [PR['PR_PLAIN'], /^-*(?:[!-z_]|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?/i], // A printable non-space non-special character - [PR.PR_PUNCTUATION, /^[^\w\t\n\r \xA0()\"\\\';]+/] + [PR['PR_PUNCTUATION'], /^[^\w\t\n\r \xA0()\"\\\';]+/] ]), ['apollo', 'agc', 'aea']); diff --git a/codepot/src/js/prettify/lang-clj.js b/codepot/src/js/prettify/lang-clj.js new file mode 100644 index 00000000..0758335f --- /dev/null +++ b/codepot/src/js/prettify/lang-clj.js @@ -0,0 +1,64 @@ +/** + * @license Copyright (C) 2011 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @fileoverview + * Registers a language handler for Clojure. + * + * + * To use, include prettify.js and this file in your HTML page. + * Then put your code in an HTML tag like + *
(my lisp code)
+ * The lang-cl class identifies the language as common lisp. + * This file supports the following language extensions: + * lang-clj - Clojure + * + * + * I used lang-lisp.js as the basis for this adding the clojure specific + * keywords and syntax. + * + * "Name" = 'Clojure' + * "Author" = 'Rich Hickey' + * "Version" = '1.2' + * "About" = 'Clojure is a lisp for the jvm with concurrency primitives and a richer set of types.' + * + * + * I used Clojure.org Reference as + * the basis for the reserved word list. + * + * + * @author jwall@google.com + */ + +PR['registerLangHandler']( + PR['createSimpleLexer']( + [ + // clojure has more paren types than minimal lisp. + ['opn', /^[\(\{\[]+/, null, '([{'], + ['clo', /^[\)\}\]]+/, null, ')]}'], + // A line comment that starts with ; + [PR['PR_COMMENT'], /^;[^\r\n]*/, null, ';'], + // Whitespace + [PR['PR_PLAIN'], /^[\t\n\r \xA0]+/, null, '\t\n\r \xA0'], + // A double quoted, possibly multi-line, string. + [PR['PR_STRING'], /^\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)/, null, '"'] + ], + [ + // clojure has a much larger set of keywords + [PR['PR_KEYWORD'], /^(?:def|if|do|let|quote|var|fn|loop|recur|throw|try|monitor-enter|monitor-exit|defmacro|defn|defn-|macroexpand|macroexpand-1|for|doseq|dosync|dotimes|and|or|when|not|assert|doto|proxy|defstruct|first|rest|cons|defprotocol|deftype|defrecord|reify|defmulti|defmethod|meta|with-meta|ns|in-ns|create-ns|import|intern|refer|alias|namespace|resolve|ref|deref|refset|new|set!|memfn|to-array|into-array|aset|gen-class|reduce|map|filter|find|nil?|empty?|hash-map|hash-set|vec|vector|seq|flatten|reverse|assoc|dissoc|list|list?|disj|get|union|difference|intersection|extend|extend-type|extend-protocol|prn)\b/, null], + [PR['PR_TYPE'], /^:[0-9a-zA-Z\-]+/] + ]), + ['clj']); diff --git a/codepot/src/js/prettify/lang-css.js b/codepot/src/js/prettify/lang-css.js index 44013d26..034bd595 100644 --- a/codepot/src/js/prettify/lang-css.js +++ b/codepot/src/js/prettify/lang-css.js @@ -30,49 +30,49 @@ * @author mikesamuel@gmail.com */ -PR.registerLangHandler( - PR.createSimpleLexer( +PR['registerLangHandler']( + PR['createSimpleLexer']( [ // The space production - [PR.PR_PLAIN, /^[ \t\r\n\f]+/, null, ' \t\r\n\f'] + [PR['PR_PLAIN'], /^[ \t\r\n\f]+/, null, ' \t\r\n\f'] ], [ // Quoted strings. and - [PR.PR_STRING, + [PR['PR_STRING'], /^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/, null], - [PR.PR_STRING, + [PR['PR_STRING'], /^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/, null], ['lang-css-str', /^url\(([^\)\"\']*)\)/i], - [PR.PR_KEYWORD, + [PR['PR_KEYWORD'], /^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i, null], // A property name -- an identifier followed by a colon. ['lang-css-kw', /^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i], // A C style block comment. The production. - [PR.PR_COMMENT, /^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//], + [PR['PR_COMMENT'], /^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//], // Escaping text spans - [PR.PR_COMMENT, /^(?:)/], + [PR['PR_COMMENT'], /^(?:)/], // A number possibly containing a suffix. - [PR.PR_LITERAL, /^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i], + [PR['PR_LITERAL'], /^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i], // A hex color - [PR.PR_LITERAL, /^#(?:[0-9a-f]{3}){1,2}/i], + [PR['PR_LITERAL'], /^#(?:[0-9a-f]{3}){1,2}/i], // An identifier - [PR.PR_PLAIN, + [PR['PR_PLAIN'], /^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i], // A run of punctuation - [PR.PR_PUNCTUATION, /^[^\s\w\'\"]+/] + [PR['PR_PUNCTUATION'], /^[^\s\w\'\"]+/] ]), ['css']); -PR.registerLangHandler( - PR.createSimpleLexer([], +PR['registerLangHandler']( + PR['createSimpleLexer']([], [ - [PR.PR_KEYWORD, + [PR['PR_KEYWORD'], /^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i] ]), ['css-kw']); -PR.registerLangHandler( - PR.createSimpleLexer([], +PR['registerLangHandler']( + PR['createSimpleLexer']([], [ - [PR.PR_STRING, /^[^\)\"\']+/] + [PR['PR_STRING'], /^[^\)\"\']+/] ]), ['css-str']); diff --git a/codepot/src/js/prettify/lang-go.js b/codepot/src/js/prettify/lang-go.js new file mode 100644 index 00000000..f329e29b --- /dev/null +++ b/codepot/src/js/prettify/lang-go.js @@ -0,0 +1,58 @@ +// Copyright (C) 2010 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 + * Registers a language handler for the Go language.. + *

+ * Based on the lexical grammar at + * http://golang.org/doc/go_spec.html#Lexical_elements + *

+ * Go uses a minimal style for highlighting so the below does not distinguish + * strings, keywords, literals, etc. by design. + * From a discussion with the Go designers: + *

+ * On Thursday, July 22, 2010, Mike Samuel <...> wrote:
+ * > On Thu, Jul 22, 2010, Rob 'Commander' Pike <...> wrote:
+ * >> Personally, I would vote for the subdued style godoc presents at http://golang.org
+ * >>
+ * >> Not as fancy as some like, but a case can be made it's the official style.
+ * >> If people want more colors, I wouldn't fight too hard, in the interest of
+ * >> encouragement through familiarity, but even then I would ask to shy away
+ * >> from technicolor starbursts.
+ * >
+ * > Like http://golang.org/pkg/go/scanner/ where comments are blue and all
+ * > other content is black?  I can do that.
+ * 
+ * + * @author mikesamuel@gmail.com + */ + +PR['registerLangHandler']( + PR['createSimpleLexer']( + [ + // Whitespace is made up of spaces, tabs and newline characters. + [PR['PR_PLAIN'], /^[\t\n\r \xA0]+/, null, '\t\n\r \xA0'], + // Not escaped as a string. See note on minimalism above. + [PR['PR_PLAIN'], /^(?:\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)|\'(?:[^\'\\]|\\[\s\S])+(?:\'|$)|`[^`]*(?:`|$))/, null, '"\''] + ], + [ + // Block comments are delimited by /* and */. + // Single-line comments begin with // and extend to the end of a line. + [PR['PR_COMMENT'], /^(?:\/\/[^\r\n]*|\/\*[\s\S]*?\*\/)/], + [PR['PR_PLAIN'], /^(?:[^\/\"\'`]|\/(?![\/\*]))+/i] + ]), + ['go']); diff --git a/codepot/src/js/prettify/lang-hs.js b/codepot/src/js/prettify/lang-hs.js index 91157b98..4a15cf08 100644 --- a/codepot/src/js/prettify/lang-hs.js +++ b/codepot/src/js/prettify/lang-hs.js @@ -39,22 +39,22 @@ * @author mikesamuel@gmail.com */ -PR.registerLangHandler( - PR.createSimpleLexer( +PR['registerLangHandler']( + PR['createSimpleLexer']( [ // Whitespace // whitechar -> newline | vertab | space | tab | uniWhite // newline -> return linefeed | return | linefeed | formfeed - [PR.PR_PLAIN, /^[\t\n\x0B\x0C\r ]+/, null, '\t\n\x0B\x0C\r '], + [PR['PR_PLAIN'], /^[\t\n\x0B\x0C\r ]+/, null, '\t\n\x0B\x0C\r '], // Single line double and single-quoted strings. // char -> ' (graphic<' | \> | space | escape<\&>) ' // string -> " {graphic<" | \> | space | escape | gap}" // escape -> \ ( charesc | ascii | decimal | o octal // | x hexadecimal ) // charesc -> a | b | f | n | r | t | v | \ | " | ' | & - [PR.PR_STRING, /^\"(?:[^\"\\\n\x0C\r]|\\[\s\S])*(?:\"|$)/, + [PR['PR_STRING'], /^\"(?:[^\"\\\n\x0C\r]|\\[\s\S])*(?:\"|$)/, null, '"'], - [PR.PR_STRING, /^\'(?:[^\'\\\n\x0C\r]|\\[^&])\'?/, + [PR['PR_STRING'], /^\'(?:[^\'\\\n\x0C\r]|\\[^&])\'?/, null, "'"], // decimal -> digit{digit} // octal -> octit{octit} @@ -65,7 +65,7 @@ PR.registerLangHandler( // float -> decimal . decimal [exponent] // | decimal exponent // exponent -> (e | E) [+ | -] decimal - [PR.PR_LITERAL, + [PR['PR_LITERAL'], /^(?:0o[0-7]+|0x[\da-f]+|\d+(?:\.\d+)?(?:e[+\-]?\d+)?)/i, null, '0123456789'] ], @@ -77,12 +77,12 @@ PR.registerLangHandler( // dashes -> '--' {'-'} // opencom -> '{-' // closecom -> '-}' - [PR.PR_COMMENT, /^(?:(?:--+(?:[^\r\n\x0C]*)?)|(?:\{-(?:[^-]|-+[^-\}])*-\}))/], + [PR['PR_COMMENT'], /^(?:(?:--+(?:[^\r\n\x0C]*)?)|(?:\{-(?:[^-]|-+[^-\}])*-\}))/], // reservedid -> case | class | data | default | deriving | do // | else | if | import | in | infix | infixl | infixr // | instance | let | module | newtype | of | then // | type | where | _ - [PR.PR_KEYWORD, /^(?:case|class|data|default|deriving|do|else|if|import|in|infix|infixl|infixr|instance|let|module|newtype|of|then|type|where|_)(?=[^a-zA-Z0-9\']|$)/, null], + [PR['PR_KEYWORD'], /^(?:case|class|data|default|deriving|do|else|if|import|in|infix|infixl|infixr|instance|let|module|newtype|of|then|type|where|_)(?=[^a-zA-Z0-9\']|$)/, null], // qvarid -> [ modid . ] varid // qconid -> [ modid . ] conid // varid -> (small {small | large | digit | ' }) @@ -94,8 +94,8 @@ PR.registerLangHandler( // large -> ascLarge | uniLarge // ascLarge -> A | B | ... | Z // uniLarge -> any uppercase or titlecase Unicode letter - [PR.PR_PLAIN, /^(?:[A-Z][\w\']*\.)*[a-zA-Z][\w\']*/], + [PR['PR_PLAIN'], /^(?:[A-Z][\w\']*\.)*[a-zA-Z][\w\']*/], // matches the symbol production - [PR.PR_PUNCTUATION, /^[^\t\n\x0B\x0C\r a-zA-Z0-9\'\"]+/] + [PR['PR_PUNCTUATION'], /^[^\t\n\x0B\x0C\r a-zA-Z0-9\'\"]+/] ]), ['hs']); diff --git a/codepot/src/js/prettify/lang-lisp.js b/codepot/src/js/prettify/lang-lisp.js index 4cffa53d..3bf75d72 100644 --- a/codepot/src/js/prettify/lang-lisp.js +++ b/codepot/src/js/prettify/lang-lisp.js @@ -64,30 +64,30 @@ * @author mikesamuel@gmail.com */ -PR.registerLangHandler( - PR.createSimpleLexer( +PR['registerLangHandler']( + PR['createSimpleLexer']( [ - ['opn', /^\(/, null, '('], - ['clo', /^\)/, null, ')'], + ['opn', /^\(+/, null, '('], + ['clo', /^\)+/, null, ')'], // A line comment that starts with ; - [PR.PR_COMMENT, /^;[^\r\n]*/, null, ';'], + [PR['PR_COMMENT'], /^;[^\r\n]*/, null, ';'], // Whitespace - [PR.PR_PLAIN, /^[\t\n\r \xA0]+/, null, '\t\n\r \xA0'], + [PR['PR_PLAIN'], /^[\t\n\r \xA0]+/, null, '\t\n\r \xA0'], // A double quoted, possibly multi-line, string. - [PR.PR_STRING, /^\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)/, null, '"'] + [PR['PR_STRING'], /^\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)/, null, '"'] ], [ - [PR.PR_KEYWORD, /^(?:block|c[ad]+r|catch|cons|defun|do|eq|eql|equal|equalp|eval-when|flet|format|go|if|labels|lambda|let|load-time-value|locally|macrolet|multiple-value-call|nil|progn|progv|quote|require|return-from|setq|symbol-macrolet|t|tagbody|the|throw|unwind)\b/, null], - [PR.PR_LITERAL, - /^[+\-]?(?:0x[0-9a-f]+|\d+\/\d+|(?:\.\d+|\d+(?:\.\d*)?)(?:[ed][+\-]?\d+)?)/i], + [PR['PR_KEYWORD'], /^(?:block|c[ad]+r|catch|con[ds]|def(?:ine|un)|do|eq|eql|equal|equalp|eval-when|flet|format|go|if|labels|lambda|let|load-time-value|locally|macrolet|multiple-value-call|nil|progn|progv|quote|require|return-from|setq|symbol-macrolet|t|tagbody|the|throw|unwind)\b/, null], + [PR['PR_LITERAL'], + /^[+\-]?(?:[0#]x[0-9a-f]+|\d+\/\d+|(?:\.\d+|\d+(?:\.\d*)?)(?:[ed][+\-]?\d+)?)/i], // A single quote possibly followed by a word that optionally ends with // = ! or ?. - [PR.PR_LITERAL, + [PR['PR_LITERAL'], /^\'(?:-*(?:\w|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?)?/], // A word that optionally ends with = ! or ?. - [PR.PR_PLAIN, + [PR['PR_PLAIN'], /^-*(?:[a-z_]|\\[\x21-\x7e])(?:[\w-]*|\\[\x21-\x7e])[=!?]?/i], // A printable non-space non-special character - [PR.PR_PUNCTUATION, /^[^\w\t\n\r \xA0()\"\\\';]+/] + [PR['PR_PUNCTUATION'], /^[^\w\t\n\r \xA0()\"\\\';]+/] ]), ['cl', 'el', 'lisp', 'scm']); diff --git a/codepot/src/js/prettify/lang-lua.js b/codepot/src/js/prettify/lang-lua.js index 68bb30b9..7a3f9766 100644 --- a/codepot/src/js/prettify/lang-lua.js +++ b/codepot/src/js/prettify/lang-lua.js @@ -32,28 +32,28 @@ * @author mikesamuel@gmail.com */ -PR.registerLangHandler( - PR.createSimpleLexer( +PR['registerLangHandler']( + PR['createSimpleLexer']( [ // Whitespace - [PR.PR_PLAIN, /^[\t\n\r \xA0]+/, null, '\t\n\r \xA0'], + [PR['PR_PLAIN'], /^[\t\n\r \xA0]+/, null, '\t\n\r \xA0'], // A double or single quoted, possibly multi-line, string. - [PR.PR_STRING, /^(?:\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)|\'(?:[^\'\\]|\\[\s\S])*(?:\'|$))/, null, '"\''] + [PR['PR_STRING'], /^(?:\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)|\'(?:[^\'\\]|\\[\s\S])*(?:\'|$))/, null, '"\''] ], [ // A comment is either a line comment that starts with two dashes, or // two dashes preceding a long bracketed block. - [PR.PR_COMMENT, /^--(?:\[(=*)\[[\s\S]*?(?:\]\1\]|$)|[^\r\n]*)/], + [PR['PR_COMMENT'], /^--(?:\[(=*)\[[\s\S]*?(?:\]\1\]|$)|[^\r\n]*)/], // A long bracketed block not preceded by -- is a string. - [PR.PR_STRING, /^\[(=*)\[[\s\S]*?(?:\]\1\]|$)/], - [PR.PR_KEYWORD, /^(?:and|break|do|else|elseif|end|false|for|function|if|in|local|nil|not|or|repeat|return|then|true|until|while)\b/, null], + [PR['PR_STRING'], /^\[(=*)\[[\s\S]*?(?:\]\1\]|$)/], + [PR['PR_KEYWORD'], /^(?:and|break|do|else|elseif|end|false|for|function|if|in|local|nil|not|or|repeat|return|then|true|until|while)\b/, null], // A number is a hex integer literal, a decimal real literal, or in // scientific notation. - [PR.PR_LITERAL, + [PR['PR_LITERAL'], /^[+-]?(?:0x[\da-f]+|(?:(?:\.\d+|\d+(?:\.\d*)?)(?:e[+\-]?\d+)?))/i], // An identifier - [PR.PR_PLAIN, /^[a-z_]\w*/i], + [PR['PR_PLAIN'], /^[a-z_]\w*/i], // A run of punctuation - [PR.PR_PUNCTUATION, /^[^\w\t\n\r \xA0][^\w\t\n\r \xA0\"\'\-\+=]*/] + [PR['PR_PUNCTUATION'], /^[^\w\t\n\r \xA0][^\w\t\n\r \xA0\"\'\-\+=]*/] ]), ['lua']); diff --git a/codepot/src/js/prettify/lang-ml.js b/codepot/src/js/prettify/lang-ml.js index c5a3db73..b5a4c171 100644 --- a/codepot/src/js/prettify/lang-ml.js +++ b/codepot/src/js/prettify/lang-ml.js @@ -19,38 +19,38 @@ * Registers a language handler for OCaml, SML, F# and similar languages. * * Based on the lexical grammar at - * http://research.microsoft.com/fsharp/manual/spec2.aspx#_Toc202383715 + * http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/manual/spec.html#_Toc270597388 * * @author mikesamuel@gmail.com */ -PR.registerLangHandler( - PR.createSimpleLexer( +PR['registerLangHandler']( + PR['createSimpleLexer']( [ // Whitespace is made up of spaces, tabs and newline characters. - [PR.PR_PLAIN, /^[\t\n\r \xA0]+/, null, '\t\n\r \xA0'], + [PR['PR_PLAIN'], /^[\t\n\r \xA0]+/, null, '\t\n\r \xA0'], // #if ident/#else/#endif directives delimit conditional compilation // sections - [PR.PR_COMMENT, + [PR['PR_COMMENT'], /^#(?:if[\t\n\r \xA0]+(?:[a-z_$][\w\']*|``[^\r\n\t`]*(?:``|$))|else|endif|light)/i, null, '#'], // A double or single quoted, possibly multi-line, string. // F# allows escaped newlines in strings. - [PR.PR_STRING, /^(?:\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)|\'(?:[^\'\\]|\\[\s\S])*(?:\'|$))/, null, '"\''] + [PR['PR_STRING'], /^(?:\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)|\'(?:[^\'\\]|\\[\s\S])(?:\'|$))/, null, '"\''] ], [ // Block comments are delimited by (* and *) and may be // nested. Single-line comments begin with // and extend to // the end of a line. // TODO: (*...*) comments can be nested. This does not handle that. - [PR.PR_COMMENT, /^(?:\/\/[^\r\n]*|\(\*[\s\S]*?\*\))/], - [PR.PR_KEYWORD, /^(?:abstract|and|as|assert|begin|class|default|delegate|do|done|downcast|downto|elif|else|end|exception|extern|false|finally|for|fun|function|if|in|inherit|inline|interface|internal|lazy|let|match|member|module|mutable|namespace|new|null|of|open|or|override|private|public|rec|return|static|struct|then|to|true|try|type|upcast|use|val|void|when|while|with|yield|asr|land|lor|lsl|lsr|lxor|mod|sig|atomic|break|checked|component|const|constraint|constructor|continue|eager|event|external|fixed|functor|global|include|method|mixin|object|parallel|process|protected|pure|sealed|trait|virtual|volatile)\b/], + [PR['PR_COMMENT'], /^(?:\/\/[^\r\n]*|\(\*[\s\S]*?\*\))/], + [PR['PR_KEYWORD'], /^(?:abstract|and|as|assert|begin|class|default|delegate|do|done|downcast|downto|elif|else|end|exception|extern|false|finally|for|fun|function|if|in|inherit|inline|interface|internal|lazy|let|match|member|module|mutable|namespace|new|null|of|open|or|override|private|public|rec|return|static|struct|then|to|true|try|type|upcast|use|val|void|when|while|with|yield|asr|land|lor|lsl|lsr|lxor|mod|sig|atomic|break|checked|component|const|constraint|constructor|continue|eager|event|external|fixed|functor|global|include|method|mixin|object|parallel|process|protected|pure|sealed|trait|virtual|volatile)\b/], // A number is a hex integer literal, a decimal real literal, or in // scientific notation. - [PR.PR_LITERAL, + [PR['PR_LITERAL'], /^[+\-]?(?:0x[\da-f]+|(?:(?:\.\d+|\d+(?:\.\d*)?)(?:e[+\-]?\d+)?))/i], - [PR.PR_PLAIN, /^(?:[a-z_]\w*[!?#]?|``[^\r\n\t`]*(?:``|$))/i], + [PR['PR_PLAIN'], /^(?:[a-z_][\w']*[!?#]?|``[^\r\n\t`]*(?:``|$))/i], // A printable non-space non-special character - [PR.PR_PUNCTUATION, /^[^\t\n\r \xA0\"\'\w]+/] + [PR['PR_PUNCTUATION'], /^[^\t\n\r \xA0\"\'\w]+/] ]), ['fs', 'ml']); diff --git a/codepot/src/js/prettify/lang-n.js b/codepot/src/js/prettify/lang-n.js new file mode 100644 index 00000000..babe8f37 --- /dev/null +++ b/codepot/src/js/prettify/lang-n.js @@ -0,0 +1,62 @@ +// Copyright (C) 2011 Zimin A.V. +// +// 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 + * Registers a language handler for the Nemerle language. + * http://nemerle.org + * @author Zimin A.V. + */ +(function () { + var keywords = 'abstract|and|as|base|catch|class|def|delegate|enum|event|extern|false|finally|' + + 'fun|implements|interface|internal|is|macro|match|matches|module|mutable|namespace|new|' + + 'null|out|override|params|partial|private|protected|public|ref|sealed|static|struct|' + + 'syntax|this|throw|true|try|type|typeof|using|variant|virtual|volatile|when|where|with|' + + 'assert|assert2|async|break|checked|continue|do|else|ensures|for|foreach|if|late|lock|new|nolate|' + + 'otherwise|regexp|repeat|requires|return|surroundwith|unchecked|unless|using|while|yield'; + + var shortcutStylePatterns = [ + [PR.PR_STRING, /^(?:\'(?:[^\\\'\r\n]|\\.)*\'|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/, null, '"'], + [PR.PR_COMMENT, /^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/, null, '#'], + [PR.PR_PLAIN, /^\s+/, null, ' \r\n\t\xA0'] + ]; + + var fallthroughStylePatterns = [ + [PR.PR_STRING, /^@\"(?:[^\"]|\"\")*(?:\"|$)/, null], + [PR.PR_STRING, /^<#(?:[^#>])*(?:#>|$)/, null], + [PR.PR_STRING, /^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/, null], + [PR.PR_COMMENT, /^\/\/[^\r\n]*/, null], + [PR.PR_COMMENT, /^\/\*[\s\S]*?(?:\*\/|$)/, null], + [PR.PR_KEYWORD, new RegExp('^(?:' + keywords + ')\\b'), null], + [PR.PR_TYPE, /^(?:array|bool|byte|char|decimal|double|float|int|list|long|object|sbyte|short|string|ulong|uint|ufloat|ulong|ushort|void)\b/, null], + [PR.PR_LITERAL, /^@[a-z_$][a-z_$@0-9]*/i, null], + [PR.PR_TYPE, /^@[A-Z]+[a-z][A-Za-z_$@0-9]*/, null], + [PR.PR_PLAIN, /^'?[A-Za-z_$][a-z_$@0-9]*/i, null], + [PR.PR_LITERAL, new RegExp( + '^(?:' + // A hex number + + '0x[a-f0-9]+' + // or an octal or decimal number, + + '|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)' + // possibly in scientific notation + + '(?:e[+\\-]?\\d+)?' + + ')' + // with an optional modifier like UL for unsigned long + + '[a-z]*', 'i'), null, '0123456789'], + + [PR.PR_PUNCTUATION, /^.[^\s\w\.$@\'\"\`\/\#]*/, null] + ]; + PR.registerLangHandler(PR.createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns), ['n', 'nemerle']); +})(); diff --git a/codepot/src/js/prettify/lang-proto.js b/codepot/src/js/prettify/lang-proto.js index d6531fd9..53954915 100644 --- a/codepot/src/js/prettify/lang-proto.js +++ b/codepot/src/js/prettify/lang-proto.js @@ -24,12 +24,12 @@ * @author mikesamuel@gmail.com */ -PR.registerLangHandler(PR.sourceDecorator({ - keywords: ( - 'bool bytes default double enum extend extensions false fixed32 ' - + 'fixed64 float group import int32 int64 max message option ' - + 'optional package repeated required returns rpc service ' - + 'sfixed32 sfixed64 sint32 sint64 string syntax to true uint32 ' - + 'uint64'), - cStyleComments: true +PR['registerLangHandler'](PR['sourceDecorator']({ + 'keywords': ( + 'bytes,default,double,enum,extend,extensions,false,' + + 'group,import,max,message,option,' + + 'optional,package,repeated,required,returns,rpc,service,' + + 'syntax,to,true'), + 'types': /^(bool|(double|s?fixed|[su]?int)(32|64)|float|string)\b/, + 'cStyleComments': true }), ['proto']); diff --git a/codepot/src/js/prettify/lang-scala.js b/codepot/src/js/prettify/lang-scala.js new file mode 100644 index 00000000..db9b484c --- /dev/null +++ b/codepot/src/js/prettify/lang-scala.js @@ -0,0 +1,54 @@ +// Copyright (C) 2010 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 + * Registers a language handler for Scala. + * + * Derived from http://lampsvn.epfl.ch/svn-repos/scala/scala-documentation/trunk/src/reference/SyntaxSummary.tex + * + * @author mikesamuel@gmail.com + */ + +PR['registerLangHandler']( + PR['createSimpleLexer']( + [ + // Whitespace + [PR['PR_PLAIN'], /^[\t\n\r \xA0]+/, null, '\t\n\r \xA0'], + // A double or single quoted string + // or a triple double-quoted multi-line string. + [PR['PR_STRING'], + /^(?:"(?:(?:""(?:""?(?!")|[^\\"]|\\.)*"{0,3})|(?:[^"\r\n\\]|\\.)*"?))/, + null, '"'], + [PR['PR_LITERAL'], /^`(?:[^\r\n\\`]|\\.)*`?/, null, '`'], + [PR['PR_PUNCTUATION'], /^[!#%&()*+,\-:;<=>?@\[\\\]^{|}~]+/, null, + '!#%&()*+,-:;<=>?@[\\]^{|}~'] + ], + [ + // A symbol literal is a single quote followed by an identifier with no + // single quote following + // A character literal has single quotes on either side + [PR['PR_STRING'], /^'(?:[^\r\n\\']|\\(?:'|[^\r\n']+))'/], + [PR['PR_LITERAL'], /^'[a-zA-Z_$][\w$]*(?!['$\w])/], + [PR['PR_KEYWORD'], /^(?:abstract|case|catch|class|def|do|else|extends|final|finally|for|forSome|if|implicit|import|lazy|match|new|object|override|package|private|protected|requires|return|sealed|super|throw|trait|try|type|val|var|while|with|yield)\b/], + [PR['PR_LITERAL'], /^(?:true|false|null|this)\b/], + [PR['PR_LITERAL'], /^(?:(?:0(?:[0-7]+|X[0-9A-F]+))L?|(?:(?:0|[1-9][0-9]*)(?:(?:\.[0-9]+)?(?:E[+\-]?[0-9]+)?F?|L?))|\\.[0-9]+(?:E[+\-]?[0-9]+)?F?)/i], + // Treat upper camel case identifiers as types. + [PR['PR_TYPE'], /^[$_]*[A-Z][_$A-Z0-9]*[a-z][\w$]*/], + [PR['PR_PLAIN'], /^[$a-zA-Z_][\w$]*/], + [PR['PR_COMMENT'], /^\/(?:\/.*|\*(?:\/|\**[^*/])*(?:\*+\/?)?)/], + [PR['PR_PUNCTUATION'], /^(?:\.+|\/)/] + ]), + ['scala']); diff --git a/codepot/src/js/prettify/lang-sql.js b/codepot/src/js/prettify/lang-sql.js index 7a580974..a4adec87 100644 --- a/codepot/src/js/prettify/lang-sql.js +++ b/codepot/src/js/prettify/lang-sql.js @@ -31,27 +31,27 @@ * @author mikesamuel@gmail.com */ -PR.registerLangHandler( - PR.createSimpleLexer( +PR['registerLangHandler']( + PR['createSimpleLexer']( [ // Whitespace - [PR.PR_PLAIN, /^[\t\n\r \xA0]+/, null, '\t\n\r \xA0'], + [PR['PR_PLAIN'], /^[\t\n\r \xA0]+/, null, '\t\n\r \xA0'], // A double or single quoted, possibly multi-line, string. - [PR.PR_STRING, /^(?:"(?:[^\"\\]|\\.)*"|'(?:[^\'\\]|\\.)*')/, null, + [PR['PR_STRING'], /^(?:"(?:[^\"\\]|\\.)*"|'(?:[^\'\\]|\\.)*')/, null, '"\''] ], [ // A comment is either a line comment that starts with two dashes, or // two dashes preceding a long bracketed block. - [PR.PR_COMMENT, /^(?:--[^\r\n]*|\/\*[\s\S]*?(?:\*\/|$))/], - [PR.PR_KEYWORD, /^(?:ADD|ALL|ALTER|AND|ANY|AS|ASC|AUTHORIZATION|BACKUP|BEGIN|BETWEEN|BREAK|BROWSE|BULK|BY|CASCADE|CASE|CHECK|CHECKPOINT|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMN|COMMIT|COMPUTE|CONSTRAINT|CONTAINS|CONTAINSTABLE|CONTINUE|CONVERT|CREATE|CROSS|CURRENT|CURRENT_DATE|CURRENT_TIME|CURRENT_TIMESTAMP|CURRENT_USER|CURSOR|DATABASE|DBCC|DEALLOCATE|DECLARE|DEFAULT|DELETE|DENY|DESC|DISK|DISTINCT|DISTRIBUTED|DOUBLE|DROP|DUMMY|DUMP|ELSE|END|ERRLVL|ESCAPE|EXCEPT|EXEC|EXECUTE|EXISTS|EXIT|FETCH|FILE|FILLFACTOR|FOR|FOREIGN|FREETEXT|FREETEXTTABLE|FROM|FULL|FUNCTION|GOTO|GRANT|GROUP|HAVING|HOLDLOCK|IDENTITY|IDENTITYCOL|IDENTITY_INSERT|IF|IN|INDEX|INNER|INSERT|INTERSECT|INTO|IS|JOIN|KEY|KILL|LEFT|LIKE|LINENO|LOAD|NATIONAL|NOCHECK|NONCLUSTERED|NOT|NULL|NULLIF|OF|OFF|OFFSETS|ON|OPEN|OPENDATASOURCE|OPENQUERY|OPENROWSET|OPENXML|OPTION|OR|ORDER|OUTER|OVER|PERCENT|PLAN|PRECISION|PRIMARY|PRINT|PROC|PROCEDURE|PUBLIC|RAISERROR|READ|READTEXT|RECONFIGURE|REFERENCES|REPLICATION|RESTORE|RESTRICT|RETURN|REVOKE|RIGHT|ROLLBACK|ROWCOUNT|ROWGUIDCOL|RULE|SAVE|SCHEMA|SELECT|SESSION_USER|SET|SETUSER|SHUTDOWN|SOME|STATISTICS|SYSTEM_USER|TABLE|TEXTSIZE|THEN|TO|TOP|TRAN|TRANSACTION|TRIGGER|TRUNCATE|TSEQUAL|UNION|UNIQUE|UPDATE|UPDATETEXT|USE|USER|VALUES|VARYING|VIEW|WAITFOR|WHEN|WHERE|WHILE|WITH|WRITETEXT)(?=[^\w-]|$)/i, null], + [PR['PR_COMMENT'], /^(?:--[^\r\n]*|\/\*[\s\S]*?(?:\*\/|$))/], + [PR['PR_KEYWORD'], /^(?:ADD|ALL|ALTER|AND|ANY|AS|ASC|AUTHORIZATION|BACKUP|BEGIN|BETWEEN|BREAK|BROWSE|BULK|BY|CASCADE|CASE|CHECK|CHECKPOINT|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMN|COMMIT|COMPUTE|CONSTRAINT|CONTAINS|CONTAINSTABLE|CONTINUE|CONVERT|CREATE|CROSS|CURRENT|CURRENT_DATE|CURRENT_TIME|CURRENT_TIMESTAMP|CURRENT_USER|CURSOR|DATABASE|DBCC|DEALLOCATE|DECLARE|DEFAULT|DELETE|DENY|DESC|DISK|DISTINCT|DISTRIBUTED|DOUBLE|DROP|DUMMY|DUMP|ELSE|END|ERRLVL|ESCAPE|EXCEPT|EXEC|EXECUTE|EXISTS|EXIT|FETCH|FILE|FILLFACTOR|FOR|FOREIGN|FREETEXT|FREETEXTTABLE|FROM|FULL|FUNCTION|GOTO|GRANT|GROUP|HAVING|HOLDLOCK|IDENTITY|IDENTITYCOL|IDENTITY_INSERT|IF|IN|INDEX|INNER|INSERT|INTERSECT|INTO|IS|JOIN|KEY|KILL|LEFT|LIKE|LINENO|LOAD|MATCH|MERGE|NATIONAL|NOCHECK|NONCLUSTERED|NOT|NULL|NULLIF|OF|OFF|OFFSETS|ON|OPEN|OPENDATASOURCE|OPENQUERY|OPENROWSET|OPENXML|OPTION|OR|ORDER|OUTER|OVER|PERCENT|PLAN|PRECISION|PRIMARY|PRINT|PROC|PROCEDURE|PUBLIC|RAISERROR|READ|READTEXT|RECONFIGURE|REFERENCES|REPLICATION|RESTORE|RESTRICT|RETURN|REVOKE|RIGHT|ROLLBACK|ROWCOUNT|ROWGUIDCOL|RULE|SAVE|SCHEMA|SELECT|SESSION_USER|SET|SETUSER|SHUTDOWN|SOME|STATISTICS|SYSTEM_USER|TABLE|TEXTSIZE|THEN|TO|TOP|TRAN|TRANSACTION|TRIGGER|TRUNCATE|TSEQUAL|UNION|UNIQUE|UPDATE|UPDATETEXT|USE|USER|USING|VALUES|VARYING|VIEW|WAITFOR|WHEN|WHERE|WHILE|WITH|WRITETEXT)(?=[^\w-]|$)/i, null], // A number is a hex integer literal, a decimal real literal, or in // scientific notation. - [PR.PR_LITERAL, + [PR['PR_LITERAL'], /^[+-]?(?:0x[\da-f]+|(?:(?:\.\d+|\d+(?:\.\d*)?)(?:e[+\-]?\d+)?))/i], // An identifier - [PR.PR_PLAIN, /^[a-z_][\w-]*/i], + [PR['PR_PLAIN'], /^[a-z_][\w-]*/i], // A run of punctuation - [PR.PR_PUNCTUATION, /^[^\w\t\n\r \xA0\"\'][^\w\t\n\r \xA0+\-\"\']*/] + [PR['PR_PUNCTUATION'], /^[^\w\t\n\r \xA0\"\'][^\w\t\n\r \xA0+\-\"\']*/] ]), ['sql']); diff --git a/codepot/src/js/prettify/lang-tex.js b/codepot/src/js/prettify/lang-tex.js new file mode 100644 index 00000000..57d0ac4c --- /dev/null +++ b/codepot/src/js/prettify/lang-tex.js @@ -0,0 +1,46 @@ +// Copyright (C) 2011 Martin S. +// +// 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 + * Support for tex highlighting as discussed on + * meta.tex.stackexchange.com. + * + * @author Martin S. + */ + +PR.registerLangHandler( + PR.createSimpleLexer( + [ + // whitespace + [PR.PR_PLAIN, /^[\t\n\r \xA0]+/, null, '\t\n\r \xA0'], + // all comments begin with '%' + [PR.PR_COMMENT, /^%[^\r\n]*/, null, '%'] + ], + [ + //[PR.PR_DECLARATION, /^\\([egx]?def|(new|renew|provide)(command|environment))\b/], + // any command starting with a \ and contains + // either only letters (a-z,A-Z), '@' (internal macros) + [PR.PR_KEYWORD, /^\\[a-zA-Z@]+/], + // or contains only one character + [PR.PR_KEYWORD, /^\\./], + // Highlight dollar for math mode and ampersam for tabular + [PR.PR_TYPE, /^[$&]/], + // numeric measurement values with attached units + [PR.PR_LITERAL, + /[+-]?(?:\.\d+|\d+(?:\.\d*)?)(cm|em|ex|in|pc|pt|bp|mm)/i], + // punctuation usually occurring within commands + [PR.PR_PUNCTUATION, /^[{}()\[\]=]+/] + ]), + ['latex', 'tex']); diff --git a/codepot/src/js/prettify/lang-vb.js b/codepot/src/js/prettify/lang-vb.js index a38db455..5fb4a380 100644 --- a/codepot/src/js/prettify/lang-vb.js +++ b/codepot/src/js/prettify/lang-vb.js @@ -30,32 +30,32 @@ * @author mikesamuel@gmail.com */ -PR.registerLangHandler( - PR.createSimpleLexer( +PR['registerLangHandler']( + PR['createSimpleLexer']( [ // Whitespace - [PR.PR_PLAIN, /^[\t\n\r \xA0\u2028\u2029]+/, null, '\t\n\r \xA0\u2028\u2029'], + [PR['PR_PLAIN'], /^[\t\n\r \xA0\u2028\u2029]+/, null, '\t\n\r \xA0\u2028\u2029'], // A double quoted string with quotes escaped by doubling them. // A single character can be suffixed with C. - [PR.PR_STRING, /^(?:[\"\u201C\u201D](?:[^\"\u201C\u201D]|[\"\u201C\u201D]{2})(?:[\"\u201C\u201D]c|$)|[\"\u201C\u201D](?:[^\"\u201C\u201D]|[\"\u201C\u201D]{2})*(?:[\"\u201C\u201D]|$))/i, null, + [PR['PR_STRING'], /^(?:[\"\u201C\u201D](?:[^\"\u201C\u201D]|[\"\u201C\u201D]{2})(?:[\"\u201C\u201D]c|$)|[\"\u201C\u201D](?:[^\"\u201C\u201D]|[\"\u201C\u201D]{2})*(?:[\"\u201C\u201D]|$))/i, null, '"\u201C\u201D'], // A comment starts with a single quote and runs until the end of the // line. - [PR.PR_COMMENT, /^[\'\u2018\u2019][^\r\n\u2028\u2029]*/, null, '\'\u2018\u2019'] + [PR['PR_COMMENT'], /^[\'\u2018\u2019][^\r\n\u2028\u2029]*/, null, '\'\u2018\u2019'] ], [ - [PR.PR_KEYWORD, /^(?:AddHandler|AddressOf|Alias|And|AndAlso|Ansi|As|Assembly|Auto|Boolean|ByRef|Byte|ByVal|Call|Case|Catch|CBool|CByte|CChar|CDate|CDbl|CDec|Char|CInt|Class|CLng|CObj|Const|CShort|CSng|CStr|CType|Date|Decimal|Declare|Default|Delegate|Dim|DirectCast|Do|Double|Each|Else|ElseIf|End|EndIf|Enum|Erase|Error|Event|Exit|Finally|For|Friend|Function|Get|GetType|GoSub|GoTo|Handles|If|Implements|Imports|In|Inherits|Integer|Interface|Is|Let|Lib|Like|Long|Loop|Me|Mod|Module|MustInherit|MustOverride|MyBase|MyClass|Namespace|New|Next|Not|NotInheritable|NotOverridable|Object|On|Option|Optional|Or|OrElse|Overloads|Overridable|Overrides|ParamArray|Preserve|Private|Property|Protected|Public|RaiseEvent|ReadOnly|ReDim|RemoveHandler|Resume|Return|Select|Set|Shadows|Shared|Short|Single|Static|Step|Stop|String|Structure|Sub|SyncLock|Then|Throw|To|Try|TypeOf|Unicode|Until|Variant|Wend|When|While|With|WithEvents|WriteOnly|Xor|EndIf|GoSub|Let|Variant|Wend)\b/i, null], + [PR['PR_KEYWORD'], /^(?:AddHandler|AddressOf|Alias|And|AndAlso|Ansi|As|Assembly|Auto|Boolean|ByRef|Byte|ByVal|Call|Case|Catch|CBool|CByte|CChar|CDate|CDbl|CDec|Char|CInt|Class|CLng|CObj|Const|CShort|CSng|CStr|CType|Date|Decimal|Declare|Default|Delegate|Dim|DirectCast|Do|Double|Each|Else|ElseIf|End|EndIf|Enum|Erase|Error|Event|Exit|Finally|For|Friend|Function|Get|GetType|GoSub|GoTo|Handles|If|Implements|Imports|In|Inherits|Integer|Interface|Is|Let|Lib|Like|Long|Loop|Me|Mod|Module|MustInherit|MustOverride|MyBase|MyClass|Namespace|New|Next|Not|NotInheritable|NotOverridable|Object|On|Option|Optional|Or|OrElse|Overloads|Overridable|Overrides|ParamArray|Preserve|Private|Property|Protected|Public|RaiseEvent|ReadOnly|ReDim|RemoveHandler|Resume|Return|Select|Set|Shadows|Shared|Short|Single|Static|Step|Stop|String|Structure|Sub|SyncLock|Then|Throw|To|Try|TypeOf|Unicode|Until|Variant|Wend|When|While|With|WithEvents|WriteOnly|Xor|EndIf|GoSub|Let|Variant|Wend)\b/i, null], // A second comment form - [PR.PR_COMMENT, /^REM[^\r\n\u2028\u2029]*/i], + [PR['PR_COMMENT'], /^REM[^\r\n\u2028\u2029]*/i], // A boolean, numeric, or date literal. - [PR.PR_LITERAL, + [PR['PR_LITERAL'], /^(?:True\b|False\b|Nothing\b|\d+(?:E[+\-]?\d+[FRD]?|[FRDSIL])?|(?:&H[0-9A-F]+|&O[0-7]+)[SIL]?|\d*\.\d+(?:E[+\-]?\d+)?[FRD]?|#\s+(?:\d+[\-\/]\d+[\-\/]\d+(?:\s+\d+:\d+(?::\d+)?(\s*(?:AM|PM))?)?|\d+:\d+(?::\d+)?(\s*(?:AM|PM))?)\s+#)/i], // An identifier? - [PR.PR_PLAIN, /^(?:(?:[a-z]|_\w)\w*|\[(?:[a-z]|_\w)\w*\])/i], + [PR['PR_PLAIN'], /^(?:(?:[a-z]|_\w)\w*|\[(?:[a-z]|_\w)\w*\])/i], // A run of punctuation - [PR.PR_PUNCTUATION, + [PR['PR_PUNCTUATION'], /^[^\w\t\n\r \"\'\[\]\xA0\u2018\u2019\u201C\u201D\u2028\u2029]+/], // Square brackets - [PR.PR_PUNCTUATION, /^(?:\[|\])/] + [PR['PR_PUNCTUATION'], /^(?:\[|\])/] ]), ['vb', 'vbs']); diff --git a/codepot/src/js/prettify/lang-vhdl.js b/codepot/src/js/prettify/lang-vhdl.js new file mode 100644 index 00000000..f6410bc7 --- /dev/null +++ b/codepot/src/js/prettify/lang-vhdl.js @@ -0,0 +1,34 @@ +/** + * @fileoverview + * Registers a language handler for VHDL '93. + * + * Based on the lexical grammar and keywords at + * http://www.iis.ee.ethz.ch/~zimmi/download/vhdl93_syntax.html + * + * @author benoit@ryder.fr + */ + +PR['registerLangHandler']( + PR['createSimpleLexer']( + [ + // Whitespace + [PR['PR_PLAIN'], /^[\t\n\r \xA0]+/, null, '\t\n\r \xA0'] + ], + [ + // String, character or bit string + [PR['PR_STRING'], /^(?:[BOX]?"(?:[^\"]|"")*"|'.')/i], + // Comment, from two dashes until end of line. + [PR['PR_COMMENT'], /^--[^\r\n]*/], + [PR['PR_KEYWORD'], /^(?:abs|access|after|alias|all|and|architecture|array|assert|attribute|begin|block|body|buffer|bus|case|component|configuration|constant|disconnect|downto|else|elsif|end|entity|exit|file|for|function|generate|generic|group|guarded|if|impure|in|inertial|inout|is|label|library|linkage|literal|loop|map|mod|nand|new|next|nor|not|null|of|on|open|or|others|out|package|port|postponed|procedure|process|pure|range|record|register|reject|rem|report|return|rol|ror|select|severity|shared|signal|sla|sll|sra|srl|subtype|then|to|transport|type|unaffected|units|until|use|variable|wait|when|while|with|xnor|xor)(?=[^\w-]|$)/i, null], + // Type, predefined or standard + [PR['PR_TYPE'], /^(?:bit|bit_vector|character|boolean|integer|real|time|string|severity_level|positive|natural|signed|unsigned|line|text|std_u?logic(?:_vector)?)(?=[^\w-]|$)/i, null], + // Predefined attributes + [PR['PR_TYPE'], /^\'(?:ACTIVE|ASCENDING|BASE|DELAYED|DRIVING|DRIVING_VALUE|EVENT|HIGH|IMAGE|INSTANCE_NAME|LAST_ACTIVE|LAST_EVENT|LAST_VALUE|LEFT|LEFTOF|LENGTH|LOW|PATH_NAME|POS|PRED|QUIET|RANGE|REVERSE_RANGE|RIGHT|RIGHTOF|SIMPLE_NAME|STABLE|SUCC|TRANSACTION|VAL|VALUE)(?=[^\w-]|$)/i, null], + // Number, decimal or based literal + [PR['PR_LITERAL'], /^\d+(?:_\d+)*(?:#[\w\\.]+#(?:[+\-]?\d+(?:_\d+)*)?|(?:\.\d+(?:_\d+)*)?(?:E[+\-]?\d+(?:_\d+)*)?)/i], + // Identifier, basic or extended + [PR['PR_PLAIN'], /^(?:[a-z]\w*|\\[^\\]*\\)/i], + // Punctuation + [PR['PR_PUNCTUATION'], /^[^\w\t\n\r \xA0\"\'][^\w\t\n\r \xA0\-\"\']*/] + ]), + ['vhdl', 'vhd']); diff --git a/codepot/src/js/prettify/lang-wiki.js b/codepot/src/js/prettify/lang-wiki.js index d4aa350a..660423e3 100644 --- a/codepot/src/js/prettify/lang-wiki.js +++ b/codepot/src/js/prettify/lang-wiki.js @@ -22,32 +22,32 @@ * @author mikesamuel@gmail.com */ -PR.registerLangHandler( - PR.createSimpleLexer( +PR['registerLangHandler']( + PR['createSimpleLexer']( [ // Whitespace - [PR.PR_PLAIN, /^[\t \xA0a-gi-z0-9]+/, null, + [PR['PR_PLAIN'], /^[\t \xA0a-gi-z0-9]+/, null, '\t \xA0abcdefgijklmnopqrstuvwxyz0123456789'], // Wiki formatting - [PR.PR_PUNCTUATION, /^[=*~\^\[\]]+/, null, '=*~^[]'] + [PR['PR_PUNCTUATION'], /^[=*~\^\[\]]+/, null, '=*~^[]'] ], [ // Meta-info like #summary, #labels, etc. ['lang-wiki.meta', /(?:^^|\r\n?|\n)(#[a-z]+)\b/], // A WikiWord - [PR.PR_LITERAL, /^(?:[A-Z][a-z][a-z0-9]+[A-Z][a-z][a-zA-Z0-9]+)\b/ + [PR['PR_LITERAL'], /^(?:[A-Z][a-z][a-z0-9]+[A-Z][a-z][a-zA-Z0-9]+)\b/ ], // A preformatted block in an unknown language ['lang-', /^\{\{\{([\s\S]+?)\}\}\}/], // A block of source code in an unknown language ['lang-', /^`([^\r\n`]+)`/], // An inline URL. - [PR.PR_STRING, + [PR['PR_STRING'], /^https?:\/\/[^\/?#\s]*(?:\/[^?#\s]*)?(?:\?[^#\s]*)?(?:#\S*)?/i], - [PR.PR_PLAIN, /^(?:\r\n|[\s\S])[^#=*~^A-Zh\{`\[\r\n]*/] + [PR['PR_PLAIN'], /^(?:\r\n|[\s\S])[^#=*~^A-Zh\{`\[\r\n]*/] ]), ['wiki']); -PR.registerLangHandler( - PR.createSimpleLexer([[PR.PR_KEYWORD, /^#[a-z]+/i, null, '#']], []), +PR['registerLangHandler']( + PR['createSimpleLexer']([[PR['PR_KEYWORD'], /^#[a-z]+/i, null, '#']], []), ['wiki.meta']); diff --git a/codepot/src/js/prettify/lang-xq.js b/codepot/src/js/prettify/lang-xq.js new file mode 100644 index 00000000..38ffd72d --- /dev/null +++ b/codepot/src/js/prettify/lang-xq.js @@ -0,0 +1,67 @@ +// Copyright (C) 2011 Patrick Wied +// +// 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 + * Registers a language handler for XQuery. + * + * To use, include prettify.js and this file in your HTML page. + * Then put your code in an HTML tag like + *

+ *
+ *
+ * @author Patrick Wied ( patpa7p@live.de )
+ * @version 2010-09-28
+ */
+
+// Falls back to plain for stylesheets that don't style fun.
+var PR_FUNCTION = 'fun pln';
+// Falls back to plaiin for stylesheets that don't style var.
+var PR_VARIABLE = 'var pln';
+
+PR['registerLangHandler'](
+    PR['createSimpleLexer'](
+        [
+         // Matching $var-ia_bles
+         [PR_VARIABLE, /^\$[A-Za-z0-9_\-]+/, null, "$"]
+        ],
+        [
+         // Matching lt and gt operators
+         // Not the best matching solution but you have to differentiate between the gt operator and the tag closing char
+         [PR['PR_PLAIN'], /^[\s=][<>][\s=]/],
+         // Matching @Attributes
+         [PR['PR_LITERAL'], /^\@[\w-]+/],
+         // Matching xml tags
+         [PR['PR_TAG'], /^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],
+         // Matching single or multiline xquery comments -> (:  :)
+         [PR['PR_COMMENT'], /^\(:[\s\S]*?:\)/],
+         // Tokenizing /{}:=;*,[]() as plain
+         [PR['PR_PLAIN'], /^[\/\{\};,\[\]\(\)]$/],
+         // Matching a double or single quoted, possibly multi-line, string.
+         // with the special condition that a { in a string changes to xquery context 
+         [PR['PR_STRING'], /^(?:\"(?:[^\"\\\{]|\\[\s\S])*(?:\"|$)|\'(?:[^\'\\\{]|\\[\s\S])*(?:\'|$))/, null, '"\''],
+         // Matching standard xquery keywords
+         [PR['PR_KEYWORD'], /^(?:xquery|where|version|variable|union|typeswitch|treat|to|then|text|stable|sortby|some|self|schema|satisfies|returns|return|ref|processing-instruction|preceding-sibling|preceding|precedes|parent|only|of|node|namespace|module|let|item|intersect|instance|in|import|if|function|for|follows|following-sibling|following|external|except|every|else|element|descending|descendant-or-self|descendant|define|default|declare|comment|child|cast|case|before|attribute|assert|ascending|as|ancestor-or-self|ancestor|after|eq|order|by|or|and|schema-element|document-node|node|at)\b/],
+         // Matching standard xquery types
+         [PR['PR_TYPE'], /^(?:xs:yearMonthDuration|xs:unsignedLong|xs:time|xs:string|xs:short|xs:QName|xs:Name|xs:long|xs:integer|xs:int|xs:gYearMonth|xs:gYear|xs:gMonthDay|xs:gDay|xs:float|xs:duration|xs:double|xs:decimal|xs:dayTimeDuration|xs:dateTime|xs:date|xs:byte|xs:boolean|xs:anyURI|xf:yearMonthDuration)\b/, null],
+         // Matching standard xquery functions
+         [PR_FUNCTION, /^(?:xp:dereference|xinc:node-expand|xinc:link-references|xinc:link-expand|xhtml:restructure|xhtml:clean|xhtml:add-lists|xdmp:zip-manifest|xdmp:zip-get|xdmp:zip-create|xdmp:xquery-version|xdmp:word-convert|xdmp:with-namespaces|xdmp:version|xdmp:value|xdmp:user-roles|xdmp:user-last-login|xdmp:user|xdmp:url-encode|xdmp:url-decode|xdmp:uri-is-file|xdmp:uri-format|xdmp:uri-content-type|xdmp:unquote|xdmp:unpath|xdmp:triggers-database|xdmp:trace|xdmp:to-json|xdmp:tidy|xdmp:subbinary|xdmp:strftime|xdmp:spawn-in|xdmp:spawn|xdmp:sleep|xdmp:shutdown|xdmp:set-session-field|xdmp:set-response-encoding|xdmp:set-response-content-type|xdmp:set-response-code|xdmp:set-request-time-limit|xdmp:set|xdmp:servers|xdmp:server-status|xdmp:server-name|xdmp:server|xdmp:security-database|xdmp:security-assert|xdmp:schema-database|xdmp:save|xdmp:role-roles|xdmp:role|xdmp:rethrow|xdmp:restart|xdmp:request-timestamp|xdmp:request-status|xdmp:request-cancel|xdmp:request|xdmp:redirect-response|xdmp:random|xdmp:quote|xdmp:query-trace|xdmp:query-meters|xdmp:product-edition|xdmp:privilege-roles|xdmp:privilege|xdmp:pretty-print|xdmp:powerpoint-convert|xdmp:platform|xdmp:permission|xdmp:pdf-convert|xdmp:path|xdmp:octal-to-integer|xdmp:node-uri|xdmp:node-replace|xdmp:node-kind|xdmp:node-insert-child|xdmp:node-insert-before|xdmp:node-insert-after|xdmp:node-delete|xdmp:node-database|xdmp:mul64|xdmp:modules-root|xdmp:modules-database|xdmp:merging|xdmp:merge-cancel|xdmp:merge|xdmp:md5|xdmp:logout|xdmp:login|xdmp:log-level|xdmp:log|xdmp:lock-release|xdmp:lock-acquire|xdmp:load|xdmp:invoke-in|xdmp:invoke|xdmp:integer-to-octal|xdmp:integer-to-hex|xdmp:http-put|xdmp:http-post|xdmp:http-options|xdmp:http-head|xdmp:http-get|xdmp:http-delete|xdmp:hosts|xdmp:host-status|xdmp:host-name|xdmp:host|xdmp:hex-to-integer|xdmp:hash64|xdmp:hash32|xdmp:has-privilege|xdmp:groups|xdmp:group-serves|xdmp:group-servers|xdmp:group-name|xdmp:group-hosts|xdmp:group|xdmp:get-session-field-names|xdmp:get-session-field|xdmp:get-response-encoding|xdmp:get-response-code|xdmp:get-request-username|xdmp:get-request-user|xdmp:get-request-url|xdmp:get-request-protocol|xdmp:get-request-path|xdmp:get-request-method|xdmp:get-request-header-names|xdmp:get-request-header|xdmp:get-request-field-names|xdmp:get-request-field-filename|xdmp:get-request-field-content-type|xdmp:get-request-field|xdmp:get-request-client-certificate|xdmp:get-request-client-address|xdmp:get-request-body|xdmp:get-current-user|xdmp:get-current-roles|xdmp:get|xdmp:function-name|xdmp:function-module|xdmp:function|xdmp:from-json|xdmp:forests|xdmp:forest-status|xdmp:forest-restore|xdmp:forest-restart|xdmp:forest-name|xdmp:forest-delete|xdmp:forest-databases|xdmp:forest-counts|xdmp:forest-clear|xdmp:forest-backup|xdmp:forest|xdmp:filesystem-file|xdmp:filesystem-directory|xdmp:exists|xdmp:excel-convert|xdmp:eval-in|xdmp:eval|xdmp:estimate|xdmp:email|xdmp:element-content-type|xdmp:elapsed-time|xdmp:document-set-quality|xdmp:document-set-property|xdmp:document-set-properties|xdmp:document-set-permissions|xdmp:document-set-collections|xdmp:document-remove-properties|xdmp:document-remove-permissions|xdmp:document-remove-collections|xdmp:document-properties|xdmp:document-locks|xdmp:document-load|xdmp:document-insert|xdmp:document-get-quality|xdmp:document-get-properties|xdmp:document-get-permissions|xdmp:document-get-collections|xdmp:document-get|xdmp:document-forest|xdmp:document-delete|xdmp:document-add-properties|xdmp:document-add-permissions|xdmp:document-add-collections|xdmp:directory-properties|xdmp:directory-locks|xdmp:directory-delete|xdmp:directory-create|xdmp:directory|xdmp:diacritic-less|xdmp:describe|xdmp:default-permissions|xdmp:default-collections|xdmp:databases|xdmp:database-restore-validate|xdmp:database-restore-status|xdmp:database-restore-cancel|xdmp:database-restore|xdmp:database-name|xdmp:database-forests|xdmp:database-backup-validate|xdmp:database-backup-status|xdmp:database-backup-purge|xdmp:database-backup-cancel|xdmp:database-backup|xdmp:database|xdmp:collection-properties|xdmp:collection-locks|xdmp:collection-delete|xdmp:collation-canonical-uri|xdmp:castable-as|xdmp:can-grant-roles|xdmp:base64-encode|xdmp:base64-decode|xdmp:architecture|xdmp:apply|xdmp:amp-roles|xdmp:amp|xdmp:add64|xdmp:add-response-header|xdmp:access|trgr:trigger-set-recursive|trgr:trigger-set-permissions|trgr:trigger-set-name|trgr:trigger-set-module|trgr:trigger-set-event|trgr:trigger-set-description|trgr:trigger-remove-permissions|trgr:trigger-module|trgr:trigger-get-permissions|trgr:trigger-enable|trgr:trigger-disable|trgr:trigger-database-online-event|trgr:trigger-data-event|trgr:trigger-add-permissions|trgr:remove-trigger|trgr:property-content|trgr:pre-commit|trgr:post-commit|trgr:get-trigger-by-id|trgr:get-trigger|trgr:document-scope|trgr:document-content|trgr:directory-scope|trgr:create-trigger|trgr:collection-scope|trgr:any-property-content|thsr:set-entry|thsr:remove-term|thsr:remove-synonym|thsr:remove-entry|thsr:query-lookup|thsr:lookup|thsr:load|thsr:insert|thsr:expand|thsr:add-synonym|spell:suggest-detailed|spell:suggest|spell:remove-word|spell:make-dictionary|spell:load|spell:levenshtein-distance|spell:is-correct|spell:insert|spell:double-metaphone|spell:add-word|sec:users-collection|sec:user-set-roles|sec:user-set-password|sec:user-set-name|sec:user-set-description|sec:user-set-default-permissions|sec:user-set-default-collections|sec:user-remove-roles|sec:user-privileges|sec:user-get-roles|sec:user-get-description|sec:user-get-default-permissions|sec:user-get-default-collections|sec:user-doc-permissions|sec:user-doc-collections|sec:user-add-roles|sec:unprotect-collection|sec:uid-for-name|sec:set-realm|sec:security-version|sec:security-namespace|sec:security-installed|sec:security-collection|sec:roles-collection|sec:role-set-roles|sec:role-set-name|sec:role-set-description|sec:role-set-default-permissions|sec:role-set-default-collections|sec:role-remove-roles|sec:role-privileges|sec:role-get-roles|sec:role-get-description|sec:role-get-default-permissions|sec:role-get-default-collections|sec:role-doc-permissions|sec:role-doc-collections|sec:role-add-roles|sec:remove-user|sec:remove-role-from-users|sec:remove-role-from-role|sec:remove-role-from-privileges|sec:remove-role-from-amps|sec:remove-role|sec:remove-privilege|sec:remove-amp|sec:protect-collection|sec:privileges-collection|sec:privilege-set-roles|sec:privilege-set-name|sec:privilege-remove-roles|sec:privilege-get-roles|sec:privilege-add-roles|sec:priv-doc-permissions|sec:priv-doc-collections|sec:get-user-names|sec:get-unique-elem-id|sec:get-role-names|sec:get-role-ids|sec:get-privilege|sec:get-distinct-permissions|sec:get-collection|sec:get-amp|sec:create-user-with-role|sec:create-user|sec:create-role|sec:create-privilege|sec:create-amp|sec:collections-collection|sec:collection-set-permissions|sec:collection-remove-permissions|sec:collection-get-permissions|sec:collection-add-permissions|sec:check-admin|sec:amps-collection|sec:amp-set-roles|sec:amp-remove-roles|sec:amp-get-roles|sec:amp-doc-permissions|sec:amp-doc-collections|sec:amp-add-roles|search:unparse|search:suggest|search:snippet|search:search|search:resolve-nodes|search:resolve|search:remove-constraint|search:parse|search:get-default-options|search:estimate|search:check-options|prof:value|prof:reset|prof:report|prof:invoke|prof:eval|prof:enable|prof:disable|prof:allowed|ppt:clean|pki:template-set-request|pki:template-set-name|pki:template-set-key-type|pki:template-set-key-options|pki:template-set-description|pki:template-in-use|pki:template-get-version|pki:template-get-request|pki:template-get-name|pki:template-get-key-type|pki:template-get-key-options|pki:template-get-id|pki:template-get-description|pki:need-certificate|pki:is-temporary|pki:insert-trusted-certificates|pki:insert-template|pki:insert-signed-certificates|pki:insert-certificate-revocation-list|pki:get-trusted-certificate-ids|pki:get-template-ids|pki:get-template-certificate-authority|pki:get-template-by-name|pki:get-template|pki:get-pending-certificate-requests-xml|pki:get-pending-certificate-requests-pem|pki:get-pending-certificate-request|pki:get-certificates-for-template-xml|pki:get-certificates-for-template|pki:get-certificates|pki:get-certificate-xml|pki:get-certificate-pem|pki:get-certificate|pki:generate-temporary-certificate-if-necessary|pki:generate-temporary-certificate|pki:generate-template-certificate-authority|pki:generate-certificate-request|pki:delete-template|pki:delete-certificate|pki:create-template|pdf:make-toc|pdf:insert-toc-headers|pdf:get-toc|pdf:clean|p:status-transition|p:state-transition|p:remove|p:pipelines|p:insert|p:get-by-id|p:get|p:execute|p:create|p:condition|p:collection|p:action|ooxml:runs-merge|ooxml:package-uris|ooxml:package-parts-insert|ooxml:package-parts|msword:clean|mcgm:polygon|mcgm:point|mcgm:geospatial-query-from-elements|mcgm:geospatial-query|mcgm:circle|math:tanh|math:tan|math:sqrt|math:sinh|math:sin|math:pow|math:modf|math:log10|math:log|math:ldexp|math:frexp|math:fmod|math:floor|math:fabs|math:exp|math:cosh|math:cos|math:ceil|math:atan2|math:atan|math:asin|math:acos|map:put|map:map|map:keys|map:get|map:delete|map:count|map:clear|lnk:to|lnk:remove|lnk:insert|lnk:get|lnk:from|lnk:create|kml:polygon|kml:point|kml:interior-polygon|kml:geospatial-query-from-elements|kml:geospatial-query|kml:circle|kml:box|gml:polygon|gml:point|gml:interior-polygon|gml:geospatial-query-from-elements|gml:geospatial-query|gml:circle|gml:box|georss:point|georss:geospatial-query|georss:circle|geo:polygon|geo:point|geo:interior-polygon|geo:geospatial-query-from-elements|geo:geospatial-query|geo:circle|geo:box|fn:zero-or-one|fn:years-from-duration|fn:year-from-dateTime|fn:year-from-date|fn:upper-case|fn:unordered|fn:true|fn:translate|fn:trace|fn:tokenize|fn:timezone-from-time|fn:timezone-from-dateTime|fn:timezone-from-date|fn:sum|fn:subtract-dateTimes-yielding-yearMonthDuration|fn:subtract-dateTimes-yielding-dayTimeDuration|fn:substring-before|fn:substring-after|fn:substring|fn:subsequence|fn:string-to-codepoints|fn:string-pad|fn:string-length|fn:string-join|fn:string|fn:static-base-uri|fn:starts-with|fn:seconds-from-time|fn:seconds-from-duration|fn:seconds-from-dateTime|fn:round-half-to-even|fn:round|fn:root|fn:reverse|fn:resolve-uri|fn:resolve-QName|fn:replace|fn:remove|fn:QName|fn:prefix-from-QName|fn:position|fn:one-or-more|fn:number|fn:not|fn:normalize-unicode|fn:normalize-space|fn:node-name|fn:node-kind|fn:nilled|fn:namespace-uri-from-QName|fn:namespace-uri-for-prefix|fn:namespace-uri|fn:name|fn:months-from-duration|fn:month-from-dateTime|fn:month-from-date|fn:minutes-from-time|fn:minutes-from-duration|fn:minutes-from-dateTime|fn:min|fn:max|fn:matches|fn:lower-case|fn:local-name-from-QName|fn:local-name|fn:last|fn:lang|fn:iri-to-uri|fn:insert-before|fn:index-of|fn:in-scope-prefixes|fn:implicit-timezone|fn:idref|fn:id|fn:hours-from-time|fn:hours-from-duration|fn:hours-from-dateTime|fn:floor|fn:false|fn:expanded-QName|fn:exists|fn:exactly-one|fn:escape-uri|fn:escape-html-uri|fn:error|fn:ends-with|fn:encode-for-uri|fn:empty|fn:document-uri|fn:doc-available|fn:doc|fn:distinct-values|fn:distinct-nodes|fn:default-collation|fn:deep-equal|fn:days-from-duration|fn:day-from-dateTime|fn:day-from-date|fn:data|fn:current-time|fn:current-dateTime|fn:current-date|fn:count|fn:contains|fn:concat|fn:compare|fn:collection|fn:codepoints-to-string|fn:codepoint-equal|fn:ceiling|fn:boolean|fn:base-uri|fn:avg|fn:adjust-time-to-timezone|fn:adjust-dateTime-to-timezone|fn:adjust-date-to-timezone|fn:abs|feed:unsubscribe|feed:subscription|feed:subscribe|feed:request|feed:item|feed:description|excel:clean|entity:enrich|dom:set-pipelines|dom:set-permissions|dom:set-name|dom:set-evaluation-context|dom:set-domain-scope|dom:set-description|dom:remove-pipeline|dom:remove-permissions|dom:remove|dom:get|dom:evaluation-context|dom:domains|dom:domain-scope|dom:create|dom:configuration-set-restart-user|dom:configuration-set-permissions|dom:configuration-set-evaluation-context|dom:configuration-set-default-domain|dom:configuration-get|dom:configuration-create|dom:collection|dom:add-pipeline|dom:add-permissions|dls:retention-rules|dls:retention-rule-remove|dls:retention-rule-insert|dls:retention-rule|dls:purge|dls:node-expand|dls:link-references|dls:link-expand|dls:documents-query|dls:document-versions-query|dls:document-version-uri|dls:document-version-query|dls:document-version-delete|dls:document-version-as-of|dls:document-version|dls:document-update|dls:document-unmanage|dls:document-set-quality|dls:document-set-property|dls:document-set-properties|dls:document-set-permissions|dls:document-set-collections|dls:document-retention-rules|dls:document-remove-properties|dls:document-remove-permissions|dls:document-remove-collections|dls:document-purge|dls:document-manage|dls:document-is-managed|dls:document-insert-and-manage|dls:document-include-query|dls:document-history|dls:document-get-permissions|dls:document-extract-part|dls:document-delete|dls:document-checkout-status|dls:document-checkout|dls:document-checkin|dls:document-add-properties|dls:document-add-permissions|dls:document-add-collections|dls:break-checkout|dls:author-query|dls:as-of-query|dbk:convert|dbg:wait|dbg:value|dbg:stopped|dbg:stop|dbg:step|dbg:status|dbg:stack|dbg:out|dbg:next|dbg:line|dbg:invoke|dbg:function|dbg:finish|dbg:expr|dbg:eval|dbg:disconnect|dbg:detach|dbg:continue|dbg:connect|dbg:clear|dbg:breakpoints|dbg:break|dbg:attached|dbg:attach|cvt:save-converted-documents|cvt:part-uri|cvt:destination-uri|cvt:basepath|cvt:basename|cts:words|cts:word-query-weight|cts:word-query-text|cts:word-query-options|cts:word-query|cts:word-match|cts:walk|cts:uris|cts:uri-match|cts:train|cts:tokenize|cts:thresholds|cts:stem|cts:similar-query-weight|cts:similar-query-nodes|cts:similar-query|cts:shortest-distance|cts:search|cts:score|cts:reverse-query-weight|cts:reverse-query-nodes|cts:reverse-query|cts:remainder|cts:registered-query-weight|cts:registered-query-options|cts:registered-query-ids|cts:registered-query|cts:register|cts:query|cts:quality|cts:properties-query-query|cts:properties-query|cts:polygon-vertices|cts:polygon|cts:point-longitude|cts:point-latitude|cts:point|cts:or-query-queries|cts:or-query|cts:not-query-weight|cts:not-query-query|cts:not-query|cts:near-query-weight|cts:near-query-queries|cts:near-query-options|cts:near-query-distance|cts:near-query|cts:highlight|cts:geospatial-co-occurrences|cts:frequency|cts:fitness|cts:field-words|cts:field-word-query-weight|cts:field-word-query-text|cts:field-word-query-options|cts:field-word-query-field-name|cts:field-word-query|cts:field-word-match|cts:entity-highlight|cts:element-words|cts:element-word-query-weight|cts:element-word-query-text|cts:element-word-query-options|cts:element-word-query-element-name|cts:element-word-query|cts:element-word-match|cts:element-values|cts:element-value-ranges|cts:element-value-query-weight|cts:element-value-query-text|cts:element-value-query-options|cts:element-value-query-element-name|cts:element-value-query|cts:element-value-match|cts:element-value-geospatial-co-occurrences|cts:element-value-co-occurrences|cts:element-range-query-weight|cts:element-range-query-value|cts:element-range-query-options|cts:element-range-query-operator|cts:element-range-query-element-name|cts:element-range-query|cts:element-query-query|cts:element-query-element-name|cts:element-query|cts:element-pair-geospatial-values|cts:element-pair-geospatial-value-match|cts:element-pair-geospatial-query-weight|cts:element-pair-geospatial-query-region|cts:element-pair-geospatial-query-options|cts:element-pair-geospatial-query-longitude-name|cts:element-pair-geospatial-query-latitude-name|cts:element-pair-geospatial-query-element-name|cts:element-pair-geospatial-query|cts:element-pair-geospatial-boxes|cts:element-geospatial-values|cts:element-geospatial-value-match|cts:element-geospatial-query-weight|cts:element-geospatial-query-region|cts:element-geospatial-query-options|cts:element-geospatial-query-element-name|cts:element-geospatial-query|cts:element-geospatial-boxes|cts:element-child-geospatial-values|cts:element-child-geospatial-value-match|cts:element-child-geospatial-query-weight|cts:element-child-geospatial-query-region|cts:element-child-geospatial-query-options|cts:element-child-geospatial-query-element-name|cts:element-child-geospatial-query-child-name|cts:element-child-geospatial-query|cts:element-child-geospatial-boxes|cts:element-attribute-words|cts:element-attribute-word-query-weight|cts:element-attribute-word-query-text|cts:element-attribute-word-query-options|cts:element-attribute-word-query-element-name|cts:element-attribute-word-query-attribute-name|cts:element-attribute-word-query|cts:element-attribute-word-match|cts:element-attribute-values|cts:element-attribute-value-ranges|cts:element-attribute-value-query-weight|cts:element-attribute-value-query-text|cts:element-attribute-value-query-options|cts:element-attribute-value-query-element-name|cts:element-attribute-value-query-attribute-name|cts:element-attribute-value-query|cts:element-attribute-value-match|cts:element-attribute-value-geospatial-co-occurrences|cts:element-attribute-value-co-occurrences|cts:element-attribute-range-query-weight|cts:element-attribute-range-query-value|cts:element-attribute-range-query-options|cts:element-attribute-range-query-operator|cts:element-attribute-range-query-element-name|cts:element-attribute-range-query-attribute-name|cts:element-attribute-range-query|cts:element-attribute-pair-geospatial-values|cts:element-attribute-pair-geospatial-value-match|cts:element-attribute-pair-geospatial-query-weight|cts:element-attribute-pair-geospatial-query-region|cts:element-attribute-pair-geospatial-query-options|cts:element-attribute-pair-geospatial-query-longitude-name|cts:element-attribute-pair-geospatial-query-latitude-name|cts:element-attribute-pair-geospatial-query-element-name|cts:element-attribute-pair-geospatial-query|cts:element-attribute-pair-geospatial-boxes|cts:document-query-uris|cts:document-query|cts:distance|cts:directory-query-uris|cts:directory-query-depth|cts:directory-query|cts:destination|cts:deregister|cts:contains|cts:confidence|cts:collections|cts:collection-query-uris|cts:collection-query|cts:collection-match|cts:classify|cts:circle-radius|cts:circle-center|cts:circle|cts:box-west|cts:box-south|cts:box-north|cts:box-east|cts:box|cts:bearing|cts:arc-intersection|cts:and-query-queries|cts:and-query-options|cts:and-query|cts:and-not-query-positive-query|cts:and-not-query-negative-query|cts:and-not-query|css:get|css:convert|cpf:success|cpf:failure|cpf:document-set-state|cpf:document-set-processing-status|cpf:document-set-last-updated|cpf:document-set-error|cpf:document-get-state|cpf:document-get-processing-status|cpf:document-get-last-updated|cpf:document-get-error|cpf:check-transition|alert:spawn-matching-actions|alert:rule-user-id-query|alert:rule-set-user-id|alert:rule-set-query|alert:rule-set-options|alert:rule-set-name|alert:rule-set-description|alert:rule-set-action|alert:rule-remove|alert:rule-name-query|alert:rule-insert|alert:rule-id-query|alert:rule-get-user-id|alert:rule-get-query|alert:rule-get-options|alert:rule-get-name|alert:rule-get-id|alert:rule-get-description|alert:rule-get-action|alert:rule-action-query|alert:remove-triggers|alert:make-rule|alert:make-log-action|alert:make-config|alert:make-action|alert:invoke-matching-actions|alert:get-my-rules|alert:get-all-rules|alert:get-actions|alert:find-matching-rules|alert:create-triggers|alert:config-set-uri|alert:config-set-trigger-ids|alert:config-set-options|alert:config-set-name|alert:config-set-description|alert:config-set-cpf-domain-names|alert:config-set-cpf-domain-ids|alert:config-insert|alert:config-get-uri|alert:config-get-trigger-ids|alert:config-get-options|alert:config-get-name|alert:config-get-id|alert:config-get-description|alert:config-get-cpf-domain-names|alert:config-get-cpf-domain-ids|alert:config-get|alert:config-delete|alert:action-set-options|alert:action-set-name|alert:action-set-module-root|alert:action-set-module-db|alert:action-set-module|alert:action-set-description|alert:action-remove|alert:action-insert|alert:action-get-options|alert:action-get-name|alert:action-get-module-root|alert:action-get-module-db|alert:action-get-module|alert:action-get-description|zero-or-one|years-from-duration|year-from-dateTime|year-from-date|upper-case|unordered|true|translate|trace|tokenize|timezone-from-time|timezone-from-dateTime|timezone-from-date|sum|subtract-dateTimes-yielding-yearMonthDuration|subtract-dateTimes-yielding-dayTimeDuration|substring-before|substring-after|substring|subsequence|string-to-codepoints|string-pad|string-length|string-join|string|static-base-uri|starts-with|seconds-from-time|seconds-from-duration|seconds-from-dateTime|round-half-to-even|round|root|reverse|resolve-uri|resolve-QName|replace|remove|QName|prefix-from-QName|position|one-or-more|number|not|normalize-unicode|normalize-space|node-name|node-kind|nilled|namespace-uri-from-QName|namespace-uri-for-prefix|namespace-uri|name|months-from-duration|month-from-dateTime|month-from-date|minutes-from-time|minutes-from-duration|minutes-from-dateTime|min|max|matches|lower-case|local-name-from-QName|local-name|last|lang|iri-to-uri|insert-before|index-of|in-scope-prefixes|implicit-timezone|idref|id|hours-from-time|hours-from-duration|hours-from-dateTime|floor|false|expanded-QName|exists|exactly-one|escape-uri|escape-html-uri|error|ends-with|encode-for-uri|empty|document-uri|doc-available|doc|distinct-values|distinct-nodes|default-collation|deep-equal|days-from-duration|day-from-dateTime|day-from-date|data|current-time|current-dateTime|current-date|count|contains|concat|compare|collection|codepoints-to-string|codepoint-equal|ceiling|boolean|base-uri|avg|adjust-time-to-timezone|adjust-dateTime-to-timezone|adjust-date-to-timezone|abs)\b/],
+         // Matching normal words if none of the previous regular expressions matched
+         [PR['PR_PLAIN'], /^[A-Za-z0-9_\-\:]+/],
+         // Matching whitespaces
+         [PR['PR_PLAIN'], /^[\t\n\r \xA0]+/]
+         ]),
+    ['xq', 'xquery']);
diff --git a/codepot/src/js/prettify/lang-yaml.js b/codepot/src/js/prettify/lang-yaml.js
new file mode 100644
index 00000000..c2e52b2d
--- /dev/null
+++ b/codepot/src/js/prettify/lang-yaml.js
@@ -0,0 +1,27 @@
+// Contributed by ribrdb @ code.google.com
+
+/**
+ * @fileoverview
+ * Registers a language handler for YAML.
+ *
+ * @author ribrdb
+ */
+
+PR['registerLangHandler'](
+  PR['createSimpleLexer'](
+    [
+      [PR['PR_PUNCTUATION'], /^[:|>?]+/, null, ':|>?'],
+      [PR['PR_DECLARATION'],  /^%(?:YAML|TAG)[^#\r\n]+/, null, '%'],
+      [PR['PR_TYPE'], /^[&]\S+/, null, '&'],
+      [PR['PR_TYPE'], /^!\S*/, null, '!'],
+      [PR['PR_STRING'], /^"(?:[^\\"]|\\.)*(?:"|$)/, null, '"'],
+      [PR['PR_STRING'], /^'(?:[^']|'')*(?:'|$)/, null, "'"],
+      [PR['PR_COMMENT'], /^#[^\r\n]*/, null, '#'],
+      [PR['PR_PLAIN'], /^\s+/, null, ' \t\r\n']
+    ],
+    [
+      [PR['PR_DECLARATION'], /^(?:---|\.\.\.)(?:[\r\n]|$)/],
+      [PR['PR_PUNCTUATION'], /^-/],
+      [PR['PR_KEYWORD'], /^\w+:[ \r\n]/],
+      [PR['PR_PLAIN'], /^\w+/]
+    ]), ['yaml', 'yml']);
diff --git a/codepot/src/js/prettify/prettify.css b/codepot/src/js/prettify/prettify.css
index e81515fa..400fd742 100644
--- a/codepot/src/js/prettify/prettify.css
+++ b/codepot/src/js/prettify/prettify.css
@@ -1,26 +1,52 @@
 /* Pretty printing styles. Used with prettify.js. */
 
-.str { color: #080; }
-.kwd { color: #008; }
-.com { color: #800; }
-.typ { color: #606; }
-.lit { color: #066; }
-.pun { color: #660; }
-.pln { color: #000; }
-.tag { color: #008; }
-.atn { color: #606; }
-.atv { color: #080; }
-.dec { color: #606; }
+/* SPAN elements with the classes below are added by prettyprint. */
+.pln { color: #000 }  /* plain text */
 
-@media print {
-  .str { color: #060; }
-  .kwd { color: #006; font-weight: bold; }
-  .com { color: #600; font-style: italic; }
-  .typ { color: #404; font-weight: bold; }
-  .lit { color: #044; }
-  .pun { color: #440; }
-  .pln { color: #000; }
-  .tag { color: #006; font-weight: bold; }
-  .atn { color: #404; }
-  .atv { color: #060; }
+@media screen {
+  .str { color: #080 }  /* string content */
+  .kwd { color: #008 }  /* a keyword */
+  .com { color: #800 }  /* a comment */
+  .typ { color: #606 }  /* a type name */
+  .lit { color: #066 }  /* a literal value */
+  /* punctuation, lisp open bracket, lisp close bracket */
+  .pun, .opn, .clo { color: #660 }
+  .tag { color: #008 }  /* a markup tag name */
+  .atn { color: #606 }  /* a markup attribute name */
+  .atv { color: #080 }  /* a markup attribute value */
+  .dec, .var { color: #606 }  /* a declaration; a variable name */
+  .fun { color: red }  /* a function name */
 }
+
+/* Use higher contrast and text-weight for printable form. */
+@media print, projection {
+  .str { color: #060 }
+  .kwd { color: #006; font-weight: bold }
+  .com { color: #600; font-style: italic }
+  .typ { color: #404; font-weight: bold }
+  .lit { color: #044 }
+  .pun, .opn, .clo { color: #440 }
+  .tag { color: #006; font-weight: bold }
+  .atn { color: #404 }
+  .atv { color: #060 }
+}
+
+/* Put a border around prettyprinted code snippets. */
+pre.prettyprint { padding: 2px; border: 1px solid #888 }
+
+/* Specify class=linenums on a pre to get line numbering */
+ol.linenums { margin-top: 0; margin-bottom: 0 } /* IE indents via margin-left */
+li.L0,
+li.L1,
+li.L2,
+li.L3,
+li.L5,
+li.L6,
+li.L7,
+li.L8 { list-style-type: none }
+/* Alternate shading for lines */
+li.L1,
+li.L3,
+li.L5,
+li.L7,
+li.L9 { background: #eee }
diff --git a/codepot/src/js/prettify/prettify.js b/codepot/src/js/prettify/prettify.js
index 09d6394f..037c26da 100644
--- a/codepot/src/js/prettify/prettify.js
+++ b/codepot/src/js/prettify/prettify.js
@@ -16,8 +16,8 @@
 /**
  * @fileoverview
  * some functions for browser-side pretty printing of code contained in html.
- * 

* + *

* For a fairly comprehensive set of languages see the * README * file that came with this source. At a minimum, the lexer should work on a @@ -50,7 +50,6 @@ * Java annotations (start with "@") are now captured as literals ("lit") * * @requires console - * @overrides window */ // JSLint declarations @@ -63,280 +62,157 @@ */ window['PR_SHOULD_USE_CONTINUATION'] = true; -/** the number of characters between tab columns */ -window['PR_TAB_WIDTH'] = 8; - -/** Walks the DOM returning a properly escaped version of innerHTML. - * @param {Node} node - * @param {Array.} out output buffer that receives chunks of HTML. - */ -window['PR_normalizedHtml'] - -/** Contains functions for creating and registering new language handlers. - * @type {Object} - */ - = window['PR'] - -/** Pretty print a chunk of code. - * - * @param {string} sourceCodeHtml code as html - * @return {string} code as html, but prettier - */ - = window['prettyPrintOne'] -/** Find all the {@code

} and {@code } tags in the DOM with
-  * {@code class=prettyprint} and prettify them.
-  * @param {Function?} opt_whenDone if specified, called when the last entry
-  *     has been finished.
-  */
-  = window['prettyPrint'] = void 0;
-
-/** browser detection. @extern @returns false if not IE, otherwise the major version. */
-window['_pr_isIE6'] = function () {
-  var ieVersion = navigator && navigator.userAgent &&
-      navigator.userAgent.match(/\bMSIE ([678])\./);
-  ieVersion = ieVersion ? +ieVersion[1] : false;
-  window['_pr_isIE6'] = function () { return ieVersion; };
-  return ieVersion;
-};
-
-
 (function () {
   // Keyword lists for various languages.
-  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 int long register 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 " +
-      "concept concept_map const_cast constexpr decltype " +
-      "dynamic_cast explicit export friend inline late_check " +
-      "mutable namespace nullptr reinterpret_cast static_assert static_cast " +
-      "template typeid typename using virtual wchar_t where ";
-  var JAVA_KEYWORDS = COMMON_KEYWORDS +
-      "abstract boolean byte extends final finally implements import " +
-      "instanceof null native package strictfp super synchronized throws " +
-      "transient ";
-  var CSHARP_KEYWORDS = JAVA_KEYWORDS +
-      "as base by checked decimal delegate descending event " +
-      "fixed foreach from group implicit in interface internal into is lock " +
-      "object out override orderby params partial readonly ref sbyte sealed " +
-      "stackalloc string select uint ulong unchecked unsafe ushort var ";
-  var JSCRIPT_KEYWORDS = COMMON_KEYWORDS +
-      "debugger eval export function get null set undefined var with " +
-      "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 ";
-  var PYTHON_KEYWORDS = FLOW_CONTROL_KEYWORDS + "and as assert class def del " +
-      "elif except exec finally from global import in is lambda " +
-      "nonlocal not or pass print raise try with yield " +
-      "False True None ";
-  var RUBY_KEYWORDS = FLOW_CONTROL_KEYWORDS + "alias and begin case class def" +
-      " defined elsif end ensure false in module next nil not or redo rescue " +
-      "retry self super then true undef unless until when yield BEGIN END ";
-  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);
+  // 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,int,long,register,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," +
+      "concept,concept_map,const_cast,constexpr,decltype," +
+      "dynamic_cast,explicit,export,friend,inline,late_check," +
+      "mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast," +
+      "template,typeid,typename,using,virtual,where"];
+  var JAVA_KEYWORDS = [COMMON_KEYWORDS,
+      "abstract,boolean,byte,extends,final,finally,implements,import," +
+      "instanceof,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,interface,internal,into,is,lock," +
+      "object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed," +
+      "stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];
+  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," +
+      "true,try,unless,until,when,while,yes";
+  var JSCRIPT_KEYWORDS = [COMMON_KEYWORDS,
+      "debugger,eval,export,function,get,null,set,undefined,var,with," +
+      "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";
+  var PYTHON_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "and,as,assert,class,def,del," +
+      "elif,except,exec,finally,from,global,import,in,is,lambda," +
+      "nonlocal,not,or,pass,print,raise,try,with,yield," +
+      "False,True,None"];
+  var RUBY_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "alias,and,begin,case,class," +
+      "def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo," +
+      "rescue,retry,self,super,then,true,undef,unless,until,when,yield," +
+      "BEGIN,END"];
+  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*)/;
 
   // token style names.  correspond to css classes
-  /** token style for a string literal */
+  /**
+   * token style for a string literal
+   * @const
+   */
   var PR_STRING = 'str';
-  /** token style for a keyword */
+  /**
+   * token style for a keyword
+   * @const
+   */
   var PR_KEYWORD = 'kwd';
-  /** token style for a comment */
+  /**
+   * token style for a comment
+   * @const
+   */
   var PR_COMMENT = 'com';
-  /** token style for a type */
+  /**
+   * token style for a type
+   * @const
+   */
   var PR_TYPE = 'typ';
-  /** token style for a literal value.  e.g. 1, null, true. */
+  /**
+   * token style for a literal value.  e.g. 1, null, true.
+   * @const
+   */
   var PR_LITERAL = 'lit';
-  /** token style for a punctuation string. */
+  /**
+   * token style for a punctuation string.
+   * @const
+   */
   var PR_PUNCTUATION = 'pun';
-  /** token style for a punctuation string. */
+  /**
+   * token style for a punctuation string.
+   * @const
+   */
   var PR_PLAIN = 'pln';
 
-  /** token style for an sgml tag. */
+  /**
+   * token style for an sgml tag.
+   * @const
+   */
   var PR_TAG = 'tag';
-  /** token style for a markup declaration such as a DOCTYPE. */
+  /**
+   * token style for a markup declaration such as a DOCTYPE.
+   * @const
+   */
   var PR_DECLARATION = 'dec';
-  /** token style for embedded source. */
+  /**
+   * token style for embedded source.
+   * @const
+   */
   var PR_SOURCE = 'src';
-  /** token style for an sgml attribute name. */
+  /**
+   * token style for an sgml attribute name.
+   * @const
+   */
   var PR_ATTRIB_NAME = 'atn';
-  /** token style for an sgml attribute value. */
+  /**
+   * token style for an sgml attribute value.
+   * @const
+   */
   var PR_ATTRIB_VALUE = 'atv';
 
   /**
    * A class that indicates a section of markup that is not code, e.g. to allow
    * embedding of line numbers within code listings.
+   * @const
    */
   var PR_NOCODE = 'nocode';
 
-  /** A set of tokens that can precede a regular expression literal in
-    * javascript.
-    * 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 a 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 - */ - var REGEXP_PRECEDER_PATTERN = function () { - var preceders = [ - "!", "!=", "!==", "#", "%", "%=", "&", "&&", "&&=", - "&=", "(", "*", "*=", /* "+", */ "+=", ",", /* "-", */ "-=", - "->", /*".", "..", "...", handled below */ "/", "/=", ":", "::", ";", - "<", "<<", "<<=", "<=", "=", "==", "===", ">", - ">=", ">>", ">>=", ">>>", ">>>=", "?", "@", "[", - "^", "^=", "^^", "^^=", "{", "|", "|=", "||", - "||=", "~" /* handles =~ and !~ */, - "break", "case", "continue", "delete", - "do", "else", "finally", "instanceof", - "return", "throw", "try", "typeof" - ]; - var pattern = '(?:^^|[+-]'; - for (var i = 0; i < preceders.length; ++i) { - pattern += '|' + preceders[i].replace(/([^=<>:&a-z])/g, '\\$1'); - } - pattern += ')\\s*'; // matches at end, and matches empty string - return pattern; - // 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. - }(); - - // 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; - /** like textToHtml but escapes double quotes to be attribute safe. */ - function attribToHtml(str) { - return str.replace(pr_amp, '&') - .replace(pr_lt, '<') - .replace(pr_gt, '>') - .replace(pr_quot, '"'); - } - - /** escapest html special characters to html. */ - function textToHtml(str) { - return str.replace(pr_amp, '&') - .replace(pr_lt, '<') - .replace(pr_gt, '>'); - } - var pr_ltEnt = /</g; - var pr_gtEnt = />/g; - var pr_aposEnt = /'/g; - var pr_quotEnt = /"/g; - var pr_ampEnt = /&/g; - var pr_nbspEnt = / /g; - /** unescapes html to plain text. */ - function htmlToText(html) { - var pos = html.indexOf('&'); - if (pos < 0) { return html; } - // Handle numeric entities specially. We can't use functional substitution - // since that doesn't work in older versions of Safari. - // These should be rare since most browsers convert them to normal chars. - for (--pos; (pos = html.indexOf('&#', pos + 1)) >= 0;) { - var end = html.indexOf(';', pos); - if (end >= 0) { - var num = html.substring(pos + 3, end); - var radix = 10; - if (num && num.charAt(0) === 'x') { - num = num.substring(1); - radix = 16; - } - var codePoint = parseInt(num, radix); - if (!isNaN(codePoint)) { - html = (html.substring(0, pos) + String.fromCharCode(codePoint) + - html.substring(end + 1)); - } - } - } +/** + * 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 a 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*'; - return html.replace(pr_ltEnt, '<') - .replace(pr_gtEnt, '>') - .replace(pr_aposEnt, "'") - .replace(pr_quotEnt, '"') - .replace(pr_nbspEnt, ' ') - .replace(pr_ampEnt, '&'); - } +// 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. - /** is the given node's innerHTML normally unescaped? */ - function isRawContent(node) { - return 'XMP' === node.tagName; - } - - var newlineRe = /[\r\n]/g; - /** - * Are newlines and adjacent spaces significant in the given node's innerHTML? - */ - function isPreformatted(node, content) { - // PRE means preformatted, and is a very common case, so don't create - // unnecessary computed style objects. - if ('PRE' === node.tagName) { return true; } - if (!newlineRe.test(content)) { return true; } // Don't care - var whitespace = ''; - // For disconnected nodes, IE has no currentStyle. - if (node.currentStyle) { - whitespace = node.currentStyle.whiteSpace; - } else if (window.getComputedStyle) { - // Firefox makes a best guess if node is disconnected whereas Safari - // returns the empty string. - whitespace = window.getComputedStyle(node, null).whiteSpace; - } - return !whitespace || whitespace === 'pre'; - } - - function normalizedHtml(node, out) { - switch (node.nodeType) { - case 1: // an element - var name = node.tagName.toLowerCase(); - out.push('<', name); - for (var i = 0; i < node.attributes.length; ++i) { - var attr = node.attributes[i]; - if (!attr.specified) { continue; } - out.push(' '); - normalizedHtml(attr, out); - } - out.push('>'); - for (var child = node.firstChild; child; child = child.nextSibling) { - normalizedHtml(child, out); - } - if (node.firstChild || !/^(?:br|link|img)$/.test(name)) { - out.push('<\/', name, '>'); - } - break; - case 2: // an attribute - out.push(node.name.toLowerCase(), '="', attribToHtml(node.value), '"'); - break; - case 3: case 4: // text - out.push(textToHtml(node.nodeValue)); - break; - } - } /** * Given a group of {@link RegExp}s, returns a {@code RegExp} that globally - * matches the union o the sets o strings matched d by the input RegExp. + * matches the union of the sets of strings matched by the input RegExp. * Since it matches globally, if the input strings have a start-of-input * anchor (/^.../), it is ignored for the purposes of unioning. * @param {Array.} regexs non multiline, non-global regexs. @@ -344,7 +220,7 @@ window['_pr_isIE6'] = function () { */ function combinePrefixPatterns(regexs) { var capturedGroupIndex = 0; - + var needToFoldCase = false; var ignoreCase = false; for (var i = 0, n = regexs.length; i < n; ++i) { @@ -358,26 +234,34 @@ window['_pr_isIE6'] = function () { break; } } - + + var escapeCharToCodeUnit = { + 'b': 8, + 't': 9, + 'n': 0xa, + 'v': 0xb, + 'f': 0xc, + 'r': 0xd + }; + function decodeEscape(charsetPart) { - if (charsetPart.charAt(0) !== '\\') { return charsetPart.charCodeAt(0); } - switch (charsetPart.charAt(1)) { - case 'b': return 8; - case 't': return 9; - case 'n': return 0xa; - case 'v': return 0xb; - case 'f': return 0xc; - case 'r': return 0xd; - case 'u': case 'x': - return parseInt(charsetPart.substring(2), 16) - || charsetPart.charCodeAt(1); - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': - return parseInt(charsetPart.substring(1), 8); - default: return charsetPart.charCodeAt(1); + var cc0 = charsetPart.charCodeAt(0); + if (cc0 !== 92 /* \\ */) { + return cc0; + } + var c1 = charsetPart.charAt(1); + cc0 = escapeCharToCodeUnit[c1]; + if (cc0) { + return cc0; + } else if ('0' <= c1 && c1 <= '7') { + return parseInt(charsetPart.substring(1), 8); + } else if (c1 === 'u' || c1 === 'x') { + return parseInt(charsetPart.substring(2), 16); + } else { + return charsetPart.charCodeAt(1); } } - + function encodeEscape(charCode) { if (charCode < 0x20) { return (charCode < 0x10 ? '\\x0' : '\\x') + charCode.toString(16); @@ -388,7 +272,7 @@ window['_pr_isIE6'] = function () { } return ch; } - + function caseFoldCharset(charSet) { var charsetParts = charSet.substring(1, charSet.length - 1).match( new RegExp( @@ -405,34 +289,33 @@ window['_pr_isIE6'] = function () { var inverse = charsetParts[0] === '^'; for (var i = inverse ? 1 : 0, n = charsetParts.length; i < n; ++i) { var p = charsetParts[i]; - switch (p) { - case '\\B': case '\\b': - case '\\D': case '\\d': - case '\\S': case '\\s': - case '\\W': case '\\w': - groups.push(p); - continue; - } - var start = decodeEscape(p); - var end; - if (i + 2 < n && '-' === charsetParts[i + 1]) { - end = decodeEscape(charsetParts[i + 2]); - i += 2; + if (/\\[bdsw]/i.test(p)) { // Don't muck with named groups. + groups.push(p); } else { - end = start; - } - ranges.push([start, end]); - // If the range might intersect letters, then expand it. - if (!(end < 65 || start > 122)) { - if (!(end < 65 || start > 90)) { - ranges.push([Math.max(65, start) | 32, Math.min(end, 90) | 32]); + var start = decodeEscape(p); + var end; + if (i + 2 < n && '-' === charsetParts[i + 1]) { + end = decodeEscape(charsetParts[i + 2]); + i += 2; + } else { + end = start; } - if (!(end < 97 || start > 122)) { - ranges.push([Math.max(97, start) & ~32, Math.min(end, 122) & ~32]); + ranges.push([start, end]); + // If the range might intersect letters, then expand it. + // This case handling is too simplistic. + // It does not deal with non-latin case folding. + // It works for latin source code identifiers though. + if (!(end < 65 || start > 122)) { + if (!(end < 65 || start > 90)) { + ranges.push([Math.max(65, start) | 32, Math.min(end, 90) | 32]); + } + if (!(end < 97 || start > 122)) { + ranges.push([Math.max(97, start) & ~32, Math.min(end, 122) & ~32]); + } } } } - + // [[1, 10], [3, 4], [8, 12], [14, 14], [16, 16], [17, 17]] // -> [[1, 12], [14, 14], [16, 17]] ranges.sort(function (a, b) { return (a[0] - b[0]) || (b[1] - a[1]); }); @@ -446,7 +329,7 @@ window['_pr_isIE6'] = function () { consolidatedRanges.push(lastRange = range); } } - + var out = ['[']; if (inverse) { out.push('^'); } out.push.apply(out, groups); @@ -461,7 +344,7 @@ window['_pr_isIE6'] = function () { out.push(']'); return out.join(''); } - + function allowAnywhereFoldCaseAndRenumberGroups(regex) { // Split into character sets, escape sequences, punctuation strings // like ('(', '(?:', ')', '^'), and runs of characters that do not @@ -480,12 +363,12 @@ window['_pr_isIE6'] = function () { + ')', 'g')); var n = parts.length; - + // Maps captured group numbers to the number they will occupy in // the output or to -1 if that has not been determined, or to // undefined if they need not be capturing in the output. var capturedGroups = []; - + // Walk over and identify back references to build the capturedGroups // mapping. for (var i = 0, groupIndex = 0; i < n; ++i) { @@ -500,7 +383,7 @@ window['_pr_isIE6'] = function () { } } } - + // Renumber groups and reduce capturing groups to non-capturing groups // where possible. for (var i = 1; i < capturedGroups.length; ++i) { @@ -522,14 +405,14 @@ window['_pr_isIE6'] = function () { } } } - + // Remove any prefix anchors so that the output will match anywhere. // ^^ really does mean an anchored match though. for (var i = 0, groupIndex = 0; i < n; ++i) { if ('^' === parts[i] && '^' !== parts[i + 1]) { parts[i] = ''; } } - - // Expand letters to groupts to handle mixing of case-sensitive and + + // Expand letters to groups to handle mixing of case-sensitive and // case-insensitive patterns if necessary. if (regex.ignoreCase && needToFoldCase) { for (var i = 0; i < n; ++i) { @@ -548,10 +431,10 @@ window['_pr_isIE6'] = function () { } } } - + return parts.join(''); } - + var rewritten = []; for (var i = 0, n = regexs.length; i < n; ++i) { var regex = regexs[i]; @@ -559,181 +442,111 @@ window['_pr_isIE6'] = function () { rewritten.push( '(?:' + allowAnywhereFoldCaseAndRenumberGroups(regex) + ')'); } - + return new RegExp(rewritten.join('|'), ignoreCase ? 'gi' : 'g'); } - var PR_innerHtmlWorks = null; - function getInnerHtml(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 - // tag, so we detect that case and emulate innerHTML. - if (null === PR_innerHtmlWorks) { - var testNode = document.createElement('PRE'); - testNode.appendChild( - document.createTextNode('\n')); - PR_innerHtmlWorks = !/ + * The HTML DOM structure:

+ *
+   * (Element   "p"
+   *   (Element "b"
+   *     (Text  "print "))       ; #1
+   *   (Text    "'Hello '")      ; #2
+   *   (Element "br")            ; #3
+   *   (Text    "  + 'World';")) ; #4
+   * 
+ *

+ * corresponds to the HTML + * {@code

print 'Hello '
+ 'World';

}.

+ * + *

+ * It will produce the output:

+ *
+   * {
+   *   sourceCode: "print 'Hello '\n  + 'World';",
+   *   //                 1         2
+   *   //       012345678901234 5678901234567
+   *   spans: [0, #1, 6, #2, 14, #3, 15, #4]
+   * }
+   * 
+ *

+ * where #1 is a reference to the {@code "print "} text node above, and so + * on for the other text nodes. + *

+ * + *

+ * The {@code} spans array is an array of pairs. Even elements are the start + * indices of substrings, and odd elements are the text nodes (or BR elements) + * that contain the text for those substrings. + * Substrings continue until the next index or the end of the source. + *

+ * + * @param {Node} node an HTML DOM subtree containing source-code. + * @return {Object} source code and the text nodes in which they occur. + */ + function extractSourceSpans(node) { + var nocode = /(?:^|\s)nocode(?:\s|$)/; + + var chunks = []; + var length = 0; + var spans = []; + var k = 0; + + var whitespace; + if (node.currentStyle) { + whitespace = node.currentStyle.whiteSpace; + } else if (window.getComputedStyle) { + whitespace = document.defaultView.getComputedStyle(node, null) + .getPropertyValue('white-space'); } - - if (PR_innerHtmlWorks) { - var content = node.innerHTML; - // XMP tags contain unescaped entities so require special handling. - if (isRawContent(node)) { - content = textToHtml(content); - } else if (!isPreformatted(node, content)) { - content = content.replace(/()[\r\n]+/g, '$1') - .replace(/(?:[\r\n]+[ \t]*)+/g, ' '); - } - return content; - } - - var out = []; - for (var child = node.firstChild; child; child = child.nextSibling) { - normalizedHtml(child, out); - } - return out.join(''); - } - - /** returns a function that expand tabs to spaces. This function can be fed - * successive chunks of text, and will maintain its own internal state to - * keep track of how tabs are expanded. - * @return {function (string) : string} a function that takes - * plain text and return the text with tabs expanded. - * @private - */ - function makeTabExpander(tabWidth) { - var SPACES = ' '; - var charInLine = 0; - - return function (plainText) { - // walk over each character looking for tabs and newlines. - // On tabs, expand them. On newlines, reset charInLine. - // Otherwise increment charInLine - var out = null; - var pos = 0; - for (var i = 0, n = plainText.length; i < n; ++i) { - var ch = plainText.charAt(i); - - switch (ch) { - case '\t': - if (!out) { out = []; } - out.push(plainText.substring(pos, i)); - // calculate how much space we need in front of this part - // nSpaces is the amount of padding -- the number of spaces needed - // to move us to the next column, where columns occur at factors of - // tabWidth. - var nSpaces = tabWidth - (charInLine % tabWidth); - charInLine += nSpaces; - for (; nSpaces >= 0; nSpaces -= SPACES.length) { - out.push(SPACES.substring(0, nSpaces)); + var isPreformatted = whitespace && 'pre' === whitespace.substring(0, 3); + + function walk(node) { + switch (node.nodeType) { + case 1: // Element + if (nocode.test(node.className)) { return; } + for (var child = node.firstChild; child; child = child.nextSibling) { + walk(child); + } + var nodeName = node.nodeName; + if ('BR' === nodeName || 'LI' === nodeName) { + chunks[k] = '\n'; + spans[k << 1] = length++; + spans[(k++ << 1) | 1] = node; + } + break; + case 3: case 4: // Text + var text = node.nodeValue; + if (text.length) { + if (!isPreformatted) { + text = text.replace(/[ \t\r\n]+/g, ' '); + } else { + text = text.replace(/\r\n?/g, '\n'); // Normalize newlines. } - pos = i + 1; - break; - case '\n': - charInLine = 0; - break; - default: - ++charInLine; - } + // TODO: handle tabs here? + chunks[k] = text; + spans[k << 1] = length; + length += text.length; + spans[(k++ << 1) | 1] = node; + } + break; } - if (!out) { return plainText; } - out.push(plainText.substring(pos)); - return out.join(''); + } + + walk(node); + + return { + sourceCode: chunks.join('').replace(/\n$/, ''), + spans: spans }; } - var pr_chunkPattern = new RegExp( - '[^<]+' // A run of characters other than '<' - + '|<\!--[\\s\\S]*?--\>' // an HTML comment - + '|' // a CDATA section - // a probable tag that should not be highlighted - + '|<\/?[a-zA-Z](?:[^>\"\']|\'[^\']*\'|\"[^\"]*\")*>' - + '|<', // A '<' that does not begin a larger chunk - 'g'); - var pr_commentPrefix = /^<\!--/; - var pr_cdataPrefix = /^) into their textual equivalent. - * - * @param {string} s html where whitespace is considered significant. - * @return {Object} source code and extracted tags. - * @private - */ - function extractTags(s) { - // since the pattern has the 'g' modifier and defines no capturing groups, - // this will return a list of all chunks which we then classify and wrap as - // PR_Tokens - var matches = s.match(pr_chunkPattern); - var sourceBuf = []; - var sourceBufLen = 0; - var extractedTags = []; - if (matches) { - for (var i = 0, n = matches.length; i < n; ++i) { - var match = matches[i]; - if (match.length > 1 && match.charAt(0) === '<') { - if (pr_commentPrefix.test(match)) { continue; } - if (pr_cdataPrefix.test(match)) { - // strip CDATA prefix and suffix. Don't unescape since it's CDATA - sourceBuf.push(match.substring(9, match.length - 3)); - sourceBufLen += match.length - 12; - } else if (pr_brPrefix.test(match)) { - //
tags are lexically significant so convert them to text. - // This is undone later. - sourceBuf.push('\n'); - ++sourceBufLen; - } else { - if (match.indexOf(PR_NOCODE) >= 0 && isNoCodeTag(match)) { - // A will start a section that should be - // ignored. Continue walking the list until we see a matching end - // tag. - var name = match.match(pr_tagNameRe)[2]; - var depth = 1; - var j; - end_tag_loop: - for (j = i + 1; j < n; ++j) { - var name2 = matches[j].match(pr_tagNameRe); - if (name2 && name2[2] === name) { - if (name2[1] === '/') { - if (--depth === 0) { break end_tag_loop; } - } else { - ++depth; - } - } - } - if (j < n) { - extractedTags.push( - sourceBufLen, matches.slice(i, j + 1).join('')); - i = j; - } else { // Ignore unclosed sections. - extractedTags.push(sourceBufLen, match); - } - } else { - extractedTags.push(sourceBufLen, match); - } - } - } else { - var literalText = htmlToText(match); - sourceBuf.push(literalText); - sourceBufLen += literalText.length; - } - } - } - return { source: sourceBuf.join(''), tags: extractedTags }; - } - - /** True if the given tag contains a class attribute with the nocode class. */ - function isNoCodeTag(tag) { - return !!tag - // First canonicalize the representation of attributes - .replace(/\s(\w+)\s*=\s*(?:\"([^\"]*)\"|'([^\']*)'|(\S+))/g, - ' $1="$2$3$4"') - // Then look for the attribute we want. - .match(/[cC][lL][aA][sS][sS]=\"[^\"]*\bnocode\b/); - } /** * Apply the given language handler to sourceCode and add the resulting @@ -744,13 +557,39 @@ window['_pr_isIE6'] = function () { function appendDecorations(basePos, sourceCode, langHandler, out) { if (!sourceCode) { return; } var job = { - source: sourceCode, + sourceCode: sourceCode, basePos: basePos }; langHandler(job); out.push.apply(out, job.decorations); } + var notWs = /\S/; + + /** + * Given an element, if it contains only one child element and any text nodes + * it contains contain only space characters, return the sole child element. + * Otherwise returns undefined. + *

+ * This is meant to return the CODE element in {@code

} when
+   * there is a single child element that contains all the non-space textual
+   * content, but not to return anything where there are multiple child elements
+   * as in {@code 
......
} or when there + * is textual content. + */ + function childContentWrapper(element) { + var wrapper = undefined; + for (var c = element.firstChild; c; c = c.nextSibling) { + var type = c.nodeType; + wrapper = (type === 1) // Element Node + ? (wrapper ? element : c) + : (type === 3) // Text Node + ? (notWs.test(c.nodeValue) ? element : wrapper) + : wrapper; + } + return wrapper === element ? undefined : wrapper; + } + /** Given triples of [style, pattern, context] returns a lexing function, * The lexing function interprets the patterns to find token boundaries and * returns a decoration list of the form @@ -824,21 +663,20 @@ window['_pr_isIE6'] = function () { })(); var nPatterns = fallthroughStylePatterns.length; - var notWs = /\S/; /** - * Lexes job.source and produces an output array job.decorations of style - * classes preceded by the position at which they start in job.source in - * order. + * Lexes job.sourceCode and produces an output array job.decorations of + * style classes preceded by the position at which they start in + * job.sourceCode in order. * - * @param {Object} job an object like {@code - * source: {string} sourceText plain text, - * basePos: {int} position of job.source in the larger chunk of + * @param {Object} job an object like
{
+     *    sourceCode: {string} sourceText plain text,
+     *    basePos: {int} position of job.sourceCode in the larger chunk of
      *        sourceCode.
-     * }
+     * }
*/ var decorate = function (job) { - var sourceCode = job.source, basePos = job.basePos; + var sourceCode = job.sourceCode, basePos = job.basePos; /** 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. @@ -965,12 +803,18 @@ window['_pr_isIE6'] = function () { fallthroughStylePatterns.push( [PR_STRING, /^@\"(?:[^\"]|\"\")*(?:\"|$)/, null]); } - if (options['hashComments']) { + var hc = options['hashComments']; + if (hc) { if (options['cStyleComments']) { - // Stop C preprocessor declarations at an unclosed open comment - shortcutStylePatterns.push( - [PR_COMMENT, /^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/, - null, '#']); + if (hc > 1) { // multiline hash comments + shortcutStylePatterns.push( + [PR_COMMENT, /^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/, null, '#']); + } else { + // Stop C preprocessor declarations at an unclosed open comment + shortcutStylePatterns.push( + [PR_COMMENT, /^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/, + null, '#']); + } fallthroughStylePatterns.push( [PR_STRING, /^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/, @@ -985,6 +829,9 @@ window['_pr_isIE6'] = function () { [PR_COMMENT, /^\/\*[\s\S]*?(?:\*\/|$)/, null]); } if (options['regexLiterals']) { + /** + * @const + */ var REGEX_LITERAL = ( // A regular expression literal starts with a slash that is // not followed by * or / so that it is not confused with @@ -1004,18 +851,24 @@ window['_pr_isIE6'] = function () { ]); } - var keywords = options['keywords'].replace(/^\s+|\s+$/g, ''); + var types = options['types']; + if (types) { + fallthroughStylePatterns.push([PR_TYPE, types]); + } + + var keywords = ("" + options['keywords']).replace(/^ | $/g, ''); if (keywords.length) { fallthroughStylePatterns.push( [PR_KEYWORD, - new RegExp('^(?:' + keywords.replace(/\s+/g, '|') + ')\\b'), null]); + new RegExp('^(?:' + keywords.replace(/[\s,]+/g, '|') + ')\\b'), + null]); } shortcutStylePatterns.push([PR_PLAIN, /^\s+/, null, ' \r\n\t\xA0']); fallthroughStylePatterns.push( // TODO(mikesamuel): recognize non-latin letters and numerals in idents [PR_LITERAL, /^@[a-z_$][a-z_$@0-9]*/i, null], - [PR_TYPE, /^@?[A-Z]+[a-z][A-Za-z_$@0-9]*/, null], + [PR_TYPE, /^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/, null], [PR_PLAIN, /^[a-z_$][a-z_$@0-9]*/i, null], [PR_LITERAL, new RegExp( @@ -1030,7 +883,9 @@ window['_pr_isIE6'] = function () { // with an optional modifier like UL for unsigned long + '[a-z]*', 'i'), null, '0123456789'], - [PR_PUNCTUATION, /^.[^\s\w\.$@\'\"\`\/\#]*/, null]); + // Don't treat escaped quotes in bash as starting strings. See issue 144. + [PR_PLAIN, /^\\[\s\S]?/, null], + [PR_PUNCTUATION, /^.[^\s\w\.$@\'\"\`\/\#\\]*/, null]); return createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns); } @@ -1043,117 +898,264 @@ window['_pr_isIE6'] = function () { 'regexLiterals': true }); - /** Breaks {@code job.source} around style boundaries in - * {@code job.decorations} while re-interleaving {@code job.extractedTags}, - * and leaves the result in {@code job.prettyPrintedHtml}. - * @param {Object} job like { - * source: {string} source as plain text, - * extractedTags: {Array.} extractedTags chunks of raw - * html preceded by their position in {@code job.source} - * in order - * decorations: {Array. outputIdx) { - if (openDecoration && openDecoration !== currentDecoration) { - // Close the current decoration - html.push(''); - openDecoration = null; - } - if (!openDecoration && currentDecoration) { - openDecoration = currentDecoration; - html.push(''); - } - // This interacts badly with some wikis which introduces paragraph tags - // into pre blocks for some strange reason. - // It's necessary for IE though which seems to lose the preformattedness - // of
 tags when their innerHTML is assigned.
-        // http://stud3.tuwien.ac.at/~e0226430/innerHtmlQuirk.html
-        // and it serves to undo the conversion of 
s to newlines done in - // chunkify. - var htmlChunk = textToHtml( - tabExpander(sourceText.substring(outputIdx, sourceIdx))) - .replace(lastWasSpace - ? startOrSpaceRe - : adjacentSpaceRe, '$1 '); - // Keep track of whether we need to escape space at the beginning of the - // next chunk. - lastWasSpace = trailingSpaceRe.test(htmlChunk); - // IE collapses multiple adjacient
s into 1 line break. - // Prefix every
with ' ' can prevent such IE's behavior. - var lineBreakHtml = window['_pr_isIE6']() ? ' 
' : '
'; - html.push(htmlChunk.replace(newlineRe, lineBreakHtml)); - outputIdx = sourceIdx; + /** + * Given a DOM subtree, wraps it in a list, and puts each line into its own + * list item. + * + * @param {Node} node modified in place. Its content is pulled into an + * 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. + */ + function numberLines(node, opt_startLineNum) { + var nocode = /(?:^|\s)nocode(?:\s|$)/; + var lineBreak = /\r\n?|\n/; + + var document = node.ownerDocument; + + var whitespace; + if (node.currentStyle) { + whitespace = node.currentStyle.whiteSpace; + } else if (window.getComputedStyle) { + whitespace = document.defaultView.getComputedStyle(node, null) + .getPropertyValue('white-space'); + } + // If it's preformatted, then we need to split lines on line breaks + // in addition to
s. + var isPreformatted = whitespace && 'pre' === whitespace.substring(0, 3); + + var li = document.createElement('LI'); + while (node.firstChild) { + li.appendChild(node.firstChild); + } + // An array of lines. We split below, so this is initialized to one + // un-split line. + var listItems = [li]; + + function walk(node) { + switch (node.nodeType) { + case 1: // Element + if (nocode.test(node.className)) { break; } + if ('BR' === node.nodeName) { + breakAfter(node); + // Discard the
since it is now flush against a . + if (node.parentNode) { + node.parentNode.removeChild(node); + } + } else { + for (var child = node.firstChild; child; child = child.nextSibling) { + walk(child); + } + } + break; + case 3: case 4: // Text + if (isPreformatted) { + var text = node.nodeValue; + var match = text.match(lineBreak); + if (match) { + var firstLine = text.substring(0, match.index); + node.nodeValue = firstLine; + var tail = text.substring(match.index + match[0].length); + if (tail) { + var parent = node.parentNode; + parent.insertBefore( + document.createTextNode(tail), node.nextSibling); + } + breakAfter(node); + if (!firstLine) { + // Don't leave blank text nodes in the DOM. + node.parentNode.removeChild(node); + } + } + } + break; } } - - while (true) { - // Determine if we're going to consume a tag this time around. Otherwise - // we consume a decoration or exit. - var outputTag; - if (tagPos < extractedTags.length) { - if (decPos < decorations.length) { - // Pick one giving preference to extractedTags since we shouldn't open - // a new style that we're going to have to immediately close in order - // to output a tag. - outputTag = extractedTags[tagPos] <= decorations[decPos]; - } else { - outputTag = true; - } - } else { - outputTag = false; + + // Split a line after the given node. + function breakAfter(lineEndNode) { + // If there's nothing to the right, then we can skip ending the line + // here, and move root-wards since splitting just before an end-tag + // would require us to create a bunch of empty copies. + while (!lineEndNode.nextSibling) { + lineEndNode = lineEndNode.parentNode; + if (!lineEndNode) { return; } } - // Consume either a decoration or a tag or exit. - if (outputTag) { - emitTextUpTo(extractedTags[tagPos]); - if (openDecoration) { - // Close the current decoration - html.push(''); - openDecoration = null; + + function breakLeftOf(limit, copy) { + // Clone shallowly if this node needs to be on both sides of the break. + var rightSide = copy ? limit.cloneNode(false) : limit; + var parent = limit.parentNode; + if (parent) { + // We clone the parent chain. + // This helps us resurrect important styling elements that cross lines. + // E.g. in Foo
Bar
+ // should be rewritten to
  • Foo
  • Bar
  • . + var parentClone = breakLeftOf(parent, 1); + // Move the clone and everything to the right of the original + // onto the cloned parent. + var next = limit.nextSibling; + parentClone.appendChild(rightSide); + for (var sibling = next; sibling; sibling = next) { + next = sibling.nextSibling; + parentClone.appendChild(sibling); + } } - html.push(extractedTags[tagPos + 1]); - tagPos += 2; - } else if (decPos < decorations.length) { - emitTextUpTo(decorations[decPos]); - currentDecoration = decorations[decPos + 1]; - decPos += 2; - } else { - break; + return rightSide; } + + var copiedListItem = breakLeftOf(lineEndNode.nextSibling, 0); + + // Walk the parent chain until we reach an unattached LI. + for (var parent; + // Check nodeType since IE invents document fragments. + (parent = copiedListItem.parentNode) && parent.nodeType === 1;) { + copiedListItem = parent; + } + // Put it on the list of lines for later processing. + listItems.push(copiedListItem); } - emitTextUpTo(sourceText.length); - if (openDecoration) { - html.push(''); + + // Split lines while there are lines left to split. + for (var i = 0; // Number of lines that have been split so far. + i < listItems.length; // length updated by breakAfter calls. + ++i) { + walk(listItems[i]); } - job.prettyPrintedHtml = html.join(''); + + // Make sure numeric indices show correctly. + if (opt_startLineNum === (opt_startLineNum|0)) { + listItems[0].setAttribute('value', opt_startLineNum); + } + + var ol = document.createElement('OL'); + ol.className = 'linenums'; + var offset = Math.max(0, ((opt_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 + // color odd/even rows, or any other row pattern that + // is co-prime with 10. + li.className = 'L' + ((i + offset) % 10); + if (!li.firstChild) { + li.appendChild(document.createTextNode('\xA0')); + } + ol.appendChild(li); + } + + node.appendChild(ol); } + /** + * 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. + * @private + */ + function recombineTagsAndDecorations(job) { + var isIE = /\bMSIE\b/.test(navigator.userAgent); + var newlineRe = /\n/g; + + var source = job.sourceCode; + var sourceLength = source.length; + // Index into source after the last code-unit recombined. + var sourceIndex = 0; + + var spans = job.spans; + var nSpans = spans.length; + // Index into spans after the last span which ends at or before sourceIndex. + var spanIndex = 0; + + var decorations = job.decorations; + var nDecorations = decorations.length; + // Index into decorations after the last decoration which ends at or before + // sourceIndex. + var decorationIndex = 0; + + // Remove all zero-length decorations. + decorations[nDecorations] = sourceLength; + var decPos, i; + for (i = decPos = 0; i < nDecorations;) { + if (decorations[i] !== decorations[i + 2]) { + decorations[decPos++] = decorations[i++]; + decorations[decPos++] = decorations[i++]; + } else { + i += 2; + } + } + nDecorations = decPos; + + // Simplify decorations. + for (i = decPos = 0; i < nDecorations;) { + var startPos = decorations[i]; + // Conflate all adjacent decorations that use the same style. + var startDec = decorations[i + 1]; + var end = i + 2; + while (end + 2 <= nDecorations && decorations[end + 1] === startDec) { + end += 2; + } + decorations[decPos++] = startPos; + decorations[decPos++] = startDec; + i = end; + } + + nDecorations = decorations.length = decPos; + + var decoration = null; + while (spanIndex < nSpans) { + var spanStart = spans[spanIndex]; + var spanEnd = spans[spanIndex + 2] || sourceLength; + + var decStart = decorations[decorationIndex]; + var decEnd = decorations[decorationIndex + 2] || sourceLength; + + var end = Math.min(spanEnd, decEnd); + + var textNode = spans[spanIndex + 1]; + var styledText; + if (textNode.nodeType !== 1 // Don't muck with
    s or
  • s + // Don't introduce spans around empty text nodes. + && (styledText = source.substring(sourceIndex, end))) { + // This may seem bizarre, and it is. Emitting LF on IE causes the + // code to display with spaces instead of line breaks. + // Emitting Windows standard issue linebreaks (CRLF) causes a blank + // space to appear at the beginning of every line but the first. + // Emitting an old Mac OS 9 line separator makes everything spiffy. + if (isIE) { styledText = styledText.replace(newlineRe, '\r'); } + textNode.nodeValue = styledText; + var document = textNode.ownerDocument; + var span = document.createElement('SPAN'); + span.className = decorations[decorationIndex + 1]; + var parentNode = textNode.parentNode; + parentNode.replaceChild(span, textNode); + span.appendChild(textNode); + if (sourceIndex < spanEnd) { // Split off a text node. + spans[spanIndex + 1] = textNode + // TODO: Possibly optimize by using '' if there's no flicker. + = document.createTextNode(source.substring(end, spanEnd)); + parentNode.insertBefore(textNode, span.nextSibling); + } + } + + sourceIndex = end; + + if (sourceIndex >= spanEnd) { + spanIndex += 2; + } + if (sourceIndex >= decEnd) { + decorationIndex += 2; + } + } + } + + /** Maps language-specific file extensions to handlers. */ var langHandlerRegistry = {}; /** Register a language handler for the given file extensions. @@ -1161,10 +1163,10 @@ window['_pr_isIE6'] = function () { * of decorations. Takes a single argument job which describes the * state of the computation. The single parameter has the form * {@code { - * source: {string} as plain text. + * sourceCode: {string} as plain text. * decorations: {Array.} an array of style classes * preceded by the position at which they start in - * job.source in order. + * 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 @@ -1177,8 +1179,8 @@ window['_pr_isIE6'] = function () { var ext = fileExtensions[i]; if (!langHandlerRegistry.hasOwnProperty(ext)) { langHandlerRegistry[ext] = handler; - } else if ('console' in window) { - console.warn('cannot override language handler %s', ext); + } else if (window['console']) { + console['warn']('cannot override language handler %s', ext); } } } @@ -1236,16 +1238,18 @@ window['_pr_isIE6'] = function () { registerLangHandler(sourceDecorator({ 'keywords': CPP_KEYWORDS, 'hashComments': true, - 'cStyleComments': true + 'cStyleComments': true, + 'types': C_TYPES }), ['c', 'cc', 'cpp', 'cxx', 'cyc', 'm']); registerLangHandler(sourceDecorator({ - 'keywords': 'null true false' + 'keywords': 'null,true,false' }), ['json']); registerLangHandler(sourceDecorator({ 'keywords': CSHARP_KEYWORDS, 'hashComments': true, 'cStyleComments': true, - 'verbatimStrings': true + 'verbatimStrings': true, + 'types': C_TYPES }), ['cs']); registerLangHandler(sourceDecorator({ 'keywords': JAVA_KEYWORDS, @@ -1279,62 +1283,71 @@ window['_pr_isIE6'] = function () { 'cStyleComments': true, 'regexLiterals': true }), ['js']); - registerLangHandler( - createSimpleLexer([], [[PR_STRING, /^[\s\S]+/]]), ['regex']); + registerLangHandler(sourceDecorator({ + 'keywords': COFFEE_KEYWORDS, + 'hashComments': 3, // ### style block comments + 'cStyleComments': true, + 'multilineStrings': true, + 'tripleQuotedStrings': true, + 'regexLiterals': true + }), ['coffee']); + registerLangHandler(createSimpleLexer([], [[PR_STRING, /^[\s\S]+/]]), ['regex']); function applyDecorator(job) { - var sourceCodeHtml = job.sourceCodeHtml; var opt_langExtension = job.langExtension; - // Prepopulate output in case processing fails with an exception. - job.prettyPrintedHtml = sourceCodeHtml; - try { // Extract tags, and convert the source code to plain text. - var sourceAndExtractedTags = extractTags(sourceCodeHtml); + var sourceAndSpans = extractSourceSpans(job.sourceNode); /** Plain text. @type {string} */ - var source = sourceAndExtractedTags.source; - job.source = source; + var source = sourceAndSpans.sourceCode; + job.sourceCode = source; + job.spans = sourceAndSpans.spans; job.basePos = 0; - /** Even entries are positions in source in ascending order. Odd entries - * are tags that were extracted at that position. - * @type {Array.} - */ - job.extractedTags = sourceAndExtractedTags.tags; - // Apply the appropriate language handler langHandlerForExtension(opt_langExtension, source)(job); - // Integrate the decorations and tags back into the source code to produce - // a decorated html string which is left in job.prettyPrintedHtml. + + // Integrate the decorations and tags back into the source code, + // modifying the sourceNode in place. recombineTagsAndDecorations(job); } catch (e) { if ('console' in window) { - console.log(e); - console.trace(); + console['log'](e && e['stack'] ? e['stack'] : e); } } } - function prettyPrintOne(sourceCodeHtml, opt_langExtension) { + /** + * @param sourceCodeHtml {string} The HTML to pretty print. + * @param opt_langExtension {string} The language name to use. + * Typically, a filename extension like 'cpp' or 'java'. + * @param opt_numberLines {number|boolean} True to number lines, + * or the 1-indexed number of the first line in sourceCodeHtml. + */ + function prettyPrintOne(sourceCodeHtml, opt_langExtension, opt_numberLines) { + var container = document.createElement('PRE'); + // This could cause images to load and onload listeners to fire. + // E.g. . + // We assume that the inner HTML is from a trusted source. + container.innerHTML = sourceCodeHtml; + if (opt_numberLines) { + numberLines(container, opt_numberLines); + } + var job = { - sourceCodeHtml: sourceCodeHtml, - langExtension: opt_langExtension + langExtension: opt_langExtension, + numberLines: opt_numberLines, + sourceNode: container }; applyDecorator(job); - return job.prettyPrintedHtml; + return container.innerHTML; } function prettyPrint(opt_whenDone) { - var isIE678 = window['_pr_isIE6'](); - var ieNewline = isIE678 === 6 ? '\r\n' : '\r'; - // See bug 71 and http://stackoverflow.com/questions/136443/why-doesnt-ie7- - + function byTagName(tn) { return document.getElementsByTagName(tn); } // fetch a list of nodes to rewrite - var codeSegments = [ - document.getElementsByTagName('pre'), - document.getElementsByTagName('code'), - document.getElementsByTagName('xmp') ]; + var codeSegments = [byTagName('pre'), byTagName('code'), byTagName('xmp')]; var elements = []; for (var i = 0; i < codeSegments.length; ++i) { for (var j = 0, n = codeSegments[i].length; j < n; ++j) { @@ -1345,7 +1358,7 @@ window['_pr_isIE6'] = function () { var clock = Date; if (!clock['now']) { - clock = { 'now': function () { return (new Date).getTime(); } }; + clock = { 'now': function () { return +(new Date); } }; } // The loop is broken into a series of continuations to make sure that we @@ -1353,20 +1366,36 @@ window['_pr_isIE6'] = function () { var k = 0; var prettyPrintingJob; + var langExtensionRe = /\blang(?:uage)?-([\w.]+)(?!\S)/; + var prettyPrintRe = /\bprettyprint\b/; + function doWork() { var endTime = (window['PR_SHOULD_USE_CONTINUATION'] ? - clock.now() + 250 /* ms */ : + clock['now']() + 250 /* ms */ : Infinity); - for (; k < elements.length && clock.now() < endTime; k++) { + for (; k < elements.length && clock['now']() < endTime; k++) { var cs = elements[k]; - if (cs.className && cs.className.indexOf('prettyprint') >= 0) { + var className = cs.className; + if (className.indexOf('prettyprint') >= 0) { // If the classes includes a language extensions, use it. // Language extensions can be specified like //
               // the language extension "cpp" is used to find a language handler as
    -          // passed to PR_registerLangHandler.
    -          var langExtension = cs.className.match(/\blang-(\w+)\b/);
    -          if (langExtension) { langExtension = langExtension[1]; }
    +          // passed to PR.registerLangHandler.
    +          // 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))
    +              && "CODE" === wrapper.tagName) {
    +            langExtension = wrapper.className.match(langExtensionRe);
    +          }
    +
    +          if (langExtension) {
    +            langExtension = langExtension[1];
    +          }
     
               // make sure this is not nested in an already prettified element
               var nested = false;
    @@ -1379,19 +1408,21 @@ window['_pr_isIE6'] = function () {
                 }
               }
               if (!nested) {
    -            // fetch the content as a snippet of properly escaped HTML.
    -            // Firefox adds newlines at the end.
    -            var content = getInnerHtml(cs);
    -            content = content.replace(/(?:\r\n?|\n)$/, '');
    +            // 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
    +                  : false;
    +            if (lineNums) { numberLines(cs, lineNums); }
     
                 // do the pretty printing
                 prettyPrintingJob = {
    -              sourceCodeHtml: content,
                   langExtension: langExtension,
    -              sourceNode: cs
    +              sourceNode: cs,
    +              numberLines: lineNums
                 };
                 applyDecorator(prettyPrintingJob);
    -            replaceWithPrettyPrintedHtml();
               }
             }
           }
    @@ -1403,61 +1434,29 @@ window['_pr_isIE6'] = function () {
           }
         }
     
    -    function replaceWithPrettyPrintedHtml() {
    -      var newContent = prettyPrintingJob.prettyPrintedHtml;
    -      if (!newContent) { return; }
    -      var cs = prettyPrintingJob.sourceNode;
    -
    -      // push the prettified html back into the tag.
    -      if (!isRawContent(cs)) {
    -        // just replace the old html with the new
    -        cs.innerHTML = newContent;
    -      } else {
    -        // we need to change the tag to a 
     since s do not allow
    -        // embedded tags such as the span tags used to attach styles to
    -        // sections of source code.
    -        var pre = document.createElement('PRE');
    -        for (var i = 0; i < cs.attributes.length; ++i) {
    -          var a = cs.attributes[i];
    -          if (a.specified) {
    -            var aname = a.name.toLowerCase();
    -            if (aname === 'class') {
    -              pre.className = a.value;  // For IE 6
    -            } else {
    -              pre.setAttribute(a.name, a.value);
    -            }
    -          }
    -        }
    -        pre.innerHTML = newContent;
    -
    -        // remove the old
    -        cs.parentNode.replaceChild(pre, cs);
    -        cs = pre;
    -      }
    -
    -      // Replace <br>s with line-feeds so that copying and pasting works
    -      // on IE 6.
    -      // Doing this on other browsers breaks lots of stuff since \r\n is
    -      // treated as two newlines on Firefox, and doing this also slows
    -      // down rendering.
    -      if (isIE678 && cs.tagName === 'PRE') {
    -        var lineBreaks = cs.getElementsByTagName('br');
    -        for (var j = lineBreaks.length; --j >= 0;) {
    -          var lineBreak = lineBreaks[j];
    -          lineBreak.parentNode.replaceChild(
    -              document.createTextNode(ieNewline), lineBreak);
    -        }
    -      }
    -    }
    -
         doWork();
       }
     
    -  window['PR_normalizedHtml'] = normalizedHtml;
    +   /**
    +    * Find all the {@code <pre>} and {@code <code>} tags in the DOM with
    +    * {@code class=prettyprint} and prettify them.
    +    *
    +    * @param {Function?} opt_whenDone if specified, called when the last entry
    +    *     has been finished.
    +    */
       window['prettyPrintOne'] = prettyPrintOne;
    +   /**
    +    * Pretty print a chunk of code.
    +    *
    +    * @param {string} sourceCodeHtml code as html
    +    * @return {string} code as html, but prettier
    +    */
       window['prettyPrint'] = prettyPrint;
    +   /**
    +    * Contains functions for creating and registering new language handlers.
    +    * @type {Object}
    +    */
       window['PR'] = {
    -        'combinePrefixPatterns': combinePrefixPatterns,
             'createSimpleLexer': createSimpleLexer,
             'registerLangHandler': registerLangHandler,
             'sourceDecorator': sourceDecorator,