git ssb

2+

cel / scuttlebot.io



Tree: b943b01f452dcc8c932c81886d0346f7a38269e4

Files: b943b01f452dcc8c932c81886d0346f7a38269e4 / markdown.js

3697 bytesRaw
1var fs = require('fs')
2var remark = require('remark')
3var html = require('remark-html')
4var slug = require('remark-slug')
5var autolinkHeadings = require('remark-autolink-headings')
6var com = require('./tmpl/com.part')
7var select = require('unist-util-select')
8var ssbRef = require('ssb-ref')
9
10const linkSvg = '<svg aria-hidden="true" class="octicon octicon-link" height="16" role="img" version="1.1" viewBox="0 0 16 16" width="16"><path d="M4 9h1v1h-1c-1.5 0-3-1.69-3-3.5s1.55-3.5 3-3.5h4c1.45 0 3 1.69 3 3.5 0 1.41-0.91 2.72-2 3.25v-1.16c0.58-0.45 1-1.27 1-2.09 0-1.28-1.02-2.5-2-2.5H4c-0.98 0-2 1.22-2 2.5s1 2.5 2 2.5z m9-3h-1v1h1c1 0 2 1.22 2 2.5s-1.02 2.5-2 2.5H9c-0.98 0-2-1.22-2-2.5 0-0.83 0.42-1.64 1-2.09v-1.16c-1.09 0.53-2 1.84-2 3.25 0 1.81 1.55 3.5 3 3.5h4c1.45 0 3-1.69 3-3.5s-1.5-3.5-3-3.5z"></path></svg>'
11
12module.exports.doc = function (path) {
13 var text = fs.readFileSync(path, 'utf-8')
14 return remark()
15 .use(slug)
16 .use(autolinkHeadings, {
17 attributes: { class: 'anchor' },
18 template: linkSvg
19 })
20 .use(html)
21 .use(injectTOC)
22 .use(transformCodeExamples)
23 .use(transformSsbLinks)
24 .process(text)
25}
26
27// find all h2s and create a dropdown table-of-contents
28function injectTOC (remark, options) {
29 remark.Compiler.prototype.visitors.tableOfContents = renderTOC
30 return ast => {
31 var headings = ast.children.filter(node => node.type == 'heading' && node.depth == 2)
32 if (headings.length > 3)
33 createTOC(ast, headings)
34 return ast
35 }
36}
37
38// add the tableOfContents node to the ast
39function createTOC (ast, headings) {
40 ast.children.unshift({ type: 'tableOfContents', children: headings })
41}
42
43// render the tableOfContents widget
44function renderTOC (node, root) {
45 return com.tableOfContents(node.children)
46}
47
48// find any <code> sections and group them together into our code-examples component
49function transformCodeExamples (remark, options) {
50 remark.Compiler.prototype.visitors.codeExamples = renderCodeExamples
51 return ast => {
52 var groups = findCodeGroupings(ast)
53 createCodeExamples(ast, groups)
54 return ast
55 }
56}
57
58// locate the contiguous <code> groupings
59function findCodeGroupings (ast) {
60 var groups = [], groupStart = false
61 ast.children.forEach((node, i) => {
62 if (groupStart) {
63 // in a grouping, look for a non-code item
64 if (node.type !== 'code' || !node.lang) {
65 groups.push([groupStart, i])
66 groupStart = false
67 }
68 } else {
69 // not in a grouping, look for a code item
70 if (node.type === 'code' && node.lang) {
71 groupStart = i
72 }
73 }
74 })
75 if (groupStart)
76 groups.push([groupStart, ast.children.length])
77 return groups
78}
79
80// replace <code> groupings with code-example nodes
81function createCodeExamples (ast, groups) {
82 var offset = 0 // offset to counter the changes introduced by splices
83 groups.forEach(group => {
84 var start = group[0], end = group[1]
85 var len = end - start
86 ast.children.splice(start-offset, len, {
87 type: 'codeExamples',
88 children: ast.children.slice(start-offset, start-offset+len),
89 position: false // TODO - needed? doesnt look like it
90 })
91 offset += len - 1
92 })
93}
94
95// convert from AST to html
96function renderCodeExamples (node, root) {
97 var codes = {}
98 node.children.forEach(node => {
99 if (node.type == 'code' && !!node.lang)
100 codes[node.lang] = node.value
101 })
102
103 return com.code(codes)
104}
105
106// add a prefix to links to ssb refs
107function transformSsbLinks (remark, options) {
108 return ast => {
109 select(ast, "link").forEach(link => {
110 if (ssbRef.isLink(link.url)) {
111 link.url = 'https://git.scuttlebot.io/' + link.url
112 }
113 })
114 return ast
115 }
116}
117

Built with git-ssb-web