OutlineParser.js 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. const COMMAND_LEVELS = {
  2. section: 0,
  3. subsection: 1,
  4. subsubsection: 2
  5. }
  6. function matchOutline(content) {
  7. const lines = content.split('\n')
  8. const flatOutline = []
  9. lines.forEach((line, lineId) => {
  10. const match = line.match(/\\(?<command>[sub]*section)\{(?<title>[^}]+)\}/)
  11. if (!match) return
  12. const {
  13. groups: { command, title }
  14. } = match
  15. flatOutline.push({
  16. line: lineId + 1,
  17. title,
  18. level: COMMAND_LEVELS[command]
  19. })
  20. })
  21. return flatOutline
  22. }
  23. function nestOutline(flatOutline) {
  24. let parentOutlines = {}
  25. let nestedOutlines = []
  26. flatOutline.forEach(outline => {
  27. const parentOutline = parentOutlines[outline.level - 1]
  28. if (!parentOutline) {
  29. // top level
  30. nestedOutlines.push(outline)
  31. } else if (!parentOutline.children) {
  32. // first outline in this node
  33. parentOutline.children = [outline]
  34. } else {
  35. // push outline to node
  36. parentOutline.children.push(outline)
  37. }
  38. parentOutlines[outline.level] = outline
  39. })
  40. return nestedOutlines
  41. }
  42. function parseOutline(content) {
  43. const flatOutline = matchOutline(content)
  44. return nestOutline(flatOutline)
  45. }
  46. export default parseOutline