diff --git a/parser-generator/assets/grammar.ohm b/parser-generator/assets/grammar.ohm new file mode 100644 index 0000000..86aaa91 --- /dev/null +++ b/parser-generator/assets/grammar.ohm @@ -0,0 +1,33 @@ +G { + Main = Flashcard* end + + // PLUGIN SYNTAX + Flashcard = FlashcardTagged + FlashcardTagged = question answer flashcardId? + question = (~delimiter questionContentType)* delimiter + answer = (~(flashcardId? delimiter) answerContentType)* + + tag = "#card" + answerTaggedDelimiter = newline newline + + answerContentType = any + questionContentType = any + + // Anki card ID - e.g. ^1643061575720 + flashcardId = "^" digit digit digit digit digit digit digit digit digit digit digit digit digit + + // OTHER + newline = "\r\n" | "\n" | "\r" + + // OBSIDIAN SYNTAX + + // Obsidian tag - e.g. #main_tag/sub_tag-with123/other_sub + //Tag = "#" letter (alnum | "_" | "-" | "/")* + + header1 = "#" + header2 = "##" + header3 = "###" + header4 = "####" + header5 = "#####" + header6 = "######" +} \ No newline at end of file diff --git a/parser-generator/assets/testnote.md b/parser-generator/assets/testnote.md new file mode 100644 index 0000000..8e80d96 --- /dev/null +++ b/parser-generator/assets/testnote.md @@ -0,0 +1,8 @@ +Question1 #card Answer 1 ^1666356393425 + +Question2 #card Answer 2a Answer 2b + +Question2 #card +Answer 2a +Answer 2b + diff --git a/parser-generator/src/generate.js b/parser-generator/src/generate.js new file mode 100644 index 0000000..d7e8117 --- /dev/null +++ b/parser-generator/src/generate.js @@ -0,0 +1,54 @@ +const fs = require("fs"); +const ohm = require("ohm-js"); + +const file = fs.readFileSync('../assets/grammar.ohm').toString(); +const grammar = ohm.grammar(file); +const semantics = grammar.createSemantics(); +semantics.addOperation('eval()', { + Main(cards, eof) { + const out = cards.children.map((card) => { + return card.eval(); + }); + return out; + }, + + Flashcard(flashcard) { + return { + flashcard: flashcard.eval(), + }; + }, + + FlashcardTagged(question, answer, tag) { + console.log(Object.getOwnPropertyNames(tag.source)) + return { + question: question.eval(), + answer: answer.sourceString, + tag: tag.child(0)?.eval(), + }; + }, + + question(question, _delimiter) { + return question.sourceString; + }, + + flashcardId(_, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13) { + const digits = [d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13].map(d => d.sourceString).join(''); + return parseInt(digits, 10); + }, +}); + + +const markdownFile = fs.readFileSync('../assets/testnote.md', 'utf-8'); + +const m = grammar.match(markdownFile); +if (m.succeeded()) { + console.log('\x1b[32m%s\x1b[0m', "Parsed successfully."); +} else { + console.log('\x1b[31m%s\x1b[0m', "Could not parse."); +} + +const result = semantics(m).eval(); + +console.log("The final result is: ") +console.log(result); +