markly 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - checksums.yaml.gz.sig +0 -0
 - data/conduct.md +133 -0
 - data/ext/markly/arena.c +9 -8
 - data/ext/markly/autolink.c +217 -134
 - data/ext/markly/blocks.c +27 -2
 - data/ext/markly/cmark-gfm-core-extensions.h +11 -11
 - data/ext/markly/cmark-gfm-extension_api.h +1 -0
 - data/ext/markly/cmark-gfm.h +18 -2
 - data/ext/markly/cmark.c +3 -3
 - data/ext/markly/commonmark.c +19 -34
 - data/ext/markly/extconf.rb +8 -1
 - data/ext/markly/html.c +22 -6
 - data/ext/markly/inlines.c +148 -51
 - data/ext/markly/latex.c +6 -4
 - data/ext/markly/man.c +7 -11
 - data/ext/markly/map.c +11 -4
 - data/ext/markly/map.h +5 -2
 - data/ext/markly/markly.c +582 -586
 - data/ext/markly/markly.h +1 -1
 - data/ext/markly/node.c +76 -10
 - data/ext/markly/node.h +42 -1
 - data/ext/markly/parser.h +1 -0
 - data/ext/markly/plaintext.c +12 -29
 - data/ext/markly/references.c +1 -0
 - data/ext/markly/render.c +15 -7
 - data/ext/markly/scanners.c +13916 -10380
 - data/ext/markly/scanners.h +8 -0
 - data/ext/markly/scanners.re +47 -8
 - data/ext/markly/strikethrough.c +1 -1
 - data/ext/markly/table.c +81 -31
 - data/ext/markly/xml.c +2 -1
 - data/lib/markly/flags.rb +16 -0
 - data/lib/markly/node/inspect.rb +59 -53
 - data/lib/markly/node.rb +125 -58
 - data/lib/markly/renderer/generic.rb +129 -124
 - data/lib/markly/renderer/html.rb +294 -275
 - data/lib/markly/version.rb +7 -1
 - data/lib/markly.rb +36 -30
 - data/license.md +39 -0
 - data/readme.md +36 -0
 - data.tar.gz.sig +0 -0
 - metadata +61 -29
 - metadata.gz.sig +0 -0
 - data/bin/markly +0 -94
 - data/lib/markly/markly.bundle +0 -0
 
    
        data/ext/markly/scanners.h
    CHANGED
    
    | 
         @@ -15,6 +15,10 @@ bufsize_t _scan_autolink_uri(const unsigned char *p); 
     | 
|
| 
       15 
15 
     | 
    
         
             
            bufsize_t _scan_autolink_email(const unsigned char *p);
         
     | 
| 
       16 
16 
     | 
    
         
             
            bufsize_t _scan_html_tag(const unsigned char *p);
         
     | 
| 
       17 
17 
     | 
    
         
             
            bufsize_t _scan_liberal_html_tag(const unsigned char *p);
         
     | 
| 
      
 18 
     | 
    
         
            +
            bufsize_t _scan_html_comment(const unsigned char *p);
         
     | 
| 
      
 19 
     | 
    
         
            +
            bufsize_t _scan_html_pi(const unsigned char *p);
         
     | 
| 
      
 20 
     | 
    
         
            +
            bufsize_t _scan_html_declaration(const unsigned char *p);
         
     | 
| 
      
 21 
     | 
    
         
            +
            bufsize_t _scan_html_cdata(const unsigned char *p);
         
     | 
| 
       18 
22 
     | 
    
         
             
            bufsize_t _scan_html_block_start(const unsigned char *p);
         
     | 
| 
       19 
23 
     | 
    
         
             
            bufsize_t _scan_html_block_start_7(const unsigned char *p);
         
     | 
| 
       20 
24 
     | 
    
         
             
            bufsize_t _scan_html_block_end_1(const unsigned char *p);
         
     | 
| 
         @@ -37,6 +41,10 @@ bufsize_t _scan_footnote_definition(const unsigned char *p); 
     | 
|
| 
       37 
41 
     | 
    
         
             
            #define scan_autolink_email(c, n) _scan_at(&_scan_autolink_email, c, n)
         
     | 
| 
       38 
42 
     | 
    
         
             
            #define scan_html_tag(c, n) _scan_at(&_scan_html_tag, c, n)
         
     | 
| 
       39 
43 
     | 
    
         
             
            #define scan_liberal_html_tag(c, n) _scan_at(&_scan_liberal_html_tag, c, n)
         
     | 
| 
      
 44 
     | 
    
         
            +
            #define scan_html_comment(c, n) _scan_at(&_scan_html_comment, c, n)
         
     | 
| 
      
 45 
     | 
    
         
            +
            #define scan_html_pi(c, n) _scan_at(&_scan_html_pi, c, n)
         
     | 
| 
      
 46 
     | 
    
         
            +
            #define scan_html_declaration(c, n) _scan_at(&_scan_html_declaration, c, n)
         
     | 
| 
      
 47 
     | 
    
         
            +
            #define scan_html_cdata(c, n) _scan_at(&_scan_html_cdata, c, n)
         
     | 
| 
       40 
48 
     | 
    
         
             
            #define scan_html_block_start(c, n) _scan_at(&_scan_html_block_start, c, n)
         
     | 
| 
       41 
49 
     | 
    
         
             
            #define scan_html_block_start_7(c, n) _scan_at(&_scan_html_block_start_7, c, n)
         
     | 
| 
       42 
50 
     | 
    
         
             
            #define scan_html_block_end_1(c, n) _scan_at(&_scan_html_block_end_1, c, n)
         
     | 
    
        data/ext/markly/scanners.re
    CHANGED
    
    | 
         @@ -54,16 +54,15 @@ bufsize_t _scan_at(bufsize_t (*scanner)(const unsigned char *), cmark_chunk *c, 
     | 
|
| 
       54 
54 
     | 
    
         
             
              opentag = tagname attribute* spacechar* [/]? [>];
         
     | 
| 
       55 
55 
     | 
    
         
             
              closetag = [/] tagname spacechar* [>];
         
     | 
| 
       56 
56 
     | 
    
         | 
| 
       57 
     | 
    
         
            -
              htmlcomment = " 
     | 
| 
      
 57 
     | 
    
         
            +
              htmlcomment = "--" ([^\x00-]+ | "-" [^\x00-] | "--" [^\x00>])* "-->";
         
     | 
| 
       58 
58 
     | 
    
         | 
| 
       59 
     | 
    
         
            -
              processinginstruction =  
     | 
| 
      
 59 
     | 
    
         
            +
              processinginstruction = ([^?>\x00]+ | [?][^>\x00] | [>])+;
         
     | 
| 
       60 
60 
     | 
    
         | 
| 
       61 
     | 
    
         
            -
              declaration =  
     | 
| 
      
 61 
     | 
    
         
            +
              declaration = [A-Z]+ spacechar+ [^>\x00]*;
         
     | 
| 
       62 
62 
     | 
    
         | 
| 
       63 
     | 
    
         
            -
              cdata = " 
     | 
| 
      
 63 
     | 
    
         
            +
              cdata = "CDATA[" ([^\]\x00]+ | "]" [^\]\x00] | "]]" [^>\x00])*;
         
     | 
| 
       64 
64 
     | 
    
         | 
| 
       65 
     | 
    
         
            -
              htmltag = opentag | closetag 
     | 
| 
       66 
     | 
    
         
            -
                        declaration | cdata;
         
     | 
| 
      
 65 
     | 
    
         
            +
              htmltag = opentag | closetag;
         
     | 
| 
       67 
66 
     | 
    
         | 
| 
       68 
67 
     | 
    
         
             
              in_parens_nosp   = [(] (reg_char|escaped_char|[\\])* [)];
         
     | 
| 
       69 
68 
     | 
    
         | 
| 
         @@ -133,6 +132,46 @@ bufsize_t _scan_liberal_html_tag(const unsigned char *p) 
     | 
|
| 
       133 
132 
     | 
    
         
             
            */
         
     | 
| 
       134 
133 
     | 
    
         
             
            }
         
     | 
| 
       135 
134 
     | 
    
         | 
| 
      
 135 
     | 
    
         
            +
            bufsize_t _scan_html_comment(const unsigned char *p)
         
     | 
| 
      
 136 
     | 
    
         
            +
            {
         
     | 
| 
      
 137 
     | 
    
         
            +
              const unsigned char *marker = NULL;
         
     | 
| 
      
 138 
     | 
    
         
            +
              const unsigned char *start = p;
         
     | 
| 
      
 139 
     | 
    
         
            +
            /*!re2c
         
     | 
| 
      
 140 
     | 
    
         
            +
              htmlcomment { return (bufsize_t)(p - start); }
         
     | 
| 
      
 141 
     | 
    
         
            +
              * { return 0; }
         
     | 
| 
      
 142 
     | 
    
         
            +
            */
         
     | 
| 
      
 143 
     | 
    
         
            +
            }
         
     | 
| 
      
 144 
     | 
    
         
            +
             
     | 
| 
      
 145 
     | 
    
         
            +
            bufsize_t _scan_html_pi(const unsigned char *p)
         
     | 
| 
      
 146 
     | 
    
         
            +
            {
         
     | 
| 
      
 147 
     | 
    
         
            +
              const unsigned char *marker = NULL;
         
     | 
| 
      
 148 
     | 
    
         
            +
              const unsigned char *start = p;
         
     | 
| 
      
 149 
     | 
    
         
            +
            /*!re2c
         
     | 
| 
      
 150 
     | 
    
         
            +
              processinginstruction { return (bufsize_t)(p - start); }
         
     | 
| 
      
 151 
     | 
    
         
            +
              * { return 0; }
         
     | 
| 
      
 152 
     | 
    
         
            +
            */
         
     | 
| 
      
 153 
     | 
    
         
            +
            }
         
     | 
| 
      
 154 
     | 
    
         
            +
             
     | 
| 
      
 155 
     | 
    
         
            +
            bufsize_t _scan_html_declaration(const unsigned char *p)
         
     | 
| 
      
 156 
     | 
    
         
            +
            {
         
     | 
| 
      
 157 
     | 
    
         
            +
              const unsigned char *marker = NULL;
         
     | 
| 
      
 158 
     | 
    
         
            +
              const unsigned char *start = p;
         
     | 
| 
      
 159 
     | 
    
         
            +
            /*!re2c
         
     | 
| 
      
 160 
     | 
    
         
            +
              declaration { return (bufsize_t)(p - start); }
         
     | 
| 
      
 161 
     | 
    
         
            +
              * { return 0; }
         
     | 
| 
      
 162 
     | 
    
         
            +
            */
         
     | 
| 
      
 163 
     | 
    
         
            +
            }
         
     | 
| 
      
 164 
     | 
    
         
            +
             
     | 
| 
      
 165 
     | 
    
         
            +
            bufsize_t _scan_html_cdata(const unsigned char *p)
         
     | 
| 
      
 166 
     | 
    
         
            +
            {
         
     | 
| 
      
 167 
     | 
    
         
            +
              const unsigned char *marker = NULL;
         
     | 
| 
      
 168 
     | 
    
         
            +
              const unsigned char *start = p;
         
     | 
| 
      
 169 
     | 
    
         
            +
            /*!re2c
         
     | 
| 
      
 170 
     | 
    
         
            +
              cdata { return (bufsize_t)(p - start); }
         
     | 
| 
      
 171 
     | 
    
         
            +
              * { return 0; }
         
     | 
| 
      
 172 
     | 
    
         
            +
            */
         
     | 
| 
      
 173 
     | 
    
         
            +
            }
         
     | 
| 
      
 174 
     | 
    
         
            +
             
     | 
| 
       136 
175 
     | 
    
         
             
            // Try to match an HTML block tag start line, returning
         
     | 
| 
       137 
176 
     | 
    
         
             
            // an integer code for the type of block (1-6, matching the spec).
         
     | 
| 
       138 
177 
     | 
    
         
             
            // #7 is handled by a separate function, below.
         
     | 
| 
         @@ -140,7 +179,7 @@ bufsize_t _scan_html_block_start(const unsigned char *p) 
     | 
|
| 
       140 
179 
     | 
    
         
             
            {
         
     | 
| 
       141 
180 
     | 
    
         
             
              const unsigned char *marker = NULL;
         
     | 
| 
       142 
181 
     | 
    
         
             
            /*!re2c
         
     | 
| 
       143 
     | 
    
         
            -
              [<] ('script'|'pre'|'style') (spacechar | [>]) { return 1; }
         
     | 
| 
      
 182 
     | 
    
         
            +
              [<] ('script'|'pre'|'textarea'|'style') (spacechar | [>]) { return 1; }
         
     | 
| 
       144 
183 
     | 
    
         
             
              '<!--' { return 2; }
         
     | 
| 
       145 
184 
     | 
    
         
             
              '<?' { return 3; }
         
     | 
| 
       146 
185 
     | 
    
         
             
              '<!' [A-Z] { return 4; }
         
     | 
| 
         @@ -167,7 +206,7 @@ bufsize_t _scan_html_block_end_1(const unsigned char *p) 
     | 
|
| 
       167 
206 
     | 
    
         
             
              const unsigned char *marker = NULL;
         
     | 
| 
       168 
207 
     | 
    
         
             
              const unsigned char *start = p;
         
     | 
| 
       169 
208 
     | 
    
         
             
            /*!re2c
         
     | 
| 
       170 
     | 
    
         
            -
              [^\n\x00]* [<] [/] ('script'|'pre'|'style') [>] { return (bufsize_t)(p - start); }
         
     | 
| 
      
 209 
     | 
    
         
            +
              [^\n\x00]* [<] [/] ('script'|'pre'|'textarea'|'style') [>] { return (bufsize_t)(p - start); }
         
     | 
| 
       171 
210 
     | 
    
         
             
              * { return 0; }
         
     | 
| 
       172 
211 
     | 
    
         
             
            */
         
     | 
| 
       173 
212 
     | 
    
         
             
            }
         
     | 
    
        data/ext/markly/strikethrough.c
    CHANGED
    
    | 
         @@ -67,6 +67,7 @@ static delimiter *insert(cmark_syntax_extension *self, cmark_parser *parser, 
     | 
|
| 
       67 
67 
     | 
    
         
             
              strikethrough->end_column = closer->inl_text->start_column + closer->inl_text->as.literal.len - 1;
         
     | 
| 
       68 
68 
     | 
    
         
             
              cmark_node_free(closer->inl_text);
         
     | 
| 
       69 
69 
     | 
    
         | 
| 
      
 70 
     | 
    
         
            +
            done:
         
     | 
| 
       70 
71 
     | 
    
         
             
              delim = closer;
         
     | 
| 
       71 
72 
     | 
    
         
             
              while (delim != NULL && delim != opener) {
         
     | 
| 
       72 
73 
     | 
    
         
             
                tmp_delim = delim->previous;
         
     | 
| 
         @@ -76,7 +77,6 @@ static delimiter *insert(cmark_syntax_extension *self, cmark_parser *parser, 
     | 
|
| 
       76 
77 
     | 
    
         | 
| 
       77 
78 
     | 
    
         
             
              cmark_inline_parser_remove_delimiter(inline_parser, opener);
         
     | 
| 
       78 
79 
     | 
    
         | 
| 
       79 
     | 
    
         
            -
            done:
         
     | 
| 
       80 
80 
     | 
    
         
             
              return res;
         
     | 
| 
       81 
81 
     | 
    
         
             
            }
         
     | 
| 
       82 
82 
     | 
    
         | 
    
        data/ext/markly/table.c
    CHANGED
    
    | 
         @@ -11,13 +11,21 @@ 
     | 
|
| 
       11 
11 
     | 
    
         
             
            #include "table.h"
         
     | 
| 
       12 
12 
     | 
    
         
             
            #include "cmark-gfm-core-extensions.h"
         
     | 
| 
       13 
13 
     | 
    
         | 
| 
      
 14 
     | 
    
         
            +
            // Custom node flag, initialized in `create_table_extension`.
         
     | 
| 
      
 15 
     | 
    
         
            +
            static cmark_node_internal_flags CMARK_NODE__TABLE_VISITED;
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
       14 
17 
     | 
    
         
             
            cmark_node_type CMARK_NODE_TABLE, CMARK_NODE_TABLE_ROW,
         
     | 
| 
       15 
18 
     | 
    
         
             
                CMARK_NODE_TABLE_CELL;
         
     | 
| 
       16 
19 
     | 
    
         | 
| 
      
 20 
     | 
    
         
            +
            typedef struct {
         
     | 
| 
      
 21 
     | 
    
         
            +
              cmark_strbuf *buf;
         
     | 
| 
      
 22 
     | 
    
         
            +
              int start_offset, end_offset, internal_offset;
         
     | 
| 
      
 23 
     | 
    
         
            +
            } node_cell;
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
       17 
25 
     | 
    
         
             
            typedef struct {
         
     | 
| 
       18 
26 
     | 
    
         
             
              uint16_t n_columns;
         
     | 
| 
       19 
27 
     | 
    
         
             
              int paragraph_offset;
         
     | 
| 
       20 
     | 
    
         
            -
               
     | 
| 
      
 28 
     | 
    
         
            +
              node_cell *cells;
         
     | 
| 
       21 
29 
     | 
    
         
             
            } table_row;
         
     | 
| 
       22 
30 
     | 
    
         | 
| 
       23 
31 
     | 
    
         
             
            typedef struct {
         
     | 
| 
         @@ -29,24 +37,24 @@ typedef struct { 
     | 
|
| 
       29 
37 
     | 
    
         
             
              bool is_header;
         
     | 
| 
       30 
38 
     | 
    
         
             
            } node_table_row;
         
     | 
| 
       31 
39 
     | 
    
         | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
              cmark_strbuf *buf;
         
     | 
| 
       34 
     | 
    
         
            -
              int start_offset, end_offset, internal_offset;
         
     | 
| 
       35 
     | 
    
         
            -
            } node_cell;
         
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
            static void free_table_cell(cmark_mem *mem, void *data) {
         
     | 
| 
       38 
     | 
    
         
            -
              node_cell *cell = (node_cell *)data;
         
     | 
| 
      
 40 
     | 
    
         
            +
            static void free_table_cell(cmark_mem *mem, node_cell *cell) {
         
     | 
| 
       39 
41 
     | 
    
         
             
              cmark_strbuf_free((cmark_strbuf *)cell->buf);
         
     | 
| 
       40 
42 
     | 
    
         
             
              mem->free(cell->buf);
         
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
      
 43 
     | 
    
         
            +
            }
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
            static void free_row_cells(cmark_mem *mem, table_row *row) {
         
     | 
| 
      
 46 
     | 
    
         
            +
              while (row->n_columns > 0) {
         
     | 
| 
      
 47 
     | 
    
         
            +
                free_table_cell(mem, &row->cells[--row->n_columns]);
         
     | 
| 
      
 48 
     | 
    
         
            +
              }
         
     | 
| 
      
 49 
     | 
    
         
            +
              mem->free(row->cells);
         
     | 
| 
      
 50 
     | 
    
         
            +
              row->cells = NULL;
         
     | 
| 
       42 
51 
     | 
    
         
             
            }
         
     | 
| 
       43 
52 
     | 
    
         | 
| 
       44 
53 
     | 
    
         
             
            static void free_table_row(cmark_mem *mem, table_row *row) {
         
     | 
| 
       45 
54 
     | 
    
         
             
              if (!row)
         
     | 
| 
       46 
55 
     | 
    
         
             
                return;
         
     | 
| 
       47 
56 
     | 
    
         | 
| 
       48 
     | 
    
         
            -
               
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
      
 57 
     | 
    
         
            +
              free_row_cells(mem, row);
         
     | 
| 
       50 
58 
     | 
    
         
             
              mem->free(row);
         
     | 
| 
       51 
59 
     | 
    
         
             
            }
         
     | 
| 
       52 
60 
     | 
    
         | 
| 
         @@ -111,6 +119,24 @@ static cmark_strbuf *unescape_pipes(cmark_mem *mem, unsigned char *string, bufsi 
     | 
|
| 
       111 
119 
     | 
    
         
             
              return res;
         
     | 
| 
       112 
120 
     | 
    
         
             
            }
         
     | 
| 
       113 
121 
     | 
    
         | 
| 
      
 122 
     | 
    
         
            +
            // Adds a new cell to the end of the row. A pointer to the new cell is returned
         
     | 
| 
      
 123 
     | 
    
         
            +
            // for the caller to initialize.
         
     | 
| 
      
 124 
     | 
    
         
            +
            static node_cell* append_row_cell(cmark_mem *mem, table_row *row) {
         
     | 
| 
      
 125 
     | 
    
         
            +
              const uint32_t n_columns = row->n_columns + 1;
         
     | 
| 
      
 126 
     | 
    
         
            +
              // realloc when n_columns is a power of 2
         
     | 
| 
      
 127 
     | 
    
         
            +
              if ((n_columns & (n_columns-1)) == 0) {
         
     | 
| 
      
 128 
     | 
    
         
            +
                // make sure we never wrap row->n_columns
         
     | 
| 
      
 129 
     | 
    
         
            +
                // offset will != len and our exit will clean up as intended
         
     | 
| 
      
 130 
     | 
    
         
            +
                if (n_columns > UINT16_MAX) {
         
     | 
| 
      
 131 
     | 
    
         
            +
                  return NULL;
         
     | 
| 
      
 132 
     | 
    
         
            +
                }
         
     | 
| 
      
 133 
     | 
    
         
            +
                // Use realloc to double the size of the buffer.
         
     | 
| 
      
 134 
     | 
    
         
            +
                row->cells = (node_cell *)mem->realloc(row->cells, (2 * n_columns - 1) * sizeof(node_cell));
         
     | 
| 
      
 135 
     | 
    
         
            +
              }
         
     | 
| 
      
 136 
     | 
    
         
            +
              row->n_columns = (uint16_t)n_columns;
         
     | 
| 
      
 137 
     | 
    
         
            +
              return &row->cells[n_columns-1];
         
     | 
| 
      
 138 
     | 
    
         
            +
            }
         
     | 
| 
      
 139 
     | 
    
         
            +
             
     | 
| 
       114 
140 
     | 
    
         
             
            static table_row *row_from_string(cmark_syntax_extension *self,
         
     | 
| 
       115 
141 
     | 
    
         
             
                                              cmark_parser *parser, unsigned char *string,
         
     | 
| 
       116 
142 
     | 
    
         
             
                                              int len) {
         
     | 
| 
         @@ -129,6 +155,7 @@ static table_row *row_from_string(cmark_syntax_extension *self, 
     | 
|
| 
       129 
155 
     | 
    
         
             
              bufsize_t cell_matched = 1, pipe_matched = 1, offset;
         
     | 
| 
       130 
156 
     | 
    
         
             
              int expect_more_cells = 1;
         
     | 
| 
       131 
157 
     | 
    
         
             
              int row_end_offset = 0;
         
     | 
| 
      
 158 
     | 
    
         
            +
              int int_overflow_abort = 0;
         
     | 
| 
       132 
159 
     | 
    
         | 
| 
       133 
160 
     | 
    
         
             
              row = (table_row *)parser->mem->calloc(1, sizeof(table_row));
         
     | 
| 
       134 
161 
     | 
    
         
             
              row->n_columns = 0;
         
     | 
| 
         @@ -151,18 +178,22 @@ static table_row *row_from_string(cmark_syntax_extension *self, 
     | 
|
| 
       151 
178 
     | 
    
         
             
                      cell_matched);
         
     | 
| 
       152 
179 
     | 
    
         
             
                  cmark_strbuf_trim(cell_buf);
         
     | 
| 
       153 
180 
     | 
    
         | 
| 
       154 
     | 
    
         
            -
                  node_cell *cell = ( 
     | 
| 
      
 181 
     | 
    
         
            +
                  node_cell *cell = append_row_cell(parser->mem, row);
         
     | 
| 
      
 182 
     | 
    
         
            +
                  if (!cell) {
         
     | 
| 
      
 183 
     | 
    
         
            +
                    int_overflow_abort = 1;
         
     | 
| 
      
 184 
     | 
    
         
            +
                    cmark_strbuf_free(cell_buf);
         
     | 
| 
      
 185 
     | 
    
         
            +
                    parser->mem->free(cell_buf);
         
     | 
| 
      
 186 
     | 
    
         
            +
                    break;
         
     | 
| 
      
 187 
     | 
    
         
            +
                  }
         
     | 
| 
       155 
188 
     | 
    
         
             
                  cell->buf = cell_buf;
         
     | 
| 
       156 
189 
     | 
    
         
             
                  cell->start_offset = offset;
         
     | 
| 
       157 
190 
     | 
    
         
             
                  cell->end_offset = offset + cell_matched - 1;
         
     | 
| 
      
 191 
     | 
    
         
            +
                  cell->internal_offset = 0;
         
     | 
| 
       158 
192 
     | 
    
         | 
| 
       159 
     | 
    
         
            -
                  while (cell->start_offset >  
     | 
| 
      
 193 
     | 
    
         
            +
                  while (cell->start_offset > row->paragraph_offset && string[cell->start_offset - 1] != '|') {
         
     | 
| 
       160 
194 
     | 
    
         
             
                    --cell->start_offset;
         
     | 
| 
       161 
195 
     | 
    
         
             
                    ++cell->internal_offset;
         
     | 
| 
       162 
196 
     | 
    
         
             
                  }
         
     | 
| 
       163 
     | 
    
         
            -
             
     | 
| 
       164 
     | 
    
         
            -
                  row->n_columns += 1;
         
     | 
| 
       165 
     | 
    
         
            -
                  row->cells = cmark_llist_append(parser->mem, row->cells, cell);
         
     | 
| 
       166 
197 
     | 
    
         
             
                }
         
     | 
| 
       167 
198 
     | 
    
         | 
| 
       168 
199 
     | 
    
         
             
                offset += cell_matched + pipe_matched;
         
     | 
| 
         @@ -180,9 +211,7 @@ static table_row *row_from_string(cmark_syntax_extension *self, 
     | 
|
| 
       180 
211 
     | 
    
         
             
                  if (row_end_offset && offset != len) {
         
     | 
| 
       181 
212 
     | 
    
         
             
                    row->paragraph_offset = offset;
         
     | 
| 
       182 
213 
     | 
    
         | 
| 
       183 
     | 
    
         
            -
                     
     | 
| 
       184 
     | 
    
         
            -
                    row->cells = NULL;
         
     | 
| 
       185 
     | 
    
         
            -
                    row->n_columns = 0;
         
     | 
| 
      
 214 
     | 
    
         
            +
                    free_row_cells(parser->mem, row);
         
     | 
| 
       186 
215 
     | 
    
         | 
| 
       187 
216 
     | 
    
         
             
                    // Scan past the (optional) leading pipe.
         
     | 
| 
       188 
217 
     | 
    
         
             
                    offset += scan_table_cell_end(string, len, offset);
         
     | 
| 
         @@ -194,7 +223,7 @@ static table_row *row_from_string(cmark_syntax_extension *self, 
     | 
|
| 
       194 
223 
     | 
    
         
             
                }
         
     | 
| 
       195 
224 
     | 
    
         
             
              }
         
     | 
| 
       196 
225 
     | 
    
         | 
| 
       197 
     | 
    
         
            -
              if (offset != len || row->n_columns == 0) {
         
     | 
| 
      
 226 
     | 
    
         
            +
              if (offset != len || row->n_columns == 0 || int_overflow_abort) {
         
     | 
| 
       198 
227 
     | 
    
         
             
                free_table_row(parser->mem, row);
         
     | 
| 
       199 
228 
     | 
    
         
             
                row = NULL;
         
     | 
| 
       200 
229 
     | 
    
         
             
              }
         
     | 
| 
         @@ -233,6 +262,10 @@ static cmark_node *try_opening_table_header(cmark_syntax_extension *self, 
     | 
|
| 
       233 
262 
     | 
    
         
             
              const char *parent_string;
         
     | 
| 
       234 
263 
     | 
    
         
             
              uint16_t i;
         
     | 
| 
       235 
264 
     | 
    
         | 
| 
      
 265 
     | 
    
         
            +
              if (parent_container->flags & CMARK_NODE__TABLE_VISITED) {
         
     | 
| 
      
 266 
     | 
    
         
            +
                return parent_container;
         
     | 
| 
      
 267 
     | 
    
         
            +
              }
         
     | 
| 
      
 268 
     | 
    
         
            +
             
     | 
| 
       236 
269 
     | 
    
         
             
              if (!scan_table_start(input, len, cmark_parser_get_first_nonspace(parser))) {
         
     | 
| 
       237 
270 
     | 
    
         
             
                return parent_container;
         
     | 
| 
       238 
271 
     | 
    
         
             
              }
         
     | 
| 
         @@ -241,6 +274,11 @@ static cmark_node *try_opening_table_header(cmark_syntax_extension *self, 
     | 
|
| 
       241 
274 
     | 
    
         
             
              marker_row = row_from_string(self, parser,
         
     | 
| 
       242 
275 
     | 
    
         
             
                                           input + cmark_parser_get_first_nonspace(parser),
         
     | 
| 
       243 
276 
     | 
    
         
             
                                           len - cmark_parser_get_first_nonspace(parser));
         
     | 
| 
      
 277 
     | 
    
         
            +
              // assert may be optimized out, don't rely on it for security boundaries
         
     | 
| 
      
 278 
     | 
    
         
            +
              if (!marker_row) {
         
     | 
| 
      
 279 
     | 
    
         
            +
                  return parent_container;
         
     | 
| 
      
 280 
     | 
    
         
            +
              }
         
     | 
| 
      
 281 
     | 
    
         
            +
              
         
     | 
| 
       244 
282 
     | 
    
         
             
              assert(marker_row);
         
     | 
| 
       245 
283 
     | 
    
         | 
| 
       246 
284 
     | 
    
         
             
              cmark_arena_push();
         
     | 
| 
         @@ -255,6 +293,7 @@ static cmark_node *try_opening_table_header(cmark_syntax_extension *self, 
     | 
|
| 
       255 
293 
     | 
    
         
             
                free_table_row(parser->mem, marker_row);
         
     | 
| 
       256 
294 
     | 
    
         
             
                free_table_row(parser->mem, header_row);
         
     | 
| 
       257 
295 
     | 
    
         
             
                cmark_arena_pop();
         
     | 
| 
      
 296 
     | 
    
         
            +
                parent_container->flags |= CMARK_NODE__TABLE_VISITED;
         
     | 
| 
       258 
297 
     | 
    
         
             
                return parent_container;
         
     | 
| 
       259 
298 
     | 
    
         
             
              }
         
     | 
| 
       260 
299 
     | 
    
         | 
| 
         @@ -264,6 +303,12 @@ static cmark_node *try_opening_table_header(cmark_syntax_extension *self, 
     | 
|
| 
       264 
303 
     | 
    
         
             
                    len - cmark_parser_get_first_nonspace(parser));
         
     | 
| 
       265 
304 
     | 
    
         
             
                header_row = row_from_string(self, parser, (unsigned char *)parent_string,
         
     | 
| 
       266 
305 
     | 
    
         
             
                                             (int)strlen(parent_string));
         
     | 
| 
      
 306 
     | 
    
         
            +
                // row_from_string can return NULL, add additional check to ensure n_columns match
         
     | 
| 
      
 307 
     | 
    
         
            +
                if (!marker_row || !header_row || header_row->n_columns != marker_row->n_columns) {
         
     | 
| 
      
 308 
     | 
    
         
            +
                    free_table_row(parser->mem, marker_row);
         
     | 
| 
      
 309 
     | 
    
         
            +
                    free_table_row(parser->mem, header_row);
         
     | 
| 
      
 310 
     | 
    
         
            +
                    return parent_container;
         
     | 
| 
      
 311 
     | 
    
         
            +
                }
         
     | 
| 
       267 
312 
     | 
    
         
             
              }
         
     | 
| 
       268 
313 
     | 
    
         | 
| 
       269 
314 
     | 
    
         
             
              if (!cmark_node_set_type(parent_container, CMARK_NODE_TABLE)) {
         
     | 
| 
         @@ -281,11 +326,12 @@ static cmark_node *try_opening_table_header(cmark_syntax_extension *self, 
     | 
|
| 
       281 
326 
     | 
    
         
             
              parent_container->as.opaque = parser->mem->calloc(1, sizeof(node_table));
         
     | 
| 
       282 
327 
     | 
    
         
             
              set_n_table_columns(parent_container, header_row->n_columns);
         
     | 
| 
       283 
328 
     | 
    
         | 
| 
      
 329 
     | 
    
         
            +
              // allocate alignments based on marker_row->n_columns
         
     | 
| 
      
 330 
     | 
    
         
            +
              // since we populate the alignments array based on marker_row->cells
         
     | 
| 
       284 
331 
     | 
    
         
             
              uint8_t *alignments =
         
     | 
| 
       285 
     | 
    
         
            -
                  (uint8_t *)parser->mem->calloc( 
     | 
| 
       286 
     | 
    
         
            -
               
     | 
| 
       287 
     | 
    
         
            -
             
     | 
| 
       288 
     | 
    
         
            -
                node_cell *node = (node_cell *)it->data;
         
     | 
| 
      
 332 
     | 
    
         
            +
                  (uint8_t *)parser->mem->calloc(marker_row->n_columns, sizeof(uint8_t));
         
     | 
| 
      
 333 
     | 
    
         
            +
              for (i = 0; i < marker_row->n_columns; ++i) {
         
     | 
| 
      
 334 
     | 
    
         
            +
                node_cell *node = &marker_row->cells[i];
         
     | 
| 
       289 
335 
     | 
    
         
             
                bool left = node->buf->ptr[0] == ':', right = node->buf->ptr[node->buf->size - 1] == ':';
         
     | 
| 
       290 
336 
     | 
    
         | 
| 
       291 
337 
     | 
    
         
             
                if (left && right)
         
     | 
| 
         @@ -308,10 +354,8 @@ static cmark_node *try_opening_table_header(cmark_syntax_extension *self, 
     | 
|
| 
       308 
354 
     | 
    
         
             
              ntr->is_header = true;
         
     | 
| 
       309 
355 
     | 
    
         | 
| 
       310 
356 
     | 
    
         
             
              {
         
     | 
| 
       311 
     | 
    
         
            -
                 
     | 
| 
       312 
     | 
    
         
            -
             
     | 
| 
       313 
     | 
    
         
            -
                for (tmp = header_row->cells; tmp; tmp = tmp->next) {
         
     | 
| 
       314 
     | 
    
         
            -
                  node_cell *cell = (node_cell *) tmp->data;
         
     | 
| 
      
 357 
     | 
    
         
            +
                for (i = 0; i < header_row->n_columns; ++i) {
         
     | 
| 
      
 358 
     | 
    
         
            +
                  node_cell *cell = &header_row->cells[i];
         
     | 
| 
       315 
359 
     | 
    
         
             
                  cmark_node *header_cell = cmark_parser_add_child(parser, table_header,
         
     | 
| 
       316 
360 
     | 
    
         
             
                      CMARK_NODE_TABLE_CELL, parent_container->start_column + cell->start_offset);
         
     | 
| 
       317 
361 
     | 
    
         
             
                  header_cell->start_line = header_cell->end_line = parent_container->start_line;
         
     | 
| 
         @@ -351,12 +395,17 @@ static cmark_node *try_opening_table_row(cmark_syntax_extension *self, 
     | 
|
| 
       351 
395 
     | 
    
         
             
              row = row_from_string(self, parser, input + cmark_parser_get_first_nonspace(parser),
         
     | 
| 
       352 
396 
     | 
    
         
             
                  len - cmark_parser_get_first_nonspace(parser));
         
     | 
| 
       353 
397 
     | 
    
         | 
| 
      
 398 
     | 
    
         
            +
              if (!row) {
         
     | 
| 
      
 399 
     | 
    
         
            +
                  // clean up the dangling node
         
     | 
| 
      
 400 
     | 
    
         
            +
                  cmark_node_free(table_row_block);
         
     | 
| 
      
 401 
     | 
    
         
            +
                  return NULL;
         
     | 
| 
      
 402 
     | 
    
         
            +
              }
         
     | 
| 
      
 403 
     | 
    
         
            +
             
     | 
| 
       354 
404 
     | 
    
         
             
              {
         
     | 
| 
       355 
     | 
    
         
            -
                cmark_llist *tmp;
         
     | 
| 
       356 
405 
     | 
    
         
             
                int i, table_columns = get_n_table_columns(parent_container);
         
     | 
| 
       357 
406 
     | 
    
         | 
| 
       358 
     | 
    
         
            -
                for ( 
     | 
| 
       359 
     | 
    
         
            -
                  node_cell *cell =  
     | 
| 
      
 407 
     | 
    
         
            +
                for (i = 0; i < row->n_columns && i < table_columns; ++i) {
         
     | 
| 
      
 408 
     | 
    
         
            +
                  node_cell *cell = &row->cells[i];
         
     | 
| 
       360 
409 
     | 
    
         
             
                  cmark_node *node = cmark_parser_add_child(parser, table_row_block,
         
     | 
| 
       361 
410 
     | 
    
         
             
                      CMARK_NODE_TABLE_CELL, parent_container->start_column + cell->start_offset);
         
     | 
| 
       362 
411 
     | 
    
         
             
                  node->internal_offset = cell->internal_offset;
         
     | 
| 
         @@ -759,6 +808,7 @@ static int escape(cmark_syntax_extension *self, cmark_node *node, int c) { 
     | 
|
| 
       759 
808 
     | 
    
         
             
            cmark_syntax_extension *create_table_extension(void) {
         
     | 
| 
       760 
809 
     | 
    
         
             
              cmark_syntax_extension *self = cmark_syntax_extension_new("table");
         
     | 
| 
       761 
810 
     | 
    
         | 
| 
      
 811 
     | 
    
         
            +
              cmark_register_node_flag(&CMARK_NODE__TABLE_VISITED);
         
     | 
| 
       762 
812 
     | 
    
         
             
              cmark_syntax_extension_set_match_block_func(self, matches);
         
     | 
| 
       763 
813 
     | 
    
         
             
              cmark_syntax_extension_set_open_block_func(self, try_opening_table_block);
         
     | 
| 
       764 
814 
     | 
    
         
             
              cmark_syntax_extension_set_get_type_string_func(self, get_type_string);
         
     | 
    
        data/ext/markly/xml.c
    CHANGED
    
    | 
         @@ -11,6 +11,7 @@ 
     | 
|
| 
       11 
11 
     | 
    
         
             
            #include "syntax_extension.h"
         
     | 
| 
       12 
12 
     | 
    
         | 
| 
       13 
13 
     | 
    
         
             
            #define BUFFER_SIZE 100
         
     | 
| 
      
 14 
     | 
    
         
            +
            #define MAX_INDENT 40
         
     | 
| 
       14 
15 
     | 
    
         | 
| 
       15 
16 
     | 
    
         
             
            // Functions to convert cmark_nodes to XML strings.
         
     | 
| 
       16 
17 
     | 
    
         | 
| 
         @@ -26,7 +27,7 @@ struct render_state { 
     | 
|
| 
       26 
27 
     | 
    
         | 
| 
       27 
28 
     | 
    
         
             
            static CMARK_INLINE void indent(struct render_state *state) {
         
     | 
| 
       28 
29 
     | 
    
         
             
              int i;
         
     | 
| 
       29 
     | 
    
         
            -
              for (i = 0; i < state->indent; i++) {
         
     | 
| 
      
 30 
     | 
    
         
            +
              for (i = 0; i < state->indent && i < MAX_INDENT; i++) {
         
     | 
| 
       30 
31 
     | 
    
         
             
                cmark_strbuf_putc(state->xml, ' ');
         
     | 
| 
       31 
32 
     | 
    
         
             
              }
         
     | 
| 
       32 
33 
     | 
    
         
             
            }
         
     | 
    
        data/lib/markly/flags.rb
    CHANGED
    
    | 
         @@ -1,12 +1,22 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
      
 3 
     | 
    
         
            +
            # Released under the MIT License.
         
     | 
| 
      
 4 
     | 
    
         
            +
            # Copyright, 2020-2023, by Samuel Williams.
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
       3 
6 
     | 
    
         
             
            module Markly
         
     | 
| 
      
 7 
     | 
    
         
            +
            	# The default parsing system.
         
     | 
| 
       4 
8 
     | 
    
         
             
            	DEFAULT = 0
         
     | 
| 
      
 9 
     | 
    
         
            +
            	# Replace illegal sequences with the replacement character `U+FFFD`.
         
     | 
| 
       5 
10 
     | 
    
         
             
            	VALIDATE_UTF8 = 1 << 9
         
     | 
| 
      
 11 
     | 
    
         
            +
            	# Use smart punctuation (curly quotes, etc.).
         
     | 
| 
       6 
12 
     | 
    
         
             
            	SMART = 1 << 10
         
     | 
| 
      
 13 
     | 
    
         
            +
            	# Support liberal parsing of inline HTML tags.
         
     | 
| 
       7 
14 
     | 
    
         
             
            	LIBERAL_HTML_TAG = 1 << 12
         
     | 
| 
      
 15 
     | 
    
         
            +
            	# Parse footnotes.
         
     | 
| 
       8 
16 
     | 
    
         
             
            	FOOTNOTES = 1 << 13
         
     | 
| 
      
 17 
     | 
    
         
            +
            	# Support strikethrough using double tildes.
         
     | 
| 
       9 
18 
     | 
    
         
             
            	STRIKETHROUGH_DOUBLE_TILDE = 1 << 14
         
     | 
| 
      
 19 
     | 
    
         
            +
            	# Allow raw/custom HTML and unsafe links.
         
     | 
| 
       10 
20 
     | 
    
         
             
            	UNSAFE = 1 << 17
         
     | 
| 
       11 
21 
     | 
    
         | 
| 
       12 
22 
     | 
    
         
             
            	PARSE_FLAGS = {
         
     | 
| 
         @@ -18,11 +28,17 @@ module Markly 
     | 
|
| 
       18 
28 
     | 
    
         
             
            		unsafe: UNSAFE,
         
     | 
| 
       19 
29 
     | 
    
         
             
            	}
         
     | 
| 
       20 
30 
     | 
    
         | 
| 
      
 31 
     | 
    
         
            +
            	# Include source position in rendered HTML.
         
     | 
| 
       21 
32 
     | 
    
         
             
            	SOURCE_POSITION = 1 << 1
         
     | 
| 
      
 33 
     | 
    
         
            +
            	# Treat `\n` as hardbreaks (by adding `<br/>`).
         
     | 
| 
       22 
34 
     | 
    
         
             
            	HARD_BREAKS = 1 << 2
         
     | 
| 
      
 35 
     | 
    
         
            +
            	# Translate `\n` in the source to a single whitespace.
         
     | 
| 
       23 
36 
     | 
    
         
             
            	NO_BREAKS = 1 << 4
         
     | 
| 
      
 37 
     | 
    
         
            +
            	# Use GitHub-style `<pre lang>` for fenced code blocks.
         
     | 
| 
       24 
38 
     | 
    
         
             
            	GITHUB_PRE_LANG = 1 << 11
         
     | 
| 
      
 39 
     | 
    
         
            +
            	# Use `style` insted of `align` for table cells.
         
     | 
| 
       25 
40 
     | 
    
         
             
            	TABLE_PREFER_STYLE_ATTRIBUTES = 1 << 15
         
     | 
| 
      
 41 
     | 
    
         
            +
            	# Include full info strings of code blocks in separate attribute.
         
     | 
| 
       26 
42 
     | 
    
         
             
            	FULL_INFO_STRING = 1 << 16
         
     | 
| 
       27 
43 
     | 
    
         | 
| 
       28 
44 
     | 
    
         
             
            	RENDER_FLAGS = {
         
     | 
    
        data/lib/markly/node/inspect.rb
    CHANGED
    
    | 
         @@ -1,59 +1,65 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
      
 3 
     | 
    
         
            +
            # Released under the MIT License.
         
     | 
| 
      
 4 
     | 
    
         
            +
            # Copyright, 2017, by Goro Fuji.
         
     | 
| 
      
 5 
     | 
    
         
            +
            # Copyright, 2017-2019, by Garen Torikian.
         
     | 
| 
      
 6 
     | 
    
         
            +
            # Copyright, 2020, by Olle Jonsson.
         
     | 
| 
      
 7 
     | 
    
         
            +
            # Copyright, 2020-2023, by Samuel Williams.
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
       3 
9 
     | 
    
         
             
            require 'pp'
         
     | 
| 
       4 
10 
     | 
    
         | 
| 
       5 
11 
     | 
    
         
             
            module Markly
         
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
      
 12 
     | 
    
         
            +
            	class Node
         
     | 
| 
      
 13 
     | 
    
         
            +
            		module Inspect
         
     | 
| 
      
 14 
     | 
    
         
            +
            			PP_INDENT_SIZE = 2
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            			def inspect
         
     | 
| 
      
 17 
     | 
    
         
            +
            				PP.pp(self, +'', Float::INFINITY)
         
     | 
| 
      
 18 
     | 
    
         
            +
            			end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            			# @param printer [PrettyPrint] pp
         
     | 
| 
      
 21 
     | 
    
         
            +
            			def pretty_print(printer)
         
     | 
| 
      
 22 
     | 
    
         
            +
            				printer.group(PP_INDENT_SIZE, "#<#{self.class}(#{type}):", '>') do
         
     | 
| 
      
 23 
     | 
    
         
            +
            					printer.breakable
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            					attrs = %i[
         
     | 
| 
      
 26 
     | 
    
         
            +
            						source_position
         
     | 
| 
      
 27 
     | 
    
         
            +
            						string_content
         
     | 
| 
      
 28 
     | 
    
         
            +
            						url
         
     | 
| 
      
 29 
     | 
    
         
            +
            						title
         
     | 
| 
      
 30 
     | 
    
         
            +
            						header_level
         
     | 
| 
      
 31 
     | 
    
         
            +
            						list_type
         
     | 
| 
      
 32 
     | 
    
         
            +
            						list_start
         
     | 
| 
      
 33 
     | 
    
         
            +
            						list_tight
         
     | 
| 
      
 34 
     | 
    
         
            +
            						fence_info
         
     | 
| 
      
 35 
     | 
    
         
            +
            					].map do |name|
         
     | 
| 
      
 36 
     | 
    
         
            +
            						begin
         
     | 
| 
      
 37 
     | 
    
         
            +
            							[name, __send__(name)]
         
     | 
| 
      
 38 
     | 
    
         
            +
            						rescue Error
         
     | 
| 
      
 39 
     | 
    
         
            +
            							nil
         
     | 
| 
      
 40 
     | 
    
         
            +
            						end
         
     | 
| 
      
 41 
     | 
    
         
            +
            					end.compact
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
            					printer.seplist(attrs) do |name, value|
         
     | 
| 
      
 44 
     | 
    
         
            +
            						printer.text "#{name}="
         
     | 
| 
      
 45 
     | 
    
         
            +
            						printer.pp value
         
     | 
| 
      
 46 
     | 
    
         
            +
            					end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
            					if first_child
         
     | 
| 
      
 49 
     | 
    
         
            +
            						printer.breakable
         
     | 
| 
      
 50 
     | 
    
         
            +
            						printer.group(PP_INDENT_SIZE) do
         
     | 
| 
      
 51 
     | 
    
         
            +
            							children = []
         
     | 
| 
      
 52 
     | 
    
         
            +
            							node = first_child
         
     | 
| 
      
 53 
     | 
    
         
            +
            							while node
         
     | 
| 
      
 54 
     | 
    
         
            +
            								children << node
         
     | 
| 
      
 55 
     | 
    
         
            +
            								node = node.next
         
     | 
| 
      
 56 
     | 
    
         
            +
            							end
         
     | 
| 
      
 57 
     | 
    
         
            +
            							printer.text 'children='
         
     | 
| 
      
 58 
     | 
    
         
            +
            							printer.pp children
         
     | 
| 
      
 59 
     | 
    
         
            +
            						end
         
     | 
| 
      
 60 
     | 
    
         
            +
            					end
         
     | 
| 
      
 61 
     | 
    
         
            +
            				end
         
     | 
| 
      
 62 
     | 
    
         
            +
            			end
         
     | 
| 
      
 63 
     | 
    
         
            +
            		end
         
     | 
| 
      
 64 
     | 
    
         
            +
            	end
         
     | 
| 
       59 
65 
     | 
    
         
             
            end
         
     |