From: Fletcher T. Penney Date: Wed, 8 Aug 2018 00:27:35 +0000 (-0500) Subject: FIXED: Use Setext headers when necessary to convert from OPML to text (fixes #138) X-Git-Tag: 6.4.0^2~5 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=cd6c4902545f941d6a821dfef59bfb65b11c1d63;p=multimarkdown FIXED: Use Setext headers when necessary to convert from OPML to text (fixes #138) --- diff --git a/Sources/libMultiMarkdown/opml-lexer.c b/Sources/libMultiMarkdown/opml-lexer.c index ca92df9..1588ee7 100644 --- a/Sources/libMultiMarkdown/opml-lexer.c +++ b/Sources/libMultiMarkdown/opml-lexer.c @@ -1,4 +1,4 @@ -/* Generated by re2c 1.0.3 on Mon Aug 6 17:50:40 2018 */ +/* Generated by re2c 1.0.3 on Tue Aug 7 19:20:45 2018 */ /** MultiMarkdown -- Lightweight markup processor to produce HTML, LaTeX, and more. @@ -2090,3 +2090,94 @@ yy206: } } + + +/// Does the string include encoded newline? +size_t scan_encoded_newline(const char * c, size_t len) { + const char * marker = NULL; + const char * start = c; + +scan: + + if ((*c == '\0') || ((c - start) > len)) { + // Not found + return -1; + } + + + { + unsigned char yych; + yych = *c; + + switch (yych) { + case '\n': + goto yy210; + + case '&': + goto yy213; + + default: + goto yy211; + } + +yy210: + c = marker; + goto yy212; +yy211: + ++c; +yy212: { + goto scan; + } +yy213: + yych = *(marker = ++c); + + switch (yych) { + case '#': + goto yy214; + + default: + goto yy212; + } + +yy214: + yych = *++c; + + switch (yych) { + case '1': + goto yy215; + + default: + goto yy210; + } + +yy215: + yych = *++c; + + switch (yych) { + case '0': + case '3': + goto yy216; + + default: + goto yy210; + } + +yy216: + yych = *++c; + + switch (yych) { + case ';': + goto yy217; + + default: + goto yy210; + } + +yy217: + ++c; + { + return (size_t)(c - start); + } + } + +} diff --git a/Sources/libMultiMarkdown/opml-lexer.h b/Sources/libMultiMarkdown/opml-lexer.h index 482d67e..e17ef09 100644 --- a/Sources/libMultiMarkdown/opml-lexer.h +++ b/Sources/libMultiMarkdown/opml-lexer.h @@ -150,4 +150,8 @@ size_t scan_note(const char * c); /// find end of double quoted value size_t scan_double_quoted(const char * c); +/// Does the string include encoded newline? +size_t scan_encoded_newline(const char * c, size_t len); + + #endif diff --git a/Sources/libMultiMarkdown/opml-lexer.re b/Sources/libMultiMarkdown/opml-lexer.re index 3146a2d..25f9360 100644 --- a/Sources/libMultiMarkdown/opml-lexer.re +++ b/Sources/libMultiMarkdown/opml-lexer.re @@ -138,6 +138,8 @@ int opml_scan(Scanner * s, const char * stop) { text_attribute = WSNL* 'text' WSNL* EQUAL WSNL*; note_attribute = WSNL* '_note' WSNL* EQUAL WSNL*; + contains_newline = " " | " "; + '\x00]* '>' { return OPML_XML; } '\x00]* '>' { return OPML_OPML_OPEN; } @@ -184,7 +186,7 @@ size_t scan_text(const char * c) { const char * start = c; /*!re2c - text_attribute / double_quoted { return (size_t)( c - start ); } + text_attribute / double_quoted { return (size_t)( c - start ); } .? { return 0; } */ } @@ -196,7 +198,7 @@ size_t scan_note(const char * c) { const char * start = c; /*!re2c - note_attribute / double_quoted { return (size_t)( c - start ); } + note_attribute / double_quoted { return (size_t)( c - start ); } .? { return 0; } */ } @@ -212,3 +214,22 @@ size_t scan_double_quoted(const char * c) { .? { return 0; } */ } + + +/// Does the string include encoded newline? +size_t scan_encoded_newline(const char * c, size_t len) { + const char * marker = NULL; + const char * start = c; + + scan: + + if ((*c == '\0') || ((c - start) > len)) { + // Not found + return -1; + } + +/*!re2c + contains_newline { return (size_t)(c - start); } + . { goto scan; } +*/ +} diff --git a/Sources/libMultiMarkdown/opml-reader.c b/Sources/libMultiMarkdown/opml-reader.c index db1385c..f373fff 100644 --- a/Sources/libMultiMarkdown/opml-reader.c +++ b/Sources/libMultiMarkdown/opml-reader.c @@ -337,18 +337,35 @@ void parse_opml_token_chain(mmd_engine * e, token * chain) { print_const(":\t"); } else { // Print header - for (int i = 0; i < header_level; ++i) { - print_char('#'); - } + if (scan_encoded_newline(&(e->dstr->str[start + 1]), len - 2) == -1) { + // ATX header + for (int i = 0; i < header_level; ++i) { + print_char('#'); + } - print_char(' '); + print_char(' '); + } print_opml_text(out, e->dstr->str, start + 1, len - 2); - print_char(' '); - - for (int i = 0; i < header_level; ++i) { - print_char('#'); + if (scan_encoded_newline(&(e->dstr->str[start + 1]), len - 2) == -1) { + // ATX header + print_char(' '); + + for (int i = 0; i < header_level; ++i) { + print_char('#'); + } + } else { + // Print Setext Header + switch (header_level) { + case 1: + print_const("\n======"); + break; + + default: + print_const("\n------"); + break; + } } print_const("\n");