plugins/line-highlight/prism-line-highlight.js
function highlightLines(pre, lines, classes) {
		lines = typeof lines === 'string' ? lines : pre.getAttribute('data-line');

		var ranges = lines.replace(/\s+/g, '').split(',');
		var offset = +pre.getAttribute('data-line-offset') || 0;

		var parseMethod = isLineHeightRounded() ? parseInt : parseFloat;
		var lineHeight = parseMethod(getComputedStyle(pre).lineHeight);
		var hasLineNumbers = hasClass(pre, 'line-numbers');
		var parentElement = hasLineNumbers ? pre : pre.querySelector('code') || pre;
		var mutateActions = /** @type {(() => void)[]} */ ([]);

		ranges.forEach(function (currentRange) {
			var range = currentRange.split('-');

			var start = +range[0];
			var end = +range[1] || start;

			var line = pre.querySelector('.line-highlight[data-range="' + currentRange + '"]') || document.createElement('div');

			mutateActions.push(function () {
				line.setAttribute('aria-hidden', 'true');
				line.setAttribute('data-range', currentRange);
				line.className = (classes || '') + ' line-highlight';
			});

			// if the line-numbers plugin is enabled, then there is no reason for this plugin to display the line numbers
			if (hasLineNumbers && Prism.plugins.lineNumbers) {
				var startNode = Prism.plugins.lineNumbers.getLine(pre, start);
				var endNode = Prism.plugins.lineNumbers.getLine(pre, end);

				if (startNode) {
					var top = startNode.offsetTop + 'px';
					mutateActions.push(function () {
						line.style.top = top;
					});
				}

				if (endNode) {
					var height = (endNode.offsetTop - startNode.offsetTop) + endNode.offsetHeight + 'px';
					mutateActions.push(function () {
						line.style.height = height;
					});
				}
			} else {
				mutateActions.push(function () {
					line.setAttribute('data-start', start);

					if (end > start) {
						line.setAttribute('data-end', end);
					}

					line.style.top = (start - offset - 1) * lineHeight + 'px';

					line.textContent = new Array(end - start + 2).join(' \n');
				});
			}

			mutateActions.push(function () {
				// allow this to play nicely with the line-numbers plugin
				// need to attack to pre as when line-numbers is enabled, the code tag is relatively which screws up the positioning
				parentElement.appendChild(line);
			});
		});

		return function () {
			mutateActions.forEach(callFunction);
		};
	}
function highlightLines(pre, lines, classes) {
		lines = typeof lines === 'string' ? lines : pre.getAttribute('data-line');

		var ranges = lines.replace(/\s+/g, '').split(',');
		var offset = +pre.getAttribute('data-line-offset') || 0;

		var parseMethod = isLineHeightRounded() ? parseInt : parseFloat;
		var lineHeight = parseMethod(getComputedStyle(pre).lineHeight);
		var hasLineNumbers = hasClass(pre, 'line-numbers');
		var parentElement = hasLineNumbers ? pre : pre.querySelector('code') || pre;
		var mutateActions = /** @type {(() => void)[]} */ ([]);

		ranges.forEach(function (currentRange) {
			var range = currentRange.split('-');

			var start = +range[0];
			var end = +range[1] || start;

			var line = pre.querySelector('.line-highlight[data-range="' + currentRange + '"]') || document.createElement('div');

			mutateActions.push(function () {
				line.setAttribute('aria-hidden', 'true');
				line.setAttribute('data-range', currentRange);
				line.className = (classes || '') + ' line-highlight';
			});

			// if the line-numbers plugin is enabled, then there is no reason for this plugin to display the line numbers
			if (hasLineNumbers && Prism.plugins.lineNumbers) {
				var startNode = Prism.plugins.lineNumbers.getLine(pre, start);
				var endNode = Prism.plugins.lineNumbers.getLine(pre, end);

				if (startNode) {
					var top = startNode.offsetTop + 'px';
					mutateActions.push(function () {
						line.style.top = top;
					});
				}

				if (endNode) {
					var height = (endNode.offsetTop - startNode.offsetTop) + endNode.offsetHeight + 'px';
					mutateActions.push(function () {
						line.style.height = height;
					});
				}
			} else {
				mutateActions.push(function () {
					line.setAttribute('data-start', start);

					if (end > start) {
						line.setAttribute('data-end', end);
					}

					line.style.top = (start - offset - 1) * lineHeight + 'px';

					line.textContent = new Array(end - start + 2).join(' \n');
				});
			}

			mutateActions.push(function () {
				// allow this to play nicely with the line-numbers plugin
				// need to attack to pre as when line-numbers is enabled, the code tag is relatively which screws up the positioning
				parentElement.appendChild(line);
			});
		});

		return function () {
			mutateActions.forEach(callFunction);
		};
	}
function highlightLines ( pre , lines , classes ) { lines = typeof lines === 'string' ? lines : pre . getAttribute ( 'data-line' ) ; var ranges = lines . replace ( / \s+ / g , '' ) . split ( ',' ) ; var offset = + pre . getAttribute ( 'data-line-offset' ) || 0 ; var parseMethod = isLineHeightRounded ( ) ? parseInt : parseFloat ; var lineHeight = parseMethod ( getComputedStyle ( pre ) . lineHeight ) ; var hasLineNumbers = hasClass ( pre , 'line-numbers' ) ; var parentElement = hasLineNumbers ? pre : pre . querySelector ( 'code' ) || pre ; var mutateActions = /** @type {(() => void)[]} */ ( [ ] ) ; ranges . forEach ( function ( currentRange ) { var range = currentRange . split ( '-' ) ; var start = + range [ 0 ] ; var end = + range [ 1 ] || start ; var line = pre . querySelector ( '.line-highlight[data-range="' + currentRange + '"]' ) || document . createElement ( 'div' ) ; mutateActions . push ( function ( ) { line . setAttribute ( 'aria-hidden' , 'true' ) ; line . setAttribute ( 'data-range' , currentRange ) ; line . className = ( classes || '' ) + ' line-highlight' ; } ) ; // if the line-numbers plugin is enabled, then there is no reason for this plugin to display the line numbers if ( hasLineNumbers && Prism . plugins . lineNumbers ) { var startNode = Prism . plugins . lineNumbers . getLine ( pre , start ) ; var endNode = Prism . plugins . lineNumbers . getLine ( pre , end ) ; if ( startNode ) { var top = startNode . offsetTop + 'px' ; mutateActions . push ( function ( ) { line . style . top = top ; } ) ; } if ( endNode ) { var height = ( endNode . offsetTop - startNode . offsetTop ) + endNode . offsetHeight + 'px' ; mutateActions . push ( function ( ) { line . style . height = height ; } ) ; } } else { mutateActions . push ( function ( ) { line . setAttribute ( 'data-start' , start ) ; if ( end > start ) { line . setAttribute ( 'data-end' , end ) ; } line . style . top = ( start - offset - 1 ) * lineHeight + 'px' ; line . textContent = new Array ( end - start + 2 ) . join ( ' \n' ) ; } ) ; } mutateActions . push ( function ( ) { // allow this to play nicely with the line-numbers plugin // need to attack to pre as when line-numbers is enabled, the code tag is relatively which screws up the positioning parentElement . appendChild ( line ) ; } ) ; } ) ; return function ( ) { mutateActions . forEach ( callFunction ) ; } ; }
Highlights the lines of the given pre.

This function is split into a DOM measuring and mutate phase to improve performance.
The returned function mutates the DOM when called.

@param {HTMLElement} pre
@param {string} [lines]
@param {string} [classes='']
@returns {() => void}
Highlights the lines of the given pre .