From 73345c7dc06a6488f34d4a76906a62171a519278 Mon Sep 17 00:00:00 2001
From: Aleksey Veresov ");
+        opened_block = header_6;
     } else if (piece.level == 2) {
-        exporter.Put("h5>");
+        exporter.Put("
");
+        opened_block = header_5;
     } else if (piece.level == 3) {
-        exporter.Put("h4>");
+        exporter.Put("
");
+        opened_block = header_4;
     } else if (piece.level == 4) {
-        exporter.Put("h3>");
+        exporter.Put("
");
+        opened_block = header_3;
     } else if (piece.level == 5) {
-        exporter.Put("h2>");
+        exporter.Put("
");
+        opened_block = header_2;
     } else {
-        exporter.Put("h1>");
+        exporter.Put("
");
+        opened_block = header_1;
     }
 }
 
 void TexoProducerHTML::Put(const TexoParagraph &piece)
 {
-    if (piece.closing) {
-        exporter.Put("
"); - } + Close(); + opened_block = paragraph; + exporter.Put("
"); } void TexoProducerHTML::Put(const TexoCode &piece) { - if (piece.closing) { - exporter.Put(""); - } else { - exporter.Put("
");
-    }
+    Close();
+    opened_block = code;
+    exporter.Put("");
 }
 
 void TexoProducerHTML::Put(const TexoQuote &piece)
 {
-    if (piece.closing) {
-        exporter.Put("");
-    } else {
-        exporter.Put("");
-    }
+    Close();
+    opened_block = quote;
+    exporter.Put("
");
 }
 
 void TexoProducerHTML::Put(const TexoMono &piece)
 {
-    if (piece.closing) {
+    static bool closing = false;
+    if (closing) {
         exporter.Put("");
     } else {
         exporter.Put("");
     }
+    closing = !closing;
 }
 
 void TexoProducerHTML::Put(const TexoBold &piece)
 {
-    if (piece.closing) {
+    static bool closing = false;
+    if (closing) {
         exporter.Put("");
     } else {
         exporter.Put("");
     }
+    closing = !closing;
 }
 
 void TexoProducerHTML::Put(const TexoItalic &piece)
 {
-    if (piece.closing) {
+    static bool closing = false;
+    if (closing) {
         exporter.Put("");
     } else {
         exporter.Put("");
     }
+    closing = !closing;
 }
 
 void TexoProducerHTML::Put(const TexoUnderline &piece)
 {
-    if (piece.closing) {
+    static bool closing = false;
+    if (closing) {
         exporter.Put("");
     } else {
         exporter.Put("");
     }
+    closing = !closing;
 }
 
 void TexoProducerHTML::Put(const TexoStrike &piece)
 {
-    if (piece.closing) {
+    static bool closing = false;
+    if (closing) {
         exporter.Put("");
     } else {
         exporter.Put("");
     }
+    closing = !closing;
 }
 
 void TexoProducerHTML::Put(const TexoImage &piece)
@@ -154,14 +167,25 @@ void TexoProducerHTML::Put(const TexoLink &piece)
     }
 }
 
-void TexoProducerHTML::Put(const TexoLineBreak &piece)
+void TexoProducerHTML::Put(const TexoHorizontalRule &piece)
 {
-    exporter.Put("
");
+    exporter.Put("
");
 }
 
-void TexoProducerHTML::Put(const TexoHorizontalRule &piece)
+void TexoProducerHTML::Close()
 {
-    exporter.Put("
");
+    switch (opened_block) {
+    case none:                                         break;
+    case header_1:  exporter.Put("");             break;
+    case header_2:  exporter.Put("");             break;
+    case header_3:  exporter.Put("");             break;
+    case header_4:  exporter.Put("");             break;
+    case header_5:  exporter.Put("");             break;
+    case header_6:  exporter.Put("");             break;
+    case paragraph: exporter.Put("
");              break;
+    case quote:     exporter.Put("
"); break;
+    case code:      exporter.Put("
");            break;
+    }
 }
 
 
diff --git a/src/html.hpp b/src/html.hpp
index c9d2e97..8091d74 100644
--- a/src/html.hpp
+++ b/src/html.hpp
@@ -10,6 +10,8 @@ class TexoProducerHTML: public TexoProducer {
 public:
     TexoProducerHTML(TexoExporter &exporter);
 
+    void End();
+
     void Put(const Texo &piece);
 
     void Put(const TexoHeader &piece);
@@ -25,8 +27,23 @@ public:
 
     void Put(const TexoImage &piece);
     void Put(const TexoLink &piece);
-    void Put(const TexoLineBreak &piece);
     void Put(const TexoHorizontalRule &piece);
+
+private:
+    void Close();
+
+    enum {
+        none = 0,
+        header_1,
+        header_2,
+        header_3,
+        header_4,
+        header_5,
+        header_6,
+        paragraph,
+        code,
+        quote
+    } opened_block;
 };
 
 
diff --git a/src/importer.cpp b/src/importer.cpp
index 73f23e6..af475a5 100644
--- a/src/importer.cpp
+++ b/src/importer.cpp
@@ -4,6 +4,11 @@
 TexoImporter::TexoImporter(TexoProducer &producer): producer(producer)
 {}
 
+void TexoImporter::End()
+{
+    producer.End();
+}
+
 void TexoImporter::Put(const ScriptVariable &str)
 {
     const int len = str.Length();
diff --git a/src/importer.hpp b/src/importer.hpp
index 915416c..3a31fab 100644
--- a/src/importer.hpp
+++ b/src/importer.hpp
@@ -9,6 +9,8 @@ class TexoImporter {
 public:
     TexoImporter(TexoProducer &producer);
 
+    virtual void End();
+
     virtual void Put(char c) = 0;
     virtual void Put(const ScriptVariable &str);
     virtual void Put(FILE *file);
diff --git a/src/lines.cpp b/src/lines.cpp
index f77ae40..3d93598 100644
--- a/src/lines.cpp
+++ b/src/lines.cpp
@@ -10,6 +10,7 @@ void TexoProducerLines::Put(const Texo &piece)
     if (piece.c == '\n') {
         if (!newline) {
             exporter.Put(' ');
+            newline = true;
         }
     } else {
         exporter.Put(piece.c);
@@ -19,65 +20,36 @@ void TexoProducerLines::Put(const Texo &piece)
 
 void TexoProducerLines::Put(const TexoParagraph &piece)
 {
-    if (piece.closing) {
-        exporter.Put('\n');
-        newline = true;
-    }
+    exporter.Put('\n');
+    newline = true;
 }
 
 void TexoProducerLines::Put(const TexoQuote &piece)
 {
-    if (piece.closing) {
-        exporter.Put('\n');
-        newline = true;
-    } else {
-        exporter.Put('>');
-    }
-}
-
-void TexoProducerLines::Put(const TexoLineBreak &piece)
-{
-    exporter.Put('\n');
-    newline = true;
+    exporter.Put("\n>");
+    newline = false;
 }
 
 
 TexoImporterLines::TexoImporterLines(TexoProducer &producer):
-    TexoImporter(producer), quoted(false), newline(true)
+    TexoImporter(producer), newline(true)
 {}
 
-TexoImporterLines::~TexoImporterLines()
-{
-    if (!newline) {
-        if (quoted) {
-            producer.Put(TexoQuote(true));
-        } else {
-            producer.Put(TexoParagraph(true));
-        }
-    }
-}
-
 void TexoImporterLines::Put(char c)
 {
     if (c == '\n') {
         if (!newline) {
-            if (quoted) {
-                producer.Put(TexoQuote(true));
-                quoted = false;
-            } else {
-                producer.Put(TexoParagraph(true));
-            }
             newline = true;
         }
-    } else if (newline && c == '>') {
-        producer.Put(TexoQuote());
-        newline = false;
-        quoted  = true;
-    } else {
-        if (newline) {
+    } else if (newline) {
+        if (c == '>') {
+            producer.Put(TexoQuote());
+        } else {
             producer.Put(TexoParagraph());
-            newline = false;
+            producer.Put(c);
         }
+        newline = false;
+    } else {
         producer.Put(c);
     }
 }
diff --git a/src/lines.hpp b/src/lines.hpp
index 7ddee07..ccd226c 100644
--- a/src/lines.hpp
+++ b/src/lines.hpp
@@ -15,8 +15,6 @@ public:
     void Put(const TexoParagraph &piece);
     void Put(const TexoQuote &piece);
 
-    void Put(const TexoLineBreak &piece);
-
 private:
     bool newline;
 };
@@ -25,14 +23,12 @@ private:
 class TexoImporterLines: public TexoImporter {
 public:
     TexoImporterLines(TexoProducer &producer);
-    ~TexoImporterLines();
 
     void Put(char c);
     void Put(const ScriptVariable &str);
     void Put(FILE *file);
 
 private:
-    bool quoted;
     bool newline;
 };
 
diff --git a/src/markdown.cpp b/src/markdown.cpp
index fb538fc..0d03e83 100644
--- a/src/markdown.cpp
+++ b/src/markdown.cpp
@@ -27,58 +27,41 @@ void TexoProducerMarkdown::Put(const Texo &piece)
 
 void TexoProducerMarkdown::Put(const TexoHeader &piece)
 {
-    if (piece.closing) {
-        exporter.Put('\n');
-        header  = false;
-        newline = true;
+    Close();
+    if (piece.level <= 1) {
+        exporter.Put("###### ");
+    } else if (piece.level == 2) {
+        exporter.Put("##### ");
+    } else if (piece.level == 3) {
+        exporter.Put("#### ");
+    } else if (piece.level == 4) {
+        exporter.Put("### ");
+    } else if (piece.level == 5) {
+        exporter.Put("## ");
     } else {
-        if (!newline) {
-            exporter.Put('\n');
-        }
-        if (piece.level <= 1) {
-            exporter.Put("###### ");
-        } else if (piece.level == 2) {
-            exporter.Put("##### ");
-        } else if (piece.level == 3) {
-            exporter.Put("#### ");
-        } else if (piece.level == 4) {
-            exporter.Put("### ");
-        } else if (piece.level == 5) {
-            exporter.Put("## ");
-        } else {
-            exporter.Put("# ");
-        }
-        header = true;
+        exporter.Put("# ");
     }
+    header = true;
 }
 
 void TexoProducerMarkdown::Put(const TexoParagraph &piece)
 {
-    if (piece.closing) {
-        exporter.Put("\n\n");
-        newline = true;
-    }
+    Close();
+    exporter.Put('\n');
 }
 
 void TexoProducerMarkdown::Put(const TexoCode &piece)
 {
-    exporter.Put("\n```\n");
-    code = !code;
+    Close();
+    exporter.Put("```\n");
+    code = true;
 }
 
 void TexoProducerMarkdown::Put(const TexoQuote &piece)
 {
-    if (piece.closing) {
-        exporter.Put("\n\n");
-        quoted  = false;
-        newline = true;
-    } else {
-        if (!newline) {
-            exporter.Put('\n');
-        }
-        exporter.Put(">");
-        quoted = true;
-    }
+    Close();
+    exporter.Put('>');
+    quoted = true;
 }
 
 void TexoProducerMarkdown::Put(const TexoMono &piece)
@@ -152,31 +135,32 @@ void TexoProducerMarkdown::Put(const TexoLink &piece)
     }
 }
 
-void TexoProducerMarkdown::Put(const TexoLineBreak &piece)
-{
-    exporter.Put("\\\n");
-    newline = true;
-}
-
 void TexoProducerMarkdown::Put(const TexoHorizontalRule &piece)
 {
     if (!newline) {
         exporter.Put('\n');
     }
     exporter.Put("---\n");
-    newline = false;
+    newline = true;
+}
+
+void TexoProducerMarkdown::Close()
+{
+    if (code) {
+        exporter.Put("\n```");
+        code = false;
+    }
+    exporter.Put('\n');
+    header  = false;
+    quoted  = false;
+    newline = true;
 }
 
 
 TexoImporterMarkdown::TexoImporterMarkdown(TexoProducer &producer):
-    TexoImporter(producer), state(start), wrapping_state(error), mod_pos(-1)
+    TexoImporter(producer), state(start)
 {}
 
-TexoImporterMarkdown::~TexoImporterMarkdown()
-{
-    EndBlock();
-}
-
 void TexoImporterMarkdown::Put(char c)
 {
     switch (state) {
@@ -220,22 +204,24 @@ void TexoImporterMarkdown::Start(char c)
         state        = header;
         header_level = 6;
     } else if (c == '>') {
-        BlockState(quote_text);
+        producer.Put(TexoQuote());
     } else if (c == '-') {
-        BlockState(text);
+        producer.Put(TexoParagraph());
         state           = rule;
         rule_dash_count = 1;
     } else if (c == '`') {
         state            = code;
         code_quote_count = 1;
     } else {
-        BlockState(text);
+        producer.Put(TexoParagraph());
+        state = text;
         Put(c);
     }
 }
 
 void TexoImporterMarkdown::Text(char c)
 {
+    back = text;
     switch (c) {
     case '\\': state = backslash; break;
     case '\n': state = newline;   break;
@@ -250,6 +236,7 @@ void TexoImporterMarkdown::Text(char c)
 
 void TexoImporterMarkdown::HeaderText(char c)
 {
+    back = header_text;
     switch (c) {
     case '\\': state = backslash; break;
     case '\n': state = paragraph; break;
@@ -264,6 +251,7 @@ void TexoImporterMarkdown::HeaderText(char c)
 
 void TexoImporterMarkdown::QuoteText(char c)
 {
+    back = quote_text;
     switch (c) {
     case '\\': state = backslash;     break;
     case '\n': state = quote_newline; break;
@@ -279,6 +267,7 @@ void TexoImporterMarkdown::QuoteText(char c)
 void TexoImporterMarkdown::QuoteNewline(char c)
 {
     if (c == '>') {
+        producer.Put('\n');
         state = quote_text;
     } else {
         state = paragraph;
@@ -288,6 +277,7 @@ void TexoImporterMarkdown::QuoteNewline(char c)
 
 void TexoImporterMarkdown::CodeText(char c)
 {
+    back = code_text;
     switch (c) {
     case '\\': state = backslash;    break;
     case '\n': state = code_newline; break;
@@ -319,7 +309,6 @@ void TexoImporterMarkdown::CodeEnd(char c)
     } else  if (c == '\n') {
         if (code_quote_count == 3) {
             state = paragraph;
-            Put(c);
         } else {
             state = error;
         }
@@ -331,56 +320,36 @@ void TexoImporterMarkdown::CodeEnd(char c)
 void TexoImporterMarkdown::Backslash(char c)
 {
     producer.Put(c);
-    state = wrapping_state;
+    state = back;
 }
 
 void TexoImporterMarkdown::Asterisk(char c)
 {
-    state = wrapping_state;
+    state = back;
     if (c == '*') {
-        if (CheckMods(bold)) {
-            producer.Put(TexoBold(Mod(bold)));
-        } else {
-            state = error;
-        }
+        producer.Put(TexoBold());
     } else {
-        if (CheckMods(italic)) {
-            producer.Put(TexoItalic(Mod(italic)));
-            Put(c);
-        } else {
-            state = error;
-        }
+        producer.Put(TexoItalic());
+        Put(c);
     }
 }
 
 void TexoImporterMarkdown::Underline(char c)
 {
-    state = wrapping_state;
+    state = back;
     if (c == '_') {
-        if (CheckMods(bold)) {
-            producer.Put(TexoBold(Mod(bold)));
-        } else {
-            state = error;
-        }
+        producer.Put(TexoBold());
     } else {
-        if (CheckMods(italic)) {
-            producer.Put(TexoItalic(Mod(italic)));
-            Put(c);
-        } else {
-            state = error;
-        }
+        producer.Put(TexoItalic());
+        Put(c);
     }
 }
 
 void TexoImporterMarkdown::Plus(char c)
 {
-    state = wrapping_state;
+    state = back;
     if (c == '+') {
-        if (CheckMods(underlined)) {
-            producer.Put(TexoUnderline(Mod(underlined)));
-        } else {
-            state = error;
-        }
+        producer.Put(TexoUnderline());
     } else {
         producer.Put('+');
         Put(c);
@@ -389,13 +358,9 @@ void TexoImporterMarkdown::Plus(char c)
 
 void TexoImporterMarkdown::Tilde(char c)
 {
-    state = wrapping_state;
+    state = back;
     if (c == '~') {
-        if (CheckMods(strike)) {
-            producer.Put(TexoStrike(Mod(strike)));
-        } else {
-            state = error;
-        }
+        producer.Put(TexoStrike());
     } else {
         producer.Put('~');
         Put(c);
@@ -410,7 +375,8 @@ void TexoImporterMarkdown::Newline(char c)
         state        = header;
         header_level = 6;
     } else if (c == '>') {
-        BlockState(quote_text);
+        producer.Put(TexoQuote());
+        state = quote_text;
     } else if (c == '-') {
         state           = rule;
         rule_dash_count = 1;
@@ -436,7 +402,7 @@ void TexoImporterMarkdown::Rule(char c)
         for (int i = 0; i < rule_dash_count; ++i) {
             producer.Put('-');
         }
-        state = wrapping_state;
+        state = text;
         Put(c);
     }
 }
@@ -447,16 +413,18 @@ void TexoImporterMarkdown::Paragraph(char c)
         state        = header;
         header_level = 6;
     } else if (c == '>') {
-        BlockState(quote_text);
+        producer.Put(TexoQuote());
+        state = quote_text;
     } else if (c == '-') {
-        BlockState(text);
+        producer.Put(TexoParagraph());
         state           = rule;
         rule_dash_count = 1;
     } else if (c == '`') {
         state            = code;
         code_quote_count = 1;
-    } else {
-        BlockState(text);
+    } else if (c != '\n') {
+        producer.Put(TexoParagraph());
+        state = text;
         Put(c);
     }
 }
@@ -470,8 +438,8 @@ void TexoImporterMarkdown::Header(char c)
             state = error;
         }
     } else {
-        BlockState(header_text);
-        header_level_last = header_level;
+        producer.Put(TexoHeader(header_level));
+        state = header_text;
         Put(c);
     }
 }
@@ -482,77 +450,17 @@ void TexoImporterMarkdown::Code(char c)
         ++code_quote_count;
     } else  if (c == '\n') {
         if (code_quote_count == 3) {
-            BlockState(code_text);
-        } else {
-            state = error;
-        }
-    } else {
-        state = error;
-    }
-}
-
-void TexoImporterMarkdown::Backquote()
-{
-    if (CheckMods(mono)) {
-        producer.Put(TexoMono(Mod(mono)));
-    } else {
-        state = error;
-    }
-}
-
-bool TexoImporterMarkdown::CheckMods(Modificator mod)
-{
-    bool ok = true;
-    for (int i = 0; ok && i < mod_pos; ++i) {
-        ok = mods[i] != mod;
-    }
-    return ok;
-}
-
-bool TexoImporterMarkdown::Mod(Modificator mod)
-{
-    if (mod_pos == -1 || mods[mod_pos] != mod) {
-        ++mod_pos;
-        mods[mod_pos] = mod;
-        return false;
-    }
-    --mod_pos;
-    return true;
-}
-
-void TexoImporterMarkdown::BlockState(State st)
-{
-    if (mod_pos == -1) {
-        state = st;
-        EndBlock();
-        if (st == text) {
-            producer.Put(TexoParagraph());
-        } else if (st == quote_text) {
-            producer.Put(TexoQuote());
-        } else if (st == code_text) {
             producer.Put(TexoCode());
-        } else if (st == header_text) {
-            producer.Put(TexoHeader(header_level));
+            state = code_text;
         } else {
             state = error;
         }
-        wrapping_state = st;
     } else {
         state = error;
     }
 }
 
-void TexoImporterMarkdown::EndBlock()
+void TexoImporterMarkdown::Backquote()
 {
-    if (wrapping_state == text) {
-        producer.Put(TexoParagraph(true));
-    } else if (wrapping_state == quote_text) {
-        producer.Put(TexoQuote(true));
-    } else if (wrapping_state == code_text) {
-        producer.Put(TexoCode(true));
-    } else if (wrapping_state == header_text) {
-        producer.Put(TexoHeader(header_level_last, true));
-    } else if (wrapping_state != error) {
-        state = error;
-    }
+    producer.Put(TexoMono());
 }
diff --git a/src/markdown.hpp b/src/markdown.hpp
index e10efa3..765993c 100644
--- a/src/markdown.hpp
+++ b/src/markdown.hpp
@@ -25,10 +25,11 @@ public:
 
     void Put(const TexoImage &piece);
     void Put(const TexoLink &piece);
-    void Put(const TexoLineBreak &piece);
     void Put(const TexoHorizontalRule &piece);
 
 private:
+    void Close();
+
     bool quoted;
     bool newline;
     bool header;
@@ -39,7 +40,6 @@ private:
 class TexoImporterMarkdown: public TexoImporter {
 public:
     TexoImporterMarkdown(TexoProducer &producer);
-    ~TexoImporterMarkdown();
 
     void Put(char c);
     void Put(const ScriptVariable &str);
@@ -66,17 +66,7 @@ private:
         paragraph,
         header,
         code
-    } state;
-    State wrapping_state;
-    enum Modificator {
-        italic,
-        bold,
-        mono,
-        underlined,
-        strike
-    } mods[5];
-    int mod_pos;
-    int header_level_last;
+    } state, back;
     int header_level;
     int rule_dash_count;
     int code_quote_count;
@@ -101,12 +91,6 @@ private:
     void Code(char c);
 
     void Backquote();
-
-    bool CheckMods(Modificator mod);
-    bool Mod(Modificator mod);
-
-    void BlockState(State st);
-    void EndBlock();
 };
 
 
diff --git a/src/plain.cpp b/src/plain.cpp
index d6d262d..2639c65 100644
--- a/src/plain.cpp
+++ b/src/plain.cpp
@@ -24,31 +24,15 @@ void TexoProducerPlain::Put(const Texo &piece)
 
 void TexoProducerPlain::Put(const TexoParagraph &piece)
 {
-    if (piece.closing) {
-        exporter.Put("\n\n");
-        newline = true;
-    }
+    exporter.Put("\n\n");
+    quoted  = false;
+    newline = true;
 }
 
 void TexoProducerPlain::Put(const TexoQuote &piece)
 {
-    if (piece.closing) {
-        exporter.Put("\n\n");
-        quoted  = false;
-        newline = true;
-    } else {
-        if (!newline) {
-            exporter.Put('\n');
-        }
-        exporter.Put(">");
-        quoted = true;
-    }
-}
-
-void TexoProducerPlain::Put(const TexoLineBreak &piece)
-{
-    exporter.Put("\n\n");
-    newline = true;
+    exporter.Put("\n\n>");
+    quoted = true;
 }
 
 void TexoProducerPlain::Put(const TexoHorizontalRule &piece)
@@ -57,7 +41,7 @@ void TexoProducerPlain::Put(const TexoHorizontalRule &piece)
         exporter.Put('\n');
     }
     exporter.Put("--------------------------------------------------\n");
-    newline = false;
+    newline = true;
 }
 
 
@@ -67,34 +51,25 @@ TexoImporterPlain::TexoImporterPlain(TexoProducer &producer):
     producer.Put(TexoParagraph());
 }
 
-TexoImporterPlain::~TexoImporterPlain()
+void TexoImporterPlain::End()
 {
-    switch (state) {
-    case rule:
-        producer.Put('\n');
-        for (;dash_count > 0; --dash_count) {
-            producer.Put('-');
-        }
-    case text: case newline:
-        producer.Put(TexoParagraph(true));
-        break;
-    case quote: case quote_newline:
-        producer.Put(TexoQuote(true));
-        break;
-    case paragraph:
-        break;
+    if (state == rule) {
+        producer.Put(TexoHorizontalRule());
+        state = text;
     }
+    producer.End();
 }
 
 void TexoImporterPlain::Put(char c)
 {
     switch (state) {
-    case text:          Text(c);         break;
-    case newline:       Newline(c);      break;
-    case paragraph:     Paragraph(c);    break;
-    case quote:         Quote(c);        break;
-    case quote_newline: QuoteNewline(c); break;
-    case rule:          Rule(c);         break;
+    case text:           Text(c);          break;
+    case newline:        Newline(c);       break;
+    case paragraph:      Paragraph(c);     break;
+    case quote:          Quote(c);         break;
+    case quote_newline:  QuoteNewline(c);  break;
+    case rule:           Rule(c);          break;
+    case paragraph_rule: ParagraphRule(c); break;
     }
 }
 
@@ -133,14 +108,12 @@ void TexoImporterPlain::Newline(char c)
 void TexoImporterPlain::Paragraph(char c)
 {
     if (c == '>') {
-        producer.Put(TexoParagraph(true));
         producer.Put(TexoQuote());
         state = quote;
     } else if (c == '-') {
         dash_count = 1;
-        state = rule;
+        state = paragraph_rule;
     } else if (c != '\n') {
-        producer.Put(TexoParagraph(true));
         producer.Put(TexoParagraph());
         state = text;
         Text(c);
@@ -161,16 +134,11 @@ void TexoImporterPlain::QuoteNewline(char c)
         producer.Put('\n');
         state = quote;
     } else if (c == '\n') {
-        producer.Put(TexoQuote(true));
-        producer.Put(TexoParagraph());
         state = paragraph;
     } else if (c == '-') {
-        producer.Put(TexoQuote(true));
-        producer.Put(TexoParagraph());
         dash_count = 1;
-        state = rule;
+        state = paragraph_rule;
     } else {
-        producer.Put(TexoQuote(true));
         producer.Put(TexoParagraph());
         state = text;
         Text(c);
@@ -193,3 +161,11 @@ void TexoImporterPlain::Rule(char c)
         Text(c);
     }
 }
+
+void TexoImporterPlain::ParagraphRule(char c)
+{
+    if (c == '\n') {
+        producer.Put(TexoParagraph());
+    }
+    Rule(c);
+}
diff --git a/src/plain.hpp b/src/plain.hpp
index f758843..4c6a8b7 100644
--- a/src/plain.hpp
+++ b/src/plain.hpp
@@ -15,7 +15,6 @@ public:
     void Put(const TexoParagraph &piece);
     void Put(const TexoQuote &piece);
 
-    void Put(const TexoLineBreak &piece);
     void Put(const TexoHorizontalRule &piece);
 
 private:
@@ -27,7 +26,8 @@ private:
 class TexoImporterPlain: public TexoImporter {
 public:
     TexoImporterPlain(TexoProducer &producer);
-    ~TexoImporterPlain();
+
+    void End();
 
     void Put(char c);
     void Put(const ScriptVariable &str);
@@ -40,7 +40,8 @@ private:
         paragraph,
         quote,
         quote_newline,
-        rule
+        rule,
+        paragraph_rule
     } state;
 
     void Text(char c);
@@ -49,6 +50,7 @@ private:
     void Quote(char c);
     void QuoteNewline(char c);
     void Rule(char c);
+    void ParagraphRule(char c);
 
     int dash_count;
 };
diff --git a/src/producer.cpp b/src/producer.cpp
index 8651912..2c60d48 100644
--- a/src/producer.cpp
+++ b/src/producer.cpp
@@ -4,6 +4,9 @@
 TexoProducer::TexoProducer(TexoExporter &exporter): exporter(exporter)
 {}
 
+void TexoProducer::End()
+{}
+
 void TexoProducer::Put(char c)
 {
     Put(Texo(c));
@@ -14,18 +17,27 @@ void TexoProducer::Put(const Texo &piece)
     exporter.Put(piece.c);
 }
 
-void TexoProducer::Put(const TexoHeader &piece)          {}
-void TexoProducer::Put(const TexoParagraph &piece)       {}
-void TexoProducer::Put(const TexoCode &piece)            {}
-void TexoProducer::Put(const TexoQuote &piece)           {}
+void TexoProducer::Put(const TexoHeader &piece)
+{
+    Put(TexoParagraph());
+}
+
+void TexoProducer::Put(const TexoQuote &piece)
+{
+    Put(TexoParagraph());
+}
+
+void TexoProducer::Put(const TexoCode &piece)
+{
+    Put(TexoParagraph());
+}
 
 void TexoProducer::Put(const TexoMono &piece)            {}
 void TexoProducer::Put(const TexoBold &piece)            {}
 void TexoProducer::Put(const TexoItalic &piece)          {}
 void TexoProducer::Put(const TexoUnderline &piece)       {}
 void TexoProducer::Put(const TexoStrike &piece)          {}
-void TexoProducer::Put(const TexoLink &piece)            {}
 
 void TexoProducer::Put(const TexoImage &piece)           {}
-void TexoProducer::Put(const TexoLineBreak &piece)       {}
+void TexoProducer::Put(const TexoLink &piece)            {}
 void TexoProducer::Put(const TexoHorizontalRule &piece)  {}
diff --git a/src/producer.hpp b/src/producer.hpp
index c6fcd5f..62e098d 100644
--- a/src/producer.hpp
+++ b/src/producer.hpp
@@ -9,11 +9,13 @@ class TexoProducer {
 public:
     TexoProducer(TexoExporter &exporter);
 
+    virtual void End();
+
     virtual void Put(char c);
     virtual void Put(const Texo &piece);
 
     virtual void Put(const TexoHeader &piece);
-    virtual void Put(const TexoParagraph &piece);
+    virtual void Put(const TexoParagraph &piece) = 0;
     virtual void Put(const TexoCode &piece);
     virtual void Put(const TexoQuote &piece);
 
@@ -25,7 +27,6 @@ public:
 
     virtual void Put(const TexoImage &piece);
     virtual void Put(const TexoLink &piece);
-    virtual void Put(const TexoLineBreak &piece);
     virtual void Put(const TexoHorizontalRule &piece);
 
 protected:
diff --git a/src/texo.cpp b/src/texo.cpp
index fa4b4be..99d74f8 100644
--- a/src/texo.cpp
+++ b/src/texo.cpp
@@ -4,29 +4,5 @@
 Texo::Texo(char c): c(c)
 {}
 
-TexoHeader::TexoHeader(int level, bool closing): level(level), closing(closing)
-{}
-
-TexoParagraph::TexoParagraph(bool closing): closing(closing)
-{}
-
-TexoCode::TexoCode(bool closing): closing(closing)
-{}
-
-TexoQuote::TexoQuote(bool closing): closing(closing)
-{}
-
-TexoMono::TexoMono(bool closing): closing(closing)
-{}
-
-TexoBold::TexoBold(bool closing): closing(closing)
-{}
-
-TexoItalic::TexoItalic(bool closing): closing(closing)
-{}
-
-TexoUnderline::TexoUnderline(bool closing): closing(closing)
-{}
-
-TexoStrike::TexoStrike(bool closing): closing(closing)
+TexoHeader::TexoHeader(int level): level(level)
 {}
diff --git a/src/texo.hpp b/src/texo.hpp
index 82c384e..b8ae394 100644
--- a/src/texo.hpp
+++ b/src/texo.hpp
@@ -1,6 +1,5 @@
 #ifndef TEXO_INCLUDED_TEXO
 #define TEXO_INCLUDED_TEXO
-// TODO: lists & maybe tables
 
 #include 
 
@@ -10,57 +9,35 @@ struct Texo {
     char c;
 };
 
+
 /*
  * Texo Blocks
  */
 struct TexoHeader {
-    TexoHeader(int level, bool closing = false);
-    int  level; // Number >= 1, bigger for bigger.
-    bool closing;
+    TexoHeader(int level);
+    int level;  // Number >= 1, bigger for bigger.
 };
 
-struct TexoParagraph {
-    TexoParagraph(bool closing = false);
-    bool closing;
-};
+struct TexoParagraph {};
 
-struct TexoCode {
-    TexoCode(bool closing = false);
-    bool closing;
-};
+struct TexoCode {};
+
+struct TexoQuote {};
 
-struct TexoQuote {
-    TexoQuote(bool closing = false);
-    bool closing;
-};
 
 /*
  * Texo Decorators
  */
-struct TexoMono {
-    TexoMono(bool closing = false);
-    bool closing;
-};
+struct TexoMono {};
 
-struct TexoBold {
-    TexoBold(bool closing = false);
-    bool closing;
-};
+struct TexoBold {};
 
-struct TexoItalic {
-    TexoItalic(bool closing = false);
-    bool closing;
-};
+struct TexoItalic {};
 
-struct TexoUnderline {
-    TexoUnderline(bool closing = false);
-    bool closing;
-};
+struct TexoUnderline {};
+
+struct TexoStrike {};
 
-struct TexoStrike {
-    TexoStrike(bool closing = false);
-    bool closing;
-};
 
 /*
  * Texo Signals
@@ -78,11 +55,7 @@ struct TexoLink {
     ScriptVariable title;
 };
 
-struct TexoLineBreak {
-};
-
-struct TexoHorizontalRule {
-};
+struct TexoHorizontalRule {};
 
 
 #endif
-- 
cgit v1.2.3