From c6419eed96f2832b1de2b94d711552efaa9b172d Mon Sep 17 00:00:00 2001
From: Aleksey Veresov <aleksey@veresov.pro>
Date: Wed, 6 Nov 2019 20:09:07 +0300
Subject: [texo] Prettier print (+ fixes).

---
 src/html.cpp     |  58 ++++++++++------------------
 src/html.hpp     |  10 -----
 src/lines.cpp    |  30 ++++++++++++---
 src/lines.hpp    |   3 ++
 src/markdown.cpp | 112 ++++++++++++++++++++++++++++++++++++++++---------------
 src/markdown.hpp |   7 ++++
 src/plain.cpp    |  53 +++++++++++++++++++-------
 src/plain.hpp    |   5 +++
 8 files changed, 180 insertions(+), 98 deletions(-)

(limited to 'src')

diff --git a/src/html.cpp b/src/html.cpp
index 4cf8174..f40b8bd 100644
--- a/src/html.cpp
+++ b/src/html.cpp
@@ -25,22 +25,22 @@ void TexoProducerHTML::Put(const TexoHeader &piece)
 {
     Close();
     if (piece.level <= 1) {
-        exporter.Put("<h6>");
+        exporter.Put("\n<h6>\n");
         opened_block = header_6;
     } else if (piece.level == 2) {
-        exporter.Put("<h5>");
+        exporter.Put("\n<h5>\n");
         opened_block = header_5;
     } else if (piece.level == 3) {
-        exporter.Put("<h4>");
+        exporter.Put("\n<h4>\n");
         opened_block = header_4;
     } else if (piece.level == 4) {
-        exporter.Put("<h3>");
+        exporter.Put("\n<h3>\n");
         opened_block = header_3;
     } else if (piece.level == 5) {
-        exporter.Put("<h2>");
+        exporter.Put("\n<h2>\n");
         opened_block = header_2;
     } else {
-        exporter.Put("<h1>");
+        exporter.Put("\n<h1>\n");
         opened_block = header_1;
     }
 }
@@ -49,21 +49,21 @@ void TexoProducerHTML::Put(const TexoParagraph &piece)
 {
     Close();
     opened_block = paragraph;
-    exporter.Put("<p>");
+    exporter.Put("\n<p>\n");
 }
 
 void TexoProducerHTML::Put(const TexoCode &piece)
 {
     Close();
     opened_block = code;
-    exporter.Put("<pre>");
+    exporter.Put("\n<pre>\n");
 }
 
 void TexoProducerHTML::Put(const TexoQuote &piece)
 {
     Close();
     opened_block = quote;
-    exporter.Put("<blockquote><p>");
+    exporter.Put("\n<blockquote><p>\n");
 }
 
 void TexoProducerHTML::Put(const TexoMono &piece)
@@ -169,41 +169,21 @@ void TexoProducerHTML::Put(const TexoLink &piece)
 
 void TexoProducerHTML::Put(const TexoHorizontalRule &piece)
 {
-    exporter.Put("<hr/>");
+    exporter.Put("\n<hr/>\n");
 }
 
 void TexoProducerHTML::Close()
 {
     switch (opened_block) {
     case none:                                         break;
-    case header_1:  exporter.Put("</h1>");             break;
-    case header_2:  exporter.Put("</h2>");             break;
-    case header_3:  exporter.Put("</h3>");             break;
-    case header_4:  exporter.Put("</h4>");             break;
-    case header_5:  exporter.Put("</h5>");             break;
-    case header_6:  exporter.Put("</h6>");             break;
-    case paragraph: exporter.Put("</p>");              break;
-    case quote:     exporter.Put("</p></blockquote>"); break;
-    case code:      exporter.Put("</pre>");            break;
+    case header_1:  exporter.Put("\n</h1>\n");             break;
+    case header_2:  exporter.Put("\n</h2>\n");             break;
+    case header_3:  exporter.Put("\n</h3>\n");             break;
+    case header_4:  exporter.Put("\n</h4>\n");             break;
+    case header_5:  exporter.Put("\n</h5>\n");             break;
+    case header_6:  exporter.Put("\n</h6>\n");             break;
+    case paragraph: exporter.Put("\n</p>\n");              break;
+    case quote:     exporter.Put("\n</p></blockquote>\n"); break;
+    case code:      exporter.Put("\n</pre>\n");            break;
     }
 }
-
-
-TexoImporterHTML::TexoImporterHTML(TexoProducer &producer):
-    TexoImporter(producer)
-{}
-
-void TexoImporterHTML::Put(char c)
-{  // TODO
-    producer.Put(Texo(c));
-}
-
-void TexoImporterHTML::Put(const ScriptVariable &str)
-{
-    TexoImporter::Put(str);
-}
-
-void TexoImporterHTML::Put(FILE *file)
-{
-    TexoImporter::Put(file);
-}
diff --git a/src/html.hpp b/src/html.hpp
index 8091d74..b96200f 100644
--- a/src/html.hpp
+++ b/src/html.hpp
@@ -47,14 +47,4 @@ private:
 };
 
 
-class TexoImporterHTML: public TexoImporter {
-public:
-    TexoImporterHTML(TexoProducer &producer);
-
-    void Put(char c);
-    void Put(const ScriptVariable &str);
-    void Put(FILE *file);
-};
-
-
 #endif
diff --git a/src/lines.cpp b/src/lines.cpp
index 3d93598..bacf048 100644
--- a/src/lines.cpp
+++ b/src/lines.cpp
@@ -2,9 +2,17 @@
 
 
 TexoProducerLines::TexoProducerLines(TexoExporter &exporter):
-    TexoProducer(exporter), newline(false)
+    TexoProducer(exporter), newline(true)
 {}
 
+void TexoProducerLines::End()
+{
+    if (!newline) {
+        exporter.Put('\n');
+        newline = true;
+    }
+}
+
 void TexoProducerLines::Put(const Texo &piece)
 {
     if (piece.c == '\n') {
@@ -20,19 +28,24 @@ void TexoProducerLines::Put(const Texo &piece)
 
 void TexoProducerLines::Put(const TexoParagraph &piece)
 {
-    exporter.Put('\n');
-    newline = true;
+    if (!newline) {
+        exporter.Put('\n');
+        newline = true;
+    }
 }
 
 void TexoProducerLines::Put(const TexoQuote &piece)
 {
-    exporter.Put("\n>");
+    if (!newline) {
+        exporter.Put('\n');
+    }
+    exporter.Put("> ");
     newline = false;
 }
 
 
 TexoImporterLines::TexoImporterLines(TexoProducer &producer):
-    TexoImporter(producer), newline(true)
+    TexoImporter(producer), newline(true), quote(false)
 {}
 
 void TexoImporterLines::Put(char c)
@@ -40,15 +53,22 @@ void TexoImporterLines::Put(char c)
     if (c == '\n') {
         if (!newline) {
             newline = true;
+            quote   = false;
         }
     } else if (newline) {
         if (c == '>') {
             producer.Put(TexoQuote());
+            quote = true;
         } else {
             producer.Put(TexoParagraph());
             producer.Put(c);
         }
         newline = false;
+    } else if (quote) {
+        if (c != ' ') {
+            quote = false;
+            producer.Put(c);
+        }
     } else {
         producer.Put(c);
     }
diff --git a/src/lines.hpp b/src/lines.hpp
index ccd226c..d6ce555 100644
--- a/src/lines.hpp
+++ b/src/lines.hpp
@@ -10,6 +10,8 @@ class TexoProducerLines: public TexoProducer {
 public:
     TexoProducerLines(TexoExporter &exporter);
 
+    void End();
+
     void Put(const Texo &piece);
 
     void Put(const TexoParagraph &piece);
@@ -30,6 +32,7 @@ public:
 
 private:
     bool newline;
+    bool quote;
 };
 
 
diff --git a/src/markdown.cpp b/src/markdown.cpp
index 0d03e83..facba67 100644
--- a/src/markdown.cpp
+++ b/src/markdown.cpp
@@ -3,25 +3,40 @@
 
 TexoProducerMarkdown::TexoProducerMarkdown(TexoExporter &exporter):
     TexoProducer(exporter),
-    quoted(false), newline(false), header(false), code(false)
+    quoted(false), newline(false), header(false), code(false), nospace(true)
 {}
 
+void TexoProducerMarkdown::End()
+{
+    if (!newline) {
+        exporter.Put('\n');
+        newline = true;
+    }
+}
+
 void TexoProducerMarkdown::Put(const Texo &piece)
 {
-    if (piece.c == '\n') {
+    char c = piece.c;
+    if (c == '\n') {
         if (code) {
             exporter.Put('\n');
         } else if (quoted) {
-            exporter.Put("\n>");
-        } else if (header || newline) {
-            exporter.Put(' ');
-        } else {
-            exporter.Put('\n');
-            newline = true;
+            exporter.Put("\n> ");
+        } else if (!nospace) {
+            if (header || newline) {
+                exporter.Put(' ');
+            } else {
+                exporter.Put('\n');
+                newline = true;
+            }
         }
     } else {
-        exporter.Put(piece.c);
+        if (c == '*' || c == '_' || c == '`' || c == '+' || c == '~') {
+            exporter.Put('\\');
+        }
+        exporter.Put(c);
         newline = false;
+        nospace = false;
     }
 }
 
@@ -41,13 +56,12 @@ void TexoProducerMarkdown::Put(const TexoHeader &piece)
     } else {
         exporter.Put("# ");
     }
-    header = true;
+    header  = true;
 }
 
 void TexoProducerMarkdown::Put(const TexoParagraph &piece)
 {
     Close();
-    exporter.Put('\n');
 }
 
 void TexoProducerMarkdown::Put(const TexoCode &piece)
@@ -60,33 +74,43 @@ void TexoProducerMarkdown::Put(const TexoCode &piece)
 void TexoProducerMarkdown::Put(const TexoQuote &piece)
 {
     Close();
-    exporter.Put('>');
+    exporter.Put("> ");
     quoted = true;
 }
 
 void TexoProducerMarkdown::Put(const TexoMono &piece)
 {
     exporter.Put("`");
+    newline = false;
+    nospace = false;
 }
 
 void TexoProducerMarkdown::Put(const TexoBold &piece)
 {
     exporter.Put("**");
+    newline = false;
+    nospace = false;
 }
 
 void TexoProducerMarkdown::Put(const TexoItalic &piece)
 {
-    exporter.Put("*");
+    exporter.Put("_");
+    newline = false;
+    nospace = false;
 }
 
 void TexoProducerMarkdown::Put(const TexoUnderline &piece)
 {
     exporter.Put("++");
+    newline = false;
+    nospace = false;
 }
 
 void TexoProducerMarkdown::Put(const TexoStrike &piece)
 {
     exporter.Put("~~");
+    newline = false;
+    nospace = false;
 }
 
 void TexoProducerMarkdown::Put(const TexoImage &piece)
@@ -117,6 +141,8 @@ void TexoProducerMarkdown::Put(const TexoImage &piece)
             exporter.Put(')');
         }
     }
+    newline = false;
+    nospace = false;
 }
 
 void TexoProducerMarkdown::Put(const TexoLink &piece)
@@ -133,27 +159,33 @@ void TexoProducerMarkdown::Put(const TexoLink &piece)
         }
         exporter.Put(')');
     }
+    newline = false;
+    nospace = false;
 }
 
 void TexoProducerMarkdown::Put(const TexoHorizontalRule &piece)
 {
-    if (!newline) {
+    if (!newline && !nospace) {
         exporter.Put('\n');
     }
-    exporter.Put("---\n");
-    newline = true;
+    exporter.Put("--------------------------------------------------\n");
+    nospace = true;
 }
 
 void TexoProducerMarkdown::Close()
 {
     if (code) {
         exporter.Put("\n```");
-        code = false;
+        code    = false;
+        nospace = false;
+        newline = false;
+    }
+    if (!newline && !nospace) {
+        exporter.Put("\n\n");
     }
-    exporter.Put('\n');
     header  = false;
     quoted  = false;
-    newline = true;
+    nospace = true;
 }
 
 
@@ -168,6 +200,7 @@ void TexoImporterMarkdown::Put(char c)
     case start:         Start(c);        break;
     case text:          Text(c);         break;
     case header_text:   HeaderText(c);   break;
+    case quote_pre:     QuotePre(c);     break;
     case quote_text:    QuoteText(c);    break;
     case quote_newline: QuoteNewline(c); break;
     case code_text:     CodeText(c);     break;
@@ -182,6 +215,7 @@ void TexoImporterMarkdown::Put(char c)
     case rule:          Rule(c);         break;
     case paragraph:     Paragraph(c);    break;
     case header:        Header(c);       break;
+    case header_pre:    HeaderPre(c);    break;
     case code:          Code(c);         break;
     }
 }
@@ -205,6 +239,7 @@ void TexoImporterMarkdown::Start(char c)
         header_level = 6;
     } else if (c == '>') {
         producer.Put(TexoQuote());
+        state = quote_pre;
     } else if (c == '-') {
         producer.Put(TexoParagraph());
         state           = rule;
@@ -249,6 +284,14 @@ void TexoImporterMarkdown::HeaderText(char c)
     }
 }
 
+void TexoImporterMarkdown::QuotePre(char c)
+{
+    if (c != ' ') {
+        state = quote_text;
+        QuoteText(c);
+    }
+}
+
 void TexoImporterMarkdown::QuoteText(char c)
 {
     back = quote_text;
@@ -268,10 +311,10 @@ void TexoImporterMarkdown::QuoteNewline(char c)
 {
     if (c == '>') {
         producer.Put('\n');
-        state = quote_text;
+        state = quote_pre;
     } else {
         state = paragraph;
-        Put(c);
+        Paragraph(c);
     }
 }
 
@@ -298,7 +341,7 @@ void TexoImporterMarkdown::CodeNewline(char c)
     } else {
         producer.Put('\n');
         state = code_text;
-        Put(c);
+        CodeText(c);
     }
 }
 
@@ -376,7 +419,7 @@ void TexoImporterMarkdown::Newline(char c)
         header_level = 6;
     } else if (c == '>') {
         producer.Put(TexoQuote());
-        state = quote_text;
+        state = quote_pre;
     } else if (c == '-') {
         state           = rule;
         rule_dash_count = 1;
@@ -384,9 +427,9 @@ void TexoImporterMarkdown::Newline(char c)
         state            = code;
         code_quote_count = 1;
     } else {
-        producer.Put(' ');
+        producer.Put('\n');
         state = text;
-        Put(c);
+        Text(c);
     }
 }
 
@@ -403,7 +446,7 @@ void TexoImporterMarkdown::Rule(char c)
             producer.Put('-');
         }
         state = text;
-        Put(c);
+        Text(c);
     }
 }
 
@@ -414,7 +457,7 @@ void TexoImporterMarkdown::Paragraph(char c)
         header_level = 6;
     } else if (c == '>') {
         producer.Put(TexoQuote());
-        state = quote_text;
+        state = quote_pre;
     } else if (c == '-') {
         producer.Put(TexoParagraph());
         state           = rule;
@@ -425,7 +468,7 @@ void TexoImporterMarkdown::Paragraph(char c)
     } else if (c != '\n') {
         producer.Put(TexoParagraph());
         state = text;
-        Put(c);
+        Text(c);
     }
 }
 
@@ -437,10 +480,19 @@ void TexoImporterMarkdown::Header(char c)
         } else {
             state = error;
         }
-    } else {
+    } else if (c == ' ') {
         producer.Put(TexoHeader(header_level));
+        state = header_pre;
+    } else {
+        state = error;
+    }
+}
+
+void TexoImporterMarkdown::HeaderPre(char c)
+{
+    if (c != ' ') {
         state = header_text;
-        Put(c);
+        HeaderText(c);
     }
 }
 
diff --git a/src/markdown.hpp b/src/markdown.hpp
index 765993c..f9b25f4 100644
--- a/src/markdown.hpp
+++ b/src/markdown.hpp
@@ -10,6 +10,8 @@ class TexoProducerMarkdown: public TexoProducer {
 public:
     TexoProducerMarkdown(TexoExporter &exporter);
 
+    void End();
+
     void Put(const Texo &piece);
 
     void Put(const TexoHeader &piece);
@@ -34,6 +36,7 @@ private:
     bool newline;
     bool header;
     bool code;
+    bool nospace;
 };
 
 
@@ -51,6 +54,7 @@ private:
         start,
         text,
         header_text,
+        quote_pre,
         quote_text,
         quote_newline,
         code_text,
@@ -65,6 +69,7 @@ private:
         rule,
         paragraph,
         header,
+        header_pre,
         code
     } state, back;
     int header_level;
@@ -74,6 +79,7 @@ private:
     void Start(char c);
     void Text(char c);
     void HeaderText(char c);
+    void QuotePre(char c);
     void QuoteText(char c);
     void QuoteNewline(char c);
     void CodeText(char c);
@@ -88,6 +94,7 @@ private:
     void Rule(char c);
     void Paragraph(char c);
     void Header(char c);
+    void HeaderPre(char c);
     void Code(char c);
 
     void Backquote();
diff --git a/src/plain.cpp b/src/plain.cpp
index 2639c65..8b3d470 100644
--- a/src/plain.cpp
+++ b/src/plain.cpp
@@ -2,46 +2,62 @@
 
 
 TexoProducerPlain::TexoProducerPlain(TexoExporter &exporter):
-    TexoProducer(exporter), quoted(false), newline(false)
+    TexoProducer(exporter), quoted(false), newline(false), nospace(true)
 {}
 
+void TexoProducerPlain::End()
+{
+    if (!newline) {
+        exporter.Put('\n');
+        newline = true;
+    }
+}
+
 void TexoProducerPlain::Put(const Texo &piece)
 {
     if (piece.c == '\n') {
         if (quoted) {
-            exporter.Put("\n>");
-        } else if (newline) {
-            exporter.Put(' ');
-        } else {
-            exporter.Put('\n');
-            newline = true;
+            exporter.Put("\n> ");
+        } else if (!nospace) {
+            if (newline) {
+                exporter.Put(' ');
+            } else {
+                exporter.Put('\n');
+                newline = true;
+            }
         }
     } else {
         exporter.Put(piece.c);
         newline = false;
+        nospace = false;
     }
 }
 
 void TexoProducerPlain::Put(const TexoParagraph &piece)
 {
-    exporter.Put("\n\n");
+    if (!nospace) {
+        exporter.Put("\n\n");
+    }
     quoted  = false;
-    newline = true;
+    nospace = true;
 }
 
 void TexoProducerPlain::Put(const TexoQuote &piece)
 {
-    exporter.Put("\n\n>");
+    if (!nospace) {
+        exporter.Put("\n\n");
+    }
+    exporter.Put("> ");
     quoted = true;
 }
 
 void TexoProducerPlain::Put(const TexoHorizontalRule &piece)
 {
-    if (!newline) {
+    if (!newline && !nospace) {
         exporter.Put('\n');
     }
     exporter.Put("--------------------------------------------------\n");
-    newline = true;
+    nospace = true;
 }
 
 
@@ -66,6 +82,7 @@ void TexoImporterPlain::Put(char c)
     case text:           Text(c);          break;
     case newline:        Newline(c);       break;
     case paragraph:      Paragraph(c);     break;
+    case quote_pre:      QuotePre(c);      break;
     case quote:          Quote(c);         break;
     case quote_newline:  QuoteNewline(c);  break;
     case rule:           Rule(c);          break;
@@ -109,7 +126,7 @@ void TexoImporterPlain::Paragraph(char c)
 {
     if (c == '>') {
         producer.Put(TexoQuote());
-        state = quote;
+        state = quote_pre;
     } else if (c == '-') {
         dash_count = 1;
         state = paragraph_rule;
@@ -120,6 +137,14 @@ void TexoImporterPlain::Paragraph(char c)
     }
 }
 
+void TexoImporterPlain::QuotePre(char c)
+{
+    if (c != ' ') {
+        state = quote;
+        Quote(c);
+    }
+}
+
 void TexoImporterPlain::Quote(char c)
 {
     switch (c) {
@@ -132,7 +157,7 @@ void TexoImporterPlain::QuoteNewline(char c)
 {
     if (c == '>') {
         producer.Put('\n');
-        state = quote;
+        state = quote_pre;
     } else if (c == '\n') {
         state = paragraph;
     } else if (c == '-') {
diff --git a/src/plain.hpp b/src/plain.hpp
index 4c6a8b7..13a2c0c 100644
--- a/src/plain.hpp
+++ b/src/plain.hpp
@@ -10,6 +10,8 @@ class TexoProducerPlain: public TexoProducer {
 public:
     TexoProducerPlain(TexoExporter &exporter);
 
+    void End();
+
     void Put(const Texo &piece);
 
     void Put(const TexoParagraph &piece);
@@ -20,6 +22,7 @@ public:
 private:
     bool quoted;
     bool newline;
+    bool nospace;
 };
 
 
@@ -38,6 +41,7 @@ private:
         text,
         newline,
         paragraph,
+        quote_pre,
         quote,
         quote_newline,
         rule,
@@ -47,6 +51,7 @@ private:
     void Text(char c);
     void Newline(char c);
     void Paragraph(char c);
+    void QuotePre(char c);
     void Quote(char c);
     void QuoteNewline(char c);
     void Rule(char c);
-- 
cgit v1.2.3