/* extract a =HHHxWWW size from the input stream */ static int linkysize(MMIOT *f, Footnote *ref) { int height=0, width=0; int whence = mmiottell(f); int c; if ( isspace(peek(f,0)) ) { pull(f); /* eat '=' */ for ( c = pull(f); isdigit(c); c = pull(f)) width = (width * 10) + (c - '0'); if ( c == 'x' ) { for ( c = pull(f); isdigit(c); c = pull(f)) height = (height*10) + (c - '0'); if ( isspace(c) ) c = eatspace(f); if ( (c == ')') || ((c == '\'' || c == '"') && linkytitle(f, c, ref)) ) { ref->height = height; ref->width = width; return 1; } } } mmiotseek(f, whence); return 0; }
/* look up (or construct) a footnote from the [xxx] link * at the head of the stream. */ static int linkykey(int image, Footnote *val, MMIOT *f) { Footnote *ret; Cstring mylabel; memset(val, 0, sizeof *val); if ( (T(val->tag) = linkylabel(f, &S(val->tag))) == 0 ) return 0; eatspace(f); switch ( pull(f) ) { case '(': /* embedded link */ if ( (T(val->link) = linkyurl(f,&S(val->link))) == 0 ) return 0; if ( image && !linkysize(f, &val->height, &val->width) ) return 0; T(val->title) = linkytitle(f, &S(val->title)); return peek(f,0) == ')'; case '[': /* footnote link */ mylabel = val->tag; if ( (T(val->tag) = linkylabel(f, &S(val->tag))) == 0 ) return 0; if ( !S(val->tag) ) val->tag = mylabel; ret = bsearch(val, T(*f->footnotes), S(*f->footnotes), sizeof *val, (stfu)__mkd_footsort); if ( ret ) { val->tag = mylabel; val->link = ret->link; val->title = ret->title; val->height = ret->height; val->width = ret->width; return 1; } } return 0; }
/* extract a (-prefixed url from the input stream. * the label is either of the format `<link>`, where I * extract until I find a >, or it is of the format * `text`, where I extract until I reach a ')', a quote, * or (if image) a '=' */ static int linkyurl(MMIOT *f, int image, Footnote *p) { int c; int mayneedtotrim=0; if ( (c = eatspace(f)) == EOF ) return 0; if ( c == '<' ) { pull(f); if ( !(f->flags & MKD_1_COMPAT) ) return linkybroket(f,image,p); mayneedtotrim=1; } T(p->link) = cursor(f); for ( S(p->link)=0; (c = peek(f,1)) != ')'; ++S(p->link) ) { if ( c == EOF ) return 0; else if ( (c == '"' || c == '\'') && linkytitle(f, c, p) ) break; else if ( image && (c == '=') && linkysize(f, p) ) break; else if ( (c == '\\') && ispunct(peek(f,2)) ) { ++S(p->link); pull(f); } pull(f); } if ( peek(f, 1) == ')' ) pull(f); ___mkd_tidy(&p->link); if ( mayneedtotrim && (T(p->link)[S(p->link)-1] == '>') ) --S(p->link); return 1; }
/* extract a <...>-encased url from the input stream. * (markdown 1.0.2b8 compatibility; older versions * of markdown treated the < and > as syntactic * sugar that didn't have to be there. 1.0.2b8 * requires a closing >, and then falls into the * title or closing ) */ static int linkybroket(MMIOT *f, int image, Footnote *p) { int c; int good = 0; T(p->link) = cursor(f); for ( S(p->link)=0; (c = pull(f)) != '>'; ++S(p->link) ) { /* pull in all input until a '>' is found, or die trying. */ if ( c == EOF ) return 0; else if ( (c == '\\') && ispunct(peek(f,2)) ) { ++S(p->link); pull(f); } } c = eatspace(f); /* next nonspace needs to be a title, a size, or ) */ if ( ( c == '\'' || c == '"' ) && linkytitle(f,c,p) ) good=1; else if ( image && (c == '=') && linkysize(f,p) ) good=1; else good=( c == ')' ); if ( good ) { if ( peek(f, 1) == ')' ) pull(f); ___mkd_tidy(&p->link); } return good; } /* linkybroket */