From 14be748977fad9d1d8c07a08763cfb5d6b182c8b Mon Sep 17 00:00:00 2001 From: Michael Schmidt Date: Sun, 10 Mar 2019 18:56:59 +0100 Subject: [PATCH] Line numbers: Added inheritance for the `line-numbers` class (#1799) This adds inheritance for the `line-numbers` class for the Line numbers plugin similar to the inheritance of `language-xxxx` classes. --- plugins/line-numbers/index.html | 7 ++-- plugins/line-numbers/prism-line-numbers.js | 41 +++++++++++-------- .../line-numbers/prism-line-numbers.min.js | 2 +- 3 files changed, 30 insertions(+), 20 deletions(-) diff --git a/plugins/line-numbers/index.html b/plugins/line-numbers/index.html index 43afcc20bd..ac00d3c2d4 100644 --- a/plugins/line-numbers/index.html +++ b/plugins/line-numbers/index.html @@ -27,19 +27,20 @@

Line Numbers

How to use

Obviously, this is supposed to work only for code blocks (<pre><code>) and not for inline code.

-

Add the line-numbers class to your desired <pre>, and the line-numbers plugin will take care of the rest.

+

Add the line-numbers class to your desired <pre> or any of its ancestors, and the line-numbers plugin will take care of the rest. To given all code blocks line numbers, add the line-numbers class to the <body> of the page.

Optional: You can specify the data-start (Number) attribute on the <pre> element. It will shift the line counter.

Optional: To support multiline line numbers using soft wrap, apply the CSS white-space: pre-line; or white-space: pre-wrap; to your desired <pre>.

-
+

Examples

JavaScript


 
   

CSS

-

+  

Please note that this <pre> does not have the line-numbers class but its parent does.

+

 
   

HTML

Please note the data-start="-5" in the code below.

diff --git a/plugins/line-numbers/prism-line-numbers.js b/plugins/line-numbers/prism-line-numbers.js index 820158db01..7ab1dc046b 100644 --- a/plugins/line-numbers/prism-line-numbers.js +++ b/plugins/line-numbers/prism-line-numbers.js @@ -71,28 +71,38 @@ return; } + var code = env.element; + var pre = code.parentNode; + // works only for wrapped inside
 (not inline)
-		var pre = env.element.parentNode;
-		var clsReg = /(?:^|\s)line-numbers(?:\s|$)/;
-		if (
-			!pre || !/pre/i.test(pre.nodeName) ||
-			// Abort only if nor the 
 nor the  have the class
-			(!clsReg.test(pre.className) && !clsReg.test(env.element.className))
-		) {
+		if (!pre || !/pre/i.test(pre.nodeName)) {
 			return;
 		}
 
-		if (env.element.querySelector('.line-numbers-rows')) {
-			// Abort if line numbers already exists
+		// Abort if line numbers already exists
+		if (code.querySelector('.line-numbers-rows')) {
 			return;
 		}
 
-		if (clsReg.test(env.element.className)) {
-			// Remove the class 'line-numbers' from the 
-			env.element.className = env.element.className.replace(clsReg, ' ');
+		var addLineNumbers = false;
+		var lineNumbersRegex = /(?:^|\s)line-numbers(?:\s|$)/;
+
+		for (var element = code; element; element = element.parentNode) {
+			if (lineNumbersRegex.test(element.className)) {
+				addLineNumbers = true;
+				break;
+			}
 		}
-		if (!clsReg.test(pre.className)) {
-			// Add the class 'line-numbers' to the 
+
+		// only add line numbers if  or one of its ancestors has the `line-numbers` class
+		if (!addLineNumbers) {
+			return;
+		}
+
+		// Remove the class 'line-numbers' from the 
+		code.className = code.className.replace(lineNumbersRegex, ' ');
+		// Add the class 'line-numbers' to the 
+		if (!lineNumbersRegex.test(pre.className)) {
 			pre.className += ' line-numbers';
 		}
 
@@ -100,8 +110,7 @@
 		var linesNum = match ? match.length + 1 : 1;
 		var lineNumbersWrapper;
 
-		var lines = new Array(linesNum + 1);
-		lines = lines.join('');
+		var lines = new Array(linesNum + 1).join('');
 
 		lineNumbersWrapper = document.createElement('span');
 		lineNumbersWrapper.setAttribute('aria-hidden', 'true');
diff --git a/plugins/line-numbers/prism-line-numbers.min.js b/plugins/line-numbers/prism-line-numbers.min.js
index b0064b6fdd..ca84bbe3e9 100644
--- a/plugins/line-numbers/prism-line-numbers.min.js
+++ b/plugins/line-numbers/prism-line-numbers.min.js
@@ -1 +1 @@
-!function(){if("undefined"!=typeof self&&self.Prism&&self.document){var i="line-numbers",a=/\n(?!$)/g,o=function(e){var t=u(e)["white-space"];if("pre-wrap"===t||"pre-line"===t){var n=e.querySelector("code"),r=e.querySelector(".line-numbers-rows"),s=e.querySelector(".line-numbers-sizer"),l=n.textContent.split(a);s||((s=document.createElement("span")).className="line-numbers-sizer",n.appendChild(s)),s.style.display="block",l.forEach(function(e,t){s.textContent=e||"\n";var n=s.getBoundingClientRect().height;r.children[t].style.height=n+"px"}),s.textContent="",s.style.display="none"}},u=function(e){return e?window.getComputedStyle?getComputedStyle(e):e.currentStyle||null:null};window.addEventListener("resize",function(){Array.prototype.forEach.call(document.querySelectorAll("pre."+i),o)}),Prism.hooks.add("complete",function(e){if(e.code){var t=e.element.parentNode,n=/(?:^|\s)line-numbers(?:\s|$)/;if(t&&/pre/i.test(t.nodeName)&&(n.test(t.className)||n.test(e.element.className))&&!e.element.querySelector(".line-numbers-rows")){n.test(e.element.className)&&(e.element.className=e.element.className.replace(n," ")),n.test(t.className)||(t.className+=" line-numbers");var r,s=e.code.match(a),l=s?s.length+1:1,i=new Array(l+1);i=i.join(""),(r=document.createElement("span")).setAttribute("aria-hidden","true"),r.className="line-numbers-rows",r.innerHTML=i,t.hasAttribute("data-start")&&(t.style.counterReset="linenumber "+(parseInt(t.getAttribute("data-start"),10)-1)),e.element.appendChild(r),o(t),Prism.hooks.run("line-numbers",e)}}}),Prism.hooks.add("line-numbers",function(e){e.plugins=e.plugins||{},e.plugins.lineNumbers=!0}),Prism.plugins.lineNumbers={getLine:function(e,t){if("PRE"===e.tagName&&e.classList.contains(i)){var n=e.querySelector(".line-numbers-rows"),r=parseInt(e.getAttribute("data-start"),10)||1,s=r+(n.children.length-1);t");(l=document.createElement("span")).setAttribute("aria-hidden","true"),l.className="line-numbers-rows",l.innerHTML=u,n.hasAttribute("data-start")&&(n.style.counterReset="linenumber "+(parseInt(n.getAttribute("data-start"),10)-1)),e.element.appendChild(l),m(n),Prism.hooks.run("line-numbers",e)}}}}),Prism.hooks.add("line-numbers",function(e){e.plugins=e.plugins||{},e.plugins.lineNumbers=!0}),Prism.plugins.lineNumbers={getLine:function(e,t){if("PRE"===e.tagName&&e.classList.contains(l)){var n=e.querySelector(".line-numbers-rows"),r=parseInt(e.getAttribute("data-start"),10)||1,s=r+(n.children.length-1);t