@@ -179,15 +179,17 @@ buildDocs = (watch = no) ->
179179 sectionsSourceFolder = ' documentation/sections'
180180 examplesSourceFolder = ' documentation/examples'
181181 outputFolder = " docs/v#{ majorVersion} "
182+ searchCollections = docs : [], changelogs : []
183+ {structure } = require " ./documentation/structure.coffee"
182184
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' ]
186186
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} "
190190
191+ # Helpers
192+ releaseHeader = (date , version , prevVersion ) ->
191193 """
192194 <div class="anchor" id="#{ version} "></div>
193195 <h2 class="header">
@@ -198,6 +200,69 @@ buildDocs = (watch = no) ->
198200
199201 codeFor = require " ./documentation/site/code.coffee"
200202
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+
201266 htmlFor = ->
202267 hljs = require ' highlight.js'
203268 hljs .configure classPrefix : ' '
@@ -212,7 +277,6 @@ buildDocs = (watch = no) ->
212277 catch ex
213278 return ' ' # No syntax highlighting
214279
215-
216280 # Add some custom overrides to Markdown-It’s rendering, per
217281 # https://github.com/markdown-it/markdown-it/blob/master/docs/architecture.md#renderer
218282 defaultFence = markdownRenderer .renderer .rules .fence
@@ -223,11 +287,12 @@ buildDocs = (watch = no) ->
223287 else
224288 " <blockquote class=\" uneditable-code-block\" >#{ defaultFence .apply @ , arguments } </blockquote>"
225289
226- (file , bookmark ) ->
290+ (file , searchData ) ->
227291 md = fs .readFileSync " #{ sectionsSourceFolder} /#{ file} .md" , ' utf-8'
228292 md = md .replace / <%= releaseHeader %>/ g , releaseHeader
229293 md = md .replace / <%= majorVersion %>/ g , majorVersion
230294 md = md .replace / <%= fullVersion %>/ g , CoffeeScript .VERSION
295+ searchCatalogue md, file, searchData
231296 html = markdownRenderer .render md
232297 html = _ .template (html)
233298 codeFor : codeFor ()
@@ -241,6 +306,64 @@ buildDocs = (watch = no) ->
241306 code = transpile code
242307 code
243308
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+
244367 include = ->
245368 (file ) ->
246369 file = " #{ siteSourceFolder} /#{ file} " unless ' /' in file
@@ -252,16 +375,23 @@ buildDocs = (watch = no) ->
252375 majorVersion : majorVersion
253376 fullVersion : CoffeeScript .VERSION
254377 htmlFor : htmlFor ()
378+ buildBody : buildBody
379+ buildSidebar : buildSidebar
255380 codeFor : codeFor ()
256381 include : include ()
257382 includeScript : includeScript ()
258383 output
259384
260- # Task
261385 do renderIndex = ->
262386 render = _ .template fs .readFileSync (indexFile, ' utf-8' )
263387 output = render
264388 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
265395 fs .writeFileSync " #{ outputFolder} /index.html" , output
266396 log ' compiled' , green, " #{ indexFile} → #{ outputFolder} /index.html"
267397 try
0 commit comments