Skip to content

Commit e3baf62

Browse files
committed
refactor search index
1 parent 067b5dd commit e3baf62

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+2290
-1430
lines changed

Cakefile

+49-114
Original file line numberDiff line numberDiff line change
@@ -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} &mdash; #{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

Comments
 (0)