diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/managed/Managed.hpp | 2 | ||||
-rw-r--r-- | src/core/model/Document.cpp | 8 | ||||
-rw-r--r-- | src/core/model/Document.hpp | 73 | ||||
-rw-r--r-- | src/plugins/html/DemoOutput.cpp | 38 |
4 files changed, 79 insertions, 42 deletions
diff --git a/src/core/managed/Managed.hpp b/src/core/managed/Managed.hpp index 8ad609f..dd1a23a 100644 --- a/src/core/managed/Managed.hpp +++ b/src/core/managed/Managed.hpp @@ -357,7 +357,7 @@ public: * Statically casts the handle to a handle of the given type. */ template <class T2> - Handle<T2> cast() + Handle<T2> cast() const { return Handle<T2>(static_cast<T2 *>(ptr)); } diff --git a/src/core/model/Document.cpp b/src/core/model/Document.cpp index f591095..723aafd 100644 --- a/src/core/model/Document.cpp +++ b/src/core/model/Document.cpp @@ -111,13 +111,15 @@ const Rtti<model::Document> Document = const Rtti<model::AnnotationEntity> AnnotationEntity = RttiBuilder("AnnotationEntity").parent(&DocumentEntity).composedOf( &StructuredEntity); +const Rtti<model::StructureNode> StructureNode = + RttiBuilder("StructureNode").parent(&Node); const Rtti<model::StructuredEntity> StructuredEntity = - RttiBuilder("StructuredEntity").parent(&DocumentEntity).composedOf( + RttiBuilder("StructuredEntity").parent(&DocumentEntity).parent(&StructureNode).composedOf( {&StructuredEntity, &Anchor, &DocumentPrimitive}); const Rtti<model::DocumentPrimitive> DocumentPrimitive = - RttiBuilder("DocumentPrimitive").parent(&StructuredEntity); + RttiBuilder("DocumentPrimitive").parent(&StructureNode); const Rtti<model::AnnotationEntity::Anchor> Anchor = - RttiBuilder("Anchor").parent(&StructuredEntity); + RttiBuilder("Anchor").parent(&StructureNode); } } diff --git a/src/core/model/Document.hpp b/src/core/model/Document.hpp index 6e3b320..9bf8f07 100644 --- a/src/core/model/Document.hpp +++ b/src/core/model/Document.hpp @@ -124,9 +124,8 @@ class Rtti; namespace model { -class StructuredEntity; -class AnnotationEntity; class Document; +class StructureNode; /** * A DocumentEntity is the common superclass for StructuredEntities and @@ -139,11 +138,11 @@ class Document; * name. * */ -class DocumentEntity : public Node { +class DocumentEntity : public virtual Node { private: Owned<Descriptor> descriptor; const Variant attributes; - std::vector<NodeVector<StructuredEntity>> fields; + std::vector<NodeVector<StructureNode>> fields; int getFieldDescriptorIndex(const std::string &fieldName, bool enforce) const; @@ -164,10 +163,12 @@ public: if (!descriptor.isNull()) { for (size_t f = 0; f < descriptor->getFieldDescriptors().size(); f++) { - fields.push_back(NodeVector<StructuredEntity>(this)); + fields.push_back(NodeVector<StructureNode>(this)); } } } + //TODO: Is this necessary? + virtual ~DocumentEntity() {}; Rooted<Descriptor> getDescriptor() const { return descriptor; } @@ -203,7 +204,7 @@ public: * FieldDescriptor in the Domain description. * @return a NodeVector of all StructuredEntities in that field. */ - const NodeVector<StructuredEntity> &getField( + const NodeVector<StructureNode> &getField( const std::string &fieldName = "") const { return fields[getFieldDescriptorIndex(fieldName, true)]; @@ -220,7 +221,7 @@ public: * this DocumentEntity. * @return a NodeVector of all StructuredEntities in that field. */ - const NodeVector<StructuredEntity> &getField( + const NodeVector<StructureNode> &getField( Handle<FieldDescriptor> fieldDescriptor) const { return fields[getFieldDescriptorIndex(fieldDescriptor, true)]; @@ -238,7 +239,7 @@ public: * @param fieldName is the name of a field as specified in the * FieldDescriptor in the Domain description. */ - void addStructuredEntity(Handle<StructuredEntity> s, + void addStructuredEntity(Handle<StructureNode> s, const std::string &fieldName = "") { fields[getFieldDescriptorIndex(fieldName, true)].push_back(s); @@ -256,10 +257,10 @@ public: * @param fieldName is the name of a field as specified in the * FieldDescriptor in the Domain description. */ - void addStructuredEntities(const std::vector<Handle<StructuredEntity>> &ss, + void addStructuredEntities(const std::vector<Handle<StructureNode>> &ss, const std::string &fieldName = "") { - NodeVector<StructuredEntity> &field = + NodeVector<StructureNode> &field = fields[getFieldDescriptorIndex(fieldName, true)]; field.insert(field.end(), ss.begin(), ss.end()); } @@ -274,7 +275,7 @@ public: * @param fieldDescriptor is a FieldDescriptor defined in the Descriptor for * this DocumentEntity. */ - void addStructuredEntity(Handle<StructuredEntity> s, + void addStructuredEntity(Handle<StructureNode> s, Handle<FieldDescriptor> fieldDescriptor) { fields[getFieldDescriptorIndex(fieldDescriptor, true)].push_back(s); @@ -291,26 +292,42 @@ public: * @param fieldDescriptor is a FieldDescriptor defined in the Descriptor for * this DocumentEntity. */ - void addStructuredEntities(const std::vector<Handle<StructuredEntity>> &ss, + void addStructuredEntities(const std::vector<Handle<StructureNode>> &ss, Handle<FieldDescriptor> fieldDescriptor) { - NodeVector<StructuredEntity> &field = + NodeVector<StructureNode> &field = fields[getFieldDescriptorIndex(fieldDescriptor, true)]; field.insert(field.end(), ss.begin(), ss.end()); } }; /** - * A StructuredEntity is a node in the Structure Tree of a document. For more + * A StructureNode is a Node of the StructureTree of the document. This is a + * common superclass for StructuredEntity, Anchor and DocumentPrimitive. + */ +class StructureNode : public virtual Node { +public: + StructureNode(Manager &mgr, std::string name, Handle<Node> parent) + : Node(mgr, std::move(name), parent) + { + } + //TODO: Is this necessary? + virtual ~StructureNode(){}; +}; + +/** + * A StructuredEntity is an instance of a StructuredClass. For more * information please refer to the header documentation above. */ -class StructuredEntity : public DocumentEntity { +class StructuredEntity : public DocumentEntity, public StructureNode { public: StructuredEntity(Manager &mgr, Handle<Node> parent, Handle<StructuredClass> descriptor, Variant attributes, std::string name = "") - : DocumentEntity(mgr, parent, descriptor, std::move(attributes), - std::move(name)) + : Node(mgr, std::move(name), parent), + DocumentEntity(mgr, parent, descriptor, std::move(attributes), + std::move(name)), + StructureNode(mgr, std::move(name), parent) { } }; @@ -320,15 +337,20 @@ public: * The most straightforward example for this is the actual document text, e.g. * inside a paragraph. In that case this would represent a mere string. */ -class DocumentPrimitive : public StructuredEntity { +class DocumentPrimitive : public StructureNode { +private: + Variant content; + public: DocumentPrimitive(Manager &mgr, Handle<DocumentEntity> parent, Variant content = {}) - : StructuredEntity(mgr, parent, nullptr, std::move(content)) + : Node(mgr, parent), + StructureNode(mgr, "", parent), + content(content) { } - Variant getContent() const { return getAttributes(); } + Variant getContent() const { return content; } // TODO: Override such methods like "getField" to disable them? }; @@ -361,7 +383,7 @@ public: * referenced by an AnnotationEntity as it start and end point. * Please refer to the AnnotationEntity documentation for more information. */ - class Anchor : public StructuredEntity { + class Anchor : public StructureNode { public: /** * @param mgr is the Manager instance. @@ -369,8 +391,9 @@ public: * not the AnnotationEntity that references this Anchor. * @param name is the Anchor id. */ - Anchor(Manager &mgr, Handle<DocumentEntity> parent, std::string name) - : StructuredEntity(mgr, parent, nullptr, Variant(), std::move(name)) + Anchor(Manager &mgr, std::string name, Handle<DocumentEntity> parent) + : Node(mgr, std::move(name), parent), + StructureNode(mgr, std::move(name), parent) { } }; @@ -399,7 +422,8 @@ public: Handle<AnnotationClass> descriptor, Handle<Anchor> start, Handle<Anchor> end, Variant attributes = {}, std::string name = "") - : DocumentEntity(mgr, parent, descriptor, attributes, std::move(name)), + : Node(mgr, std::move(name), parent), + DocumentEntity(mgr, parent, descriptor, attributes, std::move(name)), start(acquire(start)), end(acquire(end)) { @@ -509,6 +533,7 @@ namespace RttiTypes { extern const Rtti<model::Document> Document; extern const Rtti<model::DocumentEntity> DocumentEntity; extern const Rtti<model::AnnotationEntity> AnnotationEntity; +extern const Rtti<model::StructureNode> StructureNode; extern const Rtti<model::StructuredEntity> StructuredEntity; extern const Rtti<model::DocumentPrimitive> DocumentPrimitive; extern const Rtti<model::AnnotationEntity::Anchor> Anchor; diff --git a/src/plugins/html/DemoOutput.cpp b/src/plugins/html/DemoOutput.cpp index 4cadf12..7dc1660 100644 --- a/src/plugins/html/DemoOutput.cpp +++ b/src/plugins/html/DemoOutput.cpp @@ -33,8 +33,7 @@ void DemoHTMLTransformer::writeHTML(Handle<model::Document> doc, { Manager &mgr = doc->getManager(); // Create an XML object tree for the document first. - Rooted<xml::Element> html{new xml::Element{ - mgr, {nullptr}, "html"}}; + Rooted<xml::Element> html{new xml::Element{mgr, {nullptr}, "html"}}; // add the head Element Rooted<xml::Element> head{new xml::Element{mgr, html, "head"}}; html->addChild(head); @@ -117,8 +116,8 @@ Rooted<xml::Element> DemoHTMLTransformer::transformSection( // check if we have a heading. if (section->hasField("heading") && section->getField("heading").size() > 0) { - Rooted<model::StructuredEntity> heading = - section->getField("heading")[0]; + Handle<model::StructuredEntity> heading = + section->getField("heading")[0].cast<model::StructuredEntity>(); std::string headingclass; switch (type) { case SectionType::BOOK: @@ -147,8 +146,11 @@ Rooted<xml::Element> DemoHTMLTransformer::transformSection( } // Then we get all the children. - NodeVector<model::StructuredEntity> mainField = section->getField(); - for (auto &n : mainField) { + for (auto &n : section->getField()) { + if (!n->isa(RttiTypes::StructuredEntity)) { + continue; + } + Handle<model::StructuredEntity> s = n.cast<model::StructuredEntity>(); /* * 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 @@ -156,14 +158,14 @@ Rooted<xml::Element> DemoHTMLTransformer::transformSection( * to be a listener structure of transformations that check if they can * transform this specific node. */ - const std::string childDescriptorName = n->getDescriptor()->getName(); + const std::string childDescriptorName = s->getDescriptor()->getName(); Rooted<xml::Element> child; if (childDescriptorName == "paragraph") { - child = transformParagraph(sec, n, startMap, endMap); + child = transformParagraph(sec, s, startMap, endMap); } else if (childDescriptorName == "ul" || childDescriptorName == "ol") { - child = transformList(sec, n, startMap, endMap); + child = transformList(sec, s, startMap, endMap); } else { - child = transformSection(sec, n, startMap, endMap); + child = transformSection(sec, s, startMap, endMap); } if (!child.isNull()) { sec->addChild(child); @@ -181,7 +183,9 @@ Rooted<xml::Element> DemoHTMLTransformer::transformList( std::string listclass = list->getDescriptor()->getName(); Rooted<xml::Element> l{new xml::Element{mgr, parent, listclass}}; // iterate through list items. - for (auto &item : list->getField()) { + for (auto &it : list->getField()) { + Handle<model::StructuredEntity> item = + it.cast<model::StructuredEntity>(); std::string itDescrName = item->getDescriptor()->getName(); if (itDescrName == "item") { // create the list item. @@ -259,7 +263,8 @@ Rooted<xml::Element> DemoHTMLTransformer::transformParagraph( // check if we have a heading. if (par->hasField("heading") && par->getField("heading").size() > 0) { - Rooted<model::StructuredEntity> heading = par->getField("heading")[0]; + Handle<model::StructuredEntity> heading = + par->getField("heading")[0].cast<model::StructuredEntity>(); // put the heading in a strong xml::Element. Rooted<xml::Element> strong{new xml::Element{mgr, p, "strong"}}; p->addChild(strong); @@ -334,10 +339,15 @@ Rooted<xml::Element> DemoHTMLTransformer::transformParagraph( continue; } // if this is not an anchor, we can only handle text. - std::string childDescriptorName = n->getDescriptor()->getName(); + if(!n->isa(RttiTypes::StructuredEntity)){ + continue; + } + Handle<model::StructuredEntity> t = n.cast<model::StructuredEntity>(); + + std::string childDescriptorName = t->getDescriptor()->getName(); if (childDescriptorName == "text") { Handle<model::DocumentPrimitive> primitive = - n->getField()[0].cast<model::DocumentPrimitive>(); + t->getField()[0].cast<model::DocumentPrimitive>(); if (primitive.isNull()) { throw OusiaException("Text field is not primitive!"); } |