From 0182b5a10684632fc15fb714fabbc47c58977f45 Mon Sep 17 00:00:00 2001 From: akshan Date: Fri, 9 Oct 2020 12:15:02 +0530 Subject: [PATCH] first version --- .prettierrc | 12 +++++ WriteParser.js | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 11 ++++ 3 files changed, 180 insertions(+) create mode 100644 .prettierrc create mode 100644 WriteParser.js create mode 100644 package.json diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..d0bb80a --- /dev/null +++ b/.prettierrc @@ -0,0 +1,12 @@ +{ + "trailingComma": "all", + "useTabs": true, + "semi": true, + "singleQuote": false, + "quoteProps": "consistent", + "jsxSingleQuote": false, + "bracketSpacing": true, + "jsxBracketSameLine": true, + "arrowParens": "avoid", + "printWidth": 80 +} diff --git a/WriteParser.js b/WriteParser.js new file mode 100644 index 0000000..b4beea1 --- /dev/null +++ b/WriteParser.js @@ -0,0 +1,157 @@ +const { inspect } = require("util"); + +function* prepare(str) { + for (let i = 0; i < str.length; i++) { + yield { + current: str[i], + next: (n = 1) => str.slice(i + 1, i + 1 + n), + prev: (n = 1) => str.slice(i - n, i), + skip: (n = 1) => (i += n), + }; + } +} + +function Parse(str, inner = false) { + let context = null; + let buffer = ""; + let AST = []; + let link = ""; + + const flush = () => { + if (buffer) { + if (context === null && inner) { + AST.push(buffer); + } else { + if (context === "url") { + AST.push({ + type: context, + children: Parse(buffer, true), + url: link, + }); + } else { + AST.push({ + type: context || "text", + children: context === null ? [buffer] : Parse(buffer, true), + }); + } + } + buffer = ""; + } + context = null; + link = ""; + }; + + for (const char of prepare(str)) { + const currentContext = context; + if ( + (!context || context === "bold") && + char.current === "*" && + char.next() === "*" + ) { + flush(); + if (!currentContext) { + context = "bold"; + } + char.skip(); + } else if ( + (!context || context === "italics") && + char.current === "_" + ) { + flush(); + if (!currentContext) { + context = "italics"; + } + } else if ( + (!context || context === "strikethrough") && + char.current === "~" && + char.next() === "~" + ) { + flush(); + if (!currentContext) { + context = "strikethrough"; + } + char.skip(); + } else if ( + (!context || context === "underline") && + char.current === "=" && + char.next() === "=" + ) { + flush(); + if (!currentContext) { + context = "underline"; + } + char.skip(); + } + else if ((char.current === "[" || char.current === ']') && (!context || context === "link")) { + if (char.current === "[") { + flush(); + context = "link"; + } + if (inner) { + buffer += char.current; + } + } + else if ((context === "link" || !context || context === "url") && (char.current === "(" || char.current === ")") && !inner) { + if (char.prev() === "]") { + if (!currentContext || currentContext === "link") { + context = "url"; + } + } + else { + flush(); + } + } else { + if (context === "url") { + link += char.current; + } + else { + buffer += char.current; + } + } + } + + const updater = (char) => { + context = null; + let result = Parse(buffer); + for (const check of result) { + if (check.type !== "text") { + if (!AST.length) { + buffer = char; + flush(); + } + AST.push(check); + buffer = ""; + } + else { + buffer = check.children[0]; + if (!AST.length) { + buffer = char + buffer; + } + flush(); + } + } + } + + if (context === "bold") { + console.log("triggered"); + updater("**"); + } else if (context === "italics") { + updater("_"); + } else if (context === "strikethrough") { + updater("~~"); + } else if (context == "underline") { + updater("=="); + } + + if (buffer) { + context = null; + flush(); + } + + return AST; +} + +const input = "[link](google.com)"; + +console.log("input:", input); +console.log("output:", inspect(Parse(input), false, Infinity, true)); diff --git a/package.json b/package.json new file mode 100644 index 0000000..aa64e9f --- /dev/null +++ b/package.json @@ -0,0 +1,11 @@ +{ + "name": "write-parser", + "version": "1.0.0", + "description": "", + "main": "WriteParser.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC" +}