]> granicus.if.org Git - multimarkdown/commitdiff
ADDED: Add basic table support
authorFletcher T. Penney <fletcher@fletcherpenney.net>
Sun, 5 Feb 2017 01:38:10 +0000 (20:38 -0500)
committerFletcher T. Penney <fletcher@fletcherpenney.net>
Sun, 5 Feb 2017 01:38:10 +0000 (20:38 -0500)
20 files changed:
src/html.c
src/lexer.c
src/lexer.re
src/libMultiMarkdown.h
src/mmd.c
src/parser.c
src/parser.h
src/parser.out
src/parser.y
src/scanners.c
src/scanners.h
src/scanners.re
src/token.c
src/writer.c
src/writer.h
tests/MMD6Tests/Edge Cases.html
tests/MMD6Tests/Edge Cases.htmlc
tests/MMD6Tests/Tables.html [new file with mode: 0644]
tests/MMD6Tests/Tables.htmlc [new file with mode: 0644]
tests/MMD6Tests/Tables.text [new file with mode: 0644]

index e7ccbfbe4b7cc4e0c9ec4920e865e4f158df5710..932fe88926579851a0ad3da3a8c9e57910c78d88 100644 (file)
@@ -476,6 +476,58 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t
                                print("</p>");
                        scratch->padded = 0;
                        break;
+               case BLOCK_TABLE:
+                       pad(out, 2, scratch);
+                       print("<table>\n");
+                       scratch->padded = 2;
+                       read_table_column_alignments(source, t, scratch);
+
+                       print("<colgroup>\n");
+                       for (int i = 0; i < scratch->table_column_count; ++i)
+                       {
+                               switch (scratch->table_alignment[i]) {
+                                       case 'l':
+                                       case 'L':
+                                               print("<col style=\"text-align:left;\"/>\n");
+                                               break;
+                                       case 'r':
+                                       case 'R':
+                                               print("<col style=\"text-align:right;\"/>\n");
+                                               break;
+                                       case 'c':
+                                       case 'C':
+                                               print("<col style=\"text-align:center;\"/>\n");
+                                               break;
+                                       default:
+                                               print("<col />\n");
+                                               break;
+                               }
+                       }
+                       print("</colgroup>\n");
+                       scratch->padded = 1;
+
+                       mmd_export_token_tree_html(out, source, t->child, offset, scratch);
+                       pad(out, 1, scratch);
+                       print("</table>");
+                       scratch->padded = 0;
+                       break;
+               case BLOCK_TABLE_HEADER:
+                       pad(out, 2, scratch);
+                       print("<thead>\n");
+                       scratch->in_table_header = 1;
+                       mmd_export_token_tree_html(out, source, t->child, offset, scratch);
+                       scratch->in_table_header = 0;
+                       print("</thead>\n");
+                       scratch->padded = 1;
+                       break;
+               case BLOCK_TABLE_SECTION:
+                       pad(out, 2, scratch);
+                       print("<tbody>\n");
+                       scratch->padded = 2;
+                       mmd_export_token_tree_html(out, source, t->child, offset, scratch);
+                       print("</tbody>");
+                       scratch->padded = 0;
+                       break;
                case BLOCK_TERM:
                        pad(out, 2, scratch);
                        print("<dt>");
@@ -1023,6 +1075,45 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t
                                print("^");
                        }       
                        break;
+               case TABLE_CELL:
+                       if (scratch->in_table_header) {
+                               print("\t<th");
+                       } else {
+                               print("\t<td");
+                       }
+                       switch (scratch->table_alignment[scratch->table_cell_count]) {
+                               case 'l':
+                                       print(" style=\"text-align:left;\"");
+                                       break;
+                               case 'r':
+                                       print(" style=\"text-align:right;\"");
+                                       break;
+                               case 'c':
+                                       print(" style=\"text-align:center;\"");
+                                       break;
+                       }
+                       if (t->next->type == TABLE_DIVIDER) {
+                               if (t->next->len > 1) {
+                                       printf(" colspan=\"%d\"", t->next->len);
+                               }
+                       }
+                       print(">");
+                       mmd_export_token_tree_html(out, source, t->child, offset, scratch);
+                       if (scratch->in_table_header) {
+                               print("</th>\n");
+                       } else {
+                               print("</td>\n");
+                       }
+                       scratch->table_cell_count += t->next->len;
+                       break;
+               case TABLE_DIVIDER:
+                       break;
+               case TABLE_ROW:
+                       print("<tr>\n");
+                       scratch->table_cell_count = 0;
+                       mmd_export_token_tree_html(out, source, t->child, offset, scratch);
+                       print("</tr>\n");
+                       break;
                case TEXT_LINEBREAK:
                        if (t->next) {
                                print("<br />\n");
index f67cd240bde946837285dea953d3cba4d174fa51..c34dd7124868df5d4560981b69d3b343c3746752 100644 (file)
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.14.3 on Sat Jan 28 22:49:30 2017 */
+/* Generated by re2c 0.14.3 on Sat Feb  4 13:15:42 2017 */
 /**
 
        MultiMarkdown 6 -- Lightweight markup processor to produce HTML, LaTeX, and more.
@@ -130,12 +130,12 @@ yy2:
        yyaccept = 0;
        yych = *(YYMARKER = ++YYCURSOR);
        switch (yych) {
-       case '+':       goto yy248;
-       case '-':       goto yy247;
-       case '=':       goto yy244;
-       case '>':       goto yy246;
-       case '{':       goto yy242;
-       case '~':       goto yy245;
+       case '+':       goto yy251;
+       case '-':       goto yy250;
+       case '=':       goto yy247;
+       case '>':       goto yy249;
+       case '{':       goto yy245;
+       case '~':       goto yy248;
        default:        goto yy3;
        }
 yy3:
@@ -144,7 +144,7 @@ yy4:
        yyaccept = 1;
        yych = *(YYMARKER = ++YYCURSOR);
        switch (yych) {
-       case '+':       goto yy239;
+       case '+':       goto yy242;
        default:        goto yy5;
        }
 yy5:
@@ -152,7 +152,7 @@ yy5:
 yy6:
        ++YYCURSOR;
        switch ((yych = *YYCURSOR)) {
-       case '-':       goto yy233;
+       case '-':       goto yy236;
        default:        goto yy7;
        }
 yy7:
@@ -161,7 +161,7 @@ yy8:
        yyaccept = 2;
        yych = *(YYMARKER = ++YYCURSOR);
        switch (yych) {
-       case '<':       goto yy230;
+       case '<':       goto yy233;
        default:        goto yy9;
        }
 yy9:
@@ -170,8 +170,8 @@ yy10:
        yyaccept = 3;
        yych = *(YYMARKER = ++YYCURSOR);
        switch (yych) {
-       case '>':       goto yy226;
-       case '~':       goto yy225;
+       case '>':       goto yy229;
+       case '~':       goto yy228;
        default:        goto yy11;
        }
 yy11:
@@ -180,15 +180,15 @@ yy12:
        yyaccept = 0;
        yych = *(YYMARKER = ++YYCURSOR);
        switch (yych) {
-       case '=':       goto yy222;
+       case '=':       goto yy225;
        default:        goto yy3;
        }
 yy13:
        ++YYCURSOR;
        switch ((yych = *YYCURSOR)) {
-       case '#':       goto yy218;
-       case '%':       goto yy216;
-       case '^':       goto yy220;
+       case '#':       goto yy221;
+       case '%':       goto yy219;
+       case '^':       goto yy223;
        default:        goto yy14;
        }
 yy14:
@@ -199,7 +199,7 @@ yy15:
 yy17:
        yych = *++YYCURSOR;
        switch (yych) {
-       case '[':       goto yy214;
+       case '[':       goto yy217;
        default:        goto yy3;
        }
 yy18:
@@ -214,7 +214,7 @@ yy22:
 yy24:
        yych = *++YYCURSOR;
        switch (yych) {
-       case '}':       goto yy212;
+       case '}':       goto yy215;
        default:        goto yy3;
        }
 yy25:
@@ -223,7 +223,7 @@ yy25:
 yy27:
        ++YYCURSOR;
        switch ((yych = *YYCURSOR)) {
-       case '\'':      goto yy210;
+       case '\'':      goto yy213;
        default:        goto yy28;
        }
 yy28:
@@ -233,11 +233,11 @@ yy29:
        yyaccept = 0;
        yych = *(YYMARKER = ++YYCURSOR);
        switch (yych) {
-       case '\t':      goto yy200;
-       case '\n':      goto yy197;
-       case '\r':      goto yy199;
-       case ' ':       goto yy202;
-       case '.':       goto yy203;
+       case '\t':      goto yy203;
+       case '\n':      goto yy200;
+       case '\r':      goto yy202;
+       case ' ':       goto yy205;
+       case '.':       goto yy206;
        default:        goto yy3;
        }
 yy30:
@@ -248,7 +248,7 @@ yy32:
        yych = *(YYMARKER = ++YYCURSOR);
        switch (yych) {
        case 'A':
-       case 'a':       goto yy192;
+       case 'a':       goto yy195;
        default:        goto yy33;
        }
 yy33:
@@ -256,44 +256,44 @@ yy33:
 yy34:
        yych = *++YYCURSOR;
        switch (yych) {
-       case '!':       goto yy180;
-       case '"':       goto yy170;
-       case '#':       goto yy150;
-       case '$':       goto yy148;
-       case '%':       goto yy146;
-       case '&':       goto yy134;
-       case '\'':      goto yy168;
-       case '(':       goto yy162;
-       case ')':       goto yy160;
-       case '*':       goto yy126;
-       case '+':       goto yy144;
-       case ',':       goto yy176;
-       case '-':       goto yy142;
-       case '.':       goto yy182;
-       case '/':       goto yy130;
-       case ':':       goto yy172;
-       case ';':       goto yy174;
-       case '<':       goto yy138;
-       case '=':       goto yy140;
-       case '>':       goto yy136;
-       case '?':       goto yy178;
-       case '@':       goto yy132;
-       case '[':       goto yy154;
-       case '\\':      goto yy120;
-       case ']':       goto yy152;
-       case '^':       goto yy128;
-       case '_':       goto yy124;
-       case '`':       goto yy166;
-       case '{':       goto yy158;
-       case '|':       goto yy122;
-       case '}':       goto yy156;
-       case '~':       goto yy164;
+       case '!':       goto yy183;
+       case '"':       goto yy173;
+       case '#':       goto yy153;
+       case '$':       goto yy151;
+       case '%':       goto yy149;
+       case '&':       goto yy137;
+       case '\'':      goto yy171;
+       case '(':       goto yy165;
+       case ')':       goto yy163;
+       case '*':       goto yy129;
+       case '+':       goto yy147;
+       case ',':       goto yy179;
+       case '-':       goto yy145;
+       case '.':       goto yy185;
+       case '/':       goto yy133;
+       case ':':       goto yy175;
+       case ';':       goto yy177;
+       case '<':       goto yy141;
+       case '=':       goto yy143;
+       case '>':       goto yy139;
+       case '?':       goto yy181;
+       case '@':       goto yy135;
+       case '[':       goto yy157;
+       case '\\':      goto yy123;
+       case ']':       goto yy155;
+       case '^':       goto yy131;
+       case '_':       goto yy127;
+       case '`':       goto yy169;
+       case '{':       goto yy161;
+       case '|':       goto yy125;
+       case '}':       goto yy159;
+       case '~':       goto yy167;
        default:        goto yy3;
        }
 yy35:
        ++YYCURSOR;
        switch ((yych = *YYCURSOR)) {
-       case '$':       goto yy118;
+       case '$':       goto yy121;
        default:        goto yy36;
        }
 yy36:
@@ -307,6 +307,8 @@ yy39:
 yy41:
        yych = *++YYCURSOR;
        switch (yych) {
+       case '\n':      goto yy44;
+       case '\r':      goto yy112;
        case ' ':       goto yy110;
        default:        goto yy3;
        }
@@ -404,8 +406,9 @@ yy61:
        case 2:         goto yy9;
        case 3:         goto yy11;
        case 4:         goto yy33;
-       case 5:         goto yy198;
-       default:        goto yy243;
+       case 5:         goto yy118;
+       case 6:         goto yy201;
+       default:        goto yy246;
        }
 yy62:
        YYCTXMARKER = YYCURSOR + 1;
@@ -645,9 +648,9 @@ yy109:
 yy110:
        ++YYCURSOR;
        switch ((yych = *YYCURSOR)) {
-       case '\n':      goto yy113;
-       case '\r':      goto yy115;
-       case ' ':       goto yy112;
+       case '\n':      goto yy114;
+       case '\r':      goto yy116;
+       case ' ':       goto yy113;
        default:        goto yy111;
        }
 yy111:
@@ -655,366 +658,391 @@ yy111:
 yy112:
        yych = *++YYCURSOR;
        switch (yych) {
-       case ' ':       goto yy116;
-       default:        goto yy111;
+       case '\n':      goto yy44;
+       default:        goto yy45;
        }
 yy113:
-       ++YYCURSOR;
+       yych = *++YYCURSOR;
+       switch (yych) {
+       case '\n':      goto yy114;
+       case '\r':      goto yy116;
+       case ' ':       goto yy117;
+       default:        goto yy111;
+       }
 yy114:
-       { return TEXT_LINEBREAK; }
+       ++YYCURSOR;
 yy115:
+       { return TEXT_LINEBREAK; }
+yy116:
        yych = *++YYCURSOR;
        switch (yych) {
-       case '\n':      goto yy113;
-       default:        goto yy114;
+       case '\n':      goto yy114;
+       default:        goto yy115;
+       }
+yy117:
+       yyaccept = 5;
+       yych = *(YYMARKER = ++YYCURSOR);
+       switch (yych) {
+       case '\n':      goto yy114;
+       case '\r':      goto yy116;
+       case ' ':       goto yy119;
+       default:        goto yy118;
        }
-yy116:
-       ++YYCURSOR;
-       { return INDENT_SPACE; }
 yy118:
+       { return INDENT_SPACE; }
+yy119:
+       ++YYCURSOR;
+       yych = *YYCURSOR;
+       switch (yych) {
+       case '\n':      goto yy114;
+       case '\r':      goto yy116;
+       case ' ':       goto yy119;
+       default:        goto yy61;
+       }
+yy121:
        ++YYCURSOR;
        { return MATH_DOLLAR_DOUBLE; }
-yy120:
+yy123:
        ++YYCURSOR;
        switch ((yych = *YYCURSOR)) {
-       case '(':       goto yy184;
-       case ')':       goto yy186;
-       case '[':       goto yy188;
-       case ']':       goto yy190;
-       default:        goto yy121;
+       case '(':       goto yy187;
+       case ')':       goto yy189;
+       case '[':       goto yy191;
+       case ']':       goto yy193;
+       default:        goto yy124;
        }
-yy121:
+yy124:
        { return ESCAPED_CHARACTER; }
-yy122:
+yy125:
        ++YYCURSOR;
        { return ESCAPED_CHARACTER; }
-yy124:
+yy127:
        ++YYCURSOR;
        { return ESCAPED_CHARACTER; }
-yy126:
+yy129:
        ++YYCURSOR;
        { return ESCAPED_CHARACTER; }
-yy128:
+yy131:
        ++YYCURSOR;
        { return ESCAPED_CHARACTER; }
-yy130:
+yy133:
        ++YYCURSOR;
        { return ESCAPED_CHARACTER; }
-yy132:
+yy135:
        ++YYCURSOR;
        { return ESCAPED_CHARACTER; }
-yy134:
+yy137:
        ++YYCURSOR;
        { return ESCAPED_CHARACTER; }
-yy136:
+yy139:
        ++YYCURSOR;
        { return ESCAPED_CHARACTER; }
-yy138:
+yy141:
        ++YYCURSOR;
        { return ESCAPED_CHARACTER; }
-yy140:
+yy143:
        ++YYCURSOR;
        { return ESCAPED_CHARACTER; }
-yy142:
+yy145:
        ++YYCURSOR;
        { return ESCAPED_CHARACTER; }
-yy144:
+yy147:
        ++YYCURSOR;
        { return ESCAPED_CHARACTER; }
-yy146:
+yy149:
        ++YYCURSOR;
        { return ESCAPED_CHARACTER; }
-yy148:
+yy151:
        ++YYCURSOR;
        { return ESCAPED_CHARACTER; }
-yy150:
+yy153:
        ++YYCURSOR;
        { return ESCAPED_CHARACTER; }
-yy152:
+yy155:
        ++YYCURSOR;
        { return ESCAPED_CHARACTER; }
-yy154:
+yy157:
        ++YYCURSOR;
        { return ESCAPED_CHARACTER; }
-yy156:
+yy159:
        ++YYCURSOR;
        { return ESCAPED_CHARACTER; }
-yy158:
+yy161:
        ++YYCURSOR;
        { return ESCAPED_CHARACTER; }
-yy160:
+yy163:
        ++YYCURSOR;
        { return ESCAPED_CHARACTER; }
-yy162:
+yy165:
        ++YYCURSOR;
        { return ESCAPED_CHARACTER; }
-yy164:
+yy167:
        ++YYCURSOR;
        { return ESCAPED_CHARACTER; }
-yy166:
+yy169:
        ++YYCURSOR;
        { return ESCAPED_CHARACTER; }
-yy168:
+yy171:
        ++YYCURSOR;
        { return ESCAPED_CHARACTER; }
-yy170:
+yy173:
        ++YYCURSOR;
        { return ESCAPED_CHARACTER; }
-yy172:
+yy175:
        ++YYCURSOR;
        { return ESCAPED_CHARACTER; }
-yy174:
+yy177:
        ++YYCURSOR;
        { return ESCAPED_CHARACTER; }
-yy176:
+yy179:
        ++YYCURSOR;
        { return ESCAPED_CHARACTER; }
-yy178:
+yy181:
        ++YYCURSOR;
        { return ESCAPED_CHARACTER; }
-yy180:
+yy183:
        ++YYCURSOR;
        { return ESCAPED_CHARACTER; }
-yy182:
+yy185:
        ++YYCURSOR;
        { return ESCAPED_CHARACTER; }
-yy184:
+yy187:
        ++YYCURSOR;
        { return MATH_PAREN_OPEN; }
-yy186:
+yy189:
        ++YYCURSOR;
        { return MATH_PAREN_CLOSE; }
-yy188:
+yy191:
        ++YYCURSOR;
        { return MATH_BRACKET_OPEN; }
-yy190:
+yy193:
        ++YYCURSOR;
        { return MATH_BRACKET_CLOSE; }
-yy192:
+yy195:
        yych = *++YYCURSOR;
        switch (yych) {
        case 'M':
-       case 'm':       goto yy193;
+       case 'm':       goto yy196;
        default:        goto yy61;
        }
-yy193:
+yy196:
        yych = *++YYCURSOR;
        switch (yych) {
        case 'P':
-       case 'p':       goto yy194;
+       case 'p':       goto yy197;
        default:        goto yy61;
        }
-yy194:
+yy197:
        yych = *++YYCURSOR;
        switch (yych) {
-       case ';':       goto yy195;
+       case ';':       goto yy198;
        default:        goto yy61;
        }
-yy195:
+yy198:
        ++YYCURSOR;
        { return AMPERSAND_LONG; }
-yy197:
+yy200:
        ++YYCURSOR;
-yy198:
+yy201:
        YYCURSOR = YYCTXMARKER;
        { return TEXT_PERIOD; }
-yy199:
+yy202:
        yych = *++YYCURSOR;
        switch (yych) {
-       case '\n':      goto yy197;
-       default:        goto yy198;
+       case '\n':      goto yy200;
+       default:        goto yy201;
        }
-yy200:
+yy203:
        ++YYCURSOR;
        yych = *YYCURSOR;
-yy201:
+yy204:
        switch (yych) {
        case '\t':
-       case ' ':       goto yy200;
-       default:        goto yy198;
+       case ' ':       goto yy203;
+       default:        goto yy201;
        }
-yy202:
-       yyaccept = 5;
+yy205:
+       yyaccept = 6;
        yych = *(YYMARKER = ++YYCURSOR);
        switch (yych) {
-       case '.':       goto yy206;
-       default:        goto yy201;
+       case '.':       goto yy209;
+       default:        goto yy204;
        }
-yy203:
+yy206:
        yych = *++YYCURSOR;
        switch (yych) {
-       case '.':       goto yy204;
+       case '.':       goto yy207;
        default:        goto yy61;
        }
-yy204:
+yy207:
        ++YYCURSOR;
        { return ELLIPSIS; }
-yy206:
+yy209:
        yych = *++YYCURSOR;
        switch (yych) {
-       case ' ':       goto yy207;
+       case ' ':       goto yy210;
        default:        goto yy61;
        }
-yy207:
+yy210:
        yych = *++YYCURSOR;
        switch (yych) {
-       case '.':       goto yy208;
+       case '.':       goto yy211;
        default:        goto yy61;
        }
-yy208:
+yy211:
        ++YYCURSOR;
        { return ELLIPSIS; }
-yy210:
+yy213:
        ++YYCURSOR;
        { return QUOTE_RIGHT_ALT; }
-yy212:
+yy215:
        ++YYCURSOR;
        { return BRACE_DOUBLE_RIGHT; }
-yy214:
+yy217:
        ++YYCURSOR;
        { return BRACKET_IMAGE_LEFT; }
-yy216:
+yy219:
        ++YYCURSOR;
        { return BRACKET_VARIABLE_LEFT; }
-yy218:
+yy221:
        ++YYCURSOR;
        { return BRACKET_CITATION_LEFT; }
-yy220:
+yy223:
        ++YYCURSOR;
        { return BRACKET_FOOTNOTE_LEFT; }
-yy222:
+yy225:
        yych = *++YYCURSOR;
        switch (yych) {
-       case '}':       goto yy223;
+       case '}':       goto yy226;
        default:        goto yy61;
        }
-yy223:
+yy226:
        ++YYCURSOR;
        { return CRITIC_HI_CLOSE; }
-yy225:
+yy228:
        yych = *++YYCURSOR;
        switch (yych) {
-       case '}':       goto yy228;
+       case '}':       goto yy231;
        default:        goto yy61;
        }
-yy226:
+yy229:
        ++YYCURSOR;
        { return CRITIC_SUB_DIV; }
-yy228:
+yy231:
        ++YYCURSOR;
        { return CRITIC_SUB_CLOSE; }
-yy230:
+yy233:
        yych = *++YYCURSOR;
        switch (yych) {
-       case '}':       goto yy231;
+       case '}':       goto yy234;
        default:        goto yy61;
        }
-yy231:
+yy234:
        ++YYCURSOR;
        { return CRITIC_COM_CLOSE; }
-yy233:
+yy236:
        ++YYCURSOR;
        switch ((yych = *YYCURSOR)) {
-       case '-':       goto yy237;
-       case '}':       goto yy235;
-       default:        goto yy234;
+       case '-':       goto yy240;
+       case '}':       goto yy238;
+       default:        goto yy237;
        }
-yy234:
+yy237:
        { return DASH_N; }
-yy235:
+yy238:
        ++YYCURSOR;
        { return CRITIC_DEL_CLOSE; }
-yy237:
+yy240:
        ++YYCURSOR;
        { return DASH_M; }
-yy239:
+yy242:
        yych = *++YYCURSOR;
        switch (yych) {
-       case '}':       goto yy240;
+       case '}':       goto yy243;
        default:        goto yy61;
        }
-yy240:
+yy243:
        ++YYCURSOR;
        { return CRITIC_ADD_CLOSE; }
-yy242:
-       yyaccept = 6;
+yy245:
+       yyaccept = 7;
        yych = *(YYMARKER = ++YYCURSOR);
        switch (yych) {
-       case 'T':       goto yy259;
-       default:        goto yy243;
+       case 'T':       goto yy262;
+       default:        goto yy246;
        }
-yy243:
+yy246:
        { return BRACE_DOUBLE_LEFT; }
-yy244:
+yy247:
        yych = *++YYCURSOR;
        switch (yych) {
-       case '=':       goto yy257;
+       case '=':       goto yy260;
        default:        goto yy61;
        }
-yy245:
+yy248:
        yych = *++YYCURSOR;
        switch (yych) {
-       case '~':       goto yy255;
+       case '~':       goto yy258;
        default:        goto yy61;
        }
-yy246:
+yy249:
        yych = *++YYCURSOR;
        switch (yych) {
-       case '>':       goto yy253;
+       case '>':       goto yy256;
        default:        goto yy61;
        }
-yy247:
+yy250:
        yych = *++YYCURSOR;
        switch (yych) {
-       case '-':       goto yy251;
+       case '-':       goto yy254;
        default:        goto yy61;
        }
-yy248:
+yy251:
        yych = *++YYCURSOR;
        switch (yych) {
-       case '+':       goto yy249;
+       case '+':       goto yy252;
        default:        goto yy61;
        }
-yy249:
+yy252:
        ++YYCURSOR;
        { return CRITIC_ADD_OPEN; }
-yy251:
+yy254:
        ++YYCURSOR;
        { return CRITIC_DEL_OPEN; }
-yy253:
+yy256:
        ++YYCURSOR;
        { return CRITIC_COM_OPEN; }
-yy255:
+yy258:
        ++YYCURSOR;
        { return CRITIC_SUB_OPEN; }
-yy257:
+yy260:
        ++YYCURSOR;
        { return CRITIC_HI_OPEN; }
-yy259:
+yy262:
        yych = *++YYCURSOR;
        switch (yych) {
-       case 'O':       goto yy260;
+       case 'O':       goto yy263;
        default:        goto yy61;
        }
-yy260:
+yy263:
        yych = *++YYCURSOR;
        switch (yych) {
-       case 'C':       goto yy261;
+       case 'C':       goto yy264;
        default:        goto yy61;
        }
-yy261:
+yy264:
        yych = *++YYCURSOR;
        switch (yych) {
-       case '}':       goto yy262;
+       case '}':       goto yy265;
        default:        goto yy61;
        }
-yy262:
+yy265:
        yych = *++YYCURSOR;
        switch (yych) {
-       case '}':       goto yy263;
+       case '}':       goto yy266;
        default:        goto yy61;
        }
-yy263:
+yy266:
        ++YYCURSOR;
        { return TOC; }
 }
index 16da856c091c0c8ccecf10edc3b52c2389001b35..6f41c5eb13e353962bd412206991a705172ccdb5 100644 (file)
@@ -88,7 +88,7 @@ int scan(Scanner * s, const char * stop) {
                INDENT_SPACE                                    = ' '{4};
                NON_INDENT_SPACE                                = ' '{2,3};
 
-               TEXT_LINEBREAK                                  = "  " NL;
+               TEXT_LINEBREAK                                  = ' '{2,} NL;
 
                // The order of these seems to matter
 
@@ -211,7 +211,7 @@ int scan(Scanner * s, const char * stop) {
                '.' / (SP|NL)                                   { return TEXT_PERIOD; }
 
                TEXT_LINEBREAK                                  { return TEXT_LINEBREAK; }
-               NL                                                              { return TEXT_NL; }
+               ' '? NL                                                 { return TEXT_NL; }
 
                NON_INDENT_SPACE                                { return NON_INDENT_SPACE; }
 
index 571f76c59f48764abbbd22d5575f54928457dd41..43f2c2a713142764a4a35063d0760d5936937030 100644 (file)
@@ -137,9 +137,10 @@ enum token_types {
        BLOCK_META,
        BLOCK_PARA,
        BLOCK_TABLE,
+       BLOCK_TABLE_HEADER,
+       BLOCK_TABLE_SECTION,
        BLOCK_TERM,
        BLOCK_TOC,
-       ROW_TABLE,
 
        CRITIC_ADD_OPEN,
        CRITIC_ADD_CLOSE,
@@ -255,6 +256,10 @@ enum token_types {
        MARKER_LIST_BULLET,
        MARKER_LIST_ENUMERATOR,
 
+       TABLE_ROW,
+       TABLE_CELL,
+       TABLE_DIVIDER,
+
        TOC,
        
        TEXT_EMPTY,
index 5d0b628659ca0edf93b167925335604b98560c4b..b499db2367f629835f62657e27bd73f71fee0788 100644 (file)
--- a/src/mmd.c
+++ b/src/mmd.c
@@ -544,6 +544,14 @@ void mmd_assign_line_type(mmd_engine * e, token * line) {
                                line->type = LINE_PLAIN;
                        }
                        break;
+               case PIPE:
+                       // If PIPE is first, save checking later and assign LINE_TABLE now
+                       if (!(e->extensions & EXT_COMPATIBILITY)) {
+                               scan_len = scan_table_separator(&source[line->start]);
+                               line->type = (scan_len) ? LINE_TABLE_SEPARATOR : LINE_TABLE;
+
+                               break;
+                       }
                case TEXT_PLAIN:
                        if (e->allow_meta && !(e->extensions & EXT_COMPATIBILITY)) {
                                scan_len = scan_url(&source[line->start]);
@@ -558,12 +566,15 @@ void mmd_assign_line_type(mmd_engine * e, token * line) {
                        break;
        }
 
-       if (line->type == LINE_PLAIN) {
+       if ((line->type == LINE_PLAIN) &&
+               !(e->extensions & EXT_COMPATIBILITY)) {
+               // Check if this is a potential table line
                token * walker = line->child;
 
                while (walker != NULL) {
                        if (walker->type == PIPE) {
-                               line->type = LINE_TABLE;
+                               scan_len = scan_table_separator(&source[line->start]);
+                               line->type = (scan_len) ? LINE_TABLE_SEPARATOR : LINE_TABLE;
 
                                return;
                        }
@@ -769,7 +780,9 @@ void mmd_parse_token_chain(mmd_engine * e, token * chain) {
        token * walker = chain->child;                          // Walk the existing tree
        token * remainder;                                                      // Hold unparsed tail of chain
 
-//     ParseTrace(stderr, "parser >>");
+#ifndef NDEBUG
+       ParseTrace(stderr, "parser >>");
+#endif
 
        // Remove existing token tree
        e->root = NULL;
@@ -784,7 +797,9 @@ void mmd_parse_token_chain(mmd_engine * e, token * chain) {
                if (remainder)
                        remainder->prev = NULL;
 
-//             fprintf(stderr, "\nNew line\n");
+#ifndef NDEBUG
+               fprintf(stderr, "\nNew line\n");
+#endif
 
                Parse(pParser, walker->type, walker, e);
 
@@ -792,6 +807,9 @@ void mmd_parse_token_chain(mmd_engine * e, token * chain) {
        }
 
        // Signal finish to parser
+#ifndef NDEBUG
+       fprintf(stderr, "\nFinish parse\n");
+#endif
        Parse(pParser, 0, NULL, e);
 
        // Disconnect of (now empty) root
@@ -1307,7 +1325,9 @@ void is_list_loose(token * list) {
 
 /// Is this actually an HTML block?
 void is_para_html(mmd_engine * e, token * block) {
-       if (block->child->type != LINE_PLAIN)
+       if ((block == NULL) ||
+               (block->child == NULL) ||
+               (block->child->type != LINE_PLAIN))
                return;
        token * t = block->child->child;
 
@@ -1431,6 +1451,78 @@ void strip_line_tokens_from_deflist(mmd_engine * e, token * deflist) {
 }
 
 
+void strip_line_tokens_from_table(mmd_engine * e, token * table) {
+       token * walker = table->child;
+
+       while (walker) {
+               switch (walker->type) {
+                       case BLOCK_TABLE_SECTION:
+                               strip_line_tokens_from_block(e, walker);
+                               break;
+                       case BLOCK_TABLE_HEADER:
+                               strip_line_tokens_from_block(e, walker);
+                               break;
+                       case LINE_EMPTY:
+                               walker->type = TEXT_EMPTY;
+                               break;
+               }
+
+               walker = walker->next;
+       }
+}
+
+
+void parse_table_row_into_cells(token * row) {
+       token * first = NULL;
+       token * last = NULL;
+
+       token * walker = row->child;
+
+       if (walker->type == PIPE) {
+               walker->type = TABLE_DIVIDER;
+               first = walker->next;
+       } else {
+               first = walker;
+               last = first;
+       }
+
+
+       walker = walker->next;
+
+       while (walker) {
+               switch (walker->type) {
+                       case PIPE:
+                               if (row->child == first) {
+                                       row->child = token_prune_graft(first, last, TABLE_CELL);
+                               } else {
+                                       token_prune_graft(first, last, TABLE_CELL);
+                               }
+                               first = NULL;
+                               last = NULL;
+                               walker->type = TABLE_DIVIDER;
+                               break;
+                       case TEXT_NL:
+                       case TEXT_LINEBREAK:
+                               break;
+                       default:
+                               if (!first)
+                                       first = walker;
+                               last = walker;
+               }
+
+               walker = walker->next;
+       }
+
+       if (first) {
+               if (row->child == first) {
+                       row->child = token_prune_graft(first, last, TABLE_CELL);
+               } else {
+                       token_prune_graft(first, last, TABLE_CELL);
+               }
+       }
+}
+
+
 void strip_line_tokens_from_block(mmd_engine * e, token * block) {
        if ((block == NULL) || (block->child == NULL))
                return;
@@ -1455,6 +1547,9 @@ void strip_line_tokens_from_block(mmd_engine * e, token * block) {
                case BLOCK_DEFLIST:
                        // Handle definition lists
                        return strip_line_tokens_from_deflist(e, block);
+               case BLOCK_TABLE:
+                       // Handle tables
+                       return strip_line_tokens_from_table(e, block);
        }
 
        token * children = NULL;
@@ -1486,6 +1581,7 @@ void strip_line_tokens_from_block(mmd_engine * e, token * block) {
                        case LINE_LIST_ENUMERATED:
                        case LINE_META:
                        case LINE_PLAIN:
+                               handle_line:
                                // Remove leading non-indent space from line
                                if (l->child && l->child->type == NON_INDENT_SPACE)
                                token_remove_first_child(l);
@@ -1515,10 +1611,17 @@ void strip_line_tokens_from_block(mmd_engine * e, token * block) {
                                // Advance to next line
                                l = l->next;
                                break;
+                       case LINE_TABLE_SEPARATOR:
                        case LINE_TABLE:
-                               l->type = ROW_TABLE;
-                               break;
+                               if ((block->type == BLOCK_TABLE_SECTION) ||
+                                       (block->type == BLOCK_TABLE_HEADER)) {
+                                       l->type = (l->type == LINE_TABLE) ? TABLE_ROW : LINE_TABLE_SEPARATOR;
+                                       parse_table_row_into_cells(l);
+                               } else {
+                                       goto handle_line;
+                               }
                        default:
+                               handle_block:
                                //fprintf(stderr, "Unspecified line type %d inside block type %d\n", l->type, block->type);
                                // This is a block, need to remove it from chain and
                                // Add to parent
index da0aaaeb9cfcc69a395d73fbc40f1e993a926d02..9f0bfa1377026294b0a40c5e84106995370fc395 100644 (file)
@@ -92,7 +92,7 @@
 #endif
 /************* Begin control #defines *****************************************/
 #define YYCODETYPE unsigned char
-#define YYNOCODE 65
+#define YYNOCODE 69
 #define YYACTIONTYPE unsigned short int
 #define ParseTOKENTYPE  token * 
 typedef union {
@@ -107,16 +107,16 @@ typedef union {
 #define ParseARG_FETCH  mmd_engine * engine  = yypParser->engine 
 #define ParseARG_STORE yypParser->engine  = engine 
 #define YYFALLBACK 1
-#define YYNSTATE             47
-#define YYNRULE              103
-#define YY_MAX_SHIFT         46
-#define YY_MIN_SHIFTREDUCE   107
-#define YY_MAX_SHIFTREDUCE   209
-#define YY_MIN_REDUCE        210
-#define YY_MAX_REDUCE        312
-#define YY_ERROR_ACTION      313
-#define YY_ACCEPT_ACTION     314
-#define YY_NO_ACTION         315
+#define YYNSTATE             54
+#define YYNRULE              111
+#define YY_MAX_SHIFT         53
+#define YY_MIN_SHIFTREDUCE   117
+#define YY_MAX_SHIFTREDUCE   227
+#define YY_MIN_REDUCE        228
+#define YY_MAX_REDUCE        338
+#define YY_ERROR_ACTION      339
+#define YY_ACCEPT_ACTION     340
+#define YY_NO_ACTION         341
 /************* End control #defines *******************************************/
 
 /* Define the yytestcase() macro to be a no-op if is not already defined
@@ -188,79 +188,85 @@ typedef union {
 **  yy_default[]       Default action for each state.
 **
 *********** Begin parsing tables **********************************************/
-#define YY_ACTTAB_COUNT (191)
+#define YY_ACTTAB_COUNT (211)
 static const YYACTIONTYPE yy_action[] = {
- /*     0 */   210,  183,   23,  181,  182,   14,  112,  113,  114,  115,
- /*    10 */   116,  117,  123,   15,    5,    4,  192,    3,    2,   17,
- /*    20 */    13,   12,  130,  183,   11,   23,  181,  182,   14,  112,
- /*    30 */   113,  114,  115,  116,  117,  123,   15,    5,    4,  192,
- /*    40 */     3,    2,   17,   13,   12,  130,  183,   11,  314,    1,
- /*    50 */   109,   29,   10,   45,   41,   39,  121,   44,  124,  125,
- /*    60 */   126,  127,  128,  129,   38,  134,  134,  177,   10,   33,
- /*    70 */    33,   41,   42,   39,   30,   30,   31,   31,   34,   34,
- /*    80 */    28,   38,  108,   29,   10,   45,   41,   39,  121,   44,
- /*    90 */   124,  125,  126,  127,  128,  129,   38,   32,  177,  165,
- /*   100 */    10,  181,  182,   41,  198,   39,  160,  187,  199,    6,
- /*   110 */     6,   23,  201,   38,   32,  167,   18,   32,   18,  186,
- /*   120 */   183,  180,  201,  137,   32,  133,    7,    7,   32,    8,
- /*   130 */     8,  163,  135,   20,  202,   20,   24,  133,   24,  206,
- /*   140 */     9,    9,   32,   19,  202,   19,   32,   26,   22,   26,
- /*   150 */     4,   32,  143,  181,  182,  133,   16,  201,    5,  133,
- /*   160 */    32,   21,  205,   21,  133,   25,  138,   25,   35,   35,
- /*   170 */    27,  209,   27,  135,   36,   36,  161,  171,  168,  202,
- /*   180 */    46,  148,  151,   43,   43,   37,   37,   40,   40,  174,
- /*   190 */   135,
+ /*     0 */   228,   26,   41,   41,  199,  200,   17,  122,  123,  124,
+ /*    10 */   125,  126,  127,  133,   18,    5,    4,  210,    3,    2,
+ /*    20 */    19,   16,   15,  140,  201,   14,   26,  144,  144,  199,
+ /*    30 */   200,   17,  122,  123,  124,  125,  126,  127,  133,   18,
+ /*    40 */     5,    4,  210,    3,    2,   19,   16,   15,  140,  201,
+ /*    50 */    14,  340,    1,  119,   32,   13,   52,   46,   44,  131,
+ /*    60 */   132,  134,  135,  136,  137,  138,  139,   43,   36,   36,
+ /*    70 */   195,   13,   33,   33,   46,  201,   44,   25,   24,  210,
+ /*    80 */    11,   34,   34,   47,   37,   37,   31,   43,  118,   32,
+ /*    90 */    13,   52,   46,   44,  131,  132,  134,  135,  136,  137,
+ /*   100 */   138,  139,   43,   12,  216,   35,   13,  217,   35,   46,
+ /*   110 */   183,   44,   35,   24,   26,   11,  180,    6,    6,  182,
+ /*   120 */     7,    7,   43,   35,   20,  143,   20,   22,   35,   22,
+ /*   130 */   210,   21,   35,   21,  147,    8,    8,  145,  143,   35,
+ /*   140 */     9,    9,   27,   35,   27,  143,  175,   29,  224,   29,
+ /*   150 */    50,   23,  143,   23,  163,  195,  143,  195,   28,  219,
+ /*   160 */    28,  219,   30,  195,   30,  199,  200,  199,  200,  166,
+ /*   170 */   223,  166,  219,   38,   38,  205,  190,  178,  190,  176,
+ /*   180 */   220,   35,  220,   10,  201,  198,  204,  145,   39,   39,
+ /*   190 */    51,   49,    4,  220,   48,   48,    5,  153,   42,   42,
+ /*   200 */    45,   45,  158,  227,   53,  186,  166,   40,  148,  145,
+ /*   210 */   189,
 };
 static const YYCODETYPE yy_lookahead[] = {
- /*     0 */     0,   23,    2,    3,    4,    5,    6,    7,    8,    9,
+ /*     0 */     0,    1,   45,   46,    4,    5,    6,    7,    8,    9,
  /*    10 */    10,   11,   12,   13,   14,   15,   16,   17,   18,   19,
- /*    20 */    20,   21,   22,   23,   24,    2,    3,    4,    5,    6,
- /*    30 */     7,    8,    9,   10,   11,   12,   13,   14,   15,   16,
- /*    40 */    17,   18,   19,   20,   21,   22,   23,   24,   27,   28,
- /*    50 */    29,   30,   31,   32,   33,   34,   35,   36,   37,   38,
- /*    60 */    39,   40,   41,   42,   43,   46,   47,    1,   47,   58,
- /*    70 */    59,   50,   25,   52,   56,   57,   56,   57,   54,   55,
- /*    80 */    47,   60,   29,   30,   31,   32,   33,   34,   35,   36,
- /*    90 */    37,   38,   39,   40,   41,   42,   43,   32,    1,   57,
- /*   100 */    47,    3,    4,   50,    1,   52,   55,    1,    5,   44,
- /*   110 */    45,    2,    1,   60,   32,   59,   51,   32,   53,   13,
- /*   120 */    23,   23,    1,   49,   32,   45,   44,   45,   32,   44,
- /*   130 */    45,   20,   23,   51,   23,   53,   51,   45,   53,    1,
- /*   140 */    44,   45,   32,   51,   23,   53,   32,   51,   30,   53,
- /*   150 */    15,   32,   52,    3,    4,   45,   32,    1,   14,   45,
- /*   160 */    32,   51,   24,   53,   45,   51,   50,   53,   48,   49,
- /*   170 */    51,    1,   53,   23,   44,   45,   20,   62,   60,   23,
- /*   180 */    63,   53,   16,   61,   62,   44,   45,   44,   45,    1,
- /*   190 */    23,
+ /*    20 */    20,   21,   22,   23,   24,   25,    1,   47,   48,    4,
+ /*    30 */     5,    6,    7,    8,    9,   10,   11,   12,   13,   14,
+ /*    40 */    15,   16,   17,   18,   19,   20,   21,   22,   23,   24,
+ /*    50 */    25,   28,   29,   30,   31,   32,   33,   34,   35,   36,
+ /*    60 */    37,   38,   39,   40,   41,   42,   43,   44,   62,   63,
+ /*    70 */     3,   48,   60,   61,   51,   24,   53,   31,   55,   17,
+ /*    80 */    57,   60,   61,   26,   58,   59,   48,   64,   30,   31,
+ /*    90 */    32,   33,   34,   35,   36,   37,   38,   39,   40,   41,
+ /*   100 */    42,   43,   44,   57,    3,   33,   48,    6,   33,   51,
+ /*   110 */    64,   53,   33,   55,    1,   57,   61,   45,   46,   63,
+ /*   120 */    45,   46,   64,   33,   52,   46,   54,   52,   33,   54,
+ /*   130 */    17,   52,   33,   54,   50,   45,   46,   24,   46,   33,
+ /*   140 */    45,   46,   52,   33,   54,   46,   59,   52,    3,   54,
+ /*   150 */    57,   52,   46,   54,    2,    3,   46,    3,   52,    3,
+ /*   160 */    54,    3,   52,    3,   54,    4,    5,    4,    5,   17,
+ /*   170 */    25,   17,    3,   49,   50,    3,   24,   21,   24,   21,
+ /*   180 */    24,   33,   24,   33,   24,   24,   14,   24,   45,   46,
+ /*   190 */    56,   57,   16,   24,   65,   66,   15,   53,   45,   46,
+ /*   200 */    45,   46,   54,    3,   67,   66,   17,   24,   51,   24,
+ /*   210 */     3,
 };
-#define YY_SHIFT_USE_DFLT (191)
-#define YY_SHIFT_COUNT    (46)
-#define YY_SHIFT_MIN      (-22)
-#define YY_SHIFT_MAX      (188)
-static const short yy_shift_ofst[] = {
- /*     0 */    23,    0,   97,   97,   97,   97,   97,   97,   97,   97,
- /*    10 */    98,  138,  121,  121,  103,  106,  109,   66,  -22,  -22,
- /*    20 */   -22,  -22,   47,   66,  -22,  -22,  -22,  -22,   66,   47,
- /*    30 */   111,  156,  150,  138,  103,  106,   66,   66,  -22,  135,
- /*    40 */    66,  144,  170,   47,  166,  167,  188,
+#define YY_SHIFT_USE_DFLT (211)
+#define YY_SHIFT_COUNT    (53)
+#define YY_SHIFT_MIN      (0)
+#define YY_SHIFT_MAX      (207)
+static const unsigned char yy_shift_ofst[] = {
+ /*     0 */    25,    0,  160,  160,  160,  160,  160,  160,  160,  160,
+ /*    10 */   113,  152,  154,  161,  145,  169,  169,  101,  172,   67,
+ /*    20 */    51,   51,   51,   51,   62,   57,   67,   51,   51,   51,
+ /*    30 */    51,   67,   57,  156,  158,  163,  145,  101,  172,   67,
+ /*    40 */    62,   67,   67,   51,  176,   67,  181,  200,   57,  189,
+ /*    50 */   189,  183,  185,  207,
 };
-#define YY_REDUCE_USE_DFLT (-1)
-#define YY_REDUCE_COUNT (43)
-#define YY_REDUCE_MIN   (0)
-#define YY_REDUCE_MAX   (143)
+#define YY_REDUCE_USE_DFLT (-44)
+#define YY_REDUCE_COUNT (48)
+#define YY_REDUCE_MIN   (-43)
+#define YY_REDUCE_MAX   (157)
 static const short yy_reduce_ofst[] = {
- /*     0 */    21,   53,   65,   82,   85,   96,   92,  110,  114,  119,
- /*    10 */    19,   11,   18,   20,   24,  120,  118,  130,  128,  128,
- /*    20 */   128,  128,  122,  141,  128,  128,  128,  128,  143,  122,
- /*    30 */    42,   42,   33,   56,   51,   74,   80,   80,  124,  100,
- /*    40 */    80,  116,  117,  115,
+ /*     0 */    23,   58,   72,   75,   90,   95,   79,   99,  106,  110,
+ /*    10 */    46,  -43,  -43,  -20,    6,   12,   21,   26,  124,  143,
+ /*    20 */   148,  148,  148,  148,  134,  129,  153,  148,  148,  148,
+ /*    30 */   148,  155,  129,   55,   55,   38,   56,   87,   84,   92,
+ /*    40 */    93,   92,   92,  150,  144,   92,  157,  137,  139,
 };
 static const YYACTIONTYPE yy_default[] = {
- /*     0 */   313,  313,  297,  296,  250,  245,  259,  256,  248,  243,
- /*    10 */   214,  306,  313,  313,  299,  287,  272,  298,  260,  258,
- /*    20 */   257,  255,  313,  278,  249,  247,  244,  242,  253,  213,
- /*    30 */   267,  265,  294,  269,  262,  239,  261,  235,  234,  223,
- /*    40 */   252,  222,  276,  273,  225,  221,  275,
+ /*     0 */   339,  339,  323,  322,  268,  263,  282,  279,  266,  261,
+ /*    10 */   295,  303,  303,  232,  332,  339,  339,  325,  313,  324,
+ /*    20 */   283,  281,  280,  278,  339,  339,  304,  267,  265,  262,
+ /*    30 */   260,  271,  231,  290,  288,  320,  292,  285,  257,  284,
+ /*    40 */   272,  302,  253,  252,  241,  270,  240,  299,  296,  276,
+ /*    50 */   275,  273,  239,  298,
 };
 /********** End of lemon-generated parsing tables *****************************/
 
@@ -281,27 +287,28 @@ static const YYACTIONTYPE yy_default[] = {
 #ifdef YYFALLBACK
 static const YYCODETYPE yyFallback[] = {
     0,  /*          $ => nothing */
+    3,  /* LINE_PLAIN => LINE_CONTINUATION */
+    1,  /* LINE_TABLE_SEPARATOR => LINE_PLAIN */
     0,  /* LINE_CONTINUATION => nothing */
-    1,  /* LINE_PLAIN => LINE_CONTINUATION */
-    1,  /* LINE_INDENTED_TAB => LINE_CONTINUATION */
-    1,  /* LINE_INDENTED_SPACE => LINE_CONTINUATION */
+    3,  /* LINE_INDENTED_TAB => LINE_CONTINUATION */
+    3,  /* LINE_INDENTED_SPACE => LINE_CONTINUATION */
     0,  /*  LINE_HTML => nothing */
-    5,  /* LINE_ATX_1 => LINE_HTML */
-    5,  /* LINE_ATX_2 => LINE_HTML */
-    5,  /* LINE_ATX_3 => LINE_HTML */
-    5,  /* LINE_ATX_4 => LINE_HTML */
-    5,  /* LINE_ATX_5 => LINE_HTML */
-    5,  /* LINE_ATX_6 => LINE_HTML */
-    5,  /*    LINE_HR => LINE_HTML */
-    5,  /* LINE_BLOCKQUOTE => LINE_HTML */
-    5,  /* LINE_LIST_BULLETED => LINE_HTML */
-    5,  /* LINE_LIST_ENUMERATED => LINE_HTML */
-    5,  /* LINE_TABLE => LINE_HTML */
-    5,  /* LINE_DEF_CITATION => LINE_HTML */
-    5,  /* LINE_DEF_FOOTNOTE => LINE_HTML */
-    5,  /* LINE_DEF_LINK => LINE_HTML */
-    5,  /* LINE_FENCE_BACKTICK => LINE_HTML */
-    5,  /* LINE_FENCE_BACKTICK_START => LINE_HTML */
+    6,  /* LINE_ATX_1 => LINE_HTML */
+    6,  /* LINE_ATX_2 => LINE_HTML */
+    6,  /* LINE_ATX_3 => LINE_HTML */
+    6,  /* LINE_ATX_4 => LINE_HTML */
+    6,  /* LINE_ATX_5 => LINE_HTML */
+    6,  /* LINE_ATX_6 => LINE_HTML */
+    6,  /*    LINE_HR => LINE_HTML */
+    6,  /* LINE_BLOCKQUOTE => LINE_HTML */
+    6,  /* LINE_LIST_BULLETED => LINE_HTML */
+    6,  /* LINE_LIST_ENUMERATED => LINE_HTML */
+    6,  /* LINE_TABLE => LINE_HTML */
+    6,  /* LINE_DEF_CITATION => LINE_HTML */
+    6,  /* LINE_DEF_FOOTNOTE => LINE_HTML */
+    6,  /* LINE_DEF_LINK => LINE_HTML */
+    6,  /* LINE_FENCE_BACKTICK => LINE_HTML */
+    6,  /* LINE_FENCE_BACKTICK_START => LINE_HTML */
 };
 #endif /* YYFALLBACK */
 
@@ -387,20 +394,21 @@ void ParseTrace(FILE *TraceFILE, char *zTracePrompt){
 /* For tracing shifts, the names of all terminals and nonterminals
 ** are required.  The following table supplies these names */
 static const char *const yyTokenName[] = { 
-  "$",             "LINE_CONTINUATION",  "LINE_PLAIN",    "LINE_INDENTED_TAB",
-  "LINE_INDENTED_SPACE",  "LINE_HTML",     "LINE_ATX_1",    "LINE_ATX_2",  
-  "LINE_ATX_3",    "LINE_ATX_4",    "LINE_ATX_5",    "LINE_ATX_6",  
-  "LINE_HR",       "LINE_BLOCKQUOTE",  "LINE_LIST_BULLETED",  "LINE_LIST_ENUMERATED",
-  "LINE_TABLE",    "LINE_DEF_CITATION",  "LINE_DEF_FOOTNOTE",  "LINE_DEF_LINK",
-  "LINE_FENCE_BACKTICK",  "LINE_FENCE_BACKTICK_START",  "LINE_TOC",      "LINE_EMPTY",  
-  "LINE_META",     "LINE_DEFINITION",  "error",         "doc",         
-  "blocks",        "block",         "para",          "indented_code",
-  "empty",         "list_bulleted",  "list_enumerated",  "blockquote",  
-  "table",         "def_citation",  "def_footnote",  "def_link",    
-  "html_block",    "fenced_block",  "meta_block",    "definition_block",
-  "para_lines",    "para_line",     "code_line",     "indented_line",
-  "quote_lines",   "quote_line",    "item_bulleted",  "cont_blocks", 
-  "item_enumerated",  "cont_block",    "html_block_lines",  "html_block_line",
+  "$",             "LINE_PLAIN",    "LINE_TABLE_SEPARATOR",  "LINE_CONTINUATION",
+  "LINE_INDENTED_TAB",  "LINE_INDENTED_SPACE",  "LINE_HTML",     "LINE_ATX_1",  
+  "LINE_ATX_2",    "LINE_ATX_3",    "LINE_ATX_4",    "LINE_ATX_5",  
+  "LINE_ATX_6",    "LINE_HR",       "LINE_BLOCKQUOTE",  "LINE_LIST_BULLETED",
+  "LINE_LIST_ENUMERATED",  "LINE_TABLE",    "LINE_DEF_CITATION",  "LINE_DEF_FOOTNOTE",
+  "LINE_DEF_LINK",  "LINE_FENCE_BACKTICK",  "LINE_FENCE_BACKTICK_START",  "LINE_TOC",    
+  "LINE_EMPTY",    "LINE_META",     "LINE_DEFINITION",  "error",       
+  "doc",           "blocks",        "block",         "para",        
+  "indented_code",  "empty",         "list_bulleted",  "list_enumerated",
+  "blockquote",    "table",         "def_citation",  "def_footnote",
+  "def_link",      "html_block",    "fenced_block",  "meta_block",  
+  "definition_block",  "para_lines",    "para_line",     "code_line",   
+  "indented_line",  "quote_lines",   "quote_line",    "item_bulleted",
+  "cont_blocks",   "item_enumerated",  "cont_block",    "table_header",
+  "table_body",    "table_section",  "html_block_lines",  "html_block_line",
   "fenced_lines",  "fenced_line",   "meta_lines",    "meta_line",   
   "definition",    "defs",          "def",           "def_lines",   
 };
@@ -454,65 +462,73 @@ static const char *const yyRuleName[] = {
  /*  41 */ "cont_blocks ::= cont_blocks cont_block",
  /*  42 */ "cont_block ::= empty indented_line para_lines",
  /*  43 */ "cont_block ::= empty indented_line",
- /*  44 */ "table ::= table LINE_TABLE",
- /*  45 */ "def_citation ::= LINE_DEF_CITATION para_lines cont_blocks",
- /*  46 */ "def_citation ::= LINE_DEF_CITATION para_lines",
- /*  47 */ "def_citation ::= LINE_DEF_CITATION cont_blocks",
- /*  48 */ "def_footnote ::= LINE_DEF_FOOTNOTE para_lines cont_blocks",
- /*  49 */ "def_footnote ::= LINE_DEF_FOOTNOTE para_lines",
- /*  50 */ "def_footnote ::= LINE_DEF_FOOTNOTE cont_blocks",
- /*  51 */ "def_link ::= LINE_DEF_LINK para_lines",
- /*  52 */ "html_block ::= LINE_HTML html_block_lines",
- /*  53 */ "html_block_lines ::= html_block_lines html_block_line",
- /*  54 */ "fenced_block ::= LINE_FENCE_BACKTICK fenced_lines LINE_FENCE_BACKTICK",
- /*  55 */ "fenced_block ::= LINE_FENCE_BACKTICK fenced_lines",
- /*  56 */ "fenced_block ::= LINE_FENCE_BACKTICK_START fenced_lines LINE_FENCE_BACKTICK",
- /*  57 */ "fenced_block ::= LINE_FENCE_BACKTICK_START fenced_lines",
- /*  58 */ "fenced_lines ::= fenced_lines fenced_line",
- /*  59 */ "meta_block ::= LINE_META meta_lines",
- /*  60 */ "meta_lines ::= meta_lines meta_line",
- /*  61 */ "definition_block ::= definition_block empty definition",
- /*  62 */ "definition_block ::= definition_block empty",
- /*  63 */ "definition ::= para defs",
- /*  64 */ "defs ::= defs def",
- /*  65 */ "def ::= LINE_DEFINITION def_lines",
- /*  66 */ "def ::= LINE_DEFINITION",
- /*  67 */ "def_lines ::= def_lines LINE_CONTINUATION",
- /*  68 */ "para ::= LINE_PLAIN",
- /*  69 */ "para_lines ::= para_line",
- /*  70 */ "para_line ::= LINE_CONTINUATION",
- /*  71 */ "indented_code ::= indented_line",
- /*  72 */ "code_line ::= indented_line",
- /*  73 */ "code_line ::= LINE_EMPTY",
- /*  74 */ "indented_line ::= LINE_INDENTED_TAB",
- /*  75 */ "indented_line ::= LINE_INDENTED_SPACE",
- /*  76 */ "empty ::= LINE_EMPTY",
- /*  77 */ "blockquote ::= LINE_BLOCKQUOTE",
- /*  78 */ "quote_lines ::= quote_line",
- /*  79 */ "quote_line ::= LINE_BLOCKQUOTE",
- /*  80 */ "quote_line ::= LINE_CONTINUATION",
- /*  81 */ "list_bulleted ::= item_bulleted",
- /*  82 */ "list_enumerated ::= item_enumerated",
- /*  83 */ "cont_blocks ::= cont_block",
- /*  84 */ "cont_block ::= empty",
- /*  85 */ "table ::= LINE_TABLE",
- /*  86 */ "def_citation ::= LINE_DEF_CITATION",
- /*  87 */ "def_footnote ::= LINE_DEF_FOOTNOTE",
- /*  88 */ "def_link ::= LINE_DEF_LINK",
- /*  89 */ "html_block ::= LINE_HTML",
- /*  90 */ "html_block_lines ::= html_block_line",
- /*  91 */ "html_block_line ::= LINE_CONTINUATION",
- /*  92 */ "html_block_line ::= LINE_HTML",
- /*  93 */ "fenced_lines ::= fenced_line",
- /*  94 */ "fenced_line ::= LINE_CONTINUATION",
- /*  95 */ "fenced_line ::= LINE_EMPTY",
- /*  96 */ "meta_block ::= LINE_META",
- /*  97 */ "meta_lines ::= meta_line",
- /*  98 */ "meta_line ::= LINE_META",
- /*  99 */ "meta_line ::= LINE_CONTINUATION",
- /* 100 */ "definition_block ::= definition",
- /* 101 */ "defs ::= def",
- /* 102 */ "def_lines ::= LINE_CONTINUATION",
+ /*  44 */ "table ::= table_header table_body LINE_EMPTY",
+ /*  45 */ "table ::= table_header table_body",
+ /*  46 */ "table_header ::= table_section LINE_TABLE_SEPARATOR",
+ /*  47 */ "table_body ::= table_body LINE_EMPTY table_section",
+ /*  48 */ "table_body ::= table_section",
+ /*  49 */ "table_section ::= table_section LINE_TABLE",
+ /*  50 */ "def_citation ::= LINE_DEF_CITATION para_lines cont_blocks",
+ /*  51 */ "def_citation ::= LINE_DEF_CITATION para_lines",
+ /*  52 */ "def_citation ::= LINE_DEF_CITATION cont_blocks",
+ /*  53 */ "def_footnote ::= LINE_DEF_FOOTNOTE para_lines cont_blocks",
+ /*  54 */ "def_footnote ::= LINE_DEF_FOOTNOTE para_lines",
+ /*  55 */ "def_footnote ::= LINE_DEF_FOOTNOTE cont_blocks",
+ /*  56 */ "def_link ::= LINE_DEF_LINK para_lines",
+ /*  57 */ "html_block ::= LINE_HTML html_block_lines",
+ /*  58 */ "html_block_lines ::= html_block_lines html_block_line",
+ /*  59 */ "fenced_block ::= LINE_FENCE_BACKTICK fenced_lines LINE_FENCE_BACKTICK",
+ /*  60 */ "fenced_block ::= LINE_FENCE_BACKTICK fenced_lines",
+ /*  61 */ "fenced_block ::= LINE_FENCE_BACKTICK_START fenced_lines LINE_FENCE_BACKTICK",
+ /*  62 */ "fenced_block ::= LINE_FENCE_BACKTICK_START fenced_lines",
+ /*  63 */ "fenced_lines ::= fenced_lines fenced_line",
+ /*  64 */ "meta_block ::= LINE_META meta_lines",
+ /*  65 */ "meta_lines ::= meta_lines meta_line",
+ /*  66 */ "definition_block ::= definition_block empty definition",
+ /*  67 */ "definition_block ::= definition_block empty",
+ /*  68 */ "definition ::= para defs",
+ /*  69 */ "defs ::= defs def",
+ /*  70 */ "def ::= LINE_DEFINITION def_lines",
+ /*  71 */ "def ::= LINE_DEFINITION",
+ /*  72 */ "def_lines ::= def_lines LINE_CONTINUATION",
+ /*  73 */ "para ::= table_section LINE_EMPTY",
+ /*  74 */ "para ::= table_section para_lines",
+ /*  75 */ "para ::= table_section",
+ /*  76 */ "para ::= LINE_PLAIN",
+ /*  77 */ "para_lines ::= para_line",
+ /*  78 */ "para_line ::= LINE_CONTINUATION",
+ /*  79 */ "indented_code ::= indented_line",
+ /*  80 */ "code_line ::= indented_line",
+ /*  81 */ "code_line ::= LINE_EMPTY",
+ /*  82 */ "indented_line ::= LINE_INDENTED_TAB",
+ /*  83 */ "indented_line ::= LINE_INDENTED_SPACE",
+ /*  84 */ "empty ::= LINE_EMPTY",
+ /*  85 */ "blockquote ::= LINE_BLOCKQUOTE",
+ /*  86 */ "quote_lines ::= quote_line",
+ /*  87 */ "quote_line ::= LINE_BLOCKQUOTE",
+ /*  88 */ "quote_line ::= LINE_CONTINUATION",
+ /*  89 */ "list_bulleted ::= item_bulleted",
+ /*  90 */ "list_enumerated ::= item_enumerated",
+ /*  91 */ "cont_blocks ::= cont_block",
+ /*  92 */ "cont_block ::= empty",
+ /*  93 */ "table_section ::= LINE_TABLE",
+ /*  94 */ "def_citation ::= LINE_DEF_CITATION",
+ /*  95 */ "def_footnote ::= LINE_DEF_FOOTNOTE",
+ /*  96 */ "def_link ::= LINE_DEF_LINK",
+ /*  97 */ "html_block ::= LINE_HTML",
+ /*  98 */ "html_block_lines ::= html_block_line",
+ /*  99 */ "html_block_line ::= LINE_CONTINUATION",
+ /* 100 */ "html_block_line ::= LINE_HTML",
+ /* 101 */ "fenced_lines ::= fenced_line",
+ /* 102 */ "fenced_line ::= LINE_CONTINUATION",
+ /* 103 */ "fenced_line ::= LINE_EMPTY",
+ /* 104 */ "meta_block ::= LINE_META",
+ /* 105 */ "meta_lines ::= meta_line",
+ /* 106 */ "meta_line ::= LINE_META",
+ /* 107 */ "meta_line ::= LINE_CONTINUATION",
+ /* 108 */ "definition_block ::= definition",
+ /* 109 */ "defs ::= def",
+ /* 110 */ "def_lines ::= LINE_CONTINUATION",
 };
 #endif /* NDEBUG */
 
@@ -861,109 +877,117 @@ static const struct {
   YYCODETYPE lhs;         /* Symbol on the left-hand side of the rule */
   unsigned char nrhs;     /* Number of right-hand side symbols in the rule */
 } yyRuleInfo[] = {
-  { 27, 1 },
-  { 28, 2 },
   { 28, 1 },
+  { 29, 2 },
   { 29, 1 },
-  { 29, 1 },
-  { 29, 1 },
-  { 29, 1 },
-  { 29, 1 },
-  { 29, 1 },
-  { 29, 1 },
-  { 29, 1 },
-  { 29, 1 },
-  { 29, 1 },
-  { 29, 1 },
-  { 29, 1 },
-  { 29, 1 },
-  { 29, 1 },
-  { 29, 1 },
-  { 29, 1 },
-  { 29, 1 },
-  { 29, 1 },
-  { 29, 1 },
-  { 29, 1 },
-  { 29, 1 },
-  { 29, 1 },
-  { 30, 2 },
-  { 44, 2 },
+  { 30, 1 },
+  { 30, 1 },
+  { 30, 1 },
+  { 30, 1 },
+  { 30, 1 },
+  { 30, 1 },
+  { 30, 1 },
+  { 30, 1 },
+  { 30, 1 },
+  { 30, 1 },
+  { 30, 1 },
+  { 30, 1 },
+  { 30, 1 },
+  { 30, 1 },
+  { 30, 1 },
+  { 30, 1 },
+  { 30, 1 },
+  { 30, 1 },
+  { 30, 1 },
+  { 30, 1 },
+  { 30, 1 },
+  { 30, 1 },
   { 31, 2 },
+  { 45, 2 },
   { 32, 2 },
-  { 35, 2 },
-  { 48, 2 },
   { 33, 2 },
-  { 50, 3 },
-  { 50, 2 },
-  { 50, 2 },
-  { 50, 1 },
+  { 36, 2 },
+  { 49, 2 },
   { 34, 2 },
-  { 52, 3 },
-  { 52, 2 },
-  { 52, 2 },
-  { 52, 1 },
+  { 51, 3 },
   { 51, 2 },
+  { 51, 2 },
+  { 51, 1 },
+  { 35, 2 },
   { 53, 3 },
   { 53, 2 },
-  { 36, 2 },
+  { 53, 2 },
+  { 53, 1 },
+  { 52, 2 },
+  { 54, 3 },
+  { 54, 2 },
   { 37, 3 },
   { 37, 2 },
-  { 37, 2 },
+  { 55, 2 },
+  { 56, 3 },
+  { 56, 1 },
+  { 57, 2 },
   { 38, 3 },
   { 38, 2 },
   { 38, 2 },
+  { 39, 3 },
+  { 39, 2 },
   { 39, 2 },
   { 40, 2 },
-  { 54, 2 },
-  { 41, 3 },
-  { 41, 2 },
-  { 41, 3 },
   { 41, 2 },
-  { 56, 2 },
-  { 42, 2 },
   { 58, 2 },
-  { 43, 3 },
-  { 43, 2 },
+  { 42, 3 },
+  { 42, 2 },
+  { 42, 3 },
+  { 42, 2 },
   { 60, 2 },
-  { 61, 2 },
+  { 43, 2 },
   { 62, 2 },
-  { 62, 1 },
-  { 63, 2 },
-  { 30, 1 },
-  { 44, 1 },
-  { 45, 1 },
+  { 44, 3 },
+  { 44, 2 },
+  { 64, 2 },
+  { 65, 2 },
+  { 66, 2 },
+  { 66, 1 },
+  { 67, 2 },
+  { 31, 2 },
+  { 31, 2 },
   { 31, 1 },
+  { 31, 1 },
+  { 45, 1 },
   { 46, 1 },
-  { 46, 1 },
+  { 32, 1 },
   { 47, 1 },
   { 47, 1 },
-  { 32, 1 },
-  { 35, 1 },
   { 48, 1 },
-  { 49, 1 },
-  { 49, 1 },
+  { 48, 1 },
   { 33, 1 },
-  { 34, 1 },
-  { 51, 1 },
-  { 53, 1 },
   { 36, 1 },
-  { 37, 1 },
+  { 49, 1 },
+  { 50, 1 },
+  { 50, 1 },
+  { 34, 1 },
+  { 35, 1 },
+  { 52, 1 },
+  { 54, 1 },
+  { 57, 1 },
   { 38, 1 },
   { 39, 1 },
   { 40, 1 },
-  { 54, 1 },
-  { 55, 1 },
-  { 55, 1 },
-  { 56, 1 },
-  { 57, 1 },
-  { 57, 1 },
-  { 42, 1 },
+  { 41, 1 },
   { 58, 1 },
   { 59, 1 },
   { 59, 1 },
-  { 43, 1 },
+  { 60, 1 },
+  { 61, 1 },
   { 61, 1 },
+  { 43, 1 },
+  { 62, 1 },
   { 63, 1 },
+  { 63, 1 },
+  { 44, 1 },
+  { 65, 1 },
+  { 67, 1 },
 };
 
 static void yy_accept(yyParser*);  /* Forward Declaration */
@@ -1149,22 +1173,25 @@ static void yy_reduce(
       case 31: /* list_bulleted ::= list_bulleted item_bulleted */ yytestcase(yyruleno==31);
       case 36: /* list_enumerated ::= list_enumerated item_enumerated */ yytestcase(yyruleno==36);
       case 41: /* cont_blocks ::= cont_blocks cont_block */ yytestcase(yyruleno==41);
-      case 44: /* table ::= table LINE_TABLE */ yytestcase(yyruleno==44);
-      case 46: /* def_citation ::= LINE_DEF_CITATION para_lines */ yytestcase(yyruleno==46);
-      case 47: /* def_citation ::= LINE_DEF_CITATION cont_blocks */ yytestcase(yyruleno==47);
-      case 49: /* def_footnote ::= LINE_DEF_FOOTNOTE para_lines */ yytestcase(yyruleno==49);
-      case 50: /* def_footnote ::= LINE_DEF_FOOTNOTE cont_blocks */ yytestcase(yyruleno==50);
-      case 51: /* def_link ::= LINE_DEF_LINK para_lines */ yytestcase(yyruleno==51);
-      case 52: /* html_block ::= LINE_HTML html_block_lines */ yytestcase(yyruleno==52);
-      case 53: /* html_block_lines ::= html_block_lines html_block_line */ yytestcase(yyruleno==53);
-      case 55: /* fenced_block ::= LINE_FENCE_BACKTICK fenced_lines */ yytestcase(yyruleno==55);
-      case 57: /* fenced_block ::= LINE_FENCE_BACKTICK_START fenced_lines */ yytestcase(yyruleno==57);
-      case 58: /* fenced_lines ::= fenced_lines fenced_line */ yytestcase(yyruleno==58);
-      case 59: /* meta_block ::= LINE_META meta_lines */ yytestcase(yyruleno==59);
-      case 60: /* meta_lines ::= meta_lines meta_line */ yytestcase(yyruleno==60);
-      case 62: /* definition_block ::= definition_block empty */ yytestcase(yyruleno==62);
-      case 64: /* defs ::= defs def */ yytestcase(yyruleno==64);
-      case 67: /* def_lines ::= def_lines LINE_CONTINUATION */ yytestcase(yyruleno==67);
+      case 45: /* table ::= table_header table_body */ yytestcase(yyruleno==45);
+      case 49: /* table_section ::= table_section LINE_TABLE */ yytestcase(yyruleno==49);
+      case 51: /* def_citation ::= LINE_DEF_CITATION para_lines */ yytestcase(yyruleno==51);
+      case 52: /* def_citation ::= LINE_DEF_CITATION cont_blocks */ yytestcase(yyruleno==52);
+      case 54: /* def_footnote ::= LINE_DEF_FOOTNOTE para_lines */ yytestcase(yyruleno==54);
+      case 55: /* def_footnote ::= LINE_DEF_FOOTNOTE cont_blocks */ yytestcase(yyruleno==55);
+      case 56: /* def_link ::= LINE_DEF_LINK para_lines */ yytestcase(yyruleno==56);
+      case 57: /* html_block ::= LINE_HTML html_block_lines */ yytestcase(yyruleno==57);
+      case 58: /* html_block_lines ::= html_block_lines html_block_line */ yytestcase(yyruleno==58);
+      case 60: /* fenced_block ::= LINE_FENCE_BACKTICK fenced_lines */ yytestcase(yyruleno==60);
+      case 62: /* fenced_block ::= LINE_FENCE_BACKTICK_START fenced_lines */ yytestcase(yyruleno==62);
+      case 63: /* fenced_lines ::= fenced_lines fenced_line */ yytestcase(yyruleno==63);
+      case 64: /* meta_block ::= LINE_META meta_lines */ yytestcase(yyruleno==64);
+      case 65: /* meta_lines ::= meta_lines meta_line */ yytestcase(yyruleno==65);
+      case 67: /* definition_block ::= definition_block empty */ yytestcase(yyruleno==67);
+      case 69: /* defs ::= defs def */ yytestcase(yyruleno==69);
+      case 72: /* def_lines ::= def_lines LINE_CONTINUATION */ yytestcase(yyruleno==72);
+      case 73: /* para ::= table_section LINE_EMPTY */ yytestcase(yyruleno==73);
+      case 74: /* para ::= table_section para_lines */ yytestcase(yyruleno==74);
 { yylhsminor.yy0 = yymsp[-1].minor.yy0; token_chain_append(yymsp[-1].minor.yy0, yymsp[0].minor.yy0); }
   yymsp[-1].minor.yy0 = yylhsminor.yy0;
         break;
@@ -1199,65 +1226,82 @@ static void yy_reduce(
 { yylhsminor.yy0 = yymsp[-1].minor.yy0; token_chain_append(yymsp[-1].minor.yy0, yymsp[0].minor.yy0); yymsp[0].minor.yy0->type = LINE_CONTINUATION; }
   yymsp[-1].minor.yy0 = yylhsminor.yy0;
         break;
-      case 45: /* def_citation ::= LINE_DEF_CITATION para_lines cont_blocks */
-      case 48: /* def_footnote ::= LINE_DEF_FOOTNOTE para_lines cont_blocks */ yytestcase(yyruleno==48);
-      case 61: /* definition_block ::= definition_block empty definition */ yytestcase(yyruleno==61);
+      case 44: /* table ::= table_header table_body LINE_EMPTY */
+      case 50: /* def_citation ::= LINE_DEF_CITATION para_lines cont_blocks */ yytestcase(yyruleno==50);
+      case 53: /* def_footnote ::= LINE_DEF_FOOTNOTE para_lines cont_blocks */ yytestcase(yyruleno==53);
+      case 66: /* definition_block ::= definition_block empty definition */ yytestcase(yyruleno==66);
 { yylhsminor.yy0 = yymsp[-2].minor.yy0; token_chain_append(yymsp[-2].minor.yy0, yymsp[-1].minor.yy0); token_chain_append(yymsp[-2].minor.yy0, yymsp[0].minor.yy0); }
   yymsp[-2].minor.yy0 = yylhsminor.yy0;
         break;
-      case 54: /* fenced_block ::= LINE_FENCE_BACKTICK fenced_lines LINE_FENCE_BACKTICK */
-      case 56: /* fenced_block ::= LINE_FENCE_BACKTICK_START fenced_lines LINE_FENCE_BACKTICK */ yytestcase(yyruleno==56);
+      case 46: /* table_header ::= table_section LINE_TABLE_SEPARATOR */
+{ yylhsminor.yy0 = token_new_parent(yymsp[-1].minor.yy0, BLOCK_TABLE_HEADER); token_chain_append(yymsp[-1].minor.yy0, yymsp[0].minor.yy0); }
+  yymsp[-1].minor.yy0 = yylhsminor.yy0;
+        break;
+      case 47: /* table_body ::= table_body LINE_EMPTY table_section */
+{ yylhsminor.yy0 = yymsp[-2].minor.yy0; token_chain_append(yymsp[-2].minor.yy0, yymsp[-1].minor.yy0); token_chain_append(yymsp[-2].minor.yy0, token_new_parent(yymsp[0].minor.yy0, BLOCK_TABLE_SECTION)); }
+  yymsp[-2].minor.yy0 = yylhsminor.yy0;
+        break;
+      case 48: /* table_body ::= table_section */
+{ yylhsminor.yy0 = token_new_parent(yymsp[0].minor.yy0, BLOCK_TABLE_SECTION); }
+  yymsp[0].minor.yy0 = yylhsminor.yy0;
+        break;
+      case 59: /* fenced_block ::= LINE_FENCE_BACKTICK fenced_lines LINE_FENCE_BACKTICK */
+      case 61: /* fenced_block ::= LINE_FENCE_BACKTICK_START fenced_lines LINE_FENCE_BACKTICK */ yytestcase(yyruleno==61);
 { yylhsminor.yy0 = yymsp[-2].minor.yy0; token_chain_append(yymsp[-2].minor.yy0, yymsp[-1].minor.yy0); token_chain_append(yymsp[-2].minor.yy0, yymsp[0].minor.yy0); yymsp[0].minor.yy0->child->type = CODE_FENCE; }
   yymsp[-2].minor.yy0 = yylhsminor.yy0;
         break;
-      case 63: /* definition ::= para defs */
+      case 68: /* definition ::= para defs */
 { yylhsminor.yy0 = token_new_parent(yymsp[-1].minor.yy0, BLOCK_DEFINITION_GROUP); 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 65: /* def ::= LINE_DEFINITION def_lines */
+      case 70: /* def ::= LINE_DEFINITION def_lines */
 { yylhsminor.yy0 = token_new_parent(yymsp[-1].minor.yy0, BLOCK_DEFINITION); token_chain_append(yymsp[-1].minor.yy0, yymsp[0].minor.yy0); }
   yymsp[-1].minor.yy0 = yylhsminor.yy0;
         break;
-      case 66: /* def ::= LINE_DEFINITION */
+      case 71: /* def ::= LINE_DEFINITION */
 { yylhsminor.yy0 = token_new_parent(yymsp[0].minor.yy0, BLOCK_DEFINITION); }
+  yymsp[0].minor.yy0 = yylhsminor.yy0;
+        break;
+      case 75: /* para ::= table_section */
+{ yylhsminor.yy0 = yymsp[0].minor.yy0; }
   yymsp[0].minor.yy0 = yylhsminor.yy0;
         break;
       default:
-      /* (68) para ::= LINE_PLAIN */ yytestcase(yyruleno==68);
-      /* (69) para_lines ::= para_line (OPTIMIZED OUT) */ assert(yyruleno!=69);
-      /* (70) para_line ::= LINE_CONTINUATION */ yytestcase(yyruleno==70);
-      /* (71) indented_code ::= indented_line (OPTIMIZED OUT) */ assert(yyruleno!=71);
-      /* (72) code_line ::= indented_line (OPTIMIZED OUT) */ assert(yyruleno!=72);
-      /* (73) code_line ::= LINE_EMPTY */ yytestcase(yyruleno==73);
-      /* (74) indented_line ::= LINE_INDENTED_TAB */ yytestcase(yyruleno==74);
-      /* (75) indented_line ::= LINE_INDENTED_SPACE */ yytestcase(yyruleno==75);
-      /* (76) empty ::= LINE_EMPTY */ yytestcase(yyruleno==76);
-      /* (77) blockquote ::= LINE_BLOCKQUOTE */ yytestcase(yyruleno==77);
-      /* (78) quote_lines ::= quote_line (OPTIMIZED OUT) */ assert(yyruleno!=78);
-      /* (79) quote_line ::= LINE_BLOCKQUOTE */ yytestcase(yyruleno==79);
-      /* (80) quote_line ::= LINE_CONTINUATION */ yytestcase(yyruleno==80);
-      /* (81) list_bulleted ::= item_bulleted (OPTIMIZED OUT) */ assert(yyruleno!=81);
-      /* (82) list_enumerated ::= item_enumerated (OPTIMIZED OUT) */ assert(yyruleno!=82);
-      /* (83) cont_blocks ::= cont_block (OPTIMIZED OUT) */ assert(yyruleno!=83);
-      /* (84) cont_block ::= empty */ yytestcase(yyruleno==84);
-      /* (85) table ::= LINE_TABLE */ yytestcase(yyruleno==85);
-      /* (86) def_citation ::= LINE_DEF_CITATION */ yytestcase(yyruleno==86);
-      /* (87) def_footnote ::= LINE_DEF_FOOTNOTE */ yytestcase(yyruleno==87);
-      /* (88) def_link ::= LINE_DEF_LINK */ yytestcase(yyruleno==88);
-      /* (89) html_block ::= LINE_HTML */ yytestcase(yyruleno==89);
-      /* (90) html_block_lines ::= html_block_line (OPTIMIZED OUT) */ assert(yyruleno!=90);
-      /* (91) html_block_line ::= LINE_CONTINUATION */ yytestcase(yyruleno==91);
-      /* (92) html_block_line ::= LINE_HTML */ yytestcase(yyruleno==92);
-      /* (93) fenced_lines ::= fenced_line (OPTIMIZED OUT) */ assert(yyruleno!=93);
-      /* (94) fenced_line ::= LINE_CONTINUATION */ yytestcase(yyruleno==94);
-      /* (95) fenced_line ::= LINE_EMPTY */ yytestcase(yyruleno==95);
-      /* (96) meta_block ::= LINE_META */ yytestcase(yyruleno==96);
-      /* (97) meta_lines ::= meta_line (OPTIMIZED OUT) */ assert(yyruleno!=97);
-      /* (98) meta_line ::= LINE_META */ yytestcase(yyruleno==98);
-      /* (99) meta_line ::= LINE_CONTINUATION */ yytestcase(yyruleno==99);
-      /* (100) definition_block ::= definition (OPTIMIZED OUT) */ assert(yyruleno!=100);
-      /* (101) defs ::= def (OPTIMIZED OUT) */ assert(yyruleno!=101);
-      /* (102) def_lines ::= LINE_CONTINUATION */ yytestcase(yyruleno==102);
+      /* (76) para ::= LINE_PLAIN */ yytestcase(yyruleno==76);
+      /* (77) para_lines ::= para_line (OPTIMIZED OUT) */ assert(yyruleno!=77);
+      /* (78) para_line ::= LINE_CONTINUATION */ yytestcase(yyruleno==78);
+      /* (79) indented_code ::= indented_line (OPTIMIZED OUT) */ assert(yyruleno!=79);
+      /* (80) code_line ::= indented_line (OPTIMIZED OUT) */ assert(yyruleno!=80);
+      /* (81) code_line ::= LINE_EMPTY */ yytestcase(yyruleno==81);
+      /* (82) indented_line ::= LINE_INDENTED_TAB */ yytestcase(yyruleno==82);
+      /* (83) indented_line ::= LINE_INDENTED_SPACE */ yytestcase(yyruleno==83);
+      /* (84) empty ::= LINE_EMPTY */ yytestcase(yyruleno==84);
+      /* (85) blockquote ::= LINE_BLOCKQUOTE */ yytestcase(yyruleno==85);
+      /* (86) quote_lines ::= quote_line (OPTIMIZED OUT) */ assert(yyruleno!=86);
+      /* (87) quote_line ::= LINE_BLOCKQUOTE */ yytestcase(yyruleno==87);
+      /* (88) quote_line ::= LINE_CONTINUATION */ yytestcase(yyruleno==88);
+      /* (89) list_bulleted ::= item_bulleted (OPTIMIZED OUT) */ assert(yyruleno!=89);
+      /* (90) list_enumerated ::= item_enumerated (OPTIMIZED OUT) */ assert(yyruleno!=90);
+      /* (91) cont_blocks ::= cont_block (OPTIMIZED OUT) */ assert(yyruleno!=91);
+      /* (92) cont_block ::= empty */ yytestcase(yyruleno==92);
+      /* (93) table_section ::= LINE_TABLE */ yytestcase(yyruleno==93);
+      /* (94) def_citation ::= LINE_DEF_CITATION */ yytestcase(yyruleno==94);
+      /* (95) def_footnote ::= LINE_DEF_FOOTNOTE */ yytestcase(yyruleno==95);
+      /* (96) def_link ::= LINE_DEF_LINK */ yytestcase(yyruleno==96);
+      /* (97) html_block ::= LINE_HTML */ yytestcase(yyruleno==97);
+      /* (98) html_block_lines ::= html_block_line (OPTIMIZED OUT) */ assert(yyruleno!=98);
+      /* (99) html_block_line ::= LINE_CONTINUATION */ yytestcase(yyruleno==99);
+      /* (100) html_block_line ::= LINE_HTML */ yytestcase(yyruleno==100);
+      /* (101) fenced_lines ::= fenced_line (OPTIMIZED OUT) */ assert(yyruleno!=101);
+      /* (102) fenced_line ::= LINE_CONTINUATION */ yytestcase(yyruleno==102);
+      /* (103) fenced_line ::= LINE_EMPTY */ yytestcase(yyruleno==103);
+      /* (104) meta_block ::= LINE_META */ yytestcase(yyruleno==104);
+      /* (105) meta_lines ::= meta_line (OPTIMIZED OUT) */ assert(yyruleno!=105);
+      /* (106) meta_line ::= LINE_META */ yytestcase(yyruleno==106);
+      /* (107) meta_line ::= LINE_CONTINUATION */ yytestcase(yyruleno==107);
+      /* (108) definition_block ::= definition (OPTIMIZED OUT) */ assert(yyruleno!=108);
+      /* (109) defs ::= def (OPTIMIZED OUT) */ assert(yyruleno!=109);
+      /* (110) def_lines ::= LINE_CONTINUATION */ yytestcase(yyruleno==110);
         break;
 /********** End reduce actions ************************************************/
   };
index 8fbed60b4bc88f45af8f9c840a31a92435baf6ca..02c261a4073b4890f210663d69e37cbcc8aef381 100644 (file)
@@ -1,25 +1,26 @@
-#define LINE_CONTINUATION                1
-#define LINE_PLAIN                       2
-#define LINE_INDENTED_TAB                3
-#define LINE_INDENTED_SPACE              4
-#define LINE_HTML                        5
-#define LINE_ATX_1                       6
-#define LINE_ATX_2                       7
-#define LINE_ATX_3                       8
-#define LINE_ATX_4                       9
-#define LINE_ATX_5                      10
-#define LINE_ATX_6                      11
-#define LINE_HR                         12
-#define LINE_BLOCKQUOTE                 13
-#define LINE_LIST_BULLETED              14
-#define LINE_LIST_ENUMERATED            15
-#define LINE_TABLE                      16
-#define LINE_DEF_CITATION               17
-#define LINE_DEF_FOOTNOTE               18
-#define LINE_DEF_LINK                   19
-#define LINE_FENCE_BACKTICK             20
-#define LINE_FENCE_BACKTICK_START       21
-#define LINE_TOC                        22
-#define LINE_EMPTY                      23
-#define LINE_META                       24
-#define LINE_DEFINITION                 25
+#define LINE_PLAIN                       1
+#define LINE_TABLE_SEPARATOR             2
+#define LINE_CONTINUATION                3
+#define LINE_INDENTED_TAB                4
+#define LINE_INDENTED_SPACE              5
+#define LINE_HTML                        6
+#define LINE_ATX_1                       7
+#define LINE_ATX_2                       8
+#define LINE_ATX_3                       9
+#define LINE_ATX_4                      10
+#define LINE_ATX_5                      11
+#define LINE_ATX_6                      12
+#define LINE_HR                         13
+#define LINE_BLOCKQUOTE                 14
+#define LINE_LIST_BULLETED              15
+#define LINE_LIST_ENUMERATED            16
+#define LINE_TABLE                      17
+#define LINE_DEF_CITATION               18
+#define LINE_DEF_FOOTNOTE               19
+#define LINE_DEF_LINK                   20
+#define LINE_FENCE_BACKTICK             21
+#define LINE_FENCE_BACKTICK_START       22
+#define LINE_TOC                        23
+#define LINE_EMPTY                      24
+#define LINE_META                       25
+#define LINE_DEFINITION                 26
index 5fcdbc3c17df296d91af0b7599dc656896243e45..748d5179a3190f98190e3873be1c44aa3f8d77f1 100644 (file)
@@ -46,8 +46,11 @@ State 0:
           item_enumerated ::= * LINE_LIST_ENUMERATED para_lines
           item_enumerated ::= * LINE_LIST_ENUMERATED cont_blocks
           item_enumerated ::= * LINE_LIST_ENUMERATED
-          table ::= * table LINE_TABLE
-          table ::= * LINE_TABLE
+          table ::= * table_header table_body LINE_EMPTY
+          table ::= * table_header table_body
+          table_header ::= * table_section LINE_TABLE_SEPARATOR
+          table_section ::= * table_section LINE_TABLE
+          table_section ::= * LINE_TABLE
           def_citation ::= * LINE_DEF_CITATION para_lines cont_blocks
           def_citation ::= * LINE_DEF_CITATION para_lines
           def_citation ::= * LINE_DEF_CITATION cont_blocks
@@ -70,11 +73,14 @@ State 0:
           definition_block ::= * definition_block empty
           definition_block ::= * definition
           definition ::= * para defs
-
-                    LINE_PLAIN shift        23     
-             LINE_INDENTED_TAB shift-reduce 74     indented_line ::= LINE_INDENTED_TAB
-           LINE_INDENTED_SPACE shift-reduce 75     indented_line ::= LINE_INDENTED_SPACE
-                     LINE_HTML shift        14     
+          para ::= * table_section LINE_EMPTY
+          para ::= * table_section para_lines
+          para ::= * table_section
+
+                    LINE_PLAIN shift        26     
+             LINE_INDENTED_TAB shift-reduce 82     indented_line ::= LINE_INDENTED_TAB
+           LINE_INDENTED_SPACE shift-reduce 83     indented_line ::= LINE_INDENTED_SPACE
+                     LINE_HTML shift        17     
                     LINE_ATX_1 shift-reduce 5      block ::= LINE_ATX_1
                     LINE_ATX_2 shift-reduce 6      block ::= LINE_ATX_2
                     LINE_ATX_3 shift-reduce 7      block ::= LINE_ATX_3
@@ -82,39 +88,41 @@ State 0:
                     LINE_ATX_5 shift-reduce 9      block ::= LINE_ATX_5
                     LINE_ATX_6 shift-reduce 10     block ::= LINE_ATX_6
                        LINE_HR shift-reduce 16     block ::= LINE_HR
-               LINE_BLOCKQUOTE shift        15     
+               LINE_BLOCKQUOTE shift        18     
             LINE_LIST_BULLETED shift        5      
           LINE_LIST_ENUMERATED shift        4      
-                    LINE_TABLE shift-reduce 85     table ::= LINE_TABLE
+                    LINE_TABLE shift-reduce 93     table_section ::= LINE_TABLE
              LINE_DEF_CITATION shift        3      
              LINE_DEF_FOOTNOTE shift        2      
-                 LINE_DEF_LINK shift        17     
-           LINE_FENCE_BACKTICK shift        13     
-     LINE_FENCE_BACKTICK_START shift        12     
+                 LINE_DEF_LINK shift        19     
+           LINE_FENCE_BACKTICK shift        16     
+     LINE_FENCE_BACKTICK_START shift        15     
                       LINE_TOC shift-reduce 23     block ::= LINE_TOC
-                    LINE_EMPTY shift-reduce 76     empty ::= LINE_EMPTY
-                     LINE_META shift        11     
+                    LINE_EMPTY shift-reduce 84     empty ::= LINE_EMPTY
+                     LINE_META shift        14     
                            doc accept
                         blocks shift        1      
                          block shift-reduce 2      blocks ::= block
-                          para shift        29     
-                 indented_code shift        10     
-                         empty shift        45     
-                 list_bulleted shift        41     
-               list_enumerated shift        39     
+                          para shift        32     
+                 indented_code shift        13     
+                         empty shift        52     
+                 list_bulleted shift        46     
+               list_enumerated shift        44     
                     blockquote shift-reduce 14     block ::= blockquote
-                         table shift        44     
+                         table shift-reduce 15     block ::= table
                   def_citation shift-reduce 17     block ::= def_citation
                   def_footnote shift-reduce 18     block ::= def_footnote
                       def_link shift-reduce 19     block ::= def_link
                     html_block shift-reduce 20     block ::= html_block
                   fenced_block shift-reduce 21     block ::= fenced_block
                     meta_block shift-reduce 22     block ::= meta_block
-              definition_block shift        38     
-                 indented_line shift        10       /* because indented_line==indented_code */
-                 item_bulleted shift        41       /* because item_bulleted==list_bulleted */
-               item_enumerated shift        39       /* because item_enumerated==list_enumerated */
-                    definition shift        38       /* because definition==definition_block */
+              definition_block shift        43     
+                 indented_line shift        13       /* because indented_line==indented_code */
+                 item_bulleted shift        46       /* because item_bulleted==list_bulleted */
+               item_enumerated shift        44       /* because item_enumerated==list_enumerated */
+                  table_header shift        24     
+                 table_section shift        11     
+                    definition shift        43       /* because definition==definition_block */
 
 State 1:
       (0) doc ::= blocks *
@@ -163,8 +171,11 @@ State 1:
           item_enumerated ::= * LINE_LIST_ENUMERATED para_lines
           item_enumerated ::= * LINE_LIST_ENUMERATED cont_blocks
           item_enumerated ::= * LINE_LIST_ENUMERATED
-          table ::= * table LINE_TABLE
-          table ::= * LINE_TABLE
+          table ::= * table_header table_body LINE_EMPTY
+          table ::= * table_header table_body
+          table_header ::= * table_section LINE_TABLE_SEPARATOR
+          table_section ::= * table_section LINE_TABLE
+          table_section ::= * LINE_TABLE
           def_citation ::= * LINE_DEF_CITATION para_lines cont_blocks
           def_citation ::= * LINE_DEF_CITATION para_lines
           def_citation ::= * LINE_DEF_CITATION cont_blocks
@@ -187,12 +198,15 @@ State 1:
           definition_block ::= * definition_block empty
           definition_block ::= * definition
           definition ::= * para defs
+          para ::= * table_section LINE_EMPTY
+          para ::= * table_section para_lines
+          para ::= * table_section
 
                              $ reduce       0      doc ::= blocks
-                    LINE_PLAIN shift        23     
-             LINE_INDENTED_TAB shift-reduce 74     indented_line ::= LINE_INDENTED_TAB
-           LINE_INDENTED_SPACE shift-reduce 75     indented_line ::= LINE_INDENTED_SPACE
-                     LINE_HTML shift        14     
+                    LINE_PLAIN shift        26     
+             LINE_INDENTED_TAB shift-reduce 82     indented_line ::= LINE_INDENTED_TAB
+           LINE_INDENTED_SPACE shift-reduce 83     indented_line ::= LINE_INDENTED_SPACE
+                     LINE_HTML shift        17     
                     LINE_ATX_1 shift-reduce 5      block ::= LINE_ATX_1
                     LINE_ATX_2 shift-reduce 6      block ::= LINE_ATX_2
                     LINE_ATX_3 shift-reduce 7      block ::= LINE_ATX_3
@@ -200,37 +214,39 @@ State 1:
                     LINE_ATX_5 shift-reduce 9      block ::= LINE_ATX_5
                     LINE_ATX_6 shift-reduce 10     block ::= LINE_ATX_6
                        LINE_HR shift-reduce 16     block ::= LINE_HR
-               LINE_BLOCKQUOTE shift        15     
+               LINE_BLOCKQUOTE shift        18     
             LINE_LIST_BULLETED shift        5      
           LINE_LIST_ENUMERATED shift        4      
-                    LINE_TABLE shift-reduce 85     table ::= LINE_TABLE
+                    LINE_TABLE shift-reduce 93     table_section ::= LINE_TABLE
              LINE_DEF_CITATION shift        3      
              LINE_DEF_FOOTNOTE shift        2      
-                 LINE_DEF_LINK shift        17     
-           LINE_FENCE_BACKTICK shift        13     
-     LINE_FENCE_BACKTICK_START shift        12     
+                 LINE_DEF_LINK shift        19     
+           LINE_FENCE_BACKTICK shift        16     
+     LINE_FENCE_BACKTICK_START shift        15     
                       LINE_TOC shift-reduce 23     block ::= LINE_TOC
-                    LINE_EMPTY shift-reduce 76     empty ::= LINE_EMPTY
-                     LINE_META shift        11     
+                    LINE_EMPTY shift-reduce 84     empty ::= LINE_EMPTY
+                     LINE_META shift        14     
                          block shift-reduce 1      blocks ::= blocks block
-                          para shift        29     
-                 indented_code shift        10     
-                         empty shift        45     
-                 list_bulleted shift        41     
-               list_enumerated shift        39     
+                          para shift        32     
+                 indented_code shift        13     
+                         empty shift        52     
+                 list_bulleted shift        46     
+               list_enumerated shift        44     
                     blockquote shift-reduce 14     block ::= blockquote
-                         table shift        44     
+                         table shift-reduce 15     block ::= table
                   def_citation shift-reduce 17     block ::= def_citation
                   def_footnote shift-reduce 18     block ::= def_footnote
                       def_link shift-reduce 19     block ::= def_link
                     html_block shift-reduce 20     block ::= html_block
                   fenced_block shift-reduce 21     block ::= fenced_block
                     meta_block shift-reduce 22     block ::= meta_block
-              definition_block shift        38     
-                 indented_line shift        10       /* because indented_line==indented_code */
-                 item_bulleted shift        41       /* because item_bulleted==list_bulleted */
-               item_enumerated shift        39       /* because item_enumerated==list_enumerated */
-                    definition shift        38       /* because definition==definition_block */
+              definition_block shift        43     
+                 indented_line shift        13       /* because indented_line==indented_code */
+                 item_bulleted shift        46       /* because item_bulleted==list_bulleted */
+               item_enumerated shift        44       /* because item_enumerated==list_enumerated */
+                  table_header shift        24     
+                 table_section shift        11     
+                    definition shift        43       /* because definition==definition_block */
 
 State 2:
           para_lines ::= * para_lines para_line
@@ -246,17 +262,17 @@ State 2:
           def_footnote ::= LINE_DEF_FOOTNOTE * para_lines cont_blocks
           def_footnote ::= LINE_DEF_FOOTNOTE * para_lines
           def_footnote ::= LINE_DEF_FOOTNOTE * cont_blocks
-     (87) def_footnote ::= LINE_DEF_FOOTNOTE *
+     (95) def_footnote ::= LINE_DEF_FOOTNOTE *
 
-             LINE_CONTINUATION shift-reduce 70     para_line ::= LINE_CONTINUATION
-                    LINE_EMPTY shift-reduce 76     empty ::= LINE_EMPTY
-                    LINE_EMPTY reduce       87      ** Parsing conflict **
-                         empty shift        32     
+             LINE_CONTINUATION shift-reduce 78     para_line ::= LINE_CONTINUATION
+                    LINE_EMPTY shift-reduce 84     empty ::= LINE_EMPTY
+                    LINE_EMPTY reduce       95      ** Parsing conflict **
+                         empty shift        35     
                     para_lines shift        6      
                      para_line shift        6        /* because para_line==para_lines */
-                   cont_blocks shift        18     
-                    cont_block shift        18       /* because cont_block==cont_blocks */
-                     {default} reduce       87     def_footnote ::= LINE_DEF_FOOTNOTE
+                   cont_blocks shift        20     
+                    cont_block shift        20       /* because cont_block==cont_blocks */
+                     {default} reduce       95     def_footnote ::= LINE_DEF_FOOTNOTE
 
 State 3:
           para_lines ::= * para_lines para_line
@@ -272,17 +288,17 @@ State 3:
           def_citation ::= LINE_DEF_CITATION * para_lines cont_blocks
           def_citation ::= LINE_DEF_CITATION * para_lines
           def_citation ::= LINE_DEF_CITATION * cont_blocks
-     (86) def_citation ::= LINE_DEF_CITATION *
+     (94) def_citation ::= LINE_DEF_CITATION *
 
-             LINE_CONTINUATION shift-reduce 70     para_line ::= LINE_CONTINUATION
-                    LINE_EMPTY shift-reduce 76     empty ::= LINE_EMPTY
-                    LINE_EMPTY reduce       86      ** Parsing conflict **
-                         empty shift        32     
+             LINE_CONTINUATION shift-reduce 78     para_line ::= LINE_CONTINUATION
+                    LINE_EMPTY shift-reduce 84     empty ::= LINE_EMPTY
+                    LINE_EMPTY reduce       94      ** Parsing conflict **
+                         empty shift        35     
                     para_lines shift        7      
                      para_line shift        7        /* because para_line==para_lines */
-                   cont_blocks shift        20     
-                    cont_block shift        20       /* because cont_block==cont_blocks */
-                     {default} reduce       86     def_citation ::= LINE_DEF_CITATION
+                   cont_blocks shift        22     
+                    cont_block shift        22       /* because cont_block==cont_blocks */
+                     {default} reduce       94     def_citation ::= LINE_DEF_CITATION
 
 State 4:
           para_lines ::= * para_lines para_line
@@ -300,14 +316,14 @@ State 4:
           cont_block ::= * empty indented_line
           cont_block ::= * empty
 
-             LINE_CONTINUATION shift-reduce 70     para_line ::= LINE_CONTINUATION
-                    LINE_EMPTY shift-reduce 76     empty ::= LINE_EMPTY
+             LINE_CONTINUATION shift-reduce 78     para_line ::= LINE_CONTINUATION
+                    LINE_EMPTY shift-reduce 84     empty ::= LINE_EMPTY
                     LINE_EMPTY reduce       40      ** Parsing conflict **
-                         empty shift        32     
+                         empty shift        35     
                     para_lines shift        8      
                      para_line shift        8        /* because para_line==para_lines */
-                   cont_blocks shift        24     
-                    cont_block shift        24       /* because cont_block==cont_blocks */
+                   cont_blocks shift        27     
+                    cont_block shift        27       /* because cont_block==cont_blocks */
                      {default} reduce       40     item_enumerated ::= LINE_LIST_ENUMERATED
 
 State 5:
@@ -326,14 +342,14 @@ State 5:
           cont_block ::= * empty indented_line
           cont_block ::= * empty
 
-             LINE_CONTINUATION shift-reduce 70     para_line ::= LINE_CONTINUATION
-                    LINE_EMPTY shift-reduce 76     empty ::= LINE_EMPTY
+             LINE_CONTINUATION shift-reduce 78     para_line ::= LINE_CONTINUATION
+                    LINE_EMPTY shift-reduce 84     empty ::= LINE_EMPTY
                     LINE_EMPTY reduce       35      ** Parsing conflict **
-                         empty shift        32     
+                         empty shift        35     
                     para_lines shift        9      
                      para_line shift        9        /* because para_line==para_lines */
-                   cont_blocks shift        26     
-                    cont_block shift        26       /* because cont_block==cont_blocks */
+                   cont_blocks shift        29     
+                    cont_block shift        29       /* because cont_block==cont_blocks */
                      {default} reduce       35     item_bulleted ::= LINE_LIST_BULLETED
 
 State 6:
@@ -347,16 +363,16 @@ State 6:
           cont_block ::= * empty indented_line
           cont_block ::= * empty
           def_footnote ::= LINE_DEF_FOOTNOTE para_lines * cont_blocks
-     (49) def_footnote ::= LINE_DEF_FOOTNOTE para_lines *
+     (54) def_footnote ::= LINE_DEF_FOOTNOTE para_lines *
 
-             LINE_CONTINUATION shift-reduce 70     para_line ::= LINE_CONTINUATION
-                    LINE_EMPTY shift-reduce 76     empty ::= LINE_EMPTY
-                    LINE_EMPTY reduce       49      ** Parsing conflict **
-                         empty shift        32     
+             LINE_CONTINUATION shift-reduce 78     para_line ::= LINE_CONTINUATION
+                    LINE_EMPTY shift-reduce 84     empty ::= LINE_EMPTY
+                    LINE_EMPTY reduce       54      ** Parsing conflict **
+                         empty shift        35     
                      para_line shift-reduce 26     para_lines ::= para_lines para_line
-                   cont_blocks shift        19     
-                    cont_block shift        19       /* because cont_block==cont_blocks */
-                     {default} reduce       49     def_footnote ::= LINE_DEF_FOOTNOTE para_lines
+                   cont_blocks shift        21     
+                    cont_block shift        21       /* because cont_block==cont_blocks */
+                     {default} reduce       54     def_footnote ::= LINE_DEF_FOOTNOTE para_lines
 
 State 7:
           para_lines ::= para_lines * para_line
@@ -369,16 +385,16 @@ State 7:
           cont_block ::= * empty indented_line
           cont_block ::= * empty
           def_citation ::= LINE_DEF_CITATION para_lines * cont_blocks
-     (46) def_citation ::= LINE_DEF_CITATION para_lines *
+     (51) def_citation ::= LINE_DEF_CITATION para_lines *
 
-             LINE_CONTINUATION shift-reduce 70     para_line ::= LINE_CONTINUATION
-                    LINE_EMPTY shift-reduce 76     empty ::= LINE_EMPTY
-                    LINE_EMPTY reduce       46      ** Parsing conflict **
-                         empty shift        32     
+             LINE_CONTINUATION shift-reduce 78     para_line ::= LINE_CONTINUATION
+                    LINE_EMPTY shift-reduce 84     empty ::= LINE_EMPTY
+                    LINE_EMPTY reduce       51      ** Parsing conflict **
+                         empty shift        35     
                      para_line shift-reduce 26     para_lines ::= para_lines para_line
-                   cont_blocks shift        21     
-                    cont_block shift        21       /* because cont_block==cont_blocks */
-                     {default} reduce       46     def_citation ::= LINE_DEF_CITATION para_lines
+                   cont_blocks shift        23     
+                    cont_block shift        23       /* because cont_block==cont_blocks */
+                     {default} reduce       51     def_citation ::= LINE_DEF_CITATION para_lines
 
 State 8:
           para_lines ::= para_lines * para_line
@@ -393,13 +409,13 @@ State 8:
           cont_block ::= * empty indented_line
           cont_block ::= * empty
 
-             LINE_CONTINUATION shift-reduce 70     para_line ::= LINE_CONTINUATION
-                    LINE_EMPTY shift-reduce 76     empty ::= LINE_EMPTY
+             LINE_CONTINUATION shift-reduce 78     para_line ::= LINE_CONTINUATION
+                    LINE_EMPTY shift-reduce 84     empty ::= LINE_EMPTY
                     LINE_EMPTY reduce       38      ** Parsing conflict **
-                         empty shift        32     
+                         empty shift        35     
                      para_line shift-reduce 26     para_lines ::= para_lines para_line
-                   cont_blocks shift        25     
-                    cont_block shift        25       /* because cont_block==cont_blocks */
+                   cont_blocks shift        28     
+                    cont_block shift        28       /* because cont_block==cont_blocks */
                      {default} reduce       38     item_enumerated ::= LINE_LIST_ENUMERATED para_lines
 
 State 9:
@@ -415,16 +431,76 @@ State 9:
           cont_block ::= * empty indented_line
           cont_block ::= * empty
 
-             LINE_CONTINUATION shift-reduce 70     para_line ::= LINE_CONTINUATION
-                    LINE_EMPTY shift-reduce 76     empty ::= LINE_EMPTY
+             LINE_CONTINUATION shift-reduce 78     para_line ::= LINE_CONTINUATION
+                    LINE_EMPTY shift-reduce 84     empty ::= LINE_EMPTY
                     LINE_EMPTY reduce       33      ** Parsing conflict **
-                         empty shift        32     
+                         empty shift        35     
                      para_line shift-reduce 26     para_lines ::= para_lines para_line
-                   cont_blocks shift        27     
-                    cont_block shift        27       /* because cont_block==cont_blocks */
+                   cont_blocks shift        30     
+                    cont_block shift        30       /* because cont_block==cont_blocks */
                      {default} reduce       33     item_bulleted ::= LINE_LIST_BULLETED para_lines
 
 State 10:
+          para ::= * LINE_PLAIN para_lines
+          para ::= * LINE_PLAIN
+          empty ::= empty * LINE_EMPTY
+          table_section ::= * table_section LINE_TABLE
+          table_section ::= * LINE_TABLE
+          definition_block ::= definition_block empty * definition
+     (67) definition_block ::= definition_block empty *
+          definition ::= * para defs
+          para ::= * table_section LINE_EMPTY
+          para ::= * table_section para_lines
+          para ::= * table_section
+
+                    LINE_PLAIN shift        26     
+                    LINE_PLAIN reduce       67      ** Parsing conflict **
+                    LINE_TABLE shift-reduce 93     table_section ::= LINE_TABLE
+                    LINE_TABLE reduce       67      ** Parsing conflict **
+                    LINE_EMPTY shift-reduce 28     empty ::= empty LINE_EMPTY
+                    LINE_EMPTY reduce       67      ** Parsing conflict **
+                          para shift        25     
+                 table_section shift        12     
+                    definition shift-reduce 66     definition_block ::= definition_block empty definition
+                     {default} reduce       67     definition_block ::= definition_block empty
+
+State 11:
+          para_lines ::= * para_lines para_line
+          para_lines ::= * para_line
+          para_line ::= * LINE_CONTINUATION
+          table_header ::= table_section * LINE_TABLE_SEPARATOR
+          table_section ::= table_section * LINE_TABLE
+          para ::= table_section * LINE_EMPTY
+          para ::= table_section * para_lines
+     (75) para ::= table_section *
+
+          LINE_TABLE_SEPARATOR shift-reduce 46     table_header ::= table_section LINE_TABLE_SEPARATOR
+             LINE_CONTINUATION shift-reduce 78     para_line ::= LINE_CONTINUATION
+                    LINE_TABLE shift-reduce 49     table_section ::= table_section LINE_TABLE
+                    LINE_TABLE reduce       75      ** Parsing conflict **
+                    LINE_EMPTY shift-reduce 73     para ::= table_section LINE_EMPTY
+                    LINE_EMPTY reduce       75      ** Parsing conflict **
+                    para_lines shift        41     
+                     para_line shift        41       /* because para_line==para_lines */
+                     {default} reduce       75     para ::= table_section
+
+State 12:
+          para_lines ::= * para_lines para_line
+          para_lines ::= * para_line
+          para_line ::= * LINE_CONTINUATION
+          table_section ::= table_section * LINE_TABLE
+          para ::= table_section * LINE_EMPTY
+          para ::= table_section * para_lines
+     (75) para ::= table_section *
+
+             LINE_CONTINUATION shift-reduce 78     para_line ::= LINE_CONTINUATION
+                    LINE_TABLE shift-reduce 49     table_section ::= table_section LINE_TABLE
+                    LINE_EMPTY shift-reduce 73     para ::= table_section LINE_EMPTY
+                    para_lines shift        41     
+                     para_line shift        41       /* because para_line==para_lines */
+                     {default} reduce       75     para ::= table_section
+
+State 13:
       (4) block ::= indented_code *
           indented_code ::= indented_code * code_line
           code_line ::= * indented_line
@@ -432,32 +508,32 @@ State 10:
           indented_line ::= * LINE_INDENTED_TAB
           indented_line ::= * LINE_INDENTED_SPACE
 
-             LINE_INDENTED_TAB shift-reduce 74     indented_line ::= LINE_INDENTED_TAB
+             LINE_INDENTED_TAB shift-reduce 82     indented_line ::= LINE_INDENTED_TAB
              LINE_INDENTED_TAB reduce       4       ** Parsing conflict **
-           LINE_INDENTED_SPACE shift-reduce 75     indented_line ::= LINE_INDENTED_SPACE
+           LINE_INDENTED_SPACE shift-reduce 83     indented_line ::= LINE_INDENTED_SPACE
            LINE_INDENTED_SPACE reduce       4       ** Parsing conflict **
-                    LINE_EMPTY shift-reduce 73     code_line ::= LINE_EMPTY
+                    LINE_EMPTY shift-reduce 81     code_line ::= LINE_EMPTY
                     LINE_EMPTY reduce       4       ** Parsing conflict **
                      code_line shift-reduce 27     indented_code ::= indented_code code_line
                  indented_line shift-reduce 27     indented_code ::= indented_code code_line  /* because indented_line==code_line */
                      {default} reduce       4      block ::= indented_code
 
-State 11:
+State 14:
           meta_block ::= LINE_META * meta_lines
-     (96) meta_block ::= LINE_META *
+    (104) meta_block ::= LINE_META *
           meta_lines ::= * meta_lines meta_line
           meta_lines ::= * meta_line
           meta_line ::= * LINE_META
           meta_line ::= * LINE_CONTINUATION
 
-             LINE_CONTINUATION shift-reduce 99     meta_line ::= LINE_CONTINUATION
-                     LINE_META shift-reduce 98     meta_line ::= LINE_META
-                     LINE_META reduce       96      ** Parsing conflict **
-                    meta_lines shift        33     
-                     meta_line shift        33       /* because meta_line==meta_lines */
-                     {default} reduce       96     meta_block ::= LINE_META
+             LINE_CONTINUATION shift-reduce 107    meta_line ::= LINE_CONTINUATION
+                     LINE_META shift-reduce 106    meta_line ::= LINE_META
+                     LINE_META reduce       104     ** Parsing conflict **
+                    meta_lines shift        36     
+                     meta_line shift        36       /* because meta_line==meta_lines */
+                     {default} reduce       104    meta_block ::= LINE_META
 
-State 12:
+State 15:
           fenced_block ::= LINE_FENCE_BACKTICK_START * fenced_lines LINE_FENCE_BACKTICK
           fenced_block ::= LINE_FENCE_BACKTICK_START * fenced_lines
           fenced_lines ::= * fenced_lines fenced_line
@@ -465,12 +541,12 @@ State 12:
           fenced_line ::= * LINE_CONTINUATION
           fenced_line ::= * LINE_EMPTY
 
-             LINE_CONTINUATION shift-reduce 94     fenced_line ::= LINE_CONTINUATION
-                    LINE_EMPTY shift-reduce 95     fenced_line ::= LINE_EMPTY
-                  fenced_lines shift        30     
-                   fenced_line shift        30       /* because fenced_line==fenced_lines */
+             LINE_CONTINUATION shift-reduce 102    fenced_line ::= LINE_CONTINUATION
+                    LINE_EMPTY shift-reduce 103    fenced_line ::= LINE_EMPTY
+                  fenced_lines shift        33     
+                   fenced_line shift        33       /* because fenced_line==fenced_lines */
 
-State 13:
+State 16:
           fenced_block ::= LINE_FENCE_BACKTICK * fenced_lines LINE_FENCE_BACKTICK
           fenced_block ::= LINE_FENCE_BACKTICK * fenced_lines
           fenced_lines ::= * fenced_lines fenced_line
@@ -478,153 +554,149 @@ State 13:
           fenced_line ::= * LINE_CONTINUATION
           fenced_line ::= * LINE_EMPTY
 
-             LINE_CONTINUATION shift-reduce 94     fenced_line ::= LINE_CONTINUATION
-                    LINE_EMPTY shift-reduce 95     fenced_line ::= LINE_EMPTY
-                  fenced_lines shift        31     
-                   fenced_line shift        31       /* because fenced_line==fenced_lines */
+             LINE_CONTINUATION shift-reduce 102    fenced_line ::= LINE_CONTINUATION
+                    LINE_EMPTY shift-reduce 103    fenced_line ::= LINE_EMPTY
+                  fenced_lines shift        34     
+                   fenced_line shift        34       /* because fenced_line==fenced_lines */
 
-State 14:
+State 17:
           html_block ::= LINE_HTML * html_block_lines
-     (89) html_block ::= LINE_HTML *
+     (97) html_block ::= LINE_HTML *
           html_block_lines ::= * html_block_lines html_block_line
           html_block_lines ::= * html_block_line
           html_block_line ::= * LINE_CONTINUATION
           html_block_line ::= * LINE_HTML
 
-             LINE_CONTINUATION shift-reduce 91     html_block_line ::= LINE_CONTINUATION
-                     LINE_HTML shift-reduce 92     html_block_line ::= LINE_HTML
-                     LINE_HTML reduce       89      ** Parsing conflict **
-              html_block_lines shift        34     
-               html_block_line shift        34       /* because html_block_line==html_block_lines */
-                     {default} reduce       89     html_block ::= LINE_HTML
+             LINE_CONTINUATION shift-reduce 99     html_block_line ::= LINE_CONTINUATION
+                     LINE_HTML shift-reduce 100    html_block_line ::= LINE_HTML
+                     LINE_HTML reduce       97      ** Parsing conflict **
+              html_block_lines shift        37     
+               html_block_line shift        37       /* because html_block_line==html_block_lines */
+                     {default} reduce       97     html_block ::= LINE_HTML
 
-State 15:
+State 18:
           blockquote ::= LINE_BLOCKQUOTE * quote_lines
-     (77) blockquote ::= LINE_BLOCKQUOTE *
+     (85) blockquote ::= LINE_BLOCKQUOTE *
           quote_lines ::= * quote_lines quote_line
           quote_lines ::= * quote_line
           quote_line ::= * LINE_BLOCKQUOTE
           quote_line ::= * LINE_CONTINUATION
 
-             LINE_CONTINUATION shift-reduce 80     quote_line ::= LINE_CONTINUATION
-               LINE_BLOCKQUOTE shift-reduce 79     quote_line ::= LINE_BLOCKQUOTE
-               LINE_BLOCKQUOTE reduce       77      ** Parsing conflict **
-                   quote_lines shift        35     
-                    quote_line shift        35       /* because quote_line==quote_lines */
-                     {default} reduce       77     blockquote ::= LINE_BLOCKQUOTE
-
-State 16:
-          para ::= * LINE_PLAIN para_lines
-          para ::= * LINE_PLAIN
-          empty ::= empty * LINE_EMPTY
-          definition_block ::= definition_block empty * definition
-     (62) definition_block ::= definition_block empty *
-          definition ::= * para defs
-
-                    LINE_PLAIN shift        23     
-                    LINE_PLAIN reduce       62      ** Parsing conflict **
-                    LINE_EMPTY shift-reduce 28     empty ::= empty LINE_EMPTY
-                    LINE_EMPTY reduce       62      ** Parsing conflict **
-                          para shift        22     
-                    definition shift-reduce 61     definition_block ::= definition_block empty definition
-                     {default} reduce       62     definition_block ::= definition_block empty
+             LINE_CONTINUATION shift-reduce 88     quote_line ::= LINE_CONTINUATION
+               LINE_BLOCKQUOTE shift-reduce 87     quote_line ::= LINE_BLOCKQUOTE
+               LINE_BLOCKQUOTE reduce       85      ** Parsing conflict **
+                   quote_lines shift        38     
+                    quote_line shift        38       /* because quote_line==quote_lines */
+                     {default} reduce       85     blockquote ::= LINE_BLOCKQUOTE
 
-State 17:
+State 19:
           para_lines ::= * para_lines para_line
           para_lines ::= * para_line
           para_line ::= * LINE_CONTINUATION
           def_link ::= LINE_DEF_LINK * para_lines
-     (88) def_link ::= LINE_DEF_LINK *
+     (96) def_link ::= LINE_DEF_LINK *
 
-             LINE_CONTINUATION shift-reduce 70     para_line ::= LINE_CONTINUATION
-                    para_lines shift        36     
-                     para_line shift        36       /* because para_line==para_lines */
-                     {default} reduce       88     def_link ::= LINE_DEF_LINK
+             LINE_CONTINUATION shift-reduce 78     para_line ::= LINE_CONTINUATION
+                    para_lines shift        39     
+                     para_line shift        39       /* because para_line==para_lines */
+                     {default} reduce       96     def_link ::= LINE_DEF_LINK
 
-State 18:
+State 20:
           empty ::= * empty LINE_EMPTY
           empty ::= * LINE_EMPTY
           cont_blocks ::= cont_blocks * cont_block
           cont_block ::= * empty indented_line para_lines
           cont_block ::= * empty indented_line
           cont_block ::= * empty
-     (50) def_footnote ::= LINE_DEF_FOOTNOTE cont_blocks *
+     (55) def_footnote ::= LINE_DEF_FOOTNOTE cont_blocks *
 
-                    LINE_EMPTY shift-reduce 76     empty ::= LINE_EMPTY
-                    LINE_EMPTY reduce       50      ** Parsing conflict **
-                         empty shift        32     
+                    LINE_EMPTY shift-reduce 84     empty ::= LINE_EMPTY
+                    LINE_EMPTY reduce       55      ** Parsing conflict **
+                         empty shift        35     
                     cont_block shift-reduce 41     cont_blocks ::= cont_blocks cont_block
-                     {default} reduce       50     def_footnote ::= LINE_DEF_FOOTNOTE cont_blocks
+                     {default} reduce       55     def_footnote ::= LINE_DEF_FOOTNOTE cont_blocks
 
-State 19:
+State 21:
           empty ::= * empty LINE_EMPTY
           empty ::= * LINE_EMPTY
           cont_blocks ::= cont_blocks * cont_block
           cont_block ::= * empty indented_line para_lines
           cont_block ::= * empty indented_line
           cont_block ::= * empty
-     (48) def_footnote ::= LINE_DEF_FOOTNOTE para_lines cont_blocks *
+     (53) def_footnote ::= LINE_DEF_FOOTNOTE para_lines cont_blocks *
 
-                    LINE_EMPTY shift-reduce 76     empty ::= LINE_EMPTY
-                    LINE_EMPTY reduce       48      ** Parsing conflict **
-                         empty shift        32     
+                    LINE_EMPTY shift-reduce 84     empty ::= LINE_EMPTY
+                    LINE_EMPTY reduce       53      ** Parsing conflict **
+                         empty shift        35     
                     cont_block shift-reduce 41     cont_blocks ::= cont_blocks cont_block
-                     {default} reduce       48     def_footnote ::= LINE_DEF_FOOTNOTE para_lines cont_blocks
+                     {default} reduce       53     def_footnote ::= LINE_DEF_FOOTNOTE para_lines cont_blocks
 
-State 20:
+State 22:
           empty ::= * empty LINE_EMPTY
           empty ::= * LINE_EMPTY
           cont_blocks ::= cont_blocks * cont_block
           cont_block ::= * empty indented_line para_lines
           cont_block ::= * empty indented_line
           cont_block ::= * empty
-     (47) def_citation ::= LINE_DEF_CITATION cont_blocks *
+     (52) def_citation ::= LINE_DEF_CITATION cont_blocks *
 
-                    LINE_EMPTY shift-reduce 76     empty ::= LINE_EMPTY
-                    LINE_EMPTY reduce       47      ** Parsing conflict **
-                         empty shift        32     
+                    LINE_EMPTY shift-reduce 84     empty ::= LINE_EMPTY
+                    LINE_EMPTY reduce       52      ** Parsing conflict **
+                         empty shift        35     
                     cont_block shift-reduce 41     cont_blocks ::= cont_blocks cont_block
-                     {default} reduce       47     def_citation ::= LINE_DEF_CITATION cont_blocks
+                     {default} reduce       52     def_citation ::= LINE_DEF_CITATION cont_blocks
 
-State 21:
+State 23:
           empty ::= * empty LINE_EMPTY
           empty ::= * LINE_EMPTY
           cont_blocks ::= cont_blocks * cont_block
           cont_block ::= * empty indented_line para_lines
           cont_block ::= * empty indented_line
           cont_block ::= * empty
-     (45) def_citation ::= LINE_DEF_CITATION para_lines cont_blocks *
+     (50) def_citation ::= LINE_DEF_CITATION para_lines cont_blocks *
 
-                    LINE_EMPTY shift-reduce 76     empty ::= LINE_EMPTY
-                    LINE_EMPTY reduce       45      ** Parsing conflict **
-                         empty shift        32     
+                    LINE_EMPTY shift-reduce 84     empty ::= LINE_EMPTY
+                    LINE_EMPTY reduce       50      ** Parsing conflict **
+                         empty shift        35     
                     cont_block shift-reduce 41     cont_blocks ::= cont_blocks cont_block
-                     {default} reduce       45     def_citation ::= LINE_DEF_CITATION para_lines cont_blocks
+                     {default} reduce       50     def_citation ::= LINE_DEF_CITATION para_lines cont_blocks
 
-State 22:
+State 24:
+          table ::= table_header * table_body LINE_EMPTY
+          table ::= table_header * table_body
+          table_body ::= * table_body LINE_EMPTY table_section
+          table_body ::= * table_section
+          table_section ::= * table_section LINE_TABLE
+          table_section ::= * LINE_TABLE
+
+                    LINE_TABLE shift-reduce 93     table_section ::= LINE_TABLE
+                    table_body shift        51     
+                 table_section shift        49     
+
+State 25:
           definition ::= para * defs
           defs ::= * defs def
           defs ::= * def
           def ::= * LINE_DEFINITION def_lines
           def ::= * LINE_DEFINITION
 
-               LINE_DEFINITION shift        42     
-                          defs shift        43     
-                           def shift        43       /* because def==defs */
+               LINE_DEFINITION shift        47     
+                          defs shift        48     
+                           def shift        48       /* because def==defs */
 
-State 23:
+State 26:
           para ::= LINE_PLAIN * para_lines
-     (68) para ::= LINE_PLAIN *
+     (76) para ::= LINE_PLAIN *
           para_lines ::= * para_lines para_line
           para_lines ::= * para_line
           para_line ::= * LINE_CONTINUATION
 
-             LINE_CONTINUATION shift-reduce 70     para_line ::= LINE_CONTINUATION
-                    para_lines shift        37     
-                     para_line shift        37       /* because para_line==para_lines */
-                     {default} reduce       68     para ::= LINE_PLAIN
+             LINE_CONTINUATION shift-reduce 78     para_line ::= LINE_CONTINUATION
+                    para_lines shift        42     
+                     para_line shift        42       /* because para_line==para_lines */
+                     {default} reduce       76     para ::= LINE_PLAIN
 
-State 24:
+State 27:
           empty ::= * empty LINE_EMPTY
           empty ::= * LINE_EMPTY
      (39) item_enumerated ::= LINE_LIST_ENUMERATED cont_blocks *
@@ -633,13 +705,13 @@ State 24:
           cont_block ::= * empty indented_line
           cont_block ::= * empty
 
-                    LINE_EMPTY shift-reduce 76     empty ::= LINE_EMPTY
+                    LINE_EMPTY shift-reduce 84     empty ::= LINE_EMPTY
                     LINE_EMPTY reduce       39      ** Parsing conflict **
-                         empty shift        32     
+                         empty shift        35     
                     cont_block shift-reduce 41     cont_blocks ::= cont_blocks cont_block
                      {default} reduce       39     item_enumerated ::= LINE_LIST_ENUMERATED cont_blocks
 
-State 25:
+State 28:
           empty ::= * empty LINE_EMPTY
           empty ::= * LINE_EMPTY
      (37) item_enumerated ::= LINE_LIST_ENUMERATED para_lines cont_blocks *
@@ -648,13 +720,13 @@ State 25:
           cont_block ::= * empty indented_line
           cont_block ::= * empty
 
-                    LINE_EMPTY shift-reduce 76     empty ::= LINE_EMPTY
+                    LINE_EMPTY shift-reduce 84     empty ::= LINE_EMPTY
                     LINE_EMPTY reduce       37      ** Parsing conflict **
-                         empty shift        32     
+                         empty shift        35     
                     cont_block shift-reduce 41     cont_blocks ::= cont_blocks cont_block
                      {default} reduce       37     item_enumerated ::= LINE_LIST_ENUMERATED para_lines cont_blocks
 
-State 26:
+State 29:
           empty ::= * empty LINE_EMPTY
           empty ::= * LINE_EMPTY
      (34) item_bulleted ::= LINE_LIST_BULLETED cont_blocks *
@@ -663,13 +735,13 @@ State 26:
           cont_block ::= * empty indented_line
           cont_block ::= * empty
 
-                    LINE_EMPTY shift-reduce 76     empty ::= LINE_EMPTY
+                    LINE_EMPTY shift-reduce 84     empty ::= LINE_EMPTY
                     LINE_EMPTY reduce       34      ** Parsing conflict **
-                         empty shift        32     
+                         empty shift        35     
                     cont_block shift-reduce 41     cont_blocks ::= cont_blocks cont_block
                      {default} reduce       34     item_bulleted ::= LINE_LIST_BULLETED cont_blocks
 
-State 27:
+State 30:
           empty ::= * empty LINE_EMPTY
           empty ::= * LINE_EMPTY
      (32) item_bulleted ::= LINE_LIST_BULLETED para_lines cont_blocks *
@@ -678,25 +750,25 @@ State 27:
           cont_block ::= * empty indented_line
           cont_block ::= * empty
 
-                    LINE_EMPTY shift-reduce 76     empty ::= LINE_EMPTY
+                    LINE_EMPTY shift-reduce 84     empty ::= LINE_EMPTY
                     LINE_EMPTY reduce       32      ** Parsing conflict **
-                         empty shift        32     
+                         empty shift        35     
                     cont_block shift-reduce 41     cont_blocks ::= cont_blocks cont_block
                      {default} reduce       32     item_bulleted ::= LINE_LIST_BULLETED para_lines cont_blocks
 
-State 28:
+State 31:
           para_lines ::= * para_lines para_line
           para_lines ::= * para_line
           para_line ::= * LINE_CONTINUATION
           cont_block ::= empty indented_line * para_lines
      (43) cont_block ::= empty indented_line *
 
-             LINE_CONTINUATION shift-reduce 70     para_line ::= LINE_CONTINUATION
-                    para_lines shift        40     
-                     para_line shift        40       /* because para_line==para_lines */
+             LINE_CONTINUATION shift-reduce 78     para_line ::= LINE_CONTINUATION
+                    para_lines shift        45     
+                     para_line shift        45       /* because para_line==para_lines */
                      {default} reduce       43     cont_block ::= empty indented_line
 
-State 29:
+State 32:
       (3) block ::= para *
           definition ::= para * defs
           defs ::= * defs def
@@ -704,125 +776,145 @@ State 29:
           def ::= * LINE_DEFINITION def_lines
           def ::= * LINE_DEFINITION
 
-               LINE_DEFINITION shift        42     
-                          defs shift        43     
-                           def shift        43       /* because def==defs */
+               LINE_DEFINITION shift        47     
+                          defs shift        48     
+                           def shift        48       /* because def==defs */
                      {default} reduce       3      block ::= para
 
-State 30:
+State 33:
           fenced_block ::= LINE_FENCE_BACKTICK_START fenced_lines * LINE_FENCE_BACKTICK
-     (57) fenced_block ::= LINE_FENCE_BACKTICK_START fenced_lines *
+     (62) fenced_block ::= LINE_FENCE_BACKTICK_START fenced_lines *
           fenced_lines ::= fenced_lines * fenced_line
           fenced_line ::= * LINE_CONTINUATION
           fenced_line ::= * LINE_EMPTY
 
-             LINE_CONTINUATION shift-reduce 94     fenced_line ::= LINE_CONTINUATION
-           LINE_FENCE_BACKTICK shift-reduce 56     fenced_block ::= LINE_FENCE_BACKTICK_START fenced_lines LINE_FENCE_BACKTICK
-           LINE_FENCE_BACKTICK reduce       57      ** Parsing conflict **
-                    LINE_EMPTY shift-reduce 95     fenced_line ::= LINE_EMPTY
-                    LINE_EMPTY reduce       57      ** Parsing conflict **
-                   fenced_line shift-reduce 58     fenced_lines ::= fenced_lines fenced_line
-                     {default} reduce       57     fenced_block ::= LINE_FENCE_BACKTICK_START fenced_lines
+             LINE_CONTINUATION shift-reduce 102    fenced_line ::= LINE_CONTINUATION
+           LINE_FENCE_BACKTICK shift-reduce 61     fenced_block ::= LINE_FENCE_BACKTICK_START fenced_lines LINE_FENCE_BACKTICK
+           LINE_FENCE_BACKTICK reduce       62      ** Parsing conflict **
+                    LINE_EMPTY shift-reduce 103    fenced_line ::= LINE_EMPTY
+                    LINE_EMPTY reduce       62      ** Parsing conflict **
+                   fenced_line shift-reduce 63     fenced_lines ::= fenced_lines fenced_line
+                     {default} reduce       62     fenced_block ::= LINE_FENCE_BACKTICK_START fenced_lines
 
-State 31:
+State 34:
           fenced_block ::= LINE_FENCE_BACKTICK fenced_lines * LINE_FENCE_BACKTICK
-     (55) fenced_block ::= LINE_FENCE_BACKTICK fenced_lines *
+     (60) fenced_block ::= LINE_FENCE_BACKTICK fenced_lines *
           fenced_lines ::= fenced_lines * fenced_line
           fenced_line ::= * LINE_CONTINUATION
           fenced_line ::= * LINE_EMPTY
 
-             LINE_CONTINUATION shift-reduce 94     fenced_line ::= LINE_CONTINUATION
-           LINE_FENCE_BACKTICK shift-reduce 54     fenced_block ::= LINE_FENCE_BACKTICK fenced_lines LINE_FENCE_BACKTICK
-           LINE_FENCE_BACKTICK reduce       55      ** Parsing conflict **
-                    LINE_EMPTY shift-reduce 95     fenced_line ::= LINE_EMPTY
-                    LINE_EMPTY reduce       55      ** Parsing conflict **
-                   fenced_line shift-reduce 58     fenced_lines ::= fenced_lines fenced_line
-                     {default} reduce       55     fenced_block ::= LINE_FENCE_BACKTICK fenced_lines
+             LINE_CONTINUATION shift-reduce 102    fenced_line ::= LINE_CONTINUATION
+           LINE_FENCE_BACKTICK shift-reduce 59     fenced_block ::= LINE_FENCE_BACKTICK fenced_lines LINE_FENCE_BACKTICK
+           LINE_FENCE_BACKTICK reduce       60      ** Parsing conflict **
+                    LINE_EMPTY shift-reduce 103    fenced_line ::= LINE_EMPTY
+                    LINE_EMPTY reduce       60      ** Parsing conflict **
+                   fenced_line shift-reduce 63     fenced_lines ::= fenced_lines fenced_line
+                     {default} reduce       60     fenced_block ::= LINE_FENCE_BACKTICK fenced_lines
 
-State 32:
+State 35:
           indented_line ::= * LINE_INDENTED_TAB
           indented_line ::= * LINE_INDENTED_SPACE
           empty ::= empty * LINE_EMPTY
           cont_block ::= empty * indented_line para_lines
           cont_block ::= empty * indented_line
-     (84) cont_block ::= empty *
+     (92) cont_block ::= empty *
 
-             LINE_INDENTED_TAB shift-reduce 74     indented_line ::= LINE_INDENTED_TAB
-             LINE_INDENTED_TAB reduce       84      ** Parsing conflict **
-           LINE_INDENTED_SPACE shift-reduce 75     indented_line ::= LINE_INDENTED_SPACE
-           LINE_INDENTED_SPACE reduce       84      ** Parsing conflict **
+             LINE_INDENTED_TAB shift-reduce 82     indented_line ::= LINE_INDENTED_TAB
+             LINE_INDENTED_TAB reduce       92      ** Parsing conflict **
+           LINE_INDENTED_SPACE shift-reduce 83     indented_line ::= LINE_INDENTED_SPACE
+           LINE_INDENTED_SPACE reduce       92      ** Parsing conflict **
                     LINE_EMPTY shift-reduce 28     empty ::= empty LINE_EMPTY
-                    LINE_EMPTY reduce       84      ** Parsing conflict **
-                 indented_line shift        28     
-                     {default} reduce       84     cont_block ::= empty
+                    LINE_EMPTY reduce       92      ** Parsing conflict **
+                 indented_line shift        31     
+                     {default} reduce       92     cont_block ::= empty
 
-State 33:
-     (59) meta_block ::= LINE_META meta_lines *
+State 36:
+     (64) meta_block ::= LINE_META meta_lines *
           meta_lines ::= meta_lines * meta_line
           meta_line ::= * LINE_META
           meta_line ::= * LINE_CONTINUATION
 
-             LINE_CONTINUATION shift-reduce 99     meta_line ::= LINE_CONTINUATION
-                     LINE_META shift-reduce 98     meta_line ::= LINE_META
-                     LINE_META reduce       59      ** Parsing conflict **
-                     meta_line shift-reduce 60     meta_lines ::= meta_lines meta_line
-                     {default} reduce       59     meta_block ::= LINE_META meta_lines
+             LINE_CONTINUATION shift-reduce 107    meta_line ::= LINE_CONTINUATION
+                     LINE_META shift-reduce 106    meta_line ::= LINE_META
+                     LINE_META reduce       64      ** Parsing conflict **
+                     meta_line shift-reduce 65     meta_lines ::= meta_lines meta_line
+                     {default} reduce       64     meta_block ::= LINE_META meta_lines
 
-State 34:
-     (52) html_block ::= LINE_HTML html_block_lines *
+State 37:
+     (57) html_block ::= LINE_HTML html_block_lines *
           html_block_lines ::= html_block_lines * html_block_line
           html_block_line ::= * LINE_CONTINUATION
           html_block_line ::= * LINE_HTML
 
-             LINE_CONTINUATION shift-reduce 91     html_block_line ::= LINE_CONTINUATION
-                     LINE_HTML shift-reduce 92     html_block_line ::= LINE_HTML
-                     LINE_HTML reduce       52      ** Parsing conflict **
-               html_block_line shift-reduce 53     html_block_lines ::= html_block_lines html_block_line
-                     {default} reduce       52     html_block ::= LINE_HTML html_block_lines
+             LINE_CONTINUATION shift-reduce 99     html_block_line ::= LINE_CONTINUATION
+                     LINE_HTML shift-reduce 100    html_block_line ::= LINE_HTML
+                     LINE_HTML reduce       57      ** Parsing conflict **
+               html_block_line shift-reduce 58     html_block_lines ::= html_block_lines html_block_line
+                     {default} reduce       57     html_block ::= LINE_HTML html_block_lines
 
-State 35:
+State 38:
      (29) blockquote ::= LINE_BLOCKQUOTE quote_lines *
           quote_lines ::= quote_lines * quote_line
           quote_line ::= * LINE_BLOCKQUOTE
           quote_line ::= * LINE_CONTINUATION
 
-             LINE_CONTINUATION shift-reduce 80     quote_line ::= LINE_CONTINUATION
-               LINE_BLOCKQUOTE shift-reduce 79     quote_line ::= LINE_BLOCKQUOTE
+             LINE_CONTINUATION shift-reduce 88     quote_line ::= LINE_CONTINUATION
+               LINE_BLOCKQUOTE shift-reduce 87     quote_line ::= LINE_BLOCKQUOTE
                LINE_BLOCKQUOTE reduce       29      ** Parsing conflict **
                     quote_line shift-reduce 30     quote_lines ::= quote_lines quote_line
                      {default} reduce       29     blockquote ::= LINE_BLOCKQUOTE quote_lines
 
-State 36:
+State 39:
           para_lines ::= para_lines * para_line
           para_line ::= * LINE_CONTINUATION
-     (51) def_link ::= LINE_DEF_LINK para_lines *
+     (56) def_link ::= LINE_DEF_LINK para_lines *
 
-             LINE_CONTINUATION shift-reduce 70     para_line ::= LINE_CONTINUATION
+             LINE_CONTINUATION shift-reduce 78     para_line ::= LINE_CONTINUATION
                      para_line shift-reduce 26     para_lines ::= para_lines para_line
-                     {default} reduce       51     def_link ::= LINE_DEF_LINK para_lines
+                     {default} reduce       56     def_link ::= LINE_DEF_LINK para_lines
 
-State 37:
+State 40:
+     (44) table ::= table_header table_body LINE_EMPTY *
+          table_body ::= table_body LINE_EMPTY * table_section
+          table_section ::= * table_section LINE_TABLE
+          table_section ::= * LINE_TABLE
+
+                    LINE_TABLE shift-reduce 93     table_section ::= LINE_TABLE
+                    LINE_TABLE reduce       44      ** Parsing conflict **
+                 table_section shift        50     
+                     {default} reduce       44     table ::= table_header table_body LINE_EMPTY
+
+State 41:
+          para_lines ::= para_lines * para_line
+          para_line ::= * LINE_CONTINUATION
+     (74) para ::= table_section para_lines *
+
+             LINE_CONTINUATION shift-reduce 78     para_line ::= LINE_CONTINUATION
+                     para_line shift-reduce 26     para_lines ::= para_lines para_line
+                     {default} reduce       74     para ::= table_section para_lines
+
+State 42:
      (25) para ::= LINE_PLAIN para_lines *
           para_lines ::= para_lines * para_line
           para_line ::= * LINE_CONTINUATION
 
-             LINE_CONTINUATION shift-reduce 70     para_line ::= LINE_CONTINUATION
+             LINE_CONTINUATION shift-reduce 78     para_line ::= LINE_CONTINUATION
                      para_line shift-reduce 26     para_lines ::= para_lines para_line
                      {default} reduce       25     para ::= LINE_PLAIN para_lines
 
-State 38:
+State 43:
      (24) block ::= definition_block *
           empty ::= * empty LINE_EMPTY
           empty ::= * LINE_EMPTY
           definition_block ::= definition_block * empty definition
           definition_block ::= definition_block * empty
 
-                    LINE_EMPTY shift-reduce 76     empty ::= LINE_EMPTY
+                    LINE_EMPTY shift-reduce 84     empty ::= LINE_EMPTY
                     LINE_EMPTY reduce       24      ** Parsing conflict **
-                         empty shift        16     
+                         empty shift        10     
                      {default} reduce       24     block ::= definition_block
 
-State 39:
+State 44:
      (13) block ::= list_enumerated *
           list_enumerated ::= list_enumerated * item_enumerated
           item_enumerated ::= * LINE_LIST_ENUMERATED para_lines cont_blocks
@@ -835,16 +927,16 @@ State 39:
                item_enumerated shift-reduce 36     list_enumerated ::= list_enumerated item_enumerated
                      {default} reduce       13     block ::= list_enumerated
 
-State 40:
+State 45:
           para_lines ::= para_lines * para_line
           para_line ::= * LINE_CONTINUATION
      (42) cont_block ::= empty indented_line para_lines *
 
-             LINE_CONTINUATION shift-reduce 70     para_line ::= LINE_CONTINUATION
+             LINE_CONTINUATION shift-reduce 78     para_line ::= LINE_CONTINUATION
                      para_line shift-reduce 26     para_lines ::= para_lines para_line
                      {default} reduce       42     cont_block ::= empty indented_line para_lines
 
-State 41:
+State 46:
      (12) block ::= list_bulleted *
           list_bulleted ::= list_bulleted * item_bulleted
           item_bulleted ::= * LINE_LIST_BULLETED para_lines cont_blocks
@@ -857,35 +949,52 @@ State 41:
                  item_bulleted shift-reduce 31     list_bulleted ::= list_bulleted item_bulleted
                      {default} reduce       12     block ::= list_bulleted
 
-State 42:
+State 47:
           def ::= LINE_DEFINITION * def_lines
-     (66) def ::= LINE_DEFINITION *
+     (71) def ::= LINE_DEFINITION *
           def_lines ::= * def_lines LINE_CONTINUATION
           def_lines ::= * LINE_CONTINUATION
 
-             LINE_CONTINUATION shift-reduce 102    def_lines ::= LINE_CONTINUATION
-                     def_lines shift        46     
-                     {default} reduce       66     def ::= LINE_DEFINITION
+             LINE_CONTINUATION shift-reduce 110    def_lines ::= LINE_CONTINUATION
+                     def_lines shift        53     
+                     {default} reduce       71     def ::= LINE_DEFINITION
 
-State 43:
-     (63) definition ::= para defs *
+State 48:
+     (68) definition ::= para defs *
           defs ::= defs * def
           def ::= * LINE_DEFINITION def_lines
           def ::= * LINE_DEFINITION
 
-               LINE_DEFINITION shift        42     
-                           def shift-reduce 64     defs ::= defs def
-                     {default} reduce       63     definition ::= para defs
+               LINE_DEFINITION shift        47     
+                           def shift-reduce 69     defs ::= defs def
+                     {default} reduce       68     definition ::= para defs
 
-State 44:
-     (15) block ::= table *
-          table ::= table * LINE_TABLE
+State 49:
+     (48) table_body ::= table_section *
+          table_section ::= table_section * LINE_TABLE
 
-                    LINE_TABLE shift-reduce 44     table ::= table LINE_TABLE
-                    LINE_TABLE reduce       15      ** Parsing conflict **
-                     {default} reduce       15     block ::= table
+                    LINE_TABLE shift-reduce 49     table_section ::= table_section LINE_TABLE
+                    LINE_TABLE reduce       48      ** Parsing conflict **
+                     {default} reduce       48     table_body ::= table_section
 
-State 45:
+State 50:
+     (47) table_body ::= table_body LINE_EMPTY table_section *
+          table_section ::= table_section * LINE_TABLE
+
+                    LINE_TABLE shift-reduce 49     table_section ::= table_section LINE_TABLE
+                    LINE_TABLE reduce       47      ** Parsing conflict **
+                     {default} reduce       47     table_body ::= table_body LINE_EMPTY table_section
+
+State 51:
+          table ::= table_header table_body * LINE_EMPTY
+     (45) table ::= table_header table_body *
+          table_body ::= table_body * LINE_EMPTY table_section
+
+                    LINE_EMPTY shift        40     
+                    LINE_EMPTY reduce       45      ** Parsing conflict **
+                     {default} reduce       45     table ::= table_header table_body
+
+State 52:
      (11) block ::= empty *
           empty ::= empty * LINE_EMPTY
 
@@ -893,76 +1002,80 @@ State 45:
                     LINE_EMPTY reduce       11      ** Parsing conflict **
                      {default} reduce       11     block ::= empty
 
-State 46:
-     (65) def ::= LINE_DEFINITION def_lines *
+State 53:
+     (70) def ::= LINE_DEFINITION def_lines *
           def_lines ::= def_lines * LINE_CONTINUATION
 
-             LINE_CONTINUATION shift-reduce 67     def_lines ::= def_lines LINE_CONTINUATION
-                     {default} reduce       65     def ::= LINE_DEFINITION def_lines
+             LINE_CONTINUATION shift-reduce 72     def_lines ::= def_lines LINE_CONTINUATION
+                     {default} reduce       70     def ::= LINE_DEFINITION def_lines
 
 ----------------------------------------------------
 Symbols:
     0: $:
-    1: LINE_CONTINUATION
-    2: LINE_PLAIN
-    3: LINE_INDENTED_TAB
-    4: LINE_INDENTED_SPACE
-    5: LINE_HTML
-    6: LINE_ATX_1
-    7: LINE_ATX_2
-    8: LINE_ATX_3
-    9: LINE_ATX_4
-   10: LINE_ATX_5
-   11: LINE_ATX_6
-   12: LINE_HR
-   13: LINE_BLOCKQUOTE
-   14: LINE_LIST_BULLETED
-   15: LINE_LIST_ENUMERATED
-   16: LINE_TABLE
-   17: LINE_DEF_CITATION
-   18: LINE_DEF_FOOTNOTE
-   19: LINE_DEF_LINK
-   20: LINE_FENCE_BACKTICK
-   21: LINE_FENCE_BACKTICK_START
-   22: LINE_TOC
-   23: LINE_EMPTY
-   24: LINE_META
-   25: LINE_DEFINITION
-   26: error:
-   27: doc: LINE_PLAIN LINE_INDENTED_TAB LINE_INDENTED_SPACE LINE_HTML LINE_ATX_1 LINE_ATX_2 LINE_ATX_3 LINE_ATX_4 LINE_ATX_5 LINE_ATX_6 LINE_HR LINE_BLOCKQUOTE LINE_LIST_BULLETED LINE_LIST_ENUMERATED LINE_TABLE LINE_DEF_CITATION LINE_DEF_FOOTNOTE LINE_DEF_LINK LINE_FENCE_BACKTICK LINE_FENCE_BACKTICK_START LINE_TOC LINE_EMPTY LINE_META
-   28: blocks: LINE_PLAIN LINE_INDENTED_TAB LINE_INDENTED_SPACE LINE_HTML LINE_ATX_1 LINE_ATX_2 LINE_ATX_3 LINE_ATX_4 LINE_ATX_5 LINE_ATX_6 LINE_HR LINE_BLOCKQUOTE LINE_LIST_BULLETED LINE_LIST_ENUMERATED LINE_TABLE LINE_DEF_CITATION LINE_DEF_FOOTNOTE LINE_DEF_LINK LINE_FENCE_BACKTICK LINE_FENCE_BACKTICK_START LINE_TOC LINE_EMPTY LINE_META
-   29: block: LINE_PLAIN LINE_INDENTED_TAB LINE_INDENTED_SPACE LINE_HTML LINE_ATX_1 LINE_ATX_2 LINE_ATX_3 LINE_ATX_4 LINE_ATX_5 LINE_ATX_6 LINE_HR LINE_BLOCKQUOTE LINE_LIST_BULLETED LINE_LIST_ENUMERATED LINE_TABLE LINE_DEF_CITATION LINE_DEF_FOOTNOTE LINE_DEF_LINK LINE_FENCE_BACKTICK LINE_FENCE_BACKTICK_START LINE_TOC LINE_EMPTY LINE_META
-   30: para: LINE_PLAIN
-   31: indented_code: LINE_INDENTED_TAB LINE_INDENTED_SPACE
-   32: empty: LINE_EMPTY
-   33: list_bulleted: LINE_LIST_BULLETED
-   34: list_enumerated: LINE_LIST_ENUMERATED
-   35: blockquote: LINE_BLOCKQUOTE
-   36: table: LINE_TABLE
-   37: def_citation: LINE_DEF_CITATION
-   38: def_footnote: LINE_DEF_FOOTNOTE
-   39: def_link: LINE_DEF_LINK
-   40: html_block: LINE_HTML
-   41: fenced_block: LINE_FENCE_BACKTICK LINE_FENCE_BACKTICK_START
-   42: meta_block: LINE_META
-   43: definition_block: LINE_PLAIN
-   44: para_lines: LINE_CONTINUATION
-   45: para_line: LINE_CONTINUATION
-   46: code_line: LINE_INDENTED_TAB LINE_INDENTED_SPACE LINE_EMPTY
-   47: indented_line: LINE_INDENTED_TAB LINE_INDENTED_SPACE
-   48: quote_lines: LINE_CONTINUATION LINE_BLOCKQUOTE
-   49: quote_line: LINE_CONTINUATION LINE_BLOCKQUOTE
-   50: item_bulleted: LINE_LIST_BULLETED
-   51: cont_blocks: LINE_EMPTY
-   52: item_enumerated: LINE_LIST_ENUMERATED
-   53: cont_block: LINE_EMPTY
-   54: html_block_lines: LINE_CONTINUATION LINE_HTML
-   55: html_block_line: LINE_CONTINUATION LINE_HTML
-   56: fenced_lines: LINE_CONTINUATION LINE_EMPTY
-   57: fenced_line: LINE_CONTINUATION LINE_EMPTY
-   58: meta_lines: LINE_CONTINUATION LINE_META
-   59: meta_line: LINE_CONTINUATION LINE_META
-   60: definition: LINE_PLAIN
-   61: defs: LINE_DEFINITION
-   62: def: LINE_DEFINITION
-   63: def_lines: LINE_CONTINUATION
+    1: LINE_PLAIN
+    2: LINE_TABLE_SEPARATOR
+    3: LINE_CONTINUATION
+    4: LINE_INDENTED_TAB
+    5: LINE_INDENTED_SPACE
+    6: LINE_HTML
+    7: LINE_ATX_1
+    8: LINE_ATX_2
+    9: LINE_ATX_3
+   10: LINE_ATX_4
+   11: LINE_ATX_5
+   12: LINE_ATX_6
+   13: LINE_HR
+   14: LINE_BLOCKQUOTE
+   15: LINE_LIST_BULLETED
+   16: LINE_LIST_ENUMERATED
+   17: LINE_TABLE
+   18: LINE_DEF_CITATION
+   19: LINE_DEF_FOOTNOTE
+   20: LINE_DEF_LINK
+   21: LINE_FENCE_BACKTICK
+   22: LINE_FENCE_BACKTICK_START
+   23: LINE_TOC
+   24: LINE_EMPTY
+   25: LINE_META
+   26: LINE_DEFINITION
+   27: error:
+   28: doc: LINE_PLAIN LINE_INDENTED_TAB LINE_INDENTED_SPACE LINE_HTML LINE_ATX_1 LINE_ATX_2 LINE_ATX_3 LINE_ATX_4 LINE_ATX_5 LINE_ATX_6 LINE_HR LINE_BLOCKQUOTE LINE_LIST_BULLETED LINE_LIST_ENUMERATED LINE_TABLE LINE_DEF_CITATION LINE_DEF_FOOTNOTE LINE_DEF_LINK LINE_FENCE_BACKTICK LINE_FENCE_BACKTICK_START LINE_TOC LINE_EMPTY LINE_META
+   29: blocks: LINE_PLAIN LINE_INDENTED_TAB LINE_INDENTED_SPACE LINE_HTML LINE_ATX_1 LINE_ATX_2 LINE_ATX_3 LINE_ATX_4 LINE_ATX_5 LINE_ATX_6 LINE_HR LINE_BLOCKQUOTE LINE_LIST_BULLETED LINE_LIST_ENUMERATED LINE_TABLE LINE_DEF_CITATION LINE_DEF_FOOTNOTE LINE_DEF_LINK LINE_FENCE_BACKTICK LINE_FENCE_BACKTICK_START LINE_TOC LINE_EMPTY LINE_META
+   30: block: LINE_PLAIN LINE_INDENTED_TAB LINE_INDENTED_SPACE LINE_HTML LINE_ATX_1 LINE_ATX_2 LINE_ATX_3 LINE_ATX_4 LINE_ATX_5 LINE_ATX_6 LINE_HR LINE_BLOCKQUOTE LINE_LIST_BULLETED LINE_LIST_ENUMERATED LINE_TABLE LINE_DEF_CITATION LINE_DEF_FOOTNOTE LINE_DEF_LINK LINE_FENCE_BACKTICK LINE_FENCE_BACKTICK_START LINE_TOC LINE_EMPTY LINE_META
+   31: para: LINE_PLAIN LINE_TABLE
+   32: indented_code: LINE_INDENTED_TAB LINE_INDENTED_SPACE
+   33: empty: LINE_EMPTY
+   34: list_bulleted: LINE_LIST_BULLETED
+   35: list_enumerated: LINE_LIST_ENUMERATED
+   36: blockquote: LINE_BLOCKQUOTE
+   37: table: LINE_TABLE
+   38: def_citation: LINE_DEF_CITATION
+   39: def_footnote: LINE_DEF_FOOTNOTE
+   40: def_link: LINE_DEF_LINK
+   41: html_block: LINE_HTML
+   42: fenced_block: LINE_FENCE_BACKTICK LINE_FENCE_BACKTICK_START
+   43: meta_block: LINE_META
+   44: definition_block: LINE_PLAIN LINE_TABLE
+   45: para_lines: LINE_CONTINUATION
+   46: para_line: LINE_CONTINUATION
+   47: code_line: LINE_INDENTED_TAB LINE_INDENTED_SPACE LINE_EMPTY
+   48: indented_line: LINE_INDENTED_TAB LINE_INDENTED_SPACE
+   49: quote_lines: LINE_CONTINUATION LINE_BLOCKQUOTE
+   50: quote_line: LINE_CONTINUATION LINE_BLOCKQUOTE
+   51: item_bulleted: LINE_LIST_BULLETED
+   52: cont_blocks: LINE_EMPTY
+   53: item_enumerated: LINE_LIST_ENUMERATED
+   54: cont_block: LINE_EMPTY
+   55: table_header: LINE_TABLE
+   56: table_body: LINE_TABLE
+   57: table_section: LINE_TABLE
+   58: html_block_lines: LINE_CONTINUATION LINE_HTML
+   59: html_block_line: LINE_CONTINUATION LINE_HTML
+   60: fenced_lines: LINE_CONTINUATION LINE_EMPTY
+   61: fenced_line: LINE_CONTINUATION LINE_EMPTY
+   62: meta_lines: LINE_CONTINUATION LINE_META
+   63: meta_line: LINE_CONTINUATION LINE_META
+   64: definition: LINE_PLAIN LINE_TABLE
+   65: defs: LINE_DEFINITION
+   66: def: LINE_DEFINITION
+   67: def_lines: LINE_CONTINUATION
index d53ab98e9992019fa6c5b0e67cee98c5e08942f2..752fb84a6cdd1255a3dd1893d3848a8f25089f70 100644 (file)
@@ -62,6 +62,8 @@
 
 %extra_argument { mmd_engine * engine }
 
+%fallback LINE_PLAIN LINE_TABLE_SEPARATOR.
+
 %fallback LINE_CONTINUATION LINE_PLAIN LINE_INDENTED_TAB LINE_INDENTED_SPACE.
 
 %fallback LINE_HTML LINE_ATX_1 LINE_ATX_2 LINE_ATX_3 LINE_ATX_4 LINE_ATX_5 LINE_ATX_6 LINE_HR LINE_BLOCKQUOTE LINE_LIST_BULLETED LINE_LIST_ENUMERATED LINE_TABLE LINE_DEF_CITATION LINE_DEF_FOOTNOTE LINE_DEF_LINK LINE_FENCE_BACKTICK LINE_FENCE_BACKTICK_START.
@@ -163,8 +165,16 @@ cont_block(A)              ::= empty(B) indented_line(C) para_lines(D).{ A = B; token_chain_
 cont_block(A)          ::= empty(B) indented_line(C).                          { A = B; token_chain_append(B, C); C->type = LINE_CONTINUATION; }
 cont_block                     ::= empty.
 
-table(A)                       ::= table(B) LINE_TABLE(C).                                     { A = B; token_chain_append(B, C); }
-table                          ::= LINE_TABLE.
+table(A)                       ::= table_header(B) table_body(C) LINE_EMPTY(D).        { A = B; token_chain_append(B, C); token_chain_append(B, D); }
+table(A)                       ::= table_header(B) table_body(C).                      { A = B; token_chain_append(B, C); }
+
+table_header(A)                ::= table_section(B) LINE_TABLE_SEPARATOR(C).   { A = token_new_parent(B, BLOCK_TABLE_HEADER); token_chain_append(B, C); }
+
+table_body(A)          ::= table_body(B) LINE_EMPTY(C) table_section(D).       { A = B; token_chain_append(B, C); token_chain_append(B, token_new_parent(D, BLOCK_TABLE_SECTION)); }
+table_body(A)          ::= table_section(B).                                           { A = token_new_parent(B, BLOCK_TABLE_SECTION); }
+
+table_section(A)       ::= table_section(B) LINE_TABLE(C).                     { A = B; token_chain_append(B, C); }
+table_section          ::= LINE_TABLE.
 
 def_citation(A)                ::= LINE_DEF_CITATION(B) para_lines(C) cont_blocks(D).  { A = B; token_chain_append(B, C); token_chain_append(B, D); }
 def_citation(A)                ::= LINE_DEF_CITATION(B) para_lines(C).         { A = B; token_chain_append(B, C); }
@@ -227,6 +237,13 @@ def_lines(A)               ::= def_lines(B) LINE_CONTINUATION(C).          { A = B; token_chain_appen
 def_lines                      ::= LINE_CONTINUATION.
 
 
+// Fallbacks for improper structures
+para(A)                                ::= table_section(B) LINE_EMPTY(C).                     { A = B; token_chain_append(B, C); }
+para(A)                                ::= table_section(B) para_lines(C).                     { A = B; token_chain_append(B, C); }
+para(A)                                ::= table_section(B).                                           { A = B; }
+
+
+
 //
 // Additional Configuration
 //
index e8e2d78cbd7c34d7f4b340632b7f4bc99a1dcf06..8dae2a147b95df1894e584ae7d65b5c1f75490f7 100644 (file)
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.14.3 on Sat Feb  4 08:26:54 2017 */
+/* Generated by re2c 0.14.3 on Sat Feb  4 17:39:29 2017 */
 /**
 
        MultiMarkdown 6 -- Lightweight markup processor to produce HTML, LaTeX, and more.
@@ -9041,6 +9041,354 @@ yy655:
 }
 
 
+size_t scan_table_separator(const char * c) {
+       const char * marker = NULL;
+       const char * start = c;
+
+
+{
+       char yych;
+       yych = *c;
+       switch (yych) {
+       case '\t':
+       case ' ':
+       case '+':
+       case '-':
+       case ':':
+       case '=':       goto yy660;
+       case '\n':      goto yy658;
+       case '|':       goto yy659;
+       default:        goto yy661;
+       }
+yy658:
+       { return 0; }
+yy659:
+       yych = *(marker = ++c);
+       switch (yych) {
+       case '\t':
+       case '\n':
+       case '\r':
+       case ' ':
+       case '+':
+       case '-':
+       case ':':
+       case '=':
+       case '|':       goto yy671;
+       default:        goto yy658;
+       }
+yy660:
+       yych = *(marker = ++c);
+       switch (yych) {
+       case '\t':
+       case ' ':
+       case '+':
+       case '-':
+       case ':':
+       case '=':       goto yy665;
+       case '|':       goto yy662;
+       default:        goto yy658;
+       }
+yy661:
+       yych = *++c;
+       goto yy658;
+yy662:
+       ++c;
+       yych = *c;
+       switch (yych) {
+       case '\t':
+       case ' ':
+       case '+':
+       case '-':
+       case ':':
+       case '=':
+       case '|':       goto yy662;
+       case '\n':      goto yy667;
+       case '\r':      goto yy669;
+       default:        goto yy664;
+       }
+yy664:
+       c = marker;
+       goto yy658;
+yy665:
+       ++c;
+       yych = *c;
+       switch (yych) {
+       case '\t':
+       case ' ':
+       case '+':
+       case '-':
+       case ':':
+       case '=':       goto yy665;
+       case '|':       goto yy662;
+       default:        goto yy664;
+       }
+yy667:
+       ++c;
+yy668:
+       { return (size_t)( c - start ); }
+yy669:
+       yych = *++c;
+       switch (yych) {
+       case '\n':      goto yy667;
+       default:        goto yy668;
+       }
+yy670:
+       ++c;
+       yych = *c;
+yy671:
+       switch (yych) {
+       case '\t':
+       case ' ':
+       case '+':
+       case '-':
+       case ':':
+       case '=':
+       case '|':       goto yy670;
+       case '\n':      goto yy667;
+       case '\r':      goto yy669;
+       default:        goto yy664;
+       }
+}
+       
+}
+
+
+size_t scan_alignment_string(const char * c) {
+       const char * marker = NULL;
+
+
+{
+       char yych;
+       yych = *c;
+       switch (yych) {
+       case '\t':
+       case ' ':       goto yy675;
+       case '\n':      goto yy674;
+       case '-':
+       case '=':       goto yy677;
+       case ':':       goto yy676;
+       default:        goto yy678;
+       }
+yy674:
+       { return 0; }
+yy675:
+       yych = *(marker = ++c);
+       switch (yych) {
+       case '\t':
+       case ' ':       goto yy717;
+       case '-':
+       case '=':       goto yy681;
+       case ':':       goto yy716;
+       default:        goto yy674;
+       }
+yy676:
+       yych = *(marker = ++c);
+       switch (yych) {
+       case '-':
+       case '=':       goto yy693;
+       default:        goto yy674;
+       }
+yy677:
+       yych = *(marker = ++c);
+       switch (yych) {
+       case '-':
+       case '=':       goto yy681;
+       case ':':       goto yy679;
+       default:        goto yy674;
+       }
+yy678:
+       yych = *++c;
+       goto yy674;
+yy679:
+       yych = *++c;
+       switch (yych) {
+       case '+':       goto yy688;
+       default:        goto yy684;
+       }
+yy680:
+       c = marker;
+       goto yy674;
+yy681:
+       ++c;
+       yych = *c;
+       switch (yych) {
+       case '-':
+       case '=':       goto yy681;
+       case ':':       goto yy679;
+       default:        goto yy680;
+       }
+yy683:
+       ++c;
+       yych = *c;
+yy684:
+       switch (yych) {
+       case '\t':
+       case ' ':       goto yy683;
+       case '\n':
+       case '|':       goto yy685;
+       case '\r':      goto yy687;
+       default:        goto yy680;
+       }
+yy685:
+       ++c;
+yy686:
+       { return ALIGN_RIGHT; }
+yy687:
+       yych = *++c;
+       switch (yych) {
+       case '\n':      goto yy685;
+       default:        goto yy686;
+       }
+yy688:
+       ++c;
+       yych = *c;
+       switch (yych) {
+       case '\t':
+       case ' ':       goto yy688;
+       case '\n':
+       case '|':       goto yy690;
+       case '\r':      goto yy692;
+       default:        goto yy680;
+       }
+yy690:
+       ++c;
+yy691:
+       { return ALIGN_WRAP | ALIGN_RIGHT; }
+yy692:
+       yych = *++c;
+       switch (yych) {
+       case '\n':      goto yy690;
+       default:        goto yy691;
+       }
+yy693:
+       ++c;
+       yych = *c;
+       switch (yych) {
+       case '\t':
+       case ' ':       goto yy695;
+       case '\n':
+       case '|':       goto yy697;
+       case '\r':      goto yy699;
+       case '+':       goto yy701;
+       case '-':
+       case '=':       goto yy693;
+       case ':':       goto yy700;
+       default:        goto yy680;
+       }
+yy695:
+       ++c;
+       yych = *c;
+       switch (yych) {
+       case '\t':
+       case ' ':       goto yy695;
+       case '\n':
+       case '|':       goto yy697;
+       case '\r':      goto yy699;
+       default:        goto yy680;
+       }
+yy697:
+       ++c;
+yy698:
+       { return ALIGN_LEFT; }
+yy699:
+       yych = *++c;
+       switch (yych) {
+       case '\n':      goto yy697;
+       default:        goto yy698;
+       }
+yy700:
+       yych = *++c;
+       switch (yych) {
+       case '+':       goto yy706;
+       default:        goto yy709;
+       }
+yy701:
+       ++c;
+       yych = *c;
+       switch (yych) {
+       case '\t':
+       case ' ':       goto yy701;
+       case '\n':
+       case '|':       goto yy703;
+       case '\r':      goto yy705;
+       default:        goto yy680;
+       }
+yy703:
+       ++c;
+yy704:
+       { return ALIGN_WRAP | ALIGN_LEFT; }
+yy705:
+       yych = *++c;
+       switch (yych) {
+       case '\n':      goto yy703;
+       default:        goto yy704;
+       }
+yy706:
+       ++c;
+       yych = *c;
+       switch (yych) {
+       case '\t':
+       case ' ':       goto yy706;
+       case '\n':
+       case '|':       goto yy713;
+       case '\r':      goto yy715;
+       default:        goto yy680;
+       }
+yy708:
+       ++c;
+       yych = *c;
+yy709:
+       switch (yych) {
+       case '\t':
+       case ' ':       goto yy708;
+       case '\n':
+       case '|':       goto yy710;
+       case '\r':      goto yy712;
+       default:        goto yy680;
+       }
+yy710:
+       ++c;
+yy711:
+       { return ALIGN_CENTER; }
+yy712:
+       yych = *++c;
+       switch (yych) {
+       case '\n':      goto yy710;
+       default:        goto yy711;
+       }
+yy713:
+       ++c;
+yy714:
+       { return ALIGN_WRAP | ALIGN_CENTER; }
+yy715:
+       yych = *++c;
+       switch (yych) {
+       case '\n':      goto yy713;
+       default:        goto yy714;
+       }
+yy716:
+       yych = *++c;
+       switch (yych) {
+       case '-':
+       case '=':       goto yy693;
+       default:        goto yy680;
+       }
+yy717:
+       ++c;
+       yych = *c;
+       switch (yych) {
+       case '\t':
+       case ' ':       goto yy717;
+       case '-':
+       case '=':       goto yy681;
+       case ':':       goto yy716;
+       default:        goto yy680;
+       }
+}
+       
+}
+
+
 #ifdef TEST
 void Test_scan_url(CuTest* tc) {
        int url_len;
index 6233483d9d0a0561a102aa942d6caf7112680da4..6abd6bb7a377ba2dee66a565dfaa6cebaa1cd474 100644 (file)
 #include "CuTest.h"
 #endif
 
+enum alignments {
+       ALIGN_LEFT      = 1 << 0,
+       ALIGN_RIGHT     = 1 << 1,
+       ALIGN_CENTER    = 1 << 2,
+       ALIGN_WRAP      = 1 << 3
+};
+
+
+size_t scan_alignment_string(const char * c);
 size_t scan_attr(const char * c);
 size_t scan_attributes(const char * c);
 size_t scan_definition(const char * c);
@@ -78,6 +87,7 @@ size_t scan_ref_foot(const char * c);
 size_t scan_ref_link(const char * c);
 size_t scan_ref_link_no_attributes(const char * c);
 size_t scan_spnl(const char * c);
+size_t scan_table_separator(const char * c);
 size_t scan_url(const char * c);
 size_t scan_value(const char * c);
 
index 5956de09e0910ec6f39dbe4bc952e1b8e9b2aeef..e6e804038ae82ccd55461b0353cafcb6c0138fe9 100644 (file)
        meta_line       = meta_key sp ':' meta_value nl;        // meta_line can't match url above
 
        definition      = non_indent ':' sp [^\n\r\x00];
+
+       table_separator = (('|' [:\-= \t|+]*) | ([:\-= \t+]+ '|' [:\-= \t|+]*)) nl;
+
+       align           = [\-=]+;
+       align_left      = sp ':' align sp ('|' | nl);
+       align_right     = sp align ':' sp ('|' | nl);
+       align_center    = sp ':' align ':' sp ('|' | nl);
+       align_wrap_left         = sp ':' align '+' sp ('|' | nl);
+       align_wrap_right        = sp align ':' '+' sp ('|' | nl);
+       align_wrap_center       = sp ':' align ':' '+' sp ('|' | nl);
+
 */
 
 
@@ -348,6 +359,34 @@ size_t scan_definition(const char * c) {
 }
 
 
+size_t scan_table_separator(const char * c) {
+       const char * marker = NULL;
+       const char * start = c;
+
+/*!re2c
+       table_separator { return (size_t)( c - start ); }
+       .?                      { return 0; }
+*/     
+}
+
+
+size_t scan_alignment_string(const char * c) {
+       const char * marker = NULL;
+
+/*!re2c
+       align_left              { return ALIGN_LEFT; }
+       align_right             { return ALIGN_RIGHT; }
+       align_center    { return ALIGN_CENTER; }
+
+       align_wrap_left         { return ALIGN_WRAP | ALIGN_LEFT; }
+       align_wrap_right        { return ALIGN_WRAP | ALIGN_RIGHT; }
+       align_wrap_center       { return ALIGN_WRAP | ALIGN_CENTER; }
+
+       .?                      { return 0; }
+*/     
+}
+
+
 #ifdef TEST
 void Test_scan_url(CuTest* tc) {
        int url_len;
index 17cd42770e9a7d03e3f44856f6869323b346edd5..e9983756b0707497440103fff32accb03daebbb7 100644 (file)
@@ -134,6 +134,10 @@ token * token_new(unsigned short type, size_t start, size_t len) {
 
 /// Create a parent for a chain of tokens
 token * token_new_parent(token * child, unsigned short type) {
+       if (child == NULL) {
+               return token_new(type, 0, 0);
+       }
+       
        token * t = token_new(type, child->start, 0);
        t->child = child;
        child->prev = NULL;
index 3adaa6c299cc0d14e95ad4deaa8063c769949806..8fc6853a6f4e43f4c84eca22bee93b63c2d50d58 100644 (file)
@@ -1353,3 +1353,61 @@ void citation_from_bracket(const char * source, scratch_pad * scratch, token * t
        }
 }
 
+
+void read_table_column_alignments(const char * source, token * table, scratch_pad * scratch) {
+       token * walker = table->child->child;
+
+       // Find the separator line      
+       while (walker->next) 
+               walker = walker->next;
+
+       walker->type = TEXT_EMPTY;
+
+       // Iterate through cells to create alignment string
+       short counter = 0;
+       short align = 0;
+
+       walker = walker->child;
+
+       while (walker) {
+               switch (walker->type) {
+                       case TABLE_CELL:
+                               align = scan_alignment_string(&source[walker->start]);
+
+                               switch (align) {
+                                       case ALIGN_LEFT:
+                                               scratch->table_alignment[counter] = 'l';
+                                               break;
+                                       case ALIGN_RIGHT:
+                                               scratch->table_alignment[counter] = 'r';
+                                               break;
+                                       case ALIGN_CENTER:
+                                               scratch->table_alignment[counter] = 'c';
+                                               break;
+                                       case ALIGN_LEFT | ALIGN_WRAP:
+                                               scratch->table_alignment[counter] = 'L';
+                                               break;
+                                       case ALIGN_RIGHT | ALIGN_WRAP:
+                                               scratch->table_alignment[counter] = 'R';
+                                               break;
+                                       case ALIGN_CENTER | ALIGN_WRAP:
+                                               scratch->table_alignment[counter] = 'C';
+                                               break;
+                                       case ALIGN_WRAP:
+                                               scratch->table_alignment[counter] = 'C';
+                                               break;
+                                       default:
+                                               scratch->table_alignment[counter] = 'n';
+                               }
+
+                               counter++;
+                               break;
+               }
+
+               walker = walker->next;
+       }
+
+       scratch->table_alignment[counter] = '\0';
+       scratch->table_column_count = counter;
+}
+
index d94c676c84081ae6bc814c358a81d59b9a1e616d..106f626dfc0d0815f599b10c9501a356ddbe91bc 100644 (file)
@@ -69,6 +69,7 @@
 
 #define kMaxExportRecursiveDepth 1000          //!< Maximum recursion depth when exporting token tree -- to prevent stack overflow with "pathologic" input
 
+#define kMaxTableColumns 48                                    //!< Maximum number of table columns for specifying alignment
 
 typedef struct {
        struct link *           link_hash;
@@ -97,6 +98,11 @@ typedef struct {
 
        short                           recurse_depth;
        
+       short                           in_table_header;
+       short                           table_column_count;
+       short                           table_cell_count;
+       char                            table_alignment[kMaxTableColumns];
+
        char                            _PADDING[4];    //!< pad struct for alignment
 
 } scratch_pad;
@@ -189,5 +195,7 @@ void meta_set_value(meta * m, const char * value);
 void meta_free(meta * m);
 char * extract_metadata(scratch_pad * scratch, const char * target);
 
+void read_table_column_alignments(const char * source, token * table, scratch_pad * scratch);
+
 #endif
 
index fe61d345de4c43d104c0a57cc72d2eddb6c3d3cb..57d368bd51819353abb4424814dc9514955ac254 100644 (file)
@@ -86,4 +86,4 @@ bar</p>
 
 <p>This is <em><strong>another</strong> test</em> of <em>italics</em> and <strong>bold</strong>.</p>
 
-<p>*a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a </p>
+<p>*a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a</p>
index 6e1a2c56ff0e10c5e8a7eb91744bf4601c538587..e1869f918e992ce2e6367371793b5aa9240c7ce7 100644 (file)
@@ -86,4 +86,4 @@ bar</p>
 
 <p>This is <em><strong>another</strong> test</em> of <em>italics</em> and <strong>bold</strong>.</p>
 
-<p>*a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a </p>
+<p>*a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a *a</p>
diff --git a/tests/MMD6Tests/Tables.html b/tests/MMD6Tests/Tables.html
new file mode 100644 (file)
index 0000000..4e4c245
--- /dev/null
@@ -0,0 +1,44 @@
+<table>
+<caption id="prototypetable">Prototype table</caption>
+<colgroup>
+<col />
+<col style="text-align:center;"/>
+<col style="text-align:right;"/>
+</colgroup>
+
+<thead>
+<tr>
+       <th>    </th>
+       <th style="text-align:center;" colspan="2">   Grouping   </th>
+</tr>
+<tr>
+       <th>First Header </th>
+       <th style="text-align:center;"> Second Header </th>
+       <th style="text-align:right;"> Third Header </th>
+</tr>
+</thead>
+
+<tbody>
+<tr>
+       <td>Content  </td>
+       <td style="text-align:center;" colspan="2">   <em>Long Cell</em>  </td>
+</tr>
+<tr>
+       <td> Content  </td>
+       <td style="text-align:center;"> <strong>Cell</strong> </td>
+       <td style="text-align:right;">   Cell </td>
+</tr>
+</tbody>
+
+<tbody>
+<tr>
+       <td>New section </td>
+       <td style="text-align:center;">  More  </td>
+       <td style="text-align:right;">   Data</td>
+</tr>
+<tr>
+       <td colspan="2">And more  </td>
+       <td style="text-align:right;"> With an escaped &#8216;|&#8217;   </td>
+</tr>
+</tbody>
+</table>
diff --git a/tests/MMD6Tests/Tables.htmlc b/tests/MMD6Tests/Tables.htmlc
new file mode 100644 (file)
index 0000000..06c07d9
--- /dev/null
@@ -0,0 +1,9 @@
+<p>|    |   Grouping   ||
+First Header | Second Header | Third Header |
+------------ | :-----------: | -----------: |
+Content  |   <em>Long Cell</em>  ||
+| Content  | <strong>Cell</strong> |   Cell |</p>
+
+<p>New section |  More  |   Data
+And more  || With an escaped '|'   |<br />
+[Prototype table]</p>
diff --git a/tests/MMD6Tests/Tables.text b/tests/MMD6Tests/Tables.text
new file mode 100644 (file)
index 0000000..d5b1151
--- /dev/null
@@ -0,0 +1,10 @@
+[Prototype table]
+|             |          Grouping           ||
+First Header  | Second Header | Third Header |
+ ------------ | :-----------: | -----------: |
+Content       |          *Long Cell*        || 
+| Content       |   **Cell**    |         Cell |  
+
+New section   |     More      |         Data
+And more      || With an escaped '\|'         |  
+[Prototype table]