diff --git a/src/obsidian/processors/latexProcessor.ts b/src/obsidian/processors/latexProcessor.ts index cb709d2..b015288 100644 --- a/src/obsidian/processors/latexProcessor.ts +++ b/src/obsidian/processors/latexProcessor.ts @@ -2,6 +2,28 @@ export class LatexProcessor { private singleLine = /\$(.*?)\$/g; process(markdown: string) { + return this.skipCodeBlocks(markdown); + } + + skipCodeBlocks(markdown: string): string { + const regex = + /(?<=(^|\r|\n|\r\n))`{3,}.*?(\r|\n|\r\n)[\s\S]*?(\r|\n|\r\n)`{3,}(?=($|\r|\n|\r\n))/; + const match = regex.exec(markdown); + + if (match) { + return ( + this.transformLatex(markdown.substring(0, match['index'])) + + match[0] + + this.skipCodeBlocks( + markdown.substring(match['index'] + match[0].length), + ) + ); + } else { + return this.transformLatex(markdown); + } + } + + private transformLatex(markdown: string) { const withoutEscapedCharaters = this.markEscapedCharacters(markdown); const processedMultiline = this.processMultiLine( withoutEscapedCharaters, diff --git a/test/__snapshots__/codeBlocks.unit.test.ts.snap b/test/__snapshots__/codeBlocks.unit.test.ts.snap new file mode 100644 index 0000000..481a4b7 --- /dev/null +++ b/test/__snapshots__/codeBlocks.unit.test.ts.snap @@ -0,0 +1,124 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Basic Markdown Syntax > Code Blocks 1`] = ` +" +
+ +\`\`\`dockerfile +FROM ubuntu +\`\`\` +
" +`; + +exports[`Basic Markdown Syntax > Code Blocks with multiple $ characters 1`] = ` +" +
+ +\`\`\`dockerfile +USER $USER_NAME:$USER_NAME +\`\`\` +
" +`; + +exports[`Basic Markdown Syntax > Math with Code Blocks 1`] = ` +" +
+ +$egin{vmatrix}a & b\\ +c & d +end{vmatrix}=ad-bc$ + +\`\`\`dockerfile +USER $USER_NAME:$USER_NAME +\`\`\` + +You can also do inline math like \`$s^{-2}_{n}sum_{i=1}^{n}$\` +
" +`; + +exports[`Basic Markdown Syntax > Math with Multiple Code Blocks 1`] = ` +" +
+ +$egin{vmatrix}a & b\\ +c & d +end{vmatrix}=ad-bc$ + +\`\`\`dockerfile +USER $USER_NAME:$USER_NAME +\`\`\` + +You can also do inline math like \`$s^{-2}_{n}sum_{i=1}^{n}$\` + +\`\`\`bash +eval "$(/home/$USER_NAME/.rbenv/bin/rbenv init -)" +\`\`\` + +That was ruby, now we have javascript: + +\`\`\` +console.log("Hello world!") +\`\`\` +
" +`; + +exports[`Code Block Syntax > Headers 1`] = ` +" +
+ +\`\`\` +USER $USER_NAME:$USER_NAME +\`\`\` + +The above does not show backticks +
" +`; + +exports[`Code Block Syntax > Headers 2`] = ` +" +
+ +\`\`\` +USER \`$USER_NAME:$\`USER_NAME +\`\`\` + +The above does show backticks +
" +`; + +exports[`Code Block Syntax > Headers 3`] = ` +" +
+ +\`\`\` +USER $USER_NAME:$USER_NAME +\`\`\` + +The above does not show backticks +
" +`; + +exports[`Embedded code has extra characters near dollar signs 1`] = ` +" +
+ +\`\`\`javascript +export class CounterService { + count$ = new BehaviorSubject(1000); + + double$ = this.count$.pipe(map((count) => count * 2)); + triple$ = this.count$.pipe(map((count) => count * 3)); + + combined$ = combineLatest([this.double$, this.triple$]).pipe( + map(([double, triple]) => double + triple) + ); + + over9000$ = this.combined$.pipe(map((combined) => combined > 9000)); + + message$ = this.over9000$.pipe( + map((over9000) => (over9000 ? "It's over 9000!" : "It's under 9000.")) + ); +} +\`\`\` +
" +`; diff --git a/test/codeBlocks.unit.test.ts b/test/codeBlocks.unit.test.ts new file mode 100644 index 0000000..414188c --- /dev/null +++ b/test/codeBlocks.unit.test.ts @@ -0,0 +1,145 @@ +import { MarkdownProcessor } from 'src/obsidian/markdownProcessor'; +import { obsidianUtils as utilsInstance } from './__mocks__/mockObsidianUtils'; +import { prepare } from './testUtils'; + +test('Basic Markdown Syntax > Code Blocks', () => { + const input = ` +\`\`\`dockerfile +FROM ubuntu +\`\`\` +`; + + const { options, markdown } = prepare(input); + const sut = new MarkdownProcessor(utilsInstance); + + return expect(sut.process(markdown, options)).toMatchSnapshot(); +}); + +test('Basic Markdown Syntax > Code Blocks with multiple $ characters', () => { + const input = ` +\`\`\`dockerfile +USER $USER_NAME:$USER_NAME +\`\`\` +`; + + const { options, markdown } = prepare(input); + const sut = new MarkdownProcessor(utilsInstance); + + return expect(sut.process(markdown, options)).toMatchSnapshot(); +}); + +test('Code Block Syntax > Headers', () => { + const input = ` +\`\`\` +USER $USER_NAME:$USER_NAME +\`\`\` + +The above does not show backticks +`; + + const { options, markdown } = prepare(input); + const sut = new MarkdownProcessor(utilsInstance); + + return expect(sut.process(markdown, options)).toMatchSnapshot(); +}); + +test('Code Block Syntax > Headers', () => { + const input = ` \`\`\` +USER $USER_NAME:$USER_NAME +\`\`\` + +The above does show backticks +`; + + const { options, markdown } = prepare(input); + const sut = new MarkdownProcessor(utilsInstance); + + return expect(sut.process(markdown, options)).toMatchSnapshot(); +}); + +test('Code Block Syntax > Headers', () => { + const input = `\`\`\` +USER $USER_NAME:$USER_NAME +\`\`\` + +The above does not show backticks +`; + + const { options, markdown } = prepare(input); + const sut = new MarkdownProcessor(utilsInstance); + + return expect(sut.process(markdown, options)).toMatchSnapshot(); +}); + +test('Basic Markdown Syntax > Math with Code Blocks', () => { + const input = `$$\begin{vmatrix}a & b\\ +c & d +\end{vmatrix}=ad-bc$$ + +\`\`\`dockerfile +USER $USER_NAME:$USER_NAME +\`\`\` + +You can also do inline math like $s^{-2}_{n}sum_{i=1}^{n}$`; + + const { options, markdown } = prepare(input); + const sut = new MarkdownProcessor(utilsInstance); + + return expect(sut.process(markdown, options)).toMatchSnapshot(); +}); + +test('Basic Markdown Syntax > Math with Multiple Code Blocks', () => { + const input = `$$\begin{vmatrix}a & b\\ +c & d +\end{vmatrix}=ad-bc$$ + +\`\`\`dockerfile +USER $USER_NAME:$USER_NAME +\`\`\` + +You can also do inline math like $s^{-2}_{n}sum_{i=1}^{n}$ + +\`\`\`bash +eval "$(/home/$USER_NAME/.rbenv/bin/rbenv init -)" +\`\`\` + +That was ruby, now we have javascript: + +\`\`\` +console.log("Hello world!") +\`\`\` +`; + + const { options, markdown } = prepare(input); + const sut = new MarkdownProcessor(utilsInstance); + + return expect(sut.process(markdown, options)).toMatchSnapshot(); +}); + +test('Embedded code has extra characters near dollar signs', () => { + const input = ` +\`\`\`javascript +export class CounterService { + count$ = new BehaviorSubject(1000); + + double$ = this.count$.pipe(map((count) => count * 2)); + triple$ = this.count$.pipe(map((count) => count * 3)); + + combined$ = combineLatest([this.double$, this.triple$]).pipe( + map(([double, triple]) => double + triple) + ); + + over9000$ = this.combined$.pipe(map((combined) => combined > 9000)); + + message$ = this.over9000$.pipe( + map((over9000) => (over9000 ? "It's over 9000!" : "It's under 9000.")) + ); +} +\`\`\``; + + const { options, markdown } = prepare(input); + const sut = new MarkdownProcessor(utilsInstance); + + return expect(sut.process(markdown, options)).toMatchSnapshot(); +}); +