1 #ifndef CMARK_GFM_EXTENSION_API_H 2 #define CMARK_GFM_EXTENSION_API_H 3 4 #ifdef __cplusplus 5 extern "C" { 6 #endif 7 8 #include "cmark-gfm.h" 9 10 struct cmark_renderer; 11 struct cmark_html_renderer; 12 struct cmark_chunk; 13 14 /** 15 * ## Extension Support 16 * 17 * While the "core" of libcmark is strictly compliant with the 18 * specification, an API is provided for extension writers to 19 * hook into the parsing process. 20 * 21 * It should be noted that the cmark_node API already offers 22 * room for customization, with methods offered to traverse and 23 * modify the AST, and even define custom blocks. 24 * When the desired customization is achievable in an error-proof 25 * way using that API, it should be the preferred method. 26 * 27 * The following API requires a more in-depth understanding 28 * of libcmark's parsing strategy, which is exposed 29 * [here](http://spec.commonmark.org/0.24/#appendix-a-parsing-strategy). 30 * 31 * It should be used when "a posteriori" modification of the AST 32 * proves to be too difficult / impossible to implement correctly. 33 * 34 * It can also serve as an intermediary step before extending 35 * the specification, as an extension implemented using this API 36 * will be trivially integrated in the core if it proves to be 37 * desirable. 38 */ 39 40 typedef struct cmark_plugin cmark_plugin; 41 42 /** A syntax extension that can be attached to a cmark_parser 43 * with cmark_parser_attach_syntax_extension(). 44 * 45 * Extension writers should assign functions matching 46 * the signature of the following 'virtual methods' to 47 * implement new functionality. 48 * 49 * Their calling order and expected behaviour match the procedure outlined 50 * at <http://spec.commonmark.org/0.24/#phase-1-block-structure>: 51 * 52 * During step 1, cmark will call the function provided through 53 * 'cmark_syntax_extension_set_match_block_func' when it 54 * iterates over an open block created by this extension, 55 * to determine whether it could contain the new line. 56 * If no function was provided, cmark will close the block. 57 * 58 * During step 2, if and only if the new line doesn't match any 59 * of the standard syntax rules, cmark will call the function 60 * provided through 'cmark_syntax_extension_set_open_block_func' 61 * to let the extension determine whether that new line matches 62 * one of its syntax rules. 63 * It is the responsibility of the parser to create and add the 64 * new block with cmark_parser_make_block and cmark_parser_add_child. 65 * If no function was provided is NULL, the extension will have 66 * no effect at all on the final block structure of the AST. 67 * 68 * #### Inline parsing phase hooks 69 * 70 * For each character provided by the extension through 71 * 'cmark_syntax_extension_set_special_inline_chars', 72 * the function provided by the extension through 73 * 'cmark_syntax_extension_set_match_inline_func' 74 * will get called, it is the responsibility of the extension 75 * to scan the characters located at the current inline parsing offset 76 * with the cmark_inline_parser API. 77 * 78 * Depending on the type of the extension, it can either: 79 * 80 * * Scan forward, determine that the syntax matches and return 81 * a newly-created inline node with the appropriate type. 82 * This is the technique that would be used if inline code 83 * (with backticks) was implemented as an extension. 84 * * Scan only the character(s) that its syntax rules require 85 * for opening and closing nodes, push a delimiter on the 86 * delimiter stack, and return a simple text node with its 87 * contents set to the character(s) consumed. 88 * This is the technique that would be used if emphasis 89 * inlines were implemented as an extension. 90 * 91 * When an extension has pushed delimiters on the stack, 92 * the function provided through 93 * 'cmark_syntax_extension_set_inline_from_delim_func' 94 * will get called in a latter phase, 95 * when the inline parser has matched opener and closer delimiters 96 * created by the extension together. 97 * 98 * It is then the responsibility of the extension to modify 99 * and populate the opener inline text node, and to remove 100 * the necessary delimiters from the delimiter stack. 101 * 102 * Finally, the extension should return NULL if its scan didn't 103 * match its syntax rules. 104 * 105 * The extension can store whatever private data it might need 106 * with 'cmark_syntax_extension_set_private', 107 * and optionally define a free function for this data. 108 */ 109 typedef struct subject cmark_inline_parser; 110 111 /** Exposed raw for now */ 112 113 typedef struct delimiter { 114 struct delimiter *previous; 115 struct delimiter *next; 116 cmark_node *inl_text; 117 bufsize_t length; 118 unsigned char delim_char; 119 int can_open; 120 int can_close; 121 } delimiter; 122 123 /** 124 * ### Plugin API. 125 * 126 * Extensions should be distributed as dynamic libraries, 127 * with a single exported function named after the distributed 128 * filename. 129 * 130 * When discovering extensions (see cmark_init), cmark will 131 * try to load a symbol named "init_{{filename}}" in all the 132 * dynamic libraries it encounters. 133 * 134 * For example, given a dynamic library named myextension.so 135 * (or myextension.dll), cmark will try to load the symbol 136 * named "init_myextension". This means that the filename 137 * must lend itself to forming a valid C identifier, with 138 * the notable exception of dashes, which will be translated 139 * to underscores, which means cmark will look for a function 140 * named "init_my_extension" if it encounters a dynamic library 141 * named "my-extension.so". 142 * 143 * See the 'cmark_plugin_init_func' typedef for the exact prototype 144 * this function should follow. 145 * 146 * For now the extensibility of cmark is not complete, as 147 * it only offers API to hook into the block parsing phase 148 * (<http://spec.commonmark.org/0.24/#phase-1-block-structure>). 149 * 150 * See 'cmark_plugin_register_syntax_extension' for more information. 151 */ 152 153 /** The prototype plugins' init function should follow. 154 */ 155 typedef int (*cmark_plugin_init_func)(cmark_plugin *plugin); 156 157 /** Register a syntax 'extension' with the 'plugin', it will be made 158 * available as an extension and, if attached to a cmark_parser 159 * with 'cmark_parser_attach_syntax_extension', it will contribute 160 * to the block parsing process. 161 * 162 * See the documentation for 'cmark_syntax_extension' for information 163 * on how to implement one. 164 * 165 * This function will typically be called from the init function 166 * of external modules. 167 * 168 * This takes ownership of 'extension', one should not call 169 * 'cmark_syntax_extension_free' on a registered extension. 170 */ 171 CMARK_GFM_EXPORT 172 int cmark_plugin_register_syntax_extension(cmark_plugin *plugin, 173 cmark_syntax_extension *extension); 174 175 /** This will search for the syntax extension named 'name' among the 176 * registered syntax extensions. 177 * 178 * It can then be attached to a cmark_parser 179 * with the cmark_parser_attach_syntax_extension method. 180 */ 181 CMARK_GFM_EXPORT 182 cmark_syntax_extension *cmark_find_syntax_extension(const char *name); 183 184 /** Should create and add a new open block to 'parent_container' if 185 * 'input' matches a syntax rule for that block type. It is allowed 186 * to modify the type of 'parent_container'. 187 * 188 * Should return the newly created block if there is one, or 189 * 'parent_container' if its type was modified, or NULL. 190 */ 191 typedef cmark_node * (*cmark_open_block_func) (cmark_syntax_extension *extension, 192 int indented, 193 cmark_parser *parser, 194 cmark_node *parent_container, 195 unsigned char *input, 196 int len); 197 198 typedef cmark_node *(*cmark_match_inline_func)(cmark_syntax_extension *extension, 199 cmark_parser *parser, 200 cmark_node *parent, 201 unsigned char character, 202 cmark_inline_parser *inline_parser); 203 204 typedef delimiter *(*cmark_inline_from_delim_func)(cmark_syntax_extension *extension, 205 cmark_parser *parser, 206 cmark_inline_parser *inline_parser, 207 delimiter *opener, 208 delimiter *closer); 209 210 /** Should return 'true' if 'input' can be contained in 'container', 211 * 'false' otherwise. 212 */ 213 typedef int (*cmark_match_block_func) (cmark_syntax_extension *extension, 214 cmark_parser *parser, 215 unsigned char *input, 216 int len, 217 cmark_node *container); 218 219 typedef const char *(*cmark_get_type_string_func) (cmark_syntax_extension *extension, 220 cmark_node *node); 221 222 typedef int (*cmark_can_contain_func) (cmark_syntax_extension *extension, 223 cmark_node *node, 224 cmark_node_type child); 225 226 typedef int (*cmark_contains_inlines_func) (cmark_syntax_extension *extension, 227 cmark_node *node); 228 229 typedef void (*cmark_common_render_func) (cmark_syntax_extension *extension, 230 struct cmark_renderer *renderer, 231 cmark_node *node, 232 cmark_event_type ev_type, 233 int options); 234 235 typedef int (*cmark_commonmark_escape_func) (cmark_syntax_extension *extension, 236 cmark_node *node, 237 int c); 238 239 typedef const char* (*cmark_xml_attr_func) (cmark_syntax_extension *extension, 240 cmark_node *node); 241 242 typedef void (*cmark_html_render_func) (cmark_syntax_extension *extension, 243 struct cmark_html_renderer *renderer, 244 cmark_node *node, 245 cmark_event_type ev_type, 246 int options); 247 248 typedef int (*cmark_html_filter_func) (cmark_syntax_extension *extension, 249 const unsigned char *tag, 250 size_t tag_len); 251 252 typedef cmark_node *(*cmark_postprocess_func) (cmark_syntax_extension *extension, 253 cmark_parser *parser, 254 cmark_node *root); 255 256 typedef int (*cmark_ispunct_func) (char c); 257 258 typedef void (*cmark_opaque_alloc_func) (cmark_syntax_extension *extension, 259 cmark_mem *mem, 260 cmark_node *node); 261 262 typedef void (*cmark_opaque_free_func) (cmark_syntax_extension *extension, 263 cmark_mem *mem, 264 cmark_node *node); 265 266 /** Free a cmark_syntax_extension. 267 */ 268 CMARK_GFM_EXPORT 269 void cmark_syntax_extension_free (cmark_mem *mem, cmark_syntax_extension *extension); 270 271 /** Return a newly-constructed cmark_syntax_extension, named 'name'. 272 */ 273 CMARK_GFM_EXPORT 274 cmark_syntax_extension *cmark_syntax_extension_new (const char *name); 275 276 CMARK_GFM_EXPORT 277 cmark_node_type cmark_syntax_extension_add_node(int is_inline); 278 279 CMARK_GFM_EXPORT 280 void cmark_syntax_extension_set_emphasis(cmark_syntax_extension *extension, int emphasis); 281 282 /** See the documentation for 'cmark_syntax_extension' 283 */ 284 CMARK_GFM_EXPORT 285 void cmark_syntax_extension_set_open_block_func(cmark_syntax_extension *extension, 286 cmark_open_block_func func); 287 288 /** See the documentation for 'cmark_syntax_extension' 289 */ 290 CMARK_GFM_EXPORT 291 void cmark_syntax_extension_set_match_block_func(cmark_syntax_extension *extension, 292 cmark_match_block_func func); 293 294 /** See the documentation for 'cmark_syntax_extension' 295 */ 296 CMARK_GFM_EXPORT 297 void cmark_syntax_extension_set_match_inline_func(cmark_syntax_extension *extension, 298 cmark_match_inline_func func); 299 300 /** See the documentation for 'cmark_syntax_extension' 301 */ 302 CMARK_GFM_EXPORT 303 void cmark_syntax_extension_set_inline_from_delim_func(cmark_syntax_extension *extension, 304 cmark_inline_from_delim_func func); 305 306 /** See the documentation for 'cmark_syntax_extension' 307 */ 308 CMARK_GFM_EXPORT 309 void cmark_syntax_extension_set_special_inline_chars(cmark_syntax_extension *extension, 310 cmark_llist *special_chars); 311 312 /** See the documentation for 'cmark_syntax_extension' 313 */ 314 CMARK_GFM_EXPORT 315 void cmark_syntax_extension_set_get_type_string_func(cmark_syntax_extension *extension, 316 cmark_get_type_string_func func); 317 318 /** See the documentation for 'cmark_syntax_extension' 319 */ 320 CMARK_GFM_EXPORT 321 void cmark_syntax_extension_set_can_contain_func(cmark_syntax_extension *extension, 322 cmark_can_contain_func func); 323 324 /** See the documentation for 'cmark_syntax_extension' 325 */ 326 CMARK_GFM_EXPORT 327 void cmark_syntax_extension_set_contains_inlines_func(cmark_syntax_extension *extension, 328 cmark_contains_inlines_func func); 329 330 /** See the documentation for 'cmark_syntax_extension' 331 */ 332 CMARK_GFM_EXPORT 333 void cmark_syntax_extension_set_commonmark_render_func(cmark_syntax_extension *extension, 334 cmark_common_render_func func); 335 336 /** See the documentation for 'cmark_syntax_extension' 337 */ 338 CMARK_GFM_EXPORT 339 void cmark_syntax_extension_set_plaintext_render_func(cmark_syntax_extension *extension, 340 cmark_common_render_func func); 341 342 /** See the documentation for 'cmark_syntax_extension' 343 */ 344 CMARK_GFM_EXPORT 345 void cmark_syntax_extension_set_latex_render_func(cmark_syntax_extension *extension, 346 cmark_common_render_func func); 347 348 /** See the documentation for 'cmark_syntax_extension' 349 */ 350 CMARK_GFM_EXPORT 351 void cmark_syntax_extension_set_xml_attr_func(cmark_syntax_extension *extension, 352 cmark_xml_attr_func func); 353 354 /** See the documentation for 'cmark_syntax_extension' 355 */ 356 CMARK_GFM_EXPORT 357 void cmark_syntax_extension_set_man_render_func(cmark_syntax_extension *extension, 358 cmark_common_render_func func); 359 360 /** See the documentation for 'cmark_syntax_extension' 361 */ 362 CMARK_GFM_EXPORT 363 void cmark_syntax_extension_set_html_render_func(cmark_syntax_extension *extension, 364 cmark_html_render_func func); 365 366 /** See the documentation for 'cmark_syntax_extension' 367 */ 368 CMARK_GFM_EXPORT 369 void cmark_syntax_extension_set_html_filter_func(cmark_syntax_extension *extension, 370 cmark_html_filter_func func); 371 372 /** See the documentation for 'cmark_syntax_extension' 373 */ 374 CMARK_GFM_EXPORT 375 void cmark_syntax_extension_set_commonmark_escape_func(cmark_syntax_extension *extension, 376 cmark_commonmark_escape_func func); 377 378 /** See the documentation for 'cmark_syntax_extension' 379 */ 380 CMARK_GFM_EXPORT 381 void cmark_syntax_extension_set_private(cmark_syntax_extension *extension, 382 void *priv, 383 cmark_free_func free_func); 384 385 /** See the documentation for 'cmark_syntax_extension' 386 */ 387 CMARK_GFM_EXPORT 388 void *cmark_syntax_extension_get_private(cmark_syntax_extension *extension); 389 390 /** See the documentation for 'cmark_syntax_extension' 391 */ 392 CMARK_GFM_EXPORT 393 void cmark_syntax_extension_set_postprocess_func(cmark_syntax_extension *extension, 394 cmark_postprocess_func func); 395 396 /** See the documentation for 'cmark_syntax_extension' 397 */ 398 CMARK_GFM_EXPORT 399 void cmark_syntax_extension_set_opaque_alloc_func(cmark_syntax_extension *extension, 400 cmark_opaque_alloc_func func); 401 402 /** See the documentation for 'cmark_syntax_extension' 403 */ 404 CMARK_GFM_EXPORT 405 void cmark_syntax_extension_set_opaque_free_func(cmark_syntax_extension *extension, 406 cmark_opaque_free_func func); 407 408 /** See the documentation for 'cmark_syntax_extension' 409 */ 410 CMARK_GFM_EXPORT 411 void cmark_parser_set_backslash_ispunct_func(cmark_parser *parser, 412 cmark_ispunct_func func); 413 414 /** Return the index of the line currently being parsed, starting with 1. 415 */ 416 CMARK_GFM_EXPORT 417 int cmark_parser_get_line_number(cmark_parser *parser); 418 419 /** Return the offset in bytes in the line being processed. 420 * 421 * Example: 422 * 423 * ### foo 424 * 425 * Here, offset will first be 0, then 5 (the index of the 'f' character). 426 */ 427 CMARK_GFM_EXPORT 428 int cmark_parser_get_offset(cmark_parser *parser); 429 430 /** 431 * Return the offset in 'columns' in the line being processed. 432 * 433 * This value may differ from the value returned by 434 * cmark_parser_get_offset() in that it accounts for tabs, 435 * and as such should not be used as an index in the current line's 436 * buffer. 437 * 438 * Example: 439 * 440 * cmark_parser_advance_offset() can be called to advance the 441 * offset by a number of columns, instead of a number of bytes. 442 * 443 * In that case, if offset falls "in the middle" of a tab 444 * character, 'column' and offset will differ. 445 * 446 * ``` 447 * foo \t bar 448 * ^ ^^ 449 * offset (0) 20 450 * ``` 451 * 452 * If cmark_parser_advance_offset is called here with 'columns' 453 * set to 'true' and 'offset' set to 22, cmark_parser_get_offset() 454 * will return 20, whereas cmark_parser_get_column() will return 455 * 22. 456 * 457 * Additionally, as tabs expand to the next multiple of 4 column, 458 * cmark_parser_has_partially_consumed_tab() will now return 459 * 'true'. 460 */ 461 CMARK_GFM_EXPORT 462 int cmark_parser_get_column(cmark_parser *parser); 463 464 /** Return the absolute index in bytes of the first nonspace 465 * character coming after the offset as returned by 466 * cmark_parser_get_offset() in the line currently being processed. 467 * 468 * Example: 469 * 470 * ``` 471 * foo bar baz \n 472 * ^ ^ ^ 473 * 0 offset (16) first_nonspace (28) 474 * ``` 475 */ 476 CMARK_GFM_EXPORT 477 int cmark_parser_get_first_nonspace(cmark_parser *parser); 478 479 /** Return the absolute index of the first nonspace column coming after 'offset' 480 * in the line currently being processed, counting tabs as multiple 481 * columns as appropriate. 482 * 483 * See the documentation for cmark_parser_get_first_nonspace() and 484 * cmark_parser_get_column() for more information. 485 */ 486 CMARK_GFM_EXPORT 487 int cmark_parser_get_first_nonspace_column(cmark_parser *parser); 488 489 /** Return the difference between the values returned by 490 * cmark_parser_get_first_nonspace_column() and 491 * cmark_parser_get_column(). 492 * 493 * This is not a byte offset, as it can count one tab as multiple 494 * characters. 495 */ 496 CMARK_GFM_EXPORT 497 int cmark_parser_get_indent(cmark_parser *parser); 498 499 /** Return 'true' if the line currently being processed has been entirely 500 * consumed, 'false' otherwise. 501 * 502 * Example: 503 * 504 * ``` 505 * foo bar baz \n 506 * ^ 507 * offset 508 * ``` 509 * 510 * This function will return 'false' here. 511 * 512 * ``` 513 * foo bar baz \n 514 * ^ 515 * offset 516 * ``` 517 * This function will still return 'false'. 518 * 519 * ``` 520 * foo bar baz \n 521 * ^ 522 * offset 523 * ``` 524 * 525 * At this point, this function will now return 'true'. 526 */ 527 CMARK_GFM_EXPORT 528 int cmark_parser_is_blank(cmark_parser *parser); 529 530 /** Return 'true' if the value returned by cmark_parser_get_offset() 531 * is 'inside' an expanded tab. 532 * 533 * See the documentation for cmark_parser_get_column() for more 534 * information. 535 */ 536 CMARK_GFM_EXPORT 537 int cmark_parser_has_partially_consumed_tab(cmark_parser *parser); 538 539 /** Return the length in bytes of the previously processed line, excluding potential 540 * newline (\n) and carriage return (\r) trailing characters. 541 */ 542 CMARK_GFM_EXPORT 543 int cmark_parser_get_last_line_length(cmark_parser *parser); 544 545 /** Add a child to 'parent' during the parsing process. 546 * 547 * If 'parent' isn't the kind of node that can accept this child, 548 * this function will back up till it hits a node that can, closing 549 * blocks as appropriate. 550 */ 551 CMARK_GFM_EXPORT 552 cmark_node*cmark_parser_add_child(cmark_parser *parser, 553 cmark_node *parent, 554 cmark_node_type block_type, 555 int start_column); 556 557 /** Advance the 'offset' of the parser in the current line. 558 * 559 * See the documentation of cmark_parser_get_offset() and 560 * cmark_parser_get_column() for more information. 561 */ 562 CMARK_GFM_EXPORT 563 void cmark_parser_advance_offset(cmark_parser *parser, 564 const char *input, 565 int count, 566 int columns); 567 568 569 CMARK_GFM_EXPORT 570 void cmark_parser_feed_reentrant(cmark_parser *parser, const char *buffer, size_t len); 571 572 /** Attach the syntax 'extension' to the 'parser', to provide extra syntax 573 * rules. 574 * See the documentation for cmark_syntax_extension for more information. 575 * 576 * Returns 'true' if the 'extension' was successfully attached, 577 * 'false' otherwise. 578 */ 579 CMARK_GFM_EXPORT 580 int cmark_parser_attach_syntax_extension(cmark_parser *parser, cmark_syntax_extension *extension); 581 582 /** Change the type of 'node'. 583 * 584 * Return 0 if the type could be changed, 1 otherwise. 585 */ 586 CMARK_GFM_EXPORT int cmark_node_set_type(cmark_node *node, cmark_node_type type); 587 588 /** Return the string content for all types of 'node'. 589 * The pointer stays valid as long as 'node' isn't freed. 590 */ 591 CMARK_GFM_EXPORT const char *cmark_node_get_string_content(cmark_node *node); 592 593 /** Set the string 'content' for all types of 'node'. 594 * Copies 'content'. 595 */ 596 CMARK_GFM_EXPORT int cmark_node_set_string_content(cmark_node *node, const char *content); 597 598 /** Get the syntax extension responsible for the creation of 'node'. 599 * Return NULL if 'node' was created because it matched standard syntax rules. 600 */ 601 CMARK_GFM_EXPORT cmark_syntax_extension *cmark_node_get_syntax_extension(cmark_node *node); 602 603 /** Set the syntax extension responsible for creating 'node'. 604 */ 605 CMARK_GFM_EXPORT int cmark_node_set_syntax_extension(cmark_node *node, 606 cmark_syntax_extension *extension); 607 608 /** 609 * ## Inline syntax extension helpers 610 * 611 * The inline parsing process is described in detail at 612 * <http://spec.commonmark.org/0.24/#phase-2-inline-structure> 613 */ 614 615 /** Should return 'true' if the predicate matches 'c', 'false' otherwise 616 */ 617 typedef int (*cmark_inline_predicate)(int c); 618 619 /** Advance the current inline parsing offset */ 620 CMARK_GFM_EXPORT 621 void cmark_inline_parser_advance_offset(cmark_inline_parser *parser); 622 623 /** Get the current inline parsing offset */ 624 CMARK_GFM_EXPORT 625 int cmark_inline_parser_get_offset(cmark_inline_parser *parser); 626 627 /** Set the offset in bytes in the chunk being processed by the given inline parser. 628 */ 629 CMARK_GFM_EXPORT 630 void cmark_inline_parser_set_offset(cmark_inline_parser *parser, int offset); 631 632 /** Gets the cmark_chunk being operated on by the given inline parser. 633 * Use cmark_inline_parser_get_offset to get our current position in the chunk. 634 */ 635 CMARK_GFM_EXPORT 636 struct cmark_chunk *cmark_inline_parser_get_chunk(cmark_inline_parser *parser); 637 638 /** Returns 1 if the inline parser is currently in a bracket; pass 1 for 'image' 639 * if you want to know about an image-type bracket, 0 for link-type. */ 640 CMARK_GFM_EXPORT 641 int cmark_inline_parser_in_bracket(cmark_inline_parser *parser, int image); 642 643 /** Remove the last n characters from the last child of the given node. 644 * This only works where all n characters are in the single last child, and the last 645 * child is CMARK_NODE_TEXT. 646 */ 647 CMARK_GFM_EXPORT 648 void cmark_node_unput(cmark_node *node, int n); 649 650 651 /** Get the character located at the current inline parsing offset 652 */ 653 CMARK_GFM_EXPORT 654 unsigned char cmark_inline_parser_peek_char(cmark_inline_parser *parser); 655 656 /** Get the character located 'pos' bytes in the current line. 657 */ 658 CMARK_GFM_EXPORT 659 unsigned char cmark_inline_parser_peek_at(cmark_inline_parser *parser, int pos); 660 661 /** Whether the inline parser has reached the end of the current line 662 */ 663 CMARK_GFM_EXPORT 664 int cmark_inline_parser_is_eof(cmark_inline_parser *parser); 665 666 /** Get the characters located after the current inline parsing offset 667 * while 'pred' matches. Free after usage. 668 */ 669 CMARK_GFM_EXPORT 670 char *cmark_inline_parser_take_while(cmark_inline_parser *parser, cmark_inline_predicate pred); 671 672 /** Push a delimiter on the delimiter stack. 673 * See <<http://spec.commonmark.org/0.24/#phase-2-inline-structure> for 674 * more information on the parameters 675 */ 676 CMARK_GFM_EXPORT 677 void cmark_inline_parser_push_delimiter(cmark_inline_parser *parser, 678 unsigned char c, 679 int can_open, 680 int can_close, 681 cmark_node *inl_text); 682 683 /** Remove 'delim' from the delimiter stack 684 */ 685 CMARK_GFM_EXPORT 686 void cmark_inline_parser_remove_delimiter(cmark_inline_parser *parser, delimiter *delim); 687 688 CMARK_GFM_EXPORT 689 delimiter *cmark_inline_parser_get_last_delimiter(cmark_inline_parser *parser); 690 691 CMARK_GFM_EXPORT 692 int cmark_inline_parser_get_line(cmark_inline_parser *parser); 693 694 CMARK_GFM_EXPORT 695 int cmark_inline_parser_get_column(cmark_inline_parser *parser); 696 697 /** Convenience function to scan a given delimiter. 698 * 699 * 'left_flanking' and 'right_flanking' will be set to true if they 700 * respectively precede and follow a non-space, non-punctuation 701 * character. 702 * 703 * Additionally, 'punct_before' and 'punct_after' will respectively be set 704 * if the preceding or following character is a punctuation character. 705 * 706 * Note that 'left_flanking' and 'right_flanking' can both be 'true'. 707 * 708 * Returns the number of delimiters encountered, in the limit 709 * of 'max_delims', and advances the inline parsing offset. 710 */ 711 CMARK_GFM_EXPORT 712 int cmark_inline_parser_scan_delimiters(cmark_inline_parser *parser, 713 int max_delims, 714 unsigned char c, 715 int *left_flanking, 716 int *right_flanking, 717 int *punct_before, 718 int *punct_after); 719 720 CMARK_GFM_EXPORT 721 void cmark_manage_extensions_special_characters(cmark_parser *parser, int add); 722 723 CMARK_GFM_EXPORT 724 cmark_llist *cmark_parser_get_syntax_extensions(cmark_parser *parser); 725 726 CMARK_GFM_EXPORT 727 void cmark_arena_push(void); 728 729 CMARK_GFM_EXPORT 730 int cmark_arena_pop(void); 731 732 #ifdef __cplusplus 733 } 734 #endif 735 736 #endif 737