rdiscount-1.6.8/ 0000755 0001750 0001750 00000000000 11643305656 013507 5 ustar virtual virtual rdiscount-1.6.8/BUILDING 0000644 0001750 0001750 00000002271 11643305656 014631 0 ustar virtual virtual BUILDING rdiscount
==================
You'll be needing Ruby, rake, and a basic build environment.
Build the rdiscount extension for tests and local development:
$ rake build
Use your rdiscount working copy when running ruby programs:
$ export RUBYLIB=~/rdiscount/lib:$RUBYLIB
$ ruby some-program.rb
Gathering changes from an upstream Orc/discount.git clone requires first
grabbing the discount submodule into the root of the project and then running
the rake gather task to copy discount source files into the ext/ directory:
$ git submodule init
Submodule 'discount' (git://github.com/rtomayko/discount.git) registered for path 'discount'
$ rake gather
$ rake build
The rtomayko/discount.git repository's master branch is the default submodule
head. It exists to merge branches for rdiscount specific patches to the upstream
discount codebase.
Do work in the submodule and then add a remote for your clone THAT YOU FORKED ON
GITHUB BECAUSE YOU'RE GOING TO SEND ME A PULL REQUEST. After you've committed
your great changes somewhere, push them up with:
$ cd discount
$ git remote add you git@github.com:you/discount.git
$ git push you HEAD:topic-branch-name
rdiscount-1.6.8/metadata.yml 0000644 0001750 0001750 00000003461 11643305656 016016 0 ustar virtual virtual --- !ruby/object:Gem::Specification
name: rdiscount
version: !ruby/object:Gem::Version
hash: 31
prerelease: false
segments:
- 1
- 6
- 8
version: 1.6.8
platform: ruby
authors:
- Ryan Tomayko
- David Loren Parsons
- Andrew White
autorequire:
bindir: bin
cert_chain: []
date: 2011-01-25 00:00:00 -08:00
default_executable:
dependencies: []
description:
email: rtomayko@gmail.com
executables:
- rdiscount
extensions:
- ext/extconf.rb
extra_rdoc_files:
- COPYING
files:
- BUILDING
- COPYING
- README.markdown
- Rakefile
- bin/rdiscount
- ext/Csio.c
- ext/amalloc.h
- ext/basename.c
- ext/config.h
- ext/css.c
- ext/cstring.h
- ext/docheader.c
- ext/dumptree.c
- ext/emmatch.c
- ext/extconf.rb
- ext/generate.c
- ext/html5.c
- ext/markdown.c
- ext/markdown.h
- ext/mkdio.c
- ext/mkdio.h
- ext/rdiscount.c
- ext/resource.c
- ext/tags.c
- ext/tags.h
- ext/toc.c
- ext/xml.c
- lib/markdown.rb
- lib/rdiscount.rb
- man/markdown.7
- man/rdiscount.1
- man/rdiscount.1.ronn
- rdiscount.gemspec
- test/benchmark.rb
- test/benchmark.txt
- test/markdown_test.rb
- test/rdiscount_test.rb
has_rdoc: true
homepage: http://github.com/rtomayko/rdiscount
licenses: []
post_install_message:
rdoc_options: []
require_paths:
- lib
required_ruby_version: !ruby/object:Gem::Requirement
none: false
requirements:
- - ">="
- !ruby/object:Gem::Version
hash: 3
segments:
- 0
version: "0"
required_rubygems_version: !ruby/object:Gem::Requirement
none: false
requirements:
- - ">="
- !ruby/object:Gem::Version
hash: 3
segments:
- 0
version: "0"
requirements: []
rubyforge_project: wink
rubygems_version: 1.3.7
signing_key:
specification_version: 3
summary: Fast Implementation of Gruber's Markdown in C
test_files:
- test/markdown_test.rb
- test/rdiscount_test.rb
rdiscount-1.6.8/bin/ 0000755 0001750 0001750 00000000000 11643305656 014257 5 ustar virtual virtual rdiscount-1.6.8/bin/rdiscount 0000755 0001750 0001750 00000000631 11643305656 016217 0 ustar virtual virtual #!/usr/bin/env ruby
# Usage: rdiscount [ ", " " };
static char *End[] = { "", "", DENY_IMG|INSIDE_TAG, IS_URL };
static linkytype linkt = { 0, 0, "", "", DENY_A, IS_URL };
/*
* pseudo-protocols for [][];
*
* id: generates tag
* class: generates tag
* raw: just dump the link without any processing
*/
static linkytype specials[] = {
{ "id:", 3, "", "", 0, IS_URL },
{ "raw:", 4, 0, 0, 0, 0, 0, DENY_HTML, 0 },
{ "lang:", 5, "", "", 0, 0 },
{ "abbr:", 5, "", "", 0, 0 },
{ "class:", 6, "", "", 0, 0 },
} ;
#define NR(x) (sizeof x / sizeof x[0])
/* see if t contains one of our pseudo-protocols.
*/
static linkytype *
pseudo(Cstring t)
{
int i;
linkytype *r;
for ( i=0, r=specials; i < NR(specials); i++,r++ ) {
if ( (S(t) > r->szpat) && (strncasecmp(T(t), r->pat, r->szpat) == 0) )
return r;
}
return 0;
}
/* print out the start of an `img' or `a' tag, applying callbacks as needed.
*/
static void
printlinkyref(MMIOT *f, linkytype *tag, char *link, int size)
{
char *edit;
Qstring(tag->link_pfx, f);
if ( tag->kind & IS_URL ) {
if ( f->cb->e_url && (edit = (*f->cb->e_url)(link, size, f->cb->e_data)) ) {
puturl(edit, strlen(edit), f, 0);
if ( f->cb->e_free ) (*f->cb->e_free)(edit, f->cb->e_data);
}
else
puturl(link + tag->szpat, size - tag->szpat, f, 0);
}
else
___mkd_reparse(link + tag->szpat, size - tag->szpat, INSIDE_TAG, f);
Qstring(tag->link_sfx, f);
if ( f->cb->e_flags && (edit = (*f->cb->e_flags)(link, size, f->cb->e_data)) ) {
Qchar(' ', f);
Qstring(edit, f);
if ( f->cb->e_free ) (*f->cb->e_free)(edit, f->cb->e_data);
}
} /* printlinkyref */
/* print out a linky (or fail if it's Not Allowed)
*/
static int
linkyformat(MMIOT *f, Cstring text, int image, Footnote *ref)
{
linkytype *tag;
if ( image )
tag = &imaget;
else if ( tag = pseudo(ref->link) ) {
if ( f->flags & (NO_PSEUDO_PROTO|SAFELINK) )
return 0;
}
else if ( (f->flags & SAFELINK) && T(ref->link)
&& (T(ref->link)[0] != '/')
&& !isautoprefix(T(ref->link), S(ref->link)) )
/* if SAFELINK, only accept links that are local or
* a well-known protocol
*/
return 0;
else
tag = &linkt;
if ( f->flags & tag->flags )
return 0;
if ( tag->link_pfx ) {
printlinkyref(f, tag, T(ref->link), S(ref->link));
if ( tag->WxH ) {
if ( ref->height ) Qprintf(f," height=\"%d\"", ref->height);
if ( ref->width ) Qprintf(f, " width=\"%d\"", ref->width);
}
if ( S(ref->title) ) {
Qstring(" title=\"", f);
___mkd_reparse(T(ref->title), S(ref->title), INSIDE_TAG, f);
Qchar('"', f);
}
Qstring(tag->text_pfx, f);
___mkd_reparse(T(text), S(text), tag->flags, f);
Qstring(tag->text_sfx, f);
}
else
Qwrite(T(ref->link) + tag->szpat, S(ref->link) - tag->szpat, f);
return 1;
} /* linkyformat */
/*
* process embedded links and images
*/
static int
linkylinky(int image, MMIOT *f)
{
int start = mmiottell(f);
Cstring name;
Footnote key, *ref;
int status = 0;
CREATE(name);
memset(&key, 0, sizeof key);
if ( linkylabel(f, &name) ) {
if ( peek(f,1) == '(' ) {
pull(f);
if ( linkyurl(f, image, &key) )
status = linkyformat(f, name, image, &key);
}
else {
int goodlink, implicit_mark = mmiottell(f);
if ( eatspace(f) == '[' ) {
pull(f); /* consume leading '[' */
goodlink = linkylabel(f, &key.tag);
}
else {
/* new markdown implicit name syntax doesn't
* require a second []
*/
mmiotseek(f, implicit_mark);
goodlink = !(f->flags & MKD_1_COMPAT);
}
if ( goodlink ) {
if ( !S(key.tag) ) {
DELETE(key.tag);
T(key.tag) = T(name);
S(key.tag) = S(name);
}
if ( ref = bsearch(&key, T(*f->footnotes), S(*f->footnotes),
sizeof key, (stfu)__mkd_footsort) )
status = linkyformat(f, name, image, ref);
}
}
}
DELETE(name);
___mkd_freefootnote(&key);
if ( status == 0 )
mmiotseek(f, start);
return status;
}
/* write a character to output, doing text escapes ( & -> &,
* > -> > < -> < )
*/
static void
cputc(int c, MMIOT *f)
{
switch (c) {
case '&': Qstring("&", f); break;
case '>': Qstring(">", f); break;
case '<': Qstring("<", f); break;
default : Qchar(c, f); break;
}
}
/*
* convert an email address to a string of nonsense
*/
static void
mangle(char *s, int len, MMIOT *f)
{
while ( len-- > 0 ) {
Qstring("", f);
Qprintf(f, COINTOSS() ? "x%02x;" : "%02d;", *((unsigned char*)(s++)) );
}
}
/* nrticks() -- count up a row of tick marks
*/
static int
nrticks(int offset, int tickchar, MMIOT *f)
{
int tick = 0;
while ( peek(f, offset+tick) == tickchar ) tick++;
return tick;
} /* nrticks */
/* matchticks() -- match a certain # of ticks, and if that fails
* match the largest subset of those ticks.
*
* if a subset was matched, return the # of ticks
* that were matched.
*/
static int
matchticks(MMIOT *f, int tickchar, int ticks, int *endticks)
{
int size, count, c;
int subsize=0, subtick=0;
*endticks = ticks;
for (size = 0; (c=peek(f,size+ticks)) != EOF; size ++) {
if ( (c == tickchar) && ( count = nrticks(size+ticks,tickchar,f)) ) {
if ( count == ticks )
return size;
else if ( count ) {
if ( (count > subtick) && (count < ticks) ) {
subsize = size;
subtick = count;
}
size += count;
}
}
}
if ( subsize ) {
*endticks = subtick;
return subsize;
}
return 0;
} /* matchticks */
/* code() -- write a string out as code. The only characters that have
* special meaning in a code block are * `<' and `&' , which
* are /always/ expanded to < and &
*/
static void
code(MMIOT *f, char *s, int length)
{
int i,c;
for ( i=0; i < length; i++ )
if ( (c = s[i]) == 003) /* ^C: expand back to 2 spaces */
Qstring(" ", f);
else
cputc(c, f);
} /* code */
/* delspan() -- write out a chunk of text, blocking with
...
*/
static void
delspan(MMIOT *f, int size)
{
Qstring("", f);
___mkd_reparse(cursor(f)-1, size, 0, f);
Qstring("", f);
}
/* codespan() -- write out a chunk of text as code, trimming one
* space off the front and/or back as appropriate.
*/
static void
codespan(MMIOT *f, int size)
{
int i=0;
if ( size > 1 && peek(f, size-1) == ' ' ) --size;
if ( peek(f,i) == ' ' ) ++i, --size;
Qstring("", f);
code(f, cursor(f)+(i-1), size);
Qstring("
", f);
} /* codespan */
/* before letting a tag through, validate against
* DENY_A and DENY_IMG
*/
static int
forbidden_tag(MMIOT *f)
{
int c = toupper(peek(f, 1));
if ( f->flags & DENY_HTML )
return 1;
if ( c == 'A' && (f->flags & DENY_A) && !isthisalnum(f,2) )
return 1;
if ( c == 'I' && (f->flags & DENY_IMG)
&& strncasecmp(cursor(f)+1, "MG", 2) == 0
&& !isthisalnum(f,4) )
return 1;
return 0;
}
/* Check a string to see if it looks like a mail address
* "looks like a mail address" means alphanumeric + some
* specials, then a `@`, then alphanumeric + some specials,
* but with a `.`
*/
static int
maybe_address(char *p, int size)
{
int ok = 0;
for ( ;size && (isalnum(*p) || strchr("._-+*", *p)); ++p, --size)
;
if ( ! (size && *p == '@') )
return 0;
--size, ++p;
if ( size && *p == '.' ) return 0;
for ( ;size && (isalnum(*p) || strchr("._-+", *p)); ++p, --size )
if ( *p == '.' && size > 1 ) ok = 1;
return size ? 0 : ok;
}
/* The size-length token at cursor(f) is either a mailto:, an
* implicit mailto:, one of the approved url protocols, or just
* plain old text. If it's a mailto: or an approved protocol,
* linkify it, otherwise say "no"
*/
static int
process_possible_link(MMIOT *f, int size)
{
int address= 0;
int mailto = 0;
char *text = cursor(f);
if ( f->flags & DENY_A ) return 0;
if ( (size > 7) && strncasecmp(text, "mailto:", 7) == 0 ) {
/* if it says it's a mailto, it's a mailto -- who am
* I to second-guess the user?
*/
address = 1;
mailto = 7; /* 7 is the length of "mailto:"; we need this */
}
else
address = maybe_address(text, size);
if ( address ) {
Qstring("", f);
mangle(text+mailto, size-mailto, f);
Qstring("", f);
return 1;
}
else if ( isautoprefix(text, size) ) {
printlinkyref(f, &linkt, text, size);
Qchar('>', f);
puturl(text,size,f, 1);
Qstring("", f);
return 1;
}
return 0;
} /* process_possible_link */
/* a < may be just a regular character, the start of an embedded html
* tag, or the start of an
", f);
break;
case '>': if ( tag_text(f) )
Qstring(">", f);
else
Qchar(c, f);
break;
case '"': if ( tag_text(f) )
Qstring(""", f);
else
Qchar(c, f);
break;
case '!': if ( peek(f,1) == '[' ) {
pull(f);
if ( tag_text(f) || !linkylinky(1, f) )
Qstring("![", f);
}
else
Qchar(c, f);
break;
case '[': if ( tag_text(f) || !linkylinky(0, f) )
Qchar(c, f);
break;
#if SUPERSCRIPT
/* A^B -> AB */
case '^': if ( (f->flags & (STRICT|INSIDE_TAG)) || isthisspace(f,-1) || isthisspace(f,1) )
Qchar(c,f);
else {
char *sup = cursor(f);
int len = 0;
Qstring("",f);
while ( !isthisspace(f,1+len) ) {
++len;
}
shift(f,len);
___mkd_reparse(sup, len, 0, f);
Qstring("", f);
}
break;
#endif
case '_':
#if RELAXED_EMPHASIS
/* Underscores don't count if they're in the middle of a word */
if ( !(f->flags & STRICT) && isthisalnum(f,-1)
&& isthisalnum(f,1) ) {
Qchar(c, f);
break;
}
#endif
case '*':
/* Underscores & stars don't count if they're out in the middle
* of whitespace */
if ( isthisspace(f,-1) && isthisspace(f,1) ) {
Qchar(c, f);
break;
}
/* else fall into the regular old emphasis case */
if ( tag_text(f) )
Qchar(c, f);
else {
for (rep = 1; peek(f,1) == c; pull(f) )
++rep;
Qem(f,c,rep);
}
break;
case '~': if ( (f->flags & (NOSTRIKETHROUGH|INSIDE_TAG|STRICT)) || !tickhandler(f,c,2,delspan) )
Qchar(c, f);
break;
case '`': if ( tag_text(f) || !tickhandler(f,c,1,codespan) )
Qchar(c, f);
break;
case '\\': switch ( c = pull(f) ) {
case '&': Qstring("&", f);
break;
case '<': Qstring("<", f);
break;
case '>': case '#': case '.': case '-':
case '+': case '{': case '}': case ']':
case '!': case '[': case '*': case '_':
case '\\':case '(': case ')':
case '`': Qchar(c, f);
break;
default:
Qchar('\\', f);
if ( c != EOF )
shift(f,-1);
break;
}
break;
case '<': if ( !maybe_tag_or_link(f) )
Qstring("<", f);
break;
case '&': j = (peek(f,1) == '#' ) ? 2 : 1;
while ( isthisalnum(f,j) )
++j;
if ( peek(f,j) != ';' )
Qstring("&", f);
else
Qchar(c, f);
break;
default: Qchar(c, f);
break;
}
}
/* truncate the input string after we've finished processing it */
S(f->in) = f->isp = 0;
} /* text */
/* print a header block
*/
static void
printheader(Paragraph *pp, MMIOT *f)
{
Qprintf(f, "\n", f);
while ( idx < S(p->text) ) {
first = idx;
if ( force && (colno >= S(align)-1) )
idx = S(p->text);
else
while ( (idx < S(p->text)) && (T(p->text)[idx] != '|') )
++idx;
Qprintf(f, "<%s%s>",
block,
alignments[ (colno < S(align)) ? T(align)[colno] : a_NONE ]);
___mkd_reparse(T(p->text)+first, idx-first, 0, f);
Qprintf(f, "%s>\n", block);
idx++;
colno++;
}
if ( force )
while (colno < S(align) ) {
Qprintf(f, "<%s>%s>\n", block, block);
++colno;
}
Qstring(" \n", f);
return colno;
}
static int
printtable(Paragraph *pp, MMIOT *f)
{
/* header, dashes, then lines of content */
Line *hdr, *dash, *body;
Istring align;
int start;
int hcols;
char *p;
if ( !(pp->text && pp->text->next) )
return 0;
hdr = pp->text;
dash= hdr->next;
body= dash->next;
/* first figure out cell alignments */
CREATE(align);
for (p=T(dash->text), start=0; start < S(dash->text); ) {
char first, last;
int end;
last=first=0;
for (end=start ; (end < S(dash->text)) && p[end] != '|'; ++ end ) {
if ( !isspace(p[end]) ) {
if ( !first) first = p[end];
last = p[end];
}
}
EXPAND(align) = ( first == ':' ) ? (( last == ':') ? a_CENTER : a_LEFT)
: (( last == ':') ? a_RIGHT : a_NONE );
start = 1+end;
}
Qstring("\n", f);
Qstring("\n", f);
hcols = splat(hdr, "th", align, 0, f);
Qstring("\n", f);
if ( hcols < S(align) )
S(align) = hcols;
else
while ( hcols > S(align) )
EXPAND(align) = a_NONE;
Qstring("\n", f);
for ( ; body; body = body->next)
splat(body, "td", align, 1, f);
Qstring("\n", f);
Qstring("
\n", f);
DELETE(align);
return 1;
}
static int
printblock(Paragraph *pp, MMIOT *f)
{
Line *t = pp->text;
static char *Begin[] = { "", "
", f);
for ( blanks = 0; t ; t = t->next ) {
if ( S(t->text) > t->dle ) {
while ( blanks ) {
Qchar('\n', f);
--blanks;
}
code(f, T(t->text), S(t->text));
Qchar('\n', f);
}
else blanks++;
}
Qstring("
", f);
}
static void
printhtml(Line *t, MMIOT *f)
{
int blanks;
for ( blanks=0; t ; t = t->next )
if ( S(t->text) ) {
for ( ; blanks; --blanks )
Qchar('\n', f);
Qwrite(T(t->text), S(t->text), f);
Qchar('\n', f);
}
else
blanks++;
}
static void
htmlify(Paragraph *p, char *block, char *arguments, MMIOT *f)
{
___mkd_emblock(f);
if ( block )
Qprintf(f, arguments ? "<%s %s>" : "<%s>", block, arguments);
___mkd_emblock(f);
while (( p = display(p, f) )) {
___mkd_emblock(f);
Qstring("\n\n", f);
}
if ( block )
Qprintf(f, "%s>", block);
___mkd_emblock(f);
}
#if DL_TAG_EXTENSION
static void
definitionlist(Paragraph *p, MMIOT *f)
{
Line *tag;
if ( p ) {
Qstring("