1use libc::c_void;
3
4use std::ptr;
5
6use buffer::Buffer;
7use ffi::{
8 hoedown_buffer,
9 hoedown_renderer,
10 hoedown_html_renderer_new,
11 hoedown_html_toc_renderer_new,
12 hoedown_html_smartypants,
13 hoedown_html_renderer_free
14};
15
16use super::Render;
17
18pub fn smartypants(content: &Buffer, output: &mut Buffer) {
22 let content: &hoedown_buffer = content.as_ref();
23
24 unsafe {
25 hoedown_html_smartypants(
26 output.as_mut(),
27 content.data,
28 content.size);
29 }
30}
31
32bitflags! {
34 pub flags Flags: u32 {
36 const SKIP_HTML = 1 << 0,
38
39 const ESCAPE = 1 << 1,
41
42 const HARD_WRAP = 1 << 2,
44
45 const USE_XHTML = 1 << 3,
47 }
48}
49
50pub struct Html {
69 renderer: *mut hoedown_renderer,
70}
71
72impl Html {
73 pub fn new(flags: Flags, nesting_level: i32) -> Html {
85 let renderer = unsafe {
86 hoedown_html_renderer_new(flags.bits(), nesting_level)
87 };
88
89 Html {
90 renderer: renderer,
91 }
92 }
93
94 pub fn toc(nesting_level: i32) -> Html {
102 let renderer = unsafe {
103 hoedown_html_toc_renderer_new(nesting_level)
104 };
105
106 Html {
107 renderer: renderer,
108 }
109 }
110
111 pub fn get(&self) -> &hoedown_renderer {
114 unsafe { &*self.renderer }
115 }
116
117 pub fn as_mut(&mut self) -> &mut hoedown_renderer {
119 unsafe { &mut *self.renderer }
120 }
121}
122
123impl Render for Html {
124 unsafe fn to_hoedown(&mut self) -> hoedown_renderer {
125 *self.renderer
126 }
127
128 fn code_block(&mut self, ob: &mut Buffer, text: Option<&Buffer>, lang: Option<&Buffer>) {
129 let data = self.renderer as *mut c_void;
130
131 if let Some(func) = unsafe { (*self.renderer).blockcode } {
132 func(ob.as_mut(),
133 text.map_or(ptr::null(), |t| t.as_ref()),
134 lang.map_or(ptr::null(), |l| l.as_ref()), data)
135 }
136 }
137
138 fn quote_block(&mut self, ob: &mut Buffer, content: Option<&Buffer>) {
139 let data = self.renderer as *mut c_void;
140
141 if let Some(func) = unsafe { (*self.renderer).blockquote } {
142 func(ob.as_mut(), content.map_or(ptr::null(), |b| b.as_ref()), data)
143 }
144 }
145
146 fn header(&mut self, ob: &mut Buffer, content: Option<&Buffer>, level: i32) {
147 let data = self.renderer as *mut c_void;
148
149 if let Some(func) = unsafe { (*self.renderer).header } {
150 func(ob.as_mut(), content.map_or(ptr::null(), |b| b.as_ref()), level, data)
151 }
152 }
153
154 fn horizontal_rule(&mut self, ob: &mut Buffer) {
155 let data = self.renderer as *mut c_void;
156
157 if let Some(func) = unsafe { (*self.renderer).hrule } {
158 func(ob.as_mut(), data)
159 }
160 }
161
162 fn list(&mut self, ob: &mut Buffer, content: Option<&Buffer>, flags: ::renderer::list::List) {
163 let data = self.renderer as *mut c_void;
164
165 if let Some(func) = unsafe { (*self.renderer).list } {
166 func(ob.as_mut(), content.map_or(ptr::null(), |b| b.as_ref()), flags.bits(), data)
167 }
168 }
169
170 fn list_item(&mut self, ob: &mut Buffer, content: Option<&Buffer>, flags: ::renderer::list::List) {
171 let data = self.renderer as *mut c_void;
172
173 if let Some(func) = unsafe { (*self.renderer).listitem } {
174 func(ob.as_mut(), content.map_or(ptr::null(), |b| b.as_ref()), flags.bits(), data)
175 }
176 }
177
178 fn paragraph(&mut self, ob: &mut Buffer, content: Option<&Buffer>) {
179 let data = self.renderer as *mut c_void;
180
181 if let Some(func) = unsafe { (*self.renderer).paragraph } {
182 func(ob.as_mut(), content.map_or(ptr::null(), |b| b.as_ref()), data)
183 }
184 }
185
186 fn table(&mut self, ob: &mut Buffer, content: Option<&Buffer>) {
187 let data = self.renderer as *mut c_void;
188
189 if let Some(func) = unsafe { (*self.renderer).table } {
190 func(ob.as_mut(), content.map_or(ptr::null(), |b| b.as_ref()), data)
191 }
192 }
193
194 fn table_header(&mut self, ob: &mut Buffer, content: Option<&Buffer>) {
195 let data = self.renderer as *mut c_void;
196
197 if let Some(func) = unsafe { (*self.renderer).table_header } {
198 func(ob.as_mut(), content.map_or(ptr::null(), |b| b.as_ref()), data)
199 }
200 }
201
202 fn table_body(&mut self, ob: &mut Buffer, content: Option<&Buffer>) {
203 let data = self.renderer as *mut c_void;
204
205 if let Some(func) = unsafe { (*self.renderer).table_body } {
206 func(ob.as_mut(), content.map_or(ptr::null(), |b| b.as_ref()), data)
207 }
208 }
209
210 fn table_row(&mut self, ob: &mut Buffer, content: Option<&Buffer>) {
211 let data = self.renderer as *mut c_void;
212
213 if let Some(func) = unsafe { (*self.renderer).table_row } {
214 func(ob.as_mut(), content.map_or(ptr::null(), |b| b.as_ref()), data)
215 }
216 }
217
218 fn table_cell(&mut self, ob: &mut Buffer, content: Option<&Buffer>, flags: ::renderer::Table) {
219 let data = self.renderer as *mut c_void;
220
221 if let Some(func) = unsafe { (*self.renderer).table_cell } {
222 func(ob.as_mut(), content.map_or(ptr::null(), |b| b.as_ref()), flags, data)
223 }
224 }
225
226 fn footnotes(&mut self, ob: &mut Buffer, content: Option<&Buffer>) {
227 let data = self.renderer as *mut c_void;
228
229 if let Some(func) = unsafe { (*self.renderer).footnotes } {
230 func(ob.as_mut(), content.map_or(ptr::null(), |b| b.as_ref()), data)
231 }
232 }
233
234 fn footnote_definition(&mut self, ob: &mut Buffer, content: Option<&Buffer>, num: u32) {
235 let data = self.renderer as *mut c_void;
236
237 if let Some(func) = unsafe { (*self.renderer).footnote_def } {
238 func(ob.as_mut(), content.map_or(ptr::null(), |b| b.as_ref()), num, data)
239 }
240 }
241
242 fn html_block(&mut self, ob: &mut Buffer, text: Option<&Buffer>) {
243 let data = self.renderer as *mut c_void;
244
245 if let Some(func) = unsafe { (*self.renderer).blockhtml } {
246 func(ob.as_mut(), text.map_or(ptr::null(), |b| b.as_ref()), data)
247 }
248 }
249
250 fn autolink(&mut self, ob: &mut Buffer, link: Option<&Buffer>, ty: ::renderer::AutoLink) -> bool {
251 let data = self.renderer as *mut c_void;
252
253 if let Some(func) = unsafe { (*self.renderer).autolink } {
254 func(ob.as_mut(), link.map_or(ptr::null(), |b| b.as_ref()), ty, data) != 0
255 } else {
256 false
257 }
258 }
259
260 fn code_span(&mut self, ob: &mut Buffer, text: Option<&Buffer>) -> bool {
261 let data = self.renderer as *mut c_void;
262
263 if let Some(func) = unsafe { (*self.renderer).codespan } {
264 func(ob.as_mut(), text.map_or(ptr::null(), |b| b.as_ref()), data) != 0
265 } else {
266 false
267 }
268 }
269
270 fn double_emphasis(&mut self, ob: &mut Buffer, content: Option<&Buffer>) -> bool {
271 let data = self.renderer as *mut c_void;
272
273 if let Some(func) = unsafe { (*self.renderer).double_emphasis } {
274 func(ob.as_mut(), content.map_or(ptr::null(), |b| b.as_ref()), data) != 0
275 } else {
276 false
277 }
278 }
279
280 fn emphasis(&mut self, ob: &mut Buffer, content: Option<&Buffer>) -> bool {
281 let data = self.renderer as *mut c_void;
282
283 if let Some(func) = unsafe { (*self.renderer).emphasis } {
284 func(ob.as_mut(), content.map_or(ptr::null(), |b| b.as_ref()), data) != 0
285 } else {
286 false
287 }
288 }
289
290 fn underline(&mut self, ob: &mut Buffer, content: Option<&Buffer>) -> bool {
291 let data = self.renderer as *mut c_void;
292
293 if let Some(func) = unsafe { (*self.renderer).underline } {
294 func(ob.as_mut(), content.map_or(ptr::null(), |b| b.as_ref()), data) != 0
295 } else {
296 false
297 }
298 }
299
300 fn highlight(&mut self, ob: &mut Buffer, content: Option<&Buffer>) -> bool {
301 let data = self.renderer as *mut c_void;
302
303 if let Some(func) = unsafe { (*self.renderer).highlight } {
304 func(ob.as_mut(), content.map_or(ptr::null(), |b| b.as_ref()), data) != 0
305 } else {
306 false
307 }
308 }
309
310 fn quote_span(&mut self, ob: &mut Buffer, content: Option<&Buffer>) -> bool {
311 let data = self.renderer as *mut c_void;
312
313 if let Some(func) = unsafe { (*self.renderer).quote } {
314 func(ob.as_mut(), content.map_or(ptr::null(), |b| b.as_ref()), data) != 0
315 } else {
316 false
317 }
318 }
319
320 fn image(&mut self, ob: &mut Buffer, link: Option<&Buffer>, title: Option<&Buffer>, alt: Option<&Buffer>) -> bool {
321 let data = self.renderer as *mut c_void;
322
323 if let Some(func) = unsafe { (*self.renderer).image } {
324 func(ob.as_mut(),
325 link.map_or(ptr::null(), |b| b.as_ref()),
326 title.map_or(ptr::null(), |b| b.as_ref()),
327 alt.map_or(ptr::null(), |b| b.as_ref()),
328 data) != 0
329 } else {
330 false
331 }
332 }
333
334 fn line_break(&mut self, ob: &mut Buffer) -> bool {
335 let data = self.renderer as *mut c_void;
336
337 if let Some(func) = unsafe { (*self.renderer).linebreak } {
338 func(ob.as_mut(), data) != 0
339 } else {
340 false
341 }
342 }
343
344 fn link(&mut self, ob: &mut Buffer, content: Option<&Buffer>, link: Option<&Buffer>, title: Option<&Buffer>) -> bool {
345 let data = self.renderer as *mut c_void;
346
347 if let Some(func) = unsafe { (*self.renderer).link } {
348 func(ob.as_mut(),
349 content.map_or(ptr::null(), |b| b.as_ref()),
350 link.map_or(ptr::null(), |b| b.as_ref()),
351 title.map_or(ptr::null(), |b| b.as_ref()),
352 data) != 0
353 } else {
354 false
355 }
356 }
357
358 fn triple_emphasis(&mut self, ob: &mut Buffer, content: Option<&Buffer>) -> bool {
359 let data = self.renderer as *mut c_void;
360
361 if let Some(func) = unsafe { (*self.renderer).triple_emphasis } {
362 func(ob.as_mut(), content.map_or(ptr::null(), |b| b.as_ref()), data) != 0
363 } else {
364 false
365 }
366 }
367
368 fn strikethrough(&mut self, ob: &mut Buffer, content: Option<&Buffer>) -> bool {
369 let data = self.renderer as *mut c_void;
370
371 if let Some(func) = unsafe { (*self.renderer).strikethrough } {
372 func(ob.as_mut(), content.map_or(ptr::null(), |b| b.as_ref()), data) != 0
373 } else {
374 false
375 }
376 }
377
378 fn superscript(&mut self, ob: &mut Buffer, content: Option<&Buffer>) -> bool {
379 let data = self.renderer as *mut c_void;
380
381 if let Some(func) = unsafe { (*self.renderer).superscript } {
382 func(ob.as_mut(), content.map_or(ptr::null(), |b| b.as_ref()), data) != 0
383 } else {
384 false
385 }
386 }
387
388 fn footnote_reference(&mut self, ob: &mut Buffer, num: u32) -> bool {
389 let data = self.renderer as *mut c_void;
390
391 if let Some(func) = unsafe { (*self.renderer).footnote_ref } {
392 func(ob.as_mut(), num, data) != 0
393 } else {
394 false
395 }
396 }
397
398 fn math(&mut self, ob: &mut Buffer, text: Option<&Buffer>, displaymode: i32) -> bool {
399 let data = self.renderer as *mut c_void;
400
401 if let Some(func) = unsafe { (*self.renderer).math } {
402 func(ob.as_mut(), text.map_or(ptr::null(), |b| b.as_ref()), displaymode, data) != 0
403 } else {
404 false
405 }
406 }
407
408 fn html_span(&mut self, ob: &mut Buffer, text: Option<&Buffer>) -> bool {
409 let data = self.renderer as *mut c_void;
410
411 if let Some(func) = unsafe { (*self.renderer).raw_html } {
412 func(ob.as_mut(), text.map_or(ptr::null(), |b| b.as_ref()), data) != 0
413 } else {
414 false
415 }
416 }
417
418 fn entity(&mut self, ob: &mut Buffer, text: Option<&Buffer>) {
419 let data = self.renderer as *mut c_void;
420
421 if let Some(func) = unsafe { (*self.renderer).entity } {
422 func(ob.as_mut(), text.map_or(ptr::null(), |b| b.as_ref()), data)
423 } else {
424 text.map(|t| ob.pipe(t));
425 }
426 }
427
428 fn normal_text(&mut self, ob: &mut Buffer, text: Option<&Buffer>) {
429 let data = self.renderer as *mut c_void;
430
431 if let Some(func) = unsafe { (*self.renderer).normal_text } {
432 func(ob.as_mut(), text.map_or(ptr::null(), |b| b.as_ref()), data)
433 } else {
434 text.map(|t| ob.pipe(t));
435 }
436 }
437
438 fn before_render(&mut self, ob: &mut Buffer, inline_render: bool) {
439 let data = self.renderer as *mut c_void;
440
441 if let Some(func) = unsafe { (*self.renderer).doc_header } {
442 func(ob.as_mut(), inline_render as i32, data)
443 }
444 }
445
446 fn after_render(&mut self, ob: &mut Buffer, inline_render: bool) {
447 let data = self.renderer as *mut c_void;
448
449 if let Some(func) = unsafe { (*self.renderer).doc_footer } {
450 func(ob.as_mut(), inline_render as i32, data)
451 }
452 }
453}
454
455impl Drop for Html {
456 fn drop(&mut self) {
457 unsafe { hoedown_html_renderer_free(self.renderer); }
458 }
459}
460