From 3047ed6100a56a529f26e43ada0a3fc3c3815c3e Mon Sep 17 00:00:00 2001
From: Aleksey Veresov
Date: Fri, 8 Nov 2019 19:49:40 +0300
Subject: [texo] Full rewrite of inner representation.
---
src/exporter.cpp | 11 +-
src/exporter.hpp | 8 +-
src/file.cpp | 10 +-
src/file.hpp | 10 +-
src/html.cpp | 235 ++++++++++++++++--------------------
src/html.hpp | 70 +++++------
src/importer.cpp | 49 ++++++--
src/importer.hpp | 24 +++-
src/lines.cpp | 52 ++++----
src/lines.hpp | 25 ++--
src/markdown.cpp | 355 ++++++++++++++++++++++++++-----------------------------
src/markdown.hpp | 49 +++++---
src/plain.cpp | 132 ++++++++++++---------
src/plain.hpp | 26 ++--
src/producer.cpp | 311 ++++++++++++++++++++++++++++++++++++++++++++----
src/producer.hpp | 189 ++++++++++++++++++++++++++---
src/script.cpp | 21 ++++
src/script.hpp | 25 ++++
src/str.cpp | 15 ---
src/str.hpp | 19 ---
src/texo.cpp | 8 --
src/texo.hpp | 61 ----------
22 files changed, 1074 insertions(+), 631 deletions(-)
create mode 100644 src/script.cpp
create mode 100644 src/script.hpp
delete mode 100644 src/str.cpp
delete mode 100644 src/str.hpp
delete mode 100644 src/texo.cpp
delete mode 100644 src/texo.hpp
diff --git a/src/exporter.cpp b/src/exporter.cpp
index 3baa99e..b9a5b3f 100644
--- a/src/exporter.cpp
+++ b/src/exporter.cpp
@@ -1,10 +1,15 @@
#include "exporter.hpp"
-void TexoExporter::Put(const ScriptVariable &str)
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Texo Exporter
+ */
+bool TexoExporter::Put(const ScriptVariable &str)
{
+ bool ok = true;
const int len = str.Length();
- for (int i = 0; i < len; ++i) {
- Put(str[i]);
+ for (int i = 0; ok && i < len; ++i) {
+ ok = Put(str[i]);
}
+ return ok;
}
diff --git a/src/exporter.hpp b/src/exporter.hpp
index 6a0be93..a20f695 100644
--- a/src/exporter.hpp
+++ b/src/exporter.hpp
@@ -4,10 +4,14 @@
#include
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Texo Exporter
+ * Texo interface for outputting.
+ */
class TexoExporter {
public:
- virtual void Put(char c) = 0;
- virtual void Put(const ScriptVariable &str);
+ virtual bool Put(char c) = 0;
+ virtual bool Put(const ScriptVariable &str);
};
diff --git a/src/file.cpp b/src/file.cpp
index ae41bde..221ff81 100644
--- a/src/file.cpp
+++ b/src/file.cpp
@@ -1,15 +1,21 @@
#include "file.hpp"
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Texo File Exporter
+ */
TexoExporterFile::TexoExporterFile(FILE *file): file(file)
{}
-void TexoExporterFile::Put(char c)
+
+bool TexoExporterFile::Put(char c)
{
fputc(c, file);
+ return !ferror(file);
}
-void TexoExporterFile::Put(const ScriptVariable &str)
+bool TexoExporterFile::Put(const ScriptVariable &str)
{
fwrite(str.c_str(), 1, str.Length(), file);
+ return !ferror(file);
}
diff --git a/src/file.hpp b/src/file.hpp
index 1cfea0b..5f8adb6 100644
--- a/src/file.hpp
+++ b/src/file.hpp
@@ -5,12 +5,18 @@
#include
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Texo File Exporter
+ * Simple utility class to make output into FILE *variable.
+ */
class TexoExporterFile: public TexoExporter {
public:
TexoExporterFile(FILE *file);
- void Put(char c);
- void Put(const ScriptVariable &str);
+
+ bool Put(char c);
+ bool Put(const ScriptVariable &str);
+
private:
FILE *file;
diff --git a/src/html.cpp b/src/html.cpp
index f40b8bd..ed67781 100644
--- a/src/html.cpp
+++ b/src/html.cpp
@@ -2,188 +2,153 @@
TexoProducerHTML::TexoProducerHTML(TexoExporter &exporter):
- TexoProducer(exporter), opened_block(none)
+ TexoProducerStrict(exporter)
{}
-void TexoProducerHTML::End()
+
+bool TexoProducerHTML::TruePut(char c)
{
- Close();
- opened_block = none;
+ switch (c) {
+ case '<': return exporter.Put("<"); break;
+ case '>': return exporter.Put(">"); break;
+ case '&': return exporter.Put("&"); break;
+ default: return exporter.Put(c);
+ }
}
-void TexoProducerHTML::Put(const Texo &piece)
+
+bool TexoProducerHTML::StartCode()
{
- switch (piece.c) {
- case '<': exporter.Put("<"); break;
- case '>': exporter.Put(">"); break;
- case '&': exporter.Put("&"); break;
- default: exporter.Put(piece.c); break;
- }
+ return exporter.Put("\n\n");
}
-void TexoProducerHTML::Put(const TexoHeader &piece)
+bool TexoProducerHTML::StartHeader(int level)
{
- Close();
- if (piece.level <= 1) {
- exporter.Put("\n\n");
- opened_block = header_6;
- } else if (piece.level == 2) {
- exporter.Put("\n\n");
- opened_block = header_5;
- } else if (piece.level == 3) {
- exporter.Put("\n\n");
- opened_block = header_4;
- } else if (piece.level == 4) {
- exporter.Put("\n\n");
- opened_block = header_3;
- } else if (piece.level == 5) {
- exporter.Put("\n\n");
- opened_block = header_2;
+ if (level <= 1) {
+ return exporter.Put("\n\n");
+ } else if (level == 2) {
+ return exporter.Put("\n\n");
+ } else if (level == 3) {
+ return exporter.Put("\n\n");
+ } else if (level == 4) {
+ return exporter.Put("\n\n");
+ } else if (level == 5) {
+ return exporter.Put("\n\n");
} else {
- exporter.Put("\n\n");
- opened_block = header_1;
+ return exporter.Put("\n\n");
}
}
-void TexoProducerHTML::Put(const TexoParagraph &piece)
+bool TexoProducerHTML::StartParagraph()
{
- Close();
- opened_block = paragraph;
- exporter.Put("\n
\n");
+ return exporter.Put("\n
\n");
}
-void TexoProducerHTML::Put(const TexoCode &piece)
+bool TexoProducerHTML::StartQuote()
{
- Close();
- opened_block = code;
- exporter.Put("\n
\n");
+ return exporter.Put("\n\n");
}
-void TexoProducerHTML::Put(const TexoQuote &piece)
+bool TexoProducerHTML::CloseCode()
{
- Close();
- opened_block = quote;
- exporter.Put("\n
\n");
+ return exporter.Put("\n
\n");
}
-void TexoProducerHTML::Put(const TexoMono &piece)
+bool TexoProducerHTML::CloseHeader(int level)
{
- static bool closing = false;
- if (closing) {
- exporter.Put("");
+ if (level <= 1) {
+ return exporter.Put("\n\n");
+ } else if (level == 2) {
+ return exporter.Put("\n\n");
+ } else if (level == 3) {
+ return exporter.Put("\n\n");
+ } else if (level == 4) {
+ return exporter.Put("\n\n");
+ } else if (level == 5) {
+ return exporter.Put("\n\n");
} else {
- exporter.Put("");
+ return exporter.Put("\n\n");
}
- closing = !closing;
}
-void TexoProducerHTML::Put(const TexoBold &piece)
+bool TexoProducerHTML::CloseParagraph()
{
- static bool closing = false;
- if (closing) {
- exporter.Put("");
- } else {
- exporter.Put("");
- }
- closing = !closing;
+ return exporter.Put("\n
\n");
}
-void TexoProducerHTML::Put(const TexoItalic &piece)
+bool TexoProducerHTML::CloseQuote()
{
- static bool closing = false;
- if (closing) {
- exporter.Put("");
- } else {
- exporter.Put("");
- }
- closing = !closing;
+ return exporter.Put("\n\n");
}
-void TexoProducerHTML::Put(const TexoUnderline &piece)
+
+bool TexoProducerHTML::StartBold() { return exporter.Put(""); }
+bool TexoProducerHTML::StartItalic() { return exporter.Put(""); }
+bool TexoProducerHTML::StartMono() { return exporter.Put(""); }
+bool TexoProducerHTML::StartStrike() { return exporter.Put(""); }
+bool TexoProducerHTML::StartUnderline() { return exporter.Put(""); }
+
+bool TexoProducerHTML::CloseBold() { return exporter.Put("
"); }
+bool TexoProducerHTML::CloseItalic() { return exporter.Put(""); }
+bool TexoProducerHTML::CloseMono() { return exporter.Put(""); }
+bool TexoProducerHTML::CloseStrike() { return exporter.Put(""); }
+bool TexoProducerHTML::CloseUnderline() { return exporter.Put(""); }
+
+bool TexoProducerHTML::StartLink(
+ const ScriptVariable &link,
+ const ScriptVariable &title
+)
{
- static bool closing = false;
- if (closing) {
- exporter.Put("");
- } else {
- exporter.Put("");
+ bool ok = true;
+ if (link != "") {
+ ok = ok && exporter.Put("");
}
- closing = !closing;
+ return ok;
}
-void TexoProducerHTML::Put(const TexoStrike &piece)
+bool TexoProducerHTML::CloseLink(
+ const ScriptVariable &link,
+ const ScriptVariable &title
+)
{
- static bool closing = false;
- if (closing) {
- exporter.Put("");
+ if (link != "") {
+ return exporter.Put("");
} else {
- exporter.Put("");
+ return true;
}
- closing = !closing;
}
-void TexoProducerHTML::Put(const TexoImage &piece)
-{
- if (piece.path != "") {
- bool link = piece.link != "";
- bool title = piece.title != "";
- if (link) {
- exporter.Put("");
- }
- exporter.Put("");
- if (link) {
- exporter.Put("");
- }
- }
-}
-void TexoProducerHTML::Put(const TexoLink &piece)
+bool TexoProducerHTML::TruePutImage(
+ const ScriptVariable &src,
+ const ScriptVariable &alt,
+ const ScriptVariable &title
+)
{
- if (piece.text != "" && piece.link != "") {
- exporter.Put("");
- exporter.Put(piece.text);
- exporter.Put("");
+ ok = ok && exporter.Put("'/>");
}
+ return ok;
}
-void TexoProducerHTML::Put(const TexoHorizontalRule &piece)
-{
- exporter.Put("\n
\n");
-}
-
-void TexoProducerHTML::Close()
+bool TexoProducerHTML::TruePutHorizontalRule()
{
- switch (opened_block) {
- case none: break;
- case header_1: exporter.Put("\n\n"); break;
- case header_2: exporter.Put("\n\n"); break;
- case header_3: exporter.Put("\n\n"); break;
- case header_4: exporter.Put("\n\n"); break;
- case header_5: exporter.Put("\n\n"); break;
- case header_6: exporter.Put("\n\n"); break;
- case paragraph: exporter.Put("\n\n"); break;
- case quote: exporter.Put("\n\n"); break;
- case code: exporter.Put("\n\n"); break;
- }
+ return exporter.Put("\n
\n");
}
diff --git a/src/html.hpp b/src/html.hpp
index b96200f..aa22cf1 100644
--- a/src/html.hpp
+++ b/src/html.hpp
@@ -6,44 +6,44 @@
#include "importer.hpp"
-class TexoProducerHTML: public TexoProducer {
+class TexoProducerHTML: public TexoProducerStrict {
public:
TexoProducerHTML(TexoExporter &exporter);
- void End();
-
- void Put(const Texo &piece);
-
- void Put(const TexoHeader &piece);
- void Put(const TexoParagraph &piece);
- void Put(const TexoCode &piece);
- void Put(const TexoQuote &piece);
-
- void Put(const TexoMono &piece);
- void Put(const TexoBold &piece);
- void Put(const TexoItalic &piece);
- void Put(const TexoUnderline &piece);
- void Put(const TexoStrike &piece);
-
- void Put(const TexoImage &piece);
- void Put(const TexoLink &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;
+protected:
+ bool TruePut(char c);
+
+ bool StartCode();
+ bool StartHeader(int level);
+ bool StartParagraph();
+ bool StartQuote();
+
+ bool CloseCode();
+ bool CloseHeader(int level);
+ bool CloseParagraph();
+ bool CloseQuote();
+
+ bool StartBold();
+ bool StartItalic();
+ bool StartMono();
+ bool StartStrike();
+ bool StartUnderline();
+
+ bool CloseBold();
+ bool CloseItalic();
+ bool CloseMono();
+ bool CloseStrike();
+ bool CloseUnderline();
+
+ bool StartLink(const ScriptVariable &link, const ScriptVariable &title);
+ bool CloseLink(const ScriptVariable &link, const ScriptVariable &title);
+
+ bool TruePutImage(
+ const ScriptVariable &src,
+ const ScriptVariable &alt,
+ const ScriptVariable &title
+ );
+ bool TruePutHorizontalRule();
};
diff --git a/src/importer.cpp b/src/importer.cpp
index af475a5..73ff060 100644
--- a/src/importer.cpp
+++ b/src/importer.cpp
@@ -1,27 +1,58 @@
#include "importer.hpp"
-TexoImporter::TexoImporter(TexoProducer &producer): producer(producer)
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Texo Importer
+ */
+TexoImporter::TexoImporter(TexoProducer &producer):
+ producer(producer), ok(true)
{}
-void TexoImporter::End()
+TexoImporter::~TexoImporter() { End(); }
+
+
+bool TexoImporter::End()
+{
+ return ok = ok && TrueEnd();
+}
+
+bool TexoImporter::Put(char c)
+{
+ return ok = ok && TruePut(c);
+}
+
+bool TexoImporter::Put(const ScriptVariable &s)
{
- producer.End();
+ return ok = ok && TruePut(s);
}
-void TexoImporter::Put(const ScriptVariable &str)
+bool TexoImporter::Put(FILE *f)
+{
+ return ok = ok && TruePut(f);
+}
+
+
+bool TexoImporter::TrueEnd()
+{
+ return producer.End();
+}
+
+
+bool TexoImporter::TruePut(const ScriptVariable &str)
{
const int len = str.Length();
- for (int i = 0; i < len; ++i) {
- Put(str[i]);
+ for (int i = 0; ok && i < len; ++i) {
+ ok = TruePut(str[i]);
}
+ return ok;
}
-void TexoImporter::Put(FILE *file)
+bool TexoImporter::TruePut(FILE *file)
{
if (file) {
- for (int c = fgetc(file); c != EOF; c = fgetc(file)) {
- Put(c);
+ for (int c = fgetc(file); ok && c != EOF; c = fgetc(file)) {
+ ok = TruePut(c);
}
}
+ return ok;
}
diff --git a/src/importer.hpp b/src/importer.hpp
index 3a31fab..9280a34 100644
--- a/src/importer.hpp
+++ b/src/importer.hpp
@@ -5,18 +5,34 @@
#include
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Texo Importer
+ * Texo interface for parsers from input characters into inner representation,
+ * described by Texo Producer.
+ */
class TexoImporter {
public:
TexoImporter(TexoProducer &producer);
+ ~TexoImporter();
- virtual void End();
- virtual void Put(char c) = 0;
- virtual void Put(const ScriptVariable &str);
- virtual void Put(FILE *file);
+ bool End();
+ bool Put(char c);
+ bool Put(const ScriptVariable &s);
+ bool Put(FILE *f);
+
protected:
+ virtual bool TrueEnd();
+
+
+ virtual bool TruePut(char c) = 0;
+ virtual bool TruePut(const ScriptVariable &str);
+ virtual bool TruePut(FILE *file);
+
+
TexoProducer &producer;
+ bool ok;
};
diff --git a/src/lines.cpp b/src/lines.cpp
index bacf048..c7b605b 100644
--- a/src/lines.cpp
+++ b/src/lines.cpp
@@ -1,85 +1,91 @@
#include "lines.hpp"
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Texo Lines Producer
+ */
TexoProducerLines::TexoProducerLines(TexoExporter &exporter):
TexoProducer(exporter), newline(true)
{}
-void TexoProducerLines::End()
+
+bool TexoProducerLines::End()
{
if (!newline) {
exporter.Put('\n');
newline = true;
}
+ return true;
}
-void TexoProducerLines::Put(const Texo &piece)
+
+bool TexoProducerLines::Put(char c)
{
- if (piece.c == '\n') {
+ if (c == '\n') {
if (!newline) {
exporter.Put(' ');
newline = true;
}
} else {
- exporter.Put(piece.c);
+ exporter.Put(c);
newline = false;
}
+ return true;
}
-void TexoProducerLines::Put(const TexoParagraph &piece)
+
+bool TexoProducerLines::Paragraph()
{
if (!newline) {
exporter.Put('\n');
newline = true;
}
+ return true;
}
-void TexoProducerLines::Put(const TexoQuote &piece)
+bool TexoProducerLines::Quote()
{
if (!newline) {
exporter.Put('\n');
}
exporter.Put("> ");
newline = false;
+ return true;
}
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Texo Lines Importer
+ */
TexoImporterLines::TexoImporterLines(TexoProducer &producer):
TexoImporter(producer), newline(true), quote(false)
{}
-void TexoImporterLines::Put(char c)
+
+bool TexoImporterLines::TruePut(char c)
{
if (c == '\n') {
if (!newline) {
newline = true;
quote = false;
}
+ return true;
} else if (newline) {
+ newline = false;
if (c == '>') {
- producer.Put(TexoQuote());
quote = true;
+ return producer.Quote();
} else {
- producer.Put(TexoParagraph());
- producer.Put(c);
+ return producer.Paragraph() && producer.Put(c);
}
- newline = false;
} else if (quote) {
if (c != ' ') {
quote = false;
- producer.Put(c);
+ return producer.Put(c);
+ } else {
+ return true;
}
} else {
- producer.Put(c);
+ return producer.Put(c);
}
}
-
-void TexoImporterLines::Put(const ScriptVariable &str)
-{
- TexoImporter::Put(str);
-}
-
-void TexoImporterLines::Put(FILE *file)
-{
- TexoImporter::Put(file);
-}
diff --git a/src/lines.hpp b/src/lines.hpp
index d6ce555..7049919 100644
--- a/src/lines.hpp
+++ b/src/lines.hpp
@@ -6,29 +6,40 @@
#include "importer.hpp"
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Texo Lines Producer
+ */
class TexoProducerLines: public TexoProducer {
public:
TexoProducerLines(TexoExporter &exporter);
- void End();
- void Put(const Texo &piece);
+ bool End();
+
+
+ bool Put(char c);
+
+
+ bool Paragraph();
+ bool Quote();
- void Put(const TexoParagraph &piece);
- void Put(const TexoQuote &piece);
private:
bool newline;
};
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Texo Lines Importer
+ */
class TexoImporterLines: public TexoImporter {
public:
TexoImporterLines(TexoProducer &producer);
- void Put(char c);
- void Put(const ScriptVariable &str);
- void Put(FILE *file);
+
+protected:
+ bool TruePut(char c);
+
private:
bool newline;
diff --git a/src/markdown.cpp b/src/markdown.cpp
index facba67..6931461 100644
--- a/src/markdown.cpp
+++ b/src/markdown.cpp
@@ -6,186 +6,180 @@ TexoProducerMarkdown::TexoProducerMarkdown(TexoExporter &exporter):
quoted(false), newline(false), header(false), code(false), nospace(true)
{}
-void TexoProducerMarkdown::End()
+bool TexoProducerMarkdown::End()
{
if (!newline) {
- exporter.Put('\n');
newline = true;
+ return exporter.Put('\n');
}
+ return true;
}
-void TexoProducerMarkdown::Put(const Texo &piece)
+bool TexoProducerMarkdown::Put(char c)
{
- char c = piece.c;
+ bool ok = true;
if (c == '\n') {
if (code) {
- exporter.Put('\n');
+ ok = exporter.Put('\n');
} else if (quoted) {
- exporter.Put("\n> ");
+ ok = exporter.Put("\n> ");
} else if (!nospace) {
if (header || newline) {
- exporter.Put(' ');
+ ok = exporter.Put(' ');
} else {
- exporter.Put('\n');
+ ok = exporter.Put('\n');
newline = true;
}
}
} else {
if (c == '*' || c == '_' || c == '`' || c == '+' || c == '~') {
- exporter.Put('\\');
+ ok = exporter.Put('\\');
}
- exporter.Put(c);
+ ok = ok && exporter.Put(c);
newline = false;
nospace = false;
}
+ return ok;
}
-void TexoProducerMarkdown::Put(const TexoHeader &piece)
+
+bool TexoProducerMarkdown::Code()
{
- 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("## ");
+ bool ok = Close();
+ code = true;
+ return ok && exporter.Put("```\n");
+}
+
+bool TexoProducerMarkdown::Header(int level)
+{
+ bool ok = Close();
+ if (level <= 1) {
+ ok = ok && exporter.Put("###### ");
+ } else if (level == 2) {
+ ok = ok && exporter.Put("##### ");
+ } else if (level == 3) {
+ ok = ok && exporter.Put("#### ");
+ } else if (level == 4) {
+ ok = ok && exporter.Put("### ");
+ } else if (level == 5) {
+ ok = ok && exporter.Put("## ");
} else {
- exporter.Put("# ");
+ ok = ok && exporter.Put("# ");
}
- header = true;
+ header = true;
+ return ok;
}
-void TexoProducerMarkdown::Put(const TexoParagraph &piece)
+bool TexoProducerMarkdown::Paragraph()
{
- Close();
+ return Close();
}
-void TexoProducerMarkdown::Put(const TexoCode &piece)
+bool TexoProducerMarkdown::Quote()
{
- Close();
- exporter.Put("```\n");
- code = true;
-}
-
-void TexoProducerMarkdown::Put(const TexoQuote &piece)
-{
- Close();
- exporter.Put("> ");
+ bool ok = Close();
quoted = true;
+ return ok && exporter.Put("> ");
}
-void TexoProducerMarkdown::Put(const TexoMono &piece)
-{
- exporter.Put("`");
- newline = false;
- nospace = false;
-}
-void TexoProducerMarkdown::Put(const TexoBold &piece)
-{
- exporter.Put("**");
- newline = false;
- nospace = false;
-}
+bool TexoProducerMarkdown::Mono() { return Mod("`"); }
+bool TexoProducerMarkdown::Bold() { return Mod("**"); }
+bool TexoProducerMarkdown::Italic() { return Mod("_"); }
+bool TexoProducerMarkdown::Underline() { return Mod("++"); }
+bool TexoProducerMarkdown::Strike() { return Mod("~~"); }
-void TexoProducerMarkdown::Put(const TexoItalic &piece)
+bool TexoProducerMarkdown::Link(
+ const ScriptVariable &link,
+ const ScriptVariable &title
+)
{
- 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;
+ bool ok = Link();
+ if (link != "") {
+ ok = ok && exporter.Put('[');
+ link_link = link;
+ link_title = title;
+ }
+ return ok;
}
-void TexoProducerMarkdown::Put(const TexoImage &piece)
+bool TexoProducerMarkdown::Link()
{
- if (piece.path != "") {
- const bool link = piece.link != "";
- if (link) {
- exporter.Put('[');
- }
- exporter.Put("![");
- exporter.Put(piece.alt);
- exporter.Put("](");
- exporter.Put(piece.path);
- if (piece.title != "") {
- exporter.Put(" \"");
- exporter.Put(piece.title);
- exporter.Put('"');
- }
- exporter.Put(')');
- if (link) {
- exporter.Put("](");
- exporter.Put(piece.link);
- if (piece.title != "") {
- exporter.Put(" \"");
- exporter.Put(piece.title);
- exporter.Put('"');
- }
- exporter.Put(')');
+ bool ok = true;
+ if (link_link != "") {
+ ok = ok && exporter.Put("](");
+ ok = ok && exporter.Put(link_link);
+ if (link_title != "") {
+ ok = ok && exporter.Put(" \"");
+ ok = ok && exporter.Put(link_title);
+ ok = ok && exporter.Put('"');
}
+ ok = ok && exporter.Put(')');
}
- newline = false;
- nospace = false;
-}
-
-void TexoProducerMarkdown::Put(const TexoLink &piece)
-{
- if (piece.text != "") {
- exporter.Put('[');
- exporter.Put(piece.text);
- exporter.Put("](");
- exporter.Put(piece.link);
- if (piece.title != "") {
- exporter.Put(" \"");
- exporter.Put(piece.title);
- exporter.Put('"');
+ return ok;
+}
+
+
+bool TexoProducerMarkdown::PutImage(
+ const ScriptVariable &src,
+ const ScriptVariable &alt,
+ const ScriptVariable &title
+)
+{
+ bool ok = true;
+ if (src != "") {
+ ok = ok && exporter.Put("![");
+ ok = ok && exporter.Put(alt);
+ ok = ok && exporter.Put("](");
+ ok = ok && exporter.Put(src);
+ if (title != "") {
+ ok = ok && exporter.Put(" \"");
+ ok = ok && exporter.Put(title);
+ ok = ok && exporter.Put('"');
}
- exporter.Put(')');
+ ok = ok && exporter.Put(')');
}
newline = false;
nospace = false;
+ return ok;
}
-void TexoProducerMarkdown::Put(const TexoHorizontalRule &piece)
+bool TexoProducerMarkdown::PutHorizontalRule()
{
+ bool ok = true;
if (!newline && !nospace) {
- exporter.Put('\n');
+ ok = ok && exporter.Put('\n');
}
- exporter.Put("--------------------------------------------------\n");
nospace = true;
+ return ok && exporter.Put(
+ "--------------------------------------------------\n"
+ );
}
-void TexoProducerMarkdown::Close()
+
+bool TexoProducerMarkdown::Mod(const ScriptVariable &str)
{
+ newline = false;
+ nospace = false;
+ return exporter.Put(str);
+}
+
+bool TexoProducerMarkdown::Close()
+{
+ bool ok = true;
if (code) {
- exporter.Put("\n```");
+ ok = exporter.Put("\n```");
code = false;
nospace = false;
newline = false;
}
if (!newline && !nospace) {
- exporter.Put("\n\n");
+ ok = ok && exporter.Put("\n\n");
}
header = false;
quoted = false;
nospace = true;
+ return ok;
}
@@ -193,10 +187,10 @@ TexoImporterMarkdown::TexoImporterMarkdown(TexoProducer &producer):
TexoImporter(producer), state(start)
{}
-void TexoImporterMarkdown::Put(char c)
+
+bool TexoImporterMarkdown::TruePut(char c)
{
switch (state) {
- case error: break;
case start: Start(c); break;
case text: Text(c); break;
case header_text: HeaderText(c); break;
@@ -218,17 +212,9 @@ void TexoImporterMarkdown::Put(char c)
case header_pre: HeaderPre(c); break;
case code: Code(c); break;
}
+ return ok;
}
-void TexoImporterMarkdown::Put(const ScriptVariable &str)
-{
- TexoImporter::Put(str);
-}
-
-void TexoImporterMarkdown::Put(FILE *file)
-{
- TexoImporter::Put(file);
-}
void TexoImporterMarkdown::Start(char c)
{
@@ -238,17 +224,17 @@ void TexoImporterMarkdown::Start(char c)
state = header;
header_level = 6;
} else if (c == '>') {
- producer.Put(TexoQuote());
+ ok = producer.Quote();
state = quote_pre;
} else if (c == '-') {
- producer.Put(TexoParagraph());
+ ok = producer.Paragraph();
state = rule;
rule_dash_count = 1;
} else if (c == '`') {
state = code;
code_quote_count = 1;
} else {
- producer.Put(TexoParagraph());
+ ok = producer.Paragraph();
state = text;
Put(c);
}
@@ -258,14 +244,14 @@ void TexoImporterMarkdown::Text(char c)
{
back = text;
switch (c) {
- case '\\': state = backslash; break;
- case '\n': state = newline; break;
- case '*': state = asterisk; break;
- case '_': state = underline; break;
- case '+': state = plus; break;
- case '~': state = tilde; break;
- case '`': Backquote(); break;
- default: producer.Put(c);
+ case '\\': state = backslash; break;
+ case '\n': state = newline; break;
+ case '*': state = asterisk; break;
+ case '_': state = underline; break;
+ case '+': state = plus; break;
+ case '~': state = tilde; break;
+ case '`': Backquote(); break;
+ default: ok = producer.Put(c);
}
}
@@ -273,14 +259,14 @@ void TexoImporterMarkdown::HeaderText(char c)
{
back = header_text;
switch (c) {
- case '\\': state = backslash; break;
- case '\n': state = paragraph; break;
- case '*': state = asterisk; break;
- case '_': state = underline; break;
- case '+': state = plus; break;
- case '~': state = tilde; break;
- case '`': Backquote(); break;
- default: producer.Put(c);
+ case '\\': state = backslash; break;
+ case '\n': state = paragraph; break;
+ case '*': state = asterisk; break;
+ case '_': state = underline; break;
+ case '+': state = plus; break;
+ case '~': state = tilde; break;
+ case '`': Backquote(); break;
+ default: ok = producer.Put(c);
}
}
@@ -303,14 +289,14 @@ void TexoImporterMarkdown::QuoteText(char c)
case '+': state = plus; break;
case '~': state = tilde; break;
case '`': Backquote(); break;
- default: producer.Put(c);
+ default: ok = producer.Put(c);
}
}
void TexoImporterMarkdown::QuoteNewline(char c)
{
if (c == '>') {
- producer.Put('\n');
+ ok = producer.Put('\n');
state = quote_pre;
} else {
state = paragraph;
@@ -322,14 +308,13 @@ void TexoImporterMarkdown::CodeText(char c)
{
back = code_text;
switch (c) {
- case '\\': state = backslash; break;
- case '\n': state = code_newline; break;
- case '*': state = asterisk; break;
- case '_': state = underline; break;
- case '+': state = plus; break;
- case '~': state = tilde; break;
- case '`': state = error; break;
- default: producer.Put(c);
+ case '\\': state = backslash; break;
+ case '\n': state = code_newline; break;
+ case '*': state = asterisk; break;
+ case '_': state = underline; break;
+ case '+': state = plus; break;
+ case '~': state = tilde; break;
+ default: ok = producer.Put(c);
}
}
@@ -339,9 +324,9 @@ void TexoImporterMarkdown::CodeNewline(char c)
state = code_end;
code_quote_count = 1;
} else {
- producer.Put('\n');
+ ok = producer.Put('\n');
state = code_text;
- CodeText(c);
+ Put(c);
}
}
@@ -353,16 +338,16 @@ void TexoImporterMarkdown::CodeEnd(char c)
if (code_quote_count == 3) {
state = paragraph;
} else {
- state = error;
+ ok = false;
}
} else {
- state = error;
+ ok = false;
}
}
void TexoImporterMarkdown::Backslash(char c)
{
- producer.Put(c);
+ ok = producer.Put(c);
state = back;
}
@@ -370,9 +355,9 @@ void TexoImporterMarkdown::Asterisk(char c)
{
state = back;
if (c == '*') {
- producer.Put(TexoBold());
+ ok = producer.Bold();
} else {
- producer.Put(TexoItalic());
+ ok = producer.Italic();
Put(c);
}
}
@@ -381,9 +366,9 @@ void TexoImporterMarkdown::Underline(char c)
{
state = back;
if (c == '_') {
- producer.Put(TexoBold());
+ ok = producer.Bold();
} else {
- producer.Put(TexoItalic());
+ ok = producer.Italic();
Put(c);
}
}
@@ -392,9 +377,9 @@ void TexoImporterMarkdown::Plus(char c)
{
state = back;
if (c == '+') {
- producer.Put(TexoUnderline());
+ ok = producer.Underline();
} else {
- producer.Put('+');
+ ok = producer.Put('+');
Put(c);
}
}
@@ -403,9 +388,9 @@ void TexoImporterMarkdown::Tilde(char c)
{
state = back;
if (c == '~') {
- producer.Put(TexoStrike());
+ ok = producer.Strike();
} else {
- producer.Put('~');
+ ok = producer.Put('~');
Put(c);
}
}
@@ -418,7 +403,7 @@ void TexoImporterMarkdown::Newline(char c)
state = header;
header_level = 6;
} else if (c == '>') {
- producer.Put(TexoQuote());
+ ok = producer.Quote();
state = quote_pre;
} else if (c == '-') {
state = rule;
@@ -427,9 +412,9 @@ void TexoImporterMarkdown::Newline(char c)
state = code;
code_quote_count = 1;
} else {
- producer.Put('\n');
+ ok = producer.Put('\n');
state = text;
- Text(c);
+ Put(c);
}
}
@@ -438,15 +423,15 @@ void TexoImporterMarkdown::Rule(char c)
if (c == '-') {
++rule_dash_count;
} else if (c == '\n' && rule_dash_count >= 3) {
- producer.Put(TexoHorizontalRule());
+ ok = producer.PutHorizontalRule();
state = newline;
} else {
- producer.Put(' ');
- for (int i = 0; i < rule_dash_count; ++i) {
- producer.Put('-');
+ ok = producer.Put(' ');
+ for (int i = 0; ok && i < rule_dash_count; ++i) {
+ ok = producer.Put('-');
}
state = text;
- Text(c);
+ Put(c);
}
}
@@ -456,19 +441,19 @@ void TexoImporterMarkdown::Paragraph(char c)
state = header;
header_level = 6;
} else if (c == '>') {
- producer.Put(TexoQuote());
+ ok = producer.Quote();
state = quote_pre;
} else if (c == '-') {
- producer.Put(TexoParagraph());
+ ok = producer.Paragraph();
state = rule;
rule_dash_count = 1;
} else if (c == '`') {
state = code;
code_quote_count = 1;
} else if (c != '\n') {
- producer.Put(TexoParagraph());
+ ok = producer.Paragraph();
state = text;
- Text(c);
+ Put(c);
}
}
@@ -478,13 +463,13 @@ void TexoImporterMarkdown::Header(char c)
if (header_level > 1) {
--header_level;
} else {
- state = error;
+ ok = false;
}
} else if (c == ' ') {
- producer.Put(TexoHeader(header_level));
+ ok = producer.Header(header_level);
state = header_pre;
} else {
- state = error;
+ ok = false;
}
}
@@ -502,17 +487,17 @@ void TexoImporterMarkdown::Code(char c)
++code_quote_count;
} else if (c == '\n') {
if (code_quote_count == 3) {
- producer.Put(TexoCode());
+ ok = producer.Code();
state = code_text;
} else {
- state = error;
+ ok = false;
}
} else {
- state = error;
+ ok = false;
}
}
void TexoImporterMarkdown::Backquote()
{
- producer.Put(TexoMono());
+ ok = producer.Mono();
}
diff --git a/src/markdown.hpp b/src/markdown.hpp
index f9b25f4..ee8aee8 100644
--- a/src/markdown.hpp
+++ b/src/markdown.hpp
@@ -10,33 +10,44 @@ class TexoProducerMarkdown: public TexoProducer {
public:
TexoProducerMarkdown(TexoExporter &exporter);
- void End();
+ bool End();
- void Put(const Texo &piece);
+ bool Put(char c);
- void Put(const TexoHeader &piece);
- void Put(const TexoParagraph &piece);
- void Put(const TexoCode &piece);
- void Put(const TexoQuote &piece);
+ bool Code();
+ bool Header(int level);
+ bool Paragraph();
+ bool Quote();
- void Put(const TexoMono &piece);
- void Put(const TexoBold &piece);
- void Put(const TexoItalic &piece);
- void Put(const TexoUnderline &piece);
- void Put(const TexoStrike &piece);
+ bool Bold();
+ bool Italic();
+ bool Mono();
+ bool Strike();
+ bool Underline();
- void Put(const TexoImage &piece);
- void Put(const TexoLink &piece);
- void Put(const TexoHorizontalRule &piece);
+ bool Link(const ScriptVariable &link, const ScriptVariable &title);
+ bool Link();
+
+ bool PutImage(
+ const ScriptVariable &src,
+ const ScriptVariable &alt,
+ const ScriptVariable &title
+ );
+ bool PutHorizontalRule();
private:
- void Close();
+ bool Mod(const ScriptVariable &str);
+ bool Close();
+ bool CloseLink();
bool quoted;
bool newline;
bool header;
bool code;
bool nospace;
+
+ ScriptVariable link_link;
+ ScriptVariable link_title;
};
@@ -44,13 +55,13 @@ class TexoImporterMarkdown: public TexoImporter {
public:
TexoImporterMarkdown(TexoProducer &producer);
- void Put(char c);
- void Put(const ScriptVariable &str);
- void Put(FILE *file);
+
+protected:
+ bool TruePut(char c);
+
private:
enum State {
- error,
start,
text,
header_text,
diff --git a/src/plain.cpp b/src/plain.cpp
index 8b3d470..9e9280e 100644
--- a/src/plain.cpp
+++ b/src/plain.cpp
@@ -1,82 +1,100 @@
#include "plain.hpp"
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Texo Plain Producer
+ */
TexoProducerPlain::TexoProducerPlain(TexoExporter &exporter):
TexoProducer(exporter), quoted(false), newline(false), nospace(true)
{}
-void TexoProducerPlain::End()
+
+bool TexoProducerPlain::End()
{
if (!newline) {
exporter.Put('\n');
newline = true;
}
+ return true;
}
-void TexoProducerPlain::Put(const Texo &piece)
+
+bool TexoProducerPlain::Put(char c)
{
- if (piece.c == '\n') {
+ if (c == '\n') {
if (quoted) {
- exporter.Put("\n> ");
+ return exporter.Put("\n> ");
} else if (!nospace) {
if (newline) {
- exporter.Put(' ');
+ return exporter.Put(' ');
} else {
- exporter.Put('\n');
newline = true;
+ return exporter.Put('\n');
}
+ } else {
+ return true;
}
} else {
- exporter.Put(piece.c);
newline = false;
nospace = false;
+ return exporter.Put(c);
}
}
-void TexoProducerPlain::Put(const TexoParagraph &piece)
+
+bool TexoProducerPlain::Paragraph()
{
+ quoted = false;
if (!nospace) {
- exporter.Put("\n\n");
+ nospace = true;
+ return exporter.Put("\n\n");
+ } else {
+ return true;
}
- quoted = false;
- nospace = true;
}
-void TexoProducerPlain::Put(const TexoQuote &piece)
+bool TexoProducerPlain::Quote()
{
+ quoted = true;
if (!nospace) {
- exporter.Put("\n\n");
+ return exporter.Put("\n\n> ");
+ } else {
+ return exporter.Put("> ");
}
- exporter.Put("> ");
- quoted = true;
}
-void TexoProducerPlain::Put(const TexoHorizontalRule &piece)
+bool TexoProducerPlain::PutHorizontalRule()
{
+ bool ok = true;
if (!newline && !nospace) {
- exporter.Put('\n');
+ ok = exporter.Put('\n');
}
- exporter.Put("--------------------------------------------------\n");
nospace = true;
+ return ok && exporter.Put(
+ "--------------------------------------------------\n"
+ );
}
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Texo Plain Importer
+ */
TexoImporterPlain::TexoImporterPlain(TexoProducer &producer):
TexoImporter(producer), state(text)
-{
- producer.Put(TexoParagraph());
-}
+{}
+
-void TexoImporterPlain::End()
+bool TexoImporterPlain::TrueEnd()
{
if (state == rule) {
- producer.Put(TexoHorizontalRule());
+ ok = producer.PutHorizontalRule();
state = text;
}
- producer.End();
+ return ok && producer.End();
}
-void TexoImporterPlain::Put(char c)
+
+bool TexoImporterPlain::TruePut(char c)
{
switch (state) {
case text: Text(c); break;
@@ -88,23 +106,15 @@ void TexoImporterPlain::Put(char c)
case rule: Rule(c); break;
case paragraph_rule: ParagraphRule(c); break;
}
+ return ok;
}
-void TexoImporterPlain::Put(const ScriptVariable &str)
-{
- TexoImporter::Put(str);
-}
-
-void TexoImporterPlain::Put(FILE *file)
-{
- TexoImporter::Put(file);
-}
void TexoImporterPlain::Text(char c)
{
switch (c) {
- case '\n': state = newline; break;
- default: producer.Put(c); break;
+ case '\n': state = newline; break;
+ default: ok = producer.Put(c); break;
}
}
@@ -114,26 +124,30 @@ void TexoImporterPlain::Newline(char c)
state = paragraph;
} else if (c == '-') {
dash_count = 1;
- state = rule;
+ state = rule;
} else {
- producer.Put('\n');
state = text;
- Text(c);
+ ok = producer.Put('\n');
+ if (ok) {
+ Text(c);
+ }
}
}
void TexoImporterPlain::Paragraph(char c)
{
if (c == '>') {
- producer.Put(TexoQuote());
+ ok = producer.Quote();
state = quote_pre;
} else if (c == '-') {
dash_count = 1;
- state = paragraph_rule;
+ state = paragraph_rule;
} else if (c != '\n') {
- producer.Put(TexoParagraph());
state = text;
- Text(c);
+ ok = producer.Paragraph();
+ if (ok) {
+ Text(c);
+ }
}
}
@@ -148,49 +162,55 @@ void TexoImporterPlain::QuotePre(char c)
void TexoImporterPlain::Quote(char c)
{
switch (c) {
- case '\n': state = quote_newline; break;
- default: producer.Put(c); break;
+ case '\n': state = quote_newline; break;
+ default: ok = producer.Put(c); break;
}
}
void TexoImporterPlain::QuoteNewline(char c)
{
if (c == '>') {
- producer.Put('\n');
+ ok = producer.Put('\n');
state = quote_pre;
} else if (c == '\n') {
state = paragraph;
} else if (c == '-') {
dash_count = 1;
- state = paragraph_rule;
+ state = paragraph_rule;
} else {
- producer.Put(TexoParagraph());
state = text;
- Text(c);
+ ok = producer.Paragraph();
+ if (ok) {
+ Text(c);
+ }
}
}
void TexoImporterPlain::Rule(char c)
{
if (c == '\n') {
- producer.Put(TexoHorizontalRule());
+ ok = producer.PutHorizontalRule();
state = text;
} else if (c == '-') {
++dash_count;
} else {
- producer.Put('\n');
- for (;dash_count > 0; --dash_count) {
- producer.Put('-');
+ ok = producer.Put('\n');
+ for (; ok && dash_count > 0; --dash_count) {
+ ok = producer.Put('-');
}
state = text;
- Text(c);
+ if (ok) {
+ Text(c);
+ }
}
}
void TexoImporterPlain::ParagraphRule(char c)
{
if (c == '\n') {
- producer.Put(TexoParagraph());
+ ok = producer.Paragraph();
+ }
+ if (ok) {
+ Rule(c);
}
- Rule(c);
}
diff --git a/src/plain.hpp b/src/plain.hpp
index 13a2c0c..66ee5f1 100644
--- a/src/plain.hpp
+++ b/src/plain.hpp
@@ -6,18 +6,21 @@
#include "importer.hpp"
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Texo Plain Producer
+ */
class TexoProducerPlain: public TexoProducer {
public:
TexoProducerPlain(TexoExporter &exporter);
- void End();
+ bool End();
- void Put(const Texo &piece);
+ bool Put(char c);
- void Put(const TexoParagraph &piece);
- void Put(const TexoQuote &piece);
+ bool Paragraph();
+ bool Quote();
- void Put(const TexoHorizontalRule &piece);
+ bool PutHorizontalRule();
private:
bool quoted;
@@ -26,15 +29,20 @@ private:
};
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Texo Plain Importer
+ */
class TexoImporterPlain: public TexoImporter {
public:
TexoImporterPlain(TexoProducer &producer);
- void End();
- void Put(char c);
- void Put(const ScriptVariable &str);
- void Put(FILE *file);
+protected:
+ bool TrueEnd();
+
+
+ bool TruePut(char c);
+
private:
enum State {
diff --git a/src/producer.cpp b/src/producer.cpp
index 2c60d48..c650459 100644
--- a/src/producer.cpp
+++ b/src/producer.cpp
@@ -1,43 +1,314 @@
#include "producer.hpp"
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Texo Producer
+ */
TexoProducer::TexoProducer(TexoExporter &exporter): exporter(exporter)
-{}
+{} // Just save exporter for future use.
+
+
+bool TexoProducer::End()
+{ // By default, no checks performed, so no error produced.
+ return true;
+}
+
+
+bool TexoProducer::Put(char c)
+{ // By default characters are not escaped, error means error in exporter.
+ return exporter.Put(c);
+}
+
+
+// Block Signal Handlers
+// By default, nothing has to be done, and no error produced,
+// except for paragraphs, which must be implemented.
+bool TexoProducer::Code() { return true; }
+bool TexoProducer::Header(int level) { return true; }
+bool TexoProducer::Quote() { return true; }
+
+
+// Modificator Signal Handlers
+// By default, nothing has to be done, and no error produced.
+bool TexoProducer::Bold() { return true; }
+bool TexoProducer::Italic() { return true; }
+bool TexoProducer::Mono() { return true; }
+bool TexoProducer::Strike() { return true; }
+bool TexoProducer::Underline() { return true; }
-void TexoProducer::End()
+bool TexoProducer::Link(
+ const ScriptVariable &link,
+ const ScriptVariable &title
+)
+{
+ return true;
+}
+
+bool TexoProducer::Link()
+{
+ return true;
+}
+
+
+bool TexoProducer::PutImage(
+ const ScriptVariable &src,
+ const ScriptVariable &alt,
+ const ScriptVariable &title
+)
+{
+ return true;
+}
+
+bool TexoProducer::PutHorizontalRule()
+{
+ return true;
+}
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Texo Strict Producer
+ */
+TexoProducerStrict::TexoProducerStrict(TexoExporter &exporter):
+ TexoProducer(exporter), block(block_none), opened(0)
{}
-void TexoProducer::Put(char c)
+
+bool TexoProducerStrict::End()
{
- Put(Texo(c));
+ bool ok = CloseBlock();
+ block = block_none;
+ return ok;
}
-void TexoProducer::Put(const Texo &piece)
+
+bool TexoProducerStrict::Put(char c)
{
- exporter.Put(piece.c);
+ return Start() && TruePut(c);
}
-void TexoProducer::Put(const TexoHeader &piece)
+
+bool TexoProducerStrict::Code()
{
- Put(TexoParagraph());
+ if (CloseBlock()) {
+ block = code;
+ return StartCode();
+ } else {
+ return false;
+ }
}
-void TexoProducer::Put(const TexoQuote &piece)
+bool TexoProducerStrict::Header(int level)
{
- Put(TexoParagraph());
+ if (CloseBlock()) {
+ block = header;
+ header_level = level;
+ return StartHeader(level);
+ } else {
+ return false;
+ }
}
-void TexoProducer::Put(const TexoCode &piece)
+bool TexoProducerStrict::Paragraph()
{
- Put(TexoParagraph());
+ if (CloseBlock()) {
+ block = paragraph;
+ return StartParagraph();
+ } else {
+ return false;
+ }
}
-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) {}
+bool TexoProducerStrict::Quote()
+{
+ if (CloseBlock()) {
+ block = quote;
+ return StartQuote();
+ } else {
+ return false;
+ }
+}
+
+
+bool TexoProducerStrict::Bold()
+{
+ return SwitchMod(bold);
+}
+
+bool TexoProducerStrict::Italic()
+{
+ return SwitchMod(italic);
+}
+
+bool TexoProducerStrict::Mono()
+{
+ return SwitchMod(mono);
+}
+
+bool TexoProducerStrict::Strike()
+{
+ return SwitchMod(strike);
+}
-void TexoProducer::Put(const TexoImage &piece) {}
-void TexoProducer::Put(const TexoLink &piece) {}
-void TexoProducer::Put(const TexoHorizontalRule &piece) {}
+bool TexoProducerStrict::Underline()
+{
+ return SwitchMod(underline);
+}
+
+bool TexoProducerStrict::Link(
+ const ScriptVariable &path,
+ const ScriptVariable &title
+)
+{
+ if (IsOpened(link)) {
+ int closed = CloseMods(link);
+ if (closed >= 0) {
+ return Reopen(closed);
+ } else {
+ return false;
+ }
+ } else {
+ link_link = &path;
+ link_title = &title;
+ return Start() && OpenMod(link);
+ }
+}
+
+bool TexoProducerStrict::Link()
+{
+ if (IsOpened(link)) {
+ int closed = CloseMods(link);
+ if (closed >= 0) {
+ return Reopen(closed);
+ } else {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool TexoProducerStrict::PutImage(
+ const ScriptVariable &src,
+ const ScriptVariable &alt,
+ const ScriptVariable &title
+)
+{
+ return Start() && TruePutImage(src, alt, title);
+}
+
+bool TexoProducerStrict::PutHorizontalRule()
+{
+ return Start() && TruePutHorizontalRule();
+}
+
+
+bool TexoProducerStrict::Start()
+{
+ if (!block) {
+ block = paragraph;
+ return StartParagraph();
+ } else {
+ return true;
+ }
+}
+
+bool TexoProducerStrict::CloseBlock()
+{
+ if (CloseMods()) {
+ switch (block) {
+ case block_none: return true;
+ case code: return CloseCode();
+ case header: return CloseHeader(header_level);
+ case paragraph: return CloseParagraph();
+ case quote: return CloseQuote();
+ }
+ return true; // Inpossible, since all cases are in switch.
+ } else {
+ return false;
+ }
+}
+
+bool TexoProducerStrict::SwitchMod(Mod mod)
+{
+ if (IsOpened(mod)) {
+ int closed = CloseMods(mod);
+ if (closed >= 0) {
+ return Reopen(closed);
+ } else {
+ return false;
+ }
+ } else {
+ return Start() && OpenMod(mod);
+ }
+}
+
+bool TexoProducerStrict::OpenMod(Mod mod)
+{
+ mods[opened] = mod;
+ ++opened;
+ switch (mod) {
+ case bold: return StartBold();
+ case italic: return StartItalic();
+ case link: return StartLink(*link_link, *link_title);
+ case mono: return StartMono();
+ case strike: return StartStrike();
+ case underline: return StartUnderline();
+ }
+ return true; // Inpossible, since all cases are in switch.
+}
+
+bool TexoProducerStrict::CloseMod(Mod mod)
+{
+ switch (mod) {
+ case bold: return CloseBold();
+ case italic: return CloseItalic();
+ case link: return CloseLink(*link_link, *link_title);
+ case mono: return CloseMono();
+ case strike: return CloseStrike();
+ case underline: return CloseUnderline();
+ }
+ return true; // Inpossible, since all cases are in switch.
+}
+
+int TexoProducerStrict::CloseMods(Mod last)
+{
+ const int old = opened;
+ while (opened) {
+ Mod top = mods[--opened];
+ if (CloseMod(top)) {
+ if (top == last) {
+ return old - opened;
+ }
+ } else {
+ return -1;
+ }
+ }
+ return old - opened;
+}
+
+bool TexoProducerStrict::CloseMods()
+{
+ bool ok = true;
+ while (ok && opened) {
+ ok = CloseMod(mods[--opened]);
+ }
+ return ok;
+}
+
+bool TexoProducerStrict::Reopen(int closed)
+{
+ bool ok = true;
+ int new_opened = opened + closed;
+ while (ok && opened != new_opened) {
+ ok = OpenMod(mods[opened]);
+ }
+ return ok;
+}
+
+bool TexoProducerStrict::IsOpened(Mod mod) const
+{
+ bool is = false;
+ for (int i = opened - 1; !is && i >= 0; --i) {
+ is = mods[i] == mod;
+ }
+ return is;
+}
diff --git a/src/producer.hpp b/src/producer.hpp
index 62e098d..f55cb91 100644
--- a/src/producer.hpp
+++ b/src/producer.hpp
@@ -1,37 +1,192 @@
#ifndef TEXO_INCLUDED_PRODUCER
#define TEXO_INCLUDED_PRODUCER
-#include "texo.hpp"
#include "exporter.hpp"
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Texo Producer
+ * Texo interface for producing output based on inner representation.
+ */
class TexoProducer {
public:
- TexoProducer(TexoExporter &exporter);
+ TexoProducer(TexoExporter &exporter); // Setup exporter used for output.
- virtual void End();
- virtual void Put(char c);
- virtual void Put(const Texo &piece);
+ virtual bool End(); // Notify producer, what input is ended.
- virtual void Put(const TexoHeader &piece);
- virtual void Put(const TexoParagraph &piece) = 0;
- virtual void Put(const TexoCode &piece);
- virtual void Put(const TexoQuote &piece);
- virtual void Put(const TexoMono &piece);
- virtual void Put(const TexoBold &piece);
- virtual void Put(const TexoItalic &piece);
- virtual void Put(const TexoUnderline &piece);
- virtual void Put(const TexoStrike &piece);
+ virtual bool Put(char c); // Output c, possibly escaping it.
+
+
+ // Block Signal Handlers
+ // Only one can be opened at one moment.
+ virtual bool Code();
+ virtual bool Header(int level);
+ virtual bool Paragraph() = 0;
+ virtual bool Quote();
+
+
+ // Modificator Signal Handlers
+ // Independently switch one of text modificators.
+ virtual bool Bold();
+ virtual bool Italic();
+ virtual bool Mono();
+ virtual bool Strike();
+ virtual bool Underline();
+
+ // Switch link to given or switch it off, if no one is given.
+ virtual bool Link(
+ const ScriptVariable &link,
+ const ScriptVariable &title
+ );
+ virtual bool Link();
+
+
+ virtual bool PutImage(
+ const ScriptVariable &src,
+ const ScriptVariable &alt,
+ const ScriptVariable &title
+ );
+ virtual bool PutHorizontalRule();
- virtual void Put(const TexoImage &piece);
- virtual void Put(const TexoLink &piece);
- virtual void Put(const TexoHorizontalRule &piece);
protected:
TexoExporter &exporter;
};
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Texo Strict Producer
+ * Converts switch-signal interface of Texo Producer into
+ * sequence of start/close signals with disjoint modificator sections,
+ * as well as block sections, which are provided on top level.
+ */
+class TexoProducerStrict: public TexoProducer {
+public:
+ TexoProducerStrict(TexoExporter &exporter);
+
+
+ bool End();
+
+
+ bool Put(char c);
+
+
+ bool Code();
+ bool Header(int level);
+ bool Paragraph();
+ bool Quote();
+
+
+ bool Bold();
+ bool Italic();
+ bool Mono();
+ bool Strike();
+ bool Underline();
+
+ bool Link(const ScriptVariable &path, const ScriptVariable &title);
+ bool Link();
+
+ bool PutImage(
+ const ScriptVariable &src,
+ const ScriptVariable &alt,
+ const ScriptVariable &title
+ );
+ bool PutHorizontalRule();
+
+
+protected:
+ virtual bool TruePut(char c) = 0;
+
+ virtual bool StartCode() = 0;
+ virtual bool StartHeader(int level) = 0;
+ virtual bool StartParagraph() = 0;
+ virtual bool StartQuote() = 0;
+
+ virtual bool CloseCode() = 0;
+ virtual bool CloseHeader(int level) = 0;
+ virtual bool CloseParagraph() = 0;
+ virtual bool CloseQuote() = 0;
+
+
+ virtual bool StartBold() = 0;
+ virtual bool StartItalic() = 0;
+ virtual bool StartMono() = 0;
+ virtual bool StartStrike() = 0;
+ virtual bool StartUnderline() = 0;
+
+ virtual bool CloseBold() = 0;
+ virtual bool CloseItalic() = 0;
+ virtual bool CloseMono() = 0;
+ virtual bool CloseStrike() = 0;
+ virtual bool CloseUnderline() = 0;
+
+ virtual bool StartLink(
+ const ScriptVariable &link,
+ const ScriptVariable &title
+ ) = 0;
+ virtual bool CloseLink(
+ const ScriptVariable &link,
+ const ScriptVariable &title
+ ) = 0;
+
+
+ virtual bool TruePutImage(
+ const ScriptVariable &src,
+ const ScriptVariable &alt,
+ const ScriptVariable &title
+ ) = 0;
+ virtual bool TruePutHorizontalRule() = 0;
+
+
+private:
+ enum Block {
+ block_none = 0,
+ code,
+ header,
+ paragraph,
+ quote
+ } block;
+
+ int header_level;
+
+
+ enum Mod {
+ bold,
+ italic,
+ link,
+ mono,
+ strike,
+ underline
+ } mods[6];
+ int opened;
+
+ const ScriptVariable *link_link;
+ const ScriptVariable *link_title;
+
+
+ bool Start(); // Open paragraph if no block is opened.
+
+ bool CloseBlock();
+
+ bool SwitchMod(Mod mod);
+
+ bool OpenMod(Mod mod);
+
+ bool CloseMod(Mod mod);
+
+ // Close all opened mods sequentially, down to (including) last,
+ // returning count of closed mods, or negative number in case of error.
+ int CloseMods(Mod last);
+
+ // Close all opened mods.
+ bool CloseMods();
+
+ bool Reopen(int closed);
+
+ bool IsOpened(Mod mod) const;
+};
+
+
#endif
diff --git a/src/script.cpp b/src/script.cpp
new file mode 100644
index 0000000..d335ff0
--- /dev/null
+++ b/src/script.cpp
@@ -0,0 +1,21 @@
+#include "script.hpp"
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Texo String Exporter
+ */
+TexoExporterString::TexoExporterString(ScriptVariable &str): str(str)
+{}
+
+
+bool TexoExporterString::Put(char c)
+{
+ str += c;
+ return true;
+}
+
+bool TexoExporterString::Put(const ScriptVariable &addon)
+{
+ str += addon;
+ return true;
+}
diff --git a/src/script.hpp b/src/script.hpp
new file mode 100644
index 0000000..77f75df
--- /dev/null
+++ b/src/script.hpp
@@ -0,0 +1,25 @@
+#ifndef TEXO_INCLUDED_SCRIPT
+#define TEXO_INCLUDED_SCRIPT
+
+#include "exporter.hpp"
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Texo String Exporter
+ * Simple utility class to make output into Script Variable,
+ * which can be easily transformed into C string via c_str method.
+ */
+class TexoExporterString: public TexoExporter {
+public:
+ TexoExporterString(ScriptVariable &str);
+
+
+ bool Put(char c);
+ bool Put(const ScriptVariable &addon);
+
+
+private:
+ ScriptVariable &str;
+};
+
+
+#endif
diff --git a/src/str.cpp b/src/str.cpp
deleted file mode 100644
index 463a8dc..0000000
--- a/src/str.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-#include "str.hpp"
-
-
-TexoExporterString::TexoExporterString(ScriptVariable &str): str(str)
-{}
-
-void TexoExporterString::Put(char c)
-{
- str += c;
-}
-
-void TexoExporterString::Put(const ScriptVariable &addon)
-{
- str += addon;
-}
diff --git a/src/str.hpp b/src/str.hpp
deleted file mode 100644
index c7cecfc..0000000
--- a/src/str.hpp
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef TEXO_INCLUDED_STR
-#define TEXO_INCLUDED_STR
-
-#include "exporter.hpp"
-
-
-class TexoExporterString: public TexoExporter {
-public:
- TexoExporterString(ScriptVariable &str);
-
- void Put(char c);
- void Put(const ScriptVariable &addon);
-
-private:
- ScriptVariable &str;
-};
-
-
-#endif
diff --git a/src/texo.cpp b/src/texo.cpp
deleted file mode 100644
index 99d74f8..0000000
--- a/src/texo.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
-#include "texo.hpp"
-
-
-Texo::Texo(char c): c(c)
-{}
-
-TexoHeader::TexoHeader(int level): level(level)
-{}
diff --git a/src/texo.hpp b/src/texo.hpp
deleted file mode 100644
index b8ae394..0000000
--- a/src/texo.hpp
+++ /dev/null
@@ -1,61 +0,0 @@
-#ifndef TEXO_INCLUDED_TEXO
-#define TEXO_INCLUDED_TEXO
-
-#include
-
-
-struct Texo {
- Texo(char c);
- char c;
-};
-
-
-/*
- * Texo Blocks
- */
-struct TexoHeader {
- TexoHeader(int level);
- int level; // Number >= 1, bigger for bigger.
-};
-
-struct TexoParagraph {};
-
-struct TexoCode {};
-
-struct TexoQuote {};
-
-
-/*
- * Texo Decorators
- */
-struct TexoMono {};
-
-struct TexoBold {};
-
-struct TexoItalic {};
-
-struct TexoUnderline {};
-
-struct TexoStrike {};
-
-
-/*
- * Texo Signals
- */
-struct TexoImage {
- ScriptVariable path;
- ScriptVariable title;
- ScriptVariable alt;
- ScriptVariable link;
-};
-
-struct TexoLink {
- ScriptVariable text;
- ScriptVariable link;
- ScriptVariable title;
-};
-
-struct TexoHorizontalRule {};
-
-
-#endif
--
cgit v1.2.3