1 | path = require('path')
|
2 | fs = require('fs')
|
3 | _ = require('lodash')
|
4 |
|
5 | HbHelper = require('@resin.io/doxx-handlebars-helper')
|
6 | { walkFiles, walkTree } = require('@resin.io/doxx-utils')
|
7 |
|
8 | LunrIndex = require('./lunr-index')
|
9 | Dicts = require('./dictionaries')
|
10 |
|
11 | { extractTitleFromText, slugify, replacePlaceholders,
|
12 | filenameToRef, refToFilename, getValue } = require('./util')
|
13 |
|
14 |
|
15 | module.exports = (config, navTree) ->
|
16 | dicts = Dicts(config)
|
17 | exports = {}
|
18 |
|
19 | exports.skipPrivate = walkFiles (file, files) ->
|
20 | if path.parse(file).name.match(/^_/)
|
21 | delete files[file]
|
22 |
|
23 | fileByRef = {}
|
24 |
|
25 | exports.populateFileMeta = walkFiles (file, files) ->
|
26 | obj = files[file]
|
27 | title = obj.title or extractTitleFromText(obj.contents.toString())
|
28 | obj.title = HbHelper.render(title, obj)
|
29 | [ obj.ref, obj.ext ] = filenameToRef(file)
|
30 | fileByRef[obj.ref] = obj
|
31 | obj.selfLink = '/' + obj.ref
|
32 | _.assign(obj, getValue(config.metaExtra, file, obj))
|
33 |
|
34 | exports.buildSearchIndex = ->
|
35 | console.log('Building search index...')
|
36 | searchIndex = LunrIndex.create()
|
37 |
|
38 | return (files, metalsmith, done) ->
|
39 | for file of files
|
40 | obj = files[file]
|
41 | searchIndex.add
|
42 | id: obj.ref
|
43 | title: obj.title
|
44 | body: obj.contents.toString()
|
45 | indexFilePath = config.buildLunrIndex
|
46 | searchIndex.write indexFilePath, (err) ->
|
47 | throw err if err
|
48 | console.log('Successfully finished indexing.')
|
49 | done()
|
50 |
|
51 | navByRef = null
|
52 |
|
53 | exports.parseNav = ->
|
54 | setRefRec = (ref, node, remainingVariables) ->
|
55 | if not remainingVariables?.length
|
56 | return setRef(ref, node)
|
57 | [ nextVariable, remainingVariables... ] = remainingVariables
|
58 | for value in dicts.getValues(nextVariable)
|
59 | setRefRec(
|
60 | replacePlaceholders(ref, { "#{nextVariable}": value }),
|
61 | node,
|
62 | remainingVariables
|
63 | )
|
64 |
|
65 | setRef = (ref, node) ->
|
66 | return if not ref?
|
67 | if ref.indexOf('$') >= 0
|
68 | setRefRec(ref, node, dicts.dictNames)
|
69 | else
|
70 | navByRef[ref] = node
|
71 |
|
72 | setRefs = walkTree
|
73 | visitNode: (node) ->
|
74 | if node.level?
|
75 | setRef(node.ref, node)
|
76 |
|
77 | fixNavNodeTitleAndSetSlug = walkTree
|
78 | visitNode: (node) ->
|
79 | if node.level?
|
80 | node.title or= fileByRef[node.ref]?.title
|
81 | node.slug = slugify(node.title)
|
82 |
|
83 | addNavParents = walkTree
|
84 | visitNode: (node, parents) ->
|
85 | if node.level?
|
86 | node.parents = parents.concat(node)
|
87 | buildNextArgs: (node, parents) ->
|
88 | if node.level?
|
89 | [ parents.concat(node) ]
|
90 | else
|
91 | [ parents ]
|
92 |
|
93 | return (files, metalsmith, done) ->
|
94 | console.log('Parsing navigation...')
|
95 |
|
96 | fixNavNodeTitleAndSetSlug(navTree)
|
97 | addNavParents(navTree, [])
|
98 |
|
99 | navByRef = {}
|
100 | setRefs(navTree)
|
101 |
|
102 | console.log('Navigation parsed and indexed.')
|
103 | done()
|
104 |
|
105 | exports.serializeNav = ->
|
106 |
|
107 |
|
108 | removeBackRefs = walkTree
|
109 | visitNode: (node) ->
|
110 | delete node.parent
|
111 | delete node.parents
|
112 |
|
113 | return (files, metalsmith, done) ->
|
114 | removeBackRefs(navTree)
|
115 |
|
116 | filename = config.serializeNav
|
117 | fs.writeFile filename, JSON.stringify(navTree), (err) ->
|
118 | throw err if err
|
119 | console.log('Successfully serialized navigation tree.')
|
120 | done()
|
121 |
|
122 | exports.populateFileNavMeta = ->
|
123 |
|
124 | setBreadcrumbsForFile = (file, obj) ->
|
125 | [ ref ] = filenameToRef(file)
|
126 | navNode = navByRef[ref]
|
127 | obj.breadcrumbs = bc = navNode?.parents
|
128 | .map (node) -> node.title
|
129 |
|
130 | if navNode?.isDynamic and bc?.length
|
131 | bc[bc.length - 1] =
|
132 | HbHelper.render(navNode.titleTemplate, obj)
|
133 |
|
134 | setPathForFile = (file, obj) ->
|
135 | [ ref ] = filenameToRef(file)
|
136 | navNode = navByRef[ref]
|
137 | if navPath = navNode?.parents
|
138 | obj.navPath = {}
|
139 | for node in navPath
|
140 | obj.navPath[node.$id] = true
|
141 |
|
142 | return (files, metalsmith, done) ->
|
143 | for file of files
|
144 | obj = files[file]
|
145 | setPathForFile(file, obj)
|
146 | setBreadcrumbsForFile(file, obj)
|
147 | done()
|
148 |
|
149 |
|
150 | return exports
|