Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support of v10.48 todos implemented #438

Merged
merged 5 commits into from
Jan 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/YarleOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,5 @@ export interface YarleOptions {
turndownOptions?: Record<string, any>;
taskOutputFormat?: TaskOutputFormat;
obsidianTaskTag?: string;
useUniqueUnknownFileNames?: boolean;
useUniqueUnknownFileNames?: boolean;
}
2 changes: 1 addition & 1 deletion src/ui/settingsMapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
Expand Down
6 changes: 4 additions & 2 deletions src/utils/filename-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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, '')
;
};

Expand Down Expand Up @@ -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);
Expand All @@ -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;

};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/utils/templates/checker-functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 => {
Expand Down
4 changes: 2 additions & 2 deletions src/utils/templates/templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
applyReminderOrderTemplate,
applyReminderTimeTemplate,
applySourceUrlTemplate,
applyTagsArrayTemplate,
applyTagsArrayTemplate,
applyTagsTemplate,
applyTitleTemplate,
applyUpdatedAtTemplate,
Expand All @@ -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);

Expand Down
29 changes: 27 additions & 2 deletions src/utils/turndown-rules/task-list-rule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down
16 changes: 16 additions & 0 deletions test/data/test-checkboxes.enex
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE en-export SYSTEM "http://xml.evernote.com/pub/evernote-export4.dtd">
<en-export export-date="20230220T204656Z" application="Evernote" version="10.51.7">
<note>
<title>checkboxes</title>
<created>20230120T204520Z</created>
<updated>20230120T204630Z</updated>
<note-attributes>
<author>akos</author>
</note-attributes>
<content>
<![CDATA[<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd"><en-note><div><br /></div><ul style="--en-todo:true;"><li style="--en-checked:false;"><div> Checkbox not completed</div></li><li style="--en-checked:true;"><div>Checkbox done</div></li></ul></en-note> ]]>
</content>
</note>
</en-export>
8 changes: 8 additions & 0 deletions test/data/test-checkboxes.md
Original file line number Diff line number Diff line change
@@ -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

11 changes: 6 additions & 5 deletions test/data/test-checklist.enex
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE en-export SYSTEM "http://xml.evernote.com/pub/evernote-export4.dtd">
<en-export export-date="20210816T233721Z" application="Evernote" version="10.17.6">
<en-export export-date="20230221T101035Z" application="Evernote" version="10.52.8">
<note>
<title>test - checklist</title>
<created>20210714T004736Z</created>
<updated>20210716T233704Z</updated>
<title>test-checkbox.v10.48</title>
<created>20230121T093733Z</created>
<updated>20230121T101027Z</updated>
<note-attributes>
<author>akos</author>
</note-attributes>
<content>
<![CDATA[<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd"><en-note><ul style=""><li style=""><div><en-todo checked="false" />Checklist item 1</div></li><ul style=""><li style=""><div><en-todo checked="false" />Nested item 1a</div></li><li style=""><div><en-todo checked="true" />Nested item 1b is checked</div></li></ul><li style=""><div><en-todo checked="true" />Checklist item 2 is checked</div></li><ul><li style="--en-checked:false;"><div>Nested unordered 2a</div></li></ul><li style=""><div><en-todo checked="false" />Checklist item 3</div></li><ol><li style="--en-checked:false;"><div>Nested ordered 3a</div></li></ol></ul><div><br /></div><ul><li><div>Unordered list item</div></li><ul style=""><li style=""><div><en-todo checked="false" />Nested checklist item</div></li></ul></ul><div><br /></div><ul style=""><li style=""><div><en-todo checked="false" />Checklist <b>bold</b> <code style="--en-code: true">inline code</code> &amp; <a href="https://example.com?a=1&amp;b=2">link</a></div></li></ul><div><br /></div></en-note> ]]>
<!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd"><en-note><ul style="--en-todo:true;"><li style="--en-checked:false;"><div> Checklist item 1</div></li><ul style="--en-todo:true;"><li style="--en-checked:false;"><div>Nested item 1a</div></li><li style="--en-checked:true;"><div>Nested checked item</div></li></ul><li style="--en-checked:true;"><div>Checked checklist item 2</div></li><ul><li><div>Nested unordered 2a</div></li></ul><li style="--en-checked:false;"><div> Checklist item 3</div></li><ol><li><div>Nested ordered 3a</div></li></ol></ul><div><br /></div><ul><li><div>unordered item</div></li><ul style="--en-todo:true;"><li style="--en-checked:false;"><div> nested checklist</div></li></ul></ul><ul style="--en-todo:true;"><li style="--en-checked:false;"><div>Checklist <b>bold </b>and &amp; <a href="https://example.com/?a=1&amp;b=2">link</a></div></li></ul><div style="--en-codeblock:true;box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.14902); background-position: initial initial; background-repeat: initial initial;"><div>codeblock</div></div><div><br /></div></en-note> ]]>
</content>
</note>
</en-export>
26 changes: 15 additions & 11 deletions test/data/test-checklist.md
Original file line number Diff line number Diff line change
@@ -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

15 changes: 11 additions & 4 deletions test/yarle-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -469,10 +469,18 @@ export const yarleTests: Array<YarleTest> = [
},
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: {
Expand Down Expand Up @@ -525,8 +533,7 @@ export const yarleTests: Array<YarleTest> = [
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`,
},

Expand Down