From c333e9c8026334ae71ef94d0fd094fce79f44008 Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Fri, 15 Dec 2023 11:53:44 +0000 Subject: [PATCH] Desktop, Cli: Fixes #9483: Markdown-FrontMatter exporter generates invalid file when note starts with a dash in title --- .../support/test_notes/yaml/title_start_with_dash.md | 5 +++++ .../InteropService_Exporter_Md_frontmatter.test.ts | 8 ++++++++ .../interop/InteropService_Exporter_Md_frontmatter.ts | 9 +++++++++ .../InteropService_Importer_Md_frontmatter.test.ts | 5 +++++ .../interop/InteropService_Importer_Md_frontmatter.ts | 4 ++-- 5 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 packages/app-cli/tests/support/test_notes/yaml/title_start_with_dash.md diff --git a/packages/app-cli/tests/support/test_notes/yaml/title_start_with_dash.md b/packages/app-cli/tests/support/test_notes/yaml/title_start_with_dash.md new file mode 100644 index 000000000..15a395d50 --- /dev/null +++ b/packages/app-cli/tests/support/test_notes/yaml/title_start_with_dash.md @@ -0,0 +1,5 @@ +--- +Title: -Start with dash +--- + +This note title starts with a dash and is not quoted. It should still work and not be detected as a list item. \ No newline at end of file diff --git a/packages/lib/services/interop/InteropService_Exporter_Md_frontmatter.test.ts b/packages/lib/services/interop/InteropService_Exporter_Md_frontmatter.test.ts index 1087118d4..016a666b5 100644 --- a/packages/lib/services/interop/InteropService_Exporter_Md_frontmatter.test.ts +++ b/packages/lib/services/interop/InteropService_Exporter_Md_frontmatter.test.ts @@ -142,4 +142,12 @@ describe('interop/InteropService_Exporter_Md_frontmatter', () => { const content = await exportAndLoad(`${exportDir()}/folder1/NoTag.md`); expect(content).not.toContain('tag'); })); + + test('should export a valid file when the title starts with a dash', (async () => { + const folder1 = await Folder.save({ title: 'folder1' }); + await Note.save({ title: '- title with dash', body: '**ma note**', parent_id: folder1.id }); + + const content = await exportAndLoad(`${exportDir()}/folder1/- title with dash.md`); + expect(content).toContain('title: \'- title with dash\''); + })); }); diff --git a/packages/lib/services/interop/InteropService_Exporter_Md_frontmatter.ts b/packages/lib/services/interop/InteropService_Exporter_Md_frontmatter.ts index c713e1e85..6d5939f62 100644 --- a/packages/lib/services/interop/InteropService_Exporter_Md_frontmatter.ts +++ b/packages/lib/services/interop/InteropService_Exporter_Md_frontmatter.ts @@ -24,6 +24,14 @@ interface FrontMatterContext extends NoteTagContext, TagContext {} function trimQuotes(rawOutput: string): string { return rawOutput.split('\n').map(line => { const index = line.indexOf(': \'-'); + const indexWithSpace = line.indexOf(': \'- '); + + // We don't apply this processing if the string starts with a dash + // followed by a space. Those should actually be in quotes, otherwise + // they are detected as invalid list items when we later try to import + // the file. + if (index === indexWithSpace) return line; + if (index >= 0) { // The plus 2 eats the : and space characters const start = line.substring(0, index + 2); @@ -31,6 +39,7 @@ function trimQuotes(rawOutput: string): string { const end = line.substring(index + 3, line.length - 1); return start + end; } + return line; }).join('\n'); } diff --git a/packages/lib/services/interop/InteropService_Importer_Md_frontmatter.test.ts b/packages/lib/services/interop/InteropService_Importer_Md_frontmatter.test.ts index c66152968..56cdc69c0 100644 --- a/packages/lib/services/interop/InteropService_Importer_Md_frontmatter.test.ts +++ b/packages/lib/services/interop/InteropService_Importer_Md_frontmatter.test.ts @@ -155,4 +155,9 @@ describe('InteropService_Importer_Md_frontmatter: importMetadata', () => { const note = await importTestFile('multiple_newlines_after_marker.md'); expect(note.body).toBe('\n\nnote body'); }); + + it('should accept note with a title that starts with a dash', async () => { + const note = await importTestFile('title_start_with_dash.md'); + expect(note.title).toBe('-Start with dash'); + }); }); diff --git a/packages/lib/services/interop/InteropService_Importer_Md_frontmatter.ts b/packages/lib/services/interop/InteropService_Importer_Md_frontmatter.ts index b666440d0..5711d2417 100644 --- a/packages/lib/services/interop/InteropService_Importer_Md_frontmatter.ts +++ b/packages/lib/services/interop/InteropService_Importer_Md_frontmatter.ts @@ -97,7 +97,7 @@ export default class InteropService_Importer_Md_frontmatter extends InteropServi const { header, body } = this.getNoteHeader(note); - const md: Record = this.toLowerCase(yaml.load(header, { schema: yaml.FAILSAFE_SCHEMA })); + const md = this.toLowerCase(yaml.load(header, { schema: yaml.FAILSAFE_SCHEMA })); const metadata: NoteEntity = { title: md['title'] || '', source_url: md['source'] || '', @@ -148,7 +148,7 @@ export default class InteropService_Importer_Md_frontmatter extends InteropServi } // Only create unique tags - tags = [...new Set(tags)] as string[]; + tags = [...new Set(tags)]; metadata['body'] = body;