ext/generate.c in pixeltrix-rdiscount-1.2.11 vs ext/generate.c in pixeltrix-rdiscount-1.3.4
- old
+ new
@@ -24,10 +24,11 @@
typedef int (*stfu)(const void*,const void*);
/* forward declarations */
+static int iscodeblock(MMIOT*);
static void code(int, MMIOT*);
static void text(MMIOT *f);
static Paragraph *display(Paragraph*, MMIOT*);
/* externals from markdown.c */
@@ -72,10 +73,35 @@
{
return T(f->in) + f->isp;
}
+static int
+isthisspace(MMIOT *f, int i)
+{
+ int c = peek(f, i);
+
+ return isspace(c) || (c == EOF);
+}
+
+
+static int
+isthisalnum(MMIOT *f, int i)
+{
+ int c = peek(f, i);
+
+ return (c != EOF) && isalnum(c);
+}
+
+
+static int
+isthisnonword(MMIOT *f, int i)
+{
+ return isthisspace(f, i) || ispunct(peek(f,i));
+}
+
+
/* return/set the current cursor position
*/
#define mmiotseek(f,x) (f->isp = x)
#define mmiottell(f) (f->isp)
@@ -249,14 +275,14 @@
start->b_count -= match;
}
}
-/* emblock()
+/* ___mkd_emblock()
*/
-static void
-emblock(MMIOT *f)
+void
+___mkd_emblock(MMIOT *f)
{
int i;
block *p;
for (i=0; i < S(f->Q); i++) {
@@ -273,12 +299,12 @@
}
/* generate html from a markup fragment
*/
-static void
-reparse(char *bfr, int size, int flags, MMIOT *f)
+void
+___mkd_reparse(char *bfr, int size, int flags, MMIOT *f)
{
MMIOT sub;
___mkd_initmmiot(&sub, f->footnotes);
@@ -288,11 +314,11 @@
push(bfr, size, &sub);
EXPAND(sub.in) = 0;
S(sub.in)--;
text(&sub);
- emblock(&sub);
+ ___mkd_emblock(&sub);
Qwrite(T(sub.out), S(sub.out), f);
___mkd_freemmiot(&sub, f->footnotes);
}
@@ -311,10 +337,12 @@
if ( c == '&' )
Qstring("&", f);
else if ( c == '<' )
Qstring("<", f);
+ else if ( isalnum(c) || ispunct(c) )
+ Qchar(c, f);
else
Qchar(c, f);
}
}
@@ -467,16 +495,18 @@
static int
linkykey(int image, Footnote *val, MMIOT *f)
{
Footnote *ret;
Cstring mylabel;
+ int here;
memset(val, 0, sizeof *val);
if ( (T(val->tag) = linkylabel(f, &S(val->tag))) == 0 )
return 0;
+ here = mmiottell(f);
eatspace(f);
switch ( pull(f) ) {
case '(':
/* embedded link */
if ( (T(val->link) = linkyurl(f,&S(val->link))) == 0 )
@@ -487,18 +517,25 @@
T(val->title) = linkytitle(f, &S(val->title));
return peek(f,0) == ')';
- case '[':
+ case '[': /* footnote links /as defined in the standard/ */
+ default: /* footnote links -- undocumented extension */
/* footnote link */
mylabel = val->tag;
- if ( (T(val->tag) = linkylabel(f, &S(val->tag))) == 0 )
- return 0;
+ if ( peek(f,0) == '[' ) {
+ if ( (T(val->tag) = linkylabel(f, &S(val->tag))) == 0 )
+ return 0;
- if ( !S(val->tag) )
- val->tag = mylabel;
+ if ( !S(val->tag) )
+ val->tag = mylabel;
+ }
+ else if ( f->flags & MKD_1_COMPAT )
+ break;
+ else
+ mmiotseek(f,here);
ret = bsearch(val, T(*f->footnotes), S(*f->footnotes),
sizeof *val, (stfu)__mkd_footsort);
if ( ret ) {
@@ -574,11 +611,11 @@
{
int start = mmiottell(f);
Footnote link;
linkytype *tag;
- if ( !(linkykey(image, &link, f) && S(link.tag)) ) {
+ if ( !linkykey(image, &link, f) ) {
mmiotseek(f, start);
return 0;
}
if ( image )
@@ -603,16 +640,16 @@
Qprintf(f, " width=\"%d\"", link.width);
}
if ( S(link.title) ) {
Qstring(" title=\"", f);
- reparse(T(link.title), S(link.title), INSIDE_TAG, f);
+ ___mkd_reparse(T(link.title), S(link.title), INSIDE_TAG, f);
Qchar('"', f);
}
Qstring(tag->text_pfx, f);
- reparse(T(link.tag), S(link.tag), tag->flags, f);
+ ___mkd_reparse(T(link.tag), S(link.tag), tag->flags, f);
Qstring(tag->text_sfx, f);
}
else
Qwrite(T(link.link) + tag->szpat, S(link.link) - tag->szpat, f);
@@ -657,15 +694,15 @@
int c = toupper(peek(f, 1));
if ( f->flags & DENY_HTML )
return 1;
- if ( c == 'A' && (f->flags & DENY_A) && !isalnum(peek(f,2)) )
+ if ( c == 'A' && (f->flags & DENY_A) && !isthisalnum(f,2) )
return 1;
if ( c == 'I' && (f->flags & DENY_IMG)
&& strncasecmp(cursor(f)+1, "MG", 2) == 0
- && !isalnum(peek(f,4)) )
+ && !isthisalnum(f,4) )
return 1;
return 0;
}
@@ -741,26 +778,10 @@
shift(f, -(size+1));
return 0;
} /* maybe_tag_or_link */
-static int
-isthisspace(MMIOT *f, int i)
-{
- int c = peek(f, i);
-
- return isspace(c) || (c == EOF);
-}
-
-
-static int
-isthisnonword(MMIOT *f, int i)
-{
- return isthisspace(f, i) || ispunct(peek(f,i));
-}
-
-
/* smartyquote code that's common for single and double quotes
*/
static int
smartyquote(int *flags, char typeofquote, MMIOT *f)
{
@@ -871,11 +892,11 @@
j += 2;
else if ( c == '`' )
break;
else if ( c == '\'' && peek(f, j+1) == '\'' ) {
Qstring("“", f);
- reparse(cursor(f)+1, j-2, 0, f);
+ ___mkd_reparse(cursor(f)+1, j-2, 0, f);
Qstring("”", f);
shift(f,j+1);
return 1;
}
else ++j;
@@ -926,32 +947,32 @@
break;
case '[': if ( tag_text(f) || !linkylinky(0, f) )
Qchar(c, f);
break;
#if SUPERSCRIPT
- case '^': if ( isthisspace(f,-1) || isthisspace(f,1) )
+ /* A^B -> A<sup>B</sup> */
+ case '^': if ( (f->flags & (STRICT|INSIDE_TAG)) || isthisspace(f,-1) || isthisspace(f,1) )
Qchar(c,f);
else {
char *sup = cursor(f);
int len = 0;
Qstring("<sup>",f);
while ( !isthisspace(f,1+len) ) {
++len;
}
shift(f,len);
- reparse(sup, len, 0, f);
+ ___mkd_reparse(sup, len, 0, f);
Qstring("</sup>", f);
}
break;
#endif
case '_':
#if RELAXED_EMPHASIS
- /* If RELAXED_EMPHASIS, underscores don't count when
- * they're in the middle of a word.
- */
- if ( (isthisspace(f,-1) && isthisspace(f,1))
- || (isalnum(peek(f,-1)) && isalnum(peek(f,1))) ) {
+ /* Underscores don't count if they're in the middle of a word */
+ if ( (!(f->flags & STRICT))
+ && ((isthisspace(f,-1) && isthisspace(f,1))
+ || (isthisalnum(f,-1) && isthisalnum(f,1))) ){
Qchar(c, f);
break;
}
/* else fall into the regular old emphasis case */
#endif
@@ -962,11 +983,11 @@
++rep;
Qem(f,c,rep);
}
break;
- case '`': if ( tag_text(f) )
+ case '`': if ( tag_text(f) || !iscodeblock(f) )
Qchar(c, f);
else {
Qstring("<code>", f);
if ( peek(f, 1) == '`' ) {
pull(f);
@@ -1001,11 +1022,11 @@
case '<': if ( !maybe_tag_or_link(f) )
Qstring("<", f);
break;
case '&': j = (peek(f,1) == '#' ) ? 2 : 1;
- while ( isalnum(peek(f,j)) )
+ while ( isthisalnum(f,j) )
++j;
if ( peek(f,j) != ';' )
Qstring("&", f);
else
@@ -1014,14 +1035,36 @@
default: Qchar(c, f);
break;
}
}
+ /* truncate the input string after we've finished processing it */
+ S(f->in) = f->isp = 0;
} /* text */
static int
+iscodeblock(MMIOT *f)
+{
+ int i=1, single = 1, c;
+
+ if ( peek(f,i) == '`' ) {
+ single=0;
+ i++;
+ }
+ while ( (c=peek(f,i)) != EOF ) {
+ if ( (c == '`') && (single || peek(f,i+1) == '`') )
+ return 1;
+ else if ( c == '\\' )
+ i++;
+ i++;
+ }
+ return 0;
+
+}
+
+static int
endofcode(int escape, int offset, MMIOT *f)
{
switch (escape) {
case 2: if ( peek(f, offset+1) == '`' ) {
shift(f,1);
@@ -1070,11 +1113,17 @@
/* print a header block
*/
static void
printheader(Paragraph *pp, MMIOT *f)
{
- Qprintf(f, "<h%d>", pp->hnumber);
+ Qprintf(f, "<h%d", pp->hnumber);
+ if ( f->flags & TOC ) {
+ Qprintf(f, " id=\"", pp->hnumber);
+ mkd_string_to_anchor(T(pp->text->text), S(pp->text->text), Qchar, f);
+ Qchar('"', f);
+ }
+ Qchar('>', f);
push(T(pp->text->text), S(pp->text->text), f);
text(f);
Qprintf(f, "</h%d>", pp->hnumber);
}
@@ -1092,10 +1141,11 @@
&& T(t->text)[S(t->text)-1] == ' ') {
push(T(t->text), S(t->text)-2, f);
push("<br/>\n", 6, f);
}
else {
+ ___mkd_tidy(t);
push(T(t->text), S(t->text), f);
if ( t->next )
push("\n", 1, f);
}
}
@@ -1147,23 +1197,25 @@
blanks++;
}
static void
-htmlify(Paragraph *p, char *block, MMIOT *f)
+htmlify(Paragraph *p, char *block, char *arguments, MMIOT *f)
{
- emblock(f);
- if ( block ) Qprintf(f, "<%s>", block);
- emblock(f);
+ ___mkd_emblock(f);
+ if ( block )
+ Qprintf(f, arguments ? "<%s %s>" : "<%s>", block, arguments);
+ ___mkd_emblock(f);
while (( p = display(p, f) )) {
- emblock(f);
+ ___mkd_emblock(f);
Qstring("\n\n", f);
}
- if ( block ) Qprintf(f, "</%s>", block);
- emblock(f);
+ if ( block )
+ Qprintf(f, "</%s>", block);
+ ___mkd_emblock(f);
}
#if DL_TAG_EXTENSION
static void
@@ -1175,15 +1227,15 @@
Qstring("<dl>\n", f);
for ( ; p ; p = p->next) {
for ( tag = p->text; tag; tag = tag->next ) {
Qstring("<dt>", f);
- reparse(T(tag->text), S(tag->text), 0, f);
+ ___mkd_reparse(T(tag->text), S(tag->text), 0, f);
Qstring("</dt>\n", f);
}
- htmlify(p->down, "dd", f);
+ htmlify(p->down, "dd", p->ident, f);
}
Qstring("</dl>", f);
}
}
@@ -1192,14 +1244,17 @@
static void
listdisplay(int typ, Paragraph *p, MMIOT* f)
{
if ( p ) {
- Qprintf(f, "<%cl>\n", (typ==UL)?'u':'o');
+ Qprintf(f, "<%cl", (typ==UL)?'u':'o');
+ if ( typ == AL )
+ Qprintf(f, " type=a");
+ Qprintf(f, ">\n");
for ( ; p ; p = p->next ) {
- htmlify(p->down, "li", f);
+ htmlify(p->down, "li", p->ident, f);
Qchar('\n', f);
}
Qprintf(f, "</%cl>\n", (typ==UL)?'u':'o');
}
@@ -1225,15 +1280,16 @@
case CODE:
printcode(p->text, f);
break;
case QUOTE:
- htmlify(p->down, "blockquote", f);
+ htmlify(p->down, p->ident ? "div" : "blockquote", p->ident, f);
break;
case UL:
case OL:
+ case AL:
listdisplay(p->typ, p->down, f);
break;
#if DL_TAG_EXTENSION
case DL:
@@ -1286,32 +1342,32 @@
int
mkd_document(Document *p, char **res)
{
if ( p && p->compiled ) {
if ( ! p->html ) {
- htmlify(p->code, 0, p->ctx);
+ htmlify(p->code, 0, 0, p->ctx);
p->html = 1;
}
*res = T(p->ctx->out);
return S(p->ctx->out);
}
return EOF;
}
-/* public interface for reparse()
+/* public interface for ___mkd_reparse()
*/
int
mkd_text(char *bfr, int size, FILE *output, int flags)
{
MMIOT f;
___mkd_initmmiot(&f, 0);
f.flags = flags & USER_FLAGS;
- reparse(bfr, size, 0, &f);
- emblock(&f);
+ ___mkd_reparse(bfr, size, 0, &f);
+ ___mkd_emblock(&f);
if ( flags & CDATA_OUTPUT )
___mkd_xml(T(f.out), S(f.out), output);
else
fwrite(T(f.out), S(f.out), 1, output);