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