patcito-rdiscount 1.6.8
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 +34 -0
- data/COPYING +52 -0
- data/README.markdown +71 -0
- data/Rakefile +182 -0
- data/bin/rdiscount +13 -0
- data/ext/Csio.c +61 -0
- data/ext/amalloc.h +29 -0
- data/ext/basename.c +43 -0
- data/ext/config.h +23 -0
- data/ext/css.c +85 -0
- data/ext/cstring.h +77 -0
- data/ext/docheader.c +49 -0
- data/ext/dumptree.c +152 -0
- data/ext/emmatch.c +188 -0
- data/ext/extconf.rb +23 -0
- data/ext/generate.c +1708 -0
- data/ext/html5.c +24 -0
- data/ext/markdown.c +1215 -0
- data/ext/markdown.h +171 -0
- data/ext/mkdio.c +344 -0
- data/ext/mkdio.h +101 -0
- data/ext/rdiscount.c +132 -0
- data/ext/resource.c +157 -0
- data/ext/tags.c +123 -0
- data/ext/tags.h +19 -0
- data/ext/toc.c +101 -0
- data/ext/xml.c +82 -0
- data/lib/markdown.rb +1 -0
- data/lib/rdiscount.rb +101 -0
- data/man/markdown.7 +1020 -0
- data/man/rdiscount.1 +22 -0
- data/man/rdiscount.1.ronn +24 -0
- data/rdiscount.gemspec +57 -0
- data/test/benchmark.rb +56 -0
- data/test/benchmark.txt +306 -0
- data/test/markdown_test.rb +158 -0
- data/test/rdiscount_test.rb +111 -0
- metadata +88 -0
data/BUILDING
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
BUILDING rdiscount
|
2
|
+
==================
|
3
|
+
|
4
|
+
You'll be needing Ruby, rake, and a basic build environment.
|
5
|
+
|
6
|
+
Build the rdiscount extension for tests and local development:
|
7
|
+
|
8
|
+
$ rake build
|
9
|
+
|
10
|
+
Use your rdiscount working copy when running ruby programs:
|
11
|
+
|
12
|
+
$ export RUBYLIB=~/rdiscount/lib:$RUBYLIB
|
13
|
+
$ ruby some-program.rb
|
14
|
+
|
15
|
+
Gathering changes from an upstream Orc/discount.git clone requires first
|
16
|
+
grabbing the discount submodule into the root of the project and then running
|
17
|
+
the rake gather task to copy discount source files into the ext/ directory:
|
18
|
+
|
19
|
+
$ git submodule init
|
20
|
+
Submodule 'discount' (git://github.com/rtomayko/discount.git) registered for path 'discount'
|
21
|
+
$ rake gather
|
22
|
+
$ rake build
|
23
|
+
|
24
|
+
The rtomayko/discount.git repository's master branch is the default submodule
|
25
|
+
head. It exists to merge branches for rdiscount specific patches to the upstream
|
26
|
+
discount codebase.
|
27
|
+
|
28
|
+
Do work in the submodule and then add a remote for your clone THAT YOU FORKED ON
|
29
|
+
GITHUB BECAUSE YOU'RE GOING TO SEND ME A PULL REQUEST. After you've committed
|
30
|
+
your great changes somewhere, push them up with:
|
31
|
+
|
32
|
+
$ cd discount
|
33
|
+
$ git remote add you git@github.com:you/discount.git
|
34
|
+
$ git push you HEAD:topic-branch-name
|
data/COPYING
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
The core Discount C sources are
|
2
|
+
Copyright (C) 2007 David Loren Parsons.
|
3
|
+
|
4
|
+
The Discount Ruby extension sources are
|
5
|
+
Copyright (C) 2008 Ryan Tomayko.
|
6
|
+
|
7
|
+
All rights reserved.
|
8
|
+
|
9
|
+
Permission is hereby granted, free of charge, to any person
|
10
|
+
obtaining a copy of this software and associated documentation files
|
11
|
+
(the "Software"), to deal in the Software without restriction,
|
12
|
+
including without limitation the rights to use, copy, modify, merge,
|
13
|
+
publish, distribute, sublicence, and/or sell copies of the Software,
|
14
|
+
and to permit persons to whom the Software is furnished to do so,
|
15
|
+
subject to the following conditions:
|
16
|
+
|
17
|
+
1. Redistributions of source code must retain the above copyright
|
18
|
+
notice, this list of conditions, and the following disclaimer.
|
19
|
+
|
20
|
+
2. Redistributions in binary form must reproduce the above
|
21
|
+
copyright notice, this list of conditions and the following
|
22
|
+
disclaimer in the documentation and/or other materials provided
|
23
|
+
with the distribution, and in the same place and form as other
|
24
|
+
copyright, license and disclaimer information.
|
25
|
+
|
26
|
+
3. The end-user documentation included with the redistribution, if
|
27
|
+
any, must include the following acknowledgment:
|
28
|
+
|
29
|
+
This product includes software developed by
|
30
|
+
David Loren Parsons <http://www.pell.portland.or.us/~orc>
|
31
|
+
|
32
|
+
in the same place and form as other third-party acknowledgments.
|
33
|
+
Alternately, this acknowledgment may appear in the software
|
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.
|
data/README.markdown
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
Discount Markdown Processor for Ruby
|
2
|
+
====================================
|
3
|
+
|
4
|
+
Discount is an implementation of John Gruber's Markdown markup language in C. It
|
5
|
+
implements all of the language described in [the markdown syntax document][1] and
|
6
|
+
passes the [Markdown 1.0 test suite][2].
|
7
|
+
|
8
|
+
CODE: `git clone git://github.com/rtomayko/rdiscount.git`
|
9
|
+
HOME: <http://github.com/rtomayko/rdiscount>
|
10
|
+
DOCS: <http://rdoc.info/projects/rtomayko/rdiscount>
|
11
|
+
BUGS: <http://github.com/rtomayko/rdiscount/issues>
|
12
|
+
|
13
|
+
Discount was developed by [David Loren Parsons][3]. The Ruby extension
|
14
|
+
is maintained by [Ryan Tomayko][4].
|
15
|
+
|
16
|
+
[1]: http://daringfireball.net/projects/markdown/syntax
|
17
|
+
[2]: http://daringfireball.net/projects/downloads/MarkdownTest_1.0.zip
|
18
|
+
[3]: http://www.pell.portland.or.us/~orc
|
19
|
+
[4]: http://tomayko.com/about
|
20
|
+
|
21
|
+
INSTALL, HACKING
|
22
|
+
----------------
|
23
|
+
|
24
|
+
New releases of RDiscount are published to [gemcutter][]:
|
25
|
+
|
26
|
+
$ [sudo] gem install rdiscount -s http://gemcutter.org
|
27
|
+
|
28
|
+
The RDiscount sources are available via Git:
|
29
|
+
|
30
|
+
$ git clone git://github.com/rtomayko/rdiscount.git
|
31
|
+
$ cd rdiscount
|
32
|
+
$ rake --tasks
|
33
|
+
|
34
|
+
See the file [BUILDING][] for hacking instructions.
|
35
|
+
|
36
|
+
[gemcutter]: http://gemcutter.org/gems/rdiscount
|
37
|
+
[BUILDING]: BUILDING
|
38
|
+
|
39
|
+
USAGE
|
40
|
+
-----
|
41
|
+
|
42
|
+
RDiscount implements the basic protocol popularized by RedCloth and adopted
|
43
|
+
by BlueCloth:
|
44
|
+
|
45
|
+
require 'rdiscount'
|
46
|
+
markdown = RDiscount.new("Hello World!")
|
47
|
+
puts markdown.to_html
|
48
|
+
|
49
|
+
Additional processing options can be turned on when creating the
|
50
|
+
RDiscount object:
|
51
|
+
|
52
|
+
markdown = RDiscount.new("Hello World!", :smart, :filter_html)
|
53
|
+
|
54
|
+
Inject RDiscount into your BlueCloth-using code by replacing your bluecloth
|
55
|
+
require statements with the following:
|
56
|
+
|
57
|
+
begin
|
58
|
+
require 'rdiscount'
|
59
|
+
BlueCloth = RDiscount
|
60
|
+
rescue LoadError
|
61
|
+
require 'bluecloth'
|
62
|
+
end
|
63
|
+
|
64
|
+
COPYING
|
65
|
+
-------
|
66
|
+
|
67
|
+
Discount is free software; it is released under a BSD-style license
|
68
|
+
that allows you to do as you wish with it as long as you don't attempt
|
69
|
+
to claim it as your own work. RDiscount adopts Discount's license
|
70
|
+
verbatim. See the file `COPYING` for more information.
|
71
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,182 @@
|
|
1
|
+
require 'date'
|
2
|
+
require 'rake/clean'
|
3
|
+
require 'digest/md5'
|
4
|
+
|
5
|
+
task :default => :test
|
6
|
+
|
7
|
+
# ==========================================================
|
8
|
+
# Ruby Extension
|
9
|
+
# ==========================================================
|
10
|
+
|
11
|
+
DLEXT = Config::MAKEFILE_CONFIG['DLEXT']
|
12
|
+
RUBYDIGEST = Digest::MD5.hexdigest(`#{RUBY} --version`)
|
13
|
+
|
14
|
+
file "ext/ruby-#{RUBYDIGEST}" do |f|
|
15
|
+
rm_f FileList["ext/ruby-*"]
|
16
|
+
touch f.name
|
17
|
+
end
|
18
|
+
CLEAN.include "ext/ruby-*"
|
19
|
+
|
20
|
+
file 'ext/Makefile' => FileList['ext/*.{c,h,rb}', "ext/ruby-#{RUBYDIGEST}"] do
|
21
|
+
chdir('ext') { ruby 'extconf.rb' }
|
22
|
+
end
|
23
|
+
CLEAN.include 'ext/Makefile', 'ext/mkmf.log'
|
24
|
+
|
25
|
+
file "ext/rdiscount.#{DLEXT}" => FileList["ext/Makefile"] do |f|
|
26
|
+
sh 'cd ext && make clean && make && rm -rf conftest.dSYM'
|
27
|
+
end
|
28
|
+
CLEAN.include 'ext/*.{o,bundle,so,dll}'
|
29
|
+
|
30
|
+
file "lib/rdiscount.#{DLEXT}" => "ext/rdiscount.#{DLEXT}" do |f|
|
31
|
+
cp f.prerequisites, "lib/", :preserve => true
|
32
|
+
end
|
33
|
+
|
34
|
+
desc 'Build the rdiscount extension'
|
35
|
+
task :build => "lib/rdiscount.#{DLEXT}"
|
36
|
+
|
37
|
+
# ==========================================================
|
38
|
+
# Manual
|
39
|
+
# ==========================================================
|
40
|
+
|
41
|
+
file 'man/rdiscount.1' => 'man/rdiscount.1.ronn' do
|
42
|
+
sh "ronn --manual=RUBY -b man/rdiscount.1.ronn"
|
43
|
+
end
|
44
|
+
CLOBBER.include 'man/rdiscount.1'
|
45
|
+
|
46
|
+
desc 'Build manpages'
|
47
|
+
task :man => 'man/rdiscount.1'
|
48
|
+
|
49
|
+
# ==========================================================
|
50
|
+
# Testing
|
51
|
+
# ==========================================================
|
52
|
+
|
53
|
+
require 'rake/testtask'
|
54
|
+
Rake::TestTask.new('test:unit') do |t|
|
55
|
+
t.test_files = FileList['test/*_test.rb']
|
56
|
+
t.ruby_opts += ['-rubygems'] if defined? Gem
|
57
|
+
end
|
58
|
+
task 'test:unit' => [:build]
|
59
|
+
|
60
|
+
desc 'Run conformance tests (MARKDOWN_TEST_VER=1.0)'
|
61
|
+
task 'test:conformance' => [:build] do |t|
|
62
|
+
script = "#{pwd}/bin/rdiscount"
|
63
|
+
test_version = ENV['MARKDOWN_TEST_VER'] || '1.0.3'
|
64
|
+
lib_dir = "#{pwd}/lib"
|
65
|
+
chdir("test/MarkdownTest_#{test_version}") do
|
66
|
+
sh "RUBYLIB=#{lib_dir} ./MarkdownTest.pl --script='#{script}' --tidy"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
desc 'Run version 1.0 conformance suite'
|
71
|
+
task 'test:conformance:1.0' => [:build] do |t|
|
72
|
+
ENV['MARKDOWN_TEST_VER'] = '1.0'
|
73
|
+
Rake::Task['test:conformance'].invoke
|
74
|
+
end
|
75
|
+
|
76
|
+
desc 'Run 1.0.3 conformance suite'
|
77
|
+
task 'test:conformance:1.0.3' => [:build] do |t|
|
78
|
+
ENV['MARKDOWN_TEST_VER'] = '1.0.3'
|
79
|
+
Rake::Task['test:conformance'].invoke
|
80
|
+
end
|
81
|
+
|
82
|
+
desc 'Run unit and conformance tests'
|
83
|
+
task :test => %w[test:unit test:conformance]
|
84
|
+
|
85
|
+
desc 'Run benchmarks'
|
86
|
+
task :benchmark => :build do |t|
|
87
|
+
$:.unshift 'lib'
|
88
|
+
load 'test/benchmark.rb'
|
89
|
+
end
|
90
|
+
|
91
|
+
# ==========================================================
|
92
|
+
# Documentation
|
93
|
+
# ==========================================================
|
94
|
+
|
95
|
+
desc 'Generate API documentation'
|
96
|
+
task :doc => 'doc/index.html'
|
97
|
+
|
98
|
+
file 'doc/index.html' => FileList['lib/*.rb'] do |f|
|
99
|
+
sh((<<-end).gsub(/\s+/, ' '))
|
100
|
+
hanna --charset utf8 --fmt html --inline-source --line-numbers \
|
101
|
+
--main RDiscount --op doc --title 'RDiscount API Documentation' \
|
102
|
+
#{f.prerequisites.join(' ')}
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
CLEAN.include 'doc'
|
107
|
+
|
108
|
+
# ==========================================================
|
109
|
+
# Update package's Discount sources
|
110
|
+
# ==========================================================
|
111
|
+
|
112
|
+
desc 'Gather required discount sources into extension directory'
|
113
|
+
task :gather => 'discount/markdown.h' do |t|
|
114
|
+
files =
|
115
|
+
FileList[
|
116
|
+
'discount/{markdown,mkdio,amalloc,cstring,tags}.h',
|
117
|
+
'discount/{markdown,docheader,dumptree,generate,mkdio,resource,toc,Csio,xml,css,basename,emmatch,tags,html5}.c'
|
118
|
+
]
|
119
|
+
cp files, 'ext/',
|
120
|
+
:preserve => true,
|
121
|
+
:verbose => true
|
122
|
+
cp 'discount/markdown.7', 'man/'
|
123
|
+
end
|
124
|
+
|
125
|
+
file 'discount/markdown.h' do |t|
|
126
|
+
abort "The discount submodule is required. See the file BUILDING for getting set up."
|
127
|
+
end
|
128
|
+
|
129
|
+
# PACKAGING =================================================================
|
130
|
+
|
131
|
+
require 'rubygems'
|
132
|
+
$spec = eval(File.read('rdiscount.gemspec'))
|
133
|
+
|
134
|
+
def package(ext='')
|
135
|
+
"pkg/rdiscount-#{$spec.version}" + ext
|
136
|
+
end
|
137
|
+
|
138
|
+
desc 'Build packages'
|
139
|
+
task :package => %w[.gem .tar.gz].map {|e| package(e)}
|
140
|
+
|
141
|
+
desc 'Build and install as local gem'
|
142
|
+
task :install => package('.gem') do
|
143
|
+
sh "gem install #{package('.gem')}"
|
144
|
+
end
|
145
|
+
|
146
|
+
directory 'pkg/'
|
147
|
+
|
148
|
+
file package('.gem') => %w[pkg/ rdiscount.gemspec] + $spec.files do |f|
|
149
|
+
sh "gem build rdiscount.gemspec"
|
150
|
+
mv File.basename(f.name), f.name
|
151
|
+
end
|
152
|
+
|
153
|
+
file package('.tar.gz') => %w[pkg/] + $spec.files do |f|
|
154
|
+
sh "git archive --format=tar HEAD | gzip > #{f.name}"
|
155
|
+
end
|
156
|
+
|
157
|
+
# GEMSPEC HELPERS ==========================================================
|
158
|
+
|
159
|
+
def source_version
|
160
|
+
line = File.read('lib/rdiscount.rb')[/^\s*VERSION = .*/]
|
161
|
+
line.match(/.*VERSION = '(.*)'/)[1]
|
162
|
+
end
|
163
|
+
|
164
|
+
file 'rdiscount.gemspec' => FileList['Rakefile','lib/rdiscount.rb'] do |f|
|
165
|
+
# read spec file and split out manifest section
|
166
|
+
spec = File.read(f.name)
|
167
|
+
head, manifest, tail = spec.split(" # = MANIFEST =\n")
|
168
|
+
head.sub!(/\.version = '.*'/, ".version = '#{source_version}'")
|
169
|
+
head.sub!(/\.date = '.*'/, ".date = '#{Date.today.to_s}'")
|
170
|
+
# determine file list from git ls-files
|
171
|
+
files = `git ls-files`.
|
172
|
+
split("\n").
|
173
|
+
sort.
|
174
|
+
reject{ |file| file =~ /^\./ || file =~ /^test\/MarkdownTest/ }.
|
175
|
+
map{ |file| " #{file}" }.
|
176
|
+
join("\n")
|
177
|
+
# piece file back together and write...
|
178
|
+
manifest = " s.files = %w[\n#{files}\n ]\n"
|
179
|
+
spec = [head,manifest,tail].join(" # = MANIFEST =\n")
|
180
|
+
File.open(f.name, 'w') { |io| io.write(spec) }
|
181
|
+
puts "updated #{f.name}"
|
182
|
+
end
|
data/bin/rdiscount
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Usage: rdiscount [<file>...]
|
3
|
+
# Convert one or more Markdown files to HTML and write to standard output. With
|
4
|
+
# no <file> or when <file> is '-', read Markdown source text from standard input.
|
5
|
+
if ARGV.include?('--help')
|
6
|
+
File.read(__FILE__).split("\n").grep(/^# /).each do |line|
|
7
|
+
puts line[2..-1]
|
8
|
+
end
|
9
|
+
exit 0
|
10
|
+
end
|
11
|
+
|
12
|
+
require 'rdiscount'
|
13
|
+
STDOUT.write(RDiscount.new(ARGF.read).to_html)
|
data/ext/Csio.c
ADDED
@@ -0,0 +1,61 @@
|
|
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), ALLOCATED(*iot)-S(*iot), fmt, ptr);
|
30
|
+
va_end(ptr);
|
31
|
+
} while ( siz > (ALLOCATED(*iot)-S(*iot)) );
|
32
|
+
|
33
|
+
S(*iot) += siz;
|
34
|
+
return siz;
|
35
|
+
}
|
36
|
+
|
37
|
+
|
38
|
+
/* write() into a cstring
|
39
|
+
*/
|
40
|
+
int
|
41
|
+
Cswrite(Cstring *iot, char *bfr, int size)
|
42
|
+
{
|
43
|
+
RESERVE(*iot, size);
|
44
|
+
memcpy(T(*iot)+S(*iot), bfr, size);
|
45
|
+
S(*iot) += size;
|
46
|
+
return size;
|
47
|
+
}
|
48
|
+
|
49
|
+
|
50
|
+
/* reparse() into a cstring
|
51
|
+
*/
|
52
|
+
void
|
53
|
+
Csreparse(Cstring *iot, char *buf, int size, int flags)
|
54
|
+
{
|
55
|
+
MMIOT f;
|
56
|
+
___mkd_initmmiot(&f, 0);
|
57
|
+
___mkd_reparse(buf, size, 0, &f);
|
58
|
+
___mkd_emblock(&f);
|
59
|
+
SUFFIX(*iot, T(f.out), S(f.out));
|
60
|
+
___mkd_freemmiot(&f, 0);
|
61
|
+
}
|
data/ext/amalloc.h
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
/*
|
2
|
+
* debugging malloc()/realloc()/calloc()/free() that attempts
|
3
|
+
* to keep track of just what's been allocated today.
|
4
|
+
*/
|
5
|
+
#ifndef AMALLOC_D
|
6
|
+
#define AMALLOC_D
|
7
|
+
|
8
|
+
#include "config.h"
|
9
|
+
|
10
|
+
#ifdef USE_AMALLOC
|
11
|
+
|
12
|
+
extern void *amalloc(int);
|
13
|
+
extern void *acalloc(int,int);
|
14
|
+
extern void *arealloc(void*,int);
|
15
|
+
extern void afree(void*);
|
16
|
+
extern void adump();
|
17
|
+
|
18
|
+
#define malloc amalloc
|
19
|
+
#define calloc acalloc
|
20
|
+
#define realloc arealloc
|
21
|
+
#define free afree
|
22
|
+
|
23
|
+
#else
|
24
|
+
|
25
|
+
#define adump() (void)1
|
26
|
+
|
27
|
+
#endif
|
28
|
+
|
29
|
+
#endif/*AMALLOC_D*/
|
data/ext/basename.c
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
/*
|
2
|
+
* mkdio -- markdown front end input functions
|
3
|
+
*
|
4
|
+
* Copyright (C) 2007 David L Parsons.
|
5
|
+
* The redistribution terms are provided in the COPYRIGHT file that must
|
6
|
+
* be distributed with this source code.
|
7
|
+
*/
|
8
|
+
#include "config.h"
|
9
|
+
#include <stdio.h>
|
10
|
+
#include <stdlib.h>
|
11
|
+
#include <ctype.h>
|
12
|
+
|
13
|
+
#include "mkdio.h"
|
14
|
+
#include "cstring.h"
|
15
|
+
#include "amalloc.h"
|
16
|
+
|
17
|
+
static char *
|
18
|
+
e_basename(const char *string, const int size, void *context)
|
19
|
+
{
|
20
|
+
char *ret;
|
21
|
+
char *base = (char*)context;
|
22
|
+
|
23
|
+
if ( base && string && (*string == '/') && (ret=malloc(strlen(base)+size+2)) ) {
|
24
|
+
strcpy(ret, base);
|
25
|
+
strncat(ret, string, size);
|
26
|
+
return ret;
|
27
|
+
}
|
28
|
+
return 0;
|
29
|
+
}
|
30
|
+
|
31
|
+
static void
|
32
|
+
e_free(char *string, void *context)
|
33
|
+
{
|
34
|
+
if ( string ) free(string);
|
35
|
+
}
|
36
|
+
|
37
|
+
void
|
38
|
+
mkd_basename(MMIOT *document, char *base)
|
39
|
+
{
|
40
|
+
mkd_e_url(document, e_basename);
|
41
|
+
mkd_e_data(document, base);
|
42
|
+
mkd_e_free(document, e_free);
|
43
|
+
}
|
data/ext/config.h
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
/*
|
2
|
+
* rdiscount extension discount configuration
|
3
|
+
*/
|
4
|
+
#ifndef __MARKDOWN_D
|
5
|
+
#define __MARKDOWN_D 1
|
6
|
+
|
7
|
+
/* tabs are four spaces */
|
8
|
+
#define TABSTOP 4
|
9
|
+
|
10
|
+
/* these are setup by extconf.rb */
|
11
|
+
#if HAVE_RANDOM
|
12
|
+
#define COINTOSS() (random()&1)
|
13
|
+
#elif HAVE_RAND
|
14
|
+
#define COINTOSS() (rand()&1)
|
15
|
+
#endif
|
16
|
+
|
17
|
+
#if HAVE_SRANDOM
|
18
|
+
#define INITRNG(x) srandom((unsigned int)x)
|
19
|
+
#elif HAVE_SRAND
|
20
|
+
#define INITRNG(x) srand((unsigned int)x)
|
21
|
+
#endif
|
22
|
+
|
23
|
+
#endif/* __MARKDOWN_D */
|
data/ext/css.c
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
/* markdown: a C implementation of John Gruber's Markdown markup language.
|
2
|
+
*
|
3
|
+
* Copyright (C) 2009 David L Parsons.
|
4
|
+
* The redistribution terms are provided in the COPYRIGHT file that must
|
5
|
+
* be distributed with this source code.
|
6
|
+
*/
|
7
|
+
#include <stdio.h>
|
8
|
+
#include <string.h>
|
9
|
+
#include <stdarg.h>
|
10
|
+
#include <stdlib.h>
|
11
|
+
#include <time.h>
|
12
|
+
#include <ctype.h>
|
13
|
+
|
14
|
+
#include "config.h"
|
15
|
+
|
16
|
+
#include "cstring.h"
|
17
|
+
#include "markdown.h"
|
18
|
+
#include "amalloc.h"
|
19
|
+
|
20
|
+
|
21
|
+
/*
|
22
|
+
* dump out stylesheet sections.
|
23
|
+
*/
|
24
|
+
static void
|
25
|
+
stylesheets(Paragraph *p, Cstring *f)
|
26
|
+
{
|
27
|
+
Line* q;
|
28
|
+
|
29
|
+
for ( ; p ; p = p->next ) {
|
30
|
+
if ( p->typ == STYLE ) {
|
31
|
+
for ( q = p->text; q ; q = q->next ) {
|
32
|
+
Cswrite(f, T(q->text), S(q->text));
|
33
|
+
Csputc('\n', f);
|
34
|
+
}
|
35
|
+
}
|
36
|
+
if ( p->down )
|
37
|
+
stylesheets(p->down, f);
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
41
|
+
|
42
|
+
/* dump any embedded styles to a string
|
43
|
+
*/
|
44
|
+
int
|
45
|
+
mkd_css(Document *d, char **res)
|
46
|
+
{
|
47
|
+
Cstring f;
|
48
|
+
int size;
|
49
|
+
|
50
|
+
if ( res && d && d->compiled ) {
|
51
|
+
*res = 0;
|
52
|
+
CREATE(f);
|
53
|
+
RESERVE(f, 100);
|
54
|
+
stylesheets(d->code, &f);
|
55
|
+
|
56
|
+
if ( (size = S(f)) > 0 ) {
|
57
|
+
EXPAND(f) = 0;
|
58
|
+
/* HACK ALERT! HACK ALERT! HACK ALERT! */
|
59
|
+
*res = T(f);/* we know that a T(Cstring) is a character pointer */
|
60
|
+
/* so we can simply pick it up and carry it away, */
|
61
|
+
/* leaving the husk of the Ctring on the stack */
|
62
|
+
/* END HACK ALERT */
|
63
|
+
}
|
64
|
+
else
|
65
|
+
DELETE(f);
|
66
|
+
return size;
|
67
|
+
}
|
68
|
+
return EOF;
|
69
|
+
}
|
70
|
+
|
71
|
+
|
72
|
+
/* dump any embedded styles to a file
|
73
|
+
*/
|
74
|
+
int
|
75
|
+
mkd_generatecss(Document *d, FILE *f)
|
76
|
+
{
|
77
|
+
char *res;
|
78
|
+
int written = EOF, size = mkd_css(d, &res);
|
79
|
+
|
80
|
+
if ( size > 0 )
|
81
|
+
written = fwrite(res, 1, size, f);
|
82
|
+
if ( res )
|
83
|
+
free(res);
|
84
|
+
return (written == size) ? size : EOF;
|
85
|
+
}
|
data/ext/cstring.h
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
/* two template types: STRING(t) which defines a pascal-style string
|
2
|
+
* of element (t) [STRING(char) is the closest to the pascal string],
|
3
|
+
* and ANCHOR(t) which defines a baseplate that a linked list can be
|
4
|
+
* built up from. [The linked list /must/ contain a ->next pointer
|
5
|
+
* for linking the list together with.]
|
6
|
+
*/
|
7
|
+
#ifndef _CSTRING_D
|
8
|
+
#define _CSTRING_D
|
9
|
+
|
10
|
+
#include <string.h>
|
11
|
+
#include <stdlib.h>
|
12
|
+
|
13
|
+
#ifndef __WITHOUT_AMALLOC
|
14
|
+
# include "amalloc.h"
|
15
|
+
#endif
|
16
|
+
|
17
|
+
/* expandable Pascal-style string.
|
18
|
+
*/
|
19
|
+
#define STRING(type) struct { type *text; int size, alloc; }
|
20
|
+
|
21
|
+
#define CREATE(x) ( (T(x) = (void*)0), (S(x) = (x).alloc = 0) )
|
22
|
+
#define EXPAND(x) (S(x)++)[(S(x) < (x).alloc) \
|
23
|
+
? (T(x)) \
|
24
|
+
: (T(x) = T(x) ? realloc(T(x), sizeof T(x)[0] * ((x).alloc += 100)) \
|
25
|
+
: malloc(sizeof T(x)[0] * ((x).alloc += 100)) )]
|
26
|
+
|
27
|
+
#define DELETE(x) ALLOCATED(x) ? (free(T(x)), S(x) = (x).alloc = 0) \
|
28
|
+
: ( S(x) = 0 )
|
29
|
+
#define CLIP(t,i,sz) \
|
30
|
+
( ((i) >= 0) && ((sz) > 0) && (((i)+(sz)) <= S(t)) ) ? \
|
31
|
+
(memmove(&T(t)[i], &T(t)[i+sz], (S(t)-(i+sz)+1)*sizeof(T(t)[0])), \
|
32
|
+
S(t) -= (sz)) : -1
|
33
|
+
|
34
|
+
#define RESERVE(x, sz) T(x) = ((x).alloc > S(x) + (sz) \
|
35
|
+
? T(x) \
|
36
|
+
: T(x) \
|
37
|
+
? realloc(T(x), sizeof T(x)[0] * ((x).alloc = 100+(sz)+S(x))) \
|
38
|
+
: malloc(sizeof T(x)[0] * ((x).alloc = 100+(sz)+S(x))))
|
39
|
+
#define SUFFIX(t,p,sz) \
|
40
|
+
memcpy(((S(t) += (sz)) - (sz)) + \
|
41
|
+
(T(t) = T(t) ? realloc(T(t), sizeof T(t)[0] * ((t).alloc += sz)) \
|
42
|
+
: malloc(sizeof T(t)[0] * ((t).alloc += sz))), \
|
43
|
+
(p), sizeof(T(t)[0])*(sz))
|
44
|
+
|
45
|
+
#define PREFIX(t,p,sz) \
|
46
|
+
RESERVE( (t), (sz) ); \
|
47
|
+
if ( S(t) ) { memmove(T(t)+(sz), T(t), S(t)); } \
|
48
|
+
memcpy( T(t), (p), (sz) ); \
|
49
|
+
S(t) += (sz)
|
50
|
+
|
51
|
+
/* reference-style links (and images) are stored in an array
|
52
|
+
*/
|
53
|
+
#define T(x) (x).text
|
54
|
+
#define S(x) (x).size
|
55
|
+
#define ALLOCATED(x) (x).alloc
|
56
|
+
|
57
|
+
/* abstract anchor type that defines a list base
|
58
|
+
* with a function that attaches an element to
|
59
|
+
* the end of the list.
|
60
|
+
*
|
61
|
+
* the list base field is named .text so that the T()
|
62
|
+
* macro will work with it.
|
63
|
+
*/
|
64
|
+
#define ANCHOR(t) struct { t *text, *end; }
|
65
|
+
#define E(t) ((t).end)
|
66
|
+
|
67
|
+
#define ATTACH(t, p) ( T(t) ? ( (E(t)->next = (p)), (E(t) = (p)) ) \
|
68
|
+
: ( (T(t) = E(t) = (p)) ) )
|
69
|
+
|
70
|
+
typedef STRING(char) Cstring;
|
71
|
+
|
72
|
+
extern void Csputc(int, Cstring *);
|
73
|
+
extern int Csprintf(Cstring *, char *, ...);
|
74
|
+
extern int Cswrite(Cstring *, char *, int);
|
75
|
+
extern void Csreparse(Cstring *, char *, int, int);
|
76
|
+
|
77
|
+
#endif/*_CSTRING_D*/
|