@peaceroad/markdown-it-figure-with-p-caption 0.10.1 → 0.11.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 +42 -0
- package/imgAttrToPCaption.js +104 -0
- package/index.js +131 -174
- package/package.json +6 -3
- package/test/examples-all-iframe-type-figure-class-name.txt +192 -0
- package/test/examples-img-alt-caption-number.en.txt +51 -0
- package/test/examples-img-alt-caption.en.txt +9 -0
- package/test/examples-img-title-caption-number.en.txt +60 -0
- package/test/examples-no-option.txt +27 -0
- package/test/examples-set-figure-number.en.txt +21 -0
- package/test/test.js +29 -1
package/README.md
CHANGED
|
@@ -515,3 +515,45 @@ From version 0.8, role="doc-example" is not included as standard in figure.f-pre
|
|
|
515
515
|
```js
|
|
516
516
|
const mdImgAltCaption = mdit({html: true}).use(mditFigureWithPCaption, {roleDocExample: true})
|
|
517
517
|
```
|
|
518
|
+
|
|
519
|
+
### Option: allIframeTypeFigureClassName
|
|
520
|
+
|
|
521
|
+
From version 0.16.0, unify the figure element that wraps the iframe or blockquote tag in the embed code to figure.f-embed (this may become the default in the future).
|
|
522
|
+
|
|
523
|
+
```js
|
|
524
|
+
const mdAllIframeTypeFigureClassName = mdit({html: true}).use(mdFigureWithPCaption, {
|
|
525
|
+
allIframeTypeFigureClassName: 'f-embed',
|
|
526
|
+
videoWithoutCaption = true,
|
|
527
|
+
iframeWithoutCaption = true,
|
|
528
|
+
iframeTypeBlockquoteWithoutCaption = true,
|
|
529
|
+
}).use(mditAttrs).use(mditRndererFence);
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
```
|
|
533
|
+
[Markdown]
|
|
534
|
+
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/XXXXXXXXXXX" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
|
535
|
+
[HTML]
|
|
536
|
+
<figure class="f-embed">
|
|
537
|
+
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/XXXXXXXXXXX" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
|
538
|
+
</figure>
|
|
539
|
+
|
|
540
|
+
|
|
541
|
+
[Markdown]
|
|
542
|
+
Video. A youtube.
|
|
543
|
+
|
|
544
|
+
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/XXXXXXXXXXX" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
|
545
|
+
[HTML]
|
|
546
|
+
<figure class="f-embed">
|
|
547
|
+
<figcaption><span class="f-video-label">Video<span class="f-video-label-joint">.</span></span> A youtube.</figcaption>
|
|
548
|
+
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/XXXXXXXXXXX" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
|
549
|
+
</figure>
|
|
550
|
+
|
|
551
|
+
|
|
552
|
+
[Markdown]
|
|
553
|
+
<blockquote class="mastodon-embed" data-embed-url="https://mastodon.social/@xxxx/xxxx/embed" ...>xxxxxxxxxxxxxxxx</blockquote> <script data-allowed-prefixes="https://mastodon.social/" async src="https://mastodon.social/embed.js"></script>
|
|
554
|
+
|
|
555
|
+
[HTML]
|
|
556
|
+
<figure class="f-embed">
|
|
557
|
+
<blockquote class="mastodon-embed" data-embed-url="https://mastodon.social/@xxxx/xxxx/embed" ...>xxxxxxxxxxxxxxxx</blockquote> <script data-allowed-prefixes="https://mastodon.social/" async src="https://mastodon.social/embed.js"></script>
|
|
558
|
+
</figure>
|
|
559
|
+
```
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { markReg } from 'p7d-markdown-it-p-captions'
|
|
2
|
+
|
|
3
|
+
const imgReg = /^( *!\[)(.*?)\]\( *?((.*?)(?: +?\"(.*?)\")?) *?\)( *?\{.*?\})? *$/
|
|
4
|
+
|
|
5
|
+
const imgAttrToPCaption = (state, startLine, opt) => {
|
|
6
|
+
let pos = state.bMarks[startLine] + state.tShift[startLine]
|
|
7
|
+
let max = state.eMarks[startLine]
|
|
8
|
+
//console.log('init inline: ' + state.src.slice(pos, max))
|
|
9
|
+
let inline = state.src.slice(pos, max)
|
|
10
|
+
const img = inline.match(imgReg)
|
|
11
|
+
if (!img) return
|
|
12
|
+
|
|
13
|
+
let alt = img[2] === undefined ? '' : img[2]
|
|
14
|
+
let title = img[5] === undefined ? '' : img[5]
|
|
15
|
+
//console.log('alt: ' + alt + ', title: ' + title)
|
|
16
|
+
|
|
17
|
+
let caption = ''
|
|
18
|
+
if (opt.imgAltCaption) caption = alt
|
|
19
|
+
if (opt.imgTitleCaption) caption = title
|
|
20
|
+
|
|
21
|
+
const hasMarkLabel = caption.match(markReg['img'])
|
|
22
|
+
|
|
23
|
+
let modCaption = ''
|
|
24
|
+
if (hasMarkLabel) {
|
|
25
|
+
modCaption = caption
|
|
26
|
+
} else {
|
|
27
|
+
if (typeof opt.imgAltCaption === 'string' || typeof opt.imgTitleCaption === 'string') {
|
|
28
|
+
if (/[a-zA-Z]/.test(opt.imgAltCaption)) {
|
|
29
|
+
if (caption === '') {
|
|
30
|
+
modCaption = (opt.imgAltCaption ? opt.imgAltCaption : opt.imgTitleCaption) + '.'
|
|
31
|
+
} else {
|
|
32
|
+
modCaption = (opt.imgAltCaption ? opt.imgAltCaption : opt.imgTitleCaption) + '. ' + caption
|
|
33
|
+
}
|
|
34
|
+
} else {
|
|
35
|
+
if (caption === '') {
|
|
36
|
+
modCaption = (opt.imgAltCaption ? opt.imgAltCaption : opt.imgTitleCaption) + ' '
|
|
37
|
+
} else {
|
|
38
|
+
modCaption = (opt.imgAltCaption ? opt.imgAltCaption : opt.imgTitleCaption) + ' ' + caption
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
} else {
|
|
42
|
+
modCaption = 'Figure.'
|
|
43
|
+
if (caption !== '') modCaption += ' ' + caption
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
//console.log('modCaption: ' + modCaption)
|
|
47
|
+
let token = state.push('paragraph_open', 'p', 1)
|
|
48
|
+
token.map = [startLine, startLine + 1]
|
|
49
|
+
token = state.push('inline', '', 0)
|
|
50
|
+
token.content = modCaption
|
|
51
|
+
token.children = [new state.Token('text', modCaption, 0)]
|
|
52
|
+
if (!opt.setFigureNumber) {
|
|
53
|
+
if(caption === '') token.attrs = [['class', 'nocaption']]
|
|
54
|
+
}
|
|
55
|
+
token = state.push('paragraph_close', 'p', -1)
|
|
56
|
+
return true
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const setAltToLabel = (state, n) => {
|
|
60
|
+
if (n < 2) return false
|
|
61
|
+
if (state.tokens[n+1].children[0].type !== 'image' || !state.tokens[n-2].children) return false
|
|
62
|
+
if (state.tokens[n-2].children) {
|
|
63
|
+
state.tokens[n+1].content = state.tokens[n+1].content.replace(/^!\[.*?\]/, '![' + state.tokens[n-2].children[0].content + ']')
|
|
64
|
+
if (!state.tokens[n+1].children[0].children[0]) {
|
|
65
|
+
const textToken = new state.Token('text', '', 0)
|
|
66
|
+
state.tokens[n+1].children[0].children.push(textToken)
|
|
67
|
+
}
|
|
68
|
+
// Set figure label:
|
|
69
|
+
//state.tokens[n+1].children[0].children[0].content = state.tokens[n-2].children[2].content
|
|
70
|
+
// Set img alt to empty value:
|
|
71
|
+
state.tokens[n+1].children[0].children[0].content = ''
|
|
72
|
+
}
|
|
73
|
+
// Set figure label:
|
|
74
|
+
//state.tokens[n+1].children[0].content = state.tokens[n-2].children[2].content
|
|
75
|
+
// Set img alt to empty value:
|
|
76
|
+
state.tokens[n+1].children[0].content = ''
|
|
77
|
+
//console.log(state.tokens[n+1].children[0])
|
|
78
|
+
return true
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const setTitleToLabel = (state, n) => {
|
|
82
|
+
if (n < 2) return false
|
|
83
|
+
if (state.tokens[n+1].children[0].type !== 'image') return false
|
|
84
|
+
if (!state.tokens[n-2].children[0]) return false
|
|
85
|
+
state.tokens[n+1].children[0].attrSet('alt', state.tokens[n+1].children[0].content)
|
|
86
|
+
if (!state.tokens[n+1].children[0].children[0]) {
|
|
87
|
+
const textToken = new state.Token('text', '', 0)
|
|
88
|
+
state.tokens[n+1].children[0].children.push(textToken)
|
|
89
|
+
}
|
|
90
|
+
let i = 0
|
|
91
|
+
while (0 < state.tokens[n+1].children[0].attrs.length) {
|
|
92
|
+
if (state.tokens[n+1].children[0].attrs[i][0] === 'title') {
|
|
93
|
+
state.tokens[n+1].children[0].attrs.splice(i, i + 1)
|
|
94
|
+
break
|
|
95
|
+
} else {
|
|
96
|
+
state.tokens[n+1].children[0].attrJoin('title', '')
|
|
97
|
+
}
|
|
98
|
+
i++
|
|
99
|
+
}
|
|
100
|
+
//console.log(state.tokens[n+1].children[0])
|
|
101
|
+
return true
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export { imgAttrToPCaption, setAltToLabel, setTitleToLabel }
|
package/index.js
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import {setCaptionParagraph} from 'p7d-markdown-it-p-captions'
|
|
1
|
+
import { setCaptionParagraph } from 'p7d-markdown-it-p-captions'
|
|
2
|
+
import { imgAttrToPCaption, setAltToLabel, setTitleToLabel } from './imgAttrToPCaption.js'
|
|
2
3
|
|
|
3
|
-
const checkPrevCaption = (state, n, caption, sp, opt) => {
|
|
4
|
+
const checkPrevCaption = (state, n, caption, fNum, sp, opt) => {
|
|
4
5
|
if(n < 3) return caption
|
|
5
6
|
const captionStartToken = state.tokens[n-3]
|
|
6
7
|
const captionEndToken = state.tokens[n-1]
|
|
7
|
-
if (captionStartToken === undefined || captionEndToken === undefined) return
|
|
8
|
+
if (captionStartToken === undefined || captionEndToken === undefined) return
|
|
8
9
|
|
|
9
|
-
if (captionStartToken.type !== 'paragraph_open' && captionEndToken.type !== 'paragraph_close') return
|
|
10
|
+
if (captionStartToken.type !== 'paragraph_open' && captionEndToken.type !== 'paragraph_close') return
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
setCaptionParagraph(n-3, state, caption, fNum, sp, opt)
|
|
12
13
|
|
|
13
14
|
let captionName = ''
|
|
14
15
|
if (captionStartToken.attrs) {
|
|
@@ -17,30 +18,34 @@ const checkPrevCaption = (state, n, caption, sp, opt) => {
|
|
|
17
18
|
if (attr[0] === 'class' && hasCaptionName) captionName = hasCaptionName[1]
|
|
18
19
|
})
|
|
19
20
|
}
|
|
20
|
-
if(!captionName) return
|
|
21
|
+
if(!captionName) return
|
|
21
22
|
caption.name = captionName
|
|
22
23
|
caption.isPrev = true
|
|
23
|
-
return
|
|
24
|
+
return
|
|
24
25
|
}
|
|
25
26
|
|
|
26
|
-
const changePrevCaptionPosition = (state, n, caption) => {
|
|
27
|
+
const changePrevCaptionPosition = (state, n, caption, opt) => {
|
|
27
28
|
const captionStartToken = state.tokens[n-3]
|
|
28
29
|
const captionInlineToken = state.tokens[n-2]
|
|
29
30
|
const captionEndToken = state.tokens[n-1]
|
|
30
|
-
|
|
31
|
-
if (
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
|
|
32
|
+
if (opt.imgAltCaption || opt.imgTitleCaption) {
|
|
33
|
+
let isNoCaption = false
|
|
34
|
+
if (captionInlineToken.attrs) {
|
|
35
|
+
for (let attr of captionInlineToken.attrs) {
|
|
36
|
+
if (attr[0] === 'class' && attr[1] === 'nocaption') isNoCaption = true
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (isNoCaption) {
|
|
40
|
+
state.tokens.splice(n-3, 3)
|
|
41
|
+
return false
|
|
34
42
|
}
|
|
35
|
-
}
|
|
36
|
-
if (isNoCaption) {
|
|
37
|
-
state.tokens.splice(n-3, 3)
|
|
38
|
-
return
|
|
39
43
|
}
|
|
40
44
|
|
|
45
|
+
const attrReplaceReg = new RegExp(' *?f-' + caption.name)
|
|
41
46
|
captionStartToken.attrs.forEach(attr => {
|
|
42
47
|
if (attr[0] === 'class') {
|
|
43
|
-
attr[1] = attr[1].replace(
|
|
48
|
+
attr[1] = attr[1].replace(attrReplaceReg, '').trim()
|
|
44
49
|
if(attr[1] === '') {
|
|
45
50
|
captionStartToken.attrs.splice(captionStartToken.attrIndex('class'), 1)
|
|
46
51
|
}
|
|
@@ -55,14 +60,14 @@ const changePrevCaptionPosition = (state, n, caption) => {
|
|
|
55
60
|
return true
|
|
56
61
|
}
|
|
57
62
|
|
|
58
|
-
const checkNextCaption = (state, en, caption, sp, opt) => {
|
|
59
|
-
if (en + 2 > state.tokens.length) return
|
|
63
|
+
const checkNextCaption = (state, en, caption, fNum, sp, opt) => {
|
|
64
|
+
if (en + 2 > state.tokens.length) return
|
|
60
65
|
const captionStartToken = state.tokens[en+1]
|
|
61
66
|
const captionEndToken = state.tokens[en+3]
|
|
62
|
-
if (captionStartToken === undefined || captionEndToken === undefined) return
|
|
63
|
-
if (captionStartToken.type !== 'paragraph_open' && captionEndToken.type !== 'paragraph_close') return
|
|
67
|
+
if (captionStartToken === undefined || captionEndToken === undefined) return
|
|
68
|
+
if (captionStartToken.type !== 'paragraph_open' && captionEndToken.type !== 'paragraph_close') return
|
|
64
69
|
|
|
65
|
-
|
|
70
|
+
setCaptionParagraph(en+1, state, caption, fNum, sp, opt)
|
|
66
71
|
|
|
67
72
|
let captionName = ''
|
|
68
73
|
if (captionStartToken.attrs) {
|
|
@@ -71,10 +76,10 @@ const checkNextCaption = (state, en, caption, sp, opt) => {
|
|
|
71
76
|
if (attr[0] === 'class' && hasCaptionName) captionName = hasCaptionName[1]
|
|
72
77
|
})
|
|
73
78
|
}
|
|
74
|
-
if(!captionName) return
|
|
79
|
+
if(!captionName) return
|
|
75
80
|
caption.name = captionName
|
|
76
81
|
caption.isNext = true
|
|
77
|
-
return
|
|
82
|
+
return
|
|
78
83
|
}
|
|
79
84
|
|
|
80
85
|
const changeNextCaptionPosition = (state, en, caption) => {
|
|
@@ -103,23 +108,29 @@ const wrapWithFigure = (state, range, checkTokenTagName, caption, replaceInstead
|
|
|
103
108
|
let en = range.end
|
|
104
109
|
const figureStartToken = new state.Token('figure_open', 'figure', 1)
|
|
105
110
|
figureStartToken.attrSet('class', 'f-' + checkTokenTagName)
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
if (
|
|
112
|
-
|
|
113
|
-
|
|
111
|
+
|
|
112
|
+
if (opt.allIframeTypeFigureClassName === '') {
|
|
113
|
+
if (sp.isVideoIframe) {
|
|
114
|
+
figureStartToken.attrSet('class', 'f-video')
|
|
115
|
+
}
|
|
116
|
+
if (sp.isIframeTypeBlockquote) {
|
|
117
|
+
let figureClassThatWrapsIframeTypeBlockquote = 'i-frame'
|
|
118
|
+
if (caption.isPrev || caption.isNext) {
|
|
119
|
+
if (caption.name === 'blockquote' || caption.name === 'img') {
|
|
120
|
+
figureClassThatWrapsIframeTypeBlockquote = 'f-img'
|
|
121
|
+
}
|
|
122
|
+
figureStartToken.attrSet('class', figureClassThatWrapsIframeTypeBlockquote)
|
|
123
|
+
} else {
|
|
124
|
+
figureClassThatWrapsIframeTypeBlockquote = opt.figureClassThatWrapsIframeTypeBlockquote
|
|
125
|
+
figureStartToken.attrSet('class', figureClassThatWrapsIframeTypeBlockquote)
|
|
114
126
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
figureStartToken.attrSet('class',
|
|
127
|
+
}
|
|
128
|
+
} else {
|
|
129
|
+
if (checkTokenTagName === 'iframe' || sp.isIframeTypeBlockquote) {
|
|
130
|
+
figureStartToken.attrSet('class', opt.allIframeTypeFigureClassName)
|
|
119
131
|
}
|
|
120
132
|
}
|
|
121
133
|
|
|
122
|
-
|
|
123
134
|
if(/pre-(?:code|samp)/.test(checkTokenTagName) && opt.roleDocExample) {
|
|
124
135
|
figureStartToken.attrSet('role', 'doc-example')
|
|
125
136
|
}
|
|
@@ -151,18 +162,22 @@ const wrapWithFigure = (state, range, checkTokenTagName, caption, replaceInstead
|
|
|
151
162
|
}
|
|
152
163
|
range.start = n
|
|
153
164
|
range.end = en
|
|
154
|
-
return
|
|
165
|
+
return
|
|
155
166
|
}
|
|
156
167
|
|
|
157
|
-
const checkCaption = (state, n, en, caption, sp, opt) => {
|
|
158
|
-
|
|
159
|
-
if (caption.isPrev) return
|
|
160
|
-
|
|
161
|
-
return
|
|
168
|
+
const checkCaption = (state, n, en, caption, fNum, sp, opt) => {
|
|
169
|
+
checkPrevCaption(state, n, caption, fNum, sp, opt)
|
|
170
|
+
if (caption.isPrev) return
|
|
171
|
+
checkNextCaption(state, en, caption, fNum, sp, opt)
|
|
172
|
+
return
|
|
162
173
|
}
|
|
163
174
|
|
|
164
175
|
const figureWithCaption = (state, opt) => {
|
|
165
176
|
let n = 0
|
|
177
|
+
let fNum = {
|
|
178
|
+
img: 0,
|
|
179
|
+
table: 0,
|
|
180
|
+
}
|
|
166
181
|
while (n < state.tokens.length) {
|
|
167
182
|
const token = state.tokens[n]
|
|
168
183
|
const nextToken = state.tokens[n+1]
|
|
@@ -172,7 +187,6 @@ const figureWithCaption = (state, opt) => {
|
|
|
172
187
|
end: en,
|
|
173
188
|
}
|
|
174
189
|
let checkToken = false
|
|
175
|
-
let hasCloseTag = false
|
|
176
190
|
let checkTokenTagName = ''
|
|
177
191
|
let caption = {
|
|
178
192
|
mark: '',
|
|
@@ -207,15 +221,14 @@ const figureWithCaption = (state, opt) => {
|
|
|
207
221
|
}
|
|
208
222
|
while (en < state.tokens.length) {
|
|
209
223
|
if(state.tokens[en].type === checkTokenTagName + '_close') {
|
|
210
|
-
hasCloseTag = true
|
|
211
224
|
break
|
|
212
225
|
}
|
|
213
226
|
en++
|
|
214
227
|
}
|
|
215
228
|
range.end = en
|
|
216
|
-
|
|
229
|
+
checkCaption(state, n, en, caption, fNum, sp, opt)
|
|
217
230
|
if (caption.isPrev || caption.isNext) {
|
|
218
|
-
|
|
231
|
+
wrapWithFigure(state, range, checkTokenTagName, caption, false, sp, opt)
|
|
219
232
|
}
|
|
220
233
|
break
|
|
221
234
|
}
|
|
@@ -235,9 +248,9 @@ const figureWithCaption = (state, opt) => {
|
|
|
235
248
|
checkTokenTagName = 'pre-code'
|
|
236
249
|
caption.name = 'pre-code'
|
|
237
250
|
}
|
|
238
|
-
|
|
251
|
+
checkCaption(state, n, en, caption, fNum, sp, opt)
|
|
239
252
|
if (caption.isPrev || caption.isNext) {
|
|
240
|
-
|
|
253
|
+
wrapWithFigure(state, range, checkTokenTagName, caption, false, sp, opt)
|
|
241
254
|
break
|
|
242
255
|
}
|
|
243
256
|
}
|
|
@@ -247,23 +260,66 @@ const figureWithCaption = (state, opt) => {
|
|
|
247
260
|
}
|
|
248
261
|
|
|
249
262
|
if (token.type === 'html_block') {
|
|
250
|
-
const tags = ['video', 'audio', 'iframe', 'blockquote']
|
|
263
|
+
const tags = ['video', 'audio', 'iframe', 'blockquote', 'div']
|
|
251
264
|
let ctj = 0
|
|
265
|
+
let hasTag
|
|
252
266
|
while (ctj < tags.length) {
|
|
253
|
-
|
|
254
|
-
|
|
267
|
+
if (tags[ctj] === 'div') {
|
|
268
|
+
// for vimeo
|
|
269
|
+
hasTag = token.content.match(new RegExp('^<'+ tags[ctj] + ' ?[^>]*?><iframe[^>]*?>[\\s\\S]*?<\\/iframe><\\/' + tags[ctj] + '>(\\n| *?)(<script [^>]*?>(?:<\\/script>)?)? *(\\n|$)'))
|
|
270
|
+
tags[ctj] = 'iframe'
|
|
271
|
+
sp.isVideoIframe = true
|
|
272
|
+
} else {
|
|
273
|
+
hasTag = token.content.match(new RegExp('^<'+ tags[ctj] + ' ?[^>]*?>[\\s\\S]*?<\\/' + tags[ctj] + '>(\\n| *?)(<script [^>]*?>(?:<\\/script>)?)? *(\\n|$)'))
|
|
274
|
+
}
|
|
275
|
+
const blueskyContMatch = token.content.match(new RegExp('^<blockquote class="bluesky-embed"[^]*?>[\\s\\S]*$'))
|
|
276
|
+
if (!(hasTag || (blueskyContMatch && tags[ctj] === 'blockquote'))) {
|
|
255
277
|
ctj++
|
|
256
278
|
continue
|
|
257
279
|
}
|
|
258
|
-
if (
|
|
259
|
-
|
|
280
|
+
if (hasTag) {
|
|
281
|
+
if ((hasTag[2] && hasTag[3] !== '\n') || (hasTag[1] !== '\n' && hasTag[2] === undefined)) {
|
|
282
|
+
token.content += '\n'
|
|
283
|
+
}
|
|
284
|
+
} else if (blueskyContMatch) {
|
|
285
|
+
let addedCont = '';
|
|
286
|
+
let j = n + 1
|
|
287
|
+
let hasEndBlockquote = true
|
|
288
|
+
while (j < state.tokens.length) {
|
|
289
|
+
const nextToken = state.tokens[j]
|
|
290
|
+
if (nextToken.type === 'inline' && /<\/blockquote> *<script[^>]*?><\/script>$/.test(nextToken.content)) {
|
|
291
|
+
addedCont += nextToken.content + '\n'
|
|
292
|
+
if (state.tokens[j + 1] && state.tokens[j + 1].type === 'paragraph_close') {
|
|
293
|
+
state.tokens.splice(j + 1, 1)
|
|
294
|
+
}
|
|
295
|
+
state.tokens[j].content = ''
|
|
296
|
+
state.tokens[j].children.forEach((child, i) => {
|
|
297
|
+
child.content = ''
|
|
298
|
+
})
|
|
299
|
+
break
|
|
300
|
+
}
|
|
301
|
+
if (nextToken.type === 'paragraph_open') {
|
|
302
|
+
addedCont += '\n'
|
|
303
|
+
state.tokens.splice(j, 1)
|
|
304
|
+
continue
|
|
305
|
+
}
|
|
306
|
+
j++;
|
|
307
|
+
}
|
|
308
|
+
token.content += addedCont;
|
|
309
|
+
if (!hasEndBlockquote) {
|
|
310
|
+
ctj++
|
|
311
|
+
continue
|
|
312
|
+
}
|
|
260
313
|
}
|
|
314
|
+
|
|
261
315
|
checkTokenTagName = tags[ctj]
|
|
262
316
|
caption.name = tags[ctj]
|
|
263
317
|
checkToken = true
|
|
264
318
|
if (checkTokenTagName === 'blockquote') {
|
|
265
|
-
|
|
266
|
-
|
|
319
|
+
const classNameReg = /^<[^>]*? class="(twitter-tweet|instagram-media|text-post-media|bluesky-embed|mastodon-embed)"/
|
|
320
|
+
const isIframeTypeBlockquote = token.content.match(classNameReg)
|
|
321
|
+
//console.log(isIframeTypeBlockquote)
|
|
322
|
+
if(isIframeTypeBlockquote) {
|
|
267
323
|
sp.isIframeTypeBlockquote = true
|
|
268
324
|
} else {
|
|
269
325
|
ctj++
|
|
@@ -279,14 +335,14 @@ const figureWithCaption = (state, opt) => {
|
|
|
279
335
|
}
|
|
280
336
|
}
|
|
281
337
|
|
|
282
|
-
|
|
338
|
+
checkCaption(state, n, en, caption, fNum, sp, opt)
|
|
283
339
|
if (caption.isPrev || caption.isNext) {
|
|
284
|
-
|
|
340
|
+
wrapWithFigure(state, range, checkTokenTagName, caption, false, sp, opt)
|
|
285
341
|
n = en + 2
|
|
286
342
|
} else if ((opt.iframeWithoutCaption && (checkTokenTagName === 'iframe')) ||
|
|
287
343
|
(opt.videoWithoutCaption && (checkTokenTagName === 'video')) ||
|
|
288
344
|
(opt.iframeTypeBlockquoteWithoutCaption && (checkTokenTagName === 'blockquote'))) {
|
|
289
|
-
|
|
345
|
+
wrapWithFigure(state, range, checkTokenTagName, caption, false, sp, opt)
|
|
290
346
|
n = en + 2
|
|
291
347
|
}
|
|
292
348
|
}
|
|
@@ -369,15 +425,15 @@ const figureWithCaption = (state, opt) => {
|
|
|
369
425
|
nextToken.children[0].type = 'image'
|
|
370
426
|
|
|
371
427
|
if (opt.imgAltCaption) setAltToLabel(state, n)
|
|
372
|
-
if (opt.imgTitleCaption) setTitleToLabel(state, n
|
|
373
|
-
|
|
428
|
+
if (opt.imgTitleCaption) setTitleToLabel(state, n)
|
|
429
|
+
checkCaption(state, n, en, caption, fNum, sp, opt)
|
|
374
430
|
|
|
375
431
|
if (opt.oneImageWithoutCaption && state.tokens[n-1]) {
|
|
376
432
|
if (state.tokens[n-1].type === 'list_item_open') checkToken = false
|
|
377
433
|
}
|
|
378
434
|
if (checkToken && (opt.oneImageWithoutCaption || caption.isPrev || caption.isNext)) {
|
|
379
435
|
if (caption.nameSuffix) checkTokenTagName += caption.nameSuffix
|
|
380
|
-
|
|
436
|
+
wrapWithFigure(state, range, checkTokenTagName, caption, true, sp, opt)
|
|
381
437
|
}
|
|
382
438
|
}
|
|
383
439
|
|
|
@@ -386,7 +442,7 @@ const figureWithCaption = (state, opt) => {
|
|
|
386
442
|
n = range.start
|
|
387
443
|
en = range.end
|
|
388
444
|
if (caption.isPrev) {
|
|
389
|
-
changePrevCaptionPosition(state, n, caption)
|
|
445
|
+
changePrevCaptionPosition(state, n, caption, opt)
|
|
390
446
|
n = en + 1
|
|
391
447
|
continue
|
|
392
448
|
}
|
|
@@ -400,112 +456,7 @@ const figureWithCaption = (state, opt) => {
|
|
|
400
456
|
return
|
|
401
457
|
}
|
|
402
458
|
|
|
403
|
-
const setAltToLabel = (state, n) => {
|
|
404
|
-
if (n < 2) return false
|
|
405
|
-
if (state.tokens[n+1].children[0].type !== 'image' || !state.tokens[n-2].children) return false
|
|
406
|
-
if (state.tokens[n-2].children) {
|
|
407
|
-
state.tokens[n+1].content = state.tokens[n+1].content.replace(/^!\[.*?\]/, '![' + state.tokens[n-2].children[0].content + ']')
|
|
408
|
-
if (!state.tokens[n+1].children[0].children[0]) {
|
|
409
|
-
const textToken = new state.Token('text', '', 0)
|
|
410
|
-
state.tokens[n+1].children[0].children.push(textToken)
|
|
411
|
-
}
|
|
412
|
-
// Set figure label:
|
|
413
|
-
//state.tokens[n+1].children[0].children[0].content = state.tokens[n-2].children[2].content
|
|
414
|
-
// Set img alt to empty value:
|
|
415
|
-
state.tokens[n+1].children[0].children[0].content = ''
|
|
416
|
-
}
|
|
417
|
-
// Set figure label:
|
|
418
|
-
//state.tokens[n+1].children[0].content = state.tokens[n-2].children[2].content
|
|
419
|
-
// Set img alt to empty value:
|
|
420
|
-
state.tokens[n+1].children[0].content = ''
|
|
421
|
-
//console.log(state.tokens[n+1].children[0])
|
|
422
|
-
return true
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
const setTitleToLabel = (state, n, en, checkTokenTagName, caption, opt) => {
|
|
426
|
-
if (n < 2) return false
|
|
427
|
-
if (state.tokens[n+1].children[0].type !== 'image') return false
|
|
428
|
-
if (!state.tokens[n-2].children[0]) return false
|
|
429
|
-
state.tokens[n+1].children[0].attrSet('alt', state.tokens[n+1].children[0].content)
|
|
430
|
-
if (!state.tokens[n+1].children[0].children[0]) {
|
|
431
|
-
const textToken = new state.Token('text', '', 0)
|
|
432
|
-
state.tokens[n+1].children[0].children.push(textToken)
|
|
433
|
-
}
|
|
434
|
-
let i = 0
|
|
435
|
-
while (0 < state.tokens[n+1].children[0].attrs.length) {
|
|
436
|
-
if (state.tokens[n+1].children[0].attrs[i][0] === 'title') {
|
|
437
|
-
state.tokens[n+1].children[0].attrs.splice(i, i + 1)
|
|
438
|
-
break
|
|
439
|
-
} else {
|
|
440
|
-
state.tokens[n+1].children[0].attrJoin('title', '')
|
|
441
|
-
}
|
|
442
|
-
i++
|
|
443
|
-
}
|
|
444
|
-
//console.log(state.tokens[n+1].children[0])
|
|
445
|
-
return true
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
const imgAttrToPCaption = (state, startLine, opt) => {
|
|
449
|
-
let pos = state.bMarks[startLine] + state.tShift[startLine]
|
|
450
|
-
let max = state.eMarks[startLine]
|
|
451
|
-
let inline = state.src.slice(pos, max)
|
|
452
|
-
let label = ''
|
|
453
|
-
if (opt.imgAltCaption && typeof opt.imgAltCaption === 'string') label = opt.imgAltCaption
|
|
454
|
-
if (opt.imgTitleCaption && typeof opt.imgTitleCaption === 'string') label = opt.imgTitleCaption
|
|
455
|
-
let caption = ''
|
|
456
|
-
let imgAttrUsedCaption = ''
|
|
457
|
-
|
|
458
|
-
const img = inline.match(/^( *!\[)(.*?)\]\( *?((.*?)(?: +?\"(.*?)\")?) *?\)( *?\{.*?\})? *$/)
|
|
459
|
-
if (!img) return
|
|
460
|
-
|
|
461
|
-
let hasLabel
|
|
462
|
-
if (opt.imgAltCaption) {
|
|
463
|
-
caption = img[2]
|
|
464
|
-
hasLabel = img[2].match(new RegExp('^' + opt.imgAltCaption))
|
|
465
|
-
imgAttrUsedCaption = 'alt'
|
|
466
|
-
}
|
|
467
|
-
if (opt.imgTitleCaption) {
|
|
468
|
-
if (!img[5]) img[5] = ''
|
|
469
|
-
caption = img[5]
|
|
470
|
-
hasLabel = img[5].match(new RegExp('^' + opt.imgTitleCaption))
|
|
471
|
-
imgAttrUsedCaption = 'title'
|
|
472
|
-
}
|
|
473
|
-
let token
|
|
474
|
-
token = state.push('paragraph_open', 'p', 1)
|
|
475
|
-
token.map = [startLine, startLine + 1]
|
|
476
|
-
token = state.push('inline', '', 0)
|
|
477
|
-
if (hasLabel) {
|
|
478
|
-
token.content = caption
|
|
479
|
-
} else {
|
|
480
|
-
if (!label) {
|
|
481
|
-
if (imgAttrUsedCaption === 'alt') {
|
|
482
|
-
label = opt.imgAltCaption
|
|
483
|
-
} else if (imgAttrUsedCaption === 'title') {
|
|
484
|
-
label = opt.imgTitleCaption
|
|
485
|
-
} else if (imgAttrUsedCaption) {
|
|
486
|
-
label = 'Figure'
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
token.content = label
|
|
490
|
-
if (/[a-zA-Z]/.test(label)) {
|
|
491
|
-
token.content += '.'
|
|
492
|
-
if (caption) token.content += ' '
|
|
493
|
-
} else {
|
|
494
|
-
token.content += ' '
|
|
495
|
-
}
|
|
496
|
-
token.content += caption
|
|
497
|
-
}
|
|
498
|
-
token.map = [startLine, startLine + 1]
|
|
499
|
-
token.children = []
|
|
500
|
-
if (caption.length === 0) {
|
|
501
|
-
token.attrs = [['class', 'nocaption']]
|
|
502
|
-
}
|
|
503
|
-
token = state.push('paragraph_close', 'p', -1)
|
|
504
|
-
return
|
|
505
|
-
}
|
|
506
|
-
|
|
507
459
|
const mditFigureWithPCaption = (md, option) => {
|
|
508
|
-
|
|
509
460
|
let opt = {
|
|
510
461
|
classPrefix: 'f',
|
|
511
462
|
figureClassThatWrapsIframeTypeBlockquote: 'f-img',
|
|
@@ -523,19 +474,25 @@ const mditFigureWithPCaption = (md, option) => {
|
|
|
523
474
|
iframeTypeBlockquoteWithoutCaption: false,
|
|
524
475
|
removeUnnumberedLabel: false,
|
|
525
476
|
removeUnnumberedLabelExceptMarks: [],
|
|
477
|
+
removeMarkNameInCaptionClass: false,
|
|
526
478
|
multipleImages: true,
|
|
527
479
|
imgAltCaption: false,
|
|
480
|
+
setFigureNumber: false,
|
|
528
481
|
imgTitleCaption: false,
|
|
529
482
|
roleDocExample: false,
|
|
483
|
+
allIframeTypeFigureClassName: '',
|
|
530
484
|
}
|
|
531
|
-
if (option
|
|
532
|
-
for (let o in option) {
|
|
533
|
-
opt[o] = option[o]
|
|
534
|
-
}
|
|
535
|
-
}
|
|
485
|
+
if (option) Object.assign(opt, option)
|
|
536
486
|
|
|
537
487
|
if (opt.imgAltCaption || opt.imgTitleCaption) {
|
|
538
|
-
opt.oneImageWithoutCaption =
|
|
488
|
+
opt.oneImageWithoutCaption = true
|
|
489
|
+
opt.multipleImages = false
|
|
490
|
+
if (opt.setFigureNumber) {
|
|
491
|
+
for (let mark of opt.removeUnnumberedLabelExceptMarks) {
|
|
492
|
+
if (mark === 'img') opt.removeUnnumberedLabelExceptMarks.splice(opt.removeUnnumberedLabelExceptMarks.indexOf(mark), 1)
|
|
493
|
+
if (mark === 'table') opt.removeUnnumberedLabelExceptMarks.splice(opt.removeUnnumberedLabelExceptMarks.indexOf(mark), 1)
|
|
494
|
+
}
|
|
495
|
+
}
|
|
539
496
|
md.block.ruler.before('paragraph', 'img_attr_caption', (state) => {
|
|
540
497
|
imgAttrToPCaption(state, state.line, opt)
|
|
541
498
|
})
|
package/package.json
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@peaceroad/markdown-it-figure-with-p-caption",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "A markdown-it plugin. For a paragraph with only one image, a table or code block or blockquote, and by writing a caption paragraph immediately before or after, they are converted into the figure element with the figcaption element.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"test": "node test/test.js"
|
|
9
9
|
},
|
|
10
|
-
"repository":
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "git+https://github.com/peaceroad/p7d-markdown-it-figure-with-p-caption.git"
|
|
13
|
+
},
|
|
11
14
|
"author": "peaceroad <peaceroad@gmail.com>",
|
|
12
15
|
"license": "MIT",
|
|
13
16
|
"bugs": {
|
|
@@ -20,6 +23,6 @@
|
|
|
20
23
|
"markdown-it-attrs": "^4.2.0"
|
|
21
24
|
},
|
|
22
25
|
"dependencies": {
|
|
23
|
-
"p7d-markdown-it-p-captions": "^0.
|
|
26
|
+
"p7d-markdown-it-p-captions": "^0.16.0"
|
|
24
27
|
}
|
|
25
28
|
}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
[Markdown]
|
|
2
|
+
A paragraph.
|
|
3
|
+
|
|
4
|
+
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/XXXXXXXXXXX" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
|
5
|
+
|
|
6
|
+
A paragraph.
|
|
7
|
+
[HTML]
|
|
8
|
+
<p>A paragraph.</p>
|
|
9
|
+
<figure class="f-embed">
|
|
10
|
+
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/XXXXXXXXXXX" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
|
11
|
+
</figure>
|
|
12
|
+
<p>A paragraph.</p>
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
[Markdown]
|
|
16
|
+
A paragraph.
|
|
17
|
+
|
|
18
|
+
Video. A youtube.
|
|
19
|
+
|
|
20
|
+
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/XXXXXXXXXXX" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
|
21
|
+
|
|
22
|
+
A paragraph.
|
|
23
|
+
[HTML]
|
|
24
|
+
<p>A paragraph.</p>
|
|
25
|
+
<figure class="f-embed">
|
|
26
|
+
<figcaption><span class="f-video-label">Video<span class="f-video-label-joint">.</span></span> A youtube.</figcaption>
|
|
27
|
+
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/XXXXXXXXXXX" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
|
28
|
+
</figure>
|
|
29
|
+
<p>A paragraph.</p>
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
[Markdown]
|
|
33
|
+
A paragraph.
|
|
34
|
+
|
|
35
|
+
Source. Twitter Post.
|
|
36
|
+
|
|
37
|
+
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">XXXXX <a href="https://t.co/XXXXX">https://t.co/XXXXX</a></p>— User (@twitter) <a href="https://twitter.com/UserID/status/XXXXX">August 4, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
|
|
38
|
+
|
|
39
|
+
A paragraph.
|
|
40
|
+
[HTML]
|
|
41
|
+
<p>A paragraph.</p>
|
|
42
|
+
<figure class="f-embed">
|
|
43
|
+
<figcaption><span class="f-blockquote-label">Source<span class="f-blockquote-label-joint">.</span></span> Twitter Post.</figcaption>
|
|
44
|
+
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">XXXXX <a href="https://t.co/XXXXX">https://t.co/XXXXX</a></p>— User (@twitter) <a href="https://twitter.com/UserID/status/XXXXX">August 4, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
|
|
45
|
+
</figure>
|
|
46
|
+
<p>A paragraph.</p>
|
|
47
|
+
|
|
48
|
+
[Markdown]
|
|
49
|
+
A paragraph.
|
|
50
|
+
|
|
51
|
+
Figure. Twitter Post.
|
|
52
|
+
|
|
53
|
+
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">XXXXX <a href="https://t.co/XXXXX">https://t.co/XXXXX</a></p>— User (@twitter) <a href="https://twitter.com/UserID/status/XXXXX">August 4, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
|
|
54
|
+
|
|
55
|
+
A paragraph.
|
|
56
|
+
[HTML]
|
|
57
|
+
<p>A paragraph.</p>
|
|
58
|
+
<figure class="f-embed">
|
|
59
|
+
<figcaption><span class="f-img-label">Figure<span class="f-img-label-joint">.</span></span> Twitter Post.</figcaption>
|
|
60
|
+
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">XXXXX <a href="https://t.co/XXXXX">https://t.co/XXXXX</a></p>— User (@twitter) <a href="https://twitter.com/UserID/status/XXXXX">August 4, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
|
|
61
|
+
</figure>
|
|
62
|
+
<p>A paragraph.</p>
|
|
63
|
+
|
|
64
|
+
[Markdown]
|
|
65
|
+
A paragraph.
|
|
66
|
+
|
|
67
|
+
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">XXXXX <a href="https://t.co/XXXXX">https://t.co/XXXXX</a></p>— User (@twitter) <a href="https://twitter.com/UserID/status/XXXXX">August 4, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
|
|
68
|
+
|
|
69
|
+
Figure. Twitter Post.
|
|
70
|
+
|
|
71
|
+
A paragraph.
|
|
72
|
+
[HTML]
|
|
73
|
+
<p>A paragraph.</p>
|
|
74
|
+
<figure class="f-embed">
|
|
75
|
+
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">XXXXX <a href="https://t.co/XXXXX">https://t.co/XXXXX</a></p>— User (@twitter) <a href="https://twitter.com/UserID/status/XXXXX">August 4, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
|
|
76
|
+
<figcaption><span class="f-img-label">Figure<span class="f-img-label-joint">.</span></span> Twitter Post.</figcaption>
|
|
77
|
+
</figure>
|
|
78
|
+
<p>A paragraph.</p>
|
|
79
|
+
|
|
80
|
+
[Markdown]
|
|
81
|
+
A paragraph.
|
|
82
|
+
|
|
83
|
+
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">XXXXX <a href="https://t.co/XXXXX">https://t.co/XXXXX</a></p>— User (@twitter) <a href="https://twitter.com/UserID/status/XXXXX">August 4, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
|
|
84
|
+
|
|
85
|
+
Quote. Twitter Post.
|
|
86
|
+
|
|
87
|
+
A paragraph.
|
|
88
|
+
[HTML]
|
|
89
|
+
<p>A paragraph.</p>
|
|
90
|
+
<figure class="f-embed">
|
|
91
|
+
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">XXXXX <a href="https://t.co/XXXXX">https://t.co/XXXXX</a></p>— User (@twitter) <a href="https://twitter.com/UserID/status/XXXXX">August 4, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
|
|
92
|
+
<figcaption><span class="f-blockquote-label">Quote<span class="f-blockquote-label-joint">.</span></span> Twitter Post.</figcaption>
|
|
93
|
+
</figure>
|
|
94
|
+
<p>A paragraph.</p>
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
[Markdown]
|
|
98
|
+
A paragraph. 28.
|
|
99
|
+
|
|
100
|
+
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">XXXXX <a href="https://t.co/XXXXX">https://t.co/XXXXX</a></p>— User (@twitter) <a href="https://twitter.com/UserID/status/XXXXX">August 4, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
|
|
101
|
+
|
|
102
|
+
A paragraph.
|
|
103
|
+
[HTML]
|
|
104
|
+
<p>A paragraph. 28.</p>
|
|
105
|
+
<figure class="f-embed">
|
|
106
|
+
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">XXXXX <a href="https://t.co/XXXXX">https://t.co/XXXXX</a></p>— User (@twitter) <a href="https://twitter.com/UserID/status/XXXXX">August 4, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
|
|
107
|
+
</figure>
|
|
108
|
+
<p>A paragraph.</p>
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
[Markdown]
|
|
112
|
+
<video controls width="400" height="300">
|
|
113
|
+
<source src="example.mp4" type="video/mp4">
|
|
114
|
+
</video>
|
|
115
|
+
[HTML]
|
|
116
|
+
<figure class="f-video">
|
|
117
|
+
<video controls width="400" height="300">
|
|
118
|
+
<source src="example.mp4" type="video/mp4">
|
|
119
|
+
</video>
|
|
120
|
+
</figure>
|
|
121
|
+
|
|
122
|
+
[Markdown]
|
|
123
|
+
Video. A caption.
|
|
124
|
+
|
|
125
|
+
<video controls width="400" height="300">
|
|
126
|
+
<source src="example.mp4" type="video/mp4">
|
|
127
|
+
</video>
|
|
128
|
+
[HTML]
|
|
129
|
+
<figure class="f-video">
|
|
130
|
+
<figcaption><span class="f-video-label">Video<span class="f-video-label-joint">.</span></span> A caption.</figcaption>
|
|
131
|
+
<video controls width="400" height="300">
|
|
132
|
+
<source src="example.mp4" type="video/mp4">
|
|
133
|
+
</video>
|
|
134
|
+
</figure>
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
[Markdown]
|
|
138
|
+
A YouTube paragraph.
|
|
139
|
+
|
|
140
|
+
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/XXXXXXXXXXX" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
|
141
|
+
|
|
142
|
+
A paragraph.
|
|
143
|
+
[HTML]
|
|
144
|
+
<p>A YouTube paragraph.</p>
|
|
145
|
+
<figure class="f-embed">
|
|
146
|
+
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/XXXXXXXXXXX" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
|
147
|
+
</figure>
|
|
148
|
+
<p>A paragraph.</p>
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
[Markdown]
|
|
152
|
+
Video. A YouTube caption.
|
|
153
|
+
|
|
154
|
+
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/XXXXXXXXXXX" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
|
155
|
+
|
|
156
|
+
A paragraph.
|
|
157
|
+
[HTML]
|
|
158
|
+
<figure class="f-embed">
|
|
159
|
+
<figcaption><span class="f-video-label">Video<span class="f-video-label-joint">.</span></span> A YouTube caption.</figcaption>
|
|
160
|
+
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/XXXXXXXXXXX" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
|
161
|
+
</figure>
|
|
162
|
+
<p>A paragraph.</p>
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
[Markdown]
|
|
166
|
+
<blockquote class="bluesky-embed" data-bluesky-uri="at://xxxxxxxxxxxxx" data-bluesky-cid="xxxx"><p lang="en">xxxx
|
|
167
|
+
|
|
168
|
+
xxxx</p>— xxxx (<a href="https://bsky.app/profile/xxx">@xxx</a>) <a href="https://bsky.app/profile/xxx?ref_src=embed">1970年01月01日 00:00</a></blockquote><script async src="https://embed.bsky.app/static/embed.js" charset="utf-8"></script>
|
|
169
|
+
|
|
170
|
+
[HTML]
|
|
171
|
+
<figure class="f-embed">
|
|
172
|
+
<blockquote class="bluesky-embed" data-bluesky-uri="at://xxxxxxxxxxxxx" data-bluesky-cid="xxxx"><p lang="en">xxxx
|
|
173
|
+
|
|
174
|
+
xxxx</p>— xxxx (<a href="https://bsky.app/profile/xxx">@xxx</a>) <a href="https://bsky.app/profile/xxx?ref_src=embed">1970年01月01日 00:00</a></blockquote><script async src="https://embed.bsky.app/static/embed.js" charset="utf-8"></script>
|
|
175
|
+
</figure>
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
[Markdown]
|
|
179
|
+
<blockquote class="mastodon-embed" data-embed-url="https://mastodon.social/@xxxx/xxxx/embed" style="background: #FCF8FF; border-radius: 8px; border: 1px solid #C9C4DA; margin: 0; max-width: 540px; min-width: 270px; overflow: hidden; padding: 0;"> <a href="https://mastodon.social/xxxx" target="_blank" style="align-items: center; color: #1C1A25; display: flex; flex-direction: column; font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Oxygen, Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', Roboto, sans-serif; font-size: 14px; justify-content: center; letter-spacing: 0.25px; line-height: 20px; padding: 24px; text-decoration: none;"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32" viewBox="0 0 79 75"><path d="xxx" fill="currentColor"/></svg> <div style="color: #787588; margin-top: 16px;">Post by @xxx</div> <div style="font-weight: 500;">View on Mastodon</div> </a> </blockquote> <script data-allowed-prefixes="https://mastodon.social/" async src="https://mastodon.social/embed.js"></script>
|
|
180
|
+
|
|
181
|
+
[HTML]
|
|
182
|
+
<figure class="f-embed">
|
|
183
|
+
<blockquote class="mastodon-embed" data-embed-url="https://mastodon.social/@xxxx/xxxx/embed" style="background: #FCF8FF; border-radius: 8px; border: 1px solid #C9C4DA; margin: 0; max-width: 540px; min-width: 270px; overflow: hidden; padding: 0;"> <a href="https://mastodon.social/xxxx" target="_blank" style="align-items: center; color: #1C1A25; display: flex; flex-direction: column; font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Oxygen, Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', Roboto, sans-serif; font-size: 14px; justify-content: center; letter-spacing: 0.25px; line-height: 20px; padding: 24px; text-decoration: none;"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32" viewBox="0 0 79 75"><path d="xxx" fill="currentColor"/></svg> <div style="color: #787588; margin-top: 16px;">Post by @xxx</div> <div style="font-weight: 500;">View on Mastodon</div> </a> </blockquote> <script data-allowed-prefixes="https://mastodon.social/" async src="https://mastodon.social/embed.js"></script>
|
|
184
|
+
</figure>
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
[Markdown]
|
|
188
|
+
<div style="padding:56.25% 0 0 0;position:relative;"><iframe src="https://player.vimeo.com/video/xxxxxxx" frameborder="0" allow="autoplay; fullscreen; picture-in-picture; clipboard-write" style="position:absolute;top:0;left:0;width:100%;height:100%;" title="xxxx"></iframe></div><script src="https://player.vimeo.com/api/player.js"></script>
|
|
189
|
+
[HTML]
|
|
190
|
+
<figure class="f-embed">
|
|
191
|
+
<div style="padding:56.25% 0 0 0;position:relative;"><iframe src="https://player.vimeo.com/video/xxxxxxx" frameborder="0" allow="autoplay; fullscreen; picture-in-picture; clipboard-write" style="position:absolute;top:0;left:0;width:100%;height:100%;" title="xxxx"></iframe></div><script src="https://player.vimeo.com/api/player.js"></script>
|
|
192
|
+
</figure>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
[Markdown]
|
|
2
|
+

|
|
3
|
+
|
|
4
|
+
[HTML]
|
|
5
|
+
<figure class="f-img">
|
|
6
|
+
<figcaption><span class="f-img-label">Figure 1<span class="f-img-label-joint">.</span></span> A caption.</figcaption>
|
|
7
|
+
<img src="cat.jpg" alt="">
|
|
8
|
+
</figure>
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
[Markdown]
|
|
12
|
+

|
|
13
|
+
|
|
14
|
+
[HTML]
|
|
15
|
+
<figure class="f-img">
|
|
16
|
+
<figcaption><span class="f-img-label">Figure 1<span class="f-img-label-joint">.</span></span> A caption.</figcaption>
|
|
17
|
+
<img src="cat.jpg" alt="">
|
|
18
|
+
</figure>
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
[Markdown]
|
|
22
|
+

|
|
23
|
+
|
|
24
|
+
[HTML]
|
|
25
|
+
<figure class="f-img">
|
|
26
|
+
<figcaption><span class="f-img-label">Figure 1<span class="f-img-label-joint">.</span></span></figcaption>
|
|
27
|
+
<img src="cat.jpg" alt="">
|
|
28
|
+
</figure>
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
[Markdown]
|
|
32
|
+
Figure. A caption.
|
|
33
|
+
|
|
34
|
+

|
|
35
|
+
|
|
36
|
+
[HTML]
|
|
37
|
+
<p>Figure. A caption.</p>
|
|
38
|
+
<figure class="f-img">
|
|
39
|
+
<figcaption><span class="f-img-label">Figure 1<span class="f-img-label-joint">.</span></span></figcaption>
|
|
40
|
+
<img src="cat.jpg" alt="">
|
|
41
|
+
</figure>
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
[Markdown]
|
|
45
|
+

|
|
46
|
+
|
|
47
|
+
[HTML]
|
|
48
|
+
<figure class="f-img">
|
|
49
|
+
<figcaption><span class="f-img-label">Figure 12<span class="f-img-label-joint">.</span></span> A caption.</figcaption>
|
|
50
|
+
<img src="cat.jpg" alt="">
|
|
51
|
+
</figure>
|
|
@@ -48,4 +48,13 @@ Figure. A caption.
|
|
|
48
48
|
<img src="cat.jpg" alt="">
|
|
49
49
|
</figure>
|
|
50
50
|
|
|
51
|
+
[Markdown]
|
|
52
|
+

|
|
53
|
+
|
|
54
|
+
[HTML]
|
|
55
|
+
<figure class="f-img">
|
|
56
|
+
<figcaption><span class="f-img-label">Figure.1</span> A caption.</figcaption>
|
|
57
|
+
<img src="cat.jpg" alt="">
|
|
58
|
+
</figure>
|
|
59
|
+
|
|
51
60
|
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
[Markdown]
|
|
2
|
+

|
|
3
|
+
|
|
4
|
+
[HTML]
|
|
5
|
+
<figure class="f-img">
|
|
6
|
+
<figcaption><span class="f-img-label">Figure 1<span class="f-img-label-joint">.</span></span> A caption.</figcaption>
|
|
7
|
+
<img src="cat.jpg" alt="">
|
|
8
|
+
</figure>
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
[Markdown]
|
|
12
|
+

|
|
13
|
+
|
|
14
|
+
[HTML]
|
|
15
|
+
<figure class="f-img">
|
|
16
|
+
<figcaption><span class="f-img-label">Figure 1<span class="f-img-label-joint">.</span></span> A caption.</figcaption>
|
|
17
|
+
<img src="cat.jpg" alt="">
|
|
18
|
+
</figure>
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
[Markdown]
|
|
22
|
+

|
|
23
|
+
|
|
24
|
+
[HTML]
|
|
25
|
+
<figure class="f-img">
|
|
26
|
+
<img src="cat.jpg" alt="A alt text.">
|
|
27
|
+
</figure>
|
|
28
|
+
|
|
29
|
+
[Markdown]
|
|
30
|
+

|
|
31
|
+
|
|
32
|
+
[HTML]
|
|
33
|
+
<figure class="f-img">
|
|
34
|
+
<figcaption><span class="f-img-label">Figure 1<span class="f-img-label-joint">.</span></span></figcaption>
|
|
35
|
+
<img src="cat.jpg" alt="A alt text.">
|
|
36
|
+
</figure>
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
[Markdown]
|
|
40
|
+
Figure. A caption.
|
|
41
|
+
|
|
42
|
+

|
|
43
|
+
|
|
44
|
+
[HTML]
|
|
45
|
+
<p>Figure. A caption.</p>
|
|
46
|
+
<figure class="f-img">
|
|
47
|
+
<img src="cat.jpg" alt="">
|
|
48
|
+
</figure>
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
[Markdown]
|
|
52
|
+

|
|
53
|
+
|
|
54
|
+
[HTML]
|
|
55
|
+
<figure class="f-img">
|
|
56
|
+
<figcaption><span class="f-img-label">Figure 12<span class="f-img-label-joint">.</span></span> A caption.</figcaption>
|
|
57
|
+
<img src="cat.jpg" alt="">
|
|
58
|
+
</figure>
|
|
59
|
+
|
|
60
|
+
|
|
@@ -741,3 +741,30 @@ code
|
|
|
741
741
|
<pre><samp>>
|
|
742
742
|
</samp></pre>
|
|
743
743
|
</figure>
|
|
744
|
+
|
|
745
|
+
[Markdown]
|
|
746
|
+
リスト キャプション
|
|
747
|
+
|
|
748
|
+
```
|
|
749
|
+
>
|
|
750
|
+
```
|
|
751
|
+
[HTML]
|
|
752
|
+
<figure class="f-pre-code">
|
|
753
|
+
<figcaption><span class="f-pre-code-label">リスト</span> キャプション</figcaption>
|
|
754
|
+
<pre><code>>
|
|
755
|
+
</code></pre>
|
|
756
|
+
</figure>
|
|
757
|
+
|
|
758
|
+
|
|
759
|
+
[Markdown]
|
|
760
|
+
図 キャプション
|
|
761
|
+
|
|
762
|
+
```samp
|
|
763
|
+
>
|
|
764
|
+
```
|
|
765
|
+
[HTML]
|
|
766
|
+
<figure class="f-pre-samp">
|
|
767
|
+
<figcaption><span class="f-pre-samp-label">図</span> キャプション</figcaption>
|
|
768
|
+
<pre><samp>>
|
|
769
|
+
</samp></pre>
|
|
770
|
+
</figure>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
[Markdown]
|
|
2
|
+
Figure. A caption.
|
|
3
|
+
|
|
4
|
+

|
|
5
|
+
|
|
6
|
+
Figure. A caption.
|
|
7
|
+
|
|
8
|
+

|
|
9
|
+
|
|
10
|
+
[HTML]
|
|
11
|
+
<figure class="f-img">
|
|
12
|
+
<figcaption><span class="f-img-label">Figure 1<span class="f-img-label-joint">.</span></span> A caption.</figcaption>
|
|
13
|
+
<img src="example.jpg" alt="">
|
|
14
|
+
</figure>
|
|
15
|
+
<figure class="f-img">
|
|
16
|
+
<figcaption><span class="f-img-label">Figure 2<span class="f-img-label-joint">.</span></span> A caption.</figcaption>
|
|
17
|
+
<img src="example.jpg" alt="">
|
|
18
|
+
</figure>
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
package/test/test.js
CHANGED
|
@@ -16,6 +16,7 @@ let opt = {
|
|
|
16
16
|
videoWithoutCaption: false,
|
|
17
17
|
hasNumClass: false,
|
|
18
18
|
iframeTypeBlockquoteWithoutCaption: false,
|
|
19
|
+
setFigureNumber: false,
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
const md = mdit({ html: true }).use(mdFigureWithPCaption, opt).use(mditAttrs).use(mditRndererFence);
|
|
@@ -40,6 +41,7 @@ const mdMultipleImages = mdit({ html: true }).use(mdFigureWithPCaption, opt).use
|
|
|
40
41
|
opt.videoWithoutCaption = true
|
|
41
42
|
const mdVideoWithoutCaption = mdit({ html: true }).use(mdFigureWithPCaption, opt).use(mditAttrs).use(mditRndererFence);
|
|
42
43
|
|
|
44
|
+
|
|
43
45
|
const mdConsole = mdit({
|
|
44
46
|
html: true,
|
|
45
47
|
langPrefix: 'language-',
|
|
@@ -73,6 +75,10 @@ const testData = {
|
|
|
73
75
|
imgAltCaption: __dirname + path.sep + 'examples-img-alt-caption.txt',
|
|
74
76
|
imgTitleCaption: __dirname + path.sep + 'examples-img-title-caption.txt',
|
|
75
77
|
console: __dirname + path.sep + 'examples-console.txt',
|
|
78
|
+
setFigureNumber: __dirname + path.sep + 'examples-set-figure-number.txt',
|
|
79
|
+
imgAltCaptionNumber: __dirname + path.sep + 'examples-img-alt-caption-number.txt',
|
|
80
|
+
imgTitleCaptionNumber: __dirname + path.sep + 'examples-img-title-caption-number.txt',
|
|
81
|
+
allIframeTypeFigureClassName: __dirname + path.sep + 'examples-all-iframe-type-figure-class-name.txt',
|
|
76
82
|
}
|
|
77
83
|
|
|
78
84
|
const getTestData = (pat) => {
|
|
@@ -125,7 +131,7 @@ const runTest = (process, pat, pass, testId) => {
|
|
|
125
131
|
while(n <= end) {
|
|
126
132
|
|
|
127
133
|
if (!ms[n]
|
|
128
|
-
//|| n !=
|
|
134
|
+
//|| n != 11
|
|
129
135
|
) {
|
|
130
136
|
n++
|
|
131
137
|
continue
|
|
@@ -177,4 +183,26 @@ opt.imgTitleCaption = '図'
|
|
|
177
183
|
const mdImgTitleCaptionJa = mdit({html: true}).use(mdFigureWithPCaption, opt).use(mditAttrs).use(mditRndererFence);
|
|
178
184
|
pass = runTest(mdImgTitleCaptionJa, testData.imgTitleCaption.replace(/.txt$/, '.ja.txt'), pass)
|
|
179
185
|
|
|
186
|
+
opt = {}
|
|
187
|
+
opt.setFigureNumber = true
|
|
188
|
+
const mdSetFigureNumber = mdit({html: true}).use(mdFigureWithPCaption, opt).use(mditAttrs).use(mditRndererFence);
|
|
189
|
+
pass = runTest(mdSetFigureNumber, testData.setFigureNumber.replace(/\.txt$/, '.en.txt'), pass)
|
|
190
|
+
|
|
191
|
+
opt.imgAltCaption = true
|
|
192
|
+
const mdImgAltCaptionNumber = mdit({html: true}).use(mdFigureWithPCaption, opt).use(mditAttrs).use(mditRndererFence);
|
|
193
|
+
pass = runTest(mdImgAltCaptionNumber, testData.imgAltCaptionNumber.replace(/\.txt$/, '.en.txt'), pass)
|
|
194
|
+
|
|
195
|
+
opt = {}
|
|
196
|
+
opt.imgTitleCaption = true
|
|
197
|
+
const mdImgTitleCaptionNumber = mdit({html: true}).use(mdFigureWithPCaption, opt).use(mditAttrs).use(mditRndererFence);
|
|
198
|
+
//pass = runTest(mdImgTitleCaptionNumber, testData.imgTitleCaptionNumber.replace(/\.txt$/, '.en.txt'), pass)
|
|
199
|
+
|
|
200
|
+
opt = {}
|
|
201
|
+
opt.videoWithoutCaption = true
|
|
202
|
+
opt.iframeWithoutCaption = true
|
|
203
|
+
opt.iframeTypeBlockquoteWithoutCaption = true
|
|
204
|
+
opt.allIframeTypeFigureClassName = 'f-embed'
|
|
205
|
+
const mdAllIframeTypeFigureClassName = mdit({html: true}).use(mdFigureWithPCaption, opt).use(mditAttrs).use(mditRndererFence);
|
|
206
|
+
pass = runTest(mdAllIframeTypeFigureClassName, testData.allIframeTypeFigureClassName, pass)
|
|
207
|
+
|
|
180
208
|
if (pass) console.log('Passed all test.')
|