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.
- data/BUILDING +4 -3
- data/COPYING +25 -44
- data/Rakefile +4 -0
- data/ext/Csio.c +1 -1
- data/ext/VERSION +1 -1
- data/ext/blocktags +33 -0
- data/ext/config.h +6 -0
- data/ext/cstring.h +2 -2
- data/ext/flags.c +1 -0
- data/ext/generate.c +146 -64
- data/ext/github_flavoured.c +100 -0
- data/ext/html5.c +0 -2
- data/ext/markdown.c +229 -136
- data/ext/markdown.h +40 -3
- data/ext/mkdio.c +25 -28
- data/ext/mkdio.h +9 -2
- data/ext/mktags.c +89 -0
- data/ext/pgm_options.c +138 -0
- data/ext/pgm_options.h +9 -0
- data/ext/rdiscount.c +52 -52
- data/ext/setup.c +1 -9
- data/ext/tags.c +34 -66
- data/ext/toc.c +21 -10
- data/ext/version.c +9 -1
- data/lib/rdiscount.rb +7 -1
- data/rdiscount.gemspec +7 -2
- data/test/rdiscount_test.rb +86 -1
- metadata +7 -2
data/BUILDING
CHANGED
@@ -20,7 +20,7 @@ the rake gather task to copy discount source files into the ext/ directory:
|
|
20
20
|
Submodule 'discount' (git://github.com/davidfstr/discount.git) registered for path 'discount'
|
21
21
|
Cloning into discount...
|
22
22
|
$ cd discount
|
23
|
-
$ ./configure.sh
|
23
|
+
$ ./configure.sh --with-fenced-code --with-github-tags
|
24
24
|
$ cd ..
|
25
25
|
$ rake gather
|
26
26
|
$ rake build
|
@@ -49,7 +49,7 @@ Copy the new Discount sources to the appropriate directories for RDiscount:
|
|
49
49
|
Update rdiscount.gemspec to include all *.c, *.h, and *.rb files in
|
50
50
|
ext. This must be done manually. Here's a quick way to get the full list:
|
51
51
|
|
52
|
-
$ echo ext/*.c ext/*.h ext/*.rb ext/VERSION | tr ' ' "\n" | sort
|
52
|
+
$ echo ext/*.c ext/*.h ext/*.rb ext/blocktags ext/VERSION | tr ' ' "\n" | sort
|
53
53
|
|
54
54
|
Build the RDiscount gem. If you get errors related to missing files
|
55
55
|
in ext, make sure you updated the gemspec correctly in the previous step.
|
@@ -92,7 +92,8 @@ release tests mentioned above.
|
|
92
92
|
|
93
93
|
Update the CHANGELOG.
|
94
94
|
|
95
|
-
Update rdiscount.gemspec with the new version number and date.
|
95
|
+
Update rdiscount.gemspec with the new RDiscount version number and date.
|
96
|
+
Also update the VERSION constant in lib/rdiscount.rb.
|
96
97
|
Push that change as the final commit with a message in the format
|
97
98
|
"2.0.7 release".
|
98
99
|
|
data/COPYING
CHANGED
@@ -6,47 +6,28 @@ Copyright (C) 2008 Ryan Tomayko.
|
|
6
6
|
|
7
7
|
All rights reserved.
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
itself, in the same form and location as other such third-party
|
35
|
-
acknowledgments.
|
36
|
-
|
37
|
-
4. Except as contained in this notice, the name of David Loren
|
38
|
-
Parsons shall not be used in advertising or otherwise to promote
|
39
|
-
the sale, use or other dealings in this Software without prior
|
40
|
-
written authorization from David Loren Parsons.
|
41
|
-
|
42
|
-
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
|
43
|
-
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
44
|
-
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
45
|
-
IN NO EVENT SHALL DAVID LOREN PARSONS BE LIABLE FOR ANY DIRECT,
|
46
|
-
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
47
|
-
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
48
|
-
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
49
|
-
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
50
|
-
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
51
|
-
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
52
|
-
OF THE POSSIBILITY OF SUCH DAMAGE.
|
9
|
+
Redistribution and use in source and binary forms, with or without
|
10
|
+
modification, are permitted provided that the following conditions
|
11
|
+
are met:
|
12
|
+
|
13
|
+
1. Redistributions of works must retain the original copyright notice,
|
14
|
+
this list of conditions and the following disclaimer.
|
15
|
+
2. Redistributions in binary form must reproduce the original copyright
|
16
|
+
notice, this list of conditions and the following disclaimer in the
|
17
|
+
documentation and/or other materials provided with the distribution.
|
18
|
+
3. Neither my name (David L Parsons) nor the names of contributors to
|
19
|
+
this code may be used to endorse or promote products derived
|
20
|
+
from this work without specific prior written permission.
|
21
|
+
|
22
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
23
|
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
24
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
25
|
+
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
26
|
+
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
27
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
28
|
+
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
29
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
30
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
31
|
+
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
32
|
+
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
33
|
+
POSSIBILITY OF SUCH DAMAGE.
|
data/Rakefile
CHANGED
@@ -111,12 +111,14 @@ CLEAN.include 'doc'
|
|
111
111
|
|
112
112
|
desc 'Gather required discount sources into extension directory'
|
113
113
|
task :gather => 'discount/markdown.h' do |t|
|
114
|
+
# Files unique to /ext that should not be overridden
|
114
115
|
rdiscount_ext_files = [
|
115
116
|
"config.h",
|
116
117
|
"extconf.rb",
|
117
118
|
"rdiscount.c",
|
118
119
|
]
|
119
120
|
|
121
|
+
# Files in /discount that have a main function and should not be copied to /ext
|
120
122
|
discount_c_files_with_main_function = [
|
121
123
|
"main.c",
|
122
124
|
"makepage.c",
|
@@ -152,6 +154,8 @@ task :gather => 'discount/markdown.h' do |t|
|
|
152
154
|
:verbose => true
|
153
155
|
end
|
154
156
|
|
157
|
+
# Copy special files from discount -> ext
|
158
|
+
cp 'discount/blocktags', 'ext/'
|
155
159
|
cp 'discount/VERSION', 'ext/'
|
156
160
|
|
157
161
|
# Copy man page
|
data/ext/Csio.c
CHANGED
@@ -54,7 +54,7 @@ Csreparse(Cstring *iot, char *buf, int size, int flags)
|
|
54
54
|
{
|
55
55
|
MMIOT f;
|
56
56
|
___mkd_initmmiot(&f, 0);
|
57
|
-
___mkd_reparse(buf, size, 0, &f);
|
57
|
+
___mkd_reparse(buf, size, 0, &f, 0);
|
58
58
|
___mkd_emblock(&f);
|
59
59
|
SUFFIX(*iot, T(f.out), S(f.out));
|
60
60
|
___mkd_freemmiot(&f, 0);
|
data/ext/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.1.6
|
data/ext/blocktags
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
static struct kw blocktags[] = {
|
2
|
+
{ "P", 1, 0 },
|
3
|
+
{ "DL", 2, 0 },
|
4
|
+
{ "H1", 2, 0 },
|
5
|
+
{ "H2", 2, 0 },
|
6
|
+
{ "H3", 2, 0 },
|
7
|
+
{ "H4", 2, 0 },
|
8
|
+
{ "H5", 2, 0 },
|
9
|
+
{ "H6", 2, 0 },
|
10
|
+
{ "HR", 2, 1 },
|
11
|
+
{ "OL", 2, 0 },
|
12
|
+
{ "UL", 2, 0 },
|
13
|
+
{ "BDO", 3, 0 },
|
14
|
+
{ "DFN", 3, 0 },
|
15
|
+
{ "DIV", 3, 0 },
|
16
|
+
{ "MAP", 3, 0 },
|
17
|
+
{ "PRE", 3, 0 },
|
18
|
+
{ "WBR", 3, 0 },
|
19
|
+
{ "XMP", 3, 0 },
|
20
|
+
{ "NOBR", 4, 0 },
|
21
|
+
{ "STYLE", 5, 0 },
|
22
|
+
{ "TABLE", 5, 0 },
|
23
|
+
{ "CENTER", 6, 0 },
|
24
|
+
{ "IFRAME", 6, 0 },
|
25
|
+
{ "OBJECT", 6, 0 },
|
26
|
+
{ "SCRIPT", 6, 0 },
|
27
|
+
{ "ADDRESS", 7, 0 },
|
28
|
+
{ "LISTING", 7, 0 },
|
29
|
+
{ "PLAINTEXT", 9, 0 },
|
30
|
+
{ "BLOCKQUOTE", 10, 0 },
|
31
|
+
};
|
32
|
+
|
33
|
+
#define NR_blocktags 29
|
data/ext/config.h
CHANGED
@@ -7,6 +7,12 @@
|
|
7
7
|
/* tabs are four spaces */
|
8
8
|
#define TABSTOP 4
|
9
9
|
|
10
|
+
/* enable fenced code blocks */
|
11
|
+
#define WITH_FENCED_CODE 1
|
12
|
+
|
13
|
+
/* include - and _ as acceptable characters in HTML tag names */
|
14
|
+
#define WITH_GITHUB_TAGS 1
|
15
|
+
|
10
16
|
/* these are setup by extconf.rb */
|
11
17
|
#if HAVE_RANDOM
|
12
18
|
#define COINTOSS() (random()&1)
|
data/ext/cstring.h
CHANGED
@@ -27,9 +27,9 @@
|
|
27
27
|
#define DELETE(x) ALLOCATED(x) ? (free(T(x)), S(x) = (x).alloc = 0) \
|
28
28
|
: ( S(x) = 0 )
|
29
29
|
#define CLIP(t,i,sz) \
|
30
|
-
( ((i) >= 0) && ((sz) > 0) && (((i)+(sz)) <= S(t)) ) ? \
|
30
|
+
S(t) -= ( ((i) >= 0) && ((sz) > 0) && (((i)+(sz)) <= S(t)) ) ? \
|
31
31
|
(memmove(&T(t)[i], &T(t)[i+sz], (S(t)-(i+sz)+1)*sizeof(T(t)[0])), \
|
32
|
-
|
32
|
+
(sz)) : 0
|
33
33
|
|
34
34
|
#define RESERVE(x, sz) T(x) = ((x).alloc > S(x) + (sz) \
|
35
35
|
? T(x) \
|
data/ext/flags.c
CHANGED
data/ext/generate.c
CHANGED
@@ -40,7 +40,7 @@ push(char *bfr, int size, MMIOT *f)
|
|
40
40
|
|
41
41
|
/* look <i> characters ahead of the cursor.
|
42
42
|
*/
|
43
|
-
static int
|
43
|
+
static inline int
|
44
44
|
peek(MMIOT *f, int i)
|
45
45
|
{
|
46
46
|
|
@@ -52,7 +52,7 @@ peek(MMIOT *f, int i)
|
|
52
52
|
|
53
53
|
/* pull a byte from the input buffer
|
54
54
|
*/
|
55
|
-
static int
|
55
|
+
static inline int
|
56
56
|
pull(MMIOT *f)
|
57
57
|
{
|
58
58
|
return ( f->isp < S(f->in) ) ? T(f->in)[f->isp++] : EOF;
|
@@ -61,23 +61,23 @@ pull(MMIOT *f)
|
|
61
61
|
|
62
62
|
/* return a pointer to the current position in the input buffer.
|
63
63
|
*/
|
64
|
-
static char*
|
64
|
+
static inline char*
|
65
65
|
cursor(MMIOT *f)
|
66
66
|
{
|
67
67
|
return T(f->in) + f->isp;
|
68
68
|
}
|
69
69
|
|
70
70
|
|
71
|
-
static int
|
71
|
+
static inline int
|
72
72
|
isthisspace(MMIOT *f, int i)
|
73
73
|
{
|
74
74
|
int c = peek(f, i);
|
75
75
|
|
76
|
-
return isspace(c) || (c
|
76
|
+
return isspace(c) || (c < ' ');
|
77
77
|
}
|
78
78
|
|
79
79
|
|
80
|
-
static int
|
80
|
+
static inline int
|
81
81
|
isthisalnum(MMIOT *f, int i)
|
82
82
|
{
|
83
83
|
int c = peek(f, i);
|
@@ -86,7 +86,7 @@ isthisalnum(MMIOT *f, int i)
|
|
86
86
|
}
|
87
87
|
|
88
88
|
|
89
|
-
static int
|
89
|
+
static inline int
|
90
90
|
isthisnonword(MMIOT *f, int i)
|
91
91
|
{
|
92
92
|
return isthisspace(f, i) || ispunct(peek(f,i));
|
@@ -183,9 +183,10 @@ Qem(MMIOT *f, char c, int count)
|
|
183
183
|
/* generate html from a markup fragment
|
184
184
|
*/
|
185
185
|
void
|
186
|
-
___mkd_reparse(char *bfr, int size, int flags, MMIOT *f)
|
186
|
+
___mkd_reparse(char *bfr, int size, int flags, MMIOT *f, char *esc)
|
187
187
|
{
|
188
188
|
MMIOT sub;
|
189
|
+
struct escaped e;
|
189
190
|
|
190
191
|
___mkd_initmmiot(&sub, f->footnotes);
|
191
192
|
|
@@ -193,6 +194,14 @@ ___mkd_reparse(char *bfr, int size, int flags, MMIOT *f)
|
|
193
194
|
sub.cb = f->cb;
|
194
195
|
sub.ref_prefix = f->ref_prefix;
|
195
196
|
|
197
|
+
if ( esc ) {
|
198
|
+
sub.esc = &e;
|
199
|
+
e.up = f->esc;
|
200
|
+
e.text = esc;
|
201
|
+
}
|
202
|
+
else
|
203
|
+
sub.esc = f->esc;
|
204
|
+
|
196
205
|
push(bfr, size, &sub);
|
197
206
|
EXPAND(sub.in) = 0;
|
198
207
|
S(sub.in)--;
|
@@ -206,6 +215,23 @@ ___mkd_reparse(char *bfr, int size, int flags, MMIOT *f)
|
|
206
215
|
}
|
207
216
|
|
208
217
|
|
218
|
+
/*
|
219
|
+
* check the escape list for special cases
|
220
|
+
*/
|
221
|
+
static int
|
222
|
+
escaped(MMIOT *f, char c)
|
223
|
+
{
|
224
|
+
struct escaped *thing = f->esc;
|
225
|
+
|
226
|
+
while ( thing ) {
|
227
|
+
if ( strchr(thing->text, c) )
|
228
|
+
return 1;
|
229
|
+
thing = thing->up;
|
230
|
+
}
|
231
|
+
return 0;
|
232
|
+
}
|
233
|
+
|
234
|
+
|
209
235
|
/*
|
210
236
|
* write out a url, escaping problematic characters
|
211
237
|
*/
|
@@ -553,7 +579,7 @@ printlinkyref(MMIOT *f, linkytype *tag, char *link, int size)
|
|
553
579
|
puturl(link + tag->szpat, size - tag->szpat, f, 0);
|
554
580
|
}
|
555
581
|
else
|
556
|
-
___mkd_reparse(link + tag->szpat, size - tag->szpat, MKD_TAGTEXT, f);
|
582
|
+
___mkd_reparse(link + tag->szpat, size - tag->szpat, MKD_TAGTEXT, f, 0);
|
557
583
|
|
558
584
|
Qstring(tag->link_sfx, f);
|
559
585
|
|
@@ -585,7 +611,7 @@ extra_linky(MMIOT *f, Cstring text, Footnote *ref)
|
|
585
611
|
return 0;
|
586
612
|
|
587
613
|
if ( f->flags & IS_LABEL )
|
588
|
-
___mkd_reparse(T(text), S(text), linkt.flags, f);
|
614
|
+
___mkd_reparse(T(text), S(text), linkt.flags, f, 0);
|
589
615
|
else {
|
590
616
|
ref->flags |= REFERENCED;
|
591
617
|
ref->refnumber = ++ f->reference;
|
@@ -604,7 +630,8 @@ linkyformat(MMIOT *f, Cstring text, int image, Footnote *ref)
|
|
604
630
|
{
|
605
631
|
linkytype *tag;
|
606
632
|
|
607
|
-
|
633
|
+
|
634
|
+
if ( image )
|
608
635
|
tag = &imaget;
|
609
636
|
else if ( tag = pseudo(ref->link) ) {
|
610
637
|
if ( f->flags & (MKD_NO_EXT|MKD_SAFELINK) )
|
@@ -624,7 +651,7 @@ linkyformat(MMIOT *f, Cstring text, int image, Footnote *ref)
|
|
624
651
|
return 0;
|
625
652
|
|
626
653
|
if ( f->flags & IS_LABEL )
|
627
|
-
___mkd_reparse(T(text), S(text), tag->flags, f);
|
654
|
+
___mkd_reparse(T(text), S(text), tag->flags, f, 0);
|
628
655
|
else if ( tag->link_pfx ) {
|
629
656
|
printlinkyref(f, tag, T(ref->link), S(ref->link));
|
630
657
|
|
@@ -635,12 +662,12 @@ linkyformat(MMIOT *f, Cstring text, int image, Footnote *ref)
|
|
635
662
|
|
636
663
|
if ( S(ref->title) ) {
|
637
664
|
Qstring(" title=\"", f);
|
638
|
-
___mkd_reparse(T(ref->title), S(ref->title), MKD_TAGTEXT, f);
|
665
|
+
___mkd_reparse(T(ref->title), S(ref->title), MKD_TAGTEXT, f, 0);
|
639
666
|
Qchar('"', f);
|
640
667
|
}
|
641
668
|
|
642
669
|
Qstring(tag->text_pfx, f);
|
643
|
-
___mkd_reparse(T(text), S(text), tag->flags, f);
|
670
|
+
___mkd_reparse(T(text), S(text), tag->flags, f, 0);
|
644
671
|
Qstring(tag->text_sfx, f);
|
645
672
|
}
|
646
673
|
else
|
@@ -707,8 +734,6 @@ linkylinky(int image, MMIOT *f)
|
|
707
734
|
else
|
708
735
|
status = linkyformat(f, name, image, ref);
|
709
736
|
}
|
710
|
-
else if ( f->flags & IS_LABEL )
|
711
|
-
status = linkyformat(f, name, image, 0);
|
712
737
|
}
|
713
738
|
}
|
714
739
|
}
|
@@ -810,6 +835,8 @@ code(MMIOT *f, char *s, int length)
|
|
810
835
|
for ( i=0; i < length; i++ )
|
811
836
|
if ( (c = s[i]) == 003) /* ^C: expand back to 2 spaces */
|
812
837
|
Qstring(" ", f);
|
838
|
+
else if ( c == '\\' && (i < length-1) && escaped(f, s[i+1]) )
|
839
|
+
cputc(s[++i], f);
|
813
840
|
else
|
814
841
|
cputc(c, f);
|
815
842
|
} /* code */
|
@@ -821,7 +848,7 @@ static void
|
|
821
848
|
delspan(MMIOT *f, int size)
|
822
849
|
{
|
823
850
|
Qstring("<del>", f);
|
824
|
-
___mkd_reparse(cursor(f)-1, size, 0, f);
|
851
|
+
___mkd_reparse(cursor(f)-1, size, 0, f, 0);
|
825
852
|
Qstring("</del>", f);
|
826
853
|
}
|
827
854
|
|
@@ -963,7 +990,11 @@ maybe_tag_or_link(MMIOT *f)
|
|
963
990
|
}
|
964
991
|
else if ( isspace(c) )
|
965
992
|
break;
|
993
|
+
#if WITH_GITHUB_TAGS
|
994
|
+
else if ( ! (c == '/' || c == '-' || c == '_' || isalnum(c) ) )
|
995
|
+
#else
|
966
996
|
else if ( ! (c == '/' || isalnum(c) ) )
|
997
|
+
#endif
|
967
998
|
maybetag=0;
|
968
999
|
}
|
969
1000
|
|
@@ -1054,7 +1085,7 @@ islike(MMIOT *f, char *s)
|
|
1054
1085
|
int len;
|
1055
1086
|
int i;
|
1056
1087
|
|
1057
|
-
if ( s[0] == '
|
1088
|
+
if ( s[0] == '|' ) {
|
1058
1089
|
if ( !isthisnonword(f, -1) )
|
1059
1090
|
return 0;
|
1060
1091
|
++s;
|
@@ -1063,7 +1094,7 @@ islike(MMIOT *f, char *s)
|
|
1063
1094
|
if ( !(len = strlen(s)) )
|
1064
1095
|
return 0;
|
1065
1096
|
|
1066
|
-
if ( s[len-1] == '
|
1097
|
+
if ( s[len-1] == '|' ) {
|
1067
1098
|
if ( !isthisnonword(f,len-1) )
|
1068
1099
|
return 0;
|
1069
1100
|
len--;
|
@@ -1082,25 +1113,25 @@ static struct smarties {
|
|
1082
1113
|
char *entity;
|
1083
1114
|
int shift;
|
1084
1115
|
} smarties[] = {
|
1085
|
-
{ '\'', "'s
|
1086
|
-
{ '\'', "'t
|
1087
|
-
{ '\'', "'re
|
1088
|
-
{ '\'', "'ll
|
1089
|
-
{ '\'', "'ve
|
1090
|
-
{ '\'', "'m
|
1091
|
-
{ '\'', "'d
|
1092
|
-
{ '-', "
|
1093
|
-
{ '-', "
|
1116
|
+
{ '\'', "'s|", "rsquo", 0 },
|
1117
|
+
{ '\'', "'t|", "rsquo", 0 },
|
1118
|
+
{ '\'', "'re|", "rsquo", 0 },
|
1119
|
+
{ '\'', "'ll|", "rsquo", 0 },
|
1120
|
+
{ '\'', "'ve|", "rsquo", 0 },
|
1121
|
+
{ '\'', "'m|", "rsquo", 0 },
|
1122
|
+
{ '\'', "'d|", "rsquo", 0 },
|
1123
|
+
{ '-', "---", "mdash", 2 },
|
1124
|
+
{ '-', "--", "ndash", 1 },
|
1094
1125
|
{ '.', "...", "hellip", 2 },
|
1095
1126
|
{ '.', ". . .", "hellip", 4 },
|
1096
1127
|
{ '(', "(c)", "copy", 2 },
|
1097
1128
|
{ '(', "(r)", "reg", 2 },
|
1098
1129
|
{ '(', "(tm)", "trade", 3 },
|
1099
|
-
{ '3', "
|
1100
|
-
{ '3', "
|
1101
|
-
{ '1', "
|
1102
|
-
{ '1', "
|
1103
|
-
{ '1', "
|
1130
|
+
{ '3', "|3/4|", "frac34", 2 },
|
1131
|
+
{ '3', "|3/4ths|", "frac34", 2 },
|
1132
|
+
{ '1', "|1/2|", "frac12", 2 },
|
1133
|
+
{ '1', "|1/4|", "frac14", 2 },
|
1134
|
+
{ '1', "|1/4th|", "frac14", 2 },
|
1104
1135
|
{ '&', "�", 0, 3 },
|
1105
1136
|
} ;
|
1106
1137
|
#define NRSMART ( sizeof smarties / sizeof smarties[0] )
|
@@ -1142,7 +1173,7 @@ smartypants(int c, int *flags, MMIOT *f)
|
|
1142
1173
|
break;
|
1143
1174
|
else if ( c == '\'' && peek(f, j+1) == '\'' ) {
|
1144
1175
|
Qstring("“", f);
|
1145
|
-
___mkd_reparse(cursor(f)+1, j-2, 0, f);
|
1176
|
+
___mkd_reparse(cursor(f)+1, j-2, 0, f, 0);
|
1146
1177
|
Qstring("”", f);
|
1147
1178
|
shift(f,j+1);
|
1148
1179
|
return 1;
|
@@ -1162,11 +1193,14 @@ smartypants(int c, int *flags, MMIOT *f)
|
|
1162
1193
|
* let the caller figure it out.
|
1163
1194
|
*/
|
1164
1195
|
static int
|
1165
|
-
tickhandler(MMIOT *f, int tickchar, int minticks, spanhandler spanner)
|
1196
|
+
tickhandler(MMIOT *f, int tickchar, int minticks, int allow_space, spanhandler spanner)
|
1166
1197
|
{
|
1167
1198
|
int endticks, size;
|
1168
1199
|
int tick = nrticks(0, tickchar, f);
|
1169
1200
|
|
1201
|
+
if ( !allow_space && isspace(peek(f,tick)) )
|
1202
|
+
return 0;
|
1203
|
+
|
1170
1204
|
if ( (tick >= minticks) && (size = matchticks(f,tickchar,tick,&endticks)) ) {
|
1171
1205
|
if ( endticks < tick ) {
|
1172
1206
|
size += (tick - endticks);
|
@@ -1261,7 +1295,7 @@ text(MMIOT *f)
|
|
1261
1295
|
shift(f,len);
|
1262
1296
|
}
|
1263
1297
|
Qstring("<sup>",f);
|
1264
|
-
___mkd_reparse(sup, len, 0, f);
|
1298
|
+
___mkd_reparse(sup, len, 0, f, "()");
|
1265
1299
|
Qstring("</sup>", f);
|
1266
1300
|
}
|
1267
1301
|
break;
|
@@ -1290,18 +1324,27 @@ text(MMIOT *f)
|
|
1290
1324
|
}
|
1291
1325
|
break;
|
1292
1326
|
|
1293
|
-
case '~': if ( (f->flags & (MKD_NOSTRIKETHROUGH|MKD_TAGTEXT|MKD_STRICT)) || !tickhandler(f,c,2,delspan) )
|
1327
|
+
case '~': if ( (f->flags & (MKD_NOSTRIKETHROUGH|MKD_TAGTEXT|MKD_STRICT)) || ! tickhandler(f,c,2,0, delspan) )
|
1294
1328
|
Qchar(c, f);
|
1295
1329
|
break;
|
1296
1330
|
|
1297
|
-
case '`': if ( tag_text(f) || !tickhandler(f,c,1,codespan) )
|
1331
|
+
case '`': if ( tag_text(f) || !tickhandler(f,c,1,1,codespan) )
|
1298
1332
|
Qchar(c, f);
|
1299
1333
|
break;
|
1300
1334
|
|
1301
1335
|
case '\\': switch ( c = pull(f) ) {
|
1302
1336
|
case '&': Qstring("&", f);
|
1303
1337
|
break;
|
1304
|
-
case '<':
|
1338
|
+
case '<': c = peek(f,1);
|
1339
|
+
if ( (c == EOF) || isspace(c) )
|
1340
|
+
Qstring("<", f);
|
1341
|
+
else {
|
1342
|
+
/* Markdown.pl does not escape <[nonwhite]
|
1343
|
+
* sequences */
|
1344
|
+
Qchar('\\', f);
|
1345
|
+
shift(f, -1);
|
1346
|
+
}
|
1347
|
+
|
1305
1348
|
break;
|
1306
1349
|
case '^': if ( f->flags & (MKD_STRICT|MKD_NOSUPERSCRIPT) ) {
|
1307
1350
|
Qchar('\\', f);
|
@@ -1311,16 +1354,25 @@ text(MMIOT *f)
|
|
1311
1354
|
Qchar(c, f);
|
1312
1355
|
break;
|
1313
1356
|
|
1314
|
-
case '
|
1315
|
-
|
1316
|
-
|
1317
|
-
case '\\':case '(': case ')':
|
1318
|
-
case '`': Qchar(c, f);
|
1319
|
-
break;
|
1320
|
-
default:
|
1321
|
-
Qchar('\\', f);
|
1322
|
-
if ( c != EOF )
|
1357
|
+
case ':': case '|':
|
1358
|
+
if ( f->flags & MKD_NOTABLES ) {
|
1359
|
+
Qchar('\\', f);
|
1323
1360
|
shift(f,-1);
|
1361
|
+
break;
|
1362
|
+
}
|
1363
|
+
Qchar(c, f);
|
1364
|
+
break;
|
1365
|
+
|
1366
|
+
case EOF: Qchar('\\', f);
|
1367
|
+
break;
|
1368
|
+
|
1369
|
+
default: if ( escaped(f,c) ||
|
1370
|
+
strchr(">#.-+{}]![*_\\()`", c) )
|
1371
|
+
Qchar(c, f);
|
1372
|
+
else {
|
1373
|
+
Qchar('\\', f);
|
1374
|
+
shift(f, -1);
|
1375
|
+
}
|
1324
1376
|
break;
|
1325
1377
|
}
|
1326
1378
|
break;
|
@@ -1353,6 +1405,17 @@ text(MMIOT *f)
|
|
1353
1405
|
static void
|
1354
1406
|
printheader(Paragraph *pp, MMIOT *f)
|
1355
1407
|
{
|
1408
|
+
#if WITH_ID_ANCHOR
|
1409
|
+
Qprintf(f, "<h%d", pp->hnumber);
|
1410
|
+
if ( f->flags & MKD_TOC ) {
|
1411
|
+
Qstring(" id=\"", f);
|
1412
|
+
mkd_string_to_anchor(T(pp->text->text),
|
1413
|
+
S(pp->text->text),
|
1414
|
+
(mkd_sta_function_t)Qchar, f, 1);
|
1415
|
+
Qchar('"', f);
|
1416
|
+
}
|
1417
|
+
Qchar('>', f);
|
1418
|
+
#else
|
1356
1419
|
if ( f->flags & MKD_TOC ) {
|
1357
1420
|
Qstring("<a name=\"", f);
|
1358
1421
|
mkd_string_to_anchor(T(pp->text->text),
|
@@ -1361,6 +1424,7 @@ printheader(Paragraph *pp, MMIOT *f)
|
|
1361
1424
|
Qstring("\"></a>\n", f);
|
1362
1425
|
}
|
1363
1426
|
Qprintf(f, "<h%d>", pp->hnumber);
|
1427
|
+
#endif
|
1364
1428
|
push(T(pp->text->text), S(pp->text->text), f);
|
1365
1429
|
text(f);
|
1366
1430
|
Qprintf(f, "</h%d>", pp->hnumber);
|
@@ -1369,8 +1433,9 @@ printheader(Paragraph *pp, MMIOT *f)
|
|
1369
1433
|
|
1370
1434
|
enum e_alignments { a_NONE, a_CENTER, a_LEFT, a_RIGHT };
|
1371
1435
|
|
1372
|
-
static char* alignments[] = { "", "
|
1373
|
-
"
|
1436
|
+
static char* alignments[] = { "", " style=\"text-align:center;\"",
|
1437
|
+
" style=\"text-align:left;\"",
|
1438
|
+
" style=\"text-align:right;\"" };
|
1374
1439
|
|
1375
1440
|
typedef STRING(int) Istring;
|
1376
1441
|
|
@@ -1378,22 +1443,30 @@ static int
|
|
1378
1443
|
splat(Line *p, char *block, Istring align, int force, MMIOT *f)
|
1379
1444
|
{
|
1380
1445
|
int first,
|
1381
|
-
idx =
|
1446
|
+
idx = p->dle,
|
1382
1447
|
colno = 0;
|
1383
1448
|
|
1449
|
+
|
1450
|
+
___mkd_tidy(&p->text);
|
1451
|
+
if ( T(p->text)[S(p->text)-1] == '|' )
|
1452
|
+
--S(p->text);
|
1453
|
+
|
1384
1454
|
Qstring("<tr>\n", f);
|
1385
1455
|
while ( idx < S(p->text) ) {
|
1386
1456
|
first = idx;
|
1387
1457
|
if ( force && (colno >= S(align)-1) )
|
1388
1458
|
idx = S(p->text);
|
1389
1459
|
else
|
1390
|
-
while ( (idx < S(p->text)) && (T(p->text)[idx] != '|') )
|
1460
|
+
while ( (idx < S(p->text)) && (T(p->text)[idx] != '|') ) {
|
1461
|
+
if ( T(p->text)[idx] == '\\' )
|
1462
|
+
++idx;
|
1391
1463
|
++idx;
|
1464
|
+
}
|
1392
1465
|
|
1393
1466
|
Qprintf(f, "<%s%s>",
|
1394
1467
|
block,
|
1395
1468
|
alignments[ (colno < S(align)) ? T(align)[colno] : a_NONE ]);
|
1396
|
-
___mkd_reparse(T(p->text)+first, idx-first, 0, f);
|
1469
|
+
___mkd_reparse(T(p->text)+first, idx-first, 0, f, "|");
|
1397
1470
|
Qprintf(f, "</%s>\n", block);
|
1398
1471
|
idx++;
|
1399
1472
|
colno++;
|
@@ -1415,34 +1488,43 @@ printtable(Paragraph *pp, MMIOT *f)
|
|
1415
1488
|
|
1416
1489
|
Line *hdr, *dash, *body;
|
1417
1490
|
Istring align;
|
1418
|
-
int start;
|
1419
|
-
int hcols;
|
1491
|
+
int hcols,start;
|
1420
1492
|
char *p;
|
1421
|
-
|
1422
|
-
if ( !(pp->text && pp->text->next) )
|
1423
|
-
return 0;
|
1493
|
+
enum e_alignments it;
|
1424
1494
|
|
1425
1495
|
hdr = pp->text;
|
1426
1496
|
dash= hdr->next;
|
1427
1497
|
body= dash->next;
|
1428
1498
|
|
1429
|
-
|
1499
|
+
if ( T(hdr->text)[hdr->dle] == '|' ) {
|
1500
|
+
/* trim leading pipe off all lines
|
1501
|
+
*/
|
1502
|
+
Line *r;
|
1503
|
+
for ( r = pp->text; r; r = r->next )
|
1504
|
+
r->dle ++;
|
1505
|
+
}
|
1506
|
+
|
1507
|
+
/* figure out cell alignments */
|
1430
1508
|
|
1431
1509
|
CREATE(align);
|
1432
1510
|
|
1433
|
-
for (p=T(dash->text), start=
|
1511
|
+
for (p=T(dash->text), start=dash->dle; start < S(dash->text); ) {
|
1434
1512
|
char first, last;
|
1435
1513
|
int end;
|
1436
1514
|
|
1437
1515
|
last=first=0;
|
1438
1516
|
for (end=start ; (end < S(dash->text)) && p[end] != '|'; ++ end ) {
|
1439
|
-
if (
|
1517
|
+
if ( p[end] == '\\' )
|
1518
|
+
++ end;
|
1519
|
+
else if ( !isspace(p[end]) ) {
|
1440
1520
|
if ( !first) first = p[end];
|
1441
1521
|
last = p[end];
|
1442
1522
|
}
|
1443
1523
|
}
|
1444
|
-
|
1445
|
-
|
1524
|
+
it = ( first == ':' ) ? (( last == ':') ? a_CENTER : a_LEFT)
|
1525
|
+
: (( last == ':') ? a_RIGHT : a_NONE );
|
1526
|
+
|
1527
|
+
EXPAND(align) = it;
|
1446
1528
|
start = 1+end;
|
1447
1529
|
}
|
1448
1530
|
|
@@ -1568,7 +1650,7 @@ definitionlist(Paragraph *p, MMIOT *f)
|
|
1568
1650
|
for ( ; p ; p = p->next) {
|
1569
1651
|
for ( tag = p->text; tag; tag = tag->next ) {
|
1570
1652
|
Qstring("<dt>", f);
|
1571
|
-
___mkd_reparse(T(tag->text), S(tag->text), 0, f);
|
1653
|
+
___mkd_reparse(T(tag->text), S(tag->text), 0, f, 0);
|
1572
1654
|
Qstring("</dt>\n", f);
|
1573
1655
|
}
|
1574
1656
|
|