Skip to content

Commit 849f1d6

Browse files
committed
Merge branch 'gh-pages' of https://github.com/VitaliyR/prism into VitaliyR-gh-pages
# Conflicts: # plugins/line-numbers/index.html # plugins/line-numbers/prism-line-numbers.js
2 parents 2e32fc7 + 407fc67 commit 849f1d6

File tree

3 files changed

+106
-42
lines changed

3 files changed

+106
-42
lines changed

plugins/line-numbers/index.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ <h1>How to use</h1>
2929
<p>Obviously, this is supposed to work only for code blocks (<code>&lt;pre>&lt;code></code>) and not for inline code.</p>
3030
<p>Add class <strong>line-numbers</strong> to your desired <code>&lt;pre></code> and line-numbers plugin will take care.</p>
3131
<p>Optional: You can specify the <code>data-start</code> (Number) attribute on the <code>&lt;pre></code> element. It will shift the line counter.</p>
32+
<p>Optional: To support multiline line numbers using soft wrap add css <code>white-space</code> to <code>pre-line</code> or <code>pre-wrap</code>.</p>
3233
</section>
3334

3435
<section>
@@ -49,6 +50,10 @@ <h2>Unknown languages</h2>
4950
is not highlighted
5051
but it still has
5152
lines numbers</code></pre>
53+
54+
<h2>Soft wrap support</h2>
55+
<pre class="line-numbers" data-src="plugins/line-numbers/index.html" data-start="-5" style="white-space:pre-wrap;"></pre>
56+
5257
</section>
5358

5459
<footer data-src="templates/footer.html" data-type="text/html"></footer>

plugins/line-numbers/prism-line-numbers.css

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ pre.line-numbers {
66

77
pre.line-numbers > code {
88
position: relative;
9+
display: inline-block;
10+
white-space: inherit;
911
}
1012

1113
.line-numbers .line-numbers-rows {
Lines changed: 99 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,114 @@
1-
(function() {
1+
(function () {
22

3-
if (typeof self === 'undefined' || !self.Prism || !self.document) {
4-
return;
5-
}
6-
7-
Prism.hooks.add('complete', function (env) {
8-
if (!env.code) {
3+
if (typeof self === 'undefined' || !self.Prism || !self.document) {
94
return;
105
}
116

12-
// works only for <code> wrapped inside <pre> (not inline)
13-
var pre = env.element.parentNode;
14-
var clsReg = /\s*\bline-numbers\b\s*/;
15-
if (
16-
!pre || !/pre/i.test(pre.nodeName) ||
7+
/**
8+
* Class name for <pre> which is activating the plugin
9+
* @type {String}
10+
*/
11+
var PLUGIN_CLASS = 'line-numbers';
12+
13+
/**
14+
* Resizes line numbers spans according to height of line of code
15+
* @param {Element} element <pre> element
16+
*/
17+
var _resizeElement = function (element) {
18+
var codeStyles = getStyles(element);
19+
var whiteSpace = codeStyles['white-space'];
20+
21+
if (whiteSpace === 'pre-wrap' || whiteSpace === 'pre-line') {
22+
var codeElement = element.querySelector('code');
23+
var lineNumbersWrapper = element.querySelector('.line-numbers-rows');
24+
var lineNumberSizer = element.querySelector('.line-numbers-sizer');
25+
var codeLines = element.textContent.split('\n');
26+
27+
if (!lineNumberSizer) {
28+
lineNumberSizer = document.createElement('span');
29+
lineNumberSizer.className = 'line-numbers-sizer';
30+
31+
codeElement.appendChild(lineNumberSizer);
32+
}
33+
34+
lineNumberSizer.style.display = 'block';
35+
36+
codeLines.forEach(function (line, lineNumber) {
37+
lineNumberSizer.textContent = line || '\n';
38+
var lineSize = lineNumberSizer.getBoundingClientRect().height;
39+
lineNumbersWrapper.children[lineNumber].style.height = lineSize + 'px';
40+
});
41+
42+
lineNumberSizer.textContent = '';
43+
lineNumberSizer.style.display = 'none';
44+
}
45+
};
46+
47+
/**
48+
* Returns style declarations for the element
49+
* @param {Element} element
50+
*/
51+
var getStyles = function (element) {
52+
if (!element) {
53+
return null;
54+
}
55+
56+
return window.getComputedStyle ? getComputedStyle(element) : (element.currentStyle || null);
57+
};
58+
59+
window.addEventListener('resize', function () {
60+
Array.prototype.forEach.call(document.querySelectorAll('pre.' + PLUGIN_CLASS), _resizeElement);
61+
});
62+
63+
Prism.hooks.add('complete', function (env) {
64+
if (!env.code) {
65+
return;
66+
}
67+
68+
// works only for <code> wrapped inside <pre> (not inline)
69+
var pre = env.element.parentNode;
70+
var clsReg = /\s*\bline-numbers\b\s*/;
71+
if (
72+
!pre || !/pre/i.test(pre.nodeName) ||
1773
// Abort only if nor the <pre> nor the <code> have the class
18-
(!clsReg.test(pre.className) && !clsReg.test(env.element.className))
19-
) {
20-
return;
21-
}
74+
(!clsReg.test(pre.className) && !clsReg.test(env.element.className))
75+
) {
76+
return;
77+
}
2278

23-
if (env.element.querySelector(".line-numbers-rows")) {
24-
// Abort if line numbers already exists
25-
return;
26-
}
79+
if (env.element.querySelector(".line-numbers-rows")) {
80+
// Abort if line numbers already exists
81+
return;
82+
}
2783

28-
if (clsReg.test(env.element.className)) {
29-
// Remove the class "line-numbers" from the <code>
30-
env.element.className = env.element.className.replace(clsReg, '');
31-
}
32-
if (!clsReg.test(pre.className)) {
33-
// Add the class "line-numbers" to the <pre>
34-
pre.className += ' line-numbers';
35-
}
84+
if (clsReg.test(env.element.className)) {
85+
// Remove the class "line-numbers" from the <code>
86+
env.element.className = env.element.className.replace(clsReg, '');
87+
}
88+
if (!clsReg.test(pre.className)) {
89+
// Add the class "line-numbers" to the <pre>
90+
pre.className += ' line-numbers';
91+
}
3692

37-
var match = env.code.match(/\n(?!$)/g);
38-
var linesNum = match ? match.length + 1 : 1;
39-
var lineNumbersWrapper;
93+
var match = env.code.match(/\n(?!$)/g);
94+
var linesNum = match ? match.length + 1 : 1;
95+
var lineNumbersWrapper;
4096

41-
var lines = new Array(linesNum + 1);
42-
lines = lines.join('<span></span>');
97+
var lines = new Array(linesNum + 1);
98+
lines = lines.join('<span></span>');
4399

44-
lineNumbersWrapper = document.createElement('span');
45-
lineNumbersWrapper.setAttribute('aria-hidden', 'true');
46-
lineNumbersWrapper.className = 'line-numbers-rows';
47-
lineNumbersWrapper.innerHTML = lines;
100+
lineNumbersWrapper = document.createElement('span');
101+
lineNumbersWrapper.setAttribute('aria-hidden', 'true');
102+
lineNumbersWrapper.className = 'line-numbers-rows';
103+
lineNumbersWrapper.innerHTML = lines;
48104

49-
if (pre.hasAttribute('data-start')) {
50-
pre.style.counterReset = 'linenumber ' + (parseInt(pre.getAttribute('data-start'), 10) - 1);
51-
}
105+
if (pre.hasAttribute('data-start')) {
106+
pre.style.counterReset = 'linenumber ' + (parseInt(pre.getAttribute('data-start'), 10) - 1);
107+
}
52108

53-
env.element.appendChild(lineNumbersWrapper);
109+
env.element.appendChild(lineNumbersWrapper);
54110

55-
});
111+
_resizeElement(pre);
112+
});
56113

57114
}());

0 commit comments

Comments
 (0)