@peaceroad/markdown-it-figure-with-p-caption 0.14.2 → 0.15.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.
- package/README.md +596 -579
- package/index.js +290 -167
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,579 +1,596 @@
|
|
|
1
|
-
# p7d-markdown-it-figure-with-p-caption
|
|
2
|
-
|
|
3
|
-
This markdown-it plugin converts paragraphs representing captions before or after image/table/code/video/audio/iframe into `figcaption` element, and wraps them in `figure` element. Caption parsing (labels, filenames, spacing rules) is delegated to [`p7d-markdown-it-p-captions`](https://www.npmjs.com/package/p7d-markdown-it-p-captions), so this plugin focuses on detecting the surrounding structure. Optionally, you have the option to wrap it in a `figure` element, even if there is no caption paragraph.
|
|
4
|
-
|
|
5
|
-
For images, even if they don't have a caption paragraph, they can be treated as captions if they have a caption string in the image's `alt`/`title` text (there is also an option to promote them to captions even if they don't have that string).
|
|
6
|
-
|
|
7
|
-
Optionally, you can auto-number image and table caption paragraphs starting from the beginning of the document if they only have label names.
|
|
8
|
-
|
|
9
|
-
**Note.** If you want to adjust the image `width`/`height`, please also use [`@peaceroad/markdown-it-renderer-image`](https://www.npmjs.com/package/@peaceroad/markdown-it-renderer-image). Also, if you want to use the `samp` element when displaying terminal output, please also use [`@peaceroad/markdown-it-renderer-fence`](https://www.npmjs.com/package/@peaceroad/markdown-it-renderer-fence). This document shows output using the latter option.
|
|
10
|
-
|
|
11
|
-
## Behavior
|
|
12
|
-
|
|
13
|
-
### Image
|
|
14
|
-
|
|
15
|
-
- Pure image paragraphs (``) become `<figure class="f-img">` blocks as soon as a caption paragraph (previous or next) or an auto-detected caption exists.
|
|
16
|
-
- Auto detection runs per image paragraph when `autoCaptionDetection` is `true` (default). The priority is:
|
|
17
|
-
1. Caption paragraphs immediately before or after the image (standard syntax).
|
|
18
|
-
2. Image `alt` text that already matches p7d-markdown-it-p-captions label formats (`Figure. `, `Figure 1. `, `図 `,`図1 `, etc.).
|
|
19
|
-
3. Image `title` attribute that matches the same labels.
|
|
20
|
-
4. Optional fallbacks (`autoAltCaption`, `autoTitleCaption`) that inject the label when the alt/title lacks one.
|
|
21
|
-
- `autoAltCaption`: `false` (default), `true`, or a string label. `true` inspects the first sentence of the caption text and picks `Figure` / `図` based on detected language; a string uses that label verbatim.
|
|
22
|
-
- `autoTitleCaption`: same behavior but sourced from the image `title`. It stays off by default so other plugins can keep using the `title` attribute for metadata.
|
|
23
|
-
- Set `autoCaptionDetection: false` to disable the auto-caption workflow entirely.
|
|
24
|
-
- Multi-image paragraphs are still wrapped as one figure when `multipleImages: true` (default). Layout-specific classes help with styling:
|
|
25
|
-
- `f-img-horizontal` when images sit on the same line (space-delimited).
|
|
26
|
-
- `f-img-vertical` when separated only by soft breaks.
|
|
27
|
-
- `f-img-multiple` for mixed layouts.
|
|
28
|
-
- Automatic detection inspects only the first image in the paragraph. If it yields a caption, the entire figure reuses that caption while later images keep their own `alt`/`title`.
|
|
29
|
-
- Paragraphs that contain only images also convert when they appear inside loose lists (leave blank lines between items), blockquotes, or description lists.
|
|
30
|
-
|
|
31
|
-
### Table
|
|
32
|
-
|
|
33
|
-
- Markdown tables (including those produced by `markdown-it-multimd-table` or similar) convert into `<figure class="f-table">` blocks.
|
|
34
|
-
- Caption paragraphs immediately before/after the table become `<figcaption>` element ahead of the `<table>`.
|
|
35
|
-
|
|
36
|
-
### Code block
|
|
37
|
-
|
|
38
|
-
- Captions labeled `Code. `, `Terminal. `, etc. wrap the fence in `<figure class="f-pre-code">` / `<figure class="f-pre-samp">`.
|
|
39
|
-
- If `roleDocExample: true`, these figures add `role="doc-example"`.
|
|
40
|
-
|
|
41
|
-
### Blockquote
|
|
42
|
-
|
|
43
|
-
- Captioned blockquotes (e.g., “Source. A paragraph. Ewritten immediately before or after `> ...`) become `<figure class="f-blockquote">` while keeping the original blockquote intact.
|
|
44
|
-
|
|
45
|
-
### Video & Audio
|
|
46
|
-
|
|
47
|
-
- Inline HTML `<video>` and `<audio>` tags are detected as media figures (`<figure class="f-video">` and `<figure class="f-audio">`).
|
|
48
|
-
- A caption paragraph labeled `Video. ` / `Audio. ` (or any registered label) is promoted to `<figcaption>` before/after the media so controls remain unobstructed.
|
|
49
|
-
|
|
50
|
-
### Embedded content by iframe
|
|
51
|
-
|
|
52
|
-
- Inline HTML `<iframe>` elements become `<figure class="f-video">` when they point to known video hosts (YouTube `youtube.com` / `youtube-nocookie.com`, Vimeo `player.vimeo.com`).
|
|
53
|
-
- Blockquote-based social embeds (Twitter/X `twitter-tweet`, Mastodon `mastodon-embed`, Bluesky `bluesky-embed`, Instagram `instagram-media`, Tumblr `text-post-media`) are treated like iframe-type embeds when their `class` matches those providers. By default they become `<figure class="f-img">` so the caption label behaves like an image label (Labels can also use quote labels). You can override that figure class with `figureClassThatWrapsIframeTypeBlockquote` or the global `allIframeTypeFigureClassName`.
|
|
54
|
-
- `p7d-markdown-it-p-captions` ships with a `Slide.` label. When you use it (for example with Speaker Deck or SlideShare iframes), the `<figure>` wrapper automatically switches to `f-slide` (or whatever you set via `figureClassThatWrapsSlides`) so slides can get their own layout. If `allIframeTypeFigureClassName` is also configured, that class takes precedence even for slides, so you get a uniform embed wrapper without touching the slide option.
|
|
55
|
-
- All other iframes fall back to `<figure class="f-iframe">` unless you override the class via `allIframeTypeFigureClassName`.
|
|
56
|
-
|
|
57
|
-
### label span class name
|
|
58
|
-
|
|
59
|
-
- The label inside the figcaption (the `span` element used for the label) is generated by `p7d-markdown-it-p-captions`, not by this plugin. By default the class name is formed by combining `classPrefix` with the mark name, producing names such as `f-img-label`, `f-video-label`, `f-blockquote-label`, and `f-slide-label`.
|
|
60
|
-
- With `markdown-it-attrs`, any attribute block (`{ .foo #bar }`) attached to the caption paragraph is moved to the generated `<figure>` by default (`styleProcess: true`). This keeps per-figure classes/IDs on the wrapper instead of the original paragraph; disable the option only if you explicitly want the attributes to stay on the paragraph.
|
|
61
|
-
|
|
62
|
-
## Behavior Customization
|
|
63
|
-
|
|
64
|
-
### Styles
|
|
65
|
-
|
|
66
|
-
- Set `allIframeTypeFigureClassName: 'f-embed'` (recommended) to force a single CSS class across `<iframe>` and social-embed figures so they can share styles, ensuring every embed wrapper shares the same predictable class name.
|
|
67
|
-
- `figureClassThatWrapsIframeTypeBlockquote`: override the class used when blockquote-based embeds (Twitter, Mastodon, Bluesky) are wrapped.
|
|
68
|
-
- `figureClassThatWrapsSlides`: override the class assigned when a caption paragraph uses the `Slide.` label.
|
|
69
|
-
- `classPrefix` (default `f`) controls the CSS namespace for every figure (`f-img`, `f-table`, etc.) so you can align with existing styles.
|
|
70
|
-
|
|
71
|
-
### Wrapping without captions
|
|
72
|
-
|
|
73
|
-
- `oneImageWithoutCaption`: turn single-image paragraphs into `<figure>` elements even when no caption paragraph/auto caption is present. This is independent of automatic detection.
|
|
74
|
-
- `videoWithoutCaption`, `audioWithoutCaption`, `iframeWithoutCaption`, `iframeTypeBlockquoteWithoutCaption`: wrap the respective media blocks without caption.
|
|
75
|
-
|
|
76
|
-
### Caption text helpers (delegated to `p7d-markdown-it-p-captions`)
|
|
77
|
-
|
|
78
|
-
Every option below is forwarded verbatim to `p7d-markdown-it-p-captions`, which owns the actual figcaption rendering:
|
|
79
|
-
|
|
80
|
-
- `strongFilename` / `dquoteFilename`: pull out filenames from captions using `**filename**` or `"filename"` syntax and wrap them in `<strong class="f-*-filename">`.
|
|
81
|
-
- `jointSpaceUseHalfWidth`: replace full-width space between Japanese labels and caption body with half-width space.
|
|
82
|
-
- `bLabel` / `strongLabel`: emphasize the label span itself.
|
|
83
|
-
- `removeUnnumberedLabel`: drop the leading “Figure. Etext entirely when no label number is present. Use `removeUnnumberedLabelExceptMarks` to keep specific labels (e.g., `['blockquote']` keeps `Quote. `).
|
|
84
|
-
- `removeMarkNameInCaptionClass`: replace `.f-img-label` / `.f-table-label` with the generic `.f-label`.
|
|
85
|
-
- `wrapCaptionBody`: wrap the non-label caption text in a span element.
|
|
86
|
-
- `hasNumClass`: add a class attribute to label span element if it has a label number.
|
|
87
|
-
- `labelClassFollowsFigure`: mirror the resolved `<figure>` class onto the `figcaption` spans (`f-embed-label`, `f-embed-label-joint`, `f-embed-body`, etc.) when you want captions styled alongside the wrapper.
|
|
88
|
-
- `figureToLabelClassMap`: extend `labelClassFollowsFigure` by mapping specific figure classes (e.g., `f-embed`) to custom caption label classes such as `caption-embed caption-social` for fine-grained control.
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
- `
|
|
94
|
-
-
|
|
95
|
-
-
|
|
96
|
-
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
import
|
|
103
|
-
import
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
.use(
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
// <
|
|
112
|
-
// <
|
|
113
|
-
//
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
//
|
|
134
|
-
//
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
[
|
|
178
|
-
|
|
179
|
-
<
|
|
180
|
-
<
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
<
|
|
191
|
-
<
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
|
200
|
-
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
<
|
|
205
|
-
<
|
|
206
|
-
<table>
|
|
207
|
-
<
|
|
208
|
-
<
|
|
209
|
-
<
|
|
210
|
-
<th>
|
|
211
|
-
</
|
|
212
|
-
</
|
|
213
|
-
|
|
214
|
-
<
|
|
215
|
-
<
|
|
216
|
-
<td>
|
|
217
|
-
</
|
|
218
|
-
</
|
|
219
|
-
</
|
|
220
|
-
</
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
<
|
|
233
|
-
<pre
|
|
234
|
-
|
|
235
|
-
</
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
<
|
|
248
|
-
<blockquote>
|
|
249
|
-
<
|
|
250
|
-
|
|
251
|
-
</
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
<
|
|
265
|
-
<pre
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
</
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
<
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
<
|
|
282
|
-
<
|
|
283
|
-
<
|
|
284
|
-
|
|
285
|
-
</
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
<
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
<
|
|
298
|
-
<audio
|
|
299
|
-
<
|
|
300
|
-
|
|
301
|
-
</
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
<
|
|
312
|
-
<
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
<
|
|
324
|
-
<
|
|
325
|
-
</
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
<
|
|
336
|
-
<
|
|
337
|
-
</
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
<
|
|
348
|
-
<
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
<
|
|
361
|
-
<
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
<
|
|
371
|
-
<
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
<
|
|
389
|
-
<
|
|
390
|
-
<
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
<
|
|
406
|
-
<
|
|
407
|
-
<
|
|
408
|
-
<img src="
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
, so this plugin focuses on detecting the surrounding structure. Optionally, you have the option to wrap it in a `figure` element, even if there is no caption paragraph.
|
|
4
|
+
|
|
5
|
+
For images, even if they don't have a caption paragraph, they can be treated as captions if they have a caption string in the image's `alt`/`title` text (there is also an option to promote them to captions even if they don't have that string).
|
|
6
|
+
|
|
7
|
+
Optionally, you can auto-number image and table caption paragraphs starting from the beginning of the document if they only have label names.
|
|
8
|
+
|
|
9
|
+
**Note.** If you want to adjust the image `width`/`height`, please also use [`@peaceroad/markdown-it-renderer-image`](https://www.npmjs.com/package/@peaceroad/markdown-it-renderer-image). Also, if you want to use the `samp` element when displaying terminal output, please also use [`@peaceroad/markdown-it-renderer-fence`](https://www.npmjs.com/package/@peaceroad/markdown-it-renderer-fence). This document shows output using the latter option.
|
|
10
|
+
|
|
11
|
+
## Behavior
|
|
12
|
+
|
|
13
|
+
### Image
|
|
14
|
+
|
|
15
|
+
- Pure image paragraphs (``) become `<figure class="f-img">` blocks as soon as a caption paragraph (previous or next) or an auto-detected caption exists.
|
|
16
|
+
- Auto detection runs per image paragraph when `autoCaptionDetection` is `true` (default). The priority is:
|
|
17
|
+
1. Caption paragraphs immediately before or after the image (standard syntax).
|
|
18
|
+
2. Image `alt` text that already matches p7d-markdown-it-p-captions label formats (`Figure. `, `Figure 1. `, `図 `,`図1 `, etc.).
|
|
19
|
+
3. Image `title` attribute that matches the same labels.
|
|
20
|
+
4. Optional fallbacks (`autoAltCaption`, `autoTitleCaption`) that inject the label when the alt/title lacks one.
|
|
21
|
+
- `autoAltCaption`: `false` (default), `true`, or a string label. `true` inspects the first sentence of the caption text and picks `Figure` / `図` based on detected language; a string uses that label verbatim.
|
|
22
|
+
- `autoTitleCaption`: same behavior but sourced from the image `title`. It stays off by default so other plugins can keep using the `title` attribute for metadata.
|
|
23
|
+
- Set `autoCaptionDetection: false` to disable the auto-caption workflow entirely.
|
|
24
|
+
- Multi-image paragraphs are still wrapped as one figure when `multipleImages: true` (default). Layout-specific classes help with styling:
|
|
25
|
+
- `f-img-horizontal` when images sit on the same line (space-delimited).
|
|
26
|
+
- `f-img-vertical` when separated only by soft breaks.
|
|
27
|
+
- `f-img-multiple` for mixed layouts.
|
|
28
|
+
- Automatic detection inspects only the first image in the paragraph. If it yields a caption, the entire figure reuses that caption while later images keep their own `alt`/`title`.
|
|
29
|
+
- Paragraphs that contain only images also convert when they appear inside loose lists (leave blank lines between items), blockquotes, or description lists.
|
|
30
|
+
|
|
31
|
+
### Table
|
|
32
|
+
|
|
33
|
+
- Markdown tables (including those produced by `markdown-it-multimd-table` or similar) convert into `<figure class="f-table">` blocks.
|
|
34
|
+
- Caption paragraphs immediately before/after the table become `<figcaption>` element ahead of the `<table>`.
|
|
35
|
+
|
|
36
|
+
### Code block
|
|
37
|
+
|
|
38
|
+
- Captions labeled `Code. `, `Terminal. `, etc. wrap the fence in `<figure class="f-pre-code">` / `<figure class="f-pre-samp">`.
|
|
39
|
+
- If `roleDocExample: true`, these figures add `role="doc-example"`.
|
|
40
|
+
|
|
41
|
+
### Blockquote
|
|
42
|
+
|
|
43
|
+
- Captioned blockquotes (e.g., “Source. A paragraph. Ewritten immediately before or after `> ...`) become `<figure class="f-blockquote">` while keeping the original blockquote intact.
|
|
44
|
+
|
|
45
|
+
### Video & Audio
|
|
46
|
+
|
|
47
|
+
- Inline HTML `<video>` and `<audio>` tags are detected as media figures (`<figure class="f-video">` and `<figure class="f-audio">`).
|
|
48
|
+
- A caption paragraph labeled `Video. ` / `Audio. ` (or any registered label) is promoted to `<figcaption>` before/after the media so controls remain unobstructed.
|
|
49
|
+
|
|
50
|
+
### Embedded content by iframe
|
|
51
|
+
|
|
52
|
+
- Inline HTML `<iframe>` elements become `<figure class="f-video">` when they point to known video hosts (YouTube `youtube.com` / `youtube-nocookie.com`, Vimeo `player.vimeo.com`).
|
|
53
|
+
- Blockquote-based social embeds (Twitter/X `twitter-tweet`, Mastodon `mastodon-embed`, Bluesky `bluesky-embed`, Instagram `instagram-media`, Tumblr `text-post-media`) are treated like iframe-type embeds when their `class` matches those providers. By default they become `<figure class="f-img">` so the caption label behaves like an image label (Labels can also use quote labels). You can override that figure class with `figureClassThatWrapsIframeTypeBlockquote` or the global `allIframeTypeFigureClassName`.
|
|
54
|
+
- `p7d-markdown-it-p-captions` ships with a `Slide.` label. When you use it (for example with Speaker Deck or SlideShare iframes), the `<figure>` wrapper automatically switches to `f-slide` (or whatever you set via `figureClassThatWrapsSlides`) so slides can get their own layout. If `allIframeTypeFigureClassName` is also configured, that class takes precedence even for slides, so you get a uniform embed wrapper without touching the slide option.
|
|
55
|
+
- All other iframes fall back to `<figure class="f-iframe">` unless you override the class via `allIframeTypeFigureClassName`.
|
|
56
|
+
|
|
57
|
+
### label span class name
|
|
58
|
+
|
|
59
|
+
- The label inside the figcaption (the `span` element used for the label) is generated by `p7d-markdown-it-p-captions`, not by this plugin. By default the class name is formed by combining `classPrefix` with the mark name, producing names such as `f-img-label`, `f-video-label`, `f-blockquote-label`, and `f-slide-label`.
|
|
60
|
+
- With `markdown-it-attrs`, any attribute block (`{ .foo #bar }`) attached to the caption paragraph is moved to the generated `<figure>` by default (`styleProcess: true`). This keeps per-figure classes/IDs on the wrapper instead of the original paragraph; disable the option only if you explicitly want the attributes to stay on the paragraph.
|
|
61
|
+
|
|
62
|
+
## Behavior Customization
|
|
63
|
+
|
|
64
|
+
### Styles
|
|
65
|
+
|
|
66
|
+
- Set `allIframeTypeFigureClassName: 'f-embed'` (recommended) to force a single CSS class across `<iframe>` and social-embed figures so they can share styles, ensuring every embed wrapper shares the same predictable class name.
|
|
67
|
+
- `figureClassThatWrapsIframeTypeBlockquote`: override the class used when blockquote-based embeds (Twitter, Mastodon, Bluesky) are wrapped.
|
|
68
|
+
- `figureClassThatWrapsSlides`: override the class assigned when a caption paragraph uses the `Slide.` label.
|
|
69
|
+
- `classPrefix` (default `f`) controls the CSS namespace for every figure (`f-img`, `f-table`, etc.) so you can align with existing styles.
|
|
70
|
+
|
|
71
|
+
### Wrapping without captions
|
|
72
|
+
|
|
73
|
+
- `oneImageWithoutCaption`: turn single-image paragraphs into `<figure>` elements even when no caption paragraph/auto caption is present. This is independent of automatic detection.
|
|
74
|
+
- `videoWithoutCaption`, `audioWithoutCaption`, `iframeWithoutCaption`, `iframeTypeBlockquoteWithoutCaption`: wrap the respective media blocks without caption.
|
|
75
|
+
|
|
76
|
+
### Caption text helpers (delegated to `p7d-markdown-it-p-captions`)
|
|
77
|
+
|
|
78
|
+
Every option below is forwarded verbatim to `p7d-markdown-it-p-captions`, which owns the actual figcaption rendering:
|
|
79
|
+
|
|
80
|
+
- `strongFilename` / `dquoteFilename`: pull out filenames from captions using `**filename**` or `"filename"` syntax and wrap them in `<strong class="f-*-filename">`.
|
|
81
|
+
- `jointSpaceUseHalfWidth`: replace full-width space between Japanese labels and caption body with half-width space.
|
|
82
|
+
- `bLabel` / `strongLabel`: emphasize the label span itself.
|
|
83
|
+
- `removeUnnumberedLabel`: drop the leading “Figure. Etext entirely when no label number is present. Use `removeUnnumberedLabelExceptMarks` to keep specific labels (e.g., `['blockquote']` keeps `Quote. `).
|
|
84
|
+
- `removeMarkNameInCaptionClass`: replace `.f-img-label` / `.f-table-label` with the generic `.f-label`.
|
|
85
|
+
- `wrapCaptionBody`: wrap the non-label caption text in a span element.
|
|
86
|
+
- `hasNumClass`: add a class attribute to label span element if it has a label number.
|
|
87
|
+
- `labelClassFollowsFigure`: mirror the resolved `<figure>` class onto the `figcaption` spans (`f-embed-label`, `f-embed-label-joint`, `f-embed-body`, etc.) when you want captions styled alongside the wrapper.
|
|
88
|
+
- `figureToLabelClassMap`: extend `labelClassFollowsFigure` by mapping specific figure classes (e.g., `f-embed`) to custom caption label classes such as `caption-embed caption-social` for fine-grained control.
|
|
89
|
+
- `labelPrefixMarker`: allow a leading marker before labels (string or array, e.g., `*Figure. ...`). Arrays are limited to two markers; extras are ignored.
|
|
90
|
+
|
|
91
|
+
### Automatic numbering
|
|
92
|
+
|
|
93
|
+
- `autoLabelNumberSets`: enable numbering per media type. Pass an array such as `['img']`, `['table']`, or `['img', 'table']`.
|
|
94
|
+
- `autoLabelNumber`: shorthand for turning numbering on for both images and tables without passing the array yourself. Provide `autoLabelNumberSets` explicitly (e.g., `['img']`) when you need finer control—the explicit array always wins.
|
|
95
|
+
- Counters start at `1` near the top of the document and increment sequentially per media type. Figures and tables keep independent counters even when mixed together.
|
|
96
|
+
- The counter only advances when a real caption exists (paragraph, auto-detected alt/title, or fallback text). Figures emitted solely because of `oneImageWithoutCaption` stay unnumbered.
|
|
97
|
+
- Manual numbers inside the caption text (e.g., `Figure 5.`) always win. The plugin updates its internal counter so the next automatic number becomes `6`. This applies to captions sourced from paragraphs, auto detection, and fallback captions.
|
|
98
|
+
|
|
99
|
+
## Basic Usage
|
|
100
|
+
|
|
101
|
+
```js
|
|
102
|
+
import mdit from 'markdown-it'
|
|
103
|
+
import mditFigureWithPCaption from '@peaceroad/markdown-it-figure-with-p-caption'
|
|
104
|
+
import mditRendererFence from '@peaceroad/markdown-it-renderer-fence' // optional but keeps fences aligned with samples
|
|
105
|
+
|
|
106
|
+
const md = mdit({ html: true, langPrefix: 'language-', })
|
|
107
|
+
.use(mditFigureWithPCaption)
|
|
108
|
+
.use(mditRendererFence)
|
|
109
|
+
|
|
110
|
+
console.log(md.render('Figure. A Cat.\n\n'))
|
|
111
|
+
// <figure class="f-img">
|
|
112
|
+
// <figcaption><span class="f-img-label">Figure<span class="f-img-label-joint">.</span></span> A Cat.</figcaption>
|
|
113
|
+
// <img src="cat.jpg" alt="A cat">
|
|
114
|
+
// </figure>
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Basic Recommended Options
|
|
118
|
+
|
|
119
|
+
Auto label numbering for images and tables.
|
|
120
|
+
|
|
121
|
+
```js
|
|
122
|
+
const figureOption = {
|
|
123
|
+
// Opinionated defaults
|
|
124
|
+
oneImageWithoutCaption: true,
|
|
125
|
+
videoWithoutCaption: true,
|
|
126
|
+
audioWithoutCaption: true,
|
|
127
|
+
iframeWithoutCaption: true,
|
|
128
|
+
iframeTypeBlockquoteWithoutCaption: true,
|
|
129
|
+
removeUnnumberedLabelExceptMarks: ['blockquote'], // keep “Quote. Elabels even when unnumbered
|
|
130
|
+
allIframeTypeFigureClassName: 'f-embed', // apply a uniform class to every iframe-style embed
|
|
131
|
+
autoLabelNumber: true,
|
|
132
|
+
|
|
133
|
+
// If you want to enable auto alt/title captioning fallbacks without caption label.
|
|
134
|
+
//autoAltCaption: true,
|
|
135
|
+
//autoTitleCaption: true,
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
If there is no label number, the label will also be deleted.
|
|
140
|
+
|
|
141
|
+
```js
|
|
142
|
+
const figureOption = {
|
|
143
|
+
oneImageWithoutCaption: true,
|
|
144
|
+
videoWithoutCaption: true,
|
|
145
|
+
audioWithoutCaption: true,
|
|
146
|
+
iframeWithoutCaption: true,
|
|
147
|
+
iframeTypeBlockquoteWithoutCaption: true,
|
|
148
|
+
removeUnnumberedLabelExceptMarks: ['blockquote'],
|
|
149
|
+
allIframeTypeFigureClassName: 'f-embed',
|
|
150
|
+
removeUnnumberedLabel: true,
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
These options can be used as follows:
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
const md = mdit({ html: true }).use(mditFigureWithPCaption, figureOption)
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Conversion Examples
|
|
161
|
+
|
|
162
|
+
### Default before/after caption paragraph detection
|
|
163
|
+
|
|
164
|
+
~~~
|
|
165
|
+
[Markdown]
|
|
166
|
+

|
|
167
|
+
|
|
168
|
+
[HTML]
|
|
169
|
+
<p><img src="figure.jpg" alt="A single cat"></p>
|
|
170
|
+
|
|
171
|
+
<!-- Above: If oneImageWithoutCaption is true, this img element has wrapped into figure element without caption. -->
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
[Markdown]
|
|
175
|
+
Figure. A Caption.
|
|
176
|
+
|
|
177
|
+

|
|
178
|
+
[HTML]
|
|
179
|
+
<figure class="f-img">
|
|
180
|
+
<figcaption><span class="f-img-label">Figure<span class="f-img-label-joint">.</span></span> A Caption.</figcaption>
|
|
181
|
+
<img src="figure.jpg" alt="A single cat">
|
|
182
|
+
</figure>
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
[Markdown]
|
|
186
|
+

|
|
187
|
+
|
|
188
|
+
Figure. A Caption.
|
|
189
|
+
[HTML]
|
|
190
|
+
<figure class="f-img">
|
|
191
|
+
<img src="figure.jpg" alt="A single cat">
|
|
192
|
+
<figcaption><span class="f-img-label">Figure<span class="f-img-label-joint">.</span></span> A Caption.</figcaption>
|
|
193
|
+
</figure>
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
[Markdown]
|
|
197
|
+
Table. A Caption.
|
|
198
|
+
|
|
199
|
+
| Tokyo | Osaka |
|
|
200
|
+
| ----- | ----- |
|
|
201
|
+
| Sushi | Takoyaki |
|
|
202
|
+
|
|
203
|
+
[HTML]
|
|
204
|
+
<p>A paragraph.</p>
|
|
205
|
+
<figure class="f-table">
|
|
206
|
+
<figcaption><span class="f-table-label">Table<span class="f-table-label-joint">.</span></span> A Caption.</figcaption>
|
|
207
|
+
<table>
|
|
208
|
+
<thead>
|
|
209
|
+
<tr>
|
|
210
|
+
<th>Tokyo</th>
|
|
211
|
+
<th>Osaka</th>
|
|
212
|
+
</tr>
|
|
213
|
+
</thead>
|
|
214
|
+
<tbody>
|
|
215
|
+
<tr>
|
|
216
|
+
<td>Sushi</td>
|
|
217
|
+
<td>Takoyaki</td>
|
|
218
|
+
</tr>
|
|
219
|
+
</tbody>
|
|
220
|
+
</table>
|
|
221
|
+
</figure>
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
[Markdown]
|
|
225
|
+
Code. A Caption.
|
|
226
|
+
|
|
227
|
+
```js
|
|
228
|
+
console.log('Hello World!');
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
[HTML]
|
|
232
|
+
<figure class="f-pre-code">
|
|
233
|
+
<figcaption><span class="f-pre-code-label">Code<span class="f-pre-code-label-joint">.</span></span> A Caption.</figcaption>
|
|
234
|
+
<pre><code class="language-js">console.log('Hello World!');
|
|
235
|
+
</code></pre>
|
|
236
|
+
</figure>
|
|
237
|
+
|
|
238
|
+
<!-- Above: class attribute of code element is generated by markdown-it option. -->
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
[Markdown]
|
|
242
|
+
Source. A Caption.
|
|
243
|
+
|
|
244
|
+
> A quoted paragraph.
|
|
245
|
+
|
|
246
|
+
[HTML]
|
|
247
|
+
<figure class="f-blockquote">
|
|
248
|
+
<figcaption><span class="f-blockquote-label">Source<span class="f-blockquote-label-joint">.</span></span> A Caption.</figcaption>
|
|
249
|
+
<blockquote>
|
|
250
|
+
<p>A quoted paragraph.</p>
|
|
251
|
+
</blockquote>
|
|
252
|
+
</figure>
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
[Markdown]
|
|
256
|
+
Terminal. A Caption.
|
|
257
|
+
|
|
258
|
+
```samp
|
|
259
|
+
$ pwd
|
|
260
|
+
/home/user
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
[HTML]
|
|
264
|
+
<figure class="f-pre-samp">
|
|
265
|
+
<figcaption><span class="f-pre-samp-label">Terminal<span class="f-pre-samp-label-joint">.</span></span> A Caption.</figcaption>
|
|
266
|
+
<pre><samp>$ pwd
|
|
267
|
+
/home/user
|
|
268
|
+
</samp></pre>
|
|
269
|
+
</figure>
|
|
270
|
+
|
|
271
|
+
<!-- Above: When @peaceroad/markdown-it-renderer-fence is used, samp element are generated automatically for `samp` fences. -->
|
|
272
|
+
|
|
273
|
+
[Markdown]
|
|
274
|
+
Video. A mp4.
|
|
275
|
+
|
|
276
|
+
<video controls width="400" height="300">
|
|
277
|
+
<source src="example.mp4" type="video/mp4">
|
|
278
|
+
</video>
|
|
279
|
+
|
|
280
|
+
[HTML]
|
|
281
|
+
<figure class="f-video">
|
|
282
|
+
<figcaption><span class="f-video-label">Video<span class="f-video-label-joint">.</span></span> A mp4.</figcaption>
|
|
283
|
+
<video controls width="400" height="300">
|
|
284
|
+
<source src="example.mp4" type="video/mp4">
|
|
285
|
+
</video>
|
|
286
|
+
</figure>
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
[Markdown]
|
|
290
|
+
Audio. A narration.
|
|
291
|
+
|
|
292
|
+
<audio controls>
|
|
293
|
+
<source src="example.mp3" type="audio/mpeg">
|
|
294
|
+
</audio>
|
|
295
|
+
|
|
296
|
+
[HTML]
|
|
297
|
+
<figure class="f-audio">
|
|
298
|
+
<figcaption><span class="f-audio-label">Audio<span class="f-audio-label-joint">.</span></span> A narration.</figcaption>
|
|
299
|
+
<audio controls>
|
|
300
|
+
<source src="example.mp3" type="audio/mpeg">
|
|
301
|
+
</audio>
|
|
302
|
+
</figure>
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
[Markdown]
|
|
306
|
+
Video. A YouTube video.
|
|
307
|
+
|
|
308
|
+
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/XXXXXXXXXXX" ...></iframe>
|
|
309
|
+
|
|
310
|
+
[HTML]
|
|
311
|
+
<figure class="f-video">
|
|
312
|
+
<figcaption><span class="f-video-label">Video<span class="f-video-label-joint">.</span></span> A YouTube video.</figcaption>
|
|
313
|
+
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/XXXXXXXXXXX" ...></iframe>
|
|
314
|
+
</figure>
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
[Markdown]
|
|
318
|
+
Figure. Mastodon post.
|
|
319
|
+
|
|
320
|
+
<blockquote class="mastodon-embed" ...> ...... </blockquote><script async src="https://example.com/embed.js"></script>
|
|
321
|
+
|
|
322
|
+
[HTML]
|
|
323
|
+
<figure class="f-img">
|
|
324
|
+
<figcaption><span class="f-img-label">Figure<span class="f-img-label-joint">.</span></span> Mastodon post.</figcaption>
|
|
325
|
+
<blockquote class="mastodon-embed" ...> ...... </blockquote><script async src="https://example.com/embed.js"></script>
|
|
326
|
+
</figure>
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
[Markdown]
|
|
330
|
+
Quote. Mastodon post.
|
|
331
|
+
|
|
332
|
+
<blockquote class="mastodon-embed" ...> ...... </blockquote><script async src="https://example.com/embed.js"></script>
|
|
333
|
+
|
|
334
|
+
[HTML]
|
|
335
|
+
<figure class="f-img">
|
|
336
|
+
<figcaption><span class="f-blockquote-label">Quote<span class="f-blockquote-label-joint">.</span></span> X post.</figcaption>
|
|
337
|
+
<blockquote class="mastodon-embed" ...> ...... </blockquote><script async src="https://example.com/embed.js"></script>
|
|
338
|
+
</figure>
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
[Markdown]
|
|
342
|
+
Slide. A Speaker Deck.
|
|
343
|
+
|
|
344
|
+
<iframe src="https://speakerdeck.com/player/XXXXXXXXXXX" width="640" height="360" frameborder="0" allowfullscreen></iframe>
|
|
345
|
+
|
|
346
|
+
[HTML]
|
|
347
|
+
<figure class="f-slide">
|
|
348
|
+
<figcaption><span class="f-slide-label">Slide<span class="f-slide-label-joint">.</span></span> A Speaker Deck.</figcaption>
|
|
349
|
+
<iframe src="https://speakerdeck.com/player/XXXXXXXXXXX" width="640" height="360" frameborder="0" allowfullscreen></iframe>
|
|
350
|
+
</figure>
|
|
351
|
+
~~~
|
|
352
|
+
|
|
353
|
+
### Auto alt/title detection
|
|
354
|
+
|
|
355
|
+
```
|
|
356
|
+
[Markdown]
|
|
357
|
+

|
|
358
|
+
|
|
359
|
+
[HTML]
|
|
360
|
+
<figure class="f-img">
|
|
361
|
+
<figcaption><span class="f-img-label">Figure<span class="f-img-label-joint">.</span></span> A cat.</figcaption>
|
|
362
|
+
<img src="cat.jpg" alt="">
|
|
363
|
+
</figure>
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
[Markdown]
|
|
367
|
+

|
|
368
|
+
|
|
369
|
+
[HTML]
|
|
370
|
+
<figure class="f-img">
|
|
371
|
+
<figcaption><span class="f-img-label">Figure<span class="f-img-label-joint">.</span></span> A cat.</figcaption>
|
|
372
|
+
<img src="cat.jpg" alt="A white cat eats fishs.">
|
|
373
|
+
</figure>
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
### Multiple images
|
|
377
|
+
|
|
378
|
+
~~~
|
|
379
|
+
[Markdown]
|
|
380
|
+
A paragraph. multipleImages: true. horizontal images only.
|
|
381
|
+
|
|
382
|
+
 
|
|
383
|
+
|
|
384
|
+
Figure. Cats.
|
|
385
|
+
|
|
386
|
+
A paragraph.
|
|
387
|
+
[HTML]
|
|
388
|
+
<p>A paragraph. multipleImages: true. horizontal images only</p>
|
|
389
|
+
<figure class="f-img-horizontal">
|
|
390
|
+
<img src="cat1.jpg" alt="Sitting cat"><img src="cat2.jpg" alt="Standing cat">
|
|
391
|
+
<figcaption><span class="f-img-label">Figure<span class="f-img-label-joint">.</span></span> Cats.</figcaption>
|
|
392
|
+
</figure>
|
|
393
|
+
<p>A paragraph.</p>
|
|
394
|
+
|
|
395
|
+
[Markdown]
|
|
396
|
+
A paragraph. multipleImages: true. vertical images only.
|
|
397
|
+
|
|
398
|
+
Figure. Cats.
|
|
399
|
+
|
|
400
|
+

|
|
401
|
+

|
|
402
|
+
|
|
403
|
+
A paragraph.
|
|
404
|
+
[HTML]
|
|
405
|
+
<p>A paragraph. multipleImages: true. vertical images only.</p>
|
|
406
|
+
<figure class="f-img-vertical">
|
|
407
|
+
<figcaption><span class="f-img-label">Figure<span class="f-img-label-joint">.</span></span> Cats.</figcaption>
|
|
408
|
+
<img src="cat1.jpg" alt="Sitting cat">
|
|
409
|
+
<img src="cat2.jpg" alt="Standing cat">
|
|
410
|
+
</figure>
|
|
411
|
+
<p>A paragraph.</p>
|
|
412
|
+
|
|
413
|
+
[Markdown]
|
|
414
|
+
A paragraph. multipleImages: true.
|
|
415
|
+
|
|
416
|
+
Figure. Cats.
|
|
417
|
+
|
|
418
|
+
 
|
|
419
|
+

|
|
420
|
+
|
|
421
|
+
A paragraph.
|
|
422
|
+
[HTML]
|
|
423
|
+
<p>A paragraph. multipleImages: true.</p>
|
|
424
|
+
<figure class="f-img-multiple">
|
|
425
|
+
<figcaption><span class="f-img-label">Figure<span class="f-img-label-joint">.</span></span> Cats.</figcaption>
|
|
426
|
+
<img src="cat1.jpg" alt="Sitting cat"><img src="cat2.jpg" alt="Standing cat">
|
|
427
|
+
<img src="cat3.jpg" alt="Sleeping cat">
|
|
428
|
+
</figure>
|
|
429
|
+
<p>A paragraph.</p>
|
|
430
|
+
~~~
|
|
431
|
+
|
|
432
|
+
## Option Examples
|
|
433
|
+
|
|
434
|
+
### Styles
|
|
435
|
+
|
|
436
|
+
This example uses `classPrefix: 'custom'` and leaves `styleProcess: true` so a trailing `{.notice}` block moves onto the `<figure>` wrapper.
|
|
437
|
+
|
|
438
|
+
```
|
|
439
|
+
[Markdown]
|
|
440
|
+
Figure. Highlighted cat. {.notice}
|
|
441
|
+
|
|
442
|
+

|
|
443
|
+
[HTML]
|
|
444
|
+
<figure class="custom-img notice">
|
|
445
|
+
<figcaption><span class="custom-img-label">Figure<span class="custom-img-label-joint">.</span></span> Highlighted cat.</figcaption>
|
|
446
|
+
<img src="cat.jpg" alt="Highlighted cat">
|
|
447
|
+
</figure>
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
### Automatic detection fallbacks
|
|
451
|
+
|
|
452
|
+
`autoCaptionDetection` combined with `autoAltCaption` / `autoTitleCaption` can still generate caption text even when the original alt/title lacks labels. The corresponding attributes are cleared after conversion so the figcaption becomes the canonical source.
|
|
453
|
+
|
|
454
|
+
```
|
|
455
|
+
[Markdown]
|
|
456
|
+

|
|
457
|
+
|
|
458
|
+
[HTML]
|
|
459
|
+
<figure class="f-img">
|
|
460
|
+
<figcaption><span class="f-img-label">Figure<span class="f-img-label-joint">.</span></span> Alt fallback example</figcaption>
|
|
461
|
+
<img src="bird.jpg" alt="">
|
|
462
|
+
</figure>
|
|
463
|
+
|
|
464
|
+
|
|
465
|
+
[Markdown]
|
|
466
|
+

|
|
467
|
+
|
|
468
|
+
[HTML]
|
|
469
|
+
<figure class="f-img">
|
|
470
|
+
<figcaption><span class="f-img-label">Figure<span class="f-img-label-joint">.</span></span> Plain title text</figcaption>
|
|
471
|
+
<img src="fish.jpg" alt="No caption">
|
|
472
|
+
</figure>
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
### Role helpers
|
|
476
|
+
|
|
477
|
+
Set `roleDocExample: true` to add `role="doc-example"` to code/samp figures.
|
|
478
|
+
|
|
479
|
+
~~~
|
|
480
|
+
[Markdown]
|
|
481
|
+
```samp
|
|
482
|
+
$ pwd
|
|
483
|
+
/home/user
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
[HTML]
|
|
487
|
+
<figure class="f-pre-samp" role="doc-example">
|
|
488
|
+
...
|
|
489
|
+
</figure>
|
|
490
|
+
~~~
|
|
491
|
+
|
|
492
|
+
### Captionless conversion toggles
|
|
493
|
+
|
|
494
|
+
If `oneImageWithoutCaption` is enabled, a single image paragraph will be wrapped with `<figure class="f-img">` even without a caption.
|
|
495
|
+
|
|
496
|
+
```
|
|
497
|
+
[Markdown]
|
|
498
|
+

|
|
499
|
+
|
|
500
|
+
[HTML]
|
|
501
|
+
<figure class="f-img">
|
|
502
|
+
<img src="cat.jpg" alt="A single cat">
|
|
503
|
+
</figure>
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
If `videoWithoutCaption` is enabled, an `iframe` pointing to a known video host (such as YouTube or video elements) will be wrapped with `<figure class="f-video">`.
|
|
507
|
+
|
|
508
|
+
```
|
|
509
|
+
[Markdown]
|
|
510
|
+
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/XXXXXXXXXXX" ...></iframe>
|
|
511
|
+
|
|
512
|
+
[HTML]
|
|
513
|
+
<figure class="f-video">
|
|
514
|
+
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/XXXXXXXXXXX" ...></iframe>
|
|
515
|
+
</figure>
|
|
516
|
+
|
|
517
|
+
|
|
518
|
+
[Markdown]
|
|
519
|
+
<video controls width="400" height="300">
|
|
520
|
+
<source src="example.mp4" type="video/mp4">
|
|
521
|
+
</video>
|
|
522
|
+
[HTML]
|
|
523
|
+
<figure class="f-video">
|
|
524
|
+
<video controls width="400" height="300">
|
|
525
|
+
<source src="example.mp4" type="video/mp4">
|
|
526
|
+
</video>
|
|
527
|
+
</figure>
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
When `iframeWithoutCaption` is enabled, iframe elements will be wrapped with `<figure class="f-iframe">`. And if `iframeTypeBlockquoteWithoutCaption` is enabled, blockquote-based embeds (for example, X) will be wrapped with `<figure class="f-img">` (or another configured class).
|
|
531
|
+
|
|
532
|
+
```
|
|
533
|
+
[Markdown]
|
|
534
|
+
<iframe>
|
|
535
|
+
...
|
|
536
|
+
</iframe>
|
|
537
|
+
|
|
538
|
+
[HTML]
|
|
539
|
+
<figure class="f-iframe">
|
|
540
|
+
<iframe>
|
|
541
|
+
...
|
|
542
|
+
</iframe>
|
|
543
|
+
</figure>
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
### Iframe-type blockquote class override
|
|
547
|
+
|
|
548
|
+
Set `figureClassThatWrapsIframeTypeBlockquote: 'f-social'` (or any class you prefer) to wrap blockquote-based embeds (for example, X, Mastodon, Bluesky) with that class.
|
|
549
|
+
|
|
550
|
+
```
|
|
551
|
+
[Markdown]
|
|
552
|
+
Figure. Twitter embed.
|
|
553
|
+
|
|
554
|
+
<blockquote class="twitter-tweet"><p>Embed content</p></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
|
|
555
|
+
|
|
556
|
+
[HTML]
|
|
557
|
+
<figure class="f-social">
|
|
558
|
+
<figcaption><span class="f-img-label">Figure<span class="f-img-label-joint">.</span></span> Twitter embed.</figcaption>
|
|
559
|
+
<blockquote class="twitter-tweet"><p>Embed content</p></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
|
|
560
|
+
</figure>
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
### All iframe/embed class override
|
|
564
|
+
|
|
565
|
+
Set `allIframeTypeFigureClassName: 'f-embed'` (or any class you prefer) to consolidate iframe-like embeds under one class.
|
|
566
|
+
|
|
567
|
+
```
|
|
568
|
+
[Markdown]
|
|
569
|
+
Video. Custom embed.
|
|
570
|
+
|
|
571
|
+
<iframe width="560" height="315" src="https://example.com/embed/123" title="Custom embed" frameborder="0" allowfullscreen></iframe>
|
|
572
|
+
|
|
573
|
+
[HTML]
|
|
574
|
+
<figure class="f-embed">
|
|
575
|
+
<figcaption><span class="f-video-label">Video<span class="f-video-label-joint">.</span></span> Custom embed.</figcaption>
|
|
576
|
+
<iframe width="560" height="315" src="https://example.com/embed/123" title="Custom embed" frameborder="0" allowfullscreen></iframe>
|
|
577
|
+
</figure>
|
|
578
|
+
```
|
|
579
|
+
|
|
580
|
+
Need matching caption classes too? Combine this option with `labelClassFollowsFigure` (and optionally `figureToLabelClassMap`) so the `figcaption` spans inherit the embed class you just applied (e.g., `f-embed-label`, `f-embed-label-joint`).
|
|
581
|
+
|
|
582
|
+
|
|
583
|
+
### Caption markers
|
|
584
|
+
|
|
585
|
+
- `allowLabelPrefixMarkerWithoutLabel`: when `true`, marker-only paragraphs (e.g., `▼Caption`) are treated as captions without labels. If `labelPrefixMarker` is an array, the first entry is used for the previous caption and the second for the next caption. The marker is stripped from output.
|
|
586
|
+
|
|
587
|
+
```js
|
|
588
|
+
const figureOption = {
|
|
589
|
+
labelPrefixMarker: ['▼', '▲'],
|
|
590
|
+
allowLabelPrefixMarkerWithoutLabel: true,
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
const md = mdit({ html: true }).use(mditFigureWithPCaption, figureOption)
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
The first marker applies to captions before the figure, the second to captions after it.
|