diff --git a/src/parser/core-parser.pegjs b/src/parser/core-parser.pegjs index 5f48929aadf62b283f6ffbda239246c6efe80c2a..3a7a7730194c1f5c36617d26a4c3f9d6879e8eac 100644 --- a/src/parser/core-parser.pegjs +++ b/src/parser/core-parser.pegjs @@ -1,99 +1,166 @@ -start = root +{ + function buildList(head, others) { + return [ head, ...others ]; + } + + function createTree(type, props, children) { + props = props || { }; + children = children || [ ]; + children = !Array.isArray(children) ? [children] : children; + + return { + node: { type, props }, + children: children + }; + } +} -// general +root + = block + / inline -space - = [ \t] -lineBreak - = "\n" / "\r\n" / "\r" -spacing - = space / lineBreak +// plain +// = -// titile +block + = title + / quote + / search + / blockCode -title_nestContent - = inline +inline + = big -titleA_char - = !(title_nestContent / lineBreak / "】") c:. { return c; } -titleA_text - = t:$(titleA_char+) { return t; } +// block: title -titleA_content - = (title_nestContent / titleA_text)+ +title + = titleA / titleB titleA - = "ã€" titleA_content "】" + = "ã€" content:titleA_content "】" +{ + return createTree('title', { }, content); +} -titleB_char - = !(title_nestContent / lineBreak / "]") c:. { return c; } +titleA_content + = (inline / titleA_text)+ -titleB_text - = t:$(titleB_char+) { return t; } +titleA_text + = s:$(titleA_char+) +{ + return createTree('text', { text: s }); +} -titleB_content - = (title_nestContent / titleB_text)+ +titleA_char + = !(inline / "】") c:CHAR { return c; } titleB - = "[" titleB_content "]" + = "[" content: titleB_content "]" +{ + return createTree('title', { }, content); +} -title - = titleA / titleB +titleB_content + = (inline / titleB_text)+ -// blockCode +titleB_text + = s:$(titleB_char+) +{ + return createTree('text', { text: s }); +} -blockCode_char - = !(lineBreak / "```") c:. { return c; } +titleB_char + = !(inline / "]") c:CHAR { return c; } -blockCode_line - = t:$(blockCode_char*) lineBreak { return t; } + +// block: quote +// (handle the line as quote block if got a char ">" of the line head.) + +quote + = head:quote_line tail:(NEWLINE tree:quote_line { return tree; })* +{ + const trees = [head, ...tail]; + console.log(trees.map(tree => tree.children));//.flat(); + return [head, ...tail].join('\n'); +} + +quote_line + = ">" content:quote_content &ENDLINE { return createTree('quote', { }, content); } + +// TODO: allow nesting +quote_content + = quote_text + +quote_text + = s:$(CHAR+) { return createTree('text', { text: s }); } + + +// block: search + +search + = q:search_query sp:[  \t] key:search_keyToken &ENDLINE +{ + return createTree('search', { + query: q, + content: [ q, sp, key ].join('') + }); +} + +search_query = + head:CHAR tail:(!([  \t] search_keyToken ENDLINE) c:CHAR { return c; })* +{ + return head + tail.join(''); +} + +search_keyToken + = "検索" / "search"i + + +// block: blockCode blockCode - = "```" lineBreak blockCode_line* "```" + = "```" NEWLINE lines: (!("```" ENDLINE) line:blockCode_line NEWLINE { return line; } )* "```" &ENDLINE { return lines; } -// parts +// TODO: allow nesting +blockCode_line + = t:$(CHAR*) { return t; } -// plain -// = emoji -// / text - -// block -// = title -// / quote -// / search -// / blockCode -// / mathBlock -// / center - -// inline -// = big -// / bold -// / small -// / italic -// / strike -// / motion -// / spin -// / jump -// / flip -// / inlineCode -// / mathInline -// / mention -// / hashtag -// / url -// / link -// / plain - -// root -// = block -// / inline -block - = title - / blockCode +// inline: big -inline = "inline" +big + = "***" content:big_content "***" +{ + return createTree('big', { }, content); +} -root - = block - / inline +big_content + = (big_text / inline)* + +big_text + = s:$(big_char+) { return createTree('text', { text: s }); } + +big_char + = !("***") c:CHAR { return c; } + + +// Core rules + +CHAR + = !NEWLINE c:. { return c; } + +ENDLINE + = NEWLINE / EOF + +NEWLINE + = "\r\n" / [\r\n] + +EOF + = !. + +// __ "whitespaces" +// = _+ + +// _ "whitespace" +// = [ \t]