@abreen/tada 1.6.2 → 1.6.4
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/build/utils/markdown.ts +41 -12
- package/init/content/markdown.md +11 -3
- package/package.json +1 -1
- package/src/header/index.ts +12 -0
- package/src/style.scss +26 -3
package/build/utils/markdown.ts
CHANGED
|
@@ -36,6 +36,22 @@ function capitalize(str: string): string {
|
|
|
36
36
|
return str[0].toUpperCase() + str.slice(1);
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
const MAX_FOOTNOTES = 35;
|
|
40
|
+
|
|
41
|
+
export function footnoteLabel(oneBasedIndex: number): string {
|
|
42
|
+
if (oneBasedIndex < 1 || oneBasedIndex > MAX_FOOTNOTES) {
|
|
43
|
+
throw new Error(
|
|
44
|
+
`Tada supports at most ${MAX_FOOTNOTES} footnotes per page ` +
|
|
45
|
+
`(9 digits + 26 capital letters), but footnote ${oneBasedIndex} ` +
|
|
46
|
+
`was requested. Reduce the number of footnotes on this page.`,
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
if (oneBasedIndex <= 9) {
|
|
50
|
+
return String(oneBasedIndex);
|
|
51
|
+
}
|
|
52
|
+
return String.fromCharCode('A'.charCodeAt(0) + (oneBasedIndex - 10));
|
|
53
|
+
}
|
|
54
|
+
|
|
39
55
|
export function createMarkdown(
|
|
40
56
|
siteVariables: SiteVariables,
|
|
41
57
|
options: CreateMarkdownOptions = {},
|
|
@@ -196,24 +212,22 @@ export function createMarkdown(
|
|
|
196
212
|
});
|
|
197
213
|
|
|
198
214
|
/*
|
|
199
|
-
* Customize markdown-it-footnote renderer
|
|
215
|
+
* Customize markdown-it-footnote renderer.
|
|
216
|
+
*
|
|
217
|
+
* Footnotes are labeled with single characters from Inter's ss06
|
|
218
|
+
* stylistic set: 1-9 for the first nine footnotes, then A-Z. The
|
|
219
|
+
* default <ol> numbering is suppressed via CSS and we inject a
|
|
220
|
+
* marker span per item so the label sequence can mix digits and
|
|
221
|
+
* letters.
|
|
200
222
|
*/
|
|
201
223
|
markdown.renderer.rules.footnote_block_open = () =>
|
|
202
224
|
'<div class="footnotes"><p class="title">Footnotes</p><ol>';
|
|
203
225
|
|
|
204
226
|
markdown.renderer.rules.footnote_block_close = () => '</ol></div>';
|
|
205
227
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
tokens: Token[],
|
|
210
|
-
idx: number,
|
|
211
|
-
options: Options,
|
|
212
|
-
env: unknown,
|
|
213
|
-
self: Renderer,
|
|
214
|
-
) => {
|
|
215
|
-
const str = caption(tokens, idx, options, env, self);
|
|
216
|
-
return str.slice(1, str.length - 1);
|
|
228
|
+
markdown.renderer.rules.footnote_caption = (tokens: Token[], idx: number) => {
|
|
229
|
+
const id = tokens[idx].meta!.id as number;
|
|
230
|
+
return footnoteLabel(id + 1);
|
|
217
231
|
};
|
|
218
232
|
|
|
219
233
|
const footnoteRef = markdown.renderer.rules.footnote_ref!;
|
|
@@ -224,11 +238,26 @@ export function createMarkdown(
|
|
|
224
238
|
env: unknown,
|
|
225
239
|
self: Renderer,
|
|
226
240
|
) =>
|
|
241
|
+
// Prepend a non-breaking space so the reference link cannot wrap
|
|
242
|
+
// away from the word it follows.
|
|
243
|
+
'\u00a0' +
|
|
227
244
|
footnoteRef(tokens, idx, options, env, self)
|
|
228
245
|
.replace('<sup class="footnote-ref">', '')
|
|
229
246
|
.replace('</sup>', '')
|
|
230
247
|
.replace('<a href="', '<a class="footnote-ref" href="');
|
|
231
248
|
|
|
249
|
+
markdown.renderer.rules.footnote_open = (tokens: Token[], idx: number) => {
|
|
250
|
+
const id = tokens[idx].meta!.id as number;
|
|
251
|
+
const label = footnoteLabel(id + 1);
|
|
252
|
+
const refid = id + 1;
|
|
253
|
+
return (
|
|
254
|
+
`<li id="fn${refid}" class="footnote-item">` +
|
|
255
|
+
`<span class="footnote-marker" aria-hidden="true">${label}</span> `
|
|
256
|
+
);
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
markdown.renderer.rules.footnote_close = () => '</li>\n';
|
|
260
|
+
|
|
232
261
|
const footnoteAnchor = markdown.renderer.rules.footnote_anchor!;
|
|
233
262
|
markdown.renderer.rules.footnote_anchor = (
|
|
234
263
|
tokens: Token[],
|
package/init/content/markdown.md
CHANGED
|
@@ -182,10 +182,10 @@ footnote.[^example-footnote]
|
|
|
182
182
|
Definition lists are supported using the same syntax as Presto:
|
|
183
183
|
|
|
184
184
|
Stack
|
|
185
|
-
: Last-in first-out collection.
|
|
185
|
+
: Last-in first-out collection.[^footnote-2]
|
|
186
186
|
|
|
187
187
|
Queue
|
|
188
|
-
: First-in first-out collection.
|
|
188
|
+
: First-in first-out collection.[^footnote-3]
|
|
189
189
|
|
|
190
190
|
Binary tree
|
|
191
191
|
: Hierarchical structure where each node has up to two children.
|
|
@@ -417,7 +417,15 @@ Here's a time range:
|
|
|
417
417
|
|
|
418
418
|
|
|
419
419
|
[^example-footnote]: Footnotes render inside a numbered list at the bottom of
|
|
420
|
-
the page.
|
|
420
|
+
the page.
|
|
421
|
+
|
|
422
|
+
Here's a second paragraph.
|
|
423
|
+
|
|
424
|
+
Here's a third paragraph.
|
|
425
|
+
|
|
426
|
+
[^footnote-2]: Also known as "LIFO".
|
|
427
|
+
|
|
428
|
+
[^footnote-3]: Also known as "FIFO".
|
|
421
429
|
|
|
422
430
|
[front-matter]: https://www.npmjs.com/package/front-matter
|
|
423
431
|
[markdown-it]: https://markdown-it.github.io/
|
package/package.json
CHANGED
package/src/header/index.ts
CHANGED
|
@@ -35,9 +35,21 @@ export default (window: Window) => {
|
|
|
35
35
|
}
|
|
36
36
|
window.addEventListener('keydown', handleWindowKeyDown);
|
|
37
37
|
|
|
38
|
+
function handleDetailsFocusOut(e: FocusEvent) {
|
|
39
|
+
if (!details.open) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const next = e.relatedTarget as Node | null;
|
|
43
|
+
if (!next || !details.contains(next)) {
|
|
44
|
+
close();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
details.addEventListener('focusout', handleDetailsFocusOut);
|
|
48
|
+
|
|
38
49
|
return () => {
|
|
39
50
|
window.removeEventListener('keydown', handleWindowKeyDown);
|
|
40
51
|
window.removeEventListener('click', handleWindowClick);
|
|
41
52
|
details.removeEventListener('click', handleDetailsClick);
|
|
53
|
+
details.removeEventListener('focusout', handleDetailsFocusOut);
|
|
42
54
|
};
|
|
43
55
|
};
|
package/src/style.scss
CHANGED
|
@@ -91,14 +91,34 @@ a.external:not(:has(.external-link-tail))::after {
|
|
|
91
91
|
margin: 0;
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
+
.footnotes ol {
|
|
95
|
+
list-style: none;
|
|
96
|
+
padding-left: 0;
|
|
97
|
+
}
|
|
98
|
+
|
|
94
99
|
.footnotes li {
|
|
100
|
+
position: relative;
|
|
101
|
+
padding-left: 1.8em;
|
|
95
102
|
margin-bottom: 8px;
|
|
96
103
|
}
|
|
97
104
|
|
|
98
105
|
a.footnote-ref {
|
|
99
|
-
vertical-align:
|
|
100
|
-
border-bottom: none;
|
|
106
|
+
vertical-align: text-bottom;
|
|
101
107
|
font-size: 0.8em;
|
|
108
|
+
font-weight: 600;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.footnote-marker {
|
|
112
|
+
@include user-select(none);
|
|
113
|
+
position: absolute;
|
|
114
|
+
left: 0;
|
|
115
|
+
top: 0;
|
|
116
|
+
font-weight: 500;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
a.footnote-ref,
|
|
120
|
+
.footnote-marker {
|
|
121
|
+
font-feature-settings: 'ss06';
|
|
102
122
|
}
|
|
103
123
|
|
|
104
124
|
.footnote-item {
|
|
@@ -108,7 +128,10 @@ a.footnote-ref {
|
|
|
108
128
|
}
|
|
109
129
|
}
|
|
110
130
|
|
|
111
|
-
a.footnote-ref
|
|
131
|
+
a.footnote-ref {
|
|
132
|
+
@include user-select(none);
|
|
133
|
+
}
|
|
134
|
+
|
|
112
135
|
.footnotes .footnote-backref {
|
|
113
136
|
display: inline-block;
|
|
114
137
|
@include user-select(none);
|