diff --git a/src/__tests__/highlightSpans.test.ts b/src/__tests__/highlightSpans.test.ts
new file mode 100644
index 0000000..207a8de
--- /dev/null
+++ b/src/__tests__/highlightSpans.test.ts
@@ -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 + ``;
+ });
+}
+
+describe('highlightSpans regex (issue #2)', () => {
+ it('highlights a span preceded by a non-backtick character', () => {
+ const result = applyHighlightPattern('call `method`(arg)');
+ expect(result).toContain('');
+ });
+
+ it('highlights a span at the very start of a string', () => {
+ const result = applyHighlightPattern('`highlightedMethod`(arg1, arg2)');
+ expect(result).toContain('');
+ });
+
+ 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('');
+ expect(result).toContain('normalMethod(a)');
+ });
+
+ it('does not double-highlight adjacent backtick spans', () => {
+ const result = applyHighlightPattern('`a` and `b`');
+ expect(result).toContain('');
+ expect(result).toContain('');
+ });
+
+ 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');
+ });
+});
diff --git a/src/mdeck/views/slideView.ts b/src/mdeck/views/slideView.ts
index e948f0f..a28fc34 100644
--- a/src/mdeck/views/slideView.ts
+++ b/src/mdeck/views/slideView.ts
@@ -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');
}