38 #if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199409L
41 #define inline __inline__
42 #elif defined _MSC_VER
43 #define inline __inline
50 #if !defined MD4C_USE_ASCII && !defined MD4C_USE_UTF8 && !defined MD4C_USE_UTF16
58 #if defined MD4C_USE_UTF16
65 #define SIZEOF_ARRAY(a) (sizeof(a) / sizeof(a[0]))
67 #define STRINGIZE_(x) #x
68 #define STRINGIZE(x) STRINGIZE_(x)
77 if(ctx->parser.debug_log != NULL) \
78 ctx->parser.debug_log((msg), ctx->userdata); \
82 #define MD_ASSERT(cond) \
85 MD_LOG(__FILE__ ":" STRINGIZE(__LINE__) ": " \
86 "Assertion '" STRINGIZE(cond) "' failed."); \
91 #define MD_UNREACHABLE() MD_ASSERT(1 == 0)
94 #define MD_ASSERT(cond) do { if(!(cond)) __builtin_unreachable(); } while(0)
95 #define MD_UNREACHABLE() do { __builtin_unreachable(); } while(0)
96 #elif defined _MSC_VER && _MSC_VER > 120
97 #define MD_ASSERT(cond) do { __assume(cond); } while(0)
98 #define MD_UNREACHABLE() do { __assume(0); } while(0)
100 #define MD_ASSERT(cond) do {} while(0)
101 #define MD_UNREACHABLE() do {} while(0)
106 #if defined __clang__ && __clang_major__ >= 12
107 #define MD_FALLTHROUGH() __attribute__((fallthrough))
108 #elif defined __GNUC__ && __GNUC__ >= 7
109 #define MD_FALLTHROUGH() __attribute__((fallthrough))
111 #define MD_FALLTHROUGH() ((void)0)
115 #define MD_UNUSED(x) ((void)x)
125 #define OFF MD_OFFSET
174 #if defined MD4C_USE_UTF16
182 #define PTR_CHAIN (ctx->mark_chains[0])
183 #define TABLECELLBOUNDARIES (ctx->mark_chains[1])
184 #define ASTERISK_OPENERS_extraword_mod3_0 (ctx->mark_chains[2])
185 #define ASTERISK_OPENERS_extraword_mod3_1 (ctx->mark_chains[3])
186 #define ASTERISK_OPENERS_extraword_mod3_2 (ctx->mark_chains[4])
187 #define ASTERISK_OPENERS_intraword_mod3_0 (ctx->mark_chains[5])
188 #define ASTERISK_OPENERS_intraword_mod3_1 (ctx->mark_chains[6])
189 #define ASTERISK_OPENERS_intraword_mod3_2 (ctx->mark_chains[7])
190 #define UNDERSCORE_OPENERS (ctx->mark_chains[8])
191 #define TILDE_OPENERS_1 (ctx->mark_chains[9])
192 #define TILDE_OPENERS_2 (ctx->mark_chains[10])
193 #define BRACKET_OPENERS (ctx->mark_chains[11])
194 #define DOLLAR_OPENERS (ctx->mark_chains[12])
195 #define OPENERS_CHAIN_FIRST 2
196 #define OPENERS_CHAIN_LAST 12
280 #define CH(off) (ctx->text[(off)])
281 #define STR(off) (ctx->text + (off))
285 #define ISIN_(ch, ch_min, ch_max) ((ch_min) <= (unsigned)(ch) && (unsigned)(ch) <= (ch_max))
286 #define ISANYOF_(ch, palette) ((ch) != _T('\0') && md_strchr((palette), (ch)) != NULL)
287 #define ISANYOF2_(ch, ch1, ch2) ((ch) == (ch1) || (ch) == (ch2))
288 #define ISANYOF3_(ch, ch1, ch2, ch3) ((ch) == (ch1) || (ch) == (ch2) || (ch) == (ch3))
289 #define ISASCII_(ch) ((unsigned)(ch) <= 127)
290 #define ISBLANK_(ch) (ISANYOF2_((ch), _T(' '), _T('\t')))
291 #define ISNEWLINE_(ch) (ISANYOF2_((ch), _T('\r'), _T('\n')))
292 #define ISWHITESPACE_(ch) (ISBLANK_(ch) || ISANYOF2_((ch), _T('\v'), _T('\f')))
293 #define ISCNTRL_(ch) ((unsigned)(ch) <= 31 || (unsigned)(ch) == 127)
294 #define ISPUNCT_(ch) (ISIN_(ch, 33, 47) || ISIN_(ch, 58, 64) || ISIN_(ch, 91, 96) || ISIN_(ch, 123, 126))
295 #define ISUPPER_(ch) (ISIN_(ch, _T('A'), _T('Z')))
296 #define ISLOWER_(ch) (ISIN_(ch, _T('a'), _T('z')))
297 #define ISALPHA_(ch) (ISUPPER_(ch) || ISLOWER_(ch))
298 #define ISDIGIT_(ch) (ISIN_(ch, _T('0'), _T('9')))
299 #define ISXDIGIT_(ch) (ISDIGIT_(ch) || ISIN_(ch, _T('A'), _T('F')) || ISIN_(ch, _T('a'), _T('f')))
300 #define ISALNUM_(ch) (ISALPHA_(ch) || ISDIGIT_(ch))
302 #define ISANYOF(off, palette) ISANYOF_(CH(off), (palette))
303 #define ISANYOF2(off, ch1, ch2) ISANYOF2_(CH(off), (ch1), (ch2))
304 #define ISANYOF3(off, ch1, ch2, ch3) ISANYOF3_(CH(off), (ch1), (ch2), (ch3))
305 #define ISASCII(off) ISASCII_(CH(off))
306 #define ISBLANK(off) ISBLANK_(CH(off))
307 #define ISNEWLINE(off) ISNEWLINE_(CH(off))
308 #define ISWHITESPACE(off) ISWHITESPACE_(CH(off))
309 #define ISCNTRL(off) ISCNTRL_(CH(off))
310 #define ISPUNCT(off) ISPUNCT_(CH(off))
311 #define ISUPPER(off) ISUPPER_(CH(off))
312 #define ISLOWER(off) ISLOWER_(CH(off))
313 #define ISALPHA(off) ISALPHA_(CH(off))
314 #define ISDIGIT(off) ISDIGIT_(CH(off))
315 #define ISXDIGIT(off) ISXDIGIT_(CH(off))
316 #define ISALNUM(off) ISALNUM_(CH(off))
319 #if defined MD4C_USE_UTF16
320 #define md_strchr wcschr
322 #define md_strchr strchr
331 for(
i = 0;
i <
n;
i++) {
348 return memcmp(
s1,
s2,
n *
sizeof(
CHAR)) == 0;
358 while(off <
size &&
str[off] !=
_T(
'\0'))
382 #define MD_CHECK(func) \
390 #define MD_TEMP_BUFFER(sz) \
392 if(sz > ctx->alloc_buffer) { \
394 SZ new_size = ((sz) + (sz) / 2 + 128) & ~127; \
396 new_buffer = realloc(ctx->buffer, new_size); \
397 if(new_buffer == NULL) { \
398 MD_LOG("realloc() failed."); \
403 ctx->buffer = new_buffer; \
404 ctx->alloc_buffer = new_size; \
409 #define MD_ENTER_BLOCK(type, arg) \
411 ret = ctx->parser.enter_block((type), (arg), ctx->userdata); \
413 MD_LOG("Aborted from enter_block() callback."); \
418 #define MD_LEAVE_BLOCK(type, arg) \
420 ret = ctx->parser.leave_block((type), (arg), ctx->userdata); \
422 MD_LOG("Aborted from leave_block() callback."); \
427 #define MD_ENTER_SPAN(type, arg) \
429 ret = ctx->parser.enter_span((type), (arg), ctx->userdata); \
431 MD_LOG("Aborted from enter_span() callback."); \
436 #define MD_LEAVE_SPAN(type, arg) \
438 ret = ctx->parser.leave_span((type), (arg), ctx->userdata); \
440 MD_LOG("Aborted from leave_span() callback."); \
445 #define MD_TEXT(type, str, size) \
448 ret = ctx->parser.text((type), (str), (size), ctx->userdata); \
450 MD_LOG("Aborted from text() callback."); \
456 #define MD_TEXT_INSECURE(type, str, size) \
459 ret = md_text_with_null_replacement(ctx, type, str, size); \
461 MD_LOG("Aborted from text() callback."); \
480 #if defined MD4C_USE_UTF16 || defined MD4C_USE_UTF8
488 md_unicode_bsearch__(
unsigned codepoint,
const unsigned*
map,
size_t map_size)
491 int pivot_beg, pivot_end;
494 end = (int) map_size-1;
497 pivot_beg = pivot_end = (beg +
end) / 2;
498 if(
map[pivot_end] & 0x40000000)
500 if(
map[pivot_beg] & 0x80000000)
503 if(codepoint < (
map[pivot_beg] & 0x00ffffff))
505 else if(codepoint > (
map[pivot_end] & 0x00ffffff))
515 md_is_unicode_whitespace__(
unsigned codepoint)
517 #define R(cp_min, cp_max) ((cp_min) | 0x40000000), ((cp_max) | 0x80000000)
521 static const unsigned WHITESPACE_MAP[] = {
522 S(0x0020),
S(0x00a0),
S(0x1680),
R(0x2000,0x200a),
S(0x202f),
S(0x205f),
S(0x3000)
529 if(codepoint <= 0x7f)
532 return (md_unicode_bsearch__(codepoint, WHITESPACE_MAP,
SIZEOF_ARRAY(WHITESPACE_MAP)) >= 0);
536 md_is_unicode_punct__(
unsigned codepoint)
538 #define R(cp_min, cp_max) ((cp_min) | 0x40000000), ((cp_max) | 0x80000000)
542 static const unsigned PUNCT_MAP[] = {
543 R(0x0021,0x0023),
R(0x0025,0x002a),
R(0x002c,0x002f),
R(0x003a,0x003b),
R(0x003f,0x0040),
544 R(0x005b,0x005d),
S(0x005f),
S(0x007b),
S(0x007d),
S(0x00a1),
S(0x00a7),
S(0x00ab),
R(0x00b6,0x00b7),
545 S(0x00bb),
S(0x00bf),
S(0x037e),
S(0x0387),
R(0x055a,0x055f),
R(0x0589,0x058a),
S(0x05be),
S(0x05c0),
546 S(0x05c3),
S(0x05c6),
R(0x05f3,0x05f4),
R(0x0609,0x060a),
R(0x060c,0x060d),
S(0x061b),
R(0x061e,0x061f),
547 R(0x066a,0x066d),
S(0x06d4),
R(0x0700,0x070d),
R(0x07f7,0x07f9),
R(0x0830,0x083e),
S(0x085e),
548 R(0x0964,0x0965),
S(0x0970),
S(0x09fd),
S(0x0a76),
S(0x0af0),
S(0x0c77),
S(0x0c84),
S(0x0df4),
S(0x0e4f),
549 R(0x0e5a,0x0e5b),
R(0x0f04,0x0f12),
S(0x0f14),
R(0x0f3a,0x0f3d),
S(0x0f85),
R(0x0fd0,0x0fd4),
550 R(0x0fd9,0x0fda),
R(0x104a,0x104f),
S(0x10fb),
R(0x1360,0x1368),
S(0x1400),
S(0x166e),
R(0x169b,0x169c),
551 R(0x16eb,0x16ed),
R(0x1735,0x1736),
R(0x17d4,0x17d6),
R(0x17d8,0x17da),
R(0x1800,0x180a),
552 R(0x1944,0x1945),
R(0x1a1e,0x1a1f),
R(0x1aa0,0x1aa6),
R(0x1aa8,0x1aad),
R(0x1b5a,0x1b60),
553 R(0x1bfc,0x1bff),
R(0x1c3b,0x1c3f),
R(0x1c7e,0x1c7f),
R(0x1cc0,0x1cc7),
S(0x1cd3),
R(0x2010,0x2027),
554 R(0x2030,0x2043),
R(0x2045,0x2051),
R(0x2053,0x205e),
R(0x207d,0x207e),
R(0x208d,0x208e),
555 R(0x2308,0x230b),
R(0x2329,0x232a),
R(0x2768,0x2775),
R(0x27c5,0x27c6),
R(0x27e6,0x27ef),
556 R(0x2983,0x2998),
R(0x29d8,0x29db),
R(0x29fc,0x29fd),
R(0x2cf9,0x2cfc),
R(0x2cfe,0x2cff),
S(0x2d70),
557 R(0x2e00,0x2e2e),
R(0x2e30,0x2e4f),
S(0x2e52),
R(0x3001,0x3003),
R(0x3008,0x3011),
R(0x3014,0x301f),
558 S(0x3030),
S(0x303d),
S(0x30a0),
S(0x30fb),
R(0xa4fe,0xa4ff),
R(0xa60d,0xa60f),
S(0xa673),
S(0xa67e),
559 R(0xa6f2,0xa6f7),
R(0xa874,0xa877),
R(0xa8ce,0xa8cf),
R(0xa8f8,0xa8fa),
S(0xa8fc),
R(0xa92e,0xa92f),
560 S(0xa95f),
R(0xa9c1,0xa9cd),
R(0xa9de,0xa9df),
R(0xaa5c,0xaa5f),
R(0xaade,0xaadf),
R(0xaaf0,0xaaf1),
561 S(0xabeb),
R(0xfd3e,0xfd3f),
R(0xfe10,0xfe19),
R(0xfe30,0xfe52),
R(0xfe54,0xfe61),
S(0xfe63),
S(0xfe68),
562 R(0xfe6a,0xfe6b),
R(0xff01,0xff03),
R(0xff05,0xff0a),
R(0xff0c,0xff0f),
R(0xff1a,0xff1b),
563 R(0xff1f,0xff20),
R(0xff3b,0xff3d),
S(0xff3f),
S(0xff5b),
S(0xff5d),
R(0xff5f,0xff65),
R(0x10100,0x10102),
564 S(0x1039f),
S(0x103d0),
S(0x1056f),
S(0x10857),
S(0x1091f),
S(0x1093f),
R(0x10a50,0x10a58),
S(0x10a7f),
565 R(0x10af0,0x10af6),
R(0x10b39,0x10b3f),
R(0x10b99,0x10b9c),
S(0x10ead),
R(0x10f55,0x10f59),
566 R(0x11047,0x1104d),
R(0x110bb,0x110bc),
R(0x110be,0x110c1),
R(0x11140,0x11143),
R(0x11174,0x11175),
567 R(0x111c5,0x111c8),
S(0x111cd),
S(0x111db),
R(0x111dd,0x111df),
R(0x11238,0x1123d),
S(0x112a9),
568 R(0x1144b,0x1144f),
R(0x1145a,0x1145b),
S(0x1145d),
S(0x114c6),
R(0x115c1,0x115d7),
R(0x11641,0x11643),
569 R(0x11660,0x1166c),
R(0x1173c,0x1173e),
S(0x1183b),
R(0x11944,0x11946),
S(0x119e2),
R(0x11a3f,0x11a46),
570 R(0x11a9a,0x11a9c),
R(0x11a9e,0x11aa2),
R(0x11c41,0x11c45),
R(0x11c70,0x11c71),
R(0x11ef7,0x11ef8),
571 S(0x11fff),
R(0x12470,0x12474),
R(0x16a6e,0x16a6f),
S(0x16af5),
R(0x16b37,0x16b3b),
S(0x16b44),
572 R(0x16e97,0x16e9a),
S(0x16fe2),
S(0x1bc9f),
R(0x1da87,0x1da8b),
R(0x1e95e,0x1e95f)
579 if(codepoint <= 0x7f)
582 return (md_unicode_bsearch__(codepoint, PUNCT_MAP,
SIZEOF_ARRAY(PUNCT_MAP)) >= 0);
588 #define R(cp_min, cp_max) ((cp_min) | 0x40000000), ((cp_max) | 0x80000000)
592 static const unsigned FOLD_MAP_1[] = {
593 R(0x0041,0x005a),
S(0x00b5),
R(0x00c0,0x00d6),
R(0x00d8,0x00de),
R(0x0100,0x012e),
R(0x0132,0x0136),
594 R(0x0139,0x0147),
R(0x014a,0x0176),
S(0x0178),
R(0x0179,0x017d),
S(0x017f),
S(0x0181),
S(0x0182),
595 S(0x0184),
S(0x0186),
S(0x0187),
S(0x0189),
S(0x018a),
S(0x018b),
S(0x018e),
S(0x018f),
S(0x0190),
596 S(0x0191),
S(0x0193),
S(0x0194),
S(0x0196),
S(0x0197),
S(0x0198),
S(0x019c),
S(0x019d),
S(0x019f),
597 R(0x01a0,0x01a4),
S(0x01a6),
S(0x01a7),
S(0x01a9),
S(0x01ac),
S(0x01ae),
S(0x01af),
S(0x01b1),
S(0x01b2),
598 S(0x01b3),
S(0x01b5),
S(0x01b7),
S(0x01b8),
S(0x01bc),
S(0x01c4),
S(0x01c5),
S(0x01c7),
S(0x01c8),
599 S(0x01ca),
R(0x01cb,0x01db),
R(0x01de,0x01ee),
S(0x01f1),
S(0x01f2),
S(0x01f4),
S(0x01f6),
S(0x01f7),
600 R(0x01f8,0x021e),
S(0x0220),
R(0x0222,0x0232),
S(0x023a),
S(0x023b),
S(0x023d),
S(0x023e),
S(0x0241),
601 S(0x0243),
S(0x0244),
S(0x0245),
R(0x0246,0x024e),
S(0x0345),
S(0x0370),
S(0x0372),
S(0x0376),
S(0x037f),
602 S(0x0386),
R(0x0388,0x038a),
S(0x038c),
S(0x038e),
S(0x038f),
R(0x0391,0x03a1),
R(0x03a3,0x03ab),
603 S(0x03c2),
S(0x03cf),
S(0x03d0),
S(0x03d1),
S(0x03d5),
S(0x03d6),
R(0x03d8,0x03ee),
S(0x03f0),
S(0x03f1),
604 S(0x03f4),
S(0x03f5),
S(0x03f7),
S(0x03f9),
S(0x03fa),
R(0x03fd,0x03ff),
R(0x0400,0x040f),
605 R(0x0410,0x042f),
R(0x0460,0x0480),
R(0x048a,0x04be),
S(0x04c0),
R(0x04c1,0x04cd),
R(0x04d0,0x052e),
606 R(0x0531,0x0556),
R(0x10a0,0x10c5),
S(0x10c7),
S(0x10cd),
R(0x13f8,0x13fd),
S(0x1c80),
S(0x1c81),
607 S(0x1c82),
S(0x1c83),
S(0x1c84),
S(0x1c85),
S(0x1c86),
S(0x1c87),
S(0x1c88),
R(0x1c90,0x1cba),
608 R(0x1cbd,0x1cbf),
R(0x1e00,0x1e94),
S(0x1e9b),
R(0x1ea0,0x1efe),
R(0x1f08,0x1f0f),
R(0x1f18,0x1f1d),
609 R(0x1f28,0x1f2f),
R(0x1f38,0x1f3f),
R(0x1f48,0x1f4d),
S(0x1f59),
S(0x1f5b),
S(0x1f5d),
S(0x1f5f),
610 R(0x1f68,0x1f6f),
S(0x1fb8),
S(0x1fb9),
S(0x1fba),
S(0x1fbb),
S(0x1fbe),
R(0x1fc8,0x1fcb),
S(0x1fd8),
611 S(0x1fd9),
S(0x1fda),
S(0x1fdb),
S(0x1fe8),
S(0x1fe9),
S(0x1fea),
S(0x1feb),
S(0x1fec),
S(0x1ff8),
612 S(0x1ff9),
S(0x1ffa),
S(0x1ffb),
S(0x2126),
S(0x212a),
S(0x212b),
S(0x2132),
R(0x2160,0x216f),
S(0x2183),
613 R(0x24b6,0x24cf),
R(0x2c00,0x2c2e),
S(0x2c60),
S(0x2c62),
S(0x2c63),
S(0x2c64),
R(0x2c67,0x2c6b),
614 S(0x2c6d),
S(0x2c6e),
S(0x2c6f),
S(0x2c70),
S(0x2c72),
S(0x2c75),
S(0x2c7e),
S(0x2c7f),
R(0x2c80,0x2ce2),
615 S(0x2ceb),
S(0x2ced),
S(0x2cf2),
R(0xa640,0xa66c),
R(0xa680,0xa69a),
R(0xa722,0xa72e),
R(0xa732,0xa76e),
616 S(0xa779),
S(0xa77b),
S(0xa77d),
R(0xa77e,0xa786),
S(0xa78b),
S(0xa78d),
S(0xa790),
S(0xa792),
617 R(0xa796,0xa7a8),
S(0xa7aa),
S(0xa7ab),
S(0xa7ac),
S(0xa7ad),
S(0xa7ae),
S(0xa7b0),
S(0xa7b1),
S(0xa7b2),
618 S(0xa7b3),
R(0xa7b4,0xa7be),
S(0xa7c2),
S(0xa7c4),
S(0xa7c5),
S(0xa7c6),
S(0xa7c7),
S(0xa7c9),
S(0xa7f5),
619 R(0xab70,0xabbf),
R(0xff21,0xff3a),
R(0x10400,0x10427),
R(0x104b0,0x104d3),
R(0x10c80,0x10cb2),
620 R(0x118a0,0x118bf),
R(0x16e40,0x16e5f),
R(0x1e900,0x1e921)
622 static const unsigned FOLD_MAP_1_DATA[] = {
623 0x0061, 0x007a, 0x03bc, 0x00e0, 0x00f6, 0x00f8, 0x00fe, 0x0101, 0x012f, 0x0133, 0x0137, 0x013a, 0x0148,
624 0x014b, 0x0177, 0x00ff, 0x017a, 0x017e, 0x0073, 0x0253, 0x0183, 0x0185, 0x0254, 0x0188, 0x0256, 0x0257,
625 0x018c, 0x01dd, 0x0259, 0x025b, 0x0192, 0x0260, 0x0263, 0x0269, 0x0268, 0x0199, 0x026f, 0x0272, 0x0275,
626 0x01a1, 0x01a5, 0x0280, 0x01a8, 0x0283, 0x01ad, 0x0288, 0x01b0, 0x028a, 0x028b, 0x01b4, 0x01b6, 0x0292,
627 0x01b9, 0x01bd, 0x01c6, 0x01c6, 0x01c9, 0x01c9, 0x01cc, 0x01cc, 0x01dc, 0x01df, 0x01ef, 0x01f3, 0x01f3,
628 0x01f5, 0x0195, 0x01bf, 0x01f9, 0x021f, 0x019e, 0x0223, 0x0233, 0x2c65, 0x023c, 0x019a, 0x2c66, 0x0242,
629 0x0180, 0x0289, 0x028c, 0x0247, 0x024f, 0x03b9, 0x0371, 0x0373, 0x0377, 0x03f3, 0x03ac, 0x03ad, 0x03af,
630 0x03cc, 0x03cd, 0x03ce, 0x03b1, 0x03c1, 0x03c3, 0x03cb, 0x03c3, 0x03d7, 0x03b2, 0x03b8, 0x03c6, 0x03c0,
631 0x03d9, 0x03ef, 0x03ba, 0x03c1, 0x03b8, 0x03b5, 0x03f8, 0x03f2, 0x03fb, 0x037b, 0x037d, 0x0450, 0x045f,
632 0x0430, 0x044f, 0x0461, 0x0481, 0x048b, 0x04bf, 0x04cf, 0x04c2, 0x04ce, 0x04d1, 0x052f, 0x0561, 0x0586,
633 0x2d00, 0x2d25, 0x2d27, 0x2d2d, 0x13f0, 0x13f5, 0x0432, 0x0434, 0x043e, 0x0441, 0x0442, 0x0442, 0x044a,
634 0x0463, 0xa64b, 0x10d0, 0x10fa, 0x10fd, 0x10ff, 0x1e01, 0x1e95, 0x1e61, 0x1ea1, 0x1eff, 0x1f00, 0x1f07,
635 0x1f10, 0x1f15, 0x1f20, 0x1f27, 0x1f30, 0x1f37, 0x1f40, 0x1f45, 0x1f51, 0x1f53, 0x1f55, 0x1f57, 0x1f60,
636 0x1f67, 0x1fb0, 0x1fb1, 0x1f70, 0x1f71, 0x03b9, 0x1f72, 0x1f75, 0x1fd0, 0x1fd1, 0x1f76, 0x1f77, 0x1fe0,
637 0x1fe1, 0x1f7a, 0x1f7b, 0x1fe5, 0x1f78, 0x1f79, 0x1f7c, 0x1f7d, 0x03c9, 0x006b, 0x00e5, 0x214e, 0x2170,
638 0x217f, 0x2184, 0x24d0, 0x24e9, 0x2c30, 0x2c5e, 0x2c61, 0x026b, 0x1d7d, 0x027d, 0x2c68, 0x2c6c, 0x0251,
639 0x0271, 0x0250, 0x0252, 0x2c73, 0x2c76, 0x023f, 0x0240, 0x2c81, 0x2ce3, 0x2cec, 0x2cee, 0x2cf3, 0xa641,
640 0xa66d, 0xa681, 0xa69b, 0xa723, 0xa72f, 0xa733, 0xa76f, 0xa77a, 0xa77c, 0x1d79, 0xa77f, 0xa787, 0xa78c,
641 0x0265, 0xa791, 0xa793, 0xa797, 0xa7a9, 0x0266, 0x025c, 0x0261, 0x026c, 0x026a, 0x029e, 0x0287, 0x029d,
642 0xab53, 0xa7b5, 0xa7bf, 0xa7c3, 0xa794, 0x0282, 0x1d8e, 0xa7c8, 0xa7ca, 0xa7f6, 0x13a0, 0x13ef, 0xff41,
643 0xff5a, 0x10428, 0x1044f, 0x104d8, 0x104fb, 0x10cc0, 0x10cf2, 0x118c0, 0x118df, 0x16e60, 0x16e7f, 0x1e922,
646 static const unsigned FOLD_MAP_2[] = {
647 S(0x00df),
S(0x0130),
S(0x0149),
S(0x01f0),
S(0x0587),
S(0x1e96),
S(0x1e97),
S(0x1e98),
S(0x1e99),
648 S(0x1e9a),
S(0x1e9e),
S(0x1f50),
R(0x1f80,0x1f87),
R(0x1f88,0x1f8f),
R(0x1f90,0x1f97),
R(0x1f98,0x1f9f),
649 R(0x1fa0,0x1fa7),
R(0x1fa8,0x1faf),
S(0x1fb2),
S(0x1fb3),
S(0x1fb4),
S(0x1fb6),
S(0x1fbc),
S(0x1fc2),
650 S(0x1fc3),
S(0x1fc4),
S(0x1fc6),
S(0x1fcc),
S(0x1fd6),
S(0x1fe4),
S(0x1fe6),
S(0x1ff2),
S(0x1ff3),
651 S(0x1ff4),
S(0x1ff6),
S(0x1ffc),
S(0xfb00),
S(0xfb01),
S(0xfb02),
S(0xfb05),
S(0xfb06),
S(0xfb13),
652 S(0xfb14),
S(0xfb15),
S(0xfb16),
S(0xfb17)
654 static const unsigned FOLD_MAP_2_DATA[] = {
655 0x0073,0x0073, 0x0069,0x0307, 0x02bc,0x006e, 0x006a,0x030c, 0x0565,0x0582, 0x0068,0x0331, 0x0074,0x0308,
656 0x0077,0x030a, 0x0079,0x030a, 0x0061,0x02be, 0x0073,0x0073, 0x03c5,0x0313, 0x1f00,0x03b9, 0x1f07,0x03b9,
657 0x1f00,0x03b9, 0x1f07,0x03b9, 0x1f20,0x03b9, 0x1f27,0x03b9, 0x1f20,0x03b9, 0x1f27,0x03b9, 0x1f60,0x03b9,
658 0x1f67,0x03b9, 0x1f60,0x03b9, 0x1f67,0x03b9, 0x1f70,0x03b9, 0x03b1,0x03b9, 0x03ac,0x03b9, 0x03b1,0x0342,
659 0x03b1,0x03b9, 0x1f74,0x03b9, 0x03b7,0x03b9, 0x03ae,0x03b9, 0x03b7,0x0342, 0x03b7,0x03b9, 0x03b9,0x0342,
660 0x03c1,0x0313, 0x03c5,0x0342, 0x1f7c,0x03b9, 0x03c9,0x03b9, 0x03ce,0x03b9, 0x03c9,0x0342, 0x03c9,0x03b9,
661 0x0066,0x0066, 0x0066,0x0069, 0x0066,0x006c, 0x0073,0x0074, 0x0073,0x0074, 0x0574,0x0576, 0x0574,0x0565,
662 0x0574,0x056b, 0x057e,0x0576, 0x0574,0x056d
664 static const unsigned FOLD_MAP_3[] = {
665 S(0x0390),
S(0x03b0),
S(0x1f52),
S(0x1f54),
S(0x1f56),
S(0x1fb7),
S(0x1fc7),
S(0x1fd2),
S(0x1fd3),
666 S(0x1fd7),
S(0x1fe2),
S(0x1fe3),
S(0x1fe7),
S(0x1ff7),
S(0xfb03),
S(0xfb04)
668 static const unsigned FOLD_MAP_3_DATA[] = {
669 0x03b9,0x0308,0x0301, 0x03c5,0x0308,0x0301, 0x03c5,0x0313,0x0300, 0x03c5,0x0313,0x0301,
670 0x03c5,0x0313,0x0342, 0x03b1,0x0342,0x03b9, 0x03b7,0x0342,0x03b9, 0x03b9,0x0308,0x0300,
671 0x03b9,0x0308,0x0301, 0x03b9,0x0308,0x0342, 0x03c5,0x0308,0x0300, 0x03c5,0x0308,0x0301,
672 0x03c5,0x0308,0x0342, 0x03c9,0x0342,0x03b9, 0x0066,0x0066,0x0069, 0x0066,0x0066,0x006c
676 static const struct {
678 const unsigned*
data;
680 unsigned n_codepoints;
681 } FOLD_MAP_LIST[] = {
682 { FOLD_MAP_1, FOLD_MAP_1_DATA,
SIZEOF_ARRAY(FOLD_MAP_1), 1 },
683 { FOLD_MAP_2, FOLD_MAP_2_DATA,
SIZEOF_ARRAY(FOLD_MAP_2), 2 },
684 { FOLD_MAP_3, FOLD_MAP_3_DATA,
SIZEOF_ARRAY(FOLD_MAP_3), 3 }
690 if(codepoint <= 0x7f) {
691 info->codepoints[0] = codepoint;
693 info->codepoints[0] +=
'a' -
'A';
694 info->n_codepoints = 1;
702 index = md_unicode_bsearch__(codepoint, FOLD_MAP_LIST[
i].
map, FOLD_MAP_LIST[
i].map_size);
705 unsigned n_codepoints = FOLD_MAP_LIST[
i].n_codepoints;
706 const unsigned*
map = FOLD_MAP_LIST[
i].map;
707 const unsigned* codepoints = FOLD_MAP_LIST[
i].data + (
index * n_codepoints);
709 memcpy(
info->codepoints, codepoints,
sizeof(
unsigned) * n_codepoints);
710 info->n_codepoints = n_codepoints;
712 if(FOLD_MAP_LIST[
i].
map[
index] != codepoint) {
715 if((
map[
index] & 0x00ffffff)+1 == codepoints[0]) {
717 info->codepoints[0] = codepoint + ((codepoint & 0x1) == (
map[
index] & 0x1) ? 1 : 0);
720 info->codepoints[0] += (codepoint - (
map[
index] & 0x00ffffff));
729 info->codepoints[0] = codepoint;
730 info->n_codepoints = 1;
735 #if defined MD4C_USE_UTF16
736 #define IS_UTF16_SURROGATE_HI(word) (((WORD)(word) & 0xfc00) == 0xd800)
737 #define IS_UTF16_SURROGATE_LO(word) (((WORD)(word) & 0xfc00) == 0xdc00)
738 #define UTF16_DECODE_SURROGATE(hi, lo) (0x10000 + ((((unsigned)(hi) & 0x3ff) << 10) | (((unsigned)(lo) & 0x3ff) << 0)))
741 md_decode_utf16le__(
const CHAR*
str,
SZ str_size,
SZ* p_size)
743 if(IS_UTF16_SURROGATE_HI(
str[0])) {
744 if(1 < str_size && IS_UTF16_SURROGATE_LO(
str[1])) {
747 return UTF16_DECODE_SURROGATE(
str[0],
str[1]);
757 md_decode_utf16le_before__(
MD_CTX* ctx,
OFF off)
759 if(off > 2 && IS_UTF16_SURROGATE_HI(
CH(off-2)) && IS_UTF16_SURROGATE_LO(
CH(off-1)))
760 return UTF16_DECODE_SURROGATE(
CH(off-2),
CH(off-1));
766 #define ISUNICODEWHITESPACE_(codepoint) md_is_unicode_whitespace__(codepoint)
767 #define ISUNICODEWHITESPACE(off) md_is_unicode_whitespace__(CH(off))
768 #define ISUNICODEWHITESPACEBEFORE(off) md_is_unicode_whitespace__(CH((off)-1))
770 #define ISUNICODEPUNCT(off) md_is_unicode_punct__(md_decode_utf16le__(STR(off), ctx->size - (off), NULL))
771 #define ISUNICODEPUNCTBEFORE(off) md_is_unicode_punct__(md_decode_utf16le_before__(ctx, off))
774 md_decode_unicode(
const CHAR*
str,
OFF off,
SZ str_size,
SZ* p_char_size)
776 return md_decode_utf16le__(
str+off, str_size-off, p_char_size);
778 #elif defined MD4C_USE_UTF8
779 #define IS_UTF8_LEAD1(byte) ((unsigned char)(byte) <= 0x7f)
780 #define IS_UTF8_LEAD2(byte) (((unsigned char)(byte) & 0xe0) == 0xc0)
781 #define IS_UTF8_LEAD3(byte) (((unsigned char)(byte) & 0xf0) == 0xe0)
782 #define IS_UTF8_LEAD4(byte) (((unsigned char)(byte) & 0xf8) == 0xf0)
783 #define IS_UTF8_TAIL(byte) (((unsigned char)(byte) & 0xc0) == 0x80)
786 md_decode_utf8__(
const CHAR*
str,
SZ str_size,
SZ* p_size)
794 return (((
unsigned int)
str[0] & 0x1f) << 6) |
795 (((
unsigned int)
str[1] & 0x3f) << 0);
802 return (((
unsigned int)
str[0] & 0x0f) << 12) |
803 (((
unsigned int)
str[1] & 0x3f) << 6) |
804 (((
unsigned int)
str[2] & 0x3f) << 0);
811 return (((
unsigned int)
str[0] & 0x07) << 18) |
812 (((
unsigned int)
str[1] & 0x3f) << 12) |
813 (((
unsigned int)
str[2] & 0x3f) << 6) |
814 (((
unsigned int)
str[3] & 0x3f) << 0);
821 return (
unsigned)
str[0];
825 md_decode_utf8_before__(
MD_CTX* ctx,
OFF off)
829 return (((
unsigned int)
CH(off-2) & 0x1f) << 6) |
830 (((
unsigned int)
CH(off-1) & 0x3f) << 0);
833 return (((
unsigned int)
CH(off-3) & 0x0f) << 12) |
834 (((
unsigned int)
CH(off-2) & 0x3f) << 6) |
835 (((
unsigned int)
CH(off-1) & 0x3f) << 0);
838 return (((
unsigned int)
CH(off-4) & 0x07) << 18) |
839 (((
unsigned int)
CH(off-3) & 0x3f) << 12) |
840 (((
unsigned int)
CH(off-2) & 0x3f) << 6) |
841 (((
unsigned int)
CH(off-1) & 0x3f) << 0);
844 return (
unsigned)
CH(off-1);
847 #define ISUNICODEWHITESPACE_(codepoint) md_is_unicode_whitespace__(codepoint)
848 #define ISUNICODEWHITESPACE(off) md_is_unicode_whitespace__(md_decode_utf8__(STR(off), ctx->size - (off), NULL))
849 #define ISUNICODEWHITESPACEBEFORE(off) md_is_unicode_whitespace__(md_decode_utf8_before__(ctx, off))
851 #define ISUNICODEPUNCT(off) md_is_unicode_punct__(md_decode_utf8__(STR(off), ctx->size - (off), NULL))
852 #define ISUNICODEPUNCTBEFORE(off) md_is_unicode_punct__(md_decode_utf8_before__(ctx, off))
854 static inline unsigned
855 md_decode_unicode(
const CHAR*
str,
OFF off,
SZ str_size,
SZ* p_char_size)
857 return md_decode_utf8__(
str+off, str_size-off, p_char_size);
860 #define ISUNICODEWHITESPACE_(codepoint) ISWHITESPACE_(codepoint)
861 #define ISUNICODEWHITESPACE(off) ISWHITESPACE(off)
862 #define ISUNICODEWHITESPACEBEFORE(off) ISWHITESPACE((off)-1)
864 #define ISUNICODEPUNCT(off) ISPUNCT(off)
865 #define ISUNICODEPUNCTBEFORE(off) ISPUNCT((off)-1)
870 info->codepoints[0] = codepoint;
872 info->codepoints[0] +=
'a' -
'A';
873 info->n_codepoints = 1;
876 static inline unsigned
877 md_decode_unicode(
const CHAR*
str,
OFF off,
SZ str_size,
SZ* p_size)
880 return (
unsigned)
str[off];
912 while(off < line_end) {
923 *ptr = line_break_replacement_char;
927 off = lines[line_index].
beg;
935 CHAR line_break_replacement_char,
CHAR** p_str,
SZ* p_size)
941 MD_LOG(
"malloc() failed.");
945 md_merge_lines(ctx, beg,
end, lines, n_lines,
946 line_break_replacement_char,
buffer, p_size);
959 codepoint = md_decode_unicode(
label, off,
size, &char_size);
985 OFF line_end = (n_lines > 0) ? lines[0].
end : ctx->
size;
990 if(off + 1 >= line_end)
1006 if(
CH(off) ==
_T(
'/')) {
1013 if(off >= line_end || !
ISALPHA(off))
1016 while(off < line_end && (
ISALNUM(off) ||
CH(off) ==
_T(
'-')))
1022 while(off < line_end && !
ISNEWLINE(off)) {
1023 if(attr_state > 40) {
1027 }
else if(attr_state == 42 &&
CH(off) ==
_T(
'\'')) {
1029 }
else if(attr_state == 43 &&
CH(off) ==
_T(
'"')) {
1037 }
else if(attr_state <= 2 &&
CH(off) ==
_T(
'>')) {
1040 }
else if(attr_state <= 2 &&
CH(off) ==
_T(
'/') && off+1 < line_end &&
CH(off+1) ==
_T(
'>')) {
1044 }
else if((attr_state == 1 || attr_state == 2) && (
ISALPHA(off) ||
CH(off) ==
_T(
'_') ||
CH(off) ==
_T(
':'))) {
1050 }
else if(attr_state == 2 &&
CH(off) ==
_T(
'=')) {
1054 }
else if(attr_state == 3) {
1056 if(
CH(off) ==
_T(
'"'))
1058 else if(
CH(off) ==
_T(
'\''))
1081 line_end = lines[
i].
end;
1083 if(attr_state == 0 || attr_state == 41)
1100 const MD_LINE* lines,
int n_lines,
1102 OFF* p_scan_horizon)
1107 if(off < *p_scan_horizon && *p_scan_horizon >= max_end -
len) {
1114 while(off +
len <= lines[
i].
end && off +
len <= max_end) {
1124 if(off >= max_end ||
i >= n_lines) {
1126 *p_scan_horizon = off;
1141 if(off + 4 >= lines[0].
end)
1143 if(
CH(off+1) !=
_T(
'!') ||
CH(off+2) !=
_T(
'-') ||
CH(off+3) !=
_T(
'-'))
1148 if(off < lines[0].
end &&
CH(off) ==
_T(
'>'))
1150 if(off+1 < lines[0].
end &&
CH(off) ==
_T(
'-') &&
CH(off+1) ==
_T(
'>'))
1155 if(md_scan_for_html_closer(ctx,
_T(
"--"), 2,
1158 if(*p_end < max_end &&
CH(*p_end) ==
_T(
'>')) {
1159 *p_end = *p_end + 1;
1168 md_is_html_processing_instruction(
MD_CTX* ctx,
const MD_LINE* lines,
int n_lines,
OFF beg,
OFF max_end,
OFF* p_end)
1172 if(off + 2 >= lines[0].
end)
1174 if(
CH(off+1) !=
_T(
'?'))
1178 return md_scan_for_html_closer(ctx,
_T(
"?>"), 2,
1187 if(off + 2 >= lines[0].
end)
1189 if(
CH(off+1) !=
_T(
'!'))
1202 return md_scan_for_html_closer(ctx,
_T(
">"), 1,
1209 static const CHAR open_str[] =
_T(
"<![CDATA[");
1214 if(off + open_size >= lines[0].
end)
1216 if(memcmp(
STR(off), open_str, open_size) != 0)
1220 if(lines[n_lines-1].
end < max_end)
1221 max_end = lines[n_lines-1].
end - 2;
1223 return md_scan_for_html_closer(ctx,
_T(
"]]>"), 3,
1231 return (md_is_html_tag(ctx, lines, n_lines, beg, max_end, p_end) ||
1232 md_is_html_comment(ctx, lines, n_lines, beg, max_end, p_end) ||
1233 md_is_html_processing_instruction(ctx, lines, n_lines, beg, max_end, p_end) ||
1234 md_is_html_declaration(ctx, lines, n_lines, beg, max_end, p_end) ||
1235 md_is_html_cdata(ctx, lines, n_lines, beg, max_end, p_end));
1249 while(off < max_end &&
ISXDIGIT_(
text[off]) && off - beg <= 8)
1252 if(1 <= off - beg && off - beg <= 6) {
1266 while(off < max_end &&
ISDIGIT_(
text[off]) && off - beg <= 8)
1269 if(1 <= off - beg && off - beg <= 7) {
1288 while(off < max_end &&
ISALNUM_(
text[off]) && off - beg <= 48)
1291 if(2 <= off - beg && off - beg <= 48) {
1308 if(off+2 < max_end &&
text[off] ==
_T(
'#') && (
text[off+1] ==
_T(
'x') ||
text[off+1] ==
_T(
'X')))
1309 is_contents = md_is_hex_entity_contents(ctx,
text, off+2, max_end, &off);
1310 else if(off+1 < max_end &&
text[off] ==
_T(
'#'))
1311 is_contents = md_is_dec_entity_contents(ctx,
text, off+1, max_end, &off);
1313 is_contents = md_is_named_entity_contents(ctx,
text, off, max_end, &off);
1315 if(is_contents && off < max_end &&
text[off] ==
_T(
';')) {
1326 return md_is_entity_str(ctx, ctx->
text, beg, max_end, p_end);
1346 #define MD_BUILD_ATTR_NO_ESCAPES 0x0001
1352 if(
build->substr_count >=
build->substr_alloc) {
1354 OFF* new_substr_offsets;
1356 build->substr_alloc = (
build->substr_alloc > 0
1357 ?
build->substr_alloc +
build->substr_alloc / 2
1361 if(new_substr_types ==
NULL) {
1362 MD_LOG(
"realloc() failed.");
1366 new_substr_offsets = (
OFF*) realloc(
build->substr_offsets,
1367 (
build->substr_alloc+1) *
sizeof(
OFF));
1368 if(new_substr_offsets ==
NULL) {
1369 MD_LOG(
"realloc() failed.");
1370 free(new_substr_types);
1374 build->substr_types = new_substr_types;
1375 build->substr_offsets = new_substr_offsets;
1379 build->substr_offsets[
build->substr_count] = off;
1380 build->substr_count++;
1389 if(
build->substr_alloc > 0) {
1391 free(
build->substr_types);
1392 free(
build->substr_offsets);
1397 md_build_attribute(
MD_CTX* ctx,
const CHAR* raw_text,
SZ raw_size,
1409 for(raw_off = 0; raw_off < raw_size; raw_off++) {
1419 build->substr_offsets =
build->trivial_offsets;
1420 build->substr_count = 1;
1421 build->substr_alloc = 0;
1423 build->trivial_offsets[0] = 0;
1424 build->trivial_offsets[1] = raw_size;
1429 MD_LOG(
"malloc() failed.");
1436 while(raw_off < raw_size) {
1437 if(raw_text[raw_off] ==
_T(
'\0')) {
1439 memcpy(
build->text + off, raw_text + raw_off, 1);
1445 if(raw_text[raw_off] ==
_T(
'&')) {
1448 if(md_is_entity_str(ctx, raw_text, raw_off, raw_size, &ent_end)) {
1450 memcpy(
build->text + off, raw_text + raw_off, ent_end - raw_off);
1451 off += ent_end - raw_off;
1461 raw_text[raw_off] ==
_T(
'\\') && raw_off+1 < raw_size &&
1465 build->text[off++] = raw_text[raw_off++];
1467 build->substr_offsets[
build->substr_count] = off;
1472 attr->substr_offsets =
build->substr_offsets;
1473 attr->substr_types =
build->substr_types;
1477 md_free_attribute(ctx,
build);
1486 #define MD_FNV1A_BASE 2166136261U
1487 #define MD_FNV1A_PRIME 16777619U
1489 static inline unsigned
1490 md_fnv1a(
unsigned base,
const void*
data,
size_t n)
1492 const unsigned char*
buf = (
const unsigned char*)
data;
1496 for(
i = 0;
i <
n;
i++) {
1529 off = md_skip_unicode_whitespace(
label, 0,
size);
1533 codepoint = md_decode_unicode(
label, off,
size, &char_size);
1538 hash = md_fnv1a(
hash, &codepoint,
sizeof(
unsigned));
1539 off = md_skip_unicode_whitespace(
label, off,
size);
1543 md_get_unicode_fold_info(codepoint, &fold_info);
1564 codepoint = md_decode_unicode(
label, off,
size, &char_size);
1572 md_get_unicode_fold_info(codepoint, fold_info);
1578 return md_skip_unicode_whitespace(
label, off,
size);
1582 md_link_label_cmp(
const CHAR* a_label,
SZ a_size,
const CHAR* b_label,
SZ b_size)
1592 a_off = md_skip_unicode_whitespace(a_label, 0, a_size);
1593 b_off = md_skip_unicode_whitespace(b_label, 0, b_size);
1594 while(a_off < a_size || a_fi_off < a_fi.
n_codepoints ||
1600 a_off = md_link_label_cmp_load_fold_info(a_label, a_off, a_size, &a_fi);
1604 b_off = md_link_label_cmp_load_fold_info(b_label, b_off, b_size, &b_fi);
1626 md_ref_def_cmp(
const void*
a,
const void*
b)
1640 md_ref_def_cmp_for_sort(
const void*
a,
const void*
b)
1644 cmp = md_ref_def_cmp(
a,
b);
1653 else if(a_ref > b_ref)
1663 md_build_ref_def_hashtable(
MD_CTX* ctx)
1673 MD_LOG(
"malloc() failed.");
1692 if(bucket ==
NULL) {
1712 MD_LOG(
"malloc() failed.");
1715 list->ref_defs[0] = old_def;
1716 list->ref_defs[1] = def;
1717 list->n_ref_defs = 2;
1718 list->alloc_ref_defs = 2;
1730 if(
list->n_ref_defs >=
list->alloc_ref_defs) {
1731 int alloc_ref_defs =
list->alloc_ref_defs +
list->alloc_ref_defs / 2;
1734 if(list_tmp ==
NULL) {
1735 MD_LOG(
"realloc() failed.");
1739 list->alloc_ref_defs = alloc_ref_defs;
1743 list->ref_defs[
list->n_ref_defs] = def;
1758 qsort(
list->ref_defs,
list->n_ref_defs,
sizeof(
MD_REF_DEF*), md_ref_def_cmp_for_sort);
1764 for(
j = 1;
j <
list->n_ref_defs;
j++) {
1765 if(md_ref_def_cmp(&
list->ref_defs[
j-1], &
list->ref_defs[
j]) == 0)
1777 md_free_ref_def_hashtable(
MD_CTX* ctx)
1804 hash = md_link_label_hash(
label, label_size);
1807 if(bucket ==
NULL) {
1857 OFF* p_end,
int* p_beg_line_index,
int* p_end_line_index,
1858 OFF* p_contents_beg,
OFF* p_contents_end)
1861 OFF contents_beg = 0;
1862 OFF contents_end = 0;
1866 if(
CH(off) !=
_T(
'['))
1871 OFF line_end = lines[line_index].
end;
1873 while(off < line_end) {
1875 if(contents_end == 0) {
1877 *p_beg_line_index = line_index;
1879 contents_end = off + 2;
1881 }
else if(
CH(off) ==
_T(
'[')) {
1883 }
else if(
CH(off) ==
_T(
']')) {
1884 if(contents_beg < contents_end) {
1886 *p_contents_beg = contents_beg;
1887 *p_contents_end = contents_end;
1889 *p_end_line_index = line_index;
1899 codepoint = md_decode_unicode(ctx->
text, off, ctx->
size, &char_size);
1901 if(contents_end == 0) {
1903 *p_beg_line_index = line_index;
1905 contents_end = off + char_size;
1918 if(line_index < n_lines)
1919 off = lines[line_index].
beg;
1928 md_is_link_destination_A(
MD_CTX* ctx,
OFF beg,
OFF max_end,
OFF* p_end,
1929 OFF* p_contents_beg,
OFF* p_contents_end)
1933 if(off >= max_end ||
CH(off) !=
_T(
'<'))
1937 while(off < max_end) {
1938 if(
CH(off) ==
_T(
'\\') && off+1 < max_end &&
ISPUNCT(off+1)) {
1946 if(
CH(off) ==
_T(
'>')) {
1948 *p_contents_beg = beg+1;
1949 *p_contents_end = off;
1961 md_is_link_destination_B(
MD_CTX* ctx,
OFF beg,
OFF max_end,
OFF* p_end,
1962 OFF* p_contents_beg,
OFF* p_contents_end)
1965 int parenthesis_level = 0;
1967 while(off < max_end) {
1968 if(
CH(off) ==
_T(
'\\') && off+1 < max_end &&
ISPUNCT(off+1)) {
1979 if(
CH(off) ==
_T(
'(')) {
1980 parenthesis_level++;
1981 if(parenthesis_level > 32)
1983 }
else if(
CH(off) ==
_T(
')')) {
1984 if(parenthesis_level == 0)
1986 parenthesis_level--;
1992 if(parenthesis_level != 0 || off == beg)
1996 *p_contents_beg = beg;
1997 *p_contents_end = off;
2004 OFF* p_contents_beg,
OFF* p_contents_end)
2006 if(
CH(beg) ==
_T(
'<'))
2007 return md_is_link_destination_A(ctx, beg, max_end, p_end, p_contents_beg, p_contents_end);
2009 return md_is_link_destination_B(ctx, beg, max_end, p_end, p_contents_beg, p_contents_end);
2014 OFF* p_end,
int* p_beg_line_index,
int* p_end_line_index,
2015 OFF* p_contents_beg,
OFF* p_contents_end)
2024 if(off >= lines[line_index].
end) {
2026 if(line_index >= n_lines)
2028 off = lines[line_index].
beg;
2033 *p_beg_line_index = line_index;
2037 case _T(
'"'): closer_char =
_T(
'"');
break;
2038 case _T(
'\''): closer_char =
_T(
'\'');
break;
2039 case _T(
'('): closer_char =
_T(
')');
break;
2040 default:
return FALSE;
2044 *p_contents_beg = off;
2046 while(line_index < n_lines) {
2047 OFF line_end = lines[line_index].
end;
2049 while(off < line_end) {
2052 }
else if(
CH(off) == closer_char) {
2054 *p_contents_end = off;
2056 *p_end_line_index = line_index;
2058 }
else if(closer_char ==
_T(
')') &&
CH(off) ==
_T(
'(')) {
2081 md_is_link_reference_definition(
MD_CTX* ctx,
const MD_LINE* lines,
int n_lines)
2083 OFF label_contents_beg;
2084 OFF label_contents_end;
2085 int label_contents_line_index = -1;
2086 int label_is_multiline =
FALSE;
2087 OFF dest_contents_beg;
2088 OFF dest_contents_end;
2089 OFF title_contents_beg;
2090 OFF title_contents_end;
2091 int title_contents_line_index;
2092 int title_is_multiline =
FALSE;
2100 if(!md_is_link_label(ctx, lines, n_lines, lines[0].beg,
2101 &off, &label_contents_line_index, &line_index,
2102 &label_contents_beg, &label_contents_end))
2104 label_is_multiline = (label_contents_line_index != line_index);
2107 if(off >= lines[line_index].
end ||
CH(off) !=
_T(
':'))
2114 if(off >= lines[line_index].
end) {
2116 if(line_index >= n_lines)
2118 off = lines[line_index].
beg;
2122 if(!md_is_link_destination(ctx, off, lines[line_index].
end,
2123 &off, &dest_contents_beg, &dest_contents_end))
2128 if(md_is_link_title(ctx, lines + line_index, n_lines - line_index, off,
2129 &off, &title_contents_line_index, &tmp_line_index,
2130 &title_contents_beg, &title_contents_end)
2131 && off >= lines[line_index + tmp_line_index].
end)
2133 title_is_multiline = (tmp_line_index != title_contents_line_index);
2134 title_contents_line_index += line_index;
2135 line_index += tmp_line_index;
2138 title_is_multiline =
FALSE;
2139 title_contents_beg = off;
2140 title_contents_end = off;
2141 title_contents_line_index = 0;
2145 if(off < lines[line_index].
end)
2156 if(new_defs ==
NULL) {
2157 MD_LOG(
"realloc() failed.");
2166 if(label_is_multiline) {
2167 MD_CHECK(md_merge_lines_alloc(ctx, label_contents_beg, label_contents_end,
2168 lines + label_contents_line_index, n_lines - label_contents_line_index,
2173 def->
label_size = label_contents_end - label_contents_beg;
2176 if(title_is_multiline) {
2177 MD_CHECK(md_merge_lines_alloc(ctx, title_contents_beg, title_contents_end,
2178 lines + title_contents_line_index, n_lines - title_contents_line_index,
2183 def->
title_size = title_contents_end - title_contents_beg;
2191 return line_index + 1;
2203 md_is_link_reference(
MD_CTX* ctx,
const MD_LINE* lines,
int n_lines,
2216 beg += (
CH(beg) ==
_T(
'!') ? 2 : 1);
2222 while(beg >= beg_line->
end)
2226 end_line = beg_line;
2227 while(
end >= end_line->
end)
2230 if(beg_line != end_line) {
2231 MD_CHECK(md_merge_lines_alloc(ctx, beg,
end, beg_line,
2232 (
int)(n_lines - (beg_line - lines)),
_T(
' '), &
label, &label_size));
2235 label_size =
end - beg;
2238 def = md_lookup_ref_def(ctx,
label, label_size);
2247 if(beg_line != end_line)
2257 md_is_inline_link_spec(
MD_CTX* ctx,
const MD_LINE* lines,
int n_lines,
2262 OFF title_contents_beg;
2263 OFF title_contents_end;
2264 int title_contents_line_index;
2265 int title_is_multiline;
2269 while(off >= lines[line_index].
end)
2280 if(line_index >= n_lines)
2282 off = lines[line_index].
beg;
2286 if(off < ctx->
size &&
CH(off) ==
_T(
')')) {
2287 attr->dest_beg = off;
2288 attr->dest_end = off;
2290 attr->title_size = 0;
2298 if(!md_is_link_destination(ctx, off, lines[line_index].
end,
2299 &off, &
attr->dest_beg, &
attr->dest_end))
2303 if(md_is_link_title(ctx, lines + line_index, n_lines - line_index, off,
2304 &off, &title_contents_line_index, &tmp_line_index,
2305 &title_contents_beg, &title_contents_end))
2307 title_is_multiline = (tmp_line_index != title_contents_line_index);
2308 title_contents_line_index += line_index;
2309 line_index += tmp_line_index;
2312 title_is_multiline =
FALSE;
2313 title_contents_beg = off;
2314 title_contents_end = off;
2315 title_contents_line_index = 0;
2323 if(line_index >= n_lines)
2325 off = lines[line_index].
beg;
2327 if(
CH(off) !=
_T(
')'))
2331 if(title_contents_beg >= title_contents_end) {
2333 attr->title_size = 0;
2335 }
else if(!title_is_multiline) {
2337 attr->title_size = title_contents_end - title_contents_beg;
2340 MD_CHECK(md_merge_lines_alloc(ctx, title_contents_beg, title_contents_end,
2341 lines + title_contents_line_index, n_lines - title_contents_line_index,
2354 md_free_ref_defs(
MD_CTX* ctx)
2454 #define MD_MARK_POTENTIAL_OPENER 0x01
2455 #define MD_MARK_POTENTIAL_CLOSER 0x02
2456 #define MD_MARK_OPENER 0x04
2457 #define MD_MARK_CLOSER 0x08
2458 #define MD_MARK_RESOLVED 0x10
2461 #define MD_MARK_EMPH_INTRAWORD 0x20
2462 #define MD_MARK_EMPH_MOD3_0 0x40
2463 #define MD_MARK_EMPH_MOD3_1 0x80
2464 #define MD_MARK_EMPH_MOD3_2 (0x40 | 0x80)
2465 #define MD_MARK_EMPH_MOD3_MASK (0x40 | 0x80)
2466 #define MD_MARK_AUTOLINK 0x20
2467 #define MD_MARK_VALIDPERMISSIVEAUTOLINK 0x20
2485 md_mark_chain(
MD_CTX* ctx,
int mark_index)
2495 default:
return NULL;
2500 md_push_mark(
MD_CTX* ctx)
2509 if(new_marks ==
NULL) {
2510 MD_LOG(
"realloc() failed.");
2514 ctx->
marks = new_marks;
2520 #define PUSH_MARK_() \
2522 mark = md_push_mark(ctx); \
2523 if(mark == NULL) { \
2529 #define PUSH_MARK(ch_, beg_, end_, flags_) \
2532 mark->beg = (beg_); \
2533 mark->end = (end_); \
2536 mark->ch = (char)(ch_); \
2537 mark->flags = (flags_); \
2544 if(chain->
tail >= 0)
2547 chain->
head = mark_index;
2551 chain->
tail = mark_index;
2558 md_mark_store_ptr(
MD_CTX* ctx,
int mark_index,
void* ptr)
2565 memcpy(mark, &ptr,
sizeof(
void*));
2569 md_mark_get_ptr(
MD_CTX* ctx,
int mark_index)
2574 memcpy(&ptr, mark,
sizeof(
void*));
2579 md_resolve_range(
MD_CTX* ctx,
MD_MARKCHAIN* chain,
int opener_index,
int closer_index)
2598 opener->next = closer_index;
2600 closer->prev = opener_index;
2605 #define MD_ROLLBACK_ALL 0
2606 #define MD_ROLLBACK_CROSSING 1
2624 md_rollback(
MD_CTX* ctx,
int opener_index,
int closer_index,
int how)
2633 while(chain->
tail >= opener_index)
2636 if(chain->
tail >= 0)
2644 mark_index = closer_index - 1;
2645 while(mark_index > opener_index) {
2647 int mark_flags = mark->
flags;
2651 int mark_opener_index = mark->
prev;
2654 if(mark_opener_index < opener_index) {
2659 chain = md_mark_chain(ctx, opener_index);
2661 md_mark_chain_append(ctx, chain, mark_opener_index);
2677 mark_index = mark->
prev;
2689 md_build_mark_char_map(
MD_CTX* ctx)
2737 #define CODESPAN_MARK_MAXLEN 32
2741 OFF* p_opener_beg,
OFF* p_opener_end,
2742 OFF* p_closer_beg,
OFF* p_closer_end,
2744 int* p_reached_paragraph_end)
2746 OFF opener_beg = beg;
2752 int has_space_after_opener =
FALSE;
2753 int has_eol_after_opener =
FALSE;
2754 int has_space_before_closer =
FALSE;
2755 int has_eol_before_closer =
FALSE;
2756 int has_only_space =
TRUE;
2759 line_end = lines[0].
end;
2760 opener_end = opener_beg;
2761 while(opener_end < line_end &&
CH(opener_end) ==
_T(
'`'))
2763 has_space_after_opener = (opener_end < line_end &&
CH(opener_end) ==
_T(
' '));
2764 has_eol_after_opener = (opener_end == line_end);
2767 *p_opener_end = opener_end;
2769 mark_len = opener_end - opener_beg;
2775 if(last_potential_closers[mark_len-1] >= lines[n_lines-1].
end ||
2776 (*p_reached_paragraph_end && last_potential_closers[mark_len-1] < opener_end))
2779 closer_beg = opener_end;
2780 closer_end = opener_end;
2784 while(closer_beg < line_end &&
CH(closer_beg) !=
_T(
'`')) {
2785 if(
CH(closer_beg) !=
_T(
' '))
2786 has_only_space =
FALSE;
2789 closer_end = closer_beg;
2790 while(closer_end < line_end &&
CH(closer_end) ==
_T(
'`'))
2793 if(closer_end - closer_beg == mark_len) {
2795 has_space_before_closer = (closer_beg > lines[line_index].
beg &&
CH(closer_beg-1) ==
_T(
' '));
2796 has_eol_before_closer = (closer_beg == lines[line_index].
beg);
2800 if(closer_end - closer_beg > 0) {
2802 has_only_space =
FALSE;
2808 if(closer_beg > last_potential_closers[closer_end - closer_beg - 1])
2809 last_potential_closers[closer_end - closer_beg - 1] = closer_beg;
2813 if(closer_end >= line_end) {
2815 if(line_index >= n_lines) {
2817 *p_reached_paragraph_end =
TRUE;
2821 line_end = lines[line_index].
end;
2822 closer_beg = lines[line_index].
beg;
2824 closer_beg = closer_end;
2831 if(!has_only_space &&
2832 (has_space_after_opener || has_eol_after_opener) &&
2833 (has_space_before_closer || has_eol_before_closer))
2835 if(has_space_after_opener)
2838 opener_end = lines[1].
beg;
2840 if(has_space_before_closer)
2843 closer_beg = lines[line_index-1].
end;
2846 while(closer_beg < ctx->
size &&
ISBLANK(closer_beg))
2851 *p_opener_beg = opener_beg;
2852 *p_opener_end = opener_end;
2853 *p_closer_beg = closer_beg;
2854 *p_closer_end = closer_end;
2866 if(off >= max_end || !
ISASCII(off))
2874 if(
CH(off) ==
_T(
':') && off - beg >= 3)
2882 while(off < max_end &&
CH(off) !=
_T(
'>')) {
2911 while(off < max_end && (
ISALNUM(off) ||
ISANYOF(off,
_T(
".!#$%&'*+/=?^_`{|}~-"))))
2917 if(off >= max_end ||
CH(off) !=
_T(
'@'))
2924 while(off < max_end) {
2927 else if(
CH(off) ==
_T(
'-') && label_len > 0)
2929 else if(
CH(off) ==
_T(
'.') && label_len > 0 &&
CH(off-1) !=
_T(
'-'))
2940 if(label_len <= 0 || off >= max_end ||
CH(off) !=
_T(
'>') ||
CH(off-1) ==
_T(
'-'))
2948 md_is_autolink(
MD_CTX* ctx,
OFF beg,
OFF max_end,
OFF* p_end,
int* p_missing_mailto)
2950 if(md_is_autolink_uri(ctx, beg, max_end, p_end)) {
2951 *p_missing_mailto =
FALSE;
2955 if(md_is_autolink_email(ctx, beg, max_end, p_end)) {
2956 *p_missing_mailto =
TRUE;
2964 md_collect_marks(
MD_CTX* ctx,
const MD_LINE* lines,
int n_lines,
int table_mode)
2970 int codespan_scanned_till_paragraph_end =
FALSE;
2972 for(
i = 0;
i < n_lines;
i++) {
2980 #ifdef MD4C_USE_UTF16
2982 #define IS_MARK_CHAR(off) ((CH(off) < SIZEOF_ARRAY(ctx->mark_char_map)) && \
2983 (ctx->mark_char_map[(unsigned char) CH(off)]))
2986 #define IS_MARK_CHAR(off) (ctx->mark_char_map[(unsigned char) CH(off)])
3013 if(
ch ==
_T(
'*') ||
ch ==
_T(
'_')) {
3018 while(tmp < line_end &&
CH(tmp) ==
ch)
3036 if(
ch ==
_T(
'_') && left_level == 2 && right_level == 2) {
3041 if(left_level != 0 || right_level != 0) {
3044 if(left_level > 0 && left_level >= right_level)
3046 if(right_level > 0 && right_level >= left_level)
3048 if(left_level == 2 && right_level == 2)
3055 switch((tmp - off) % 3) {
3081 OFF opener_beg, opener_end;
3082 OFF closer_beg, closer_end;
3085 is_code_span = md_is_code_span(ctx, lines +
i, n_lines -
i, off,
3086 &opener_beg, &opener_end, &closer_beg, &closer_end,
3087 codespan_last_potential_closers,
3088 &codespan_scanned_till_paragraph_end);
3098 while(off > line_end) {
3140 is_html = md_is_html_any(ctx, lines +
i, n_lines -
i, off,
3141 lines[n_lines-1].
end, &html_end);
3150 while(off > line_end) {
3159 is_autolink = md_is_autolink(ctx, off, lines[n_lines-1].
end,
3160 &autolink_end, &missing_mailto);
3177 if(
ch ==
_T(
'[') || (
ch ==
_T(
'!') && off+1 < line_end &&
CH(off+1) ==
_T(
'['))) {
3178 OFF tmp = (
ch ==
_T(
'[') ? off+1 : off+2);
3216 {
_T(
"http"), 4,
_T(
"//"), 2 },
3217 {
_T(
"https"), 5,
_T(
"//"), 2 },
3218 {
_T(
"ftp"), 3,
_T(
"//"), 2 }
3222 for(scheme_index = 0; scheme_index < (int)
SIZEOF_ARRAY(scheme_map); scheme_index++) {
3223 const CHAR* scheme = scheme_map[scheme_index].scheme;
3224 const SZ scheme_size = scheme_map[scheme_index].scheme_size;
3225 const CHAR* suffix = scheme_map[scheme_index].suffix;
3226 const SZ suffix_size = scheme_map[scheme_index].suffix_size;
3228 if(
line->beg + scheme_size <= off && md_ascii_eq(
STR(off-scheme_size), scheme, scheme_size) &&
3230 off + 1 + suffix_size < line->
end && md_ascii_eq(
STR(off+1), suffix, suffix_size))
3235 off += 1 + suffix_size;
3246 if(
line->beg + 3 <= off && md_ascii_eq(
STR(off-3),
_T(
"www"), 3) &&
3272 while(tmp < line_end &&
CH(tmp) ==
_T(
'~'))
3296 while(tmp < line_end &&
CH(tmp) ==
_T(
'$'))
3312 if(tmp - off > 1 ||
ch !=
_T(
' '))
3320 if(
ch ==
_T(
'\0')) {
3339 md_analyze_bracket(
MD_CTX* ctx,
int mark_index)
3372 opener->next = mark_index;
3373 mark->
prev = opener_index;
3388 static void md_analyze_link_contents(
MD_CTX* ctx,
const MD_LINE* lines,
int n_lines,
3389 int mark_beg,
int mark_end);
3392 md_resolve_links(
MD_CTX* ctx,
const MD_LINE* lines,
int n_lines)
3395 OFF last_link_beg = 0;
3396 OFF last_link_end = 0;
3397 OFF last_img_beg = 0;
3398 OFF last_img_end = 0;
3400 while(opener_index >= 0) {
3402 int closer_index =
opener->next;
3404 int next_index =
opener->prev;
3408 int is_link =
FALSE;
3410 if(next_index >= 0) {
3411 next_opener = &ctx->
marks[next_index];
3412 next_closer = &ctx->
marks[next_opener->
next];
3425 if((
opener->beg < last_link_beg &&
closer->end < last_link_end) ||
3426 (
opener->beg < last_img_beg &&
closer->end < last_img_end) ||
3429 opener_index = next_index;
3438 next_opener !=
NULL &&
3439 next_opener->
ch ==
'[' &&
3440 (next_opener->
beg ==
opener->beg - 1) &&
3441 (next_opener->
end - next_opener->
beg == 1) &&
3442 next_closer !=
NULL &&
3443 next_closer->
ch ==
']' &&
3444 (next_closer->
beg ==
closer->beg + 1) &&
3445 (next_closer->
end - next_closer->
beg == 1))
3449 OFF dest_beg, dest_end;
3456 delim_index = opener_index + 1;
3457 while(delim_index < closer_index) {
3463 if(
m->ch !=
'D' &&
m->beg -
opener->end > 100)
3469 if(dest_end - dest_beg == 0 || dest_end - dest_beg > 100)
3475 for(off = dest_beg; off < dest_end; off++) {
3495 opener->next = closer_index;
3499 closer->prev = opener_index;
3502 last_link_beg =
opener->beg;
3503 last_link_end =
closer->end;
3508 md_analyze_link_contents(ctx, lines, n_lines, opener_index+1, closer_index);
3513 opener_index = next_opener->
prev;
3518 if(next_opener !=
NULL && next_opener->
beg ==
closer->end) {
3519 if(next_closer->
beg >
closer->end + 1) {
3521 is_link = md_is_link_reference(ctx, lines, n_lines, next_opener->
beg, next_closer->
end, &
attr);
3524 is_link = md_is_link_reference(ctx, lines, n_lines,
opener->beg,
closer->end, &
attr);
3536 next_index = ctx->
marks[next_index].
prev;
3541 OFF inline_link_end = UINT_MAX;
3543 is_link = md_is_inline_link_spec(ctx, lines, n_lines,
closer->end, &inline_link_end, &
attr);
3550 int i = closer_index + 1;
3552 while(i < ctx->n_marks) {
3555 if(mark->
beg >= inline_link_end)
3560 if(
attr.title_needs_free)
3575 closer->end = inline_link_end;
3581 is_link = md_is_link_reference(ctx, lines, n_lines,
opener->beg,
closer->end, &
attr);
3599 md_mark_store_ptr(ctx, opener_index+2,
attr.title);
3601 if(
attr.title_needs_free)
3602 md_mark_chain_append(ctx, &
PTR_CHAIN, opener_index+2);
3606 last_link_beg =
opener->beg;
3607 last_link_end =
closer->end;
3609 last_img_beg =
opener->beg;
3610 last_img_end =
closer->end;
3613 md_analyze_link_contents(ctx, lines, n_lines, opener_index+1, closer_index);
3622 first_nested =
opener + 1;
3623 while(first_nested->
ch ==
_T(
'D') && first_nested <
closer)
3626 last_nested =
closer - 1;
3627 while(first_nested->
ch ==
_T(
'D') && last_nested >
opener)
3633 first_nested->
next == (last_nested - ctx->
marks) &&
3636 first_nested->
ch =
_T(
'D');
3638 last_nested->
ch =
_T(
'D');
3644 opener_index = next_index;
3653 md_analyze_entity(
MD_CTX* ctx,
int mark_index)
3666 if(mark_index + 1 >= ctx->
n_marks)
3672 if(md_is_entity(ctx,
opener->beg,
closer->end, &off)) {
3675 md_resolve_range(ctx,
NULL, mark_index, mark_index+1);
3681 md_analyze_table_cell_boundary(
MD_CTX* ctx,
int mark_index)
3695 md_split_emph_mark(
MD_CTX* ctx,
int mark_index,
SZ n)
3698 int new_mark_index = mark_index + (mark->
end - mark->
beg -
n);
3708 return new_mark_index;
3712 md_analyze_emph(
MD_CTX* ctx,
int mark_index)
3720 int opener_index = 0;
3722 if(mark->
ch ==
_T(
'*')) {
3724 int i, n_opener_chains;
3728 n_opener_chains = 0;
3741 for(
i = 0;
i < n_opener_chains;
i++) {
3742 if(opener_chains[
i]->tail >= 0) {
3743 int tmp_index = opener_chains[
i]->
tail;
3746 opener_index = tmp_index;
3753 if(chain->
tail >= 0) {
3754 opener_index = chain->
tail;
3762 SZ closer_size = mark->
end - mark->
beg;
3763 MD_MARKCHAIN* opener_chain = md_mark_chain(ctx, opener_index);
3765 if(opener_size > closer_size) {
3766 opener_index = md_split_emph_mark(ctx, opener_index, closer_size);
3767 md_mark_chain_append(ctx, opener_chain, opener_index);
3768 }
else if(opener_size < closer_size) {
3769 md_split_emph_mark(ctx, mark_index, closer_size - opener_size);
3773 md_resolve_range(ctx, opener_chain, opener_index, mark_index);
3780 md_mark_chain_append(ctx, chain, mark_index);
3784 md_analyze_tilde(
MD_CTX* ctx,
int mark_index)
3794 int opener_index = chain->
head;
3797 md_resolve_range(ctx, chain, opener_index, mark_index);
3802 md_mark_chain_append(ctx, chain, mark_index);
3806 md_analyze_dollar(
MD_CTX* ctx,
int mark_index)
3824 md_resolve_range(ctx, &
DOLLAR_OPENERS, opener_index, mark_index);
3836 md_analyze_permissive_url_autolink(
MD_CTX* ctx,
int mark_index)
3839 int closer_index = mark_index + 1;
3844 int has_underscore_in_last_seg =
FALSE;
3845 int has_underscore_in_next_to_last_seg =
FALSE;
3846 int n_opened_parenthesis = 0;
3847 int n_excess_parenthesis = 0;
3850 while(off < ctx->
size) {
3853 }
else if(
CH(off) ==
_T(
'.')) {
3856 has_underscore_in_next_to_last_seg = has_underscore_in_last_seg;
3857 has_underscore_in_last_seg =
FALSE;
3859 }
else if(
CH(off) ==
_T(
'_')) {
3861 has_underscore_in_last_seg =
TRUE;
3867 if(off >
opener->end &&
CH(off-1) ==
_T(
'.')) {
3871 if(off <= opener->
end || n_dots == 0 || has_underscore_in_next_to_last_seg || has_underscore_in_last_seg)
3875 next_resolved_mark =
closer + 1;
3877 next_resolved_mark++;
3880 if(
CH(off) ==
_T(
'(')) {
3881 n_opened_parenthesis++;
3882 }
else if(
CH(off) ==
_T(
')')) {
3883 if(n_opened_parenthesis > 0)
3884 n_opened_parenthesis--;
3886 n_excess_parenthesis++;
3896 }
else if(
CH(off-1) ==
')' && n_excess_parenthesis > 0) {
3901 n_excess_parenthesis--;
3914 md_resolve_range(ctx,
NULL, mark_index, closer_index);
3922 md_analyze_permissive_email_autolink(
MD_CTX* ctx,
int mark_index)
3949 if(
CH(
end-1) ==
_T(
'@') || dot_count == 0)
3954 closer_index = mark_index + 1;
3963 md_resolve_range(ctx,
NULL, mark_index, closer_index);
3967 md_analyze_marks(
MD_CTX* ctx,
const MD_LINE* lines,
int n_lines,
3968 int mark_beg,
int mark_end,
const CHAR* mark_chars)
3974 while(
i < mark_end) {
3998 case ']': md_analyze_bracket(ctx,
i);
break;
3999 case '&': md_analyze_entity(ctx,
i);
break;
4000 case '|': md_analyze_table_cell_boundary(ctx,
i);
break;
4002 case '*': md_analyze_emph(ctx,
i);
break;
4003 case '~': md_analyze_tilde(ctx,
i);
break;
4004 case '$': md_analyze_dollar(ctx,
i);
break;
4006 case ':': md_analyze_permissive_url_autolink(ctx,
i);
break;
4007 case '@': md_analyze_permissive_email_autolink(ctx,
i);
break;
4016 md_analyze_inlines(
MD_CTX* ctx,
const MD_LINE* lines,
int n_lines,
int table_mode)
4024 MD_CHECK(md_collect_marks(ctx, lines, n_lines, table_mode));
4028 md_analyze_marks(ctx, lines, n_lines, 0, ctx->
n_marks,
_T(
"&"));
4031 md_analyze_marks(ctx, lines, n_lines, 0, ctx->
n_marks,
_T(
"[]!"));
4032 MD_CHECK(md_resolve_links(ctx, lines, n_lines));
4046 md_analyze_marks(ctx, lines, n_lines, 0, ctx->
n_marks,
_T(
"|"));
4051 md_analyze_link_contents(ctx, lines, n_lines, 0, ctx->
n_marks);
4058 md_analyze_link_contents(
MD_CTX* ctx,
const MD_LINE* lines,
int n_lines,
4059 int mark_beg,
int mark_end)
4063 md_analyze_marks(ctx, lines, n_lines, mark_beg, mark_end,
_T(
"*_~$@:."));
4073 const CHAR* dest,
SZ dest_size,
int prohibit_escapes_in_dest,
4084 MD_CHECK(md_build_attribute(ctx, dest, dest_size,
4086 &det.
href, &href_build));
4095 md_free_attribute(ctx, &href_build);
4096 md_free_attribute(ctx, &title_build);
4101 md_enter_leave_span_wikilink(
MD_CTX* ctx,
int enter,
const CHAR*
target,
SZ target_size)
4116 md_free_attribute(ctx, &target_build);
4123 md_process_inlines(
MD_CTX* ctx,
const MD_LINE* lines,
int n_lines)
4131 int enforce_hardbreak = 0;
4153 if(off >= mark->
beg) {
4157 enforce_hardbreak = 1;
4179 while(off < mark->
end) {
4184 while(off < mark->
end) {
4195 if((mark->
end - off) % 2) {
4199 while(off + 1 < mark->
end) {
4204 while(off + 1 < mark->
end) {
4208 if((mark->
end - off) % 2) {
4253 MD_CHECK(md_enter_leave_span_wikilink(ctx, (mark->
ch !=
']'),
4265 MD_CHECK(md_enter_leave_span_a(ctx, (mark->
ch !=
']'),
4268 md_mark_get_ptr(ctx, (
int)(title_mark - ctx->
marks)), title_mark->
prev));
4271 if(mark->
ch ==
']') {
4314 (
opener->ch ==
'@' ?
_T(
"mailto:") :
_T(
"http://")),
4316 memcpy(ctx->
buffer + 7, dest, (dest_size-7) *
sizeof(
CHAR));
4369 if(prev_mark->
end < off && off < mark->beg)
4386 if(enforce_hardbreak)
4399 enforce_hardbreak = 0;
4418 while(n_align > 0) {
4421 while(
CH(off) !=
_T(
'-'))
4423 if(off > beg &&
CH(off-1) ==
_T(
':'))
4425 while(off <
end &&
CH(off) ==
_T(
'-'))
4427 if(off <
end &&
CH(off) ==
_T(
':'))
4430 *align = align_map[
index];
4438 static int md_process_normal_block_contents(
MD_CTX* ctx,
const MD_LINE* lines,
int n_lines);
4457 MD_CHECK(md_process_normal_block_contents(ctx, &
line, 1));
4466 const MD_ALIGN* align,
int col_count)
4483 pipe_offs = (
OFF*) malloc(
n *
sizeof(
OFF));
4484 if(pipe_offs ==
NULL) {
4485 MD_LOG(
"malloc() failed.");
4490 pipe_offs[
j++] = beg;
4493 pipe_offs[
j++] = mark->
end;
4495 pipe_offs[
j++] =
end+1;
4500 for(
i = 0;
i <
j-1 && k < col_count;
i++) {
4501 if(pipe_offs[
i] < pipe_offs[
i+1]-1)
4502 MD_CHECK(md_process_table_cell(ctx, cell_type, align[k++], pipe_offs[
i], pipe_offs[
i+1]-1));
4506 while(k < col_count)
4507 MD_CHECK(md_process_table_cell(ctx, cell_type, align[k++], 0, 0));
4515 free(md_mark_get_ptr(ctx,
i));
4523 md_process_table_block_contents(
MD_CTX* ctx,
int col_count,
const MD_LINE* lines,
int n_lines)
4533 align = malloc(col_count *
sizeof(
MD_ALIGN));
4535 MD_LOG(
"malloc() failed.");
4540 md_analyze_table_alignment(ctx, lines[1].beg, lines[1].
end, align, col_count);
4544 lines[0].beg, lines[0].
end, align, col_count));
4549 for(
i = 2;
i < n_lines;
i++) {
4551 lines[
i].beg, lines[
i].
end, align, col_count));
4566 #define MD_BLOCK_CONTAINER_OPENER 0x01
4567 #define MD_BLOCK_CONTAINER_CLOSER 0x02
4568 #define MD_BLOCK_CONTAINER (MD_BLOCK_CONTAINER_OPENER | MD_BLOCK_CONTAINER_CLOSER)
4569 #define MD_BLOCK_LOOSE_LIST 0x04
4570 #define MD_BLOCK_SETEXT_HEADER 0x08
4603 md_process_normal_block_contents(
MD_CTX* ctx,
const MD_LINE* lines,
int n_lines)
4609 MD_CHECK(md_process_inlines(ctx, lines, n_lines));
4614 free(md_mark_get_ptr(ctx,
i));
4624 static const CHAR indent_chunk_str[] =
_T(
" ");
4625 static const SZ indent_chunk_size =
SIZEOF_ARRAY(indent_chunk_str) - 1;
4630 for(
i = 0;
i < n_lines;
i++) {
4632 int indent =
line->indent;
4637 while(indent > (
int) indent_chunk_size) {
4638 MD_TEXT(text_type, indent_chunk_str, indent_chunk_size);
4639 indent -= indent_chunk_size;
4642 MD_TEXT(text_type, indent_chunk_str, indent);
4656 md_process_code_block_contents(
MD_CTX* ctx,
int is_fenced,
const MD_VERBATIMLINE* lines,
int n_lines)
4665 while(n_lines > 0 && lines[0].beg == lines[0].
end) {
4669 while(n_lines > 0 && lines[n_lines-1].beg == lines[n_lines-1].
end) {
4677 return md_process_verbatim_block_contents(ctx,
MD_TEXT_CODE, lines, n_lines);
4685 OFF beg = fence_line->
beg;
4692 while(beg < ctx->
size &&
CH(beg) == fence_ch)
4695 while(beg < ctx->
size &&
CH(beg) ==
_T(
' '))
4709 MD_CHECK(md_build_attribute(ctx,
STR(beg), lang_end - beg, 0, &det->
lang, lang_build));
4727 int is_in_tight_list;
4728 int clean_fence_code_detail =
FALSE;
4731 memset(&det, 0,
sizeof(det));
4734 is_in_tight_list =
FALSE;
4738 switch(
block->type) {
4740 det.header.level =
block->data;
4745 if(
block->data != 0) {
4747 clean_fence_code_detail =
TRUE;
4748 MD_CHECK(md_setup_fenced_code_detail(ctx,
block, &det.code, &info_build, &lang_build));
4753 det.table.col_count =
block->data;
4754 det.table.head_row_count = 1;
4755 det.table.body_row_count =
block->n_lines - 2;
4767 switch(
block->type) {
4773 MD_CHECK(md_process_code_block_contents(ctx, (
block->data != 0),
4788 MD_CHECK(md_process_normal_block_contents(ctx,
4797 if(clean_fence_code_detail) {
4798 md_free_attribute(ctx, &info_build);
4799 md_free_attribute(ctx, &lang_build);
4805 md_process_all_blocks(
MD_CTX* ctx)
4816 while(byte_off < ctx->n_block_bytes) {
4824 switch(
block->type) {
4831 det.ol.start =
block->n_lines;
4833 det.ol.mark_delimiter = (
CHAR)
block->data;
4837 det.li.is_task = (
block->data != 0);
4839 det.li.task_mark_offset = (
OFF)
block->n_lines;
4893 md_push_block_bytes(
MD_CTX* ctx,
int n_bytes)
4898 void* new_block_bytes;
4904 if(new_block_bytes ==
NULL) {
4905 MD_LOG(
"realloc() failed.");
4934 switch(
line->type) {
4980 md_consume_link_reference_definitions(
MD_CTX* ctx)
4988 while(
n < n_lines) {
4989 int n_link_ref_lines;
4991 n_link_ref_lines = md_is_link_reference_definition(ctx,
4992 lines +
n, n_lines -
n);
4994 if(n_link_ref_lines == 0)
4999 if(n_link_ref_lines < 0)
5002 n += n_link_ref_lines;
5025 md_end_current_block(
MD_CTX* ctx)
5039 if(
CH(lines[0].beg) ==
_T(
'[')) {
5040 MD_CHECK(md_consume_link_reference_definitions(ctx));
5105 MD_CHECK(md_end_current_block(ctx));
5132 while(off < ctx->
size && (
CH(off) ==
CH(beg) ||
CH(off) ==
_T(
' ') ||
CH(off) ==
_T(
'\t'))) {
5133 if(
CH(off) ==
CH(beg))
5154 md_is_atxheader_line(
MD_CTX* ctx,
OFF beg,
OFF* p_beg,
OFF* p_end,
unsigned* p_level)
5159 while(off < ctx->
size &&
CH(off) ==
_T(
'#') && off - beg < 7)
5171 while(off < ctx->
size &&
CH(off) ==
_T(
' '))
5179 md_is_setext_underline(
MD_CTX* ctx,
OFF beg,
OFF* p_end,
unsigned* p_level)
5183 while(off < ctx->
size &&
CH(off) ==
CH(beg))
5187 while(off < ctx->
size &&
CH(off) ==
_T(
' '))
5194 *p_level = (
CH(beg) ==
_T(
'=') ? 1 : 2);
5200 md_is_table_underline(
MD_CTX* ctx,
OFF beg,
OFF* p_end,
unsigned* p_col_count)
5203 int found_pipe =
FALSE;
5204 unsigned col_count = 0;
5206 if(off < ctx->
size &&
CH(off) ==
_T(
'|')) {
5215 int delimited =
FALSE;
5219 if(off < ctx->
size &&
CH(off) ==
_T(
':'))
5221 while(off < ctx->
size &&
CH(off) ==
_T(
'-'))
5223 if(off < ctx->
size &&
CH(off) ==
_T(
':'))
5225 if(off - cell_beg < 3)
5233 if(off < ctx->
size &&
CH(off) ==
_T(
'|')) {
5253 *p_col_count = col_count;
5258 md_is_opening_code_fence(
MD_CTX* ctx,
OFF beg,
OFF* p_end)
5262 while(off < ctx->
size &&
CH(off) ==
CH(beg))
5272 while(off < ctx->
size &&
CH(off) ==
_T(
' '))
5278 if(
CH(beg) ==
_T(
'`') &&
CH(off) ==
_T(
'`'))
5295 while(off < ctx->
size &&
CH(off) ==
ch)
5297 if(off - beg < ctx->code_fence_length)
5301 while(off < ctx->
size &&
CH(off) ==
_T(
' '))
5321 md_is_html_block_start_condition(
MD_CTX* ctx,
OFF beg)
5323 typedef struct TAG_tag
TAG;
5334 #define X(name) { _T(name), (sizeof(name)-1) / sizeof(CHAR) }
5335 #define Xend { NULL, 0 }
5336 static const TAG t1[] = {
X(
"script"),
X(
"pre"),
X(
"style"),
Xend };
5338 static const TAG a6[] = {
X(
"address"),
X(
"article"),
X(
"aside"),
Xend };
5339 static const TAG b6[] = {
X(
"base"),
X(
"basefont"),
X(
"blockquote"),
X(
"body"),
Xend };
5340 static const TAG c6[] = {
X(
"caption"),
X(
"center"),
X(
"col"),
X(
"colgroup"),
Xend };
5341 static const TAG d6[] = {
X(
"dd"),
X(
"details"),
X(
"dialog"),
X(
"dir"),
5342 X(
"div"),
X(
"dl"),
X(
"dt"),
Xend };
5343 static const TAG f6[] = {
X(
"fieldset"),
X(
"figcaption"),
X(
"figure"),
X(
"footer"),
5344 X(
"form"),
X(
"frame"),
X(
"frameset"),
Xend };
5345 static const TAG h6[] = {
X(
"h1"),
X(
"head"),
X(
"header"),
X(
"hr"),
X(
"html"),
Xend };
5346 static const TAG i6[] = {
X(
"iframe"),
Xend };
5347 static const TAG l6[] = {
X(
"legend"),
X(
"li"),
X(
"link"),
Xend };
5348 static const TAG m6[] = {
X(
"main"),
X(
"menu"),
X(
"menuitem"),
Xend };
5349 static const TAG n6[] = {
X(
"nav"),
X(
"noframes"),
Xend };
5350 static const TAG o6[] = {
X(
"ol"),
X(
"optgroup"),
X(
"option"),
Xend };
5351 static const TAG p6[] = {
X(
"p"),
X(
"param"),
Xend };
5352 static const TAG s6[] = {
X(
"section"),
X(
"source"),
X(
"summary"),
Xend };
5353 static const TAG t6[] = {
X(
"table"),
X(
"tbody"),
X(
"td"),
X(
"tfoot"),
X(
"th"),
5354 X(
"thead"),
X(
"title"),
X(
"tr"),
X(
"track"),
Xend };
5355 static const TAG u6[] = {
X(
"ul"),
Xend };
5356 static const TAG xx[] = {
Xend };
5359 static const TAG* map6[26] = {
5360 a6, b6, c6, d6, xx, f6, xx, h6, i6, xx, xx, l6, m6,
5361 n6, o6, p6, xx, xx,
s6,
t6, u6, xx, xx, xx, xx, xx
5375 if(off + 3 < ctx->
size &&
CH(off) ==
_T(
'!') &&
CH(off+1) ==
_T(
'-') &&
CH(off+2) ==
_T(
'-'))
5379 if(off < ctx->
size &&
CH(off) ==
_T(
'?'))
5383 if(off < ctx->
size &&
CH(off) ==
_T(
'!')) {
5389 if(off + 8 < ctx->
size) {
5390 if(md_ascii_eq(
STR(off),
_T(
"![CDATA["), 8))
5400 if(
CH(off) ==
_T(
'/'))
5403 slot = (
ISUPPER(off) ?
CH(off) -
'A' :
CH(off) -
'a');
5406 for(
i = 0; tags[
i].name !=
NULL;
i++) {
5408 if(md_ascii_case_eq(
STR(off), tags[
i].
name, tags[
i].
len)) {
5409 OFF tmp = off + tags[
i].len;
5410 if(tmp >= ctx->
size)
5414 if(tmp+1 < ctx->
size &&
CH(tmp) ==
_T(
'/') &&
CH(tmp+1) ==
_T(
'>'))
5423 if(off + 1 < ctx->
size) {
5426 if(md_is_html_tag(ctx,
NULL, 0, beg, ctx->
size, &
end)) {
5444 for(
i = beg;
i + what_len < ctx->
size;
i++) {
5447 if(memcmp(
STR(
i), what, what_len *
sizeof(
CHAR)) == 0) {
5448 *p_end =
i + what_len;
5463 md_is_html_block_end_condition(
MD_CTX* ctx,
OFF beg,
OFF* p_end)
5471 if(
CH(off) ==
_T(
'<')) {
5472 if(md_ascii_case_eq(
STR(off),
_T(
"</script>"), 9)) {
5477 if(md_ascii_case_eq(
STR(off),
_T(
"</style>"), 8)) {
5482 if(md_ascii_case_eq(
STR(off),
_T(
"</pre>"), 6)) {
5495 return (md_line_contains(ctx, beg,
_T(
"-->"), 3, p_end) ? 2 :
FALSE);
5498 return (md_line_contains(ctx, beg,
_T(
"?>"), 2, p_end) ? 3 :
FALSE);
5501 return (md_line_contains(ctx, beg,
_T(
">"), 1, p_end) ? 4 :
FALSE);
5504 return (md_line_contains(ctx, beg,
_T(
"]]>"), 3, p_end) ? 5 :
FALSE);
5522 if(container->
ch ==
_T(
'>'))
5525 if(container->
ch != pivot->
ch)
5543 if(new_containers ==
NULL) {
5544 MD_LOG(
"realloc() failed.");
5556 md_enter_child_containers(
MD_CTX* ctx,
int n_children)
5561 for(
i = ctx->
n_containers - n_children; i < ctx->n_containers;
i++) {
5563 int is_ordered_list =
FALSE;
5568 is_ordered_list =
TRUE;
5576 md_end_current_block(ctx);
5579 MD_CHECK(md_push_container_bytes(ctx,
5584 (
c->is_task ?
CH(
c->task_mark_off) : 0),
5603 md_leave_child_containers(
MD_CTX* ctx,
int n_keep)
5609 int is_ordered_list =
FALSE;
5614 is_ordered_list =
TRUE;
5621 c->task_mark_off, (
c->is_task ?
CH(
c->task_mark_off) : 0),
5623 MD_CHECK(md_push_container_bytes(ctx,
5655 if(
CH(off) ==
_T(
'>')) {
5657 p_container->
ch =
_T(
'>');
5668 p_container->
ch =
CH(off);
5679 if(max_end > ctx->
size)
5680 max_end = ctx->
size;
5681 p_container->
start = 0;
5682 while(off < max_end &&
ISDIGIT(off)) {
5683 p_container->
start = p_container->
start * 10 +
CH(off) -
_T(
'0');
5687 (
CH(off) ==
_T(
'.') ||
CH(off) ==
_T(
')')) &&
5690 p_container->
ch =
CH(off);
5703 md_line_indentation(
MD_CTX* ctx,
unsigned total_indent,
OFF beg,
OFF* p_end)
5706 unsigned indent = total_indent;
5709 if(
CH(off) ==
_T(
'\t'))
5710 indent = (indent + 4) & ~3;
5717 return indent - total_indent;
5728 unsigned total_indent = 0;
5738 line->indent = md_line_indentation(ctx, total_indent, off, &off);
5739 total_indent +=
line->indent;
5744 while(n_parents < ctx->n_containers) {
5748 off < ctx->
size &&
CH(off) ==
_T(
'>'))
5753 line->indent = md_line_indentation(ctx, total_indent, off, &off);
5754 total_indent +=
line->indent;
5757 if(
line->indent > 0)
5762 }
else if(
c->ch !=
_T(
'>') &&
line->indent >=
c->contents_indent) {
5764 line->indent -=
c->contents_indent;
5775 if(n_brothers + n_children == 0) {
5776 while(n_parents < ctx->n_containers && ctx->
containers[n_parents].
ch !=
_T(
'>'))
5789 if(md_is_closing_code_fence(ctx,
CH(pivot_line->
beg), off, &off)) {
5810 if(n_parents < ctx->n_containers) {
5815 int html_block_type;
5817 html_block_type = md_is_html_block_end_condition(ctx, off, &off);
5818 if(html_block_type > 0) {
5825 if(html_block_type == 6 || html_block_type == 7) {
5850 n_brothers + n_children == 0 &&
5865 if(n_parents > 0 && ctx->
containers[n_parents-1].
ch !=
_T(
'>') &&
5884 if(n_parents > 0 && ctx->
containers[n_parents-1].
ch !=
_T(
'>') &&
5905 if(md_is_setext_underline(ctx, off, &off, &
level)) {
5914 && off < ctx->
size && off >= hr_killer
5917 if(md_is_hr_line(ctx, off, &off, &hr_killer)) {
5925 if(n_parents < ctx->n_containers && n_brothers + n_children == 0) {
5928 if(md_is_container_mark(ctx,
line->indent, off, &tmp, &container) &&
5929 md_is_container_compatible(&ctx->
containers[n_parents], &container))
5931 pivot_line = &md_dummy_blank_line;
5936 line->indent = md_line_indentation(ctx, total_indent, off, &off);
5937 total_indent +=
line->indent;
5973 md_is_container_mark(ctx,
line->indent, off, &off, &container))
5985 line->indent = md_line_indentation(ctx, total_indent, off, &off);
5986 total_indent +=
line->indent;
6002 if(n_brothers + n_children == 0)
6003 pivot_line = &md_dummy_blank_line;
6006 MD_CHECK(md_leave_child_containers(ctx, n_parents + n_brothers));
6009 MD_CHECK(md_push_container(ctx, &container));
6022 off < ctx->
size &&
CH(off) ==
_T(
'#'))
6026 if(md_is_atxheader_line(ctx, off, &
line->beg, &off, &
level)) {
6035 if(md_is_opening_code_fence(ctx, off, &off)) {
6043 if(off < ctx->
size &&
CH(off) ==
_T(
'<')
6054 if(md_is_html_block_end_condition(ctx, off, &off) == ctx->
html_block_type) {
6072 md_is_table_underline(ctx, off, &off, &col_count))
6093 while(tmp < ctx->
size && tmp < off + 3 &&
ISBLANK(tmp))
6095 if(tmp + 2 < ctx->
size &&
CH(tmp) ==
_T(
'[') &&
6117 #if defined __linux__ && !defined MD4C_USE_UTF16
6122 off += (
OFF) strcspn(
STR(off),
"\r\n");
6126 if(
CH(off) ==
_T(
'\0'))
6148 while(tmp >
line->beg &&
CH(tmp-1) ==
_T(
' '))
6150 while(tmp >
line->beg &&
CH(tmp-1) ==
_T(
'#'))
6163 if(off < ctx->
size &&
CH(off) ==
_T(
'\r'))
6165 if(off < ctx->
size &&
CH(off) ==
_T(
'\n'))
6171 if(prev_line_has_list_loosening_effect &&
line->type !=
MD_LINE_BLANK && n_parents + n_brothers > 0) {
6173 if(
c->ch !=
_T(
'>')) {
6180 if(n_children == 0 && n_parents + n_brothers < ctx->n_containers)
6181 MD_CHECK(md_leave_child_containers(ctx, n_parents + n_brothers));
6184 if(n_brothers > 0) {
6199 MD_CHECK(md_enter_child_containers(ctx, n_children));
6213 MD_CHECK(md_end_current_block(ctx));
6214 *p_pivot_line = &md_dummy_blank_line;
6220 MD_CHECK(md_end_current_block(ctx));
6225 MD_CHECK(md_end_current_block(ctx));
6226 *p_pivot_line = &md_dummy_blank_line;
6237 MD_CHECK(md_end_current_block(ctx));
6239 *p_pivot_line = &md_dummy_blank_line;
6244 *p_pivot_line =
line;
6255 MD_ASSERT(pivot_line != &md_dummy_blank_line);
6263 MD_CHECK(md_end_current_block(ctx));
6268 *p_pivot_line =
line;
6279 md_process_doc(
MD_CTX *ctx)
6289 while(off < ctx->
size) {
6290 if(
line == pivot_line)
6291 line = (
line == &line_buf[0] ? &line_buf[1] : &line_buf[0]);
6293 MD_CHECK(md_analyze_line(ctx, off, &off, pivot_line,
line));
6297 md_end_current_block(ctx);
6299 MD_CHECK(md_build_ref_def_hashtable(ctx));
6302 MD_CHECK(md_leave_child_containers(ctx, 0));
6303 MD_CHECK(md_process_all_blocks(ctx));
6313 sprintf(
buffer,
"Alloced %u bytes for block buffer.",
6317 sprintf(
buffer,
"Alloced %u bytes for containers buffer.",
6321 sprintf(
buffer,
"Alloced %u bytes for marks buffer.",
6325 sprintf(
buffer,
"Alloced %u bytes for aux. buffer.",
6346 if(
parser->abi_version != 0) {
6348 parser->debug_log(
"Unsupported abi_version.", userdata);
6353 memset(&ctx, 0,
sizeof(
MD_CTX));
6359 md_build_mark_char_map(&ctx);
6371 ret = md_process_doc(&ctx);
6374 md_free_ref_defs(&ctx);
6375 md_free_ref_def_hashtable(&ctx);
small capitals from c petite p scientific i
[1]
QHash< int, QWidget * > hash
[35multi]
QMap< QString, QString > map
[6]
backing_store_ptr info
[4]
#define MD_MARK_VALIDPERMISSIVEAUTOLINK
#define MD_TEMP_BUFFER(sz)
#define R(cp_min, cp_max)
#define MD_MARK_EMPH_MOD3_MASK
#define ISANYOF3(off, ch1, ch2, ch3)
#define MD_MARK_EMPH_MOD3_1
#define MD_TEXT(type, str, size)
#define MD_ROLLBACK_CROSSING
#define ASTERISK_OPENERS_intraword_mod3_2
#define MD_BLOCK_LOOSE_LIST
#define IS_MARK_CHAR(off)
#define ISANYOF2(off, ch1, ch2)
#define MD_LEAVE_BLOCK(type, arg)
enum MD_LINETYPE_tag MD_LINETYPE
#define MD_MARK_POTENTIAL_CLOSER
#define MD_MARK_EMPH_MOD3_0
#define MD_BLOCK_CONTAINER
#define MD_LEAVE_SPAN(type, arg)
#define ISANYOF_(ch, palette)
struct MD_LINE_tag MD_LINE
struct MD_VERBATIMLINE_tag MD_VERBATIMLINE
#define CODESPAN_MARK_MAXLEN
#define MD_BUILD_ATTR_NO_ESCAPES
#define MD_BLOCK_CONTAINER_CLOSER
#define MD_MARK_EMPH_MOD3_2
#define TABLECELLBOUNDARIES
#define ASTERISK_OPENERS_extraword_mod3_0
int md_parse(const MD_CHAR *text, MD_SIZE size, const MD_PARSER *parser, void *userdata)
#define PUSH_MARK(ch_, beg_, end_, flags_)
#define IS_UTF8_LEAD3(byte)
#define ISUNICODEPUNCT(off)
#define MD_TEXT_INSECURE(type, str, size)
#define IS_UTF8_LEAD1(byte)
#define ISWHITESPACE_(ch)
#define ISUNICODEPUNCTBEFORE(off)
#define ISWHITESPACE(off)
#define ISUNICODEWHITESPACEBEFORE(off)
#define ASTERISK_OPENERS_intraword_mod3_0
#define OPENERS_CHAIN_FIRST
#define OPENERS_CHAIN_LAST
#define ISANYOF3_(ch, ch1, ch2, ch3)
#define ISANYOF2_(ch, ch1, ch2)
#define ISANYOF(off, palette)
#define IS_UTF8_TAIL(byte)
#define MD_ENTER_SPAN(type, arg)
#define MD_MARK_POTENTIAL_OPENER
#define MD_ENTER_BLOCK(type, arg)
#define ISUNICODEWHITESPACE_(codepoint)
#define IS_UTF8_LEAD2(byte)
#define MD_MARK_EMPH_INTRAWORD
#define MD_BLOCK_CONTAINER_OPENER
#define ASTERISK_OPENERS_extraword_mod3_2
#define ASTERISK_OPENERS_extraword_mod3_1
#define ASTERISK_OPENERS_intraword_mod3_1
#define MD_BLOCK_SETEXT_HEADER
@ MD_LINE_SETEXTUNDERLINE
#define ISUNICODEWHITESPACE(off)
#define IS_UTF8_LEAD4(byte)
#define UNDERSCORE_OPENERS
struct MD_BLOCK_tag MD_BLOCK
#define MD_FLAG_TASKLISTS
#define MD_FLAG_NOHTMLBLOCKS
#define MD_FLAG_NOINDENTEDCODEBLOCKS
#define MD_FLAG_PERMISSIVEURLAUTOLINKS
#define MD_FLAG_PERMISSIVEWWWAUTOLINKS
#define MD_FLAG_UNDERLINE
#define MD_FLAG_PERMISSIVEEMAILAUTOLINKS
@ MD_SPAN_LATEXMATH_DISPLAY
#define MD_FLAG_PERMISSIVEATXHEADERS
#define MD_FLAG_WIKILINKS
#define MD_FLAG_PERMISSIVEAUTOLINKS
#define MD_FLAG_NOHTMLSPANS
#define MD_FLAG_COLLAPSEWHITESPACE
#define MD_FLAG_LATEXMATHSPANS
#define MD_FLAG_STRIKETHROUGH
void *PRIV() memmove(void *d, const void *s, size_t n)
QT_BEGIN_NAMESPACE bool done
GLboolean GLboolean GLboolean b
GLenum GLuint GLint level
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s1
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t1
[4]
GLuint GLsizei const GLchar * label
[43]
GLenum GLuint GLenum GLsizei const GLchar * buf
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLenum GLsizei void * table
file open(QIODevice::ReadOnly)
QTextStream out(stdout)
[7]
QHttpRequestHeader header("GET", QUrl::toPercentEncoding("/index.html"))
[1]
MD_TEXTTYPE * substr_types
MD_TEXTTYPE trivial_types[1]
int last_list_item_starts_with_two_blank_lines
MD_MARKCHAIN mark_chains[13]
MD_CONTAINER * containers
int n_table_cell_boundaries
OFF html_proc_instr_horizon
unsigned code_indent_offset
int last_line_has_list_loosening_effect
int doc_ends_with_newline
int ref_def_hashtable_size
void ** ref_def_hashtable
int(* text)(MD_TEXTTYPE, const MD_CHAR *, MD_SIZE, void *)
unsigned char title_needs_free
unsigned char label_needs_free
QThreadStorage< int * > dummy[8]
void build(const QString &name)
XmlOutput::xml_output attr(const QString &name, const QString &value)