UNPKG

2.89 kBtext/coffeescriptView Raw
1fs = require('fs')
2_ = require('lodash')
3{ walkTree } = require('@resin.io/doxx-utils')
4
5fixLinks = walkTree
6 visitNode: (node) ->
7 if node.level? and not node.link
8 if not node.children?.length
9 throw new Error("No link and no child lines. #{node.raw}")
10 node.isGateway = true
11 node.link = node.children[0].link
12
13calcRefs = walkTree
14 visitNode: (node) ->
15 { link } = node
16 if link and link[0] is '/'
17 node.ref = link[1..]
18
19 if node.level? and not node.ref? and not node.title
20 throw new Error("No title for external link node. #{node.raw}")
21
22calcIds = (rootNode, rootId) ->
23 setId = (node, id) ->
24 node.$id = id
25 if node.children
26 for child, i in node.children
27 setId(child, "#{id}.#{i + 1}")
28 setId(rootNode, rootId)
29
30exports.parse = (config) ->
31 lines = fs.readFileSync(config.parseNav)
32 .toString()
33 .split('\n')
34 .map (s) -> s.trimRight()
35 .filter (s) -> s and not s.match(/\s*#/)
36 .map (s) ->
37 [ pad, line ] = s.match(/^(\s*)(.*)$/)[1..]
38 if pad.length % 2 or not pad.match(/^ *$/)
39 throw new Error("Wrong indent! Must be even and spaces-only. #{s}")
40 return { level: pad.length / 2, raw: line }
41 .map ({ level, raw }) ->
42 [ title, skip, link ] = raw.match(/^([^\[]+)?(\[(.+)\])?$/)[1..]
43 node = { level, raw, title, link }
44 if link?.match(/\$/)
45 node.isDynamic = true
46 linkReParts = link.split(/\$[\w_]+/).map(_.escapeRegExp)
47 node.linkRe = new RegExp('^' + linkReParts.join('.*') + '$')
48 if not title
49 throw new Error("Dynamic pages must specify the title. #{raw}")
50 titleParts = title.split(/\s*~\s*/)
51 node.title = titleParts[0]
52 node.titleTemplate = titleParts[1] or titleParts[0]
53 return node
54
55 trees = []
56 currentNode = null
57
58 for line in lines
59 if not currentNode?
60 if line.level isnt 0
61 throw new Error("First line must have no indent. #{line.raw}")
62
63 trees.push(line)
64 else
65 if line.level > currentNode.level + 1
66 throw new Error("Indent too big. #{line.raw}")
67
68 while currentNode and line.level <= currentNode.level
69 currentNode = currentNode.parent
70 if not currentNode
71 trees.push(line)
72 else
73 currentNode.children ?= []
74 currentNode.children.push(line)
75 line.parent = currentNode
76
77 currentNode = line
78
79 result =
80 level: null
81 ref: undefined
82 link: null
83 title: '<root>'
84 raw: '<root>'
85 children: trees
86
87 fixLinks(result)
88 calcRefs(result)
89 calcIds(result, '$0')
90
91 return result
92
93ppNode = walkTree
94 visitNode: (node, indent = '') ->
95 title = node.title or '(No title)'
96 link = if node.link then "[#{node.link}]" else ''
97 console.log "#{indent}|--#{title}#{link}"
98 buildNextArgs: (node, indent = '') ->
99 [ indent + '| ' ]
100
101exports.pp = (tree) ->
102 ppNode(tree)
103
104exports.serialize = (tree, path) ->
105 return