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