@@ -63,7 +63,7 @@ var PR_TAB_WIDTH = 8;
63
63
var PR_normalizedHtml ;
64
64
65
65
/** Contains functions for creating and registering new language handlers.
66
- * @namespace
66
+ * @type { Object }
67
67
*/
68
68
var PR ;
69
69
@@ -80,11 +80,11 @@ var prettyPrintOne;
80
80
*/
81
81
var prettyPrint ;
82
82
83
- /** browser detection. */
84
- function pr_isIE6 ( ) {
83
+ /** browser detection. @extern */
84
+ function _pr_isIE6 ( ) {
85
85
var isIE6 = navigator && navigator . userAgent &&
86
86
/ \b M S I E 6 \. / . test ( navigator . userAgent ) ;
87
- pr_isIE6 = function ( ) { return isIE6 ; } ;
87
+ _pr_isIE6 = function ( ) { return isIE6 ; } ;
88
88
return isIE6 ;
89
89
}
90
90
@@ -170,6 +170,12 @@ function pr_isIE6() {
170
170
/** token style for an sgml attribute value. */
171
171
var PR_ATTRIB_VALUE = 'atv' ;
172
172
173
+ /**
174
+ * A class that indicates a section of markup that is not code, e.g. to allow
175
+ * embedding of line numbers within code listings.
176
+ */
177
+ var PR_NOCODE = 'nocode' ;
178
+
173
179
function isWordChar ( ch ) {
174
180
return ( ch >= 'a' && ch <= 'z' ) || ( ch >= 'A' && ch <= 'Z' ) ;
175
181
}
@@ -366,7 +372,7 @@ function pr_isIE6() {
366
372
/** returns a function that expand tabs to spaces. This function can be fed
367
373
* successive chunks of text, and will maintain its own internal state to
368
374
* keep track of how tabs are expanded.
369
- * @return {function (plainText : string) : string } a function that takes
375
+ * @return {function (string) : string } a function that takes
370
376
* plain text and return the text with tabs expanded.
371
377
* @private
372
378
*/
@@ -422,6 +428,7 @@ function pr_isIE6() {
422
428
var pr_commentPrefix = / ^ < ! - - / ;
423
429
var pr_cdataPrefix = / ^ < \[ C D A T A \[ / ;
424
430
var pr_brPrefix = / ^ < b r \b / i;
431
+ var pr_tagNameRe = / ^ < ( \/ ? ) ( [ a - z A - Z ] + ) / ;
425
432
426
433
/** split markup into chunks of html tags (style null) and
427
434
* plain text (style {@link #PR_PLAIN}), converting tags which are
@@ -454,7 +461,33 @@ function pr_isIE6() {
454
461
sourceBuf . push ( '\n' ) ;
455
462
++ sourceBufLen ;
456
463
} else {
457
- extractedTags . push ( sourceBufLen , match ) ;
464
+ if ( match . indexOf ( PR_NOCODE ) >= 0 && isNoCodeTag ( match ) ) {
465
+ // A <span class="nocode"> will start a section that should be
466
+ // ignored. Continue walking the list until we see a matching end
467
+ // tag.
468
+ var name = match . match ( pr_tagNameRe ) [ 2 ] ;
469
+ var depth = 1 ;
470
+ end_tag_loop:
471
+ for ( var j = i + 1 ; j < n ; ++ j ) {
472
+ var name2 = matches [ j ] . match ( pr_tagNameRe ) ;
473
+ if ( name2 && name2 [ 2 ] === name ) {
474
+ if ( name2 [ 1 ] === '/' ) {
475
+ if ( -- depth === 0 ) { break end_tag_loop; }
476
+ } else {
477
+ ++ depth ;
478
+ }
479
+ }
480
+ }
481
+ if ( j < n ) {
482
+ extractedTags . push (
483
+ sourceBufLen , matches . slice ( i , j + 1 ) . join ( '' ) ) ;
484
+ i = j ;
485
+ } else { // Ignore unclosed sections.
486
+ extractedTags . push ( sourceBufLen , match ) ;
487
+ }
488
+ } else {
489
+ extractedTags . push ( sourceBufLen , match ) ;
490
+ }
458
491
}
459
492
} else {
460
493
var literalText = htmlToText ( match ) ;
@@ -466,6 +499,16 @@ function pr_isIE6() {
466
499
return { source : sourceBuf . join ( '' ) , tags : extractedTags } ;
467
500
}
468
501
502
+ /** True if the given tag contains a class attribute with the nocode class. */
503
+ function isNoCodeTag ( tag ) {
504
+ return ! ! tag
505
+ // First canonicalize the representation of attributes
506
+ . replace ( / \s ( \w + ) \s * = \s * (?: \" ( [ ^ \" ] * ) \" | ' ( [ ^ \' ] * ) ' | ( \S + ) ) / g,
507
+ ' $1="$2$3$4"' )
508
+ // Then look for the attribute we want.
509
+ . match ( / [ c C ] [ l L ] [ a A ] [ s S ] [ s S ] = \" [ ^ \" ] * \b n o c o d e \b / ) ;
510
+ }
511
+
469
512
/** Given triples of [style, pattern, context] returns a lexing function,
470
513
* The lexing function interprets the patterns to find token boundaries and
471
514
* returns a decoration list of the form
@@ -494,7 +537,7 @@ function pr_isIE6() {
494
537
* @param {Array } fallthroughStylePatterns patterns that will be tried in
495
538
* order if the shortcut ones fail. May have shortcuts.
496
539
*
497
- * @return {function (sourceCode : string) -> Array.<number|string> } a
540
+ * @return {function (string, number?) : Array.<number|string> } a
498
541
* function that takes source code and returns a list of decorations.
499
542
*/
500
543
function createSimpleLexer ( shortcutStylePatterns ,
@@ -648,7 +691,7 @@ function pr_isIE6() {
648
691
* It recognizes C, C++, and shell style comments.
649
692
*
650
693
* @param {Object } options a set of optional parameters.
651
- * @return {function (sourceCode : string) : Array.<string|number> } a
694
+ * @return {function (string) : Array.<string|number> } a
652
695
* decorator that takes sourceCode as plain text and that returns a
653
696
* decoration list
654
697
*/
@@ -921,6 +964,12 @@ function pr_isIE6() {
921
964
var decPos = 0 ; // index into decorations
922
965
var tabExpander = makeTabExpander ( PR_TAB_WIDTH ) ;
923
966
967
+ var adjacentSpaceRe = / ( [ \r \n ] ) / g;
968
+ var startOrSpaceRe = / ( ^ | ) / gm;
969
+ var newlineRe = / \r \n ? | \n / g;
970
+ var trailingSpaceRe = / [ \r \n ] $ / ;
971
+ var lastWasSpace = true ; // the last text chunk emitted ended with a space.
972
+
924
973
// A helper function that is responsible for opening sections of decoration
925
974
// and outputing properly escaped chunks of source
926
975
function emitTextUpTo ( sourceIdx ) {
@@ -936,17 +985,20 @@ function pr_isIE6() {
936
985
}
937
986
// This interacts badly with some wikis which introduces paragraph tags
938
987
// into pre blocks for some strange reason.
939
- // It's necessary for IE though which seems to lose the preformattednes
940
-
988
+ // It's necessary for IE though which seems to lose the preformattedness
941
989
// of <pre> tags when their innerHTML is assigned.
942
990
// http://stud3.tuwien.ac.at/~e0226430/innerHtmlQuirk.html
943
991
// and it serves to undo the conversion of <br>s to newlines done in
944
992
// chunkify.
945
993
var htmlChunk = textToHtml (
946
994
tabExpander ( sourceText . substring ( outputIdx , sourceIdx ) ) )
947
- . replace ( / ( \r \n ? | \n | ) / g, '$1 ' )
948
- . replace ( / \r \n ? | \n / g, '<br />' ) ;
949
- html . push ( htmlChunk ) ;
995
+ . replace ( lastWasSpace
996
+ ? startOrSpaceRe
997
+ : adjacentSpaceRe , '$1 ' ) ;
998
+ // Keep track of whether we need to escape space at the beginning of the
999
+ // next chunk.
1000
+ lastWasSpace = trailingSpaceRe . test ( htmlChunk ) ;
1001
+ html . push ( htmlChunk . replace ( newlineRe , '<br />' ) ) ;
950
1002
outputIdx = sourceIdx ;
951
1003
}
952
1004
}
@@ -996,7 +1048,7 @@ function pr_isIE6() {
996
1048
/** Maps language-specific file extensions to handlers. */
997
1049
var langHandlerRegistry = { } ;
998
1050
/** Register a language handler for the given file extensions.
999
- * @param {function (sourceCode : string) : Array.<number|string> } handler
1051
+ * @param {function (string) : Array.<number|string> } handler
1000
1052
* a function from source code to a list of decorations.
1001
1053
* @param {Array.<string> } fileExtensions
1002
1054
*/
@@ -1092,7 +1144,7 @@ function pr_isIE6() {
1092
1144
}
1093
1145
1094
1146
function prettyPrint ( opt_whenDone ) {
1095
- var isIE6 = pr_isIE6 ( ) ;
1147
+ var isIE6 = _pr_isIE6 ( ) ;
1096
1148
1097
1149
// fetch a list of nodes to rewrite
1098
1150
var codeSegments = [
@@ -1212,6 +1264,7 @@ function pr_isIE6() {
1212
1264
'PR_DECLARATION' : PR_DECLARATION ,
1213
1265
'PR_KEYWORD' : PR_KEYWORD ,
1214
1266
'PR_LITERAL' : PR_LITERAL ,
1267
+ 'PR_NOCODE' : PR_NOCODE ,
1215
1268
'PR_PLAIN' : PR_PLAIN ,
1216
1269
'PR_PUNCTUATION' : PR_PUNCTUATION ,
1217
1270
'PR_SOURCE' : PR_SOURCE ,
0 commit comments