ソースを参照

indent: looks like done

Ivan Asmer 4 年 前
コミット
27a05e7d33
1 ファイル変更37 行追加24 行削除
  1. 37 24
      index.js

+ 37 - 24
index.js

@@ -208,11 +208,11 @@ const syntax = {
         childName: 'unOrderedListItem',
         //paired: true,
         recursive: true,
-        regexp: /-\s*/,
+        regexp: /-\s*\S/,
         content:{
             start:{
                 point: 'end',
-                offset: 0
+                offset: -1
             },
             end:{
                 point: 'start',
@@ -222,12 +222,13 @@ const syntax = {
         begin: 1,
         forward:  {
             point: 'end',
-            offset: -1
+            offset: 0
         }
     }
 }
 
-const indentRegexp = (regexp,count) => new RegExp(`\\n(\s${count === undefined ? '*' : `{${count}}` })` + regexp.toString().slice(1,-1))
+const indentRegexp = (regexp,count) => new RegExp(`\\n(\\s${count === undefined ? '*' : `{${count}}` })` + regexp.toString().slice(1,-1))
+const indentEndRegexp = (count) => new RegExp(`\\n(\\s${count === undefined ? '*' : `{${count}}` })\\S`)
 
 function findNearest(md, mdTags, offset=0){
     let nearest, nearestMatch = {index: Infinity};
@@ -260,8 +261,8 @@ String.prototype.offsetMatch = function(offset, ...params){
     return this.slice(offset).match(...params)
 }
 
-Array.prototype.last = function(){
-    return this[this.length -1]
+Array.prototype.last = function(amount=-1){
+    return this[this.length +amount]
 }
 
 String.prototype.cutIndent = function(indent){
@@ -270,24 +271,36 @@ String.prototype.cutIndent = function(indent){
 }
 
 function buildAST(md, mdTags=syntax, offset=0, tree={tag: 'root'}, stack=[]){
-    const currentNode     = stack.last() || tree
+    let currentNode     = stack.last() || tree
     if (currentNode.tag === 'root') md = '\n' + md + '\n'
     currentNode.children  = currentNode.children || []
     const { children }     = currentNode
 
-    let {indent, title, recursive, regexp, endRegexp, content: {end: {offset: offsetEnd, point} }, forward } = mdTags[currentNode.tag]
+    let {indent, childName, title, recursive, regexp, endRegexp, content: {end: {offset: offsetEnd, point} }, forward } = mdTags[currentNode.tag]
 
     if (indent){
-        if (currentNode.parent.tag == currentNode.tag){ //li
-
-        }
-        else { // ul or ol
+        if (currentNode.parent.tag !== currentNode.tag){ //li
+            let { parent: {children: siblings} } = currentNode
+            if (siblings.length > 1 && siblings.last(-2).tag === currentNode.tag){
+                siblings.pop()
+                currentNode = siblings.last()
+            }
+            const { children }     = currentNode
             const indentLength = currentNode.startMatch[1].length
-            endRegexp = indentRegexp(regexp, indentLength)
+            currentNode.indentLength = indentLength
+
+            endRegexp = indentEndRegexp(indentLength)
             let endMatch = md.offsetMatch(offset, endRegexp) || {index: md.length +1, 0: 'zzz'}
 
             let listMD   = md.slice(offset, endMatch.index + offset).cutIndent(currentNode.startMatch[0].length -1)
-            debugger;
+
+            const newNode = {tag: childName, startOffset: offset, parent: currentNode, startMatch: currentNode.startMatch}
+            children.push(newNode)
+
+            newNode.children = buildAST(listMD, mdTags).children
+            newNode.children.forEach(item => item.parent = currentNode)
+
+            offset = newNode.endOffset = currentNode.endOffset = endMatch.index + offset
         }
     }
     
@@ -306,11 +319,11 @@ function buildAST(md, mdTags=syntax, offset=0, tree={tag: 'root'}, stack=[]){
     while(offset < md.length){
         const [nearest, nearestMatch] = findNearest(md, mdTags, offset)
         let endMatch = md.offsetMatch(offset, endRegexp)
-        if (!recursive || endMatch) {
-            if (!recursive || !nearest || endMatch.index <= nearestMatch.index ){
+        if (!recursive || endMatch) { //if we (should) find closing tag 
+            if (!recursive || !nearest || endMatch.index <= nearestMatch.index ){ //if closing tag closer than new nested tag
                 endMatch = endMatch || {index: md.length - offset, 0: "zzz"}
                 currentNode.endContent = offset + endMatch.index + offsetEnd + (point === 'end' ? endMatch[0].length : 0)
-                children.push(md.slice(offset, currentNode.endContent))
+                offset !== currentNode.endContent && children.push(md.slice(offset, currentNode.endContent))
                 offset += endMatch.index + forward.offset + (forward.point === 'endEnd' ? endMatch[0].length : 0)
                 console.log(currentNode.tag, forward.point === 'endEnd' ? endMatch[0].length : 0)
                 currentNode.endOffset = offset
@@ -318,20 +331,20 @@ function buildAST(md, mdTags=syntax, offset=0, tree={tag: 'root'}, stack=[]){
                 return currentNode
             }
         }
-        if (nearest){
+        if (nearest){ //new nested tag
             const {begin,content: {start}} = mdTags[nearest]
-            if (nearestMatch.index){
-                children.push(md.slice(offset, offset + nearestMatch.index + begin))
+            if (nearestMatch.index){ //if just text before nested tag
+                nearestMatch.index + begin > 0 && children.push(md.slice(offset, offset + nearestMatch.index + begin))
                 offset += nearestMatch.index
             }
-            else {
-                const newNode = {tag: nearest, startOffset: offset, parent: currentNode, startMatch: nearestMatch}
+            else { //if  new tag right under cursor (offset)
+                let newNode = {tag: nearest, startOffset: offset, parent: currentNode, startMatch: nearestMatch}
                 children.push(newNode)
-                buildAST(md, mdTags, offset + start.offset + (start.point === 'end' ? nearestMatch[0].length : 0), tree, [...stack, newNode])
+                newNode = buildAST(md, mdTags, offset + start.offset + (start.point === 'end' ? nearestMatch[0].length : 0), tree, [...stack, newNode])
                 offset = newNode.endOffset
             }
         }
-        else {
+        else { //no nearest - rest of line to children as text
             children.push(md.slice(offset))
             offset = md.length
         }