@@ -179,11 +179,11 @@ buildDocs = (watch = no) ->
179179 sectionsSourceFolder = ' documentation/sections'
180180 examplesSourceFolder = ' documentation/examples'
181181 outputFolder = " docs/v#{ majorVersion} "
182- { structure } = require " ./documentation/structure.coffee "
182+ cheerio = require " cheerio "
183183
184- searchCollections =
185- docs : []
186- changelogs : []
184+ searchCollection =
185+ tree : {}
186+ data : []
187187
188188 # Helpers
189189 releaseHeader = (date , version , prevVersion ) ->
@@ -193,8 +193,8 @@ buildDocs = (watch = no) ->
193193 </h3>
194194 """
195195
196- monthNames = [' January' , ' February' , ' March' , ' April' , ' May' , ' June' , ' July' , ' August' , ' September' , ' October' , ' November' , ' December' ]
197196 formatDate = (date ) ->
197+ monthNames = [' January' , ' February' , ' March' , ' April' , ' May' , ' June' , ' July' , ' August' , ' September' , ' October' , ' November' , ' December' ]
198198 date .replace / ^ (\d\d\d\d )-(\d\d )-(\d\d )$ / , (match , $1 , $2 , $3 ) ->
199199 " #{ monthNames[$2 - 1 ]} #{ + $3} , #{ $1} "
200200
@@ -213,12 +213,7 @@ buildDocs = (watch = no) ->
213213 """
214214 # Template for search result item.
215215 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>
216+ <div class="cs-docsearch-suggestion--wrapper searchWrapper" data-href="<%= section %>">
222217 <div class="cs-docsearch-suggestion--content">
223218 <div class="cs-docsearch-suggestion--title">
224219 <%= title %>
@@ -230,39 +225,46 @@ buildDocs = (watch = no) ->
230225 searchResultsTemplate = _ .template (searchResults).source
231226 searchResultsListTemplate = _ .template (searchResultsList).source
232227
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-
243228 # Build search catalog.
244- searchCatalog = (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- {parent , href } = data
252- searchCollections .docs .push {section, title, weight, content, parent, href}
253- else
254- # Break changelogs into (release) chunks.
255- releaseLogs = content .split / ```\s * releaseHeader\( ([^ \) ] + )\) \s * ```/
256- for rlog, ix in releaseLogs when ix % 2 isnt 0
257- data = rlog .replace (/ \\ ? '/ g , " " ).split / ,\s * /
258- date = formatDate data[0 ]
259- release = data[1 ]
260- searchCollections .changelogs .push
261- section : " Changelogs"
262- title : " #{ release} — #{ date} "
263- content : releaseLogs[ix + 1 ]
264- parent : " Changelogs"
265- href : " ##{ release} "
229+ buildSearchCatalog = (html ) ->
230+ $ = cheerio .load html
231+ parseSectionContent = (section , level ) ->
232+ sectionId = $ (section).attr " id"
233+ header = " > h#{ level + 1 } "
234+ # Chagelogs subsections, e.g. <a>2.3.0</a> - <time>May 21, 2018</time>
235+ version = $ (" #{ header} a" , section).text ()
236+ date = $ (" #{ header} span time" , section).text ()
237+ title = if version and date then " #{ version} - #{ date} " else $ (header, section).text ()
238+ dataLevel = $ (section).data (" level" ) or no
239+ content = $ (" :not(section)" , section).text ()
240+ .replace /// ^ #{ title} /// , " " # Remove title from the content.
241+ .replace / \n + / g , " " # Convertnewlines into spaces.
242+ .replace / ^ (?:\t | \s )+ / g , " " # Remove extra spaces.
243+ {section : sectionId, title, content, dataLevel}
244+
245+ addCollection = ({el, level, parent = no }) ->
246+ {section , title , dataLevel } = data = {parseSectionContent (el, level)... , level, parent}
247+ if not dataLevel and parent
248+ dataLevel = searchCollection .tree [parent].dataLevel
249+ searchCollection .tree [section] = {title, parent, dataLevel}
250+ searchCollection .data .push {data... , dataLevel}
251+ section
252+
253+ parseSections = (sections , level = 1 , parent = no ) ->
254+ # Level 1, e.g. main > section
255+ sections .each (i, el) ->
256+ section = addCollection {el, level, parent}
257+ # Level 2, e.g. main > section > section
258+ subSections = $ (" section" , el)
259+ if subSections ? .length > 1
260+ parseSections subSections, level + 1 , section
261+
262+ parseSections $ (" main.main > section" )
263+ """
264+ window.searchResultTemplate = #{ searchResultsTemplate} ;
265+ window.searchResultsListTemplate = #{ searchResultsListTemplate} ;
266+ window.searchCollection = #{ JSON .stringify searchCollection} ;
267+ """
266268
267269 htmlFor = ->
268270 hljs = require ' highlight.js'
@@ -293,7 +295,6 @@ buildDocs = (watch = no) ->
293295 md = md .replace / <%= releaseHeader %>/ g , releaseHeader
294296 md = md .replace / <%= majorVersion %>/ g , majorVersion
295297 md = md .replace / <%= fullVersion %>/ g , CoffeeScript .VERSION
296- searchCatalog md, file, searchData
297298 html = markdownRenderer .render md
298299 html = _ .template (html)
299300 codeFor : codeFor ()
@@ -307,64 +308,6 @@ buildDocs = (watch = no) ->
307308 code = transpile code
308309 code
309310
310- # Build body HTML.
311- buildBody = ->
312- sectionTemplate = """
313- <section id="<%= id %>">
314- <%= sectionBody %>
315- </section>
316- """
317- body = []
318- sectionTemplate = _ .template sectionTemplate
319- buildSection = (section ) ->
320- sectionTemplate section
321-
322- for section in structure when section .html and section .html .length > 0
323- {id , title , html , href = no , children = []} = section
324- href = " ##{ id} " unless href
325- sectionBody = (@ htmlFor (h, {parent : title, href}) for h in html)
326- if children .length > 0
327- for child in children when child .html and child .html .length > 0
328- cHref = " ##{ child .id } " unless child .href
329- childBody = (@ htmlFor (h, {parent : title, href : cHref}) for h in child .html )
330- sectionBody .push buildSection {id : child .id , sectionBody : childBody .join (" " )}
331- body .push buildSection {id : section .id , sectionBody : sectionBody .join (" " )}
332-
333- body .join " "
334-
335- # Build sidebar HTML.
336- buildSidebar = ->
337- link = """
338- <a href="<%= href %>" class="nav-link<%= className %>" data-action="sidebar-nav"><%= title %></a>
339- """
340- nav = """
341- <nav class="nav flex-column">
342- <%= links %>
343- </nav>
344- """
345- sidebar = []
346- linkTemplate = _ .template link
347- navTemplate = _ .template nav
348- buildNav = (links ) ->
349- navTemplate links
350- buildLink = (link ) ->
351- link .className = " #{ link .className } " unless link .className is " "
352- linkTemplate link
353-
354- for section in structure
355- {id, title, href = no , className = " " , children = []} = section
356- href = " ##{ id} " unless href
357- sidebar .push buildLink {title, href, className}
358- if children .length > 0
359- childLinks = []
360- for child in children
361- {id : cId, title : cTitle, href : cHref = no , className : cClassName = " " } = child
362- cHref = " ##{ cId} " unless cHref
363- childLinks .push buildLink {title : cTitle, href : cHref, className : cClassName}
364- sidebar .push buildNav {links : childLinks .join " " }
365-
366- buildNav links : sidebar .join " "
367-
368311 include = ->
369312 (file ) ->
370313 file = " #{ siteSourceFolder} /#{ file} " unless ' /' in file
@@ -376,25 +319,17 @@ buildDocs = (watch = no) ->
376319 majorVersion : majorVersion
377320 fullVersion : CoffeeScript .VERSION
378321 htmlFor : htmlFor ()
379- buildBody : buildBody
380- buildSidebar : buildSidebar
381322 codeFor : codeFor ()
382323 include : include ()
383324 includeScript : includeScript ()
384325 output
385326
386327 do renderIndex = ->
387328 render = _ .template fs .readFileSync (indexFile, ' utf-8' )
388- output = render
389- include : include ()
390- searchIdx = """
391- window.searchResultTemplate = #{ searchResultsTemplate} ;
392- window.searchResultsListTemplate = #{ searchResultsListTemplate} ;
393- window.searchCollections = #{ JSON .stringify searchCollections} ;
394- window.initializeSearch();
395- """
396- fs .writeFileSync " #{ outputFolder} /search-index.js" , searchIdx
397- log ' output' , green, " #{ outputFolder} /search-index.js"
329+ output = render include : include ()
330+ searchIndex = buildSearchCatalog output
331+ fs .writeFileSync " #{ outputFolder} /search-index.js" , searchIndex
332+ log ' compiled' , green, " search index → #{ outputFolder} /search-index.js"
398333 fs .writeFileSync " #{ outputFolder} /index.html" , output
399334 log ' compiled' , green, " #{ indexFile} → #{ outputFolder} /index.html"
400335 try
0 commit comments