]> granicus.if.org Git - multimarkdown/commitdiff
FIXED: Use Setext headers when necessary to convert from OPML to text (fixes #138)
authorFletcher T. Penney <fletcher@fletcherpenney.net>
Wed, 8 Aug 2018 00:27:35 +0000 (19:27 -0500)
committerFletcher T. Penney <fletcher@fletcherpenney.net>
Wed, 8 Aug 2018 00:27:35 +0000 (19:27 -0500)
Sources/libMultiMarkdown/opml-lexer.c
Sources/libMultiMarkdown/opml-lexer.h
Sources/libMultiMarkdown/opml-lexer.re
Sources/libMultiMarkdown/opml-reader.c

index ca92df9b48758afd2019f50ac29051675899cab3..1588ee7cb707d0de735285d1048d91ceba9e3cca 100644 (file)
@@ -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);
+               }
+       }
+
+}
index 482d67e11d0b9850faabc793edf240e8a63550e2..e17ef09f53cebc88696f024fc0d55be5fd1f1c78 100644 (file)
@@ -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
index 3146a2d26df8cbc5918fc86b55d06c978f9a551c..25f9360b2c965b797f4eb235a04a44f3ba9fd84b 100644 (file)
@@ -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                                                                                = "&#10;" | "&#13;";
+
                '<?xml' [^>\x00]* '>'                                                                   { return OPML_XML; }
 
                '<opml' [^>\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; }
+*/
+}
index db1385c2b478b3b3497b82b43130f386df964430..f373fffd8d10871c14871c0d84d8a2cbd7926d43 100644 (file)
@@ -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");