-
Notifications
You must be signed in to change notification settings - Fork 713
/
Copy pathmarkdown.js
123 lines (115 loc) · 3.33 KB
/
markdown.js
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import markdownIt from 'markdown-it';
import markdownItContainer from 'markdown-it-container';
import { markdownItTable } from 'markdown-it-table';
import markdownItDefinitionList from 'markdown-it-deflist';
import markdownItAttrs from 'markdown-it-attrs';
import markdownItAnchor from 'markdown-it-anchor';
import { slugify } from '../utils/slugify.js';
/** @type {import('markdown-it/lib').MarkdownIt} */
export const markdown = (() => {
const markdown = markdownIt({ html: true })
.use(markdownItTable)
.use(markdownItDefinitionList)
.use(markdownItAttrs, {
leftDelimiter: '{:',
rightDelimiter: '}',
allowedAttributes: ['id', 'class', /^data-.*$/],
})
.use(markdownItAnchor, {
slugify: (s) => slugify(s),
level: 2,
tabIndex: false,
permalink: markdownItAnchor.permalink.ariaHidden({
space: true,
placement: 'after',
symbol: '#',
class: 'heading-link',
}),
});
_registerAsides(markdown);
_registerContainers(markdown);
return markdown;
})();
/**
* Register a custom aside/admonition.
*
* @param {import('markdown-it/lib').MarkdownIt} markdown
* @param id The name to use in Markdown to create the aside.
* @param defaultTitle The title to use if no title is specified in Markdown.
* @param icon The material icon to use in the aside.
* @param style The classes to add to the aside.
* @private
*/
function _registerAside(markdown, id, defaultTitle, icon, style) {
markdown.use(markdownItContainer, id, {
render: function (tokens, index) {
if (tokens[index].nesting === 1) {
const parsedArgs = /\s+(.*)/.exec(tokens[index].info);
const title = parsedArgs?.[1] ?? defaultTitle;
return `<aside class="alert ${style}">
<div class="alert-header">
${icon !== null ? `<i class="material-icons" aria-hidden="true">${icon}</i>` : ''}
<span>${title ?? ''}</span>
</div>
<div class="alert-content">
`;
} else {
return '</div></aside>\n';
}
},
});
}
/**
* Registers the custom asides/admonitions used on the site.
*
* @param {import('markdown-it/lib').MarkdownIt} markdown
* @private
*/
function _registerAsides(markdown) {
_registerAside(markdown, 'note', 'Note', 'info', 'alert-info');
_registerAside(
markdown,
'flutter-note',
'Flutter note',
'smartphone',
'alert-info',
);
_registerAside(
markdown,
'version-note',
'Version note',
'merge_type',
'alert-info',
);
_registerAside(markdown, 'tip', 'Tip', 'tips_and_updates', 'alert-success');
_registerAside(markdown, 'important', 'Important', 'error', 'alert-warning');
_registerAside(
markdown,
'warning',
'Warning',
'report_problem',
'alert-warning',
);
_registerAside(markdown, 'secondary', null, null, 'alert-secondary');
}
/**
* Registers custom containers used on the site.
*
* @param {import('markdown-it/lib').MarkdownIt} markdown
* @private
*/
function _registerContainers(markdown) {
// TODO(parlough): Consider removing all usages of mini-toc.
markdown.use(markdownItContainer, 'mini-toc', {
render: function (tokens, index) {
if (tokens[index].nesting === 1) {
const header = /\s+(.*)/.exec(tokens[index].info)[1];
return `<div class="mini-toc">
<h4 class="no_toc">${header}</h4>
`;
} else {
return '</div>\n';
}
},
});
}