rdiscount 2.0.7.3 → 2.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,100 @@
1
+
2
+ /*
3
+ * github_flavoured -- implement the obnoxious "returns are hard newlines"
4
+ * feature in github flavoured markdown.
5
+ *
6
+ * Copyright (C) 2012 David L Parsons.
7
+ * The redistribution terms are provided in the COPYRIGHT file that must
8
+ * be distributed with this source code.
9
+ */
10
+ #include "config.h"
11
+ #include <stdio.h>
12
+ #include <stdlib.h>
13
+ #include <ctype.h>
14
+
15
+ #include "cstring.h"
16
+ #include "markdown.h"
17
+ #include "amalloc.h"
18
+
19
+ /* build a Document from any old input.
20
+ */
21
+ typedef int (*getc_func)(void*);
22
+
23
+ Document *
24
+ gfm_populate(getc_func getc, void* ctx, int flags)
25
+ {
26
+ Cstring line;
27
+ Document *a = __mkd_new_Document();
28
+ int c;
29
+ int pandoc = 0;
30
+
31
+ if ( !a ) return 0;
32
+
33
+ a->tabstop = (flags & MKD_TABSTOP) ? 4 : TABSTOP;
34
+
35
+ CREATE(line);
36
+
37
+ while ( (c = (*getc)(ctx)) != EOF ) {
38
+ if ( c == '\n' ) {
39
+ if ( pandoc != EOF && pandoc < 3 ) {
40
+ if ( S(line) && (T(line)[0] == '%') )
41
+ pandoc++;
42
+ else
43
+ pandoc = EOF;
44
+ }
45
+
46
+ if (pandoc == EOF) {
47
+ EXPAND(line) = ' ';
48
+ EXPAND(line) = ' ';
49
+ }
50
+ __mkd_enqueue(a, &line);
51
+ S(line) = 0;
52
+ }
53
+ else if ( isprint(c) || isspace(c) || (c & 0x80) )
54
+ EXPAND(line) = c;
55
+ }
56
+
57
+ if ( S(line) )
58
+ __mkd_enqueue(a, &line);
59
+
60
+ DELETE(line);
61
+
62
+ if ( (pandoc == 3) && !(flags & (MKD_NOHEADER|MKD_STRICT)) ) {
63
+ /* the first three lines started with %, so we have a header.
64
+ * clip the first three lines out of content and hang them
65
+ * off header.
66
+ */
67
+ Line *headers = T(a->content);
68
+
69
+ a->title = headers; __mkd_header_dle(a->title);
70
+ a->author= headers->next; __mkd_header_dle(a->author);
71
+ a->date = headers->next->next; __mkd_header_dle(a->date);
72
+
73
+ T(a->content) = headers->next->next->next;
74
+ }
75
+
76
+ return a;
77
+ }
78
+
79
+
80
+ /* convert a block of text into a linked list
81
+ */
82
+ Document *
83
+ gfm_string(const char *buf, int len, DWORD flags)
84
+ {
85
+ struct string_stream about;
86
+
87
+ about.data = buf;
88
+ about.size = len;
89
+
90
+ return gfm_populate((getc_func)__mkd_io_strget, &about, flags & INPUT_MASK);
91
+ }
92
+
93
+
94
+ /* convert a file into a linked list
95
+ */
96
+ Document *
97
+ gfm_in(FILE *f, DWORD flags)
98
+ {
99
+ return gfm_populate((getc_func)fgetc, f, flags & INPUT_MASK);
100
+ }
data/ext/html5.c CHANGED
@@ -10,8 +10,6 @@ mkd_with_html5_tags()
10
10
  if ( populated ) return;
11
11
  populated = 1;
12
12
 
13
- mkd_prepare_tags();
14
-
15
13
  mkd_define_tag("ASIDE", 0);
16
14
  mkd_define_tag("FOOTER", 0);
17
15
  mkd_define_tag("HEADER", 0);
data/ext/markdown.c CHANGED
@@ -22,6 +22,9 @@ typedef int (*stfu)(const void*,const void*);
22
22
 
23
23
  typedef ANCHOR(Paragraph) ParagraphRoot;
24
24
 
25
+ static Paragraph *Pp(ParagraphRoot *, Line *, int);
26
+ static Paragraph *compile(Line *, int, MMIOT *);
27
+
25
28
  /* case insensitive string sort for Footnote tags.
26
29
  */
27
30
  int
@@ -77,7 +80,7 @@ mkd_firstnonblank(Line *p)
77
80
  }
78
81
 
79
82
 
80
- static int
83
+ static inline int
81
84
  blankline(Line *p)
82
85
  {
83
86
  return ! (p && (S(p->text) > p->dle) );
@@ -173,6 +176,68 @@ splitline(Line *t, int cutpoint)
173
176
  }
174
177
  }
175
178
 
179
+ #define UNCHECK(l) ((l)->flags &= ~CHECKED)
180
+
181
+ /*
182
+ * walk a line, seeing if it's any of half a dozen interesting regular
183
+ * types.
184
+ */
185
+ static void
186
+ checkline(Line *l)
187
+ {
188
+ int eol, i;
189
+ int dashes = 0, spaces = 0,
190
+ equals = 0, underscores = 0,
191
+ stars = 0, tildes = 0,
192
+ backticks = 0;
193
+
194
+ l->flags |= CHECKED;
195
+ l->kind = chk_text;
196
+ l->count = 0;
197
+
198
+ if (l->dle >= 4) { l->kind=chk_code; return; }
199
+
200
+ for ( eol = S(l->text); eol > l->dle && isspace(T(l->text)[eol-1]); --eol )
201
+ ;
202
+
203
+ for (i=l->dle; i<eol; i++) {
204
+ register int c = T(l->text)[i];
205
+
206
+ if ( c != ' ' ) l->count++;
207
+
208
+ switch (c) {
209
+ case '-': dashes = 1; break;
210
+ case ' ': spaces = 1; break;
211
+ case '=': equals = 1; break;
212
+ case '_': underscores = 1; break;
213
+ case '*': stars = 1; break;
214
+ #if WITH_FENCED_CODE
215
+ case '~': tildes = 1; break;
216
+ case '`': backticks = 1; break;
217
+ #endif
218
+ default: return;
219
+ }
220
+ }
221
+
222
+ if ( dashes + equals + underscores + stars + tildes + backticks > 1 )
223
+ return;
224
+
225
+ if ( spaces ) {
226
+ if ( (underscores || stars || dashes) )
227
+ l->kind = chk_hr;
228
+ return;
229
+ }
230
+
231
+ if ( stars || underscores ) { l->kind = chk_hr; }
232
+ else if ( dashes ) { l->kind = chk_dash; }
233
+ else if ( equals ) { l->kind = chk_equal; }
234
+ #if WITH_FENCED_CODE
235
+ else if ( tildes ) { l->kind = chk_tilde; }
236
+ else if ( backticks ) { l->kind = chk_backtick; }
237
+ #endif
238
+ }
239
+
240
+
176
241
 
177
242
  static Line *
178
243
  commentblock(Paragraph *p, int *unclosed)
@@ -261,37 +326,6 @@ htmlblock(Paragraph *p, struct kw *tag, int *unclosed)
261
326
  }
262
327
 
263
328
 
264
- /* tables look like
265
- * header|header{|header}
266
- * ------|------{|......}
267
- * {body lines}
268
- */
269
- static int
270
- istable(Line *t)
271
- {
272
- char *p;
273
- Line *dashes = t->next;
274
- int contains = 0; /* found character bits; 0x01 is |, 0x02 is - */
275
-
276
- /* two lines, first must contain | */
277
- if ( !(dashes && memchr(T(t->text), '|', S(t->text))) )
278
- return 0;
279
-
280
- /* second line must contain - or | and nothing
281
- * else except for whitespace or :
282
- */
283
- for ( p = T(dashes->text)+S(dashes->text)-1; p >= T(dashes->text); --p)
284
- if ( *p == '|' )
285
- contains |= 0x01;
286
- else if ( *p == '-' )
287
- contains |= 0x02;
288
- else if ( ! ((*p == ':') || isspace(*p)) )
289
- return 0;
290
-
291
- return (contains & 0x03);
292
- }
293
-
294
-
295
329
  /* footnotes look like ^<whitespace>{0,3}[stuff]: <content>$
296
330
  */
297
331
  static int
@@ -312,76 +346,46 @@ isfootnote(Line *t)
312
346
  }
313
347
 
314
348
 
315
- static int
349
+ static inline int
316
350
  isquote(Line *t)
317
351
  {
318
- int j;
319
-
320
- for ( j=0; j < 4; j++ )
321
- if ( T(t->text)[j] == '>' )
322
- return 1;
323
- else if ( !isspace(T(t->text)[j]) )
324
- return 0;
325
- return 0;
352
+ return (t->dle < 4 && T(t->text)[t->dle] == '>');
326
353
  }
327
354
 
328
355
 
329
- static int
330
- dashchar(char c)
331
- {
332
- return (c == '*') || (c == '-') || (c == '_');
333
- }
334
-
335
-
336
- static int
356
+ static inline int
337
357
  iscode(Line *t)
338
358
  {
339
359
  return (t->dle >= 4);
340
360
  }
341
361
 
342
362
 
343
- static int
363
+ static inline int
344
364
  ishr(Line *t)
345
365
  {
346
- int i, count=0;
347
- char dash = 0;
348
- char c;
349
-
350
- if ( iscode(t) ) return 0;
351
-
352
- for ( i = 0; i < S(t->text); i++) {
353
- c = T(t->text)[i];
354
- if ( (dash == 0) && dashchar(c) )
355
- dash = c;
366
+ if ( ! (t->flags & CHECKED) )
367
+ checkline(t);
356
368
 
357
- if ( c == dash ) ++count;
358
- else if ( !isspace(c) )
359
- return 0;
360
- }
361
- return (count >= 3);
369
+ if ( t->count > 2 )
370
+ return t->kind == chk_hr || t->kind == chk_dash || t->kind == chk_equal;
371
+ return 0;
362
372
  }
363
373
 
364
374
 
365
375
  static int
366
376
  issetext(Line *t, int *htyp)
367
377
  {
368
- int i;
369
- /* then check for setext-style HEADER
370
- * ======
378
+ Line *n;
379
+
380
+ /* check for setext-style HEADER
381
+ * ======
371
382
  */
372
383
 
373
- if ( t->next ) {
374
- char *q = T(t->next->text);
375
- int last = S(t->next->text);
376
-
377
- if ( (*q == '=') || (*q == '-') ) {
378
- /* ignore trailing whitespace */
379
- while ( (last > 1) && isspace(q[last-1]) )
380
- --last;
384
+ if ( (n = t->next) ) {
385
+ if ( !(n->flags & CHECKED) )
386
+ checkline(n);
381
387
 
382
- for (i=1; i < last; i++)
383
- if ( q[0] != q[i] )
384
- return 0;
388
+ if ( n->kind == chk_dash || n->kind == chk_equal ) {
385
389
  *htyp = SETEXT;
386
390
  return 1;
387
391
  }
@@ -393,28 +397,31 @@ issetext(Line *t, int *htyp)
393
397
  static int
394
398
  ishdr(Line *t, int *htyp)
395
399
  {
396
- int i;
397
-
398
-
399
- /* first check for etx-style ###HEADER###
400
- */
401
-
402
- /* leading run of `#`'s ?
403
- */
404
- for ( i=0; T(t->text)[i] == '#'; ++i)
405
- ;
406
-
407
400
  /* ANY leading `#`'s make this into an ETX header
408
401
  */
409
- if ( i && (i < S(t->text) || i > 1) ) {
402
+ if ( (t->dle == 0) && (S(t->text) > 1) && (T(t->text)[0] == '#') ) {
410
403
  *htyp = ETX;
411
404
  return 1;
412
405
  }
413
406
 
407
+ /* And if not, maybe it's a SETEXT header instead
408
+ */
414
409
  return issetext(t, htyp);
415
410
  }
416
411
 
417
412
 
413
+ static inline int
414
+ end_of_block(Line *t)
415
+ {
416
+ int dummy;
417
+
418
+ if ( !t )
419
+ return 0;
420
+
421
+ return ( (S(t->text) <= t->dle) || ishr(t) || ishdr(t, &dummy) );
422
+ }
423
+
424
+
418
425
  static Line*
419
426
  is_discount_dt(Line *t, int *clip)
420
427
  {
@@ -448,13 +455,12 @@ static Line*
448
455
  is_extra_dt(Line *t, int *clip)
449
456
  {
450
457
  #if USE_EXTRA_DL
451
- int i;
452
458
 
453
- if ( t && t->next && T(t->text)[0] != '='
459
+ if ( t && t->next && S(t->text) && T(t->text)[0] != '='
454
460
  && T(t->text)[S(t->text)-1] != '=') {
455
461
  Line *x;
456
462
 
457
- if ( iscode(t) || blankline(t) || ishdr(t,&i) || ishr(t) )
463
+ if ( iscode(t) || end_of_block(t) )
458
464
  return 0;
459
465
 
460
466
  if ( (x = skipempty(t->next)) && is_extra_dd(x) ) {
@@ -490,7 +496,7 @@ islist(Line *t, int *clip, DWORD flags, int *list_type)
490
496
  int i, j;
491
497
  char *q;
492
498
 
493
- if ( /*iscode(t) ||*/ blankline(t) || ishdr(t,&i) || ishr(t) )
499
+ if ( end_of_block(t) )
494
500
  return 0;
495
501
 
496
502
  if ( !(flags & (MKD_NODLIST|MKD_STRICT)) && isdefinition(t,clip,list_type) )
@@ -518,6 +524,7 @@ islist(Line *t, int *clip, DWORD flags, int *list_type)
518
524
  strtoul(T(t->text)+t->dle, &q, 10);
519
525
  if ( (q > T(t->text)+t->dle) && (q == T(t->text) + (j-1)) ) {
520
526
  j = nextnonblank(t,j);
527
+ /* *clip = j; */
521
528
  *clip = (j > 4) ? 4 : j;
522
529
  *list_type = OL;
523
530
  return AL;
@@ -561,6 +568,7 @@ headerblock(Paragraph *pp, int htyp)
561
568
  ++i;
562
569
 
563
570
  CLIP(p->text, 0, i);
571
+ UNCHECK(p);
564
572
 
565
573
  for (j=S(p->text); (j > 1) && (T(p->text)[j-1] == '#'); --j)
566
574
  ;
@@ -597,6 +605,49 @@ codeblock(Paragraph *p)
597
605
  }
598
606
 
599
607
 
608
+ #ifdef WITH_FENCED_CODE
609
+ static int
610
+ iscodefence(Line *r, int size, line_type kind)
611
+ {
612
+ if ( !(r->flags & CHECKED) )
613
+ checkline(r);
614
+
615
+ if ( kind )
616
+ return (r->kind == kind) && (r->count >= size);
617
+ else
618
+ return (r->kind == chk_tilde || r->kind == chk_backtick) && (r->count >= size);
619
+ }
620
+
621
+ static Paragraph *
622
+ fencedcodeblock(ParagraphRoot *d, Line **ptr)
623
+ {
624
+ Line *first, *r;
625
+ Paragraph *ret;
626
+
627
+ first = (*ptr);
628
+
629
+ /* don't allow zero-length code fences
630
+ */
631
+ if ( (first->next == 0) || iscodefence(first->next, first->count, 0) )
632
+ return 0;
633
+
634
+ /* find the closing fence, discard the fences,
635
+ * return a Paragraph with the contents
636
+ */
637
+ for ( r = first; r && r->next; r = r->next )
638
+ if ( iscodefence(r->next, first->count, first->kind) ) {
639
+ (*ptr) = r->next->next;
640
+ ret = Pp(d, first->next, CODE);
641
+ ___mkd_freeLine(first);
642
+ ___mkd_freeLine(r->next);
643
+ r->next = 0;
644
+ return ret;
645
+ }
646
+ return 0;
647
+ }
648
+ #endif
649
+
650
+
600
651
  static int
601
652
  centered(Line *first, Line *last)
602
653
  {
@@ -620,19 +671,18 @@ endoftextblock(Line *t, int toplevelblock, DWORD flags)
620
671
  {
621
672
  int z;
622
673
 
623
- if ( blankline(t)||isquote(t)||ishdr(t,&z)||ishr(t) )
674
+ if ( end_of_block(t) || isquote(t) )
624
675
  return 1;
625
676
 
626
- /* HORRIBLE STANDARDS KLUDGE: non-toplevel paragraphs absorb adjacent
627
- * code blocks
677
+ /* HORRIBLE STANDARDS KLUDGES:
678
+ * 1. non-toplevel paragraphs absorb adjacent code blocks
679
+ * 2. Toplevel paragraphs eat absorb adjacent list items,
680
+ * but sublevel blocks behave properly.
681
+ * (What this means is that we only need to check for code
682
+ * blocks at toplevel, and only check for list items at
683
+ * nested levels.)
628
684
  */
629
- if ( toplevelblock && iscode(t) )
630
- return 1;
631
-
632
- /* HORRIBLE STANDARDS KLUDGE: Toplevel paragraphs eat absorb adjacent
633
- * list items, but sublevel blocks behave properly.
634
- */
635
- return toplevelblock ? 0 : islist(t,&z,flags, &z);
685
+ return toplevelblock ? 0 : islist(t,&z,flags,&z);
636
686
  }
637
687
 
638
688
 
@@ -680,6 +730,7 @@ isdivmarker(Line *p, int start, DWORD flags)
680
730
  if ( flags & (MKD_NODIVQUOTE|MKD_STRICT) )
681
731
  return 0;
682
732
 
733
+ start = nextnonblank(p, start);
683
734
  last= S(p->text) - (1 + start);
684
735
  s = T(p->text) + start;
685
736
 
@@ -703,7 +754,7 @@ isdivmarker(Line *p, int start, DWORD flags)
703
754
  *
704
755
  * one sick horrible thing about blockquotes is that even though
705
756
  * it just takes ^> to start a quote, following lines, if quoted,
706
- * assume that the prefix is ``>''. This means that code needs
757
+ * assume that the prefix is ``> ''. This means that code needs
707
758
  * to be indented *5* spaces from the leading '>', but *4* spaces
708
759
  * from the start of the line. This does not appear to be
709
760
  * documented in the reference implementation, but it's the
@@ -728,6 +779,7 @@ quoteblock(Paragraph *p, DWORD flags)
728
779
  if ( T(t->text)[qp] == ' ' )
729
780
  qp++;
730
781
  CLIP(t->text, 0, qp);
782
+ UNCHECK(t);
731
783
  t->dle = mkd_firstnonblank(t);
732
784
  }
733
785
 
@@ -760,28 +812,6 @@ quoteblock(Paragraph *p, DWORD flags)
760
812
  }
761
813
 
762
814
 
763
- /*
764
- * A table block starts with a table header (see istable()), and continues
765
- * until EOF or a line that /doesn't/ contain a |.
766
- */
767
- static Line *
768
- tableblock(Paragraph *p)
769
- {
770
- Line *t, *q;
771
-
772
- for ( t = p->text; t && (q = t->next); t = t->next ) {
773
- if ( !memchr(T(q->text), '|', S(q->text)) ) {
774
- t->next = 0;
775
- return q;
776
- }
777
- }
778
- return 0;
779
- }
780
-
781
-
782
- static Paragraph *Pp(ParagraphRoot *, Line *, int);
783
- static Paragraph *compile(Line *, int, MMIOT *);
784
-
785
815
  typedef int (*linefn)(Line *);
786
816
 
787
817
 
@@ -800,6 +830,7 @@ listitem(Paragraph *p, int indent, DWORD flags, linefn check)
800
830
 
801
831
  for ( t = p->text; t ; t = q) {
802
832
  CLIP(t->text, 0, clip);
833
+ UNCHECK(t);
803
834
  t->dle = mkd_firstnonblank(t);
804
835
 
805
836
  if ( (q = skipempty(t->next)) == 0 ) {
@@ -853,13 +884,14 @@ definition_block(Paragraph *top, int clip, MMIOT *f, int kind)
853
884
  if ( (text = skipempty(q->next)) == 0 )
854
885
  break;
855
886
 
856
- if (( para = (text != q->next) ))
887
+ if ( para = (text != q->next) )
857
888
  ___mkd_freeLineRange(q, text);
858
889
 
859
890
  q->next = 0;
860
891
  if ( kind == 1 /* discount dl */ )
861
892
  for ( q = labels; q; q = q->next ) {
862
893
  CLIP(q->text, 0, 1);
894
+ UNCHECK(q);
863
895
  S(q->text)--;
864
896
  }
865
897
 
@@ -875,7 +907,7 @@ definition_block(Paragraph *top, int clip, MMIOT *f, int kind)
875
907
  if ( (q = skipempty(text)) == 0 )
876
908
  break;
877
909
 
878
- if (( para = (q != text) )) {
910
+ if ( para = (q != text) ) {
879
911
  Line anchor;
880
912
 
881
913
  anchor.next = text;
@@ -1065,6 +1097,7 @@ compile_document(Line *ptr, MMIOT *f)
1065
1097
 
1066
1098
  while ( ptr ) {
1067
1099
  if ( !(f->flags & MKD_NOHTML) && (tag = isopentag(ptr)) ) {
1100
+ int blocktype;
1068
1101
  /* If we encounter a html/style block, compile and save all
1069
1102
  * of the cached source BEFORE processing the html/style.
1070
1103
  */
@@ -1074,7 +1107,12 @@ compile_document(Line *ptr, MMIOT *f)
1074
1107
  p->down = compile(T(source), 1, f);
1075
1108
  T(source) = E(source) = 0;
1076
1109
  }
1077
- p = Pp(&d, ptr, strcmp(tag->id, "STYLE") == 0 ? STYLE : HTML);
1110
+
1111
+ if ( f->flags & MKD_NOSTYLE )
1112
+ blocktype = HTML;
1113
+ else
1114
+ blocktype = strcmp(tag->id, "STYLE") == 0 ? STYLE : HTML;
1115
+ p = Pp(&d, ptr, blocktype);
1078
1116
  ptr = htmlblock(p, tag, &unclosed);
1079
1117
  if ( unclosed ) {
1080
1118
  p->typ = SOURCE;
@@ -1109,6 +1147,58 @@ compile_document(Line *ptr, MMIOT *f)
1109
1147
  }
1110
1148
 
1111
1149
 
1150
+ static int
1151
+ first_nonblank_before(Line *j, int dle)
1152
+ {
1153
+ return (j->dle < dle) ? j->dle : dle;
1154
+ }
1155
+
1156
+
1157
+ static int
1158
+ actually_a_table(MMIOT *f, Line *pp)
1159
+ {
1160
+ Line *r;
1161
+ int j;
1162
+ int c;
1163
+
1164
+ /* tables need to be turned on */
1165
+ if ( f->flags & (MKD_STRICT|MKD_NOTABLES) )
1166
+ return 0;
1167
+
1168
+ /* tables need three lines */
1169
+ if ( !(pp && pp->next && pp->next->next) ) {
1170
+ return 0;
1171
+ }
1172
+
1173
+ /* all lines must contain |'s */
1174
+ for (r = pp; r; r = r->next )
1175
+ if ( !(r->flags & PIPECHAR) ) {
1176
+ return 0;
1177
+ }
1178
+
1179
+ /* if the header has a leading |, all lines must have leading |'s */
1180
+ if ( T(pp->text)[pp->dle] == '|' ) {
1181
+ for ( r = pp; r; r = r->next )
1182
+ if ( T(r->text)[first_nonblank_before(r,pp->dle)] != '|' ) {
1183
+ return 0;
1184
+ }
1185
+ }
1186
+
1187
+ /* second line must be only whitespace, -, |, or : */
1188
+ r = pp->next;
1189
+
1190
+ for ( j=r->dle; j < S(r->text); ++j ) {
1191
+ c = T(r->text)[j];
1192
+
1193
+ if ( !(isspace(c)||(c=='-')||(c==':')||(c=='|')) ) {
1194
+ return 0;
1195
+ }
1196
+ }
1197
+
1198
+ return 1;
1199
+ }
1200
+
1201
+
1112
1202
  /*
1113
1203
  * break a collection of markdown input into
1114
1204
  * blocks of lists, code, html, and text to
@@ -1139,13 +1229,17 @@ compile(Line *ptr, int toplevel, MMIOT *f)
1139
1229
 
1140
1230
  ptr = codeblock(p);
1141
1231
  }
1232
+ #if WITH_FENCED_CODE
1233
+ else if ( iscodefence(ptr,3,0) && (p=fencedcodeblock(&d, &ptr)) )
1234
+ /* yay, it's already done */ ;
1235
+ #endif
1142
1236
  else if ( ishr(ptr) ) {
1143
1237
  p = Pp(&d, 0, HR);
1144
1238
  r = ptr;
1145
1239
  ptr = ptr->next;
1146
1240
  ___mkd_freeLine(r);
1147
1241
  }
1148
- else if (( list_class = islist(ptr, &indent, f->flags, &list_type) )) {
1242
+ else if ( list_class = islist(ptr, &indent, f->flags, &list_type) ) {
1149
1243
  if ( list_class == DL ) {
1150
1244
  p = Pp(&d, ptr, DL);
1151
1245
  ptr = definition_block(p, indent, f, list_type);
@@ -1165,13 +1259,12 @@ compile(Line *ptr, int toplevel, MMIOT *f)
1165
1259
  p = Pp(&d, ptr, HDR);
1166
1260
  ptr = headerblock(p, hdr_type);
1167
1261
  }
1168
- else if ( istable(ptr) && !(f->flags & (MKD_STRICT|MKD_NOTABLES)) ) {
1169
- p = Pp(&d, ptr, TABLE);
1170
- ptr = tableblock(p);
1171
- }
1172
1262
  else {
1173
1263
  p = Pp(&d, ptr, MARKUP);
1174
1264
  ptr = textblock(p, toplevel, f->flags);
1265
+ /* tables are a special kind of paragraph */
1266
+ if ( actually_a_table(f, p->text) )
1267
+ p->typ = TABLE;
1175
1268
  }
1176
1269
 
1177
1270
  if ( (para||toplevel) && !p->align )