pixeltrix-rdiscount 1.2.11 → 1.3.4
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +70 -38
- data/ext/Csio.c +49 -0
- data/ext/cstring.h +5 -0
- data/ext/extconf.rb +0 -6
- data/ext/generate.c +115 -59
- data/ext/markdown.c +127 -34
- data/ext/markdown.h +11 -2
- data/ext/mkdio.c +16 -0
- data/ext/mkdio.h +7 -0
- data/ext/rdiscount.c +62 -14
- data/ext/resource.c +2 -0
- data/ext/toc.c +86 -0
- data/lib/rdiscount.rb +4 -0
- data/rdiscount.gemspec +39 -35
- data/test/markdown_test.rb +20 -5
- data/test/rdiscount_test.rb +29 -1
- metadata +12 -14
- data/ext/rbstrio.c +0 -48
- data/ext/rbstrio.h +0 -4
data/Rakefile
CHANGED
@@ -1,43 +1,75 @@
|
|
1
1
|
require 'rake/clean'
|
2
|
-
require 'rake/packagetask'
|
3
|
-
require 'rake/gempackagetask'
|
4
2
|
|
5
|
-
task :default =>
|
3
|
+
task :default => :test
|
6
4
|
|
7
|
-
|
8
|
-
VERS = '1.2.11'
|
9
|
-
|
10
|
-
spec =
|
11
|
-
Gem::Specification.new do |s|
|
12
|
-
s.name = "rdiscount"
|
13
|
-
s.version = VERS
|
14
|
-
s.summary = "Fast Implementation of Gruber's Markdown in C"
|
15
|
-
s.files = FileList['README.markdown','COPYING','Rakefile','test/**','{lib,ext}/**.rb','ext/*.{c,h}']
|
16
|
-
s.bindir = 'bin'
|
17
|
-
s.require_path = 'lib'
|
18
|
-
s.has_rdoc = true
|
19
|
-
s.extra_rdoc_files = ['COPYING']
|
20
|
-
s.test_files = FileList['test/*_test.rb']
|
21
|
-
s.extensions = ['ext/extconf.rb']
|
22
|
-
|
23
|
-
s.author = 'Ryan Tomayko'
|
24
|
-
s.email = 'r@tomayko.com'
|
25
|
-
s.homepage = 'http://github.com/rtomayko/rdiscount'
|
26
|
-
s.rubyforge_project = 'wink'
|
27
|
-
end
|
5
|
+
# PACKAGING =================================================================
|
28
6
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
7
|
+
# Load the gemspec using the same limitations as github
|
8
|
+
$spec =
|
9
|
+
begin
|
10
|
+
require 'rubygems/specification'
|
11
|
+
data = File.read('rdiscount.gemspec')
|
12
|
+
spec = nil
|
13
|
+
Thread.new { spec = eval("$SAFE = 3\n#{data}") }.join
|
14
|
+
spec
|
34
15
|
end
|
35
16
|
|
17
|
+
def package(ext='')
|
18
|
+
"pkg/rdiscount-#{$spec.version}" + ext
|
19
|
+
end
|
20
|
+
|
21
|
+
desc 'Build packages'
|
22
|
+
task :package => %w[.gem .tar.gz].map {|e| package(e)}
|
23
|
+
|
24
|
+
desc 'Build and install as local gem'
|
25
|
+
task :install => package('.gem') do
|
26
|
+
sh "gem install #{package('.gem')}"
|
27
|
+
end
|
28
|
+
|
29
|
+
directory 'pkg/'
|
30
|
+
|
31
|
+
file package('.gem') => %w[pkg/ rdiscount.gemspec] + $spec.files do |f|
|
32
|
+
sh "gem build rdiscount.gemspec"
|
33
|
+
mv File.basename(f.name), f.name
|
34
|
+
end
|
35
|
+
|
36
|
+
file package('.tar.gz') => %w[pkg/] + $spec.files do |f|
|
37
|
+
sh "git archive --format=tar HEAD | gzip > #{f.name}"
|
38
|
+
end
|
39
|
+
|
40
|
+
# GEMSPEC HELPERS ==========================================================
|
41
|
+
|
42
|
+
def source_version
|
43
|
+
line = File.read('lib/rdiscount.rb')[/^\s*VERSION = .*/]
|
44
|
+
line.match(/.*VERSION = '(.*)'/)[1]
|
45
|
+
end
|
46
|
+
|
47
|
+
file 'rdiscount.gemspec' => FileList['Rakefile','lib/rdiscount.rb'] do |f|
|
48
|
+
# read spec file and split out manifest section
|
49
|
+
spec = File.read(f.name)
|
50
|
+
head, manifest, tail = spec.split(" # = MANIFEST =\n")
|
51
|
+
head.sub!(/\.version = '.*'/, ".version = '#{source_version}'")
|
52
|
+
head.sub!(/\.date = '.*'/, ".date = '#{Date.today.to_s}'")
|
53
|
+
# determine file list from git ls-files
|
54
|
+
files = `git ls-files`.
|
55
|
+
split("\n").
|
56
|
+
sort.
|
57
|
+
reject{ |file| file =~ /^\./ || file =~ /^test\/MarkdownTest/ }.
|
58
|
+
map{ |file| " #{file}" }.
|
59
|
+
join("\n")
|
60
|
+
# piece file back together and write...
|
61
|
+
manifest = " s.files = %w[\n#{files}\n ]\n"
|
62
|
+
spec = [head,manifest,tail].join(" # = MANIFEST =\n")
|
63
|
+
File.open(f.name, 'w') { |io| io.write(spec) }
|
64
|
+
puts "updated #{f.name}"
|
65
|
+
end
|
36
66
|
|
37
67
|
# ==========================================================
|
38
68
|
# Ruby Extension
|
39
69
|
# ==========================================================
|
40
70
|
|
71
|
+
DLEXT = Config::CONFIG['DLEXT']
|
72
|
+
|
41
73
|
file 'ext/Makefile' => FileList['ext/{*.c,*.h,*.rb}'] do
|
42
74
|
chdir('ext') { ruby 'extconf.rb' }
|
43
75
|
end
|
@@ -55,7 +87,6 @@ end
|
|
55
87
|
desc 'Build the rdiscount extension'
|
56
88
|
task :build => "lib/rdiscount.#{DLEXT}"
|
57
89
|
|
58
|
-
|
59
90
|
# ==========================================================
|
60
91
|
# Testing
|
61
92
|
# ==========================================================
|
@@ -68,14 +99,17 @@ end
|
|
68
99
|
desc 'Run conformance tests (MARKDOWN_TEST_VER=1.0)'
|
69
100
|
task 'test:conformance' => [:build] do |t|
|
70
101
|
script = "#{pwd}/bin/rdiscount"
|
71
|
-
test_version = ENV['MARKDOWN_TEST_VER'] || '1.0'
|
102
|
+
test_version = ENV['MARKDOWN_TEST_VER'] || '1.0.3'
|
72
103
|
chdir("test/MarkdownTest_#{test_version}") do
|
73
104
|
sh "./MarkdownTest.pl --script='#{script}' --tidy"
|
74
105
|
end
|
75
106
|
end
|
76
107
|
|
77
108
|
desc 'Run version 1.0 conformance suite'
|
78
|
-
task 'test:conformance:1.0' =>
|
109
|
+
task 'test:conformance:1.0' => [:build] do |t|
|
110
|
+
ENV['MARKDOWN_TEST_VER'] = '1.0'
|
111
|
+
Rake::Task['test:conformance'].invoke
|
112
|
+
end
|
79
113
|
|
80
114
|
desc 'Run 1.0.3 conformance suite'
|
81
115
|
task 'test:conformance:1.0.3' => [:build] do |t|
|
@@ -119,13 +153,11 @@ CLEAN.include 'doc'
|
|
119
153
|
# Rubyforge
|
120
154
|
# ==========================================================
|
121
155
|
|
122
|
-
PKGNAME = "pkg/rdiscount-#{VERS}"
|
123
|
-
|
124
156
|
desc 'Publish new release to rubyforge'
|
125
|
-
task :release => [
|
157
|
+
task :release => [package('.gem'), package('.tar.gz')] do |t|
|
126
158
|
sh <<-end
|
127
|
-
rubyforge add_release wink rdiscount #{
|
128
|
-
rubyforge add_file wink rdiscount #{
|
159
|
+
rubyforge add_release wink rdiscount #{$spec.version} #{package('.gem')} &&
|
160
|
+
rubyforge add_file wink rdiscount #{$spec.version} #{package('.tar.gz')}
|
129
161
|
end
|
130
162
|
end
|
131
163
|
|
@@ -143,7 +175,7 @@ task :gather => 'discount' do |t|
|
|
143
175
|
files =
|
144
176
|
FileList[
|
145
177
|
'discount/{markdown,mkdio,amalloc,cstring}.h',
|
146
|
-
'discount/{markdown,docheader,dumptree,generate,mkdio,resource}.c'
|
178
|
+
'discount/{markdown,docheader,dumptree,generate,mkdio,resource,toc,Csio}.c'
|
147
179
|
]
|
148
180
|
cp files, 'ext/',
|
149
181
|
:preserve => true,
|
data/ext/Csio.c
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
#include <stdio.h>
|
2
|
+
#include <string.h>
|
3
|
+
#include <stdarg.h>
|
4
|
+
#include "cstring.h"
|
5
|
+
#include "markdown.h"
|
6
|
+
#include "amalloc.h"
|
7
|
+
|
8
|
+
|
9
|
+
/* putc() into a cstring
|
10
|
+
*/
|
11
|
+
void
|
12
|
+
Csputc(int c, Cstring *iot)
|
13
|
+
{
|
14
|
+
EXPAND(*iot) = c;
|
15
|
+
}
|
16
|
+
|
17
|
+
|
18
|
+
/* printf() into a cstring
|
19
|
+
*/
|
20
|
+
int
|
21
|
+
Csprintf(Cstring *iot, char *fmt, ...)
|
22
|
+
{
|
23
|
+
va_list ptr;
|
24
|
+
int siz=100;
|
25
|
+
|
26
|
+
do {
|
27
|
+
RESERVE(*iot, siz);
|
28
|
+
va_start(ptr, fmt);
|
29
|
+
siz = vsnprintf(T(*iot)+S(*iot), ALL(*iot)-S(*iot), fmt, ptr);
|
30
|
+
va_end(ptr);
|
31
|
+
} while ( siz > (ALL(*iot)-S(*iot)) );
|
32
|
+
|
33
|
+
S(*iot) += siz;
|
34
|
+
return siz;
|
35
|
+
}
|
36
|
+
|
37
|
+
|
38
|
+
/* reparse() into a cstring
|
39
|
+
*/
|
40
|
+
void
|
41
|
+
Csreparse(Cstring *iot, char *buf, int size, int flags)
|
42
|
+
{
|
43
|
+
MMIOT f;
|
44
|
+
___mkd_initmmiot(&f, 0);
|
45
|
+
___mkd_reparse(buf, size, 0, &f);
|
46
|
+
___mkd_emblock(&f);
|
47
|
+
SUFFIX(*iot, T(f.out), S(f.out));
|
48
|
+
___mkd_freemmiot(&f, 0);
|
49
|
+
}
|
data/ext/cstring.h
CHANGED
@@ -50,6 +50,7 @@
|
|
50
50
|
*/
|
51
51
|
#define T(x) (x).text
|
52
52
|
#define S(x) (x).size
|
53
|
+
#define ALL(x) (x).alloc
|
53
54
|
|
54
55
|
/* abstract anchor type that defines a list base
|
55
56
|
* with a function that attaches an element to
|
@@ -65,4 +66,8 @@
|
|
65
66
|
|
66
67
|
typedef STRING(char) Cstring;
|
67
68
|
|
69
|
+
extern void Csputc(int, Cstring *);
|
70
|
+
extern int Csprintf(Cstring *, char *, ...);
|
71
|
+
extern void Csreparse(Cstring *, char *, int, int);
|
72
|
+
|
68
73
|
#endif/*_CSTRING_D*/
|
data/ext/extconf.rb
CHANGED
@@ -4,11 +4,5 @@ dir_config('rdiscount')
|
|
4
4
|
|
5
5
|
HAVE_RANDOM = have_func('random')
|
6
6
|
HAVE_SRANDOM = have_func('srandom')
|
7
|
-
HAVE_FUNOPEN = have_func('funopen')
|
8
|
-
HAVE_FOPENCOOKIE = have_func('fopencookie')
|
9
|
-
|
10
|
-
unless HAVE_FUNOPEN || HAVE_FOPENCOOKIE
|
11
|
-
fail "No funopen or fopencookie support available."
|
12
|
-
end
|
13
7
|
|
14
8
|
create_makefile('rdiscount')
|
data/ext/generate.c
CHANGED
@@ -26,6 +26,7 @@ typedef int (*stfu)(const void*,const void*);
|
|
26
26
|
|
27
27
|
|
28
28
|
/* forward declarations */
|
29
|
+
static int iscodeblock(MMIOT*);
|
29
30
|
static void code(int, MMIOT*);
|
30
31
|
static void text(MMIOT *f);
|
31
32
|
static Paragraph *display(Paragraph*, MMIOT*);
|
@@ -74,6 +75,31 @@ cursor(MMIOT *f)
|
|
74
75
|
}
|
75
76
|
|
76
77
|
|
78
|
+
static int
|
79
|
+
isthisspace(MMIOT *f, int i)
|
80
|
+
{
|
81
|
+
int c = peek(f, i);
|
82
|
+
|
83
|
+
return isspace(c) || (c == EOF);
|
84
|
+
}
|
85
|
+
|
86
|
+
|
87
|
+
static int
|
88
|
+
isthisalnum(MMIOT *f, int i)
|
89
|
+
{
|
90
|
+
int c = peek(f, i);
|
91
|
+
|
92
|
+
return (c != EOF) && isalnum(c);
|
93
|
+
}
|
94
|
+
|
95
|
+
|
96
|
+
static int
|
97
|
+
isthisnonword(MMIOT *f, int i)
|
98
|
+
{
|
99
|
+
return isthisspace(f, i) || ispunct(peek(f,i));
|
100
|
+
}
|
101
|
+
|
102
|
+
|
77
103
|
/* return/set the current cursor position
|
78
104
|
*/
|
79
105
|
#define mmiotseek(f,x) (f->isp = x)
|
@@ -251,10 +277,10 @@ emmatch(MMIOT *f, int go)
|
|
251
277
|
}
|
252
278
|
|
253
279
|
|
254
|
-
/*
|
280
|
+
/* ___mkd_emblock()
|
255
281
|
*/
|
256
|
-
|
257
|
-
|
282
|
+
void
|
283
|
+
___mkd_emblock(MMIOT *f)
|
258
284
|
{
|
259
285
|
int i;
|
260
286
|
block *p;
|
@@ -275,8 +301,8 @@ emblock(MMIOT *f)
|
|
275
301
|
|
276
302
|
/* generate html from a markup fragment
|
277
303
|
*/
|
278
|
-
|
279
|
-
|
304
|
+
void
|
305
|
+
___mkd_reparse(char *bfr, int size, int flags, MMIOT *f)
|
280
306
|
{
|
281
307
|
MMIOT sub;
|
282
308
|
|
@@ -290,7 +316,7 @@ reparse(char *bfr, int size, int flags, MMIOT *f)
|
|
290
316
|
S(sub.in)--;
|
291
317
|
|
292
318
|
text(&sub);
|
293
|
-
|
319
|
+
___mkd_emblock(&sub);
|
294
320
|
|
295
321
|
Qwrite(T(sub.out), S(sub.out), f);
|
296
322
|
|
@@ -313,6 +339,8 @@ puturl(char *s, int size, MMIOT *f)
|
|
313
339
|
Qstring("&", f);
|
314
340
|
else if ( c == '<' )
|
315
341
|
Qstring("<", f);
|
342
|
+
else if ( isalnum(c) || ispunct(c) )
|
343
|
+
Qchar(c, f);
|
316
344
|
else
|
317
345
|
Qchar(c, f);
|
318
346
|
}
|
@@ -469,12 +497,14 @@ linkykey(int image, Footnote *val, MMIOT *f)
|
|
469
497
|
{
|
470
498
|
Footnote *ret;
|
471
499
|
Cstring mylabel;
|
500
|
+
int here;
|
472
501
|
|
473
502
|
memset(val, 0, sizeof *val);
|
474
503
|
|
475
504
|
if ( (T(val->tag) = linkylabel(f, &S(val->tag))) == 0 )
|
476
505
|
return 0;
|
477
506
|
|
507
|
+
here = mmiottell(f);
|
478
508
|
eatspace(f);
|
479
509
|
switch ( pull(f) ) {
|
480
510
|
case '(':
|
@@ -489,14 +519,21 @@ linkykey(int image, Footnote *val, MMIOT *f)
|
|
489
519
|
|
490
520
|
return peek(f,0) == ')';
|
491
521
|
|
492
|
-
case '[':
|
522
|
+
case '[': /* footnote links /as defined in the standard/ */
|
523
|
+
default: /* footnote links -- undocumented extension */
|
493
524
|
/* footnote link */
|
494
525
|
mylabel = val->tag;
|
495
|
-
if ( (
|
496
|
-
|
526
|
+
if ( peek(f,0) == '[' ) {
|
527
|
+
if ( (T(val->tag) = linkylabel(f, &S(val->tag))) == 0 )
|
528
|
+
return 0;
|
497
529
|
|
498
|
-
|
499
|
-
|
530
|
+
if ( !S(val->tag) )
|
531
|
+
val->tag = mylabel;
|
532
|
+
}
|
533
|
+
else if ( f->flags & MKD_1_COMPAT )
|
534
|
+
break;
|
535
|
+
else
|
536
|
+
mmiotseek(f,here);
|
500
537
|
|
501
538
|
ret = bsearch(val, T(*f->footnotes), S(*f->footnotes),
|
502
539
|
sizeof *val, (stfu)__mkd_footsort);
|
@@ -576,7 +613,7 @@ linkylinky(int image, MMIOT *f)
|
|
576
613
|
Footnote link;
|
577
614
|
linkytype *tag;
|
578
615
|
|
579
|
-
if ( !
|
616
|
+
if ( !linkykey(image, &link, f) ) {
|
580
617
|
mmiotseek(f, start);
|
581
618
|
return 0;
|
582
619
|
}
|
@@ -605,12 +642,12 @@ linkylinky(int image, MMIOT *f)
|
|
605
642
|
|
606
643
|
if ( S(link.title) ) {
|
607
644
|
Qstring(" title=\"", f);
|
608
|
-
|
645
|
+
___mkd_reparse(T(link.title), S(link.title), INSIDE_TAG, f);
|
609
646
|
Qchar('"', f);
|
610
647
|
}
|
611
648
|
|
612
649
|
Qstring(tag->text_pfx, f);
|
613
|
-
|
650
|
+
___mkd_reparse(T(link.tag), S(link.tag), tag->flags, f);
|
614
651
|
Qstring(tag->text_sfx, f);
|
615
652
|
}
|
616
653
|
else
|
@@ -659,11 +696,11 @@ forbidden_tag(MMIOT *f)
|
|
659
696
|
if ( f->flags & DENY_HTML )
|
660
697
|
return 1;
|
661
698
|
|
662
|
-
if ( c == 'A' && (f->flags & DENY_A) && !
|
699
|
+
if ( c == 'A' && (f->flags & DENY_A) && !isthisalnum(f,2) )
|
663
700
|
return 1;
|
664
701
|
if ( c == 'I' && (f->flags & DENY_IMG)
|
665
702
|
&& strncasecmp(cursor(f)+1, "MG", 2) == 0
|
666
|
-
&& !
|
703
|
+
&& !isthisalnum(f,4) )
|
667
704
|
return 1;
|
668
705
|
return 0;
|
669
706
|
}
|
@@ -743,22 +780,6 @@ maybe_tag_or_link(MMIOT *f)
|
|
743
780
|
} /* maybe_tag_or_link */
|
744
781
|
|
745
782
|
|
746
|
-
static int
|
747
|
-
isthisspace(MMIOT *f, int i)
|
748
|
-
{
|
749
|
-
int c = peek(f, i);
|
750
|
-
|
751
|
-
return isspace(c) || (c == EOF);
|
752
|
-
}
|
753
|
-
|
754
|
-
|
755
|
-
static int
|
756
|
-
isthisnonword(MMIOT *f, int i)
|
757
|
-
{
|
758
|
-
return isthisspace(f, i) || ispunct(peek(f,i));
|
759
|
-
}
|
760
|
-
|
761
|
-
|
762
783
|
/* smartyquote code that's common for single and double quotes
|
763
784
|
*/
|
764
785
|
static int
|
@@ -873,7 +894,7 @@ smartypants(int c, int *flags, MMIOT *f)
|
|
873
894
|
break;
|
874
895
|
else if ( c == '\'' && peek(f, j+1) == '\'' ) {
|
875
896
|
Qstring("“", f);
|
876
|
-
|
897
|
+
___mkd_reparse(cursor(f)+1, j-2, 0, f);
|
877
898
|
Qstring("”", f);
|
878
899
|
shift(f,j+1);
|
879
900
|
return 1;
|
@@ -928,7 +949,8 @@ text(MMIOT *f)
|
|
928
949
|
Qchar(c, f);
|
929
950
|
break;
|
930
951
|
#if SUPERSCRIPT
|
931
|
-
|
952
|
+
/* A^B -> A<sup>B</sup> */
|
953
|
+
case '^': if ( (f->flags & (STRICT|INSIDE_TAG)) || isthisspace(f,-1) || isthisspace(f,1) )
|
932
954
|
Qchar(c,f);
|
933
955
|
else {
|
934
956
|
char *sup = cursor(f);
|
@@ -938,18 +960,17 @@ text(MMIOT *f)
|
|
938
960
|
++len;
|
939
961
|
}
|
940
962
|
shift(f,len);
|
941
|
-
|
963
|
+
___mkd_reparse(sup, len, 0, f);
|
942
964
|
Qstring("</sup>", f);
|
943
965
|
}
|
944
966
|
break;
|
945
967
|
#endif
|
946
968
|
case '_':
|
947
969
|
#if RELAXED_EMPHASIS
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
|
952
|
-
|| (isalnum(peek(f,-1)) && isalnum(peek(f,1))) ) {
|
970
|
+
/* Underscores don't count if they're in the middle of a word */
|
971
|
+
if ( (!(f->flags & STRICT))
|
972
|
+
&& ((isthisspace(f,-1) && isthisspace(f,1))
|
973
|
+
|| (isthisalnum(f,-1) && isthisalnum(f,1))) ){
|
953
974
|
Qchar(c, f);
|
954
975
|
break;
|
955
976
|
}
|
@@ -964,7 +985,7 @@ text(MMIOT *f)
|
|
964
985
|
}
|
965
986
|
break;
|
966
987
|
|
967
|
-
case '`': if ( tag_text(f) )
|
988
|
+
case '`': if ( tag_text(f) || !iscodeblock(f) )
|
968
989
|
Qchar(c, f);
|
969
990
|
else {
|
970
991
|
Qstring("<code>", f);
|
@@ -1003,7 +1024,7 @@ text(MMIOT *f)
|
|
1003
1024
|
break;
|
1004
1025
|
|
1005
1026
|
case '&': j = (peek(f,1) == '#' ) ? 2 : 1;
|
1006
|
-
while (
|
1027
|
+
while ( isthisalnum(f,j) )
|
1007
1028
|
++j;
|
1008
1029
|
|
1009
1030
|
if ( peek(f,j) != ';' )
|
@@ -1016,9 +1037,31 @@ text(MMIOT *f)
|
|
1016
1037
|
break;
|
1017
1038
|
}
|
1018
1039
|
}
|
1040
|
+
/* truncate the input string after we've finished processing it */
|
1041
|
+
S(f->in) = f->isp = 0;
|
1019
1042
|
} /* text */
|
1020
1043
|
|
1021
1044
|
|
1045
|
+
static int
|
1046
|
+
iscodeblock(MMIOT *f)
|
1047
|
+
{
|
1048
|
+
int i=1, single = 1, c;
|
1049
|
+
|
1050
|
+
if ( peek(f,i) == '`' ) {
|
1051
|
+
single=0;
|
1052
|
+
i++;
|
1053
|
+
}
|
1054
|
+
while ( (c=peek(f,i)) != EOF ) {
|
1055
|
+
if ( (c == '`') && (single || peek(f,i+1) == '`') )
|
1056
|
+
return 1;
|
1057
|
+
else if ( c == '\\' )
|
1058
|
+
i++;
|
1059
|
+
i++;
|
1060
|
+
}
|
1061
|
+
return 0;
|
1062
|
+
|
1063
|
+
}
|
1064
|
+
|
1022
1065
|
static int
|
1023
1066
|
endofcode(int escape, int offset, MMIOT *f)
|
1024
1067
|
{
|
@@ -1072,7 +1115,13 @@ code(int escape, MMIOT *f)
|
|
1072
1115
|
static void
|
1073
1116
|
printheader(Paragraph *pp, MMIOT *f)
|
1074
1117
|
{
|
1075
|
-
Qprintf(f, "<h%d
|
1118
|
+
Qprintf(f, "<h%d", pp->hnumber);
|
1119
|
+
if ( f->flags & TOC ) {
|
1120
|
+
Qprintf(f, " id=\"", pp->hnumber);
|
1121
|
+
mkd_string_to_anchor(T(pp->text->text), S(pp->text->text), Qchar, f);
|
1122
|
+
Qchar('"', f);
|
1123
|
+
}
|
1124
|
+
Qchar('>', f);
|
1076
1125
|
push(T(pp->text->text), S(pp->text->text), f);
|
1077
1126
|
text(f);
|
1078
1127
|
Qprintf(f, "</h%d>", pp->hnumber);
|
@@ -1094,6 +1143,7 @@ printblock(Paragraph *pp, MMIOT *f)
|
|
1094
1143
|
push("<br/>\n", 6, f);
|
1095
1144
|
}
|
1096
1145
|
else {
|
1146
|
+
___mkd_tidy(t);
|
1097
1147
|
push(T(t->text), S(t->text), f);
|
1098
1148
|
if ( t->next )
|
1099
1149
|
push("\n", 1, f);
|
@@ -1149,19 +1199,21 @@ printhtml(Line *t, MMIOT *f)
|
|
1149
1199
|
|
1150
1200
|
|
1151
1201
|
static void
|
1152
|
-
htmlify(Paragraph *p, char *block, MMIOT *f)
|
1202
|
+
htmlify(Paragraph *p, char *block, char *arguments, MMIOT *f)
|
1153
1203
|
{
|
1154
|
-
|
1155
|
-
if ( block )
|
1156
|
-
|
1204
|
+
___mkd_emblock(f);
|
1205
|
+
if ( block )
|
1206
|
+
Qprintf(f, arguments ? "<%s %s>" : "<%s>", block, arguments);
|
1207
|
+
___mkd_emblock(f);
|
1157
1208
|
|
1158
1209
|
while (( p = display(p, f) )) {
|
1159
|
-
|
1210
|
+
___mkd_emblock(f);
|
1160
1211
|
Qstring("\n\n", f);
|
1161
1212
|
}
|
1162
1213
|
|
1163
|
-
if ( block )
|
1164
|
-
|
1214
|
+
if ( block )
|
1215
|
+
Qprintf(f, "</%s>", block);
|
1216
|
+
___mkd_emblock(f);
|
1165
1217
|
}
|
1166
1218
|
|
1167
1219
|
|
@@ -1177,11 +1229,11 @@ definitionlist(Paragraph *p, MMIOT *f)
|
|
1177
1229
|
for ( ; p ; p = p->next) {
|
1178
1230
|
for ( tag = p->text; tag; tag = tag->next ) {
|
1179
1231
|
Qstring("<dt>", f);
|
1180
|
-
|
1232
|
+
___mkd_reparse(T(tag->text), S(tag->text), 0, f);
|
1181
1233
|
Qstring("</dt>\n", f);
|
1182
1234
|
}
|
1183
1235
|
|
1184
|
-
htmlify(p->down, "dd", f);
|
1236
|
+
htmlify(p->down, "dd", p->ident, f);
|
1185
1237
|
}
|
1186
1238
|
|
1187
1239
|
Qstring("</dl>", f);
|
@@ -1194,10 +1246,13 @@ static void
|
|
1194
1246
|
listdisplay(int typ, Paragraph *p, MMIOT* f)
|
1195
1247
|
{
|
1196
1248
|
if ( p ) {
|
1197
|
-
Qprintf(f, "<%cl
|
1249
|
+
Qprintf(f, "<%cl", (typ==UL)?'u':'o');
|
1250
|
+
if ( typ == AL )
|
1251
|
+
Qprintf(f, " type=a");
|
1252
|
+
Qprintf(f, ">\n");
|
1198
1253
|
|
1199
1254
|
for ( ; p ; p = p->next ) {
|
1200
|
-
htmlify(p->down, "li", f);
|
1255
|
+
htmlify(p->down, "li", p->ident, f);
|
1201
1256
|
Qchar('\n', f);
|
1202
1257
|
}
|
1203
1258
|
|
@@ -1227,11 +1282,12 @@ display(Paragraph *p, MMIOT *f)
|
|
1227
1282
|
break;
|
1228
1283
|
|
1229
1284
|
case QUOTE:
|
1230
|
-
htmlify(p->down, "blockquote", f);
|
1285
|
+
htmlify(p->down, p->ident ? "div" : "blockquote", p->ident, f);
|
1231
1286
|
break;
|
1232
1287
|
|
1233
1288
|
case UL:
|
1234
1289
|
case OL:
|
1290
|
+
case AL:
|
1235
1291
|
listdisplay(p->typ, p->down, f);
|
1236
1292
|
break;
|
1237
1293
|
|
@@ -1288,7 +1344,7 @@ mkd_document(Document *p, char **res)
|
|
1288
1344
|
{
|
1289
1345
|
if ( p && p->compiled ) {
|
1290
1346
|
if ( ! p->html ) {
|
1291
|
-
htmlify(p->code, 0, p->ctx);
|
1347
|
+
htmlify(p->code, 0, 0, p->ctx);
|
1292
1348
|
p->html = 1;
|
1293
1349
|
}
|
1294
1350
|
|
@@ -1299,7 +1355,7 @@ mkd_document(Document *p, char **res)
|
|
1299
1355
|
}
|
1300
1356
|
|
1301
1357
|
|
1302
|
-
/* public interface for
|
1358
|
+
/* public interface for ___mkd_reparse()
|
1303
1359
|
*/
|
1304
1360
|
int
|
1305
1361
|
mkd_text(char *bfr, int size, FILE *output, int flags)
|
@@ -1309,8 +1365,8 @@ mkd_text(char *bfr, int size, FILE *output, int flags)
|
|
1309
1365
|
___mkd_initmmiot(&f, 0);
|
1310
1366
|
f.flags = flags & USER_FLAGS;
|
1311
1367
|
|
1312
|
-
|
1313
|
-
|
1368
|
+
___mkd_reparse(bfr, size, 0, &f);
|
1369
|
+
___mkd_emblock(&f);
|
1314
1370
|
if ( flags & CDATA_OUTPUT )
|
1315
1371
|
___mkd_xml(T(f.out), S(f.out), output);
|
1316
1372
|
else
|