Skip to content
Browse files

Bring Discount sources up to 1.3.4

  • Loading branch information...
1 parent 76461fd commit 6889bdd1ea4a040bb6fc0f76f8e37537fc7f5e3e @rtomayko rtomayko committed Mar 4, 2009
Showing with 149 additions and 47 deletions.
  1. +1 −1 Rakefile
  2. +49 −0 ext/Csio.c
  3. +5 −0 ext/cstring.h
  4. +33 −25 ext/generate.c
  5. +18 −7 ext/markdown.c
  6. +4 −0 ext/markdown.h
  7. +1 −0 ext/mkdio.h
  8. +38 −14 ext/toc.c
View
2 Rakefile
@@ -172,7 +172,7 @@ task :gather => 'discount' do |t|
files =
FileList[
'discount/{markdown,mkdio,amalloc,cstring}.h',
- 'discount/{markdown,docheader,dumptree,generate,mkdio,resource}.c'
+ 'discount/{markdown,docheader,dumptree,generate,mkdio,resource,toc,Csio}.c'
]
cp files, 'ext/',
:preserve => true,
View
49 ext/Csio.c
@@ -0,0 +1,49 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include "cstring.h"
+#include "markdown.h"
+#include "amalloc.h"
+
+
+/* putc() into a cstring
+ */
+void
+Csputc(int c, Cstring *iot)
+{
+ EXPAND(*iot) = c;
+}
+
+
+/* printf() into a cstring
+ */
+int
+Csprintf(Cstring *iot, char *fmt, ...)
+{
+ va_list ptr;
+ int siz=100;
+
+ do {
+ RESERVE(*iot, siz);
+ va_start(ptr, fmt);
+ siz = vsnprintf(T(*iot)+S(*iot), ALL(*iot)-S(*iot), fmt, ptr);
+ va_end(ptr);
+ } while ( siz > (ALL(*iot)-S(*iot)) );
+
+ S(*iot) += siz;
+ return siz;
+}
+
+
+/* reparse() into a cstring
+ */
+void
+Csreparse(Cstring *iot, char *buf, int size, int flags)
+{
+ MMIOT f;
+ ___mkd_initmmiot(&f, 0);
+ ___mkd_reparse(buf, size, 0, &f);
+ ___mkd_emblock(&f);
+ SUFFIX(*iot, T(f.out), S(f.out));
+ ___mkd_freemmiot(&f, 0);
+}
View
5 ext/cstring.h
@@ -50,6 +50,7 @@
*/
#define T(x) (x).text
#define S(x) (x).size
+#define ALL(x) (x).alloc
/* abstract anchor type that defines a list base
* with a function that attaches an element to
@@ -65,4 +66,8 @@
typedef STRING(char) Cstring;
+extern void Csputc(int, Cstring *);
+extern int Csprintf(Cstring *, char *, ...);
+extern void Csreparse(Cstring *, char *, int, int);
+
#endif/*_CSTRING_D*/
View
58 ext/generate.c
@@ -277,10 +277,10 @@ emmatch(MMIOT *f, int go)
}
-/* emblock()
+/* ___mkd_emblock()
*/
-static void
-emblock(MMIOT *f)
+void
+___mkd_emblock(MMIOT *f)
{
int i;
block *p;
@@ -301,8 +301,8 @@ emblock(MMIOT *f)
/* generate html from a markup fragment
*/
-static void
-reparse(char *bfr, int size, int flags, MMIOT *f)
+void
+___mkd_reparse(char *bfr, int size, int flags, MMIOT *f)
{
MMIOT sub;
@@ -316,7 +316,7 @@ reparse(char *bfr, int size, int flags, MMIOT *f)
S(sub.in)--;
text(&sub);
- emblock(&sub);
+ ___mkd_emblock(&sub);
Qwrite(T(sub.out), S(sub.out), f);
@@ -497,12 +497,14 @@ linkykey(int image, Footnote *val, MMIOT *f)
{
Footnote *ret;
Cstring mylabel;
+ int here;
memset(val, 0, sizeof *val);
if ( (T(val->tag) = linkylabel(f, &S(val->tag))) == 0 )
return 0;
+ here = mmiottell(f);
eatspace(f);
switch ( pull(f) ) {
case '(':
@@ -517,14 +519,21 @@ linkykey(int image, Footnote *val, MMIOT *f)
return peek(f,0) == ')';
- case '[':
+ case '[': /* footnote links /as defined in the standard/ */
+ default: /* footnote links -- undocumented extension */
/* footnote link */
mylabel = val->tag;
- if ( (T(val->tag) = linkylabel(f, &S(val->tag))) == 0 )
- return 0;
+ if ( peek(f,0) == '[' ) {
+ if ( (T(val->tag) = linkylabel(f, &S(val->tag))) == 0 )
+ return 0;
- if ( !S(val->tag) )
- val->tag = mylabel;
+ if ( !S(val->tag) )
+ val->tag = mylabel;
+ }
+ else if ( f->flags & MKD_1_COMPAT )
+ break;
+ else
+ mmiotseek(f,here);
ret = bsearch(val, T(*f->footnotes), S(*f->footnotes),
sizeof *val, (stfu)__mkd_footsort);
@@ -633,12 +642,12 @@ linkylinky(int image, MMIOT *f)
if ( S(link.title) ) {
Qstring(" title=\"", f);
- reparse(T(link.title), S(link.title), INSIDE_TAG, f);
+ ___mkd_reparse(T(link.title), S(link.title), INSIDE_TAG, f);
Qchar('"', f);
}
Qstring(tag->text_pfx, f);
- reparse(T(link.tag), S(link.tag), tag->flags, f);
+ ___mkd_reparse(T(link.tag), S(link.tag), tag->flags, f);
Qstring(tag->text_sfx, f);
}
else
@@ -830,8 +839,6 @@ static struct smarties {
} smarties[] = {
{ '\'', "'s>", "rsquo", 0 },
{ '\'', "'t>", "rsquo", 0 },
- { '\'', "'re>", "rsquo", 0 },
- { '\'', "'ll>", "rsquo", 0 },
{ '-', "--", "mdash", 1 },
{ '-', "<->", "ndash", 0 },
{ '.', "...", "hellip", 2 },
@@ -885,7 +892,7 @@ smartypants(int c, int *flags, MMIOT *f)
break;
else if ( c == '\'' && peek(f, j+1) == '\'' ) {
Qstring("&ldquo;", f);
- reparse(cursor(f)+1, j-2, 0, f);
+ ___mkd_reparse(cursor(f)+1, j-2, 0, f);
Qstring("&rdquo;", f);
shift(f,j+1);
return 1;
@@ -951,7 +958,7 @@ text(MMIOT *f)
++len;
}
shift(f,len);
- reparse(sup, len, 0, f);
+ ___mkd_reparse(sup, len, 0, f);
Qstring("</sup>", f);
}
break;
@@ -1134,6 +1141,7 @@ printblock(Paragraph *pp, MMIOT *f)
push("<br/>\n", 6, f);
}
else {
+ ___mkd_tidy(t);
push(T(t->text), S(t->text), f);
if ( t->next )
push("\n", 1, f);
@@ -1191,19 +1199,19 @@ printhtml(Line *t, MMIOT *f)
static void
htmlify(Paragraph *p, char *block, char *arguments, MMIOT *f)
{
- emblock(f);
+ ___mkd_emblock(f);
if ( block )
Qprintf(f, arguments ? "<%s %s>" : "<%s>", block, arguments);
- emblock(f);
+ ___mkd_emblock(f);
while (( p = display(p, f) )) {
- emblock(f);
+ ___mkd_emblock(f);
Qstring("\n\n", f);
}
if ( block )
Qprintf(f, "</%s>", block);
- emblock(f);
+ ___mkd_emblock(f);
}
@@ -1219,7 +1227,7 @@ definitionlist(Paragraph *p, MMIOT *f)
for ( ; p ; p = p->next) {
for ( tag = p->text; tag; tag = tag->next ) {
Qstring("<dt>", f);
- reparse(T(tag->text), S(tag->text), 0, f);
+ ___mkd_reparse(T(tag->text), S(tag->text), 0, f);
Qstring("</dt>\n", f);
}
@@ -1345,7 +1353,7 @@ mkd_document(Document *p, char **res)
}
-/* public interface for reparse()
+/* public interface for ___mkd_reparse()
*/
int
mkd_text(char *bfr, int size, FILE *output, int flags)
@@ -1355,8 +1363,8 @@ mkd_text(char *bfr, int size, FILE *output, int flags)
___mkd_initmmiot(&f, 0);
f.flags = flags & USER_FLAGS;
- reparse(bfr, size, 0, &f);
- emblock(&f);
+ ___mkd_reparse(bfr, size, 0, &f);
+ ___mkd_emblock(&f);
if ( flags & CDATA_OUTPUT )
___mkd_xml(T(f.out), S(f.out), output);
else
View
25 ext/markdown.c
@@ -124,6 +124,14 @@ skipempty(Line *p)
}
+void
+___mkd_tidy(Line *t)
+{
+ while ( S(t->text) && isspace(T(t->text)[S(t->text)-1]) )
+ --S(t->text);
+}
+
+
static char *
isopentag(Line *p)
{
@@ -434,12 +442,6 @@ codeblock(Paragraph *p)
{
Line *t = p->text, *r;
- /* HORRIBLE STANDARDS KLUDGE: the first line of every block
- * has trailing whitespace trimmed off.
- */
- while ( S(t->text) && isspace(T(t->text)[S(t->text)-1]) )
- --S(t->text);
-
for ( ; t; t = r ) {
CLIP(t->text,0,4);
t->dle = mkd_firstnonblank(t);
@@ -492,12 +494,13 @@ textblock(Paragraph *p, int toplevel)
{
Line *t, *next;
- for ( t = p->text; t ; t = next )
+ for ( t = p->text; t ; t = next ) {
if ( ((next = t->next) == 0) || endoftextblock(next, toplevel) ) {
p->align = centered(p->text, t);
t->next = 0;
return next;
}
+ }
return t;
}
@@ -833,6 +836,14 @@ compile(Line *ptr, int toplevel, MMIOT *f)
}
else if ( iscode(ptr) ) {
p = Pp(&d, ptr, CODE);
+
+ if ( f->flags & MKD_1_COMPAT) {
+ /* HORRIBLE STANDARDS KLUDGE: the first line of every block
+ * has trailing whitespace trimmed off.
+ */
+ ___mkd_tidy(p->text);
+ }
+
ptr = codeblock(p);
}
else if ( ishr(ptr) ) {
View
4 ext/markdown.h
@@ -74,6 +74,7 @@ typedef struct mmiot {
#define NO_PSEUDO_PROTO 0x0040
#define CDATA_OUTPUT 0x0080
#define TOC 0x1000
+#define MKD_1_COMPAT 0x2000
#define USER_FLAGS 0xF0FF
#define EMBEDDED DENY_A|DENY_IMG|NO_PSEUDO_PROTO|CDATA_OUTPUT
char *base;
@@ -127,5 +128,8 @@ extern void ___mkd_initmmiot(MMIOT *, void *);
extern void ___mkd_freemmiot(MMIOT *, void *);
extern void ___mkd_freeLineRange(Line *, Line *);
extern void ___mkd_xml(char *, int, FILE *);
+extern void ___mkd_reparse(char *, int, int, MMIOT*);
+extern void ___mkd_emblock(MMIOT*);
+extern void ___mkd_tidy(Line *);
#endif/*_MARKDOWN_D*/
View
1 ext/mkdio.h
@@ -54,6 +54,7 @@ extern char markdown_version[];
#define MKD_NO_EXT 0x0040 /* don't allow pseudo-protocols */
#define MKD_CDATA 0x0080 /* generate code for xml ![CDATA[...]] */
#define MKD_TOC 0x1000 /* do table-of-contents processing */
+#define MKD_1_COMPAT 0x2000 /* compatability with MarkdownTest_1.0 */
#define MKD_EMBED MKD_NOLINKS|MKD_NOIMAGE|MKD_TAGTEXT
/* special flags for mkd_in() and mkd_string()
View
52 ext/toc.c
@@ -17,12 +17,16 @@
/* write an header index
*/
int
-mkd_generatetoc(Document *p, FILE *output)
+mkd_toc(Document *p, char **doc)
{
Paragraph *pp;
+ int last_hnumber = 0;
+ Cstring res;
+
+ CREATE(res);
+ RESERVE(res, 100);
- int last_hnumber = 0,
- first_hnumber = 0;
+ *doc = 0;
if ( !(p && p->ctx) ) return -1;
if ( ! (p->ctx->flags & TOC) ) return 0;
@@ -31,32 +35,52 @@ mkd_generatetoc(Document *p, FILE *output)
if ( pp->typ == HDR && pp->text ) {
if ( last_hnumber == pp->hnumber )
- fprintf(output, "%*s</li>\n", pp->hnumber, "");
+ Csprintf(&res, "%*s</li>\n", pp->hnumber, "");
else while ( last_hnumber > pp->hnumber ) {
- fprintf(output, "%*s</li>\n%*s</ul>\n",
+ Csprintf(&res, "%*s</li>\n%*s</ul>\n",
last_hnumber, "",
last_hnumber-1,"");
--last_hnumber;
}
while ( pp->hnumber > last_hnumber ) {
- fprintf(output, "\n%*s<ul>\n", pp->hnumber, "");
+ Csprintf(&res, "\n%*s<ul>\n", pp->hnumber, "");
++last_hnumber;
}
- fprintf(output, "%*s<li><a href=\"#", pp->hnumber, "");
- mkd_string_to_anchor(T(pp->text->text), S(pp->text->text), putc, output);
- fprintf(output, "\">");
- mkd_text(T(pp->text->text), S(pp->text->text), output, 0);
- fprintf(output, "</a>");
+ Csprintf(&res, "%*s<li><a href=\"#", pp->hnumber, "");
+ mkd_string_to_anchor(T(pp->text->text), S(pp->text->text), Csputc, &res);
+ Csprintf(&res, "\">");
+ Csreparse(&res, T(pp->text->text), S(pp->text->text), 0);
+ Csprintf(&res, "</a>");
}
}
while ( last_hnumber > 0 ) {
- fprintf(output, "%*s</li>\n%*s</ul>\n",
+ Csprintf(&res, "%*s</li>\n%*s</ul>\n",
last_hnumber, "", last_hnumber, "");
--last_hnumber;
}
-
- return 0;
+ /* HACK ALERT! HACK ALERT! HACK ALERT! */
+ *doc = T(res); /* we know that a T(Cstring) is a character pointer */
+ /* so we can simply pick it up and carry it away, */
+ return S(res); /* leaving the husk of the Ctring on the stack */
+ /* END HACK ALERT */
}
+
+/* write an header index
+ */
+int
+mkd_generatetoc(Document *p, FILE *out)
+{
+ char *buf = 0;
+ int sz = mkd_toc(p, &buf);
+ int ret = EOF;
+
+ if ( sz > 0 )
+ ret = fwrite(buf, sz, 1, out);
+
+ if ( buf ) free(buf);
+
+ return ret;
+}

0 comments on commit 6889bdd

Please sign in to comment.
Something went wrong with that request. Please try again.