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

Commit 2ba17e1

Browse files
added an optional mode triggered by class=linenums to arrange prettyprinted lines in list items in an ordered list.
1 parent 6b8dae0 commit 2ba17e1

File tree

5 files changed

+207
-121
lines changed

5 files changed

+207
-121
lines changed

README.html

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -130,19 +130,46 @@ <h3>Why doesn't Prettyprinting of strings work on WordPress?</h3>
130130
>WordPress's help center</a> for info on how to stop smart quoting of code
131131
snippets.</p>
132132

133-
<h3>How do I put line numbers in my code?</h3>
133+
<h3 id="linenums">How do I put line numbers in my code?</h3>
134+
<p>You can use the <code>linenums</code> class to turn on line
135+
numbering. If your code doesn't start at line number 1, you can
136+
add a colon and a line number to the end of that class as in
137+
<code>linenums:52</code>.
138+
139+
<p>For example
140+
<pre class="prettyprint">&lt;pre class="prettyprint linenums:<b>4</b>"
141+
&gt;// This is line 4.
142+
foo();
143+
bar();
144+
baz();
145+
boo();
146+
far();
147+
faz();
148+
&lt;pre&gt;</pre>
149+
produces
150+
<pre class="prettyprint linenums:4"
151+
>// This is line 4.
152+
foo();
153+
bar();
154+
baz();
155+
boo();
156+
far();
157+
faz();
158+
</pre>
159+
160+
<h3>How do I prevent a portion of markup from being marked as code?</h3>
134161
<p>You can use the <code>nocode</code> class to identify a span of markup
135162
that is not code.
136-
<pre>&lt;pre class=prettyprint&gt;
137-
&lt;span class="<b>nocode</b>"&gt;1:&lt;/span&gt; /* This is line 1 of my code
138-
&lt;span class="<b>nocode</b>"&gt;2:&lt;/span&gt; * and here's line 2 */
139-
&lt;span class="<b>nocode</b>"&gt;3:&lt;/span&gt; print("I'm line number 3");
163+
<pre class="prettyprint">&lt;pre class=prettyprint&gt;
164+
int x = foo(); /* This is a comment &lt;span class="nocode"&gt;This is not code&lt;/span&gt;
165+
Continuation of comment */
166+
int y = bar();
140167
&lt;/pre&gt;</pre>
141168
produces
142-
<pre class=prettyprint>
143-
<span class="nocode">1:</span> /* This is line 1 of my code
144-
<span class="nocode">2:</span> * and here's line 2 */
145-
<span class="nocode">3:</span> print("I'm line number 3");
169+
<pre class="prettyprint">
170+
int x = foo(); /* This is a comment <span class="nocode">This is not code</span>
171+
Continuation of comment */
172+
int y = bar();
146173
</pre>
147174

148175
<p>For a more complete example see the issue22

src/prettify.css

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,24 @@
1111
.atn { color: #606; }
1212
.atv { color: #080; }
1313
.dec { color: #606; }
14-
pre.prettyprint { padding: 2px; border: 1px solid #888; }
14+
pre.prettyprint { padding: 2px; border: 1px solid #888; display: list }
15+
16+
/* Specify class=linenums on a pre to get line numbering */
17+
ol.linenums { margin: 0 }
18+
li.L0,
19+
li.L1,
20+
li.L2,
21+
li.L3,
22+
li.L5,
23+
li.L6,
24+
li.L7,
25+
li.L8 { list-style-type: none }
26+
/* Alternate shading for lines */
27+
li.L1,
28+
li.L3,
29+
li.L5,
30+
li.L7,
31+
li.L9 { background: #eee }
1532

1633
@media print {
1734
.str { color: #060; }

src/prettify.js

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -306,28 +306,38 @@ window['_pr_isIE6'] = function () {
306306
return !whitespace || whitespace === 'pre';
307307
}
308308

309-
function normalizedHtml(node, out) {
309+
function normalizedHtml(node, out, opt_sortAttrs) {
310310
switch (node.nodeType) {
311311
case 1: // an element
312312
var name = node.tagName.toLowerCase();
313+
313314
out.push('<', name);
314-
for (var i = 0; i < node.attributes.length; ++i) {
315-
var attr = node.attributes[i];
316-
if (!attr.specified) { continue; }
317-
out.push(' ');
318-
normalizedHtml(attr, out);
315+
var attrs = node.attributes;
316+
var n = attrs.length;
317+
if (n) {
318+
if (opt_sortAttrs) {
319+
var sortedAttrs = [];
320+
for (var i = n; --i >= 0;) { sortedAttrs[i] = attrs[i]; }
321+
sortedAttrs.sort(function (a, b) {
322+
return (a.name < b.name) ? -1 : a.name === b.name ? 0 : 1;
323+
});
324+
attrs = sortedAttrs;
325+
}
326+
for (var i = 0; i < n; ++i) {
327+
var attr = attrs[i];
328+
if (!attr.specified) { continue; }
329+
out.push(' ', attr.name.toLowerCase(),
330+
'="', attribToHtml(attr.value), '"');
331+
}
319332
}
320333
out.push('>');
321334
for (var child = node.firstChild; child; child = child.nextSibling) {
322-
normalizedHtml(child, out);
335+
normalizedHtml(child, out, opt_sortAttrs);
323336
}
324337
if (node.firstChild || !/^(?:br|link|img)$/.test(name)) {
325338
out.push('<\/', name, '>');
326339
}
327340
break;
328-
case 2: // an attribute
329-
out.push(node.name.toLowerCase(), '="', attribToHtml(node.value), '"');
330-
break;
331341
case 3: case 4: // text
332342
out.push(textToHtml(node.nodeValue));
333343
break;
@@ -1087,11 +1097,37 @@ window['_pr_isIE6'] = function () {
10871097
// Doing this on other browsers breaks lots of stuff since \r\n is
10881098
// treated as two newlines on Firefox.
10891099
? (isIE678 === 6 ? '&nbsp;\r\n' : '&nbsp;\r')
1090-
// IE collapses multiple adjacient <br>s into 1 line break.
1100+
// IE collapses multiple adjacent <br>s into 1 line break.
10911101
// Prefix every newline with '&nbsp;' to prevent such behavior.
10921102
: '&nbsp;<br />')
10931103
: '<br />');
10941104

1105+
// Look for a class like linenums or linenums:<n> where <n> is the 1-indexed
1106+
// number of the first line.
1107+
var numberLines = job.sourceNode.className.match(/\blinenums\b(?::(\d+))?/);
1108+
var lineBreaker;
1109+
if (numberLines) {
1110+
var lineBreaks = [];
1111+
for (var i = 0; i < 10; ++i) {
1112+
lineBreaks[i] = lineBreakHtml + '</li><li class="L' + i + '">';
1113+
}
1114+
var lineNum = numberLines[1] - 1 || 0; // Lines are 1-indexed
1115+
html.push('<ol class="linenums"><li class="L', (lineNum) % 10, '"');
1116+
if (lineNum) {
1117+
html.push(' value="', lineNum + 1, '"');
1118+
}
1119+
html.push('>');
1120+
lineBreaker = function () {
1121+
var lb = lineBreaks[++lineNum % 10];
1122+
// If a decoration is open, we need to close it before closing a list-item
1123+
// and reopen it on the other side of the list item.
1124+
return openDecoration
1125+
? ('</span>' + lb + '<span class="' + openDecoration + '">') : lb;
1126+
};
1127+
} else {
1128+
lineBreaker = lineBreakHtml;
1129+
}
1130+
10951131
// A helper function that is responsible for opening sections of decoration
10961132
// and outputing properly escaped chunks of source
10971133
function emitTextUpTo(sourceIdx) {
@@ -1120,7 +1156,7 @@ window['_pr_isIE6'] = function () {
11201156
// Keep track of whether we need to escape space at the beginning of the
11211157
// next chunk.
11221158
lastWasSpace = trailingSpaceRe.test(htmlChunk);
1123-
html.push(htmlChunk.replace(newlineRe, lineBreakHtml));
1159+
html.push(htmlChunk.replace(newlineRe, lineBreaker));
11241160
outputIdx = sourceIdx;
11251161
}
11261162
}
@@ -1163,6 +1199,7 @@ window['_pr_isIE6'] = function () {
11631199
if (openDecoration) {
11641200
html.push('</span>');
11651201
}
1202+
if (numberLines) { html.push('</li></ol>'); }
11661203
job.prettyPrintedHtml = html.join('');
11671204
}
11681205

0 commit comments

Comments
 (0)