Upgrade md4c to 0.4.7
Change-Id: I9400c2df13c30fb0bc14728a0c44851c2d1e9079 Pick-to: 6.0 5.15 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
This commit is contained in:
parent
1b4d70676c
commit
1f4434a8e2
2
src/3rdparty/md4c/LICENSE.md
vendored
2
src/3rdparty/md4c/LICENSE.md
vendored
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
# The MIT License (MIT)
|
# The MIT License (MIT)
|
||||||
|
|
||||||
Copyright © 2016-2019 Martin Mitáš
|
Copyright © 2016-2020 Martin Mitáš
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the “Software”),
|
copy of this software and associated documentation files (the “Software”),
|
||||||
|
187
src/3rdparty/md4c/md4c.c
vendored
187
src/3rdparty/md4c/md4c.c
vendored
@ -72,6 +72,48 @@
|
|||||||
#define FALSE 0
|
#define FALSE 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define MD_LOG(msg) \
|
||||||
|
do { \
|
||||||
|
if(ctx->parser.debug_log != NULL) \
|
||||||
|
ctx->parser.debug_log((msg), ctx->userdata); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
#define MD_ASSERT(cond) \
|
||||||
|
do { \
|
||||||
|
if(!(cond)) { \
|
||||||
|
MD_LOG(__FILE__ ":" STRINGIZE(__LINE__) ": " \
|
||||||
|
"Assertion '" STRINGIZE(cond) "' failed."); \
|
||||||
|
exit(1); \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define MD_UNREACHABLE() MD_ASSERT(1 == 0)
|
||||||
|
#else
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define MD_ASSERT(cond) do { if(!(cond)) __builtin_unreachable(); } while(0)
|
||||||
|
#define MD_UNREACHABLE() do { __builtin_unreachable(); } while(0)
|
||||||
|
#elif defined _MSC_VER && _MSC_VER > 120
|
||||||
|
#define MD_ASSERT(cond) do { __assume(cond); } while(0)
|
||||||
|
#define MD_UNREACHABLE() do { __assume(0); } while(0)
|
||||||
|
#else
|
||||||
|
#define MD_ASSERT(cond) do {} while(0)
|
||||||
|
#define MD_UNREACHABLE() do {} while(0)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* For falling through case labels in switch statements. */
|
||||||
|
#if defined __clang__ && __clang_major__ >= 12
|
||||||
|
#define MD_FALLTHROUGH() __attribute__((fallthrough))
|
||||||
|
#elif defined __GNUC__ && __GNUC__ >= 7
|
||||||
|
#define MD_FALLTHROUGH() __attribute__((fallthrough))
|
||||||
|
#else
|
||||||
|
#define MD_FALLTHROUGH() ((void)0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Suppress "unused parameter" warnings. */
|
||||||
|
#define MD_UNUSED(x) ((void)x)
|
||||||
|
|
||||||
|
|
||||||
/************************
|
/************************
|
||||||
*** Internal Types ***
|
*** Internal Types ***
|
||||||
@ -230,41 +272,6 @@ struct MD_VERBATIMLINE_tag {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*******************
|
|
||||||
*** Debugging ***
|
|
||||||
*******************/
|
|
||||||
|
|
||||||
#define MD_LOG(msg) \
|
|
||||||
do { \
|
|
||||||
if(ctx->parser.debug_log != NULL) \
|
|
||||||
ctx->parser.debug_log((msg), ctx->userdata); \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
#define MD_ASSERT(cond) \
|
|
||||||
do { \
|
|
||||||
if(!(cond)) { \
|
|
||||||
MD_LOG(__FILE__ ":" STRINGIZE(__LINE__) ": " \
|
|
||||||
"Assertion '" STRINGIZE(cond) "' failed."); \
|
|
||||||
exit(1); \
|
|
||||||
} \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
#define MD_UNREACHABLE() MD_ASSERT(1 == 0)
|
|
||||||
#else
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#define MD_ASSERT(cond) do { if(!(cond)) __builtin_unreachable(); } while(0)
|
|
||||||
#define MD_UNREACHABLE() do { __builtin_unreachable(); } while(0)
|
|
||||||
#elif defined _MSC_VER && _MSC_VER > 120
|
|
||||||
#define MD_ASSERT(cond) do { __assume(cond); } while(0)
|
|
||||||
#define MD_UNREACHABLE() do { __assume(0); } while(0)
|
|
||||||
#else
|
|
||||||
#define MD_ASSERT(cond) do {} while(0)
|
|
||||||
#define MD_UNREACHABLE() do {} while(0)
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*****************
|
/*****************
|
||||||
*** Helpers ***
|
*** Helpers ***
|
||||||
*****************/
|
*****************/
|
||||||
@ -466,7 +473,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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -670,7 +677,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 },
|
||||||
@ -695,7 +702,7 @@ struct MD_UNICODE_FOLD_INFO_tag {
|
|||||||
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);
|
||||||
|
|
||||||
@ -894,6 +901,8 @@ md_merge_lines(MD_CTX* ctx, OFF beg, OFF end, const MD_LINE* lines, int n_lines,
|
|||||||
int line_index = 0;
|
int line_index = 0;
|
||||||
OFF off = beg;
|
OFF off = beg;
|
||||||
|
|
||||||
|
MD_UNUSED(n_lines);
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
const MD_LINE* line = &lines[line_index];
|
const MD_LINE* line = &lines[line_index];
|
||||||
OFF line_end = line->end;
|
OFF line_end = line->end;
|
||||||
@ -1235,6 +1244,7 @@ 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_CTX* ctx, const CHAR* text, OFF beg, OFF max_end, OFF* p_end)
|
||||||
{
|
{
|
||||||
OFF off = beg;
|
OFF off = beg;
|
||||||
|
MD_UNUSED(ctx);
|
||||||
|
|
||||||
while(off < max_end && ISXDIGIT_(text[off]) && off - beg <= 8)
|
while(off < max_end && ISXDIGIT_(text[off]) && off - beg <= 8)
|
||||||
off++;
|
off++;
|
||||||
@ -1251,6 +1261,7 @@ 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_CTX* ctx, const CHAR* text, OFF beg, OFF max_end, OFF* p_end)
|
||||||
{
|
{
|
||||||
OFF off = beg;
|
OFF off = beg;
|
||||||
|
MD_UNUSED(ctx);
|
||||||
|
|
||||||
while(off < max_end && ISDIGIT_(text[off]) && off - beg <= 8)
|
while(off < max_end && ISDIGIT_(text[off]) && off - beg <= 8)
|
||||||
off++;
|
off++;
|
||||||
@ -1267,6 +1278,7 @@ 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_CTX* ctx, const CHAR* text, OFF beg, OFF max_end, OFF* p_end)
|
||||||
{
|
{
|
||||||
OFF off = beg;
|
OFF off = beg;
|
||||||
|
MD_UNUSED(ctx);
|
||||||
|
|
||||||
if(off < max_end && ISALPHA_(text[off]))
|
if(off < max_end && ISALPHA_(text[off]))
|
||||||
off++;
|
off++;
|
||||||
@ -1372,6 +1384,8 @@ 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_CTX* ctx, MD_ATTRIBUTE_BUILD* build)
|
||||||
{
|
{
|
||||||
|
MD_UNUSED(ctx);
|
||||||
|
|
||||||
if(build->substr_alloc > 0) {
|
if(build->substr_alloc > 0) {
|
||||||
free(build->text);
|
free(build->text);
|
||||||
free(build->substr_types);
|
free(build->substr_types);
|
||||||
@ -1547,12 +1561,6 @@ md_link_label_cmp_load_fold_info(const CHAR* label, OFF off, SZ size,
|
|||||||
goto whitespace;
|
goto whitespace;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ISNEWLINE_(label[off])) {
|
|
||||||
/* Treat new lines as a whitespace. */
|
|
||||||
off++;
|
|
||||||
goto whitespace;
|
|
||||||
}
|
|
||||||
|
|
||||||
codepoint = md_decode_unicode(label, off, size, &char_size);
|
codepoint = md_decode_unicode(label, off, size, &char_size);
|
||||||
off += char_size;
|
off += char_size;
|
||||||
if(ISUNICODEWHITESPACE_(codepoint)) {
|
if(ISUNICODEWHITESPACE_(codepoint)) {
|
||||||
@ -1575,8 +1583,6 @@ md_link_label_cmp(const CHAR* a_label, SZ a_size, const CHAR* b_label, SZ b_size
|
|||||||
{
|
{
|
||||||
OFF a_off;
|
OFF a_off;
|
||||||
OFF b_off;
|
OFF b_off;
|
||||||
int a_reached_end = FALSE;
|
|
||||||
int b_reached_end = FALSE;
|
|
||||||
MD_UNICODE_FOLD_INFO a_fi = { { 0 }, 0 };
|
MD_UNICODE_FOLD_INFO a_fi = { { 0 }, 0 };
|
||||||
MD_UNICODE_FOLD_INFO b_fi = { { 0 }, 0 };
|
MD_UNICODE_FOLD_INFO b_fi = { { 0 }, 0 };
|
||||||
OFF a_fi_off = 0;
|
OFF a_fi_off = 0;
|
||||||
@ -1585,17 +1591,17 @@ md_link_label_cmp(const CHAR* a_label, SZ a_size, const CHAR* b_label, SZ b_size
|
|||||||
|
|
||||||
a_off = md_skip_unicode_whitespace(a_label, 0, a_size);
|
a_off = md_skip_unicode_whitespace(a_label, 0, a_size);
|
||||||
b_off = md_skip_unicode_whitespace(b_label, 0, b_size);
|
b_off = md_skip_unicode_whitespace(b_label, 0, b_size);
|
||||||
while(!a_reached_end || !b_reached_end) {
|
while(a_off < a_size || a_fi_off < a_fi.n_codepoints ||
|
||||||
|
b_off < b_size || b_fi_off < b_fi.n_codepoints)
|
||||||
|
{
|
||||||
/* If needed, load fold info for next char. */
|
/* If needed, load fold info for next char. */
|
||||||
if(a_fi_off >= a_fi.n_codepoints) {
|
if(a_fi_off >= a_fi.n_codepoints) {
|
||||||
a_fi_off = 0;
|
a_fi_off = 0;
|
||||||
a_off = md_link_label_cmp_load_fold_info(a_label, a_off, a_size, &a_fi);
|
a_off = md_link_label_cmp_load_fold_info(a_label, a_off, a_size, &a_fi);
|
||||||
a_reached_end = (a_off >= a_size);
|
|
||||||
}
|
}
|
||||||
if(b_fi_off >= b_fi.n_codepoints) {
|
if(b_fi_off >= b_fi.n_codepoints) {
|
||||||
b_fi_off = 0;
|
b_fi_off = 0;
|
||||||
b_off = md_link_label_cmp_load_fold_info(b_label, b_off, b_size, &b_fi);
|
b_off = md_link_label_cmp_load_fold_info(b_label, b_off, b_size, &b_fi);
|
||||||
b_reached_end = (b_off >= b_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cmp = b_fi.codepoints[b_fi_off] - a_fi.codepoints[a_fi_off];
|
cmp = b_fi.codepoints[b_fi_off] - a_fi.codepoints[a_fi_off];
|
||||||
@ -2671,7 +2677,7 @@ md_rollback(MD_CTX* ctx, int opener_index, int closer_index, int how)
|
|||||||
mark_index = mark->prev;
|
mark_index = mark->prev;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* Pass through. */
|
MD_FALLTHROUGH();
|
||||||
default:
|
default:
|
||||||
mark_index--;
|
mark_index--;
|
||||||
break;
|
break;
|
||||||
@ -3227,7 +3233,7 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode)
|
|||||||
/* Push a dummy as a reserve for a closer. */
|
/* Push a dummy as a reserve for a closer. */
|
||||||
PUSH_MARK('D', off, off, 0);
|
PUSH_MARK('D', off, off, 0);
|
||||||
off += 1 + suffix_size;
|
off += 1 + suffix_size;
|
||||||
continue;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3524,6 +3530,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('(')) {
|
||||||
@ -3679,7 +3689,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];
|
||||||
@ -3806,6 +3816,7 @@ md_analyze_permissive_url_autolink(MD_CTX* ctx, int mark_index)
|
|||||||
int has_underscore_in_last_seg = FALSE;
|
int has_underscore_in_last_seg = FALSE;
|
||||||
int has_underscore_in_next_to_last_seg = FALSE;
|
int has_underscore_in_next_to_last_seg = FALSE;
|
||||||
int n_opened_parenthesis = 0;
|
int n_opened_parenthesis = 0;
|
||||||
|
int n_excess_parenthesis = 0;
|
||||||
|
|
||||||
/* Check for domain. */
|
/* Check for domain. */
|
||||||
while(off < ctx->size) {
|
while(off < ctx->size) {
|
||||||
@ -3844,17 +3855,28 @@ md_analyze_permissive_url_autolink(MD_CTX* ctx, int mark_index)
|
|||||||
if(n_opened_parenthesis > 0)
|
if(n_opened_parenthesis > 0)
|
||||||
n_opened_parenthesis--;
|
n_opened_parenthesis--;
|
||||||
else
|
else
|
||||||
break;
|
n_excess_parenthesis++;
|
||||||
}
|
}
|
||||||
|
|
||||||
off++;
|
off++;
|
||||||
}
|
}
|
||||||
/* These cannot be last char In such case they are more likely normal
|
|
||||||
* punctuation. */
|
|
||||||
if(ISANYOF(off-1, _T("?!.,:*_~")))
|
|
||||||
off--;
|
|
||||||
|
|
||||||
/* Ok. Lets call it auto-link. Adapt opener and create closer to zero
|
/* Trim a trailing punctuation from the end. */
|
||||||
|
while(TRUE) {
|
||||||
|
if(ISANYOF(off-1, _T("?!.,:*_~"))) {
|
||||||
|
off--;
|
||||||
|
} else if(CH(off-1) == ')' && n_excess_parenthesis > 0) {
|
||||||
|
/* Unmatched ')' can be in an interior of the path but not at the
|
||||||
|
* of it, so the auto-link may be safely nested in a parenthesis
|
||||||
|
* pair. */
|
||||||
|
off--;
|
||||||
|
n_excess_parenthesis--;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ok. Lets call it an auto-link. Adapt opener and create closer to zero
|
||||||
* length so all the contents becomes the link text. */
|
* length so all the contents becomes the link text. */
|
||||||
MD_ASSERT(closer->ch == 'D');
|
MD_ASSERT(closer->ch == 'D');
|
||||||
opener->end = opener->beg;
|
opener->end = opener->beg;
|
||||||
@ -3918,6 +3940,8 @@ md_analyze_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines,
|
|||||||
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;
|
||||||
|
MD_UNUSED(lines);
|
||||||
|
MD_UNUSED(n_lines);
|
||||||
|
|
||||||
while(i < mark_end) {
|
while(i < mark_end) {
|
||||||
MD_MARK* mark = &ctx->marks[i];
|
MD_MARK* mark = &ctx->marks[i];
|
||||||
@ -4136,7 +4160,7 @@ md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* Fall though. */
|
MD_FALLTHROUGH();
|
||||||
|
|
||||||
case '*': /* Emphasis, strong emphasis. */
|
case '*': /* Emphasis, strong emphasis. */
|
||||||
if(mark->flags & MD_MARK_OPENER) {
|
if(mark->flags & MD_MARK_OPENER) {
|
||||||
@ -4235,6 +4259,7 @@ md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* Pass through, if auto-link. */
|
/* Pass through, if auto-link. */
|
||||||
|
MD_FALLTHROUGH();
|
||||||
|
|
||||||
case '@': /* Permissive e-mail autolink. */
|
case '@': /* Permissive e-mail autolink. */
|
||||||
case ':': /* Permissive URL autolink. */
|
case ':': /* Permissive URL autolink. */
|
||||||
@ -4491,12 +4516,14 @@ md_process_table_block_contents(MD_CTX* ctx, int col_count, const MD_LINE* lines
|
|||||||
lines[0].beg, lines[0].end, align, col_count));
|
lines[0].beg, lines[0].end, align, col_count));
|
||||||
MD_LEAVE_BLOCK(MD_BLOCK_THEAD, NULL);
|
MD_LEAVE_BLOCK(MD_BLOCK_THEAD, NULL);
|
||||||
|
|
||||||
|
if(n_lines > 2) {
|
||||||
MD_ENTER_BLOCK(MD_BLOCK_TBODY, NULL);
|
MD_ENTER_BLOCK(MD_BLOCK_TBODY, NULL);
|
||||||
for(i = 2; i < n_lines; i++) {
|
for(i = 2; i < n_lines; i++) {
|
||||||
MD_CHECK(md_process_table_row(ctx, MD_BLOCK_TD,
|
MD_CHECK(md_process_table_row(ctx, MD_BLOCK_TD,
|
||||||
lines[i].beg, lines[i].end, align, col_count));
|
lines[i].beg, lines[i].end, align, col_count));
|
||||||
}
|
}
|
||||||
MD_LEAVE_BLOCK(MD_BLOCK_TBODY, NULL);
|
MD_LEAVE_BLOCK(MD_BLOCK_TBODY, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
abort:
|
abort:
|
||||||
free(align);
|
free(align);
|
||||||
@ -4665,6 +4692,7 @@ md_process_leaf_block(MD_CTX* ctx, const MD_BLOCK* block)
|
|||||||
union {
|
union {
|
||||||
MD_BLOCK_H_DETAIL header;
|
MD_BLOCK_H_DETAIL header;
|
||||||
MD_BLOCK_CODE_DETAIL code;
|
MD_BLOCK_CODE_DETAIL code;
|
||||||
|
MD_BLOCK_TABLE_DETAIL table;
|
||||||
} det;
|
} det;
|
||||||
MD_ATTRIBUTE_BUILD info_build;
|
MD_ATTRIBUTE_BUILD info_build;
|
||||||
MD_ATTRIBUTE_BUILD lang_build;
|
MD_ATTRIBUTE_BUILD lang_build;
|
||||||
@ -4693,6 +4721,12 @@ md_process_leaf_block(MD_CTX* ctx, const MD_BLOCK* block)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MD_BLOCK_TABLE:
|
||||||
|
det.table.col_count = block->data;
|
||||||
|
det.table.head_row_count = 1;
|
||||||
|
det.table.body_row_count = block->n_lines - 2;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* Noop. */
|
/* Noop. */
|
||||||
break;
|
break;
|
||||||
@ -5504,7 +5538,7 @@ md_enter_child_containers(MD_CTX* ctx, int n_children, unsigned data)
|
|||||||
case _T(')'):
|
case _T(')'):
|
||||||
case _T('.'):
|
case _T('.'):
|
||||||
is_ordered_list = TRUE;
|
is_ordered_list = TRUE;
|
||||||
/* Pass through */
|
MD_FALLTHROUGH();
|
||||||
|
|
||||||
case _T('-'):
|
case _T('-'):
|
||||||
case _T('+'):
|
case _T('+'):
|
||||||
@ -5550,7 +5584,7 @@ md_leave_child_containers(MD_CTX* ctx, int n_keep)
|
|||||||
case _T(')'):
|
case _T(')'):
|
||||||
case _T('.'):
|
case _T('.'):
|
||||||
is_ordered_list = TRUE;
|
is_ordered_list = TRUE;
|
||||||
/* Pass through */
|
MD_FALLTHROUGH();
|
||||||
|
|
||||||
case _T('-'):
|
case _T('-'):
|
||||||
case _T('+'):
|
case _T('+'):
|
||||||
@ -5586,11 +5620,11 @@ md_is_container_mark(MD_CTX* ctx, unsigned indent, OFF beg, OFF* p_end, MD_CONTA
|
|||||||
OFF off = beg;
|
OFF off = beg;
|
||||||
OFF max_end;
|
OFF max_end;
|
||||||
|
|
||||||
if(indent >= ctx->code_indent_offset)
|
if(off >= ctx->size || indent >= ctx->code_indent_offset)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* Check for block quote mark. */
|
/* Check for block quote mark. */
|
||||||
if(off < ctx->size && CH(off) == _T('>')) {
|
if(CH(off) == _T('>')) {
|
||||||
off++;
|
off++;
|
||||||
p_container->ch = _T('>');
|
p_container->ch = _T('>');
|
||||||
p_container->is_loose = FALSE;
|
p_container->is_loose = FALSE;
|
||||||
@ -5602,7 +5636,7 @@ md_is_container_mark(MD_CTX* ctx, unsigned indent, OFF beg, OFF* p_end, MD_CONTA
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check for list item bullet mark. */
|
/* Check for list item bullet mark. */
|
||||||
if(off+1 < ctx->size && ISANYOF(off, _T("-+*")) && (ISBLANK(off+1) || ISNEWLINE(off+1))) {
|
if(ISANYOF(off, _T("-+*")) && (off+1 >= ctx->size || ISBLANK(off+1) || ISNEWLINE(off+1))) {
|
||||||
p_container->ch = CH(off);
|
p_container->ch = CH(off);
|
||||||
p_container->is_loose = FALSE;
|
p_container->is_loose = FALSE;
|
||||||
p_container->is_task = FALSE;
|
p_container->is_task = FALSE;
|
||||||
@ -5621,9 +5655,9 @@ md_is_container_mark(MD_CTX* ctx, unsigned indent, OFF beg, OFF* p_end, MD_CONTA
|
|||||||
p_container->start = p_container->start * 10 + CH(off) - _T('0');
|
p_container->start = p_container->start * 10 + CH(off) - _T('0');
|
||||||
off++;
|
off++;
|
||||||
}
|
}
|
||||||
if(off > beg && off+1 < ctx->size &&
|
if(off > beg &&
|
||||||
(CH(off) == _T('.') || CH(off) == _T(')')) &&
|
(CH(off) == _T('.') || CH(off) == _T(')')) &&
|
||||||
(ISBLANK(off+1) || ISNEWLINE(off+1)))
|
(off+1 >= ctx->size || ISBLANK(off+1) || ISNEWLINE(off+1)))
|
||||||
{
|
{
|
||||||
p_container->ch = CH(off);
|
p_container->ch = CH(off);
|
||||||
p_container->is_loose = FALSE;
|
p_container->is_loose = FALSE;
|
||||||
@ -5655,7 +5689,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. */
|
||||||
@ -5786,12 +5820,14 @@ md_analyze_line(MD_CTX* ctx, OFF beg, OFF* p_end,
|
|||||||
#if 1
|
#if 1
|
||||||
/* See https://github.com/mity/md4c/issues/6
|
/* See https://github.com/mity/md4c/issues/6
|
||||||
*
|
*
|
||||||
* This ugly checking tests we are in (yet empty) list item but not
|
* This ugly checking tests we are in (yet empty) list item but
|
||||||
* its very first line (with the list item mark).
|
* not its very first line (i.e. not the line with the list
|
||||||
|
* item mark).
|
||||||
*
|
*
|
||||||
* If we are such blank line, then any following non-blank line
|
* If we are such a blank line, then any following non-blank
|
||||||
* which would be part of this list item actually ends the list
|
* line which would be part of the list item actually has to
|
||||||
* because "a list item can begin with at most one blank line."
|
* end the list because according to the specification, "a list
|
||||||
|
* item can begin with at most one blank line."
|
||||||
*/
|
*/
|
||||||
if(n_parents > 0 && ctx->containers[n_parents-1].ch != _T('>') &&
|
if(n_parents > 0 && ctx->containers[n_parents-1].ch != _T('>') &&
|
||||||
n_brothers + n_children == 0 && ctx->current_block == NULL &&
|
n_brothers + n_children == 0 && ctx->current_block == NULL &&
|
||||||
@ -5806,9 +5842,10 @@ md_analyze_line(MD_CTX* ctx, OFF beg, OFF* p_end,
|
|||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
#if 1
|
#if 1
|
||||||
/* This is 2nd half of the hack. If the flag is set (that is there
|
/* This is the 2nd half of the hack. If the flag is set (i.e. there
|
||||||
* were 2nd blank line at the start of the list item) and we would also
|
* was a 2nd blank line at the beginning of the list item) and if
|
||||||
* belonging to such list item, than interrupt the list. */
|
* we would otherwise still belong to the list item, we enforce
|
||||||
|
* the end of the list. */
|
||||||
ctx->last_line_has_list_loosening_effect = FALSE;
|
ctx->last_line_has_list_loosening_effect = FALSE;
|
||||||
if(ctx->last_list_item_starts_with_two_blank_lines) {
|
if(ctx->last_list_item_starts_with_two_blank_lines) {
|
||||||
if(n_parents > 0 && ctx->containers[n_parents-1].ch != _T('>') &&
|
if(n_parents > 0 && ctx->containers[n_parents-1].ch != _T('>') &&
|
||||||
|
10
src/3rdparty/md4c/md4c.h
vendored
10
src/3rdparty/md4c/md4c.h
vendored
@ -91,7 +91,8 @@ typedef enum MD_BLOCKTYPE {
|
|||||||
MD_BLOCK_P,
|
MD_BLOCK_P,
|
||||||
|
|
||||||
/* <table>...</table> and its contents.
|
/* <table>...</table> and its contents.
|
||||||
* Detail: Structure MD_BLOCK_TD_DETAIL (used with MD_BLOCK_TH and MD_BLOCK_TD)
|
* Detail: Structure MD_BLOCK_TABLE_DETAIL (for MD_BLOCK_TABLE),
|
||||||
|
* structure MD_BLOCK_TD_DETAIL (for MD_BLOCK_TH and MD_BLOCK_TD)
|
||||||
* Note all of these are used only if extension MD_FLAG_TABLES is enabled. */
|
* Note all of these are used only if extension MD_FLAG_TABLES is enabled. */
|
||||||
MD_BLOCK_TABLE,
|
MD_BLOCK_TABLE,
|
||||||
MD_BLOCK_THEAD,
|
MD_BLOCK_THEAD,
|
||||||
@ -267,6 +268,13 @@ typedef struct MD_BLOCK_CODE_DETAIL {
|
|||||||
MD_CHAR fence_char; /* The character used for fenced code block; or zero for indented code block. */
|
MD_CHAR fence_char; /* The character used for fenced code block; or zero for indented code block. */
|
||||||
} MD_BLOCK_CODE_DETAIL;
|
} MD_BLOCK_CODE_DETAIL;
|
||||||
|
|
||||||
|
/* Detailed info for MD_BLOCK_TABLE. */
|
||||||
|
typedef struct MD_BLOCK_TABLE_DETAIL {
|
||||||
|
unsigned col_count; /* Count of columns in the table. */
|
||||||
|
unsigned head_row_count; /* Count of rows in the table header (currently always 1) */
|
||||||
|
unsigned body_row_count; /* Count of rows in the table body */
|
||||||
|
} MD_BLOCK_TABLE_DETAIL;
|
||||||
|
|
||||||
/* Detailed info for MD_BLOCK_TH and MD_BLOCK_TD. */
|
/* Detailed info for MD_BLOCK_TH and MD_BLOCK_TD. */
|
||||||
typedef struct MD_BLOCK_TD_DETAIL {
|
typedef struct MD_BLOCK_TD_DETAIL {
|
||||||
MD_ALIGN align;
|
MD_ALIGN align;
|
||||||
|
4
src/3rdparty/md4c/qt_attribution.json
vendored
4
src/3rdparty/md4c/qt_attribution.json
vendored
@ -9,7 +9,7 @@
|
|||||||
"License": "MIT License",
|
"License": "MIT License",
|
||||||
"LicenseId": "MIT",
|
"LicenseId": "MIT",
|
||||||
"LicenseFile": "LICENSE.md",
|
"LicenseFile": "LICENSE.md",
|
||||||
"Version": "0.4.6",
|
"Version": "0.4.7",
|
||||||
"DownloadLocation": "https://github.com/mity/md4c/releases/tag/release-0.4.6",
|
"DownloadLocation": "https://github.com/mity/md4c/releases/tag/release-0.4.7",
|
||||||
"Copyright": "Copyright © 2016-2020 Martin Mitáš"
|
"Copyright": "Copyright © 2016-2020 Martin Mitáš"
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user