Skip to content

Commit c8b74c4

Browse files
committed
feat: add support for fragment indices in line highlighting
1 parent 75fbfd0 commit c8b74c4

File tree

1 file changed

+25
-8
lines changed

1 file changed

+25
-8
lines changed

src/resources/formats/revealjs/plugins/line-highlight/line-highlight.js

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ window.QuartoLineHighlight = function () {
2929

3030
const kCodeLineNumbersAttr = "data-code-line-numbers";
3131
const kFragmentIndex = "data-fragment-index";
32+
const kCodeLineFragmentIndicesAttr = "data-code-line-fragment-indices";
3233

3334
function initQuartoLineHighlight(deck) {
3435
const divSourceCode = deck
@@ -39,6 +40,16 @@ window.QuartoLineHighlight = function () {
3940
if (el.hasAttribute(kCodeLineNumbersAttr)) {
4041
const codeLineAttr = el.getAttribute(kCodeLineNumbersAttr);
4142
el.removeAttribute(kCodeLineNumbersAttr);
43+
// Get fragment index attribute if present
44+
let fragmentIndices = null;
45+
if (el.hasAttribute(kCodeLineFragmentIndicesAttr)) {
46+
const fragmentIndexAttr = el.getAttribute(kCodeLineFragmentIndicesAttr);
47+
fragmentIndices = fragmentIndexAttr.split(',').map((x) => {
48+
const v = parseInt(x.trim(), 10);
49+
return isNaN(v) ? null : v;
50+
});
51+
el.removeAttribute(kCodeLineFragmentIndicesAttr);
52+
}
4253
if (handleLinesSelector(deck, codeLineAttr)) {
4354
// Only process if attr is a string to select lines to highlights
4455
// e.g "1|3,6|8-11"
@@ -52,6 +63,10 @@ window.QuartoLineHighlight = function () {
5263
// Check if there are steps and duplicate code block accordingly
5364
const highlightSteps = splitLineNumbers(codeLineAttr);
5465
if (highlightSteps.length > 1) {
66+
if (fragmentIndices.length != highlightSteps.length) {
67+
// Don't use provided fragment indices if they don't match the number of steps
68+
fragmentIndices = null;
69+
}
5570
// If the original code block has a fragment-index,
5671
// each clone should follow in an incremental sequence
5772
let fragmentIndex = parseInt(
@@ -66,7 +81,7 @@ window.QuartoLineHighlight = function () {
6681
let stepN = 1;
6782
highlightSteps.slice(1).forEach(
6883
// Generate fragments for all steps except the original block
69-
(step) => {
84+
(step, idx) => {
7085
var fragmentBlock = code.cloneNode(true);
7186
fragmentBlock.setAttribute(
7287
"data-code-line-numbers",
@@ -92,8 +107,10 @@ window.QuartoLineHighlight = function () {
92107

93108
// Each new <code> element is highlighted based on the new attributes value
94109
highlightCodeBlock(fragmentBlock);
95-
96-
if (typeof fragmentIndex === "number") {
110+
// Use fragmentIndices if present instead of incrementing
111+
if (fragmentIndices && fragmentIndices.length > idx + 1) {
112+
fragmentBlock.setAttribute(kFragmentIndex, fragmentIndices[idx + 1]);
113+
} else if (typeof fragmentIndex === "number") {
97114
fragmentBlock.setAttribute(kFragmentIndex, fragmentIndex);
98115
fragmentIndex += 1;
99116
} else {
@@ -166,10 +183,10 @@ window.QuartoLineHighlight = function () {
166183
spanToHighlight = [].slice.call(
167184
codeBlock.querySelectorAll(
168185
":scope > span:nth-of-type(n+" +
169-
highlight.first +
170-
"):nth-of-type(-n+" +
171-
highlight.last +
172-
")"
186+
highlight.first +
187+
"):nth-of-type(-n+" +
188+
highlight.last +
189+
")"
173190
)
174191
);
175192
} else if (typeof highlight.first === "number") {
@@ -221,7 +238,7 @@ window.QuartoLineHighlight = function () {
221238
highlightBounds.top +
222239
(Math.min(highlightBounds.bottom - highlightBounds.top, viewportHeight) -
223240
viewportHeight) /
224-
2;
241+
2;
225242

226243
// Make sure the scroll target is within bounds
227244
targetTop = Math.max(

0 commit comments

Comments
 (0)