@notatki/core 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/export/anki.d.ts +6 -0
- package/dist/export/anki.d.ts.map +1 -0
- package/dist/export/anki.js +7 -0
- package/dist/export/anki.js.map +1 -0
- package/dist/export/csv.d.ts +6 -0
- package/dist/export/csv.d.ts.map +1 -0
- package/dist/{export-notes.js → export/csv.js} +9 -7
- package/dist/export/csv.js.map +1 -0
- package/dist/export/json.d.ts +31 -0
- package/dist/export/json.d.ts.map +1 -0
- package/dist/export/json.js +41 -0
- package/dist/export/json.js.map +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/insert-note-id.js.map +1 -1
- package/dist/model.d.ts +6 -6
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +5 -5
- package/dist/model.js.map +1 -1
- package/dist/nodes.d.ts +11 -0
- package/dist/nodes.d.ts.map +1 -1
- package/dist/nodes.js +47 -0
- package/dist/nodes.js.map +1 -1
- package/dist/note-parser.js +1 -1
- package/dist/note-parser.js.map +1 -1
- package/dist/note.d.ts +0 -2
- package/dist/note.d.ts.map +1 -1
- package/dist/note.js +0 -29
- package/dist/note.js.map +1 -1
- package/dist/output.js.map +1 -1
- package/dist/print-model-nodes.js +4 -4
- package/dist/print-model-nodes.js.map +1 -1
- package/dist/print-note-nodes.js.map +1 -1
- package/dist/reformat-model-nodes.js.map +1 -1
- package/dist/reformat-note-nodes.js.map +1 -1
- package/package.json +5 -4
- package/dist/export-notes.d.ts +0 -3
- package/dist/export-notes.d.ts.map +0 -1
- package/dist/export-notes.js.map +0 -1
- package/src/export-notes.ts +0 -31
- package/src/index.ts +0 -10
- package/src/insert-note-id.ts +0 -23
- package/src/model.ts +0 -155
- package/src/nodes.ts +0 -7
- package/src/note-parser.ts +0 -277
- package/src/note.ts +0 -189
- package/src/output.ts +0 -27
- package/src/print-model-nodes.ts +0 -39
- package/src/print-note-nodes.ts +0 -31
- package/src/reformat-model-nodes.ts +0 -5
- package/src/reformat-note-nodes.ts +0 -34
|
@@ -2,7 +2,7 @@ import {} from "@notatki/parser";
|
|
|
2
2
|
import { Output } from "./output.js";
|
|
3
3
|
export function printModelNodes(nodes) {
|
|
4
4
|
const out = new Output();
|
|
5
|
-
for (const { name, id, cloze, fields, cards,
|
|
5
|
+
for (const { name, id, cloze, fields, cards, styles } of nodes) {
|
|
6
6
|
out.separate();
|
|
7
7
|
out.print(`model ${name.text}`);
|
|
8
8
|
out.separate();
|
|
@@ -28,9 +28,9 @@ export function printModelNodes(nodes) {
|
|
|
28
28
|
out.print("~~~");
|
|
29
29
|
out.separate();
|
|
30
30
|
}
|
|
31
|
-
if (
|
|
32
|
-
out.print("
|
|
33
|
-
out.print(
|
|
31
|
+
if (styles != null) {
|
|
32
|
+
out.print("styles");
|
|
33
|
+
out.print(styles.text);
|
|
34
34
|
out.print("~~~");
|
|
35
35
|
}
|
|
36
36
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"print-model-nodes.js","sourceRoot":"","sources":["../src/print-model-nodes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,MAAM,UAAU,eAAe,CAAC,KAA0B;IACxD,MAAM,GAAG,GAAG,IAAI,MAAM,EAAE,CAAC;IACzB,KAAK,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"print-model-nodes.js","sourceRoot":"","sources":["../src/print-model-nodes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,MAAM,UAAU,eAAe,CAAC,KAA0B;IACxD,MAAM,GAAG,GAAG,IAAI,MAAM,EAAE,CAAC;IACzB,KAAK,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,KAAK,EAAE,CAAC;QAC/D,GAAG,CAAC,QAAQ,EAAE,CAAC;QACf,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAChC,GAAG,CAAC,QAAQ,EAAE,CAAC;QACf,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC;QAC5B,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;YAClB,GAAG,CAAC,QAAQ,EAAE,CAAC;YACf,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACrB,CAAC;QACD,GAAG,CAAC,QAAQ,EAAE,CAAC;QACf,KAAK,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,MAAM,EAAE,CAAC;YACxC,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;QACxD,CAAC;QACD,GAAG,CAAC,QAAQ,EAAE,CAAC;QACf,KAAK,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,KAAK,EAAE,CAAC;YAC1C,GAAG,CAAC,KAAK,CAAC,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;YAC/B,GAAG,CAAC,QAAQ,EAAE,CAAC;YACf,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACnB,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACtB,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACjB,GAAG,CAAC,QAAQ,EAAE,CAAC;YACf,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAClB,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACrB,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACjB,GAAG,CAAC,QAAQ,EAAE,CAAC;QACjB,CAAC;QACD,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;YACnB,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YACpB,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACvB,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;AACrB,CAAC","sourcesContent":["import { type ModelNode } from \"@notatki/parser\";\nimport { Output } from \"./output.js\";\n\nexport function printModelNodes(nodes: Iterable<ModelNode>): string {\n const out = new Output();\n for (const { name, id, cloze, fields, cards, styles } of nodes) {\n out.separate();\n out.print(`model ${name.text}`);\n out.separate();\n out.print(`id ${id.value}`);\n if (cloze != null) {\n out.separate();\n out.print(\"cloze\");\n }\n out.separate();\n for (const { name, required } of fields) {\n out.print(`field ${name.text}${required ? \"\" : \"?\"}`);\n }\n out.separate();\n for (const { name, front, back } of cards) {\n out.print(`card ${name.text}`);\n out.separate();\n out.print(\"front\");\n out.print(front.text);\n out.print(\"~~~\");\n out.separate();\n out.print(\"back\");\n out.print(back.text);\n out.print(\"~~~\");\n out.separate();\n }\n if (styles != null) {\n out.print(\"styles\");\n out.print(styles.text);\n out.print(\"~~~\");\n }\n }\n return String(out);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"print-note-nodes.js","sourceRoot":"","sources":["../src/print-note-nodes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,MAAM,UAAU,cAAc,CAAC,KAAyB;IACtD,MAAM,GAAG,GAAG,IAAI,MAAM,EAAE,CAAC;IACzB,KAAK,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,KAAK,EAAE,CAAC;QAChD,GAAG,CAAC,QAAQ,EAAE,CAAC;QACf,KAAK,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,UAAU,EAAE,CAAC;YACzC,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;gBACf,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;YAC5C,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC;QACD,GAAG,CAAC,QAAQ,EAAE,CAAC;QACf,KAAK,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,MAAM,EAAE,CAAC;YACrC,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;gBACf,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC9B,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;oBAC5B,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACxB,CAAC;qBAAM,CAAC;oBACN,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;gBAC5C,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC;QACD,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC;IACD,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;AACrB,CAAC"}
|
|
1
|
+
{"version":3,"file":"print-note-nodes.js","sourceRoot":"","sources":["../src/print-note-nodes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,MAAM,UAAU,cAAc,CAAC,KAAyB;IACtD,MAAM,GAAG,GAAG,IAAI,MAAM,EAAE,CAAC;IACzB,KAAK,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,KAAK,EAAE,CAAC;QAChD,GAAG,CAAC,QAAQ,EAAE,CAAC;QACf,KAAK,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,UAAU,EAAE,CAAC;YACzC,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;gBACf,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;YAC5C,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC;QACD,GAAG,CAAC,QAAQ,EAAE,CAAC;QACf,KAAK,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,MAAM,EAAE,CAAC;YACrC,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;gBACf,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC9B,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;oBAC5B,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACxB,CAAC;qBAAM,CAAC;oBACN,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;gBAC5C,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC;QACD,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC;IACD,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;AACrB,CAAC","sourcesContent":["import { type NoteNode } from \"@notatki/parser\";\nimport { Output } from \"./output.js\";\n\nexport function printNoteNodes(nodes: Iterable<NoteNode>): string {\n const out = new Output();\n for (const { properties, fields, end } of nodes) {\n out.separate();\n for (const { name, value } of properties) {\n if (value.text) {\n out.print(`!${name.text}: ${value.text}`);\n } else {\n out.print(`!${name.text}:`);\n }\n }\n out.separate();\n for (const { name, value } of fields) {\n if (value.text) {\n if (value.text.includes(\"\\n\")) {\n out.print(`!${name.text}:`);\n out.print(value.text);\n } else {\n out.print(`!${name.text}: ${value.text}`);\n }\n } else {\n out.print(`!${name.text}:`);\n }\n }\n out.print(end.text);\n }\n return String(out);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reformat-model-nodes.js","sourceRoot":"","sources":["../src/reformat-model-nodes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,MAAM,iBAAiB,CAAC;AAEjD,MAAM,UAAU,kBAAkB,CAAC,KAA0B;IAC3D,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC;AACpB,CAAC"}
|
|
1
|
+
{"version":3,"file":"reformat-model-nodes.js","sourceRoot":"","sources":["../src/reformat-model-nodes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,MAAM,iBAAiB,CAAC;AAEjD,MAAM,UAAU,kBAAkB,CAAC,KAA0B;IAC3D,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC;AACpB,CAAC","sourcesContent":["import { type ModelNode } from \"@notatki/parser\";\n\nexport function reformatModelNodes(nodes: Iterable<ModelNode>): ModelNode[] {\n return [...nodes];\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reformat-note-nodes.js","sourceRoot":"","sources":["../src/reformat-note-nodes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgE,MAAM,iBAAiB,CAAC;AAC/F,OAAO,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAEjC,MAAM,UAAU,iBAAiB,CAAC,KAAyB;IACzD,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;AACrC,CAAC;AAED,SAAS,WAAW,CAAC,IAAc;IACjC,OAAO;QACL,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,eAAe,CAAC;QAChD,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC;QACrC,GAAG,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE;QACzB,GAAG;KACJ,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,EAAE,IAAI,EAAE,KAAK,EAAgB;IACpD,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC;QAClB,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE;QAChC,GAAG;KACJ,CAAC;AACJ,CAAC;AACD,SAAS,YAAY,CAAC,EAAE,IAAI,EAAE,KAAK,EAAa;IAC9C,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC;QAClB,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE;QAChC,GAAG;KACJ,CAAC;AACJ,CAAC;AAED,SAAS,MAAM,CAAC,EAAE,IAAI,EAAS;IAC7B,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,EAAE,GAAG,EAAE,CAAC;AAC3C,CAAC"}
|
|
1
|
+
{"version":3,"file":"reformat-note-nodes.js","sourceRoot":"","sources":["../src/reformat-note-nodes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgE,MAAM,iBAAiB,CAAC;AAC/F,OAAO,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAEjC,MAAM,UAAU,iBAAiB,CAAC,KAAyB;IACzD,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;AACrC,CAAC;AAED,SAAS,WAAW,CAAC,IAAc;IACjC,OAAO;QACL,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,eAAe,CAAC;QAChD,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC;QACrC,GAAG,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE;QACzB,GAAG;KACJ,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,EAAE,IAAI,EAAE,KAAK,EAAgB;IACpD,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC;QAClB,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE;QAChC,GAAG;KACJ,CAAC;AACJ,CAAC;AACD,SAAS,YAAY,CAAC,EAAE,IAAI,EAAE,KAAK,EAAa;IAC9C,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC;QAClB,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE;QAChC,GAAG;KACJ,CAAC;AACJ,CAAC;AAED,SAAS,MAAM,CAAC,EAAE,IAAI,EAAS;IAC7B,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,EAAE,GAAG,EAAE,CAAC;AAC3C,CAAC","sourcesContent":["import { type FieldNode, type NoteNode, type PropertyNode, type Token } from \"@notatki/parser\";\nimport { loc } from \"./nodes.js\";\n\nexport function reformatNoteNodes(nodes: Iterable<NoteNode>): NoteNode[] {\n return [...nodes].map(mapNoteNode);\n}\n\nfunction mapNoteNode(node: NoteNode): NoteNode {\n return {\n properties: node.properties.map(mapPropertyNode),\n fields: node.fields.map(mapFieldNode),\n end: { text: \"~~~\", loc },\n loc,\n };\n}\n\nfunction mapPropertyNode({ name, value }: PropertyNode): PropertyNode {\n return {\n name: nameOf(name),\n value: { text: value.text, loc },\n loc,\n };\n}\nfunction mapFieldNode({ name, value }: FieldNode): FieldNode {\n return {\n name: nameOf(name),\n value: { text: value.text, loc },\n loc,\n };\n}\n\nfunction nameOf({ text }: Token): Token {\n return { text: text.toLowerCase(), loc };\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@notatki/core",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "A collection of tools for creating and syncing Anki notes from simple text files.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"anki",
|
|
@@ -15,11 +15,12 @@
|
|
|
15
15
|
"type": "git",
|
|
16
16
|
"url": "git+https://github.com/aradzie/notatki.git"
|
|
17
17
|
},
|
|
18
|
+
"license": "MIT",
|
|
18
19
|
"type": "module",
|
|
19
20
|
"main": "dist/index.js",
|
|
20
21
|
"dependencies": {
|
|
21
|
-
"@notatki/format": "^0.0.
|
|
22
|
-
"@notatki/parser": "^0.0.
|
|
22
|
+
"@notatki/format": "^0.0.4",
|
|
23
|
+
"@notatki/parser": "^0.0.4"
|
|
23
24
|
},
|
|
24
25
|
"scripts": {
|
|
25
26
|
"compile": "rm -fr dist && tsc",
|
|
@@ -29,5 +30,5 @@
|
|
|
29
30
|
"publishConfig": {
|
|
30
31
|
"access": "public"
|
|
31
32
|
},
|
|
32
|
-
"gitHead": "
|
|
33
|
+
"gitHead": "b2237839f8310ecbb0b05de29dcfe5571b1d786c"
|
|
33
34
|
}
|
package/dist/export-notes.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"export-notes.d.ts","sourceRoot":"","sources":["../src/export-notes.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,WAAW,CAAC;AAEtC,wBAAgB,WAAW,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,MAAM,CAiBzD"}
|
package/dist/export-notes.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"export-notes.js","sourceRoot":"","sources":["../src/export-notes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAa,MAAM,WAAW,CAAC;AAEtC,MAAM,UAAU,WAAW,CAAC,KAAqB;IAC/C,MAAM,KAAK,GAAG,EAAE,CAAC;IACjB,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IACnC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACzB,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC7B,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IACjC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC7B,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC7B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,KAAK,CAAC,IAAI,CACR,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;aACjG,GAAG,CAAC,MAAM,CAAC;aACX,IAAI,CAAC,GAAG,CAAC,CACb,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,MAAM,CAAC,KAAoB;IAClC,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;QAClB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACvE,OAAO,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC;IAC5C,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
package/src/export-notes.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { formatField } from "@notatki/format";
|
|
2
|
-
import { type Note } from "./note.js";
|
|
3
|
-
|
|
4
|
-
export function exportNotes(notes: Iterable<Note>): string {
|
|
5
|
-
const lines = [];
|
|
6
|
-
lines.push(`#separator:semicolon`);
|
|
7
|
-
lines.push(`#html:true`);
|
|
8
|
-
lines.push(`#guid column:1`);
|
|
9
|
-
lines.push(`#notetype column:2`);
|
|
10
|
-
lines.push(`#deck column:3`);
|
|
11
|
-
lines.push(`#tags column:4`);
|
|
12
|
-
for (const note of notes) {
|
|
13
|
-
lines.push(
|
|
14
|
-
[note.id, note.type.name, note.deck, note.tags, ...[...note].map(({ value }) => formatField(value))]
|
|
15
|
-
.map(escape)
|
|
16
|
-
.join(";"),
|
|
17
|
-
);
|
|
18
|
-
}
|
|
19
|
-
lines.push("");
|
|
20
|
-
return lines.join("\n");
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function escape(value: string | null): string {
|
|
24
|
-
if (value == null) {
|
|
25
|
-
return "";
|
|
26
|
-
}
|
|
27
|
-
if (value.includes(";") || value.includes("\n") || value.includes('"')) {
|
|
28
|
-
return `"${value.replaceAll('"', '""')}"`;
|
|
29
|
-
}
|
|
30
|
-
return value;
|
|
31
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export * from "./export-notes.js";
|
|
2
|
-
export * from "./insert-note-id.js";
|
|
3
|
-
export * from "./model.js";
|
|
4
|
-
export * from "./note.js";
|
|
5
|
-
export * from "./note-parser.js";
|
|
6
|
-
export * from "./output.js";
|
|
7
|
-
export * from "./print-model-nodes.js";
|
|
8
|
-
export * from "./print-note-nodes.js";
|
|
9
|
-
export * from "./reformat-model-nodes.js";
|
|
10
|
-
export * from "./reformat-note-nodes.js";
|
package/src/insert-note-id.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { type NoteNode } from "@notatki/parser";
|
|
2
|
-
import { loc } from "./nodes.js";
|
|
3
|
-
import { Note } from "./note.js";
|
|
4
|
-
|
|
5
|
-
export type IdGenerator = () => string;
|
|
6
|
-
|
|
7
|
-
export const idGenerator: IdGenerator = () => crypto.randomUUID();
|
|
8
|
-
|
|
9
|
-
export function insertNoteId(nodes: NoteNode[], gen: IdGenerator = idGenerator): boolean {
|
|
10
|
-
let changed = false;
|
|
11
|
-
for (const node of nodes) {
|
|
12
|
-
let field = node.fields.find(({ name }) => Note.isIdField(name.text));
|
|
13
|
-
if (field == null) {
|
|
14
|
-
node.fields.unshift((field = { name: { text: "id", loc }, value: { text: "", loc }, loc }));
|
|
15
|
-
}
|
|
16
|
-
const { value } = field;
|
|
17
|
-
if (!value.text) {
|
|
18
|
-
value.text = gen();
|
|
19
|
-
changed = true;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
return changed;
|
|
23
|
-
}
|
package/src/model.ts
DELETED
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
export type Model = {
|
|
2
|
-
readonly name: string;
|
|
3
|
-
readonly id: number;
|
|
4
|
-
readonly cloze: boolean;
|
|
5
|
-
readonly fields: readonly ModelField[];
|
|
6
|
-
readonly cards: readonly ModelCard[];
|
|
7
|
-
readonly styling: string;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export type ModelField = {
|
|
11
|
-
readonly name: string;
|
|
12
|
-
readonly required: boolean;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export type ModelCard = {
|
|
16
|
-
readonly name: string;
|
|
17
|
-
readonly front: string;
|
|
18
|
-
readonly back: string;
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
export class ModelMap implements Iterable<Model> {
|
|
22
|
-
static readonly basic = {
|
|
23
|
-
name: "Basic",
|
|
24
|
-
id: 1607392319,
|
|
25
|
-
cloze: false,
|
|
26
|
-
fields: [
|
|
27
|
-
{ name: "Front", required: true },
|
|
28
|
-
{ name: "Back", required: true },
|
|
29
|
-
],
|
|
30
|
-
cards: [
|
|
31
|
-
{
|
|
32
|
-
name: "Card 1",
|
|
33
|
-
front: "{{Front}}",
|
|
34
|
-
back: "{{FrontSide}}<hr>{{Back}}",
|
|
35
|
-
},
|
|
36
|
-
],
|
|
37
|
-
styling: "",
|
|
38
|
-
} as const satisfies Model;
|
|
39
|
-
|
|
40
|
-
static readonly basicAndReversedCard = {
|
|
41
|
-
name: "Basic (and reversed card)",
|
|
42
|
-
id: 1607392320,
|
|
43
|
-
cloze: false,
|
|
44
|
-
fields: [
|
|
45
|
-
{ name: "Front", required: true },
|
|
46
|
-
{ name: "Back", required: true },
|
|
47
|
-
],
|
|
48
|
-
cards: [
|
|
49
|
-
{
|
|
50
|
-
name: "Card 1",
|
|
51
|
-
front: "{{Front}}",
|
|
52
|
-
back: "{{FrontSide}}<hr>{{Back}}",
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
name: "Card 2",
|
|
56
|
-
front: "{{Back}}",
|
|
57
|
-
back: "{{FrontSide}}<hr>{{Front}}",
|
|
58
|
-
},
|
|
59
|
-
],
|
|
60
|
-
styling: "",
|
|
61
|
-
} as const satisfies Model;
|
|
62
|
-
|
|
63
|
-
static readonly basicOptionalReversedCard = {
|
|
64
|
-
name: "Basic (optional reversed card)",
|
|
65
|
-
id: 1607392321,
|
|
66
|
-
cloze: false,
|
|
67
|
-
fields: [
|
|
68
|
-
{ name: "Front", required: true },
|
|
69
|
-
{ name: "Back", required: true },
|
|
70
|
-
{ name: "Add Reverse", required: false },
|
|
71
|
-
],
|
|
72
|
-
cards: [
|
|
73
|
-
{
|
|
74
|
-
name: "Card 1",
|
|
75
|
-
front: "{{Front}}",
|
|
76
|
-
back: "{{FrontSide}}<hr>{{Back}}",
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
name: "Card 2",
|
|
80
|
-
front: "{{#Add Reverse}}{{Back}}{{/Add Reverse}}",
|
|
81
|
-
back: "{{FrontSide}}<hr>{{Front}}",
|
|
82
|
-
},
|
|
83
|
-
],
|
|
84
|
-
styling: "",
|
|
85
|
-
} as const satisfies Model;
|
|
86
|
-
|
|
87
|
-
static readonly basicTypeInAnswer = {
|
|
88
|
-
name: "Basic (type in the answer)",
|
|
89
|
-
id: 1607392322,
|
|
90
|
-
cloze: false,
|
|
91
|
-
fields: [
|
|
92
|
-
{ name: "Front", required: true },
|
|
93
|
-
{ name: "Back", required: true },
|
|
94
|
-
],
|
|
95
|
-
cards: [
|
|
96
|
-
{
|
|
97
|
-
name: "Card 1",
|
|
98
|
-
front: "{{Front}}<br>{{type:Back}}",
|
|
99
|
-
back: "{{Front}}<hr>{{Back}}",
|
|
100
|
-
},
|
|
101
|
-
],
|
|
102
|
-
styling: "",
|
|
103
|
-
} as const satisfies Model;
|
|
104
|
-
|
|
105
|
-
static readonly cloze = {
|
|
106
|
-
name: "Cloze",
|
|
107
|
-
id: 1607392323,
|
|
108
|
-
cloze: true,
|
|
109
|
-
fields: [
|
|
110
|
-
{ name: "Text", required: true },
|
|
111
|
-
{ name: "Back Extra", required: false },
|
|
112
|
-
],
|
|
113
|
-
cards: [
|
|
114
|
-
{
|
|
115
|
-
name: "Cloze",
|
|
116
|
-
front: "{{cloze:Text}}",
|
|
117
|
-
back: "{{cloze:Text}}<br>{{Back Extra}}",
|
|
118
|
-
},
|
|
119
|
-
],
|
|
120
|
-
styling: "",
|
|
121
|
-
} as const satisfies Model;
|
|
122
|
-
|
|
123
|
-
static readonly internal: readonly Model[] = [
|
|
124
|
-
ModelMap.basic,
|
|
125
|
-
ModelMap.basicAndReversedCard,
|
|
126
|
-
ModelMap.basicOptionalReversedCard,
|
|
127
|
-
ModelMap.basicTypeInAnswer,
|
|
128
|
-
ModelMap.cloze,
|
|
129
|
-
];
|
|
130
|
-
|
|
131
|
-
readonly #map = new Map<string, Model>();
|
|
132
|
-
|
|
133
|
-
constructor(initial: Iterable<Model> = ModelMap.internal) {
|
|
134
|
-
for (const model of initial) {
|
|
135
|
-
this.add(model);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
[Symbol.iterator](): Iterator<Model> {
|
|
140
|
-
return this.#map.values();
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
add(model: Model): this {
|
|
144
|
-
this.#map.set(model.name.toLowerCase(), model);
|
|
145
|
-
return this;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
has(name: string): boolean {
|
|
149
|
-
return this.#map.has(name.toLowerCase());
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
get(name: string): Model | null {
|
|
153
|
-
return this.#map.get(name.toLowerCase()) ?? null;
|
|
154
|
-
}
|
|
155
|
-
}
|
package/src/nodes.ts
DELETED
package/src/note-parser.ts
DELETED
|
@@ -1,277 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type LocationRange,
|
|
3
|
-
type ModelNode,
|
|
4
|
-
type NoteNode,
|
|
5
|
-
parseModelList,
|
|
6
|
-
parseNoteList,
|
|
7
|
-
SyntaxError,
|
|
8
|
-
type Token,
|
|
9
|
-
} from "@notatki/parser";
|
|
10
|
-
import { type Model, type ModelCard, type ModelField, ModelMap } from "./model.js";
|
|
11
|
-
import { Note, NoteList } from "./note.js";
|
|
12
|
-
|
|
13
|
-
const unknown = {
|
|
14
|
-
source: "<unknown>",
|
|
15
|
-
start: { offset: 0, line: 0, column: 0 },
|
|
16
|
-
end: { offset: 0, line: 0, column: 0 },
|
|
17
|
-
} as const satisfies LocationRange;
|
|
18
|
-
|
|
19
|
-
export type NoteError = {
|
|
20
|
-
message: string;
|
|
21
|
-
location: LocationRange;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
export class ParseError extends Error {
|
|
25
|
-
errors: readonly NoteError[];
|
|
26
|
-
|
|
27
|
-
constructor(errors: Iterable<NoteError>) {
|
|
28
|
-
super();
|
|
29
|
-
this.name = "ParseError";
|
|
30
|
-
this.message = "Note parsing error";
|
|
31
|
-
this.errors = [...errors];
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
type ParseState = {
|
|
36
|
-
type: Model;
|
|
37
|
-
deck: string;
|
|
38
|
-
tags: string;
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
export class NoteParser {
|
|
42
|
-
readonly #notes: NoteList;
|
|
43
|
-
readonly #errors: NoteError[];
|
|
44
|
-
|
|
45
|
-
constructor(notes = new NoteList()) {
|
|
46
|
-
this.#notes = notes;
|
|
47
|
-
this.#errors = [];
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
get notes(): NoteList {
|
|
51
|
-
return this.#notes;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
get errors(): readonly NoteError[] {
|
|
55
|
-
return this.#errors;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
checkErrors(): void | never {
|
|
59
|
-
if (this.#errors.length > 0) {
|
|
60
|
-
throw new ParseError(this.#errors);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
checkDuplicates() {
|
|
65
|
-
const byId = new Map<string, Note[]>();
|
|
66
|
-
const byTitle = new Map<string, Note[]>();
|
|
67
|
-
for (const note of this.#notes) {
|
|
68
|
-
const { id } = note;
|
|
69
|
-
if (id) {
|
|
70
|
-
let list = byId.get(id);
|
|
71
|
-
if (list == null) {
|
|
72
|
-
byId.set(id, (list = []));
|
|
73
|
-
}
|
|
74
|
-
list.push(note);
|
|
75
|
-
}
|
|
76
|
-
const { value } = note.first;
|
|
77
|
-
const title = value.trim().replaceAll(/\s+/g, " ");
|
|
78
|
-
if (title) {
|
|
79
|
-
let list = byTitle.get(title);
|
|
80
|
-
if (list == null) {
|
|
81
|
-
byTitle.set(title, (list = []));
|
|
82
|
-
}
|
|
83
|
-
list.push(note);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
for (const [key, list] of byId) {
|
|
87
|
-
if (list.length > 1) {
|
|
88
|
-
for (const note of list) {
|
|
89
|
-
const { node } = note.get("id");
|
|
90
|
-
this.#errors.push({ message: `Duplicate ID: "${key}"`, location: node?.value.loc ?? unknown });
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
for (const [key, list] of byTitle) {
|
|
95
|
-
if (list.length > 1) {
|
|
96
|
-
for (const note of list) {
|
|
97
|
-
const { node } = note.first;
|
|
98
|
-
this.#errors.push({ message: `Duplicate note: "${key}"`, location: node?.value.loc ?? unknown });
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
parseModels(path: string, text: string): this {
|
|
105
|
-
this.walkModelNodes(this.parseModelNodes(path, text));
|
|
106
|
-
return this;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
parseModelNodes(path: string, text: string): ModelNode[] {
|
|
110
|
-
try {
|
|
111
|
-
return parseModelList(text, path);
|
|
112
|
-
} catch (err) {
|
|
113
|
-
if (err instanceof SyntaxError) {
|
|
114
|
-
const { message, location } = err;
|
|
115
|
-
this.#errors.push({ message, location });
|
|
116
|
-
} else {
|
|
117
|
-
throw err;
|
|
118
|
-
}
|
|
119
|
-
return [];
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
walkModelNodes(nodes: readonly ModelNode[]) {
|
|
124
|
-
for (const node of nodes) {
|
|
125
|
-
this.walkModelNode(node);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
walkModelNode(node: ModelNode) {
|
|
130
|
-
if (this.#notes.types.has(node.name.text)) {
|
|
131
|
-
this.#errors.push({ message: `Duplicate model: "${node.name.text}"`, location: node.name.loc });
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
const fields: ModelField[] = [];
|
|
136
|
-
const seenFields = new SeenNames();
|
|
137
|
-
for (const fieldNode of node.fields) {
|
|
138
|
-
const { name, required } = fieldNode;
|
|
139
|
-
if (seenFields.seen(name)) {
|
|
140
|
-
this.#errors.push({ message: `Duplicate field: "${name.text}"`, location: name.loc });
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
fields.push({
|
|
144
|
-
name: name.text,
|
|
145
|
-
required,
|
|
146
|
-
});
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
const cards: ModelCard[] = [];
|
|
150
|
-
const seenCards = new SeenNames();
|
|
151
|
-
for (const cardNode of node.cards) {
|
|
152
|
-
const { name, front, back } = cardNode;
|
|
153
|
-
if (seenCards.seen(name)) {
|
|
154
|
-
this.#errors.push({ message: `Duplicate card: "${name.text}"`, location: name.loc });
|
|
155
|
-
return;
|
|
156
|
-
}
|
|
157
|
-
cards.push({
|
|
158
|
-
name: name.text,
|
|
159
|
-
front: front?.text ?? "",
|
|
160
|
-
back: back?.text ?? "",
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
this.#notes.types.add({
|
|
165
|
-
name: node.name.text,
|
|
166
|
-
id: node.id.value,
|
|
167
|
-
cloze: node.cloze != null,
|
|
168
|
-
fields,
|
|
169
|
-
cards,
|
|
170
|
-
styling: node.styling?.text ?? "",
|
|
171
|
-
});
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
parseNotes(path: string, text: string): this {
|
|
175
|
-
this.walkNoteNodes(this.parseNoteNodes(path, text));
|
|
176
|
-
return this;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
parseNoteNodes(path: string, text: string): NoteNode[] {
|
|
180
|
-
try {
|
|
181
|
-
return parseNoteList(text, path);
|
|
182
|
-
} catch (err) {
|
|
183
|
-
if (err instanceof SyntaxError) {
|
|
184
|
-
const { message, location } = err;
|
|
185
|
-
this.#errors.push({ message, location });
|
|
186
|
-
} else {
|
|
187
|
-
throw err;
|
|
188
|
-
}
|
|
189
|
-
return [];
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
walkNoteNodes(
|
|
194
|
-
nodes: readonly NoteNode[],
|
|
195
|
-
state: ParseState = {
|
|
196
|
-
type: ModelMap.basic,
|
|
197
|
-
deck: "",
|
|
198
|
-
tags: "",
|
|
199
|
-
},
|
|
200
|
-
) {
|
|
201
|
-
for (const noteNode of nodes) {
|
|
202
|
-
this.walkNoteNode(noteNode, state);
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
walkNoteNode(noteNode: NoteNode, state: ParseState) {
|
|
207
|
-
const seen = new SeenNames();
|
|
208
|
-
|
|
209
|
-
// Set note properties.
|
|
210
|
-
for (const { name, value } of noteNode.properties) {
|
|
211
|
-
if (seen.seen(name)) {
|
|
212
|
-
this.#errors.push({ message: `Duplicate property: "${name.text}"`, location: name.loc });
|
|
213
|
-
return;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
switch (name.text) {
|
|
217
|
-
case "type": {
|
|
218
|
-
const type = this.#notes.types.get(value.text);
|
|
219
|
-
if (type == null) {
|
|
220
|
-
this.#errors.push({ message: `Unknown note type: "${value.text}"`, location: value.loc });
|
|
221
|
-
return;
|
|
222
|
-
}
|
|
223
|
-
state.type = type;
|
|
224
|
-
break;
|
|
225
|
-
}
|
|
226
|
-
case "deck": {
|
|
227
|
-
state.deck = value.text;
|
|
228
|
-
break;
|
|
229
|
-
}
|
|
230
|
-
case "tags": {
|
|
231
|
-
state.tags = value.text;
|
|
232
|
-
break;
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
const note = new Note(state.type);
|
|
238
|
-
note.deck = state.deck;
|
|
239
|
-
note.tags = state.tags;
|
|
240
|
-
note.node = noteNode;
|
|
241
|
-
|
|
242
|
-
// Set note fields.
|
|
243
|
-
for (const fieldNode of noteNode.fields) {
|
|
244
|
-
const { name, value } = fieldNode;
|
|
245
|
-
|
|
246
|
-
if (seen.seen(name)) {
|
|
247
|
-
this.#errors.push({ message: `Duplicate field: "${name.text}"`, location: name.loc });
|
|
248
|
-
return;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
if (note.has(name.text)) {
|
|
252
|
-
const field = note.get(name.text);
|
|
253
|
-
field.value = value.text;
|
|
254
|
-
field.node = fieldNode;
|
|
255
|
-
} else {
|
|
256
|
-
this.#errors.push({ message: `Unknown field: "${name.text}"`, location: name.loc });
|
|
257
|
-
return;
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
this.#notes.add(note);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
class SeenNames {
|
|
266
|
-
readonly #set = new Set<string>();
|
|
267
|
-
|
|
268
|
-
seen(name: Token): boolean {
|
|
269
|
-
const key = name.text.toLowerCase();
|
|
270
|
-
if (this.#set.has(key)) {
|
|
271
|
-
return true;
|
|
272
|
-
} else {
|
|
273
|
-
this.#set.add(key);
|
|
274
|
-
return false;
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
}
|