diff --git a/src/YarleOptions.ts b/src/YarleOptions.ts index 7836afc1..68e9c7f5 100644 --- a/src/YarleOptions.ts +++ b/src/YarleOptions.ts @@ -51,5 +51,5 @@ export interface YarleOptions { turndownOptions?: Record; taskOutputFormat?: TaskOutputFormat; obsidianTaskTag?: string; - useUniqueUnknownFileNames?: boolean; + useUniqueUnknownFileNames?: boolean; } diff --git a/src/ui/settingsMapper.ts b/src/ui/settingsMapper.ts index ec9511b7..efe53834 100644 --- a/src/ui/settingsMapper.ts +++ b/src/ui/settingsMapper.ts @@ -47,7 +47,7 @@ export const mapSettingsToYarleOptions = (): YarleOptions => { urlEncodeFileNamesAndLinks: store.get('urlEncodeFileNamesAndLinks') as boolean, haveEnexLevelResources: store.get('haveEnexLevelResources') as boolean, haveGlobalResources: store.get('haveGlobalResources') as boolean, - useUniqueUnknownFileNames: store.get('useUniqueUnknownFileNames') as boolean, + useUniqueUnknownFileNames: store.get('useUniqueUnknownFileNames') as boolean, sanitizeResourceNameSpaces: store.get('sanitizeResourceNameSpaces') as boolean, replacementChar: store.get('replacementChar') as string, }; diff --git a/src/utils/filename-utils.ts b/src/utils/filename-utils.ts index ff95172c..fecc456a 100644 --- a/src/utils/filename-utils.ts +++ b/src/utils/filename-utils.ts @@ -15,7 +15,7 @@ import { escapeStringRegexp } from './escape-string-regexp'; export const normalizeTitle = (title: string) => { // Allow setting a specific replacement character for file and resource names // Default to a retrocompatible value - return sanitize(title, {replacement: yarleOptions.replacementChar || '_'}).replace(/[\[\]\#\^]/g,'') + return sanitize(title, {replacement: yarleOptions.replacementChar || '_'}).replace(/[\[\]\#\^]/g, '') ; }; @@ -110,8 +110,9 @@ export const getNoteName = (dstPath: string, note: any): string => { `${zettelPrefix}.${nextIndex}` : zettelPrefix; - if (!yarleOptions.useZettelIdAsFilename) + if (!yarleOptions.useZettelIdAsFilename) { noteName += getFilePrefix(note) !== 'Untitled' ? `${separator}${getFilePrefix(note)}` : ''; + } } else { const fileNamePrefix = getFilePrefix(note); const nextIndex = getFileIndex(dstPath, fileNamePrefix); @@ -121,6 +122,7 @@ export const getNoteName = (dstPath: string, note: any): string => { if (yarleOptions.outputFormat === OutputFormat.LogSeqMD && yarleOptions.logseqSettings.journalNotes) { return getCreationTime(note); } + return noteName; }; diff --git a/src/utils/templates/apply-functions/apply-tags-array-template.ts b/src/utils/templates/apply-functions/apply-tags-array-template.ts index 4aed9eb9..0c345ba3 100644 --- a/src/utils/templates/apply-functions/apply-tags-array-template.ts +++ b/src/utils/templates/apply-functions/apply-tags-array-template.ts @@ -8,8 +8,9 @@ import { getTemplateBlockSettings } from './get-templateblock-settings'; export const applyTagsArrayTemplate = (noteData: NoteData, inputText: string, check: Function): string => { const result = cloneDeep(inputText); - if (noteData.tags) - noteData.tags = JSON.stringify(noteData.tags.split(' ')); + if (noteData.tags) { + noteData.tags = JSON.stringify(noteData.tags.split(' ')); + } const tagsTemplateSettings = getTemplateBlockSettings(result, check, P, noteData.tags); return applyTemplateOnBlock(tagsTemplateSettings); diff --git a/src/utils/templates/checker-functions.ts b/src/utils/templates/checker-functions.ts index 4d96f1bf..e83f0745 100644 --- a/src/utils/templates/checker-functions.ts +++ b/src/utils/templates/checker-functions.ts @@ -41,7 +41,7 @@ export const hasSourceURLInTemplate = (templateContent: string): boolean => { }; export const hasAnyTagsInTemplate = (templateContent: string): boolean => { return (hasItemInTemplate(TAGS, templateContent) - || hasItemInTemplate(YAMLARRAYTAGS, templateContent)); + || hasItemInTemplate(YAMLARRAYTAGS, templateContent)); }; export const hasMetadataInTemplate = (templateContent: string): boolean => { diff --git a/src/utils/templates/templates.ts b/src/utils/templates/templates.ts index 28a7a3ec..f8831fec 100644 --- a/src/utils/templates/templates.ts +++ b/src/utils/templates/templates.ts @@ -16,7 +16,7 @@ import { applyReminderOrderTemplate, applyReminderTimeTemplate, applySourceUrlTemplate, - applyTagsArrayTemplate, + applyTagsArrayTemplate, applyTagsTemplate, applyTitleTemplate, applyUpdatedAtTemplate, @@ -40,7 +40,7 @@ export const applyTemplate = (noteData: NoteData, yarleOptions: YarleOptions) => result = applyTitleTemplate(noteData, result, () => noteData.title); result = applyTagsTemplate(noteData, result, () => !yarleOptions.skipTags); - result = applyTagsArrayTemplate(noteData, result, () => !yarleOptions.skipTags); + result = applyTagsArrayTemplate(noteData, result, () => !yarleOptions.skipTags); result = applyContentTemplate(noteData, result, () => noteData.content); diff --git a/src/utils/turndown-rules/task-list-rule.ts b/src/utils/turndown-rules/task-list-rule.ts index 49a0c72c..3dc6337f 100644 --- a/src/utils/turndown-rules/task-list-rule.ts +++ b/src/utils/turndown-rules/task-list-rule.ts @@ -7,15 +7,40 @@ const indentCharacter = ' '; export const taskListRule = { filter: 'li', replacement: (content: any, node: any, options: any) => { + + const isTodoDoneBlock = (node: any) => { + const nodeProxy = getAttributeProxy(node); + const taskFlag = '--en-checked:true;'; + + return nodeProxy.style && nodeProxy.style.value.indexOf(taskFlag) >= 0; + }; + const isTodoBlock = (node: any) => { + const nodeProxy = getAttributeProxy(node); + const taskFlag = '--en-checked:false;'; + + return nodeProxy.style && nodeProxy.style.value.indexOf(taskFlag) >= 0; + }; + const indentCount = content.match(/^\n*/)[0].length || 0; + const indentChars = indentCharacter.repeat(indentCount); + + const todoPrefix = yarleOptions.outputFormat === OutputFormat.LogSeqMD ? '' : + node.parentElement?.nodeName?.toUpperCase() === 'LI' ? '' : `${indentChars}- `; + const singleLineContent = content .replace(/^\n+/, '') // Remove leading newlines .replace(/\n+$/, '\n') // Replace trailing newlines with just a single one .replace(/\n/gm, `\n${indentCharacter}`); // Indent - const indentChars = indentCharacter.repeat(indentCount); - let prefix = indentCount > 0 ? indentChars : '* '; + let prefix = indentCount > 0 + ? indentChars + : (isTodoDoneBlock(node) + ? '- [x] ' + : (isTodoBlock(node) + ? '- [ ] ' + :'* ')) + ; const parent = node.parentNode; if (parent.nodeName === 'OL') { const start = parent.getAttribute('start'); diff --git a/test/data/test-checkboxes.enex b/test/data/test-checkboxes.enex new file mode 100644 index 00000000..cb8d78d0 --- /dev/null +++ b/test/data/test-checkboxes.enex @@ -0,0 +1,16 @@ + + + + + checkboxes + 20230120T204520Z + 20230120T204630Z + + akos + + + +

  • Checkbox not completed
  • Checkbox done
]]> +
+
+
diff --git a/test/data/test-checkboxes.md b/test/data/test-checkboxes.md new file mode 100644 index 00000000..2a52c419 --- /dev/null +++ b/test/data/test-checkboxes.md @@ -0,0 +1,8 @@ +# checkboxes + +- [ ] Checkbox not completed +- [x] Checkbox done + + Created at: 2023-01-20T20:45:20+00:00 + Updated at: 2023-01-20T20:46:30+00:00 + diff --git a/test/data/test-checklist.enex b/test/data/test-checklist.enex index 8c4b97be..95d15448 100644 --- a/test/data/test-checklist.enex +++ b/test/data/test-checklist.enex @@ -1,15 +1,16 @@ - + - test - checklist - 20210714T004736Z - 20210716T233704Z + test-checkbox.v10.48 + 20230121T093733Z + 20230121T101027Z + akos -
  • Checklist item 1
    • Nested item 1a
    • Nested item 1b is checked
  • Checklist item 2 is checked
    • Nested unordered 2a
  • Checklist item 3
    1. Nested ordered 3a

  • Unordered list item
    • Nested checklist item

  • Checklist bold inline code & link

]]> +
  • Checklist item 1
    • Nested item 1a
    • Nested checked item
  • Checked checklist item 2
    • Nested unordered 2a
  • Checklist item 3
    1. Nested ordered 3a

  • unordered item
    • nested checklist
  • Checklist bold and & link
codeblock

]]>
diff --git a/test/data/test-checklist.md b/test/data/test-checklist.md index e43f5ced..e5318429 100644 --- a/test/data/test-checklist.md +++ b/test/data/test-checklist.md @@ -1,18 +1,22 @@ -# test - checklist +# test-checkbox.v10.48 -* [ ] Checklist item 1 - * [ ] Nested item 1a - * [x] Nested item 1b is checked -* [x] Checklist item 2 is checked +- [ ] Checklist item 1 + - [ ] Nested item 1a + - [x] Nested checked item +- [x] Checked checklist item 2 * Nested unordered 2a -* [ ] Checklist item 3 +- [ ] Checklist item 3 1. Nested ordered 3a -* Unordered list item - * [ ] Nested checklist item +* unordered item + - [ ] nested checklist -* [ ] Checklist **bold** `inline code` & [link](https://example.com?a=1&b=2) +- [ ] Checklist **bold** and & [link](https://example.com/?a=1&b=2) - Created at: 2021-07-14T01:47:36+01:00 - Updated at: 2021-07-17T00:37:04+01:00 +``` +codeblock +``` + + Created at: 2023-01-21T09:37:33+00:00 + Updated at: 2023-01-21T10:10:27+00:00 diff --git a/test/yarle-tests.ts b/test/yarle-tests.ts index 4a2f7044..a7aff784 100644 --- a/test/yarle-tests.ts +++ b/test/yarle-tests.ts @@ -469,10 +469,18 @@ export const yarleTests: Array = [ }, testOutputPath: `notes${path.sep}test-empty-en-todo${path.sep}test-empty-en-todo.md`, - testModifier: YarleTestModifierOptions.only, expectedOutputPath: `${dataFolder}test-empty-en-todo.md`, }, - + { + name: 'Note checkboxes', + options: { + enexSources: [ `.${testDataFolder}test-checkboxes.enex` ], + outputDir: 'out', + isMetadataNeeded: true, + }, + testOutputPath: `notes${path.sep}test-checkboxes${path.sep}checkboxes.md`, + expectedOutputPath: `${dataFolder}test-checkboxes.md`, + }, { name: 'Note with sublists (valid html)', options: { @@ -525,8 +533,7 @@ export const yarleTests: Array = [ outputDir: 'out', isMetadataNeeded: true, }, - testOutputPath: `notes${path.sep}test-checklist${path.sep}test - checklist.md`, - + testOutputPath: `notes${path.sep}test-checklist${path.sep}test-checkbox.v10.48.md`, expectedOutputPath: `${dataFolder}test-checklist.md`, },