-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrenderMarkdown.js
More file actions
99 lines (90 loc) · 3.63 KB
/
renderMarkdown.js
File metadata and controls
99 lines (90 loc) · 3.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import { relative } from 'node:path'
import { padTable } from '@dr-js/core/module/common/format.js'
import { indentLine, forEachRegExpExec } from '@dr-js/core/module/common/string.js'
import { toPosixPath } from '@dr-js/core/module/node/fs/Path.js'
import { HOIST_LIST_KEY, EXPORT_LIST_KEY, EXPORT_HOIST_LIST_KEY } from './generate.js'
// check: https://gist.github.com/asabaylus/3071099
// [Export Path](#export-path)
// [Bin Option Format](#bin-option-format)
// [Strange Format](#strange---format)
// [Strange , , Format ALT](#strange---format-alt)
const getMarkdownHeaderLink = (
text,
link = text.trim().toLowerCase()
// borrow from marked: https://github.com/markedjs/marked/blob/v0.8.2/lib/marked.js#L1046
.replace(/<[!/a-z].*?>/ig, '')
.replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g, '')
.replace(/\s/g, '-')
) => `[${text}](#${link})`
const REGEXP_MARKDOWN_HEADER = /^#{1,6}(.+?)#*$/gm // TODO: will mis-match comment in bash, use `marked`?
const matchMarkdownHeader = (string) => {
const headerTextList = []
forEachRegExpExec(REGEXP_MARKDOWN_HEADER, string, ([ , group1 ]) => {
const headerText = group1.trim()
headerText && headerTextList.push(headerText)
})
return headerTextList
}
const renderMarkdownAutoAppendHeaderLink = (...markdownStringList) => {
const headerTextList = matchMarkdownHeader(markdownStringList.join('\n'))
return headerTextList.length ? [
...headerTextList.map((text) => `* ${getMarkdownHeaderLink(text)}`),
'',
...markdownStringList
] : []
}
const escapeMarkdownLink = (name) => name.replace(/_/g, '\\_')
const getMarkdownFileLink = (path) => `📄 [${escapeMarkdownLink(path)}](${path})`
const getMarkdownDirectoryLink = (path) => `📁 [${escapeMarkdownLink(path).replace(/\/*$/, '/')}](${path})`
const renderMarkdownBlockQuote = (text) => [
'> ```',
indentLine(text, '> '),
'> ```'
]
const renderMarkdownTable = ({
headerRow = [],
cellRowList = [],
padFuncList = [],
table = [
headerRow,
headerRow.map((_, index) => {
const pad = padFuncList[ index ]
return pad === 'L' ? ':----' : pad === 'R' ? '----:' : ':---:'
}),
...cellRowList
]
}) => [
'', // add empty line '' for better parser support
...padTable({ table, padFuncList, cellPad: ' | ', rowPad: '\n' }).split('\n')
.map((text) => `| ${text} |`)
]
const renderMarkdownExportPath = ({ exportInfoMap, rootPath }) => Object.entries(exportInfoMap)
.reduce((textList, [ path, value ]) => {
value[ EXPORT_LIST_KEY ] && textList.push(
`+ ${getMarkdownFileLink(`${toPosixPath(relative(rootPath, path))}.js`)}`,
` - ${value[ EXPORT_LIST_KEY ].map((text) => `\`${text}\``).join(', ')}`
)
return textList
}, [])
const renderMarkdownExportTree = ({ exportInfo, routeList }) => Object.entries(exportInfo)
.reduce((textList, [ key, value ]) => {
if (key === HOIST_LIST_KEY) {
// skip
} else if (key === EXPORT_LIST_KEY || key === EXPORT_HOIST_LIST_KEY) {
textList.push(`- ${value.map((text) => `\`${text}\``).join(', ')}`)
} else {
const childTextList = renderMarkdownExportTree({ exportInfo: value, routeList: [ ...routeList, key ] })
childTextList.length && textList.push(`- **${key}**`, ...childTextList.map((text) => ` ${text}`))
}
return textList
}, [])
export { // TODO: NOTE: all func name like `renderMarkdown*` should return Array, others should return String
getMarkdownHeaderLink,
escapeMarkdownLink,
getMarkdownFileLink, getMarkdownDirectoryLink,
renderMarkdownAutoAppendHeaderLink,
renderMarkdownBlockQuote,
renderMarkdownTable,
renderMarkdownExportPath,
renderMarkdownExportTree
}