add an external code block formatter to the markdown program

This commit is contained in:
david parsons
2019-04-12 08:25:02 -07:00
parent 866e9aaccb
commit 5bf1c6cfae
2 changed files with 59 additions and 7 deletions
+58 -6
View File
@@ -76,11 +76,11 @@ anchor_format(char *input, void *ctx)
if ( !ret )
return NULL;
while ( size && isspace(input[size-1]) )
--size;
for ( j=i=0; i < size; i++ ) {
if (isalnum(input[i]) || strchr("-_+", input[i]) )
ret[j++] = input[i];
@@ -88,7 +88,7 @@ anchor_format(char *input, void *ctx)
ret[j++] = '-';
}
ret[j++] = 0;
return ret;
}
@@ -99,6 +99,49 @@ free_it(char *object, void *ctx)
free(object);
}
char *
external_codefmt(char *src, int len, char *lang)
{
int extra = 0;
int i, x;
char *res;
if ( lang == 0 )
lang = "generic_code";
for ( i=0; i < len; i++) {
if ( src[i] == '&' )
extra += 5;
else if ( src[i] == '<' || src[i] == '>' )
extra += 4;
}
/* 80 characters for the format wrappers */
if ( (res = malloc(len+extra+80+strlen(lang))) ==0 )
/* out of memory? drat! */
return 0;
sprintf(res, "<pre><code class=\"%s\">\n", lang);
x = strlen(res);
for ( i=0; i < len; i++ ) {
switch (src[i]) {
case '&': strcpy(&src[x], "&amp;");
x += 5 /*strlen(&amp;)*/ ;
break;
case '<': strcpy(&src[x], "&lt;");
x += 4 /*strlen(&lt;)*/ ;
break;
case '>': strcpy(&src[x], "&gt;");
x += 4 /*strlen(&gt;)*/ ;
break;
default: res[x++] = src[i];
break;
}
}
strcpy(&res[x], "</code></pre>\n");
return res;
}
struct h_opt opts[] = {
{ 0, "html5", '5', 0, "recognise html5 block elements" },
@@ -115,8 +158,9 @@ struct h_opt opts[] = {
{ 0, 0, 't', "text", "format `text` with mkd_line()" },
{ 0, "toc", 'T', 0, "output a TOC" },
{ 0, 0, 'C', "prefix", "prefix for markdown extra footnotes" },
{ 0, 0, 'o', "file", "write output to file" },
{ 0, 0, 'o', "file", "write output to file" },
{ 0, "squash", 'x', 0, "squash toc labels to be more like github" },
{ 0, "codefmt",'X', 0, "use an external code formatter" },
};
#define NROPTS (sizeof opts/sizeof opts[0])
@@ -132,6 +176,7 @@ main(int argc, char **argv)
int with_html5 = 0;
int styles = 0;
int use_mkd_line = 0;
int use_e_codefmt = 0;
int github_flavoured = 0;
int squash = 0;
char *extra_footnote_prefix = 0;
@@ -209,6 +254,9 @@ main(int argc, char **argv)
break;
case 'x': squash = 1;
break;
case 'X': use_e_codefmt = 1;
set_flag(&flags, "fencedcode");
break;
}
}
@@ -257,10 +305,14 @@ main(int argc, char **argv)
mkd_e_data(doc, urlflags);
mkd_e_flags(doc, e_flags);
}
if ( squash ) {
if ( squash )
mkd_e_anchor(doc, (mkd_callback_t) anchor_format);
if ( use_e_codefmt )
mkd_e_code_format(doc, external_codefmt);
if ( use_e_codefmt || squash )
mkd_e_free(doc, free_it);
}
if ( extra_footnote_prefix )
mkd_ref_prefix(doc, extra_footnote_prefix);
+1 -1
View File
@@ -68,7 +68,7 @@ typedef void (*mkd_free_t)(char*, void*);
void mkd_e_url(void *, mkd_callback_t);
void mkd_e_flags(void *, mkd_callback_t);
void mkd_e_anchor(void *, mkd_callback_t);
void mkd_e_codefmt(void*, mkd_callback_t);
void mkd_e_code_format(void*, mkd_callback_t);
void mkd_e_free(void *, mkd_free_t );
void mkd_e_data(void *, void *);