rdiscount 2.2.0.1 → 2.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/README.markdown +11 -12
- data/Rakefile +11 -2
- data/bin/rdiscount +10 -3
- data/ext/Csio.c +2 -2
- data/ext/VERSION +1 -1
- data/ext/amalloc.c +1 -0
- data/ext/blocktags +2 -1
- data/ext/config.h +2 -0
- data/ext/css.c +5 -7
- data/ext/cstring.h +0 -1
- data/ext/docheader.c +6 -1
- data/ext/dumptree.c +11 -2
- data/ext/extconf.rb +1 -0
- data/ext/flags.c +4 -2
- data/ext/generate.c +339 -141
- data/ext/gethopt.c +286 -0
- data/ext/gethopt.h +43 -0
- data/ext/github_flavoured.c +8 -7
- data/ext/h1title.c +36 -0
- data/ext/html5.c +0 -1
- data/ext/markdown.c +189 -87
- data/ext/markdown.h +55 -27
- data/ext/mkdio.c +155 -58
- data/ext/mkdio.h +9 -5
- data/ext/mktags.c +3 -0
- data/ext/notspecial.c +44 -0
- data/ext/pgm_options.c +12 -12
- data/ext/pgm_options.h +2 -2
- data/ext/rdiscount.c +25 -22
- data/ext/resource.c +1 -0
- data/ext/setup.c +1 -1
- data/ext/tags.c +2 -0
- data/ext/toc.c +12 -14
- data/ext/version.c +3 -3
- data/ext/xml.c +6 -5
- data/ext/xmlpage.c +5 -8
- data/lib/rdiscount.rb +12 -1
- data/rdiscount.gemspec +8 -8
- data/test/markdown_test.rb +0 -1
- data/test/rdiscount_test.rb +46 -23
- metadata +14 -10
data/ext/generate.c
CHANGED
@@ -56,16 +56,16 @@ peek(MMIOT *f, int i)
|
|
56
56
|
|
57
57
|
i += (f->isp-1);
|
58
58
|
|
59
|
-
return (i >= 0) && (i < S(f->in)) ? T(f->in)[i] : EOF;
|
59
|
+
return (i >= 0) && (i < S(f->in)) ? (unsigned char)T(f->in)[i] : EOF;
|
60
60
|
}
|
61
61
|
|
62
62
|
|
63
63
|
/* pull a byte from the input buffer
|
64
64
|
*/
|
65
|
-
static inline int
|
65
|
+
static inline unsigned int
|
66
66
|
pull(MMIOT *f)
|
67
67
|
{
|
68
|
-
return ( f->isp < S(f->in) ) ? T(f->in)[f->isp++] : EOF;
|
68
|
+
return ( f->isp < S(f->in) ) ? (unsigned char)T(f->in)[f->isp++] : EOF;
|
69
69
|
}
|
70
70
|
|
71
71
|
|
@@ -108,8 +108,10 @@ isthisnonword(MMIOT *f, int i)
|
|
108
108
|
|
109
109
|
|
110
110
|
/* return/set the current cursor position
|
111
|
+
* (when setting the current cursor position we also need to flush the
|
112
|
+
* last character written cache)
|
111
113
|
*/
|
112
|
-
#define mmiotseek(f,x) (f->isp = x)
|
114
|
+
#define mmiotseek(f,x) ((f->isp = x), (f->last = 0))
|
113
115
|
#define mmiottell(f) (f->isp)
|
114
116
|
|
115
117
|
|
@@ -129,7 +131,7 @@ static void
|
|
129
131
|
Qchar(int c, MMIOT *f)
|
130
132
|
{
|
131
133
|
block *cur;
|
132
|
-
|
134
|
+
|
133
135
|
if ( S(f->Q) == 0 ) {
|
134
136
|
cur = &EXPAND(f->Q);
|
135
137
|
memset(cur, 0, sizeof *cur);
|
@@ -139,7 +141,7 @@ Qchar(int c, MMIOT *f)
|
|
139
141
|
cur = &T(f->Q)[S(f->Q)-1];
|
140
142
|
|
141
143
|
EXPAND(cur->b_text) = c;
|
142
|
-
|
144
|
+
|
143
145
|
}
|
144
146
|
|
145
147
|
|
@@ -178,6 +180,16 @@ Qprintf(MMIOT *f, char *fmt, ...)
|
|
178
180
|
}
|
179
181
|
|
180
182
|
|
183
|
+
/* Qanchor() prints out a suitable-for-id-tag version of a string
|
184
|
+
*/
|
185
|
+
static void
|
186
|
+
Qanchor(struct line *p, MMIOT *f)
|
187
|
+
{
|
188
|
+
mkd_string_to_anchor(T(p->text), S(p->text),
|
189
|
+
(mkd_sta_function_t)Qchar, f, 1, f);
|
190
|
+
}
|
191
|
+
|
192
|
+
|
181
193
|
/* Qem()
|
182
194
|
*/
|
183
195
|
static void
|
@@ -197,13 +209,13 @@ Qem(MMIOT *f, char c, int count)
|
|
197
209
|
/* generate html from a markup fragment
|
198
210
|
*/
|
199
211
|
void
|
200
|
-
___mkd_reparse(char *bfr, int size,
|
212
|
+
___mkd_reparse(char *bfr, int size, mkd_flag_t flags, MMIOT *f, char *esc)
|
201
213
|
{
|
202
214
|
MMIOT sub;
|
203
215
|
struct escaped e;
|
204
216
|
|
205
217
|
___mkd_initmmiot(&sub, f->footnotes);
|
206
|
-
|
218
|
+
|
207
219
|
sub.flags = f->flags | flags;
|
208
220
|
sub.cb = f->cb;
|
209
221
|
sub.ref_prefix = f->ref_prefix;
|
@@ -219,11 +231,16 @@ ___mkd_reparse(char *bfr, int size, int flags, MMIOT *f, char *esc)
|
|
219
231
|
push(bfr, size, &sub);
|
220
232
|
pushc(0, &sub);
|
221
233
|
S(sub.in)--;
|
222
|
-
|
234
|
+
|
223
235
|
text(&sub);
|
224
236
|
___mkd_emblock(&sub);
|
225
|
-
|
237
|
+
|
226
238
|
Qwrite(T(sub.out), S(sub.out), f);
|
239
|
+
/* inherit the last character printed from the reparsed
|
240
|
+
* text; this way superscripts can work when they're
|
241
|
+
* applied to something embedded in a link
|
242
|
+
*/
|
243
|
+
f->last = sub.last;
|
227
244
|
|
228
245
|
___mkd_freemmiot(&sub, f->footnotes);
|
229
246
|
}
|
@@ -263,7 +280,7 @@ puturl(char *s, int size, MMIOT *f, int display)
|
|
263
280
|
if ( !( ispunct(c) || isspace(c) ) )
|
264
281
|
Qchar('\\', f);
|
265
282
|
}
|
266
|
-
|
283
|
+
|
267
284
|
if ( c == '&' )
|
268
285
|
Qstring("&", f);
|
269
286
|
else if ( c == '<' )
|
@@ -431,7 +448,7 @@ linkybroket(MMIOT *f, int image, Footnote *p)
|
|
431
448
|
if ( good ) {
|
432
449
|
if ( peek(f, 1) == ')' )
|
433
450
|
pull(f);
|
434
|
-
|
451
|
+
|
435
452
|
___mkd_tidy(&p->link);
|
436
453
|
}
|
437
454
|
|
@@ -456,7 +473,7 @@ linkyurl(MMIOT *f, int image, Footnote *p)
|
|
456
473
|
|
457
474
|
if ( c == '<' ) {
|
458
475
|
pull(f);
|
459
|
-
if ( !(f->flags
|
476
|
+
if ( !is_flag_set(f->flags, MKD_1_COMPAT) )
|
460
477
|
return linkybroket(f,image,p);
|
461
478
|
mayneedtotrim=1;
|
462
479
|
}
|
@@ -477,12 +494,12 @@ linkyurl(MMIOT *f, int image, Footnote *p)
|
|
477
494
|
}
|
478
495
|
if ( peek(f, 1) == ')' )
|
479
496
|
pull(f);
|
480
|
-
|
497
|
+
|
481
498
|
___mkd_tidy(&p->link);
|
482
|
-
|
499
|
+
|
483
500
|
if ( mayneedtotrim && (T(p->link)[S(p->link)-1] == '>') )
|
484
501
|
--S(p->link);
|
485
|
-
|
502
|
+
|
486
503
|
return 1;
|
487
504
|
}
|
488
505
|
|
@@ -578,12 +595,12 @@ static void
|
|
578
595
|
printlinkyref(MMIOT *f, linkytype *tag, char *link, int size)
|
579
596
|
{
|
580
597
|
char *edit;
|
581
|
-
|
582
|
-
if ( f->flags
|
598
|
+
|
599
|
+
if ( is_flag_set(f->flags, IS_LABEL) )
|
583
600
|
return;
|
584
|
-
|
601
|
+
|
585
602
|
Qstring(tag->link_pfx, f);
|
586
|
-
|
603
|
+
|
587
604
|
if ( tag->kind & IS_URL ) {
|
588
605
|
if ( f->cb && f->cb->e_url && (edit = (*f->cb->e_url)(link, size, f->cb->e_data)) ) {
|
589
606
|
puturl(edit, strlen(edit), f, 0);
|
@@ -623,7 +640,7 @@ extra_linky(MMIOT *f, Cstring text, Footnote *ref)
|
|
623
640
|
{
|
624
641
|
if ( ref->flags & REFERENCED )
|
625
642
|
return 0;
|
626
|
-
|
643
|
+
|
627
644
|
if ( f->flags & IS_LABEL )
|
628
645
|
___mkd_reparse(T(text), S(text), linkt.flags, f, 0);
|
629
646
|
else {
|
@@ -637,6 +654,32 @@ extra_linky(MMIOT *f, Cstring text, Footnote *ref)
|
|
637
654
|
} /* extra_linky */
|
638
655
|
|
639
656
|
|
657
|
+
|
658
|
+
/* check a url (or url fragment to see that it begins with a known good
|
659
|
+
* protocol (or no protocol at all)
|
660
|
+
*/
|
661
|
+
static int
|
662
|
+
safelink(Cstring link)
|
663
|
+
{
|
664
|
+
char *p, *colon;
|
665
|
+
|
666
|
+
if ( T(link) == 0 ) /* no link; safe */
|
667
|
+
return 1;
|
668
|
+
|
669
|
+
p = T(link);
|
670
|
+
if ( (colon = memchr(p, ':', S(link))) == 0 )
|
671
|
+
return 1; /* no protocol specified: safe */
|
672
|
+
|
673
|
+
if ( !isalpha(*p) ) /* protocol/method is [alpha][alnum or '+.-'] */
|
674
|
+
return 1;
|
675
|
+
while ( ++p < colon )
|
676
|
+
if ( !(isalnum(*p) || *p == '.' || *p == '+' || *p == '-') )
|
677
|
+
return 1;
|
678
|
+
|
679
|
+
return isautoprefix(T(link), S(link));
|
680
|
+
}
|
681
|
+
|
682
|
+
|
640
683
|
/* print out a linky (or fail if it's Not Allowed)
|
641
684
|
*/
|
642
685
|
static int
|
@@ -648,12 +691,10 @@ linkyformat(MMIOT *f, Cstring text, int image, Footnote *ref)
|
|
648
691
|
if ( image )
|
649
692
|
tag = &imaget;
|
650
693
|
else if ( tag = pseudo(ref->link) ) {
|
651
|
-
if ( f->flags
|
694
|
+
if ( is_flag_set(f->flags, MKD_NO_EXT) || is_flag_set(f->flags, MKD_SAFELINK) )
|
652
695
|
return 0;
|
653
696
|
}
|
654
|
-
else if ( (f->flags
|
655
|
-
&& (T(ref->link)[0] != '/')
|
656
|
-
&& !isautoprefix(T(ref->link), S(ref->link)) )
|
697
|
+
else if ( is_flag_set(f->flags, MKD_SAFELINK) && !safelink(ref->link) )
|
657
698
|
/* if MKD_SAFELINK, only accept links that are local or
|
658
699
|
* a well-known protocol
|
659
700
|
*/
|
@@ -664,7 +705,7 @@ linkyformat(MMIOT *f, Cstring text, int image, Footnote *ref)
|
|
664
705
|
if ( f->flags & tag->flags )
|
665
706
|
return 0;
|
666
707
|
|
667
|
-
if ( f->flags
|
708
|
+
if ( is_flag_set(f->flags, IS_LABEL) )
|
668
709
|
___mkd_reparse(T(text), S(text), tag->flags, f, 0);
|
669
710
|
else if ( tag->link_pfx ) {
|
670
711
|
printlinkyref(f, tag, T(ref->link), S(ref->link));
|
@@ -700,7 +741,7 @@ linkylinky(int image, MMIOT *f)
|
|
700
741
|
int start = mmiottell(f);
|
701
742
|
Cstring name;
|
702
743
|
Footnote key, *ref;
|
703
|
-
|
744
|
+
|
704
745
|
int status = 0;
|
705
746
|
int extra_footnote = 0;
|
706
747
|
|
@@ -718,7 +759,7 @@ linkylinky(int image, MMIOT *f)
|
|
718
759
|
|
719
760
|
if ( isspace(peek(f,1)) )
|
720
761
|
pull(f);
|
721
|
-
|
762
|
+
|
722
763
|
if ( peek(f,1) == '[' ) {
|
723
764
|
pull(f); /* consume leading '[' */
|
724
765
|
goodlink = linkylabel(f, &key.tag);
|
@@ -728,12 +769,12 @@ linkylinky(int image, MMIOT *f)
|
|
728
769
|
* require a second []
|
729
770
|
*/
|
730
771
|
mmiotseek(f, implicit_mark);
|
731
|
-
goodlink = !(f->flags
|
772
|
+
goodlink = !is_flag_set(f->flags, MKD_1_COMPAT);
|
732
773
|
|
733
|
-
if ( (f->flags
|
774
|
+
if ( is_flag_set(f->flags, MKD_EXTRA_FOOTNOTE) && (!image) && S(name) && T(name)[0] == '^' )
|
734
775
|
extra_footnote = 1;
|
735
776
|
}
|
736
|
-
|
777
|
+
|
737
778
|
if ( goodlink ) {
|
738
779
|
if ( !S(key.tag) ) {
|
739
780
|
DELETE(key.tag);
|
@@ -777,7 +818,7 @@ cputc(int c, MMIOT *f)
|
|
777
818
|
}
|
778
819
|
}
|
779
820
|
|
780
|
-
|
821
|
+
|
781
822
|
/*
|
782
823
|
* convert an email address to a string of nonsense
|
783
824
|
*/
|
@@ -819,7 +860,7 @@ matchticks(MMIOT *f, int tickchar, int ticks, int *endticks)
|
|
819
860
|
{
|
820
861
|
int size, count, c;
|
821
862
|
int subsize=0, subtick=0;
|
822
|
-
|
863
|
+
|
823
864
|
*endticks = ticks;
|
824
865
|
for (size = 0; (c=peek(f,size+ticks)) != EOF; size ++) {
|
825
866
|
if ( (c == tickchar) && ( count = nrticks(size+ticks,tickchar,f)) ) {
|
@@ -852,7 +893,7 @@ code(MMIOT *f, char *s, int length)
|
|
852
893
|
int i,c;
|
853
894
|
|
854
895
|
for ( i=0; i < length; i++ )
|
855
|
-
if ( (c = s[i]) == MKD_EOLN) /*
|
896
|
+
if ( (c = s[i]) == MKD_EOLN) /* expand back to 2 spaces */
|
856
897
|
Qstring(" ", f);
|
857
898
|
else if ( c == '\\' && (i < length-1) && escaped(f, s[i+1]) )
|
858
899
|
cputc(s[++i], f);
|
@@ -870,6 +911,41 @@ delspan(MMIOT *f, int size)
|
|
870
911
|
Qstring("</del>", f);
|
871
912
|
}
|
872
913
|
|
914
|
+
#ifdef TYPORA
|
915
|
+
/* subspan() -- write out a chunk of text, blocking with <sub>...</sub>
|
916
|
+
*/
|
917
|
+
static void
|
918
|
+
subspan(MMIOT *f, int size)
|
919
|
+
{
|
920
|
+
Qstring("<sub>", f);
|
921
|
+
___mkd_reparse(cursor(f)-1, size, 0, f, 0);
|
922
|
+
Qstring("</sub>", f);
|
923
|
+
}
|
924
|
+
|
925
|
+
|
926
|
+
/* supspan() -- write out a chunk of text, blocking with <sup>...</sup>
|
927
|
+
*/
|
928
|
+
static void
|
929
|
+
supspan(MMIOT *f, int size)
|
930
|
+
{
|
931
|
+
Qstring("<sup>", f);
|
932
|
+
___mkd_reparse(cursor(f)-1, size, 0, f, 0);
|
933
|
+
Qstring("</sup>", f);
|
934
|
+
}
|
935
|
+
|
936
|
+
|
937
|
+
/* highlightspan() -- write out a chunk of text, blocking with <mark>...</mark>
|
938
|
+
*/
|
939
|
+
static void
|
940
|
+
highlightspan(MMIOT *f, int size)
|
941
|
+
{
|
942
|
+
Qstring("<mark>", f);
|
943
|
+
___mkd_reparse(cursor(f)-1, size, 0, f, 0);
|
944
|
+
Qstring("</mark>", f);
|
945
|
+
}
|
946
|
+
#endif
|
947
|
+
|
948
|
+
|
873
949
|
|
874
950
|
/* codespan() -- write out a chunk of text as code, trimming one
|
875
951
|
* space off the front and/or back as appropriate.
|
@@ -881,7 +957,7 @@ codespan(MMIOT *f, int size)
|
|
881
957
|
|
882
958
|
if ( size > 1 && peek(f, size-1) == ' ' ) --size;
|
883
959
|
if ( peek(f,i) == ' ' ) ++i, --size;
|
884
|
-
|
960
|
+
|
885
961
|
Qstring("<code>", f);
|
886
962
|
code(f, cursor(f)+(i-1), size);
|
887
963
|
Qstring("</code>", f);
|
@@ -896,12 +972,12 @@ forbidden_tag(MMIOT *f)
|
|
896
972
|
{
|
897
973
|
int c = toupper(peek(f, 1));
|
898
974
|
|
899
|
-
if ( f->flags
|
975
|
+
if ( is_flag_set(f->flags, MKD_NOHTML) )
|
900
976
|
return 1;
|
901
977
|
|
902
|
-
if ( c == 'A' && (f->flags
|
978
|
+
if ( c == 'A' && is_flag_set(f->flags, MKD_NOLINKS) && !isthisalnum(f,2) )
|
903
979
|
return 1;
|
904
|
-
if ( c == 'I' && (f->flags
|
980
|
+
if ( c == 'I' && is_flag_set(f->flags, MKD_NOIMAGE)
|
905
981
|
&& strncasecmp(cursor(f)+1, "MG", 2) == 0
|
906
982
|
&& !isthisalnum(f,4) )
|
907
983
|
return 1;
|
@@ -918,17 +994,17 @@ static int
|
|
918
994
|
maybe_address(char *p, int size)
|
919
995
|
{
|
920
996
|
int ok = 0;
|
921
|
-
|
997
|
+
|
922
998
|
for ( ;size && (isalnum(*p) || strchr("._-+*", *p)); ++p, --size)
|
923
999
|
;
|
924
1000
|
|
925
1001
|
if ( ! (size && *p == '@') )
|
926
1002
|
return 0;
|
927
|
-
|
1003
|
+
|
928
1004
|
--size, ++p;
|
929
1005
|
|
930
1006
|
if ( size && *p == '.' ) return 0;
|
931
|
-
|
1007
|
+
|
932
1008
|
for ( ;size && (isalnum(*p) || strchr("._-+", *p)); ++p, --size )
|
933
1009
|
if ( *p == '.' && size > 1 ) ok = 1;
|
934
1010
|
|
@@ -947,8 +1023,8 @@ process_possible_link(MMIOT *f, int size)
|
|
947
1023
|
int address= 0;
|
948
1024
|
int mailto = 0;
|
949
1025
|
char *text = cursor(f);
|
950
|
-
|
951
|
-
if ( f->flags
|
1026
|
+
|
1027
|
+
if ( is_flag_set(f->flags, MKD_NOLINKS) ) return 0;
|
952
1028
|
|
953
1029
|
if ( (size > 7) && strncasecmp(text, "mailto:", 7) == 0 ) {
|
954
1030
|
/* if it says it's a mailto, it's a mailto -- who am
|
@@ -983,6 +1059,17 @@ process_possible_link(MMIOT *f, int size)
|
|
983
1059
|
} /* process_possible_link */
|
984
1060
|
|
985
1061
|
|
1062
|
+
/*
|
1063
|
+
* check if a character is one of the things the reference implementation considers valid for starting
|
1064
|
+
* a html(ish) tag
|
1065
|
+
*/
|
1066
|
+
static inline int
|
1067
|
+
is_a_strict_tag_prefix(int c)
|
1068
|
+
{
|
1069
|
+
return isalpha(c) || (c == '/') || (c == '!') || (c == '$') || (c == '?');
|
1070
|
+
}
|
1071
|
+
|
1072
|
+
|
986
1073
|
/* a < may be just a regular character, the start of an embedded html
|
987
1074
|
* tag, or the start of an <automatic link>. If it's an automatic
|
988
1075
|
* link, we also need to know if it's an email address because if it
|
@@ -992,54 +1079,56 @@ process_possible_link(MMIOT *f, int size)
|
|
992
1079
|
static int
|
993
1080
|
maybe_tag_or_link(MMIOT *f)
|
994
1081
|
{
|
995
|
-
int c, size;
|
996
|
-
int maybetag = 1;
|
1082
|
+
int c, size=0;
|
997
1083
|
|
998
|
-
if ( f->flags
|
1084
|
+
if ( is_flag_set(f->flags, MKD_TAGTEXT) )
|
999
1085
|
return 0;
|
1000
1086
|
|
1001
|
-
|
1002
|
-
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
1087
|
+
c = peek(f, 1);
|
1088
|
+
|
1089
|
+
|
1090
|
+
if ( is_a_strict_tag_prefix(c) ) {
|
1091
|
+
/* By decree of Markdown.pl *this is a tag* and we want to absorb everything up
|
1092
|
+
* to the next '>', unless interrupted by another '<' OR a '`', at which point
|
1093
|
+
* we kick it back to the caller as plain old text.
|
1094
|
+
*/
|
1095
|
+
size=1;
|
1096
|
+
while ( (c=peek(f,size+1)) != '>' ) {
|
1097
|
+
if ( c == EOF || c == '<' )
|
1098
|
+
return 0;
|
1099
|
+
if ( is_flag_set(f->flags, MKD_STRICT) ) {
|
1100
|
+
if ( c == '`' )
|
1101
|
+
return 0;
|
1102
|
+
}
|
1103
|
+
size++;
|
1008
1104
|
}
|
1009
|
-
else if ( isspace(c) )
|
1010
|
-
break;
|
1011
|
-
else if ( ! (c == '/'
|
1012
|
-
|| (f->flags & MKD_GITHUBTAGS && (c == '-' || c == '_'))
|
1013
|
-
|| isalnum(c) ) )
|
1014
|
-
maybetag=0;
|
1015
1105
|
}
|
1016
1106
|
|
1017
|
-
if ( size ) {
|
1018
|
-
if (
|
1107
|
+
if ( size > 0 ) {
|
1108
|
+
if ( process_possible_link(f, size) ) {
|
1109
|
+
shift(f, size+1);
|
1110
|
+
return 1;
|
1111
|
+
}
|
1112
|
+
else {
|
1113
|
+
int i;
|
1019
1114
|
|
1020
|
-
/* It is not a html tag unless we find the closing '>' in
|
1021
|
-
* the same block.
|
1022
|
-
*/
|
1023
|
-
while ( (c = peek(f, size+1)) != '>' )
|
1024
|
-
if ( c == EOF )
|
1025
|
-
return 0;
|
1026
|
-
else
|
1027
|
-
size++;
|
1028
|
-
|
1029
1115
|
if ( forbidden_tag(f) )
|
1030
1116
|
return 0;
|
1031
1117
|
|
1032
|
-
|
1033
|
-
|
1034
|
-
|
1035
|
-
|
1036
|
-
|
1037
|
-
|
1118
|
+
for ( i=0; i <= size+1; i++ ) {
|
1119
|
+
c = peek(f,i);
|
1120
|
+
|
1121
|
+
if ( (c == '&') && (i > 0) )
|
1122
|
+
Qstring("&", f);
|
1123
|
+
else
|
1124
|
+
Qchar(c, f);
|
1125
|
+
}
|
1126
|
+
|
1038
1127
|
shift(f, size+1);
|
1039
1128
|
return 1;
|
1040
1129
|
}
|
1041
1130
|
}
|
1042
|
-
|
1131
|
+
|
1043
1132
|
return 0;
|
1044
1133
|
}
|
1045
1134
|
|
@@ -1163,7 +1252,9 @@ smartypants(int c, int *flags, MMIOT *f)
|
|
1163
1252
|
{
|
1164
1253
|
int i;
|
1165
1254
|
|
1166
|
-
if ( f->flags
|
1255
|
+
if ( is_flag_set(f->flags, MKD_NOPANTS)
|
1256
|
+
|| is_flag_set(f->flags, MKD_TAGTEXT)
|
1257
|
+
|| is_flag_set(f->flags, IS_LABEL) )
|
1167
1258
|
return 0;
|
1168
1259
|
|
1169
1260
|
for ( i=0; i < NRSMART; i++)
|
@@ -1207,7 +1298,6 @@ smartypants(int c, int *flags, MMIOT *f)
|
|
1207
1298
|
} /* smartypants */
|
1208
1299
|
|
1209
1300
|
|
1210
|
-
#if WITH_LATEX
|
1211
1301
|
/* process latex with arbitrary 2-character ( $$ .. $$, \[ .. \], \( .. \)
|
1212
1302
|
* delimiters
|
1213
1303
|
*/
|
@@ -1227,7 +1317,6 @@ mathhandler(MMIOT *f, int e1, int e2)
|
|
1227
1317
|
}
|
1228
1318
|
return 0;
|
1229
1319
|
}
|
1230
|
-
#endif
|
1231
1320
|
|
1232
1321
|
|
1233
1322
|
/* process a body of text encased in some sort of tick marks. If it
|
@@ -1257,7 +1346,7 @@ tickhandler(MMIOT *f, int tickchar, int minticks, int allow_space, spanhandler s
|
|
1257
1346
|
return 0;
|
1258
1347
|
}
|
1259
1348
|
|
1260
|
-
#define tag_text(f) (f->flags
|
1349
|
+
#define tag_text(f) is_flag_set(f->flags, MKD_TAGTEXT)
|
1261
1350
|
|
1262
1351
|
|
1263
1352
|
static void
|
@@ -1268,7 +1357,7 @@ text(MMIOT *f)
|
|
1268
1357
|
int smartyflags = 0;
|
1269
1358
|
|
1270
1359
|
while (1) {
|
1271
|
-
if ( (f->flags
|
1360
|
+
if ( is_flag_set(f->flags, MKD_AUTOLINK) && isalpha(peek(f,1)) && !tag_text(f) )
|
1272
1361
|
maybe_autolink(f);
|
1273
1362
|
|
1274
1363
|
c = pull(f);
|
@@ -1296,7 +1385,7 @@ text(MMIOT *f)
|
|
1296
1385
|
else
|
1297
1386
|
Qchar(c, f);
|
1298
1387
|
break;
|
1299
|
-
|
1388
|
+
|
1300
1389
|
case '!': if ( peek(f,1) == '[' ) {
|
1301
1390
|
pull(f);
|
1302
1391
|
if ( tag_text(f) || !linkylinky(1, f) )
|
@@ -1309,10 +1398,31 @@ text(MMIOT *f)
|
|
1309
1398
|
case '[': if ( tag_text(f) || !linkylinky(0, f) )
|
1310
1399
|
Qchar(c, f);
|
1311
1400
|
break;
|
1401
|
+
|
1402
|
+
#ifdef TYPORA
|
1403
|
+
case '=': if ( is_flag_set(f->flags, MKD_NOSUPERSCRIPT)
|
1404
|
+
|| is_flag_set(f->flags, MKD_STRICT)
|
1405
|
+
|| is_flag_set(f->flags, MKD_TAGTEXT)
|
1406
|
+
|| ! tickhandler(f,c,2,0, highlightspan))
|
1407
|
+
Qchar(c, f);
|
1408
|
+
break;
|
1409
|
+
|
1410
|
+
/* A^B^ -> A<sup>B</sup> */
|
1411
|
+
case '^': if ( is_flag_set(f->flags, MKD_NOSUPERSCRIPT)
|
1412
|
+
|| is_flag_set(f->flags, MKD_STRICT)
|
1413
|
+
|| is_flag_set(f->flags, MKD_TAGTEXT)
|
1414
|
+
|| ! tickhandler(f,c,1,0, supspan))
|
1415
|
+
Qchar(c, f);
|
1416
|
+
break;
|
1417
|
+
#else /* !TYPORA */
|
1312
1418
|
/* A^B -> A<sup>B</sup> */
|
1313
|
-
case '^': if ( (f->flags
|
1314
|
-
|
1315
|
-
|
1419
|
+
case '^': if ( is_flag_set(f->flags, MKD_NOSUPERSCRIPT)
|
1420
|
+
|| is_flag_set(f->flags, MKD_STRICT)
|
1421
|
+
|| is_flag_set(f->flags, MKD_TAGTEXT)
|
1422
|
+
|| (f->last == 0)
|
1423
|
+
|| ((ispunct(f->last) || isspace(f->last))
|
1424
|
+
&& f->last != ')')
|
1425
|
+
|| isthisspace(f,1) )
|
1316
1426
|
Qchar(c,f);
|
1317
1427
|
else {
|
1318
1428
|
char *sup = cursor(f);
|
@@ -1343,11 +1453,11 @@ text(MMIOT *f)
|
|
1343
1453
|
Qstring("</sup>", f);
|
1344
1454
|
}
|
1345
1455
|
break;
|
1456
|
+
#endif /* TYPORA */
|
1346
1457
|
case '_':
|
1347
1458
|
/* Underscores don't count if they're in the middle of a word */
|
1348
|
-
if ( !(f->flags
|
1349
|
-
|
1350
|
-
&& isthisalnum(f,1) ) {
|
1459
|
+
if ( !(is_flag_set(f->flags, MKD_NORELAXED) || is_flag_set(f->flags, MKD_STRICT))
|
1460
|
+
&& isthisalnum(f,-1) && isthisalnum(f,1) ) {
|
1351
1461
|
Qchar(c, f);
|
1352
1462
|
break;
|
1353
1463
|
}
|
@@ -1367,8 +1477,17 @@ text(MMIOT *f)
|
|
1367
1477
|
Qem(f,c,rep);
|
1368
1478
|
}
|
1369
1479
|
break;
|
1370
|
-
|
1371
|
-
|
1480
|
+
|
1481
|
+
#ifdef TYPORA
|
1482
|
+
#define ticktick(f,c) (tickhandler(f,c,2,0,delspan) || tickhandler(f,c,1,0,subspan))
|
1483
|
+
#else
|
1484
|
+
#define ticktick(f,c) tickhandler(f,c,2,0,delspan)
|
1485
|
+
#endif
|
1486
|
+
|
1487
|
+
case '~': if ( is_flag_set(f->flags, MKD_NOSTRIKETHROUGH)
|
1488
|
+
|| is_flag_set(f->flags, MKD_STRICT)
|
1489
|
+
|| is_flag_set(f->flags, MKD_TAGTEXT)
|
1490
|
+
|| !ticktick(f,c) )
|
1372
1491
|
Qchar(c, f);
|
1373
1492
|
break;
|
1374
1493
|
|
@@ -1388,35 +1507,35 @@ text(MMIOT *f)
|
|
1388
1507
|
Qchar('\\', f);
|
1389
1508
|
shift(f, -1);
|
1390
1509
|
}
|
1391
|
-
|
1510
|
+
|
1392
1511
|
break;
|
1393
|
-
case '^': if ( f->flags
|
1512
|
+
case '^': if ( is_flag_set(f->flags, MKD_STRICT)
|
1513
|
+
|| is_flag_set(f->flags, MKD_NOSUPERSCRIPT) ) {
|
1394
1514
|
Qchar('\\', f);
|
1395
1515
|
shift(f,-1);
|
1396
1516
|
break;
|
1397
1517
|
}
|
1398
1518
|
Qchar(c, f);
|
1399
1519
|
break;
|
1400
|
-
|
1520
|
+
|
1401
1521
|
case ':': case '|':
|
1402
|
-
if ( f->flags
|
1522
|
+
if ( is_flag_set(f->flags, MKD_NOTABLES) ) {
|
1403
1523
|
Qchar('\\', f);
|
1404
1524
|
shift(f,-1);
|
1405
1525
|
break;
|
1406
1526
|
}
|
1407
1527
|
Qchar(c, f);
|
1408
1528
|
break;
|
1409
|
-
|
1529
|
+
|
1410
1530
|
case EOF: Qchar('\\', f);
|
1411
1531
|
break;
|
1412
1532
|
|
1413
|
-
#if WITH_LATEX
|
1414
1533
|
case '[':
|
1415
|
-
case '(': if (
|
1534
|
+
case '(': if ( is_flag_set(f->flags, MKD_LATEX)
|
1535
|
+
&& mathhandler(f, '\\', (c =='(')?')':']') )
|
1416
1536
|
break;
|
1417
1537
|
/* else fall through to default */
|
1418
|
-
|
1419
|
-
|
1538
|
+
|
1420
1539
|
default: if ( escaped(f,c) ||
|
1421
1540
|
strchr(">#.-+{}]![*_\\()`", c) )
|
1422
1541
|
Qchar(c, f);
|
@@ -1428,8 +1547,12 @@ text(MMIOT *f)
|
|
1428
1547
|
}
|
1429
1548
|
break;
|
1430
1549
|
|
1431
|
-
case '<': if ( !maybe_tag_or_link(f) )
|
1432
|
-
|
1550
|
+
case '<': if ( !maybe_tag_or_link(f) ) {
|
1551
|
+
if ( is_flag_set(f->flags, MKD_STRICT) && is_a_strict_tag_prefix(peek(f,1)) )
|
1552
|
+
Qchar(c, f);
|
1553
|
+
else
|
1554
|
+
Qstring("<", f);
|
1555
|
+
}
|
1433
1556
|
break;
|
1434
1557
|
|
1435
1558
|
case '&': j = (peek(f,1) == '#' ) ? 2 : 1;
|
@@ -1442,17 +1565,16 @@ text(MMIOT *f)
|
|
1442
1565
|
Qchar(c, f);
|
1443
1566
|
break;
|
1444
1567
|
|
1445
|
-
|
1446
|
-
case '$': if ( peek(f, 1) == '$' ) {
|
1568
|
+
case '$': if ( is_flag_set(f->flags, MKD_LATEX) && (peek(f, 1) == '$') ) {
|
1447
1569
|
pull(f);
|
1448
1570
|
if ( mathhandler(f, '$', '$') )
|
1449
1571
|
break;
|
1450
1572
|
Qchar('$', f);
|
1451
1573
|
}
|
1452
1574
|
/* fall through to default */
|
1453
|
-
|
1454
|
-
|
1455
|
-
|
1575
|
+
|
1576
|
+
default: f->last = c;
|
1577
|
+
Qchar(c, f);
|
1456
1578
|
break;
|
1457
1579
|
}
|
1458
1580
|
}
|
@@ -1466,22 +1588,18 @@ text(MMIOT *f)
|
|
1466
1588
|
static void
|
1467
1589
|
printheader(Paragraph *pp, MMIOT *f)
|
1468
1590
|
{
|
1469
|
-
if ( f->flags
|
1591
|
+
if ( is_flag_set(f->flags, MKD_IDANCHOR) ) {
|
1470
1592
|
Qprintf(f, "<h%d", pp->hnumber);
|
1471
|
-
if ( f->flags
|
1593
|
+
if ( is_flag_set(f->flags, MKD_TOC) ) {
|
1472
1594
|
Qstring(" id=\"", f);
|
1473
|
-
|
1474
|
-
S(pp->text->text),
|
1475
|
-
(mkd_sta_function_t)Qchar, f, 1, f->flags);
|
1595
|
+
Qanchor(pp->text, f);
|
1476
1596
|
Qchar('"', f);
|
1477
1597
|
}
|
1478
1598
|
Qchar('>', f);
|
1479
1599
|
} else {
|
1480
|
-
if ( f->flags
|
1600
|
+
if ( is_flag_set(f->flags, MKD_TOC) ) {
|
1481
1601
|
Qstring("<a name=\"", f);
|
1482
|
-
|
1483
|
-
S(pp->text->text),
|
1484
|
-
(mkd_sta_function_t)Qchar, f, 1, f->flags);
|
1602
|
+
Qanchor(pp->text, f);
|
1485
1603
|
Qstring("\"></a>\n", f);
|
1486
1604
|
}
|
1487
1605
|
Qprintf(f, "<h%d>", pp->hnumber);
|
@@ -1511,7 +1629,7 @@ splat(Line *p, char *block, Istring align, int force, MMIOT *f)
|
|
1511
1629
|
___mkd_tidy(&p->text);
|
1512
1630
|
if ( T(p->text)[S(p->text)-1] == '|' )
|
1513
1631
|
--S(p->text);
|
1514
|
-
|
1632
|
+
|
1515
1633
|
Qstring("<tr>\n", f);
|
1516
1634
|
while ( idx < S(p->text) ) {
|
1517
1635
|
first = idx;
|
@@ -1572,7 +1690,7 @@ printtable(Paragraph *pp, MMIOT *f)
|
|
1572
1690
|
for (p=T(dash->text), start=dash->dle; start < S(dash->text); ) {
|
1573
1691
|
char first, last;
|
1574
1692
|
int end;
|
1575
|
-
|
1693
|
+
|
1576
1694
|
last=first=0;
|
1577
1695
|
for (end=start ; (end < S(dash->text)) && p[end] != '|'; ++ end ) {
|
1578
1696
|
if ( p[end] == '\\' )
|
@@ -1614,9 +1732,10 @@ printtable(Paragraph *pp, MMIOT *f)
|
|
1614
1732
|
static int
|
1615
1733
|
printblock(Paragraph *pp, MMIOT *f)
|
1616
1734
|
{
|
1617
|
-
Line *t = pp->text;
|
1618
1735
|
static char *Begin[] = { "", "<p>", "<p style=\"text-align:center;\">" };
|
1619
1736
|
static char *End[] = { "", "</p>","</p>" };
|
1737
|
+
Line *t = pp->text;
|
1738
|
+
int align = pp->align;
|
1620
1739
|
|
1621
1740
|
while (t) {
|
1622
1741
|
if ( S(t->text) ) {
|
@@ -1636,9 +1755,9 @@ printblock(Paragraph *pp, MMIOT *f)
|
|
1636
1755
|
}
|
1637
1756
|
t = t->next;
|
1638
1757
|
}
|
1639
|
-
Qstring(Begin[
|
1758
|
+
Qstring(Begin[align], f);
|
1640
1759
|
text(f);
|
1641
|
-
Qstring(End[
|
1760
|
+
Qstring(End[align], f);
|
1642
1761
|
return 1;
|
1643
1762
|
}
|
1644
1763
|
|
@@ -1648,8 +1767,44 @@ printcode(Line *t, char *lang, MMIOT *f)
|
|
1648
1767
|
{
|
1649
1768
|
int blanks;
|
1650
1769
|
|
1770
|
+
if ( f->cb->e_codefmt ) {
|
1771
|
+
/* external code block formatter; copy the text into a buffer,
|
1772
|
+
* call the formatter to style it, then dump that styled text
|
1773
|
+
* directly to the queue
|
1774
|
+
*/
|
1775
|
+
char *text;
|
1776
|
+
char *fmt;
|
1777
|
+
int size, copy_p;
|
1778
|
+
Line *p;
|
1779
|
+
|
1780
|
+
for (size=0, p = t; p; p = p->next )
|
1781
|
+
size += 1+S(p->text);
|
1782
|
+
|
1783
|
+
text = malloc(1+size);
|
1784
|
+
|
1785
|
+
for ( copy_p = 0; t ; t = t->next ) {
|
1786
|
+
memcpy(text+copy_p, T(t->text), S(t->text));
|
1787
|
+
copy_p += S(t->text);
|
1788
|
+
text[copy_p++] = '\n';
|
1789
|
+
}
|
1790
|
+
text[copy_p] = 0;
|
1791
|
+
|
1792
|
+
fmt = (*(f->cb->e_codefmt))(text, copy_p, (lang && lang[0]) ? lang : 0);
|
1793
|
+
free(text);
|
1794
|
+
|
1795
|
+
if ( fmt ) {
|
1796
|
+
Qwrite(fmt, strlen(fmt), f);
|
1797
|
+
if ( f->cb->e_free )
|
1798
|
+
(*(f->cb->e_free))(fmt, f->cb->e_data);
|
1799
|
+
return;
|
1800
|
+
}
|
1801
|
+
/* otherwise the external formatter failed and we need to
|
1802
|
+
* fall back to the traditional codeblock format
|
1803
|
+
*/
|
1804
|
+
}
|
1805
|
+
|
1651
1806
|
Qstring("<pre><code", f);
|
1652
|
-
if (lang) {
|
1807
|
+
if (lang && lang[0]) {
|
1653
1808
|
Qstring(" class=\"", f);
|
1654
1809
|
Qstring(lang, f);
|
1655
1810
|
Qstring("\"", f);
|
@@ -1674,7 +1829,7 @@ static void
|
|
1674
1829
|
printhtml(Line *t, MMIOT *f)
|
1675
1830
|
{
|
1676
1831
|
int blanks;
|
1677
|
-
|
1832
|
+
|
1678
1833
|
for ( blanks=0; t ; t = t->next )
|
1679
1834
|
if ( S(t->text) ) {
|
1680
1835
|
for ( ; blanks; --blanks )
|
@@ -1689,17 +1844,57 @@ printhtml(Line *t, MMIOT *f)
|
|
1689
1844
|
|
1690
1845
|
|
1691
1846
|
static void
|
1692
|
-
|
1847
|
+
htmlify_paragraphs(Paragraph *p, MMIOT *f)
|
1693
1848
|
{
|
1694
1849
|
___mkd_emblock(f);
|
1695
|
-
if ( block )
|
1696
|
-
Qprintf(f, arguments ? "<%s %s>" : "<%s>", block, arguments);
|
1697
|
-
___mkd_emblock(f);
|
1698
1850
|
|
1699
1851
|
while (( p = display(p, f) )) {
|
1700
1852
|
___mkd_emblock(f);
|
1701
1853
|
Qstring("\n\n", f);
|
1702
1854
|
}
|
1855
|
+
}
|
1856
|
+
|
1857
|
+
|
1858
|
+
#ifdef GITHUB_CHECKBOX
|
1859
|
+
static void
|
1860
|
+
li_htmlify(Paragraph *p, char *arguments, mkd_flag_t flags, MMIOT *f)
|
1861
|
+
{
|
1862
|
+
___mkd_emblock(f);
|
1863
|
+
|
1864
|
+
Qprintf(f, "<li");
|
1865
|
+
if ( arguments )
|
1866
|
+
Qprintf(f, " %s", arguments);
|
1867
|
+
if ( flags & GITHUB_CHECK )
|
1868
|
+
Qprintf(f, " class=\"github_checkbox\"");
|
1869
|
+
Qprintf(f, ">");
|
1870
|
+
#if CHECKBOX_AS_INPUT
|
1871
|
+
if ( flags & GITHUB_CHECK ) {
|
1872
|
+
Qprintf(f, "<input disabled=\"\" type=\"checkbox\"");
|
1873
|
+
if ( flags & IS_CHECKED )
|
1874
|
+
Qprintf(f, " checked=\"checked\"");
|
1875
|
+
Qprintf(f, "/>");
|
1876
|
+
}
|
1877
|
+
#else
|
1878
|
+
if ( flags & GITHUB_CHECK )
|
1879
|
+
Qprintf(f, flags & IS_CHECKED ? "☑" : "☐");
|
1880
|
+
#endif
|
1881
|
+
|
1882
|
+
htmlify_paragraphs(p, f);
|
1883
|
+
|
1884
|
+
Qprintf(f, "</li>");
|
1885
|
+
___mkd_emblock(f);
|
1886
|
+
}
|
1887
|
+
#endif
|
1888
|
+
|
1889
|
+
|
1890
|
+
static void
|
1891
|
+
htmlify(Paragraph *p, char *block, char *arguments, MMIOT *f)
|
1892
|
+
{
|
1893
|
+
___mkd_emblock(f);
|
1894
|
+
if ( block )
|
1895
|
+
Qprintf(f, arguments ? "<%s %s>" : "<%s>", block, arguments);
|
1896
|
+
|
1897
|
+
htmlify_paragraphs(p, f);
|
1703
1898
|
|
1704
1899
|
if ( block )
|
1705
1900
|
Qprintf(f, "</%s>", block);
|
@@ -1741,7 +1936,11 @@ listdisplay(int typ, Paragraph *p, MMIOT* f)
|
|
1741
1936
|
Qprintf(f, ">\n");
|
1742
1937
|
|
1743
1938
|
for ( ; p ; p = p->next ) {
|
1939
|
+
#ifdef GITHUB_CHECKBOX
|
1940
|
+
li_htmlify(p->down, p->ident, p->flags, f);
|
1941
|
+
#else
|
1744
1942
|
htmlify(p->down, "li", p->ident, f);
|
1943
|
+
#endif
|
1745
1944
|
Qchar('\n', f);
|
1746
1945
|
}
|
1747
1946
|
|
@@ -1756,7 +1955,7 @@ static Paragraph*
|
|
1756
1955
|
display(Paragraph *p, MMIOT *f)
|
1757
1956
|
{
|
1758
1957
|
if ( !p ) return 0;
|
1759
|
-
|
1958
|
+
|
1760
1959
|
switch ( p->typ ) {
|
1761
1960
|
case STYLE:
|
1762
1961
|
case WHITESPACE:
|
@@ -1765,15 +1964,15 @@ display(Paragraph *p, MMIOT *f)
|
|
1765
1964
|
case HTML:
|
1766
1965
|
printhtml(p->text, f);
|
1767
1966
|
break;
|
1768
|
-
|
1967
|
+
|
1769
1968
|
case CODE:
|
1770
1969
|
printcode(p->text, p->lang, f);
|
1771
1970
|
break;
|
1772
|
-
|
1971
|
+
|
1773
1972
|
case QUOTE:
|
1774
1973
|
htmlify(p->down, p->ident ? "div" : "blockquote", p->ident, f);
|
1775
1974
|
break;
|
1776
|
-
|
1975
|
+
|
1777
1976
|
case UL:
|
1778
1977
|
case OL:
|
1779
1978
|
case AL:
|
@@ -1799,7 +1998,7 @@ display(Paragraph *p, MMIOT *f)
|
|
1799
1998
|
case SOURCE:
|
1800
1999
|
htmlify(p->down, 0, 0, f);
|
1801
2000
|
break;
|
1802
|
-
|
2001
|
+
|
1803
2002
|
default:
|
1804
2003
|
printblock(p, f);
|
1805
2004
|
break;
|
@@ -1820,17 +2019,17 @@ mkd_extra_footnotes(MMIOT *m)
|
|
1820
2019
|
return;
|
1821
2020
|
|
1822
2021
|
Csprintf(&m->out, "\n<div class=\"footnotes\">\n<hr/>\n<ol>\n");
|
1823
|
-
|
2022
|
+
|
1824
2023
|
for ( i=1; i <= m->footnotes->reference; i++ ) {
|
1825
2024
|
for ( j=0; j < S(m->footnotes->note); j++ ) {
|
1826
2025
|
t = &T(m->footnotes->note)[j];
|
1827
2026
|
if ( (t->refnumber == i) && (t->flags & REFERENCED) ) {
|
1828
|
-
Csprintf(&m->out, "<li id=\"%s:%d\">\n
|
2027
|
+
Csprintf(&m->out, "<li id=\"%s:%d\">\n",
|
1829
2028
|
p_or_nothing(m), t->refnumber);
|
1830
|
-
|
2029
|
+
htmlify(t->text, 0, 0, m);
|
1831
2030
|
Csprintf(&m->out, "<a href=\"#%sref:%d\" rev=\"footnote\">↩</a>",
|
1832
2031
|
p_or_nothing(m), t->refnumber);
|
1833
|
-
Csprintf(&m->out, "</
|
2032
|
+
Csprintf(&m->out, "</li>\n");
|
1834
2033
|
}
|
1835
2034
|
}
|
1836
2035
|
}
|
@@ -1845,15 +2044,15 @@ int
|
|
1845
2044
|
mkd_document(Document *p, char **res)
|
1846
2045
|
{
|
1847
2046
|
int size;
|
1848
|
-
|
2047
|
+
|
1849
2048
|
if ( p && p->compiled ) {
|
1850
2049
|
if ( ! p->html ) {
|
1851
2050
|
htmlify(p->code, 0, 0, p->ctx);
|
1852
|
-
if ( p->ctx->flags
|
2051
|
+
if ( is_flag_set(p->ctx->flags, MKD_EXTRA_FOOTNOTE) )
|
1853
2052
|
mkd_extra_footnotes(p->ctx);
|
1854
2053
|
p->html = 1;
|
1855
2054
|
size = S(p->ctx->out);
|
1856
|
-
|
2055
|
+
|
1857
2056
|
if ( (size == 0) || T(p->ctx->out)[size-1] ) {
|
1858
2057
|
/* Add a null byte at the end of the generated html,
|
1859
2058
|
* but pretend it doesn't exist.
|
@@ -1862,10 +2061,9 @@ mkd_document(Document *p, char **res)
|
|
1862
2061
|
--S(p->ctx->out);
|
1863
2062
|
}
|
1864
2063
|
}
|
1865
|
-
|
2064
|
+
|
1866
2065
|
*res = T(p->ctx->out);
|
1867
2066
|
return S(p->ctx->out);
|
1868
2067
|
}
|
1869
2068
|
return EOF;
|
1870
2069
|
}
|
1871
|
-
|