Commit ddcc1f34dfb6fc8c0ac01fbb5a00d8251a9f7baf

Martin Mitas 2020-05-04T12:54:15

HTML renderer: Add support for XHTML mode.

diff --git a/CHANGELOG.md b/CHANGELOG.md
index f479caf..3ff3e8c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,6 +17,15 @@ New features:
    `md2html` utility automatically enables the flag (unless it is custom-built
    with `-DMD4C_USE_ASCII`).
 
+ * With `MD_RENDER_FLAG_XHTML`, The HTML renderer generates XHTML instead of
+   HTML.
+
+   This effectively means `<br />` instead of `<br>` and similarly `<hr />`
+   instead of `<hr>`.
+
+ * `md2html` utility now understands the flag `-x` or `--xhtml` to enable
+   the XHTML mode.
+
 
 ## Version 0.4.3
 
diff --git a/md2html/md2html.c b/md2html/md2html.c
index f2f2eb6..818a9cf 100644
--- a/md2html/md2html.c
+++ b/md2html/md2html.c
@@ -41,6 +41,7 @@ static unsigned parser_flags = 0;
     static unsigned renderer_flags = MD_HTML_FLAG_DEBUG;
 #endif
 static int want_fullhtml = 0;
+static int want_xhtml = 0;
 static int want_stat = 0;
 
 
@@ -154,7 +155,7 @@ process_file(FILE* in, FILE* out)
         fprintf(out, "<html>\n");
         fprintf(out, "<head>\n");
         fprintf(out, "<title></title>\n");
-        fprintf(out, "<meta name=\"generator\" content=\"md2html\">\n");
+        fprintf(out, "<meta name=\"generator\" content=\"md2html\"%s>\n", want_xhtml ? " /" : "");
         fprintf(out, "</head>\n");
         fprintf(out, "<body>\n");
     }
@@ -190,6 +191,7 @@ out:
 static const CMDLINE_OPTION cmdline_options[] = {
     { 'o', "output",                        'o', CMDLINE_OPTFLAG_REQUIREDARG },
     { 'f', "full-html",                     'f', 0 },
+    { 'x', "xhtml",                         'x', 0 },
     { 's', "stat",                          's', 0 },
     { 'h', "help",                          'h', 0 },
     { 'v', "version",                       'v', 0 },
@@ -229,6 +231,7 @@ usage(void)
         "General options:\n"
         "  -o  --output=FILE    Output file (default is standard output)\n"
         "  -f, --full-html      Generate full HTML document, including header\n"
+        "  -x, --xhtml          Generate XHTML instead of HTML\n"
         "  -s, --stat           Measure time of input parsing\n"
         "  -h, --help           Display this help and exit\n"
         "  -v, --version        Display version and exit\n"
@@ -299,6 +302,7 @@ cmdline_callback(int opt, char const* value, void* data)
 
         case 'o':   output_path = value; break;
         case 'f':   want_fullhtml = 1; break;
+        case 'x':   want_xhtml = 1; renderer_flags |= MD_HTML_FLAG_XHTML; break;
         case 's':   want_stat = 1; break;
         case 'h':   usage(); exit(0); break;
         case 'v':   version(); exit(0); break;
diff --git a/src/md4c-html.c b/src/md4c-html.c
index 51097d1..9e677fc 100644
--- a/src/md4c-html.c
+++ b/src/md4c-html.c
@@ -387,7 +387,7 @@ enter_block_callback(MD_BLOCKTYPE type, void* detail, void* userdata)
         case MD_BLOCK_UL:       RENDER_VERBATIM(r, "<ul>\n"); break;
         case MD_BLOCK_OL:       render_open_ol_block(r, (const MD_BLOCK_OL_DETAIL*)detail); break;
         case MD_BLOCK_LI:       render_open_li_block(r, (const MD_BLOCK_LI_DETAIL*)detail); break;
-        case MD_BLOCK_HR:       RENDER_VERBATIM(r, "<hr>\n"); break;
+        case MD_BLOCK_HR:       RENDER_VERBATIM(r, (r->flags & MD_HTML_FLAG_XHTML) ? "<hr />\n" : "<hr>\n"); break;
         case MD_BLOCK_H:        RENDER_VERBATIM(r, head[((MD_BLOCK_H_DETAIL*)detail)->level - 1]); break;
         case MD_BLOCK_CODE:     render_open_code_block(r, (const MD_BLOCK_CODE_DETAIL*) detail); break;
         case MD_BLOCK_HTML:     /* noop */ break;
@@ -507,7 +507,10 @@ text_callback(MD_TEXTTYPE type, const MD_CHAR* text, MD_SIZE size, void* userdat
 
     switch(type) {
         case MD_TEXT_NULLCHAR:  render_utf8_codepoint(r, 0x0000, render_verbatim); break;
-        case MD_TEXT_BR:        RENDER_VERBATIM(r, (r->image_nesting_level == 0 ? "<br>\n" : " ")); break;
+        case MD_TEXT_BR:        RENDER_VERBATIM(r, (r->image_nesting_level == 0
+                                        ? ((r->flags & MD_HTML_FLAG_XHTML) ? "<br />\n" : "<br>\n")
+                                        : " "));
+                                break;
         case MD_TEXT_SOFTBR:    RENDER_VERBATIM(r, (r->image_nesting_level == 0 ? "\n" : " ")); break;
         case MD_TEXT_HTML:      render_verbatim(r, text, size); break;
         case MD_TEXT_ENTITY:    render_entity(r, text, size, render_html_escaped); break;
diff --git a/src/md4c-html.h b/src/md4c-html.h
index 000c721..3dff647 100644
--- a/src/md4c-html.h
+++ b/src/md4c-html.h
@@ -37,6 +37,7 @@
 #define MD_HTML_FLAG_DEBUG                  0x0001
 #define MD_HTML_FLAG_VERBATIM_ENTITIES      0x0002
 #define MD_HTML_FLAG_SKIP_UTF8_BOM          0x0004
+#define MD_HTML_FLAG_XHTML                  0x0008
 
 
 /* Render Markdown into HTML.