Skip to content

Commit

Permalink
Merge pull request #12 from shafayetShafee/fix-deps
Browse files Browse the repository at this point in the history
Added event listener to DOMContentLoaded to fix #11 and restructured CSS code spaces
  • Loading branch information
shafayetShafee authored Apr 24, 2023
2 parents 38ddc17 + 21bed10 commit 21cdda3
Show file tree
Hide file tree
Showing 22 changed files with 3,864 additions and 3,829 deletions.
2 changes: 1 addition & 1 deletion _extensions/line-highlight/_extension.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
title: Line-highlight
author: Shafayet Khan Shafee
version: 1.2.0
version: 1.2.1
quarto-required: ">=1.2.0"
contributes:
filters:
Expand Down
7 changes: 6 additions & 1 deletion _extensions/line-highlight/line-highlight.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ local function ensureHtmlDeps()
name = "line-highlight",
version = "1.0.0",
scripts = {
{ path = "resources/js/line-highlight.js", attribs = {defer = "true"} }
{
path = "resources/js/line-highlight.js",
attribs = {defer = "true"},
afterBody = true

}
},
stylesheets = {"resources/css/line-highlight.css"}
})
Expand Down
30 changes: 6 additions & 24 deletions _extensions/line-highlight/resources/css/line-highlight.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,50 +4,32 @@ https://github.com/quarto-dev/quarto-cli/tree/main/src/resources/formats/revealj
*/

/* for source-line-numbers */
div.sourceCode
pre
code.has-line-highlights
> span:not(.highlight-line) {
div.sourceCode pre code.has-line-highlights > span:not(.highlight-line) {
opacity: 0.4;
}

/* for output-line-numbers */
div.sourceCode
pre.highlight
code.has-line-highlights
> span:not(.highlight-line) {
div.sourceCode pre.highlight code.has-line-highlights > span:not(.highlight-line) {
opacity: 0.4;
}

/* Adding hovering effect */
/* from https://github.com/shafayetShafee/line-highlight/issues/1#issue-1639343001 by @GShotwell*/

div.sourceCode:hover
pre
code.has-line-highlights
> span:not(.highlight-line) {
div.sourceCode:hover pre code.has-line-highlights > span:not(.highlight-line) {
opacity: 0.4;
}


div.sourceCode:hover
pre
code.has-line-highlights
> span.highlight-line {
div.sourceCode:hover pre code.has-line-highlights > span.highlight-line {
font-weight: 600;
}


div.sourceCode:hover
pre.highlight
code.has-line-highlights
> span:not(.highlight-line) {
div.sourceCode:hover pre.highlight code.has-line-highlights > span:not(.highlight-line) {
opacity: 0.4;
}

div.sourceCode:hover
pre.highlight
code.has-line-highlights
> span.highlight-line {
div.sourceCode:hover pre.highlight code.has-line-highlights > span.highlight-line {
font-weight: 600;
}
241 changes: 122 additions & 119 deletions _extensions/line-highlight/resources/js/line-highlight.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,127 +3,130 @@ modified and reduced from
https://github.com/quarto-dev/quarto-cli/tree/main/src/resources/formats/revealjs/plugins/line-highlight
*/

const delimiters = {
step: "|",
line: ",",
lineRange: "-",
};

const regex = new RegExp(
"^[\\d" + Object.values(delimiters).join("") + "]+$"
);

function handleLinesSelector(attr) {
if (regex.test(attr)) {
return true;
} else {
return false;
}
}

function highlightCodeBlock(codeBlock) {
const highlightSteps = splitLineNumbers(
codeBlock.getAttribute(kCodeLineNumbersAttr)
window.document.addEventListener("DOMContentLoaded", function (event) {
const delimiters = {
step: "|",
line: ",",
lineRange: "-",
};

const regex = new RegExp(
"^[\\d" + Object.values(delimiters).join("") + "]+$"
);

if (highlightSteps.length) {
// If we have at least one step, we generate fragments
highlightSteps[0].forEach((highlight) => {
// Add expected class on <pre> for reveal CSS
codeBlock.parentNode.classList.add("code-wrapper");

// Select lines to highlight
spanToHighlight = [];
if (typeof highlight.last === "number") {
spanToHighlight = [].slice.call(
codeBlock.querySelectorAll(
":scope > span:nth-child(n+" +
highlight.first +
"):nth-child(-n+" +
highlight.last +
")"
)
);
} else if (typeof highlight.first === "number") {
spanToHighlight = [].slice.call(
codeBlock.querySelectorAll(
":scope > span:nth-child(" + highlight.first + ")"
)
);
}
if (spanToHighlight.length) {
// Add a class on <code> and <span> to select line to highlight
spanToHighlight.forEach((span) =>
span.classList.add("highlight-line")
);
codeBlock.classList.add("has-line-highlights");
}
});
}
}



function getHighlightedLineBounds(block) {
const highlightedLines = block.querySelectorAll(".highlight-line");
if (highlightedLines.length === 0) {
return { top: 0, bottom: 0 };
} else {
const firstHighlight = highlightedLines[0];
const lastHighlight = highlightedLines[highlightedLines.length - 1];

return {
top: firstHighlight.offsetTop,
bottom: lastHighlight.offsetTop + lastHighlight.offsetHeight,
};

function handleLinesSelector(attr) {
if (regex.test(attr)) {
return true;
} else {
return false;
}
}
}


function splitLineNumbers(lineNumbersAttr) {
// remove space
lineNumbersAttr = lineNumbersAttr.replace("/s/g", "");
// seperate steps (for fragment)
lineNumbersAttr = lineNumbersAttr.split(delimiters.step);

// for each step, calculate first and last line, if any
return lineNumbersAttr.map((highlights) => {
// detect lines
const lines = highlights.split(delimiters.line);
return lines.map((range) => {
if (/^[\d-]+$/.test(range)) {
range = range.split(delimiters.lineRange);
const firstLine = parseInt(range[0], 10);
const lastLine = range[1] ? parseInt(range[1], 10) : undefined;
return {
first: firstLine,
last: lastLine,
};
} else {
return {};
}
});
});
}


const kCodeLineNumbersAttr = "data-code-line-numbers";

const divSourceCode = document.querySelectorAll("div.sourceCode");

divSourceCode.forEach((el) => {
if (el.hasAttribute(kCodeLineNumbersAttr)) {
const codeLineAttr = el.getAttribute(kCodeLineNumbersAttr);
el.removeAttribute("data-code-line-numbers");
if (handleLinesSelector(codeLineAttr)) {
// Only process if attr is a string to select lines to highlights
// e.g "1|3,6|8-11"
const codeBlock = el.querySelectorAll("pre code");
codeBlock.forEach((code) => {
// move attributes on code block
code.setAttribute(kCodeLineNumbersAttr, codeLineAttr);
highlightCodeBlock(code);

function highlightCodeBlock(codeBlock) {
const highlightSteps = splitLineNumbers(
codeBlock.getAttribute(kCodeLineNumbersAttr)
);

if (highlightSteps.length) {
// If we have at least one step, we generate fragments
highlightSteps[0].forEach((highlight) => {
// Add expected class on <pre> for reveal CSS
codeBlock.parentNode.classList.add("code-wrapper");

// Select lines to highlight
spanToHighlight = [];
if (typeof highlight.last === "number") {
spanToHighlight = [].slice.call(
codeBlock.querySelectorAll(
":scope > span:nth-child(n+" +
highlight.first +
"):nth-child(-n+" +
highlight.last +
")"
)
);
} else if (typeof highlight.first === "number") {
spanToHighlight = [].slice.call(
codeBlock.querySelectorAll(
":scope > span:nth-child(" + highlight.first + ")"
)
);
}
if (spanToHighlight.length) {
// Add a class on <code> and <span> to select line to highlight
spanToHighlight.forEach((span) =>
span.classList.add("highlight-line")
);
codeBlock.classList.add("has-line-highlights");
}
});
}
}
});



function getHighlightedLineBounds(block) {
const highlightedLines = block.querySelectorAll(".highlight-line");
if (highlightedLines.length === 0) {
return { top: 0, bottom: 0 };
} else {
const firstHighlight = highlightedLines[0];
const lastHighlight = highlightedLines[highlightedLines.length - 1];

return {
top: firstHighlight.offsetTop,
bottom: lastHighlight.offsetTop + lastHighlight.offsetHeight,
};
}
}


function splitLineNumbers(lineNumbersAttr) {
// remove space
lineNumbersAttr = lineNumbersAttr.replace("/s/g", "");
// seperate steps (for fragment)
lineNumbersAttr = lineNumbersAttr.split(delimiters.step);

// for each step, calculate first and last line, if any
return lineNumbersAttr.map((highlights) => {
// detect lines
const lines = highlights.split(delimiters.line);
return lines.map((range) => {
if (/^[\d-]+$/.test(range)) {
range = range.split(delimiters.lineRange);
const firstLine = parseInt(range[0], 10);
const lastLine = range[1] ? parseInt(range[1], 10) : undefined;
return {
first: firstLine,
last: lastLine,
};
} else {
return {};
}
});
});
}


const kCodeLineNumbersAttr = "data-code-line-numbers";

const divSourceCode = document.querySelectorAll("div.sourceCode");

divSourceCode.forEach((el) => {
if (el.hasAttribute(kCodeLineNumbersAttr)) {
const codeLineAttr = el.getAttribute(kCodeLineNumbersAttr);
el.removeAttribute("data-code-line-numbers");
if (handleLinesSelector(codeLineAttr)) {
// Only process if attr is a string to select lines to highlights
// e.g "1|3,6|8-11"
const codeBlock = el.querySelectorAll("pre code");
codeBlock.forEach((code) => {
// move attributes on code block
code.setAttribute(kCodeLineNumbersAttr, codeLineAttr);
highlightCodeBlock(code);
});
}
}
});

});
Loading

0 comments on commit 21cdda3

Please sign in to comment.