generate.c (discount-2.2.4.tar.bz2) | : | generate.c (discount-2.2.6.tar.bz2) | ||
---|---|---|---|---|
skipping to change at line 51 | skipping to change at line 51 | |||
* push a character into the generator input buffer | * push a character into the generator input buffer | |||
*/ | */ | |||
static void | static void | |||
pushc(char c, MMIOT *f) | pushc(char c, MMIOT *f) | |||
{ | { | |||
EXPAND(f->in) = c; | EXPAND(f->in) = c; | |||
} | } | |||
/* look <i> characters ahead of the cursor. | /* look <i> characters ahead of the cursor. | |||
*/ | */ | |||
static inline unsigned int | static inline int | |||
peek(MMIOT *f, int i) | peek(MMIOT *f, int i) | |||
{ | { | |||
i += (f->isp-1); | i += (f->isp-1); | |||
return (i >= 0) && (i < S(f->in)) ? (unsigned char)T(f->in)[i] : EOF; | return (i >= 0) && (i < S(f->in)) ? (unsigned char)T(f->in)[i] : EOF; | |||
} | } | |||
/* pull a byte from the input buffer | /* pull a byte from the input buffer | |||
*/ | */ | |||
skipping to change at line 169 | skipping to change at line 169 | |||
{ | { | |||
char bfr[80]; | char bfr[80]; | |||
va_list ptr; | va_list ptr; | |||
va_start(ptr,fmt); | va_start(ptr,fmt); | |||
vsnprintf(bfr, sizeof bfr, fmt, ptr); | vsnprintf(bfr, sizeof bfr, fmt, ptr); | |||
va_end(ptr); | va_end(ptr); | |||
Qstring(bfr, f); | Qstring(bfr, f); | |||
} | } | |||
/* Qanchor() prints out a suitable-for-id-tag version of a string | ||||
*/ | ||||
static void | ||||
Qanchor(struct line *p, MMIOT *f) | ||||
{ | ||||
mkd_string_to_anchor(T(p->text), S(p->text), | ||||
(mkd_sta_function_t)Qchar, f, 1, f); | ||||
} | ||||
/* Qem() | /* Qem() | |||
*/ | */ | |||
static void | static void | |||
Qem(MMIOT *f, char c, int count) | Qem(MMIOT *f, char c, int count) | |||
{ | { | |||
block *p = &EXPAND(f->Q); | block *p = &EXPAND(f->Q); | |||
memset(p, 0, sizeof *p); | memset(p, 0, sizeof *p); | |||
p->b_type = (c == '*') ? bSTAR : bUNDER; | p->b_type = (c == '*') ? bSTAR : bUNDER; | |||
p->b_char = c; | p->b_char = c; | |||
p->b_count = count; | p->b_count = count; | |||
memset(&EXPAND(f->Q), 0, sizeof(block)); | memset(&EXPAND(f->Q), 0, sizeof(block)); | |||
} | } | |||
/* generate html from a markup fragment | /* generate html from a markup fragment | |||
*/ | */ | |||
void | void | |||
___mkd_reparse(char *bfr, int size, int 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; | sub.flags = f->flags | flags; | |||
sub.cb = f->cb; | sub.cb = f->cb; | |||
sub.ref_prefix = f->ref_prefix; | sub.ref_prefix = f->ref_prefix; | |||
skipping to change at line 442 | skipping to change at line 451 | |||
linkyurl(MMIOT *f, int image, Footnote *p) | linkyurl(MMIOT *f, int image, Footnote *p) | |||
{ | { | |||
int c; | int c; | |||
int mayneedtotrim=0; | int mayneedtotrim=0; | |||
if ( (c = eatspace(f)) == EOF ) | if ( (c = eatspace(f)) == EOF ) | |||
return 0; | return 0; | |||
if ( c == '<' ) { | if ( c == '<' ) { | |||
pull(f); | pull(f); | |||
if ( !(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; | |||
} | } | |||
T(p->link) = cursor(f); | T(p->link) = cursor(f); | |||
for ( S(p->link)=0; (c = peek(f,1)) != ')'; ++S(p->link) ) { | for ( S(p->link)=0; (c = peek(f,1)) != ')'; ++S(p->link) ) { | |||
if ( c == EOF ) | if ( c == EOF ) | |||
return 0; | return 0; | |||
else if ( (c == '"' || c == '\'') && linkytitle(f, c, p) ) | else if ( (c == '"' || c == '\'') && linkytitle(f, c, p) ) | |||
break; | break; | |||
skipping to change at line 560 | skipping to change at line 569 | |||
return 0; | return 0; | |||
} | } | |||
/* print out the start of an `img' or `a' tag, applying callbacks as needed. | /* print out the start of an `img' or `a' tag, applying callbacks as needed. | |||
*/ | */ | |||
static void | static void | |||
printlinkyref(MMIOT *f, linkytype *tag, char *link, int size) | printlinkyref(MMIOT *f, linkytype *tag, char *link, int size) | |||
{ | { | |||
char *edit; | char *edit; | |||
if ( f->flags & IS_LABEL ) | if ( is_flag_set(f->flags, IS_LABEL) ) | |||
return; | return; | |||
Qstring(tag->link_pfx, f); | Qstring(tag->link_pfx, f); | |||
if ( tag->kind & IS_URL ) { | if ( tag->kind & IS_URL ) { | |||
if ( f->cb && f->cb->e_url && (edit = (*f->cb->e_url)(link, size, f->cb-> e_data)) ) { | if ( f->cb && f->cb->e_url && (edit = (*f->cb->e_url)(link, size, f->cb-> e_data)) ) { | |||
puturl(edit, strlen(edit), f, 0); | puturl(edit, strlen(edit), f, 0); | |||
if ( f->cb->e_free ) (*f->cb->e_free)(edit, f->cb->e_data); | if ( f->cb->e_free ) (*f->cb->e_free)(edit, f->cb->e_data); | |||
} | } | |||
else | else | |||
skipping to change at line 649 | skipping to change at line 658 | |||
/* print out a linky (or fail if it's Not Allowed) | /* print out a linky (or fail if it's Not Allowed) | |||
*/ | */ | |||
static int | static int | |||
linkyformat(MMIOT *f, Cstring text, int image, Footnote *ref) | linkyformat(MMIOT *f, Cstring text, int image, Footnote *ref) | |||
{ | { | |||
linkytype *tag; | linkytype *tag; | |||
if ( image ) | if ( image ) | |||
tag = &imaget; | tag = &imaget; | |||
else if ( tag = pseudo(ref->link) ) { | else if ( tag = pseudo(ref->link) ) { | |||
if ( f->flags & (MKD_NO_EXT|MKD_SAFELINK) ) | if ( is_flag_set(f->flags, MKD_NO_EXT) || is_flag_set(f->flags, MKD_SAFEL INK) ) | |||
return 0; | return 0; | |||
} | } | |||
else if ( (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 | |||
*/ | */ | |||
return 0; | return 0; | |||
else | else | |||
tag = &linkt; | tag = &linkt; | |||
if ( f->flags & tag->flags ) | if ( f->flags & tag->flags ) | |||
return 0; | return 0; | |||
if ( 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)); | |||
if ( tag->WxH ) { | if ( tag->WxH ) { | |||
if ( ref->height ) Qprintf(f," height=\"%d\"", ref->height); | if ( ref->height ) Qprintf(f," height=\"%d\"", ref->height); | |||
if ( ref->width ) Qprintf(f, " width=\"%d\"", ref->width); | if ( ref->width ) Qprintf(f, " width=\"%d\"", ref->width); | |||
} | } | |||
if ( S(ref->title) ) { | if ( S(ref->title) ) { | |||
skipping to change at line 726 | skipping to change at line 735 | |||
if ( peek(f,1) == '[' ) { | if ( peek(f,1) == '[' ) { | |||
pull(f); /* consume leading '[' */ | pull(f); /* consume leading '[' */ | |||
goodlink = linkylabel(f, &key.tag); | goodlink = linkylabel(f, &key.tag); | |||
} | } | |||
else { | else { | |||
/* new markdown implicit name syntax doesn't | /* new markdown implicit name syntax doesn't | |||
* require a second [] | * require a second [] | |||
*/ | */ | |||
mmiotseek(f, implicit_mark); | mmiotseek(f, implicit_mark); | |||
goodlink = !(f->flags & MKD_1_COMPAT); | goodlink = !is_flag_set(f->flags, MKD_1_COMPAT); | |||
if ( (f->flags & MKD_EXTRA_FOOTNOTE) && (!image) && S(name) && T( name)[0] == '^' ) | if ( is_flag_set(f->flags, MKD_EXTRA_FOOTNOTE) && (!image) && S(n ame) && T(name)[0] == '^' ) | |||
extra_footnote = 1; | extra_footnote = 1; | |||
} | } | |||
if ( goodlink ) { | if ( goodlink ) { | |||
if ( !S(key.tag) ) { | if ( !S(key.tag) ) { | |||
DELETE(key.tag); | DELETE(key.tag); | |||
T(key.tag) = T(name); | T(key.tag) = T(name); | |||
S(key.tag) = S(name); | S(key.tag) = S(name); | |||
} | } | |||
skipping to change at line 887 | skipping to change at line 896 | |||
} /* codespan */ | } /* codespan */ | |||
/* before letting a tag through, validate against | /* before letting a tag through, validate against | |||
* MKD_NOLINKS and MKD_NOIMAGE | * MKD_NOLINKS and MKD_NOIMAGE | |||
*/ | */ | |||
static int | static int | |||
forbidden_tag(MMIOT *f) | forbidden_tag(MMIOT *f) | |||
{ | { | |||
int c = toupper(peek(f, 1)); | int c = toupper(peek(f, 1)); | |||
if ( f->flags & MKD_NOHTML ) | if ( is_flag_set(f->flags, MKD_NOHTML) ) | |||
return 1; | return 1; | |||
if ( c == 'A' && (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' && (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; | |||
return 0; | return 0; | |||
} | } | |||
/* Check a string to see if it looks like a mail address | /* Check a string to see if it looks like a mail address | |||
* "looks like a mail address" means alphanumeric + some | * "looks like a mail address" means alphanumeric + some | |||
* specials, then a `@`, then alphanumeric + some specials, | * specials, then a `@`, then alphanumeric + some specials, | |||
* but with a `.` | * but with a `.` | |||
skipping to change at line 937 | skipping to change at line 946 | |||
* plain old text. If it's a mailto: or an approved protocol, | * plain old text. If it's a mailto: or an approved protocol, | |||
* linkify it, otherwise say "no" | * linkify it, otherwise say "no" | |||
*/ | */ | |||
static int | static int | |||
process_possible_link(MMIOT *f, int size) | process_possible_link(MMIOT *f, int size) | |||
{ | { | |||
int address= 0; | int address= 0; | |||
int mailto = 0; | int mailto = 0; | |||
char *text = cursor(f); | char *text = cursor(f); | |||
if ( 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 | |||
* I to second-guess the user? | * I to second-guess the user? | |||
*/ | */ | |||
address = 1; | address = 1; | |||
mailto = 7; /* 7 is the length of "mailto:"; we need this */ | mailto = 7; /* 7 is the length of "mailto:"; we need this */ | |||
} | } | |||
else | else | |||
address = maybe_address(text, size); | address = maybe_address(text, size); | |||
skipping to change at line 983 | skipping to change at line 992 | |||
* link, we also need to know if it's an email address because if it | * link, we also need to know if it's an email address because if it | |||
* is we need to mangle it in our futile attempt to cut down on the | * is we need to mangle it in our futile attempt to cut down on the | |||
* spaminess of the rendered page. | * spaminess of the rendered page. | |||
*/ | */ | |||
static int | static int | |||
maybe_tag_or_link(MMIOT *f) | maybe_tag_or_link(MMIOT *f) | |||
{ | { | |||
int c, size; | int c, size; | |||
int maybetag = 1; | int maybetag = 1; | |||
if ( 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++) { | |||
if ( c == EOF ) | if ( c == EOF ) | |||
return 0; | return 0; | |||
else if ( c == '\\' ) { | else if ( c == '\\' ) { | |||
maybetag=0; | maybetag=0; | |||
if ( peek(f, size+2) != EOF ) | if ( peek(f, size+2) != EOF ) | |||
size++; | size++; | |||
} | } | |||
else if ( isspace(c) ) | else if ( isspace(c) ) | |||
break; | break; | |||
else if ( ! (c == '/' | else if ( ! (c == '/' | |||
|| (f->flags & MKD_GITHUBTAGS && (c == '-' || c == '_')) | || (is_flag_set(f->flags, MKD_GITHUBTAGS) && (c == '-' || c == '_')) | |||
|| isalnum(c) ) ) | || isalnum(c) ) ) | |||
maybetag=0; | maybetag=0; | |||
} | } | |||
if ( size ) { | if ( size ) { | |||
if ( maybetag || (size >= 3 && strncmp(cursor(f), "!--", 3) == 0) ) { | if ( maybetag || (size >= 3 && strncmp(cursor(f), "!--", 3) == 0) ) { | |||
/* It is not a html tag unless we find the closing '>' in | /* It is not a html tag unless we find the closing '>' in | |||
* the same block. | * the same block. | |||
*/ | */ | |||
skipping to change at line 1146 | skipping to change at line 1155 | |||
} ; | } ; | |||
#define NRSMART ( sizeof smarties / sizeof smarties[0] ) | #define NRSMART ( sizeof smarties / sizeof smarties[0] ) | |||
/* Smarty-pants-style chrome for quotes, -, ellipses, and (r)(c)(tm) | /* Smarty-pants-style chrome for quotes, -, ellipses, and (r)(c)(tm) | |||
*/ | */ | |||
static int | static int | |||
smartypants(int c, int *flags, MMIOT *f) | smartypants(int c, int *flags, MMIOT *f) | |||
{ | { | |||
int i; | int i; | |||
if ( f->flags & (MKD_NOPANTS|MKD_TAGTEXT|IS_LABEL) ) | if ( is_flag_set(f->flags, MKD_NOPANTS) | |||
|| is_flag_set(f->flags, MKD_TAGTEXT) | ||||
|| is_flag_set(f->flags, IS_LABEL) ) | ||||
return 0; | return 0; | |||
for ( i=0; i < NRSMART; i++) | for ( i=0; i < NRSMART; i++) | |||
if ( (c == smarties[i].c0) && islike(f, smarties[i].pat) ) { | if ( (c == smarties[i].c0) && islike(f, smarties[i].pat) ) { | |||
if ( smarties[i].entity ) | if ( smarties[i].entity ) | |||
Qprintf(f, "&%s;", smarties[i].entity); | Qprintf(f, "&%s;", smarties[i].entity); | |||
shift(f, smarties[i].shift); | shift(f, smarties[i].shift); | |||
return 1; | return 1; | |||
} | } | |||
skipping to change at line 1236 | skipping to change at line 1247 | |||
} | } | |||
shift(f, tick); | shift(f, tick); | |||
(*spanner)(f,size); | (*spanner)(f,size); | |||
shift(f, size+tick-1); | shift(f, size+tick-1); | |||
return 1; | return 1; | |||
} | } | |||
return 0; | return 0; | |||
} | } | |||
#define tag_text(f) (f->flags & MKD_TAGTEXT) | #define tag_text(f) is_flag_set(f->flags, MKD_TAGTEXT) | |||
static void | static void | |||
text(MMIOT *f) | text(MMIOT *f) | |||
{ | { | |||
int c, j; | int c, j; | |||
int rep; | int rep; | |||
int smartyflags = 0; | int smartyflags = 0; | |||
while (1) { | while (1) { | |||
if ( (f->flags & MKD_AUTOLINK) && isalpha(peek(f,1)) && !tag_text(f) ) | if ( is_flag_set(f->flags, MKD_AUTOLINK) && isalpha(peek(f,1)) && !tag_t ext(f) ) | |||
maybe_autolink(f); | maybe_autolink(f); | |||
c = pull(f); | c = pull(f); | |||
if (c == EOF) | if (c == EOF) | |||
break; | break; | |||
if ( smartypants(c, &smartyflags, f) ) | if ( smartypants(c, &smartyflags, f) ) | |||
continue; | continue; | |||
switch (c) { | switch (c) { | |||
skipping to change at line 1288 | skipping to change at line 1299 | |||
Qstring("![", f); | Qstring("![", f); | |||
} | } | |||
else | else | |||
Qchar(c, f); | Qchar(c, f); | |||
break; | break; | |||
case '[': if ( tag_text(f) || !linkylinky(0, f) ) | case '[': if ( tag_text(f) || !linkylinky(0, f) ) | |||
Qchar(c, f); | Qchar(c, f); | |||
break; | break; | |||
/* A^B -> A<sup>B</sup> */ | /* A^B -> A<sup>B</sup> */ | |||
case '^': if ( (f->flags & (MKD_NOSUPERSCRIPT|MKD_STRICT|MKD_TAGTEXT)) | case '^': if ( is_flag_set(f->flags, MKD_NOSUPERSCRIPT) | |||
|| (f->last == 0) | || is_flag_set(f->flags, MKD_STRICT) | |||
|| ((ispunct(f->last) || isspace(f->last)) | || is_flag_set(f->flags, MKD_TAGTEXT) | |||
&& f->last != ')') | || (f->last == 0) | |||
|| isthisspace(f,1) ) | || ((ispunct(f->last) || isspace(f->last)) | |||
&& f->last != ')') | ||||
|| isthisspace(f,1) ) | ||||
Qchar(c,f); | Qchar(c,f); | |||
else { | else { | |||
char *sup = cursor(f); | char *sup = cursor(f); | |||
int len = 0; | int len = 0; | |||
if ( peek(f,1) == '(' ) { | if ( peek(f,1) == '(' ) { | |||
int here = mmiottell(f); | int here = mmiottell(f); | |||
pull(f); | pull(f); | |||
if ( (len = parenthetical('(',')',f)) <= 0 ) { | if ( (len = parenthetical('(',')',f)) <= 0 ) { | |||
skipping to change at line 1325 | skipping to change at line 1338 | |||
} | } | |||
shift(f,len); | shift(f,len); | |||
} | } | |||
Qstring("<sup>",f); | Qstring("<sup>",f); | |||
___mkd_reparse(sup, len, 0, f, "()"); | ___mkd_reparse(sup, len, 0, 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 ( !(f->flags & (MKD_NORELAXED|MKD_STRICT)) | if ( !(is_flag_set(f->flags, MKD_NORELAXED) || is_flag_set(f- | |||
&& isthisalnum(f,-1) | >flags, MKD_STRICT)) | |||
&& isthisalnum(f,1) ) { | && isthisalnum(f,-1) && isthisalnum(f,1) ) { | |||
Qchar(c, f); | Qchar(c, f); | |||
break; | break; | |||
} | } | |||
case '*': | case '*': | |||
/* Underscores & stars don't count if they're out in the middle | /* Underscores & stars don't count if they're out in the middle | |||
* of whitespace */ | * of whitespace */ | |||
if ( isthisspace(f,-1) && isthisspace(f,1) ) { | if ( isthisspace(f,-1) && isthisspace(f,1) ) { | |||
Qchar(c, f); | Qchar(c, f); | |||
break; | break; | |||
} | } | |||
/* else fall into the regular old emphasis case */ | /* else fall into the regular old emphasis case */ | |||
if ( tag_text(f) ) | if ( tag_text(f) ) | |||
Qchar(c, f); | Qchar(c, f); | |||
else { | else { | |||
for (rep = 1; peek(f,1) == c; pull(f) ) | for (rep = 1; peek(f,1) == c; pull(f) ) | |||
++rep; | ++rep; | |||
Qem(f,c,rep); | Qem(f,c,rep); | |||
} | } | |||
break; | break; | |||
case '~': if ( (f->flags & (MKD_NOSTRIKETHROUGH|MKD_TAGTEXT|MKD_STRICT) | case '~': if ( is_flag_set(f->flags, MKD_NOSTRIKETHROUGH) | |||
) || ! tickhandler(f,c,2,0, delspan) ) | || is_flag_set(f->flags, MKD_STRICT) | |||
|| is_flag_set(f->flags, MKD_TAGTEXT) | ||||
|| ! tickhandler(f,c,2,0, delspan) ) | ||||
Qchar(c, f); | Qchar(c, f); | |||
break; | break; | |||
case '`': if ( tag_text(f) || !tickhandler(f,c,1,1,codespan) ) | case '`': if ( tag_text(f) || !tickhandler(f,c,1,1,codespan) ) | |||
Qchar(c, f); | Qchar(c, f); | |||
break; | break; | |||
case '\\': switch ( c = pull(f) ) { | case '\\': switch ( c = pull(f) ) { | |||
case '&': Qstring("&", f); | case '&': Qstring("&", f); | |||
break; | break; | |||
skipping to change at line 1370 | skipping to change at line 1385 | |||
if ( (c == EOF) || isspace(c) ) | if ( (c == EOF) || isspace(c) ) | |||
Qstring("<", f); | Qstring("<", f); | |||
else { | else { | |||
/* Markdown.pl does not escape <[nonwhite] | /* Markdown.pl does not escape <[nonwhite] | |||
* sequences */ | * sequences */ | |||
Qchar('\\', f); | Qchar('\\', f); | |||
shift(f, -1); | shift(f, -1); | |||
} | } | |||
break; | break; | |||
case '^': if ( f->flags & (MKD_STRICT|MKD_NOSUPERSCRIPT) ) | case '^': if ( is_flag_set(f->flags, MKD_STRICT) | |||
{ | || is_flag_set(f->flags, MKD_NOSUPERSCRIP | |||
T) ) { | ||||
Qchar('\\', f); | Qchar('\\', f); | |||
shift(f,-1); | shift(f,-1); | |||
break; | break; | |||
} | } | |||
Qchar(c, f); | Qchar(c, f); | |||
break; | break; | |||
case ':': case '|': | case ':': case '|': | |||
if ( f->flags & MKD_NOTABLES ) { | if ( is_flag_set(f->flags, MKD_NOTABLES) ) { | |||
Qchar('\\', f); | Qchar('\\', f); | |||
shift(f,-1); | shift(f,-1); | |||
break; | break; | |||
} | } | |||
Qchar(c, f); | Qchar(c, f); | |||
break; | break; | |||
case EOF: Qchar('\\', f); | case EOF: Qchar('\\', f); | |||
break; | break; | |||
case '[': | case '[': | |||
case '(': if ( (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 */ | |||
default: if ( escaped(f,c) || | default: if ( escaped(f,c) || | |||
strchr(">#.-+{}]![*_\\()`", c) ) | strchr(">#.-+{}]![*_\\()`", c) ) | |||
Qchar(c, f); | Qchar(c, f); | |||
else { | else { | |||
Qchar('\\', f); | Qchar('\\', f); | |||
shift(f, -1); | shift(f, -1); | |||
skipping to change at line 1421 | skipping to change at line 1437 | |||
case '&': j = (peek(f,1) == '#' ) ? 2 : 1; | case '&': j = (peek(f,1) == '#' ) ? 2 : 1; | |||
while ( isthisalnum(f,j) ) | while ( isthisalnum(f,j) ) | |||
++j; | ++j; | |||
if ( peek(f,j) != ';' ) | if ( peek(f,j) != ';' ) | |||
Qstring("&", f); | Qstring("&", f); | |||
else | else | |||
Qchar(c, f); | Qchar(c, f); | |||
break; | break; | |||
case '$': if ( (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; | |||
Qchar('$', f); | Qchar('$', f); | |||
} | } | |||
/* fall through to default */ | /* fall through to default */ | |||
default: f->last = c; | default: f->last = c; | |||
Qchar(c, f); | Qchar(c, f); | |||
break; | break; | |||
skipping to change at line 1443 | skipping to change at line 1459 | |||
} | } | |||
/* truncate the input string after we've finished processing it */ | /* truncate the input string after we've finished processing it */ | |||
S(f->in) = f->isp = 0; | S(f->in) = f->isp = 0; | |||
} /* text */ | } /* text */ | |||
/* print a header block | /* print a header block | |||
*/ | */ | |||
static void | static void | |||
printheader(Paragraph *pp, MMIOT *f) | printheader(Paragraph *pp, MMIOT *f) | |||
{ | { | |||
if ( 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 ( f->flags & MKD_TOC ) { | if ( is_flag_set(f->flags, MKD_TOC) ) { | |||
Qstring(" id=\"", f); | Qstring(" id=\"", f); | |||
mkd_string_to_anchor(T(pp->text->text), | Qanchor(pp->text, f); | |||
S(pp->text->text), | ||||
(mkd_sta_function_t)Qchar, f, 1, f->flags); | ||||
Qchar('"', f); | Qchar('"', f); | |||
} | } | |||
Qchar('>', f); | Qchar('>', f); | |||
} else { | } else { | |||
if ( f->flags & MKD_TOC ) { | if ( is_flag_set(f->flags, MKD_TOC) ) { | |||
Qstring("<a name=\"", f); | Qstring("<a name=\"", f); | |||
mkd_string_to_anchor(T(pp->text->text), | Qanchor(pp->text, f); | |||
S(pp->text->text), | ||||
(mkd_sta_function_t)Qchar, f, 1, f->flags); | ||||
Qstring("\"></a>\n", f); | Qstring("\"></a>\n", f); | |||
} | } | |||
Qprintf(f, "<h%d>", pp->hnumber); | Qprintf(f, "<h%d>", pp->hnumber); | |||
} | } | |||
push(T(pp->text->text), S(pp->text->text), f); | push(T(pp->text->text), S(pp->text->text), f); | |||
text(f); | text(f); | |||
Qprintf(f, "</h%d>", pp->hnumber); | Qprintf(f, "</h%d>", pp->hnumber); | |||
} | } | |||
enum e_alignments { a_NONE, a_CENTER, a_LEFT, a_RIGHT }; | enum e_alignments { a_NONE, a_CENTER, a_LEFT, a_RIGHT }; | |||
skipping to change at line 1621 | skipping to change at line 1633 | |||
text(f); | text(f); | |||
Qstring(End[align], f); | Qstring(End[align], f); | |||
return 1; | return 1; | |||
} | } | |||
static void | static void | |||
printcode(Line *t, char *lang, MMIOT *f) | printcode(Line *t, char *lang, MMIOT *f) | |||
{ | { | |||
int blanks; | int blanks; | |||
if ( f->cb->e_codefmt ) { | ||||
/* external code block formatter; copy the text into a buffer, | ||||
* call the formatter to style it, then dump that styled text | ||||
* directly to the queue | ||||
*/ | ||||
char *text; | ||||
char *fmt; | ||||
int size, copy_p; | ||||
Line *p; | ||||
for (size=0, p = t; p; p = p->next ) | ||||
size += 1+S(p->text); | ||||
text = malloc(1+size); | ||||
for ( copy_p = 0; t ; t = t->next ) { | ||||
memcpy(text+copy_p, T(t->text), S(t->text)); | ||||
copy_p += S(t->text); | ||||
text[copy_p++] = '\n'; | ||||
} | ||||
text[copy_p] = 0; | ||||
fmt = (*(f->cb->e_codefmt))(text, copy_p, (lang && lang[0]) ? lang : 0); | ||||
free(text); | ||||
if ( fmt ) { | ||||
Qwrite(fmt, strlen(fmt), f); | ||||
if ( f->cb->e_free ) | ||||
(*(f->cb->e_free))(fmt, f->cb->e_data); | ||||
return; | ||||
} | ||||
/* otherwise the external formatter failed and we need to | ||||
* fall back to the traditional codeblock format | ||||
*/ | ||||
} | ||||
Qstring("<pre><code", f); | Qstring("<pre><code", f); | |||
if (lang) { | if (lang && lang[0]) { | |||
Qstring(" class=\"", f); | Qstring(" class=\"", f); | |||
Qstring(lang, f); | Qstring(lang, f); | |||
Qstring("\"", f); | Qstring("\"", f); | |||
} | } | |||
Qstring(">", f); | Qstring(">", f); | |||
for ( blanks = 0; t ; t = t->next ) { | for ( blanks = 0; t ; t = t->next ) { | |||
if ( S(t->text) > t->dle ) { | if ( S(t->text) > t->dle ) { | |||
while ( blanks ) { | while ( blanks ) { | |||
Qchar('\n', f); | Qchar('\n', f); | |||
--blanks; | --blanks; | |||
skipping to change at line 1672 | skipping to change at line 1720 | |||
___mkd_emblock(f); | ___mkd_emblock(f); | |||
while (( p = display(p, f) )) { | while (( p = display(p, f) )) { | |||
___mkd_emblock(f); | ___mkd_emblock(f); | |||
Qstring("\n\n", f); | Qstring("\n\n", f); | |||
} | } | |||
} | } | |||
#ifdef GITHUB_CHECKBOX | #ifdef GITHUB_CHECKBOX | |||
static void | static void | |||
li_htmlify(Paragraph *p, char *arguments, int flags, MMIOT *f) | li_htmlify(Paragraph *p, char *arguments, mkd_flag_t flags, MMIOT *f) | |||
{ | { | |||
___mkd_emblock(f); | ___mkd_emblock(f); | |||
Qprintf(f, "<li"); | Qprintf(f, "<li"); | |||
if ( arguments ) | if ( arguments ) | |||
Qprintf(f, " %s", arguments); | Qprintf(f, " %s", arguments); | |||
if ( flags & GITHUB_CHECK ) | if ( flags & GITHUB_CHECK ) | |||
Qprintf(f, " class=\"github_checkbox\""); | Qprintf(f, " class=\"github_checkbox\""); | |||
Qprintf(f, ">"); | Qprintf(f, ">"); | |||
#if CHECKBOX_AS_INPUT | #if CHECKBOX_AS_INPUT | |||
skipping to change at line 1857 | skipping to change at line 1905 | |||
* document. | * document. | |||
*/ | */ | |||
int | int | |||
mkd_document(Document *p, char **res) | mkd_document(Document *p, char **res) | |||
{ | { | |||
int size; | int size; | |||
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 ( 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); | |||
if ( (size == 0) || T(p->ctx->out)[size-1] ) { | if ( (size == 0) || T(p->ctx->out)[size-1] ) { | |||
/* Add a null byte at the end of the generated html, | /* Add a null byte at the end of the generated html, | |||
* but pretend it doesn't exist. | * but pretend it doesn't exist. | |||
*/ | */ | |||
EXPAND(p->ctx->out) = 0; | EXPAND(p->ctx->out) = 0; | |||
--S(p->ctx->out); | --S(p->ctx->out); | |||
End of changes. 35 change blocks. | ||||
45 lines changed or deleted | 93 lines changed or added |