14
14
doc: NbDoc # could be a NbBlock but we could give more guarantees with a NbDoc
15
15
backend: NbRender
16
16
17
- # this needs to be know for all container blocks
17
+ # this needs to be know for all container blocks not sure whether to put it in types
18
18
func render(nb: Nb, blk: NbBlock): string =
19
19
if blk.kind in nb.backend.funcs:
20
20
nb.backend.funcs[blk.kind](blk, nb)
21
21
else:
22
22
""
23
23
24
+ # globals.nim
25
+ var nbToJson: Table[string , proc (s: string , i: var int ): NbBlock]
26
+ var nbToHtml: NbRender # since we need it for json, let's make it also for html
27
+
28
+ # jsons.nim
29
+ import jsony
30
+
31
+ template addNbBlockToJson*(kind: untyped ) =
32
+ nbToJson[$kind] =
33
+ proc (s: string , i: var int ): NbBlock =
34
+ var v: kind
35
+ new v
36
+ parseHook(s, i, v[])
37
+ result = v
38
+
39
+ method dump(n: kind): string =
40
+ n[].toJson()
41
+
42
+ proc parseHook*(s: string , i: var int , v: var NbBlock) =
43
+ # First parse the typename
44
+ var n: NbBlock = NbBlock()
45
+ let current_i = i
46
+ parseHook(s, i, n[])
47
+ # Reset i
48
+ i = current_i
49
+ # Parse the correct type
50
+ let kind = n.kind
51
+ v = nbToJson[kind](s, i)
52
+
53
+ method dump(n: NbBlock): string =
54
+ n[].toJson()
55
+
56
+ proc dumpHook*(s: var string , v: NbBlock) =
57
+ s.add v.dump()
58
+
59
+
24
60
# themes.nim
25
61
import std / strutils
26
62
@@ -30,16 +66,16 @@ func nbDocToHtml*(blk: NbBlock, nb: Nb): string =
30
66
for b in blk.blocks:
31
67
blocks.add nb.render(b)
32
68
"<!DOCTYPE html>\n<html><head></head>\n<body>\n" & blocks.join("\n") & "\n</body>\n</html>"
33
-
69
+ addNbBlockToJson(NbDoc)
34
70
35
71
# nimib.nim
36
72
import markdown
37
73
38
74
template nbInit* =
39
75
var nb {. inject .}: Nb
40
- nb.doc = NbDoc()
41
- nb.doc.kind = "NbDoc"
42
- nbInitBackend
76
+ nb.doc = NbDoc(kind: "NbDoc" )
77
+ nbToHtml.funcs[ "NbDoc " ] = nbDocToHtml
78
+ nb.backend = nbToHtml
43
79
44
80
template nbSave* =
45
81
echo nb.render nb.doc
@@ -56,6 +92,8 @@ func nbTextToHtml*(blk: NbBlock, nb: Nb): string =
56
92
let blk = blk.NbText
57
93
{.cast(noSideEffect).}: # not sure why markdown is marked with side effects
58
94
markdown(blk.text, config= initGfmConfig())
95
+ nbToHtml.funcs[" NbText" ] = nbTextToHtml
96
+ addNbBlockToJson(NbText)
59
97
#[ the above could be shortened with sugar to:
60
98
newNbBlock(nbText):
61
99
text: string
@@ -65,7 +103,6 @@ newNbBlock(nbText):
65
103
]#
66
104
67
105
68
-
69
106
type
70
107
NbImage = ref object of NbBlock
71
108
url: string
@@ -75,37 +112,41 @@ template nbImage*(turl: string) =
75
112
func nbImageToHtml* (blk: NbBlock, nb: Nb): string =
76
113
let blk = blk.NbImage
77
114
" <img src= '" & blk.url & " '>"
115
+ nbToHtml.funcs[" NbImage" ] = nbImageToHtml
116
+ addNbBlockToJson(NbImage)
78
117
#[ the above could be shortened with sugar to:
79
118
newNbBlock(nbImage):
80
119
url: string
81
120
toHtml:
82
121
"<img src= '" & blk.url & "'>"
83
122
]#
84
123
85
-
86
-
87
- template addToBackend*(kind: string , f: NbRenderFunc) =
88
- nb.backend.funcs[kind] = f
89
-
90
- template nbInitBackend* =
91
- addToBackend("NbImage", nbImageToHtml)
92
- addToBackend("NbText", nbTextToHtml)
93
- addToBackend("NbDoc", nbDocToHtml)
94
-
95
124
when isMainModule :
96
125
import print
97
- # hello.nim
98
126
nbInit
99
127
nbText: " *hi*"
100
128
nbImage(" img.png" )
101
129
nbSave
102
-
103
- print nb
104
- print nb.doc.blocks[ 0]
105
- print nb.doc.blocks[0 ].NbText
106
- print nb.render nb.doc.blocks[0 ]
107
- # print nb.blocks[0].NbImage # correctly fails at runtime
108
- print nb.doc.blocks[1 ].NbImage
109
- print nb.render nb.doc.blocks[1 ]
110
-
111
- print nb.render nb.doc
130
+ #[
131
+ <!DOCTYPE html>
132
+ <html><head></head>
133
+ <body>
134
+ <p><em>hi</em></p>
135
+
136
+ <img src= 'img.png'>
137
+ </body>
138
+ </html>
139
+ ]#
140
+
141
+ let docToJson = nb.doc.toJson()
142
+ let docFromJson = docToJson.fromJson(NbDoc)
143
+ print docToJson
144
+ print docFromJson
145
+ print docFromJson.blocks[0 ].NbText
146
+ print docFromJson.blocks[1 ].NbImage
147
+ #[
148
+ docToJson="{"blocks":[{"text":"*hi*","kind":"NbText"},{"url":"img.png","kind":"NbImage"}],"kind":"NbDoc"}"
149
+ docFromJson=NbDoc:ObjectType(blocks: @[NbBlock:ObjectType(kind: "NbText"), NbBlock:ObjectType(kind: "NbImage")], kind: "NbDoc")
150
+ docFromJson.blocks[0].NbText=NbText:ObjectType(text: "*hi*", kind: "NbText")
151
+ docFromJson.blocks[1].NbImage=NbImage:ObjectType(url: "img.png", kind: "NbImage")
152
+ ]#
0 commit comments