Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
50 changes: 50 additions & 0 deletions src/__tests__/highlightSpans.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { describe, it, expect } from 'vitest';

// Test the highlight-spans regex behaviour directly.
// The bug (issue #2): a backtick span at the very start of a line was not
// recognised because the pattern required a non-backtick character before the
// opening backtick. The fix adds `^` as an alternative via the `m` flag.

function applyHighlightPattern(html: string): string {
// Mirrors the fixed pattern in highlightBlockSpans (highlightSpans === true).
const pattern = /(^|[^`])`([^`]+?)`/gm;
return html.replace(pattern, (m, e, c) => {
if (e === '\\') return m.slice(1);
return e + `<span class="remark-code-span-highlighted">${c}</span>`;
});
}

describe('highlightSpans regex (issue #2)', () => {
it('highlights a span preceded by a non-backtick character', () => {
const result = applyHighlightPattern('call `method`(arg)');
expect(result).toContain('<span class="remark-code-span-highlighted">method</span>');
});

it('highlights a span at the very start of a string', () => {
const result = applyHighlightPattern('`highlightedMethod`(arg1, arg2)');
expect(result).toContain('<span class="remark-code-span-highlighted">highlightedMethod</span>');
});

it('highlights a span at the start of a new line', () => {
const html = 'normalMethod(a)\n`highlightedMethod`(b)';
const result = applyHighlightPattern(html);
expect(result).toContain('<span class="remark-code-span-highlighted">highlightedMethod</span>');
expect(result).toContain('normalMethod(a)');
});

it('does not double-highlight adjacent backtick spans', () => {
const result = applyHighlightPattern('`a` and `b`');
expect(result).toContain('<span class="remark-code-span-highlighted">a</span>');
expect(result).toContain('<span class="remark-code-span-highlighted">b</span>');
});

it('does not highlight a backtick span that is escaped', () => {
const result = applyHighlightPattern('\\`notHighlighted`');
expect(result).not.toContain('remark-code-span-highlighted');
});

it('does not treat fenced code delimiters (```) as highlight spans', () => {
const result = applyHighlightPattern('```js\ncode\n```');
expect(result).not.toContain('remark-code-span-highlighted');
});
});
4 changes: 2 additions & 2 deletions src/mdeck/views/slideView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,10 +211,10 @@ function highlightBlockLines(block: HTMLElement, lines: number[]): void {
function highlightBlockSpans(block: HTMLElement, highlightSpans: boolean | RegExp): void {
let pattern: RegExp;
if (highlightSpans === true) {
pattern = /([^`])`([^`]+?)`/g;
pattern = /(^|[^`])`([^`]+?)`/gm;
} else if (highlightSpans instanceof RegExp) {
if (!highlightSpans.global) throw new Error('highlightSpans RegExp must have /g flag');
pattern = new RegExp('([^])' + highlightSpans.source, highlightSpans.flags || 'g');
pattern = new RegExp('(^|[\\s\\S])' + highlightSpans.source, (highlightSpans.flags || 'g') + 'm');
} else {
throw new Error('Illegal value for highlightSpans');
}
Expand Down