Use clang-format, llvm style, for formatting.

* Reformatted all source files.
* Added 'format' target to Makefile.
* Removed 'astyle' target.
* Updated .editorconfig.
This commit is contained in:
John MacFarlane 2015-07-27 21:35:54 -07:00
parent aca7161e53
commit 62cb38bf8a
35 changed files with 32856 additions and 26708 deletions

View File

@ -9,8 +9,8 @@ insert_final_newline = true
[*.{c,h}]
trim_trailing_whitespace = true
indent_style = tab
indent_size = 8
indent_style = space
indent_size = 2
[Makefile]
trim_trailing_whitespace = true

View File

@ -20,7 +20,7 @@ RELEASE?=CommonMark-$(VERSION)
INSTALL_PREFIX?=/usr/local
CLANG_CHECK?=clang-check
.PHONY: all cmake_build spec leakcheck clean fuzztest dingus upload test update-site upload-site debug ubsan asan mingw archive bench astyle update-spec afl clang-check
.PHONY: all cmake_build spec leakcheck clean fuzztest dingus upload test update-site upload-site debug ubsan asan mingw archive bench format update-spec afl clang-check
all: cmake_build man/man3/cmark.3
@ -115,6 +115,7 @@ $(SRCDIR)/scanners.c: $(SRCDIR)/scanners.re
esac
re2c --case-insensitive -b -i --no-generation-date -8 \
--encoding-policy substitute -o $@ $<
clang-format -style llvm -i $@
# We include entities.inc in the repository, so normally this
# doesn't need to be regenerated:
@ -167,9 +168,8 @@ bench: $(BENCHFILE)
done \
} 2>&1 | grep 'real' | awk '{print $$2}' | python3 'bench/stats.py'
astyle:
astyle --style=linux -t -p -r 'src/*.c' --exclude=scanners.c
astyle --style=linux -t -p -r 'src/*.h' --exclude=html_unescape.h
format:
clang-format -style llvm -i src/*.c src/*.h
operf: $(CMARK)
operf $< < $(BENCHINP) > /dev/null

View File

@ -1,4 +1,4 @@
.TH cmark 3 "July 13, 2015" "LOCAL" "Library Functions Manual"
.TH cmark 3 "July 27, 2015" "LOCAL" "Library Functions Manual"
.SH
NAME
.PP
@ -24,7 +24,7 @@ Node Structure
Creating and Destroying Nodes
.PP
\fIcmark_node*\f[] \fBcmark_node_new\f[](\fIcmark_node_type type\f[])
\fIcmark_node *\f[] \fBcmark_node_new\f[](\fIcmark_node_type type\f[])
.PP
Creates a new node of type \f[I]type\f[]. Note that the node may have
@ -41,34 +41,34 @@ Frees the memory allocated for a node.
Tree Traversal
.PP
\fIcmark_node*\f[] \fBcmark_node_next\f[](\fIcmark_node *node\f[])
\fIcmark_node *\f[] \fBcmark_node_next\f[](\fIcmark_node *node\f[])
.PP
Returns the next node in the sequence after \f[I]node\f[], or NULL if
there is none.
.PP
\fIcmark_node*\f[] \fBcmark_node_previous\f[](\fIcmark_node *node\f[])
\fIcmark_node *\f[] \fBcmark_node_previous\f[](\fIcmark_node *node\f[])
.PP
Returns the previous node in the sequence after \f[I]node\f[], or NULL
if there is none.
.PP
\fIcmark_node*\f[] \fBcmark_node_parent\f[](\fIcmark_node *node\f[])
\fIcmark_node *\f[] \fBcmark_node_parent\f[](\fIcmark_node *node\f[])
.PP
Returns the parent of \f[I]node\f[], or NULL if there is none.
.PP
\fIcmark_node*\f[] \fBcmark_node_first_child\f[](\fIcmark_node *node\f[])
\fIcmark_node *\f[] \fBcmark_node_first_child\f[](\fIcmark_node *node\f[])
.PP
Returns the first child of \f[I]node\f[], or NULL if \f[I]node\f[] has
no children.
.PP
\fIcmark_node*\f[] \fBcmark_node_last_child\f[](\fIcmark_node *node\f[])
\fIcmark_node *\f[] \fBcmark_node_last_child\f[](\fIcmark_node *node\f[])
.PP
Returns the last child of \f[I]node\f[], or NULL if \f[I]node\f[] has no
@ -130,7 +130,7 @@ Nodes must only be modified after an \f[C]EXIT\f[] event, or an
\f[C]ENTER\f[] event for leaf nodes.
.PP
\fIcmark_iter*\f[] \fBcmark_iter_new\f[](\fIcmark_node *root\f[])
\fIcmark_iter *\f[] \fBcmark_iter_new\f[](\fIcmark_node *root\f[])
.PP
Creates a new iterator starting at \f[I]root\f[]. The current node and
@ -152,7 +152,7 @@ Advances to the next node and returns the event type
\f[C]CMARK_EVENT_DONE\f[]).
.PP
\fIcmark_node*\f[] \fBcmark_iter_get_node\f[](\fIcmark_iter *iter\f[])
\fIcmark_node *\f[] \fBcmark_iter_get_node\f[](\fIcmark_iter *iter\f[])
.PP
Returns the current node.
@ -164,7 +164,7 @@ Returns the current node.
Returns the current event type.
.PP
\fIcmark_node*\f[] \fBcmark_iter_get_root\f[](\fIcmark_iter *iter\f[])
\fIcmark_node *\f[] \fBcmark_iter_get_root\f[](\fIcmark_iter *iter\f[])
.PP
Returns the root node.
@ -181,7 +181,7 @@ descendant of the root node or the root node itself.
Accessors
.PP
\fIvoid*\f[] \fBcmark_node_get_user_data\f[](\fIcmark_node *node\f[])
\fIvoid *\f[] \fBcmark_node_get_user_data\f[](\fIcmark_node *node\f[])
.PP
Returns the user data of \f[I]node\f[].
@ -200,14 +200,14 @@ failure.
Returns the type of \f[I]node\f[], or \f[C]CMARK_NODE_NONE\f[] on error.
.PP
\fIconst char*\f[] \fBcmark_node_get_type_string\f[](\fIcmark_node *node\f[])
\fIconst char *\f[] \fBcmark_node_get_type_string\f[](\fIcmark_node *node\f[])
.PP
Like \f[I]cmark_node_get_type\f[], but returns a string representation
of the type, or \f[C]"<unknown>"\f[].
.PP
\fIconst char*\f[] \fBcmark_node_get_literal\f[](\fIcmark_node *node\f[])
\fIconst char *\f[] \fBcmark_node_get_literal\f[](\fIcmark_node *node\f[])
.PP
Returns the string contents of \f[I]node\f[], or NULL if none.
@ -288,7 +288,7 @@ Returns 1 if \f[I]node\f[] is a tight list, 0 otherwise.
Sets the "tightness" of a list. Returns 1 on success, 0 on failure.
.PP
\fIconst char*\f[] \fBcmark_node_get_fence_info\f[](\fIcmark_node *node\f[])
\fIconst char *\f[] \fBcmark_node_get_fence_info\f[](\fIcmark_node *node\f[])
.PP
Returns the info string from a fenced code block, or NULL if none.
@ -301,7 +301,7 @@ Sets the info string in a fenced code block, returning 1 on success and
0 on failure.
.PP
\fIconst char*\f[] \fBcmark_node_get_url\f[](\fIcmark_node *node\f[])
\fIconst char *\f[] \fBcmark_node_get_url\f[](\fIcmark_node *node\f[])
.PP
Gets the URL of a link or image \f[I]node\f[], or NULL if none.
@ -314,7 +314,7 @@ Sets the URL of a link or image \f[I]node\f[]. Returns 1 on success, 0
on failure.
.PP
\fIconst char*\f[] \fBcmark_node_get_title\f[](\fIcmark_node *node\f[])
\fIconst char *\f[] \fBcmark_node_get_title\f[](\fIcmark_node *node\f[])
.PP
Gets the title of a link or image \f[I]node\f[], or NULL if none.

View File

@ -11,12 +11,12 @@ float _cmark_save_time;
#define start_timer() \
_cmark_save_time = _cmark_start_time; \
_cmark_start_time = (float)clock()/CLOCKS_PER_SEC
_cmark_start_time = (float)clock() / CLOCKS_PER_SEC
#define end_timer(M) \
_cmark_end_time = (float)clock()/CLOCKS_PER_SEC; \
fprintf(stderr, "[TIME] (%s:%d) %4.f ns " M "\n", __FILE__, \
__LINE__, (_cmark_end_time - _cmark_start_time) * 1000000); \
_cmark_end_time = (float)clock() / CLOCKS_PER_SEC; \
fprintf(stderr, "[TIME] (%s:%d) %4.f ns " M "\n", __FILE__, __LINE__, \
(_cmark_end_time - _cmark_start_time) * 1000000); \
_cmark_start_time = _cmark_save_time;
#else

View File

@ -19,26 +19,22 @@
#define peek_at(i, n) (i)->data[n]
static inline bool
S_is_line_end_char(char c)
{
static inline bool S_is_line_end_char(char c) {
return (c == '\n' || c == '\r');
}
static void
S_parser_feed(cmark_parser *parser, const unsigned char *buffer, size_t len,
bool eof);
static void S_parser_feed(cmark_parser *parser, const unsigned char *buffer,
size_t len, bool eof);
static void
S_process_line(cmark_parser *parser, const unsigned char *buffer,
static void S_process_line(cmark_parser *parser, const unsigned char *buffer,
bufsize_t bytes);
static cmark_node* make_block(cmark_node_type tag, int start_line, int start_column)
{
cmark_node* e;
static cmark_node *make_block(cmark_node_type tag, int start_line,
int start_column) {
cmark_node *e;
e = (cmark_node *)calloc(1, sizeof(*e));
if(e != NULL) {
if (e != NULL) {
e->type = tag;
e->open = true;
e->start_line = start_line;
@ -51,18 +47,16 @@ static cmark_node* make_block(cmark_node_type tag, int start_line, int start_col
}
// Create a root document node.
static cmark_node* make_document()
{
static cmark_node *make_document() {
cmark_node *e = make_block(NODE_DOCUMENT, 1, 1);
return e;
}
cmark_parser *cmark_parser_new(int options)
{
cmark_parser *parser = (cmark_parser*)malloc(sizeof(cmark_parser));
cmark_parser *cmark_parser_new(int options) {
cmark_parser *parser = (cmark_parser *)malloc(sizeof(cmark_parser));
cmark_node *document = make_document();
cmark_strbuf *line = (cmark_strbuf*)malloc(sizeof(cmark_strbuf));
cmark_strbuf *buf = (cmark_strbuf*)malloc(sizeof(cmark_strbuf));
cmark_strbuf *line = (cmark_strbuf *)malloc(sizeof(cmark_strbuf));
cmark_strbuf *buf = (cmark_strbuf *)malloc(sizeof(cmark_strbuf));
cmark_strbuf_init(line, 256);
cmark_strbuf_init(buf, 0);
@ -84,8 +78,7 @@ cmark_parser *cmark_parser_new(int options)
return parser;
}
void cmark_parser_free(cmark_parser *parser)
{
void cmark_parser_free(cmark_parser *parser) {
cmark_strbuf_free(parser->curline);
free(parser->curline);
cmark_strbuf_free(parser->linebuf);
@ -94,12 +87,10 @@ void cmark_parser_free(cmark_parser *parser)
free(parser);
}
static cmark_node*
finalize(cmark_parser *parser, cmark_node* b);
static cmark_node *finalize(cmark_parser *parser, cmark_node *b);
// Returns true if line has only space characters, else false.
static bool is_blank(cmark_strbuf *s, bufsize_t offset)
{
static bool is_blank(cmark_strbuf *s, bufsize_t offset) {
while (offset < s->size) {
switch (s->ptr[offset]) {
case '\r':
@ -119,29 +110,24 @@ static bool is_blank(cmark_strbuf *s, bufsize_t offset)
return true;
}
static inline bool can_contain(cmark_node_type parent_type, cmark_node_type child_type)
{
return ( parent_type == NODE_DOCUMENT ||
parent_type == NODE_BLOCK_QUOTE ||
static inline bool can_contain(cmark_node_type parent_type,
cmark_node_type child_type) {
return (parent_type == NODE_DOCUMENT || parent_type == NODE_BLOCK_QUOTE ||
parent_type == NODE_ITEM ||
(parent_type == NODE_LIST && child_type == NODE_ITEM) );
(parent_type == NODE_LIST && child_type == NODE_ITEM));
}
static inline bool accepts_lines(cmark_node_type block_type)
{
return (block_type == NODE_PARAGRAPH ||
block_type == NODE_HEADER ||
static inline bool accepts_lines(cmark_node_type block_type) {
return (block_type == NODE_PARAGRAPH || block_type == NODE_HEADER ||
block_type == NODE_CODE_BLOCK);
}
static void add_line(cmark_node* node, cmark_chunk *ch, bufsize_t offset)
{
static void add_line(cmark_node *node, cmark_chunk *ch, bufsize_t offset) {
assert(node->open);
cmark_strbuf_put(&node->string_content, ch->data + offset, ch->len - offset);
}
static void remove_trailing_blank_lines(cmark_strbuf *ln)
{
static void remove_trailing_blank_lines(cmark_strbuf *ln) {
bufsize_t i;
unsigned char c;
@ -157,8 +143,7 @@ static void remove_trailing_blank_lines(cmark_strbuf *ln)
return;
}
for(; i < ln->size; ++i) {
for (; i < ln->size; ++i) {
c = ln->ptr[i];
if (!S_is_line_end_char(c))
@ -171,8 +156,7 @@ static void remove_trailing_blank_lines(cmark_strbuf *ln)
// Check to see if a node ends with a blank line, descending
// if needed into lists and sublists.
static bool ends_with_blank_line(cmark_node* node)
{
static bool ends_with_blank_line(cmark_node *node) {
cmark_node *cur = node;
while (cur != NULL) {
if (cur->last_line_blank) {
@ -188,8 +172,7 @@ static bool ends_with_blank_line(cmark_node* node)
}
// Break out of all containing lists
static int break_out_of_lists(cmark_parser *parser, cmark_node ** bptr)
{
static int break_out_of_lists(cmark_parser *parser, cmark_node **bptr) {
cmark_node *container = *bptr;
cmark_node *b = parser->root;
// find first containing NODE_LIST:
@ -206,14 +189,11 @@ static int break_out_of_lists(cmark_parser *parser, cmark_node ** bptr)
return 0;
}
static cmark_node*
finalize(cmark_parser *parser, cmark_node* b)
{
static cmark_node *finalize(cmark_parser *parser, cmark_node *b) {
bufsize_t pos;
cmark_node* item;
cmark_node* subitem;
cmark_node* parent;
cmark_node *item;
cmark_node *subitem;
cmark_node *parent;
parent = b->parent;
@ -241,7 +221,8 @@ finalize(cmark_parser *parser, cmark_node* b)
switch (b->type) {
case NODE_PARAGRAPH:
while (cmark_strbuf_at(&b->string_content, 0) == '[' &&
(pos = cmark_parse_reference_inline(&b->string_content, parser->refmap))) {
(pos = cmark_parse_reference_inline(&b->string_content,
parser->refmap))) {
cmark_strbuf_drop(&b->string_content, pos);
}
@ -265,11 +246,7 @@ finalize(cmark_parser *parser, cmark_node* b)
assert(pos < b->string_content.size);
cmark_strbuf tmp = GH_BUF_INIT;
houdini_unescape_html_f(
&tmp,
b->string_content.ptr,
pos
);
houdini_unescape_html_f(&tmp, b->string_content.ptr, pos);
cmark_strbuf_trim(&tmp);
cmark_strbuf_unescape(&tmp);
b->as.code.info = cmark_chunk_buf_detach(&tmp);
@ -301,8 +278,7 @@ finalize(cmark_parser *parser, cmark_node* b)
// spaces between them:
subitem = item->first_child;
while (subitem) {
if (ends_with_blank_line(subitem) &&
(item->next || subitem->next)) {
if (ends_with_blank_line(subitem) && (item->next || subitem->next)) {
b->as.list.tight = false;
break;
}
@ -323,9 +299,8 @@ finalize(cmark_parser *parser, cmark_node* b)
}
// Add a node as child of another. Return pointer to child.
static cmark_node* add_child(cmark_parser *parser, cmark_node* parent,
cmark_node_type block_type, int start_column)
{
static cmark_node *add_child(cmark_parser *parser, cmark_node *parent,
cmark_node_type block_type, int start_column) {
assert(parent);
// if 'parent' isn't the kind of node that can accept this child,
@ -334,7 +309,7 @@ static cmark_node* add_child(cmark_parser *parser, cmark_node* parent,
parent = finalize(parser, parent);
}
cmark_node* child = make_block(block_type, parser->line_number, start_column);
cmark_node *child = make_block(block_type, parser->line_number, start_column);
child->parent = parent;
if (parent->last_child) {
@ -348,11 +323,10 @@ static cmark_node* add_child(cmark_parser *parser, cmark_node* parent,
return child;
}
// Walk through node and all children, recursively, parsing
// string content into inline content where appropriate.
static void process_inlines(cmark_node* root, cmark_reference_map *refmap, int options)
{
static void process_inlines(cmark_node *root, cmark_reference_map *refmap,
int options) {
cmark_iter *iter = cmark_iter_new(root);
cmark_node *cur;
cmark_event_type ev_type;
@ -360,8 +334,7 @@ static void process_inlines(cmark_node* root, cmark_reference_map *refmap, int o
while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {
cur = cmark_iter_get_node(iter);
if (ev_type == CMARK_EVENT_ENTER) {
if (cur->type == NODE_PARAGRAPH ||
cur->type == NODE_HEADER) {
if (cur->type == NODE_PARAGRAPH || cur->type == NODE_HEADER) {
cmark_parse_inlines(cur, refmap, options);
}
}
@ -373,8 +346,8 @@ static void process_inlines(cmark_node* root, cmark_reference_map *refmap, int o
// Attempts to parse a list item marker (bullet or enumerated).
// On success, returns length of the marker, and populates
// data with the details. On failure, returns 0.
static bufsize_t parse_list_marker(cmark_chunk *input, bufsize_t pos, cmark_list **dataptr)
{
static bufsize_t parse_list_marker(cmark_chunk *input, bufsize_t pos,
cmark_list **dataptr) {
unsigned char c;
bufsize_t startpos;
cmark_list *data;
@ -388,7 +361,7 @@ static bufsize_t parse_list_marker(cmark_chunk *input, bufsize_t pos, cmark_list
return 0;
}
data = (cmark_list *)calloc(1, sizeof(*data));
if(data == NULL) {
if (data == NULL) {
return 0;
} else {
data->marker_offset = 0; // will be adjusted later
@ -418,7 +391,7 @@ static bufsize_t parse_list_marker(cmark_chunk *input, bufsize_t pos, cmark_list
return 0;
}
data = (cmark_list *)calloc(1, sizeof(*data));
if(data == NULL) {
if (data == NULL) {
return 0;
} else {
data->marker_offset = 0; // will be adjusted later
@ -441,16 +414,14 @@ static bufsize_t parse_list_marker(cmark_chunk *input, bufsize_t pos, cmark_list
}
// Return 1 if list item belongs in list, else 0.
static int lists_match(cmark_list *list_data, cmark_list *item_data)
{
static int lists_match(cmark_list *list_data, cmark_list *item_data) {
return (list_data->list_type == item_data->list_type &&
list_data->delimiter == item_data->delimiter &&
// list_data->marker_offset == item_data.marker_offset &&
list_data->bullet_char == item_data->bullet_char);
}
static cmark_node *finalize_document(cmark_parser *parser)
{
static cmark_node *finalize_document(cmark_parser *parser) {
while (parser->current != parser->root) {
parser->current = finalize(parser, parser->current);
}
@ -461,8 +432,7 @@ static cmark_node *finalize_document(cmark_parser *parser)
return parser->root;
}
cmark_node *cmark_parse_file(FILE *f, int options)
{
cmark_node *cmark_parse_file(FILE *f, int options) {
unsigned char buffer[4096];
cmark_parser *parser = cmark_parser_new(options);
size_t bytes;
@ -481,8 +451,7 @@ cmark_node *cmark_parse_file(FILE *f, int options)
return document;
}
cmark_node *cmark_parse_document(const char *buffer, size_t len, int options)
{
cmark_node *cmark_parse_document(const char *buffer, size_t len, int options) {
cmark_parser *parser = cmark_parser_new(options);
cmark_node *document;
@ -493,16 +462,12 @@ cmark_node *cmark_parse_document(const char *buffer, size_t len, int options)
return document;
}
void
cmark_parser_feed(cmark_parser *parser, const char *buffer, size_t len)
{
void cmark_parser_feed(cmark_parser *parser, const char *buffer, size_t len) {
S_parser_feed(parser, (const unsigned char *)buffer, len, false);
}
static void
S_parser_feed(cmark_parser *parser, const unsigned char *buffer, size_t len,
bool eof)
{
static void S_parser_feed(cmark_parser *parser, const unsigned char *buffer,
size_t len, bool eof) {
const unsigned char *end = buffer + len;
static const uint8_t repl[] = {239, 191, 189};
@ -531,8 +496,7 @@ S_parser_feed(cmark_parser *parser, const unsigned char *buffer, size_t len,
if (process) {
if (parser->linebuf->size > 0) {
cmark_strbuf_put(parser->linebuf, buffer, chunk_len);
S_process_line(parser, parser->linebuf->ptr,
parser->linebuf->size);
S_process_line(parser, parser->linebuf->ptr, parser->linebuf->size);
cmark_strbuf_clear(parser->linebuf);
} else {
S_process_line(parser, buffer, chunk_len);
@ -553,8 +517,7 @@ S_parser_feed(cmark_parser *parser, const unsigned char *buffer, size_t len,
}
}
static void chop_trailing_hashtags(cmark_chunk *ch)
{
static void chop_trailing_hashtags(cmark_chunk *ch) {
bufsize_t n, orig_n;
cmark_chunk_rtrim(ch);
@ -572,9 +535,7 @@ static void chop_trailing_hashtags(cmark_chunk *ch)
}
}
static void
S_find_first_nonspace(cmark_parser *parser, cmark_chunk *input)
{
static void S_find_first_nonspace(cmark_parser *parser, cmark_chunk *input) {
char c;
int chars_to_tab = TAB_STOP - (parser->column % TAB_STOP);
@ -601,9 +562,8 @@ S_find_first_nonspace(cmark_parser *parser, cmark_chunk *input)
parser->blank = S_is_line_end_char(peek_at(input, parser->first_nonspace));
}
static void
S_advance_offset(cmark_parser *parser, cmark_chunk *input, bufsize_t count, bool columns)
{
static void S_advance_offset(cmark_parser *parser, cmark_chunk *input,
bufsize_t count, bool columns) {
char c;
int chars_to_tab;
while (count > 0 && (c = peek_at(input, parser->offset))) {
@ -620,17 +580,15 @@ S_advance_offset(cmark_parser *parser, cmark_chunk *input, bufsize_t count, bool
}
}
static void
S_process_line(cmark_parser *parser, const unsigned char *buffer, bufsize_t bytes)
{
cmark_node* last_matched_container;
static void S_process_line(cmark_parser *parser, const unsigned char *buffer,
bufsize_t bytes) {
cmark_node *last_matched_container;
bufsize_t matched = 0;
int lev = 0;
int i;
cmark_list *data = NULL;
bool all_matched = true;
cmark_node* container;
cmark_node *container;
bool indented;
cmark_chunk input;
bool maybe_lazy;
@ -661,7 +619,8 @@ S_process_line(cmark_parser *parser, const unsigned char *buffer, bufsize_t byte
S_find_first_nonspace(parser, &input);
if (container->type == NODE_BLOCK_QUOTE) {
matched = parser->indent <= 3 && peek_at(&input, parser->first_nonspace) == '>';
matched =
parser->indent <= 3 && peek_at(&input, parser->first_nonspace) == '>';
if (matched) {
S_advance_offset(parser, &input, parser->indent + 1, true);
if (peek_at(&input, parser->offset) == ' ')
@ -671,11 +630,11 @@ S_process_line(cmark_parser *parser, const unsigned char *buffer, bufsize_t byte
}
} else if (container->type == NODE_ITEM) {
if (parser->indent >= container->as.list.marker_offset +
container->as.list.padding) {
S_advance_offset(parser, &input,
container->as.list.marker_offset +
container->as.list.padding, true);
if (parser->indent >=
container->as.list.marker_offset + container->as.list.padding) {
S_advance_offset(parser, &input, container->as.list.marker_offset +
container->as.list.padding,
true);
} else if (parser->blank) {
S_advance_offset(parser, &input,
parser->first_nonspace - parser->offset, false);
@ -690,18 +649,15 @@ S_process_line(cmark_parser *parser, const unsigned char *buffer, bufsize_t byte
S_advance_offset(parser, &input, CODE_INDENT, true);
} else if (parser->blank) {
S_advance_offset(parser, &input,
parser->first_nonspace - parser->offset,
false);
parser->first_nonspace - parser->offset, false);
} else {
all_matched = false;
}
} else { // fenced
matched = 0;
if (parser->indent <= 3 &&
(peek_at(&input, parser->first_nonspace) ==
if (parser->indent <= 3 && (peek_at(&input, parser->first_nonspace) ==
container->as.code.fence_char)) {
matched = scan_close_code_fence(&input,
parser->first_nonspace);
matched = scan_close_code_fence(&input, parser->first_nonspace);
}
if (matched >= container->as.code.fence_length) {
// closing fence - and since we're at
@ -713,8 +669,7 @@ S_process_line(cmark_parser *parser, const unsigned char *buffer, bufsize_t byte
} else {
// skip opt. spaces of fence parser->offset
i = container->as.code.fence_offset;
while (i > 0 &&
peek_at(&input, parser->offset) == ' ') {
while (i > 0 && peek_at(&input, parser->offset) == ' ') {
S_advance_offset(parser, &input, 1, false);
i--;
}
@ -742,10 +697,8 @@ S_process_line(cmark_parser *parser, const unsigned char *buffer, bufsize_t byte
}
break;
default:
fprintf(stderr,
"Error (%s:%d): Unknown HTML block type %d\n",
__FILE__, __LINE__,
container->as.html_block_type);
fprintf(stderr, "Error (%s:%d): Unknown HTML block type %d\n", __FILE__,
__LINE__, container->as.html_block_type);
exit(1);
}
@ -754,7 +707,6 @@ S_process_line(cmark_parser *parser, const unsigned char *buffer, bufsize_t byte
if (parser->blank) {
all_matched = false;
}
}
if (!all_matched) {
@ -772,27 +724,31 @@ S_process_line(cmark_parser *parser, const unsigned char *buffer, bufsize_t byte
maybe_lazy = parser->current->type == NODE_PARAGRAPH;
// try new container starts:
while (container->type != NODE_CODE_BLOCK &&
container->type != NODE_HTML) {
while (container->type != NODE_CODE_BLOCK && container->type != NODE_HTML) {
S_find_first_nonspace(parser, &input);
indented = parser->indent >= CODE_INDENT;
if (!indented && peek_at(&input, parser->first_nonspace) == '>') {
S_advance_offset(parser, &input, parser->first_nonspace + 1 - parser->offset, false);
S_advance_offset(parser, &input,
parser->first_nonspace + 1 - parser->offset, false);
// optional following character
if (peek_at(&input, parser->offset) == ' ')
S_advance_offset(parser, &input, 1, false);
container = add_child(parser, container, NODE_BLOCK_QUOTE, parser->offset + 1);
container =
add_child(parser, container, NODE_BLOCK_QUOTE, parser->offset + 1);
} else if (!indented && (matched = scan_atx_header_start(&input, parser->first_nonspace))) {
} else if (!indented && (matched = scan_atx_header_start(
&input, parser->first_nonspace))) {
S_advance_offset(parser, &input,
parser->first_nonspace + matched - parser->offset, false);
parser->first_nonspace + matched - parser->offset,
false);
container = add_child(parser, container, NODE_HEADER, parser->offset + 1);
bufsize_t hashpos = cmark_chunk_strchr(&input, '#', parser->first_nonspace);
bufsize_t hashpos =
cmark_chunk_strchr(&input, '#', parser->first_nonspace);
int level = 0;
while (peek_at(&input, hashpos) == '#') {
@ -802,30 +758,38 @@ S_process_line(cmark_parser *parser, const unsigned char *buffer, bufsize_t byte
container->as.header.level = level;
container->as.header.setext = false;
} else if (!indented && (matched = scan_open_code_fence(&input, parser->first_nonspace))) {
} else if (!indented && (matched = scan_open_code_fence(
&input, parser->first_nonspace))) {
container = add_child(parser, container, NODE_CODE_BLOCK, parser->first_nonspace + 1);
container = add_child(parser, container, NODE_CODE_BLOCK,
parser->first_nonspace + 1);
container->as.code.fenced = true;
container->as.code.fence_char = peek_at(&input, parser->first_nonspace);
container->as.code.fence_length = matched;
container->as.code.fence_offset = parser->first_nonspace - parser->offset;
container->as.code.info = cmark_chunk_literal("");
S_advance_offset(parser, &input, parser->first_nonspace + matched - parser->offset, false);
S_advance_offset(parser, &input,
parser->first_nonspace + matched - parser->offset,
false);
} else if (!indented &&
((matched = scan_html_block_start(&input, parser->first_nonspace)) ||
} else if (!indented && ((matched = scan_html_block_start(
&input, parser->first_nonspace)) ||
(container->type != NODE_PARAGRAPH &&
(matched = scan_html_block_start_7(&input, parser->first_nonspace))))) {
(matched = scan_html_block_start_7(
&input, parser->first_nonspace))))) {
container = add_child(parser, container, NODE_HTML, parser->first_nonspace + 1);
container =
add_child(parser, container, NODE_HTML, parser->first_nonspace + 1);
container->as.html_block_type = matched;
// note, we don't adjust parser->offset because the tag is part of the text
// note, we don't adjust parser->offset because the tag is part of the
// text
} else if (!indented &&
container->type == NODE_PARAGRAPH &&
(lev = scan_setext_header_line(&input, parser->first_nonspace)) &&
} else if (!indented && container->type == NODE_PARAGRAPH &&
(lev =
scan_setext_header_line(&input, parser->first_nonspace)) &&
// check that there is only one line in the paragraph:
(cmark_strbuf_strrchr(&container->string_content, '\n',
(cmark_strbuf_strrchr(
&container->string_content, '\n',
cmark_strbuf_len(&container->string_content) - 2) < 0)) {
container->type = NODE_HEADER;
@ -834,22 +798,25 @@ S_process_line(cmark_parser *parser, const unsigned char *buffer, bufsize_t byte
S_advance_offset(parser, &input, input.len - 1 - parser->offset, false);
} else if (!indented &&
!(container->type == NODE_PARAGRAPH &&
!all_matched) &&
!(container->type == NODE_PARAGRAPH && !all_matched) &&
(matched = scan_hrule(&input, parser->first_nonspace))) {
// it's only now that we know the line is not part of a setext header:
container = add_child(parser, container, NODE_HRULE, parser->first_nonspace + 1);
container =
add_child(parser, container, NODE_HRULE, parser->first_nonspace + 1);
container = finalize(parser, container);
S_advance_offset(parser, &input, input.len - 1 - parser->offset, false);
} else if ((matched = parse_list_marker(&input, parser->first_nonspace, &data)) &&
} else if ((matched =
parse_list_marker(&input, parser->first_nonspace, &data)) &&
(!indented || container->type == NODE_LIST)) {
// Note that we can have new list items starting with >= 4
// spaces indent, as long as the list container is still open.
// compute padding:
S_advance_offset(parser, &input, parser->first_nonspace + matched - parser->offset, false);
S_advance_offset(parser, &input,
parser->first_nonspace + matched - parser->offset,
false);
i = 0;
while (i <= 5 && peek_at(&input, parser->offset + i) == ' ') {
i++;
@ -873,22 +840,23 @@ S_process_line(cmark_parser *parser, const unsigned char *buffer, bufsize_t byte
if (container->type != NODE_LIST ||
!lists_match(&container->as.list, data)) {
container = add_child(parser, container, NODE_LIST,
parser->first_nonspace + 1);
container =
add_child(parser, container, NODE_LIST, parser->first_nonspace + 1);
memcpy(&container->as.list, data, sizeof(*data));
}
// add the list item
container = add_child(parser, container, NODE_ITEM,
parser->first_nonspace + 1);
container =
add_child(parser, container, NODE_ITEM, parser->first_nonspace + 1);
/* TODO: static */
memcpy(&container->as.list, data, sizeof(*data));
free(data);
} else if (indented && !maybe_lazy && !parser->blank) {
S_advance_offset(parser, &input, CODE_INDENT, true);
container = add_child(parser, container, NODE_CODE_BLOCK, parser->offset + 1);
container =
add_child(parser, container, NODE_CODE_BLOCK, parser->offset + 1);
container->as.code.fenced = false;
container->as.code.fence_char = 0;
container->as.code.fence_length = 0;
@ -919,13 +887,11 @@ S_process_line(cmark_parser *parser, const unsigned char *buffer, bufsize_t byte
// and we don't count blanks in fenced code for purposes of tight/loose
// lists or breaking out of lists. we also don't set last_line_blank
// on an empty list item.
container->last_line_blank = (parser->blank &&
container->type != NODE_BLOCK_QUOTE &&
container->last_line_blank =
(parser->blank && container->type != NODE_BLOCK_QUOTE &&
container->type != NODE_HEADER &&
!(container->type == NODE_CODE_BLOCK &&
container->as.code.fenced) &&
!(container->type == NODE_ITEM &&
container->first_child == NULL &&
!(container->type == NODE_CODE_BLOCK && container->as.code.fenced) &&
!(container->type == NODE_ITEM && container->first_child == NULL &&
container->start_line == parser->line_number));
cmark_node *cont = container;
@ -935,8 +901,7 @@ S_process_line(cmark_parser *parser, const unsigned char *buffer, bufsize_t byte
}
if (parser->current != last_matched_container &&
container == last_matched_container &&
!parser->blank &&
container == last_matched_container && !parser->blank &&
parser->current->type == NODE_PARAGRAPH &&
cmark_strbuf_len(&parser->current->string_content) > 0) {
@ -1009,9 +974,9 @@ S_process_line(cmark_parser *parser, const unsigned char *buffer, bufsize_t byte
} else {
// create paragraph container for line
container = add_child(parser, container, NODE_PARAGRAPH, parser->first_nonspace + 1);
container = add_child(parser, container, NODE_PARAGRAPH,
parser->first_nonspace + 1);
add_line(container, &input, parser->first_nonspace);
}
parser->current = container;
@ -1026,14 +991,11 @@ finished:
parser->last_line_length -= 1;
cmark_strbuf_clear(parser->curline);
}
cmark_node *cmark_parser_finish(cmark_parser *parser)
{
cmark_node *cmark_parser_finish(cmark_parser *parser) {
if (parser->linebuf->size) {
S_process_line(parser, parser->linebuf->ptr,
parser->linebuf->size);
S_process_line(parser, parser->linebuf->ptr, parser->linebuf->size);
cmark_strbuf_clear(parser->linebuf);
}

View File

@ -16,11 +16,10 @@
unsigned char cmark_strbuf__initbuf[1];
#ifndef MIN
#define MIN(x,y) ((x<y) ? x : y)
#define MIN(x, y) ((x < y) ? x : y)
#endif
void cmark_strbuf_init(cmark_strbuf *buf, bufsize_t initial_size)
{
void cmark_strbuf_init(cmark_strbuf *buf, bufsize_t initial_size) {
buf->asize = 0;
buf->size = 0;
buf->ptr = cmark_strbuf__initbuf;
@ -29,15 +28,12 @@ void cmark_strbuf_init(cmark_strbuf *buf, bufsize_t initial_size)
cmark_strbuf_grow(buf, initial_size);
}
void cmark_strbuf_overflow_err()
{
void cmark_strbuf_overflow_err() {
fprintf(stderr, "String buffer overflow");
abort();
}
static inline void
S_strbuf_grow_by(cmark_strbuf *buf, size_t add)
{
static inline void S_strbuf_grow_by(cmark_strbuf *buf, size_t add) {
size_t target_size = (size_t)buf->size + add;
if (target_size < add /* Integer overflow. */
@ -51,8 +47,7 @@ S_strbuf_grow_by(cmark_strbuf *buf, size_t add)
cmark_strbuf_grow(buf, (bufsize_t)target_size);
}
void cmark_strbuf_grow(cmark_strbuf *buf, bufsize_t target_size)
{
void cmark_strbuf_grow(cmark_strbuf *buf, bufsize_t target_size) {
unsigned char *new_ptr;
if (target_size < buf->asize)
@ -97,14 +92,11 @@ void cmark_strbuf_grow(cmark_strbuf *buf, bufsize_t target_size)
buf->ptr = new_ptr;
}
bufsize_t cmark_strbuf_len(const cmark_strbuf *buf)
{
return buf->size;
}
bufsize_t cmark_strbuf_len(const cmark_strbuf *buf) { return buf->size; }
void cmark_strbuf_free(cmark_strbuf *buf)
{
if (!buf) return;
void cmark_strbuf_free(cmark_strbuf *buf) {
if (!buf)
return;
if (buf->ptr != cmark_strbuf__initbuf)
free(buf->ptr);
@ -112,16 +104,15 @@ void cmark_strbuf_free(cmark_strbuf *buf)
cmark_strbuf_init(buf, 0);
}
void cmark_strbuf_clear(cmark_strbuf *buf)
{
void cmark_strbuf_clear(cmark_strbuf *buf) {
buf->size = 0;
if (buf->asize > 0)
buf->ptr[0] = '\0';
}
void cmark_strbuf_set(cmark_strbuf *buf, const unsigned char *data, bufsize_t len)
{
void cmark_strbuf_set(cmark_strbuf *buf, const unsigned char *data,
bufsize_t len) {
if (len <= 0 || data == NULL) {
cmark_strbuf_clear(buf);
} else {
@ -135,21 +126,19 @@ void cmark_strbuf_set(cmark_strbuf *buf, const unsigned char *data, bufsize_t le
}
}
void cmark_strbuf_sets(cmark_strbuf *buf, const char *string)
{
void cmark_strbuf_sets(cmark_strbuf *buf, const char *string) {
cmark_strbuf_set(buf, (const unsigned char *)string,
string ? cmark_strbuf_safe_strlen(string) : 0);
}
void cmark_strbuf_putc(cmark_strbuf *buf, int c)
{
void cmark_strbuf_putc(cmark_strbuf *buf, int c) {
S_strbuf_grow_by(buf, 1);
buf->ptr[buf->size++] = c;
buf->ptr[buf->size] = '\0';
}
void cmark_strbuf_put(cmark_strbuf *buf, const unsigned char *data, bufsize_t len)
{
void cmark_strbuf_put(cmark_strbuf *buf, const unsigned char *data,
bufsize_t len) {
if (len <= 0)
return;
@ -159,14 +148,13 @@ void cmark_strbuf_put(cmark_strbuf *buf, const unsigned char *data, bufsize_t le
buf->ptr[buf->size] = '\0';
}
void cmark_strbuf_puts(cmark_strbuf *buf, const char *string)
{
void cmark_strbuf_puts(cmark_strbuf *buf, const char *string) {
cmark_strbuf_put(buf, (const unsigned char *)string,
cmark_strbuf_safe_strlen(string));
}
void cmark_strbuf_copy_cstr(char *data, bufsize_t datasize, const cmark_strbuf *buf)
{
void cmark_strbuf_copy_cstr(char *data, bufsize_t datasize,
const cmark_strbuf *buf) {
bufsize_t copylen;
assert(buf);
@ -185,15 +173,13 @@ void cmark_strbuf_copy_cstr(char *data, bufsize_t datasize, const cmark_strbuf *
data[copylen] = '\0';
}
void cmark_strbuf_swap(cmark_strbuf *buf_a, cmark_strbuf *buf_b)
{
void cmark_strbuf_swap(cmark_strbuf *buf_a, cmark_strbuf *buf_b) {
cmark_strbuf t = *buf_a;
*buf_a = *buf_b;
*buf_b = t;
}
unsigned char *cmark_strbuf_detach(cmark_strbuf *buf)
{
unsigned char *cmark_strbuf_detach(cmark_strbuf *buf) {
unsigned char *data = buf->ptr;
if (buf->asize == 0) {
@ -205,44 +191,41 @@ unsigned char *cmark_strbuf_detach(cmark_strbuf *buf)
return data;
}
int cmark_strbuf_cmp(const cmark_strbuf *a, const cmark_strbuf *b)
{
int cmark_strbuf_cmp(const cmark_strbuf *a, const cmark_strbuf *b) {
int result = memcmp(a->ptr, b->ptr, MIN(a->size, b->size));
return (result != 0) ? result :
(a->size < b->size) ? -1 : (a->size > b->size) ? 1 : 0;
return (result != 0) ? result
: (a->size < b->size) ? -1 : (a->size > b->size) ? 1 : 0;
}
bufsize_t cmark_strbuf_strchr(const cmark_strbuf *buf, int c, bufsize_t pos)
{
bufsize_t cmark_strbuf_strchr(const cmark_strbuf *buf, int c, bufsize_t pos) {
if (pos >= buf->size)
return -1;
if (pos < 0)
pos = 0;
const unsigned char *p = (unsigned char *)memchr(buf->ptr + pos, c, buf->size - pos);
const unsigned char *p =
(unsigned char *)memchr(buf->ptr + pos, c, buf->size - pos);
if (!p)
return -1;
return (bufsize_t)(p - (const unsigned char *)buf->ptr);
}
bufsize_t cmark_strbuf_strrchr(const cmark_strbuf *buf, int c, bufsize_t pos)
{
bufsize_t cmark_strbuf_strrchr(const cmark_strbuf *buf, int c, bufsize_t pos) {
if (pos < 0 || buf->size == 0)
return -1;
if (pos >= buf->size)
pos = buf->size - 1;
for (bufsize_t i = pos; i >= 0; i--) {
if (buf->ptr[i] == (unsigned char) c)
if (buf->ptr[i] == (unsigned char)c)
return i;
}
return -1;
}
void cmark_strbuf_truncate(cmark_strbuf *buf, bufsize_t len)
{
void cmark_strbuf_truncate(cmark_strbuf *buf, bufsize_t len) {
if (len < 0)
len = 0;
@ -252,8 +235,7 @@ void cmark_strbuf_truncate(cmark_strbuf *buf, bufsize_t len)
}
}
void cmark_strbuf_drop(cmark_strbuf *buf, bufsize_t n)
{
void cmark_strbuf_drop(cmark_strbuf *buf, bufsize_t n) {
if (n > 0) {
if (n > buf->size)
n = buf->size;
@ -265,8 +247,7 @@ void cmark_strbuf_drop(cmark_strbuf *buf, bufsize_t n)
}
}
void cmark_strbuf_rtrim(cmark_strbuf *buf)
{
void cmark_strbuf_rtrim(cmark_strbuf *buf) {
if (!buf->size)
return;
@ -280,8 +261,7 @@ void cmark_strbuf_rtrim(cmark_strbuf *buf)
buf->ptr[buf->size] = '\0';
}
void cmark_strbuf_trim(cmark_strbuf *buf)
{
void cmark_strbuf_trim(cmark_strbuf *buf) {
bufsize_t i = 0;
if (!buf->size)
@ -297,8 +277,7 @@ void cmark_strbuf_trim(cmark_strbuf *buf)
// Destructively modify string, collapsing consecutive
// space and newline characters into a single space.
void cmark_strbuf_normalize_whitespace(cmark_strbuf *s)
{
void cmark_strbuf_normalize_whitespace(cmark_strbuf *s) {
bool last_char_was_space = false;
bufsize_t r, w;
@ -323,8 +302,7 @@ void cmark_strbuf_normalize_whitespace(cmark_strbuf *s)
}
// Destructively unescape a string: remove backslashes before punctuation chars.
extern void cmark_strbuf_unescape(cmark_strbuf *buf)
{
extern void cmark_strbuf_unescape(cmark_strbuf *buf) {
bufsize_t r, w;
for (r = 0, w = 0; r < buf->size; ++r) {

View File

@ -20,7 +20,8 @@ typedef struct {
extern unsigned char cmark_strbuf__initbuf[];
#define GH_BUF_INIT { cmark_strbuf__initbuf, 0, 0 }
#define GH_BUF_INIT \
{ cmark_strbuf__initbuf, 0, 0 }
#define BUFSIZE_MAX INT_MAX
/**
@ -44,19 +45,21 @@ bufsize_t cmark_strbuf_len(const cmark_strbuf *buf);
int cmark_strbuf_cmp(const cmark_strbuf *a, const cmark_strbuf *b);
unsigned char *cmark_strbuf_detach(cmark_strbuf *buf);
void cmark_strbuf_copy_cstr(char *data, bufsize_t datasize, const cmark_strbuf *buf);
void cmark_strbuf_copy_cstr(char *data, bufsize_t datasize,
const cmark_strbuf *buf);
static inline const char *cmark_strbuf_cstr(const cmark_strbuf *buf)
{
static inline const char *cmark_strbuf_cstr(const cmark_strbuf *buf) {
return (char *)buf->ptr;
}
#define cmark_strbuf_at(buf, n) ((buf)->ptr[n])
void cmark_strbuf_set(cmark_strbuf *buf, const unsigned char *data, bufsize_t len);
void cmark_strbuf_set(cmark_strbuf *buf, const unsigned char *data,
bufsize_t len);
void cmark_strbuf_sets(cmark_strbuf *buf, const char *string);
void cmark_strbuf_putc(cmark_strbuf *buf, int c);
void cmark_strbuf_put(cmark_strbuf *buf, const unsigned char *data, bufsize_t len);
void cmark_strbuf_put(cmark_strbuf *buf, const unsigned char *data,
bufsize_t len);
void cmark_strbuf_puts(cmark_strbuf *buf, const char *string);
void cmark_strbuf_clear(cmark_strbuf *buf);
@ -72,16 +75,14 @@ void cmark_strbuf_unescape(cmark_strbuf *s);
/* Print error and abort. */
void cmark_strbuf_overflow_err(void);
static inline bufsize_t
cmark_strbuf_check_bufsize(size_t size) {
static inline bufsize_t cmark_strbuf_check_bufsize(size_t size) {
if (size > BUFSIZE_MAX) {
cmark_strbuf_overflow_err();
}
return (bufsize_t)size;
}
static inline bufsize_t
cmark_strbuf_safe_strlen(const char *str) {
static inline bufsize_t cmark_strbuf_safe_strlen(const char *str) {
return cmark_strbuf_check_bufsize(strlen(str));
}

View File

@ -7,7 +7,8 @@
#include "cmark_ctype.h"
#include "buffer.h"
#define CMARK_CHUNK_EMPTY { NULL, 0, 0 }
#define CMARK_CHUNK_EMPTY \
{ NULL, 0, 0 }
typedef struct {
unsigned char *data;
@ -15,8 +16,7 @@ typedef struct {
bufsize_t alloc; // also implies a NULL-terminated string
} cmark_chunk;
static inline void cmark_chunk_free(cmark_chunk *c)
{
static inline void cmark_chunk_free(cmark_chunk *c) {
if (c->alloc)
free(c->data);
@ -25,8 +25,7 @@ static inline void cmark_chunk_free(cmark_chunk *c)
c->len = 0;
}
static inline void cmark_chunk_ltrim(cmark_chunk *c)
{
static inline void cmark_chunk_ltrim(cmark_chunk *c) {
assert(!c->alloc);
while (c->len && cmark_isspace(c->data[0])) {
@ -35,8 +34,7 @@ static inline void cmark_chunk_ltrim(cmark_chunk *c)
}
}
static inline void cmark_chunk_rtrim(cmark_chunk *c)
{
static inline void cmark_chunk_rtrim(cmark_chunk *c) {
while (c->len > 0) {
if (!cmark_isspace(c->data[c->len - 1]))
break;
@ -45,28 +43,27 @@ static inline void cmark_chunk_rtrim(cmark_chunk *c)
}
}
static inline void cmark_chunk_trim(cmark_chunk *c)
{
static inline void cmark_chunk_trim(cmark_chunk *c) {
cmark_chunk_ltrim(c);
cmark_chunk_rtrim(c);
}
static inline bufsize_t cmark_chunk_strchr(cmark_chunk *ch, int c, bufsize_t offset)
{
const unsigned char *p = (unsigned char *)memchr(ch->data + offset, c, ch->len - offset);
static inline bufsize_t cmark_chunk_strchr(cmark_chunk *ch, int c,
bufsize_t offset) {
const unsigned char *p =
(unsigned char *)memchr(ch->data + offset, c, ch->len - offset);
return p ? (bufsize_t)(p - ch->data) : ch->len;
}
static inline const char *cmark_chunk_to_cstr(cmark_chunk *c)
{
static inline const char *cmark_chunk_to_cstr(cmark_chunk *c) {
unsigned char *str;
if (c->alloc) {
return (char *)c->data;
}
str = (unsigned char *)malloc(c->len + 1);
if(str != NULL) {
if(c->len > 0) {
if (str != NULL) {
if (c->len > 0) {
memcpy(str, c->data, c->len);
}
str[c->len] = 0;
@ -77,8 +74,7 @@ static inline const char *cmark_chunk_to_cstr(cmark_chunk *c)
return (char *)str;
}
static inline void cmark_chunk_set_cstr(cmark_chunk *c, const char *str)
{
static inline void cmark_chunk_set_cstr(cmark_chunk *c, const char *str) {
if (c->alloc) {
free(c->data);
}
@ -94,21 +90,19 @@ static inline void cmark_chunk_set_cstr(cmark_chunk *c, const char *str)
}
}
static inline cmark_chunk cmark_chunk_literal(const char *data)
{
static inline cmark_chunk cmark_chunk_literal(const char *data) {
bufsize_t len = data ? cmark_strbuf_safe_strlen(data) : 0;
cmark_chunk c = {(unsigned char *)data, len, 0};
return c;
}
static inline cmark_chunk cmark_chunk_dup(const cmark_chunk *ch, bufsize_t pos, bufsize_t len)
{
static inline cmark_chunk cmark_chunk_dup(const cmark_chunk *ch, bufsize_t pos,
bufsize_t len) {
cmark_chunk c = {ch->data + pos, len, 0};
return c;
}
static inline cmark_chunk cmark_chunk_buf_detach(cmark_strbuf *buf)
{
static inline cmark_chunk cmark_chunk_buf_detach(cmark_strbuf *buf) {
cmark_chunk c;
c.len = buf->size;

View File

@ -6,18 +6,11 @@
#include "cmark.h"
#include "buffer.h"
int cmark_version()
{
return CMARK_VERSION;
}
int cmark_version() { return CMARK_VERSION; }
const char *cmark_version_string()
{
return CMARK_VERSION_STRING;
}
const char *cmark_version_string() { return CMARK_VERSION_STRING; }
char *cmark_markdown_to_html(const char *text, size_t len, int options)
{
char *cmark_markdown_to_html(const char *text, size_t len, int options) {
cmark_node *doc;
char *result;
@ -28,4 +21,3 @@ char *cmark_markdown_to_html(const char *text, size_t len, int options)
return result;
}

View File

@ -62,7 +62,6 @@ typedef enum {
CMARK_NODE_LAST_INLINE = CMARK_NODE_IMAGE,
} cmark_node_type;
typedef enum {
CMARK_NO_LIST,
CMARK_BULLET_LIST,
@ -94,13 +93,11 @@ typedef enum {
* other required properties, which it is the caller's responsibility
* to assign.
*/
CMARK_EXPORT cmark_node*
cmark_node_new(cmark_node_type type);
CMARK_EXPORT cmark_node *cmark_node_new(cmark_node_type type);
/** Frees the memory allocated for a node.
*/
CMARK_EXPORT void
cmark_node_free(cmark_node *node);
CMARK_EXPORT void cmark_node_free(cmark_node *node);
/**
* ## Tree Traversal
@ -109,29 +106,24 @@ cmark_node_free(cmark_node *node);
/** Returns the next node in the sequence after 'node', or NULL if
* there is none.
*/
CMARK_EXPORT cmark_node*
cmark_node_next(cmark_node *node);
CMARK_EXPORT cmark_node *cmark_node_next(cmark_node *node);
/** Returns the previous node in the sequence after 'node', or NULL if
* there is none.
*/
CMARK_EXPORT cmark_node*
cmark_node_previous(cmark_node *node);
CMARK_EXPORT cmark_node *cmark_node_previous(cmark_node *node);
/** Returns the parent of 'node', or NULL if there is none.
*/
CMARK_EXPORT cmark_node*
cmark_node_parent(cmark_node *node);
CMARK_EXPORT cmark_node *cmark_node_parent(cmark_node *node);
/** Returns the first child of 'node', or NULL if 'node' has no children.
*/
CMARK_EXPORT cmark_node*
cmark_node_first_child(cmark_node *node);
CMARK_EXPORT cmark_node *cmark_node_first_child(cmark_node *node);
/** Returns the last child of 'node', or NULL if 'node' has no children.
*/
CMARK_EXPORT cmark_node*
cmark_node_last_child(cmark_node *node);
CMARK_EXPORT cmark_node *cmark_node_last_child(cmark_node *node);
/**
* ## Iterator
@ -182,47 +174,40 @@ cmark_node_last_child(cmark_node *node);
* type are undefined until `cmark_iter_next` is called for the first time.
*/
CMARK_EXPORT
cmark_iter*
cmark_iter_new(cmark_node *root);
cmark_iter *cmark_iter_new(cmark_node *root);
/** Frees the memory allocated for an iterator.
*/
CMARK_EXPORT
void
cmark_iter_free(cmark_iter *iter);
void cmark_iter_free(cmark_iter *iter);
/** Advances to the next node and returns the event type (`CMARK_EVENT_ENTER`,
* `CMARK_EVENT_EXIT` or `CMARK_EVENT_DONE`).
*/
CMARK_EXPORT
cmark_event_type
cmark_iter_next(cmark_iter *iter);
cmark_event_type cmark_iter_next(cmark_iter *iter);
/** Returns the current node.
*/
CMARK_EXPORT
cmark_node*
cmark_iter_get_node(cmark_iter *iter);
cmark_node *cmark_iter_get_node(cmark_iter *iter);
/** Returns the current event type.
*/
CMARK_EXPORT
cmark_event_type
cmark_iter_get_event_type(cmark_iter *iter);
cmark_event_type cmark_iter_get_event_type(cmark_iter *iter);
/** Returns the root node.
*/
CMARK_EXPORT
cmark_node*
cmark_iter_get_root(cmark_iter *iter);
cmark_node *cmark_iter_get_root(cmark_iter *iter);
/** Resets the iterator so that the current node is 'current' and
* the event type is 'event_type'. The new current node must be a
* descendant of the root node or the root node itself.
*/
CMARK_EXPORT
void
cmark_iter_reset(cmark_iter *iter, cmark_node *current,
void cmark_iter_reset(cmark_iter *iter, cmark_node *current,
cmark_event_type event_type);
/**
@ -231,144 +216,120 @@ cmark_iter_reset(cmark_iter *iter, cmark_node *current,
/** Returns the user data of 'node'.
*/
CMARK_EXPORT void*
cmark_node_get_user_data(cmark_node *node);
CMARK_EXPORT void *cmark_node_get_user_data(cmark_node *node);
/** Sets arbitrary user data for 'node'. Returns 1 on success,
* 0 on failure.
*/
CMARK_EXPORT int
cmark_node_set_user_data(cmark_node *node, void *user_data);
CMARK_EXPORT int cmark_node_set_user_data(cmark_node *node, void *user_data);
/** Returns the type of 'node', or `CMARK_NODE_NONE` on error.
*/
CMARK_EXPORT cmark_node_type
cmark_node_get_type(cmark_node *node);
CMARK_EXPORT cmark_node_type cmark_node_get_type(cmark_node *node);
/** Like 'cmark_node_get_type', but returns a string representation
of the type, or `"<unknown>"`.
*/
CMARK_EXPORT
const char*
cmark_node_get_type_string(cmark_node *node);
const char *cmark_node_get_type_string(cmark_node *node);
/** Returns the string contents of 'node', or NULL if none.
*/
CMARK_EXPORT const char*
cmark_node_get_literal(cmark_node *node);
CMARK_EXPORT const char *cmark_node_get_literal(cmark_node *node);
/** Sets the string contents of 'node'. Returns 1 on success,
* 0 on failure.
*/
CMARK_EXPORT int
cmark_node_set_literal(cmark_node *node, const char *content);
CMARK_EXPORT int cmark_node_set_literal(cmark_node *node, const char *content);
/** Returns the header level of 'node', or 0 if 'node' is not a header.
*/
CMARK_EXPORT int
cmark_node_get_header_level(cmark_node *node);
CMARK_EXPORT int cmark_node_get_header_level(cmark_node *node);
/** Sets the header level of 'node', returning 1 on success and 0 on error.
*/
CMARK_EXPORT int
cmark_node_set_header_level(cmark_node *node, int level);
CMARK_EXPORT int cmark_node_set_header_level(cmark_node *node, int level);
/** Returns the list type of 'node', or `CMARK_NO_LIST` if 'node'
* is not a list.
*/
CMARK_EXPORT cmark_list_type
cmark_node_get_list_type(cmark_node *node);
CMARK_EXPORT cmark_list_type cmark_node_get_list_type(cmark_node *node);
/** Sets the list type of 'node', returning 1 on success and 0 on error.
*/
CMARK_EXPORT int
cmark_node_set_list_type(cmark_node *node, cmark_list_type type);
CMARK_EXPORT int cmark_node_set_list_type(cmark_node *node,
cmark_list_type type);
/** Returns the list delimiter type of 'node', or `CMARK_NO_DELIM` if 'node'
* is not a list.
*/
CMARK_EXPORT cmark_delim_type
cmark_node_get_list_delim(cmark_node *node);
CMARK_EXPORT cmark_delim_type cmark_node_get_list_delim(cmark_node *node);
/** Sets the list delimiter type of 'node', returning 1 on success and 0
* on error.
*/
CMARK_EXPORT int
cmark_node_set_list_delim(cmark_node *node, cmark_delim_type delim);
CMARK_EXPORT int cmark_node_set_list_delim(cmark_node *node,
cmark_delim_type delim);
/** Returns starting number of 'node', if it is an ordered list, otherwise 0.
*/
CMARK_EXPORT int
cmark_node_get_list_start(cmark_node *node);
CMARK_EXPORT int cmark_node_get_list_start(cmark_node *node);
/** Sets starting number of 'node', if it is an ordered list. Returns 1
* on success, 0 on failure.
*/
CMARK_EXPORT int
cmark_node_set_list_start(cmark_node *node, int start);
CMARK_EXPORT int cmark_node_set_list_start(cmark_node *node, int start);
/** Returns 1 if 'node' is a tight list, 0 otherwise.
*/
CMARK_EXPORT int
cmark_node_get_list_tight(cmark_node *node);
CMARK_EXPORT int cmark_node_get_list_tight(cmark_node *node);
/** Sets the "tightness" of a list. Returns 1 on success, 0 on failure.
*/
CMARK_EXPORT int
cmark_node_set_list_tight(cmark_node *node, int tight);
CMARK_EXPORT int cmark_node_set_list_tight(cmark_node *node, int tight);
/** Returns the info string from a fenced code block, or NULL if none.
*/
CMARK_EXPORT const char*
cmark_node_get_fence_info(cmark_node *node);
CMARK_EXPORT const char *cmark_node_get_fence_info(cmark_node *node);
/** Sets the info string in a fenced code block, returning 1 on
* success and 0 on failure.
*/
CMARK_EXPORT int
cmark_node_set_fence_info(cmark_node *node, const char *info);
CMARK_EXPORT int cmark_node_set_fence_info(cmark_node *node, const char *info);
/** Gets the URL of a link or image 'node', or NULL if none.
*/
CMARK_EXPORT const char*
cmark_node_get_url(cmark_node *node);
CMARK_EXPORT const char *cmark_node_get_url(cmark_node *node);
/** Sets the URL of a link or image 'node'. Returns 1 on success,
* 0 on failure.
*/
CMARK_EXPORT int
cmark_node_set_url(cmark_node *node, const char *url);
CMARK_EXPORT int cmark_node_set_url(cmark_node *node, const char *url);
/** Gets the title of a link or image 'node', or NULL if none.
*/
CMARK_EXPORT const char*
cmark_node_get_title(cmark_node *node);
CMARK_EXPORT const char *cmark_node_get_title(cmark_node *node);
/** Sets the title of a link or image 'node'. Returns 1 on success,
* 0 on failure.
*/
CMARK_EXPORT int
cmark_node_set_title(cmark_node *node, const char *title);
CMARK_EXPORT int cmark_node_set_title(cmark_node *node, const char *title);
/** Returns the line on which 'node' begins.
*/
CMARK_EXPORT int
cmark_node_get_start_line(cmark_node *node);
CMARK_EXPORT int cmark_node_get_start_line(cmark_node *node);
/** Returns the column at which 'node' begins.
*/
CMARK_EXPORT int
cmark_node_get_start_column(cmark_node *node);
CMARK_EXPORT int cmark_node_get_start_column(cmark_node *node);
/** Returns the line on which 'node' ends.
*/
CMARK_EXPORT int
cmark_node_get_end_line(cmark_node *node);
CMARK_EXPORT int cmark_node_get_end_line(cmark_node *node);
/** Returns the column at which 'node' ends.
*/
CMARK_EXPORT int
cmark_node_get_end_column(cmark_node *node);
CMARK_EXPORT int cmark_node_get_end_column(cmark_node *node);
/**
* ## Tree Manipulation
@ -377,35 +338,30 @@ cmark_node_get_end_column(cmark_node *node);
/** Unlinks a 'node', removing it from the tree, but not freeing its
* memory. (Use 'cmark_node_free' for that.)
*/
CMARK_EXPORT void
cmark_node_unlink(cmark_node *node);
CMARK_EXPORT void cmark_node_unlink(cmark_node *node);
/** Inserts 'sibling' before 'node'. Returns 1 on success, 0 on failure.
*/
CMARK_EXPORT int
cmark_node_insert_before(cmark_node *node, cmark_node *sibling);
CMARK_EXPORT int cmark_node_insert_before(cmark_node *node,
cmark_node *sibling);
/** Inserts 'sibling' after 'node'. Returns 1 on success, 0 on failure.
*/
CMARK_EXPORT int
cmark_node_insert_after(cmark_node *node, cmark_node *sibling);
CMARK_EXPORT int cmark_node_insert_after(cmark_node *node, cmark_node *sibling);
/** Adds 'child' to the beginning of the children of 'node'.
* Returns 1 on success, 0 on failure.
*/
CMARK_EXPORT int
cmark_node_prepend_child(cmark_node *node, cmark_node *child);
CMARK_EXPORT int cmark_node_prepend_child(cmark_node *node, cmark_node *child);
/** Adds 'child' to the end of the children of 'node'.
* Returns 1 on success, 0 on failure.
*/
CMARK_EXPORT int
cmark_node_append_child(cmark_node *node, cmark_node *child);
CMARK_EXPORT int cmark_node_append_child(cmark_node *node, cmark_node *child);
/** Consolidates adjacent text nodes.
*/
CMARK_EXPORT void
cmark_consolidate_text_nodes(cmark_node *root);
CMARK_EXPORT void cmark_consolidate_text_nodes(cmark_node *root);
/**
* ## Parsing

View File

@ -21,33 +21,22 @@ static const int8_t cmark_ctype_class[256] = {
/* c */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* d */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* e */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/* f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
/**
* Returns 1 if c is a "whitespace" character as defined by the spec.
*/
int cmark_isspace(char c)
{
return cmark_ctype_class[(int8_t)c] == 1;
}
int cmark_isspace(char c) { return cmark_ctype_class[(int8_t)c] == 1; }
/**
* Returns 1 if c is an ascii punctuation character.
*/
int cmark_ispunct(char c)
{
return cmark_ctype_class[(int8_t)c] == 2;
}
int cmark_ispunct(char c) { return cmark_ctype_class[(int8_t)c] == 2; }
int cmark_isalnum(char c)
{
int cmark_isalnum(char c) {
int8_t result;
result = cmark_ctype_class[(int8_t)c];
return (result == 3 || result == 4);
}
int cmark_isdigit(char c)
{
return cmark_ctype_class[(int8_t)c] == 3;
}
int cmark_isdigit(char c) { return cmark_ctype_class[(int8_t)c] == 3; }

View File

@ -20,31 +20,24 @@
// Functions to convert cmark_nodes to commonmark strings.
static inline void outc(cmark_renderer *renderer,
cmark_escaping escape,
int32_t c,
unsigned char nextc)
{
static inline void outc(cmark_renderer *renderer, cmark_escaping escape,
int32_t c, unsigned char nextc) {
bool needs_escaping = false;
char encoded[20];
needs_escaping =
escape != LITERAL &&
((escape == NORMAL &&
(c == '*' || c == '_' || c == '[' || c == ']' || c == '#' ||
c == '<' || c == '>' || c == '\\' || c == '`' || c == '!' ||
(c == '&' && isalpha(nextc)) ||
(c == '!' && nextc == '[') ||
(renderer->begin_line &&
(c == '-' || c == '+' || c == '=')) ||
(c == '*' || c == '_' || c == '[' || c == ']' || c == '#' || c == '<' ||
c == '>' || c == '\\' || c == '`' || c == '!' ||
(c == '&' && isalpha(nextc)) || (c == '!' && nextc == '[') ||
(renderer->begin_line && (c == '-' || c == '+' || c == '=')) ||
((c == '.' || c == ')') &&
isdigit(renderer->buffer->ptr[renderer->buffer->size - 1])))) ||
(escape == URL &&
(c == '`' || c == '<' || c == '>' || isspace(c) ||
(escape == URL && (c == '`' || c == '<' || c == '>' || isspace(c) ||
c == '\\' || c == ')' || c == '(')) ||
(escape == TITLE &&
(c == '`' || c == '<' || c == '>' || c == '"' ||
c == '\\')));
(c == '`' || c == '<' || c == '>' || c == '"' || c == '\\')));
if (needs_escaping) {
if (isspace(c)) {
@ -61,9 +54,7 @@ static inline void outc(cmark_renderer *renderer,
}
}
static int
longest_backtick_sequence(const char *code)
{
static int longest_backtick_sequence(const char *code) {
int longest = 0;
int current = 0;
size_t i = 0;
@ -82,9 +73,7 @@ longest_backtick_sequence(const char *code)
return longest;
}
static int
shortest_unused_backtick_sequence(const char *code)
{
static int shortest_unused_backtick_sequence(const char *code) {
int32_t used = 1;
int current = 0;
size_t i = 0;
@ -109,9 +98,7 @@ shortest_unused_backtick_sequence(const char *code)
return i;
}
static bool
is_autolink(cmark_node *node)
{
static bool is_autolink(cmark_node *node) {
cmark_chunk *title;
cmark_chunk *url;
cmark_node *link_text;
@ -135,37 +122,29 @@ is_autolink(cmark_node *node)
link_text = node->first_child;
cmark_consolidate_text_nodes(link_text);
realurl = (char*)url->data;
realurl = (char *)url->data;
realurllen = url->len;
if (strncmp(realurl, "mailto:", 7) == 0) {
realurl += 7;
realurllen -= 7;
}
return (realurllen == link_text->as.literal.len &&
strncmp(realurl,
(char*)link_text->as.literal.data,
strncmp(realurl, (char *)link_text->as.literal.data,
link_text->as.literal.len) == 0);
}
// if node is a block node, returns node.
// otherwise returns first block-level node that is an ancestor of node.
static cmark_node*
get_containing_block(cmark_node *node)
{
while (node &&
(node->type < CMARK_NODE_FIRST_BLOCK ||
static cmark_node *get_containing_block(cmark_node *node) {
while (node && (node->type < CMARK_NODE_FIRST_BLOCK ||
node->type > CMARK_NODE_LAST_BLOCK)) {
node = node->parent;
}
return node;
}
static int
S_render_node(cmark_renderer *renderer,
cmark_node *node,
cmark_event_type ev_type,
int options)
{
static int S_render_node(cmark_renderer *renderer, cmark_node *node,
cmark_event_type ev_type, int options) {
cmark_node *tmp;
int list_number;
cmark_delim_type list_delim;
@ -181,15 +160,12 @@ S_render_node(cmark_renderer *renderer,
// Don't adjust tight list status til we've started the list.
// Otherwise we loose the blank line between a paragraph and
// a following list.
if (!(node->type == CMARK_NODE_ITEM && node->prev == NULL &&
entering)) {
if (!(node->type == CMARK_NODE_ITEM && node->prev == NULL && entering)) {
tmp = get_containing_block(node);
renderer->in_tight_list_item =
(tmp->type == CMARK_NODE_ITEM &&
cmark_node_get_list_tight(tmp->parent)) ||
(tmp &&
tmp->parent &&
tmp->parent->type == CMARK_NODE_ITEM &&
(tmp && tmp->parent && tmp->parent->type == CMARK_NODE_ITEM &&
cmark_node_get_list_tight(tmp->parent->parent));
}
@ -202,15 +178,13 @@ S_render_node(cmark_renderer *renderer,
LIT("> ");
cmark_strbuf_puts(renderer->prefix, "> ");
} else {
cmark_strbuf_truncate(renderer->prefix,
renderer->prefix->size - 2);
cmark_strbuf_truncate(renderer->prefix, renderer->prefix->size - 2);
BLANKLINE();
}
break;
case CMARK_NODE_LIST:
if (!entering && node->next &&
(node->next->type == CMARK_NODE_CODE_BLOCK ||
if (!entering && node->next && (node->next->type == CMARK_NODE_CODE_BLOCK ||
node->next->type == CMARK_NODE_LIST)) {
// this ensures 2 blank lines after list,
// if before code block or list:
@ -219,8 +193,7 @@ S_render_node(cmark_renderer *renderer,
break;
case CMARK_NODE_ITEM:
if (cmark_node_get_list_type(node->parent) ==
CMARK_BULLET_LIST) {
if (cmark_node_get_list_type(node->parent) == CMARK_BULLET_LIST) {
marker_width = 2;
} else {
list_number = cmark_node_get_list_start(node->parent);
@ -233,16 +206,13 @@ S_render_node(cmark_renderer *renderer,
// we ensure a width of at least 4 so
// we get nice transition from single digits
// to double
sprintf(listmarker,
"%d%s%s", list_number,
list_delim == CMARK_PAREN_DELIM ?
")" : ".",
sprintf(listmarker, "%d%s%s", list_number,
list_delim == CMARK_PAREN_DELIM ? ")" : ".",
list_number < 10 ? " " : " ");
marker_width = safe_strlen(listmarker);
}
if (entering) {
if (cmark_node_get_list_type(node->parent) ==
CMARK_BULLET_LIST) {
if (cmark_node_get_list_type(node->parent) == CMARK_BULLET_LIST) {
LIT("* ");
cmark_strbuf_puts(renderer->prefix, " ");
} else {
@ -253,8 +223,7 @@ S_render_node(cmark_renderer *renderer,
}
} else {
cmark_strbuf_truncate(renderer->prefix,
renderer->prefix->size -
marker_width);
renderer->prefix->size - marker_width);
CR();
}
break;
@ -282,17 +251,14 @@ S_render_node(cmark_renderer *renderer,
// begin or end with a blank line, and code isn't
// first thing in a list item
if (info_len == 0 &&
(code_len > 2 &&
!isspace(code[0]) &&
!(isspace(code[code_len - 1]) &&
isspace(code[code_len - 2]))) &&
(code_len > 2 && !isspace(code[0]) &&
!(isspace(code[code_len - 1]) && isspace(code[code_len - 2]))) &&
!(node->prev == NULL && node->parent &&
node->parent->type == CMARK_NODE_ITEM)) {
LIT(" ");
cmark_strbuf_puts(renderer->prefix, " ");
OUT(cmark_node_get_literal(node), false, LITERAL);
cmark_strbuf_truncate(renderer->prefix,
renderer->prefix->size - 4);
cmark_strbuf_truncate(renderer->prefix, renderer->prefix->size - 4);
} else {
numticks = longest_backtick_sequence(code) + 1;
if (numticks < 3) {
@ -343,8 +309,7 @@ S_render_node(cmark_renderer *renderer,
break;
case CMARK_NODE_SOFTBREAK:
if (renderer->width == 0 &&
!(CMARK_OPT_HARDBREAKS & options)) {
if (renderer->width == 0 && !(CMARK_OPT_HARDBREAKS & options)) {
CR();
} else {
OUT(" ", true, LITERAL);
@ -402,8 +367,7 @@ S_render_node(cmark_renderer *renderer,
if (is_autolink(node)) {
if (entering) {
LIT("<");
if (strncmp(cmark_node_get_url(node),
"mailto:", 7) == 0) {
if (strncmp(cmark_node_get_url(node), "mailto:", 7) == 0) {
LIT((char *)cmark_node_get_url(node) + 7);
} else {
LIT((char *)cmark_node_get_url(node));
@ -453,8 +417,7 @@ S_render_node(cmark_renderer *renderer,
return 1;
}
char *cmark_render_commonmark(cmark_node *root, int options, int width)
{
char *cmark_render_commonmark(cmark_node *root, int options, int width) {
if (options & CMARK_OPT_HARDBREAKS) {
// disable breaking on width, since it has
// a different meaning with OPT_HARDBREAKS

View File

@ -10,33 +10,39 @@ extern "C" {
#include "buffer.h"
#ifdef HAVE___BUILTIN_EXPECT
# define likely(x) __builtin_expect((x),1)
# define unlikely(x) __builtin_expect((x),0)
#define likely(x) __builtin_expect((x), 1)
#define unlikely(x) __builtin_expect((x), 0)
#else
# define likely(x) (x)
# define unlikely(x) (x)
#define likely(x) (x)
#define unlikely(x) (x)
#endif
#ifdef HOUDINI_USE_LOCALE
# define _isxdigit(c) isxdigit(c)
# define _isdigit(c) isdigit(c)
#define _isxdigit(c) isxdigit(c)
#define _isdigit(c) isdigit(c)
#else
/*
* Helper _isdigit methods -- do not trust the current locale
* */
# define _isxdigit(c) (strchr("0123456789ABCDEFabcdef", (c)) != NULL)
# define _isdigit(c) ((c) >= '0' && (c) <= '9')
#define _isxdigit(c) (strchr("0123456789ABCDEFabcdef", (c)) != NULL)
#define _isdigit(c) ((c) >= '0' && (c) <= '9')
#endif
#define HOUDINI_ESCAPED_SIZE(x) (((x) * 12) / 10)
#define HOUDINI_ESCAPED_SIZE(x) (((x)*12) / 10)
#define HOUDINI_UNESCAPED_SIZE(x) (x)
extern bufsize_t houdini_unescape_ent(cmark_strbuf *ob, const uint8_t *src, bufsize_t size);
extern int houdini_escape_html(cmark_strbuf *ob, const uint8_t *src, bufsize_t size);
extern int houdini_escape_html0(cmark_strbuf *ob, const uint8_t *src, bufsize_t size, int secure);
extern int houdini_unescape_html(cmark_strbuf *ob, const uint8_t *src, bufsize_t size);
extern void houdini_unescape_html_f(cmark_strbuf *ob, const uint8_t *src, bufsize_t size);
extern int houdini_escape_href(cmark_strbuf *ob, const uint8_t *src, bufsize_t size);
extern bufsize_t houdini_unescape_ent(cmark_strbuf *ob, const uint8_t *src,
bufsize_t size);
extern int houdini_escape_html(cmark_strbuf *ob, const uint8_t *src,
bufsize_t size);
extern int houdini_escape_html0(cmark_strbuf *ob, const uint8_t *src,
bufsize_t size, int secure);
extern int houdini_unescape_html(cmark_strbuf *ob, const uint8_t *src,
bufsize_t size);
extern void houdini_unescape_html_f(cmark_strbuf *ob, const uint8_t *src,
bufsize_t size);
extern int houdini_escape_href(cmark_strbuf *ob, const uint8_t *src,
bufsize_t size);
#ifdef __cplusplus
}

View File

@ -30,27 +30,20 @@
*
*/
static const char HREF_SAFE[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
int
houdini_escape_href(cmark_strbuf *ob, const uint8_t *src, bufsize_t size)
{
int houdini_escape_href(cmark_strbuf *ob, const uint8_t *src, bufsize_t size) {
static const uint8_t hex_chars[] = "0123456789ABCDEF";
bufsize_t i = 0, org;
uint8_t hex_str[3];
@ -83,7 +76,7 @@ houdini_escape_href(cmark_strbuf *ob, const uint8_t *src, bufsize_t size)
cmark_strbuf_puts(ob, "&#x27;");
break;
/* the space can be escaped to %20 or a plus
/* the space can be escaped to %20 or a plus
* sign. we're going with the generic escape
* for now. the plus thing is more commonly seen
* when building GET strings */

View File

@ -16,37 +16,24 @@
*
*/
static const char HTML_ESCAPE_TABLE[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 4,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 6, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 4,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
static const char *HTML_ESCAPES[] = {
"",
"&quot;",
"&amp;",
"&#39;",
"&#47;",
"&lt;",
"&gt;"
};
static const char *HTML_ESCAPES[] = {"", "&quot;", "&amp;", "&#39;",
"&#47;", "&lt;", "&gt;"};
int
houdini_escape_html0(cmark_strbuf *ob, const uint8_t *src, bufsize_t size, int secure)
{
int houdini_escape_html0(cmark_strbuf *ob, const uint8_t *src, bufsize_t size,
int secure) {
bufsize_t i = 0, org, esc = 0;
while (i < size) {
@ -74,8 +61,6 @@ houdini_escape_html0(cmark_strbuf *ob, const uint8_t *src, bufsize_t size, int s
return 1;
}
int
houdini_escape_html(cmark_strbuf *ob, const uint8_t *src, bufsize_t size)
{
int houdini_escape_html(cmark_strbuf *ob, const uint8_t *src, bufsize_t size) {
return houdini_escape_html0(ob, src, size, 1);
}

View File

@ -9,35 +9,33 @@
/* Binary tree lookup code for entities added by JGM */
static unsigned char *
S_lookup(int i, int low, int hi, const unsigned char *s, int len)
{
static unsigned char *S_lookup(int i, int low, int hi, const unsigned char *s,
int len) {
int j;
int cmp = strncmp((char *)s, (char *)cmark_entities[i].entity, len);
if (cmp == 0 && cmark_entities[i].entity[len] == 0) {
return (unsigned char *)cmark_entities[i].bytes;
} else if (cmp < 0 && i > low) {
j = i - ((i - low) / 2);
if (j == i) j -= 1;
if (j == i)
j -= 1;
return S_lookup(j, low, i - 1, s, len);
} else if (cmp > 0 && i < hi) {
j = i + ((hi - i) / 2);
if (j == i) j += 1;
if (j == i)
j += 1;
return S_lookup(j, i + 1, hi, s, len);
} else {
return NULL;
}
}
static unsigned char *
S_lookup_entity(const unsigned char *s, int len)
{
static unsigned char *S_lookup_entity(const unsigned char *s, int len) {
return S_lookup(CMARK_NUM_ENTITIES / 2, 0, CMARK_NUM_ENTITIES - 1, s, len);
}
bufsize_t
houdini_unescape_ent(cmark_strbuf *ob, const uint8_t *src, bufsize_t size)
{
bufsize_t houdini_unescape_ent(cmark_strbuf *ob, const uint8_t *src,
bufsize_t size) {
bufsize_t i = 0;
if (size >= 3 && src[0] == '#') {
@ -72,10 +70,8 @@ houdini_unescape_ent(cmark_strbuf *ob, const uint8_t *src, bufsize_t size)
num_digits = i - 2;
}
if (num_digits >= 1 && num_digits <= 8 &&
i < size && src[i] == ';') {
if (codepoint == 0 ||
(codepoint >= 0xD800 && codepoint < 0xE000) ||
if (num_digits >= 1 && num_digits <= 8 && i < size && src[i] == ';') {
if (codepoint == 0 || (codepoint >= 0xD800 && codepoint < 0xE000) ||
codepoint >= 0x110000) {
codepoint = 0xFFFD;
}
@ -108,9 +104,8 @@ houdini_unescape_ent(cmark_strbuf *ob, const uint8_t *src, bufsize_t size)
return 0;
}
int
houdini_unescape_html(cmark_strbuf *ob, const uint8_t *src, bufsize_t size)
{
int houdini_unescape_html(cmark_strbuf *ob, const uint8_t *src,
bufsize_t size) {
bufsize_t i = 0, org, ent;
while (i < size) {
@ -146,8 +141,8 @@ houdini_unescape_html(cmark_strbuf *ob, const uint8_t *src, bufsize_t size)
return 1;
}
void houdini_unescape_html_f(cmark_strbuf *ob, const uint8_t *src, bufsize_t size)
{
void houdini_unescape_html_f(cmark_strbuf *ob, const uint8_t *src,
bufsize_t size) {
if (!houdini_unescape_html(ob, src, size))
cmark_strbuf_put(ob, src, size);
}

View File

@ -12,40 +12,34 @@
// Functions to convert cmark_nodes to HTML strings.
static void escape_html(cmark_strbuf *dest, const unsigned char *source, bufsize_t length)
{
static void escape_html(cmark_strbuf *dest, const unsigned char *source,
bufsize_t length) {
houdini_escape_html0(dest, source, length, 0);
}
static inline void cr(cmark_strbuf *html)
{
static inline void cr(cmark_strbuf *html) {
if (html->size && html->ptr[html->size - 1] != '\n')
cmark_strbuf_putc(html, '\n');
}
struct render_state {
cmark_strbuf* html;
cmark_strbuf *html;
cmark_node *plain;
};
static void
S_render_sourcepos(cmark_node *node, cmark_strbuf *html, int options)
{
static void S_render_sourcepos(cmark_node *node, cmark_strbuf *html,
int options) {
char buffer[100];
if (CMARK_OPT_SOURCEPOS & options) {
sprintf(buffer, " data-sourcepos=\"%d:%d-%d:%d\"",
cmark_node_get_start_line(node),
cmark_node_get_start_column(node),
cmark_node_get_end_line(node),
cmark_node_get_end_column(node));
cmark_node_get_start_line(node), cmark_node_get_start_column(node),
cmark_node_get_end_line(node), cmark_node_get_end_column(node));
cmark_strbuf_puts(html, buffer);
}
}
static int
S_render_node(cmark_node *node, cmark_event_type ev_type,
struct render_state *state, int options)
{
static int S_render_node(cmark_node *node, cmark_event_type ev_type,
struct render_state *state, int options) {
cmark_node *parent;
cmark_node *grandparent;
cmark_strbuf *html = state->html;
@ -61,12 +55,11 @@ S_render_node(cmark_node *node, cmark_event_type ev_type,
}
if (state->plain != NULL) {
switch(node->type) {
switch (node->type) {
case CMARK_NODE_TEXT:
case CMARK_NODE_CODE:
case CMARK_NODE_INLINE_HTML:
escape_html(html, node->as.literal.data,
node->as.literal.len);
escape_html(html, node->as.literal.data, node->as.literal.len);
break;
case CMARK_NODE_LINEBREAK:
@ -118,8 +111,7 @@ S_render_node(cmark_node *node, cmark_event_type ev_type,
}
} else {
cmark_strbuf_puts(html,
list_type == CMARK_BULLET_LIST ?
"</ul>\n" : "</ol>\n");
list_type == CMARK_BULLET_LIST ? "</ul>\n" : "</ol>\n");
}
break;
}
@ -170,8 +162,7 @@ S_render_node(cmark_node *node, cmark_event_type ev_type,
cmark_strbuf_puts(html, "\">");
}
escape_html(html, node->as.code.literal.data,
node->as.code.literal.len);
escape_html(html, node->as.code.literal.data, node->as.code.literal.len);
cmark_strbuf_puts(html, "</code></pre>\n");
break;
@ -180,8 +171,7 @@ S_render_node(cmark_node *node, cmark_event_type ev_type,
if (options & CMARK_OPT_SAFE) {
cmark_strbuf_puts(html, "<!-- raw HTML omitted -->");
} else {
cmark_strbuf_put(html, node->as.literal.data,
node->as.literal.len);
cmark_strbuf_put(html, node->as.literal.data, node->as.literal.len);
}
cr(html);
break;
@ -196,8 +186,7 @@ S_render_node(cmark_node *node, cmark_event_type ev_type,
case CMARK_NODE_PARAGRAPH:
parent = cmark_node_parent(node);
grandparent = cmark_node_parent(parent);
if (grandparent != NULL &&
grandparent->type == CMARK_NODE_LIST) {
if (grandparent != NULL && grandparent->type == CMARK_NODE_LIST) {
tight = grandparent->as.list.tight;
} else {
tight = false;
@ -240,8 +229,7 @@ S_render_node(cmark_node *node, cmark_event_type ev_type,
if (options & CMARK_OPT_SAFE) {
cmark_strbuf_puts(html, "<!-- raw HTML omitted -->");
} else {
cmark_strbuf_put(html, node->as.literal.data,
node->as.literal.len);
cmark_strbuf_put(html, node->as.literal.data, node->as.literal.len);
}
break;
@ -266,16 +254,12 @@ S_render_node(cmark_node *node, cmark_event_type ev_type,
cmark_strbuf_puts(html, "<a href=\"");
if (!((options & CMARK_OPT_SAFE) &&
scan_dangerous_url(&node->as.link.url, 0))) {
houdini_escape_href(html,
node->as.link.url.data,
houdini_escape_href(html, node->as.link.url.data,
node->as.link.url.len);
}
if (node->as.link.title.len) {
cmark_strbuf_puts(html, "\" title=\"");
escape_html(html,
node->as.link.title.data,
node->as.link.title.len);
escape_html(html, node->as.link.title.data, node->as.link.title.len);
}
cmark_strbuf_puts(html, "\">");
} else {
@ -288,18 +272,15 @@ S_render_node(cmark_node *node, cmark_event_type ev_type,
cmark_strbuf_puts(html, "<img src=\"");
if (!((options & CMARK_OPT_SAFE) &&
scan_dangerous_url(&node->as.link.url, 0))) {
houdini_escape_href(html,
node->as.link.url.data,
houdini_escape_href(html, node->as.link.url.data,
node->as.link.url.len);
}
cmark_strbuf_puts(html, "\" alt=\"");
state->plain = node;
} else {
if (node->as.link.title.len) {
cmark_strbuf_puts(html, "\" title=\"");
escape_html(html, node->as.link.title.data,
node->as.link.title.len);
escape_html(html, node->as.link.title.data, node->as.link.title.len);
}
cmark_strbuf_puts(html, "\" />");
@ -315,13 +296,12 @@ S_render_node(cmark_node *node, cmark_event_type ev_type,
return 1;
}
char *cmark_render_html(cmark_node *root, int options)
{
char *cmark_render_html(cmark_node *root, int options) {
char *result;
cmark_strbuf html = GH_BUF_INIT;
cmark_event_type ev_type;
cmark_node *cur;
struct render_state state = { &html, NULL };
struct render_state state = {&html, NULL};
cmark_iter *iter = cmark_iter_new(root);
while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {

View File

@ -13,7 +13,6 @@
#include "scanners.h"
#include "inlines.h"
static const char *EMDASH = "\xE2\x80\x94";
static const char *ENDASH = "\xE2\x80\x93";
static const char *ELLIPSES = "\xE2\x80\xA6";
@ -22,7 +21,6 @@ static const char *RIGHTDOUBLEQUOTE = "\xE2\x80\x9D";
static const char *LEFTSINGLEQUOTE = "\xE2\x80\x98";
static const char *RIGHTSINGLEQUOTE = "\xE2\x80\x99";
// Macros for creating various kinds of simple.
#define make_str(s) make_literal(CMARK_NODE_TEXT, s)
#define make_code(s) make_literal(CMARK_NODE_CODE, s)
@ -50,26 +48,23 @@ typedef struct {
delimiter *last_delim;
} subject;
static inline bool
S_is_line_end_char(char c)
{
static inline bool S_is_line_end_char(char c) {
return (c == '\n' || c == '\r');
}
static delimiter*
S_insert_emph(subject *subj, delimiter *opener, delimiter *closer);
static delimiter *S_insert_emph(subject *subj, delimiter *opener,
delimiter *closer);
static int parse_inline(subject* subj, cmark_node * parent, int options);
static int parse_inline(subject *subj, cmark_node *parent, int options);
static void subject_from_buf(subject *e, cmark_strbuf *buffer,
cmark_reference_map *refmap);
static bufsize_t subject_find_special_char(subject *subj, int options);
// Create an inline with a literal string value.
static inline cmark_node* make_literal(cmark_node_type t, cmark_chunk s)
{
cmark_node * e = (cmark_node *)calloc(1, sizeof(*e));
if(e != NULL) {
static inline cmark_node *make_literal(cmark_node_type t, cmark_chunk s) {
cmark_node *e = (cmark_node *)calloc(1, sizeof(*e));
if (e != NULL) {
e->type = t;
e->as.literal = s;
e->next = NULL;
@ -86,10 +81,9 @@ static inline cmark_node* make_literal(cmark_node_type t, cmark_chunk s)
}
// Create an inline with no value.
static inline cmark_node* make_simple(cmark_node_type t)
{
cmark_node* e = (cmark_node *)calloc(1, sizeof(*e));
if(e != NULL) {
static inline cmark_node *make_simple(cmark_node_type t) {
cmark_node *e = (cmark_node *)calloc(1, sizeof(*e));
if (e != NULL) {
e->type = t;
e->next = NULL;
e->prev = NULL;
@ -105,8 +99,7 @@ static inline cmark_node* make_simple(cmark_node_type t)
}
// Like make_str, but parses entities.
static cmark_node *make_str_with_entities(cmark_chunk *content)
{
static cmark_node *make_str_with_entities(cmark_chunk *content) {
cmark_strbuf unescaped = GH_BUF_INIT;
if (houdini_unescape_html(&unescaped, content->data, content->len)) {
@ -118,8 +111,7 @@ static cmark_node *make_str_with_entities(cmark_chunk *content)
// Duplicate a chunk by creating a copy of the buffer not by reusing the
// buffer like cmark_chunk_dup does.
static cmark_chunk chunk_clone(cmark_chunk *src)
{
static cmark_chunk chunk_clone(cmark_chunk *src) {
cmark_chunk c;
bufsize_t len = src->len;
@ -132,8 +124,7 @@ static cmark_chunk chunk_clone(cmark_chunk *src)
return c;
}
static cmark_chunk cmark_clean_autolink(cmark_chunk *url, int is_email)
{
static cmark_chunk cmark_clean_autolink(cmark_chunk *url, int is_email) {
cmark_strbuf buf = GH_BUF_INIT;
cmark_chunk_trim(url);
@ -150,8 +141,7 @@ static cmark_chunk cmark_clean_autolink(cmark_chunk *url, int is_email)
return cmark_chunk_buf_detach(&buf);
}
static inline cmark_node* make_autolink(cmark_chunk url, int is_email)
{
static inline cmark_node *make_autolink(cmark_chunk url, int is_email) {
cmark_node *link = make_simple(CMARK_NODE_LINK);
link->as.link.url = cmark_clean_autolink(&url, is_email);
link->as.link.title = cmark_chunk_literal("");
@ -160,8 +150,7 @@ static inline cmark_node* make_autolink(cmark_chunk url, int is_email)
}
static void subject_from_buf(subject *e, cmark_strbuf *buffer,
cmark_reference_map *refmap)
{
cmark_reference_map *refmap) {
e->input.data = buffer->ptr;
e->input.len = buffer->size;
e->input.alloc = 0;
@ -170,36 +159,28 @@ static void subject_from_buf(subject *e, cmark_strbuf *buffer,
e->last_delim = NULL;
}
static inline int isbacktick(int c)
{
return (c == '`');
}
static inline int isbacktick(int c) { return (c == '`'); }
static inline unsigned char peek_char(subject *subj)
{
static inline unsigned char peek_char(subject *subj) {
// NULL bytes should have been stripped out by now. If they're
// present, it's a programming error:
assert(!(subj->pos < subj->input.len && subj->input.data[subj->pos] == 0));
return (subj->pos < subj->input.len) ? subj->input.data[subj->pos] : 0;
}
static inline unsigned char peek_at(subject *subj, bufsize_t pos)
{
static inline unsigned char peek_at(subject *subj, bufsize_t pos) {
return subj->input.data[pos];
}
// Return true if there are more characters in the subject.
static inline int is_eof(subject* subj)
{
static inline int is_eof(subject *subj) {
return (subj->pos >= subj->input.len);
}
// Advance the subject. Doesn't check for eof.
#define advance(subj) (subj)->pos += 1
static inline bool
skip_spaces(subject *subj)
{
static inline bool skip_spaces(subject *subj) {
bool skipped = false;
while (peek_char(subj) == ' ' || peek_char(subj) == '\t') {
advance(subj);
@ -208,9 +189,7 @@ skip_spaces(subject *subj)
return skipped;
}
static inline bool
skip_line_end(subject *subj)
{
static inline bool skip_line_end(subject *subj) {
bool seen_line_end_char = false;
if (peek_char(subj) == '\r') {
advance(subj);
@ -224,8 +203,7 @@ skip_line_end(subject *subj)
}
// Take characters while a predicate holds, and return a string.
static inline cmark_chunk take_while(subject* subj, int (*f)(int))
{
static inline cmark_chunk take_while(subject *subj, int (*f)(int)) {
unsigned char c;
bufsize_t startpos = subj->pos;
bufsize_t len = 0;
@ -243,8 +221,8 @@ static inline cmark_chunk take_while(subject* subj, int (*f)(int))
// parsed). Return 0 if you don't find matching closing
// backticks, otherwise return the position in the subject
// after the closing backticks.
static bufsize_t scan_to_closing_backticks(subject* subj, bufsize_t openticklength)
{
static bufsize_t scan_to_closing_backticks(subject *subj,
bufsize_t openticklength) {
// read non backticks
unsigned char c;
while ((c = peek_char(subj)) && c != '`') {
@ -259,15 +237,14 @@ static bufsize_t scan_to_closing_backticks(subject* subj, bufsize_t opentickleng
numticks++;
}
if (numticks != openticklength) {
return(scan_to_closing_backticks(subj, openticklength));
return (scan_to_closing_backticks(subj, openticklength));
}
return (subj->pos);
}
// Parse backtick code section or raw backticks, return an inline.
// Assumes that the subject has a backtick at the current position.
static cmark_node* handle_backticks(subject *subj)
{
static cmark_node *handle_backticks(subject *subj) {
cmark_chunk openticks = take_while(subj, isbacktick);
bufsize_t startpos = subj->pos;
bufsize_t endpos = scan_to_closing_backticks(subj, openticks.len);
@ -278,7 +255,8 @@ static cmark_node* handle_backticks(subject *subj)
} else {
cmark_strbuf buf = GH_BUF_INIT;
cmark_strbuf_set(&buf, subj->input.data + startpos, endpos - startpos - openticks.len);
cmark_strbuf_set(&buf, subj->input.data + startpos,
endpos - startpos - openticks.len);
cmark_strbuf_trim(&buf);
cmark_strbuf_normalize_whitespace(&buf);
@ -288,9 +266,8 @@ static cmark_node* handle_backticks(subject *subj)
// Scan ***, **, or * and return number scanned, or 0.
// Advances position.
static int
scan_delims(subject* subj, unsigned char c, bool * can_open, bool * can_close)
{
static int scan_delims(subject *subj, unsigned char c, bool *can_open,
bool *can_close) {
int numdelims = 0;
bufsize_t before_char_pos;
int32_t after_char = 0;
@ -303,8 +280,7 @@ scan_delims(subject* subj, unsigned char c, bool * can_open, bool * can_close)
} else {
before_char_pos = subj->pos - 1;
// walk back to the beginning of the UTF_8 sequence:
while (peek_at(subj, before_char_pos) >> 6 == 2 &&
before_char_pos > 0) {
while (peek_at(subj, before_char_pos) >> 6 == 2 && before_char_pos > 0) {
before_char_pos -= 1;
}
len = utf8proc_iterate(subj->input.data + before_char_pos,
@ -333,10 +309,10 @@ scan_delims(subject* subj, unsigned char c, bool * can_open, bool * can_close)
!(utf8proc_is_punctuation(after_char) &&
!utf8proc_is_space(before_char) &&
!utf8proc_is_punctuation(before_char));
right_flanking = numdelims > 0 && !utf8proc_is_space(before_char) &&
right_flanking =
numdelims > 0 && !utf8proc_is_space(before_char) &&
!(utf8proc_is_punctuation(before_char) &&
!utf8proc_is_space(after_char) &&
!utf8proc_is_punctuation(after_char));
!utf8proc_is_space(after_char) && !utf8proc_is_punctuation(after_char));
if (c == '_') {
*can_open = left_flanking &&
(!right_flanking || utf8proc_is_punctuation(before_char));
@ -358,7 +334,8 @@ static void print_delimiters(subject *subj)
delimiter *delim;
delim = subj->last_delim;
while (delim != NULL) {
printf("Item at stack pos %p, text pos %d: %d %d %d next(%p) prev(%p)\n",
printf("Item at stack pos %p, text pos %d: %d %d %d next(%p)
prev(%p)\n",
(void*)delim, delim->position, delim->delim_char,
delim->can_open, delim->can_close,
(void*)delim->next, (void*)delim->previous);
@ -367,9 +344,9 @@ static void print_delimiters(subject *subj)
}
*/
static void remove_delimiter(subject *subj, delimiter *delim)
{
if (delim == NULL) return;
static void remove_delimiter(subject *subj, delimiter *delim) {
if (delim == NULL)
return;
if (delim->next == NULL) {
// end of list:
assert(delim == subj->last_delim);
@ -384,10 +361,8 @@ static void remove_delimiter(subject *subj, delimiter *delim)
}
static void push_delimiter(subject *subj, unsigned char c, bool can_open,
bool can_close, cmark_node *inl_text)
{
delimiter *delim =
(delimiter*)malloc(sizeof(delimiter));
bool can_close, cmark_node *inl_text) {
delimiter *delim = (delimiter *)malloc(sizeof(delimiter));
if (delim == NULL) {
return;
}
@ -406,10 +381,9 @@ static void push_delimiter(subject *subj, unsigned char c, bool can_open,
}
// Assumes the subject has a c at the current position.
static cmark_node* handle_delim(subject* subj, unsigned char c, bool smart)
{
static cmark_node *handle_delim(subject *subj, unsigned char c, bool smart) {
bufsize_t numdelims;
cmark_node * inl_text;
cmark_node *inl_text;
bool can_open, can_close;
cmark_chunk contents;
@ -418,15 +392,15 @@ static cmark_node* handle_delim(subject* subj, unsigned char c, bool smart)
if (c == '\'' && smart) {
contents = cmark_chunk_literal(RIGHTSINGLEQUOTE);
} else if (c == '"' && smart) {
contents = cmark_chunk_literal(can_close ? RIGHTDOUBLEQUOTE : LEFTDOUBLEQUOTE);
contents =
cmark_chunk_literal(can_close ? RIGHTDOUBLEQUOTE : LEFTDOUBLEQUOTE);
} else {
contents = cmark_chunk_dup(&subj->input, subj->pos - numdelims, numdelims);
}
inl_text = make_str(contents);
if ((can_open || can_close) &&
(!(c == '\'' || c == '"') || smart)) {
if ((can_open || can_close) && (!(c == '\'' || c == '"') || smart)) {
push_delimiter(subj, c, can_open, can_close, inl_text);
}
@ -434,8 +408,7 @@ static cmark_node* handle_delim(subject* subj, unsigned char c, bool smart)
}
// Assumes we have a hyphen at the current position.
static cmark_node* handle_hyphen(subject* subj, bool smart)
{
static cmark_node *handle_hyphen(subject *subj, bool smart) {
int startpos = subj->pos;
advance(subj);
@ -478,8 +451,7 @@ static cmark_node* handle_hyphen(subject* subj, bool smart)
}
// Assumes we have a period at the current position.
static cmark_node* handle_period(subject* subj, bool smart)
{
static cmark_node *handle_period(subject *subj, bool smart) {
advance(subj);
if (smart && peek_char(subj) == '.') {
advance(subj);
@ -494,8 +466,7 @@ static cmark_node* handle_period(subject* subj, bool smart)
}
}
static void process_emphasis(subject *subj, delimiter *stack_bottom)
{
static void process_emphasis(subject *subj, delimiter *stack_bottom) {
delimiter *closer = subj->last_delim;
delimiter *opener;
delimiter *old_closer;
@ -523,8 +494,7 @@ static void process_emphasis(subject *subj, delimiter *stack_bottom)
opener_found = false;
while (opener != NULL && opener != stack_bottom &&
opener != openers_bottom[closer->delim_char]) {
if (opener->delim_char == closer->delim_char &&
opener->can_open) {
if (opener->delim_char == closer->delim_char && opener->can_open) {
opener_found = true;
break;
}
@ -539,22 +509,18 @@ static void process_emphasis(subject *subj, delimiter *stack_bottom)
}
} else if (closer->delim_char == '\'') {
cmark_chunk_free(&closer->inl_text->as.literal);
closer->inl_text->as.literal =
cmark_chunk_literal(RIGHTSINGLEQUOTE);
closer->inl_text->as.literal = cmark_chunk_literal(RIGHTSINGLEQUOTE);
if (opener_found) {
cmark_chunk_free(&opener->inl_text->as.literal);
opener->inl_text->as.literal =
cmark_chunk_literal(LEFTSINGLEQUOTE);
opener->inl_text->as.literal = cmark_chunk_literal(LEFTSINGLEQUOTE);
}
closer = closer->next;
} else if (closer->delim_char == '"') {
cmark_chunk_free(&closer->inl_text->as.literal);
closer->inl_text->as.literal =
cmark_chunk_literal(RIGHTDOUBLEQUOTE);
closer->inl_text->as.literal = cmark_chunk_literal(RIGHTDOUBLEQUOTE);
if (opener_found) {
cmark_chunk_free(&opener->inl_text->as.literal);
opener->inl_text->as.literal =
cmark_chunk_literal(LEFTDOUBLEQUOTE);
opener->inl_text->as.literal = cmark_chunk_literal(LEFTDOUBLEQUOTE);
}
closer = closer->next;
}
@ -578,9 +544,8 @@ static void process_emphasis(subject *subj, delimiter *stack_bottom)
}
}
static delimiter*
S_insert_emph(subject *subj, delimiter *opener, delimiter *closer)
{
static delimiter *S_insert_emph(subject *subj, delimiter *opener,
delimiter *closer) {
delimiter *delim, *tmp_delim;
bufsize_t use_delims;
cmark_node *opener_inl = opener->inl_text;
@ -591,8 +556,8 @@ S_insert_emph(subject *subj, delimiter *opener, delimiter *closer)
// calculate the actual number of characters used from this closer
if (closer_num_chars < 3 || opener_num_chars < 3) {
use_delims = closer_num_chars <= opener_num_chars ?
closer_num_chars : opener_num_chars;
use_delims = closer_num_chars <= opener_num_chars ? closer_num_chars
: opener_num_chars;
} else { // closer and opener both have >= 3 characters
use_delims = closer_num_chars % 2 == 0 ? 2 : 1;
}
@ -619,8 +584,7 @@ S_insert_emph(subject *subj, delimiter *opener, delimiter *closer)
// replace empty opener inline with emph
cmark_chunk_free(&(opener_inl->as.literal));
emph = opener_inl;
emph->type = use_delims == 1 ?
CMARK_NODE_EMPH : CMARK_NODE_STRONG;
emph->type = use_delims == 1 ? CMARK_NODE_EMPH : CMARK_NODE_STRONG;
// remove opener from list
remove_delimiter(subj, opener);
} else {
@ -659,11 +623,11 @@ S_insert_emph(subject *subj, delimiter *opener, delimiter *closer)
}
// Parse backslash-escape or just a backslash, returning an inline.
static cmark_node* handle_backslash(subject *subj)
{
static cmark_node *handle_backslash(subject *subj) {
advance(subj);
unsigned char nextchar = peek_char(subj);
if (cmark_ispunct(nextchar)) { // only ascii symbols and newline can be escaped
if (cmark_ispunct(
nextchar)) { // only ascii symbols and newline can be escaped
advance(subj);
return make_str(cmark_chunk_dup(&subj->input, subj->pos - 1, 1));
} else if (!is_eof(subj) && skip_line_end(subj)) {
@ -675,17 +639,14 @@ static cmark_node* handle_backslash(subject *subj)
// Parse an entity or a regular "&" string.
// Assumes the subject has an '&' character at the current position.
static cmark_node* handle_entity(subject* subj)
{
static cmark_node *handle_entity(subject *subj) {
cmark_strbuf ent = GH_BUF_INIT;
bufsize_t len;
advance(subj);
len = houdini_unescape_ent(&ent,
subj->input.data + subj->pos,
subj->input.len - subj->pos
);
len = houdini_unescape_ent(&ent, subj->input.data + subj->pos,
subj->input.len - subj->pos);
if (len == 0)
return make_str(cmark_chunk_literal("&"));
@ -696,8 +657,7 @@ static cmark_node* handle_entity(subject* subj)
// Clean a URL: remove surrounding whitespace and surrounding <>,
// and remove \ that escape punctuation.
cmark_chunk cmark_clean_url(cmark_chunk *url)
{
cmark_chunk cmark_clean_url(cmark_chunk *url) {
cmark_strbuf buf = GH_BUF_INIT;
cmark_chunk_trim(url);
@ -717,8 +677,7 @@ cmark_chunk cmark_clean_url(cmark_chunk *url)
return cmark_chunk_buf_detach(&buf);
}
cmark_chunk cmark_clean_title(cmark_chunk *title)
{
cmark_chunk cmark_clean_title(cmark_chunk *title) {
cmark_strbuf buf = GH_BUF_INIT;
unsigned char first, last;
@ -731,8 +690,7 @@ cmark_chunk cmark_clean_title(cmark_chunk *title)
last = title->data[title->len - 1];
// remove surrounding quotes if any:
if ((first == '\'' && last == '\'') ||
(first == '(' && last == ')') ||
if ((first == '\'' && last == '\'') || (first == '(' && last == ')') ||
(first == '"' && last == '"')) {
houdini_unescape_html_f(&buf, title->data + 1, title->len - 2);
} else {
@ -745,8 +703,7 @@ cmark_chunk cmark_clean_title(cmark_chunk *title)
// Parse an autolink or HTML tag.
// Assumes the subject has a '<' character at the current position.
static cmark_node* handle_pointy_brace(subject* subj)
{
static cmark_node *handle_pointy_brace(subject *subj) {
bufsize_t matchlen = 0;
cmark_chunk contents;
@ -786,8 +743,7 @@ static cmark_node* handle_pointy_brace(subject* subj)
// Note: unescaped brackets are not allowed in labels.
// The label begins with `[` and ends with the first `]` character
// encountered. Backticks in labels do not start code spans.
static int link_label(subject* subj, cmark_chunk *raw_label)
{
static int link_label(subject *subj, cmark_chunk *raw_label) {
bufsize_t startpos = subj->pos;
int length = 0;
unsigned char c;
@ -817,7 +773,8 @@ static int link_label(subject* subj, cmark_chunk *raw_label)
}
if (c == ']') { // match found
*raw_label = cmark_chunk_dup(&subj->input, startpos + 1, subj->pos - (startpos + 1));
*raw_label =
cmark_chunk_dup(&subj->input, startpos + 1, subj->pos - (startpos + 1));
cmark_chunk_trim(raw_label);
advance(subj); // advance past ]
return 1;
@ -826,12 +783,10 @@ static int link_label(subject* subj, cmark_chunk *raw_label)
noMatch:
subj->pos = startpos; // rewind
return 0;
}
// Return a link, an image, or a literal close bracket.
static cmark_node* handle_close_bracket(subject* subj, cmark_node *parent)
{
static cmark_node *handle_close_bracket(subject *subj, cmark_node *parent) {
bufsize_t initial_pos;
bufsize_t starturl, endurl, starttitle, endtitle, endall;
bufsize_t n;
@ -885,8 +840,9 @@ static cmark_node* handle_close_bracket(subject* subj, cmark_node *parent)
starttitle = endurl + scan_spacechars(&subj->input, endurl);
// ensure there are spaces btw url and title
endtitle = (starttitle == endurl) ? starttitle :
starttitle + scan_link_title(&subj->input, starttitle);
endtitle = (starttitle == endurl)
? starttitle
: starttitle + scan_link_title(&subj->input, starttitle);
endall = endtitle + scan_spacechars(&subj->input, endtitle);
@ -894,7 +850,8 @@ static cmark_node* handle_close_bracket(subject* subj, cmark_node *parent)
subj->pos = endall + 1;
url_chunk = cmark_chunk_dup(&subj->input, starturl, endurl - starturl);
title_chunk = cmark_chunk_dup(&subj->input, starttitle, endtitle - starttitle);
title_chunk =
cmark_chunk_dup(&subj->input, starttitle, endtitle - starttitle);
url = cmark_clean_url(&url_chunk);
title = cmark_clean_title(&title_chunk);
cmark_chunk_free(&url_chunk);
@ -983,15 +940,13 @@ match:
// Parse a hard or soft linebreak, returning an inline.
// Assumes the subject has a newline at the current position.
static cmark_node* handle_newline(subject *subj)
{
static cmark_node *handle_newline(subject *subj) {
bufsize_t nlpos = subj->pos;
// skip over newline
advance(subj);
// skip spaces at beginning of line
skip_spaces(subj);
if (nlpos > 1 &&
peek_at(subj, nlpos - 1) == ' ' &&
if (nlpos > 1 && peek_at(subj, nlpos - 1) == ' ' &&
peek_at(subj, nlpos - 2) == ' ') {
return make_linebreak();
} else {
@ -999,45 +954,33 @@ static cmark_node* handle_newline(subject *subj)
}
}
static bufsize_t subject_find_special_char(subject *subj, int options)
{
static bufsize_t subject_find_special_char(subject *subj, int options) {
// "\r\n\\`&_*[]<!"
static const int8_t SPECIAL_CHARS[256] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
// " ' . -
static const char SMART_PUNCT_CHARS[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
@ -1046,8 +989,7 @@ static bufsize_t subject_find_special_char(subject *subj, int options)
while (n < subj->input.len) {
if (SPECIAL_CHARS[subj->input.data[n]])
return n;
if (options & CMARK_OPT_SMART &&
SMART_PUNCT_CHARS[subj->input.data[n]])
if (options & CMARK_OPT_SMART && SMART_PUNCT_CHARS[subj->input.data[n]])
return n;
n++;
}
@ -1057,9 +999,8 @@ static bufsize_t subject_find_special_char(subject *subj, int options)
// Parse an inline, advancing subject, and add it as a child of parent.
// Return 0 if no inline can be parsed, 1 otherwise.
static int parse_inline(subject* subj, cmark_node * parent, int options)
{
cmark_node* new_inl = NULL;
static int parse_inline(subject *subj, cmark_node *parent, int options) {
cmark_node *new_inl = NULL;
cmark_chunk contents;
unsigned char c;
bufsize_t endpos;
@ -1067,7 +1008,7 @@ static int parse_inline(subject* subj, cmark_node * parent, int options)
if (c == 0) {
return 0;
}
switch(c) {
switch (c) {
case '\r':
case '\n':
new_inl = handle_newline(subj);
@ -1134,20 +1075,20 @@ static int parse_inline(subject* subj, cmark_node * parent, int options)
}
// Parse inlines from parent's string_content, adding as children of parent.
extern void cmark_parse_inlines(cmark_node* parent, cmark_reference_map *refmap, int options)
{
extern void cmark_parse_inlines(cmark_node *parent, cmark_reference_map *refmap,
int options) {
subject subj;
subject_from_buf(&subj, &parent->string_content, refmap);
cmark_chunk_rtrim(&subj.input);
while (!is_eof(&subj) && parse_inline(&subj, parent, options)) ;
while (!is_eof(&subj) && parse_inline(&subj, parent, options))
;
process_emphasis(&subj, NULL);
}
// Parse zero or more space characters, including at most one newline.
static void spnl(subject* subj)
{
static void spnl(subject *subj) {
skip_spaces(subj);
if (skip_line_end(subj)) {
skip_spaces(subj);
@ -1158,8 +1099,8 @@ static void spnl(subject* subj)
// Modify refmap if a reference is encountered.
// Return 0 if no reference found, otherwise position of subject
// after reference is parsed.
bufsize_t cmark_parse_reference_inline(cmark_strbuf *input, cmark_reference_map *refmap)
{
bufsize_t cmark_parse_reference_inline(cmark_strbuf *input,
cmark_reference_map *refmap) {
subject subj;
cmark_chunk lab;

View File

@ -8,9 +8,11 @@ extern "C" {
cmark_chunk cmark_clean_url(cmark_chunk *url);
cmark_chunk cmark_clean_title(cmark_chunk *title);
void cmark_parse_inlines(cmark_node* parent, cmark_reference_map *refmap, int options);
void cmark_parse_inlines(cmark_node *parent, cmark_reference_map *refmap,
int options);
bufsize_t cmark_parse_reference_inline(cmark_strbuf *input, cmark_reference_map *refmap);
bufsize_t cmark_parse_reference_inline(cmark_strbuf *input,
cmark_reference_map *refmap);
#ifdef __cplusplus
}

View File

@ -7,22 +7,16 @@
#include "iterator.h"
static const int S_leaf_mask =
(1 << CMARK_NODE_HTML) |
(1 << CMARK_NODE_HRULE) |
(1 << CMARK_NODE_CODE_BLOCK) |
(1 << CMARK_NODE_TEXT) |
(1 << CMARK_NODE_SOFTBREAK) |
(1 << CMARK_NODE_LINEBREAK) |
(1 << CMARK_NODE_CODE) |
(1 << CMARK_NODE_INLINE_HTML);
(1 << CMARK_NODE_HTML) | (1 << CMARK_NODE_HRULE) |
(1 << CMARK_NODE_CODE_BLOCK) | (1 << CMARK_NODE_TEXT) |
(1 << CMARK_NODE_SOFTBREAK) | (1 << CMARK_NODE_LINEBREAK) |
(1 << CMARK_NODE_CODE) | (1 << CMARK_NODE_INLINE_HTML);
cmark_iter*
cmark_iter_new(cmark_node *root)
{
cmark_iter *cmark_iter_new(cmark_node *root) {
if (root == NULL) {
return NULL;
}
cmark_iter *iter = (cmark_iter*)malloc(sizeof(cmark_iter));
cmark_iter *iter = (cmark_iter *)malloc(sizeof(cmark_iter));
if (iter == NULL) {
return NULL;
}
@ -34,21 +28,13 @@ cmark_iter_new(cmark_node *root)
return iter;
}
void
cmark_iter_free(cmark_iter *iter)
{
free(iter);
}
void cmark_iter_free(cmark_iter *iter) { free(iter); }
static bool
S_is_leaf(cmark_node *node)
{
static bool S_is_leaf(cmark_node *node) {
return (1 << node->type) & S_leaf_mask;
}
cmark_event_type
cmark_iter_next(cmark_iter *iter)
{
cmark_event_type cmark_iter_next(cmark_iter *iter) {
cmark_event_type ev_type = iter->next.ev_type;
cmark_node *node = iter->next.node;
@ -87,36 +73,22 @@ cmark_iter_next(cmark_iter *iter)
return ev_type;
}
void
cmark_iter_reset(cmark_iter *iter, cmark_node *current,
cmark_event_type event_type)
{
void cmark_iter_reset(cmark_iter *iter, cmark_node *current,
cmark_event_type event_type) {
iter->next.ev_type = event_type;
iter->next.node = current;
cmark_iter_next(iter);
}
cmark_node*
cmark_iter_get_node(cmark_iter *iter)
{
return iter->cur.node;
}
cmark_node *cmark_iter_get_node(cmark_iter *iter) { return iter->cur.node; }
cmark_event_type
cmark_iter_get_event_type(cmark_iter *iter)
{
cmark_event_type cmark_iter_get_event_type(cmark_iter *iter) {
return iter->cur.ev_type;
}
cmark_node*
cmark_iter_get_root(cmark_iter *iter)
{
return iter->root;
}
cmark_node *cmark_iter_get_root(cmark_iter *iter) { return iter->root; }
void cmark_consolidate_text_nodes(cmark_node *root)
{
void cmark_consolidate_text_nodes(cmark_node *root) {
cmark_iter *iter = cmark_iter_new(root);
cmark_strbuf buf = GH_BUF_INIT;
cmark_event_type ev_type;
@ -124,10 +96,8 @@ void cmark_consolidate_text_nodes(cmark_node *root)
while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {
cur = cmark_iter_get_node(iter);
if (ev_type == CMARK_EVENT_ENTER &&
cur->type == CMARK_NODE_TEXT &&
cur->next &&
cur->next->type == CMARK_NODE_TEXT) {
if (ev_type == CMARK_EVENT_ENTER && cur->type == CMARK_NODE_TEXT &&
cur->next && cur->next->type == CMARK_NODE_TEXT) {
cmark_strbuf_clear(&buf);
cmark_strbuf_put(&buf, cur->as.literal.data, cur->as.literal.len);
tmp = cur->next;

View File

@ -18,17 +18,14 @@
#define CR() renderer->cr(renderer)
#define BLANKLINE() renderer->blankline(renderer)
static inline void outc(cmark_renderer *renderer,
cmark_escaping escape,
int32_t c,
unsigned char nextc)
{
static inline void outc(cmark_renderer *renderer, cmark_escaping escape,
int32_t c, unsigned char nextc) {
if (escape == LITERAL) {
cmark_render_code_point(renderer, c);
return;
}
switch(c) {
switch (c) {
case 123: // '{'
case 125: // '}'
case 35: // '#'
@ -44,7 +41,7 @@ static inline void outc(cmark_renderer *renderer,
}
cmark_render_code_point(renderer, c);
break;
case 45 : // '-'
case 45: // '-'
if (nextc == 45) { // prevent ligature
cmark_render_ascii(renderer, "\\-");
} else {
@ -145,16 +142,9 @@ static inline void outc(cmark_renderer *renderer,
}
}
typedef enum {
NO_LINK,
URL_AUTOLINK,
EMAIL_AUTOLINK,
NORMAL_LINK
} link_type;
typedef enum { NO_LINK, URL_AUTOLINK, EMAIL_AUTOLINK, NORMAL_LINK } link_type;
static link_type
get_link_type(cmark_node *node)
{
static link_type get_link_type(cmark_node *node) {
size_t title_len, url_len;
cmark_node *link_text;
char *realurl;
@ -165,7 +155,7 @@ get_link_type(cmark_node *node)
return NO_LINK;
}
const char* url = cmark_node_get_url(node);
const char *url = cmark_node_get_url(node);
cmark_chunk url_chunk = cmark_chunk_literal(url);
url_len = safe_strlen(url);
@ -173,7 +163,7 @@ get_link_type(cmark_node *node)
return NO_LINK;
}
const char* title = cmark_node_get_title(node);
const char *title = cmark_node_get_title(node);
title_len = safe_strlen(title);
// if it has a title, we can't treat it as an autolink:
if (title_len > 0) {
@ -182,7 +172,7 @@ get_link_type(cmark_node *node)
link_text = node->first_child;
cmark_consolidate_text_nodes(link_text);
realurl = (char*)url;
realurl = (char *)url;
realurllen = url_len;
if (strncmp(realurl, "mailto:", 7) == 0) {
realurl += 7;
@ -190,8 +180,7 @@ get_link_type(cmark_node *node)
isemail = true;
}
if (realurllen == link_text->as.literal.len &&
strncmp(realurl,
(char*)link_text->as.literal.data,
strncmp(realurl, (char *)link_text->as.literal.data,
link_text->as.literal.len) == 0) {
if (isemail) {
return EMAIL_AUTOLINK;
@ -203,9 +192,7 @@ get_link_type(cmark_node *node)
}
}
static int
S_get_enumlevel(cmark_node *node)
{
static int S_get_enumlevel(cmark_node *node) {
int enumlevel = 0;
cmark_node *tmp = node;
while (tmp) {
@ -218,19 +205,14 @@ S_get_enumlevel(cmark_node *node)
return enumlevel;
}
static int
S_render_node(cmark_renderer *renderer,
cmark_node *node,
cmark_event_type ev_type,
int options)
{
static int S_render_node(cmark_renderer *renderer, cmark_node *node,
cmark_event_type ev_type, int options) {
int list_number;
char list_number_string[20];
bool entering = (ev_type == CMARK_EVENT_ENTER);
cmark_list_type list_type;
const char* roman_numerals[] = { "", "i", "ii", "iii", "iv", "v",
"vi", "vii", "viii", "ix", "x"
};
const char *roman_numerals[] = {"", "i", "ii", "iii", "iv", "v",
"vi", "vii", "viii", "ix", "x"};
// avoid warning about unused parameter:
(void)(options);
@ -253,14 +235,12 @@ S_render_node(cmark_renderer *renderer,
list_type = cmark_node_get_list_type(node);
if (entering) {
LIT("\\begin{");
LIT(list_type == CMARK_ORDERED_LIST ?
"enumerate" : "itemize");
LIT(list_type == CMARK_ORDERED_LIST ? "enumerate" : "itemize");
LIT("}");
CR();
list_number = cmark_node_get_list_start(node);
if (list_number > 1) {
sprintf(list_number_string,
"%d", list_number);
sprintf(list_number_string, "%d", list_number);
LIT("\\setcounter{enum");
LIT((char *)roman_numerals[S_get_enumlevel(node)]);
LIT("}{");
@ -270,8 +250,7 @@ S_render_node(cmark_renderer *renderer,
}
} else {
LIT("\\end{");
LIT(list_type == CMARK_ORDERED_LIST ?
"enumerate" : "itemize");
LIT(list_type == CMARK_ORDERED_LIST ? "enumerate" : "itemize");
LIT("}");
BLANKLINE();
}
@ -380,9 +359,9 @@ S_render_node(cmark_renderer *renderer,
case CMARK_NODE_LINK:
if (entering) {
const char* url = cmark_node_get_url(node);
const char *url = cmark_node_get_url(node);
// requires \usepackage{hyperref}
switch(get_link_type(node)) {
switch (get_link_type(node)) {
case URL_AUTOLINK:
LIT("\\url{");
OUT(url, false, URL);
@ -424,7 +403,6 @@ S_render_node(cmark_renderer *renderer,
return 1;
}
char *cmark_render_latex(cmark_node *root, int options, int width)
{
char *cmark_render_latex(cmark_node *root, int options, int width) {
return cmark_render(root, options, width, outc, S_render_node);
}

View File

@ -20,11 +20,11 @@ typedef enum {
FORMAT_LATEX
} writer_format;
void print_usage()
{
void print_usage() {
printf("Usage: cmark [FILE*]\n");
printf("Options:\n");
printf(" --to, -t FORMAT Specify output format (html, xml, man, commonmark, latex)\n");
printf(" --to, -t FORMAT Specify output format (html, xml, man, "
"commonmark, latex)\n");
printf(" --width WIDTH Specify wrap width (default 0 = nowrap)\n");
printf(" --sourcepos Include source position attribute\n");
printf(" --hardbreaks Treat newlines as hard line breaks\n");
@ -36,8 +36,7 @@ void print_usage()
}
static void print_document(cmark_node *document, writer_format writer,
int options, int width)
{
int options, int width) {
char *result;
switch (writer) {
@ -64,8 +63,7 @@ static void print_document(cmark_node *document, writer_format writer,
free(result);
}
int main(int argc, char *argv[])
{
int main(int argc, char *argv[]) {
int i, numfps = 0;
int *files;
char buffer[4096];
@ -109,18 +107,15 @@ int main(int argc, char *argv[])
if (i < argc) {
width = (int)strtol(argv[i], &unparsed, 10);
if (unparsed && strlen(unparsed) > 0) {
fprintf(stderr,
"failed parsing width '%s' at '%s'\n",
argv[i], unparsed);
fprintf(stderr, "failed parsing width '%s' at '%s'\n", argv[i],
unparsed);
exit(1);
}
} else {
fprintf(stderr,
"--width requires an argument\n");
fprintf(stderr, "--width requires an argument\n");
exit(1);
}
} else if ((strcmp(argv[i], "-t") == 0) ||
(strcmp(argv[i], "--to") == 0)) {
} else if ((strcmp(argv[i], "-t") == 0) || (strcmp(argv[i], "--to") == 0)) {
i += 1;
if (i < argc) {
if (strcmp(argv[i], "man") == 0) {
@ -134,13 +129,11 @@ int main(int argc, char *argv[])
} else if (strcmp(argv[i], "latex") == 0) {
writer = FORMAT_LATEX;
} else {
fprintf(stderr,
"Unknown format %s\n", argv[i]);
fprintf(stderr, "Unknown format %s\n", argv[i]);
exit(1);
}
} else {
fprintf(stderr, "No argument provided for %s\n",
argv[i - 1]);
fprintf(stderr, "No argument provided for %s\n", argv[i - 1]);
exit(1);
}
} else if (*argv[i] == '-') {
@ -155,8 +148,8 @@ int main(int argc, char *argv[])
for (i = 0; i < numfps; i++) {
FILE *fp = fopen(argv[files[i]], "r");
if (fp == NULL) {
fprintf(stderr, "Error opening file %s: %s\n",
argv[files[i]], strerror(errno));
fprintf(stderr, "Error opening file %s: %s\n", argv[files[i]],
strerror(errno));
exit(1);
}

View File

@ -16,12 +16,8 @@
#define BLANKLINE() renderer->blankline(renderer)
// Functions to convert cmark_nodes to groff man strings.
static
void S_outc(cmark_renderer *renderer,
cmark_escaping escape,
int32_t c,
unsigned char nextc)
{
static void S_outc(cmark_renderer *renderer, cmark_escaping escape, int32_t c,
unsigned char nextc) {
(void)(nextc);
if (escape == LITERAL) {
@ -29,7 +25,7 @@ void S_outc(cmark_renderer *renderer,
return;
}
switch(c) {
switch (c) {
case 46:
if (renderer->begin_line) {
cmark_render_ascii(renderer, "\\&.");
@ -73,12 +69,8 @@ void S_outc(cmark_renderer *renderer,
}
}
static int
S_render_node(cmark_renderer *renderer,
cmark_node *node,
cmark_event_type ev_type,
int options)
{
static int S_render_node(cmark_renderer *renderer, cmark_node *node,
cmark_event_type ev_type, int options) {
cmark_node *tmp;
int list_number;
bool entering = (ev_type == CMARK_EVENT_ENTER);
@ -109,8 +101,7 @@ S_render_node(cmark_renderer *renderer,
if (entering) {
CR();
LIT(".IP ");
if (cmark_node_get_list_type(node->parent) ==
CMARK_BULLET_LIST) {
if (cmark_node_get_list_type(node->parent) == CMARK_BULLET_LIST) {
LIT("\\[bu] 2");
} else {
list_number = cmark_node_get_list_start(node->parent);
@ -132,8 +123,7 @@ S_render_node(cmark_renderer *renderer,
case CMARK_NODE_HEADER:
if (entering) {
CR();
LIT(cmark_node_get_header_level(node) == 1 ?
".SH" : ".SS");
LIT(cmark_node_get_header_level(node) == 1 ? ".SH" : ".SS");
CR();
} else {
CR();
@ -143,9 +133,7 @@ S_render_node(cmark_renderer *renderer,
case CMARK_NODE_CODE_BLOCK:
CR();
LIT(".IP\n.nf\n\\f[C]\n");
OUT(cmark_node_get_literal(node),
false,
NORMAL);
OUT(cmark_node_get_literal(node), false, NORMAL);
CR();
LIT("\\f[]\n.fi");
CR();
@ -163,8 +151,7 @@ S_render_node(cmark_renderer *renderer,
case CMARK_NODE_PARAGRAPH:
if (entering) {
// no blank line if first paragraph in list:
if (node->parent &&
node->parent->type == CMARK_NODE_ITEM &&
if (node->parent && node->parent->type == CMARK_NODE_ITEM &&
node->prev == NULL) {
// no blank line or .PP
} else {
@ -243,7 +230,6 @@ S_render_node(cmark_renderer *renderer,
return 1;
}
char *cmark_render_man(cmark_node *root, int options, int width)
{
char *cmark_render_man(cmark_node *root, int options, int width) {
return cmark_render(root, options, width, S_outc, S_render_node);
}

View File

@ -4,32 +4,25 @@
#include "config.h"
#include "node.h"
static void
S_node_unlink(cmark_node *node);
static void S_node_unlink(cmark_node *node);
static inline bool
S_is_block(cmark_node *node)
{
static inline bool S_is_block(cmark_node *node) {
if (node == NULL) {
return false;
}
return node->type >= CMARK_NODE_FIRST_BLOCK
&& node->type <= CMARK_NODE_LAST_BLOCK;
return node->type >= CMARK_NODE_FIRST_BLOCK &&
node->type <= CMARK_NODE_LAST_BLOCK;
}
static inline bool
S_is_inline(cmark_node *node)
{
static inline bool S_is_inline(cmark_node *node) {
if (node == NULL) {
return false;
}
return node->type >= CMARK_NODE_FIRST_INLINE
&& node->type <= CMARK_NODE_LAST_INLINE;
return node->type >= CMARK_NODE_FIRST_INLINE &&
node->type <= CMARK_NODE_LAST_INLINE;
}
static bool
S_can_contain(cmark_node *node, cmark_node *child)
{
static bool S_can_contain(cmark_node *node, cmark_node *child) {
cmark_node *cur;
if (node == NULL || child == NULL) {
@ -53,8 +46,7 @@ S_can_contain(cmark_node *node, cmark_node *child)
case CMARK_NODE_DOCUMENT:
case CMARK_NODE_BLOCK_QUOTE:
case CMARK_NODE_ITEM:
return S_is_block(child)
&& child->type != CMARK_NODE_ITEM;
return S_is_block(child) && child->type != CMARK_NODE_ITEM;
case CMARK_NODE_LIST:
return child->type == CMARK_NODE_ITEM;
@ -74,9 +66,7 @@ S_can_contain(cmark_node *node, cmark_node *child)
return false;
}
cmark_node*
cmark_node_new(cmark_node_type type)
{
cmark_node *cmark_node_new(cmark_node_type type) {
cmark_node *node = (cmark_node *)calloc(1, sizeof(*node));
node->type = type;
@ -101,9 +91,7 @@ cmark_node_new(cmark_node_type type)
}
// Free a cmark_node list and any children.
static
void S_free_nodes(cmark_node *e)
{
static void S_free_nodes(cmark_node *e) {
cmark_node *next;
while (e != NULL) {
if (S_is_block(e)) {
@ -139,17 +127,13 @@ void S_free_nodes(cmark_node *e)
}
}
void
cmark_node_free(cmark_node *node)
{
void cmark_node_free(cmark_node *node) {
S_node_unlink(node);
node->next = NULL;
S_free_nodes(node);
}
cmark_node_type
cmark_node_get_type(cmark_node *node)
{
cmark_node_type cmark_node_get_type(cmark_node *node) {
if (node == NULL) {
return CMARK_NODE_NONE;
} else {
@ -157,9 +141,7 @@ cmark_node_get_type(cmark_node *node)
}
}
const char*
cmark_node_get_type_string(cmark_node *node)
{
const char *cmark_node_get_type_string(cmark_node *node) {
if (node == NULL) {
return "NONE";
}
@ -208,9 +190,7 @@ cmark_node_get_type_string(cmark_node *node)
return "<unknown>";
}
cmark_node*
cmark_node_next(cmark_node *node)
{
cmark_node *cmark_node_next(cmark_node *node) {
if (node == NULL) {
return NULL;
} else {
@ -218,9 +198,7 @@ cmark_node_next(cmark_node *node)
}
}
cmark_node*
cmark_node_previous(cmark_node *node)
{
cmark_node *cmark_node_previous(cmark_node *node) {
if (node == NULL) {
return NULL;
} else {
@ -228,9 +206,7 @@ cmark_node_previous(cmark_node *node)
}
}
cmark_node*
cmark_node_parent(cmark_node *node)
{
cmark_node *cmark_node_parent(cmark_node *node) {
if (node == NULL) {
return NULL;
} else {
@ -238,9 +214,7 @@ cmark_node_parent(cmark_node *node)
}
}
cmark_node*
cmark_node_first_child(cmark_node *node)
{
cmark_node *cmark_node_first_child(cmark_node *node) {
if (node == NULL) {
return NULL;
} else {
@ -248,9 +222,7 @@ cmark_node_first_child(cmark_node *node)
}
}
cmark_node*
cmark_node_last_child(cmark_node *node)
{
cmark_node *cmark_node_last_child(cmark_node *node) {
if (node == NULL) {
return NULL;
} else {
@ -258,9 +230,7 @@ cmark_node_last_child(cmark_node *node)
}
}
void*
cmark_node_get_user_data(cmark_node *node)
{
void *cmark_node_get_user_data(cmark_node *node) {
if (node == NULL) {
return NULL;
} else {
@ -268,9 +238,7 @@ cmark_node_get_user_data(cmark_node *node)
}
}
int
cmark_node_set_user_data(cmark_node *node, void *user_data)
{
int cmark_node_set_user_data(cmark_node *node, void *user_data) {
if (node == NULL) {
return 0;
}
@ -278,9 +246,7 @@ cmark_node_set_user_data(cmark_node *node, void *user_data)
return 1;
}
const char*
cmark_node_get_literal(cmark_node *node)
{
const char *cmark_node_get_literal(cmark_node *node) {
if (node == NULL) {
return NULL;
}
@ -302,9 +268,7 @@ cmark_node_get_literal(cmark_node *node)
return NULL;
}
int
cmark_node_set_literal(cmark_node *node, const char *content)
{
int cmark_node_set_literal(cmark_node *node, const char *content) {
if (node == NULL) {
return 0;
}
@ -328,9 +292,7 @@ cmark_node_set_literal(cmark_node *node, const char *content)
return 0;
}
int
cmark_node_get_header_level(cmark_node *node)
{
int cmark_node_get_header_level(cmark_node *node) {
if (node == NULL) {
return 0;
}
@ -346,9 +308,7 @@ cmark_node_get_header_level(cmark_node *node)
return 0;
}
int
cmark_node_set_header_level(cmark_node *node, int level)
{
int cmark_node_set_header_level(cmark_node *node, int level) {
if (node == NULL || level < 1 || level > 6) {
return 0;
}
@ -365,9 +325,7 @@ cmark_node_set_header_level(cmark_node *node, int level)
return 0;
}
cmark_list_type
cmark_node_get_list_type(cmark_node *node)
{
cmark_list_type cmark_node_get_list_type(cmark_node *node) {
if (node == NULL) {
return CMARK_NO_LIST;
}
@ -379,9 +337,7 @@ cmark_node_get_list_type(cmark_node *node)
}
}
int
cmark_node_set_list_type(cmark_node *node, cmark_list_type type)
{
int cmark_node_set_list_type(cmark_node *node, cmark_list_type type) {
if (!(type == CMARK_BULLET_LIST || type == CMARK_ORDERED_LIST)) {
return 0;
}
@ -398,9 +354,7 @@ cmark_node_set_list_type(cmark_node *node, cmark_list_type type)
}
}
cmark_delim_type
cmark_node_get_list_delim(cmark_node *node)
{
cmark_delim_type cmark_node_get_list_delim(cmark_node *node) {
if (node == NULL) {
return CMARK_NO_DELIM;
}
@ -412,9 +366,7 @@ cmark_node_get_list_delim(cmark_node *node)
}
}
int
cmark_node_set_list_delim(cmark_node *node, cmark_delim_type delim)
{
int cmark_node_set_list_delim(cmark_node *node, cmark_delim_type delim) {
if (!(delim == CMARK_PERIOD_DELIM || delim == CMARK_PAREN_DELIM)) {
return 0;
}
@ -431,9 +383,7 @@ cmark_node_set_list_delim(cmark_node *node, cmark_delim_type delim)
}
}
int
cmark_node_get_list_start(cmark_node *node)
{
int cmark_node_get_list_start(cmark_node *node) {
if (node == NULL) {
return 0;
}
@ -445,9 +395,7 @@ cmark_node_get_list_start(cmark_node *node)
}
}
int
cmark_node_set_list_start(cmark_node *node, int start)
{
int cmark_node_set_list_start(cmark_node *node, int start) {
if (node == NULL || start < 0) {
return 0;
}
@ -460,9 +408,7 @@ cmark_node_set_list_start(cmark_node *node, int start)
}
}
int
cmark_node_get_list_tight(cmark_node *node)
{
int cmark_node_get_list_tight(cmark_node *node) {
if (node == NULL) {
return 0;
}
@ -474,9 +420,7 @@ cmark_node_get_list_tight(cmark_node *node)
}
}
int
cmark_node_set_list_tight(cmark_node *node, int tight)
{
int cmark_node_set_list_tight(cmark_node *node, int tight) {
if (node == NULL) {
return 0;
}
@ -489,9 +433,7 @@ cmark_node_set_list_tight(cmark_node *node, int tight)
}
}
const char*
cmark_node_get_fence_info(cmark_node *node)
{
const char *cmark_node_get_fence_info(cmark_node *node) {
if (node == NULL) {
return NULL;
}
@ -503,9 +445,7 @@ cmark_node_get_fence_info(cmark_node *node)
}
}
int
cmark_node_set_fence_info(cmark_node *node, const char *info)
{
int cmark_node_set_fence_info(cmark_node *node, const char *info) {
if (node == NULL) {
return 0;
}
@ -518,9 +458,7 @@ cmark_node_set_fence_info(cmark_node *node, const char *info)
}
}
const char*
cmark_node_get_url(cmark_node *node)
{
const char *cmark_node_get_url(cmark_node *node) {
if (node == NULL) {
return NULL;
}
@ -536,9 +474,7 @@ cmark_node_get_url(cmark_node *node)
return NULL;
}
int
cmark_node_set_url(cmark_node *node, const char *url)
{
int cmark_node_set_url(cmark_node *node, const char *url) {
if (node == NULL) {
return 0;
}
@ -555,9 +491,7 @@ cmark_node_set_url(cmark_node *node, const char *url)
return 0;
}
const char*
cmark_node_get_title(cmark_node *node)
{
const char *cmark_node_get_title(cmark_node *node) {
if (node == NULL) {
return NULL;
}
@ -573,9 +507,7 @@ cmark_node_get_title(cmark_node *node)
return NULL;
}
int
cmark_node_set_title(cmark_node *node, const char *title)
{
int cmark_node_set_title(cmark_node *node, const char *title) {
if (node == NULL) {
return 0;
}
@ -592,36 +524,28 @@ cmark_node_set_title(cmark_node *node, const char *title)
return 0;
}
int
cmark_node_get_start_line(cmark_node *node)
{
int cmark_node_get_start_line(cmark_node *node) {
if (node == NULL) {
return 0;
}
return node->start_line;
}
int
cmark_node_get_start_column(cmark_node *node)
{
int cmark_node_get_start_column(cmark_node *node) {
if (node == NULL) {
return 0;
}
return node->start_column;
}
int
cmark_node_get_end_line(cmark_node *node)
{
int cmark_node_get_end_line(cmark_node *node) {
if (node == NULL) {
return 0;
}
return node->end_line;
}
int
cmark_node_get_end_column(cmark_node *node)
{
int cmark_node_get_end_column(cmark_node *node) {
if (node == NULL) {
return 0;
}
@ -629,9 +553,7 @@ cmark_node_get_end_column(cmark_node *node)
}
// Unlink a node without adjusting its next, prev, and parent pointers.
static void
S_node_unlink(cmark_node *node)
{
static void S_node_unlink(cmark_node *node) {
if (node == NULL) {
return;
}
@ -655,20 +577,15 @@ S_node_unlink(cmark_node *node)
}
}
void
cmark_node_unlink(cmark_node *node)
{
void cmark_node_unlink(cmark_node *node) {
S_node_unlink(node);
node->next = NULL;
node->prev = NULL;
node->parent = NULL;
}
int
cmark_node_insert_before(cmark_node *node, cmark_node *sibling)
{
int cmark_node_insert_before(cmark_node *node, cmark_node *sibling) {
if (node == NULL || sibling == NULL) {
return 0;
}
@ -701,9 +618,7 @@ cmark_node_insert_before(cmark_node *node, cmark_node *sibling)
return 1;
}
int
cmark_node_insert_after(cmark_node *node, cmark_node *sibling)
{
int cmark_node_insert_after(cmark_node *node, cmark_node *sibling) {
if (node == NULL || sibling == NULL) {
return 0;
}
@ -736,9 +651,7 @@ cmark_node_insert_after(cmark_node *node, cmark_node *sibling)
return 1;
}
int
cmark_node_prepend_child(cmark_node *node, cmark_node *child)
{
int cmark_node_prepend_child(cmark_node *node, cmark_node *child) {
if (!S_can_contain(node, child)) {
return 0;
}
@ -762,9 +675,7 @@ cmark_node_prepend_child(cmark_node *node, cmark_node *child)
return 1;
}
int
cmark_node_append_child(cmark_node *node, cmark_node *child)
{
int cmark_node_append_child(cmark_node *node, cmark_node *child) {
if (!S_can_contain(node, child)) {
return 0;
}
@ -788,9 +699,7 @@ cmark_node_append_child(cmark_node *node, cmark_node *child)
return 1;
}
static void
S_print_error(FILE *out, cmark_node *node, const char *elem)
{
static void S_print_error(FILE *out, cmark_node *node, const char *elem) {
if (out == NULL) {
return;
}
@ -799,9 +708,7 @@ S_print_error(FILE *out, cmark_node *node, const char *elem)
node->start_column);
}
int
cmark_node_check(cmark_node *node, FILE *out)
{
int cmark_node_check(cmark_node *node, FILE *out) {
cmark_node *cur;
int errors = 0;
@ -826,7 +733,7 @@ cmark_node_check(cmark_node *node, FILE *out)
continue;
}
next_sibling:
next_sibling:
if (cur == node) {
break;
}

View File

@ -73,8 +73,7 @@ struct cmark_node {
} as;
};
CMARK_EXPORT int
cmark_node_check(cmark_node *node, FILE *out);
CMARK_EXPORT int cmark_node_check(cmark_node *node, FILE *out);
#ifdef __cplusplus
}

View File

@ -13,8 +13,8 @@ extern "C" {
struct cmark_parser {
struct cmark_reference_map *refmap;
struct cmark_node* root;
struct cmark_node* current;
struct cmark_node *root;
struct cmark_node *current;
int line_number;
bufsize_t offset;
bufsize_t column;

View File

@ -5,9 +5,7 @@
#include "inlines.h"
#include "chunk.h"
static unsigned int
refhash(const unsigned char *link_ref)
{
static unsigned int refhash(const unsigned char *link_ref) {
unsigned int hash = 0;
while (*link_ref)
@ -16,9 +14,8 @@ refhash(const unsigned char *link_ref)
return hash;
}
static void reference_free(cmark_reference *ref)
{
if(ref != NULL) {
static void reference_free(cmark_reference *ref) {
if (ref != NULL) {
free(ref->label);
cmark_chunk_free(&ref->url);
cmark_chunk_free(&ref->title);
@ -30,12 +27,11 @@ static void reference_free(cmark_reference *ref)
// remove leading/trailing whitespace, case fold
// Return NULL if the reference name is actually empty (i.e. composed
// solely from whitespace)
static unsigned char *normalize_reference(cmark_chunk *ref)
{
static unsigned char *normalize_reference(cmark_chunk *ref) {
cmark_strbuf normalized = GH_BUF_INIT;
unsigned char *result;
if(ref == NULL)
if (ref == NULL)
return NULL;
if (ref->len == 0)
@ -56,13 +52,11 @@ static unsigned char *normalize_reference(cmark_chunk *ref)
return result;
}
static void add_reference(cmark_reference_map *map, cmark_reference* ref)
{
static void add_reference(cmark_reference_map *map, cmark_reference *ref) {
cmark_reference *t = ref->next = map->table[ref->hash % REFMAP_SIZE];
while (t) {
if (t->hash == ref->hash &&
!strcmp((char *)t->label, (char *)ref->label)) {
if (t->hash == ref->hash && !strcmp((char *)t->label, (char *)ref->label)) {
reference_free(ref);
return;
}
@ -73,9 +67,8 @@ static void add_reference(cmark_reference_map *map, cmark_reference* ref)
map->table[ref->hash % REFMAP_SIZE] = ref;
}
void cmark_reference_create(cmark_reference_map *map, cmark_chunk *label, cmark_chunk *url,
cmark_chunk *title)
{
void cmark_reference_create(cmark_reference_map *map, cmark_chunk *label,
cmark_chunk *url, cmark_chunk *title) {
cmark_reference *ref;
unsigned char *reflabel = normalize_reference(label);
@ -84,7 +77,7 @@ void cmark_reference_create(cmark_reference_map *map, cmark_chunk *label, cmark_
return;
ref = (cmark_reference *)calloc(1, sizeof(*ref));
if(ref != NULL) {
if (ref != NULL) {
ref->label = reflabel;
ref->hash = refhash(ref->label);
ref->url = cmark_clean_url(url);
@ -97,8 +90,8 @@ void cmark_reference_create(cmark_reference_map *map, cmark_chunk *label, cmark_
// Returns reference if refmap contains a reference with matching
// label, otherwise NULL.
cmark_reference* cmark_reference_lookup(cmark_reference_map *map, cmark_chunk *label)
{
cmark_reference *cmark_reference_lookup(cmark_reference_map *map,
cmark_chunk *label) {
cmark_reference *ref = NULL;
unsigned char *norm;
unsigned int hash;
@ -117,8 +110,7 @@ cmark_reference* cmark_reference_lookup(cmark_reference_map *map, cmark_chunk *l
ref = map->table[hash % REFMAP_SIZE];
while (ref) {
if (ref->hash == hash &&
!strcmp((char *)ref->label, (char *)norm))
if (ref->hash == hash && !strcmp((char *)ref->label, (char *)norm))
break;
ref = ref->next;
}
@ -127,11 +119,10 @@ cmark_reference* cmark_reference_lookup(cmark_reference_map *map, cmark_chunk *l
return ref;
}
void cmark_reference_map_free(cmark_reference_map *map)
{
void cmark_reference_map_free(cmark_reference_map *map) {
unsigned int i;
if(map == NULL)
if (map == NULL)
return;
for (i = 0; i < REFMAP_SIZE; ++i) {
@ -148,7 +139,6 @@ void cmark_reference_map_free(cmark_reference_map *map)
free(map);
}
cmark_reference_map *cmark_reference_map_new(void)
{
cmark_reference_map *cmark_reference_map_new(void) {
return (cmark_reference_map *)calloc(1, sizeof(cmark_reference_map));
}

View File

@ -27,8 +27,10 @@ typedef struct cmark_reference_map cmark_reference_map;
cmark_reference_map *cmark_reference_map_new(void);
void cmark_reference_map_free(cmark_reference_map *map);
cmark_reference* cmark_reference_lookup(cmark_reference_map *map, cmark_chunk *label);
extern void cmark_reference_create(cmark_reference_map *map, cmark_chunk *label, cmark_chunk *url, cmark_chunk *title);
cmark_reference *cmark_reference_lookup(cmark_reference_map *map,
cmark_chunk *label);
extern void cmark_reference_create(cmark_reference_map *map, cmark_chunk *label,
cmark_chunk *url, cmark_chunk *title);
#ifdef __cplusplus
}

View File

@ -5,28 +5,20 @@
#include "utf8.h"
#include "render.h"
static inline
void S_cr(cmark_renderer *renderer)
{
static inline void S_cr(cmark_renderer *renderer) {
if (renderer->need_cr < 1) {
renderer->need_cr = 1;
}
}
static inline
void S_blankline(cmark_renderer *renderer)
{
static inline void S_blankline(cmark_renderer *renderer) {
if (renderer->need_cr < 2) {
renderer->need_cr = 2;
}
}
static
void S_out(cmark_renderer *renderer,
const char *source,
bool wrap,
cmark_escaping escape)
{
static void S_out(cmark_renderer *renderer, const char *source, bool wrap,
cmark_escaping escape) {
int length = cmark_strbuf_safe_strlen(source);
unsigned char nextc;
int32_t c;
@ -73,8 +65,7 @@ void S_out(cmark_renderer *renderer,
cmark_strbuf_putc(renderer->buffer, ' ');
renderer->column += 1;
renderer->begin_line = false;
renderer->last_breakable = renderer->buffer->size -
1;
renderer->last_breakable = renderer->buffer->size - 1;
// skip following spaces
while (source[i + 1] == ' ') {
i++;
@ -96,13 +87,12 @@ void S_out(cmark_renderer *renderer,
// If adding the character went beyond width, look for an
// earlier place where the line could be broken:
if (renderer->width > 0 &&
renderer->column > renderer->width &&
!renderer->begin_line &&
renderer->last_breakable > 0) {
if (renderer->width > 0 && renderer->column > renderer->width &&
!renderer->begin_line && renderer->last_breakable > 0) {
// copy from last_breakable to remainder
cmark_chunk_set_cstr(&remainder, (char *) renderer->buffer->ptr + renderer->last_breakable + 1);
cmark_chunk_set_cstr(&remainder, (char *)renderer->buffer->ptr +
renderer->last_breakable + 1);
// truncate at last_breakable
cmark_strbuf_truncate(renderer->buffer, renderer->last_breakable);
// add newline, prefix, and remainder
@ -121,34 +111,23 @@ void S_out(cmark_renderer *renderer,
}
// Assumes no newlines, assumes ascii content:
void
cmark_render_ascii(cmark_renderer* renderer, const char* s)
{
void cmark_render_ascii(cmark_renderer *renderer, const char *s) {
int origsize = renderer->buffer->size;
cmark_strbuf_puts(renderer->buffer, s);
renderer->column += renderer->buffer->size - origsize;
}
void
cmark_render_code_point(cmark_renderer *renderer, uint32_t c)
{
void cmark_render_code_point(cmark_renderer *renderer, uint32_t c) {
utf8proc_encode_char(c, renderer->buffer);
renderer->column += 1;
}
char*
cmark_render(cmark_node *root,
int options,
int width,
void (*outc)(cmark_renderer*,
cmark_escaping,
int32_t,
char *cmark_render(cmark_node *root, int options, int width,
void (*outc)(cmark_renderer *, cmark_escaping, int32_t,
unsigned char),
int (*render_node)(cmark_renderer *renderer,
cmark_node *node,
cmark_event_type ev_type,
int options))
{
cmark_event_type ev_type, int options)) {
cmark_strbuf pref = GH_BUF_INIT;
cmark_strbuf buf = GH_BUF_INIT;
cmark_node *cur;
@ -156,10 +135,8 @@ cmark_render(cmark_node *root,
char *result;
cmark_iter *iter = cmark_iter_new(root);
cmark_renderer renderer = { &buf, &pref, 0, width,
0, 0, true, false, false,
outc, S_cr, S_blankline, S_out
};
cmark_renderer renderer = {&buf, &pref, 0, width, 0, 0, true,
false, false, outc, S_cr, S_blankline, S_out};
while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {
cur = cmark_iter_get_node(iter);

View File

@ -9,16 +9,11 @@ extern "C" {
#include "buffer.h"
#include "chunk.h"
typedef enum {
LITERAL,
NORMAL,
TITLE,
URL
} cmark_escaping;
typedef enum { LITERAL, NORMAL, TITLE, URL } cmark_escaping;
struct cmark_renderer {
cmark_strbuf* buffer;
cmark_strbuf* prefix;
cmark_strbuf *buffer;
cmark_strbuf *prefix;
int column;
int width;
int need_cr;
@ -26,38 +21,24 @@ struct cmark_renderer {
bool begin_line;
bool no_wrap;
bool in_tight_list_item;
void (*outc)(struct cmark_renderer*,
cmark_escaping,
int32_t,
unsigned char);
void (*cr)(struct cmark_renderer*);
void (*blankline)(struct cmark_renderer*);
void (*out)(struct cmark_renderer*,
const char *,
bool,
cmark_escaping);
void (*outc)(struct cmark_renderer *, cmark_escaping, int32_t, unsigned char);
void (*cr)(struct cmark_renderer *);
void (*blankline)(struct cmark_renderer *);
void (*out)(struct cmark_renderer *, const char *, bool, cmark_escaping);
};
typedef struct cmark_renderer cmark_renderer;
void
cmark_render_ascii(cmark_renderer *renderer, const char* s);
void cmark_render_ascii(cmark_renderer *renderer, const char *s);
void
cmark_render_code_point(cmark_renderer *renderer, uint32_t c);
void cmark_render_code_point(cmark_renderer *renderer, uint32_t c);
char*
cmark_render(cmark_node *root,
int options,
int width,
void (*outc)(cmark_renderer*,
cmark_escaping,
int32_t,
char *cmark_render(cmark_node *root, int options, int width,
void (*outc)(cmark_renderer *, cmark_escaping, int32_t,
unsigned char),
int (*render_node)(cmark_renderer *renderer,
cmark_node *node,
cmark_event_type ev_type,
int options));
cmark_event_type ev_type, int options));
#ifdef __cplusplus
}

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,8 @@
extern "C" {
#endif
bufsize_t _scan_at(bufsize_t (*scanner)(const unsigned char *), cmark_chunk *c, bufsize_t offset);
bufsize_t _scan_at(bufsize_t (*scanner)(const unsigned char *), cmark_chunk *c,
bufsize_t offset);
bufsize_t _scan_scheme(const unsigned char *p);
bufsize_t _scan_autolink_uri(const unsigned char *p);
bufsize_t _scan_autolink_email(const unsigned char *p);

View File

@ -6,32 +6,24 @@
#include "utf8.h"
static const int8_t utf8proc_utf8class[256] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0
};
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0};
static void encode_unknown(cmark_strbuf *buf)
{
static void encode_unknown(cmark_strbuf *buf) {
static const uint8_t repl[] = {239, 191, 189};
cmark_strbuf_put(buf, repl, 3);
}
static int utf8proc_charlen(const uint8_t *str, bufsize_t str_len)
{
static int utf8proc_charlen(const uint8_t *str, bufsize_t str_len) {
int length, i;
if (!str_len)
@ -54,8 +46,7 @@ static int utf8proc_charlen(const uint8_t *str, bufsize_t str_len)
}
// Validate a single UTF-8 character according to RFC 3629.
static int utf8proc_valid(const uint8_t *str, bufsize_t str_len)
{
static int utf8proc_valid(const uint8_t *str, bufsize_t str_len) {
int length = utf8proc_utf8class[str[0]];
if (!length)
@ -116,8 +107,7 @@ static int utf8proc_valid(const uint8_t *str, bufsize_t str_len)
return length;
}
void utf8proc_check(cmark_strbuf *ob, const uint8_t *line, bufsize_t size)
{
void utf8proc_check(cmark_strbuf *ob, const uint8_t *line, bufsize_t size) {
bufsize_t i = 0;
while (i < size) {
@ -156,8 +146,7 @@ void utf8proc_check(cmark_strbuf *ob, const uint8_t *line, bufsize_t size)
}
}
int utf8proc_iterate(const uint8_t *str, bufsize_t str_len, int32_t *dst)
{
int utf8proc_iterate(const uint8_t *str, bufsize_t str_len, int32_t *dst) {
int length;
int32_t uc = -1;
@ -172,17 +161,19 @@ int utf8proc_iterate(const uint8_t *str, bufsize_t str_len, int32_t *dst)
break;
case 2:
uc = ((str[0] & 0x1F) << 6) + (str[1] & 0x3F);
if (uc < 0x80) uc = -1;
if (uc < 0x80)
uc = -1;
break;
case 3:
uc = ((str[0] & 0x0F) << 12) + ((str[1] & 0x3F) << 6)
+ (str[2] & 0x3F);
if (uc < 0x800 || (uc >= 0xD800 && uc < 0xE000)) uc = -1;
uc = ((str[0] & 0x0F) << 12) + ((str[1] & 0x3F) << 6) + (str[2] & 0x3F);
if (uc < 0x800 || (uc >= 0xD800 && uc < 0xE000))
uc = -1;
break;
case 4:
uc = ((str[0] & 0x07) << 18) + ((str[1] & 0x3F) << 12)
+ ((str[2] & 0x3F) << 6) + (str[3] & 0x3F);
if (uc < 0x10000 || uc >= 0x110000) uc = -1;
uc = ((str[0] & 0x07) << 18) + ((str[1] & 0x3F) << 12) +
((str[2] & 0x3F) << 6) + (str[3] & 0x3F);
if (uc < 0x10000 || uc >= 0x110000)
uc = -1;
break;
}
@ -193,8 +184,7 @@ int utf8proc_iterate(const uint8_t *str, bufsize_t str_len, int32_t *dst)
return length;
}
void utf8proc_encode_char(int32_t uc, cmark_strbuf *buf)
{
void utf8proc_encode_char(int32_t uc, cmark_strbuf *buf) {
uint8_t dst[4];
bufsize_t len = 0;
@ -232,12 +222,10 @@ void utf8proc_encode_char(int32_t uc, cmark_strbuf *buf)
cmark_strbuf_put(buf, dst, len);
}
void utf8proc_case_fold(cmark_strbuf *dest, const uint8_t *str, bufsize_t len)
{
void utf8proc_case_fold(cmark_strbuf *dest, const uint8_t *str, bufsize_t len) {
int32_t c;
#define bufpush(x) \
utf8proc_encode_char(x, dest)
#define bufpush(x) utf8proc_encode_char(x, dest)
while (len > 0) {
bufsize_t char_len = utf8proc_iterate(str, len, &c);
@ -255,203 +243,72 @@ void utf8proc_case_fold(cmark_strbuf *dest, const uint8_t *str, bufsize_t len)
}
// matches anything in the Zs class, plus LF, CR, TAB, FF.
int utf8proc_is_space(int32_t uc)
{
return (uc == 9 ||
uc == 10 ||
uc == 12 ||
uc == 13 ||
uc == 32 ||
uc == 160 ||
uc == 5760 ||
(uc >= 8192 && uc <= 8202) ||
uc == 8239 ||
uc == 8287 ||
uc == 12288);
int utf8proc_is_space(int32_t uc) {
return (uc == 9 || uc == 10 || uc == 12 || uc == 13 || uc == 32 ||
uc == 160 || uc == 5760 || (uc >= 8192 && uc <= 8202) || uc == 8239 ||
uc == 8287 || uc == 12288);
}
// matches anything in the P[cdefios] classes.
int utf8proc_is_punctuation(int32_t uc)
{
return ((uc < 128 && cmark_ispunct((char)uc)) ||
uc == 161 ||
uc == 167 ||
uc == 171 ||
uc == 182 ||
uc == 183 ||
uc == 187 ||
uc == 191 ||
uc == 894 ||
uc == 903 ||
(uc >= 1370 && uc <= 1375) ||
uc == 1417 ||
uc == 1418 ||
uc == 1470 ||
uc == 1472 ||
uc == 1475 ||
uc == 1478 ||
uc == 1523 ||
uc == 1524 ||
uc == 1545 ||
uc == 1546 ||
uc == 1548 ||
uc == 1549 ||
uc == 1563 ||
uc == 1566 ||
uc == 1567 ||
(uc >= 1642 && uc <= 1645) ||
uc == 1748 ||
(uc >= 1792 && uc <= 1805) ||
(uc >= 2039 && uc <= 2041) ||
(uc >= 2096 && uc <= 2110) ||
uc == 2142 ||
uc == 2404 ||
uc == 2405 ||
uc == 2416 ||
uc == 2800 ||
uc == 3572 ||
uc == 3663 ||
uc == 3674 ||
uc == 3675 ||
(uc >= 3844 && uc <= 3858) ||
uc == 3860 ||
(uc >= 3898 && uc <= 3901) ||
uc == 3973 ||
(uc >= 4048 && uc <= 4052) ||
uc == 4057 ||
uc == 4058 ||
(uc >= 4170 && uc <= 4175) ||
uc == 4347 ||
(uc >= 4960 && uc <= 4968) ||
uc == 5120 ||
uc == 5741 ||
uc == 5742 ||
uc == 5787 ||
uc == 5788 ||
(uc >= 5867 && uc <= 5869) ||
uc == 5941 ||
uc == 5942 ||
(uc >= 6100 && uc <= 6102) ||
(uc >= 6104 && uc <= 6106) ||
(uc >= 6144 && uc <= 6154) ||
uc == 6468 ||
uc == 6469 ||
uc == 6686 ||
uc == 6687 ||
(uc >= 6816 && uc <= 6822) ||
(uc >= 6824 && uc <= 6829) ||
(uc >= 7002 && uc <= 7008) ||
(uc >= 7164 && uc <= 7167) ||
(uc >= 7227 && uc <= 7231) ||
uc == 7294 ||
uc == 7295 ||
(uc >= 7360 && uc <= 7367) ||
uc == 7379 ||
(uc >= 8208 && uc <= 8231) ||
(uc >= 8240 && uc <= 8259) ||
(uc >= 8261 && uc <= 8273) ||
(uc >= 8275 && uc <= 8286) ||
uc == 8317 ||
uc == 8318 ||
uc == 8333 ||
uc == 8334 ||
(uc >= 8968 && uc <= 8971) ||
uc == 9001 ||
uc == 9002 ||
(uc >= 10088 && uc <= 10101) ||
uc == 10181 ||
uc == 10182 ||
(uc >= 10214 && uc <= 10223) ||
(uc >= 10627 && uc <= 10648) ||
(uc >= 10712 && uc <= 10715) ||
uc == 10748 ||
uc == 10749 ||
(uc >= 11513 && uc <= 11516) ||
uc == 11518 ||
uc == 11519 ||
uc == 11632 ||
(uc >= 11776 && uc <= 11822) ||
(uc >= 11824 && uc <= 11842) ||
(uc >= 12289 && uc <= 12291) ||
(uc >= 12296 && uc <= 12305) ||
(uc >= 12308 && uc <= 12319) ||
uc == 12336 ||
uc == 12349 ||
uc == 12448 ||
uc == 12539 ||
uc == 42238 ||
uc == 42239 ||
(uc >= 42509 && uc <= 42511) ||
uc == 42611 ||
uc == 42622 ||
(uc >= 42738 && uc <= 42743) ||
(uc >= 43124 && uc <= 43127) ||
uc == 43214 ||
uc == 43215 ||
(uc >= 43256 && uc <= 43258) ||
uc == 43310 ||
uc == 43311 ||
uc == 43359 ||
(uc >= 43457 && uc <= 43469) ||
uc == 43486 ||
uc == 43487 ||
(uc >= 43612 && uc <= 43615) ||
uc == 43742 ||
uc == 43743 ||
uc == 43760 ||
uc == 43761 ||
uc == 44011 ||
uc == 64830 ||
uc == 64831 ||
(uc >= 65040 && uc <= 65049) ||
(uc >= 65072 && uc <= 65106) ||
(uc >= 65108 && uc <= 65121) ||
uc == 65123 ||
uc == 65128 ||
uc == 65130 ||
uc == 65131 ||
(uc >= 65281 && uc <= 65283) ||
(uc >= 65285 && uc <= 65290) ||
(uc >= 65292 && uc <= 65295) ||
uc == 65306 ||
uc == 65307 ||
uc == 65311 ||
uc == 65312 ||
(uc >= 65339 && uc <= 65341) ||
uc == 65343 ||
uc == 65371 ||
uc == 65373 ||
(uc >= 65375 && uc <= 65381) ||
(uc >= 65792 && uc <= 65794) ||
uc == 66463 ||
uc == 66512 ||
uc == 66927 ||
uc == 67671 ||
uc == 67871 ||
uc == 67903 ||
(uc >= 68176 && uc <= 68184) ||
uc == 68223 ||
(uc >= 68336 && uc <= 68342) ||
(uc >= 68409 && uc <= 68415) ||
(uc >= 68505 && uc <= 68508) ||
(uc >= 69703 && uc <= 69709) ||
uc == 69819 ||
uc == 69820 ||
(uc >= 69822 && uc <= 69825) ||
(uc >= 69952 && uc <= 69955) ||
uc == 70004 ||
uc == 70005 ||
(uc >= 70085 && uc <= 70088) ||
uc == 70093 ||
(uc >= 70200 && uc <= 70205) ||
uc == 70854 ||
(uc >= 71105 && uc <= 71113) ||
(uc >= 71233 && uc <= 71235) ||
(uc >= 74864 && uc <= 74868) ||
uc == 92782 ||
uc == 92783 ||
uc == 92917 ||
(uc >= 92983 && uc <= 92987) ||
uc == 92996 ||
int utf8proc_is_punctuation(int32_t uc) {
return (
(uc < 128 && cmark_ispunct((char)uc)) || uc == 161 || uc == 167 ||
uc == 171 || uc == 182 || uc == 183 || uc == 187 || uc == 191 ||
uc == 894 || uc == 903 || (uc >= 1370 && uc <= 1375) || uc == 1417 ||
uc == 1418 || uc == 1470 || uc == 1472 || uc == 1475 || uc == 1478 ||
uc == 1523 || uc == 1524 || uc == 1545 || uc == 1546 || uc == 1548 ||
uc == 1549 || uc == 1563 || uc == 1566 || uc == 1567 ||
(uc >= 1642 && uc <= 1645) || uc == 1748 || (uc >= 1792 && uc <= 1805) ||
(uc >= 2039 && uc <= 2041) || (uc >= 2096 && uc <= 2110) || uc == 2142 ||
uc == 2404 || uc == 2405 || uc == 2416 || uc == 2800 || uc == 3572 ||
uc == 3663 || uc == 3674 || uc == 3675 || (uc >= 3844 && uc <= 3858) ||
uc == 3860 || (uc >= 3898 && uc <= 3901) || uc == 3973 ||
(uc >= 4048 && uc <= 4052) || uc == 4057 || uc == 4058 ||
(uc >= 4170 && uc <= 4175) || uc == 4347 || (uc >= 4960 && uc <= 4968) ||
uc == 5120 || uc == 5741 || uc == 5742 || uc == 5787 || uc == 5788 ||
(uc >= 5867 && uc <= 5869) || uc == 5941 || uc == 5942 ||
(uc >= 6100 && uc <= 6102) || (uc >= 6104 && uc <= 6106) ||
(uc >= 6144 && uc <= 6154) || uc == 6468 || uc == 6469 || uc == 6686 ||
uc == 6687 || (uc >= 6816 && uc <= 6822) || (uc >= 6824 && uc <= 6829) ||
(uc >= 7002 && uc <= 7008) || (uc >= 7164 && uc <= 7167) ||
(uc >= 7227 && uc <= 7231) || uc == 7294 || uc == 7295 ||
(uc >= 7360 && uc <= 7367) || uc == 7379 || (uc >= 8208 && uc <= 8231) ||
(uc >= 8240 && uc <= 8259) || (uc >= 8261 && uc <= 8273) ||
(uc >= 8275 && uc <= 8286) || uc == 8317 || uc == 8318 || uc == 8333 ||
uc == 8334 || (uc >= 8968 && uc <= 8971) || uc == 9001 || uc == 9002 ||
(uc >= 10088 && uc <= 10101) || uc == 10181 || uc == 10182 ||
(uc >= 10214 && uc <= 10223) || (uc >= 10627 && uc <= 10648) ||
(uc >= 10712 && uc <= 10715) || uc == 10748 || uc == 10749 ||
(uc >= 11513 && uc <= 11516) || uc == 11518 || uc == 11519 ||
uc == 11632 || (uc >= 11776 && uc <= 11822) ||
(uc >= 11824 && uc <= 11842) || (uc >= 12289 && uc <= 12291) ||
(uc >= 12296 && uc <= 12305) || (uc >= 12308 && uc <= 12319) ||
uc == 12336 || uc == 12349 || uc == 12448 || uc == 12539 || uc == 42238 ||
uc == 42239 || (uc >= 42509 && uc <= 42511) || uc == 42611 ||
uc == 42622 || (uc >= 42738 && uc <= 42743) ||
(uc >= 43124 && uc <= 43127) || uc == 43214 || uc == 43215 ||
(uc >= 43256 && uc <= 43258) || uc == 43310 || uc == 43311 ||
uc == 43359 || (uc >= 43457 && uc <= 43469) || uc == 43486 ||
uc == 43487 || (uc >= 43612 && uc <= 43615) || uc == 43742 ||
uc == 43743 || uc == 43760 || uc == 43761 || uc == 44011 || uc == 64830 ||
uc == 64831 || (uc >= 65040 && uc <= 65049) ||
(uc >= 65072 && uc <= 65106) || (uc >= 65108 && uc <= 65121) ||
uc == 65123 || uc == 65128 || uc == 65130 || uc == 65131 ||
(uc >= 65281 && uc <= 65283) || (uc >= 65285 && uc <= 65290) ||
(uc >= 65292 && uc <= 65295) || uc == 65306 || uc == 65307 ||
uc == 65311 || uc == 65312 || (uc >= 65339 && uc <= 65341) ||
uc == 65343 || uc == 65371 || uc == 65373 ||
(uc >= 65375 && uc <= 65381) || (uc >= 65792 && uc <= 65794) ||
uc == 66463 || uc == 66512 || uc == 66927 || uc == 67671 || uc == 67871 ||
uc == 67903 || (uc >= 68176 && uc <= 68184) || uc == 68223 ||
(uc >= 68336 && uc <= 68342) || (uc >= 68409 && uc <= 68415) ||
(uc >= 68505 && uc <= 68508) || (uc >= 69703 && uc <= 69709) ||
uc == 69819 || uc == 69820 || (uc >= 69822 && uc <= 69825) ||
(uc >= 69952 && uc <= 69955) || uc == 70004 || uc == 70005 ||
(uc >= 70085 && uc <= 70088) || uc == 70093 ||
(uc >= 70200 && uc <= 70205) || uc == 70854 ||
(uc >= 71105 && uc <= 71113) || (uc >= 71233 && uc <= 71235) ||
(uc >= 74864 && uc <= 74868) || uc == 92782 || uc == 92783 ||
uc == 92917 || (uc >= 92983 && uc <= 92987) || uc == 92996 ||
uc == 113823);
}

View File

@ -11,28 +11,25 @@
// Functions to convert cmark_nodes to XML strings.
static void escape_xml(cmark_strbuf *dest, const unsigned char *source, bufsize_t length)
{
static void escape_xml(cmark_strbuf *dest, const unsigned char *source,
bufsize_t length) {
houdini_escape_html0(dest, source, length, 0);
}
struct render_state {
cmark_strbuf* xml;
cmark_strbuf *xml;
int indent;
};
static inline void indent(struct render_state *state)
{
static inline void indent(struct render_state *state) {
int i;
for (i = 0; i < state->indent; i++) {
cmark_strbuf_putc(state->xml, ' ');
}
}
static int
S_render_node(cmark_node *node, cmark_event_type ev_type,
struct render_state *state, int options)
{
static int S_render_node(cmark_node *node, cmark_event_type ev_type,
struct render_state *state, int options) {
cmark_strbuf *xml = state->xml;
bool literal = false;
cmark_delim_type delim;
@ -45,11 +42,8 @@ S_render_node(cmark_node *node, cmark_event_type ev_type,
cmark_strbuf_puts(xml, cmark_node_get_type_string(node));
if (options & CMARK_OPT_SOURCEPOS && node->start_line != 0) {
sprintf(buffer, " sourcepos=\"%d:%d-%d:%d\"",
node->start_line,
node->start_column,
node->end_line,
node->end_column);
sprintf(buffer, " sourcepos=\"%d:%d-%d:%d\"", node->start_line,
node->start_column, node->end_line, node->end_column);
cmark_strbuf_puts(xml, buffer);
}
@ -61,27 +55,22 @@ S_render_node(cmark_node *node, cmark_event_type ev_type,
case CMARK_NODE_HTML:
case CMARK_NODE_INLINE_HTML:
cmark_strbuf_puts(xml, ">");
escape_xml(xml, node->as.literal.data,
node->as.literal.len);
escape_xml(xml, node->as.literal.data, node->as.literal.len);
cmark_strbuf_puts(xml, "</");
cmark_strbuf_puts(xml,
cmark_node_get_type_string(node));
cmark_strbuf_puts(xml, cmark_node_get_type_string(node));
literal = true;
break;
case CMARK_NODE_LIST:
switch (cmark_node_get_list_type(node)) {
case CMARK_ORDERED_LIST:
cmark_strbuf_puts(xml, " type=\"ordered\"");
sprintf(buffer," start=\"%d\"",
cmark_node_get_list_start(node));
sprintf(buffer, " start=\"%d\"", cmark_node_get_list_start(node));
cmark_strbuf_puts(xml, buffer);
delim = cmark_node_get_list_delim(node);
if (delim == CMARK_PAREN_DELIM) {
cmark_strbuf_puts(xml,
" delim=\"paren\"");
cmark_strbuf_puts(xml, " delim=\"paren\"");
} else if (delim == CMARK_PERIOD_DELIM) {
cmark_strbuf_puts(xml,
" delim=\"period\"");
cmark_strbuf_puts(xml, " delim=\"period\"");
}
break;
case CMARK_BULLET_LIST:
@ -91,39 +80,32 @@ S_render_node(cmark_node *node, cmark_event_type ev_type,
break;
}
sprintf(buffer, " tight=\"%s\"",
(cmark_node_get_list_tight(node) ?
"true" : "false"));
(cmark_node_get_list_tight(node) ? "true" : "false"));
cmark_strbuf_puts(xml, buffer);
break;
case CMARK_NODE_HEADER:
sprintf(buffer, " level=\"%d\"",
node->as.header.level);
sprintf(buffer, " level=\"%d\"", node->as.header.level);
cmark_strbuf_puts(xml, buffer);
break;
case CMARK_NODE_CODE_BLOCK:
if (node->as.code.info.len > 0) {
cmark_strbuf_puts(xml, " info=\"");
escape_xml(xml, node->as.code.info.data,
node->as.code.info.len);
escape_xml(xml, node->as.code.info.data, node->as.code.info.len);
cmark_strbuf_putc(xml, '"');
}
cmark_strbuf_puts(xml, ">");
escape_xml(xml, node->as.code.literal.data,
node->as.code.literal.len);
escape_xml(xml, node->as.code.literal.data, node->as.code.literal.len);
cmark_strbuf_puts(xml, "</");
cmark_strbuf_puts(xml,
cmark_node_get_type_string(node));
cmark_strbuf_puts(xml, cmark_node_get_type_string(node));
literal = true;
break;
case CMARK_NODE_LINK:
case CMARK_NODE_IMAGE:
cmark_strbuf_puts(xml, " destination=\"");
escape_xml(xml, node->as.link.url.data,
node->as.link.url.len);
escape_xml(xml, node->as.link.url.data, node->as.link.url.len);
cmark_strbuf_putc(xml, '"');
cmark_strbuf_puts(xml, " title=\"");
escape_xml(xml, node->as.link.title.data,
node->as.link.title.len);
escape_xml(xml, node->as.link.title.data, node->as.link.title.len);
cmark_strbuf_putc(xml, '"');
break;
default:
@ -136,7 +118,6 @@ S_render_node(cmark_node *node, cmark_event_type ev_type,
}
cmark_strbuf_puts(xml, ">\n");
} else if (node->first_child) {
state->indent -= 2;
indent(state);
@ -148,18 +129,16 @@ S_render_node(cmark_node *node, cmark_event_type ev_type,
return 1;
}
char *cmark_render_xml(cmark_node *root, int options)
{
char *cmark_render_xml(cmark_node *root, int options) {
char *result;
cmark_strbuf xml = GH_BUF_INIT;
cmark_event_type ev_type;
cmark_node *cur;
struct render_state state = { &xml, 0 };
struct render_state state = {&xml, 0};
cmark_iter *iter = cmark_iter_new(root);
cmark_strbuf_puts(state.xml,
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
cmark_strbuf_puts(state.xml, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
cmark_strbuf_puts(state.xml,
"<!DOCTYPE CommonMark SYSTEM \"CommonMark.dtd\">\n");
while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {