Added support of soft wrap lines for line numbers plugin
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
diff --git a/plugins/line-numbers/index.html b/plugins/line-numbers/index.html
index f22653a..598ec93 100644
--- a/plugins/line-numbers/index.html
+++ b/plugins/line-numbers/index.html
@@ -29,6 +29,7 @@
<p>Obviously, this is supposed to work only for code blocks (<code><pre><code></code>) and not for inline code.</p>
<p>Add class <strong>line-numbers</strong> to your desired <code><pre></code> and line-numbers plugin will take care.</p>
<p>Optional: You can specify the <code>data-start</code> (Number) attribute on the <code><pre></code> element. It will shift the line counter.</p>
+ <p>Optional: To support multiline line numbers add <code>line-numbers-break-word</code> class.</p>
</section>
<section>
@@ -42,7 +43,7 @@
<h2>HTML</h2>
<p>Please note the <code>data-start="-5"</code> in the code below.</p>
- <pre class="line-numbers" data-src="plugins/line-numbers/index.html" data-start="-5"></pre>
+ <pre class="line-numbers line-numbers-break-word" data-src="plugins/line-numbers/index.html" data-start="-5"></pre>
</section>
<footer data-src="templates/footer.html" data-type="text/html"></footer>
diff --git a/plugins/line-numbers/prism-line-numbers.css b/plugins/line-numbers/prism-line-numbers.css
index 284cc0a..861d9af 100644
--- a/plugins/line-numbers/prism-line-numbers.css
+++ b/plugins/line-numbers/prism-line-numbers.css
@@ -4,6 +4,11 @@ pre.line-numbers {
counter-reset: linenumber;
}
+pre.line-numbers-break-word > code {
+ white-space: pre-wrap;
+ display: inline-block;
+}
+
pre.line-numbers > code {
position: relative;
}
diff --git a/plugins/line-numbers/prism-line-numbers.js b/plugins/line-numbers/prism-line-numbers.js
index 9443deb..5d7535f 100644
--- a/plugins/line-numbers/prism-line-numbers.js
+++ b/plugins/line-numbers/prism-line-numbers.js
@@ -1,38 +1,102 @@
-Prism.hooks.add('after-highlight', function (env) {
- // works only for <code> wrapped inside <pre> (not inline)
- var pre = env.element.parentNode;
- var clsReg = /\s*\bline-numbers\b\s*/;
- if (
- !pre || !/pre/i.test(pre.nodeName) ||
- // Abort only if nor the <pre> nor the <code> have the class
- (!clsReg.test(pre.className) && !clsReg.test(env.element.className))
- ) {
- return;
- }
-
- if (clsReg.test(env.element.className)) {
- // Remove the class "line-numbers" from the <code>
- env.element.className = env.element.className.replace(clsReg, '');
- }
- if (!clsReg.test(pre.className)) {
- // Add the class "line-numbers" to the <pre>
- pre.className += ' line-numbers';
- }
-
- var linesNum = (1 + env.code.split('\n').length);
- var lineNumbersWrapper;
-
- var lines = new Array(linesNum);
- lines = lines.join('<span></span>');
-
- lineNumbersWrapper = document.createElement('span');
- lineNumbersWrapper.className = 'line-numbers-rows';
- lineNumbersWrapper.innerHTML = lines;
-
- if (pre.hasAttribute('data-start')) {
- pre.style.counterReset = 'linenumber ' + (parseInt(pre.getAttribute('data-start'), 10) - 1);
- }
-
- env.element.appendChild(lineNumbersWrapper);
-
-});
\ No newline at end of file
+(function(){
+
+ /**
+ * Class name which is used to flag this code field has break-word css attr
+ *
+ * @type {String}
+ */
+ var BREAK_WORD_CLASS = 'line-numbers-break-word';
+
+ /**
+ * Returns style declaration for element
+ *
+ * @param {Node} el
+ * @return {Object}
+ */
+ var getStyle = function(el){
+ if (!el){
+ return {};
+ }
+ if (el.currentStyle){
+ return el.currentStyle;
+ }
+ else if (document.defaultView && document.defaultView.getComputedStyle){
+ return document.defaultView.getComputedStyle(el, '');
+ } else {
+ return el.style;
+ }
+ };
+
+ var _resizeElement = function(element){
+ var lineNumbersWrapper = element.querySelector('.line-numbers-rows');
+ var lineNumberSizer = element.querySelector('.line-numbers-sizer');
+ var codeLines = element.textContent.split('\n');
+ var lineHeight;
+
+ lineNumberSizer.style.display = 'block';
+
+ // parse line height in such way because of problems with zoom & line height css attr
+ lineNumberSizer.innerText = '\n';
+ lineHeight = lineNumberSizer.getBoundingClientRect().height;
+
+ codeLines.forEach(function(line, lineNumber){
+ lineNumberSizer.innerText = line;
+ var lineSize = lineNumberSizer.getBoundingClientRect().height || lineHeight;
+ lineNumbersWrapper.children[lineNumber].style.height = lineSize + 'px';
+ });
+
+ lineNumberSizer.innerText = '';
+ lineNumberSizer.style.display = 'none';
+ };
+
+ window.addEventListener('resize', function(){
+ Array.prototype.forEach.call(document.querySelectorAll('pre.' + BREAK_WORD_CLASS), _resizeElement);
+ });
+
+ Prism.hooks.add('after-highlight', function (env) {
+ // works only for <code> wrapped inside <pre> (not inline)
+ var pre = env.element.parentNode;
+ var clsReg = /\s*\bline-numbers\b\s*/;
+ if (
+ !pre || !/pre/i.test(pre.nodeName) ||
+ // Abort only if nor the <pre> nor the <code> have the class
+ (!clsReg.test(pre.className) && !clsReg.test(env.element.className))
+ ) {
+ return;
+ }
+
+ if (clsReg.test(env.element.className)) {
+ // Remove the class "line-numbers" from the <code>
+ env.element.className = env.element.className.replace(clsReg, '');
+ }
+ if (!clsReg.test(pre.className)) {
+ // Add the class "line-numbers" to the <pre>
+ pre.className += ' line-numbers';
+ }
+
+ var linesNum = (1 + env.code.split('\n').length);
+ var lineNumbersWrapper = document.createElement('span');
+ lineNumbersWrapper.className = 'line-numbers-rows';
+
+ var lines = new Array(linesNum);
+ lines = lines.join('<span></span>');
+
+ lineNumbersWrapper.innerHTML = lines;
+
+ if (pre.hasAttribute('data-start')) {
+ pre.style.counterReset = 'linenumber ' + (parseInt(pre.getAttribute('data-start'), 10) - 1);
+ }
+
+ env.element.appendChild(lineNumbersWrapper);
+
+ if (pre.classList.contains(BREAK_WORD_CLASS)){
+ var lineHeightSizer = document.createElement('span');
+ lineHeightSizer.className = 'line-numbers-sizer';
+
+ env.element.appendChild(lineHeightSizer);
+ _resizeElement(env.element);
+ }
+
+ });
+
+})();
\ No newline at end of file