@@ -48,6 +48,8 @@ int look_back_nonspace(mddi_context_t *ctx);
4848int inline_equation_pre(mddi_context_t *ctx);
4949int inline_equation_post(mddi_context_t *ctx);
5050
51+ int look_back_one_char(mddi_context_t *ctx, char *excludes, size_t len, int positive);
52+
5153}
5254
5355######
@@ -84,11 +86,36 @@ block <-
8486 {
8587 $$ = mdd_node_create_0(MDD_NODE_TYPE_BLANK_LINE, $0s, $0e);
8688 }
87- / (e:block_quote / e:verbatim / e:note / e:reference / e:plain)
89+ / (e:block_quote / e:verbatim / e:fenced_code_block / e:note / e:reference / e:plain)
90+ {
91+ $$ = e;
92+ }
93+
94+ fenced_code_block <- (e:fenced_code_block_tick / e:fenced_code_block_tidle)
8895 {
8996 $$ = e;
9097 }
9198
99+ fenced_code_block_tick_close <- '```' space (new_line / end_of_file)
100+
101+ fenced_code_block_tick <- '```' space <(!new_line !'`' .)*> new_line
102+ (!fenced_code_block_tick_close (!new_line .)* new_line)*
103+ fenced_code_block_tick_close
104+ {
105+ $$ = mdd_node_create_0(MDD_NODE_TYPE_FENCED_CODE_BLOCK, $0s, $0e);
106+ mdd_node_type_code_block_data_new(&$$->custom, $1);
107+ }
108+
109+ fenced_code_block_tidle_close <- '~~~' space (new_line / end_of_file)
110+
111+ fenced_code_block_tidle <- '~~~' space <(!new_line !'~' .)*> new_line
112+ (!fenced_code_block_tidle_close (!new_line .)* new_line)*
113+ fenced_code_block_tidle_close
114+ {
115+ $$ = mdd_node_create_0(MDD_NODE_TYPE_FENCED_CODE_BLOCK, $0s, $0e);
116+ mdd_node_type_code_block_data_new(&$$->custom, $1);
117+ }
118+
92119# TODO: for block quote, we need to re-parse it separately after the main parse.
93120# For now, we will only parse the inline elements within it.
94121block_quote <-
@@ -235,12 +262,15 @@ inline_equation_single <- '$' &{ @@ = inline_equation_pre(pcc_ctx); } !'$' !'\\'
235262
236263inline_equation_multiple <- '$' &{ @@ = inline_equation_pre(pcc_ctx); } !'$' nonspace_char (!'$' !new_line .)+ '$' &{ @@ = inline_equation_post(pcc_ctx); } ![0-9]
237264
265+ # Define all ticks rules together
238266ticks1 <- '`' !'`'
239267ticks2 <- '``' !'`'
240268ticks3 <- '```' !'`'
241269ticks4 <- '````' !'`'
242270ticks5 <- '`````' !'`'
243271
272+ fenced_code_block_start_tick_line <- '```' (!new_line !'`' .)* new_line
273+
244274code <- (ticks1 space ((!'`' nonspace_char)+ / !ticks1 '`'+ / !(space ticks1) (space_char / new_line !blank_line))+ space ticks1
245275 / ticks2 space ((!'`' nonspace_char)+ / !ticks2 '`'+ / !(space ticks2) (space_char / new_line !blank_line))+ space ticks2
246276 / !fenced_code_block_start_tick_line ticks3 space ((!'`' nonspace_char)+ / !ticks3 '`'+ / !(space ticks3) (space_char / new_line !blank_line))+ space ticks3
@@ -250,10 +280,6 @@ code <- (ticks1 space ((!'`' nonspace_char)+ / !ticks1 '`'+ / !(space ticks1) (s
250280 $$ = mdd_node_create_0(MDD_NODE_TYPE_CODE, $0s, $0e);
251281 }
252282
253- fenced_code_block_start_tick <- '```' (!new_line !'`' .)*
254-
255- fenced_code_block_start_tick_line <- fenced_code_block_start_tick new_line
256-
257283inline_note <- '^['
258284 {
259285 // Need to fix the range at the end.
@@ -698,15 +724,22 @@ void mddi_ast_node_custom_data__finalize(mddi_ast_node_custom_data_t *obj) {
698724}
699725
700726int look_back_nonspace(mddi_context_t *ctx) {
727+ char data[] = {' ', '\t', '\n', '\r'};
728+ return look_back_one_char(ctx, data, sizeof(data), 0);
729+ }
730+
731+ int look_back_one_char(mddi_context_t *ctx, char *chars, size_t len, int positive) {
701732 const char *buf = ctx->buffer.p + ctx->cur;
702733 if (ctx->cur == 0) {
703734 return 1;
704735 }
705736 const unsigned char ch = *(buf - 1);
706- if (ch != ' ' && ch != '\t' && ch != '\n' && ch != '\r') {
707- return 1;
737+ for (size_t i = 0; i < len; ++i) {
738+ if (ch == chars[i]) {
739+ return positive;
740+ }
708741 }
709- return 0 ;
742+ return !positive ;
710743}
711744
712745int inline_equation_pre(mddi_context_t *ctx) {
0 commit comments