You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

62 lines
1.8 KiB

  1. // Header matching code by CodeMirror, copyright (c) by Marijn Haverbeke and others
  2. // Distributed under an MIT license: https://codemirror.net/LICENSE
  3. import CodeMirror from 'codemirror'
  4. const maxDepth = 100
  5. const codeBlockStartMatch = /^`{3}[a-zA-Z0-9]+$/
  6. const codeBlockEndMatch = /^`{3}$/
  7. CodeMirror.registerHelper('fold', 'markdown', function (cm, start) {
  8. const firstLine = cm.getLine(start.line)
  9. const lastLineNo = cm.lastLine()
  10. let end
  11. function isHeader(lineNo) {
  12. const tokentype = cm.getTokenTypeAt(CodeMirror.Pos(lineNo, 0))
  13. return tokentype && /\bheader\b/.test(tokentype)
  14. }
  15. function headerLevel(lineNo, line, nextLine) {
  16. let match = line && line.match(/^#+/)
  17. if (match && isHeader(lineNo)) return match[0].length
  18. match = nextLine && nextLine.match(/^[=-]+\s*$/)
  19. if (match && isHeader(lineNo + 1)) return nextLine[0] === '=' ? 1 : 2
  20. return maxDepth
  21. }
  22. // -> CODE BLOCK
  23. if (codeBlockStartMatch.test(cm.getLine(start.line))) {
  24. end = start.line
  25. let nextNextLine = cm.getLine(end + 1)
  26. while (end < lastLineNo) {
  27. if (codeBlockEndMatch.test(nextNextLine)) {
  28. end++
  29. break
  30. }
  31. end++
  32. nextNextLine = cm.getLine(end + 1)
  33. }
  34. } else {
  35. // -> HEADER
  36. let nextLine = cm.getLine(start.line + 1)
  37. const level = headerLevel(start.line, firstLine, nextLine)
  38. if (level === maxDepth) return undefined
  39. end = start.line
  40. let nextNextLine = cm.getLine(end + 2)
  41. while (end < lastLineNo) {
  42. if (headerLevel(end + 1, nextLine, nextNextLine) <= level) break
  43. ++end
  44. nextLine = nextNextLine
  45. nextNextLine = cm.getLine(end + 2)
  46. }
  47. }
  48. return {
  49. from: CodeMirror.Pos(start.line, firstLine.length),
  50. to: CodeMirror.Pos(end, cm.getLine(end).length)
  51. }
  52. })