1 /* j/g/down.c
2 **
3 */
4 #include "all.h"
5 #include <cmark.h>
6 #include <node.h>
7 #include <buffer.h>
8
9 static u3_noun node_to_noun(cmark_node * nod);
10
list_elems_to_noun(cmark_node * nod)11 static u3_noun list_elems_to_noun(cmark_node * nod)
12 {
13 u3_noun elems = u3_nul;
14
15 cmark_node * child;
16 for ( child = nod->last_child; child; child = child->prev ) {
17 elems = u3nc(node_to_noun(child),elems);
18 }
19
20 return elems;
21 }
22
document_to_noun(cmark_node * nod)23 static u3_noun document_to_noun(cmark_node * nod)
24 {
25 return list_elems_to_noun(nod);
26 }
27
block_quote_to_noun(cmark_node * nod)28 static u3_noun block_quote_to_noun(cmark_node * nod)
29 {
30 return u3nc(u3nc(c3__bloq,u3_nul),list_elems_to_noun(nod));
31 }
32
list_to_noun(cmark_node * nod)33 static u3_noun list_to_noun(cmark_node * nod)
34 {
35 return
36 u3nc(
37 u3nt(
38 c3__list,
39 __(nod->as.list.tight),
40 (nod->as.list.list_type == CMARK_BULLET_LIST)
41 ? nod->as.list.bullet_char /* XX convert? */
42 : u3nc(nod->as.list.start,
43 (nod->as.list.delimiter == CMARK_PERIOD_DELIM)
44 ? '.'
45 : ')')),
46 list_elems_to_noun(nod));
47 }
48
list_item_to_noun(cmark_node * nod)49 static u3_noun list_item_to_noun(cmark_node * nod)
50 {
51 return u3nc(u3nc(c3__item,u3_nul),list_elems_to_noun(nod));
52 }
53
code_block_to_noun(cmark_node * nod)54 static u3_noun code_block_to_noun(cmark_node * nod)
55 {
56 u3_atom str = u3i_string((c3_c *) nod->string_content.ptr); /* XX u3i_bytes */
57 u3_noun res =
58 u3nt(
59 c3__code,
60 nod->as.code.fenced
61 ? u3nq(
62 u3_nul,
63 nod->as.code.fence_char,
64 nod->as.code.fence_length,
65 u3i_tape((c3_c *) nod->as.code.info.ptr)
66 )
67 : u3_nul,
68 u3qe_lore(str));
69 u3z(str);
70 return res;
71 }
72
html_to_noun(cmark_node * nod)73 static u3_noun html_to_noun(cmark_node * nod)
74 {
75 u3_atom str = u3i_string((c3_c *) nod->string_content.ptr); /* XX u3i_bytes */
76 u3_noun res = u3nc(c3__html, u3qe_lore(str));
77 u3z(str);
78 return res;
79 }
80
paragraph_to_noun(cmark_node * nod)81 static u3_noun paragraph_to_noun(cmark_node * nod)
82 {
83 return u3nc(c3__para, list_elems_to_noun(nod));
84 }
85
header_to_noun(cmark_node * nod)86 static u3_noun header_to_noun(cmark_node * nod)
87 {
88 /* see also nod->as.header.setext */
89 return u3nt(c3__head, nod->as.header.level, list_elems_to_noun(nod));
90 }
91
hrule_to_noun(cmark_node * nod)92 static u3_noun hrule_to_noun(cmark_node * nod)
93 {
94 return u3nc(c3__hrul, u3_nul);
95 }
96
reference_def_to_noun(cmark_node * nod)97 static u3_noun reference_def_to_noun(cmark_node * nod)
98 {
99 return u3nc(c3__defn, u3_nul);
100 }
101
text_to_noun(cmark_node * nod)102 static u3_noun text_to_noun(cmark_node * nod)
103 {
104 return u3nc(u3_blip, u3i_tape((c3_c *) cmark_chunk_to_cstr(&nod->as.literal)));
105 }
106
softbreak_to_noun(cmark_node * nod)107 static u3_noun softbreak_to_noun(cmark_node * nod) // XXX
108 {
109 return u3nt(0, 10, 0);
110 }
111
linebreak_to_noun(cmark_node * nod)112 static u3_noun linebreak_to_noun(cmark_node * nod)
113 {
114 return u3nc(c3__line, u3_nul);
115 }
116
inline_code_to_noun(cmark_node * nod)117 static u3_noun inline_code_to_noun(cmark_node * nod)
118 {
119 return u3nc(c3__code, u3i_tape((c3_c *) cmark_chunk_to_cstr(&nod->as.literal)));
120 }
121
inline_html_to_noun(cmark_node * nod)122 static u3_noun inline_html_to_noun(cmark_node * nod) // XXX
123 {
124 return u3nc(c3__htmt, u3i_string((c3_c *) cmark_chunk_to_cstr(&nod->as.literal)));
125 }
126
emph_to_noun(cmark_node * nod)127 static u3_noun emph_to_noun(cmark_node * nod)
128 {
129 return u3nc(u3nc(c3__emph, c3n), list_elems_to_noun(nod));
130 }
131
strong_to_noun(cmark_node * nod)132 static u3_noun strong_to_noun(cmark_node * nod)
133 {
134 return u3nc(u3nc(c3__emph, c3y), list_elems_to_noun(nod));
135 }
136
link_to_noun(cmark_node * nod)137 static u3_noun link_to_noun(cmark_node * nod)
138 {
139 return u3nc(u3nt(c3__link,
140 nod->as.link.url
141 ? u3i_tape((c3_c *) nod->as.link.url)
142 : u3_nul,
143 nod->as.link.title
144 ? u3nc(u3_nul, u3i_tape((c3_c *) nod->as.link.title))
145 : u3_nul),
146 list_elems_to_noun(nod));
147 }
148
image_to_noun(cmark_node * nod)149 static u3_noun image_to_noun(cmark_node * nod)
150 {
151 return u3nc(u3nt(c3__blot,
152 u3i_tape((c3_c *) nod->as.link.url),
153 nod->as.link.title
154 ? u3nc(u3_nul, u3i_tape((c3_c *) nod->as.link.title))
155 : u3_nul),
156 list_elems_to_noun(nod));
157 }
158
node_to_noun(cmark_node * nod)159 static u3_noun node_to_noun(cmark_node * nod)
160 {
161 if (!nod) {
162 fprintf(stderr, "markdown null node");
163 return u3m_bail(c3__fail);
164 }
165 switch ( nod->type ) {
166 /* Block */
167 case CMARK_NODE_DOCUMENT: return document_to_noun(nod);
168 case CMARK_NODE_BLOCK_QUOTE: return block_quote_to_noun(nod);
169 case CMARK_NODE_LIST: return list_to_noun(nod);
170 case CMARK_NODE_LIST_ITEM: return list_item_to_noun(nod);
171 case CMARK_NODE_CODE_BLOCK: return code_block_to_noun(nod);
172 case CMARK_NODE_HTML: return html_to_noun(nod);
173 case CMARK_NODE_PARAGRAPH: return paragraph_to_noun(nod);
174 case CMARK_NODE_HEADER: return header_to_noun(nod);
175 case CMARK_NODE_HRULE: return hrule_to_noun(nod);
176 case CMARK_NODE_REFERENCE_DEF: return reference_def_to_noun(nod);
177 /* Inline */
178 case CMARK_NODE_TEXT: return text_to_noun(nod);
179 case CMARK_NODE_SOFTBREAK: return softbreak_to_noun(nod);
180 case CMARK_NODE_LINEBREAK: return linebreak_to_noun(nod);
181 case CMARK_NODE_INLINE_CODE: return inline_code_to_noun(nod);
182 case CMARK_NODE_INLINE_HTML: return inline_html_to_noun(nod);
183 case CMARK_NODE_EMPH: return emph_to_noun(nod);
184 case CMARK_NODE_STRONG: return strong_to_noun(nod);
185 case CMARK_NODE_LINK: return link_to_noun(nod);
186 case CMARK_NODE_IMAGE: return image_to_noun(nod);
187 default: fprintf(stderr, "bad markdown parsing");
188 return u3m_bail(c3__fail);
189 }
190 }
191
192 /* functions
193 */
194 u3_noun
u3qg_down(u3_atom a)195 u3qg_down(u3_atom a)
196 {
197 c3_c *tex = u3r_string(a);
198
199 /* XX better strlen */
200 cmark_node * doc = cmark_parse_document(tex, strlen(tex));
201
202 u3_noun res = document_to_noun(doc);
203
204 cmark_node_free(doc);
205 // free out, tex?
206 return res;
207 }
208 u3_noun
u3wg_down(u3_noun cor)209 u3wg_down(u3_noun cor)
210 {
211 u3_noun a;
212
213 if ( (u3_none == (a = u3r_at(u3x_sam, cor))) ||
214 (c3n == u3ud(a)) )
215 {
216 return u3m_bail(c3__exit);
217 } else {
218 return u3qg_down(a);
219 }
220 }
221