@@ -171,7 +171,8 @@ static inline bool can_contain(cmark_node_type parent_type,
171171static inline bool accepts_lines (cmark_node_type block_type ) {
172172 return (block_type == CMARK_NODE_PARAGRAPH ||
173173 block_type == CMARK_NODE_HEADING ||
174- block_type == CMARK_NODE_CODE_BLOCK );
174+ block_type == CMARK_NODE_CODE_BLOCK ||
175+ block_type == CMARK_NODE_FORMULA_BLOCK );
175176}
176177
177178static inline bool contains_inlines (cmark_node_type block_type ) {
@@ -270,6 +271,7 @@ static cmark_node *finalize(cmark_parser *parser, cmark_node *b) {
270271 b -> end_column = parser -> last_line_length ;
271272 } else if (S_type (b ) == CMARK_NODE_DOCUMENT ||
272273 (S_type (b ) == CMARK_NODE_CODE_BLOCK && b -> as .code .fenced ) ||
274+ S_type (b ) == CMARK_NODE_FORMULA_BLOCK ||
273275 (S_type (b ) == CMARK_NODE_HEADING && b -> as .heading .setext )) {
274276 b -> end_line = parser -> line_number ;
275277 b -> end_column = parser -> curline .size ;
@@ -330,6 +332,11 @@ static cmark_node *finalize(cmark_parser *parser, cmark_node *b) {
330332 b -> data = cmark_strbuf_detach (node_content );
331333 break ;
332334
335+ case CMARK_NODE_FORMULA_BLOCK :
336+ b -> len = node_content -> size ;
337+ b -> data = cmark_strbuf_detach (node_content );
338+ break ;
339+
333340 case CMARK_NODE_HEADING :
334341 case CMARK_NODE_HTML_BLOCK :
335342 b -> len = node_content -> size ;
@@ -859,6 +866,37 @@ static bool parse_code_block_prefix(cmark_parser *parser, cmark_chunk *input,
859866 return res ;
860867}
861868
869+ static bool parse_formula_block_prefix (cmark_parser * parser , cmark_chunk * input ,
870+ cmark_node * container , bool * should_continue ) {
871+ bool res = false;
872+ bufsize_t matched = 0 ;
873+
874+ if (parser -> indent <= 3 ) {
875+ matched = scan_formula_block_end (input , parser -> first_nonspace );
876+ }
877+
878+ if (matched &&
879+ (matched == container -> as .formula .fence_length ||
880+ matched == container -> as .formula .fence_length - 2 )) {
881+ // closing fence - and since we're at
882+ // the end of a line, we can stop processing it:
883+ * should_continue = false;
884+ S_advance_offset (parser , input , matched , false);
885+ parser -> current = finalize (parser , container );
886+ } else {
887+ // skip opt. spaces of fence parser->offset
888+ int i = container -> as .formula .fence_offset ;
889+
890+ while (i > 0 && S_is_space_or_tab (peek_at (input , parser -> offset ))) {
891+ S_advance_offset (parser , input , 1 , true);
892+ i -- ;
893+ }
894+ res = true;
895+ }
896+
897+ return res ;
898+ }
899+
862900static bool parse_html_block_prefix (cmark_parser * parser ,
863901 cmark_node * container ) {
864902 bool res = false;
@@ -924,6 +962,7 @@ static cmark_node *check_open_blocks(cmark_parser *parser, cmark_chunk *input,
924962 // first blank line was processed. Certain block types accept
925963 // empty lines as content, so add them here.
926964 if (parser -> current -> type == CMARK_NODE_CODE_BLOCK ||
965+ parser -> current -> type == CMARK_NODE_FORMULA_BLOCK ||
927966 parser -> current -> type == CMARK_NODE_HTML_BLOCK ) {
928967 add_line (input , parser );
929968 }
@@ -942,6 +981,10 @@ static cmark_node *check_open_blocks(cmark_parser *parser, cmark_chunk *input,
942981 if (!parse_code_block_prefix (parser , input , container , & should_continue ))
943982 goto done ;
944983 break ;
984+ case CMARK_NODE_FORMULA_BLOCK :
985+ if (!parse_formula_block_prefix (parser , input , container , & should_continue ))
986+ goto done ;
987+ break ;
945988 case CMARK_NODE_HEADING :
946989 // a heading can never contain more than one line
947990 goto done ;
@@ -986,6 +1029,7 @@ static void open_new_blocks(cmark_parser *parser, cmark_node **container,
9861029 int save_column ;
9871030
9881031 while (cont_type != CMARK_NODE_CODE_BLOCK &&
1032+ cont_type != CMARK_NODE_FORMULA_BLOCK &&
9891033 cont_type != CMARK_NODE_HTML_BLOCK ) {
9901034
9911035 S_find_first_nonspace (parser , input );
@@ -1041,6 +1085,17 @@ static void open_new_blocks(cmark_parser *parser, cmark_node **container,
10411085 parser -> first_nonspace + matched - parser -> offset ,
10421086 false);
10431087
1088+ } else if (!indented && (matched = scan_formula_block_start (
1089+ input , parser -> first_nonspace ))) {
1090+ * container = add_child (parser , * container , CMARK_NODE_FORMULA_BLOCK ,
1091+ parser -> first_nonspace + 1 );
1092+ (* container )-> as .formula .fence_length = matched ;
1093+ (* container )-> as .formula .fence_offset =
1094+ (int8_t )(parser -> first_nonspace - parser -> offset );
1095+ S_advance_offset (parser , input ,
1096+ parser -> first_nonspace + matched - parser -> offset ,
1097+ false);
1098+
10441099 } else if (!indented && ((matched = scan_html_block_start (
10451100 input , parser -> first_nonspace )) ||
10461101 (cont_type != CMARK_NODE_PARAGRAPH &&
@@ -1175,6 +1230,7 @@ static void add_text_to_container(cmark_parser *parser, cmark_node *container,
11751230 const bool last_line_blank =
11761231 (parser -> blank && ctype != CMARK_NODE_BLOCK_QUOTE &&
11771232 ctype != CMARK_NODE_HEADING && ctype != CMARK_NODE_THEMATIC_BREAK &&
1233+ ctype != CMARK_NODE_FORMULA_BLOCK &&
11781234 !(ctype == CMARK_NODE_CODE_BLOCK && container -> as .code .fenced ) &&
11791235 !(ctype == CMARK_NODE_ITEM && container -> first_child == NULL &&
11801236 container -> start_line == parser -> line_number ));
@@ -1204,7 +1260,8 @@ static void add_text_to_container(cmark_parser *parser, cmark_node *container,
12041260 assert (parser -> current != NULL );
12051261 }
12061262
1207- if (S_type (container ) == CMARK_NODE_CODE_BLOCK ) {
1263+ if (S_type (container ) == CMARK_NODE_CODE_BLOCK ||
1264+ S_type (container ) == CMARK_NODE_FORMULA_BLOCK ) {
12081265 add_line (input , parser );
12091266 } else if (S_type (container ) == CMARK_NODE_HTML_BLOCK ) {
12101267 add_line (input , parser );
0 commit comments