diff --git a/src/compiler/GardenPageCompiler.ts b/src/compiler/GardenPageCompiler.ts index 1dc54ac..ec08fe4 100644 --- a/src/compiler/GardenPageCompiler.ts +++ b/src/compiler/GardenPageCompiler.ts @@ -30,6 +30,7 @@ import { import Logger from "js-logger"; import { DataviewCompiler } from "./DataviewCompiler"; import { PublishFile } from "../publishFile/PublishFile"; +import { replaceBlockIDs } from "./replaceBlockIDs"; export interface Asset { path: string; @@ -144,21 +145,7 @@ export class GardenPageCompiler { }; createBlockIDs: TCompilerStep = () => (text: string) => { - const block_pattern = / \^([\w\d-]+)/g; - const complex_block_pattern = /\n\^([\w\d-]+)\n/g; - - text = text.replace( - complex_block_pattern, - (_match: string, $1: string) => { - return `{ #${$1}}\n\n`; - }, - ); - - text = text.replace(block_pattern, (match: string, $1: string) => { - return `\n{ #${$1}}\n`; - }); - - return text; + return replaceBlockIDs(text); }; removeObsidianComments: TCompilerStep = () => (text) => { diff --git a/src/compiler/createBlockIDs.test.ts b/src/compiler/createBlockIDs.test.ts new file mode 100644 index 0000000..b05ab68 --- /dev/null +++ b/src/compiler/createBlockIDs.test.ts @@ -0,0 +1,65 @@ +import { replaceBlockIDs } from "./replaceBlockIDs"; + +describe("replaceBlockIDs", () => { + it("should replace block IDs in markdown", () => { + const EXPECTED_MARKDOWN = ` + # header + + foo ^block-id-1234 + + bar ^block-id-5678 + `; + + const result = replaceBlockIDs(EXPECTED_MARKDOWN); + + expect(result).toBe(` + # header + + foo +{ #block-id-1234} + + + bar +{ #block-id-5678} + + `); + }); + + it("should not replace block IDs in code blocks", () => { + const CODEBLOCK_WITH_BLOCKIDS = ` +\`\`\` +foobar. +this is a code block. +but it contains a block ID to try to fool the compiler +and, consequently, wreck your garden. +here it goes: ^block-id-1234 +and for fun, here's another: ^block-id-5678 +\`\`\` + +additionally, block IDs outside of code blocks should be replaced +for example, ^block-id-9999 +and ^block-id-0000 + `; + + const result = replaceBlockIDs(CODEBLOCK_WITH_BLOCKIDS); + + expect(result).toBe(` +\`\`\` +foobar. +this is a code block. +but it contains a block ID to try to fool the compiler +and, consequently, wreck your garden. +here it goes: ^block-id-1234 +and for fun, here's another: ^block-id-5678 +\`\`\` + +additionally, block IDs outside of code blocks should be replaced +for example, +{ #block-id-9999} + +and +{ #block-id-0000} + + `); + }); +}); diff --git a/src/compiler/replaceBlockIDs.ts b/src/compiler/replaceBlockIDs.ts new file mode 100644 index 0000000..50eb1a6 --- /dev/null +++ b/src/compiler/replaceBlockIDs.ts @@ -0,0 +1,35 @@ +export function replaceBlockIDs(markdown: string) { + const block_pattern = / \^([\w\d-]+)/g; + const complex_block_pattern = /\n\^([\w\d-]+)\n/g; + + // To ensure code blocks are not modified... + const codeBlockPattern = /```[\s\S]*?```/g; + + // Extract code blocks and replace them with placeholders + const codeBlocks: string[] = []; + + markdown = markdown.replace(codeBlockPattern, (match) => { + codeBlocks.push(match); + + return `{{CODE_BLOCK_${codeBlocks.length - 1}}}`; + }); + + // Replace patterns outside code blocks + markdown = markdown.replace( + complex_block_pattern, + (_match: string, $1: string) => { + return `{ #${$1}}\n\n`; + }, + ); + + markdown = markdown.replace(block_pattern, (_match: string, $1: string) => { + return `\n{ #${$1}}\n`; + }); + + // Reinsert code blocks + codeBlocks.forEach((block, index) => { + markdown = markdown.replace(`{{CODE_BLOCK_${index}}}`, block); + }); + + return markdown; +} diff --git a/src/dg-testVault/015 Code blocks.md b/src/dg-testVault/015 Code blocks.md new file mode 100644 index 0000000..d6fe2b6 --- /dev/null +++ b/src/dg-testVault/015 Code blocks.md @@ -0,0 +1,26 @@ +--- +dg-publish: true +--- +These codeblocks should not be modified upon publish. + +Sample 1 +```jinja2 +{{ highlight_text }}{% if highlight_location and highlight_location_url %} ([via]({{highlight_location_url}})){% elif highlight_location %} ({{highlight_location}}){% endif %} ^rwhi{{highlight_id}} +{% if highlight_note %} +{{ highlight_note }} ^rwhi{{highlight_id}}-note +{% endif %} +``` + +Sample 2 +```md +In medieval Latin a florilegium (plural florilegia) was a compilation of excerpts from other writings. + The word is from the Latin flos (flower) and legere (to gather): literally a gathering of flowers, or collection of fine extracts from the body of a larger work. ([via](https://en.wikipedia.org/wiki/Florilegium)) ^rwhi724352030 +``` + +Sample 3 +``` +This codeblock has a transclusion syntax in it. +Check it out: ![[001 Links]] +``` + +And for sanity, here's some block references outside of code blocks: foobar ^test-123 \ No newline at end of file diff --git a/src/test/snapshot/snapshot.md b/src/test/snapshot/snapshot.md index feb6017..da1293d 100644 --- a/src/test/snapshot/snapshot.md +++ b/src/test/snapshot/snapshot.md @@ -343,6 +343,55 @@ this is just text i guess --- +========== +015 Code blocks.md +========== +--- +{"dg-publish":true,"permalink":"/015-code-blocks/"} +--- + +These codeblocks should not be modified upon publish. + +Sample 1 +```jinja2 +{{ highlight_text }}{% if highlight_location and highlight_location_url %} ([via]({{highlight_location_url}})){% elif highlight_location %} ({{highlight_location}}){% endif %} ^rwhi{{highlight_id}} +{% if highlight_note %} +{{ highlight_note }} ^rwhi{{highlight_id}}-note +{% endif %} +``` + +Sample 2 +```md +In medieval Latin a florilegium (plural florilegia) was a compilation of excerpts from other writings. + The word is from the Latin flos (flower) and legere (to gather): literally a gathering of flowers, or collection of fine extracts from the body of a larger work. ([via](https://en.wikipedia.org/wiki/Florilegium)) ^rwhi724352030 +``` + +Sample 3 +``` +This codeblock has a transclusion syntax in it. +Check it out: +
+ +``` + +And for sanity, here's some block references outside of code blocks: foobar +{ #test-123} + ========== E Embeds/E02 PNG published.md ========== @@ -715,7 +764,7 @@ P Plugins/PD Dataview/PD3 Inline JS queries.md 3 -106 +108A paragraph
/img/user/A Assets/travolta.png