UNPKG

4.12 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{ tokenize } = require('metalsmith-dynamic').util
11
12{ extractTitleFromText, slugify, replacePlaceholders,
13 filenameToRef, refToFilename, getValue } = require('./util')
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 _.assign(obj, getValue(config.metaExtra, file, obj))
28 title = obj.title or extractTitleFromText(obj.contents.toString())
29 obj.title = HbHelper.render(title, obj)
30 [ obj.ref, obj.ext ] = filenameToRef(file)
31 fileByRef[obj.ref] = obj
32
33 exports.buildSearchIndex = ->
34 console.log('Building search index...')
35 searchIndex = LunrIndex.create()
36
37 return (files, metalsmith, done) ->
38 for file of files
39 obj = files[file]
40 searchIndex.add
41 id: obj.ref
42 title: obj.title
43 body: obj.contents.toString()
44 indexFilePath = config.buildLunrIndex
45 searchIndex.write indexFilePath, (err) ->
46 throw err if err
47 console.log('Successfully finished indexing.')
48 done()
49
50 navByRef = null
51
52 exports.parseNav = ->
53 setRefRec = (ref, node, remainingVariables) ->
54 if not remainingVariables?.length
55 return setRef(ref, node)
56 [ nextVariable, remainingVariables... ] = remainingVariables
57 for value in dicts.getValues(nextVariable)
58 setRefRec(
59 replacePlaceholders(ref, { "#{nextVariable}": value }),
60 node,
61 remainingVariables
62 )
63
64 setRef = (ref, node) ->
65 return if not ref?
66 if ref.indexOf('$') >= 0
67 tokens = (t for t, i in tokenize(ref) when i % 2)
68 setRefRec(ref, node, tokens)
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 = walkFiles (file, files) ->
123 obj = files[file]
124 { ref } = obj
125 navNode = navByRef[ref]
126
127 obj.$nav = nav =
128 url: "/#{obj.ref}"
129
130 parents = navNode?.parents
131
132 # set nav path
133 if parents?
134 nav.path = {}
135 for node in parents
136 nav.path[node.$id] = true
137
138 # set breadcrumbs
139 obj.breadcrumbs = bc = parents?.map (node) ->
140 node.title
141 # TODO: this logic is twisted and should be improved
142 if navNode?.isDynamic
143 nav.title = HbHelper.render(navNode.titleTemplate, obj)
144 if bc?.length
145 bc[bc.length - 1] = nav.title
146 else
147 nav.title = navNode?.title
148
149 return exports