From ade5690e85faf18a682e8d0a21df84a7e38c7c1d Mon Sep 17 00:00:00 2001 From: "Igor S. Morozov" Date: Mon, 26 Mar 2018 18:53:10 +0300 Subject: [PATCH] Improve webhook navigation --- package-lock.json | 2 +- package.json | 5 +-- src/main.coffee | 92 +++++++++++++++++++++++++++++++++++--------- templates/mixins.pug | 24 +++++++----- templates/scripts.js | 2 +- 5 files changed, 92 insertions(+), 33 deletions(-) diff --git a/package-lock.json b/package-lock.json index 24be3c3..234f4d9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "aglio-theme-planado", - "version": "3.2.0", + "version": "3.4.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 11ecefd..d9bd585 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,12 @@ { "name": "aglio-theme-planado", - "version": "3.3.0", + "version": "3.4.0", "description": "Custom theme for the Aglio API Blueprint renderer", "main": "lib/main.js", "scripts": { "build": "coffeelint src/*.coffee && coffee -o lib -c src", "precoverage": "npm run build", - "coverage": - "istanbul cover -x cache/*.js _mocha -- --compilers coffee:coffeescript/register -R spec", + "coverage": "istanbul cover -x cache/*.js _mocha -- --compilers coffee:coffeescript/register -R spec", "precoveralls": "npm run coverage", "coveralls": "coveralls uri , []).join('').replace(/\/+/g, '/') +prepareNav = (navigation) -> + navigation.map( + ([tag, title, id, children]) -> + link: "#" + id[1], + title: title, + children: prepareNav(children) + ) + decorate = (api, md, slugCache, verbose) -> # Decorate an API Blueprint AST with various pieces of information that # will be useful for the theme. Anything that would significantly @@ -342,34 +350,22 @@ decorate = (api, md, slugCache, verbose) -> if verbose console.log "Known data structures: #{Object.keys(dataStructures)}" - findListsAndRender = (content) -> - finalHtml = '' - for section in content.split '' - for section2 in section.split '' - finalHtml += md.render section2 - slugCache._nav.push ['ENDLIST'] - slugCache._nav.pop() - slugCache._nav.push ['STARTLIST'] - slugCache._nav.pop() - finalHtml - # API overview description” if api.description content_sections = api.description.split '' api.descriptionHtml = [] - slugCache._nav = [] - api.descriptionHtml.push([findListsAndRender content_sections[0]]) + api.descriptionHtml.push([md.render content_sections[0]]) for section in content_sections.slice 1 do -> sides = section.split '' [sides[1], rest] = sides[1].split '' - sidesContent = (findListsAndRender(side) for side in sides) + sidesContent = (md.render(side) for side in sides) api.descriptionHtml.push sidesContent - api.descriptionHtml.push [findListsAndRender rest] + api.descriptionHtml.push [md.render rest] - api.navItems = slugCache._nav + api.navItems = prepareNav(slugCache._nav) slugCache._nav = [] for meta in api.metadata or [] @@ -535,6 +531,63 @@ exports.render = (input, options, done) -> if options.themeTemplate is 'default' options.themeTemplate = path.join ROOT, 'templates', 'index.pug' + collectNavigationData = (md, opts) -> + # How it works: + # 1. We attach the function *after* all H-tags are processed + # 2. Those tags have `id` as an attribute + # 3. We build a nested list of items (pretty lispy) + # 4. We convert the list into a dict-like structure and render it + noop = () -> [] + setupCallback = if opts && opts.callback then opts.callback else noop + originalHeadingOpen = md.renderer.rules.heading_open + navigation = [] + + setupCallback(navigation) + + getHeadingLevel = (heading) -> + parseInt(heading[1]) # 'h1' -> 1, etc. + + + recursivelyAdd = (navigation, item) -> + [..., parent] = navigation + + if parent and parent.length > 0 + [parent_tag, parent_title, parent_id, parent_children] = parent + [item_tag, ...] = item + + parent_level = getHeadingLevel(parent_tag) + item_level = getHeadingLevel(item_tag) + + if parent_level < item_level # higher level = child + recursivelyAdd(parent_children, item) + else + navigation.push(item) + else + navigation.push(item) + + md.renderer.rules.heading_open = ( + tokens, + idx, + something, + somethingelse, + self + ) -> + title = tokens[idx + 1].children.reduce((acc, t) -> + acc + t.content + , "").replace(" ¶", "") + + tag = tokens[idx].tag + id = tokens[idx].attrs.find(([key, _]) -> key == "id") + + item = [tag, title, id, []] + + recursivelyAdd(navigation, item) + + if (originalHeadingOpen) + originalHeadingOpen.apply(this, arguments) + else + self.renderToken.apply(self, arguments) + # Setup markdown with code highlighting and smartypants. This also enables # automatically inserting permalinks for headers. slugCache = @@ -544,13 +597,16 @@ exports.render = (input, options, done) -> linkify: true typographer: true highlight: highlight - ).use(require('markdown-it-anchor'), + ).use(require('markdown-it-anchor'), slugify: (value) -> output = "header-#{slug(slugCache, value, true)}" - slugCache._nav.push [value, "##{output}"] return output permalink: true permalinkClass: 'permalink' + ).use( + collectNavigationData, + callback: (navigation) -> + slugCache._nav = navigation ).use(require('markdown-it-checkbox') ).use(require('markdown-it-container'), 'note' ).use(require('markdown-it-container'), 'warning') diff --git a/templates/mixins.pug b/templates/mixins.pug index d57e9c3..5c8647b 100644 --- a/templates/mixins.pug +++ b/templates/mixins.pug @@ -24,16 +24,20 @@ mixin Nav() //- resources and actions. nav if self.api.navItems && self.api.navItems.length - .resource-group - .heading - .chevron - i.open.fa.fa-angle-down - a(href='#top') - != self.locale.navigation - .collapse-content - ul: each item in self.api.navItems - li - a(href=item[1])!= item[0] + each category in self.api.navItems + .resource-group + .heading + a(href=category.link) + != category.title + .collapse-content + ul: each item in category.children + li + a(href=item.link)!= item.title + + if item.children.length > 0 + ul: each child in item.children + li + a(href=child.link)!= child.title each resourceGroup in self.api.resourceGroups || [] .resource-group .heading diff --git a/templates/scripts.js b/templates/scripts.js index 3450e39..c10a51e 100644 --- a/templates/scripts.js +++ b/templates/scripts.js @@ -210,7 +210,7 @@ function init() { // Make nav items clickable to collapse/expand their content. var navItems = document.querySelectorAll("nav .resource-group .heading"); for (i = 0; i < navItems.length; i++) { - navItems[i].onclick = toggleCollapseNav; + // navItems[i].onclick = toggleCollapseNav; // Show all by default toggleCollapseNav({ target: navItems[i].children[0] });