diff --git a/plugins/line-numbers/index.html b/plugins/line-numbers/index.html index f22653a1d4..363c2fa699 100644 --- a/plugins/line-numbers/index.html +++ b/plugins/line-numbers/index.html @@ -29,6 +29,7 @@

How to use

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

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

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 add css white-space to pre-line or pre-wrap.

@@ -42,7 +43,7 @@

CSS

HTML

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

-

+  

 
diff --git a/plugins/line-numbers/prism-line-numbers.css b/plugins/line-numbers/prism-line-numbers.css index 284cc0ac7f..e32989bc3d 100644 --- a/plugins/line-numbers/prism-line-numbers.css +++ b/plugins/line-numbers/prism-line-numbers.css @@ -6,6 +6,8 @@ pre.line-numbers { pre.line-numbers > code { position: relative; + display: inline-block; + white-space: inherit; } .line-numbers .line-numbers-rows { diff --git a/plugins/line-numbers/prism-line-numbers.js b/plugins/line-numbers/prism-line-numbers.js index 9443deb7dc..2d0f4805a0 100644 --- a/plugins/line-numbers/prism-line-numbers.js +++ b/plugins/line-numbers/prism-line-numbers.js @@ -1,38 +1,98 @@ -Prism.hooks.add('after-highlight', function (env) { - // works only for wrapped inside
 (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 
 nor the  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 
-		env.element.className = env.element.className.replace(clsReg, '');
-	}
-	if (!clsReg.test(pre.className)) {
-		// Add the class "line-numbers" to the 
-		pre.className += ' line-numbers';
-	}
-
-	var linesNum = (1 + env.code.split('\n').length);
-	var lineNumbersWrapper;
-
-	var lines = new Array(linesNum);
-	lines = lines.join('');
-
-	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 for 
 which is activating the plugin
+	 * @type {String}
+	 */
+	var PLUGIN_CLASS = 'line-numbers';
+
+	/**
+	 * Resizes line numbers spans according to height of line of code
+	 * @param  {Element} element 
 element
+	 */
+	var _resizeElement = function(element){
+    var codeStyles = getStyles(element);
+    var whiteSpace = codeStyles['white-space'];
+
+    if (whiteSpace === 'pre-wrap' || whiteSpace === 'pre-line'){
+      var codeElement = element.querySelector('code');
+      var lineNumbersWrapper = element.querySelector('.line-numbers-rows');
+      var lineNumberSizer = element.querySelector('.line-numbers-sizer');
+      var codeLines = element.textContent.split('\n');
+
+      if (!lineNumberSizer){
+        lineNumberSizer = document.createElement('span');
+        lineNumberSizer.className = 'line-numbers-sizer';
+
+        codeElement.appendChild(lineNumberSizer);
+      }
+
+      lineNumberSizer.style.display = 'block';
+
+      codeLines.forEach(function(line, lineNumber){
+        lineNumberSizer.textContent = line || '\n';
+        var lineSize = lineNumberSizer.getBoundingClientRect().height;
+        lineNumbersWrapper.children[lineNumber].style.height = lineSize + 'px';
+      });
+
+      lineNumberSizer.textContent = '';
+      lineNumberSizer.style.display = 'none';
+    }
+	};
+
+  /**
+   * Returns style declarations for the element
+   * @param {Element} element
+   */
+  var getStyles = function(element){
+    if (!element){
+      return null;
+    }
+
+    return window.getComputedStyle ? getComputedStyle(element) : (element.currentStyle || null);
+  };
+
+	window.addEventListener('resize', function(){
+		Array.prototype.forEach.call(document.querySelectorAll('pre.' + PLUGIN_CLASS), _resizeElement);
+	});
+
+	Prism.hooks.add('after-highlight', function (env) {
+		// works only for  wrapped inside 
 (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 
 nor the  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 
+			env.element.className = env.element.className.replace(clsReg, '');
+		}
+		if (!clsReg.test(pre.className)) {
+			// Add the class "line-numbers" to the 
+			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('');
+
+		lineNumbersWrapper.innerHTML = lines;
+
+		if (pre.hasAttribute('data-start')) {
+			pre.style.counterReset = 'linenumber ' + (parseInt(pre.getAttribute('data-start'), 10) - 1);
+		}
+
+		env.element.appendChild(lineNumbersWrapper);
+
+    _resizeElement(pre);
+	});
+
+})();
\ No newline at end of file