redo the whole flags dealie as an opaque blob

This commit is contained in:
david parsons
2019-12-07 22:49:52 -08:00
parent d74c180a8c
commit b9e867b574
18 changed files with 622 additions and 359 deletions
+1 -1
View File
@@ -50,7 +50,7 @@ Cswrite(Cstring *iot, char *bfr, int size)
/* reparse() into a cstring /* reparse() into a cstring
*/ */
void void
Csreparse(Cstring *iot, char *buf, int size, mkd_flag_t flags) Csreparse(Cstring *iot, char *buf, int size, mkd_flag_t* flags)
{ {
MMIOT f; MMIOT f;
___mkd_initmmiot(&f, 0); ___mkd_initmmiot(&f, 0);
+3 -3
View File
@@ -115,8 +115,8 @@ dumptree(Paragraph *pp, Stack *sp, FILE *f)
if ( pp->ident ) if ( pp->ident )
d += fprintf(f, " %s", pp->ident); d += fprintf(f, " %s", pp->ident);
if ( pp->flags ) if ( pp->para_flags )
d += fprintf(f, " %x", pp->flags); d += fprintf(f, " %x", pp->para_flags);
if ( pp->align > 1 ) if ( pp->align > 1 )
d += fprintf(f, ", <%s>", Begin[pp->align]); d += fprintf(f, ", <%s>", Begin[pp->align]);
@@ -141,7 +141,7 @@ dumptree(Paragraph *pp, Stack *sp, FILE *f)
int int
mkd_dump(Document *doc, FILE *out, mkd_flag_t flags, char *title) mkd_dump(Document *doc, FILE *out, mkd_flag_t *flags, char *title)
{ {
Stack stack; Stack stack;
+17 -4
View File
@@ -2,7 +2,7 @@
#include "markdown.h" #include "markdown.h"
struct flagnames { struct flagnames {
mkd_flag_t flag; int flag;
char *name; char *name;
}; };
@@ -41,8 +41,15 @@ static struct flagnames flagnames[] = {
#define NR(x) (sizeof x/sizeof x[0]) #define NR(x) (sizeof x/sizeof x[0])
int
mkd_flag_isset(mkd_flag_t *flags, int i)
{
return flags ? is_flag_set(flags, i) : 0;
}
void void
mkd_flags_are(FILE *f, mkd_flag_t flags, int htmlplease) mkd_flags_are(FILE *f, mkd_flag_t* flags, int htmlplease)
{ {
int i; int i;
int not, set, even=1; int not, set, even=1;
@@ -51,7 +58,7 @@ mkd_flags_are(FILE *f, mkd_flag_t flags, int htmlplease)
if ( htmlplease ) if ( htmlplease )
fprintf(f, "<table class=\"mkd_flags_are\">\n"); fprintf(f, "<table class=\"mkd_flags_are\">\n");
for (i=0; i < NR(flagnames); i++) { for (i=0; i < NR(flagnames); i++) {
set = flags & flagnames[i].flag; set = mkd_flag_isset(flags, flagnames[i].flag);
name = flagnames[i].name; name = flagnames[i].name;
if ( not = (*name == '!') ) { if ( not = (*name == '!') ) {
++name; ++name;
@@ -88,5 +95,11 @@ void
mkd_mmiot_flags(FILE *f, MMIOT *m, int htmlplease) mkd_mmiot_flags(FILE *f, MMIOT *m, int htmlplease)
{ {
if ( m ) if ( m )
mkd_flags_are(f, m->flags, htmlplease); mkd_flags_are(f, &(m->flags), htmlplease);
}
void
mkd_init_flags(mkd_flag_t *p)
{
memset(p, 0, sizeof(*p));
} }
+70 -59
View File
@@ -209,14 +209,16 @@ Qem(MMIOT *f, char c, int count)
/* generate html from a markup fragment /* generate html from a markup fragment
*/ */
void void
___mkd_reparse(char *bfr, int size, mkd_flag_t flags, MMIOT *f, char *esc) ___mkd_reparse(char *bfr, int size, mkd_flag_t* flags, MMIOT *f, char *esc)
{ {
MMIOT sub; MMIOT sub;
struct escaped e; struct escaped e;
___mkd_initmmiot(&sub, f->footnotes); ___mkd_initmmiot(&sub, f->footnotes);
sub.flags = f->flags | flags; COPY_FLAGS(sub.flags,f->flags);
if ( flags )
OR_FLAGS(&sub.flags, flags);
sub.cb = f->cb; sub.cb = f->cb;
sub.ref_prefix = f->ref_prefix; sub.ref_prefix = f->ref_prefix;
@@ -473,7 +475,7 @@ linkyurl(MMIOT *f, int image, Footnote *p)
if ( c == '<' ) { if ( c == '<' ) {
pull(f); pull(f);
if ( !is_flag_set(f->flags, MKD_1_COMPAT) ) if ( !is_flag_set(&f->flags, MKD_1_COMPAT) )
return linkybroket(f,image,p); return linkybroket(f,image,p);
mayneedtotrim=1; mayneedtotrim=1;
} }
@@ -546,15 +548,15 @@ typedef struct linkytype {
int WxH; /* this tag allows width x height arguments */ int WxH; /* this tag allows width x height arguments */
char *text_pfx; /* text prefix (eg: ">" */ char *text_pfx; /* text prefix (eg: ">" */
char *text_sfx; /* text suffix (eg: "</a>" */ char *text_sfx; /* text suffix (eg: "</a>" */
int flags; /* reparse flags */ mkd_flag_t flags; /* reparse flags */
int kind; /* tag is url or something else? */ int kind; /* tag is url or something else? */
#define IS_URL 0x01 #define IS_URL 0x01
} linkytype; } linkytype;
static linkytype imaget = { 0, 0, "<img src=\"", "\"", static linkytype imaget = { 0, 0, "<img src=\"", "\"",
1, " alt=\"", "\" />", MKD_NOIMAGE|MKD_TAGTEXT, IS_URL }; 1, " alt=\"", "\" />", { { [MKD_NOIMAGE] = 1, [MKD_TAGTEXT] = 1} }, IS_URL };
static linkytype linkt = { 0, 0, "<a href=\"", "\"", static linkytype linkt = { 0, 0, "<a href=\"", "\"",
0, ">", "</a>", MKD_NOLINKS, IS_URL }; 0, ">", "</a>", { {[MKD_NOLINKS] = 1} }, IS_URL };
/* /*
* pseudo-protocols for [][]; * pseudo-protocols for [][];
@@ -564,11 +566,11 @@ static linkytype linkt = { 0, 0, "<a href=\"", "\"",
* raw: just dump the link without any processing * raw: just dump the link without any processing
*/ */
static linkytype specials[] = { static linkytype specials[] = {
{ "id:", 3, "<span id=\"", "\"", 0, ">", "</span>", 0, 0 }, { "id:", 3, "<span id=\"", "\"", 0, ">", "</span>", {}, 0 },
{ "raw:", 4, 0, 0, 0, 0, 0, MKD_NOHTML, 0 }, { "raw:", 4, 0, 0, 0, 0, 0, { { [MKD_NOHTML] = 1 } }, 0 },
{ "lang:", 5, "<span lang=\"", "\"", 0, ">", "</span>", 0, 0 }, { "lang:", 5, "<span lang=\"", "\"", 0, ">", "</span>", {}, 0 },
{ "abbr:", 5, "<abbr title=\"", "\"", 0, ">", "</abbr>", 0, 0 }, { "abbr:", 5, "<abbr title=\"", "\"", 0, ">", "</abbr>", {}, 0 },
{ "class:", 6, "<span class=\"", "\"", 0, ">", "</span>", 0, 0 }, { "class:", 6, "<span class=\"", "\"", 0, ">", "</span>", {}, 0 },
} ; } ;
#define NR(x) (sizeof x / sizeof x[0]) #define NR(x) (sizeof x / sizeof x[0])
@@ -596,7 +598,7 @@ printlinkyref(MMIOT *f, linkytype *tag, char *link, int size)
{ {
char *edit; char *edit;
if ( is_flag_set(f->flags, IS_LABEL) ) if ( is_flag_set(&f->flags, IS_LABEL) )
return; return;
Qstring(tag->link_pfx, f); Qstring(tag->link_pfx, f);
@@ -609,8 +611,12 @@ printlinkyref(MMIOT *f, linkytype *tag, char *link, int size)
else else
puturl(link + tag->szpat, size - tag->szpat, f, 0); puturl(link + tag->szpat, size - tag->szpat, f, 0);
} }
else else {
___mkd_reparse(link + tag->szpat, size - tag->szpat, MKD_TAGTEXT, f, 0); mkd_flag_t tagtext;
mkd_init_flags(&tagtext);
set_mkd_flag(&tagtext, MKD_TAGTEXT);
___mkd_reparse(link + tag->szpat, size - tag->szpat, &tagtext, f, 0);
}
Qstring(tag->link_sfx, f); Qstring(tag->link_sfx, f);
@@ -638,13 +644,13 @@ MMIOT *p;
static int static int
extra_linky(MMIOT *f, Cstring text, Footnote *ref) extra_linky(MMIOT *f, Cstring text, Footnote *ref)
{ {
if ( ref->flags & REFERENCED ) if ( ref->fn_flags & REFERENCED )
return 0; return 0;
if ( f->flags & IS_LABEL ) if ( is_flag_set(&f->flags,IS_LABEL) )
___mkd_reparse(T(text), S(text), linkt.flags, f, 0); ___mkd_reparse(T(text), S(text), &(linkt.flags), f, 0);
else { else {
ref->flags |= REFERENCED; ref->fn_flags |= REFERENCED;
ref->refnumber = ++ f->footnotes->reference; ref->refnumber = ++ f->footnotes->reference;
Qprintf(f, "<sup id=\"%sref:%d\"><a href=\"#%s:%d\" rel=\"footnote\">%d</a></sup>", Qprintf(f, "<sup id=\"%sref:%d\"><a href=\"#%s:%d\" rel=\"footnote\">%d</a></sup>",
p_or_nothing(f), ref->refnumber, p_or_nothing(f), ref->refnumber,
@@ -686,15 +692,17 @@ static int
linkyformat(MMIOT *f, Cstring text, int image, Footnote *ref) linkyformat(MMIOT *f, Cstring text, int image, Footnote *ref)
{ {
linkytype *tag; linkytype *tag;
static mkd_flag_t tagtext = { {[MKD_TAGTEXT] = 1} };
mkd_flag_t flags;
if ( image ) if ( image )
tag = &imaget; tag = &imaget;
else if ( tag = pseudo(ref->link) ) { else if ( tag = pseudo(ref->link) ) {
if ( is_flag_set(f->flags, MKD_NO_EXT) || is_flag_set(f->flags, MKD_SAFELINK) ) if ( is_flag_set(&f->flags, MKD_NO_EXT) || is_flag_set(&f->flags, MKD_SAFELINK) )
return 0; return 0;
} }
else if ( is_flag_set(f->flags, MKD_SAFELINK) && !safelink(ref->link) ) else if ( is_flag_set(&f->flags, MKD_SAFELINK) && !safelink(ref->link) )
/* if MKD_SAFELINK, only accept links that are local or /* if MKD_SAFELINK, only accept links that are local or
* a well-known protocol * a well-known protocol
*/ */
@@ -702,11 +710,12 @@ linkyformat(MMIOT *f, Cstring text, int image, Footnote *ref)
else else
tag = &linkt; tag = &linkt;
if ( f->flags & tag->flags ) COPY_FLAGS(flags, f->flags);
if ( AND_FLAGS(&flags, &tag->flags) )
return 0; return 0;
if ( is_flag_set(f->flags, IS_LABEL) ) if ( is_flag_set(&f->flags, IS_LABEL) )
___mkd_reparse(T(text), S(text), tag->flags, f, 0); ___mkd_reparse(T(text), S(text), &(tag->flags), f, 0);
else if ( tag->link_pfx ) { else if ( tag->link_pfx ) {
printlinkyref(f, tag, T(ref->link), S(ref->link)); printlinkyref(f, tag, T(ref->link), S(ref->link));
@@ -717,12 +726,12 @@ linkyformat(MMIOT *f, Cstring text, int image, Footnote *ref)
if ( S(ref->title) ) { if ( S(ref->title) ) {
Qstring(" title=\"", f); Qstring(" title=\"", f);
___mkd_reparse(T(ref->title), S(ref->title), MKD_TAGTEXT, f, 0); ___mkd_reparse(T(ref->title), S(ref->title), &tagtext, f, 0);
Qchar('"', f); Qchar('"', f);
} }
Qstring(tag->text_pfx, f); Qstring(tag->text_pfx, f);
___mkd_reparse(T(text), S(text), tag->flags, f, 0); ___mkd_reparse(T(text), S(text), &(tag->flags), f, 0);
Qstring(tag->text_sfx, f); Qstring(tag->text_sfx, f);
} }
else else
@@ -769,9 +778,9 @@ linkylinky(int image, MMIOT *f)
* require a second [] * require a second []
*/ */
mmiotseek(f, implicit_mark); mmiotseek(f, implicit_mark);
goodlink = !is_flag_set(f->flags, MKD_1_COMPAT); goodlink = !is_flag_set(&f->flags, MKD_1_COMPAT);
if ( is_flag_set(f->flags, MKD_EXTRA_FOOTNOTE) && (!image) && S(name) && T(name)[0] == '^' ) if ( is_flag_set(&f->flags, MKD_EXTRA_FOOTNOTE) && (!image) && S(name) && T(name)[0] == '^' )
extra_footnote = 1; extra_footnote = 1;
} }
@@ -901,13 +910,14 @@ code(MMIOT *f, char *s, int length)
cputc(c, f); cputc(c, f);
} /* code */ } /* code */
/* delspan() -- write out a chunk of text, blocking with <del>...</del> /* delspan() -- write out a chunk of text, blocking with <del>...</del>
*/ */
static void static void
delspan(MMIOT *f, int size) delspan(MMIOT *f, int size)
{ {
Qstring("<del>", f); Qstring("<del>", f);
___mkd_reparse(cursor(f)-1, size, 0, f, 0); ___mkd_reparse(cursor(f)-1, size, NULL, f, 0);
Qstring("</del>", f); Qstring("</del>", f);
} }
@@ -937,12 +947,12 @@ forbidden_tag(MMIOT *f)
{ {
int c = toupper(peek(f, 1)); int c = toupper(peek(f, 1));
if ( is_flag_set(f->flags, MKD_NOHTML) ) if ( is_flag_set(&f->flags, MKD_NOHTML) )
return 1; return 1;
if ( c == 'A' && is_flag_set(f->flags, MKD_NOLINKS) && !isthisalnum(f,2) ) if ( c == 'A' && is_flag_set(&f->flags, MKD_NOLINKS) && !isthisalnum(f,2) )
return 1; return 1;
if ( c == 'I' && is_flag_set(f->flags, MKD_NOIMAGE) if ( c == 'I' && is_flag_set(&f->flags, MKD_NOIMAGE)
&& strncasecmp(cursor(f)+1, "MG", 2) == 0 && strncasecmp(cursor(f)+1, "MG", 2) == 0
&& !isthisalnum(f,4) ) && !isthisalnum(f,4) )
return 1; return 1;
@@ -989,7 +999,7 @@ process_possible_link(MMIOT *f, int size)
int mailto = 0; int mailto = 0;
char *text = cursor(f); char *text = cursor(f);
if ( is_flag_set(f->flags, MKD_NOLINKS) ) return 0; if ( is_flag_set(&f->flags, MKD_NOLINKS) ) return 0;
if ( (size > 7) && strncasecmp(text, "mailto:", 7) == 0 ) { if ( (size > 7) && strncasecmp(text, "mailto:", 7) == 0 ) {
/* if it says it's a mailto, it's a mailto -- who am /* if it says it's a mailto, it's a mailto -- who am
@@ -1036,7 +1046,7 @@ maybe_tag_or_link(MMIOT *f)
int c, size; int c, size;
int maybetag = 1; int maybetag = 1;
if ( is_flag_set(f->flags, MKD_TAGTEXT) ) if ( is_flag_set(&f->flags, MKD_TAGTEXT) )
return 0; return 0;
for ( size=0; (c = peek(f, size+1)) != '>'; size++) { for ( size=0; (c = peek(f, size+1)) != '>'; size++) {
@@ -1050,7 +1060,7 @@ maybe_tag_or_link(MMIOT *f)
else if ( isspace(c) ) else if ( isspace(c) )
break; break;
else if ( ! (c == '/' else if ( ! (c == '/'
|| (is_flag_set(f->flags, MKD_GITHUBTAGS) && (c == '-' || c == '_')) || (is_flag_set(&f->flags, MKD_GITHUBTAGS) && (c == '-' || c == '_'))
|| isalnum(c) ) ) || isalnum(c) ) )
maybetag=0; maybetag=0;
} }
@@ -1204,9 +1214,9 @@ smartypants(int c, int *flags, MMIOT *f)
{ {
int i; int i;
if ( is_flag_set(f->flags, MKD_NOPANTS) if ( is_flag_set(&f->flags, MKD_NOPANTS)
|| is_flag_set(f->flags, MKD_TAGTEXT) || is_flag_set(&f->flags, MKD_TAGTEXT)
|| is_flag_set(f->flags, IS_LABEL) ) || is_flag_set(&f->flags, IS_LABEL) )
return 0; return 0;
for ( i=0; i < NRSMART; i++) for ( i=0; i < NRSMART; i++)
@@ -1235,7 +1245,7 @@ smartypants(int c, int *flags, MMIOT *f)
break; break;
else if ( c == '\'' && peek(f, j+1) == '\'' ) { else if ( c == '\'' && peek(f, j+1) == '\'' ) {
Qstring("&ldquo;", f); Qstring("&ldquo;", f);
___mkd_reparse(cursor(f)+1, j-2, 0, f, 0); ___mkd_reparse(cursor(f)+1, j-2, NULL, f, 0);
Qstring("&rdquo;", f); Qstring("&rdquo;", f);
shift(f,j+1); shift(f,j+1);
return 1; return 1;
@@ -1298,7 +1308,7 @@ tickhandler(MMIOT *f, int tickchar, int minticks, int allow_space, spanhandler s
return 0; return 0;
} }
#define tag_text(f) is_flag_set(f->flags, MKD_TAGTEXT) #define tag_text(f) is_flag_set(&((f)->flags), MKD_TAGTEXT)
static void static void
@@ -1308,8 +1318,9 @@ text(MMIOT *f)
int rep; int rep;
int smartyflags = 0; int smartyflags = 0;
while (1) { while (1) {
if ( is_flag_set(f->flags, MKD_AUTOLINK) && isalpha(peek(f,1)) && !tag_text(f) ) if ( is_flag_set(&f->flags, MKD_AUTOLINK) && isalpha(peek(f,1)) && !tag_text(f) )
maybe_autolink(f); maybe_autolink(f);
c = pull(f); c = pull(f);
@@ -1351,8 +1362,8 @@ text(MMIOT *f)
Qchar(c, f); Qchar(c, f);
break; break;
/* A^B -> A<sup>B</sup> */ /* A^B -> A<sup>B</sup> */
case '^': if ( is_flag_set(f->flags, MKD_NOSUPERSCRIPT) case '^': if ( is_flag_set(&f->flags, MKD_NOSUPERSCRIPT)
|| is_flag_set(f->flags, MKD_TAGTEXT) || is_flag_set(&f->flags, MKD_TAGTEXT)
|| (f->last == 0) || (f->last == 0)
|| ((ispunct(f->last) || isspace(f->last)) || ((ispunct(f->last) || isspace(f->last))
&& f->last != ')') && f->last != ')')
@@ -1383,13 +1394,13 @@ text(MMIOT *f)
shift(f,len); shift(f,len);
} }
Qstring("<sup>",f); Qstring("<sup>",f);
___mkd_reparse(sup, len, 0, f, "()"); ___mkd_reparse(sup, len, NULL, f, "()");
Qstring("</sup>", f); Qstring("</sup>", f);
} }
break; break;
case '_': case '_':
/* Underscores don't count if they're in the middle of a word */ /* Underscores don't count if they're in the middle of a word */
if ( !is_flag_set(f->flags, MKD_NORELAXED) if ( !is_flag_set(&f->flags, MKD_NORELAXED)
&& isthisalnum(f,-1) && isthisalnum(f,1) ) { && isthisalnum(f,-1) && isthisalnum(f,1) ) {
Qchar(c, f); Qchar(c, f);
break; break;
@@ -1411,8 +1422,8 @@ text(MMIOT *f)
} }
break; break;
case '~': if ( is_flag_set(f->flags, MKD_NOSTRIKETHROUGH) case '~': if ( is_flag_set(&f->flags, MKD_NOSTRIKETHROUGH)
|| is_flag_set(f->flags, MKD_TAGTEXT) || is_flag_set(&f->flags, MKD_TAGTEXT)
|| ! tickhandler(f,c,2,0, delspan) ) || ! tickhandler(f,c,2,0, delspan) )
Qchar(c, f); Qchar(c, f);
break; break;
@@ -1435,7 +1446,7 @@ text(MMIOT *f)
} }
break; break;
case '^': if ( is_flag_set(f->flags, MKD_NOSUPERSCRIPT) ) { case '^': if ( is_flag_set(&f->flags, MKD_NOSUPERSCRIPT) ) {
Qchar('\\', f); Qchar('\\', f);
shift(f,-1); shift(f,-1);
break; break;
@@ -1444,7 +1455,7 @@ text(MMIOT *f)
break; break;
case ':': case '|': case ':': case '|':
if ( is_flag_set(f->flags, MKD_NOTABLES) ) { if ( is_flag_set(&f->flags, MKD_NOTABLES) ) {
Qchar('\\', f); Qchar('\\', f);
shift(f,-1); shift(f,-1);
break; break;
@@ -1456,7 +1467,7 @@ text(MMIOT *f)
break; break;
case '[': case '[':
case '(': if ( is_flag_set(f->flags, MKD_LATEX) case '(': if ( is_flag_set(&f->flags, MKD_LATEX)
&& mathhandler(f, '\\', (c =='(')?')':']') ) && mathhandler(f, '\\', (c =='(')?')':']') )
break; break;
/* else fall through to default */ /* else fall through to default */
@@ -1486,7 +1497,7 @@ text(MMIOT *f)
Qchar(c, f); Qchar(c, f);
break; break;
case '$': if ( is_flag_set(f->flags, MKD_LATEX) && (peek(f, 1) == '$') ) { case '$': if ( is_flag_set(&f->flags, MKD_LATEX) && (peek(f, 1) == '$') ) {
pull(f); pull(f);
if ( mathhandler(f, '$', '$') ) if ( mathhandler(f, '$', '$') )
break; break;
@@ -1509,16 +1520,16 @@ text(MMIOT *f)
static void static void
printheader(Paragraph *pp, MMIOT *f) printheader(Paragraph *pp, MMIOT *f)
{ {
if ( is_flag_set(f->flags, MKD_IDANCHOR) ) { if ( is_flag_set(&f->flags, MKD_IDANCHOR) ) {
Qprintf(f, "<h%d", pp->hnumber); Qprintf(f, "<h%d", pp->hnumber);
if ( is_flag_set(f->flags, MKD_TOC) ) { if ( is_flag_set(&f->flags, MKD_TOC) ) {
Qstring(" id=\"", f); Qstring(" id=\"", f);
Qanchor(pp->text, f); Qanchor(pp->text, f);
Qchar('"', f); Qchar('"', f);
} }
Qchar('>', f); Qchar('>', f);
} else { } else {
if ( is_flag_set(f->flags, MKD_TOC) ) { if ( is_flag_set(&f->flags, MKD_TOC) ) {
Qstring("<a name=\"", f); Qstring("<a name=\"", f);
Qanchor(pp->text, f); Qanchor(pp->text, f);
Qstring("\"></a>\n", f); Qstring("\"></a>\n", f);
@@ -1566,7 +1577,7 @@ splat(Line *p, char *block, Istring align, int force, MMIOT *f)
Qprintf(f, "<%s%s>", Qprintf(f, "<%s%s>",
block, block,
alignments[ (colno < S(align)) ? T(align)[colno] : a_NONE ]); alignments[ (colno < S(align)) ? T(align)[colno] : a_NONE ]);
___mkd_reparse(T(p->text)+first, idx-first, 0, f, "|"); ___mkd_reparse(T(p->text)+first, idx-first, NULL, f, "|");
Qprintf(f, "</%s>\n", block); Qprintf(f, "</%s>\n", block);
idx++; idx++;
colno++; colno++;
@@ -1777,7 +1788,7 @@ htmlify_paragraphs(Paragraph *p, MMIOT *f)
static void static void
li_htmlify(Paragraph *p, char *arguments, mkd_flag_t flags, MMIOT *f) li_htmlify(Paragraph *p, char *arguments, int flags, MMIOT *f)
{ {
___mkd_emblock(f); ___mkd_emblock(f);
@@ -1832,7 +1843,7 @@ definitionlist(Paragraph *p, MMIOT *f)
for ( ; p ; p = p->next) { for ( ; p ; p = p->next) {
for ( tag = p->text; tag; tag = tag->next ) { for ( tag = p->text; tag; tag = tag->next ) {
Qstring("<dt>", f); Qstring("<dt>", f);
___mkd_reparse(T(tag->text), S(tag->text), 0, f, 0); ___mkd_reparse(T(tag->text), S(tag->text), NULL, f, 0);
Qstring("</dt>\n", f); Qstring("</dt>\n", f);
} }
@@ -1855,7 +1866,7 @@ listdisplay(int typ, Paragraph *p, MMIOT* f)
Qprintf(f, ">\n"); Qprintf(f, ">\n");
for ( ; p ; p = p->next ) { for ( ; p ; p = p->next ) {
li_htmlify(p->down, p->ident, p->flags, f); li_htmlify(p->down, p->ident, p->para_flags, f);
Qchar('\n', f); Qchar('\n', f);
} }
@@ -1938,7 +1949,7 @@ mkd_extra_footnotes(MMIOT *m)
for ( i=1; i <= m->footnotes->reference; i++ ) { for ( i=1; i <= m->footnotes->reference; i++ ) {
for ( j=0; j < S(m->footnotes->note); j++ ) { for ( j=0; j < S(m->footnotes->note); j++ ) {
t = &T(m->footnotes->note)[j]; t = &T(m->footnotes->note)[j];
if ( (t->refnumber == i) && (t->flags & REFERENCED) ) { if ( (t->refnumber == i) && (t->fn_flags & REFERENCED) ) {
Csprintf(&m->out, "<li id=\"%s:%d\">\n", Csprintf(&m->out, "<li id=\"%s:%d\">\n",
p_or_nothing(m), t->refnumber); p_or_nothing(m), t->refnumber);
htmlify(t->text, 0, 0, m); htmlify(t->text, 0, 0, m);
@@ -1963,7 +1974,7 @@ mkd_document(Document *p, char **res)
if ( p && p->compiled ) { if ( p && p->compiled ) {
if ( ! p->html ) { if ( ! p->html ) {
htmlify(p->code, 0, 0, p->ctx); htmlify(p->code, 0, 0, p->ctx);
if ( is_flag_set(p->ctx->flags, MKD_EXTRA_FOOTNOTE) ) if ( is_flag_set(&p->ctx->flags, MKD_EXTRA_FOOTNOTE) )
mkd_extra_footnotes(p->ctx); mkd_extra_footnotes(p->ctx);
p->html = 1; p->html = 1;
size = S(p->ctx->out); size = S(p->ctx->out);
+5 -5
View File
@@ -21,7 +21,7 @@
typedef int (*getc_func)(void*); typedef int (*getc_func)(void*);
Document * Document *
gfm_populate(getc_func getc, void* ctx, int flags) gfm_populate(getc_func getc, void* ctx, mkd_flag_t *flags)
{ {
Cstring line; Cstring line;
Document *a = __mkd_new_Document(); Document *a = __mkd_new_Document();
@@ -80,21 +80,21 @@ gfm_populate(getc_func getc, void* ctx, int flags)
/* convert a block of text into a linked list /* convert a block of text into a linked list
*/ */
Document * Document *
gfm_string(const char *buf, int len, mkd_flag_t flags) gfm_string(const char *buf, int len, mkd_flag_t* flags)
{ {
struct string_stream about; struct string_stream about;
about.data = buf; about.data = buf;
about.size = len; about.size = len;
return gfm_populate((getc_func)__mkd_io_strget, &about, flags & INPUT_MASK); return gfm_populate((getc_func)__mkd_io_strget, &about, flags);
} }
/* convert a file into a linked list /* convert a file into a linked list
*/ */
Document * Document *
gfm_in(FILE *f, mkd_flag_t flags) gfm_in(FILE *f, mkd_flag_t* flags)
{ {
return gfm_populate((getc_func)fgetc, f, flags & INPUT_MASK); return gfm_populate((getc_func)fgetc, f, flags);
} }
+4 -2
View File
@@ -17,7 +17,7 @@ mkd_h1(Paragraph *p)
} }
char * char *
mkd_h1_title(Document *doc, int flags) mkd_h1_title(Document *doc, mkd_flag_t* flags)
{ {
Paragraph *title; Paragraph *title;
@@ -28,8 +28,10 @@ mkd_h1_title(Document *doc, int flags)
/* assert that a H1 header is one line long, so that's /* assert that a H1 header is one line long, so that's
* the only thing needed * the only thing needed
*/ */
set_mkd_flag(flags, MKD_TAGTEXT);
size = mkd_line(T(title->text->text), size = mkd_line(T(title->text->text),
S(title->text->text), &generated, flags|MKD_TAGTEXT); S(title->text->text), &generated, flags);
clear_mkd_flag(flags, MKD_TAGTEXT);
if ( size ) return generated; if ( size ) return generated;
} }
return 0; return 0;
+37 -25
View File
@@ -168,7 +168,7 @@ int
main(int argc, char **argv) main(int argc, char **argv)
{ {
int rc; int rc;
mkd_flag_t flags = 0; mkd_flag_t flags;
int debug = 0; int debug = 0;
int toc = 0; int toc = 0;
int content = 1; int content = 1;
@@ -192,11 +192,13 @@ main(int argc, char **argv)
hoptset(&blob, argc, argv); hoptset(&blob, argc, argv);
hopterr(&blob, 1); hopterr(&blob, 1);
if ( q = getenv("MARKDOWN_FLAGS") )
flags = strtol(q, 0, 0);
pgm = basename(argv[0]); pgm = basename(argv[0]);
mkd_init_flags(&flags);
if ( q = getenv("MARKDOWN_FLAGS") )
mkd_set_flag_bitmap(&flags, strtol(q,0,0));
while ( opt=gethopt(&blob, opts, NROPTS) ) { while ( opt=gethopt(&blob, opts, NROPTS) ) {
if ( opt == HOPTERR ) { if ( opt == HOPTERR ) {
hoptusage(pgm, opts, NROPTS, "[file]"); hoptusage(pgm, opts, NROPTS, "[file]");
@@ -213,19 +215,29 @@ main(int argc, char **argv)
break; break;
case 'E': urlflags = hoptarg(&blob); case 'E': urlflags = hoptarg(&blob);
break; break;
case 'F': if ( strcmp(hoptarg(&blob), "?") == 0 ) { case 'f': q = hoptarg(&blob);
show_flags(0, 0); if ( strcmp(q, "?") == 0 ) {
show_flags(1, version, 0);
exit(0);
}
else if ( strcmp(q, "??") == 0 ) {
show_flags(1, version, &flags);
exit(0);
}
else if ( q=mkd_set_flag_string(&flags, hoptarg(&blob)) )
complain("unknown option <%s>", q);
break;
case 'F': q = hoptarg(&blob);
if ( strcmp(q, "?") == 0 ) {
show_flags(0, 0, 0);
exit(0);
}
else if ( strcmp(q, "??") == 0 ) {
show_flags(0, version, &flags);
exit(0); exit(0);
} }
else else
flags = strtol(hoptarg(&blob), 0, 0); mkd_set_flag_bitmap(&flags,strtol(q, 0, 0));
break;
case 'f': if ( strcmp(hoptarg(&blob), "?") == 0 ) {
show_flags(1, version);
exit(0);
}
else if ( q=set_flag(&flags, hoptarg(&blob)) )
complain("unknown option <%s>", q);
break; break;
case 'G': github_flavoured = 1; case 'G': github_flavoured = 1;
break; break;
@@ -238,7 +250,7 @@ main(int argc, char **argv)
case 't': text = hoptarg(&blob); case 't': text = hoptarg(&blob);
use_mkd_line = 1; use_mkd_line = 1;
break; break;
case 'T': flags |= MKD_TOC; case 'T': mkd_set_flag_num(&flags, MKD_TOC);
toc = 1; toc = 1;
break; break;
case 'C': extra_footnote_prefix = hoptarg(&blob); case 'C': extra_footnote_prefix = hoptarg(&blob);
@@ -255,18 +267,17 @@ main(int argc, char **argv)
case 'x': squash = 1; case 'x': squash = 1;
break; break;
case 'X': use_e_codefmt = 1; case 'X': use_e_codefmt = 1;
set_flag(&flags, "fencedcode"); mkd_set_flag_num(&flags, MKD_FENCEDCODE);
break; break;
} }
} }
if ( version ) { if ( version ) {
printf("%s: discount %s%s", pgm, markdown_version, printf("%s: discount %s%s", pgm, markdown_version,
with_html5 ? " +html5":""); with_html5 ? " +html5":"");
if ( version == 2 ) if ( version == 2 )
mkd_flags_are(stdout, flags, 0); mkd_flags_are(stdout, &flags, 0);
if ( version >= 3 )
printf(" MARKDOWN_FLAGS=0x%08x", flags);
putchar('\n'); putchar('\n');
exit(0); exit(0);
} }
@@ -278,11 +289,11 @@ main(int argc, char **argv)
mkd_with_html5_tags(); mkd_with_html5_tags();
if ( use_mkd_line ) if ( use_mkd_line )
rc = mkd_generateline( text, strlen(text), stdout, flags); rc = mkd_generateline( text, strlen(text), stdout, &flags);
else { else {
if ( text ) { if ( text ) {
doc = github_flavoured ? gfm_string(text, strlen(text), flags) doc = github_flavoured ? gfm_string(text, strlen(text), &flags)
: mkd_string(text, strlen(text), flags) ; : mkd_string(text, strlen(text), &flags) ;
if ( !doc ) { if ( !doc ) {
perror(text); perror(text);
@@ -295,7 +306,8 @@ main(int argc, char **argv)
exit(1); exit(1);
} }
doc = github_flavoured ? gfm_in(stdin,flags) : mkd_in(stdin,flags); doc = github_flavoured ? gfm_in(stdin,&flags)
: mkd_in(stdin,&flags);
if ( !doc ) { if ( !doc ) {
perror(argc ? argv[0] : "stdin"); perror(argc ? argv[0] : "stdin");
exit(1); exit(1);
@@ -319,10 +331,10 @@ main(int argc, char **argv)
mkd_ref_prefix(doc, extra_footnote_prefix); mkd_ref_prefix(doc, extra_footnote_prefix);
if ( debug ) if ( debug )
rc = mkd_dump(doc, stdout, 0, argc ? basename(argv[0]) : "stdin"); rc = mkd_dump(doc, stdout, &flags, argc ? basename(argv[0]) : "stdin");
else { else {
rc = 1; rc = 1;
if ( mkd_compile(doc, flags) ) { if ( mkd_compile(doc, &flags) ) {
rc = 0; rc = 0;
if ( styles ) if ( styles )
mkd_generatecss(doc, stdout); mkd_generatecss(doc, stdout);
+25 -12
View File
@@ -37,13 +37,21 @@ char **argv;
MMIOT *doc; MMIOT *doc;
char *q; char *q;
int version = 0; int version = 0;
int ret; int ret, i;
mkd_flag_t flags = 0; DWORD bits;
mkd_flag_t flags;
struct h_opt *opt; struct h_opt *opt;
struct h_context blob; struct h_context blob;
if ( (q = getenv("MARKDOWN_FLAGS")) ) mkd_init_flags(&flags);
flags = strtol(q, 0, 0);
if ( (q = getenv("MARKDOWN_FLAGS")) ) {
bits = strtol(q, 0, 0);
for ( i=0; i < 8*sizeof(bits); i++)
if ( bits & (1<<i) )
mkd_set_flag_num(&flags, i);
}
hoptset(&blob, argc, argv); hoptset(&blob, argc, argv);
hopterr(&blob, 1); hopterr(&blob, 1);
@@ -57,17 +65,22 @@ char **argv;
case 'V': version++; case 'V': version++;
break; break;
case 'F': if ( strcmp(hoptarg(&blob), "?") == 0 ) { case 'F': if ( strcmp(hoptarg(&blob), "?") == 0 ) {
show_flags(0,0); show_flags(0,0,0);
exit(0); exit(0);
} }
else else {
flags = strtol(hoptarg(&blob), 0, 0); bits = strtol(hoptarg(&blob), 0, 0);
for (i=0; i < 8*sizeof(bits); i++)
if ( bits & (1<<i) )
mkd_set_flag_num(&flags, i);
}
break; break;
case 'f': if ( strcmp(hoptarg(&blob), "?") == 0 ) { case 'f': if ( strcmp(hoptarg(&blob), "?") == 0 ) {
show_flags(1,version); show_flags(1,version,0);
exit(0); exit(0);
} }
else if ( q = set_flag(&flags, hoptarg(&blob)) ) else if ( q = mkd_set_flag_string(&flags, hoptarg(&blob)) )
fprintf(stderr, "unknown option <%s>\n", q); fprintf(stderr, "unknown option <%s>\n", q);
break; break;
} }
@@ -79,7 +92,7 @@ char **argv;
if ( version ) { if ( version ) {
printf("%s: discount %s", pgm, markdown_version); printf("%s: discount %s", pgm, markdown_version);
if ( version > 1 ) if ( version > 1 )
mkd_flags_are(stdout, flags, 0); mkd_flags_are(stdout, &flags, 0);
putchar('\n'); putchar('\n');
exit(0); exit(0);
} }
@@ -89,12 +102,12 @@ char **argv;
exit(1); exit(1);
} }
if ( (doc = mkd_in(stdin, flags)) == 0 ) { if ( (doc = mkd_in(stdin, &flags)) == 0 ) {
perror( (argc > 1) ? argv[1] : "stdin" ); perror( (argc > 1) ? argv[1] : "stdin" );
exit(1); exit(1);
} }
ret = mkd_xhtmlpage(doc, flags, stdout); ret = mkd_xhtmlpage(doc, &flags, stdout);
mkd_cleanup(doc); mkd_cleanup(doc);
+86 -50
View File
@@ -178,7 +178,7 @@ splitline(Line *t, int cutpoint)
} }
} }
#define UNCHECK(l) ((l)->flags &= ~CHECKED) #define UNCHECK(l) ((l)->line_flags &= ~CHECKED)
#define UNLESS_FENCED(t) if (fenced) { \ #define UNLESS_FENCED(t) if (fenced) { \
other = 1; l->count += (c == ' ' ? 0 : -1); \ other = 1; l->count += (c == ' ' ? 0 : -1); \
@@ -189,7 +189,7 @@ splitline(Line *t, int cutpoint)
* types. * types.
*/ */
static void static void
checkline(Line *l, mkd_flag_t flags) checkline(Line *l, mkd_flag_t *flags)
{ {
int eol, i; int eol, i;
int dashes = 0, spaces = 0, int dashes = 0, spaces = 0,
@@ -197,7 +197,7 @@ checkline(Line *l, mkd_flag_t flags)
stars = 0, tildes = 0, other = 0, stars = 0, tildes = 0, other = 0,
backticks = 0, fenced = 0; backticks = 0, fenced = 0;
l->flags |= CHECKED; l->line_flags |= CHECKED;
l->kind = chk_text; l->kind = chk_text;
l->count = 0; l->count = 0;
@@ -381,9 +381,9 @@ iscode(Line *t)
static inline int static inline int
ishr(Line *t, mkd_flag_t flags) ishr(Line *t, mkd_flag_t *flags)
{ {
if ( ! (t->flags & CHECKED) ) if ( ! (t->line_flags & CHECKED) )
checkline(t, flags); checkline(t, flags);
if ( t->count > 2 ) if ( t->count > 2 )
@@ -393,7 +393,7 @@ ishr(Line *t, mkd_flag_t flags)
static int static int
issetext(Line *t, int *htyp, mkd_flag_t flags) issetext(Line *t, int *htyp, mkd_flag_t *flags)
{ {
Line *n; Line *n;
@@ -402,7 +402,7 @@ issetext(Line *t, int *htyp, mkd_flag_t flags)
*/ */
if ( (n = t->next) ) { if ( (n = t->next) ) {
if ( !(n->flags & CHECKED) ) if ( !(n->line_flags & CHECKED) )
checkline(n, flags); checkline(n, flags);
if ( n->kind == chk_dash || n->kind == chk_equal ) { if ( n->kind == chk_dash || n->kind == chk_equal ) {
@@ -415,7 +415,7 @@ issetext(Line *t, int *htyp, mkd_flag_t flags)
static int static int
ishdr(Line *t, int *htyp, mkd_flag_t flags) ishdr(Line *t, int *htyp, mkd_flag_t *flags)
{ {
/* ANY leading `#`'s make this into an ETX header /* ANY leading `#`'s make this into an ETX header
*/ */
@@ -431,7 +431,7 @@ ishdr(Line *t, int *htyp, mkd_flag_t flags)
static inline int static inline int
end_of_block(Line *t, mkd_flag_t flags) end_of_block(Line *t, mkd_flag_t *flags)
{ {
int dummy; int dummy;
@@ -443,7 +443,7 @@ end_of_block(Line *t, mkd_flag_t flags)
static Line* static Line*
is_discount_dt(Line *t, int *clip, mkd_flag_t flags) is_discount_dt(Line *t, int *clip, mkd_flag_t *flags)
{ {
if ( is_flag_set(flags, MKD_DLDISCOUNT) if ( is_flag_set(flags, MKD_DLDISCOUNT)
&& t && t
@@ -472,7 +472,7 @@ is_extra_dd(Line *t)
static Line* static Line*
is_extra_dt(Line *t, int *clip, mkd_flag_t flags) is_extra_dt(Line *t, int *clip, mkd_flag_t* flags)
{ {
if ( is_flag_set(flags, MKD_DLEXTRA) if ( is_flag_set(flags, MKD_DLEXTRA)
&& t && t
@@ -496,7 +496,7 @@ is_extra_dt(Line *t, int *clip, mkd_flag_t flags)
static Line* static Line*
isdefinition(Line *t, int *clip, int *kind, mkd_flag_t flags) isdefinition(Line *t, int *clip, int *kind, mkd_flag_t *flags)
{ {
Line *ret; Line *ret;
@@ -510,7 +510,7 @@ isdefinition(Line *t, int *clip, int *kind, mkd_flag_t flags)
static int static int
islist(Line *t, int *clip, mkd_flag_t flags, int *list_type) islist(Line *t, int *clip, mkd_flag_t *flags, int *list_type)
{ {
int i, j; int i, j;
char *q; char *q;
@@ -518,7 +518,7 @@ islist(Line *t, int *clip, mkd_flag_t flags, int *list_type)
if ( end_of_block(t, flags) ) if ( end_of_block(t, flags) )
return 0; return 0;
if ( is_flag_set(flags, MKD_DLIST) && isdefinition(t,clip,list_type,flags) ) if ( (is_flag_set(flags, MKD_DLEXTRA)||is_flag_set(flags, MKD_DLDISCOUNT)) && isdefinition(t,clip,list_type,flags) )
return DL; return DL;
if ( strchr("*-+", T(t->text)[t->dle]) && isspace(T(t->text)[t->dle+1]) ) { if ( strchr("*-+", T(t->text)[t->dle]) && isspace(T(t->text)[t->dle+1]) ) {
@@ -623,12 +623,12 @@ codeblock(Paragraph *p)
static int static int
iscodefence(Line *r, int size, line_type kind, mkd_flag_t flags) iscodefence(Line *r, int size, line_type kind, mkd_flag_t *flags)
{ {
if ( !is_flag_set(flags, MKD_FENCEDCODE) ) if ( !is_flag_set(flags, MKD_FENCEDCODE) )
return 0; return 0;
if ( !(r->flags & CHECKED) ) if ( !(r->line_flags & CHECKED) )
checkline(r, flags); checkline(r, flags);
if ( kind ) if ( kind )
@@ -639,7 +639,7 @@ iscodefence(Line *r, int size, line_type kind, mkd_flag_t flags)
static Paragraph * static Paragraph *
fencedcodeblock(ParagraphRoot *d, Line **ptr, mkd_flag_t flags) fencedcodeblock(ParagraphRoot *d, Line **ptr, mkd_flag_t *flags)
{ {
Line *first, *r; Line *first, *r;
Paragraph *ret; Paragraph *ret;
@@ -694,7 +694,7 @@ centered(Line *first, Line *last)
static int static int
endoftextblock(Line *t, int toplevelblock, mkd_flag_t flags) endoftextblock(Line *t, int toplevelblock, mkd_flag_t *flags)
{ {
int z; int z;
@@ -714,7 +714,7 @@ endoftextblock(Line *t, int toplevelblock, mkd_flag_t flags)
static Line * static Line *
textblock(Paragraph *p, int toplevel, mkd_flag_t flags) textblock(Paragraph *p, int toplevel, mkd_flag_t *flags)
{ {
Line *t, *next; Line *t, *next;
@@ -749,7 +749,7 @@ szmarkerclass(char *p)
#define iscsschar(c) (isalpha(c) || (c == '-') || (c == '_') ) #define iscsschar(c) (isalpha(c) || (c == '-') || (c == '_') )
static int static int
isdivmarker(Line *p, int start, mkd_flag_t flags) isdivmarker(Line *p, int start, mkd_flag_t *flags)
{ {
char *s; char *s;
int last, i; int last, i;
@@ -788,7 +788,7 @@ isdivmarker(Line *p, int start, mkd_flag_t flags)
* way the markdown sample web form at Daring Fireball works. * way the markdown sample web form at Daring Fireball works.
*/ */
static Line * static Line *
quoteblock(Paragraph *p, mkd_flag_t flags) quoteblock(Paragraph *p, mkd_flag_t *flags)
{ {
Line *t, *q; Line *t, *q;
int qp; int qp;
@@ -848,7 +848,7 @@ typedef int (*linefn)(Line *);
* marker, but multiple paragraphs need to start with a 4-space indent. * marker, but multiple paragraphs need to start with a 4-space indent.
*/ */
static Line * static Line *
listitem(Paragraph *p, int indent, mkd_flag_t flags, linefn check) listitem(Paragraph *p, int indent, mkd_flag_t *flags, linefn check)
{ {
Line *t, *q; Line *t, *q;
int clip = indent; int clip = indent;
@@ -872,9 +872,9 @@ listitem(Paragraph *p, int indent, mkd_flag_t flags, linefn check)
if ( ischeck != CHECK_NOT ) { if ( ischeck != CHECK_NOT ) {
__mkd_trim_line(t, 3); __mkd_trim_line(t, 3);
p->flags |= GITHUB_CHECK; p->para_flags |= GITHUB_CHECK;
if ( ischeck == CHECK_YES ) if ( ischeck == CHECK_YES )
p->flags |= IS_CHECKED; p->para_flags |= IS_CHECKED;
} }
firstpara = 0; firstpara = 0;
} }
@@ -930,7 +930,7 @@ definition_block(Paragraph *top, int clip, MMIOT *f, int kind)
while (( labels = q )) { while (( labels = q )) {
if ( (q = isdefinition(labels, &z, &kind, f->flags)) == 0 ) if ( (q = isdefinition(labels, &z, &kind, &(f->flags))) == 0 )
break; break;
if ( (text = skipempty(q->next)) == 0 ) if ( (text = skipempty(q->next)) == 0 )
@@ -950,7 +950,7 @@ definition_block(Paragraph *top, int clip, MMIOT *f, int kind)
dd_block: dd_block:
p = Pp(&d, text, LISTITEM); p = Pp(&d, text, LISTITEM);
text = listitem(p, clip, f->flags, (kind==2) ? is_extra_dd : 0); text = listitem(p, clip, &(f->flags), (kind==2) ? is_extra_dd : 0);
p->down = compile(p->text, 0, f); p->down = compile(p->text, 0, f);
p->text = labels; labels = 0; p->text = labels; labels = 0;
@@ -988,7 +988,7 @@ enumerated_block(Paragraph *top, int clip, MMIOT *f, int list_class)
while (( text = q )) { while (( text = q )) {
p = Pp(&d, text, LISTITEM); p = Pp(&d, text, LISTITEM);
text = listitem(p, clip, f->flags, 0); text = listitem(p, clip, &(f->flags), 0);
p->down = compile(p->text, 0, f); p->down = compile(p->text, 0, f);
p->text = 0; p->text = 0;
@@ -996,7 +996,7 @@ enumerated_block(Paragraph *top, int clip, MMIOT *f, int list_class)
if ( para && p->down ) p->down->align = PARA; if ( para && p->down ) p->down->align = PARA;
if ( (q = skipempty(text)) == 0 if ( (q = skipempty(text)) == 0
|| islist(q, &clip, f->flags, &z) != list_class ) || islist(q, &clip, &(f->flags), &z) != list_class )
break; break;
if ( para = (q != text) ) { if ( para = (q != text) ) {
@@ -1064,7 +1064,7 @@ addfootnote(Line *p, MMIOT* f)
CREATE(foot->link); CREATE(foot->link);
CREATE(foot->title); CREATE(foot->title);
foot->text = 0; foot->text = 0;
foot->flags = foot->height = foot->width = 0; foot->fn_flags = foot->height = foot->width = 0;
/* keep the footnote label */ /* keep the footnote label */
for (j=i=p->dle+1; T(p->text)[j] != ']'; j++) for (j=i=p->dle+1; T(p->text)[j] != ']'; j++)
@@ -1075,12 +1075,12 @@ addfootnote(Line *p, MMIOT* f)
/* consume the closing ]: */ /* consume the closing ]: */
j = nextnonblank(p, j+2); j = nextnonblank(p, j+2);
if ( is_flag_set(f->flags, MKD_EXTRA_FOOTNOTE) && (T(foot->tag)[0] == '^') ) { if ( is_flag_set(&(f->flags), MKD_EXTRA_FOOTNOTE) && (T(foot->tag)[0] == '^') ) {
/* markdown extra footnote: All indented lines past this point; /* markdown extra footnote: All indented lines past this point;
* the first line includes the footnote reference, so we need to * the first line includes the footnote reference, so we need to
* snip that out as we go. * snip that out as we go.
*/ */
foot->flags |= EXTRA_FOOTNOTE; foot->fn_flags |= EXTRA_FOOTNOTE;
__mkd_trim_line(p,j); __mkd_trim_line(p,j);
np = extrablock(p); np = extrablock(p);
@@ -1197,14 +1197,14 @@ compile_document(Line *ptr, MMIOT *f)
int previous_was_break = 1; int previous_was_break = 1;
while ( ptr ) { while ( ptr ) {
if ( !is_flag_set(f->flags, MKD_NOHTML) && (tag = isopentag(ptr)) ) { if ( !is_flag_set(&(f->flags), MKD_NOHTML) && (tag = isopentag(ptr)) ) {
int blocktype; int blocktype;
/* If we encounter a html/style block, compile and save all /* If we encounter a html/style block, compile and save all
* of the cached source BEFORE processing the html/style. * of the cached source BEFORE processing the html/style.
*/ */
uncache(&source, &d, f); uncache(&source, &d, f);
if (is_flag_set(f->flags, MKD_NOSTYLE) ) if (is_flag_set(&(f->flags), MKD_NOSTYLE) )
blocktype = HTML; blocktype = HTML;
else else
blocktype = strcmp(tag->id, "STYLE") == 0 ? STYLE : HTML; blocktype = strcmp(tag->id, "STYLE") == 0 ? STYLE : HTML;
@@ -1225,9 +1225,9 @@ compile_document(Line *ptr, MMIOT *f)
ptr = consume(addfootnote(ptr, f), &eaten); ptr = consume(addfootnote(ptr, f), &eaten);
previous_was_break = 1; previous_was_break = 1;
} }
else if ( previous_was_break && iscodefence(ptr,3,0,f->flags)) { else if ( previous_was_break && iscodefence(ptr,3,0,&(f->flags)) ) {
uncache(&source, &d, f); uncache(&source, &d, f);
if ( !fencedcodeblock(&d, &ptr, f->flags) ) /* just source */ if ( !fencedcodeblock(&d, &ptr, &(f->flags)) ) /* just source */
goto attach; goto attach;
} }
else { else {
@@ -1263,7 +1263,7 @@ actually_a_table(MMIOT *f, Line *pp)
int c; int c;
/* tables need to be turned on */ /* tables need to be turned on */
if ( is_flag_set(f->flags, MKD_NOTABLES) ) if ( is_flag_set(&(f->flags), MKD_NOTABLES) )
return 0; return 0;
/* tables need three lines */ /* tables need three lines */
@@ -1273,7 +1273,7 @@ actually_a_table(MMIOT *f, Line *pp)
/* all lines must contain |'s */ /* all lines must contain |'s */
for (r = pp; r; r = r->next ) for (r = pp; r; r = r->next )
if ( !(r->flags & PIPECHAR) ) { if ( !(r->line_flags & PIPECHAR) ) {
return 0; return 0;
} }
@@ -1322,7 +1322,7 @@ compile(Line *ptr, int toplevel, MMIOT *f)
if ( iscode(ptr) ) { if ( iscode(ptr) ) {
p = Pp(&d, ptr, CODE); p = Pp(&d, ptr, CODE);
if ( is_flag_set(f->flags, MKD_1_COMPAT) ) { if ( is_flag_set(&(f->flags), MKD_1_COMPAT) ) {
/* HORRIBLE STANDARDS KLUDGE: the first line of every block /* HORRIBLE STANDARDS KLUDGE: the first line of every block
* has trailing whitespace trimmed off. * has trailing whitespace trimmed off.
*/ */
@@ -1331,15 +1331,15 @@ compile(Line *ptr, int toplevel, MMIOT *f)
ptr = codeblock(p); ptr = codeblock(p);
} }
else if ( iscodefence(ptr,3,0,f->flags) && (p=fencedcodeblock(&d, &ptr, f->flags)) ) else if ( iscodefence(ptr,3,0,&(f->flags)) && (p=fencedcodeblock(&d, &ptr, &(f->flags))) )
/* yay, it's already done */ ; /* yay, it's already done */ ;
else if ( ishr(ptr, f->flags) ) { else if ( ishr(ptr, &(f->flags)) ) {
p = Pp(&d, 0, HR); p = Pp(&d, 0, HR);
r = ptr; r = ptr;
ptr = ptr->next; ptr = ptr->next;
___mkd_freeLine(r); ___mkd_freeLine(r);
} }
else if ( list_class = islist(ptr, &indent, f->flags, &list_type) ) { else if ( list_class = islist(ptr, &indent, &(f->flags), &list_type) ) {
if ( list_class == DL ) { if ( list_class == DL ) {
p = Pp(&d, ptr, DL); p = Pp(&d, ptr, DL);
ptr = definition_block(p, indent, f, list_type); ptr = definition_block(p, indent, f, list_type);
@@ -1351,11 +1351,11 @@ compile(Line *ptr, int toplevel, MMIOT *f)
} }
else if ( isquote(ptr) ) { else if ( isquote(ptr) ) {
p = Pp(&d, ptr, QUOTE); p = Pp(&d, ptr, QUOTE);
ptr = quoteblock(p, f->flags); ptr = quoteblock(p, &(f->flags) );
p->down = compile(p->text, 1, f); p->down = compile(p->text, 1, f);
p->text = 0; p->text = 0;
} }
else if ( ishdr(ptr, &hdr_type, f->flags) ) { else if ( ishdr(ptr, &hdr_type, &(f->flags) ) ) {
p = Pp(&d, ptr, HDR); p = Pp(&d, ptr, HDR);
ptr = headerblock(p, hdr_type); ptr = headerblock(p, hdr_type);
} }
@@ -1377,7 +1377,7 @@ compile(Line *ptr, int toplevel, MMIOT *f)
* processing with textblock() * processing with textblock()
*/ */
if ( !is_flag_set(f->flags, MKD_NOHTML) && (tag = isopentag(ptr)) ) { if ( !is_flag_set(&(f->flags), MKD_NOHTML) && (tag = isopentag(ptr)) ) {
/* possibly an html block /* possibly an html block
*/ */
@@ -1387,7 +1387,7 @@ compile(Line *ptr, int toplevel, MMIOT *f)
} }
} }
if ( unclosed ) { if ( unclosed ) {
ptr = textblock(p, toplevel, f->flags); ptr = textblock(p, toplevel, &(f->flags) );
/* tables are a special kind of paragraph */ /* tables are a special kind of paragraph */
if ( actually_a_table(f, p->text) ) if ( actually_a_table(f, p->text) )
p->typ = TABLE; p->typ = TABLE;
@@ -1413,19 +1413,52 @@ compile(Line *ptr, int toplevel, MMIOT *f)
* debugging. * debugging.
*/ */
#if DEBUG
static void
sayflags(char *pfx, mkd_flag_t* flags, FILE *output)
{
int i;
fprintf(output, "%.*s/", (int)strlen(pfx), " ");
for (i=0; i<MKD_NR_FLAGS; i++)
fputc( (i==0) || (i % 10) ? ' ' : (i/10)+'0', output);
fputc('\\', output);
fputc('\n', output);
fprintf(output, "%s|", pfx);
for (i=0; i<MKD_NR_FLAGS; i++)
fputc((i%10)+'0', output);
fputc('|', output);
fputc('\n', output);
fprintf(output, "%.*s\\", (int)strlen(pfx), " ");
for (i=0;i<MKD_NR_FLAGS; i++)
fputc(is_flag_set(flags, i)?'X':' ', output);
fputc('/', output);
fputc('\n', output);
}
#else
#define sayflags(pfx,flags,output) 1
#endif
/* /*
* prepare and compile `text`, returning a Paragraph tree. * prepare and compile `text`, returning a Paragraph tree.
*/ */
int int
mkd_compile(Document *doc, mkd_flag_t flags) mkd_compile(Document *doc, mkd_flag_t* flags)
{ {
if ( !doc ) if ( !doc )
return 0; return 0;
flags &= USER_FLAGS;
if ( doc->compiled ) { if ( doc->compiled ) {
if ( doc->ctx->flags == flags && !doc->dirty) mkd_flag_t changed;
if ( flags )
COPY_FLAGS(changed, *flags);
else
mkd_init_flags(&changed);
if ( AND_FLAGS(&changed, &(doc->ctx->flags)) && !doc->dirty )
return 1; return 1;
else { else {
doc->compiled = doc->dirty = 0; doc->compiled = doc->dirty = 0;
@@ -1440,12 +1473,15 @@ mkd_compile(Document *doc, mkd_flag_t flags)
memset(doc->ctx, 0, sizeof(MMIOT) ); memset(doc->ctx, 0, sizeof(MMIOT) );
doc->ctx->ref_prefix= doc->ref_prefix; doc->ctx->ref_prefix= doc->ref_prefix;
doc->ctx->cb = &(doc->cb); doc->ctx->cb = &(doc->cb);
doc->ctx->flags = flags; sayflags("flags", flags, stderr);
COPY_FLAGS(doc->ctx->flags,*flags);
sayflags("used ", &(doc->ctx->flags), stderr);
CREATE(doc->ctx->in); CREATE(doc->ctx->in);
doc->ctx->footnotes = malloc(sizeof doc->ctx->footnotes[0]); doc->ctx->footnotes = malloc(sizeof doc->ctx->footnotes[0]);
doc->ctx->footnotes->reference = 0; doc->ctx->footnotes->reference = 0;
CREATE(doc->ctx->footnotes->note); CREATE(doc->ctx->footnotes->note);
mkd_initialize(); mkd_initialize();
doc->code = compile_document(T(doc->content), doc->ctx); doc->code = compile_document(T(doc->content), doc->ctx);
+68 -55
View File
@@ -12,11 +12,64 @@
/* flags, captured into a named type /* flags, captured into a named type
*/ */
typedef DWORD mkd_flag_t; enum {
MKD_NOLINKS, /* don't do link processing, block <a> tags */
MKD_NOIMAGE, /* don't do image processing, block <img> */
MKD_NOPANTS, /* don't run smartypants() */
MKD_NOHTML, /* don't allow raw html through AT ALL */
MKD_NORMAL_LISTITEM, /* disable github-style checkbox lists */
MKD_TAGTEXT, /* process text inside an html tag; no <em>, no <bold>,
* no html or [] expansion */
MKD_NO_EXT, /* don't allow pseudo-protocols */
MKD_NOEXT, /* ^^^ (aliased for user convenience) */
MKD_CDATA, /* generate code for xml ![CDATA[...]] */
MKD_NOSUPERSCRIPT, /* no A^B */
MKD_NORELAXED, /* emphasis happens /everywhere/ */
MKD_NOTABLES, /* disallow tables */
MKD_NOSTRIKETHROUGH, /* forbid ~~strikethrough~~ */
MKD_1_COMPAT, /* compatibility with MarkdownTest_1.0 */
MKD_TOC, /* do table-of-contents processing */
MKD_AUTOLINK, /* make http://foo.com link even without <>s */
MKD_NOHEADER, /* don't process header blocks */
MKD_TABSTOP, /* expand tabs to 4 spaces */
MKD_SAFELINK, /* paranoid check for link protocol */
MKD_NODIVQUOTE, /* forbid >%class% blocks */
MKD_NOALPHALIST, /* forbid alphabetic lists */
MKD_EXTRA_FOOTNOTE, /* enable markdown extra-style footnotes */
MKD_NOSTYLE, /* don't extract <style> blocks */
MKD_DLDISCOUNT, /* enable discount-style definition lists */
MKD_DLEXTRA, /* enable extra-style definition lists */
MKD_FENCEDCODE, /* enabled fenced code blocks */
MKD_IDANCHOR, /* use id= anchors for TOC links */
MKD_GITHUBTAGS, /* allow dash and underscore in element names */
MKD_URLENCODEDANCHOR, /* urlencode non-identifier chars instead of replacing with dots */
MKD_LATEX, /* handle embedded LaTeX escapes */
MKD_EXPLICITLIST, /* don't combine numbered/bulletted lists */
/* end of user flags */
IS_LABEL,
MKD_NR_FLAGS };
#define is_flag_set(flags, item) ((flags) & (item))
#define set_flag(flags, item) ((flags) |= (item)) typedef struct { char bit[MKD_NR_FLAGS]; } mkd_flag_t;
#define clear_flag(flags, item) ((flags) &= ~(item))
void ___mkd_or_flags(mkd_flag_t* dst, mkd_flag_t* src);
int ___mkd_and_flags(mkd_flag_t* dst, mkd_flag_t* src);
void mkd_init_flags(mkd_flag_t *p);
#define is_flag_set(flags, item) ((flags)->bit[item])
#define set_mkd_flag(flags, item) ((flags)->bit[item] = 1)
#define clear_mkd_flag(flags, item) ((flags)->bit[item] = 0)
#define COPY_FLAGS(dst,src) memcpy(&dst,&src,sizeof dst)
#define OR_FLAGS(dst,src) ___mkd_or_flags(dst,src)
#define AND_FLAGS(dst,src) ___mkd_and_flags(dst,src)
#define MKD_DLIST MKD_DLDISCOUNT|MKD_DLEXTRA
#define MKD_STRICT MKD_NOSUPERSCRIPT|MKD_NORELAXED|MKD_NOSTRIKETHROUGH| \
MKD_NOHEADER|MKD_NOALPHALIST|MKD_NODIVQUOTE| \
MKD_NOTABLES|MKD_NO_EXT|MKD_NOSTYLE|MKD_NORMAL_LISTITEM| \
MKD_TABSTOP
/* each input line is read into a Line, which contains the line, /* each input line is read into a Line, which contains the line,
* the offset of the first non-space character [this assumes * the offset of the first non-space character [this assumes
@@ -31,7 +84,7 @@ typedef struct line {
Cstring text; Cstring text;
struct line *next; struct line *next;
int dle; /* leading indent on the line */ int dle; /* leading indent on the line */
int flags; /* special attributes for this line */ int line_flags; /* special attributes for this line */
#define PIPECHAR 0x01 /* line contains a | */ #define PIPECHAR 0x01 /* line contains a | */
#define CHECKED 0x02 #define CHECKED 0x02
@@ -55,7 +108,7 @@ typedef struct paragraph {
HDR, HR, TABLE, SOURCE } typ; HDR, HR, TABLE, SOURCE } typ;
enum { IMPLICIT=0, PARA, CENTER} align; enum { IMPLICIT=0, PARA, CENTER} align;
int hnumber; /* <Hn> for typ == HDR */ int hnumber; /* <Hn> for typ == HDR */
int flags; int para_flags;
#define GITHUB_CHECK 0x01 #define GITHUB_CHECK 0x01
#define IS_CHECKED 0x02 #define IS_CHECKED 0x02
} Paragraph; } Paragraph;
@@ -74,7 +127,7 @@ typedef struct footnote {
int height, width; /* dimensions (for image link) */ int height, width; /* dimensions (for image link) */
int dealloc; /* deallocation needed? */ int dealloc; /* deallocation needed? */
int refnumber; int refnumber;
int flags; int fn_flags;
#define EXTRA_FOOTNOTE 0x01 #define EXTRA_FOOTNOTE 0x01
#define REFERENCED 0x02 #define REFERENCED 0x02
} Footnote; } Footnote;
@@ -129,46 +182,6 @@ typedef struct mmiot {
char *ref_prefix; char *ref_prefix;
struct footnote_list *footnotes; struct footnote_list *footnotes;
mkd_flag_t flags; mkd_flag_t flags;
#define MKD_NOLINKS 0x00000001
#define MKD_NOIMAGE 0x00000002
#define MKD_NOPANTS 0x00000004
#define MKD_NOHTML 0x00000008
#define MKD_NORMAL_LISTITEM 0x00000010
#define MKD_TAGTEXT 0x00000020
#define MKD_NO_EXT 0x00000040
#define MKD_CDATA 0x00000080
#define MKD_NOSUPERSCRIPT 0x00000100
#define MKD_NORELAXED 0x00000200
#define MKD_NOTABLES 0x00000400
#define MKD_NOSTRIKETHROUGH 0x00000800
#define MKD_TOC 0x00001000
#define MKD_1_COMPAT 0x00002000
#define MKD_AUTOLINK 0x00004000
#define MKD_SAFELINK 0x00008000
#define MKD_NOHEADER 0x00010000
#define MKD_TABSTOP 0x00020000
#define MKD_NODIVQUOTE 0x00040000
#define MKD_NOALPHALIST 0x00080000
#define MKD_EXTRA_FOOTNOTE 0x00200000
#define MKD_NOSTYLE 0x00400000
#define MKD_DLDISCOUNT 0x00800000
#define MKD_DLEXTRA 0x01000000
#define MKD_FENCEDCODE 0x02000000
#define MKD_IDANCHOR 0x04000000
#define MKD_GITHUBTAGS 0x08000000
#define MKD_URLENCODEDANCHOR 0x10000000
#define IS_LABEL 0x20000000
#define MKD_LATEX 0x40000000
#define MKD_EXPLICITLIST 0x80000000
#define USER_FLAGS 0xFFFFFFFF
#define INPUT_MASK (MKD_NOHEADER|MKD_TABSTOP)
/* composite flags */
#define MKD_DLIST MKD_DLDISCOUNT|MKD_DLEXTRA
#define MKD_STRICT MKD_NOSUPERSCRIPT|MKD_NORELAXED|MKD_NOSTRIKETHROUGH| \
MKD_NOHEADER|MKD_NOALPHALIST|MKD_NODIVQUOTE| \
MKD_NOTABLES|MKD_NO_EXT|MKD_NOSTYLE|MKD_NORMAL_LISTITEM| \
MKD_TABSTOP
Callback_data *cb; Callback_data *cb;
} MMIOT; } MMIOT;
@@ -213,7 +226,7 @@ struct string_stream {
extern int mkd_firstnonblank(Line *); extern int mkd_firstnonblank(Line *);
extern int mkd_compile(Document *, mkd_flag_t); extern int mkd_compile(Document *, mkd_flag_t*);
extern int mkd_document(Document *, char **); extern int mkd_document(Document *, char **);
extern int mkd_generatehtml(Document *, FILE *); extern int mkd_generatehtml(Document *, FILE *);
extern int mkd_css(Document *, char **); extern int mkd_css(Document *, char **);
@@ -222,19 +235,19 @@ extern int mkd_generatecss(Document *, FILE *);
extern int mkd_xml(char *, int , char **); extern int mkd_xml(char *, int , char **);
extern int mkd_generatexml(char *, int, FILE *); extern int mkd_generatexml(char *, int, FILE *);
extern void mkd_cleanup(Document *); extern void mkd_cleanup(Document *);
extern int mkd_line(char *, int, char **, mkd_flag_t); extern int mkd_line(char *, int, char **, mkd_flag_t*);
extern int mkd_generateline(char *, int, FILE*, mkd_flag_t); extern int mkd_generateline(char *, int, FILE*, mkd_flag_t*);
#define mkd_text mkd_generateline #define mkd_text mkd_generateline
extern void mkd_basename(Document*, char *); extern void mkd_basename(Document*, char *);
typedef int (*mkd_sta_function_t)(const int,const void*); typedef int (*mkd_sta_function_t)(const int,const void*);
extern void mkd_string_to_anchor(char*,int, mkd_sta_function_t, void*, int, MMIOT *); extern void mkd_string_to_anchor(char*,int, mkd_sta_function_t, void*, int, MMIOT *);
extern Document *mkd_in(FILE *, mkd_flag_t); extern Document *mkd_in(FILE *, mkd_flag_t*);
extern Document *mkd_string(const char*, int, mkd_flag_t); extern Document *mkd_string(const char*, int, mkd_flag_t*);
extern Document *gfm_in(FILE *, mkd_flag_t); extern Document *gfm_in(FILE *, mkd_flag_t*);
extern Document *gfm_string(const char*,int, mkd_flag_t); extern Document *gfm_string(const char*,int, mkd_flag_t*);
extern void mkd_initialize(); extern void mkd_initialize();
extern void mkd_shlib_destructor(); extern void mkd_shlib_destructor();
@@ -252,7 +265,7 @@ extern void ___mkd_initmmiot(MMIOT *, void *);
extern void ___mkd_freemmiot(MMIOT *, void *); extern void ___mkd_freemmiot(MMIOT *, void *);
extern void ___mkd_freeLineRange(Line *, Line *); extern void ___mkd_freeLineRange(Line *, Line *);
extern void ___mkd_xml(char *, int, FILE *); extern void ___mkd_xml(char *, int, FILE *);
extern void ___mkd_reparse(char *, int, mkd_flag_t, MMIOT*, char*); extern void ___mkd_reparse(char *, int, mkd_flag_t*, MMIOT*, char*);
extern void ___mkd_emblock(MMIOT*); extern void ___mkd_emblock(MMIOT*);
extern void ___mkd_tidy(Cstring *); extern void ___mkd_tidy(Cstring *);
+47 -16
View File
@@ -63,7 +63,7 @@ __mkd_enqueue(Document* a, Cstring *line)
} }
else if ( c >= ' ' ) { else if ( c >= ' ' ) {
if ( c == '|' ) if ( c == '|' )
p->flags |= PIPECHAR; p->line_flags |= PIPECHAR;
EXPAND(p->text) = c; EXPAND(p->text) = c;
++xp; ++xp;
} }
@@ -95,7 +95,7 @@ __mkd_trim_line(Line *p, int clip)
typedef int (*getc_func)(void*); typedef int (*getc_func)(void*);
Document * Document *
populate(getc_func getc, void* ctx, mkd_flag_t flags) populate(getc_func getc, void* ctx, mkd_flag_t *flags)
{ {
Cstring line; Cstring line;
Document *a = __mkd_new_Document(); Document *a = __mkd_new_Document();
@@ -104,6 +104,7 @@ populate(getc_func getc, void* ctx, mkd_flag_t flags)
if ( !a ) return 0; if ( !a ) return 0;
a->tabstop = is_flag_set(flags, MKD_TABSTOP) ? 4 : TABSTOP; a->tabstop = is_flag_set(flags, MKD_TABSTOP) ? 4 : TABSTOP;
CREATE(line); CREATE(line);
@@ -149,9 +150,9 @@ populate(getc_func getc, void* ctx, mkd_flag_t flags)
/* convert a file into a linked list /* convert a file into a linked list
*/ */
Document * Document *
mkd_in(FILE *f, mkd_flag_t flags) mkd_in(FILE *f, mkd_flag_t *flags)
{ {
return populate((getc_func)fgetc, f, flags & INPUT_MASK); return populate((getc_func)fgetc, f, flags);
} }
@@ -171,14 +172,14 @@ __mkd_io_strget(struct string_stream *in)
/* convert a block of text into a linked list /* convert a block of text into a linked list
*/ */
Document * Document *
mkd_string(const char *buf, int len, mkd_flag_t flags) mkd_string(const char *buf, int len, mkd_flag_t* flags)
{ {
struct string_stream about; struct string_stream about;
about.data = buf; about.data = buf;
about.size = len; about.size = len;
return populate((getc_func)__mkd_io_strget, &about, flags & INPUT_MASK); return populate((getc_func)__mkd_io_strget, &about, flags);
} }
@@ -191,7 +192,7 @@ mkd_generatehtml(Document *p, FILE *output)
int szdoc; int szdoc;
DO_OR_DIE( szdoc = mkd_document(p,&doc) ); DO_OR_DIE( szdoc = mkd_document(p,&doc) );
if ( is_flag_set(p->ctx->flags, MKD_CDATA) ) if ( is_flag_set( &(p->ctx->flags), MKD_CDATA ) )
DO_OR_DIE( mkd_generatexml(doc, szdoc, output) ); DO_OR_DIE( mkd_generatexml(doc, szdoc, output) );
else if ( fwrite(doc, szdoc, 1, output) != 1 ) else if ( fwrite(doc, szdoc, 1, output) != 1 )
return EOF; return EOF;
@@ -203,7 +204,7 @@ mkd_generatehtml(Document *p, FILE *output)
/* convert some markdown text to html /* convert some markdown text to html
*/ */
int int
markdown(Document *document, FILE *out, mkd_flag_t flags) markdown(Document *document, FILE *out, mkd_flag_t* flags)
{ {
if ( mkd_compile(document, flags) ) { if ( mkd_compile(document, flags) ) {
mkd_generatehtml(document, out); mkd_generatehtml(document, out);
@@ -224,7 +225,7 @@ markdown(Document *document, FILE *out, mkd_flag_t flags)
* labelformat && !h4anchor:expand space to -, other isspace() & '%' to hex * labelformat && !h4anchor:expand space to -, other isspace() & '%' to hex
*/ */
static char * static char *
mkd_anchor_format(char *s, int len, int labelformat, mkd_flag_t flags) mkd_anchor_format(char *s, int len, int labelformat, mkd_flag_t *flags)
{ {
char *res; char *res;
unsigned char c; unsigned char c;
@@ -277,10 +278,13 @@ mkd_string_to_anchor(char *s, int len, mkd_sta_function_t outchar,
char *res; char *res;
char *line; char *line;
int size; int size;
mkd_flag_t flags;
int i; int i;
size = mkd_line(s, len, &line, IS_LABEL); mkd_init_flags(&flags);
set_mkd_flag(&flags,IS_LABEL);
size = mkd_line(s, len, &line, &flags);
if ( !line ) if ( !line )
return; return;
@@ -288,7 +292,7 @@ mkd_string_to_anchor(char *s, int len, mkd_sta_function_t outchar,
if ( f->cb->e_anchor ) if ( f->cb->e_anchor )
res = (*(f->cb->e_anchor))(line, size, f->cb->e_data); res = (*(f->cb->e_anchor))(line, size, f->cb->e_data);
else else
res = mkd_anchor_format(line, size, labelformat, f->flags); res = mkd_anchor_format(line, size, labelformat, &(f->flags));
free(line); free(line);
@@ -310,11 +314,11 @@ mkd_string_to_anchor(char *s, int len, mkd_sta_function_t outchar,
/* ___mkd_reparse() a line /* ___mkd_reparse() a line
*/ */
static void static void
mkd_parse_line(char *bfr, int size, MMIOT *f, mkd_flag_t flags) mkd_parse_line(char *bfr, int size, MMIOT *f, mkd_flag_t *flags)
{ {
___mkd_initmmiot(f, 0); ___mkd_initmmiot(f, 0);
f->flags = flags & USER_FLAGS; COPY_FLAGS(f->flags, *flags);
___mkd_reparse(bfr, size, 0, f, 0); ___mkd_reparse(bfr, size, NULL, f, 0);
___mkd_emblock(f); ___mkd_emblock(f);
} }
@@ -322,7 +326,7 @@ mkd_parse_line(char *bfr, int size, MMIOT *f, mkd_flag_t flags)
/* ___mkd_reparse() a line, returning it in malloc()ed memory /* ___mkd_reparse() a line, returning it in malloc()ed memory
*/ */
int int
mkd_line(char *bfr, int size, char **res, mkd_flag_t flags) mkd_line(char *bfr, int size, char **res, mkd_flag_t* flags)
{ {
MMIOT f; MMIOT f;
int len; int len;
@@ -351,7 +355,7 @@ mkd_line(char *bfr, int size, char **res, mkd_flag_t flags)
/* ___mkd_reparse() a line, writing it to a FILE /* ___mkd_reparse() a line, writing it to a FILE
*/ */
int int
mkd_generateline(char *bfr, int size, FILE *output, mkd_flag_t flags) mkd_generateline(char *bfr, int size, FILE *output, mkd_flag_t* flags)
{ {
MMIOT f; MMIOT f;
int status; int status;
@@ -455,3 +459,30 @@ mkd_ref_prefix(Document *f, char *data)
f->ref_prefix = data; f->ref_prefix = data;
} }
} }
void
___mkd_or_flags(mkd_flag_t *dst, mkd_flag_t *src)
{
int i;
for (i=0; i<MKD_NR_FLAGS; i++)
if ( is_flag_set(src,i) )
set_mkd_flag(dst, i);
}
int
___mkd_and_flags(mkd_flag_t *dst, mkd_flag_t *src)
{
int i;
int count = 0;
for (i=0; i < MKD_NR_FLAGS; i++)
if ( is_flag_set(src,i) && is_flag_set(dst,i) )
++count;
else
clear_mkd_flag(dst, i);
return count;
}
+56 -44
View File
@@ -7,17 +7,27 @@
typedef void MMIOT; typedef void MMIOT;
typedef @DWORD@ mkd_flag_t; typedef struct { char bfr[50]; } mkd_flag_t;
int mkd_flag_isset(mkd_flag_t*, int); /* check a flag status */
void mkd_flag_set(mkd_flag_t*, int); /* set a flag */
void mkd_flag_clear(mkd_flag_t*, int); /* clear a flag */
void mkd_init_flags(mkd_flag_t*); /* initialize the flags */
char *mkd_set_flag_string(mkd_flag_t*, char*); /* set named flags */
void mkd_set_flag_num(mkd_flag_t*, unsigned long);/* set a specific flag */
void mkd_clr_flag_num(mkd_flag_t*, unsigned long);/* clear a specific flag */
void mkd_set_flag_bitmap(mkd_flag_t*,long); /* set a bunch of flags */
/* line builder for markdown() /* line builder for markdown()
*/ */
MMIOT *mkd_in(FILE*,mkd_flag_t); /* assemble input from a file */ MMIOT *mkd_in(FILE*,mkd_flag_t*); /* assemble input from a file */
MMIOT *mkd_string(const char*,int,mkd_flag_t); /* assemble input from a buffer */ MMIOT *mkd_string(const char*,int,mkd_flag_t*); /* assemble input from a buffer */
/* line builder for github flavoured markdown /* line builder for github flavoured markdown
*/ */
MMIOT *gfm_in(FILE*,mkd_flag_t); /* assemble input from a file */ MMIOT *gfm_in(FILE*,mkd_flag_t*); /* assemble input from a file */
MMIOT *gfm_string(const char*,int,mkd_flag_t); /* assemble input from a buffer */ MMIOT *gfm_string(const char*,int,mkd_flag_t*); /* assemble input from a buffer */
void mkd_basename(MMIOT*,char*); void mkd_basename(MMIOT*,char*);
@@ -27,15 +37,15 @@ void mkd_shlib_destructor();
/* compilation, debugging, cleanup /* compilation, debugging, cleanup
*/ */
int mkd_compile(MMIOT*, mkd_flag_t); int mkd_compile(MMIOT*, mkd_flag_t*);
void mkd_cleanup(MMIOT*); void mkd_cleanup(MMIOT*);
/* markup functions /* markup functions
*/ */
int mkd_dump(MMIOT*, FILE*, mkd_flag_t, char*); int mkd_dump(MMIOT*, FILE*, mkd_flag_t*, char*);
int markdown(MMIOT*, FILE*, mkd_flag_t); int markdown(MMIOT*, FILE*, mkd_flag_t*);
int mkd_line(char *, int, char **, mkd_flag_t); int mkd_line(char *, int, char **, mkd_flag_t*);
int mkd_xhtmlpage(MMIOT*,mkd_flag_t,FILE*); int mkd_xhtmlpage(MMIOT*,mkd_flag_t*,FILE*);
/* header block access /* header block access
*/ */
@@ -57,7 +67,7 @@ int mkd_generatetoc(MMIOT*,FILE*);
int mkd_generatexml(char *, int,FILE*); int mkd_generatexml(char *, int,FILE*);
int mkd_generatecss(MMIOT*,FILE*); int mkd_generatecss(MMIOT*,FILE*);
#define mkd_style mkd_generatecss #define mkd_style mkd_generatecss
int mkd_generateline(char *, int, FILE*, mkd_flag_t); int mkd_generateline(char *, int, FILE*, mkd_flag_t*);
#define mkd_text mkd_generateline #define mkd_text mkd_generateline
/* url generator callbacks /* url generator callbacks
@@ -76,45 +86,47 @@ void mkd_e_data(void *, void *);
*/ */
extern char markdown_version[]; extern char markdown_version[];
void mkd_mmiot_flags(FILE *, MMIOT *, int); void mkd_mmiot_flags(FILE *, MMIOT *, int);
void mkd_flags_are(FILE*, mkd_flag_t, int); void mkd_flags_are(FILE*, mkd_flag_t*, int);
void mkd_ref_prefix(MMIOT*, char*); void mkd_ref_prefix(MMIOT*, char*);
/* special flags for markdown() and mkd_text() /* special flags for markdown() and mkd_text()
*/ */
#define MKD_NOLINKS 0x00000001 /* don't do link processing, block <a> tags */ enum {
#define MKD_NOIMAGE 0x00000002 /* don't do image processing, block <img> */ MKD_NOLINKS, /* don't do link processing, block <a> tags */
#define MKD_NOPANTS 0x00000004 /* don't run smartypants() */ MKD_NOIMAGE, /* don't do image processing, block <img> */
#define MKD_NOHTML 0x00000008 /* don't allow raw html through AT ALL */ MKD_NOPANTS, /* don't run smartypants() */
#define MKD_NORMAL_LISTITEM 0x00000010 /* disable github-style checkbox lists */ MKD_NOHTML, /* don't allow raw html through AT ALL */
#define MKD_TAGTEXT 0x00000020 /* process text inside an html tag; no MKD_NORMAL_LISTITEM, /* disable github-style checkbox lists */
* <em>, no <bold>, no html or [] expansion */ MKD_TAGTEXT, /* process text inside an html tag; no <em>, no <bold>,
#define MKD_NO_EXT 0x00000040 /* don't allow pseudo-protocols */ * no html or [] expansion */
#define MKD_NOEXT MKD_NO_EXT /* ^^^ (aliased for user convenience) */ MKD_NO_EXT, /* don't allow pseudo-protocols */
#define MKD_CDATA 0x00000080 /* generate code for xml ![CDATA[...]] */ MKD_NOEXT, /* ^^^ (aliased for user convenience) */
#define MKD_NOSUPERSCRIPT 0x00000100 /* no A^B */ MKD_CDATA, /* generate code for xml ![CDATA[...]] */
#define MKD_NORELAXED 0x00000200 /* emphasis happens /everywhere/ */ MKD_NOSUPERSCRIPT, /* no A^B */
#define MKD_NOTABLES 0x00000400 /* disallow tables */ MKD_NORELAXED, /* emphasis happens /everywhere/ */
#define MKD_NOSTRIKETHROUGH 0x00000800 /* forbid ~~strikethrough~~ */ MKD_NOTABLES, /* disallow tables */
#define MKD_TOC 0x00001000 /* do table-of-contents processing */ MKD_NOSTRIKETHROUGH, /* forbid ~~strikethrough~~ */
#define MKD_1_COMPAT 0x00002000 /* compatibility with MarkdownTest_1.0 */ MKD_1_COMPAT, /* compatibility with MarkdownTest_1.0 */
#define MKD_AUTOLINK 0x00004000 /* make http://foo.com link even without <>s */ MKD_TOC, /* do table-of-contents processing */
#define MKD_SAFELINK 0x00008000 /* paranoid check for link protocol */ MKD_AUTOLINK, /* make http://foo.com link even without <>s */
#define MKD_NOHEADER 0x00010000 /* don't process header blocks */ MKD_TABSTOP, /* expand tabs to 4 spaces */
#define MKD_TABSTOP 0x00020000 /* expand tabs to 4 spaces */ MKD_NOHEADER, /* don't process header blocks */
#define MKD_NODIVQUOTE 0x00040000 /* forbid >%class% blocks */ MKD_SAFELINK, /* paranoid check for link protocol */
#define MKD_NOALPHALIST 0x00080000 /* forbid alphabetic lists */ MKD_NODIVQUOTE, /* forbid >%class% blocks */
#define MKD_EXTRA_FOOTNOTE 0x00200000 /* enable markdown extra-style footnotes */ MKD_NOALPHALIST, /* forbid alphabetic lists */
#define MKD_NOSTYLE 0x00400000 /* don't extract <style> blocks */ MKD_EXTRA_FOOTNOTE, /* enable markdown extra-style footnotes */
#define MKD_DLDISCOUNT 0x00800000 /* enable discount-style definition lists */ MKD_NOSTYLE, /* don't extract <style> blocks */
#define MKD_DLEXTRA 0x01000000 /* enable extra-style definition lists */ MKD_DLDISCOUNT, /* enable discount-style definition lists */
#define MKD_FENCEDCODE 0x02000000 /* enabled fenced code blocks */ MKD_DLEXTRA, /* enable extra-style definition lists */
#define MKD_IDANCHOR 0x04000000 /* use id= anchors for TOC links */ MKD_FENCEDCODE, /* enabled fenced code blocks */
#define MKD_GITHUBTAGS 0x08000000 /* allow dash and underscore in element names */ MKD_IDANCHOR, /* use id= anchors for TOC links */
#define MKD_URLENCODEDANCHOR 0x10000000 /* urlencode non-identifier chars instead of replacing with dots */ MKD_GITHUBTAGS, /* allow dash and underscore in element names */
#define MKD_LATEX 0x40000000 /* handle embedded LaTeX escapes */ MKD_URLENCODEDANCHOR, /* urlencode non-identifier chars instead of replacing with dots */
#define MKD_EXPLICITLIST 0x80000000 /* don't combine numbered/bulletted lists */ MKD_LATEX, /* handle embedded LaTeX escapes */
MKD_EXPLICITLIST, /* don't combine numbered/bulletted lists */
MKD_NR_FLAGS };
#define MKD_EMBED MKD_NOLINKS|MKD_NOIMAGE|MKD_TAGTEXT #define MKD_EMBED MKD_NOLINKS|MKD_NOIMAGE|MKD_TAGTEXT
#define MKD_DLIST MKD_DLDISCOUNT|MKD_DLEXTRA #define MKD_DLIST MKD_DLDISCOUNT|MKD_DLEXTRA
+151 -40
View File
@@ -8,67 +8,78 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <limits.h> #include <limits.h>
#include <mkdio.h>
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include <stdarg.h> #include <stdarg.h>
#include "config.h" #include "config.h"
#include "markdown.h"
#include "amalloc.h" #include "amalloc.h"
#if HAVE_LIBGEN_H #if HAVE_LIBGEN_H
#include <libgen.h> #include <libgen.h>
#endif #endif
static void set_dlist(mkd_flag_t *, int);
static void set_standard(mkd_flag_t *, int);
static struct _special {
char *name;
void (*setter)(mkd_flag_t *, int);
} special[] = {
{ "definitionlist", set_dlist },
{ "dlist", set_dlist },
{ "standard", set_standard },
};
static struct _opt { static struct _opt {
char *name; char *name;
char *desc; char *desc;
int special;
int off; int off;
int skip; /* this opt is a synonym; don't display in -F? */ int alias; /* this opt is a synonym; don't display in -F? */
int composite; /* composite flag; don't display in -F? */
int sayenable; int sayenable;
mkd_flag_t flag; /* flags to set/clear */ int flag; /* flag to set/clear */
mkd_flag_t unflag; /* flags to clear/set */ int unflag; /* flag to clear/set */
} opts[] = { } opts[] = {
{ "tabstop", "default (4-space) tabstops", 0, 0, 0, 1, MKD_TABSTOP }, { "tabstop", "default (4-space) tabstops", 0, 0, 0, 1, MKD_TABSTOP },
{ "image", "images", 1, 0, 0, 1, MKD_NOIMAGE }, { "image", "images", 0, 1, 0, 1, MKD_NOIMAGE },
{ "links", "links", 1, 0, 0, 1, MKD_NOLINKS }, { "links", "links", 0, 1, 0, 1, MKD_NOLINKS },
{ "strict", "emphasis inside words", 0, 0, 0, 1, MKD_NORELAXED }, { "strict", "emphasis inside words", 0, 0, 0, 1, MKD_NORELAXED },
{ "relax", "emphasis inside words", 1, 1, 0, 1, MKD_NORELAXED }, { "relax", "emphasis inside words", 0, 1, 1, 1, MKD_NORELAXED },
{ "tables", "tables", 1, 0, 0, 1, MKD_NOTABLES }, { "tables", "tables", 0, 1, 0, 1, MKD_NOTABLES },
{ "header", "pandoc-style headers", 1, 0, 0, 1, MKD_NOHEADER }, { "header", "pandoc-style headers", 0, 1, 0, 1, MKD_NOHEADER },
{ "html", "allow raw html", 1, 0, 0, 0, MKD_NOHTML }, { "html", "allow raw html", 0, 1, 0, 0, MKD_NOHTML },
{ "ext", "extended protocols", 1, 0, 0, 1, MKD_NO_EXT }, { "ext", "extended protocols", 0, 1, 0, 1, MKD_NO_EXT },
{ "cdata", "generate cdata", 0, 0, 0, 0, MKD_CDATA }, { "cdata", "generate cdata", 0, 0, 0, 0, MKD_CDATA },
{ "smarty", "smartypants", 1, 0, 0, 1, MKD_NOPANTS }, { "smarty", "smartypants", 0, 1, 0, 1, MKD_NOPANTS },
{ "pants", "smartypants", 1, 1, 0, 1, MKD_NOPANTS }, { "pants", "smartypants", 0, 1, 1, 1, MKD_NOPANTS },
{ "toc", "tables of contents", 0, 0, 0, 1, MKD_TOC }, { "toc", "tables of contents", 0, 0, 0, 1, MKD_TOC },
{ "autolink", "autolinking", 0, 0, 0, 1, MKD_AUTOLINK }, { "autolink", "autolinking", 0, 0, 0, 1, MKD_AUTOLINK },
{ "safelink", "safe links", 0, 0, 0, 1, MKD_SAFELINK }, { "safelink", "safe links", 0, 0, 0, 1, MKD_SAFELINK },
{ "strikethrough", "strikethrough", 1, 0, 0, 1, MKD_NOSTRIKETHROUGH }, { "strikethrough", "strikethrough", 0, 1, 0, 1, MKD_NOSTRIKETHROUGH },
{ "del", "strikethrough", 1, 1, 0, 1, MKD_NOSTRIKETHROUGH }, { "del", "strikethrough", 0, 1, 1, 1, MKD_NOSTRIKETHROUGH },
{ "superscript", "superscript", 1, 0, 0, 1, MKD_NOSUPERSCRIPT }, { "superscript", "superscript", 0, 1, 0, 1, MKD_NOSUPERSCRIPT },
{ "divquote", ">%class% blockquotes", 1, 0, 0, 1, MKD_NODIVQUOTE }, { "divquote", ">%class% blockquotes", 0, 1, 0, 1, MKD_NODIVQUOTE },
{ "alphalist", "alpha lists", 1, 0, 0, 1, MKD_NOALPHALIST }, { "alphalist", "alpha lists", 0, 1, 0, 1, MKD_NOALPHALIST },
{ "definitionlist","both discount & markdown extra definition lists", 0, 0, 1, 1, MKD_DLIST },
{ "dlist", "both discount & markdown extra definition lists", 0, 1, 1, 1, MKD_DLIST },
{ "1.0", "markdown 1.0 compatibility", 0, 0, 0, 1, MKD_1_COMPAT }, { "1.0", "markdown 1.0 compatibility", 0, 0, 0, 1, MKD_1_COMPAT },
{ "footnotes", "markdown extra footnotes", 0, 0, 0, 1, MKD_EXTRA_FOOTNOTE }, { "footnotes", "markdown extra footnotes", 0, 0, 0, 1, MKD_EXTRA_FOOTNOTE },
{ "footnote", "markdown extra footnotes", 0, 1, 0, 1, MKD_EXTRA_FOOTNOTE }, { "footnote", "markdown extra footnotes", 0, 0, 1, 1, MKD_EXTRA_FOOTNOTE },
{ "style", "extract style blocks", 1, 0, 0, 1, MKD_NOSTYLE }, { "style", "extract style blocks", 0, 1, 0, 1, MKD_NOSTYLE },
{ "dldiscount", "discount-style definition lists", 0, 0, 0, 1, MKD_DLDISCOUNT }, { "dldiscount", "discount-style definition lists", 0, 0, 0, 1, MKD_DLDISCOUNT },
{ "dlextra", "markdown extra-style definition lists", 0, 0, 0, 1, MKD_DLEXTRA }, { "dlextra", "markdown extra-style definition lists", 0, 0, 0, 1, MKD_DLEXTRA },
{ "fencedcode", "fenced code blocks", 0, 0, 0, 1, MKD_FENCEDCODE }, { "fencedcode", "fenced code blocks", 0, 0, 0, 1, MKD_FENCEDCODE },
{ "idanchor", "id= anchors in TOC", 0, 0, 0, 1, MKD_IDANCHOR }, { "idanchor", "id= anchors in TOC", 0, 0, 0, 1, MKD_IDANCHOR },
{ "githubtags", "- and _ in element names", 0, 0, 0, 1, MKD_GITHUBTAGS }, { "githubtags", "- and _ in element names", 0, 0, 0, 1, MKD_GITHUBTAGS },
{ "urlencodedanchor", "html5-style anchors", 0, 0, 0, 1, MKD_URLENCODEDANCHOR }, { "urlencodedanchor", "html5-style anchors", 0, 0, 0, 1, MKD_URLENCODEDANCHOR },
{ "html5anchor", "html5-style anchors", 0, 1, 0, 1, MKD_URLENCODEDANCHOR }, { "html5anchor", "html5-style anchors", 0, 0, 1, 1, MKD_URLENCODEDANCHOR },
{ "latex", "LaTeX escapes", 0, 0, 0, 1, MKD_LATEX }, { "latex", "LaTeX escapes", 0, 0, 0, 1, MKD_LATEX },
{ "explicitlist", "merge adjacent numeric/bullet lists", 0, 0, 0, 0, MKD_EXPLICITLIST }, { "explicitlist", "merge adjacent numeric/bullet lists", 0, 0, 0, 0, MKD_EXPLICITLIST },
{ "github-listitem","github-style check items", 1, 0, 0, 1, MKD_NORMAL_LISTITEM } , { "github-listitem","github-style check items", 0, 1, 0, 1, MKD_NORMAL_LISTITEM } ,
{ "regular-listitem","github-style check items", 0, 1, 0, 1, MKD_NORMAL_LISTITEM } , { "regular-listitem","github-style check items", 0, 0, 1, 1, MKD_NORMAL_LISTITEM } ,
{ "standard", "conform to the markdown standard", 0, 0, 1, 0, MKD_STRICT, { "definitionlist","both discount & markdown extra definition lists", 1 },
MKD_FENCEDCODE|MKD_LATEX|MKD_TABSTOP|MKD_EXTRA_FOOTNOTE|MKD_AUTOLINK|MKD_SAFELINK|MKD_TOC|MKD_DLIST }, { "dlist", "both discount & markdown extra definition lists", 1, 0, 1 },
{ "standard", "conform to the markdown standard", 1 },
} ; } ;
#define NR(x) (sizeof x / sizeof x[0]) #define NR(x) (sizeof x / sizeof x[0])
@@ -90,38 +101,103 @@ sort_by_flag(struct _opt *a, struct _opt *b)
void void
show_flags(int byname, int verbose) show_flags(int byname, int verbose, mkd_flag_t *flags)
{ {
int i; int i;
if ( byname ) { if ( byname ) {
qsort(opts, NR(opts), sizeof(opts[0]), (stfu)sort_by_name); qsort(opts, NR(opts), sizeof(opts[0]), (stfu)sort_by_name);
for (i=0; i < NR(opts); i++) for (i=0; i < NR(opts); i++) {
if ( verbose || !opts[i].skip ) if ( opts[i].special || (opts[i].alias && !verbose) )
continue;
if ( (flags==0) || is_flag_set(flags, opts[i].flag) )
fprintf(stderr, "%16s : %s\n", opts[i].name, opts[i].desc); fprintf(stderr, "%16s : %s\n", opts[i].name, opts[i].desc);
}
} }
else { else {
qsort(opts, NR(opts), sizeof(opts[0]), (stfu)sort_by_flag); qsort(opts, NR(opts), sizeof(opts[0]), (stfu)sort_by_flag);
for (i=0; i < NR(opts); i++) for (i=0; i < NR(opts) && i < 8*sizeof(DWORD); i++) {
if ( !(opts[i].skip || opts[i].composite) ) {
fprintf(stderr, "%08lx : ", (long)opts[i].flag); if ( opts[i].special || opts[i].alias )
continue;
if ( (flags==0) || is_flag_set(flags, opts[i].flag) ) {
fprintf(stderr, "%08lx : ", 1L<<opts[i].flag);
if ( opts[i].sayenable ) if ( opts[i].sayenable )
fprintf(stderr, opts[i].off ? "disable " : "enable "); fprintf(stderr, opts[i].off ? "disable " : "enable ");
fprintf(stderr, "%s\n", opts[i].desc); fprintf(stderr, "%s\n", opts[i].desc);
} }
}
}
}
static void
set_dlist(mkd_flag_t *flags, int enable)
{
if ( enable ) {
set_mkd_flag(flags, MKD_DLDISCOUNT);
set_mkd_flag(flags, MKD_DLEXTRA);
}
else {
clear_mkd_flag(flags, MKD_DLDISCOUNT);
clear_mkd_flag(flags, MKD_DLEXTRA);
}
}
static void
set_standard(mkd_flag_t *flags, int enable)
{
if ( enable ) {
clear_mkd_flag(flags, MKD_FENCEDCODE);
clear_mkd_flag(flags, MKD_LATEX);
clear_mkd_flag(flags, MKD_TABSTOP);
clear_mkd_flag(flags, MKD_EXTRA_FOOTNOTE);
clear_mkd_flag(flags, MKD_AUTOLINK);
clear_mkd_flag(flags, MKD_SAFELINK);
clear_mkd_flag(flags, MKD_TOC);
clear_mkd_flag(flags, MKD_DLDISCOUNT);
clear_mkd_flag(flags, MKD_DLEXTRA);
set_mkd_flag(flags, MKD_NOSUPERSCRIPT);
set_mkd_flag(flags, MKD_NORMAL_LISTITEM);
set_mkd_flag(flags, MKD_NO_EXT);
set_mkd_flag(flags, MKD_NOEXT);
set_mkd_flag(flags, MKD_NOSUPERSCRIPT);
set_mkd_flag(flags, MKD_NORELAXED);
set_mkd_flag(flags, MKD_NOTABLES);
set_mkd_flag(flags, MKD_NOSTRIKETHROUGH);
set_mkd_flag(flags, MKD_NOHEADER);
set_mkd_flag(flags, MKD_NODIVQUOTE);
set_mkd_flag(flags, MKD_NOALPHALIST);
set_mkd_flag(flags, MKD_NOSTYLE);
} }
} }
static void
handle_special(mkd_flag_t *flags, char *opt, int enable)
{
int i;
for (i=0; i < NR(special); i++)
if ( strcasecmp(opt, special[i].name) == 0 ) {
(special[i].setter)(flags, enable);
return;
}
}
char * char *
set_flag(mkd_flag_t *flags, char *optionstring) mkd_set_flag_string(mkd_flag_t *flags, char *optionstring)
{ {
int i; int i;
int enable; int enable;
char *arg; char *arg;
if ( flags == 0 ) /* shouldn't happen */
return "NULL";
for ( arg = strtok(optionstring, ","); arg; arg = strtok(NULL, ",") ) { for ( arg = strtok(optionstring, ","); arg; arg = strtok(NULL, ",") ) {
if ( *arg == '+' || *arg == '-' ) if ( *arg == '+' || *arg == '-' )
enable = (*arg++ == '+') ? 1 : 0; enable = (*arg++ == '+') ? 1 : 0;
@@ -137,18 +213,23 @@ set_flag(mkd_flag_t *flags, char *optionstring)
break; break;
if ( i < NR(opts) ) { if ( i < NR(opts) ) {
if ( opts[i].special ) {
handle_special(flags, opts[i].name, enable);
continue;
}
if ( opts[i].off ) if ( opts[i].off )
enable = !enable; enable = !enable;
if ( enable ) { if ( enable ) {
*flags |= opts[i].flag; set_mkd_flag(flags, opts[i].flag);
if ( opts[i].unflag ) if ( opts[i].unflag )
*flags &= ~opts[i].unflag; clear_mkd_flag(flags, opts[i].unflag);
} }
else { else {
*flags &= ~opts[i].flag; clear_mkd_flag(flags, opts[i].flag);
if ( opts[i].unflag ) if ( opts[i].unflag )
*flags |= opts[i].unflag; set_mkd_flag(flags, opts[i].unflag);
} }
} }
else else
@@ -156,3 +237,33 @@ set_flag(mkd_flag_t *flags, char *optionstring)
} }
return 0; return 0;
} }
void
mkd_set_flag_num(mkd_flag_t *p, unsigned long bit)
{
if ( p && (bit < MKD_NR_FLAGS) )
set_mkd_flag(p, bit);
}
void
mkd_clr_flag_num(mkd_flag_t *p, unsigned long bit)
{
if ( p && (bit < MKD_NR_FLAGS) )
clear_mkd_flag(p, bit);
}
void
mkd_set_flag_bitmap(mkd_flag_t *p, long bits)
{
int i;
if ( p == 0 )
return;
for (i=0; i < 8*sizeof(long) && i < MKD_NR_FLAGS; i++)
if ( bits & (1<<i) )
set_mkd_flag(p, i);
}
+1 -2
View File
@@ -3,7 +3,6 @@
#include <mkdio.h> #include <mkdio.h>
char *set_flag(mkd_flag_t *flags, char *optionstring); void show_flags(int byname, int verbose, mkd_flag_t *flags);
void show_flags(int byname, int verbose);
#endif/*PGM_OPTIONS_D*/ #endif/*PGM_OPTIONS_D*/
+2 -2
View File
@@ -10,13 +10,13 @@ try -flatex 'latex w/ \( .. \) and link inside' '\([(1+2)*3-4](1-2)\)' '<p>\([(1
try -flatex 'latex w/ \( .. \) and special characters' 'Equation:\(a<+>b\).' \ try -flatex 'latex w/ \( .. \) and special characters' 'Equation:\(a<+>b\).' \
'<p>Equation:\(a&lt;+&gt;b\).</p>' '<p>Equation:\(a&lt;+&gt;b\).</p>'
try -flatex 'latex $ delimiter not supported' '$[a](b)$' '<p>$<a href="b">a</a>$</p>' #try -flatex 'latex $ delimiter not supported' '$[a](b)$' '<p>$<a href="b">a</a>$</p>'
try -flatex 'latex with $$ .. $$' '$$foo$$' '<p>$$foo$$</p>' try -flatex 'latex with $$ .. $$' '$$foo$$' '<p>$$foo$$</p>'
try -flatex 'latex with $$ .. $$ like a link' '$$[(1+2)*3-4](1-2)$$' '<p>$$[(1+2)*3-4](1-2)$$</p>' try -flatex 'latex with $$ .. $$ like a link' '$$[(1+2)*3-4](1-2)$$' '<p>$$[(1+2)*3-4](1-2)$$</p>'
try -flatex 'latex with multiple $$ .. $$' '$$[a](b)$$$$[a](b)$$' '<p>$$[a](b)$$$$[a](b)$$</p>' try -flatex 'latex with multiple $$ .. $$' '$$[a](b)$$$$[a](b)$$' '<p>$$[a](b)$$$$[a](b)$$</p>'
try -flatex 'latex with $$ .. $$ and a real link' '$$[a](b)$$[a](b)$$' '<p>$$[a](b)$$<a href="b">a</a>$$</p>' try -flatex 'latex with $$ .. $$ and a real link' '$$[a](b)$$[a](b)$$' '<p>$$[a](b)$$<a href="b">a</a>$$</p>'
try -flatex 'latex with $$ .. $$ and a real link' '$$[a](b)$$$[a](b)$$' '<p>$$[a](b)$$$<a href="b">a</a>$$</p>' #try -flatex 'latex with $$ .. $$ and a real link' '$$[a](b)$$$[a](b)$$' '<p>$$[a](b)$$$<a href="b">a</a>$$</p>'
try -flatex 'latex with $$ .. $$ multi lines' '$$\begin{split}\nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} & = \frac{4\pi}{c}\vec{\mathbf{j}} \\ \nabla \cdot \vec{\mathbf{E}} & = 4 \pi \rho \\ \nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} & = \vec{\mathbf{0}} \\ \nabla \cdot \vec{\mathbf{B}} & = 0 \end{split}$$' '<p>$$\begin{split}\nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} &amp; = \frac{4\pi}{c}\vec{\mathbf{j}} \\ \nabla \cdot \vec{\mathbf{E}} &amp; = 4 \pi \rho \\ \nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} &amp; = \vec{\mathbf{0}} \\ \nabla \cdot \vec{\mathbf{B}} &amp; = 0 \end{split}$$</p>' try -flatex 'latex with $$ .. $$ multi lines' '$$\begin{split}\nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} & = \frac{4\pi}{c}\vec{\mathbf{j}} \\ \nabla \cdot \vec{\mathbf{E}} & = 4 \pi \rho \\ \nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} & = \vec{\mathbf{0}} \\ \nabla \cdot \vec{\mathbf{B}} & = 0 \end{split}$$' '<p>$$\begin{split}\nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} &amp; = \frac{4\pi}{c}\vec{\mathbf{j}} \\ \nabla \cdot \vec{\mathbf{E}} &amp; = 4 \pi \rho \\ \nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} &amp; = \vec{\mathbf{0}} \\ \nabla \cdot \vec{\mathbf{B}} &amp; = 0 \end{split}$$</p>'
try -flatex 'latex with \[ .. \]' '\[foo\]' '<p>\[foo\]</p>' try -flatex 'latex with \[ .. \]' '\[foo\]' '<p>\[foo\]</p>'
+35 -35
View File
@@ -256,7 +256,7 @@ istag(int *p, char *pat)
/* finclude() includes some (unformatted) source /* finclude() includes some (unformatted) source
*/ */
static void static void
finclude(MMIOT *doc, FILE *out, int flags, int whence) finclude(MMIOT *doc, FILE *out, mkd_flag_t *flags, int whence)
{ {
int c; int c;
Cstring include; Cstring include;
@@ -287,7 +287,7 @@ finclude(MMIOT *doc, FILE *out, int flags, int whence)
/* fdirname() prints out the directory part of a path /* fdirname() prints out the directory part of a path
*/ */
static void static void
fdirname(MMIOT *doc, FILE *output, int flags, int whence) fdirname(MMIOT *doc, FILE *output, mkd_flag_t *flags, int whence)
{ {
char *p; char *p;
@@ -299,7 +299,7 @@ fdirname(MMIOT *doc, FILE *output, int flags, int whence)
/* fbasename() prints out the file name part of a path /* fbasename() prints out the file name part of a path
*/ */
static void static void
fbasename(MMIOT *doc, FILE *output, int flags, int whence) fbasename(MMIOT *doc, FILE *output, mkd_flag_t *flags, int whence)
{ {
char *p; char *p;
@@ -318,7 +318,7 @@ fbasename(MMIOT *doc, FILE *output, int flags, int whence)
/* ftitle() prints out the document title /* ftitle() prints out the document title
*/ */
static void static void
ftitle(MMIOT *doc, FILE* output, int flags, int whence) ftitle(MMIOT *doc, FILE* output, mkd_flag_t *flags, int whence)
{ {
char *h; char *h;
h = mkd_doc_title(doc); h = mkd_doc_title(doc);
@@ -339,19 +339,22 @@ ftitle(MMIOT *doc, FILE* output, int flags, int whence)
/* fdate() prints out the document date /* fdate() prints out the document date
*/ */
static void static void
fdate(MMIOT *doc, FILE *output, int flags, int whence) fdate(MMIOT *doc, FILE *output, mkd_flag_t *flags, int whence)
{ {
char *h; char *h;
if ( (h = mkd_doc_date(doc)) || ( infop && (h = ctime(&infop->st_mtime)) ) ) if ( (h = mkd_doc_date(doc)) || ( infop && (h = ctime(&infop->st_mtime)) ) ) {
mkd_generateline(h, strlen(h), output, flags|MKD_TAGTEXT); mkd_set_flag_num(flags, MKD_TAGTEXT);
mkd_generateline(h, strlen(h), output, flags);
mkd_clr_flag_num(flags, MKD_TAGTEXT);
}
} }
/* fauthor() prints out the document author /* fauthor() prints out the document author
*/ */
static void static void
fauthor(MMIOT *doc, FILE *output, int flags, int whence) fauthor(MMIOT *doc, FILE *output, mkd_flag_t *flags, int whence)
{ {
char *h = mkd_doc_author(doc); char *h = mkd_doc_author(doc);
@@ -369,7 +372,7 @@ fauthor(MMIOT *doc, FILE *output, int flags, int whence)
* tabular versions of the flags. * tabular versions of the flags.
*/ */
static void static void
fconfig(MMIOT *doc, FILE *output, int flags, int whence) fconfig(MMIOT *doc, FILE *output, mkd_flag_t *flags, int whence)
{ {
mkd_mmiot_flags(output, doc, (whence & (INHEAD|INTAG)) ? 0 : 1); mkd_mmiot_flags(output, doc, (whence & (INHEAD|INTAG)) ? 0 : 1);
} }
@@ -378,7 +381,7 @@ fconfig(MMIOT *doc, FILE *output, int flags, int whence)
/* fversion() prints out the document version /* fversion() prints out the document version
*/ */
static void static void
fversion(MMIOT *doc, FILE *output, int flags, int whence) fversion(MMIOT *doc, FILE *output, mkd_flag_t *flags, int whence)
{ {
fwrite(markdown_version, strlen(markdown_version), 1, output); fwrite(markdown_version, strlen(markdown_version), 1, output);
} }
@@ -387,7 +390,7 @@ fversion(MMIOT *doc, FILE *output, int flags, int whence)
/* fbody() prints out the document /* fbody() prints out the document
*/ */
static void static void
fbody(MMIOT *doc, FILE *output, int flags, int whence) fbody(MMIOT *doc, FILE *output, mkd_flag_t *flags, int whence)
{ {
mkd_generatehtml(doc, output); mkd_generatehtml(doc, output);
} }
@@ -395,7 +398,7 @@ fbody(MMIOT *doc, FILE *output, int flags, int whence)
/* ftoc() prints out the table of contents /* ftoc() prints out the table of contents
*/ */
static void static void
ftoc(MMIOT *doc, FILE *output, int flags, int whence) ftoc(MMIOT *doc, FILE *output, mkd_flag_t *flags, int whence)
{ {
mkd_generatetoc(doc, output); mkd_generatetoc(doc, output);
} }
@@ -403,7 +406,7 @@ ftoc(MMIOT *doc, FILE *output, int flags, int whence)
/* fstyle() prints out the document's style section /* fstyle() prints out the document's style section
*/ */
static void static void
fstyle(MMIOT *doc, FILE *output, int flags, int whence) fstyle(MMIOT *doc, FILE *output, mkd_flag_t *flags, int whence)
{ {
mkd_generatecss(doc, output); mkd_generatecss(doc, output);
} }
@@ -425,7 +428,7 @@ fstyle(MMIOT *doc, FILE *output, int flags, int whence)
static struct _keyword { static struct _keyword {
char *kw; char *kw;
int where; int where;
void (*what)(MMIOT*,FILE*,int,int); void (*what)(MMIOT*,FILE*,mkd_flag_t *,int);
} keyword[] = { } keyword[] = {
{ "author?>", 0xffff, fauthor }, { "author?>", 0xffff, fauthor },
{ "body?>", INBODY, fbody }, { "body?>", INBODY, fbody },
@@ -449,7 +452,7 @@ spin(FILE *template, MMIOT *doc, FILE *output)
{ {
int c; int c;
int *p; int *p;
int flags; mkd_flag_t flags;
int where = 0x0; int where = 0x0;
int i; int i;
@@ -473,17 +476,21 @@ spin(FILE *template, MMIOT *doc, FILE *output)
shift(-1); shift(-1);
p = cursor(); p = cursor();
if ( where & INTAG )
flags = MKD_TAGTEXT;
else if ( where & INHEAD )
flags = MKD_NOIMAGE|MKD_NOLINKS;
else
flags = 0;
for (i=0; i < NR(keyword); i++) for (i=0; i < NR(keyword); i++)
if ( thesame(p, keyword[i].kw) ) { if ( thesame(p, keyword[i].kw) ) {
if ( everywhere || (keyword[i].where & where) ) if ( everywhere || (keyword[i].where & where) ) {
(*keyword[i].what)(doc,output,flags,where);
mkd_init_flags(&flags);
mkd_set_flag_num(&flags, THEME_CF);
mkd_set_flag_num(&flags, MKD_TOC);
if ( where & INTAG )
mkd_set_flag_num(&flags, MKD_TAGTEXT);
else if ( where & INHEAD ) {
mkd_set_flag_num(&flags, MKD_NOIMAGE);
mkd_set_flag_num(&flags, MKD_NOLINKS);
}
(*keyword[i].what)(doc,output,&flags,where);
}
break; break;
} }
@@ -533,7 +540,7 @@ char **argv;
char *template = "page.theme"; char *template = "page.theme";
char *source = "stdin"; char *source = "stdin";
FILE *tmplfile; FILE *tmplfile;
mkd_flag_t flags = THEME_CF|MKD_TOC; mkd_flag_t flags;
int force = 0; int force = 0;
MMIOT *doc; MMIOT *doc;
struct stat sourceinfo; struct stat sourceinfo;
@@ -563,18 +570,11 @@ char **argv;
break; break;
case 't': template = hoptarg(&blob); case 't': template = hoptarg(&blob);
break; break;
case 'C': if ( strcmp(hoptarg(&blob), "?") == 0 ) {
show_flags(0,0);
exit(0);
}
else
flags = strtol(hoptarg(&blob), 0, 0);
break;
case 'c': if ( strcmp(hoptarg(&blob), "?") == 0 ) { case 'c': if ( strcmp(hoptarg(&blob), "?") == 0 ) {
show_flags(1,0); show_flags(1,0, 0);
exit(0); exit(0);
} }
else if ( q = set_flag(&flags, hoptarg(&blob)) ) else if ( q = mkd_set_flag_string(&flags, hoptarg(&blob)) )
fprintf(stderr,"%s: unknown option <%s>", pgm, q); fprintf(stderr,"%s: unknown option <%s>", pgm, q);
break; break;
case 'o': output_file = hoptarg(&blob); case 'o': output_file = hoptarg(&blob);
@@ -653,7 +653,7 @@ char **argv;
fail("out of memory"); fail("out of memory");
#endif #endif
if ( !mkd_compile(doc, flags) ) if ( !mkd_compile(doc, &flags) )
fail("couldn't compile input"); fail("couldn't compile input");
if ( tmplfile ) if ( tmplfile )
+13 -3
View File
@@ -15,6 +15,9 @@
#include "markdown.h" #include "markdown.h"
#include "amalloc.h" #include "amalloc.h"
/* inport from Csio.c */
extern void Csreparse(Cstring *, char *, int, mkd_flag_t*);
/* write an header index /* write an header index
*/ */
int int
@@ -25,14 +28,21 @@ mkd_toc(Document *p, char **doc)
Cstring res; Cstring res;
int size; int size;
int first = 1; int first = 1;
extern void Csreparse(Cstring *, char *, int, mkd_flag_t); #if 0
static mkd_flag_t islabel = { { [IS_LABEL] = 1 } };
#else
mkd_flag_t islabel;
mkd_init_flags(&islabel);
#endif
set_mkd_flag(&islabel, IS_LABEL);
if ( !(doc && p && p->ctx) ) return -1; if ( !(doc && p && p->ctx) ) return -1;
*doc = 0; *doc = 0;
if ( ! is_flag_set(p->ctx->flags, MKD_TOC) ) return 0; if ( ! is_flag_set(&p->ctx->flags, MKD_TOC) ) return 0;
CREATE(res); CREATE(res);
RESERVE(res, 100); RESERVE(res, 100);
@@ -68,7 +78,7 @@ mkd_toc(Document *p, char **doc)
&res,1,p->ctx); &res,1,p->ctx);
Csprintf(&res, "\">"); Csprintf(&res, "\">");
Csreparse(&res, T(srcp->text->text), Csreparse(&res, T(srcp->text->text),
S(srcp->text->text), IS_LABEL); S(srcp->text->text), &islabel);
Csprintf(&res, "</a>"); Csprintf(&res, "</a>");
first = 0; first = 0;
+1 -1
View File
@@ -11,7 +11,7 @@
int int
mkd_xhtmlpage(Document *p, mkd_flag_t flags, FILE *out) mkd_xhtmlpage(Document *p, mkd_flag_t* flags, FILE *out)
{ {
char *title; char *title;
extern char *mkd_doc_title(Document *); extern char *mkd_doc_title(Document *);