UNPKG

4.21 kBtext/coffeescriptView Raw
1path = require('path')
2fs = require('fs')
3_ = require('lodash')
4
5HbHelper = require('@resin.io/doxx-handlebars-helper')
6{ walkFiles, walkTree } = require('@resin.io/doxx-utils')
7
8LunrIndex = require('./lunr-index')
9Dicts = require('./dictionaries')
10
11{ extractTitleFromText, slugify, replacePlaceholders,
12 filenameToRef, refToFilename, getValue } = require('./util')
13
14
15module.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 # needed because of
107 # https://github.com/superwolff/metalsmith-layouts/issues/83
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 # TODO: this logic is twisted and should be improved
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