@@ -17,7 +17,7 @@ import { Schema } from 'prosemirror-model';
17
17
18
18
import { base64Encode , base64Decode } from './base64' ;
19
19
20
- import { PandocToken , ProsemirrorWriter , mapTokens , PandocTokenType } from './pandoc' ;
20
+ import { PandocToken , ProsemirrorWriter , mapTokensRecursive , PandocTokenType } from './pandoc' ;
21
21
22
22
// constants used for creating/consuming capsules
23
23
const kFieldDelimiter = '\n' ;
@@ -65,7 +65,7 @@ export interface PandocBlockCapsuleFilter {
65
65
p2 : string ,
66
66
p3 : string ,
67
67
p4 : string ,
68
- ) => { prefix : string ; source : string ; suffix : string } ;
68
+ ) => { prefix : string ; source : string ; suffix : string ; } ;
69
69
70
70
// provide a (text) envelope around the capsule, e.g.
71
71
// - newlines to ensure that yaml is parsed as a standalone paragraph;
@@ -88,6 +88,15 @@ export interface PandocBlockCapsuleFilter {
88
88
writeNode : ( schema : Schema , writer : ProsemirrorWriter , capsule : PandocBlockCapsule ) => void ;
89
89
}
90
90
91
+ // default extractor
92
+ const defaultExtractor = ( _match : string , p1 : string , p2 : string , p3 : string ) => {
93
+ return {
94
+ prefix : p1 ,
95
+ source : p2 ,
96
+ suffix : p3 ,
97
+ } ;
98
+ } ;
99
+
91
100
// transform the passed markdown to include base64 encoded block capsules as specified by the
92
101
// provided capsule filter. capsules are used to hoist block types that we don't want pandoc
93
102
// to see (e.g. yaml metadata or Rmd chunks) out of the markdown, only to be re-inserted
@@ -99,15 +108,6 @@ export function pandocMarkdownWithBlockCapsules(
99
108
markdown : string ,
100
109
capsuleFilter : PandocBlockCapsuleFilter ,
101
110
) {
102
- // default extractor
103
- const defaultExtractor = ( _match : string , p1 : string , p2 : string , p3 : string ) => {
104
- return {
105
- prefix : p1 ,
106
- source : p2 ,
107
- suffix : p3 ,
108
- } ;
109
- } ;
110
-
111
111
// find the original position of all the matches
112
112
const positions : number [ ] = [ ] ;
113
113
let match = capsuleFilter . match . exec ( original ) ;
@@ -179,41 +179,27 @@ export function pandocMarkdownWithBlockCapsules(
179
179
} ) ;
180
180
}
181
181
182
- // block capsules can also end up not as block tokens, but rather as text within another
183
- // token (e.g. within a backtick code block or raw_block). this function takes a set
184
- // of pandoc tokens and recursively converts block capsules that aren't of type
185
- // PandocTokenType.Str (which is what we'd see in a paragraph) into their original form
186
- export function resolvePandocBlockCapsuleText (
187
- tokens : PandocToken [ ] ,
188
- filters : readonly PandocBlockCapsuleFilter [ ] ,
189
- ) : PandocToken [ ] {
190
- // process all tokens
191
- return mapTokens ( tokens , token => {
192
- // look for non-string pandoc tokens
193
- if ( token . t !== PandocTokenType . Str && token . c ) {
194
- if ( typeof token . c === 'string' ) {
195
- token . c = decodeBlockCapsuleText ( token . c , token , filters ) ;
196
- } else if ( Array . isArray ( token . c ) ) {
197
- const children = token . c . length ;
198
- for ( let i = 0 ; i < children ; i ++ ) {
199
- if ( typeof token . c [ i ] === 'string' ) {
200
- token . c [ i ] = decodeBlockCapsuleText ( token . c [ i ] , token , filters ) ;
201
- }
202
- }
203
- }
204
- }
205
-
206
- return token ;
207
- } ) ;
208
- }
209
-
210
182
// decode the text capsule by running all of the filters (as there could be nesting)
211
183
export function decodeBlockCapsuleText ( text : string , tok : PandocToken , filters : readonly PandocBlockCapsuleFilter [ ] ) {
212
184
filters . forEach ( filter => {
213
185
text = filter . handleText ( text , tok ) ;
214
186
} ) ;
215
187
return text ;
216
188
}
189
+ const resolveTokenBlockCapsuleText = ( token : PandocToken , filters : readonly PandocBlockCapsuleFilter [ ] ) => ( {
190
+ t : token . t ,
191
+ c : token . t !== PandocTokenType . Str && typeof token . c === 'string' ?
192
+ decodeBlockCapsuleText ( token . c , token , filters ) :
193
+ token . c
194
+ } ) ;
195
+ // block capsules can also end up not as block tokens, but rather as text within another
196
+ // token (e.g. within a backtick code block or raw_block). this function takes a set
197
+ // of pandoc tokens and recursively converts block capsules that aren't of type
198
+ // PandocTokenType.Str (which is what we'd see in a paragraph) into their original form
199
+ export const resolvePandocBlockCapsuleText = (
200
+ tokens : PandocToken [ ] ,
201
+ filters : readonly PandocBlockCapsuleFilter [ ] ,
202
+ ) => mapTokensRecursive ( tokens , token => resolveTokenBlockCapsuleText ( token , filters ) ) ;
217
203
218
204
export function blockCapsuleTextHandler ( type : string , pattern : RegExp , textFilter ?: ( text : string ) => string ) {
219
205
return ( text : string , tok : PandocToken ) : string => {
@@ -263,12 +249,12 @@ export function blockCapsuleParagraphTokenHandler(type: string) {
263
249
export function encodedBlockCapsuleRegex ( prefix ?: string , suffix ?: string , flags ?: string ) {
264
250
return new RegExp (
265
251
( prefix || '' ) +
266
- kBlockCapsuleSentinel +
267
- kValueDelimiter +
268
- '((?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?)' +
269
- kValueDelimiter +
270
- kBlockCapsuleSentinel +
271
- ( suffix || '' ) ,
252
+ kBlockCapsuleSentinel +
253
+ kValueDelimiter +
254
+ '((?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?)' +
255
+ kValueDelimiter +
256
+ kBlockCapsuleSentinel +
257
+ ( suffix || '' ) ,
272
258
flags ,
273
259
) ;
274
260
}
0 commit comments