Skip to content
This repository was archived by the owner on Apr 22, 2020. It is now read-only.

Commit 7a8525d

Browse files
issue 224 : allow embedding language hints in processing instructions or comments prior to the prettified node
1 parent 743332e commit 7a8525d

File tree

5 files changed

+202
-33
lines changed

5 files changed

+202
-33
lines changed

examples/quine.html

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8" />
5+
<title>Making Quines Prettier</title>
6+
<!-- The defer is not necessary for autoloading, but is necessary for the
7+
script at the bottom to work as a Quine. -->
8+
<script src="https://google-code-prettify.googlecode.com/svn/loader/run_prettify.js?autoload=true&skin=sunburst&lang=css" defer="defer"></script>
9+
</head>
10+
11+
<body>
12+
<h1>Making Quines Prettier</h1>
13+
14+
<p>
15+
Below is the content of this page prettified. The <code>&lt;pre&gt;</code>
16+
element is prettified because it has <code>class="prettyprint"</code> and
17+
because the sourced script loads a JavaScript library that styles source
18+
code.
19+
</p>
20+
21+
<p>
22+
The line numbers to the left appear because the preceding comment
23+
<code>&lt;?prettyprint lang=html linenums=true?&gt;</code> turns on
24+
line-numbering and the
25+
<a href="http://google-code-prettify.googlecode.com/svn/trunk/styles/index.html">stylesheet</a>
26+
(see <code>skin=sunburst</code> in the <code>&lt;script src&gt;</code>)
27+
specifies that every fifth line should be numbered.
28+
</p>
29+
30+
<!-- Language hints can be put in XML application directive style comments. -->
31+
<?prettify lang=html linenums=true?>
32+
<pre class="prettyprint" id="quine" style="border:4px solid #88c"></pre>
33+
34+
<script>
35+
//<![CDATA[
36+
document.getElementById("quine").appendChild(document.createTextNode(
37+
'<!DOCTYPE html>\n<html>\n'
38+
+ document.documentElement.innerHTML
39+
+ '\n<\/html>\n'));
40+
//]]>
41+
</script></body>
42+
</html>

js-modules/prettify.js

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -850,6 +850,7 @@ var prettyPrint;
850850
var preformattedTagNameRe = /pre|xmp/i;
851851
var codeRe = /^code$/i;
852852
var preCodeXmpRe = /^(?:pre|code|xmp)$/i;
853+
var EMPTY = {};
853854

854855
function doWork() {
855856
var endTime = (win['PR_SHOULD_USE_CONTINUATION'] ?
@@ -879,6 +880,31 @@ var prettyPrint;
879880
// we shouldn't try again.
880881
cs.className += ' prettyprinted';
881882

883+
// Look for a preceding comment like
884+
// <?prettify lang="..." linenums="..."?>
885+
var attrs = EMPTY;
886+
{
887+
for (var preceder = cs; (preceder = preceder.previousSibling);) {
888+
var nt = preceder.nodeType;
889+
// <?foo?> is parsed by HTML 5 to a comment node (8)
890+
// like <!--?foo?-->, but in XML is a processing instruction
891+
var value = (nt === 7 || nt === 8) && preceder.nodeValue;
892+
if (value
893+
? !/^\??prettify\b/.test(value)
894+
: (nt !== 3 || /\S/.test(preceder.nodeValue))) {
895+
// Skip over white-space text nodes but not others.
896+
break;
897+
}
898+
if (value) {
899+
attrs = {};
900+
value.replace(
901+
/\b(\w+)=([\w:.%+-]+)/g,
902+
function (_, name, value) { attrs[name] = value; });
903+
break;
904+
}
905+
}
906+
}
907+
882908
// If the classes includes a language extensions, use it.
883909
// Language extensions can be specified like
884910
// <pre class="prettyprint lang-cpp">
@@ -887,15 +913,18 @@ var prettyPrint;
887913
// HTML5 recommends that a language be specified using "language-"
888914
// as the prefix instead. Google Code Prettify supports both.
889915
// http://dev.w3.org/html5/spec-author-view/the-code-element.html
890-
var langExtension = className.match(langExtensionRe);
891-
// Support <pre class="prettyprint"><code class="language-c">
892-
var wrapper;
893-
if (!langExtension && (wrapper = childContentWrapper(cs))
894-
&& codeRe.test(wrapper.tagName)) {
895-
langExtension = wrapper.className.match(langExtensionRe);
896-
}
916+
var langExtension = attrs['lang'];
917+
if (!langExtension) {
918+
langExtension = className.match(langExtensionRe);
919+
// Support <pre class="prettyprint"><code class="language-c">
920+
var wrapper;
921+
if (!langExtension && (wrapper = childContentWrapper(cs))
922+
&& codeRe.test(wrapper.tagName)) {
923+
langExtension = wrapper.className.match(langExtensionRe);
924+
}
897925

898-
if (langExtension) { langExtension = langExtension[1]; }
926+
if (langExtension) { langExtension = langExtension[1]; }
927+
}
899928

900929
var preformatted;
901930
if (preformattedTagNameRe.test(cs.tagName)) {
@@ -917,10 +946,15 @@ var prettyPrint;
917946

918947
// Look for a class like linenums or linenums:<n> where <n> is the
919948
// 1-indexed number of the first line.
920-
var lineNums = className.match(/\blinenums\b(?::(\d+))?/);
921-
lineNums = lineNums
922-
? lineNums[1] && lineNums[1].length ? +lineNums[1] : true
949+
var lineNums = attrs['linenums'];
950+
if (!(lineNums = lineNums === 'true' || +lineNums)) {
951+
lineNums = className.match(/\blinenums\b(?::(\d+))?/);
952+
lineNums =
953+
lineNums
954+
? lineNums[1] && lineNums[1].length
955+
? +lineNums[1] : true
923956
: false;
957+
}
924958
if (lineNums) { numberLines(cs, lineNums, preformatted); }
925959

926960
// do the pretty printing

src/prettify.js

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1458,6 +1458,7 @@ var prettyPrint;
14581458
var preformattedTagNameRe = /pre|xmp/i;
14591459
var codeRe = /^code$/i;
14601460
var preCodeXmpRe = /^(?:pre|code|xmp)$/i;
1461+
var EMPTY = {};
14611462

14621463
function doWork() {
14631464
var endTime = (win['PR_SHOULD_USE_CONTINUATION'] ?
@@ -1487,6 +1488,31 @@ var prettyPrint;
14871488
// we shouldn't try again.
14881489
cs.className += ' prettyprinted';
14891490

1491+
// Look for a preceding comment like
1492+
// <?prettify lang="..." linenums="..."?>
1493+
var attrs = EMPTY;
1494+
{
1495+
for (var preceder = cs; (preceder = preceder.previousSibling);) {
1496+
var nt = preceder.nodeType;
1497+
// <?foo?> is parsed by HTML 5 to a comment node (8)
1498+
// like <!--?foo?-->, but in XML is a processing instruction
1499+
var value = (nt === 7 || nt === 8) && preceder.nodeValue;
1500+
if (value
1501+
? !/^\??prettify\b/.test(value)
1502+
: (nt !== 3 || /\S/.test(preceder.nodeValue))) {
1503+
// Skip over white-space text nodes but not others.
1504+
break;
1505+
}
1506+
if (value) {
1507+
attrs = {};
1508+
value.replace(
1509+
/\b(\w+)=([\w:.%+-]+)/g,
1510+
function (_, name, value) { attrs[name] = value; });
1511+
break;
1512+
}
1513+
}
1514+
}
1515+
14901516
// If the classes includes a language extensions, use it.
14911517
// Language extensions can be specified like
14921518
// <pre class="prettyprint lang-cpp">
@@ -1495,15 +1521,18 @@ var prettyPrint;
14951521
// HTML5 recommends that a language be specified using "language-"
14961522
// as the prefix instead. Google Code Prettify supports both.
14971523
// http://dev.w3.org/html5/spec-author-view/the-code-element.html
1498-
var langExtension = className.match(langExtensionRe);
1499-
// Support <pre class="prettyprint"><code class="language-c">
1500-
var wrapper;
1501-
if (!langExtension && (wrapper = childContentWrapper(cs))
1502-
&& codeRe.test(wrapper.tagName)) {
1503-
langExtension = wrapper.className.match(langExtensionRe);
1504-
}
1524+
var langExtension = attrs['lang'];
1525+
if (!langExtension) {
1526+
langExtension = className.match(langExtensionRe);
1527+
// Support <pre class="prettyprint"><code class="language-c">
1528+
var wrapper;
1529+
if (!langExtension && (wrapper = childContentWrapper(cs))
1530+
&& codeRe.test(wrapper.tagName)) {
1531+
langExtension = wrapper.className.match(langExtensionRe);
1532+
}
15051533

1506-
if (langExtension) { langExtension = langExtension[1]; }
1534+
if (langExtension) { langExtension = langExtension[1]; }
1535+
}
15071536

15081537
var preformatted;
15091538
if (preformattedTagNameRe.test(cs.tagName)) {
@@ -1525,10 +1554,15 @@ var prettyPrint;
15251554

15261555
// Look for a class like linenums or linenums:<n> where <n> is the
15271556
// 1-indexed number of the first line.
1528-
var lineNums = className.match(/\blinenums\b(?::(\d+))?/);
1529-
lineNums = lineNums
1530-
? lineNums[1] && lineNums[1].length ? +lineNums[1] : true
1557+
var lineNums = attrs['linenums'];
1558+
if (!(lineNums = lineNums === 'true' || +lineNums)) {
1559+
lineNums = className.match(/\blinenums\b(?::(\d+))?/);
1560+
lineNums =
1561+
lineNums
1562+
? lineNums[1] && lineNums[1].length
1563+
? +lineNums[1] : true
15311564
: false;
1565+
}
15321566
if (lineNums) { numberLines(cs, lineNums, preformatted); }
15331567

15341568
// do the pretty printing

src/run_prettify.js

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1647,6 +1647,7 @@ var IN_GLOBAL_SCOPE = false;
16471647
var preformattedTagNameRe = /pre|xmp/i;
16481648
var codeRe = /^code$/i;
16491649
var preCodeXmpRe = /^(?:pre|code|xmp)$/i;
1650+
var EMPTY = {};
16501651

16511652
function doWork() {
16521653
var endTime = (win['PR_SHOULD_USE_CONTINUATION'] ?
@@ -1676,6 +1677,31 @@ var IN_GLOBAL_SCOPE = false;
16761677
// we shouldn't try again.
16771678
cs.className += ' prettyprinted';
16781679

1680+
// Look for a preceding comment like
1681+
// <?prettify lang="..." linenums="..."?>
1682+
var attrs = EMPTY;
1683+
{
1684+
for (var preceder = cs; (preceder = preceder.previousSibling);) {
1685+
var nt = preceder.nodeType;
1686+
// <?foo?> is parsed by HTML 5 to a comment node (8)
1687+
// like <!--?foo?-->, but in XML is a processing instruction
1688+
var value = (nt === 7 || nt === 8) && preceder.nodeValue;
1689+
if (value
1690+
? !/^\??prettify\b/.test(value)
1691+
: (nt !== 3 || /\S/.test(preceder.nodeValue))) {
1692+
// Skip over white-space text nodes but not others.
1693+
break;
1694+
}
1695+
if (value) {
1696+
attrs = {};
1697+
value.replace(
1698+
/\b(\w+)=([\w:.%+-]+)/g,
1699+
function (_, name, value) { attrs[name] = value; });
1700+
break;
1701+
}
1702+
}
1703+
}
1704+
16791705
// If the classes includes a language extensions, use it.
16801706
// Language extensions can be specified like
16811707
// <pre class="prettyprint lang-cpp">
@@ -1684,15 +1710,18 @@ var IN_GLOBAL_SCOPE = false;
16841710
// HTML5 recommends that a language be specified using "language-"
16851711
// as the prefix instead. Google Code Prettify supports both.
16861712
// http://dev.w3.org/html5/spec-author-view/the-code-element.html
1687-
var langExtension = className.match(langExtensionRe);
1688-
// Support <pre class="prettyprint"><code class="language-c">
1689-
var wrapper;
1690-
if (!langExtension && (wrapper = childContentWrapper(cs))
1691-
&& codeRe.test(wrapper.tagName)) {
1692-
langExtension = wrapper.className.match(langExtensionRe);
1693-
}
1713+
var langExtension = attrs['lang'];
1714+
if (!langExtension) {
1715+
langExtension = className.match(langExtensionRe);
1716+
// Support <pre class="prettyprint"><code class="language-c">
1717+
var wrapper;
1718+
if (!langExtension && (wrapper = childContentWrapper(cs))
1719+
&& codeRe.test(wrapper.tagName)) {
1720+
langExtension = wrapper.className.match(langExtensionRe);
1721+
}
16941722

1695-
if (langExtension) { langExtension = langExtension[1]; }
1723+
if (langExtension) { langExtension = langExtension[1]; }
1724+
}
16961725

16971726
var preformatted;
16981727
if (preformattedTagNameRe.test(cs.tagName)) {
@@ -1714,10 +1743,15 @@ var IN_GLOBAL_SCOPE = false;
17141743

17151744
// Look for a class like linenums or linenums:<n> where <n> is the
17161745
// 1-indexed number of the first line.
1717-
var lineNums = className.match(/\blinenums\b(?::(\d+))?/);
1718-
lineNums = lineNums
1719-
? lineNums[1] && lineNums[1].length ? +lineNums[1] : true
1746+
var lineNums = attrs['linenums'];
1747+
if (!(lineNums = lineNums === 'true' || +lineNums)) {
1748+
lineNums = className.match(/\blinenums\b(?::(\d+))?/);
1749+
lineNums =
1750+
lineNums
1751+
? lineNums[1] && lineNums[1].length
1752+
? +lineNums[1] : true
17201753
: false;
1754+
}
17211755
if (lineNums) { numberLines(cs, lineNums, preformatted); }
17221756

17231757
// do the pretty printing

tests/prettify_test_2.html

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,26 @@ <h1>HTML 5 nested code element language ignored if not only content</h1>
490490
<code class="language-lisp">; foo</code>
491491
</pre>
492492

493+
<p>The language is attached to an HTML5 comment that looks like an XML
494+
processing instruction.</p>
495+
<?prettify lang=lisp?>
496+
<pre class="prettyprint" id="procinstr1">; foo</pre>
497+
498+
<p>The language is attached to a regular HTML5 comment that looks like an XML
499+
processing instruction.</p>
500+
<!--prettify linenums=4 lang=lisp-->
501+
<pre class="prettyprint" id="procinstr2">; foo</pre>
502+
503+
<p>The language is attached to a regular HTML5 comment that looks like an XML
504+
processing instruction.</p>
505+
<!--prettify linenums=true lang=lisp-->
506+
<pre class="prettyprint" id="procinstr3">; foo</pre>
507+
508+
<p>The language is attached to a regular HTML5 comment that looks like an XML
509+
processing instruction.</p>
510+
<!--prettify linenums=false lang=lisp-->
511+
<pre class="prettyprint" id="procinstr4">; foo</pre>
512+
493513
<h1>Issues 185 and 261: Don't reprettify prettified content</h1>
494514
<code class="prettyprint prettyprinted" id="issue185"
495515
><span class="str">"No tag backs."</span></code>
@@ -1201,6 +1221,11 @@ <h1>LLVM</h1>
12011221
'`END</code>\n'),
12021222
html5conv4: ('`PLNbefore CODE\n' +
12031223
'`END<code class="language-lisp">`PUN;`END`PLN foo`END</code>\n'),
1224+
procinstr1: '`COM; foo`END',
1225+
procinstr2:
1226+
'<ol class="linenums"><li class="L3" value="4">`COM; foo`END</li></ol>',
1227+
procinstr3: '<ol class="linenums"><li class="L0">`COM; foo`END</li></ol>',
1228+
procinstr4: '`COM; foo`END',
12041229
issue185: '`STR"No tag backs."`END',
12051230
issue261: '<ol class="linenums"><li class="L0">`STR"No tag backs."`END</li></ol>',
12061231
issue201: '`KWDstatic`END`PLN `END`TYPPersistent`END' +

0 commit comments

Comments
 (0)