rdiscount 2.0.7.3 → 2.1.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|