Skip to content
Merged
Show file tree
Hide file tree
Changes from 23 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
7 changes: 3 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"name": "bit-docs-prettify",
"version": "0.2.1",
"version": "0.2.2-7",
"description": "prettify code plugin",
"main": "prettify.js",
"scripts": {
"test": "mocha test.js --reporter spec",
"postversion": "git push --tags && git push",
"preversion": "npm test",
"release:pre": "npm version prerelease && npm publish",
"release:pre": "npm version prerelease && npm publish --tag=pre",
"release:patch": "npm version patch && npm publish",
"release:minor": "npm version minor && npm publish",
"release:major": "npm version major && npm publish"
Expand All @@ -29,8 +29,7 @@
"bit-docs-generate-html": "^0.1.0",
"connect": "^2.14.4",
"mocha": "^3.1.2",
"q": "^1.4.1",
"zombie": "^4.2.1"
"zombie": "^4.3.0"
},
"dependencies": {
"prismjs": "^1.11.0"
Expand Down
79 changes: 61 additions & 18 deletions prettify.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,80 @@
require("./prettify.less");

require("./prism-config");
var Prism = require("prismjs");
require("prismjs/plugins/line-numbers/prism-line-numbers.js");
Copy link
Member

Choose a reason for hiding this comment

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

generally w/ steal, you don't include the .js

Copy link
Author

Choose a reason for hiding this comment

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

fixed

require("prismjs/plugins/previewers/prism-previewers.js");
require("prismjs/plugins/command-line/prism-command-line.js");
require("prismjs/plugins/line-highlight/prism-line-highlight.js");
require("prismjs/plugins/toolbar/prism-toolbar.js");
require("prismjs/plugins/copy-to-clipboard/prism-copy-to-clipboard.js");
require("./prism-collapse.js");

require("prismjs/themes/prism-coy.css");
require("prismjs/plugins/line-numbers/prism-line-numbers.css");
require("prismjs/plugins/previewers/prism-previewers.css");
require("prismjs/plugins/command-line/prism-command-line.css");
require("prismjs/plugins/line-highlight/prism-line-highlight.css");
require("prismjs/plugins/toolbar/prism-toolbar.css");
require("./prism-collapse.less");

/**
* @parent bit-docs-prettify/static
* @module {function} bit-docs-prettify/prettify.js
*
* Main front end JavaScript file for static portion of this plugin.
*
* @signature `prettyPrint()`
*
* Finds all `<code>` elements on the page and adds the `prettyprint` class
* before executing the required pretty print engine.
*
* Also requires [bit-docs-prettify/prettify.less].
* Get node for provided line number
* Copied from prism-line-numbers.js and modified to support nested spans
* @param {Element} element pre element
* @param {Number} number line number
* @return {Element|undefined}
*/
module.exports = function(){
Prism.plugins.lineNumbers.getLine = function (element, number) {
Copy link
Member

Choose a reason for hiding this comment

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

can you add some docs explaining this?

Copy link
Author

Choose a reason for hiding this comment

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

there was a bit, but I added more to the docblock above. also, this has been moved to bit-docs-html-highlight-line

if (element.tagName !== 'PRE' || !element.classList.contains('line-numbers')) {
return;
}

var lineNumberRows = element.querySelector('.line-numbers-rows');
var lineNumbers = lineNumberRows.querySelectorAll('span');
var lineNumberStart = parseInt(element.getAttribute('data-start'), 10) || 1;
var lineNumberEnd = lineNumberStart + (lineNumbers.length - 1);

if (number < lineNumberStart) {
number = lineNumberStart;
}
if (number > lineNumberEnd) {
number = lineNumberEnd;
}

var lineIndex = number - lineNumberStart;

return lineNumbers[lineIndex];
};

Prism.languages.insertBefore('javascript', 'template-string', {
'html-template-string': {
pattern: /`(?:[\s\S])*<[a-z-]+(?:\s+[^<>]*)?>(?:[\s\S])*`/,
inside: {
'interpolation': {
pattern: /\$\{[^}]+\}/,
inside: {
'interpolation-punctuation': {
pattern: /^\$\{|\}$/,
alias: 'punctuation'
},
rest: Prism.languages.javascript
}
},
rest: Prism.languages.html
}
}
});

module.exports = function() {
var codes = document.getElementsByTagName("code");
for (var i = 0; i < codes.length; i++) {
var code = codes[i];

if (code.textContent.slice(-1) === "\n") {
code.textContent = code.textContent.slice(0, -1);
}

if (code.parentNode.nodeName.toUpperCase() === "PRE") {
code.parentNode.className += " line-numbers";

Expand All @@ -37,13 +84,9 @@ module.exports = function(){

if (code.className.includes("language-shell")) {
code.parentNode.className += " command-line";

if (code.textContent.slice(-1) === "\n") {
code.textContent = code.textContent.slice(0, -1);
}
}
}
}

Prism.highlightAll();
}
window.requestAnimationFrame(Prism.highlightAll);
};
20 changes: 17 additions & 3 deletions prettify.less
Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
pre[class*="language-"] > code {
border-left: none !important;
box-shadow: 0px 0px 0px 1px #dfdfdf !important;
article {
pre[class*="language-"] > code {
font-size: 16px;
border-left: none;
box-shadow: 0px 0px 0px 1px #dfdfdf;
background-image: none;
}

pre[class*=language-]:after, pre[class*=language-]:before {
display: none;
content: none;
}

.line-highlight {
background: rgba(0, 180, 0, .1);
background: linear-gradient(to right, rgba(0, 180, 0, .1) 70%, rgba(0, 180, 0, 0));
}
}
170 changes: 170 additions & 0 deletions prism-collapse.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
if (typeof self === 'undefined' || !self.Prism || !self.document || !document.querySelector) {
throw new Error('Prism must be loaded before prism-collapse');
}

function hasClass(element, className) {
className = " " + className + " ";
return (" " + element.className + " ").replace(/[\n\t]/g, " ").indexOf(className) > -1
}

function adjustHighlights(pre, collapseRange, visible) {
collapseRange = collapseRange.split('-').map(function(value) {
return parseInt(value);
});

var highlights = $(pre).find('.line-highlight');
var lineHeight = getLineHeight(highlights);

highlights.each(function() {
var highlight = $(this);
var range = highlight.attr('data-range').split('-').map(function(value) {
return parseInt(value);
});

if (range.length === 1) {
var line = range[0];
if (line < collapseRange[0]) {
return;
}

if (line > collapseRange[1]) {
var top = parseFloat(highlight.css('top').slice(0, -2));
var offset = (collapseRange[1] - collapseRange[0]) * lineHeight;

highlight.css('top', top + (visible ? offset : -offset));
return;
}

highlight.css('display', visible ? 'block' : 'none');
return;
}

if (range.length === 2) {
if (range[1] < collapseRange[0]) {
return;
}

if (range[0] > collapseRange[1]) {
var top = parseFloat(highlight.css('top').slice(0, -2));
var offset = (collapseRange[1] - collapseRange[0]) * lineHeight;

highlight.css('top', top + (visible ? offset : -offset));
return;
}

highlight.css('display', visible ? 'block' : 'none');
return;
}
});

function getLineHeight(highlights) {
var highlight = highlights.eq(0);
var height = parseFloat(highlight.css('height').slice(0, -2));

var range = highlight.attr('data-range').split('-').map(function(value) {
return parseInt(value);
});

if (range.length === 1) {
return height;
}

return height / (range[1] - range[0] + 1);
}
}

function collapseLines(pre, config, hasLineNumbers) {
var inserts = [];

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

var wrapper = '<div class="collapse collapsed" data-index="' + i + '" data-range="' + range + '">';
inserts.push([
+parts[0],
wrapper + '<div class="collapse-code">',
wrapper + '<div class="collapse-lines">'
]);

inserts.push([
+parts[1] + 1,
'</div></div>',
'</div></div>'
]);

adjustHighlights(pre, range, false);
}

inserts.sort(function (a, b) {
return b[0] - a[0];
});


var codeContainer = pre.children[0];

var numbersContainer = null;
var numbers = null;
if (hasLineNumbers) {
numbersContainer = codeContainer.lastChild;
numbersContainer.remove();

numbers = numbersContainer.innerHTML.split('<span></span>');
}

var code = codeContainer.innerHTML.split('\n');
code = code.map(function(line, index) {
if (index === code.length - 1) {
return line;
}

return line + '\n';
});

for (var i = 0; i < inserts.length; i++) {
var line = Math.min(code.length - 1, inserts[i][0] - 1);

code.splice(line, 0, inserts[i][1]);
numbers[line] += inserts[i][2];
}

codeContainer.innerHTML = code.join('');

if (hasLineNumbers) {
numbersContainer.innerHTML = numbers.join('<span></span>');
codeContainer.appendChild(numbersContainer);
}
}

Prism.hooks.add('complete', function completeHook(env) {
var pre = env.element.parentNode;
var config = pre && pre.getAttribute('data-collapse');

if (!pre || !config || !/pre/i.test(pre.nodeName)) {
return;
}

var hasLineNumbers = Prism.plugins.lineNumbers;
var isLineNumbersLoaded = env.plugins && env.plugins.lineNumbers;

if (hasClass(pre, 'line-numbers') && hasLineNumbers && !isLineNumbersLoaded) {
Prism.hooks.add('line-numbers', completeHook);
} else {
collapseLines(pre, config, hasLineNumbers);
}
});

$('body').on('click', 'pre code .collapse.collapsed', function() {
var collapse = $(this);
var pre = collapse.closest('pre');
var code = collapse.closest('code');
var index = collapse.attr('data-index');

code
.find('.collapse[data-index=' + index + ']')
.removeClass('collapsed')
;

adjustHighlights(pre, collapse.attr('data-range'), true);
});
Loading