diff options
| author | Aleksey Veresov <aleksey@veresov.pro> | 2019-10-04 16:35:57 +0300 | 
|---|---|---|
| committer | Aleksey Veresov <aleksey@veresov.pro> | 2019-10-04 16:35:57 +0300 | 
| commit | 77f503bd6db90bd882e389ea977f02a2773e14f2 (patch) | |
| tree | c6aa2a7410744c640c530016f4f65746a1ee5ac5 | |
| parent | 5dd4f05089608a66c435d6be36d4bc93dc425986 (diff) | |
| download | texo-77f503bd6db90bd882e389ea977f02a2773e14f2.tar texo-77f503bd6db90bd882e389ea977f02a2773e14f2.tar.xz texo-77f503bd6db90bd882e389ea977f02a2773e14f2.zip | |
Semi-working html. =)
| -rw-r--r-- | example/filter_html.cpp | 5 | ||||
| -rw-r--r-- | example/makefile | 2 | ||||
| -rw-r--r-- | src/file.hpp | 1 | ||||
| -rw-r--r-- | src/html.cpp | 298 | ||||
| -rw-r--r-- | src/html.hpp | 59 | ||||
| -rw-r--r-- | src/plain.hpp | 1 | ||||
| -rw-r--r-- | src/texo.cpp | 10 | ||||
| -rw-r--r-- | src/texo.hpp | 3 | 
8 files changed, 369 insertions, 10 deletions
| diff --git a/example/filter_html.cpp b/example/filter_html.cpp index ced8f5f..a1957c3 100644 --- a/example/filter_html.cpp +++ b/example/filter_html.cpp @@ -8,11 +8,10 @@ int main()      TexoHTMLProducer producer(exporter);      TexoHTMLImporter importer(producer);      importer.PutStr( -        "<script>EVIL MAGIC</script>\n" +        "<script>EVIL MAGIC</script></p>\n"          "<a href='#'>Some</a> br:<br/>\n"          "<p class='evil_too'>And paragraphs work well too...</p>\n" -        "<b>You</b> <i>can</i> <del>use</del> <ins>some</ins> witchcraft.\n" +        "<b>You</b> <i>can</i> <del>use</del> <ins>some</ins> <p>witchcraft.\n"      );      return 0; -    return 0;  } diff --git a/example/makefile b/example/makefile index 5255f5b..39d4db7 100644 --- a/example/makefile +++ b/example/makefile @@ -2,7 +2,7 @@  # DEBUG    = yes  CC       = g++ -EXAMPLES = plain_to_html +EXAMPLES = plain_to_html filter_html  CFLAGS   = -Wall  ifeq '$(DEBUG)' 'yes' diff --git a/src/file.hpp b/src/file.hpp index 68e31cd..c867bcc 100644 --- a/src/file.hpp +++ b/src/file.hpp @@ -8,6 +8,7 @@ class TexoFileExporter: public TexoExporter {  public:      TexoFileExporter(FILE *file);      void Put(const char c); +  private:      FILE *file;  }; 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 <string.h> +  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("</a>");   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; +    }  } diff --git a/src/html.hpp b/src/html.hpp index 265ee39..7a5a511 100644 --- a/src/html.hpp +++ b/src/html.hpp @@ -8,16 +8,73 @@ class TexoHTMLProducer: public TexoProducer {  public:      TexoHTMLProducer(TexoExporter &exporter);      void Put(const Texo &piece); +  private:      void BeginLink(const Texo &piece);      void Image(const Texo &piece);  }; +class TexoHTMLStack { +public: +    TexoHTMLStack(); +    ~TexoHTMLStack(); +    void Push(Texo::Type tag); +    Texo::Type Pop(); + +private: +    TexoHTMLStack *next; +    Texo::Type    tag; +}; +  class TexoHTMLImporter: public TexoImporter {  public: -    TexoHTMLImporter(TexoProducer &producer); +    TexoHTMLImporter(TexoProducer &producer, bool is_autoclose = true); +    ~TexoHTMLImporter();      void Put(const char c); + +private: +    bool is_autoclose; + +    enum State { +        text = 0, +        tag_open, +        tag_name, +        tag_param_skip, +        tag_param_pre, +        tag_param, +        tag_param_post, +        tag_param_value_pre, +        tag_param_value, +        tag_param_value_quoted +    } state; + +    State Text(const char c); +    State TagOpen(const char c); +    State TagName(const char c); +    State TagParamSkip(const char c); +    State TagParamPre(const char c); +    State TagParam(const char c); +    State TagParamPost(const char c); +    State TagParamValuePre(const char c); +    State TagParamValue(const char c); +    State TagParamValueQuoted(const char c); + +    TexoHTMLStack opened; + +    void Close(); + +    bool       is_closing; +    Texo::Type tag; + +    void SetTag(); + +    char *readed; +    int  readed_len; +    int  readed_size; + +    void ReadedAdd(const char c); +    void ReadedClear();  }; diff --git a/src/plain.hpp b/src/plain.hpp index 8c74bce..c88f8ef 100644 --- a/src/plain.hpp +++ b/src/plain.hpp @@ -8,6 +8,7 @@ class TexoPlainImporter: public TexoImporter {  public:      TexoPlainImporter(TexoProducer &producer);      void Put(const char c); +  private:      int  space;      int  newline; diff --git a/src/texo.cpp b/src/texo.cpp index 03b31e7..3610184 100644 --- a/src/texo.cpp +++ b/src/texo.cpp @@ -23,6 +23,16 @@ void TexoExporter::PutStr(const char *str)  TexoProducer::TexoProducer(TexoExporter &exporter): exporter(exporter)  {} +void TexoProducer::PutStr(const char *str) +{ +    if (str) { +        while (*str) { +            Put(Texo(*str)); +            ++str; +        } +    } +} +  TexoImporter::TexoImporter(TexoProducer &producer): producer(producer)  {} diff --git a/src/texo.hpp b/src/texo.hpp index 2129f61..bfea181 100644 --- a/src/texo.hpp +++ b/src/texo.hpp @@ -43,6 +43,8 @@ class TexoProducer {  public:      TexoProducer(TexoExporter &exporter);      virtual void Put(const Texo &piece) = 0; +    virtual void PutStr(const char *str); +  protected:      TexoExporter &exporter;  }; @@ -54,6 +56,7 @@ public:      virtual void Put(const char c) = 0;      virtual void PutStr(const char *str);      virtual void PutFile(FILE *file); +  protected:      TexoProducer &producer;  }; | 
