Skip to content

Commit e8900cf

Browse files
committed
simplified line numbers logic
1 parent 1523dcd commit e8900cf

File tree

1 file changed

+40
-80
lines changed

1 file changed

+40
-80
lines changed

src/extensions/markdown/CodeBlock/CodeBlockHighlight/CodeBlockHighlight.ts

Lines changed: 40 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ export const CodeBlockHighlight: ExtensionAuto<CodeBlockHighlightOptions> = (bui
179179
let prevLineCount = 0;
180180

181181
if (opts.lineNumbers?.enabled) {
182-
const result = initializeLineNumbers(node, code);
182+
const result = manageLineNumbers(node, code);
183183
lineNumbersContainer = result.container;
184184
prevLineCount = result.lineCount;
185185
}
@@ -210,7 +210,7 @@ export const CodeBlockHighlight: ExtensionAuto<CodeBlockHighlightOptions> = (bui
210210
);
211211

212212
if (opts.lineNumbers?.enabled) {
213-
const result = updateLineNumbers(
213+
const result = manageLineNumbers(
214214
newNode,
215215
code,
216216
lineNumbersContainer,
@@ -296,102 +296,62 @@ function updateDomAttribute(elem: Element, attr: string, value: string | null |
296296
elem.removeAttribute(attr);
297297
}
298298
}
299-
function initializeLineNumbers(
300-
node: Node,
301-
code: HTMLElement,
302-
): {container?: HTMLDivElement; lineCount: number} {
303-
const showLineNumbers = node.attrs[CodeBlockNodeAttr.ShowLineNumbers];
304-
305-
if (!showLineNumbers) {
306-
return {container: undefined, lineCount: 0};
307-
}
308-
309-
const lineNumbersContainer = document.createElement('div');
310-
lineNumbersContainer.className = 'yfm-line-numbers';
311-
lineNumbersContainer.contentEditable = 'false';
312-
313-
const lines = node.textContent ? node.textContent.split('\n') : [''];
314-
const lineCount = lines.length;
315299

316-
appendLineNumbers(lineNumbersContainer, 1, lineCount);
317-
318-
code.prepend(lineNumbersContainer);
319-
code.classList.add('show-line-numbers');
320-
321-
return {container: lineNumbersContainer, lineCount};
322-
}
323-
324-
function updateLineNumbers(
300+
function manageLineNumbers(
325301
node: Node,
326302
code: HTMLElement,
327-
prevLineNumbersContainer?: HTMLDivElement,
303+
prevContainer?: HTMLDivElement,
328304
prevLineCount = 0,
329305
): {container?: HTMLDivElement; lineCount: number} {
330-
const showLineNumbers = node.attrs[CodeBlockNodeAttr.ShowLineNumbers];
306+
const showLineNumbers = node.attrs[CodeBlockNodeAttr.ShowLineNumbers] === 'true';
331307

332-
if (!prevLineNumbersContainer && showLineNumbers !== 'true') {
333-
return {container: undefined, lineCount: 0};
334-
} else if (!prevLineNumbersContainer && showLineNumbers === 'true') {
335-
return initializeLineNumbers(node, code);
336-
} else if (prevLineNumbersContainer && showLineNumbers !== 'true') {
337-
code.removeChild(prevLineNumbersContainer);
338-
code.classList.remove('show-line-numbers');
308+
if (!showLineNumbers) {
309+
if (prevContainer) {
310+
code.removeChild(prevContainer);
311+
code.classList.remove('show-line-numbers');
312+
}
339313
return {container: undefined, lineCount: 0};
340314
}
341315

342-
if (!prevLineNumbersContainer) {
343-
return {container: prevLineNumbersContainer, lineCount: prevLineCount};
344-
}
345-
346316
const lines = node.textContent ? node.textContent.split('\n') : [''];
347317
const currentLineCount = lines.length;
348318

349-
code.classList.add('show-line-numbers');
350-
351-
if (currentLineCount === prevLineCount) {
352-
return {container: prevLineNumbersContainer, lineCount: prevLineCount};
353-
}
354-
355-
if (currentLineCount > prevLineCount) {
356-
appendLineNumbers(prevLineNumbersContainer, prevLineCount + 1, currentLineCount);
357-
} else if (currentLineCount < prevLineCount) {
358-
removeExcessLineNumbers(prevLineNumbersContainer, currentLineCount, prevLineCount);
319+
let container = prevContainer;
320+
if (!container) {
321+
container = document.createElement('div');
322+
container.className = 'yfm-line-numbers';
323+
container.contentEditable = 'false';
324+
code.prepend(container);
359325
}
360326

361-
return {container: prevLineNumbersContainer, lineCount: currentLineCount};
362-
}
363-
364-
function appendLineNumbers(container: HTMLDivElement, startLine: number, endLine: number) {
365-
const maxDigits = String(endLine).length;
327+
code.classList.add('show-line-numbers');
366328

367-
for (let i = startLine; i <= endLine; i++) {
368-
const lineNumberElement = document.createElement('div');
369-
lineNumberElement.className = 'yfm-line-number';
370-
lineNumberElement.textContent = String(i).padStart(maxDigits, ' ');
371-
container.appendChild(lineNumberElement);
372-
}
329+
if (currentLineCount !== prevLineCount) {
330+
const maxDigits = String(currentLineCount).length;
331+
const prevMaxDigits = String(prevLineCount).length;
373332

374-
// Update padding on all line numbers if digit count changed
375-
if (startLine === 1) {
376-
updateLineNumberPadding(container, maxDigits);
377-
}
378-
}
333+
if (currentLineCount > prevLineCount) {
334+
for (let i = prevLineCount + 1; i <= currentLineCount; i++) {
335+
const lineNumberElement = document.createElement('div');
336+
lineNumberElement.className = 'yfm-line-number';
337+
lineNumberElement.textContent = String(i).padStart(maxDigits, ' ');
338+
container.appendChild(lineNumberElement);
339+
}
340+
} else if (currentLineCount < prevLineCount) {
341+
for (let i = prevLineCount; i > currentLineCount; i--) {
342+
if (container.lastChild) {
343+
container.removeChild(container.lastChild);
344+
}
345+
}
346+
}
379347

380-
function removeExcessLineNumbers(container: HTMLDivElement, keepCount: number, prevCount: number) {
381-
for (let i = prevCount; i > keepCount; i--) {
382-
if (container.lastChild) {
383-
container.removeChild(container.lastChild);
348+
if (maxDigits !== prevMaxDigits) {
349+
Array.from(container.children).forEach((lineNumber, index) => {
350+
const lineNum = index + 1;
351+
lineNumber.textContent = String(lineNum).padStart(maxDigits, ' ');
352+
});
384353
}
385354
}
386355

387-
// Update padding on remaining line numbers if digit count changed
388-
const maxDigits = String(keepCount).length;
389-
updateLineNumberPadding(container, maxDigits);
390-
}
391-
392-
function updateLineNumberPadding(container: HTMLDivElement, maxDigits: number) {
393-
Array.from(container.children).forEach((lineNumber, index) => {
394-
const lineNum = index + 1;
395-
lineNumber.textContent = String(lineNum).padStart(maxDigits, ' ');
396-
});
356+
return {container, lineCount: currentLineCount};
397357
}

0 commit comments

Comments
 (0)