@peaceroad/markdown-it-footnote-here 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -6
- package/index.js +222 -182
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -26,21 +26,34 @@ HTML:
|
|
|
26
26
|
<p>A paragraph.</p>
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
+
Notice. When multiple instances of the same footnote number appear in the main content, the default behavior is that the backlink from the footnote will refer to the first instance.
|
|
30
|
+
|
|
29
31
|
## Use
|
|
30
32
|
|
|
31
33
|
```js
|
|
32
|
-
|
|
33
|
-
|
|
34
|
+
import mdit from 'markdown-it'
|
|
35
|
+
import mditFootnoteHere from '@peaceroad/markdown-it-footnote-here'
|
|
34
36
|
|
|
37
|
+
const md = mdit().use(mditFootnoteHere)
|
|
35
38
|
md.render(/*...*/) // See examples above
|
|
36
39
|
```
|
|
37
40
|
|
|
38
41
|
## Install
|
|
39
42
|
|
|
40
|
-
```
|
|
43
|
+
```samp
|
|
41
44
|
npm install @peaceroad/markdown-it-footnote-here
|
|
42
45
|
```
|
|
43
46
|
|
|
44
|
-
##
|
|
45
|
-
|
|
46
|
-
|
|
47
|
+
## Options
|
|
48
|
+
|
|
49
|
+
- beforeSameBacklink (boolean): false by default. When true, duplicate footnote references will use letter suffixes (a, b, c, ...) and generate matching backlinks in footnote definitions.
|
|
50
|
+
- afterBacklink (boolean): false by default. If true, backlinks (↩) are placed at the end of the footnote content instead of before it.
|
|
51
|
+
- afterBacklinkContent (string): The content for the backlink (default: '↩').
|
|
52
|
+
- afterBacklinkWithNumber (boolean): If true, backlink will show a number or letter suffix.
|
|
53
|
+
- afterBacklinkSuffixArabicNumerals (boolean): If true, backlink suffix uses numbers (1, 2, ...) instead of letters (a, b, ...).
|
|
54
|
+
- afterBacklinkdAriaLabelPrefix (string): Prefix for aria-label of backlink (default: 'Back to reference ').
|
|
55
|
+
- labelBra (string): Bracket to use before footnote number (default: '[').
|
|
56
|
+
- labelKet (string): Bracket to use after footnote number (default: ']').
|
|
57
|
+
- labelSupTag (boolean): If true, wraps footnote reference in `<sup>` tag.
|
|
58
|
+
- backLabelBra (string): Bracket to use before backlink number (default: '[').
|
|
59
|
+
- backLabelKet (string): Bracket to use after backlink number (default: ']').
|
package/index.js
CHANGED
|
@@ -1,248 +1,288 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
////////////////////////////////////////////////////////////////////////////////
|
|
6
|
-
// Renderer partials
|
|
7
|
-
|
|
8
|
-
function render_footnote_anchor_name(tokens, idx, options, env/*, slf*/) {
|
|
9
|
-
var n = Number(tokens[idx].meta.id + 1).toString();
|
|
10
|
-
var prefix = '';
|
|
11
|
-
|
|
1
|
+
const render_footnote_anchor_name = (tokens, idx, opt, env) => {
|
|
2
|
+
let n = tokens[idx].meta.id + 1
|
|
3
|
+
if (!opt.afterBacklinkSuffixArabicNumerals) n = Number(n).toString()
|
|
4
|
+
let prefix = ''
|
|
12
5
|
if (typeof env.docId === 'string') {
|
|
13
|
-
prefix = '-' + env.docId + '-'
|
|
6
|
+
prefix = '-' + env.docId + '-'
|
|
14
7
|
}
|
|
15
|
-
|
|
16
|
-
return prefix + n;
|
|
8
|
+
return prefix + n
|
|
17
9
|
}
|
|
18
10
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
11
|
+
const render_footnote_ref = (tokens, idx, opt, env) => {
|
|
12
|
+
const token = tokens[idx]
|
|
13
|
+
const id = token.meta.id
|
|
14
|
+
const n = id + 1
|
|
15
|
+
const footnotes = env.footnotes
|
|
16
|
+
footnotes._refCount = footnotes._refCount || {}
|
|
17
|
+
let refIdx = (footnotes._refCount[id] = (footnotes._refCount[id] || 0) + 1)
|
|
18
|
+
if (!opt.afterBacklinkSuffixArabicNumerals) {
|
|
19
|
+
refIdx = String.fromCharCode(96 + refIdx)
|
|
20
|
+
}
|
|
21
|
+
let suffix = ''
|
|
22
|
+
let label = `${opt.labelBra}${n}${opt.labelKet}`
|
|
23
|
+
if (footnotes.totalCounts && footnotes.totalCounts[id] > 1) {
|
|
24
|
+
suffix = '-' + refIdx
|
|
25
|
+
if (opt.beforeSameBacklink) {
|
|
26
|
+
label = `${opt.labelBra}${n}${suffix}${opt.labelKet}`
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
let refCont = `<a href="#fn${n}" id="fn-ref${n}${suffix}" class="fn-noteref" role="doc-noteref">${label}</a>`
|
|
30
|
+
if (opt.labelSupTag) refCont = `<sup class="fn-noteref-wrapper">${refCont}</sup>`
|
|
31
|
+
return refCont
|
|
23
32
|
}
|
|
24
33
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
34
|
+
const render_footnote_open = (tokens, idx, opt, env, slf) => {
|
|
35
|
+
const id = slf.rules.footnote_anchor_name(tokens, idx, opt, env, slf)
|
|
36
|
+
return `<aside id="fn${id}" class="fn" role="doc-footnote">\n`
|
|
37
|
+
}
|
|
29
38
|
|
|
30
|
-
|
|
39
|
+
const render_footnote_close = () => {
|
|
40
|
+
return `</aside>\n`
|
|
31
41
|
}
|
|
32
42
|
|
|
33
|
-
|
|
34
|
-
|
|
43
|
+
const render_footnote_anchor = (tokens, idx, opt, env) => {
|
|
44
|
+
const idNum = tokens[idx].meta.id
|
|
45
|
+
const n = idNum + 1
|
|
46
|
+
const footnotes = env.footnotes
|
|
47
|
+
const counts = footnotes && footnotes.totalCounts
|
|
48
|
+
if (opt.beforeSameBacklink && counts && counts[idNum] > 1) {
|
|
49
|
+
let links = ''
|
|
50
|
+
for (let i = 1; i <= counts[idNum]; i++) {
|
|
51
|
+
const suffix = '-' + String.fromCharCode(96 + i); // a, b, c ...
|
|
52
|
+
links += `<a href="#fn-ref${n}${suffix}" class="fn-backlink" role="doc-backlink">${opt.backLabelBra}${n}${suffix}${opt.backLabelKet}</a>`
|
|
53
|
+
}
|
|
54
|
+
return links + ' '
|
|
55
|
+
}
|
|
35
56
|
|
|
36
|
-
|
|
37
|
-
}
|
|
57
|
+
if (opt.afterBacklink) {
|
|
58
|
+
return `<span class="fn-label">${opt.backLabelBra}${n}${opt.backLabelKet}</span> `
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (counts && counts[idNum] > 1) {
|
|
62
|
+
return `<a href="#fn-ref${n}-a" class="fn-backlink" role="doc-backlink">${opt.backLabelBra}${n}${opt.backLabelKet}</a> `
|
|
63
|
+
}
|
|
38
64
|
|
|
39
|
-
|
|
40
|
-
return '</aside>\n';
|
|
65
|
+
return `<a href="#fn-ref${n}" class="fn-backlink" role="doc-backlink">${opt.backLabelBra}${n}${opt.backLabelKet}</a> `
|
|
41
66
|
}
|
|
42
67
|
|
|
43
|
-
function
|
|
44
|
-
|
|
45
|
-
if (
|
|
46
|
-
|
|
68
|
+
function createAfterBackLinkToken(state, counts, n, opt) {
|
|
69
|
+
let html = ' '
|
|
70
|
+
if (counts && counts > 1) {
|
|
71
|
+
for (let i = 1; i <= counts; i++) {
|
|
72
|
+
const suffixChar = opt.afterBacklinkSuffixArabicNumerals ? i : String.fromCharCode(96 + i)
|
|
73
|
+
const suffix = '-' + suffixChar
|
|
74
|
+
html += `<a href="#fn-ref${n}${suffix}" class="fn-backlink" role="doc-backlink"`
|
|
75
|
+
if (opt.afterBacklinkdAriaLabelPrefix) html += ` aria-label="${opt.afterBacklinkdAriaLabelPrefix}${n}${suffix}"`
|
|
76
|
+
html += `>${opt.afterBacklinkContent}`
|
|
77
|
+
if (opt.afterBacklinkWithNumber) {
|
|
78
|
+
html += `<sup>${suffixChar}</sup>`
|
|
79
|
+
}
|
|
80
|
+
html += `</a>`
|
|
81
|
+
}
|
|
82
|
+
} else {
|
|
83
|
+
html += `<a href="#fn-ref${n}" class="fn-backlink" role="doc-backlink"`
|
|
84
|
+
if (opt.afterBacklinkdAriaLabelPrefix) html += ` aria-label="${opt.afterBacklinkdAriaLabelPrefix}${n}"`
|
|
85
|
+
html += `>${opt.afterBacklinkContent}</a>`
|
|
47
86
|
}
|
|
48
|
-
|
|
87
|
+
const token = new state.Token('html_inline', '', 0)
|
|
88
|
+
token.content = html
|
|
89
|
+
return token
|
|
49
90
|
}
|
|
50
91
|
|
|
92
|
+
const footnote_plugin = (md, option) =>{
|
|
93
|
+
const opt = {
|
|
94
|
+
labelBra: '[',
|
|
95
|
+
labelKet: ']',
|
|
96
|
+
labelSupTag: false,
|
|
97
|
+
backLabelBra: '[',
|
|
98
|
+
backLabelKet: ']',
|
|
99
|
+
beforeSameBacklink: false,
|
|
100
|
+
afterBacklink: false,
|
|
101
|
+
afterBacklinkContent: '↩',
|
|
102
|
+
afterBacklinkWithNumber: false,
|
|
103
|
+
afterBacklinkSuffixArabicNumerals: false,
|
|
104
|
+
afterBacklinkdAriaLabelPrefix: 'Back to reference ', /* 戻る:本文参照 */
|
|
105
|
+
}
|
|
106
|
+
if (option) Object.assign(opt, option)
|
|
51
107
|
|
|
52
|
-
|
|
53
|
-
const parseLinkLabel = md.helpers.parseLinkLabel;
|
|
54
|
-
const isSpace = md.utils.isSpace;
|
|
55
|
-
|
|
56
|
-
md.renderer.rules.footnote_ref = render_footnote_ref;
|
|
57
|
-
md.renderer.rules.footnote_open = render_footnote_open;
|
|
58
|
-
md.renderer.rules.footnote_close = render_footnote_close;
|
|
59
|
-
md.renderer.rules.footnote_anchor = render_footnote_anchor;
|
|
108
|
+
const isSpace = md.utils.isSpace
|
|
60
109
|
|
|
61
|
-
|
|
62
|
-
md.renderer.rules.
|
|
63
|
-
md.renderer.rules.
|
|
110
|
+
md.renderer.rules.footnote_ref = (tokens, idx, _options, env) => render_footnote_ref(tokens, idx, opt, env)
|
|
111
|
+
md.renderer.rules.footnote_open = render_footnote_open
|
|
112
|
+
md.renderer.rules.footnote_close = render_footnote_close
|
|
113
|
+
md.renderer.rules.footnote_anchor = (tokens, idx, _options, env, slf) => render_footnote_anchor(tokens, idx, opt, env, slf)
|
|
114
|
+
md.renderer.rules.footnote_anchor_name = render_footnote_anchor_name
|
|
64
115
|
|
|
65
116
|
// Process footnote block definition
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
max = state.eMarks[startLine];
|
|
117
|
+
const footnote_def = (state, startLine, endLine, silent) => {
|
|
118
|
+
const bMarks = state.bMarks, tShift = state.tShift, eMarks = state.eMarks, src = state.src
|
|
119
|
+
const start = bMarks[startLine] + tShift[startLine]
|
|
120
|
+
const max = eMarks[startLine]
|
|
71
121
|
|
|
72
122
|
// line should be at least 5 chars - "[^x]:"
|
|
73
123
|
if (start + 4 > max) { return false; }
|
|
74
124
|
|
|
75
|
-
if (
|
|
76
|
-
if (state.src.charCodeAt(start + 1) !== 0x5E/* ^ */) { return false; }
|
|
77
|
-
|
|
78
|
-
for (pos = start + 2; pos < max; pos++) {
|
|
79
|
-
if (state.src.charCodeAt(pos) === 0x20) { return false; }
|
|
80
|
-
if (state.src.charCodeAt(pos) === 0x5D /* ] */) {
|
|
81
|
-
break;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
if (pos === start + 2) { return false; } // no empty footnote labels
|
|
86
|
-
if (pos + 1 >= max || state.src.charCodeAt(++pos) !== 0x3A /* : */) { return false; }
|
|
87
|
-
if (silent) { return true; }
|
|
88
|
-
pos++;
|
|
125
|
+
if (src.charCodeAt(start) !== 0x5B/* [ */ || src.charCodeAt(start + 1) !== 0x5E/* ^ */) { return false; }
|
|
89
126
|
|
|
90
|
-
|
|
91
|
-
|
|
127
|
+
// locate end of label efficiently
|
|
128
|
+
const idx = src.indexOf(']:', start + 2)
|
|
129
|
+
if (idx < start + 3 || idx > max - 2) { return false; }
|
|
92
130
|
|
|
93
|
-
label =
|
|
94
|
-
|
|
95
|
-
|
|
131
|
+
const label = src.slice(start + 2, idx)
|
|
132
|
+
if (label.indexOf(' ') >= 0) { return false; }
|
|
133
|
+
const pos = idx + 2
|
|
96
134
|
|
|
97
|
-
|
|
98
|
-
token.meta = { id: id, label: label };
|
|
99
|
-
token.level = state.level++;
|
|
100
|
-
state.tokens.push(token);
|
|
101
|
-
|
|
102
|
-
oldBMark = state.bMarks[startLine];
|
|
103
|
-
oldTShift = state.tShift[startLine];
|
|
104
|
-
oldSCount = state.sCount[startLine];
|
|
105
|
-
oldParentType = state.parentType;
|
|
106
|
-
|
|
107
|
-
posAfterColon = pos;
|
|
108
|
-
initial = offset = state.sCount[startLine] + pos - (state.bMarks[startLine] + state.tShift[startLine]);
|
|
109
|
-
|
|
110
|
-
/*
|
|
111
|
-
token = new state.Token('footnote_anchor', '', 0);
|
|
112
|
-
token.meta = { id: id, label: label };
|
|
113
|
-
state.tokens.push(token);
|
|
114
|
-
*/
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
while (pos < max) {
|
|
118
|
-
ch = state.src.charCodeAt(pos);
|
|
135
|
+
if (silent) { return true; }
|
|
119
136
|
|
|
137
|
+
// initialize footnotes environment once
|
|
138
|
+
if (!state.env.footnotes) {
|
|
139
|
+
state.env.footnotes = { length: 0, refs: {}, positions: [] }
|
|
140
|
+
}
|
|
141
|
+
const fn = state.env.footnotes
|
|
142
|
+
const id = fn.length++
|
|
143
|
+
fn.refs[':' + label] = id
|
|
144
|
+
|
|
145
|
+
const token = new state.Token('footnote_open', '', 1)
|
|
146
|
+
token.meta = { id, label }
|
|
147
|
+
token.level = state.level++
|
|
148
|
+
state.tokens.push(token)
|
|
149
|
+
fn.positions.push(state.tokens.length - 1)
|
|
150
|
+
|
|
151
|
+
const oldBMark = bMarks[startLine]
|
|
152
|
+
const oldTShift = tShift[startLine]
|
|
153
|
+
const oldSCount = state.sCount[startLine]
|
|
154
|
+
const oldParentType = state.parentType
|
|
155
|
+
|
|
156
|
+
const posAfterColon = pos
|
|
157
|
+
const initial = state.sCount[startLine] + pos - (bMarks[startLine] + tShift[startLine])
|
|
158
|
+
let offset = initial
|
|
159
|
+
let newPos = pos
|
|
160
|
+
|
|
161
|
+
while (newPos < max) {
|
|
162
|
+
const ch = src.charCodeAt(newPos)
|
|
120
163
|
if (isSpace(ch)) {
|
|
121
164
|
if (ch === 0x09) {
|
|
122
|
-
offset += 4 - offset % 4
|
|
165
|
+
offset += 4 - offset % 4
|
|
123
166
|
} else {
|
|
124
|
-
offset
|
|
167
|
+
offset++
|
|
125
168
|
}
|
|
126
169
|
} else {
|
|
127
|
-
break
|
|
170
|
+
break
|
|
128
171
|
}
|
|
129
|
-
|
|
130
|
-
pos++;
|
|
172
|
+
newPos++
|
|
131
173
|
}
|
|
132
174
|
|
|
133
|
-
state.tShift[startLine] =
|
|
134
|
-
state.sCount[startLine] = offset - initial
|
|
175
|
+
state.tShift[startLine] = newPos - posAfterColon
|
|
176
|
+
state.sCount[startLine] = offset - initial
|
|
135
177
|
|
|
136
|
-
state.bMarks[startLine] = posAfterColon
|
|
137
|
-
state.blkIndent += 4
|
|
138
|
-
state.parentType = 'footnote'
|
|
178
|
+
state.bMarks[startLine] = posAfterColon
|
|
179
|
+
state.blkIndent += 4
|
|
180
|
+
state.parentType = 'footnote'
|
|
139
181
|
|
|
140
182
|
if (state.sCount[startLine] < state.blkIndent) {
|
|
141
|
-
state.sCount[startLine] += state.blkIndent
|
|
183
|
+
state.sCount[startLine] += state.blkIndent
|
|
142
184
|
}
|
|
143
185
|
|
|
144
|
-
state.md.block.tokenize(state, startLine, endLine, true)
|
|
186
|
+
state.md.block.tokenize(state, startLine, endLine, true)
|
|
145
187
|
|
|
146
|
-
state.parentType = oldParentType
|
|
147
|
-
state.blkIndent -= 4
|
|
148
|
-
state.tShift[startLine] = oldTShift
|
|
149
|
-
state.sCount[startLine] = oldSCount
|
|
150
|
-
state.bMarks[startLine] = oldBMark
|
|
188
|
+
state.parentType = oldParentType
|
|
189
|
+
state.blkIndent -= 4
|
|
190
|
+
state.tShift[startLine] = oldTShift
|
|
191
|
+
state.sCount[startLine] = oldSCount
|
|
192
|
+
state.bMarks[startLine] = oldBMark
|
|
151
193
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
state.tokens.push(
|
|
194
|
+
const closeToken = new state.Token('footnote_close', '', -1)
|
|
195
|
+
closeToken.level = --state.level
|
|
196
|
+
state.tokens.push(closeToken)
|
|
155
197
|
|
|
156
|
-
return true
|
|
198
|
+
return true
|
|
157
199
|
}
|
|
158
200
|
|
|
159
201
|
// Process footnote references ([^...])
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
if (
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
if (
|
|
178
|
-
if (state.src.charCodeAt(pos) === 0x0A) { return false; }
|
|
179
|
-
if (state.src.charCodeAt(pos) === 0x5D /* ] */) {
|
|
180
|
-
break;
|
|
181
|
-
}
|
|
202
|
+
const footnote_ref = (state, silent) => {
|
|
203
|
+
const src = state.src
|
|
204
|
+
const start = state.pos
|
|
205
|
+
const posMax = state.posMax
|
|
206
|
+
if (start + 3 >= posMax) { return false; } // - "[^x]"
|
|
207
|
+
if (src.charCodeAt(start) !== 0x5B/* [ */ || src.charCodeAt(start + 1) !== 0x5E/* ^ */) {
|
|
208
|
+
return false
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const env = state.env
|
|
212
|
+
if (!env.footnotes || !env.footnotes.refs) { return false; }
|
|
213
|
+
|
|
214
|
+
let pos = start + 2
|
|
215
|
+
let found = false
|
|
216
|
+
for (; pos < posMax && !found; pos++) {
|
|
217
|
+
const ch = src.charCodeAt(pos)
|
|
218
|
+
if (ch === 0x20 || ch === 0x0A) { return false; } // space or linebreak
|
|
219
|
+
if (ch === 0x5D /* ] */) { found = true; break; }
|
|
182
220
|
}
|
|
183
221
|
|
|
184
|
-
if (pos === start + 2) { return false; }
|
|
185
|
-
|
|
186
|
-
pos++;
|
|
222
|
+
if (!found || pos === start + 2) { return false; }
|
|
223
|
+
pos++; // pos set next ']' position.
|
|
187
224
|
|
|
188
|
-
label =
|
|
189
|
-
|
|
225
|
+
const label = src.slice(start + 2, pos - 1)
|
|
226
|
+
const id = env.footnotes.refs[':' + label]
|
|
227
|
+
|
|
228
|
+
if (id === undefined) { return false; }
|
|
190
229
|
|
|
191
230
|
if (!silent) {
|
|
192
|
-
|
|
231
|
+
const fn = env.footnotes
|
|
193
232
|
|
|
233
|
+
if (!fn.list) { fn.list = []; }
|
|
194
234
|
|
|
195
|
-
|
|
196
|
-
|
|
235
|
+
const footnoteId = fn.list.length
|
|
236
|
+
fn.list[footnoteId] = { label, count: 0 }
|
|
197
237
|
|
|
198
|
-
|
|
238
|
+
fn.totalCounts = fn.totalCounts || {}
|
|
239
|
+
fn.totalCounts[id] = (fn.totalCounts[id] || 0) + 1
|
|
199
240
|
|
|
200
|
-
token
|
|
201
|
-
token.meta = { id
|
|
241
|
+
const token = state.push('footnote_ref', '', 0)
|
|
242
|
+
token.meta = { id, label }
|
|
202
243
|
}
|
|
203
244
|
|
|
204
|
-
state.pos = pos
|
|
205
|
-
|
|
206
|
-
return true;
|
|
245
|
+
state.pos = pos
|
|
246
|
+
return true
|
|
207
247
|
}
|
|
208
248
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
const
|
|
212
|
-
const
|
|
213
|
-
if (
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
classVal += ' ' + className;
|
|
220
|
-
token.attrs[i][1] = classVal;
|
|
221
|
-
}
|
|
249
|
+
const footnote_anchor = (state) => {
|
|
250
|
+
const tokens = state.tokens
|
|
251
|
+
const fn = state.env.footnotes
|
|
252
|
+
const positions = fn && fn.positions
|
|
253
|
+
if (!positions || positions.length === 0) { return; }
|
|
254
|
+
|
|
255
|
+
const createAnchorToken = (id) => {
|
|
256
|
+
const aToken = new state.Token('footnote_anchor', '', 0)
|
|
257
|
+
aToken.meta = { id, label: id + 1 }
|
|
258
|
+
return aToken
|
|
222
259
|
}
|
|
223
|
-
}
|
|
224
260
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
const
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
261
|
+
for (let j = 0, len = positions.length; j < len; ++j) {
|
|
262
|
+
const posOpen = positions[j]
|
|
263
|
+
if (posOpen + 2 >= tokens.length) continue
|
|
264
|
+
|
|
265
|
+
const t1 = tokens[posOpen + 1]
|
|
266
|
+
if (t1.type !== 'paragraph_open') continue
|
|
267
|
+
|
|
268
|
+
const t2 = tokens[posOpen + 2]
|
|
269
|
+
if (t2.type !== 'inline') continue
|
|
270
|
+
|
|
271
|
+
const t0 = tokens[posOpen]
|
|
272
|
+
const id = t0.meta.id
|
|
273
|
+
|
|
274
|
+
t2.children.unshift(createAnchorToken(id))
|
|
275
|
+
if (opt.afterBacklink) {
|
|
276
|
+
const n = id + 1
|
|
277
|
+
const counts = fn.totalCounts && fn.totalCounts[id]
|
|
278
|
+
t2.children.push(createAfterBackLinkToken(state, counts, n, opt))
|
|
240
279
|
}
|
|
241
|
-
n++;
|
|
242
280
|
}
|
|
243
281
|
}
|
|
244
282
|
|
|
245
|
-
md.block.ruler.before('reference', 'footnote_def', footnote_def, { alt: [ 'paragraph', 'reference' ] })
|
|
246
|
-
md.inline.ruler.after('image', 'footnote_ref', footnote_ref)
|
|
247
|
-
md.core.ruler.after('inline', 'footnote_anchor', footnote_anchor)
|
|
248
|
-
}
|
|
283
|
+
md.block.ruler.before('reference', 'footnote_def', footnote_def, { alt: [ 'paragraph', 'reference' ] })
|
|
284
|
+
md.inline.ruler.after('image', 'footnote_ref', footnote_ref)
|
|
285
|
+
md.core.ruler.after('inline', 'footnote_anchor', footnote_anchor)
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
export default footnote_plugin
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@peaceroad/markdown-it-footnote-here",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "A markdown-it plugin. This generate aside[role|doc-footnote] element just below the footnote reference paragraph.",
|
|
5
|
+
"type":"module",
|
|
5
6
|
"author": "peaceroad <peaceroad@gmail.com>",
|
|
6
7
|
"repository": "https://github.com/peaceroad/markdown-it-footnote-here.git",
|
|
7
8
|
"bugs": {
|
|
@@ -12,6 +13,6 @@
|
|
|
12
13
|
"test": "node test/test.js"
|
|
13
14
|
},
|
|
14
15
|
"devDependencies": {
|
|
15
|
-
"markdown-it": "^
|
|
16
|
+
"markdown-it": "^14.1.0"
|
|
16
17
|
}
|
|
17
18
|
}
|