]> granicus.if.org Git - multimarkdown/commitdiff
ADDED: Add support for 'complex' definitions with nested blocks
authorFletcher T. Penney <fletcher@fletcherpenney.net>
Wed, 8 Feb 2017 00:02:55 +0000 (19:02 -0500)
committerFletcher T. Penney <fletcher@fletcherpenney.net>
Wed, 8 Feb 2017 00:02:55 +0000 (19:02 -0500)
12 files changed:
src/html.c
src/mmd.c
src/mmd.h
src/parser.c
src/parser.out
src/parser.y
src/writer.c
src/writer.h
test/parser_test.y
tests/MMD6Tests/Nested Definition Lists.html
tests/MMD6Tests/Nested Definition Lists.htmlc
tests/MMD6Tests/Nested Definition Lists.text

index 54dc05381b610af10d0b7134944293010cda894f..22791751d18bdb750c13b58362479cab4ee6471a 100644 (file)
@@ -324,9 +324,16 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t
                case BLOCK_DEFINITION:
                        pad(out, 2, scratch);
                        print("<dd>");
+
+                       temp_short = scratch->list_is_tight;
+                       if (!(t->child->next && (t->child->next->type == BLOCK_EMPTY) && t->child->next->next))
+                               scratch->list_is_tight = true;
+
                        mmd_export_token_tree_html(out, source, t->child, offset, scratch);
                        print("</dd>");
                        scratch->padded = 0;
+
+                       scratch->list_is_tight = temp_short;
                        break;
                case BLOCK_DEFLIST:
                        pad(out, 2, scratch);
@@ -334,7 +341,7 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t
                        // Group consecutive definition lists into a single list.
                        // lemon's LALR(1) parser can't properly handle this (to my understanding).
 
-                       if (!(t->prev && t->prev->prev && (t->prev->prev->type == BLOCK_DEFLIST)))
+                       if (!(t->prev && (t->prev->type == BLOCK_DEFLIST)))
                                print("<dl>\n");
        
                        scratch->padded = 2;
@@ -342,7 +349,7 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t
                        mmd_export_token_tree_html(out, source, t->child, t->start + offset, scratch);
                        pad(out, 1, scratch);
 
-                       if (!(t->next && t->next->next && (t->next->next->type == BLOCK_DEFLIST)))
+                       if (!(t->next && (t->next->type == BLOCK_DEFLIST)))
                                print("</dl>\n");
 
                        scratch->padded = 1;
index cd1c3612a0b578058d9102c2f360ab64ae3f1750..3e31bdd61fb8da6e2595554d4de24d655a0460ea 100644 (file)
--- a/src/mmd.c
+++ b/src/mmd.c
@@ -1281,12 +1281,28 @@ void recursive_parse_list_item(mmd_engine * e, token * block) {
        // Strip list marker from first line
        token_remove_first_child(block->child);
 
-       // Remove all leading space from first line of list item
-//     strip_all_leading_space(block->child)
+       // Remove one indent level from all lines to allow recursive parsing
+       deindent_block(e, block);
+
+       mmd_parse_token_chain(e, block);
+}
+
 
+void recursive_parse_indent(mmd_engine * e, token * block) {
        // Remove one indent level from all lines to allow recursive parsing
        deindent_block(e, block);
 
+       // First line is now plain text
+       block->child->type = LINE_PLAIN;
+
+       // Strip tokens?
+       switch (block->type) {
+               case BLOCK_DEFINITION:
+                       // Strip leading ':' from definition
+                       token_remove_first_child(block->child);
+                       break;
+       }
+
        mmd_parse_token_chain(e, block);
 }
 
index 8109ecc5ec4cfad515415488d68a18a053008a62..0ea1b4b192bb8751600cf793878f275dc17117b3 100644 (file)
--- a/src/mmd.h
+++ b/src/mmd.h
@@ -90,6 +90,7 @@ struct mmd_engine {
 
 
 /// Expose routines to lemon parser
+void recursive_parse_indent(mmd_engine * e, token * block);
 void recursive_parse_list_item(mmd_engine * e, token * block);
 void recursive_parse_blockquote(mmd_engine * e, token * block);
 void strip_line_tokens_from_block(mmd_engine * e, token * block);
index ef5f6d0a888f6cef0de54cb7037ccc1cadbe0d62..92bf3a85c6c7db1148ce706e34947b87a371c3bc 100644 (file)
@@ -107,9 +107,9 @@ typedef union {
 #define ParseARG_FETCH  mmd_engine * engine  = yypParser->engine 
 #define ParseARG_STORE yypParser->engine  = engine 
 #define YYFALLBACK 1
-#define YYNSTATE             40
+#define YYNSTATE             39
 #define YYNRULE              104
-#define YY_MAX_SHIFT         39
+#define YY_MAX_SHIFT         38
 #define YY_MIN_SHIFTREDUCE   106
 #define YY_MAX_SHIFTREDUCE   209
 #define YY_MIN_REDUCE        210
@@ -188,28 +188,29 @@ typedef union {
 **  yy_default[]       Default action for each state.
 **
 *********** Begin parsing tables **********************************************/
-#define YY_ACTTAB_COUNT (200)
+#define YY_ACTTAB_COUNT (208)
 static const YYACTIONTYPE yy_action[] = {
- /*     0 */   315,    1,  108,   27,  118,  119,  120,  121,   39,  123,
- /*    10 */    26,   24,   34,   32,   25,   17,  130,   36,  166,   11,
- /*    20 */    11,   24,  175,  176,  172,  208,   29,   37,   22,  204,
- /*    30 */    36,   34,   32,  169,    6,  187,   35,  186,   12,   12,
- /*    40 */   210,   13,  208,  145,  175,  176,  204,  193,  109,  110,
- /*    50 */   111,  112,  113,  114,  115,  180,    5,    4,    3,    2,
- /*    60 */    14,  189,  190,  116,  186,  187,  199,   13,  208,  147,
+ /*     0 */   315,    1,  108,   28,  118,  119,  120,  121,   38,  123,
+ /*    10 */    27,   25,   35,   33,   26,   18,  130,   37,  166,   12,
+ /*    20 */    12,   25,  175,  176,  172,  208,   30,   30,   23,  204,
+ /*    30 */    37,   35,   33,  169,    7,  187,   36,    4,   13,   13,
+ /*    40 */   210,   14,  208,  145,  175,  176,  204,  193,  109,  110,
+ /*    50 */   111,  112,  113,  114,  115,  180,    6,    5,    3,    2,
+ /*    60 */    15,  189,  190,  116,    4,  187,  199,   14,  208,  147,
  /*    70 */   175,  176,  204,  193,  109,  110,  111,  112,  113,  114,
- /*    80 */   115,  180,    5,    4,    3,    2,   14,  189,  190,  116,
- /*    90 */   186,  187,  199,  107,   27,  118,  119,  120,  121,   39,
- /*   100 */   123,   26,   24,   34,   32,   25,   17,  130,   31,   37,
- /*   110 */   175,  176,   24,   28,   28,  172,   23,   29,   37,   22,
- /*   120 */    30,   30,   34,   32,   23,    6,  182,   35,  132,   12,
- /*   130 */    12,  150,   23,    8,    8,   15,   15,  187,  181,  139,
- /*   140 */   139,    8,    8,   15,   15,   33,   33,  138,  138,   23,
- /*   150 */     7,   36,    7,   11,   11,   23,   20,  149,    9,    9,
- /*   160 */    18,   18,   23,  157,   10,   10,   19,   19,  191,  152,
- /*   170 */    23,  201,  131,   16,   16,  208,  161,  137,  148,  204,
- /*   180 */   131,   21,   21,  194,  164,  131,  146,  195,  165,    4,
- /*   190 */   192,   38,  156,    5,  200,  165,  151,  144,  167,  145,
+ /*    80 */   115,  180,    6,    5,    3,    2,   15,  189,  190,  116,
+ /*    90 */     4,  187,  199,  107,   28,  118,  119,  120,  121,   38,
+ /*   100 */   123,   27,   25,   35,   33,   26,   18,  130,   32,   32,
+ /*   110 */   175,  176,   25,   29,   29,  172,   24,   30,   30,   23,
+ /*   120 */    31,   31,   35,   33,   24,    7,  182,   36,  132,   13,
+ /*   130 */    13,  150,   24,    9,    9,   16,   16,  187,  181,  139,
+ /*   140 */   139,    9,    9,   16,   16,   34,   34,  138,  138,   24,
+ /*   150 */     8,   37,    8,   12,   12,  161,   24,   21,    9,    9,
+ /*   160 */    16,   16,   24,  149,  143,  143,  131,   17,   17,   24,
+ /*   170 */   137,   10,   10,   19,   19,  191,  157,   24,   11,   11,
+ /*   180 */    20,   20,  208,  152,  201,  148,  204,  131,   22,   22,
+ /*   190 */   194,  164,  131,  146,  195,  165,    5,  192,  142,  156,
+ /*   200 */     6,  151,  165,  145,  212,  167,  212,  200,
 };
 static const YYCODETYPE yy_lookahead[] = {
  /*     0 */    28,   29,   30,   31,   32,   33,   34,   35,   36,   37,
@@ -227,37 +228,38 @@ static const YYCODETYPE yy_lookahead[] = {
  /*   120 */    45,   46,   59,   60,   36,   62,    3,   64,   48,   66,
  /*   130 */    67,   25,   36,   45,   46,   47,   48,   25,   15,   51,
  /*   140 */    52,   45,   46,   47,   48,   45,   46,   51,   52,   36,
- /*   150 */    63,   64,   65,   66,   67,   36,   49,   49,   45,   46,
- /*   160 */    47,   48,   36,   50,   45,   46,   47,   48,    3,   50,
- /*   170 */    36,    3,   46,   47,   48,    2,   61,   53,   58,    6,
- /*   180 */    46,   47,   48,    3,    2,   46,   21,    7,    6,   17,
- /*   190 */    25,   55,   60,   16,   26,    6,   59,    3,   25,   25,
+ /*   150 */    63,   64,   65,   66,   67,   61,   36,   49,   45,   46,
+ /*   160 */    47,   48,   36,   49,   51,   52,   46,   47,   48,   36,
+ /*   170 */    53,   45,   46,   47,   48,    3,   50,   36,   45,   46,
+ /*   180 */    47,   48,    2,   50,    3,   58,    6,   46,   47,   48,
+ /*   190 */     3,    2,   46,   21,    7,    6,   17,   25,   55,   60,
+ /*   200 */    16,   59,    6,   25,   68,   25,   68,   26,
 };
-#define YY_SHIFT_USE_DFLT (200)
-#define YY_SHIFT_COUNT    (39)
+#define YY_SHIFT_USE_DFLT (208)
+#define YY_SHIFT_COUNT    (38)
 #define YY_SHIFT_MIN      (0)
-#define YY_SHIFT_MAX      (194)
+#define YY_SHIFT_MAX      (196)
 static const unsigned char yy_shift_ofst[] = {
- /*     0 */    66,   40,  112,  112,  112,  112,   23,   23,  112,  112,
- /*    10 */   112,  173,   23,   21,   21,   10,   10,   13,   10,   10,
- /*    20 */    21,   10,  165,   18,  106,  168,  180,  123,   21,   13,
- /*    30 */    21,   13,  172,   21,  177,  182,  189,  194,  194,  174,
+ /*     0 */    66,   40,  112,  112,  112,  112,  112,   23,   23,  112,
+ /*    10 */   112,  112,  180,   23,   21,   21,   10,   10,   13,   10,
+ /*    20 */    10,   21,   10,  172,   18,  106,  181,  187,  123,   21,
+ /*    30 */    13,   21,   13,  179,   21,  184,  189,  196,  178,
 };
 #define YY_REDUCE_USE_DFLT (-48)
-#define YY_REDUCE_COUNT (34)
+#define YY_REDUCE_COUNT (35)
 #define YY_REDUCE_MIN   (-47)
-#define YY_REDUCE_MAX   (139)
+#define YY_REDUCE_MAX   (146)
 static const short yy_reduce_ofst[] = {
- /*     0 */   -28,   63,   88,   96,  113,  119,   87,  -47,  126,  134,
- /*    10 */   134,  -34,  -34,   68,   75,   80,   80,   54,   80,   80,
- /*    20 */   100,   80,   12,  107,  108,  115,  120,  124,  139,  136,
- /*    30 */   139,  136,  132,  139,  137,
+ /*     0 */   -28,   63,   88,   96,  113,  126,  133,   87,  -47,  120,
+ /*    10 */   141,  141,  -34,  -34,   68,   75,   80,   80,   54,   80,
+ /*    20 */    80,  100,   80,   12,  108,  114,   94,  127,  117,  146,
+ /*    30 */   143,  146,  143,  139,  146,  142,
 };
 static const YYACTIONTYPE yy_default[] = {
- /*     0 */   314,  314,  288,  287,  264,  259,  307,  267,  281,  262,
- /*    10 */   257,  272,  274,  306,  289,  283,  240,  233,  263,  258,
- /*    20 */   238,  239,  292,  278,  229,  232,  228,  221,  266,  313,
- /*    30 */   244,  245,  231,  237,  230,  311,  311,  247,  246,  226,
+ /*     0 */   314,  314,  288,  287,  248,  264,  259,  307,  267,  281,
+ /*    10 */   262,  257,  272,  274,  306,  289,  283,  240,  233,  263,
+ /*    20 */   258,  238,  239,  292,  278,  229,  232,  228,  221,  266,
+ /*    30 */   313,  244,  245,  231,  237,  230,  311,  311,  226,
 };
 /********** End of lemon-generated parsing tables *****************************/
 
@@ -446,8 +448,8 @@ static const char *const yyRuleName[] = {
  /*  34 */ "def_link ::= LINE_DEF_LINK chunk",
  /*  35 */ "definition_block ::= para defs",
  /*  36 */ "defs ::= defs def",
- /*  37 */ "defs ::= def",
- /*  38 */ "def ::= def LINE_CONTINUATION",
+ /*  37 */ "def ::= LINE_DEFINITION tail",
+ /*  38 */ "def ::= LINE_DEFINITION",
  /*  39 */ "empty ::= empty LINE_EMPTY",
  /*  40 */ "fenced_block ::= fenced LINE_FENCE_BACKTICK",
  /*  41 */ "fenced ::= fenced fenced_line",
@@ -489,7 +491,7 @@ static const char *const yyRuleName[] = {
  /*  77 */ "def_citation ::= LINE_DEF_CITATION",
  /*  78 */ "def_footnote ::= LINE_DEF_FOOTNOTE",
  /*  79 */ "def_link ::= LINE_DEF_LINK",
- /*  80 */ "def ::= LINE_DEFINITION",
+ /*  80 */ "defs ::= def",
  /*  81 */ "empty ::= LINE_EMPTY",
  /*  82 */ "fenced_block ::= fenced",
  /*  83 */ "fenced ::= LINE_FENCE_BACKTICK",
@@ -898,8 +900,8 @@ static const struct {
   { 34, 2 },
   { 35, 2 },
   { 54, 2 },
-  { 54, 1 },
   { 55, 2 },
+  { 55, 1 },
   { 36, 2 },
   { 37, 2 },
   { 56, 2 },
@@ -941,7 +943,7 @@ static const struct {
   { 32, 1 },
   { 33, 1 },
   { 34, 1 },
-  { 55, 1 },
+  { 54, 1 },
   { 36, 1 },
   { 37, 1 },
   { 56, 1 },
@@ -1094,7 +1096,7 @@ static void yy_reduce(
   yymsp[0].minor.yy0 = yylhsminor.yy0;
         break;
       case 13: /* block ::= def_footnote */
-{ yylhsminor.yy0 = token_new_parent(yymsp[0].minor.yy0, BLOCK_DEF_FOOTNOTE); stack_push(engine->definition_stack, yylhsminor.yy0); }
+{ yylhsminor.yy0 = token_new_parent(yymsp[0].minor.yy0, BLOCK_DEF_FOOTNOTE); stack_push(engine->definition_stack, yylhsminor.yy0); recursive_parse_indent(engine, yylhsminor.yy0); }
   yymsp[0].minor.yy0 = yylhsminor.yy0;
         break;
       case 14: /* block ::= def_link */
@@ -1149,7 +1151,7 @@ static void yy_reduce(
       case 32: /* def_citation ::= LINE_DEF_CITATION tail */ yytestcase(yyruleno==32);
       case 33: /* def_footnote ::= LINE_DEF_FOOTNOTE tail */ yytestcase(yyruleno==33);
       case 34: /* def_link ::= LINE_DEF_LINK chunk */ yytestcase(yyruleno==34);
-      case 38: /* def ::= def LINE_CONTINUATION */ yytestcase(yyruleno==38);
+      case 36: /* defs ::= defs def */ yytestcase(yyruleno==36);
       case 39: /* empty ::= empty LINE_EMPTY */ yytestcase(yyruleno==39);
       case 41: /* fenced ::= fenced fenced_line */ yytestcase(yyruleno==41);
       case 42: /* html_block ::= html_block html_line */ yytestcase(yyruleno==42);
@@ -1178,12 +1180,12 @@ static void yy_reduce(
 { yylhsminor.yy0 = yymsp[-1].minor.yy0; token_chain_append(yymsp[-1].minor.yy0, yymsp[0].minor.yy0); yymsp[-1].minor.yy0->type = BLOCK_TERM; }
   yymsp[-1].minor.yy0 = yylhsminor.yy0;
         break;
-      case 36: /* defs ::= defs def */
-{ yylhsminor.yy0 = yymsp[-1].minor.yy0; token_chain_append(yymsp[-1].minor.yy0, token_new_parent(yymsp[0].minor.yy0, BLOCK_DEFINITION)); }
+      case 37: /* def ::= LINE_DEFINITION tail */
+{ yylhsminor.yy0 = token_new_parent(yymsp[-1].minor.yy0, BLOCK_DEFINITION); token_chain_append(yymsp[-1].minor.yy0, yymsp[0].minor.yy0); recursive_parse_indent(engine, yylhsminor.yy0); }
   yymsp[-1].minor.yy0 = yylhsminor.yy0;
         break;
-      case 37: /* defs ::= def */
-{ yylhsminor.yy0 = token_new_parent(yymsp[0].minor.yy0, BLOCK_DEFINITION); }
+      case 38: /* def ::= LINE_DEFINITION */
+{ yylhsminor.yy0 = token_new_parent(yymsp[0].minor.yy0, BLOCK_DEFINITION);  }
   yymsp[0].minor.yy0 = yylhsminor.yy0;
         break;
       case 40: /* fenced_block ::= fenced LINE_FENCE_BACKTICK */
@@ -1239,7 +1241,7 @@ static void yy_reduce(
       /* (77) def_citation ::= LINE_DEF_CITATION */ yytestcase(yyruleno==77);
       /* (78) def_footnote ::= LINE_DEF_FOOTNOTE */ yytestcase(yyruleno==78);
       /* (79) def_link ::= LINE_DEF_LINK */ yytestcase(yyruleno==79);
-      /* (80) def ::= LINE_DEFINITION */ yytestcase(yyruleno==80);
+      /* (80) defs ::= def (OPTIMIZED OUT) */ assert(yyruleno!=80);
       /* (81) empty ::= LINE_EMPTY */ yytestcase(yyruleno==81);
       /* (82) fenced_block ::= fenced */ yytestcase(yyruleno==82);
       /* (83) fenced ::= LINE_FENCE_BACKTICK */ yytestcase(yyruleno==83);
index e929ee9c0fd148c282518e64841104394a703974..704887195d7d3d7fb9187635a3fd1227d7ba3639 100644 (file)
@@ -37,7 +37,7 @@ State 0:
           definition_block ::= * para defs
           defs ::= * defs def
           defs ::= * def
-          def ::= * def LINE_CONTINUATION
+          def ::= * LINE_DEFINITION tail
           def ::= * LINE_DEFINITION
           empty ::= * empty LINE_EMPTY
           empty ::= * LINE_EMPTY
@@ -79,7 +79,7 @@ State 0:
           para ::= * all_rows
           para ::= * defs
 
-                    LINE_PLAIN shift        13     
+                    LINE_PLAIN shift        14     
           LINE_TABLE_SEPARATOR shift-reduce 102    row ::= LINE_TABLE_SEPARATOR
              LINE_INDENTED_TAB shift-reduce 69     indented_line ::= LINE_INDENTED_TAB
            LINE_INDENTED_SPACE shift-reduce 70     indented_line ::= LINE_INDENTED_SPACE
@@ -93,44 +93,44 @@ State 0:
                     LINE_ATX_6 shift-reduce 8      block ::= LINE_ATX_6
                        LINE_HR shift-reduce 9      block ::= LINE_HR
                LINE_BLOCKQUOTE shift-reduce 74     blockquote ::= LINE_BLOCKQUOTE
-            LINE_LIST_BULLETED shift        5      
-          LINE_LIST_ENUMERATED shift        4      
+            LINE_LIST_BULLETED shift        6      
+          LINE_LIST_ENUMERATED shift        5      
              LINE_DEF_CITATION shift        3      
              LINE_DEF_FOOTNOTE shift        2      
-                 LINE_DEF_LINK shift        14     
+                 LINE_DEF_LINK shift        15     
            LINE_FENCE_BACKTICK shift-reduce 83     fenced ::= LINE_FENCE_BACKTICK
      LINE_FENCE_BACKTICK_START shift-reduce 84     fenced ::= LINE_FENCE_BACKTICK_START
                       LINE_TOC shift-reduce 10     block ::= LINE_TOC
-               LINE_DEFINITION shift-reduce 80     def ::= LINE_DEFINITION
+               LINE_DEFINITION shift        4      
                     LINE_EMPTY shift-reduce 81     empty ::= LINE_EMPTY
                      LINE_META shift-reduce 93     meta_block ::= LINE_META
                            doc accept
                         blocks shift        1      
                          block shift-reduce 2      blocks ::= block
-                    blockquote shift        27     
+                    blockquote shift        28     
                   def_citation shift-reduce 12     block ::= def_citation
                   def_footnote shift-reduce 13     block ::= def_footnote
                       def_link shift-reduce 14     block ::= def_link
               definition_block shift-reduce 15     block ::= definition_block
-                         empty shift        39     
+                         empty shift        38     
                   fenced_block shift-reduce 17     block ::= fenced_block
-                    html_block shift        26     
-                 indented_code shift        24     
-                   list_bullet shift        34     
-                     list_enum shift        32     
-                    meta_block shift        25     
-                          para shift        17     
+                    html_block shift        27     
+                 indented_code shift        25     
+                   list_bullet shift        35     
+                     list_enum shift        33     
+                    meta_block shift        26     
+                          para shift        18     
                          table shift-reduce 24     block ::= table
-                 indented_line shift        24       /* because indented_line==indented_code */
-                          defs shift        29     
-                           def shift        37     
-                        fenced shift        22     
-                   item_bullet shift        34       /* because item_bullet==list_bullet */
-                     item_enum shift        32       /* because item_enum==list_enum */
-                  table_header shift        6      
-                   header_rows shift        35     
-                      all_rows shift        12     
-                           row shift        12       /* because row==all_rows */
+                 indented_line shift        25       /* because indented_line==indented_code */
+                          defs shift        30     
+                           def shift        30       /* because def==defs */
+                        fenced shift        23     
+                   item_bullet shift        35       /* because item_bullet==list_bullet */
+                     item_enum shift        33       /* because item_enum==list_enum */
+                  table_header shift        7      
+                   header_rows shift        36     
+                      all_rows shift        13     
+                           row shift        13       /* because row==all_rows */
 
 State 1:
       (0) doc ::= blocks *
@@ -170,7 +170,7 @@ State 1:
           definition_block ::= * para defs
           defs ::= * defs def
           defs ::= * def
-          def ::= * def LINE_CONTINUATION
+          def ::= * LINE_DEFINITION tail
           def ::= * LINE_DEFINITION
           empty ::= * empty LINE_EMPTY
           empty ::= * LINE_EMPTY
@@ -213,7 +213,7 @@ State 1:
           para ::= * defs
 
                              $ reduce       0      doc ::= blocks
-                    LINE_PLAIN shift        13     
+                    LINE_PLAIN shift        14     
           LINE_TABLE_SEPARATOR shift-reduce 102    row ::= LINE_TABLE_SEPARATOR
              LINE_INDENTED_TAB shift-reduce 69     indented_line ::= LINE_INDENTED_TAB
            LINE_INDENTED_SPACE shift-reduce 70     indented_line ::= LINE_INDENTED_SPACE
@@ -227,42 +227,42 @@ State 1:
                     LINE_ATX_6 shift-reduce 8      block ::= LINE_ATX_6
                        LINE_HR shift-reduce 9      block ::= LINE_HR
                LINE_BLOCKQUOTE shift-reduce 74     blockquote ::= LINE_BLOCKQUOTE
-            LINE_LIST_BULLETED shift        5      
-          LINE_LIST_ENUMERATED shift        4      
+            LINE_LIST_BULLETED shift        6      
+          LINE_LIST_ENUMERATED shift        5      
              LINE_DEF_CITATION shift        3      
              LINE_DEF_FOOTNOTE shift        2      
-                 LINE_DEF_LINK shift        14     
+                 LINE_DEF_LINK shift        15     
            LINE_FENCE_BACKTICK shift-reduce 83     fenced ::= LINE_FENCE_BACKTICK
      LINE_FENCE_BACKTICK_START shift-reduce 84     fenced ::= LINE_FENCE_BACKTICK_START
                       LINE_TOC shift-reduce 10     block ::= LINE_TOC
-               LINE_DEFINITION shift-reduce 80     def ::= LINE_DEFINITION
+               LINE_DEFINITION shift        4      
                     LINE_EMPTY shift-reduce 81     empty ::= LINE_EMPTY
                      LINE_META shift-reduce 93     meta_block ::= LINE_META
                          block shift-reduce 1      blocks ::= blocks block
-                    blockquote shift        27     
+                    blockquote shift        28     
                   def_citation shift-reduce 12     block ::= def_citation
                   def_footnote shift-reduce 13     block ::= def_footnote
                       def_link shift-reduce 14     block ::= def_link
               definition_block shift-reduce 15     block ::= definition_block
-                         empty shift        39     
+                         empty shift        38     
                   fenced_block shift-reduce 17     block ::= fenced_block
-                    html_block shift        26     
-                 indented_code shift        24     
-                   list_bullet shift        34     
-                     list_enum shift        32     
-                    meta_block shift        25     
-                          para shift        17     
+                    html_block shift        27     
+                 indented_code shift        25     
+                   list_bullet shift        35     
+                     list_enum shift        33     
+                    meta_block shift        26     
+                          para shift        18     
                          table shift-reduce 24     block ::= table
-                 indented_line shift        24       /* because indented_line==indented_code */
-                          defs shift        29     
-                           def shift        37     
-                        fenced shift        22     
-                   item_bullet shift        34       /* because item_bullet==list_bullet */
-                     item_enum shift        32       /* because item_enum==list_enum */
-                  table_header shift        6      
-                   header_rows shift        35     
-                      all_rows shift        12     
-                           row shift        12       /* because row==all_rows */
+                 indented_line shift        25       /* because indented_line==indented_code */
+                          defs shift        30     
+                           def shift        30       /* because def==defs */
+                        fenced shift        23     
+                   item_bullet shift        35       /* because item_bullet==list_bullet */
+                     item_enum shift        33       /* because item_enum==list_enum */
+                  table_header shift        7      
+                   header_rows shift        36     
+                      all_rows shift        13     
+                           row shift        13       /* because row==all_rows */
 
 State 2:
           chunk ::= * chunk chunk_line
@@ -285,11 +285,11 @@ State 2:
              LINE_CONTINUATION shift-reduce 66     chunk_line ::= LINE_CONTINUATION
                     LINE_EMPTY shift-reduce 81     empty ::= LINE_EMPTY
                     LINE_EMPTY reduce       78      ** Parsing conflict **
-                         empty shift        23     
-                         chunk shift        8      
-                    chunk_line shift        8        /* because chunk_line==chunk */
-                 nested_chunks shift        15     
-                  nested_chunk shift        15       /* because nested_chunk==nested_chunks */
+                         empty shift        24     
+                         chunk shift        9      
+                    chunk_line shift        9        /* because chunk_line==chunk */
+                 nested_chunks shift        16     
+                  nested_chunk shift        16       /* because nested_chunk==nested_chunks */
                  opt_ext_chunk shift-reduce 33     def_footnote ::= LINE_DEF_FOOTNOTE tail  /* because opt_ext_chunk==tail */
                           tail shift-reduce 33     def_footnote ::= LINE_DEF_FOOTNOTE tail
                      {default} reduce       78     def_footnote ::= LINE_DEF_FOOTNOTE
@@ -315,16 +315,46 @@ State 3:
              LINE_CONTINUATION shift-reduce 66     chunk_line ::= LINE_CONTINUATION
                     LINE_EMPTY shift-reduce 81     empty ::= LINE_EMPTY
                     LINE_EMPTY reduce       77      ** Parsing conflict **
-                         empty shift        23     
-                         chunk shift        8      
-                    chunk_line shift        8        /* because chunk_line==chunk */
-                 nested_chunks shift        15     
-                  nested_chunk shift        15       /* because nested_chunk==nested_chunks */
+                         empty shift        24     
+                         chunk shift        9      
+                    chunk_line shift        9        /* because chunk_line==chunk */
+                 nested_chunks shift        16     
+                  nested_chunk shift        16       /* because nested_chunk==nested_chunks */
                  opt_ext_chunk shift-reduce 32     def_citation ::= LINE_DEF_CITATION tail  /* because opt_ext_chunk==tail */
                           tail shift-reduce 32     def_citation ::= LINE_DEF_CITATION tail
                      {default} reduce       77     def_citation ::= LINE_DEF_CITATION
 
 State 4:
+          chunk ::= * chunk chunk_line
+          chunk ::= * chunk_line
+          chunk_line ::= * LINE_CONTINUATION
+          nested_chunks ::= * nested_chunks nested_chunk
+          nested_chunks ::= * nested_chunk
+          nested_chunk ::= * empty indented_line chunk
+          nested_chunk ::= * empty indented_line
+          nested_chunk ::= * empty
+          opt_ext_chunk ::= * chunk nested_chunks
+          opt_ext_chunk ::= * chunk
+          tail ::= * opt_ext_chunk
+          tail ::= * nested_chunks
+          def ::= LINE_DEFINITION * tail
+     (38) def ::= LINE_DEFINITION *
+          empty ::= * empty LINE_EMPTY
+          empty ::= * LINE_EMPTY
+
+             LINE_CONTINUATION shift-reduce 66     chunk_line ::= LINE_CONTINUATION
+                    LINE_EMPTY shift-reduce 81     empty ::= LINE_EMPTY
+                    LINE_EMPTY reduce       38      ** Parsing conflict **
+                         empty shift        24     
+                         chunk shift        9      
+                    chunk_line shift        9        /* because chunk_line==chunk */
+                 nested_chunks shift        16     
+                  nested_chunk shift        16       /* because nested_chunk==nested_chunks */
+                 opt_ext_chunk shift-reduce 37     def ::= LINE_DEFINITION tail  /* because opt_ext_chunk==tail */
+                          tail shift-reduce 37     def ::= LINE_DEFINITION tail
+                     {default} reduce       38     def ::= LINE_DEFINITION
+
+State 5:
           chunk ::= * chunk chunk_line
           chunk ::= * chunk_line
           chunk_line ::= * LINE_CONTINUATION
@@ -344,15 +374,15 @@ State 4:
              LINE_CONTINUATION shift-reduce 66     chunk_line ::= LINE_CONTINUATION
                     LINE_EMPTY shift-reduce 81     empty ::= LINE_EMPTY
                     LINE_EMPTY reduce       54      ** Parsing conflict **
-                         empty shift        23     
-                         chunk shift             
-                    chunk_line shift               /* because chunk_line==chunk */
-                 nested_chunks shift        18     
-                  nested_chunk shift        18       /* because nested_chunk==nested_chunks */
+                         empty shift        24     
+                         chunk shift        10     
+                    chunk_line shift        10       /* because chunk_line==chunk */
+                 nested_chunks shift        19     
+                  nested_chunk shift        19       /* because nested_chunk==nested_chunks */
                      ext_chunk shift-reduce 51     item_enum ::= LINE_LIST_ENUMERATED ext_chunk
                      {default} reduce       54     item_enum ::= LINE_LIST_ENUMERATED
 
-State 5:
+State 6:
           chunk ::= * chunk chunk_line
           chunk ::= * chunk_line
           chunk_line ::= * LINE_CONTINUATION
@@ -372,15 +402,15 @@ State 5:
              LINE_CONTINUATION shift-reduce 66     chunk_line ::= LINE_CONTINUATION
                     LINE_EMPTY shift-reduce 81     empty ::= LINE_EMPTY
                     LINE_EMPTY reduce       49      ** Parsing conflict **
-                         empty shift        23     
-                         chunk shift        10     
-                    chunk_line shift        10       /* because chunk_line==chunk */
-                 nested_chunks shift        19     
-                  nested_chunk shift        19       /* because nested_chunk==nested_chunks */
+                         empty shift        24     
+                         chunk shift        11     
+                    chunk_line shift        11       /* because chunk_line==chunk */
+                 nested_chunks shift        20     
+                  nested_chunk shift        20       /* because nested_chunk==nested_chunks */
                      ext_chunk shift-reduce 46     item_bullet ::= LINE_LIST_BULLETED ext_chunk
                      {default} reduce       49     item_bullet ::= LINE_LIST_BULLETED
 
-State 6:
+State 7:
           table ::= table_header * table_body
      (97) table ::= table_header *
           header_rows ::= * header_rows LINE_TABLE
@@ -398,14 +428,14 @@ State 6:
           LINE_TABLE_SEPARATOR reduce       97      ** Parsing conflict **
                     LINE_TABLE shift-reduce 98     header_rows ::= LINE_TABLE
                     LINE_TABLE reduce       97      ** Parsing conflict **
-                    table_body shift        7      
-                   header_rows shift        36     
-                 table_section shift        7        /* because table_section==table_body */
-                      all_rows shift        11     
-                           row shift        11       /* because row==all_rows */
+                    table_body shift        8      
+                   header_rows shift        37     
+                 table_section shift        8        /* because table_section==table_body */
+                      all_rows shift        12     
+                           row shift        12       /* because row==all_rows */
                      {default} reduce       97     table ::= table_header
 
-State 7:
+State 8:
      (57) table ::= table_header table_body *
           header_rows ::= * header_rows LINE_TABLE
           header_rows ::= * LINE_TABLE
@@ -421,13 +451,13 @@ State 7:
           LINE_TABLE_SEPARATOR reduce       57      ** Parsing conflict **
                     LINE_TABLE shift-reduce 98     header_rows ::= LINE_TABLE
                     LINE_TABLE reduce       57      ** Parsing conflict **
-                   header_rows shift        36     
+                   header_rows shift        37     
                  table_section shift-reduce 60     table_body ::= table_body table_section
-                      all_rows shift        11     
-                           row shift        11       /* because row==all_rows */
+                      all_rows shift        12     
+                           row shift        12       /* because row==all_rows */
                      {default} reduce       57     table ::= table_header table_body
 
-State 8:
+State 9:
           chunk ::= chunk * chunk_line
           chunk_line ::= * LINE_CONTINUATION
           nested_chunks ::= * nested_chunks nested_chunk
@@ -443,13 +473,13 @@ State 8:
              LINE_CONTINUATION shift-reduce 66     chunk_line ::= LINE_CONTINUATION
                     LINE_EMPTY shift-reduce 81     empty ::= LINE_EMPTY
                     LINE_EMPTY reduce       71      ** Parsing conflict **
-                         empty shift        23     
+                         empty shift        24     
                     chunk_line shift-reduce 25     chunk ::= chunk chunk_line
-                 nested_chunks shift        16     
-                  nested_chunk shift        16       /* because nested_chunk==nested_chunks */
+                 nested_chunks shift        17     
+                  nested_chunk shift        17       /* because nested_chunk==nested_chunks */
                      {default} reduce       71     opt_ext_chunk ::= chunk
 
-State 9:
+State 10:
           chunk ::= chunk * chunk_line
           chunk_line ::= * LINE_CONTINUATION
           nested_chunks ::= * nested_chunks nested_chunk
@@ -465,13 +495,13 @@ State 9:
              LINE_CONTINUATION shift-reduce 66     chunk_line ::= LINE_CONTINUATION
                     LINE_EMPTY shift-reduce 81     empty ::= LINE_EMPTY
                     LINE_EMPTY reduce       52      ** Parsing conflict **
-                         empty shift        23     
+                         empty shift        24     
                     chunk_line shift-reduce 25     chunk ::= chunk chunk_line
-                 nested_chunks shift        21     
-                  nested_chunk shift        21       /* because nested_chunk==nested_chunks */
+                 nested_chunks shift        22     
+                  nested_chunk shift        22       /* because nested_chunk==nested_chunks */
                      {default} reduce       52     item_enum ::= LINE_LIST_ENUMERATED chunk
 
-State 10:
+State 11:
           chunk ::= chunk * chunk_line
           chunk_line ::= * LINE_CONTINUATION
           nested_chunks ::= * nested_chunks nested_chunk
@@ -487,13 +517,13 @@ State 10:
              LINE_CONTINUATION shift-reduce 66     chunk_line ::= LINE_CONTINUATION
                     LINE_EMPTY shift-reduce 81     empty ::= LINE_EMPTY
                     LINE_EMPTY reduce       47      ** Parsing conflict **
-                         empty shift        23     
+                         empty shift        24     
                     chunk_line shift-reduce 25     chunk ::= chunk chunk_line
-                 nested_chunks shift        21     
-                  nested_chunk shift        21       /* because nested_chunk==nested_chunks */
+                 nested_chunks shift        22     
+                  nested_chunk shift        22       /* because nested_chunk==nested_chunks */
                      {default} reduce       47     item_bullet ::= LINE_LIST_BULLETED chunk
 
-State 11:
+State 12:
           header_rows ::= * header_rows LINE_TABLE
           header_rows ::= * LINE_TABLE
           table_section ::= all_rows * LINE_EMPTY
@@ -508,11 +538,11 @@ State 11:
                     LINE_TABLE reduce       62      ** Parsing conflict **
                     LINE_EMPTY shift-reduce 61     table_section ::= all_rows LINE_EMPTY
                     LINE_EMPTY reduce       62      ** Parsing conflict **
-                   header_rows shift        36     
+                   header_rows shift        37     
                            row shift-reduce 63     all_rows ::= all_rows row
                      {default} reduce       62     table_section ::= all_rows
 
-State 12:
+State 13:
           header_rows ::= * header_rows LINE_TABLE
           header_rows ::= * LINE_TABLE
           all_rows ::= all_rows * row
@@ -524,11 +554,11 @@ State 12:
           LINE_TABLE_SEPARATOR reduce       64      ** Parsing conflict **
                     LINE_TABLE shift-reduce 98     header_rows ::= LINE_TABLE
                     LINE_TABLE reduce       64      ** Parsing conflict **
-                   header_rows shift        36     
+                   header_rows shift        37     
                            row shift-reduce 63     all_rows ::= all_rows row
                      {default} reduce       64     para ::= all_rows
 
-State 13:
+State 14:
           chunk ::= * chunk chunk_line
           chunk ::= * chunk_line
           chunk_line ::= * LINE_CONTINUATION
@@ -536,11 +566,11 @@ State 13:
      (96) para ::= LINE_PLAIN *
 
              LINE_CONTINUATION shift-reduce 66     chunk_line ::= LINE_CONTINUATION
-                         chunk shift        28     
-                    chunk_line shift        28       /* because chunk_line==chunk */
+                         chunk shift        29     
+                    chunk_line shift        29       /* because chunk_line==chunk */
                      {default} reduce       96     para ::= LINE_PLAIN
 
-State 14:
+State 15:
           chunk ::= * chunk chunk_line
           chunk ::= * chunk_line
           chunk_line ::= * LINE_CONTINUATION
@@ -548,11 +578,11 @@ State 14:
      (79) def_link ::= LINE_DEF_LINK *
 
              LINE_CONTINUATION shift-reduce 66     chunk_line ::= LINE_CONTINUATION
-                         chunk shift        30     
-                    chunk_line shift        30       /* because chunk_line==chunk */
+                         chunk shift        31     
+                    chunk_line shift        31       /* because chunk_line==chunk */
                      {default} reduce       79     def_link ::= LINE_DEF_LINK
 
-State 15:
+State 16:
           nested_chunks ::= nested_chunks * nested_chunk
           nested_chunk ::= * empty indented_line chunk
           nested_chunk ::= * empty indented_line
@@ -563,11 +593,11 @@ State 15:
 
                     LINE_EMPTY shift-reduce 81     empty ::= LINE_EMPTY
                     LINE_EMPTY reduce       73      ** Parsing conflict **
-                         empty shift        23     
+                         empty shift        24     
                   nested_chunk shift-reduce 26     nested_chunks ::= nested_chunks nested_chunk
                      {default} reduce       73     tail ::= nested_chunks
 
-State 16:
+State 17:
           nested_chunks ::= nested_chunks * nested_chunk
           nested_chunk ::= * empty indented_line chunk
           nested_chunk ::= * empty indented_line
@@ -578,25 +608,25 @@ State 16:
 
                     LINE_EMPTY shift-reduce 81     empty ::= LINE_EMPTY
                     LINE_EMPTY reduce       30      ** Parsing conflict **
-                         empty shift        23     
+                         empty shift        24     
                   nested_chunk shift-reduce 26     nested_chunks ::= nested_chunks nested_chunk
                      {default} reduce       30     opt_ext_chunk ::= chunk nested_chunks
 
-State 17:
+State 18:
      (23) block ::= para *
           definition_block ::= para * defs
           defs ::= * defs def
           defs ::= * def
-          def ::= * def LINE_CONTINUATION
+          def ::= * LINE_DEFINITION tail
           def ::= * LINE_DEFINITION
 
-               LINE_DEFINITION shift-reduce 80     def ::= LINE_DEFINITION
+               LINE_DEFINITION shift        4      
                LINE_DEFINITION reduce       23      ** Parsing conflict **
-                          defs shift        31     
-                           def shift        37     
+                          defs shift        32     
+                           def shift        32       /* because def==defs */
                      {default} reduce       23     block ::= para
 
-State 18:
+State 19:
           nested_chunks ::= nested_chunks * nested_chunk
           nested_chunk ::= * empty indented_line chunk
           nested_chunk ::= * empty indented_line
@@ -607,11 +637,11 @@ State 18:
 
                     LINE_EMPTY shift-reduce 81     empty ::= LINE_EMPTY
                     LINE_EMPTY reduce       53      ** Parsing conflict **
-                         empty shift        23     
+                         empty shift        24     
                   nested_chunk shift-reduce 26     nested_chunks ::= nested_chunks nested_chunk
                      {default} reduce       53     item_enum ::= LINE_LIST_ENUMERATED nested_chunks
 
-State 19:
+State 20:
           nested_chunks ::= nested_chunks * nested_chunk
           nested_chunk ::= * empty indented_line chunk
           nested_chunk ::= * empty indented_line
@@ -622,11 +652,11 @@ State 19:
 
                     LINE_EMPTY shift-reduce 81     empty ::= LINE_EMPTY
                     LINE_EMPTY reduce       48      ** Parsing conflict **
-                         empty shift        23     
+                         empty shift        24     
                   nested_chunk shift-reduce 26     nested_chunks ::= nested_chunks nested_chunk
                      {default} reduce       48     item_bullet ::= LINE_LIST_BULLETED nested_chunks
 
-State 20:
+State 21:
           chunk ::= * chunk chunk_line
           chunk ::= * chunk_line
           chunk_line ::= * LINE_CONTINUATION
@@ -634,11 +664,11 @@ State 20:
      (28) nested_chunk ::= empty indented_line *
 
              LINE_CONTINUATION shift-reduce 66     chunk_line ::= LINE_CONTINUATION
-                         chunk shift        33     
-                    chunk_line shift        33       /* because chunk_line==chunk */
+                         chunk shift        34     
+                    chunk_line shift        34       /* because chunk_line==chunk */
                      {default} reduce       28     nested_chunk ::= empty indented_line
 
-State 21:
+State 22:
           nested_chunks ::= nested_chunks * nested_chunk
           nested_chunk ::= * empty indented_line chunk
           nested_chunk ::= * empty indented_line
@@ -649,11 +679,11 @@ State 21:
 
                     LINE_EMPTY shift-reduce 81     empty ::= LINE_EMPTY
                     LINE_EMPTY reduce       29      ** Parsing conflict **
-                         empty shift        23     
+                         empty shift        24     
                   nested_chunk shift-reduce 26     nested_chunks ::= nested_chunks nested_chunk
                      {default} reduce       29     ext_chunk ::= chunk nested_chunks
 
-State 22:
+State 23:
           fenced_block ::= fenced * LINE_FENCE_BACKTICK
      (82) fenced_block ::= fenced *
           fenced ::= fenced * fenced_line
@@ -668,7 +698,7 @@ State 22:
                    fenced_line shift-reduce 41     fenced ::= fenced fenced_line
                      {default} reduce       82     fenced_block ::= fenced
 
-State 23:
+State 24:
           nested_chunk ::= empty * indented_line chunk
           nested_chunk ::= empty * indented_line
      (68) nested_chunk ::= empty *
@@ -682,10 +712,10 @@ State 23:
            LINE_INDENTED_SPACE reduce       68      ** Parsing conflict **
                     LINE_EMPTY shift-reduce 39     empty ::= empty LINE_EMPTY
                     LINE_EMPTY reduce       68      ** Parsing conflict **
-                 indented_line shift        20     
+                 indented_line shift        21     
                      {default} reduce       68     nested_chunk ::= empty
 
-State 24:
+State 25:
      (19) block ::= indented_code *
           indented_line ::= * LINE_INDENTED_TAB
           indented_line ::= * LINE_INDENTED_SPACE
@@ -701,7 +731,7 @@ State 24:
                  indented_line shift-reduce 43     indented_code ::= indented_code indented_line
                      {default} reduce       19     block ::= indented_code
 
-State 25:
+State 26:
      (22) block ::= meta_block *
           meta_block ::= meta_block * meta_line
           meta_line ::= * LINE_META
@@ -713,7 +743,7 @@ State 25:
                      meta_line shift-reduce 55     meta_block ::= meta_block meta_line
                      {default} reduce       22     block ::= meta_block
 
-State 26:
+State 27:
      (18) block ::= html_block *
           html_block ::= html_block * html_line
           html_line ::= * LINE_CONTINUATION
@@ -725,7 +755,7 @@ State 26:
                      html_line shift-reduce 42     html_block ::= html_block html_line
                      {default} reduce       18     block ::= html_block
 
-State 27:
+State 28:
      (11) block ::= blockquote *
           blockquote ::= blockquote * quote_line
           quote_line ::= * LINE_BLOCKQUOTE
@@ -737,7 +767,7 @@ State 27:
                     quote_line shift-reduce 31     blockquote ::= blockquote quote_line
                      {default} reduce       11     block ::= blockquote
 
-State 28:
+State 29:
           chunk ::= chunk * chunk_line
           chunk_line ::= * LINE_CONTINUATION
      (56) para ::= LINE_PLAIN chunk *
@@ -746,18 +776,18 @@ State 28:
                     chunk_line shift-reduce 25     chunk ::= chunk chunk_line
                      {default} reduce       56     para ::= LINE_PLAIN chunk
 
-State 29:
+State 30:
           defs ::= defs * def
-          def ::= * def LINE_CONTINUATION
+          def ::= * LINE_DEFINITION tail
           def ::= * LINE_DEFINITION
     (103) para ::= defs *
 
-               LINE_DEFINITION shift-reduce 80     def ::= LINE_DEFINITION
+               LINE_DEFINITION shift        4      
                LINE_DEFINITION reduce       103     ** Parsing conflict **
-                           def shift        38     
+                           def shift-reduce 36     defs ::= defs def
                      {default} reduce       103    para ::= defs
 
-State 30:
+State 31:
           chunk ::= chunk * chunk_line
           chunk_line ::= * LINE_CONTINUATION
      (34) def_link ::= LINE_DEF_LINK chunk *
@@ -766,18 +796,18 @@ State 30:
                     chunk_line shift-reduce 25     chunk ::= chunk chunk_line
                      {default} reduce       34     def_link ::= LINE_DEF_LINK chunk
 
-State 31:
+State 32:
      (35) definition_block ::= para defs *
           defs ::= defs * def
-          def ::= * def LINE_CONTINUATION
+          def ::= * LINE_DEFINITION tail
           def ::= * LINE_DEFINITION
 
-               LINE_DEFINITION shift-reduce 80     def ::= LINE_DEFINITION
+               LINE_DEFINITION shift        4      
                LINE_DEFINITION reduce       35      ** Parsing conflict **
-                           def shift        38     
+                           def shift-reduce 36     defs ::= defs def
                      {default} reduce       35     definition_block ::= para defs
 
-State 32:
+State 33:
      (21) block ::= list_enum *
           list_enum ::= list_enum * item_enum
           item_enum ::= * LINE_LIST_ENUMERATED ext_chunk
@@ -785,12 +815,12 @@ State 32:
           item_enum ::= * LINE_LIST_ENUMERATED nested_chunks
           item_enum ::= * LINE_LIST_ENUMERATED
 
-          LINE_LIST_ENUMERATED shift        4      
+          LINE_LIST_ENUMERATED shift        5      
           LINE_LIST_ENUMERATED reduce       21      ** Parsing conflict **
                      item_enum shift-reduce 50     list_enum ::= list_enum item_enum
                      {default} reduce       21     block ::= list_enum
 
-State 33:
+State 34:
           chunk ::= chunk * chunk_line
           chunk_line ::= * LINE_CONTINUATION
      (27) nested_chunk ::= empty indented_line chunk *
@@ -799,7 +829,7 @@ State 33:
                     chunk_line shift-reduce 25     chunk ::= chunk chunk_line
                      {default} reduce       27     nested_chunk ::= empty indented_line chunk
 
-State 34:
+State 35:
      (20) block ::= list_bullet *
           list_bullet ::= list_bullet * item_bullet
           item_bullet ::= * LINE_LIST_BULLETED ext_chunk
@@ -807,12 +837,12 @@ State 34:
           item_bullet ::= * LINE_LIST_BULLETED nested_chunks
           item_bullet ::= * LINE_LIST_BULLETED
 
-            LINE_LIST_BULLETED shift        5      
+            LINE_LIST_BULLETED shift        6      
             LINE_LIST_BULLETED reduce       20      ** Parsing conflict **
                    item_bullet shift-reduce 45     list_bullet ::= list_bullet item_bullet
                      {default} reduce       20     block ::= list_bullet
 
-State 35:
+State 36:
           table_header ::= header_rows * LINE_TABLE_SEPARATOR
           header_rows ::= header_rows * LINE_TABLE
     (101) row ::= header_rows *
@@ -823,7 +853,7 @@ State 35:
                     LINE_TABLE reduce       101     ** Parsing conflict **
                      {default} reduce       101    row ::= header_rows
 
-State 36:
+State 37:
           header_rows ::= header_rows * LINE_TABLE
     (101) row ::= header_rows *
 
@@ -831,21 +861,7 @@ State 36:
                     LINE_TABLE reduce       101     ** Parsing conflict **
                      {default} reduce       101    row ::= header_rows
 
-State 37:
-     (37) defs ::= def *
-          def ::= def * LINE_CONTINUATION
-
-             LINE_CONTINUATION shift-reduce 38     def ::= def LINE_CONTINUATION
-                     {default} reduce       37     defs ::= def
-
 State 38:
-     (36) defs ::= defs def *
-          def ::= def * LINE_CONTINUATION
-
-             LINE_CONTINUATION shift-reduce 38     def ::= def LINE_CONTINUATION
-                     {default} reduce       36     defs ::= defs def
-
-State 39:
      (16) block ::= empty *
           empty ::= empty * LINE_EMPTY
 
index 416e7feae3cc19bf60637d7a47bc3e785e69bdc9..ac81ac948b3d6abd0f34db49848e1f074df5216f 100644 (file)
@@ -94,23 +94,23 @@ blocks(A)                   ::= block(B).
 
 // Single line blocks
 
-block(A)                       ::= LINE_ATX_1(B).              { A = token_new_parent(B, BLOCK_H1); if (!(engine->extensions & EXT_NO_LABELS)) stack_push(engine->header_stack, A); }
-block(A)                       ::= LINE_ATX_2(B).              { A = token_new_parent(B, BLOCK_H2); if (!(engine->extensions & EXT_NO_LABELS)) stack_push(engine->header_stack, A); }
-block(A)                       ::= LINE_ATX_3(B).              { A = token_new_parent(B, BLOCK_H3); if (!(engine->extensions & EXT_NO_LABELS)) stack_push(engine->header_stack, A); }
-block(A)                       ::= LINE_ATX_4(B).              { A = token_new_parent(B, BLOCK_H4); if (!(engine->extensions & EXT_NO_LABELS)) stack_push(engine->header_stack, A); }
-block(A)                       ::= LINE_ATX_5(B).              { A = token_new_parent(B, BLOCK_H5); if (!(engine->extensions & EXT_NO_LABELS)) stack_push(engine->header_stack, A); }
-block(A)                       ::= LINE_ATX_6(B).              { A = token_new_parent(B, BLOCK_H6); if (!(engine->extensions & EXT_NO_LABELS)) stack_push(engine->header_stack, A); }
+block(A)                       ::= LINE_ATX_1(B).                      { A = token_new_parent(B, BLOCK_H1); if (!(engine->extensions & EXT_NO_LABELS)) stack_push(engine->header_stack, A); }
+block(A)                       ::= LINE_ATX_2(B).                      { A = token_new_parent(B, BLOCK_H2); if (!(engine->extensions & EXT_NO_LABELS)) stack_push(engine->header_stack, A); }
+block(A)                       ::= LINE_ATX_3(B).                      { A = token_new_parent(B, BLOCK_H3); if (!(engine->extensions & EXT_NO_LABELS)) stack_push(engine->header_stack, A); }
+block(A)                       ::= LINE_ATX_4(B).                      { A = token_new_parent(B, BLOCK_H4); if (!(engine->extensions & EXT_NO_LABELS)) stack_push(engine->header_stack, A); }
+block(A)                       ::= LINE_ATX_5(B).                      { A = token_new_parent(B, BLOCK_H5); if (!(engine->extensions & EXT_NO_LABELS)) stack_push(engine->header_stack, A); }
+block(A)                       ::= LINE_ATX_6(B).                      { A = token_new_parent(B, BLOCK_H6); if (!(engine->extensions & EXT_NO_LABELS)) stack_push(engine->header_stack, A); }
 
-block(A)                       ::= LINE_HR(B).                 { A = token_new_parent(B, BLOCK_HR); }
+block(A)                       ::= LINE_HR(B).                         { A = token_new_parent(B, BLOCK_HR); }
 
-block(A)                       ::= LINE_TOC(B).                { A = token_new_parent(B, BLOCK_TOC); }
+block(A)                       ::= LINE_TOC(B).                        { A = token_new_parent(B, BLOCK_TOC); }
 
 
 // Multi-line blocks
 
 block(A)                       ::= blockquote(B).                      { A = token_new_parent(B, BLOCK_BLOCKQUOTE); recursive_parse_blockquote(engine, A); }
 block(A)                       ::= def_citation(B).            { A = token_new_parent(B, BLOCK_DEF_CITATION); stack_push(engine->definition_stack, A); }
-block(A)                       ::= def_footnote(B).            { A = token_new_parent(B, BLOCK_DEF_FOOTNOTE); stack_push(engine->definition_stack, A); }
+block(A)                       ::= def_footnote(B).            { A = token_new_parent(B, BLOCK_DEF_FOOTNOTE); stack_push(engine->definition_stack, A); recursive_parse_indent(engine, A); }
 block(A)                       ::= def_link(B).                        { A = token_new_parent(B, BLOCK_DEF_LINK); stack_push(engine->definition_stack, A); }
 block(A)                       ::= definition_block(B).        { A = token_new_parent(B, BLOCK_DEFLIST); }
 block(A)                       ::= empty(B).                           { A = token_new_parent(B, BLOCK_EMPTY); }
@@ -170,6 +170,7 @@ opt_ext_chunk               ::= chunk.
 // Shortcut for anything that falls into the extended chunk pattern
 tail                           ::= opt_ext_chunk.
 tail                           ::= nested_chunks.
+//tail                                 ::= empty.
 
 
 // Blockquotes
@@ -197,11 +198,11 @@ def_link                  ::= LINE_DEF_LINK.
 // We have to bundle them when exporting, if desired.
 definition_block(A)    ::= para(B) defs(C).                                            { A = B; token_chain_append(B, C); B->type = BLOCK_TERM; }
 
-defs(A)                                ::= defs(B) def(C).                                                     { A = B; token_chain_append(B, token_new_parent(C, BLOCK_DEFINITION)); }
-defs(A)                                ::= def(B).                                                                     { A = token_new_parent(B, BLOCK_DEFINITION); }
+defs(A)                                ::= defs(B) def(C).                                                     { A = B; token_chain_append(B, C); }
+defs                           ::= def.                                                                        
 
-def(A)                         ::= def(B) LINE_CONTINUATION(C).                        { A = B; token_chain_append(B, C); }
-def                                    ::= LINE_DEFINITION.
+def(A)                         ::= LINE_DEFINITION(B) tail(C).                         { A = token_new_parent(B, BLOCK_DEFINITION); token_chain_append(B, C); recursive_parse_indent(engine, A); }
+def(A)                         ::= LINE_DEFINITION(B).                                         { A = token_new_parent(B, BLOCK_DEFINITION);  }
 
 
 // Empty lines
index 8fc6853a6f4e43f4c84eca22bee93b63c2d50d58..e511e2adba7d4bba5f4a12983ddb4769e99864f1 100644 (file)
@@ -988,31 +988,34 @@ bool definition_extract(mmd_engine * e, token ** remainder) {
 
 
 void process_definition_block(mmd_engine * e, token * block) {
-       token * remainder = block->child;
-       bool def_list = false;
-
-//     while (remainder) {
-               switch (remainder->type) {
-                       case PAIR_BRACKET_FOOTNOTE:
-                       case PAIR_BRACKET_CITATION:
-                       case PAIR_BRACKET_VARIABLE:
-                               if (!(e->extensions & EXT_NOTES))
-                                       return;
-                       case PAIR_BRACKET:
-                               if (definition_extract(e, &remainder))
-                                       def_list = true;
-                               break;
-                       default:
-                               // Rest of block is not definitions (or has already been processed)
-                               if (def_list) {
-                                       tokens_prune(block->child, remainder->prev);
-                                       block->child = remainder;
-                               }
-                               return;
-               }
-//     }
-       
-       // Ignore this block in the future
+       footnote * f;
+
+       token * label = block->child;
+       if (label->type == BLOCK_PARA)
+               label = label->child;
+
+       switch (block->type) {
+               case BLOCK_DEF_FOOTNOTE:
+                       f = footnote_new(e->dstr->str, label, block->child);
+                       stack_push(e->footnote_stack, f);
+                       label->type = TEXT_EMPTY;
+                       label->next->type = TEXT_EMPTY;
+                       strip_leading_whitespace(label, e->dstr->str);
+                       break;
+               case BLOCK_DEF_CITATION:
+                       f = footnote_new(e->dstr->str, label, block->child);
+                       stack_push(e->citation_stack, f);
+                       label->type = TEXT_EMPTY;
+                       label->next->type = TEXT_EMPTY;
+                       strip_leading_whitespace(label, e->dstr->str);
+                       break;
+               case BLOCK_DEF_LINK:
+                       definition_extract(e, &(block->child));
+                       break;
+               default:
+                       fprintf(stderr, "proceess %d\n", block->type);
+       }
+
        block->type = BLOCK_EMPTY;
 }
 
@@ -1411,3 +1414,23 @@ void read_table_column_alignments(const char * source, token * table, scratch_pa
        scratch->table_column_count = counter;
 }
 
+
+void strip_leading_whitespace(token * chain, const char * source) {
+       while (chain) {
+               switch (chain->type) {
+                       case INDENT_TAB:
+                       case INDENT_SPACE:
+                       case NON_INDENT_SPACE:
+                               chain->type = TEXT_EMPTY;
+                       case TEXT_EMPTY:
+                               chain = chain->next;
+                               break;
+                       case TEXT_PLAIN:
+                               token_trim_leading_whitespace(chain, source);
+                       default:
+                               return;
+               }
+
+               chain = chain->next;
+       }
+}
\ No newline at end of file
index 106f626dfc0d0815f599b10c9501a356ddbe91bc..7f2260d6cb7af3f5cd1c8098c98dc62c11da2fc3 100644 (file)
@@ -197,5 +197,7 @@ char * extract_metadata(scratch_pad * scratch, const char * target);
 
 void read_table_column_alignments(const char * source, token * table, scratch_pad * scratch);
 
+void strip_leading_whitespace(token * chain, const char * source);
+
 #endif
 
index e5512cdcb32ad6b9aef9f7accf5ec675f8cb77bb..c121b711f0fc26a7d91c3b319fb1f7b8debbeb4e 100644 (file)
@@ -114,8 +114,8 @@ def_footnote ::= LINE_DEF_FOOTNOTE tail.
 def_link ::= LINE_DEF_LINK chunk.
 definition_block ::= para defs.
 defs ::= defs def.
-defs ::= def.
-def ::= def LINE_CONTINUATION.
+def ::= LINE_DEFINITION tail.
+def ::= LINE_DEFINITION.
 empty ::= empty LINE_EMPTY.
 fenced_block ::= fenced LINE_FENCE_BACKTICK.
 fenced ::= fenced fenced_line.
@@ -157,7 +157,7 @@ quote_line ::= LINE_CONTINUATION.
 def_citation ::= LINE_DEF_CITATION.
 def_footnote ::= LINE_DEF_FOOTNOTE.
 def_link ::= LINE_DEF_LINK.
-def ::= LINE_DEFINITION.
+defs ::= def.
 empty ::= LINE_EMPTY.
 fenced_block ::= fenced.
 fenced ::= LINE_FENCE_BACKTICK.
index ad17d133b3839dc064e3b37f5ef08cac53bd4320..8f9c994f05fa0c4c8afa805c9a5103f47de139e6 100644 (file)
@@ -1,10 +1,9 @@
 <dl>
 <dt>bat</dt>
-<dd>
-<p><em>foo</em></p>
+<dd><p><em>foo</em></p>
 
 <p>bar</p>
 
-<pre><code>foo
+<pre><code>*foo*
 </code></pre></dd>
 </dl>
index 042d4512e75920ec72370616dd09babfe1db972c..a51b23c83a2dcbde47b2d986c3ed7e12a6a9aea1 100644 (file)
@@ -3,5 +3,5 @@
 
 <pre><code>bar
 
-       foo
+       *foo*
 </code></pre>
index 01191d61370cce4ef89946b90a1242cd432f9896..3f4615595a03114230a0816d2cb1fd070323feee 100644 (file)
@@ -3,4 +3,4 @@ bat
 
        bar
 
-               foo
+               *foo*