You've already forked joplin
							
							
				mirror of
				https://github.com/laurent22/joplin.git
				synced 2025-10-31 00:07:48 +02:00 
			
		
		
		
	Desktop, Cli: Fixes #9483: Markdown-FrontMatter exporter generates invalid file when note starts with a dash in title
This commit is contained in:
		| @@ -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. | ||||
| @@ -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\''); | ||||
| 	})); | ||||
| }); | ||||
|   | ||||
| @@ -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'); | ||||
| } | ||||
|   | ||||
| @@ -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'); | ||||
| 	}); | ||||
| }); | ||||
|   | ||||
| @@ -97,7 +97,7 @@ export default class InteropService_Importer_Md_frontmatter extends InteropServi | ||||
|  | ||||
| 		const { header, body } = this.getNoteHeader(note); | ||||
|  | ||||
| 		const md: Record<string, any> = 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; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user