@@ -179,15 +179,17 @@ buildDocs = (watch = no) ->
179
179
sectionsSourceFolder = ' documentation/sections'
180
180
examplesSourceFolder = ' documentation/examples'
181
181
outputFolder = " docs/v#{ majorVersion} "
182
+ searchCollections = docs : [], changelogs : []
183
+ {structure } = require " ./documentation/structure.coffee"
182
184
183
- # Helpers
184
- releaseHeader = (date , version , prevVersion ) ->
185
- monthNames = [' January' , ' February' , ' March' , ' April' , ' May' , ' June' , ' July' , ' August' , ' September' , ' October' , ' November' , ' December' ]
185
+ monthNames = [' January' , ' February' , ' March' , ' April' , ' May' , ' June' , ' July' , ' August' , ' September' , ' October' , ' November' , ' December' ]
186
186
187
- formatDate = (date ) ->
188
- date .replace / ^ (\d\d\d\d )-(\d\d )-(\d\d )$ / , (match , $1 , $2 , $3 ) ->
189
- " #{ monthNames[$2 - 1 ]} #{ + $3} , #{ $1} "
187
+ formatDate = (date ) ->
188
+ date .replace / ^ (\d\d\d\d )-(\d\d )-(\d\d )$ / , (match , $1 , $2 , $3 ) ->
189
+ " #{ monthNames[$2 - 1 ]} #{ + $3} , #{ $1} "
190
190
191
+ # Helpers
192
+ releaseHeader = (date , version , prevVersion ) ->
191
193
"""
192
194
<div class="anchor" id="#{ version} "></div>
193
195
<h2 class="header">
@@ -198,6 +200,69 @@ buildDocs = (watch = no) ->
198
200
199
201
codeFor = require " ./documentation/site/code.coffee"
200
202
203
+ # Template for search results.
204
+ searchResults = """
205
+ <div class="ds-suggestion">
206
+ <div class="cs-docsearch-suggestion cs-docsearch-suggestion__main cs-docsearch-suggestion__secondary" style="white-space: normal;">
207
+ <div class="cs-docsearch-suggestion--category-header">
208
+ <span class="cs-docsearch-suggestion--category-header-lvl0"><%= section %></span>
209
+ </div>
210
+ <%= results %>
211
+ </div>
212
+ </div>
213
+ """
214
+ # Template for search result item.
215
+ searchResultsList = """
216
+ <div class="cs-docsearch-suggestion--wrapper searchWrapper" data-href="<%= href %>">
217
+ <div class="cs-docsearch-suggestion--subcategory-column">
218
+ <span class="cs-docsearch-suggestion--subcategory-column-text">
219
+ <%= subsection %>
220
+ </span>
221
+ </div>
222
+ <div class="cs-docsearch-suggestion--content">
223
+ <div class="cs-docsearch-suggestion--title">
224
+ <%= title %>
225
+ </div>
226
+ <div class="cs-docsearch-suggestion--text"><%= content %></div>
227
+ </div>
228
+ </div>
229
+ """
230
+ searchResultsTemplate = _ .template (searchResults).source
231
+ searchResultsListTemplate = _ .template (searchResultsList).source
232
+
233
+ # Remove markup from content used for search collections
234
+ clean = (content ) ->
235
+ content
236
+ .replace / <[^ >] * >/ g , " " # remove HTML tags
237
+ .replace / \[ ([^ \] ] + )\]\( [^ \) ] + \) / g , " $1" # remove URL link
238
+ .replace / \* [^ \S ] + / g , " " # remove list markup
239
+ .replace / \*\* ? | __? | #+? / g , " " # remove Markdown format
240
+ .replace / \t | \n / g , " "
241
+ .replace / ^ \s + / g , " "
242
+
243
+ # Build search catalogue.
244
+ searchCatalogue = (mdDoc , section , data ) ->
245
+ return unless match = / ^ (#+? )\s + ([^ \n ] + )\s + ([\s\S ] + )/ .exec mdDoc
246
+ [, level , title , body ] = match
247
+ content = clean body
248
+ unless section is " changelog"
249
+ content = content .replace / ```[^ \` ] + ```/ g , " "
250
+ weight = level .length
251
+ searchCollections .docs .push {section, title, weight, content, data... }
252
+ else
253
+ # Break changelogs into (release) chunks.
254
+ releaseLogs = content .split / ```\s * releaseHeader\( ([^ \) ] + )\) \s * ```/
255
+ for rlog, ix in releaseLogs when ix % 2 isnt 0
256
+ data = rlog .replace (/ \\ ? '/ g , " " ).split / ,\s * /
257
+ date = formatDate data[0 ]
258
+ release = data[1 ]
259
+ searchCollections .changelogs .push
260
+ section : " Changelogs"
261
+ title : " #{ release} — #{ date} "
262
+ content : releaseLogs[ix + 1 ]
263
+ parent : " Changelogs"
264
+ href : " ##{ release} "
265
+
201
266
htmlFor = ->
202
267
hljs = require ' highlight.js'
203
268
hljs .configure classPrefix : ' '
@@ -212,7 +277,6 @@ buildDocs = (watch = no) ->
212
277
catch ex
213
278
return ' ' # No syntax highlighting
214
279
215
-
216
280
# Add some custom overrides to Markdown-It’s rendering, per
217
281
# https://github.com/markdown-it/markdown-it/blob/master/docs/architecture.md#renderer
218
282
defaultFence = markdownRenderer .renderer .rules .fence
@@ -223,11 +287,12 @@ buildDocs = (watch = no) ->
223
287
else
224
288
" <blockquote class=\" uneditable-code-block\" >#{ defaultFence .apply @ , arguments } </blockquote>"
225
289
226
- (file , bookmark ) ->
290
+ (file , searchData ) ->
227
291
md = fs .readFileSync " #{ sectionsSourceFolder} /#{ file} .md" , ' utf-8'
228
292
md = md .replace / <%= releaseHeader %>/ g , releaseHeader
229
293
md = md .replace / <%= majorVersion %>/ g , majorVersion
230
294
md = md .replace / <%= fullVersion %>/ g , CoffeeScript .VERSION
295
+ searchCatalogue md, file, searchData
231
296
html = markdownRenderer .render md
232
297
html = _ .template (html)
233
298
codeFor : codeFor ()
@@ -241,6 +306,64 @@ buildDocs = (watch = no) ->
241
306
code = transpile code
242
307
code
243
308
309
+ # Build body HTML.
310
+ buildBody = ->
311
+ sectionTemplate = """
312
+ <section id="<%= id %>">
313
+ <%= sectionBody %>
314
+ </section>
315
+ """
316
+ body = []
317
+ sectionTemplate = _ .template sectionTemplate
318
+ buildSection = (section ) ->
319
+ sectionTemplate section
320
+
321
+ for section in structure when section .html and section .html .length > 0
322
+ {id , title , html , href = no , children = []} = section
323
+ href = " ##{ id} " unless href
324
+ sectionBody = (@ htmlFor (h, {parent : title, href}) for h in html)
325
+ if children .length > 0
326
+ for child in children when child .html and child .html .length > 0
327
+ cHref = " ##{ child .id } " unless child .href
328
+ childBody = (@ htmlFor (h, {parent : title, href : cHref}) for h in child .html )
329
+ sectionBody .push buildSection {id : child .id , sectionBody : childBody .join (" " )}
330
+ body .push buildSection {id : section .id , sectionBody : sectionBody .join (" " )}
331
+
332
+ body .join " "
333
+
334
+ # Build sidebar HTML.
335
+ buildSidebar = ->
336
+ link = """
337
+ <a href="<%= href %>" class="nav-link<%= className %>" data-action="sidebar-nav"><%= title %></a>
338
+ """
339
+ nav = """
340
+ <nav class="nav flex-column">
341
+ <%= links %>
342
+ </nav>
343
+ """
344
+ sidebar = []
345
+ linkTemplate = _ .template link
346
+ navTemplate = _ .template nav
347
+ buildNav = (links ) ->
348
+ navTemplate links
349
+ buildLink = (link ) ->
350
+ link .className = " #{ link .className } " unless link .className is " "
351
+ linkTemplate link
352
+
353
+ for section in structure
354
+ {id, title, href = no , className = " " , children = []} = section
355
+ href = " ##{ id} " unless href
356
+ sidebar .push buildLink {title, href, className}
357
+ if children .length > 0
358
+ childLinks = []
359
+ for child in children
360
+ {id : cId, title : cTitle, href : cHref = no , className : cClassName = " " } = child
361
+ cHref = " ##{ cId} " unless cHref
362
+ childLinks .push buildLink {title : cTitle, href : cHref, className : cClassName}
363
+ sidebar .push buildNav {links : childLinks .join " " }
364
+
365
+ buildNav links : sidebar .join " "
366
+
244
367
include = ->
245
368
(file ) ->
246
369
file = " #{ siteSourceFolder} /#{ file} " unless ' /' in file
@@ -252,16 +375,23 @@ buildDocs = (watch = no) ->
252
375
majorVersion : majorVersion
253
376
fullVersion : CoffeeScript .VERSION
254
377
htmlFor : htmlFor ()
378
+ buildBody : buildBody
379
+ buildSidebar : buildSidebar
255
380
codeFor : codeFor ()
256
381
include : include ()
257
382
includeScript : includeScript ()
258
383
output
259
384
260
- # Task
261
385
do renderIndex = ->
262
386
render = _ .template fs .readFileSync (indexFile, ' utf-8' )
263
387
output = render
264
388
include : include ()
389
+ searchIdx = """
390
+ window.searchResultTemplate = #{ searchResultsTemplate} ;
391
+ window.searchResultsListTemplate = #{ searchResultsListTemplate} ;
392
+ window.searchCollections = #{ JSON .stringify searchCollections} ;
393
+ """
394
+ fs .writeFileSync " #{ outputFolder} /search_index.js" , searchIdx
265
395
fs .writeFileSync " #{ outputFolder} /index.html" , output
266
396
log ' compiled' , green, " #{ indexFile} → #{ outputFolder} /index.html"
267
397
try
0 commit comments