libcmark_sys/
lib.rs

1#![allow(non_camel_case_types)]
2
3extern crate libc;
4
5use libc::{c_int, c_char, c_void, size_t};
6
7pub use cmark_node_type::*;
8pub use cmark_list_type::*;
9pub use cmark_delim_type::*;
10pub use cmark_event_type::*;
11
12#[repr(C)]
13#[derive(Copy, Clone, PartialEq, Eq)]
14pub enum cmark_node_type {
15    // Error status
16    CMARK_NODE_NONE,
17
18    // Block
19    CMARK_NODE_DOCUMENT,
20    CMARK_NODE_BLOCK_QUOTE,
21    CMARK_NODE_LIST,
22    CMARK_NODE_ITEM,
23    CMARK_NODE_CODE_BLOCK,
24	  CMARK_NODE_HTML,
25	  CMARK_NODE_PARAGRAPH,
26	  CMARK_NODE_HEADER,
27	  CMARK_NODE_HRULE,
28
29    // CMARK_NODE_FIRST_BLOCK = CMARK_NODE_DOCUMENT,
30    // CMARK_NODE_LAST_BLOCK = CMARK_NODE_HRULE,
31
32    // Inline
33    CMARK_NODE_TEXT,
34    CMARK_NODE_SOFTBREAK,
35    CMARK_NODE_LINEBREAK,
36    CMARK_NODE_CODE,
37    CMARK_NODE_INLINE_HTML,
38    CMARK_NODE_EMPH,
39    CMARK_NODE_STRONG,
40    CMARK_NODE_LINK,
41    CMARK_NODE_IMAGE,
42
43    // CMARK_NODE_FIRST_INLINE = CMARK_NODE_TEXT,
44    // CMARK_NODE_LAST_INLINE = CMARK_NODE_IMAGE,
45}
46
47#[repr(C)]
48#[derive(Copy, Clone, PartialEq, Eq)]
49pub enum cmark_list_type {
50    CMARK_NO_LIST,
51    CMARK_BULLET_LIST,
52    CMARK_ORDERED_LIST,
53}
54
55#[repr(C)]
56#[derive(Copy, Clone, PartialEq, Eq)]
57pub enum cmark_delim_type {
58    CMARK_NO_DELIM,
59    CMARK_PERIOD_DELIM,
60    CMARK_PAREN_DELIM,
61}
62
63#[repr(C)]
64#[derive(Copy, Clone, PartialEq, Eq)]
65pub enum cmark_event_type {
66    CMARK_EVENT_NONE,
67    CMARK_EVENT_DONE,
68    CMARK_EVENT_ENTER,
69    CMARK_EVENT_EXIT,
70}
71
72pub enum cmark_node {}
73pub enum cmark_parser {}
74pub enum cmark_iter {}
75
76pub const CMARK_OPT_DEFAULT: c_int = 0;
77pub const CMARK_OPT_SOURCEPOS: c_int = 1;
78pub const CMARK_OPT_HARDBREAKS: c_int = 2;
79pub const CMARK_OPT_NORMALIZE: c_int = 4;
80pub const CMARK_OPT_SMART: c_int = 8;
81
82extern {
83    // Basic API
84    pub fn cmark_markdown_to_html(text: *const c_char, len: c_int, options: c_int) -> *mut c_char;
85
86    // Node operations
87    pub fn cmark_node_new(node_type: cmark_node_type) -> *mut cmark_node;
88    pub fn cmark_node_free(node: *mut cmark_node);
89
90    // Tree traversal
91    pub fn cmark_node_next(node: *const cmark_node) -> *mut cmark_node;
92    pub fn cmark_node_previous(node: *const cmark_node) -> *mut cmark_node;
93    pub fn cmark_node_parent(node: *const cmark_node) -> *mut cmark_node;
94    pub fn cmark_node_first_child(node: *const cmark_node) -> *mut cmark_node;
95    pub fn cmark_node_last_child(node: *const cmark_node) -> *mut cmark_node;
96
97    // Iterator
98    pub fn cmark_iter_new(root: *const cmark_node) -> *mut cmark_iter;
99    pub fn cmark_iter_free(iter: *mut cmark_iter);
100    pub fn cmark_iter_next(iter: *mut cmark_iter) -> cmark_event_type;
101    pub fn cmark_iter_get_node(iter: *const cmark_iter) -> *mut cmark_node;
102    pub fn cmark_iter_get_event_type(iter: *const cmark_iter) -> cmark_event_type;
103    pub fn cmark_iter_get_root(iter: *const cmark_iter) -> *mut cmark_node;
104    pub fn cmark_iter_reset(iter: *mut cmark_iter, current: *const cmark_node, event_type: cmark_event_type);
105
106    // Accessors
107    pub fn cmark_node_get_user_data(node: *const cmark_node) -> *const c_void;
108    pub fn cmark_node_set_user_data(node: *mut cmark_node, user_data: *const c_void) -> c_int;
109    pub fn cmark_node_get_type(node: *const cmark_node) -> cmark_node_type;
110    pub fn cmark_node_get_type_string(node: *const cmark_node) -> *const c_char;
111    pub fn cmark_node_get_literal(node: *const cmark_node) -> *const c_char;
112    pub fn cmark_node_set_literal(node: *mut cmark_node, content: *const c_char) -> c_int;
113    pub fn cmark_node_get_header_level(node: *const cmark_node) -> c_int;
114    pub fn cmark_node_set_header_level(node: *mut cmark_node, level: c_int) -> c_int;
115    pub fn cmark_node_get_list_type(node: *const cmark_node) -> cmark_list_type;
116    pub fn cmark_node_set_list_type(node: *mut cmark_node, list_type: cmark_list_type) -> c_int;
117    pub fn cmark_node_get_list_delim(node: *const cmark_node) -> cmark_delim_type;
118    pub fn cmark_node_set_list_delim(node: *mut cmark_node, delim_type: cmark_delim_type) -> c_int;
119    pub fn cmark_node_get_list_start(node: *const cmark_node) -> c_int;
120    pub fn cmark_node_set_list_start(node: *mut cmark_node, start: c_int) -> c_int;
121    pub fn cmark_node_get_list_tight(node: *const cmark_node) -> c_int;
122    pub fn cmark_node_set_list_tight(node: *mut cmark_node, tight: c_int) -> c_int;
123    pub fn cmark_node_get_fence_info(node: *const cmark_node) -> *const c_char;
124    pub fn cmark_node_set_fence_info(node: *mut cmark_node, info: *const c_char) -> c_int;
125    pub fn cmark_node_get_url(node: *const cmark_node) -> *const c_char;
126    pub fn cmark_node_set_url(node: *mut cmark_node, url: *const c_char) -> c_int;
127    pub fn cmark_node_get_title(node: *const cmark_node) -> *const c_char;
128    pub fn cmark_node_set_title(node: *mut cmark_node, title: *const c_char) -> c_int;
129    pub fn cmark_node_get_start_line(node: *const cmark_node) -> c_int;
130    pub fn cmark_node_get_start_column(node: *const cmark_node) -> c_int;
131    pub fn cmark_node_get_end_line(node: *const cmark_node) -> c_int;
132    pub fn cmark_node_get_end_column(node: *const cmark_node) -> c_int;
133
134    // Tree manipulation
135    pub fn cmark_node_unlink(node: *mut cmark_node);
136    pub fn cmark_node_insert_before(node: *mut cmark_node, sibling: *mut cmark_node) -> c_int;
137    pub fn cmark_node_insert_after(node: *mut cmark_node, sibling: *mut cmark_node) -> c_int;
138    pub fn cmark_node_prepend_child(node: *mut cmark_node, child: *mut cmark_node) -> c_int;
139    pub fn cmark_node_append_child(node: *mut cmark_node, child: *mut cmark_node) -> c_int;
140    pub fn cmark_consolidate_text_nodes(root: *mut cmark_node);
141
142    // Parsing
143    pub fn cmark_parser_new(options: c_int) -> *mut cmark_parser;
144    pub fn cmark_parser_free(parser: *mut cmark_parser);
145    pub fn cmark_parser_feed(parser: *mut cmark_parser, buffer: *const c_char, len: size_t);
146    pub fn cmark_parser_finish(parser: *mut cmark_parser) -> *mut cmark_node;
147    pub fn cmark_parse_document(buffer: *const c_char, len: size_t, options: c_int) -> *mut cmark_node;
148
149    // Rendering
150    pub fn cmark_render_xml(root: *const cmark_node, options: c_int) -> *mut c_char;
151    pub fn cmark_render_html(root: *const cmark_node, options: c_int) -> *mut c_char;
152    pub fn cmark_render_man(root: *const cmark_node, options: c_int) -> *mut c_char;
153    pub fn cmark_render_commonmark(root: *const cmark_node, options: c_int, width: c_int) -> *mut c_char;
154
155    // Version information
156    pub static cmark_version: c_int;
157    pub static cmark_version_string: *const c_char;
158}
159
160#[cfg(test)]
161mod test {
162    use super::*;
163    use std::ffi::{CString, CStr};
164    use std::str;
165    use libc::c_int;
166
167    #[test]
168    fn basic_api() {
169        let source = CString::new("**This** is _CommonMark_").unwrap();
170        unsafe {
171            let html = CStr::from_ptr(cmark_markdown_to_html(source.as_ptr(), source.as_bytes().len() as c_int, 0));
172            let html_buf = html.to_bytes();
173            let html_str = str::from_utf8(html_buf).unwrap();
174            assert!(html_str == "<p><strong>This</strong> is <em>CommonMark</em></p>\n");
175        }
176    }
177}