|
@@ -88,15 +88,37 @@ const syntax = {
|
|
offset: -1
|
|
offset: -1
|
|
}
|
|
}
|
|
},
|
|
},
|
|
|
|
+ root: {
|
|
|
|
+ paired: true,
|
|
|
|
+ recursive: true,
|
|
|
|
+ startRegexp: /^/,
|
|
|
|
+ endRegexp: /$/,
|
|
|
|
+ content: {
|
|
|
|
+ start: {
|
|
|
|
+ point: 'start',
|
|
|
|
+ offset: 1
|
|
|
|
+ },
|
|
|
|
+ end: {
|
|
|
|
+ point: 'end',
|
|
|
|
+ offset: 0
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ begin: 0,
|
|
|
|
+ forward: {
|
|
|
|
+ point: 'endEnd', //start, startEnd, end, endEnd
|
|
|
|
+ offset: -1
|
|
|
|
+ }
|
|
|
|
+ },
|
|
}
|
|
}
|
|
|
|
|
|
-function findNearest(md, mdTags){
|
|
|
|
|
|
+function findNearest(md, mdTags, offset=0){
|
|
let nearest, nearestMatch = {index: Infinity};
|
|
let nearest, nearestMatch = {index: Infinity};
|
|
for (let [mdTag, {paired,
|
|
for (let [mdTag, {paired,
|
|
startRegexp,
|
|
startRegexp,
|
|
rexexp}] of Object.entries(mdTags)) {
|
|
rexexp}] of Object.entries(mdTags)) {
|
|
|
|
+ if (mdTag === 'root') continue;
|
|
|
|
|
|
- let match = md.match(startRegexp || regexp)
|
|
|
|
|
|
+ let match = md.offsetMatch(offset, startRegexp || regexp)
|
|
if (match && match.index < nearestMatch.index){
|
|
if (match && match.index < nearestMatch.index){
|
|
nearestMatch = match
|
|
nearestMatch = match
|
|
nearest = mdTag
|
|
nearest = mdTag
|
|
@@ -112,28 +134,64 @@ function cutNode(md, match, tagName, {paired, recursive, startRegexp, endRegexp,
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
-function buildAST(md, mdTags=syntax, tree=[], path=[]){
|
|
|
|
- const result = []
|
|
|
|
- while(md){
|
|
|
|
- const [nearest, nearestMatch] = findNearest(md, mdTags)
|
|
|
|
|
|
+//node:
|
|
|
|
+//{
|
|
|
|
+// tag: 'keyFromSyntax',
|
|
|
|
+// children: [String, Node]
|
|
|
|
+// parent: node
|
|
|
|
+//}
|
|
|
|
+//
|
|
|
|
+String.prototype.offsetMatch = function(offset, ...params){
|
|
|
|
+ return this.slice(offset).match(...params)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Array.prototype.last = function(){
|
|
|
|
+ return this[this.length -1]
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+function buildAST(md, mdTags=syntax, offset=0, tree={tag: 'root'}, stack=[]){
|
|
|
|
+ const currentNode = stack.last() || tree
|
|
|
|
+ currentNode.children = currentNode.children || []
|
|
|
|
+ const { children } = currentNode
|
|
|
|
+
|
|
|
|
+ const { endRegexp, content: {end: {offset: offsetEnd} }, forward } = mdTags[currentNode.tag]
|
|
|
|
+
|
|
|
|
+ while(offset < md.length){
|
|
|
|
+ const [nearest, nearestMatch] = findNearest(md, mdTags, offset)
|
|
|
|
+ const endMatch = md.offsetMatch(offset, endRegexp)
|
|
|
|
+ if (endMatch) {
|
|
|
|
+ if (!nearest || endMatch.index < nearestMatch.index){
|
|
|
|
+ currentNode.endContent = offset + endMatch.index + offsetEnd
|
|
|
|
+ children.push(md.slice(offset, currentNode.endContent))
|
|
|
|
+ offset += endMatch.index + endMatch[0].length + forward.offset
|
|
|
|
+ currentNode.endOffset = offset
|
|
|
|
+ console.log('endmatch current', currentNode)
|
|
|
|
+ return currentNode
|
|
|
|
+ }
|
|
|
|
+ }
|
|
if (nearest){
|
|
if (nearest){
|
|
- const {begin} = mdTags[nearest]
|
|
|
|
|
|
+ const {begin,content: {start}} = mdTags[nearest]
|
|
if (nearestMatch.index){
|
|
if (nearestMatch.index){
|
|
- result.push(md.slice(0, nearestMatch.index + begin))
|
|
|
|
- md = md.slice(nearestMatch.index)
|
|
|
|
|
|
+ children.push(md.slice(offset, offset + nearestMatch.index + begin))
|
|
|
|
+ offset += nearestMatch.index
|
|
|
|
+ console.log(offset, md.slice(offset))
|
|
}
|
|
}
|
|
else {
|
|
else {
|
|
- console.log(nearestMatch)
|
|
|
|
- break //to avoid infinite loop, add cutNode here
|
|
|
|
|
|
+ const newNode = {tag: nearest, startOffset: offset, parent: currentNode}
|
|
|
|
+ children.push(newNode)
|
|
|
|
+ buildAST(md, mdTags, offset + start.offset, tree, [...stack, newNode])
|
|
|
|
+ console.log('same', newNode)
|
|
|
|
+ offset = newNode.endOffset
|
|
|
|
+ console.log(offset, md.slice(offset))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
else {
|
|
- result.push(md)
|
|
|
|
|
|
+ children.push(md)
|
|
md = ''
|
|
md = ''
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- return result
|
|
|
|
|
|
+ return currentNode
|
|
}
|
|
}
|
|
|
|
|
|
-console.log(buildAST("I just __love__ __bold text__. "))
|
|
|
|
|
|
+console.log(buildAST("I just **love _bold text_ adddd** hahaha").children[1])
|
|
|
|
|