Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes to compatibility of line number and line higlight plugins #1194

Merged
merged 4 commits into from
Dec 5, 2017
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 23 additions & 6 deletions plugins/line-highlight/prism-line-highlight.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,37 +36,51 @@ var isLineHeightRounded = (function() {
}());

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

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

var parseMethod = isLineHeightRounded() ? parseInt : parseFloat;
var lineHeight = parseMethod(getComputedStyle(pre).lineHeight);
var hasLineNumbers = hasClass(pre, 'line-numbers');

for (var i=0, range; range = ranges[i++];) {
range = range.split('-');

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

var line = document.createElement('div');
var line = pre.querySelector('.line-highlight') || document.createElement('div');

line.textContent = Array(end - start + 2).join(' \n');
line.setAttribute('aria-hidden', 'true');
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(!hasClass(pre, '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) {
line.style.top = startNode.offsetTop + 'px';
}

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

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

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

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

//allow this to play nicely with the line-numbers plugin
if(hasClass(pre, 'line-numbers')) {
if(hasLineNumbers) {
//need to attack to pre as when line-numbers is enabled, the code tag is relatively which screws up the positioning
pre.appendChild(line);
} else {
Expand Down Expand Up @@ -148,5 +162,8 @@ Prism.hooks.add('complete', function(env) {
});

window.addEventListener('hashchange', applyHash);
window.addEventListener('resize', function () {
Array.prototype.forEach.call(document.querySelectorAll('pre[data-line]'), highlightLines);
});

})();
})();
42 changes: 36 additions & 6 deletions plugins/line-numbers/prism-line-numbers.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,16 @@
* @type {String}
*/
var PLUGIN_CLASS = 'line-numbers';

/**
* Regular expression used for determining line breaks
* @type {RegExp}
*/
var NEW_LINE_EXP = /\n(?!$)/g;

/**
* Resizes line numbers spans according to height of line of code
* @param {Element} element <pre> element
* @param {Element} element <pre> element
*/
var _resizeElement = function (element) {
var codeStyles = getStyles(element);
Expand All @@ -22,7 +28,7 @@
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');
var codeLines = codeElement.textContent.split(NEW_LINE_EXP);

if (!lineNumberSizer) {
lineNumberSizer = document.createElement('span');
Expand Down Expand Up @@ -76,21 +82,21 @@
return;
}

if (env.element.querySelector(".line-numbers-rows")) {
if (env.element.querySelector('.line-numbers-rows')) {
// Abort if line numbers already exists
return;
}

if (clsReg.test(env.element.className)) {
// Remove the class "line-numbers" from the <code>
// 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>
// Add the class 'line-numbers' to the <pre>
pre.className += ' line-numbers';
}

var match = env.code.match(/\n(?!$)/g);
var match = env.code.match(NEW_LINE_EXP);
var linesNum = match ? match.length + 1 : 1;
var lineNumbersWrapper;

Expand All @@ -110,5 +116,29 @@

_resizeElement(pre);
});

/**
* Global exports
*/
Prism.plugins.lineNumbers = {
/**
* Get node for provided line number
* @param {Element} element pre element
* @param {Number} number line number
* @return {Element|undefined}
*/
getLine: function (element, number) {
if (element.tagName !== 'PRE' || !element.classList.contains(PLUGIN_CLASS)) {
return;
}

var lineNumberStart = element.getAttribute('data-start') || 0;
var lineNumberRows = element.querySelector('.line-numbers-rows');

number = Math.abs(lineNumberStart) + number;

return lineNumberRows.children[number];
Copy link
Contributor

@Golmote Golmote Oct 10, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@VitaliyR I think there is something wrong here. children is zero-indexed, while number (a value from data-line) is one-indexed. I tested in local and the highlighted line is indeed shifted down by one when line-numbers is used.

}
};

}());