@podlite/to-jsx 0.0.16 → 0.0.17

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/src/index.tsx CHANGED
@@ -1,184 +1,225 @@
1
1
  import * as React from 'react'
2
- import {createElement} from 'react'
3
- import { frozenIds, podlite as podlite_core, PodliteExport, toAnyRules } from 'podlite'
4
- import {Verbatim, PodNode, Text, Rules, RulesStrict, getNodeId, parse, makeAttrs, emptyContent, content as nodeContent, setFn, subUse, toAny, isNamedBlock, isSemanticBlock, Writer} from '@podlite/schema'
5
- import { Toc, Plugin, pluginCleanLocation as clean_plugin } from '@podlite/schema'
6
-
2
+ import { createElement } from 'react'
3
+ import { podlite as podlite_core } from 'podlite'
4
+ import {
5
+ Verbatim,
6
+ PodNode,
7
+ Text,
8
+ Rules,
9
+ RulesStrict,
10
+ getNodeId,
11
+ parse,
12
+ makeAttrs,
13
+ emptyContent,
14
+ content as nodeContent,
15
+ setFn,
16
+ subUse,
17
+ toAny,
18
+ isNamedBlock,
19
+ isSemanticBlock,
20
+ Writer,
21
+ toAnyRules,
22
+ PodliteExport,
23
+ frozenIds,
24
+ } from '@podlite/schema'
25
+ import { Toc, Plugin, pluginCleanLocation as clean_plugin } from '@podlite/schema'
7
26
 
8
27
  // interface SetFn { <T>(<T>node, ctx:any) => () => () =>void
9
28
  // }
10
29
  export type CreateElement = typeof React.createElement
11
- const helperMakeReact = ({wrapElement}:{wrapElement?:WrapElement})=>{
12
- let i_key_i = 0;
13
- let mapByType= {};
14
- const getIdForNode = ({type="notype",name="noname"}) =>{
15
- const type_idx = `${type}_${name}`
16
- if ( ! mapByType[type_idx] ) { mapByType[type_idx] = 0}
17
- ++mapByType[type_idx]
18
- return `${type_idx}_${mapByType[type_idx]}`
30
+ const helperMakeReact = ({ wrapElement }: { wrapElement?: WrapElement }) => {
31
+ let i_key_i = 0
32
+ let mapByType = {}
33
+ const getIdForNode = ({ type = 'notype', name = 'noname' }) => {
34
+ const type_idx = `${type}_${name}`
35
+ if (!mapByType[type_idx]) {
36
+ mapByType[type_idx] = 0
19
37
  }
20
- return function(src:string|Function, node:PodNode, children, extraProps = {}, ctx = {} ) {
21
- // for string return it
22
- if (typeof node == 'string') {
23
- return node
24
- }
25
- const { ...attr} = node
38
+ ++mapByType[type_idx]
39
+ return `${type_idx}_${mapByType[type_idx]}`
40
+ }
41
+ return function (src: string | Function, node: PodNode, children, extraProps = {}, ctx = {}) {
42
+ // for string return it
43
+ if (typeof node == 'string') {
44
+ return node
45
+ }
46
+ const { ...attr } = node
26
47
 
27
- const key = 'type' in node && node.type ? getIdForNode(node) : ++i_key_i
28
- const result =
29
- typeof src === 'function'
30
- ? src({ ...attr, key , children}, children)
31
- : createElement(src,{ ...extraProps, key }, children )
48
+ const key = 'type' in node && node.type ? getIdForNode(node) : ++i_key_i
49
+ const result =
50
+ typeof src === 'function'
51
+ ? src({ ...attr, key, children }, children)
52
+ : createElement(src, { ...extraProps, key }, children)
32
53
 
33
- // // create react element and pass key
34
- // if (!isValidElementType(src)) {
35
- // throw new Error(`Bad React element for ${ruleName} rule `)
36
- // }
54
+ // // create react element and pass key
55
+ // if (!isValidElementType(src)) {
56
+ // throw new Error(`Bad React element for ${ruleName} rule `)
57
+ // }
37
58
 
38
- if (typeof wrapElement === 'function') {
39
- return wrapElement( node, result, ctx )
40
- }
41
- return result
59
+ if (typeof wrapElement === 'function') {
60
+ return wrapElement(node, result, ctx)
42
61
  }
43
- }
62
+ return result
63
+ }
64
+ }
44
65
 
45
- export interface WrapElement {
46
- (
47
- node: PodNode,
48
- children: React.ReactChild,
49
- ctx: any
50
- ) : JSX.Element
51
- }
66
+ export interface WrapElement {
67
+ (node: PodNode, children: React.ReactChild, ctx: any): JSX.Element
68
+ }
52
69
  export const Podlite: React.FC<{
53
- [key: string]: any
54
- children?: string
55
- file?:string,
56
- plugins?:any,
57
- wrapElement?:WrapElement,
58
- tree?:PodliteExport
59
- }> = ({ children, ...options }) => {
60
- const result:any = podlite(children, options)
61
- return result
70
+ [key: string]: any
71
+ children?: string
72
+ file?: string
73
+ plugins?: any
74
+ wrapElement?: WrapElement
75
+ tree?: PodliteExport
76
+ }> = ({ children, ...options }) => {
77
+ const result: any = podlite(children, options)
78
+ return result
79
+ }
80
+ const mapToReact = (makeComponent): Partial<RulesStrict> => {
81
+ const mkComponent = src => (writer, processor) => (node, ctx, interator) => {
82
+ // prepare extraProps for createElement
83
+ // add id attribute if exists
84
+ const id = getNodeId(node, ctx)?.replace(/\s/g, '-')
85
+ // check if node.content defined
86
+ return makeComponent(src, node, 'content' in node ? interator(node.content, { ...ctx }) : [], { id }, ctx)
62
87
  }
63
- const mapToReact = (makeComponent):Partial<RulesStrict> => {
64
-
65
- const mkComponent = (src) => ( writer, processor )=>( node, ctx, interator )=>{
66
- // prepare extraProps for createElement
67
- // add id attribute if exists
68
- const id = getNodeId(node, ctx)?.replace(/\s/g,'-');
69
- // check if node.content defined
70
- return makeComponent(src, node, 'content' in node ? interator(node.content, { ...ctx}) : [], {id}, ctx)
71
- }
72
- // Handle nested block and :nested block attribute
73
- const handleNested = ( defaultHandler, implicitLevel?:number ) => {
74
-
75
- return ( writer, processor ) => {
76
- const defaultHandlerInited = defaultHandler( writer, processor )
77
- return ( node, ctx, interator ) => {
78
-
79
- const nesting = makeAttrs(node, ctx).getFirstValue('nested') || implicitLevel
80
- const children = defaultHandlerInited( node, ctx, interator )
81
- // if no nesting needs - simply return children
82
- if (!nesting) {return children }
83
- const arr = [...Array(nesting).keys()]
84
- return arr.reduce((acc)=>makeComponent('blockquote', node, acc), children)
85
-
86
- }
88
+ // Handle nested block and :nested block attribute
89
+ const handleNested = (defaultHandler, implicitLevel?: number) => {
90
+ return (writer, processor) => {
91
+ const defaultHandlerInited = defaultHandler(writer, processor)
92
+ return (node, ctx, interator) => {
93
+ const nesting = makeAttrs(node, ctx).getFirstValue('nested') || implicitLevel
94
+ const children = defaultHandlerInited(node, ctx, interator)
95
+ // if no nesting needs - simply return children
96
+ if (!nesting) {
97
+ return children
87
98
  }
99
+ const arr = [...Array(nesting).keys()]
100
+ return arr.reduce(acc => makeComponent('blockquote', node, acc), children)
101
+ }
88
102
  }
103
+ }
89
104
 
90
- return {
91
- 'pod': mkComponent('div'),
92
- 'root': nodeContent,
93
- 'data': emptyContent(),
105
+ return {
106
+ pod: mkComponent('div'),
107
+ root: nodeContent,
108
+ data: emptyContent(),
94
109
  ':ambient': emptyContent(),
95
- ':code': mkComponent(({ children, key })=><code key={key}><pre>{children}</pre></code>),
96
- 'code': mkComponent(({ children, key })=><code key={key}><pre>{children}</pre></code>),
97
- 'image':nodeContent,
98
- ':image': setFn(( node, ctx ) => {
99
- return mkComponent(({ children, key })=><img key={key} src={node.src} alt={node.alt}/>)
110
+ ':code': mkComponent(({ children, key }) => (
111
+ <code key={key}>
112
+ <pre>{children}</pre>
113
+ </code>
114
+ )),
115
+ code: mkComponent(({ children, key }) => (
116
+ <code key={key}>
117
+ <pre>{children}</pre>
118
+ </code>
119
+ )),
120
+ image: nodeContent,
121
+ ':image': setFn((node, ctx) => {
122
+ return mkComponent(({ children, key }) => <img key={key} src={node.src} alt={node.alt} />)
100
123
  }),
101
124
 
102
- ':text':( writer, processor )=>( node:Text, ctx, interator )=>{
103
- return node.value
125
+ ':text': (writer, processor) => (node: Text, ctx, interator) => {
126
+ return node.value
104
127
  },
105
- ':verbatim' : ( writer, processor )=>( node:Verbatim, ctx, interator )=>{
106
- return node.value
128
+ ':verbatim': (writer, processor) => (node: Verbatim, ctx, interator) => {
129
+ return node.value
107
130
  },
108
- 'head:block': subUse({
131
+ 'head:block': subUse(
132
+ {
109
133
  // inside head don't wrap into <p>
110
- ':para' : nodeContent,
111
- },
112
- setFn(( node, ctx ) => {
113
- const {level } = node
114
- const id = getNodeId(node, ctx)?.replace(/\s/g,'-');
115
- return mkComponent(({level,children, key })=>createElement(`h${level}`,{key, id}, children))
116
- })
117
- ),
134
+ ':para': nodeContent,
135
+ },
136
+ setFn((node, ctx) => {
137
+ const { level } = node
138
+ const id = getNodeId(node, ctx)?.replace(/\s/g, '-')
139
+ return mkComponent(({ level, children, key }) => createElement(`h${level}`, { key, id }, children))
140
+ }),
141
+ ),
118
142
 
119
143
  ':blankline': emptyContent(),
120
- ':para' : mkComponent('p'),
121
- 'para' : mkComponent('div'),
144
+ ':para': mkComponent('p'),
145
+ para: mkComponent('div'),
122
146
  'comment:block': emptyContent(),
123
- 'defn':subUse([
124
- // to avoid overlap para blocks handlers
125
- // define general :para at first
126
- {':para':mkComponent('dd')},
127
- {'term:para' : mkComponent('dt')},
128
- ],
129
- nodeContent
147
+ defn: subUse(
148
+ [
149
+ // to avoid overlap para blocks handlers
150
+ // define general :para at first
151
+ { ':para': mkComponent('dd') },
152
+ { 'term:para': mkComponent('dt') },
153
+ ],
154
+ nodeContent,
130
155
  ),
131
- "nested":handleNested(nodeContent, 1),
132
- 'output': mkComponent(({children, key })=><pre key={key}><samp>{children}</samp></pre>),
133
- 'input': mkComponent(({children, key })=><pre key={key}><kbd>{children}</kbd></pre>),
156
+ nested: handleNested(nodeContent, 1),
157
+ output: mkComponent(({ children, key }) => (
158
+ <pre key={key}>
159
+ <samp>{children}</samp>
160
+ </pre>
161
+ )),
162
+ input: mkComponent(({ children, key }) => (
163
+ <pre key={key}>
164
+ <kbd>{children}</kbd>
165
+ </pre>
166
+ )),
134
167
 
135
- // Directives
136
- ':config': setFn(( node, ctx ) => {
137
- // setup context
138
- if ( ! ctx.hasOwnProperty('config') ) ctx.config = {}
139
- //collect configs in context
140
- ctx.config[node.name] = node.config
141
- return emptyContent()}),
142
- ':alias': setFn(( node, ctx ) => {
143
- // set alias
144
- if ( ! ctx.hasOwnProperty('alias') ) ctx.alias = {}
145
- //collect configs in context
146
- ctx.alias[node.name] = node.replacement
147
- return emptyContent()
168
+ // Directives
169
+ ':config': setFn((node, ctx) => {
170
+ // setup context
171
+ if (!ctx.hasOwnProperty('config')) ctx.config = {}
172
+ //collect configs in context
173
+ ctx.config[node.name] = node.config
174
+ return emptyContent()
175
+ }),
176
+ ':alias': setFn((node, ctx) => {
177
+ // set alias
178
+ if (!ctx.hasOwnProperty('alias')) ctx.alias = {}
179
+ //collect configs in context
180
+ ctx.alias[node.name] = node.replacement
181
+ return emptyContent()
148
182
  }),
149
183
 
150
184
  // Formatting codes
151
- 'A<>': ( writer, processor ) => ( node, ctx, interator ) => {
152
- let term = node.content
153
- if ( typeof term !== 'string' && 'value' in term ) {
154
- term = term.value
155
- }
156
- //get replacement text
157
- if (! (ctx.alias && ctx.alias.hasOwnProperty(term)) ) {
158
- return makeComponent(({children, key})=><code key={key}>A&lt;{children}&gt;</code>, node, interator( node.content, ctx ))
185
+ 'A<>': (writer, processor) => (node, ctx, interator) => {
186
+ let term = node.content
187
+ if (typeof term !== 'string' && 'value' in term) {
188
+ term = term.value
189
+ }
190
+ //get replacement text
191
+ if (!(ctx.alias && ctx.alias.hasOwnProperty(term))) {
192
+ return makeComponent(
193
+ ({ children, key }) => <code key={key}>A&lt;{children}&gt;</code>,
194
+ node,
195
+ interator(node.content, ctx),
196
+ )
197
+ } else {
198
+ const src = ctx.alias[term].join('\n')
199
+ const tree_1 = processor(src)
200
+ // now clean locations
201
+ const tree = clean_plugin()(tree_1)
202
+ if (tree[0].type === 'para') {
203
+ return interator(tree[0].content, ctx)
159
204
  } else {
160
- const src = ctx.alias[ term ].join('\n')
161
- const tree_1 = processor( src )
162
- // now clean locations
163
- const tree = clean_plugin()(tree_1)
164
- if ( tree[0].type === 'para') {
165
- return interator( tree[0].content, ctx )
166
- } else {
167
- return interator( tree, ctx )
168
- }
205
+ return interator(tree, ctx)
169
206
  }
207
+ }
170
208
  },
171
209
  'B<>': mkComponent('strong'),
172
210
  'C<>': mkComponent('code'),
173
- 'E<>': ( writer, processor )=>( node, ctx, interator )=>{
174
- if ('content' in node && Array.isArray(node.content) )
175
- return node.content.filter(e=>e && e.type == 'number').map(element=>{
211
+ 'E<>': (writer, processor) => (node, ctx, interator) => {
212
+ if ('content' in node && Array.isArray(node.content))
213
+ return node.content
214
+ .filter(e => e && e.type == 'number')
215
+ .map(element => {
176
216
  return String.fromCharCode(element.value)
177
- }).join('')
217
+ })
218
+ .join('')
178
219
  },
179
220
  'I<>': mkComponent('i'),
180
221
  'K<>': mkComponent('kbd'),
181
- /**
222
+ /**
182
223
  * CSS rules for footnotes
183
224
 
184
225
  .footnote a {
@@ -190,258 +231,317 @@ const mapToReact = (makeComponent):Partial<RulesStrict> => {
190
231
  border-top-color: #eee;
191
232
  }
192
233
  */
193
- 'N<>' : ( writer, processor ) => {
194
- writer.addListener('end', ()=>{
195
- if ( !writer.hasOwnProperty('FOOTNOTES') ) { return }
196
- const footnotes = writer.FOOTNOTES
197
- if ( footnotes.length < 1 ) { return } // if empty footnotes
198
- if ( !writer.hasOwnProperty('postInterator') ) { writer.postInterator = []}
199
-
200
- const FootNotes = makeComponent(({children, key})=><div key={`${key}_FOOTNOTES`} className="footnotes">
201
- {
202
- footnotes.map((footnote, id) =>{
203
- return <p key={id}>
204
- <sup id={footnote.fnId} className="footnote"><a href={`#${footnote.fnRefId}`}>[{footnote.gid}]</a></sup>
205
- { footnote.make() }
206
- </p>
207
- })
208
- }
209
- </div>,{})
210
-
211
- writer.postInterator.push( FootNotes )
212
-
213
- })
214
- return ( node, ctx, interator ) => {
215
- // skip empty notes
216
- if ( node.content.length < 1 ) { return }
217
- if ( !writer.hasOwnProperty('gid') ) { writer.gid = 1}
218
- // get foot note id
219
- const gid = writer.gid++
220
- const fnRefId = `fnref:${gid}`
221
- const fnId = `fn:${gid}`
222
- if ( !writer.hasOwnProperty('FOOTNOTES') ) { writer.FOOTNOTES = []}
223
- writer.FOOTNOTES.push({
224
- gid,
225
- fnRefId,
226
- fnId,
227
- node,
228
- make: ( )=>{ return interator(node.content, ctx) }
229
- })
230
- return makeComponent(({children, key})=><sup key={key} id={fnRefId} className="footnote"><a href={`#${fnId}`}>[{gid}]</a></sup> , node )
234
+ 'N<>': (writer, processor) => {
235
+ writer.addListener('end', () => {
236
+ if (!writer.hasOwnProperty('FOOTNOTES')) {
237
+ return
231
238
  }
232
- },
233
- 'R<>': mkComponent('var'),
234
- 'T<>': mkComponent('samp'),
235
- 'D<>': ( writer, processor ) => ( node, ctx, interator ) => {
236
-
237
- let { synonyms } = node
238
- let definition:string[] = [node.content[0]]
239
- if ( synonyms ) {
240
- definition = synonyms
239
+ const footnotes = writer.FOOTNOTES
240
+ if (footnotes.length < 1) {
241
+ return
242
+ } // if empty footnotes
243
+ if (!writer.hasOwnProperty('postInterator')) {
244
+ writer.postInterator = []
241
245
  }
242
246
 
243
- if ( !writer.hasOwnProperty('DEFINITIONS') ) { writer.DEFINITIONS = []}
244
- writer.DEFINITIONS.push({ definition })
245
- return makeComponent('dfn', node, interator(node.content, ctx))
246
- },
247
- "L<>": setFn(( node, ctx ) => {
248
- let { meta } = node
249
- if ( meta === null) {
250
- meta = node.content
251
- }
252
- //TODO: extract text from content array
253
- if ( Array.isArray(meta)) {
254
- meta = meta[0]
247
+ const FootNotes = makeComponent(
248
+ ({ children, key }) => (
249
+ <div key={`${key}_FOOTNOTES`} className="footnotes">
250
+ {footnotes.map((footnote, id) => {
251
+ return (
252
+ <p key={id}>
253
+ <sup id={footnote.fnId} className="footnote">
254
+ <a href={`#${footnote.fnRefId}`}>[{footnote.gid}]</a>
255
+ </sup>
256
+ {footnote.make()}
257
+ </p>
258
+ )
259
+ })}
260
+ </div>
261
+ ),
262
+ {},
263
+ )
264
+
265
+ writer.postInterator.push(FootNotes)
266
+ })
267
+ return (node, ctx, interator) => {
268
+ // skip empty notes
269
+ if (node.content.length < 1) {
270
+ return
255
271
  }
256
- if ( meta && typeof meta !== 'string' && 'value' in meta ) {
257
- meta = meta.value
272
+ if (!writer.hasOwnProperty('gid')) {
273
+ writer.gid = 1
258
274
  }
259
- return mkComponent(({children, key })=><a href={meta} key={key}>{children}</a>)
260
- }),
261
- 'S<>' :( writer, processor )=>( node, ctx, interator )=>{
262
- let content = node.content || ''
263
- if (typeof content !== 'string' && 'value' in content ) {
264
- content = content.value
275
+ // get foot note id
276
+ const gid = writer.gid++
277
+ const fnRefId = `fnref:${gid}`
278
+ const fnId = `fn:${gid}`
279
+ if (!writer.hasOwnProperty('FOOTNOTES')) {
280
+ writer.FOOTNOTES = []
265
281
  }
266
- const Content = content.split('').map((symbol,index) => {
267
- if (symbol === ' ') return "\u00a0";
268
- if (symbol === '\n') return <br key={index}/>;
269
- return symbol
282
+ writer.FOOTNOTES.push({
283
+ gid,
284
+ fnRefId,
285
+ fnId,
286
+ node,
287
+ make: () => {
288
+ return interator(node.content, ctx)
289
+ },
270
290
  })
271
- return makeComponent(({children, key })=>children, {}, Content )
291
+ return makeComponent(
292
+ ({ children, key }) => (
293
+ <sup key={key} id={fnRefId} className="footnote">
294
+ <a href={`#${fnId}`}>[{gid}]</a>
295
+ </sup>
296
+ ),
297
+ node,
298
+ )
299
+ }
300
+ },
301
+ 'R<>': mkComponent('var'),
302
+ 'T<>': mkComponent('samp'),
303
+ 'D<>': (writer, processor) => (node, ctx, interator) => {
304
+ let { synonyms } = node
305
+ let definition: string[] = [node.content[0]]
306
+ if (synonyms) {
307
+ definition = synonyms
308
+ }
309
+
310
+ if (!writer.hasOwnProperty('DEFINITIONS')) {
311
+ writer.DEFINITIONS = []
312
+ }
313
+ writer.DEFINITIONS.push({ definition })
314
+ return makeComponent('dfn', node, interator(node.content, ctx))
315
+ },
316
+ 'L<>': setFn((node, ctx) => {
317
+ let { meta } = node
318
+ if (meta === null) {
319
+ meta = node.content
320
+ }
321
+ //TODO: extract text from content array
322
+ if (Array.isArray(meta)) {
323
+ meta = meta[0]
324
+ }
325
+ if (meta && typeof meta !== 'string' && 'value' in meta) {
326
+ meta = meta.value
327
+ }
328
+ return mkComponent(({ children, key }) => (
329
+ <a href={meta} key={key}>
330
+ {children}
331
+ </a>
332
+ ))
333
+ }),
334
+ 'S<>': (writer, processor) => (node, ctx, interator) => {
335
+ let content = node.content || ''
336
+ if (typeof content !== 'string' && 'value' in content) {
337
+ content = content.value
338
+ }
339
+ const Content = content.split('').map((symbol, index) => {
340
+ if (symbol === ' ') return '\u00a0'
341
+ if (symbol === '\n') return <br key={index} />
342
+ return symbol
343
+ })
344
+ return makeComponent(({ children, key }) => children, {}, Content)
272
345
  },
273
346
  'V<>': nodeContent,
274
347
  'Z<>': emptyContent(),
275
348
  'U<>': mkComponent('u'),
276
- 'X<>' : ( writer, processor ) => ( node, ctx, interator ) => {
277
- let {entry} = node
278
- if ( entry === null && node.content.length > 0) {
279
- //@ts-ignore
280
- entry = [node.content[0]]
281
- }
282
- // else { return }
283
- if ( !writer.hasOwnProperty('INDEXTERMS') ) { writer.INDEXTERMS = []}
284
- writer.INDEXTERMS.push({
285
- entry
286
- })
287
- return interator(node.content, ctx)
288
- },
349
+ 'X<>': (writer, processor) => (node, ctx, interator) => {
350
+ let { entry } = node
351
+ if (entry === null && node.content.length > 0) {
352
+ //@ts-ignore
353
+ entry = [node.content[0]]
354
+ }
355
+ // else { return }
356
+ if (!writer.hasOwnProperty('INDEXTERMS')) {
357
+ writer.INDEXTERMS = []
358
+ }
359
+ writer.INDEXTERMS.push({
360
+ entry,
361
+ })
362
+ return interator(node.content, ctx)
363
+ },
289
364
  'Delete<>': mkComponent('del'),
290
365
  // table section
291
- 'table' :
292
- ( writer, processor ) =>
293
- ( node, ctx, interator ) =>
294
- {
295
- const conf = makeAttrs(node, ctx)
296
- let attr = {caption:''}
297
- if ( conf.exists('caption') ) {
298
- const caption = conf.getFirstValue('caption')
299
- attr.caption = caption
300
- }
301
- if ( typeof node === 'string' ) {
302
- return node
303
- }
304
- if (! ('content' in node) ) {
305
- console.warn('[jsx] no content in node')
306
- return ''
307
- }
308
- const id = getNodeId(node, ctx)?.replace(/\s/g,'-');
309
- return makeComponent(({key, children})=>{
310
- return <table key={key} id={id}>
311
- <caption className="caption">{attr.caption}</caption>
312
- <tbody>{children}</tbody></table>
313
- }, node, interator(node.content, { ...ctx}) )
314
- }
315
- ,
316
- ':separator' : emptyContent(),
317
- 'table_row' : mkComponent('tr'),
318
- 'table_cell': mkComponent('td'),
319
- 'table_head' : subUse(
320
- {
321
- 'table_cell': mkComponent('th')
366
+ table: (writer, processor) => (node, ctx, interator) => {
367
+ const conf = makeAttrs(node, ctx)
368
+ let attr = { caption: '' }
369
+ if (conf.exists('caption')) {
370
+ const caption = conf.getFirstValue('caption')
371
+ attr.caption = caption
372
+ }
373
+ if (typeof node === 'string') {
374
+ return node
375
+ }
376
+ if (!('content' in node)) {
377
+ console.warn('[jsx] no content in node')
378
+ return ''
379
+ }
380
+ const id = getNodeId(node, ctx)?.replace(/\s/g, '-')
381
+ return makeComponent(
382
+ ({ key, children }) => {
383
+ return (
384
+ <table key={key} id={id}>
385
+ <caption className="caption">{attr.caption}</caption>
386
+ <tbody>{children}</tbody>
387
+ </table>
388
+ )
322
389
  },
323
- mkComponent('tr')
324
- ),
325
- ':list': setFn(( node, ctx ) =>
326
- node.list === 'ordered' ? mkComponent('ol')
327
- : node.list === 'variable' ? mkComponent('dl')
328
- : mkComponent('ul')
329
- ),
330
- 'item:block': ( writer, processor ) => ( node, ctx, interator ) => {
331
- if ( typeof node === 'string' ) {
332
- return node
333
- }
334
- if (! ('content' in node) ) {
335
- console.warn('[jsx] no content in node')
336
- return ''
337
- }
338
- // make text from first para
339
- if (! (node.content instanceof Array)) {
340
- console.error(node)
341
- }
342
- const id = getNodeId(node,ctx)?.replace(/\s/g,'-');
343
- return makeComponent('li', node, interator(node.content, { ...ctx}), {id} )
390
+ node,
391
+ interator(node.content, { ...ctx }),
392
+ )
393
+ },
394
+ ':separator': emptyContent(),
395
+ table_row: mkComponent('tr'),
396
+ table_cell: mkComponent('td'),
397
+ table_head: subUse(
398
+ {
399
+ table_cell: mkComponent('th'),
400
+ },
401
+ mkComponent('tr'),
402
+ ),
403
+ ':list': setFn((node, ctx) =>
404
+ node.list === 'ordered' ? mkComponent('ol') : node.list === 'variable' ? mkComponent('dl') : mkComponent('ul'),
405
+ ),
406
+ 'item:block': (writer, processor) => (node, ctx, interator) => {
407
+ if (typeof node === 'string') {
408
+ return node
409
+ }
410
+ if (!('content' in node)) {
411
+ console.warn('[jsx] no content in node')
412
+ return ''
413
+ }
414
+ // make text from first para
415
+ if (!(node.content instanceof Array)) {
416
+ console.error(node)
417
+ }
418
+ const id = getNodeId(node, ctx)?.replace(/\s/g, '-')
419
+ return makeComponent('li', node, interator(node.content, { ...ctx }), { id })
344
420
  },
345
421
  // table of content
346
- ':toc': setFn(( node:Toc, ctx ) => {
347
- const tocTitle = node.title
348
- return mkComponent(({children, key })=><div className="toc" key={key}>{ tocTitle ? <div className="toctitle">{tocTitle}</div> : '' }{children}</div>)
422
+ ':toc': setFn((node: Toc, ctx) => {
423
+ const tocTitle = node.title
424
+ return mkComponent(({ children, key }) => (
425
+ <div className="toc" key={key}>
426
+ {tocTitle ? <div className="toctitle">{tocTitle}</div> : ''}
427
+ {children}
428
+ </div>
429
+ ))
349
430
  }),
350
- ':toc-list': setFn(( node, ctx ) => {
351
- const { level } = node
352
- return mkComponent(({children, key })=><ul className={`toc-list listlevel${level}`} key={key}>{children}</ul>)
431
+ ':toc-list': setFn((node, ctx) => {
432
+ const { level } = node
433
+ return mkComponent(({ children, key }) => (
434
+ <ul className={`toc-list listlevel${level}`} key={key}>
435
+ {children}
436
+ </ul>
437
+ ))
353
438
  }),
354
- ':toc-item': subUse({
439
+ ':toc-item': subUse(
440
+ {
355
441
  // inside head don't wrap into <p>
356
- ':para' : nodeContent,
357
- },
358
- setFn(( node, ctx ) => {
359
- return mkComponent(({children, key })=><li className="toc-item" key={key}>{children}</li>)
360
- })),
361
-
362
- }
442
+ ':para': nodeContent,
443
+ },
444
+ setFn((node, ctx) => {
445
+ return mkComponent(({ children, key }) => (
446
+ <li className="toc-item" key={key}>
447
+ {children}
448
+ </li>
449
+ ))
450
+ }),
451
+ ),
452
+ }
363
453
  }
364
- function podlite (children:string, { file,plugins=()=>{}, wrapElement, tree}:{file?:string, plugins?:any, wrapElement?:WrapElement, tree?:PodliteExport}, ...args) {
365
-
366
- const ast = ((tree)=>{
367
- if (tree) return tree.interator
368
- let podlite = podlite_core({ importPlugins: true })
369
- let treeAfterParsed = podlite.parse(children || file)
370
- return podlite.toAst(treeAfterParsed)
371
- })(tree)
454
+ function podlite(
455
+ children: string,
456
+ {
457
+ file,
458
+ plugins = () => {},
459
+ wrapElement,
460
+ tree,
461
+ }: { file?: string; plugins?: any; wrapElement?: WrapElement; tree?: PodliteExport },
462
+ ...args
463
+ ) {
464
+ const ast = (tree => {
465
+ if (tree) return tree.interator
466
+ let podlite = podlite_core({ importPlugins: true })
467
+ let treeAfterParsed = podlite.parse(children || file)
468
+ return podlite.toAst(treeAfterParsed)
469
+ })(tree)
372
470
 
373
- // const ast = parse( children || content )
374
- let i_key_i = 10000
375
- const makeComponent = helperMakeReact({wrapElement})
471
+ // const ast = parse( children || content )
472
+ let i_key_i = 10000
473
+ const makeComponent = helperMakeReact({ wrapElement })
376
474
 
377
- const jsxPlugins:{[name :string]:Plugin['toJSX']} = toAnyRules('toJSX', podlite_core({ importPlugins: true }).getPlugins())
378
- // initialize each plugin
379
- const jsxPluginInited =
380
- Object.fromEntries(Object.entries(jsxPlugins).map(([key, value])=>[key, value(makeComponent)]))
381
-
382
- const rules:Rules = {
383
- ...mapToReact(makeComponent),
384
- ...plugins(makeComponent),
385
- ...jsxPluginInited,
386
- }
387
- interface WriterPostinterator extends Writer {
388
- postInterator? : any
389
- }
390
- const writer = new Writer((s)=>{
391
- }) as WriterPostinterator
392
- const res =
393
- toAny({processor:parse})
394
- .use({'*:*':() => ( node, ctx, interator ) => {
475
+ const jsxPlugins: { [name: string]: Plugin['toJSX'] } = toAnyRules(
476
+ 'toJSX',
477
+ podlite_core({ importPlugins: true }).getPlugins(),
478
+ )
479
+ // initialize each plugin
480
+ const jsxPluginInited = Object.fromEntries(
481
+ Object.entries(jsxPlugins).map(([key, value]) => [key, value(makeComponent)]),
482
+ )
395
483
 
484
+ const rules: Rules = {
485
+ ...mapToReact(makeComponent),
486
+ ...plugins(makeComponent),
487
+ ...jsxPluginInited,
488
+ }
489
+ interface WriterPostinterator extends Writer {
490
+ postInterator?: any
491
+ }
492
+ const writer = new Writer(s => {}) as WriterPostinterator
493
+ const res = toAny({ processor: parse })
494
+ .use({
495
+ '*:*': () => (node, ctx, interator) => {
396
496
  // skip named blocks
397
497
  if (isNamedBlock(node.name)) {
398
- return null
498
+ return null
399
499
  }
400
- if ( isSemanticBlock(node) ) {
401
- return makeComponent(({key, children})=>{
402
- return <div key={key}><h1 className={node.name} key={key}>{node.name}</h1>
403
- {interator(node.content, { ...ctx}) }
500
+ if (isSemanticBlock(node)) {
501
+ return makeComponent(
502
+ ({ key, children }) => {
503
+ return (
504
+ <div key={key}>
505
+ <h1 className={node.name} key={key}>
506
+ {node.name}
507
+ </h1>
508
+ {interator(node.content, { ...ctx })}
404
509
  </div>
405
- }, node, interator(node.content, { ...ctx}) )
510
+ )
511
+ },
512
+ node,
513
+ interator(node.content, { ...ctx }),
514
+ )
406
515
  }
407
- console.warn('[podlite] Not supported: ' + JSON.stringify(node,null,2))
408
- return createElement('code',{key:++i_key_i},`not supported node:${JSON.stringify(node,null,2)}`)
409
- }})
516
+ console.warn('[podlite] Not supported: ' + JSON.stringify(node, null, 2))
517
+ return createElement('code', { key: ++i_key_i }, `not supported node:${JSON.stringify(node, null, 2)}`)
518
+ },
519
+ })
410
520
  .use(rules)
411
521
  .run(ast, writer)
412
- // union main react elements and post processed via onEnd event
413
- return new Array().concat( res.interator, writer.postInterator )
522
+ // union main react elements and post processed via onEnd event
523
+ return new Array().concat(res.interator, writer.postInterator)
414
524
  }
415
525
 
416
526
  // this is a helper function for using in unit test
417
527
  export const TestPodlite = ({ children, ...options }) => {
418
- let podlite = podlite_core({ importPlugins: true });
419
-
420
- // its replace all ids with "id"
421
- let treeAfterParsed = frozenIds()(podlite.parse(children));
422
-
423
- const tree = podlite.toAst(treeAfterParsed);
424
- return (
425
- <Podlite
426
- {...{ children, ...options, tree: { interator: tree } as PodliteExport }}
427
- />
428
- );
429
- };
430
-
431
- export const makeTestPodlite = (podlite = podlite_core({ importPlugins: true })) => ({ children, ...options }) => {
528
+ let podlite = podlite_core({ importPlugins: true })
432
529
 
433
- let treeAfterParsed = podlite.parse(children);
530
+ // its replace all ids with "id"
531
+ let treeAfterParsed = frozenIds()(podlite.parse(children))
434
532
 
435
- // its replace all ids with "id"
436
- const tree = frozenIds()(podlite.toAst(treeAfterParsed));
437
- return (
438
- <Podlite
439
- {...{ children, ...options, tree: { interator: tree } as PodliteExport }}
440
- />
441
- );
442
- };
443
-
533
+ const tree = podlite.toAst(treeAfterParsed)
534
+ return <Podlite {...{ children, ...options, tree: { interator: tree } as PodliteExport }} />
535
+ }
444
536
 
445
- export default Podlite
537
+ export const makeTestPodlite =
538
+ (podlite = podlite_core({ importPlugins: true })) =>
539
+ ({ children, ...options }) => {
540
+ let treeAfterParsed = podlite.parse(children)
446
541
 
542
+ // its replace all ids with "id"
543
+ const tree = frozenIds()(podlite.toAst(treeAfterParsed))
544
+ return <Podlite {...{ children, ...options, tree: { interator: tree } as PodliteExport }} />
545
+ }
447
546
 
547
+ export default Podlite