From 77f503bd6db90bd882e389ea977f02a2773e14f2 Mon Sep 17 00:00:00 2001 From: Aleksey Veresov Date: Fri, 4 Oct 2019 16:35:57 +0300 Subject: Semi-working html. =) --- src/html.cpp | 298 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 293 insertions(+), 5 deletions(-) (limited to 'src/html.cpp') diff --git a/src/html.cpp b/src/html.cpp index c9e3cde..76e9fb9 100644 --- a/src/html.cpp +++ b/src/html.cpp @@ -1,5 +1,7 @@ #include "html.hpp" +#include + TexoHTMLProducer::TexoHTMLProducer(TexoExporter &exporter): TexoProducer(exporter) @@ -23,7 +25,7 @@ void TexoHTMLProducer::Put(const Texo &piece) case Texo::link_begin: BeginLink(piece); break; case Texo::link_end: exporter.PutStr(""); break; case Texo::image: Image(piece); break; - default: break; + default: break; } } @@ -55,11 +57,297 @@ void TexoHTMLProducer::Image(const Texo &piece) } -TexoHTMLImporter::TexoHTMLImporter(TexoProducer &producer): - TexoImporter(producer) +TexoHTMLStack::TexoHTMLStack(): next(0) +{} + +TexoHTMLStack::~TexoHTMLStack() +{ + if (next) { + while (next != this) { + Pop(); + } + } +} + +void TexoHTMLStack::Push(Texo::Type tag) +{ + if (next) { + TexoHTMLStack *buf = next; + next = new TexoHTMLStack; + next->next = buf; + next->tag = this->tag; + } else { + next = this; + } + this->tag = tag; +} + +Texo::Type TexoHTMLStack::Pop() +{ + if (next) { + Texo::Type res = tag; + if (next != this) { + TexoHTMLStack *buf = next; + tag = next->tag; + next = next->next; + delete buf; + } else { + next = 0; + } + return res; + } else { + return Texo::character; + } +} + + +TexoHTMLImporter::TexoHTMLImporter(TexoProducer &producer, bool is_autoclose): + TexoImporter(producer), state(text), is_closing(0), tag(Texo::character), + readed(0), readed_len(0), readed_size(0), is_autoclose(is_autoclose) {} +TexoHTMLImporter::~TexoHTMLImporter() +{ + ReadedClear(); +} + void TexoHTMLImporter::Put(const char c) -{ // TODO by automata - producer.Put(Texo(c)); +{ + if (c) { + switch (state) { + case text: state = Text(c); break; + case tag_open: state = TagOpen(c); break; + case tag_name: state = TagName(c); break; + case tag_param_skip: state = TagParamSkip(c); break; + case tag_param_pre: state = TagParamPre(c); break; + case tag_param: state = TagParam(c); break; + case tag_param_post: state = TagParamPost(c); break; + case tag_param_value_pre: state = TagParamValuePre(c); break; + case tag_param_value: state = TagParamValue(c); break; + case tag_param_value_quoted: state = TagParamValueQuoted(c); break; + default: break; + } + } else { + tag = Texo::character; + Close(); + } +} + +TexoHTMLImporter::State TexoHTMLImporter::Text(const char c) +{ + State st = text; + switch (c) { + case '<': st = tag_open; break; + case '>': producer.PutStr(">"); break; + default: producer.Put(Texo(c)); break; + } + return st; +} + +TexoHTMLImporter::State TexoHTMLImporter::TagOpen(const char c) +{ + State st = tag_open; + switch (c) { + case '/': + is_closing = 1; + break; + case ' ': + st = text; + producer.PutStr("<"); + if (is_closing) { + producer.Put(Texo('/')); + } + producer.Put(Texo(' ')); + break; + case '>': + st = text; + producer.PutStr("<"); + if (is_closing) { + producer.Put(Texo('/')); + } + producer.PutStr(">"); + break; + default: + st = tag_name; + ReadedAdd(c); + break; + } + return st; +} + +TexoHTMLImporter::State TexoHTMLImporter::TagName(const char c) +{ + State st = tag_name; + switch (c) { + case ' ': + st = tag_param_skip; + SetTag(); + break; + case '/': + st = tag_param_skip; + SetTag(); + break; + case '>': + st = text; + SetTag(); + if (tag) { + if (is_closing) { + Close(); + } else { + producer.Put(Texo(tag)); + } + } + is_closing = false; + break; + default: + ReadedAdd(c); + break; + } + return st; +} + +TexoHTMLImporter::State TexoHTMLImporter::TagParamSkip(const char c) +{ + State st = tag_param_skip; + switch (c) { + case '>': + st = text; + if (tag) { + if (is_closing) { + Close(); + } else { + producer.Put(Texo(tag)); + } + } + is_closing = false; + break; + default: + break; + } + return st; +} + +TexoHTMLImporter::State TexoHTMLImporter::TagParamPre(const char c) +{ + return text; +} + +TexoHTMLImporter::State TexoHTMLImporter::TagParam(const char c) +{ + return text; +} + +TexoHTMLImporter::State TexoHTMLImporter::TagParamPost(const char c) +{ + return text; +} + +TexoHTMLImporter::State TexoHTMLImporter::TagParamValuePre(const char c) +{ + return text; +} + +TexoHTMLImporter::State TexoHTMLImporter::TagParamValue(const char c) +{ + return text; +} + +TexoHTMLImporter::State TexoHTMLImporter::TagParamValueQuoted(const char c) +{ + return text; +} + +void TexoHTMLImporter::Close() +{ + Texo::Type current = opened.Pop(); + while ((current != tag) && current) { + producer.Put(Texo(current)); + current = opened.Pop(); + } + if (current) { + producer.Put(Texo(current)); + } +} + +void TexoHTMLImporter::SetTag() +{ + if (!strcmp(readed, "a")) { + if (is_closing) { + tag = Texo::link_end; + } else { + tag = Texo::link_begin; + opened.Push(Texo::link_end); + } + } else if (!strcmp(readed, "img")) { + tag = Texo::image; + } else if (!strcmp(readed, "b")) { + if (is_closing) { + tag = Texo::bold_end; + } else { + tag = Texo::bold_begin; + opened.Push(Texo::bold_end); + } + } else if (!strcmp(readed, "i")) { + if (is_closing) { + tag = Texo::italic_end; + } else { + tag = Texo::italic_begin; + opened.Push(Texo::italic_end); + } + } else if (!strcmp(readed, "del")) { + if (is_closing) { + tag = Texo::strike_end; + } else { + tag = Texo::strike_begin; + opened.Push(Texo::strike_end); + } + } else if (!strcmp(readed, "ins")) { + if (is_closing) { + tag = Texo::underline_end; + } else { + tag = Texo::underline_begin; + opened.Push(Texo::underline_end); + } + } else if (!strcmp(readed, "p")) { + if (is_closing) { + tag = Texo::paragraph_end; + } else { + tag = Texo::paragraph_begin; + opened.Push(Texo::paragraph_end); + } + } else if (!strcmp(readed, "br")) { + tag = Texo::newline; + } else { + tag = Texo::character; + } + ReadedClear(); +} + +void TexoHTMLImporter::ReadedAdd(const char c) +{ + if (readed_size == 0) { + readed_size = 2; + readed = new char[readed_size]; + } else if (readed_size - 1 == readed_len) { + char *buf = readed; + readed_size = readed_size << 1; + readed = new char[readed_size]; + for (int i = 0; i < readed_len; ++i) { + readed[i] = buf[i]; + } + delete buf; + } + ++readed_len; + readed[readed_len - 1] = c; + readed[readed_len] = 0; +} + +void TexoHTMLImporter::ReadedClear() +{ + readed_len = 0; + readed_size = 0; + if (readed) { + delete readed; + readed = 0; + } } -- cgit v1.2.3