@@ -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