-
-
Notifications
You must be signed in to change notification settings - Fork 43
/
Copy pathfooter.js
125 lines (108 loc) · 3.09 KB
/
footer.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
/**
* @typedef {import('mdast').BlockContent} BlockContent
* @typedef {import('mdast').FootnoteDefinition} FootnoteDefinition
* @typedef {import('hast').Element} Element
* @typedef {import('hast').ElementContent} ElementContent
* @typedef {import('./index.js').H} H
*/
import {sanitizeUri} from 'micromark-util-sanitize-uri'
import {u} from 'unist-builder'
import {all} from './traverse.js'
import {wrap} from './wrap.js'
/**
* @param {H} h
*/
export function footer(h) {
let index = -1
/** @type {Array<ElementContent>} */
const listItems = []
while (++index < h.footnoteOrder.length) {
const def = h.footnoteById[h.footnoteOrder[index].toUpperCase()]
if (!def) {
continue
}
const content = all(h, def)
const id = String(def.identifier)
const safeId = sanitizeUri(id.toLowerCase())
let referenceIndex = 0
/** @type {Array<ElementContent>} */
const backReferences = []
while (++referenceIndex <= h.footnoteCounts[id]) {
/** @type {Element} */
const backReference = {
type: 'element',
tagName: 'a',
properties: {
href:
'#' +
h.clobberPrefix +
'fnref-' +
safeId +
(referenceIndex > 1 ? '-' + referenceIndex : ''),
dataFootnoteBackref: true,
className: ['data-footnote-backref'],
ariaLabel: h.footnoteBackLabel
},
children: [{type: 'text', value: '↩'}]
}
if (referenceIndex > 1) {
backReference.children.push({
type: 'element',
tagName: 'sup',
children: [{type: 'text', value: String(referenceIndex)}]
})
}
if (backReferences.length > 0) {
backReferences.push({type: 'text', value: ' '})
}
backReferences.push(backReference)
}
const tail = content[content.length - 1]
if (tail && tail.type === 'element' && tail.tagName === 'p') {
const tailTail = tail.children[tail.children.length - 1]
if (tailTail && tailTail.type === 'text') {
tailTail.value += ' '
} else {
tail.children.push({type: 'text', value: ' '})
}
tail.children.push(...backReferences)
} else {
content.push(...backReferences)
}
/** @type {Element} */
const listItem = {
type: 'element',
tagName: 'li',
properties: {id: h.clobberPrefix + 'fn-' + safeId},
children: wrap(content, true)
}
if (def.position) {
listItem.position = def.position
}
listItems.push(listItem)
}
if (listItems.length === 0) {
return null
}
return {
type: 'element',
tagName: 'section',
properties: {dataFootnotes: true, className: ['footnotes']},
children: [
{
type: 'element',
tagName: 'h2',
properties: {id: 'footnote-label', className: ['sr-only']},
children: [u('text', h.footnoteLabel)]
},
{type: 'text', value: '\n'},
{
type: 'element',
tagName: 'ol',
properties: {},
children: wrap(listItems, true)
},
{type: 'text', value: '\n'}
]
}
}