mirror of
https://github.com/danbulant/markdown-wasm
synced 2026-05-24 12:35:34 +00:00
md4c: bring in patch mity/md4c#131 and rsms/md4c@strengthen-build Closes #4
This commit is contained in:
parent
cb877fce88
commit
a67763470e
1 changed files with 41 additions and 31 deletions
72
src/md4c.c
72
src/md4c.c
|
|
@ -26,6 +26,7 @@
|
||||||
#include "md4c.h"
|
#include "md4c.h"
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|
@ -71,6 +72,12 @@
|
||||||
#define FALSE 0
|
#define FALSE 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(__has_attribute) && __has_attribute(unused)
|
||||||
|
#define MD_UNUSED __attribute__((unused))
|
||||||
|
#else
|
||||||
|
#define MD_UNUSED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/************************
|
/************************
|
||||||
*** Internal Types ***
|
*** Internal Types ***
|
||||||
|
|
@ -465,7 +472,7 @@ md_text_with_null_replacement(MD_CTX* ctx, MD_TEXTTYPE type, const CHAR* str, SZ
|
||||||
typedef struct MD_UNICODE_FOLD_INFO_tag MD_UNICODE_FOLD_INFO;
|
typedef struct MD_UNICODE_FOLD_INFO_tag MD_UNICODE_FOLD_INFO;
|
||||||
struct MD_UNICODE_FOLD_INFO_tag {
|
struct MD_UNICODE_FOLD_INFO_tag {
|
||||||
unsigned codepoints[3];
|
unsigned codepoints[3];
|
||||||
int n_codepoints;
|
unsigned n_codepoints;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -669,7 +676,7 @@ struct MD_UNICODE_FOLD_INFO_tag {
|
||||||
const unsigned* map;
|
const unsigned* map;
|
||||||
const unsigned* data;
|
const unsigned* data;
|
||||||
size_t map_size;
|
size_t map_size;
|
||||||
int n_codepoints;
|
unsigned n_codepoints;
|
||||||
} FOLD_MAP_LIST[] = {
|
} FOLD_MAP_LIST[] = {
|
||||||
{ FOLD_MAP_1, FOLD_MAP_1_DATA, SIZEOF_ARRAY(FOLD_MAP_1), 1 },
|
{ FOLD_MAP_1, FOLD_MAP_1_DATA, SIZEOF_ARRAY(FOLD_MAP_1), 1 },
|
||||||
{ FOLD_MAP_2, FOLD_MAP_2_DATA, SIZEOF_ARRAY(FOLD_MAP_2), 2 },
|
{ FOLD_MAP_2, FOLD_MAP_2_DATA, SIZEOF_ARRAY(FOLD_MAP_2), 2 },
|
||||||
|
|
@ -689,12 +696,12 @@ struct MD_UNICODE_FOLD_INFO_tag {
|
||||||
|
|
||||||
/* Try to locate the codepoint in any of the maps. */
|
/* Try to locate the codepoint in any of the maps. */
|
||||||
for(i = 0; i < (int) SIZEOF_ARRAY(FOLD_MAP_LIST); i++) {
|
for(i = 0; i < (int) SIZEOF_ARRAY(FOLD_MAP_LIST); i++) {
|
||||||
int index;
|
unsigned index;
|
||||||
|
|
||||||
index = md_unicode_bsearch__(codepoint, FOLD_MAP_LIST[i].map, FOLD_MAP_LIST[i].map_size);
|
index = md_unicode_bsearch__(codepoint, FOLD_MAP_LIST[i].map, FOLD_MAP_LIST[i].map_size);
|
||||||
if(index >= 0) {
|
if(index >= 0) {
|
||||||
/* Found the mapping. */
|
/* Found the mapping. */
|
||||||
int n_codepoints = FOLD_MAP_LIST[i].n_codepoints;
|
unsigned n_codepoints = FOLD_MAP_LIST[i].n_codepoints;
|
||||||
const unsigned* map = FOLD_MAP_LIST[i].map;
|
const unsigned* map = FOLD_MAP_LIST[i].map;
|
||||||
const unsigned* codepoints = FOLD_MAP_LIST[i].data + (index * n_codepoints);
|
const unsigned* codepoints = FOLD_MAP_LIST[i].data + (index * n_codepoints);
|
||||||
|
|
||||||
|
|
@ -886,7 +893,7 @@ struct MD_UNICODE_FOLD_INFO_tag {
|
||||||
* what the caller should allocate.)
|
* what the caller should allocate.)
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
md_merge_lines(MD_CTX* ctx, OFF beg, OFF end, const MD_LINE* lines, int n_lines,
|
md_merge_lines(MD_CTX* ctx, OFF beg, OFF end, const MD_LINE* lines,
|
||||||
CHAR line_break_replacement_char, CHAR* buffer, SZ* p_size)
|
CHAR line_break_replacement_char, CHAR* buffer, SZ* p_size)
|
||||||
{
|
{
|
||||||
CHAR* ptr = buffer;
|
CHAR* ptr = buffer;
|
||||||
|
|
@ -921,7 +928,7 @@ md_merge_lines(MD_CTX* ctx, OFF beg, OFF end, const MD_LINE* lines, int n_lines,
|
||||||
/* Wrapper of md_merge_lines() which allocates new buffer for the output string.
|
/* Wrapper of md_merge_lines() which allocates new buffer for the output string.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
md_merge_lines_alloc(MD_CTX* ctx, OFF beg, OFF end, const MD_LINE* lines, int n_lines,
|
md_merge_lines_alloc(MD_CTX* ctx, OFF beg, OFF end, const MD_LINE* lines,
|
||||||
CHAR line_break_replacement_char, CHAR** p_str, SZ* p_size)
|
CHAR line_break_replacement_char, CHAR** p_str, SZ* p_size)
|
||||||
{
|
{
|
||||||
CHAR* buffer;
|
CHAR* buffer;
|
||||||
|
|
@ -932,7 +939,7 @@ md_merge_lines_alloc(MD_CTX* ctx, OFF beg, OFF end, const MD_LINE* lines, int n_
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
md_merge_lines(ctx, beg, end, lines, n_lines,
|
md_merge_lines(ctx, beg, end, lines,
|
||||||
line_break_replacement_char, buffer, p_size);
|
line_break_replacement_char, buffer, p_size);
|
||||||
|
|
||||||
*p_str = buffer;
|
*p_str = buffer;
|
||||||
|
|
@ -1231,7 +1238,8 @@ md_is_html_any(MD_CTX* ctx, const MD_LINE* lines, int n_lines, OFF beg, OFF max_
|
||||||
****************************/
|
****************************/
|
||||||
|
|
||||||
static int
|
static int
|
||||||
md_is_hex_entity_contents(MD_CTX* ctx, const CHAR* text, OFF beg, OFF max_end, OFF* p_end)
|
md_is_hex_entity_contents(MD_UNUSED MD_CTX* ctx, const CHAR* text,
|
||||||
|
OFF beg, OFF max_end, OFF* p_end)
|
||||||
{
|
{
|
||||||
OFF off = beg;
|
OFF off = beg;
|
||||||
|
|
||||||
|
|
@ -1247,7 +1255,8 @@ md_is_hex_entity_contents(MD_CTX* ctx, const CHAR* text, OFF beg, OFF max_end, O
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
md_is_dec_entity_contents(MD_CTX* ctx, const CHAR* text, OFF beg, OFF max_end, OFF* p_end)
|
md_is_dec_entity_contents(MD_UNUSED MD_CTX* ctx, const CHAR* text,
|
||||||
|
OFF beg, OFF max_end, OFF* p_end)
|
||||||
{
|
{
|
||||||
OFF off = beg;
|
OFF off = beg;
|
||||||
|
|
||||||
|
|
@ -1263,7 +1272,8 @@ md_is_dec_entity_contents(MD_CTX* ctx, const CHAR* text, OFF beg, OFF max_end, O
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
md_is_named_entity_contents(MD_CTX* ctx, const CHAR* text, OFF beg, OFF max_end, OFF* p_end)
|
md_is_named_entity_contents(MD_UNUSED MD_CTX* ctx, const CHAR* text,
|
||||||
|
OFF beg, OFF max_end, OFF* p_end)
|
||||||
{
|
{
|
||||||
OFF off = beg;
|
OFF off = beg;
|
||||||
|
|
||||||
|
|
@ -1369,7 +1379,7 @@ md_build_attr_append_substr(MD_CTX* ctx, MD_ATTRIBUTE_BUILD* build,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
md_free_attribute(MD_CTX* ctx, MD_ATTRIBUTE_BUILD* build)
|
md_free_attribute(MD_UNUSED MD_CTX* ctx, MD_ATTRIBUTE_BUILD* build)
|
||||||
{
|
{
|
||||||
if(build->substr_alloc > 0) {
|
if(build->substr_alloc > 0) {
|
||||||
free(build->text);
|
free(build->text);
|
||||||
|
|
@ -2158,7 +2168,7 @@ md_is_link_reference_definition(MD_CTX* ctx, const MD_LINE* lines, int n_lines)
|
||||||
|
|
||||||
if(label_is_multiline) {
|
if(label_is_multiline) {
|
||||||
MD_CHECK(md_merge_lines_alloc(ctx, label_contents_beg, label_contents_end,
|
MD_CHECK(md_merge_lines_alloc(ctx, label_contents_beg, label_contents_end,
|
||||||
lines + label_contents_line_index, n_lines - label_contents_line_index,
|
lines + label_contents_line_index,
|
||||||
_T(' '), &def->label, &def->label_size));
|
_T(' '), &def->label, &def->label_size));
|
||||||
def->label_needs_free = TRUE;
|
def->label_needs_free = TRUE;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -2168,7 +2178,7 @@ md_is_link_reference_definition(MD_CTX* ctx, const MD_LINE* lines, int n_lines)
|
||||||
|
|
||||||
if(title_is_multiline) {
|
if(title_is_multiline) {
|
||||||
MD_CHECK(md_merge_lines_alloc(ctx, title_contents_beg, title_contents_end,
|
MD_CHECK(md_merge_lines_alloc(ctx, title_contents_beg, title_contents_end,
|
||||||
lines + title_contents_line_index, n_lines - title_contents_line_index,
|
lines + title_contents_line_index,
|
||||||
_T('\n'), &def->title, &def->title_size));
|
_T('\n'), &def->title, &def->title_size));
|
||||||
def->title_needs_free = TRUE;
|
def->title_needs_free = TRUE;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -2221,8 +2231,7 @@ md_is_link_reference(MD_CTX* ctx, const MD_LINE* lines, int n_lines,
|
||||||
end_line++;
|
end_line++;
|
||||||
|
|
||||||
if(beg_line != end_line) {
|
if(beg_line != end_line) {
|
||||||
MD_CHECK(md_merge_lines_alloc(ctx, beg, end, beg_line,
|
MD_CHECK(md_merge_lines_alloc(ctx, beg, end, beg_line, _T(' '), &label, &label_size));
|
||||||
n_lines - (beg_line - lines), _T(' '), &label, &label_size));
|
|
||||||
} else {
|
} else {
|
||||||
label = (CHAR*) STR(beg);
|
label = (CHAR*) STR(beg);
|
||||||
label_size = end - beg;
|
label_size = end - beg;
|
||||||
|
|
@ -2331,7 +2340,7 @@ md_is_inline_link_spec(MD_CTX* ctx, const MD_LINE* lines, int n_lines,
|
||||||
attr->title_needs_free = FALSE;
|
attr->title_needs_free = FALSE;
|
||||||
} else {
|
} else {
|
||||||
MD_CHECK(md_merge_lines_alloc(ctx, title_contents_beg, title_contents_end,
|
MD_CHECK(md_merge_lines_alloc(ctx, title_contents_beg, title_contents_end,
|
||||||
lines + title_contents_line_index, n_lines - title_contents_line_index,
|
lines + title_contents_line_index,
|
||||||
_T('\n'), &attr->title, &attr->title_size));
|
_T('\n'), &attr->title, &attr->title_size));
|
||||||
attr->title_needs_free = TRUE;
|
attr->title_needs_free = TRUE;
|
||||||
}
|
}
|
||||||
|
|
@ -3378,8 +3387,7 @@ md_analyze_bracket(MD_CTX* ctx, int mark_index)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Forward declaration. */
|
/* Forward declaration. */
|
||||||
static void md_analyze_link_contents(MD_CTX* ctx, const MD_LINE* lines, int n_lines,
|
static void md_analyze_link_contents(MD_CTX* ctx, int mark_beg, int mark_end);
|
||||||
int mark_beg, int mark_end);
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
md_resolve_links(MD_CTX* ctx, const MD_LINE* lines, int n_lines)
|
md_resolve_links(MD_CTX* ctx, const MD_LINE* lines, int n_lines)
|
||||||
|
|
@ -3498,7 +3506,7 @@ md_resolve_links(MD_CTX* ctx, const MD_LINE* lines, int n_lines)
|
||||||
if(delim != NULL) {
|
if(delim != NULL) {
|
||||||
delim->flags |= MD_MARK_RESOLVED;
|
delim->flags |= MD_MARK_RESOLVED;
|
||||||
md_rollback(ctx, opener_index, delim_index, MD_ROLLBACK_ALL);
|
md_rollback(ctx, opener_index, delim_index, MD_ROLLBACK_ALL);
|
||||||
md_analyze_link_contents(ctx, lines, n_lines, opener_index+1, closer_index);
|
md_analyze_link_contents(ctx, opener_index+1, closer_index);
|
||||||
} else {
|
} else {
|
||||||
md_rollback(ctx, opener_index, closer_index, MD_ROLLBACK_ALL);
|
md_rollback(ctx, opener_index, closer_index, MD_ROLLBACK_ALL);
|
||||||
}
|
}
|
||||||
|
|
@ -3523,6 +3531,10 @@ md_resolve_links(MD_CTX* ctx, const MD_LINE* lines, int n_lines)
|
||||||
if(is_link) {
|
if(is_link) {
|
||||||
/* Eat the 2nd "[...]". */
|
/* Eat the 2nd "[...]". */
|
||||||
closer->end = next_closer->end;
|
closer->end = next_closer->end;
|
||||||
|
|
||||||
|
/* Do not analyze the label as a standalone link in the next
|
||||||
|
* iteration. */
|
||||||
|
next_index = ctx->marks[next_index].prev;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(closer->end < ctx->size && CH(closer->end) == _T('(')) {
|
if(closer->end < ctx->size && CH(closer->end) == _T('(')) {
|
||||||
|
|
@ -3599,7 +3611,7 @@ md_resolve_links(MD_CTX* ctx, const MD_LINE* lines, int n_lines)
|
||||||
last_img_end = closer->end;
|
last_img_end = closer->end;
|
||||||
}
|
}
|
||||||
|
|
||||||
md_analyze_link_contents(ctx, lines, n_lines, opener_index+1, closer_index);
|
md_analyze_link_contents(ctx, opener_index+1, closer_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
opener_index = next_index;
|
opener_index = next_index;
|
||||||
|
|
@ -3678,7 +3690,7 @@ md_analyze_emph(MD_CTX* ctx, int mark_index)
|
||||||
/* If we can be a closer, try to resolve with the preceding opener. */
|
/* If we can be a closer, try to resolve with the preceding opener. */
|
||||||
if(mark->flags & MD_MARK_POTENTIAL_CLOSER) {
|
if(mark->flags & MD_MARK_POTENTIAL_CLOSER) {
|
||||||
MD_MARK* opener = NULL;
|
MD_MARK* opener = NULL;
|
||||||
int opener_index;
|
int opener_index = 0;
|
||||||
|
|
||||||
if(mark->ch == _T('*')) {
|
if(mark->ch == _T('*')) {
|
||||||
MD_MARKCHAIN* opener_chains[6];
|
MD_MARKCHAIN* opener_chains[6];
|
||||||
|
|
@ -3913,8 +3925,7 @@ md_analyze_permissive_email_autolink(MD_CTX* ctx, int mark_index)
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
md_analyze_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines,
|
md_analyze_marks(MD_CTX* ctx, int mark_beg, int mark_end, const CHAR* mark_chars)
|
||||||
int mark_beg, int mark_end, const CHAR* mark_chars)
|
|
||||||
{
|
{
|
||||||
int i = mark_beg;
|
int i = mark_beg;
|
||||||
|
|
||||||
|
|
@ -3972,10 +3983,10 @@ md_analyze_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mod
|
||||||
|
|
||||||
/* We analyze marks in few groups to handle their precedence. */
|
/* We analyze marks in few groups to handle their precedence. */
|
||||||
/* (1) Entities; code spans; autolinks; raw HTML. */
|
/* (1) Entities; code spans; autolinks; raw HTML. */
|
||||||
md_analyze_marks(ctx, lines, n_lines, 0, ctx->n_marks, _T("&"));
|
md_analyze_marks(ctx, 0, ctx->n_marks, _T("&"));
|
||||||
|
|
||||||
/* (2) Links. */
|
/* (2) Links. */
|
||||||
md_analyze_marks(ctx, lines, n_lines, 0, ctx->n_marks, _T("[]!"));
|
md_analyze_marks(ctx, 0, ctx->n_marks, _T("[]!"));
|
||||||
MD_CHECK(md_resolve_links(ctx, lines, n_lines));
|
MD_CHECK(md_resolve_links(ctx, lines, n_lines));
|
||||||
BRACKET_OPENERS.head = -1;
|
BRACKET_OPENERS.head = -1;
|
||||||
BRACKET_OPENERS.tail = -1;
|
BRACKET_OPENERS.tail = -1;
|
||||||
|
|
@ -3990,24 +4001,23 @@ md_analyze_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mod
|
||||||
TABLECELLBOUNDARIES.head = -1;
|
TABLECELLBOUNDARIES.head = -1;
|
||||||
TABLECELLBOUNDARIES.tail = -1;
|
TABLECELLBOUNDARIES.tail = -1;
|
||||||
ctx->n_table_cell_boundaries = 0;
|
ctx->n_table_cell_boundaries = 0;
|
||||||
md_analyze_marks(ctx, lines, n_lines, 0, ctx->n_marks, _T("|"));
|
md_analyze_marks(ctx, 0, ctx->n_marks, _T("|"));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (4) Emphasis and strong emphasis; permissive autolinks. */
|
/* (4) Emphasis and strong emphasis; permissive autolinks. */
|
||||||
md_analyze_link_contents(ctx, lines, n_lines, 0, ctx->n_marks);
|
md_analyze_link_contents(ctx, 0, ctx->n_marks);
|
||||||
|
|
||||||
abort:
|
abort:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
md_analyze_link_contents(MD_CTX* ctx, const MD_LINE* lines, int n_lines,
|
md_analyze_link_contents(MD_CTX* ctx, int mark_beg, int mark_end)
|
||||||
int mark_beg, int mark_end)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
md_analyze_marks(ctx, lines, n_lines, mark_beg, mark_end, _T("*_~$@:."));
|
md_analyze_marks(ctx, mark_beg, mark_end, _T("*_~$@:."));
|
||||||
|
|
||||||
for(i = OPENERS_CHAIN_FIRST; i <= OPENERS_CHAIN_LAST; i++) {
|
for(i = OPENERS_CHAIN_FIRST; i <= OPENERS_CHAIN_LAST; i++) {
|
||||||
ctx->mark_chains[i].head = -1;
|
ctx->mark_chains[i].head = -1;
|
||||||
|
|
@ -5654,7 +5664,7 @@ md_line_indentation(MD_CTX* ctx, unsigned total_indent, OFF beg, OFF* p_end)
|
||||||
return indent - total_indent;
|
return indent - total_indent;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const MD_LINE_ANALYSIS md_dummy_blank_line = { MD_LINE_BLANK, 0 };
|
static const MD_LINE_ANALYSIS md_dummy_blank_line = { MD_LINE_BLANK, 0, 0, 0, 0 };
|
||||||
|
|
||||||
/* Analyze type of the line and find some its properties. This serves as a
|
/* Analyze type of the line and find some its properties. This serves as a
|
||||||
* main input for determining type and boundaries of a block. */
|
* main input for determining type and boundaries of a block. */
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue