/* markdown: a C implementation of John Gruber's Markdown markup language. * * Copyright (C) 2007-2011 Jessica L Parsons. * The redistribution terms are provided in the COPYRIGHT file that must * be distributed with this source code. */ #include #include #include #include #include #include #include "config.h" #include "markdown.h" #include "amalloc.h" #if HAVE_LIBGEN_H #include #endif static void set_dlist(mkd_flag_t *flags, int enable); static struct _special { char *name; void (*setter)(mkd_flag_t *, int); } special[] = { { "definitionlist", set_dlist }, { "dlist", set_dlist }, }; static struct _opt { char *name; char *desc; int special; int off; int alias; /* this opt is a synonym; don't display in -F? */ int sayenable; int flag; /* flag to set/clear */ int unflag; /* flag to clear/set */ } opts[] = { { "tabstop", "default (4-space) tabstops", 0, 0, 0, 1, MKD_TABSTOP }, { "image", "images", 0, 1, 0, 1, MKD_NOIMAGE }, { "links", "links", 0, 1, 0, 1, MKD_NOLINKS }, { "strict", "conform to the markdown standard", 0, 0, 0, 1, MKD_STRICT }, { "relax", "(don't) conform to the markdown standard", 0, 1, 1, 1, MKD_STRICT }, { "standard", "conform to the markdown standard", 0, 0, 1, 1, MKD_STRICT }, { "tables", "tables", 0, 1, 0, 1, MKD_NOTABLES }, { "header", "pandoc-style headers", 0, 1, 0, 1, MKD_NOHEADER }, { "html", "allow raw html", 0, 1, 0, 0, MKD_NOHTML }, { "ext", "extended protocols", 0, 1, 0, 1, MKD_NO_EXT }, { "cdata", "generate cdata", 0, 0, 0, 0, MKD_CDATA }, { "smarty", "smartypants", 0, 1, 0, 1, MKD_NOPANTS }, { "pants", "smartypants", 0, 1, 1, 1, MKD_NOPANTS }, { "toc", "tables of contents", 0, 0, 0, 1, MKD_TOC }, { "autolink", "autolinking", 0, 0, 0, 1, MKD_AUTOLINK }, { "safelink", "safe links", 0, 0, 0, 1, MKD_SAFELINK }, { "strikethrough", "strikethrough", 0, 1, 0, 1, MKD_NOSTRIKETHROUGH }, { "del", "strikethrough", 0, 1, 1, 1, MKD_NOSTRIKETHROUGH }, { "superscript", "superscript", 0, 1, 0, 1, MKD_NOSUPERSCRIPT }, { "divquote", ">%class% blockquotes", 0, 1, 0, 1, MKD_NODIVQUOTE }, { "alphalist", "alpha lists", 0, 1, 0, 1, MKD_NOALPHALIST }, { "1.0", "markdown 1.0 compatibility", 0, 0, 0, 1, MKD_1_COMPAT }, { "footnotes", "markdown extra footnotes", 0, 0, 0, 1, MKD_EXTRA_FOOTNOTE }, { "footnote", "markdown extra footnotes", 0, 0, 1, 1, MKD_EXTRA_FOOTNOTE }, { "style", "extract style blocks", 0, 1, 0, 1, MKD_NOSTYLE }, { "dldiscount", "discount-style definition lists", 0, 0, 0, 1, MKD_DLDISCOUNT }, { "dlextra", "markdown extra-style definition lists", 0, 0, 0, 1, MKD_DLEXTRA }, { "fencedcode", "fenced code blocks", 0, 0, 0, 1, MKD_FENCEDCODE }, { "idanchor", "id= anchors in TOC", 0, 0, 0, 1, MKD_IDANCHOR }, { "githubtags", "- and _ in element names", 0, 0, 0, 1, MKD_GITHUBTAGS }, { "urlencodedanchor", "html5-style anchors", 0, 0, 0, 1, MKD_URLENCODEDANCHOR }, { "html5anchor", "html5-style anchors", 0, 0, 1, 1, MKD_URLENCODEDANCHOR }, { "latex", "LaTeX escapes", 0, 0, 0, 1, MKD_LATEX }, { "explicitlist", "merge adjacent numeric/bullet lists", 0, 0, 0, 0, MKD_EXPLICITLIST }, { "github-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 } , { "definitionlist","both discount & markdown extra definition lists", 1 }, { "dlist", "both discount & markdown extra definition lists", 1, 0, 1 }, { "alt_as_title", "use the alt text as a title if there isn't one (images)", 0, 0, 0, 1, MKD_ALT_AS_TITLE }, { "extended_attr", "allow extended attributes on links", 0, 0, 1, 1, MKD_EXTENDED_ATTR }, { "extended_attributes", "allow extended attributes on links", 0, 0, 0, 1, MKD_EXTENDED_ATTR }, { "html5", "handle html5 tags (obsolete?)", 0, 0, 0, 1, MKD_HTML5 }, } ; #define NR(x) (sizeof x / sizeof x[0]) typedef int (*stfu)(const void *, const void *); int sort_by_name(struct _opt *a, struct _opt *b) { return strcmp(a->name,b->name); } int sort_by_flag(struct _opt *a, struct _opt *b) { return a->flag - b->flag; } void show_flags(int byname, int verbose, mkd_flag_t *flags) { int i; if ( byname ) { int size, len=0; qsort(opts, NR(opts), sizeof(opts[0]), (stfu)sort_by_name); for (i=0; i < NR(opts); i++) if ( (size=strlen(opts[i].name)) > len ) len = size; for (i=0; i < NR(opts); i++) { if ( opts[i].alias && !verbose ) continue; if ( (flags==0) || is_flag_set(flags, opts[i].flag) ) fprintf(stderr, "%*s : %s\n", len+1, opts[i].name, opts[i].desc); } } else { qsort(opts, NR(opts), sizeof(opts[0]), (stfu)sort_by_flag); for (i=0; i < NR(opts) && i < 8*sizeof(DWORD); i++) { if ( opts[i].special || opts[i].alias ) continue; if ( (flags==0) || is_flag_set(flags, opts[i].flag) ) { fprintf(stderr, "%08lx : ", 1L<