@abreen/tada 1.0.2 → 1.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 +96 -48
- package/bin/tada.ts +621 -0
- package/bin/validators.test.ts +205 -0
- package/bin/validators.ts +85 -0
- package/{webpack/apply-base-path-plugin.js → build/apply-base-path-plugin.ts} +37 -17
- package/build/build-manifest.test.ts +349 -0
- package/build/build-manifest.ts +165 -0
- package/build/bundle.ts +116 -0
- package/{webpack/code.test.js → build/code.test.ts} +10 -7
- package/build/colors.ts +25 -0
- package/build/content-watch.ts +107 -0
- package/build/copy.ts +118 -0
- package/{webpack/deflist-id-plugin.js → build/deflist-id-plugin.ts} +7 -6
- package/{webpack/external-links-plugin.js → build/external-links-plugin.ts} +14 -5
- package/build/features.ts +11 -0
- package/build/generate-content-assets.ts +320 -0
- package/build/generate-favicon.ts +172 -0
- package/build/generate-fonts.ts +31 -0
- package/build/generate-katex-assets.ts +35 -0
- package/{webpack/generate-manifest-plugin.js → build/generate-manifest.ts} +29 -36
- package/build/globals.test.ts +99 -0
- package/build/globals.ts +88 -0
- package/{webpack/heading-subtitle-plugin.js → build/heading-subtitle-plugin.ts} +4 -2
- package/build/json-schema.test.ts +57 -0
- package/build/json-schema.ts +33 -0
- package/build/log.test.ts +111 -0
- package/build/log.ts +167 -0
- package/build/markdown-plugins.test.ts +396 -0
- package/{webpack/pagefind-plugin.test.js → build/pagefind.test.ts} +74 -13
- package/build/pagefind.ts +339 -0
- package/build/pdf-text.test.ts +52 -0
- package/{webpack/pdf-text.js → build/pdf-text.ts} +47 -27
- package/build/pipeline.ts +120 -0
- package/{webpack/reachability.test.js → build/reachability.test.ts} +3 -3
- package/{webpack/reachability.js → build/reachability.ts} +77 -34
- package/build/serve.ts +112 -0
- package/build/site-variables.ts +68 -0
- package/{webpack/templates.js → build/templates.ts} +38 -35
- package/{webpack/text-to-id.js → build/text-to-id.ts} +2 -2
- package/build/toc-plugin.test.ts +105 -0
- package/{webpack/toc-plugin.js → build/toc-plugin.ts} +32 -13
- package/build/types.ts +181 -0
- package/build/util.ts +26 -0
- package/{webpack/utils/code.js → build/utils/code.ts} +119 -60
- package/{webpack/utils/content-files.js → build/utils/content-files.ts} +40 -35
- package/build/utils/derive-theme.test.ts +111 -0
- package/build/utils/derive-theme.ts +85 -0
- package/build/utils/file-types.test.ts +61 -0
- package/build/utils/file-types.ts +13 -0
- package/build/utils/front-matter.test.ts +77 -0
- package/{webpack/utils/front-matter.js → build/utils/front-matter.ts} +22 -9
- package/{webpack → build}/utils/jdi-runner/LiterateRunner.java +1 -1
- package/{webpack/utils/literate-java.js → build/utils/literate-java.ts} +68 -38
- package/{webpack/utils/markdown.js → build/utils/markdown.ts} +126 -49
- package/build/utils/paths.test.ts +91 -0
- package/{webpack/utils/paths.js → build/utils/paths.ts} +18 -22
- package/{webpack/utils/render.js → build/utils/render.ts} +208 -130
- package/build/utils/shiki-highlighter.ts +29 -0
- package/build/validate-internal-links-plugin.test.ts +106 -0
- package/{webpack/validate-internal-links-plugin.js → build/validate-internal-links-plugin.ts} +47 -20
- package/{webpack/watch-reachability-state.test.js → build/watch-reachability-state.test.ts} +8 -8
- package/{webpack/watch-reachability-state.js → build/watch-reachability-state.ts} +63 -24
- package/{webpack/watch-reload-client.js → build/watch-reload-client.ts} +3 -1
- package/build/watch.ts +549 -0
- package/fonts/google-sans-code/woff2/GoogleSansCodeVariable-Italic.woff2 +0 -0
- package/fonts/google-sans-code/woff2/GoogleSansCodeVariable.woff2 +0 -0
- package/fonts/inter/woff2/InterVariable-Italic.woff2 +0 -0
- package/fonts/inter/woff2/InterVariable.woff2 +0 -0
- package/{content → init/content}/index.md +9 -3
- package/{content → init/content}/lectures/index.md +1 -1
- package/{content → init/content}/markdown.md +28 -8
- package/init/content/problem_sets/index.html +14 -0
- package/package.json +33 -22
- package/{templates → schema}/nav.schema.json +1 -2
- package/{webpack → schema}/site.schema.json +4 -12
- package/src/_alerts.scss +96 -0
- package/src/_base.scss +145 -0
- package/src/{layout.scss → _layout.scss} +36 -1
- package/src/anchor/index.ts +0 -1
- package/src/anchor/style.scss +1 -9
- package/src/code/index.ts +3 -3
- package/src/code.scss +1 -1
- package/src/critical.scss +5 -0
- package/src/header/_base.scss +129 -0
- package/src/header/style.scss +3 -131
- package/src/index.ts +4 -5
- package/src/question/style.scss +1 -1
- package/src/search/index.test.ts +203 -0
- package/src/search/index.ts +38 -93
- package/src/search/pdf-utils.ts +79 -0
- package/src/search/style.scss +8 -28
- package/src/style.scss +15 -326
- package/src/timezone/index.ts +5 -6
- package/src/toc/style.scss +5 -39
- package/src/util.ts +9 -6
- package/templates/_theme.scss +38 -14
- package/templates/_top.html +1 -1
- package/tsconfig.json +10 -6
- package/types/dev.d.ts +1 -0
- package/types/file-system-access.d.ts +5 -0
- package/types/markdown-it-plugins.d.ts +11 -0
- package/types/site-variables.d.ts +6 -10
- package/types/untyped-modules.d.ts +47 -0
- package/bin/tada.js +0 -361
- package/config/authors.json +0 -1
- package/config/nav.json +0 -28
- package/content/problem_sets/index.md +0 -6
- package/types/dev.ts +0 -3
- package/webpack/build-state.js +0 -97
- package/webpack/colors.js +0 -15
- package/webpack/config.base.js +0 -151
- package/webpack/config.dev.js +0 -23
- package/webpack/config.prod.js +0 -32
- package/webpack/content-watch-plugin.js +0 -153
- package/webpack/features.js +0 -5
- package/webpack/generate-content-assets-plugin.js +0 -308
- package/webpack/generate-favicon-plugin.js +0 -198
- package/webpack/generate-fonts-plugin.js +0 -69
- package/webpack/globals.js +0 -74
- package/webpack/json-schema.js +0 -19
- package/webpack/log.js +0 -143
- package/webpack/markdown-plugins.test.js +0 -203
- package/webpack/pagefind-plugin.js +0 -379
- package/webpack/print-flair-plugin.js +0 -22
- package/webpack/serve.js +0 -104
- package/webpack/site-variables.js +0 -53
- package/webpack/util.js +0 -49
- package/webpack/utils/define-plugin.js +0 -20
- package/webpack/utils/file-types.js +0 -26
- package/webpack/utils/parse-hsl.js +0 -8
- package/webpack/utils/shiki-highlighter.js +0 -26
- package/webpack/watch.js +0 -166
- /package/{webpack → build}/flair.json +0 -0
- /package/{webpack → build}/utils/jdi-runner/LiterateRunner.class +0 -0
- /package/fonts/google-sans-code/{GoogleSansCodeVariable-Italic.ttf → ttf/GoogleSansCodeVariable-Italic.ttf} +0 -0
- /package/fonts/google-sans-code/{GoogleSansCodeVariable.ttf → ttf/GoogleSansCodeVariable.ttf} +0 -0
- /package/fonts/inter/{InterVariable-Italic.ttf → ttf/InterVariable-Italic.ttf} +0 -0
- /package/fonts/inter/{InterVariable.ttf → ttf/InterVariable.ttf} +0 -0
- /package/{content → init/content}/lectures/01/Pair.java.md +0 -0
- /package/{content → init/content}/lectures/01/Rectangle.java +0 -0
- /package/{content → init/content}/lectures/01/demo.py +0 -0
- /package/{content → init/content}/lectures/01/index.md +0 -0
- /package/{content → init/content}/lectures/01/lecture1.pdf +0 -0
- /package/{public → init/public}/avatars/alex.jpg +0 -0
- /package/{public → init/public}/test.txt +0 -0
- /package/{templates → schema}/authors.schema.json +0 -0
package/webpack/log.js
DELETED
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
const { inspect } = require('node:util');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
const { G, R, P, Y, L } = require('./colors');
|
|
4
|
-
const FLAIR_STRINGS = require('./flair.json');
|
|
5
|
-
|
|
6
|
-
const LEVELS = ['debug', 'info', 'warn', 'error'];
|
|
7
|
-
|
|
8
|
-
const ENV_LOG_LEVEL = process.env.TADA_LOG_LEVEL;
|
|
9
|
-
|
|
10
|
-
if (ENV_LOG_LEVEL && !LEVELS.includes(ENV_LOG_LEVEL)) {
|
|
11
|
-
throw new Error(
|
|
12
|
-
`Invalid TADA_LOG_LEVEL "${ENV_LOG_LEVEL}", must be one of: ${LEVELS.join(', ')}`,
|
|
13
|
-
);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
function shouldLog(loggerLevel, level) {
|
|
17
|
-
return LEVELS.indexOf(level) >= LEVELS.indexOf(loggerLevel);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function validateLevel(level) {
|
|
21
|
-
if (!LEVELS.includes(level)) {
|
|
22
|
-
throw new Error(
|
|
23
|
-
`Invalid log level "${level}", must be one of: ${LEVELS.join(', ')}`,
|
|
24
|
-
);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function print(strings, stream = 'stdout', end = '\n') {
|
|
29
|
-
for (const s of strings) {
|
|
30
|
-
process[stream].write(s);
|
|
31
|
-
}
|
|
32
|
-
process[stream].write(end);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function makeLogger(name, logLevel = 'info') {
|
|
36
|
-
validateLevel(logLevel);
|
|
37
|
-
|
|
38
|
-
if (ENV_LOG_LEVEL) {
|
|
39
|
-
logLevel = ENV_LOG_LEVEL;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
if (!name) {
|
|
43
|
-
name = '';
|
|
44
|
-
} else {
|
|
45
|
-
// Allow for passing __filename
|
|
46
|
-
name = path.basename(name);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const logger = {
|
|
50
|
-
/** Don't log if the level is < minLogLevel */
|
|
51
|
-
setMinLogLevel(minLogLevel) {
|
|
52
|
-
this.minLogLevel = minLogLevel;
|
|
53
|
-
},
|
|
54
|
-
getArgs(level, strings, args, colorFn) {
|
|
55
|
-
const params = [];
|
|
56
|
-
params.push(colorFn`${level}` + '\t');
|
|
57
|
-
params.push(format(strings, ...args));
|
|
58
|
-
return params;
|
|
59
|
-
},
|
|
60
|
-
debug(strings, ...args) {
|
|
61
|
-
if (shouldLog(this.minLogLevel, 'debug')) {
|
|
62
|
-
print(this.getArgs('debug', strings, args, L), 'stderr');
|
|
63
|
-
}
|
|
64
|
-
},
|
|
65
|
-
info(strings, ...args) {
|
|
66
|
-
if (shouldLog(this.minLogLevel, 'info')) {
|
|
67
|
-
print(this.getArgs('info', strings, args, L));
|
|
68
|
-
}
|
|
69
|
-
},
|
|
70
|
-
warn(strings, ...args) {
|
|
71
|
-
if (shouldLog(this.minLogLevel, 'warn')) {
|
|
72
|
-
print(this.getArgs('warn', strings, args, Y));
|
|
73
|
-
}
|
|
74
|
-
},
|
|
75
|
-
error(strings, ...args) {
|
|
76
|
-
if (shouldLog(this.minLogLevel, 'error')) {
|
|
77
|
-
print(this.getArgs('error', strings, args, R));
|
|
78
|
-
}
|
|
79
|
-
},
|
|
80
|
-
event(strings, ...args) {
|
|
81
|
-
print(this.getArgs('event', strings, args, G));
|
|
82
|
-
},
|
|
83
|
-
followup(strings) {
|
|
84
|
-
print(strings);
|
|
85
|
-
},
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
logger.setMinLogLevel(logLevel);
|
|
89
|
-
return logger;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
function format(strings, ...args) {
|
|
93
|
-
// Called as template tag: first arg is an array-like with .raw
|
|
94
|
-
if (strings && typeof strings === 'object' && 'raw' in strings) {
|
|
95
|
-
try {
|
|
96
|
-
return String.raw(strings, ...args.map(toString));
|
|
97
|
-
} catch (e) {
|
|
98
|
-
// fallback to safe join
|
|
99
|
-
}
|
|
100
|
-
} else {
|
|
101
|
-
if (Array.isArray(strings)) {
|
|
102
|
-
args.unshift(...strings);
|
|
103
|
-
} else {
|
|
104
|
-
args.unshift(strings);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
return args.map(toString).join(' ');
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
function toString(item) {
|
|
112
|
-
if (item === undefined) {
|
|
113
|
-
return 'undefined';
|
|
114
|
-
}
|
|
115
|
-
if (item === null) {
|
|
116
|
-
return 'null';
|
|
117
|
-
}
|
|
118
|
-
if (typeof item === 'string') {
|
|
119
|
-
return item;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
try {
|
|
123
|
-
if (typeof item === 'object') {
|
|
124
|
-
return inspect(item, {
|
|
125
|
-
compact: true,
|
|
126
|
-
depth: 2,
|
|
127
|
-
breakLength: 80,
|
|
128
|
-
maxStringLength: 250,
|
|
129
|
-
colors: true,
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
throw new Error('not an object');
|
|
133
|
-
} catch (e) {
|
|
134
|
-
return String(item);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
function getFlair() {
|
|
139
|
-
const i = Math.floor(Math.random() * FLAIR_STRINGS.length);
|
|
140
|
-
return P`${FLAIR_STRINGS[i]}!` + ' 🎉';
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
module.exports = { makeLogger, getFlair };
|
|
@@ -1,203 +0,0 @@
|
|
|
1
|
-
const { describe, expect, test } = require('bun:test');
|
|
2
|
-
const MarkdownIt = require('markdown-it');
|
|
3
|
-
const deflist = require('markdown-it-deflist');
|
|
4
|
-
const applyBasePathPlugin = require('./apply-base-path-plugin');
|
|
5
|
-
const deflistIdPlugin = require('./deflist-id-plugin');
|
|
6
|
-
const externalLinksPlugin = require('./external-links-plugin');
|
|
7
|
-
const headingSubtitlePlugin = require('./heading-subtitle-plugin');
|
|
8
|
-
const { createMarkdown } = require('./utils/markdown');
|
|
9
|
-
|
|
10
|
-
describe('apply-base-path-plugin', () => {
|
|
11
|
-
test('rewrites internal links, images, and raw html image sources', () => {
|
|
12
|
-
const md = new MarkdownIt({ html: true });
|
|
13
|
-
md.use(applyBasePathPlugin, {
|
|
14
|
-
basePath: '/course/',
|
|
15
|
-
codeLanguages: { java: 'java' },
|
|
16
|
-
features: { code: true },
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
const html = md.render(
|
|
20
|
-
[
|
|
21
|
-
'[Code](/src/example.java?view=1#top)',
|
|
22
|
-
'',
|
|
23
|
-
'',
|
|
24
|
-
'',
|
|
25
|
-
'<img src="/images/raw.png" alt="Raw">',
|
|
26
|
-
].join('\n'),
|
|
27
|
-
);
|
|
28
|
-
|
|
29
|
-
expect(html).toContain('href="/course/src/example.html?view=1#top"');
|
|
30
|
-
expect(html).toContain('src="/course/images/pic.png"');
|
|
31
|
-
expect(html).toContain('src="/course/images/raw.png"');
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
test('rewrites relative code file links without applying base path', () => {
|
|
35
|
-
const md = new MarkdownIt();
|
|
36
|
-
md.use(applyBasePathPlugin, {
|
|
37
|
-
basePath: '/course/',
|
|
38
|
-
codeLanguages: { java: 'java' },
|
|
39
|
-
features: { code: true },
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
const html = md.render('[App](./App.java)');
|
|
43
|
-
|
|
44
|
-
expect(html).toContain('href="./App.html"');
|
|
45
|
-
expect(html).not.toContain('href="./App.java"');
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
test('keeps code file extensions when the code feature is disabled', () => {
|
|
49
|
-
const md = new MarkdownIt();
|
|
50
|
-
md.use(applyBasePathPlugin, {
|
|
51
|
-
basePath: '/course',
|
|
52
|
-
codeLanguages: { java: 'java' },
|
|
53
|
-
features: { code: false },
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
const html = md.render('[Code](/src/example.java#L1)');
|
|
57
|
-
|
|
58
|
-
expect(html).toContain('href="/course/src/example.java#L1"');
|
|
59
|
-
expect(html).not.toContain('href="/course/src/example.html#L1"');
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
describe('external-links-plugin', () => {
|
|
64
|
-
test('marks external http links without changing internal or non-http links', () => {
|
|
65
|
-
const md = new MarkdownIt();
|
|
66
|
-
md.use(externalLinksPlugin, { internalDomains: ['example.com'] });
|
|
67
|
-
|
|
68
|
-
const html = md.render(
|
|
69
|
-
[
|
|
70
|
-
'[External](https://outside.example/docs)',
|
|
71
|
-
'[Internal](https://example.com/docs)',
|
|
72
|
-
'[Mail](mailto:test@example.com)',
|
|
73
|
-
].join(' '),
|
|
74
|
-
);
|
|
75
|
-
|
|
76
|
-
expect(html).toContain(
|
|
77
|
-
'<a href="https://outside.example/docs" class="external" target="_blank">External</a>',
|
|
78
|
-
);
|
|
79
|
-
expect(html).toContain('<a href="https://example.com/docs">Internal</a>');
|
|
80
|
-
expect(html).toContain('<a href="mailto:test@example.com">Mail</a>');
|
|
81
|
-
});
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
describe('heading-subtitle-plugin', () => {
|
|
85
|
-
test('wraps heading subtitles while preserving inline formatting', () => {
|
|
86
|
-
const md = new MarkdownIt();
|
|
87
|
-
md.use(headingSubtitlePlugin);
|
|
88
|
-
|
|
89
|
-
const html = md.render('## Title # *Subtitle*').trim();
|
|
90
|
-
|
|
91
|
-
expect(html).toBe(
|
|
92
|
-
'<h2 class="has-subtitle">Title <span class="heading-subtitle"><em>Subtitle</em></span></h2>',
|
|
93
|
-
);
|
|
94
|
-
});
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
describe('deflist-id-plugin', () => {
|
|
98
|
-
test('injects unique ids for terms and falls back when a term slug is empty', () => {
|
|
99
|
-
const md = new MarkdownIt();
|
|
100
|
-
md.use(deflist);
|
|
101
|
-
md.use(deflistIdPlugin);
|
|
102
|
-
|
|
103
|
-
const html = md.render(
|
|
104
|
-
['Term 1', ': One', '', 'Term 1', ': Two', '', '!!!', ': Three'].join(
|
|
105
|
-
'\n',
|
|
106
|
-
),
|
|
107
|
-
);
|
|
108
|
-
|
|
109
|
-
expect(html).toContain('<a id="term-1"></a>Term 1');
|
|
110
|
-
expect(html).toContain('<a id="term-1-2"></a>Term 1');
|
|
111
|
-
expect(html).toContain('<a id="term"></a>!!!');
|
|
112
|
-
});
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
describe('custom markdown containers', () => {
|
|
116
|
-
function createProjectMarkdown() {
|
|
117
|
-
return createMarkdown(
|
|
118
|
-
{ basePath: '/', internalDomains: [], codeLanguages: {}, features: {} },
|
|
119
|
-
{ validatorOptions: { enabled: false } },
|
|
120
|
-
);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
test('renders collapsible details blocks', () => {
|
|
124
|
-
const md = createProjectMarkdown();
|
|
125
|
-
|
|
126
|
-
const html = md.render(
|
|
127
|
-
['<<< details More info', 'Hello', '<<<'].join('\n'),
|
|
128
|
-
);
|
|
129
|
-
|
|
130
|
-
expect(html).toContain('<details><summary>More info</summary>');
|
|
131
|
-
expect(html).toContain('<div class="content">');
|
|
132
|
-
expect(html).toContain('<p>Hello</p>');
|
|
133
|
-
expect(html).toContain('</div></details>');
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
test('renders collapsible details blocks with inline Markdown in summary', () => {
|
|
137
|
-
const md = createProjectMarkdown();
|
|
138
|
-
|
|
139
|
-
const html = md.render(
|
|
140
|
-
['<<< details More **info**', 'Hello', '<<<'].join('\n'),
|
|
141
|
-
);
|
|
142
|
-
|
|
143
|
-
expect(html).toContain(
|
|
144
|
-
'<details><summary>More <strong>info</strong></summary>',
|
|
145
|
-
);
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
test('renders section containers as section elements', () => {
|
|
149
|
-
const md = createProjectMarkdown();
|
|
150
|
-
|
|
151
|
-
const html = md.render(['::: section', 'Body', ':::'].join('\n'));
|
|
152
|
-
|
|
153
|
-
expect(html).toContain('<section>');
|
|
154
|
-
expect(html).toContain('<p>Body</p>');
|
|
155
|
-
expect(html).toContain('</section>');
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
test('renders questions with question and spoiler answer', () => {
|
|
159
|
-
const md = createProjectMarkdown();
|
|
160
|
-
|
|
161
|
-
const html = md.render(
|
|
162
|
-
[
|
|
163
|
-
'??? question What is a data structure?',
|
|
164
|
-
'An organized collection.',
|
|
165
|
-
'???',
|
|
166
|
-
].join('\n'),
|
|
167
|
-
);
|
|
168
|
-
|
|
169
|
-
expect(html).toContain('<div class="question">');
|
|
170
|
-
expect(html).toContain(
|
|
171
|
-
'<p class="question-q"><span class="question-label">Q.</span><span>What is a data structure?</span></p>',
|
|
172
|
-
);
|
|
173
|
-
expect(html).toContain('<p class="question-a-label">A.</p>');
|
|
174
|
-
expect(html).toContain(
|
|
175
|
-
'<div class="question-a-body" data-pagefind-ignore>',
|
|
176
|
-
);
|
|
177
|
-
expect(html).toContain('<p>An organized collection.</p>');
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
test('renders alert containers with custom and default titles', () => {
|
|
181
|
-
const md = createProjectMarkdown();
|
|
182
|
-
|
|
183
|
-
const html = md.render(
|
|
184
|
-
[
|
|
185
|
-
'!!! note "Read this"',
|
|
186
|
-
'Body',
|
|
187
|
-
'!!!',
|
|
188
|
-
'',
|
|
189
|
-
'!!! warning',
|
|
190
|
-
'Careful',
|
|
191
|
-
'!!!',
|
|
192
|
-
].join('\n'),
|
|
193
|
-
);
|
|
194
|
-
|
|
195
|
-
expect(html).toContain('<div class="alert note">');
|
|
196
|
-
expect(html).toContain('<p class="title" id="read-this">');
|
|
197
|
-
expect(html).toContain(
|
|
198
|
-
'<div class="alert warning"><p class="title">Warning</p>',
|
|
199
|
-
);
|
|
200
|
-
expect(html).toContain('<p>Body</p>');
|
|
201
|
-
expect(html).toContain('<p>Careful</p>');
|
|
202
|
-
});
|
|
203
|
-
});
|