From 2c3b327739b79d5ba7fe931e205bec1ad320b360 Mon Sep 17 00:00:00 2001 From: Benjamin Paassen Date: Thu, 8 Jan 2015 18:11:21 +0100 Subject: further extended the advanced document example, slightly improved XML serialization and fixed a bug in DemoOutput leading to errors if a section/paragraph had no heading. --- src/core/XML.cpp | 29 +++++++++++++++--------- src/core/XML.hpp | 7 ++++-- src/core/model/Domain.hpp | 13 +++++------ src/plugins/html/DemoOutput.cpp | 50 ++++++++++++++++++++++++++++------------- src/plugins/html/DemoOutput.hpp | 8 +------ 5 files changed, 65 insertions(+), 42 deletions(-) (limited to 'src') diff --git a/src/core/XML.cpp b/src/core/XML.cpp index 038cb86..7f03b35 100644 --- a/src/core/XML.cpp +++ b/src/core/XML.cpp @@ -4,12 +4,16 @@ namespace ousia { namespace xml { -void Node::serialize(std::ostream& out){ +void Node::serialize(std::ostream &out, const std::string &doctype) +{ out << "\n"; + if (doctype != "") { + out << doctype << "\n"; + } doSerialize(out, 0); } -void Element::doSerialize(std::ostream& out, unsigned int tabdepth) +void Element::doSerialize(std::ostream &out, unsigned int tabdepth) { for (unsigned int t = 0; t < tabdepth; t++) { out << '\t'; @@ -18,17 +22,22 @@ void Element::doSerialize(std::ostream& out, unsigned int tabdepth) for (auto &a : attributes) { out << ' ' << a.first << "=\"" << a.second << '\"'; } - out << ">\n"; - for (auto &n : children) { - n->doSerialize(out, tabdepth + 1); - } - for (unsigned int t = 0; t < tabdepth; t++) { - out << '\t'; + // if we have no children, we close the tag immediately. + if (children.size() == 0) { + out << "/>\n"; + } else { + out << ">\n"; + for (auto &n : children) { + n->doSerialize(out, tabdepth + 1); + } + for (unsigned int t = 0; t < tabdepth; t++) { + out << '\t'; + } + out << "\n"; } - out << "\n"; } -void Text::doSerialize(std::ostream& out, unsigned int tabdepth) +void Text::doSerialize(std::ostream &out, unsigned int tabdepth) { for (unsigned int t = 0; t < tabdepth; t++) { out << '\t'; diff --git a/src/core/XML.hpp b/src/core/XML.hpp index 9ca124a..51ef6fd 100644 --- a/src/core/XML.hpp +++ b/src/core/XML.hpp @@ -64,9 +64,12 @@ public: /** * This method writes an XML prolog and the XML representing the current * node, including all children, to the given output stream. - * @param out is the output stream the serialized data shall be written to. + * @param out is the output stream the serialized data shall be + * written to. + * @param doctype enables you to add a prefix after the XML prolog + * specifying the doctype. */ - void serialize(std::ostream &out); + void serialize(std::ostream &out, const std::string & doctype = ""); /** * This method just writes the XML representation of this node to the * output stream, without the XML prolog. diff --git a/src/core/model/Domain.hpp b/src/core/model/Domain.hpp index 96e13c7..8d5de0c 100644 --- a/src/core/model/Domain.hpp +++ b/src/core/model/Domain.hpp @@ -261,11 +261,6 @@ protected: VisitorSet &visited) override; public: - /** - * Note, that this flag will always be set to "false" for non-primitive - * FieldDescriptors, because in that case the cardinalities regulate - * whether children have to be inserted or not. - */ const bool optional; // TODO: What about the name of default fields? @@ -305,15 +300,19 @@ public: * TREE for the main or default structure or SUBTREE * for supporting structures. * @param name is the name of this field. + * @param optional should be set to 'false' is this field needs to be + * filled in order for an instance of the parent + * Descriptor to be valid. */ FieldDescriptor(Manager &mgr, Handle parent, FieldType fieldType = FieldType::TREE, - std::string name = "") + std::string name = "", + bool optional = false) : Node(mgr, std::move(name), parent), children(this), fieldType(fieldType), // TODO: What would be a wise initialization of the primitiveType? - optional(false) + optional(optional) { } diff --git a/src/plugins/html/DemoOutput.cpp b/src/plugins/html/DemoOutput.cpp index 035ba25..eac240b 100644 --- a/src/plugins/html/DemoOutput.cpp +++ b/src/plugins/html/DemoOutput.cpp @@ -30,10 +30,18 @@ void DemoHTMLTransformer::writeHTML(Handle doc, { Manager &mgr = doc->getManager(); // Create an XML object tree for the document first. - Rooted html{new xml::Element{mgr, "html"}}; + Rooted html{new xml::Element{ + mgr, "html", {{"xlmns", "http://www.w3.org/1999/xhtml"}}}}; // add the head Element Rooted head{new xml::Element{mgr, "head"}}; html->children.push_back(head); + // add the meta element. + Rooted meta{ + new xml::Element{mgr, + "meta", + {{"http-equiv", "Content-Type"}, + {"content", "text/html; charset=utf-8"}}}}; + head->children.push_back(meta); // add the title Element with Text Rooted title{new xml::Element{mgr, "title"}}; head->children.push_back(title); @@ -56,20 +64,21 @@ void DemoHTMLTransformer::writeHTML(Handle doc, body->children.push_back(book); // After the content has been transformed, we serialize it. - html->serialize(out); + html->serialize( + out, + ""); } /** * This is just for easier internal handling. */ -enum class SectionType { BOOK, CHAPTER, SECTION, SUBSECTION, NONE }; +enum class SectionType { BOOK, 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") { @@ -79,7 +88,8 @@ SectionType getSectionType(const std::string &name) } } -Rooted DemoHTMLTransformer::transformSection(Handle section) +Rooted DemoHTMLTransformer::transformSection( + Handle section) { Manager &mgr = section->getManager(); // check the section type. @@ -93,7 +103,8 @@ Rooted DemoHTMLTransformer::transformSection(Handle sec{ new xml::Element{mgr, "div", {{"class", secclass}}}}; // check if we have a heading. - if (section->hasField("heading")) { + if (section->hasField("heading") && + section->getField("heading").size() > 0) { Rooted heading = section->getField("heading")[0]; std::string headingclass; @@ -101,14 +112,11 @@ Rooted DemoHTMLTransformer::transformSection(Handle DemoHTMLTransformer::transformSection(Handle DemoHTMLTransformer::transformParagraph(Handle par) +Rooted DemoHTMLTransformer::transformParagraph( + Handle par) { Manager &mgr = par->getManager(); - // create the p xml::Element + // create the p Element Rooted p{new xml::Element{mgr, "p"}}; // check if we have a heading. - if (par->hasField("heading")) { + if (par->hasField("heading") && par->getField("heading").size() > 0) { Rooted heading = par->getField("heading")[0]; // put the heading in a strong xml::Element. Rooted strong{new xml::Element{mgr, "strong"}}; @@ -172,7 +181,7 @@ Rooted DemoHTMLTransformer::transformParagraph(Handlechildren.push_back(n); } } - + // transform paragraph children to XML as well for (auto &n : par->getField()) { std::string childDescriptorName = n->getDescriptor()->getName(); @@ -189,5 +198,14 @@ Rooted DemoHTMLTransformer::transformParagraph(Handle +// DemoHTMLTransformer::transformList(Handle list){ +// Manager &mgr = list->getManager(); +// // create the list Element, which is either ul or ol (depends on descriptor) +// std::string listclass = list->getDescriptor()->getName(); +// Rooted l{new xml::Element{mgr, listclass}}; +// // iterate through +//} } } diff --git a/src/plugins/html/DemoOutput.hpp b/src/plugins/html/DemoOutput.hpp index 70a5daa..0819d7f 100644 --- a/src/plugins/html/DemoOutput.hpp +++ b/src/plugins/html/DemoOutput.hpp @@ -46,13 +46,7 @@ private: */ Rooted transformSection(Handle sec); Rooted transformParagraph(Handle par); - /** - * This method is to be called recursively to write a list to HTML. - * TODO: Implement - */ -// void writeList(Handle sec, std::ostream& out, -// int tabdepth); - +// Rooted transformList(Handle list); //TODO: Implement emphasis. public: -- cgit v1.2.3