index.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /*
  2. * md ast - pluggable markdown parser
  3. */
  4. const syntax = {
  5. bold: {
  6. paired: true,
  7. recursive: true,
  8. startRegexp: /\*\*\S.*/,
  9. endRegexp: /\S\*\*\s/,
  10. content: {
  11. start: {
  12. point: 'start',
  13. offset: 2
  14. },
  15. end: {
  16. point: 'end',
  17. offset: 1
  18. }
  19. },
  20. begin: 0,
  21. forward: {
  22. point: 'endEnd', //start, startEnd, end, endEnd
  23. offset: -1
  24. }
  25. },
  26. bold2: {
  27. paired: true,
  28. recursive: true,
  29. startRegexp: /\s__\S.*/,
  30. endRegexp: /\S__\s/,
  31. content: {
  32. start: {
  33. point: 'start',
  34. offset: 3
  35. },
  36. end: {
  37. point: 'end',
  38. offset: 1
  39. }
  40. },
  41. begin: 1,
  42. forward: {
  43. point: 'endEnd', //start, startEnd, end, endEnd
  44. offset: -1
  45. }
  46. },
  47. italic: {
  48. paired: true,
  49. recursive: true,
  50. startRegexp: /\*\S.*/,
  51. endRegexp: /\S\*\s/,
  52. content: {
  53. start: {
  54. point: 'start',
  55. offset: 2
  56. },
  57. end: {
  58. point: 'end',
  59. offset: 1
  60. }
  61. },
  62. begin: 0,
  63. forward: {
  64. point: 'endEnd', //start, startEnd, end, endEnd
  65. offset: -1
  66. }
  67. },
  68. italic2: {
  69. paired: true,
  70. recursive: true,
  71. startRegexp: /\s_\S.*/,
  72. endRegexp: /\S_\s/,
  73. content: {
  74. start: {
  75. point: 'start',
  76. offset: 2
  77. },
  78. end: {
  79. point: 'end',
  80. offset: 1
  81. }
  82. },
  83. begin: 1,
  84. forward: {
  85. point: 'endEnd', //start, startEnd, end, endEnd
  86. offset: -1
  87. }
  88. },
  89. }
  90. function findNearest(md, mdTags){
  91. let nearest, nearestMatch = {index: Infinity};
  92. for (let [mdTag, {paired,
  93. startRegexp,
  94. rexexp}] of Object.entries(mdTags)) {
  95. let match = md.match(startRegexp || regexp)
  96. if (match && match.index < nearestMatch.index){
  97. nearestMatch = match
  98. nearest = mdTag
  99. }
  100. }
  101. return [nearest, nearestMatch]
  102. }
  103. function cutNode(md, match, tagName, {paired, recursive, startRegexp, endRegexp, content: {start, end}, begin, forward}){
  104. //if (paired){
  105. //md.match()
  106. //}
  107. }
  108. function buildAST(md, mdTags=syntax, tree=[], path=[]){
  109. const result = []
  110. while(md){
  111. const [nearest, nearestMatch] = findNearest(md, mdTags)
  112. if (nearest){
  113. const {begin} = mdTags[nearest]
  114. if (nearestMatch.index){
  115. result.push(md.slice(0, nearestMatch.index + begin))
  116. md = md.slice(nearestMatch.index)
  117. }
  118. else {
  119. console.log(nearestMatch)
  120. break //to avoid infinite loop, add cutNode here
  121. }
  122. }
  123. else {
  124. result.push(md)
  125. md = ''
  126. }
  127. }
  128. return result
  129. }
  130. console.log(buildAST("I just __love__ __bold text__. "))