From 8ddfb981eff89b4e76d71e7203af5d0975b63eda Mon Sep 17 00:00:00 2001 From: jessica parsons Date: Wed, 3 Sep 2025 17:26:21 -0700 Subject: [PATCH] redo the html5 flag option to make it a per-MMIOT thing, instead of being a global block that we have to deallocate when we're done; also take the opportunity to clean up mkd_initmmiot to have it set fags & html5 extraflags instead of duplicating that code in three places --- Csio.c | 3 ++- flags.c | 1 + generate.c | 10 ++++---- html5.c | 23 +++++++----------- main.c | 10 ++------ markdown.c | 21 +++++++---------- markdown.h | 19 ++++++++++++--- mkdio.c | 7 ++---- mktags.c | 1 + pgm_options.c | 1 + resource.c | 13 ++++++++++- setup.c | 8 ------- tags.c | 65 ++++++++++++++++++++++++++++++++++++--------------- tags.h | 17 +++++--------- 14 files changed, 112 insertions(+), 87 deletions(-) diff --git a/Csio.c b/Csio.c index 71dd9bb..112fd17 100644 --- a/Csio.c +++ b/Csio.c @@ -53,7 +53,8 @@ void Csreparse(Cstring *iot, char *buf, int size, mkd_flag_t* flags) { MMIOT f; - ___mkd_initmmiot(&f, 0); + ___mkd_initmmiot(&f, 0, flags); + ___mkd_reparse(buf, size, flags, &f, 0); ___mkd_emblock(&f); SUFFIX(*iot, T(f.out), S(f.out)); diff --git a/flags.c b/flags.c index 626907c..7e09cb9 100644 --- a/flags.c +++ b/flags.c @@ -39,6 +39,7 @@ static struct flagnames flagnames[] = { { MKD_EXPLICITLIST, "EXPLICITLIST" }, { MKD_ALT_AS_TITLE, "ALT_AS_TITLE" }, { MKD_EXTENDED_ATTR, "EXTENDED_ATTR" }, + { MKD_HTML5, "HTML5" }, }; #define NR(x) (sizeof x/sizeof x[0]) diff --git a/generate.c b/generate.c index c740764..6e092a7 100644 --- a/generate.c +++ b/generate.c @@ -16,6 +16,7 @@ #include "cstring.h" #include "markdown.h" #include "amalloc.h" +#include "tags.h" typedef int (*stfu)(const void*,const void*); typedef void (*spanhandler)(MMIOT*,int); @@ -213,11 +214,12 @@ ___mkd_reparse(char *bfr, int size, mkd_flag_t* flags, MMIOT *f, char *esc) MMIOT sub; struct escaped e; - ___mkd_initmmiot(&sub, f->footnotes); + ___mkd_initmmiot(&sub, f->footnotes, flags); - COPY_FLAGS(sub.flags, f->flags); - if ( flags ) - ADD_FLAGS(&sub.flags, flags); + ___mkd_or_flags(&sub.flags, &f->flags); + + + sub.cb = f->cb; sub.ref_prefix = f->ref_prefix; diff --git a/html5.c b/html5.c index df1df2c..2e05d04 100644 --- a/html5.c +++ b/html5.c @@ -1,21 +1,16 @@ /* block-level tags for passing html5 blocks through the blender */ +#include +#include "markdown.h" #include "tags.h" void -mkd_with_html5_tags(void) +mkd_add_html5_tags(MMIOT* doc) { - static int populated = 0; - - if ( populated ) return; - populated = 1; - - mkd_define_tag("ASIDE", 0); - mkd_define_tag("FOOTER", 0); - mkd_define_tag("HEADER", 0); - mkd_define_tag("NAV", 0); - mkd_define_tag("SECTION", 0); - mkd_define_tag("ARTICLE", 0); - - mkd_sort_tags(); + mkd_define_tag(doc, "ASIDE", 0); + mkd_define_tag(doc, "FOOTER", 0); + mkd_define_tag(doc, "HEADER", 0); + mkd_define_tag(doc, "NAV", 0); + mkd_define_tag(doc, "SECTION", 0); + mkd_define_tag(doc, "ARTICLE", 0); } diff --git a/main.c b/main.c index 9926554..c7a855c 100644 --- a/main.c +++ b/main.c @@ -198,7 +198,6 @@ main(int argc, char **argv) int toc = 0; int content = 1; int version = 0; - int with_html5 = 0; int styles = 0; int use_mkd_line = 0; int use_e_codefmt = 0; @@ -232,7 +231,7 @@ main(int argc, char **argv) exit(1); } switch (opt->optchar) { - case '5': with_html5 = 1; + case '5': mkd_set_flag_num(flags, MKD_HTML5); break; case 'b': urlbase = hoptarg(&blob); break; @@ -305,8 +304,7 @@ main(int argc, char **argv) if ( version ) { - printf("%s: discount %s%s", pgm, markdown_version, - with_html5 ? " +html5":""); + printf("%s: discount %s", pgm, markdown_version); if ( version == 2 ) mkd_flags_are(stdout, flags, 0); putchar('\n'); @@ -316,9 +314,6 @@ main(int argc, char **argv) argc -= hoptind(&blob); argv += hoptind(&blob); - if ( with_html5 ) - mkd_with_html5_tags(); - if ( use_mkd_line ) rc = mkd_generateline( text, strlen(text), stdout, flags); else { @@ -377,7 +372,6 @@ main(int argc, char **argv) } mkd_cleanup(doc); } - mkd_deallocate_tags(); mkd_free_flags(flags); adump(); exit( (rc == 0) ? 0 : errno ); diff --git a/markdown.c b/markdown.c index 31a4ef5..7d3bf54 100644 --- a/markdown.c +++ b/markdown.c @@ -105,7 +105,7 @@ ___mkd_tidy(Cstring *t) static struct kw comment = { "!--", 3, 0 }; static struct kw * -isopentag(Line *p) +isopentag(MMIOT *doc, Line *p) { int i=0, len; char *line; @@ -133,7 +133,7 @@ isopentag(Line *p) ; - return mkd_search_tags(T(p->text)+1, i-1); + return mkd_search_tags(doc, T(p->text)+1, i-1); } @@ -1269,7 +1269,7 @@ compile_document(Line *ptr, MMIOT *f) int previous_was_break = 1; while ( ptr ) { - if ( !is_flag_set(&(f->flags), MKD_NOHTML) && (tag = isopentag(ptr)) ) { + if ( !is_flag_set(&(f->flags), MKD_NOHTML) && (tag = isopentag(f, ptr)) ) { int blocktype; /* If we encounter a html/style block, compile and save all * of the cached source BEFORE processing the html/style. @@ -1468,7 +1468,7 @@ compile(Line *ptr, int toplevel, MMIOT *f) * processing with textblock() */ - if ( !is_flag_set(&(f->flags), MKD_NOHTML) && (tag = isopentag(ptr)) ) { + if ( !is_flag_set(&(f->flags), MKD_NOHTML) && (tag = isopentag(f, ptr)) ) { /* possibly an html block */ @@ -1527,18 +1527,13 @@ mkd_compile(Document *doc, mkd_flag_t* flags) } doc->compiled = 1; - memset(doc->ctx, 0, sizeof(MMIOT) ); + + ___mkd_initmmiot(doc->ctx, NULL, flags); + doc->ctx->ref_prefix= doc->ref_prefix; doc->ctx->cb = &(doc->cb); - if (flags) - COPY_FLAGS(doc->ctx->flags, *flags); - else - mkd_init_flags(&doc->ctx->flags); - CREATE(doc->ctx->in); - doc->ctx->footnotes = malloc(sizeof doc->ctx->footnotes[0]); - doc->ctx->footnotes->reference = 0; - CREATE(doc->ctx->footnotes->note); + CREATE(doc->ctx->in); mkd_initialize(); diff --git a/markdown.h b/markdown.h index 74464f6..c53b830 100644 --- a/markdown.h +++ b/markdown.h @@ -45,6 +45,7 @@ enum { MKD_NOLINKS=0, /* don't do link processing, block tags */ MKD_LATEX, /* handle embedded LaTeX escapes */ MKD_ALT_AS_TITLE, /* use alt text as the title if no title is listed */ MKD_EXTENDED_ATTR, /* allow extended attribute suffixes */ + MKD_HTML5, /* handle html5 tags (obsolete?) */ /* end of user flags */ IS_LABEL, MKD_NR_FLAGS }; @@ -174,6 +175,17 @@ struct footnote_list { } ; + +/* html tag structure (here for MMIOT->extratags) + */ +struct kw { + char *id; + int size; + int selfclose; +} ; + + + /* a magic markdown io thing holds all the data structures needed to * do the backend processing of a markdown document */ @@ -181,7 +193,7 @@ typedef struct mmiot { Cstring out; Cstring in; Qblock Q; - char last; /* last text character added to out */ + char last; /* last text character added to out */ int isp; struct escaped *esc; char *ref_prefix; @@ -189,6 +201,7 @@ typedef struct mmiot { mkd_flag_t flags; Callback_data *cb; + STRING(struct kw) extratags; /* extra (mainly html5) tags */ } MMIOT; @@ -262,6 +275,7 @@ extern int mkd_line(char *, int, char **, mkd_flag_t*); extern int mkd_generateline(char *, int, FILE*, mkd_flag_t*); #define mkd_text mkd_generateline extern void mkd_basename(Document*, char *); +extern void mkd_add_html5_tags(MMIOT*); typedef int (*mkd_sta_function_t)(const int,const void*); extern void mkd_string_to_anchor(char*,int, mkd_sta_function_t, void*, int, MMIOT *); @@ -273,7 +287,6 @@ extern Document *gfm_in(FILE *, mkd_flag_t*); extern Document *gfm_string(const char*,int, mkd_flag_t*); extern void mkd_initialize(void); -extern void mkd_shlib_destructor(void); extern void mkd_ref_prefix(Document*, char*); @@ -284,7 +297,7 @@ extern void ___mkd_freeLines(Line *); extern void ___mkd_freeParagraph(Paragraph *); extern void ___mkd_freefootnote(Footnote *); extern void ___mkd_freefootnotes(MMIOT *); -extern void ___mkd_initmmiot(MMIOT *, void *); +extern void ___mkd_initmmiot(MMIOT *, void *, mkd_flag_t*); extern void ___mkd_freemmiot(MMIOT *, void *); extern void ___mkd_freeLineRange(Line *, Line *); extern void ___mkd_xml(char *, int, FILE *); diff --git a/mkdio.c b/mkdio.c index 8c3eb2b..325363f 100644 --- a/mkdio.c +++ b/mkdio.c @@ -13,6 +13,7 @@ #include "cstring.h" #include "markdown.h" #include "amalloc.h" +#include "tags.h" typedef ANCHOR(Line) LineAnchor; @@ -319,11 +320,7 @@ mkd_string_to_anchor(char *s, int len, mkd_sta_function_t outchar, static void mkd_parse_line(char *bfr, int size, MMIOT *f, mkd_flag_t *flags) { - ___mkd_initmmiot(f, 0); - if ( flags ) - COPY_FLAGS(f->flags, *flags); - else - mkd_init_flags(&f->flags); + ___mkd_initmmiot(f, 0, flags); ___mkd_reparse(bfr, size, NULL, f, 0); ___mkd_emblock(f); } diff --git a/mktags.c b/mktags.c index 8c1d13f..51bb226 100644 --- a/mktags.c +++ b/mktags.c @@ -4,6 +4,7 @@ #define __WITHOUT_AMALLOC 1 #include "config.h" +#include "markdown.h" #include "cstring.h" #include "tags.h" diff --git a/pgm_options.c b/pgm_options.c index 2aebb11..b8f1073 100644 --- a/pgm_options.c +++ b/pgm_options.c @@ -81,6 +81,7 @@ static struct _opt { { "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]) diff --git a/resource.c b/resource.c index 8c57e8d..f8802d1 100644 --- a/resource.c +++ b/resource.c @@ -95,19 +95,28 @@ ___mkd_freefootnotes(MMIOT *f) /* initialize a new MMIOT */ void -___mkd_initmmiot(MMIOT *f, void *footnotes) +___mkd_initmmiot(MMIOT *f, void *footnotes, mkd_flag_t *flags) { if ( f ) { memset(f, 0, sizeof *f); CREATE(f->in); CREATE(f->out); CREATE(f->Q); + CREATE(f->extratags); if ( footnotes ) f->footnotes = footnotes; else { f->footnotes = malloc(sizeof f->footnotes[0]); CREATE(f->footnotes->note); } + if ( flags ) + COPY_FLAGS(f->flags, *flags); + else + mkd_init_flags(&f->flags); + + if ( is_flag_set(&f->flags, MKD_HTML5) ) + mkd_add_html5_tags(f); + } } @@ -121,8 +130,10 @@ ___mkd_freemmiot(MMIOT *f, void *footnotes) DELETE(f->in); DELETE(f->out); DELETE(f->Q); + DELETE(f->extratags); if ( f->footnotes != footnotes ) ___mkd_freefootnotes(f); + memset(f, 0, sizeof *f); } } diff --git a/setup.c b/setup.c index 6cfe7eb..954ccd8 100644 --- a/setup.c +++ b/setup.c @@ -29,11 +29,3 @@ mkd_initialize(void) INITRNG(time(0)); } } - - -void DESTRUCTOR -mkd_shlib_destructor(void) -{ - mkd_deallocate_tags(); -} - diff --git a/tags.c b/tags.c index 05d7140..a5af24e 100644 --- a/tags.c +++ b/tags.c @@ -3,11 +3,11 @@ #include "config.h" #define __WITHOUT_AMALLOC 1 +#include +#include "markdown.h" #include "cstring.h" #include "tags.h" -STRING(struct kw) extratags; - /* the standard collection of tags are built and sorted when * discount is configured, so all we need to do is pull them * in and use them. @@ -20,21 +20,20 @@ STRING(struct kw) extratags; /* define an additional html block tag */ void -mkd_define_tag(char *id, int selfclose) +mkd_define_tag(MMIOT *doc, char *id, int selfclose) { struct kw *p; /* only add the new tag if it doesn't exist in * either the standard or extra tag tables. */ - if ( !(p = mkd_search_tags(id, strlen(id))) ) { - /* extratags could be deallocated */ - if ( S(extratags) == 0 ) - CREATE(extratags); - p = &EXPAND(extratags); - p->id = id; + if ( !(p = mkd_search_tags(doc, id, strlen(id))) ) { + p = &EXPAND(doc->extratags); + p->id = strdup(id); p->size = strlen(id); p->selfclose = selfclose; + + mkd_sort_tags(doc); } } @@ -59,16 +58,17 @@ typedef int (*stfu)(const void*,const void*); /* sort the list of extra html block tags for later searching */ void -mkd_sort_tags(void) +mkd_sort_tags(MMIOT *doc) { - qsort(T(extratags), S(extratags), sizeof(struct kw), (stfu)casort); + if ( S(doc->extratags) ) + qsort(T(doc->extratags), S(doc->extratags), sizeof(struct kw), (stfu)casort); } /* look for a token in the html block tag list */ struct kw* -mkd_search_tags(char *pat, int len) +mkd_search_tags(MMIOT *doc, char *pat, int len) { struct kw key; struct kw *ret; @@ -79,18 +79,45 @@ mkd_search_tags(char *pat, int len) if ( (ret=bsearch(&key,blocktags,NR_blocktags,sizeof key,(stfu)casort)) ) return ret; - if ( S(extratags) ) - return bsearch(&key,T(extratags),S(extratags),sizeof key,(stfu)casort); + if ( S(doc->extratags) ) + return bsearch(&key,T(doc->extratags),S(doc->extratags),sizeof key,(stfu)casort); return 0; } -/* destroy the extratags list (for shared libraries) +/* delete an extratags structure + */ + +void +___mkd_delete_extratags(MMIOT *doc) +{ + int i; + + for ( i=0; iextratags); i++ ) + free(T(doc->extratags)[i].id); + + S(doc->extratags) = 0; +} + + +/* duplicate an extratags structure */ void -mkd_deallocate_tags(void) +___mkd_copy_extratags(MMIOT *dst, MMIOT *src) { - if ( S(extratags) > 0 ) - DELETE(extratags); -} /* mkd_deallocate_tags */ + int i; + + if ( (src == NULL) || (dst == NULL) ) + return; + + if ( S(dst->extratags) ) + ___mkd_delete_extratags(dst); + + for (i=0; i< S(src->extratags); i++ ) { + EXPAND(dst->extratags); + T(dst->extratags)[i].id = strdup(T(src->extratags)[i].id); + T(dst->extratags)[i].size = T(src->extratags)[i].size; + T(dst->extratags)[i].selfclose = T(src->extratags)[i].selfclose; + } +} diff --git a/tags.h b/tags.h index b9af8b5..459287a 100644 --- a/tags.h +++ b/tags.h @@ -3,17 +3,12 @@ #ifndef _TAGS_D #define _TAGS_D -struct kw { - char *id; - int size; - int selfclose; -} ; +#include - -struct kw* mkd_search_tags(char *, int); -void mkd_prepare_tags(void); -void mkd_deallocate_tags(void); -void mkd_sort_tags(void); -void mkd_define_tag(char *, int); +struct kw* mkd_search_tags(MMIOT*, char *, int); +void mkd_sort_tags(MMIOT *); +void mkd_define_tag(MMIOT*, char *, int); +void ___mkd_copy_extratags(MMIOT *dst, MMIOT *src); +void ___mkd_delete_extratags(MMIOT *doc); #endif