diff options
Diffstat (limited to 'src/plugins/html')
-rw-r--r-- | src/plugins/html/DemoOutput.cpp | 187 | ||||
-rw-r--r-- | src/plugins/html/DemoOutput.hpp | 85 |
2 files changed, 272 insertions, 0 deletions
diff --git a/src/plugins/html/DemoOutput.cpp b/src/plugins/html/DemoOutput.cpp new file mode 100644 index 0000000..6b9b3a4 --- /dev/null +++ b/src/plugins/html/DemoOutput.cpp @@ -0,0 +1,187 @@ +/* + Ousía + Copyright (C) 2014 Benjamin Paaßen, Andreas Stöckel + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <core/common/Exceptions.hpp> +#include <core/common/Rtti.hpp> + +#include "DemoOutput.hpp" + +namespace ousia { +namespace html { + +void DemoHTMLTransformer::writeHTML(Handle<model::Document> doc, + std::ostream &out) +{ + // write preamble + out << "<?xml version=\" 1.0 \"?>\n"; + out << "<html>\n"; + out << "\t<head>\n"; + out << "\t\t<title>Test HTML Output for" << doc->getName() << "</title>\n"; + out << "\t</head>\n"; + out << "\t<body>\n"; + + // look for the book root node. + Rooted<model::StructuredEntity> root = doc->getRoot(); + if (root->getDescriptor()->getName() != "book") { + throw OusiaException("The given documents root is no book node!"); + } + // write it to HTML. + writeSection(root, out); + // write end + out << "\t</body>\n"; + out << "</html>\n"; +} + +/** + * This is just for easier internal handling. + */ +enum class SectionType { BOOK, CHAPTER, SECTION, SUBSECTION, NONE }; + +SectionType getSectionType(const std::string &name) +{ + if (name == "book") { + return SectionType::BOOK; + } else if (name == "chapter") { + return SectionType::CHAPTER; + } else if (name == "section") { + return SectionType::SECTION; + } else if (name == "subsection") { + return SectionType::SUBSECTION; + } else { + return SectionType::NONE; + } +} + +void DemoHTMLTransformer::writeSection(Handle<model::StructuredEntity> sec, + std::ostream &out) +{ + // check the section type. + SectionType type = getSectionType(sec->getDescriptor()->getName()); + if (type == SectionType::NONE) { + // if the input node is no section, we ignore it. + return; + } + // get the fields. + std::vector<NodeVector<model::StructuredEntity>> &fields = sec->getFields(); + // check if we have a heading. + if (fields.size() > 1 && fields[1].size() > 0) { + out << "\t\t"; + switch (type) { + case SectionType::BOOK: + out << "<h1>"; + break; + case SectionType::CHAPTER: + out << "<h2>"; + break; + case SectionType::SECTION: + out << "<h3>"; + break; + case SectionType::SUBSECTION: + out << "<h4>"; + break; + case SectionType::NONE: + // this can not happen; + break; + } + // the second field marks the heading. So let's write it. + writeParagraph(fields[1][0], out, false); + // close the heading tag. + switch (type) { + case SectionType::BOOK: + out << "</h1>"; + break; + case SectionType::CHAPTER: + out << "</h2>"; + break; + case SectionType::SECTION: + out << "</h3>"; + break; + case SectionType::SUBSECTION: + out << "</h4>"; + break; + case SectionType::NONE: + // this can not happen; + break; + } + out << "\n"; + } + + // then write the section content recursively. + for (auto &n : fields[0]) { + /* + * Strictly speaking this is the wrong mechanism, because we would have + * to make an "isa" call here because we can not rely on our knowledge + * that paragraphs can only be paragraphs or lists. There would have + * to be a listener structure of transformations that check if they can + * transform this specific node. + */ + std::string childDescriptorName = n->getDescriptor()->getName(); + if (childDescriptorName == "paragraph") { + writeParagraph(n, out); + // TODO: Implement + // } else if(childDescriptorName == "ul"){ + // writeList(n, out); + } else { + writeSection(n, out); + } + } +} + +void DemoHTMLTransformer::writeParagraph(Handle<model::StructuredEntity> par, + std::ostream &out, bool writePTags) +{ + // validate descriptor. + if (par->getDescriptor()->getName() != "paragraph") { + throw OusiaException("Expected paragraph!"); + } + // get the fields. + std::vector<NodeVector<model::StructuredEntity>> &fields = par->getFields(); + // write heading if its there. + // check if we have a heading. + if (fields.size() > 1 && fields[1].size() > 0) { + // start the heading tag + out << "\t\t<h5>"; + // the second field marks the heading. So let's write it. + writeParagraph(fields[1][0], out, false); + // close the heading tag. + out << "</h5>\n"; + } + // write start tag + if (writePTags) { + out << "\t\t<p>"; + } + // write content + // TODO: What about emphasis? + for (auto &text : fields[0]) { + if (text->getDescriptor()->getName() != "text") { + throw OusiaException("Expected text!"); + } + Handle<model::DocumentPrimitive> primitive = + text->getFields()[0][0].cast<model::DocumentPrimitive>(); + if (primitive == nullptr) { + throw OusiaException("Text field is not primitive!"); + } + out << primitive->getContent().asString(); + } + // write end tag + if (writePTags) { + out << "</p>\n"; + } +} +} +} diff --git a/src/plugins/html/DemoOutput.hpp b/src/plugins/html/DemoOutput.hpp new file mode 100644 index 0000000..ca9bcd2 --- /dev/null +++ b/src/plugins/html/DemoOutput.hpp @@ -0,0 +1,85 @@ +/* + Ousía + Copyright (C) 2014 Benjamin Paaßen, Andreas Stöckel + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +/** + * @file DemoOutput.hpp + * + * This implements a Demo HTML output for the following domains: + * * book + * * headings + * * emphasis + * * lists + * + * @author Benjamin Paassen - bpaassen@techfak.uni-bielefeld.de + */ +#ifndef _OUSIA_HTML_DEMO_OUTPUT_HPP_ +#define _OUSIA_HTML_DEMO_OUTPUT_HPP_ + +#include <ostream> + +#include <core/model/Document.hpp> + +namespace ousia { +namespace html { + +class DemoHTMLTransformer { +private: + /** + * This method is to be called recursively to write a chapter, section or + * subsection to HTML. + */ + void writeSection(Handle<model::StructuredEntity> sec, std::ostream& out); + /** + * This method is to be called recursively to write a paragraph to HTML. + */ + void writeParagraph(Handle<model::StructuredEntity> par, std::ostream& out, + bool writePTags = true); + /** + * This method is to be called recursively to write a list to HTML. + * TODO: Implement + */ +// void writeList(Handle<StructuredEntity> sec, std::ostream& out, +// int tabdepth); + + //TODO: Implement emphasis. + +public: + /** + * This writes a HTML representation of the given document to the given + * output stream. Note that this method lacks the generality of our Ousia + * approach with respect to two important points: + * 1.) It hardcodes the dependency to a certain set of domains in the C++ + * code. + * 2.) It does not use the proposed pipeline of first copying the document + * graph, then attaching style attributes and then transforming it to a + * specific output format but does all of these steps at once. + * 3.) It does not use different transformers for the different domains but + * does all transformations at once. + * Therefore this is not an adequate model of our algorithms but only a + * Demo. + * + * @param doc is a Document using concepts of the book, headings, emphasis + * and lists domains but no other. + * @param out is the output stream the data shall be written to. + */ + void writeHTML(Handle<model::Document> doc, std::ostream& out); +}; +} +} + +#endif |