@peaceroad/markdown-it-footnote-here 0.2.1 → 0.3.1

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.
Files changed (3) hide show
  1. package/README.md +35 -1
  2. package/index.js +211 -81
  3. package/package.json +6 -1
package/README.md CHANGED
@@ -28,6 +28,34 @@ HTML:
28
28
 
29
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
30
 
31
+ ## Endnotes
32
+
33
+ When a footnote label starts with the endnote prefix (default: `en-`), it is collected at the end of the document and rendered as endnotes. The reference/backlink label for endnotes is prefixed by `endnotesLabelPrefix` (default: `E`), so endnotes appear as `[E1]`, `[E2]`, ...
34
+
35
+ Markdown:
36
+
37
+ ```md
38
+ A paragraph.[^en-1]
39
+
40
+ [^en-1]: A endnote.
41
+
42
+ A paragraph.
43
+ ```
44
+
45
+ HTML:
46
+
47
+ ```html
48
+ <p>A paragraph.<a href="#en1" id="en-ref1" class="en-noteref" role="doc-noteref">[E1]</a></p>
49
+ <p>A paragraph.</p>
50
+ <section aria-label="Notes" id="endnotes" role="doc-endnotes">
51
+ <ol>
52
+ <li id="en1">
53
+ <p><a href="#en-ref1" class="en-backlink" role="doc-backlink">[E1]</a> A endnote.</p>
54
+ </li>
55
+ </ol>
56
+ </section>
57
+ ```
58
+
31
59
  ## Use
32
60
 
33
61
  ```js
@@ -53,7 +81,13 @@ npm install @peaceroad/markdown-it-footnote-here
53
81
  - afterBacklinkSuffixArabicNumerals (boolean): If true, backlink suffix uses numbers (1, 2, ...) instead of letters (a, b, ...).
54
82
  - afterBacklinkdAriaLabelPrefix (string): Prefix for aria-label of backlink (default: 'Back to reference ').
55
83
  - labelBra (string): Bracket to use before footnote number (default: '[').
56
- - labelKet (string): Bracket to use after footnote number (default: ']').
84
+ - labelKet (string): Bracket to use after footnote number (default: ']').
57
85
  - labelSupTag (boolean): If true, wraps footnote reference in `<sup>` tag.
58
86
  - backLabelBra (string): Bracket to use before backlink number (default: '[').
59
87
  - backLabelKet (string): Bracket to use after backlink number (default: ']').
88
+ - endnotesPrefix (string): Prefix that marks a footnote as an endnote (default: `'en-'`).
89
+ - endnotesLabelPrefix (string): Label prefix for endnote refs/backlinks (default: `'E'`, e.g., `[E1]`).
90
+ - endnotesSectionId (string): `id` attribute for the endnotes section wrapper; omitted when empty (default: `'endnotes'`).
91
+ - endnotesSectionClass (string): `class` attribute for the endnotes section wrapper; omitted when empty (default: `''`).
92
+ - endnotesSectionAriaLabel (string): Used as `aria-label` when `endnotesUseHeading` is false. When `endnotesUseHeading` is true, this value becomes the heading text (default: `'Notes'`).
93
+ - endnotesUseHeading (boolean): If true, render `<h2>{endnotesSectionAriaLabel}</h2>` and omit `aria-label`. If false (default), omit the heading and set `aria-label` when provided.
package/index.js CHANGED
@@ -1,78 +1,130 @@
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 = ''
5
- if (typeof env.docId === 'string') {
6
- prefix = '-' + env.docId + '-'
7
- }
1
+ const render_footnote_anchor_name = (tokens, idx, _opt, env) => {
2
+ const n = tokens[idx].meta.id + 1
3
+ const prefix = typeof env.docId === 'string' ? `-${env.docId}-` : ''
8
4
  return prefix + n
9
5
  }
10
6
 
7
+ const isEndnoteLabel = (label, opt) => {
8
+ if (!opt.endnotesPrefix) return false
9
+ return label.startsWith(opt.endnotesPrefix)
10
+ }
11
+
12
+ const ensureNotesEnv = (env, key) => {
13
+ if (!env[key]) {
14
+ env[key] = { length: 0, refs: {}, positions: [] }
15
+ }
16
+ return env[key]
17
+ }
18
+
19
+ const ENDNOTE_DOM_PREFIX = 'en'
20
+
21
+ const selectNoteEnv = (label, env, preferEndnote) => {
22
+ const footRefs = env.footnotes && env.footnotes.refs
23
+ const endRefs = env.endnotes && env.endnotes.refs
24
+ if (!footRefs && !endRefs) return null
25
+ const key = ':' + label
26
+
27
+ if (preferEndnote && endRefs) {
28
+ const endId = endRefs[key]
29
+ if (endId !== undefined) {
30
+ return { env: env.endnotes, id: endId, isEndnote: true }
31
+ }
32
+ }
33
+ if (footRefs) {
34
+ const footId = footRefs[key]
35
+ if (footId !== undefined) {
36
+ return { env: env.footnotes, id: footId, isEndnote: false }
37
+ }
38
+ }
39
+ if (!preferEndnote && endRefs) {
40
+ const endId = endRefs[key]
41
+ if (endId !== undefined) {
42
+ return { env: env.endnotes, id: endId, isEndnote: true }
43
+ }
44
+ }
45
+ return null
46
+ }
47
+
11
48
  const render_footnote_ref = (tokens, idx, opt, env) => {
12
49
  const token = tokens[idx]
13
50
  const id = token.meta.id
14
51
  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
- }
52
+ const isEndnote = token.meta.isEndnote
53
+ const notes = isEndnote ? env.endnotes : env.footnotes
54
+ const noteDomPrefix = isEndnote ? ENDNOTE_DOM_PREFIX : 'fn'
55
+ const displayPrefix = isEndnote ? opt.endnotesLabelPrefix : ''
56
+ const totalCounts = notes.totalCounts ? notes.totalCounts[id] || 0 : 0
21
57
  let suffix = ''
22
- let label = `${opt.labelBra}${n}${opt.labelKet}`
23
- if (footnotes.totalCounts && footnotes.totalCounts[id] > 1) {
58
+ let label = `${opt.labelBra}${displayPrefix}${n}${opt.labelKet}`
59
+ if (totalCounts > 1) {
60
+ const refCount = notes._refCount || (notes._refCount = [])
61
+ let refIdx = (refCount[id] = (refCount[id] || 0) + 1)
62
+ if (!opt.afterBacklinkSuffixArabicNumerals) {
63
+ refIdx = String.fromCharCode(96 + refIdx)
64
+ }
24
65
  suffix = '-' + refIdx
25
66
  if (opt.beforeSameBacklink) {
26
- label = `${opt.labelBra}${n}${suffix}${opt.labelKet}`
67
+ label = `${opt.labelBra}${displayPrefix}${n}${suffix}${opt.labelKet}`
27
68
  }
28
69
  }
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>`
70
+ const href = `${noteDomPrefix}${n}`
71
+ let refCont = `<a href="#${href}" id="${noteDomPrefix}-ref${n}${suffix}" class="${noteDomPrefix}-noteref" role="doc-noteref">${label}</a>`
72
+ if (opt.labelSupTag) refCont = `<sup class="${noteDomPrefix}-noteref-wrapper">${refCont}</sup>`
31
73
  return refCont
32
74
  }
33
75
 
34
76
  const render_footnote_open = (tokens, idx, opt, env, slf) => {
35
77
  const id = slf.rules.footnote_anchor_name(tokens, idx, opt, env, slf)
78
+ const isEndnote = tokens[idx].meta.isEndnote
79
+ if (isEndnote) return `<li id="${ENDNOTE_DOM_PREFIX}${id}">\n`
36
80
  return `<aside id="fn${id}" class="fn" role="doc-footnote">\n`
37
81
  }
38
82
 
39
- const render_footnote_close = () => {
83
+ const render_footnote_close = (tokens, idx) => {
84
+ const isEndnote = tokens[idx].meta.isEndnote
85
+ if (isEndnote) return `</li>\n`
40
86
  return `</aside>\n`
41
87
  }
42
88
 
43
89
  const render_footnote_anchor = (tokens, idx, opt, env) => {
44
90
  const idNum = tokens[idx].meta.id
45
91
  const n = idNum + 1
46
- const footnotes = env.footnotes
47
- const counts = footnotes && footnotes.totalCounts
48
- if (opt.beforeSameBacklink && counts && counts[idNum] > 1) {
92
+ const isEndnote = tokens[idx].meta.isEndnote
93
+ const notes = isEndnote ? env.endnotes : env.footnotes
94
+ const totalCounts = notes.totalCounts
95
+ const count = totalCounts ? totalCounts[idNum] || 0 : 0
96
+ const noteDomPrefix = isEndnote ? ENDNOTE_DOM_PREFIX : 'fn'
97
+ const displayPrefix = isEndnote ? opt.endnotesLabelPrefix : ''
98
+
99
+ if (opt.beforeSameBacklink && count > 1) {
49
100
  let links = ''
50
- for (let i = 1; i <= counts[idNum]; i++) {
101
+ for (let i = 1; i <= count; i++) {
51
102
  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>`
103
+ links += `<a href="#${noteDomPrefix}-ref${n}${suffix}" class="${noteDomPrefix}-backlink" role="doc-backlink">${opt.backLabelBra}${displayPrefix}${n}${suffix}${opt.backLabelKet}</a>`
53
104
  }
54
105
  return links + ' '
55
106
  }
56
107
 
57
108
  if (opt.afterBacklink) {
58
- return `<span class="fn-label">${opt.backLabelBra}${n}${opt.backLabelKet}</span> `
109
+ return `<span class="${noteDomPrefix}-label">${opt.backLabelBra}${displayPrefix}${n}${opt.backLabelKet}</span> `
59
110
  }
60
111
 
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> `
112
+ if (count > 1) {
113
+ return `<a href="#${noteDomPrefix}-ref${n}-a" class="${noteDomPrefix}-backlink" role="doc-backlink">${opt.backLabelBra}${displayPrefix}${n}${opt.backLabelKet}</a> `
63
114
  }
64
115
 
65
- return `<a href="#fn-ref${n}" class="fn-backlink" role="doc-backlink">${opt.backLabelBra}${n}${opt.backLabelKet}</a> `
116
+ return `<a href="#${noteDomPrefix}-ref${n}" class="${noteDomPrefix}-backlink" role="doc-backlink">${opt.backLabelBra}${displayPrefix}${n}${opt.backLabelKet}</a> `
66
117
  }
67
118
 
68
- function createAfterBackLinkToken(state, counts, n, opt) {
119
+ function createAfterBackLinkToken(state, counts, n, opt, noteDomPrefix, isEndnote) {
120
+ const displayPrefix = isEndnote ? opt.endnotesLabelPrefix : ''
69
121
  let html = ' '
70
122
  if (counts && counts > 1) {
71
123
  for (let i = 1; i <= counts; i++) {
72
124
  const suffixChar = opt.afterBacklinkSuffixArabicNumerals ? i : String.fromCharCode(96 + i)
73
125
  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}"`
126
+ html += `<a href="#${noteDomPrefix}-ref${n}${suffix}" class="${noteDomPrefix}-backlink" role="doc-backlink"`
127
+ if (opt.afterBacklinkdAriaLabelPrefix) html += ` aria-label="${opt.afterBacklinkdAriaLabelPrefix}${displayPrefix}${n}${suffix}"`
76
128
  html += `>${opt.afterBacklinkContent}`
77
129
  if (opt.afterBacklinkWithNumber) {
78
130
  html += `<sup>${suffixChar}</sup>`
@@ -80,8 +132,8 @@ function createAfterBackLinkToken(state, counts, n, opt) {
80
132
  html += `</a>`
81
133
  }
82
134
  } else {
83
- html += `<a href="#fn-ref${n}" class="fn-backlink" role="doc-backlink"`
84
- if (opt.afterBacklinkdAriaLabelPrefix) html += ` aria-label="${opt.afterBacklinkdAriaLabelPrefix}${n}"`
135
+ html += `<a href="#${noteDomPrefix}-ref${n}" class="${noteDomPrefix}-backlink" role="doc-backlink"`
136
+ if (opt.afterBacklinkdAriaLabelPrefix) html += ` aria-label="${opt.afterBacklinkdAriaLabelPrefix}${displayPrefix}${n}"`
85
137
  html += `>${opt.afterBacklinkContent}</a>`
86
138
  }
87
139
  const token = new state.Token('html_inline', '', 0)
@@ -102,16 +154,22 @@ const footnote_plugin = (md, option) =>{
102
154
  afterBacklinkWithNumber: false,
103
155
  afterBacklinkSuffixArabicNumerals: false,
104
156
  afterBacklinkdAriaLabelPrefix: 'Back to reference ', /* 戻る:本文参照 */
157
+ endnotesPrefix: 'en-',
158
+ endnotesLabelPrefix: 'E',
159
+ endnotesSectionId: 'endnotes',
160
+ endnotesSectionClass: '',
161
+ endnotesSectionAriaLabel: 'Notes',
162
+ endnotesUseHeading: false,
105
163
  }
106
164
  if (option) Object.assign(opt, option)
107
165
 
108
166
  const isSpace = md.utils.isSpace
109
167
 
110
168
  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
169
+ md.renderer.rules.footnote_open = (tokens, idx, _options, env, slf) => render_footnote_open(tokens, idx, opt, env, slf)
170
+ md.renderer.rules.footnote_close = (tokens, idx, _options, env, slf) => render_footnote_close(tokens, idx, opt, env, slf)
113
171
  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
172
+ md.renderer.rules.footnote_anchor_name = (tokens, idx, _options, env, slf) => render_footnote_anchor_name(tokens, idx, opt, env, slf)
115
173
 
116
174
  // Process footnote block definition
117
175
  const footnote_def = (state, startLine, endLine, silent) => {
@@ -134,16 +192,13 @@ const footnote_plugin = (md, option) =>{
134
192
 
135
193
  if (silent) { return true; }
136
194
 
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
195
+ const isEndnote = isEndnoteLabel(label, opt)
196
+ const fn = ensureNotesEnv(state.env, isEndnote ? 'endnotes' : 'footnotes')
142
197
  const id = fn.length++
143
198
  fn.refs[':' + label] = id
144
199
 
145
200
  const token = new state.Token('footnote_open', '', 1)
146
- token.meta = { id, label }
201
+ token.meta = { id, isEndnote }
147
202
  token.level = state.level++
148
203
  state.tokens.push(token)
149
204
  fn.positions.push(state.tokens.length - 1)
@@ -193,6 +248,7 @@ const footnote_plugin = (md, option) =>{
193
248
 
194
249
  const closeToken = new state.Token('footnote_close', '', -1)
195
250
  closeToken.level = --state.level
251
+ closeToken.meta = { isEndnote }
196
252
  state.tokens.push(closeToken)
197
253
 
198
254
  return true
@@ -208,38 +264,30 @@ const footnote_plugin = (md, option) =>{
208
264
  return false
209
265
  }
210
266
 
211
- const env = state.env
212
- if (!env.footnotes || !env.footnotes.refs) { return false; }
213
-
214
267
  let pos = start + 2
215
- let found = false
216
- for (; pos < posMax && !found; pos++) {
268
+ for (; pos < posMax; pos++) {
217
269
  const ch = src.charCodeAt(pos)
270
+ if (ch === 0x5D /* ] */) break
218
271
  if (ch === 0x20 || ch === 0x0A) { return false; } // space or linebreak
219
- if (ch === 0x5D /* ] */) { found = true; break; }
220
272
  }
221
273
 
222
- if (!found || pos === start + 2) { return false; }
274
+ if (pos >= posMax || pos === start + 2) { return false; }
223
275
  pos++; // pos set next ']' position.
224
276
 
225
277
  const label = src.slice(start + 2, pos - 1)
226
- const id = env.footnotes.refs[':' + label]
227
-
228
- if (id === undefined) { return false; }
278
+ const env = state.env
279
+ const preferEndnote = isEndnoteLabel(label, opt)
280
+ const resolved = selectNoteEnv(label, env, preferEndnote)
229
281
 
282
+ if (!resolved) { return false; }
230
283
  if (!silent) {
231
- const fn = env.footnotes
284
+ const fn = resolved.env
232
285
 
233
- if (!fn.list) { fn.list = []; }
234
-
235
- const footnoteId = fn.list.length
236
- fn.list[footnoteId] = { label, count: 0 }
237
-
238
- fn.totalCounts = fn.totalCounts || {}
239
- fn.totalCounts[id] = (fn.totalCounts[id] || 0) + 1
286
+ fn.totalCounts = fn.totalCounts || []
287
+ fn.totalCounts[resolved.id] = (fn.totalCounts[resolved.id] || 0) + 1
240
288
 
241
289
  const token = state.push('footnote_ref', '', 0)
242
- token.meta = { id, label }
290
+ token.meta = { id: resolved.id, isEndnote: resolved.isEndnote }
243
291
  }
244
292
 
245
293
  state.pos = pos
@@ -247,42 +295,124 @@ const footnote_plugin = (md, option) =>{
247
295
  }
248
296
 
249
297
  const footnote_anchor = (state) => {
298
+ if (!state.env.footnotes && !state.env.endnotes) return
250
299
  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) => {
300
+ const createAnchorToken = (id, isEndnote) => {
256
301
  const aToken = new state.Token('footnote_anchor', '', 0)
257
- aToken.meta = { id, label: id + 1 }
302
+ aToken.meta = { id, isEndnote }
258
303
  return aToken
259
304
  }
260
305
 
261
- for (let j = 0, len = positions.length; j < len; ++j) {
262
- const posOpen = positions[j]
263
- if (posOpen + 2 >= tokens.length) continue
306
+ const injectAnchors = (notes, isEndnote) => {
307
+ const positions = notes && notes.positions
308
+ if (!positions || positions.length === 0) { return; }
264
309
 
265
- const t1 = tokens[posOpen + 1]
266
- if (t1.type !== 'paragraph_open') continue
310
+ if (opt.afterBacklink) {
311
+ const noteDomPrefix = isEndnote ? ENDNOTE_DOM_PREFIX : 'fn'
312
+ const totalCounts = notes.totalCounts
313
+ for (let j = 0, len = positions.length; j < len; ++j) {
314
+ const posOpen = positions[j]
315
+ if (posOpen + 2 >= tokens.length) continue
267
316
 
268
- const t2 = tokens[posOpen + 2]
269
- if (t2.type !== 'inline') continue
317
+ const t1 = tokens[posOpen + 1]
318
+ if (t1.type !== 'paragraph_open') continue
270
319
 
271
- const t0 = tokens[posOpen]
272
- const id = t0.meta.id
320
+ const t2 = tokens[posOpen + 2]
321
+ if (t2.type !== 'inline') continue
273
322
 
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))
323
+ const t0 = tokens[posOpen]
324
+ const id = t0.meta.id
325
+
326
+ t2.children.unshift(createAnchorToken(id, isEndnote))
327
+ const n = id + 1
328
+ const counts = totalCounts && totalCounts[id]
329
+ t2.children.push(createAfterBackLinkToken(state, counts, n, opt, noteDomPrefix, isEndnote))
330
+ }
331
+ return
332
+ }
333
+
334
+ for (let j = 0, len = positions.length; j < len; ++j) {
335
+ const posOpen = positions[j]
336
+ if (posOpen + 2 >= tokens.length) continue
337
+
338
+ const t1 = tokens[posOpen + 1]
339
+ if (t1.type !== 'paragraph_open') continue
340
+
341
+ const t2 = tokens[posOpen + 2]
342
+ if (t2.type !== 'inline') continue
343
+
344
+ const t0 = tokens[posOpen]
345
+ const id = t0.meta.id
346
+
347
+ t2.children.unshift(createAnchorToken(id, isEndnote))
279
348
  }
280
349
  }
350
+
351
+ injectAnchors(state.env.footnotes, false)
352
+ injectAnchors(state.env.endnotes, true)
353
+ }
354
+
355
+ const move_endnotes_to_section = (state) => {
356
+ if (!opt.endnotesPrefix) return
357
+ if (!state.env.endnotes || !state.env.endnotes.positions || state.env.endnotes.positions.length === 0) {
358
+ return
359
+ }
360
+
361
+ const tokens = state.tokens
362
+ const endnoteTokens = []
363
+
364
+ let write = 0
365
+ let i = 0
366
+ while (i < tokens.length) {
367
+ const token = tokens[i]
368
+ if (token.type === 'footnote_open' && token.meta && token.meta.isEndnote) {
369
+ endnoteTokens.push(token)
370
+ i++
371
+ while (i < tokens.length) {
372
+ const t = tokens[i]
373
+ endnoteTokens.push(t)
374
+ if (t.type === 'footnote_close' && t.meta && t.meta.isEndnote) {
375
+ i++
376
+ break
377
+ }
378
+ i++
379
+ }
380
+ continue
381
+ }
382
+ tokens[write++] = token
383
+ i++
384
+ }
385
+
386
+ if (endnoteTokens.length === 0) return
387
+
388
+ const sectionOpen = new state.Token('html_block', '', 0)
389
+ const attrs = []
390
+ if (!opt.endnotesUseHeading && opt.endnotesSectionAriaLabel) {
391
+ attrs.push(`aria-label="${opt.endnotesSectionAriaLabel}"`)
392
+ }
393
+ if (opt.endnotesSectionId) attrs.push(`id="${opt.endnotesSectionId}"`)
394
+ if (opt.endnotesSectionClass) attrs.push(`class="${opt.endnotesSectionClass}"`)
395
+ attrs.push('role="doc-endnotes"')
396
+ let sectionContent = `<section ${attrs.join(' ')}>\n`
397
+ if (opt.endnotesUseHeading && opt.endnotesSectionAriaLabel) {
398
+ sectionContent += `<h2>${opt.endnotesSectionAriaLabel}</h2>\n`
399
+ }
400
+ sectionContent += '<ol>\n'
401
+ sectionOpen.content = sectionContent
402
+
403
+ const sectionClose = new state.Token('html_block', '', 0)
404
+ sectionClose.content = '</ol>\n</section>\n'
405
+
406
+ tokens.length = write
407
+ tokens.push(sectionOpen)
408
+ for (let j = 0; j < endnoteTokens.length; j++) tokens.push(endnoteTokens[j])
409
+ tokens.push(sectionClose)
281
410
  }
282
411
 
283
412
  md.block.ruler.before('reference', 'footnote_def', footnote_def, { alt: [ 'paragraph', 'reference' ] })
284
413
  md.inline.ruler.after('image', 'footnote_ref', footnote_ref)
285
414
  md.core.ruler.after('inline', 'footnote_anchor', footnote_anchor)
415
+ md.core.ruler.after('footnote_anchor', 'endnotes_move', move_endnotes_to_section)
286
416
  }
287
417
 
288
418
  export default footnote_plugin
package/package.json CHANGED
@@ -1,9 +1,14 @@
1
1
  {
2
2
  "name": "@peaceroad/markdown-it-footnote-here",
3
- "version": "0.2.1",
3
+ "version": "0.3.1",
4
4
  "description": "A markdown-it plugin. This generate aside[role|doc-footnote] element just below the footnote reference paragraph.",
5
5
  "main": "index.js",
6
6
  "type":"module",
7
+ "files" : [
8
+ "index.js",
9
+ "LICENSE",
10
+ "README.md"
11
+ ],
7
12
  "author": "peaceroad <peaceroad@gmail.com>",
8
13
  "homepage": "https://github.com/peaceroad/markdown-it-footnote-here#readme",
9
14
  "repository": {