-
Notifications
You must be signed in to change notification settings - Fork 144
Expand file tree
/
Copy pathimages.ts
More file actions
69 lines (66 loc) · 2.5 KB
/
images.ts
File metadata and controls
69 lines (66 loc) · 2.5 KB
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
import type { Plugin } from 'unified';
import type { Container, Paragraph, PhrasingContent, Image } from 'myst-spec';
import type { VFile } from 'vfile';
import { select, selectAll } from 'unist-util-select';
import { visit, SKIP } from 'unist-util-visit';
import type { GenericParent } from 'myst-common';
import { fileWarn, toText, RuleId } from 'myst-common';
const TRANSFORM_SOURCE = 'myst-transforms:images';
/**
* Generate image alt text from figure caption
*/
export function imageAltTextTransform(tree: GenericParent) {
const containers = selectAll('container', tree) as Container[];
// Go through containers in reverse so subfigures captions are preferentially applied
containers.reverse().forEach((container) => {
const images = selectAll('image', container) as Image[];
images.forEach((image) => {
if (!image || image.alt) return;
// Only look at direct child captions
const para = select(
'paragraph',
container.children.find((child) => child.type === 'caption'),
) as Paragraph;
if (!para) return;
// Do not write the captionNumber to image alt text
const content = para.children?.filter((n) => (n.type as string) !== 'captionNumber');
if (!content || content.length < 1) return;
image.alt = toText(content as PhrasingContent[]);
(image.data ??= {}).altTextIsAutoGenerated = true;
});
});
}
export function imageNoAltTextTransform(tree: GenericParent, file: VFile) {
visit(tree, ['output', 'image'], (node) => {
switch (node.type) {
// Do not recurse into outputs, as they rarely have alt-texts and are usually embedded
// into a figure that does
case 'output': {
return SKIP;
}
case 'image': {
if (node.alt == null) {
fileWarn(file, `missing alt text for ${node.url}`, {
ruleId: RuleId.imageHasAltText,
node: node,
source: TRANSFORM_SOURCE,
key: node.url,
});
}
if (node.data?.altTextIsAutoGenerated) {
fileWarn(file, `alt text for ${node.url} was auto-generated`, {
ruleId: RuleId.imageAltTextGenerated,
node: node,
source: TRANSFORM_SOURCE,
key: node.url,
note: 'You can remove this warning by writing your own alt text',
});
}
}
}
});
}
export const imageAltTextPlugin: Plugin<[], GenericParent, GenericParent> = () => (tree, file) => {
imageAltTextTransform(tree);
imageNoAltTextTransform(tree, file);
};