-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
146 lines (131 loc) · 3.82 KB
/
index.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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
'use strict'
// Load plugins
const typography = require('markdown-it-replacements')
// Set typographic replacements
typography.replacements.push({
name: 'copyright',
re: /\([cC]\)/mg,
sub: '©',
default: true,
})
typography.replacements.push({
name: 'trademark',
re: /\((?:tm|TM)\)/mg,
sub: '™',
default: true,
})
typography.replacements.push({
name: 'registered',
re: /\([rR]\)/mg,
sub: '®',
default: true,
})
typography.replacements.push({
name: 'mdash2',
re: /(^|[^-])---?([^-])/mg,
sub: '$1\u2014$2',
default: true,
})
typography.replacements.push({
name: 'mdash2',
re: /([^-])---?([^-]|$)/mg,
sub: '$1\u2014$2',
default: true,
})
typography.replacements.push({
name: 'mdash2',
re: /(^|[^-\s])---?([^-\s])/mg,
sub: '$1\u2014$2',
default: true,
})
typography.replacements.push({
name: 'mdash2',
re: /([^-\s])---?([^-\s]|$)/mg,
sub: '$1\u2014$2',
default: true,
})
// Catch em-dashes surrounded by spaces
typography.replacements.push({
name: 'mdash2',
re: /(^|[^-]) (?:--|—) ([^-]|$)/mg,
sub: '$1\u2014$2',
default: true,
})
// Load markdown
const md = require('markdown-it')('commonmark', {
typographer: true,
})
.enable(['linkify', 'smartquotes', 'replacements'])
.disable(['backticks'])
.use(require('markdown-it-footnote'))
.use(require('markdown-it-macron-underline'))
.use(require('markdown-it-indented-quotes'))
.use(require('markdown-it-flat-lists'))
.use(require('markdown-it-pagenumbers'))
.use(require('markdown-it-underline'))
.use(require('markdown-it-attrs'), {
allowedAttributes: ['id', 'class', /^(¶|data)/],
})
.use(typography, {
plusminus: false,
ellipsis: false,
ndash: false,
mdash: false,
})
function flatten(state) {
let i = 0
let token
let classes = []
let blockquoteLevel = 0
let listLevel = 0
let stubs = {}
let lastParagraph = {}
for (; i < state.tokens.length; i++) {
token = state.tokens[i]
// Capture level information from blockquote and list tokens
if (token.type === 'blockquote_open') {
blockquoteLevel += token.nesting
if (token.attrs && token.attrs.length) {
stubs[blockquoteLevel] = new state.Token()
stubs[blockquoteLevel].attrs = token.attrs
}
}
else if (token.type === 'blockquote_close') {
if (lastParagraph[blockquoteLevel] && stubs[blockquoteLevel]) {
for (let x = 0; x < stubs[blockquoteLevel].attrs.length; x++) {
state.tokens[lastParagraph[blockquoteLevel]].attrJoin(stubs[blockquoteLevel].attrs[x][0], stubs[blockquoteLevel].attrs[x][1])
}
stubs[blockquoteLevel + 1] = null
}
blockquoteLevel += token.nesting
}
else if (token.type.indexOf('_list_') > -1) listLevel += token.nesting
// Add proper classes to content tokens
if (token.tag === 'p' ||
token.tag === 'div' ||
token.type === 'fence' ||
token.tag === 'pre') {
if (token.type.indexOf('_close') === -1) {
classes = []
// Add blockquote class (list classes are handled by markdown-it-flat-lists)
if (blockquoteLevel) {
classes.push('blockquote')
classes.push('bq-' + blockquoteLevel)
}
// Add indent level
if (blockquoteLevel || listLevel) classes.push(`indent-${blockquoteLevel + listLevel}`)
// Add classes to token
if (classes.length) state.tokens[i].attrJoin('class', classes.join(' '))
// Remember last paragraph for possible blockquote attributes
if (blockquoteLevel) lastParagraph[blockquoteLevel] = i
}
// do not hide content tokens
state.tokens[i].hidden = false
}
}
}
function noRender() { return '' }
md.core.ruler.after('curly_attributes', 'flatten', flatten)
md.renderer.rules.blockquote_open = noRender
md.renderer.rules.blockquote_close = noRender
module.exports = md