feat(snippets): add text transform for cleaning inline double dollar equations

- Implement `Clean Inline Double Dollar Symbols` text transform snippet.
- Convert inline double dollar signs `$$` to single dollar sign `$`.
- Keep block/display equation dollar signs (`$$`) intact (e.g. multi-line blocks or single-line equations starting/ending with `$$`).
- Add unit tests in `test_helpers/transforms.test.ts` to verify behavior.
- Update documentation in `docs/features/snippets.md` to document the new and existing double-dollar cleanup transforms.
This commit is contained in:
JK 2026-06-28 12:34:59 +02:00
parent 5783d3591f
commit 8e7a3072ef
3 changed files with 74 additions and 0 deletions

View file

@ -32,5 +32,7 @@ The **Run Text Transform Snippet** command processes your highlighted editor tex
| **Title Kebab Case** | `Example-Text-String` | Title heading slugifications. |
| **Title Case** | `Example Text String` | Formatting article or note headings. |
| **Clean Zotero Highlight** | Reformats HTML tags to raw markdown | Converting Zotero desktop highlights into blockquotes. |
| **Clean Double Dollar Symbols** | `$$` → `$` | Replaces all double dollar signs with single dollar signs in the selected text/line. |
| **Clean Inline Double Dollar Symbols** | `$$x$$` → `$x$` | Converts inline double dollar math into single dollar inline math while preserving display/block math blocks. |
When any transformation runs, TeXcore displays a notice toast in the top-right corner indicating whether the change was successfully applied.

View file

@ -77,6 +77,22 @@ function cleanDoubleDollarSymbols(input: string): string {
return input.replace(/\$\$/g, '$');
}
function cleanInlineDoubleDollarSymbols(input: string): string {
const lines = input.split(/\r?\n/);
const processedLines = lines.map(line => {
const trimmed = line.trim();
const isBlockEquation =
trimmed === '$$' ||
(trimmed.startsWith('$$') && trimmed.endsWith('$$') && trimmed.length > 2);
if (isBlockEquation) {
return line;
}
return line.replace(/\$\$/g, '$');
});
const hasCarriageReturn = input.includes('\r\n');
return processedLines.join(hasCarriageReturn ? '\r\n' : '\n');
}
export const BUILTIN_TEXT_TRANSFORM_SNIPPETS: TextTransformSnippet[] = [
{
id: 'kebab-case',
@ -112,6 +128,13 @@ export const BUILTIN_TEXT_TRANSFORM_SNIPPETS: TextTransformSnippet[] = [
description: 'Replace all $$ with $',
keywords: ['dollar', 'latex', 'equation', 'cleanup'],
transform: cleanDoubleDollarSymbols
},
{
id: 'clean-inline-double-dollar-symbols',
name: 'Clean Inline Double Dollar Symbols',
description: 'Replace inline $$ with $ while keeping block $$',
keywords: ['dollar', 'latex', 'equation', 'inline', 'cleanup'],
transform: cleanInlineDoubleDollarSymbols
}
];

View file

@ -0,0 +1,49 @@
import { BUILTIN_TEXT_TRANSFORM_SNIPPETS } from '../src/features/snippets/transforms';
describe('transforms.ts tests', () => {
const inlineDoubleDollarTransform = BUILTIN_TEXT_TRANSFORM_SNIPPETS.find(
s => s.id === 'clean-inline-double-dollar-symbols'
)?.transform;
it('should exist', () => {
expect(inlineDoubleDollarTransform).toBeDefined();
});
if (inlineDoubleDollarTransform) {
it('should convert inline $$ to $ while keeping block $$', () => {
const sample = `At low concentrations, however, the expansion,
$$
\\varepsilon_{\\rm reg}(k)=b_0^*+b_2^*k^2+\\cdots
$$
has $$b_0^*$$ dominated by water dipole correlations, so $$E^*(\\kappa)\\approx\\varepsilon_{\\rm dip}(c)$$`;
const expected = `At low concentrations, however, the expansion,
$$
\\varepsilon_{\\rm reg}(k)=b_0^*+b_2^*k^2+\\cdots
$$
has $b_0^*$ dominated by water dipole correlations, so $E^*(\\kappa)\\approx\\varepsilon_{\\rm dip}(c)$`;
expect(inlineDoubleDollarTransform(sample)).toBe(expected);
});
it('should keep block $$ with leading spaces', () => {
const sample = ` $$
\\varepsilon = b
$$`;
expect(inlineDoubleDollarTransform(sample)).toBe(sample);
});
it('should keep single-line block equation', () => {
expect(inlineDoubleDollarTransform('$$ x = y $$')).toBe('$$ x = y $$');
expect(inlineDoubleDollarTransform(' $$ x = y $$ ')).toBe(' $$ x = y $$ ');
});
it('should handle single-line input for inline $$', () => {
expect(inlineDoubleDollarTransform('has $$b_0^*$$')).toBe('has $b_0^*$');
});
it('should handle inline equation that starts at beginning of line but has text on same line', () => {
expect(inlineDoubleDollarTransform('$$b_0^*$$ is the value')).toBe('$b_0^*$ is the value');
});
}
});