From 8357a653b22d693e2328e71b638762ace086a28a Mon Sep 17 00:00:00 2001 From: andiwand Date: Sun, 3 Dec 2023 12:00:46 +0100 Subject: [PATCH] revert element id --- src/odr/document_element.cpp | 219 +++++------- src/odr/document_element.hpp | 36 +- src/odr/internal/abstract/document.hpp | 3 +- .../internal/abstract/document_element.hpp | 329 +++++++----------- src/odr/internal/common/document_element.cpp | 56 +-- src/odr/internal/common/document_element.hpp | 66 ++-- src/odr/internal/odf/odf_document.cpp | 5 +- src/odr/internal/odf/odf_document.hpp | 3 +- src/odr/internal/odf/odf_element.cpp | 201 +++++------ src/odr/internal/odf/odf_element.hpp | 196 ++++------- src/odr/internal/odf/odf_parser.cpp | 14 +- src/odr/internal/odf/odf_spreadsheet.cpp | 59 ++-- src/odr/internal/odf/odf_spreadsheet.hpp | 32 +- .../ooxml_presentation_document.cpp | 15 +- .../ooxml_presentation_document.hpp | 10 +- .../ooxml_presentation_element.cpp | 104 ++---- .../ooxml_presentation_element.hpp | 117 +++---- .../ooxml_presentation_parser.cpp | 61 ++-- .../ooxml_presentation_parser.hpp | 9 +- .../ooxml_spreadsheet_document.cpp | 12 +- .../ooxml_spreadsheet_document.hpp | 9 +- .../spreadsheet/ooxml_spreadsheet_element.cpp | 146 ++++---- .../spreadsheet/ooxml_spreadsheet_element.hpp | 112 +++--- .../spreadsheet/ooxml_spreadsheet_parser.cpp | 58 ++- .../spreadsheet/ooxml_spreadsheet_parser.hpp | 9 +- .../spreadsheet/ooxml_spreadsheet_style.hpp | 4 +- .../ooxml/text/ooxml_text_document.cpp | 15 +- .../ooxml/text/ooxml_text_document.hpp | 5 +- .../ooxml/text/ooxml_text_element.cpp | 196 ++++------- .../ooxml/text/ooxml_text_element.hpp | 145 ++++---- .../internal/ooxml/text/ooxml_text_parser.cpp | 99 +++--- .../internal/ooxml/text/ooxml_text_parser.hpp | 7 +- 32 files changed, 947 insertions(+), 1405 deletions(-) diff --git a/src/odr/document_element.cpp b/src/odr/document_element.cpp index cdbcf702..b06a0bff 100644 --- a/src/odr/document_element.cpp +++ b/src/odr/document_element.cpp @@ -9,9 +9,8 @@ namespace odr { Element::Element() = default; -Element::Element( - const internal::abstract::Document *document, - std::pair element) +Element::Element(const internal::abstract::Document *document, + internal::abstract::Element *element) : m_document{document}, m_element{element} {} bool Element::operator==(const Element &rhs) const { @@ -24,39 +23,31 @@ bool Element::operator!=(const Element &rhs) const { Element::operator bool() const { return exists_(); } -bool Element::exists_() const { return m_element.first != nullptr; } - -internal::abstract::Element *Element::element_() const { - return m_element.first; -} - -ElementIdentifier Element::id_() const { return m_element.second; } +bool Element::exists_() const { return m_element != nullptr; } ElementType Element::type() const { - return exists_() ? element_()->type(m_document, id_()) : ElementType::none; + return exists_() ? m_element->type(m_document) : ElementType::none; } Element Element::parent() const { - return exists_() ? Element(m_document, element_()->parent(m_document, id_())) + return exists_() ? Element(m_document, m_element->parent(m_document)) : Element(); } Element Element::first_child() const { - return exists_() - ? Element(m_document, element_()->first_child(m_document, id_())) - : Element(); + return exists_() ? Element(m_document, m_element->first_child(m_document)) + : Element(); } Element Element::previous_sibling() const { - return exists_() ? Element(m_document, - element_()->previous_sibling(m_document, id_())) - : Element(); + return exists_() + ? Element(m_document, m_element->previous_sibling(m_document)) + : Element(); } Element Element::next_sibling() const { - return exists_() - ? Element(m_document, element_()->next_sibling(m_document, id_())) - : Element(); + return exists_() ? Element(m_document, m_element->next_sibling(m_document)) + : Element(); } TextRoot Element::text_root() const { return {m_document, m_element}; } @@ -104,16 +95,16 @@ CustomShape Element::custom_shape() const { return {m_document, m_element}; } Image Element::image() const { return {m_document, m_element}; } ElementRange Element::children() const { - return {exists_() ? ElementIterator(m_document, element_()->first_child( - m_document, id_())) - : ElementIterator(), + return {exists_() + ? ElementIterator(m_document, m_element->first_child(m_document)) + : ElementIterator(), ElementIterator()}; } ElementIterator::ElementIterator() = default; ElementIterator::ElementIterator(const internal::abstract::Document *document, - InternalElement element) + internal::abstract::Element *element) : m_document{document}, m_element{element} {} bool ElementIterator::operator==(const ElementIterator &rhs) const { @@ -130,7 +121,7 @@ ElementIterator::reference ElementIterator::operator*() const { ElementIterator &ElementIterator::operator++() { if (exists_()) { - m_element = element_()->next_sibling(m_document, id_()); + m_element = m_element->next_sibling(m_document); } return *this; } @@ -139,16 +130,10 @@ ElementIterator ElementIterator::operator++(int) { if (!exists_()) { return {}; } - return {m_document, element_()->next_sibling(m_document, id_())}; + return {m_document, m_element->next_sibling(m_document)}; } -bool ElementIterator::exists_() const { return m_element.first != nullptr; } - -internal::abstract::Element *ElementIterator::element_() const { - return m_element.first; -} - -ElementIdentifier ElementIterator::id_() const { return m_element.second; } +bool ElementIterator::exists_() const { return m_element != nullptr; } ElementRange::ElementRange() = default; @@ -162,310 +147,292 @@ ElementIterator ElementRange::begin() const { return m_begin; } ElementIterator ElementRange::end() const { return m_end; } PageLayout TextRoot::page_layout() const { - return exists_() ? element_()->page_layout(m_document, id_()) : PageLayout(); + return exists_() ? m_element->page_layout(m_document) : PageLayout(); } MasterPage TextRoot::first_master_page() const { return exists_() - ? MasterPage(m_document, - element_()->first_master_page(m_document, id_())) + ? MasterPage(m_document, m_element->first_master_page(m_document)) : MasterPage(); } std::string Slide::name() const { - return exists_() ? element_()->name(m_document, id_()) : ""; + return exists_() ? m_element->name(m_document) : ""; } PageLayout Slide::page_layout() const { - return exists_() ? element_()->page_layout(m_document, id_()) : PageLayout(); + return exists_() ? m_element->page_layout(m_document) : PageLayout(); } MasterPage Slide::master_page() const { - return exists_() ? MasterPage(m_document, - element_()->master_page(m_document, id_())) + return exists_() ? MasterPage(m_document, m_element->master_page(m_document)) : MasterPage(); } std::string Sheet::name() const { - return exists_() ? element_()->name(m_document, id_()) : ""; + return exists_() ? m_element->name(m_document) : ""; } TableDimensions Sheet::dimensions() const { - return exists_() ? element_()->dimensions(m_document, id_()) - : TableDimensions(); + return exists_() ? m_element->dimensions(m_document) : TableDimensions(); } TableDimensions Sheet::content(std::optional range) const { - return exists_() ? element_()->content(m_document, id_(), range) - : TableDimensions(); + return exists_() ? m_element->content(m_document, range) : TableDimensions(); } TableColumn Sheet::column(std::uint32_t column) const { - return exists_() ? TableColumn(m_document, - {element_()->column(m_document, id_(), column), - 0}) // TODO - : TableColumn(); + return exists_() + ? TableColumn(m_document, m_element->column(m_document, column)) + : TableColumn(); } TableRow Sheet::row(std::uint32_t row) const { - return exists_() - ? TableRow(m_document, - {element_()->row(m_document, id_(), row), 0}) // TODO - : TableRow(); + return exists_() ? TableRow(m_document, m_element->row(m_document, row)) + : TableRow(); } TableCell Sheet::cell(std::uint32_t column, std::uint32_t row) const { return exists_() - ? TableCell(m_document, - {element_()->cell(m_document, id_(), column, row), - 0}) // TODO + ? TableCell(m_document, m_element->cell(m_document, column, row)) : TableCell(); } ElementRange Sheet::shapes() const { - return exists_() - ? ElementRange(ElementIterator( - m_document, - {element_()->first_shape(m_document, id_()), 0})) // TODO - : ElementRange(); + return exists_() ? ElementRange(ElementIterator( + m_document, m_element->first_shape(m_document))) + : ElementRange(); } TableStyle Sheet::style() const { - return exists_() ? element_()->style(m_document, id_()) : TableStyle(); + return exists_() ? m_element->style(m_document) : TableStyle(); } std::string Page::name() const { - return exists_() ? element_()->name(m_document, id_()) : ""; + return exists_() ? m_element->name(m_document) : ""; } PageLayout Page::page_layout() const { - return exists_() ? element_()->page_layout(m_document, id_()) : PageLayout(); + return exists_() ? m_element->page_layout(m_document) : PageLayout(); } MasterPage Page::master_page() const { - return exists_() ? MasterPage(m_document, - element_()->master_page(m_document, id_())) + return exists_() ? MasterPage(m_document, m_element->master_page(m_document)) : MasterPage(); } PageLayout MasterPage::page_layout() const { - return exists_() ? element_()->page_layout(m_document, id_()) : PageLayout(); + return exists_() ? m_element->page_layout(m_document) : PageLayout(); } TextStyle LineBreak::style() const { - return exists_() ? element_()->style(m_document, id_()) : TextStyle(); + return exists_() ? m_element->style(m_document) : TextStyle(); } ParagraphStyle Paragraph::style() const { - return exists_() ? element_()->style(m_document, id_()) : ParagraphStyle(); + return exists_() ? m_element->style(m_document) : ParagraphStyle(); } TextStyle Paragraph::text_style() const { - return exists_() ? element_()->text_style(m_document, id_()) : TextStyle(); + return exists_() ? m_element->text_style(m_document) : TextStyle(); } TextStyle Span::style() const { - return exists_() ? element_()->style(m_document, id_()) : TextStyle(); + return exists_() ? m_element->style(m_document) : TextStyle(); } std::string Text::content() const { - return exists_() ? element_()->content(m_document, id_()) : ""; + return exists_() ? m_element->content(m_document) : ""; } void Text::set_content(const std::string &text) const { if (exists_()) { - element_()->set_content(m_document, id_(), text); + m_element->set_content(m_document, text); } } TextStyle Text::style() const { - return exists_() ? element_()->style(m_document, id_()) : TextStyle(); + return exists_() ? m_element->style(m_document) : TextStyle(); } std::string Link::href() const { - return exists_() ? element_()->href(m_document, id_()) : ""; + return exists_() ? m_element->href(m_document) : ""; } std::string Bookmark::name() const { - return exists_() ? element_()->name(m_document, id_()) : ""; + return exists_() ? m_element->name(m_document) : ""; } TextStyle ListItem::style() const { - return exists_() ? element_()->style(m_document, id_()) : TextStyle(); + return exists_() ? m_element->style(m_document) : TextStyle(); } ElementRange Table::columns() const { - return exists_() - ? ElementRange(ElementIterator( - m_document, element_()->first_column(m_document, id_()))) - : ElementRange(); + return exists_() ? ElementRange(ElementIterator( + m_document, m_element->first_column(m_document))) + : ElementRange(); } ElementRange Table::rows() const { return exists_() ? ElementRange(ElementIterator( - m_document, element_()->first_row(m_document, id_()))) + m_document, m_element->first_row(m_document))) : ElementRange(); } TableDimensions Table::dimensions() const { - return exists_() ? element_()->dimensions(m_document, id_()) - : TableDimensions(); + return exists_() ? m_element->dimensions(m_document) : TableDimensions(); } TableStyle Table::style() const { - return exists_() ? element_()->style(m_document, id_()) : TableStyle(); + return exists_() ? m_element->style(m_document) : TableStyle(); } TableColumnStyle TableColumn::style() const { - return exists_() ? element_()->style(m_document, id_()) : TableColumnStyle(); + return exists_() ? m_element->style(m_document) : TableColumnStyle(); } TableRowStyle TableRow::style() const { - return exists_() ? element_()->style(m_document, id_()) : TableRowStyle(); + return exists_() ? m_element->style(m_document) : TableRowStyle(); } bool TableCell::covered() const { - return exists_() && element_()->covered(m_document, id_()); + return exists_() && m_element->covered(m_document); } TableDimensions TableCell::span() const { - return exists_() ? element_()->span(m_document, id_()) : TableDimensions(); + return exists_() ? m_element->span(m_document) : TableDimensions(); } ValueType TableCell::value_type() const { - return exists_() ? element_()->value_type(m_document, id_()) - : ValueType::string; + return exists_() ? m_element->value_type(m_document) : ValueType::string; } TableCellStyle TableCell::style() const { - return exists_() ? element_()->style(m_document, id_()) : TableCellStyle(); + return exists_() ? m_element->style(m_document) : TableCellStyle(); } AnchorType Frame::anchor_type() const { - return exists_() ? element_()->anchor_type(m_document, id_()) + return exists_() ? m_element->anchor_type(m_document) : AnchorType::as_char; // TODO default? } std::optional Frame::x() const { - return exists_() ? element_()->x(m_document, id_()) - : std::optional(); + return exists_() ? m_element->x(m_document) : std::optional(); } std::optional Frame::y() const { - return exists_() ? element_()->y(m_document, id_()) - : std::optional(); + return exists_() ? m_element->y(m_document) : std::optional(); } std::optional Frame::width() const { - return exists_() ? element_()->width(m_document, id_()) + return exists_() ? m_element->width(m_document) : std::optional(); } std::optional Frame::height() const { - return exists_() ? element_()->height(m_document, id_()) + return exists_() ? m_element->height(m_document) : std::optional(); } std::optional Frame::z_index() const { - return exists_() ? element_()->z_index(m_document, id_()) + return exists_() ? m_element->z_index(m_document) : std::optional(); } GraphicStyle Frame::style() const { - return exists_() ? element_()->style(m_document, id_()) : GraphicStyle(); + return exists_() ? m_element->style(m_document) : GraphicStyle(); } std::string Rect::x() const { - return exists_() ? element_()->x(m_document, id_()) : ""; + return exists_() ? m_element->x(m_document) : ""; } std::string Rect::y() const { - return exists_() ? element_()->y(m_document, id_()) : ""; + return exists_() ? m_element->y(m_document) : ""; } std::string Rect::width() const { - return exists_() ? element_()->width(m_document, id_()) : ""; + return exists_() ? m_element->width(m_document) : ""; } std::string Rect::height() const { - return exists_() ? element_()->height(m_document, id_()) : ""; + return exists_() ? m_element->height(m_document) : ""; } GraphicStyle Rect::style() const { - return exists_() ? element_()->style(m_document, id_()) : GraphicStyle(); + return exists_() ? m_element->style(m_document) : GraphicStyle(); } std::string Line::x1() const { - return exists_() ? element_()->x1(m_document, id_()) : ""; + return exists_() ? m_element->x1(m_document) : ""; } std::string Line::y1() const { - return exists_() ? element_()->y1(m_document, id_()) : ""; + return exists_() ? m_element->y1(m_document) : ""; } std::string Line::x2() const { - return exists_() ? element_()->x2(m_document, id_()) : ""; + return exists_() ? m_element->x2(m_document) : ""; } std::string Line::y2() const { - return exists_() ? element_()->y2(m_document, id_()) : ""; + return exists_() ? m_element->y2(m_document) : ""; } GraphicStyle Line::style() const { - return exists_() ? element_()->style(m_document, id_()) : GraphicStyle(); + return exists_() ? m_element->style(m_document) : GraphicStyle(); } std::string Circle::x() const { - return exists_() ? element_()->x(m_document, id_()) : ""; + return exists_() ? m_element->x(m_document) : ""; } std::string Circle::y() const { - return exists_() ? element_()->y(m_document, id_()) : ""; + return exists_() ? m_element->y(m_document) : ""; } std::string Circle::width() const { - return exists_() ? element_()->width(m_document, id_()) : ""; + return exists_() ? m_element->width(m_document) : ""; } std::string Circle::height() const { - return exists_() ? element_()->height(m_document, id_()) : ""; + return exists_() ? m_element->height(m_document) : ""; } GraphicStyle Circle::style() const { - return exists_() ? element_()->style(m_document, id_()) : GraphicStyle(); + return exists_() ? m_element->style(m_document) : GraphicStyle(); } std::optional CustomShape::x() const { - return exists_() ? element_()->x(m_document, id_()) : ""; + return exists_() ? m_element->x(m_document) : ""; } std::optional CustomShape::y() const { - return exists_() ? element_()->y(m_document, id_()) : ""; + return exists_() ? m_element->y(m_document) : ""; } std::string CustomShape::width() const { - return exists_() ? element_()->width(m_document, id_()) : ""; + return exists_() ? m_element->width(m_document) : ""; } std::string CustomShape::height() const { - return exists_() ? element_()->height(m_document, id_()) : ""; + return exists_() ? m_element->height(m_document) : ""; } GraphicStyle CustomShape::style() const { - return exists_() ? element_()->style(m_document, id_()) : GraphicStyle(); + return exists_() ? m_element->style(m_document) : GraphicStyle(); } bool Image::internal() const { - return exists_() && element_()->internal(m_document, id_()); + return exists_() && m_element->internal(m_document); } std::optional Image::file() const { - return exists_() ? element_()->file(m_document, id_()) - : std::optional(); + return exists_() ? m_element->file(m_document) : std::optional(); } std::string Image::href() const { - return exists_() ? element_()->href(m_document, id_()) : ""; + return exists_() ? m_element->href(m_document) : ""; } } // namespace odr diff --git a/src/odr/document_element.hpp b/src/odr/document_element.hpp index 19c99e80..99bcb1ef 100644 --- a/src/odr/document_element.hpp +++ b/src/odr/document_element.hpp @@ -73,14 +73,6 @@ class Circle; class CustomShape; class Image; -using ElementIdentifier = std::uint64_t; -using ColumnIndex = std::uint32_t; -using RowIndex = std::uint32_t; -using InternalElement = - std::pair; -template -using TypedInternalElement = std::pair; - enum class ElementType { none, @@ -133,7 +125,7 @@ enum class ValueType { class Element { public: Element(); - Element(const internal::abstract::Document *, InternalElement); + Element(const internal::abstract::Document *, internal::abstract::Element *); bool operator==(const Element &rhs) const; bool operator!=(const Element &rhs) const; @@ -174,11 +166,9 @@ class Element { protected: const internal::abstract::Document *m_document{nullptr}; - InternalElement m_element; + internal::abstract::Element *m_element{nullptr}; bool exists_() const; - internal::abstract::Element *element_() const; - ElementIdentifier id_() const; }; class ElementIterator { @@ -190,7 +180,8 @@ class ElementIterator { using iterator_category = std::forward_iterator_tag; ElementIterator(); - ElementIterator(const internal::abstract::Document *, InternalElement); + ElementIterator(const internal::abstract::Document *, + internal::abstract::Element *); bool operator==(const ElementIterator &rhs) const; bool operator!=(const ElementIterator &rhs) const; @@ -202,11 +193,9 @@ class ElementIterator { private: const internal::abstract::Document *m_document{nullptr}; - InternalElement m_element; + internal::abstract::Element *m_element{nullptr}; bool exists_() const; - internal::abstract::Element *element_() const; - ElementIdentifier id_() const; }; class ElementRange { @@ -227,9 +216,8 @@ template class TypedElement : public Element { public: TypedElement() = default; TypedElement(const internal::abstract::Document *document, - InternalElement element) - : Element(document, element), m_typed_element{ - dynamic_cast(element.first)} {} + internal::abstract::Element *element) + : Element(document, element), m_element{dynamic_cast(element)} {} bool operator==(const TypedElement &rhs) const { return m_element == rhs.m_element; @@ -239,9 +227,7 @@ template class TypedElement : public Element { } protected: - T *m_typed_element; - - T *element_() const { return m_typed_element; } + T *m_element; }; class TextRoot final : public TypedElement { @@ -274,9 +260,9 @@ class Sheet final : public TypedElement { [[nodiscard]] TableDimensions content(std::optional range) const; - [[nodiscard]] TableColumn column(ColumnIndex column) const; - [[nodiscard]] TableRow row(RowIndex row) const; - [[nodiscard]] TableCell cell(ColumnIndex column, RowIndex row) const; + [[nodiscard]] TableColumn column(std::uint32_t column) const; + [[nodiscard]] TableRow row(std::uint32_t row) const; + [[nodiscard]] TableCell cell(std::uint32_t column, std::uint32_t row) const; [[nodiscard]] ElementRange shapes() const; diff --git a/src/odr/internal/abstract/document.hpp b/src/odr/internal/abstract/document.hpp index 7a79fb97..b58daa07 100644 --- a/src/odr/internal/abstract/document.hpp +++ b/src/odr/internal/abstract/document.hpp @@ -48,8 +48,7 @@ class Document { files() const noexcept = 0; /// \return cursor to the root element of the document. - [[nodiscard]] virtual std::pair - root_element() const = 0; + [[nodiscard]] virtual Element *root_element() const = 0; }; } // namespace odr::internal::abstract diff --git a/src/odr/internal/abstract/document_element.hpp b/src/odr/internal/abstract/document_element.hpp index d9fcc3bb..e387ecf6 100644 --- a/src/odr/internal/abstract/document_element.hpp +++ b/src/odr/internal/abstract/document_element.hpp @@ -30,411 +30,324 @@ class Element { public: virtual ~Element() = default; - [[nodiscard]] virtual ElementType type(const Document *, - ElementIdentifier) const = 0; - - [[nodiscard]] virtual std::pair - parent(const Document *, ElementIdentifier) const = 0; - [[nodiscard]] virtual std::pair - first_child(const Document *, ElementIdentifier) const = 0; - [[nodiscard]] virtual std::pair - last_child(const Document *, ElementIdentifier) const = 0; - [[nodiscard]] virtual std::pair - previous_sibling(const Document *, ElementIdentifier) const = 0; - [[nodiscard]] virtual std::pair - next_sibling(const Document *, ElementIdentifier) const = 0; + [[nodiscard]] virtual ElementType type(const Document *) const = 0; + + [[nodiscard]] virtual Element *parent(const Document *) const = 0; + [[nodiscard]] virtual Element *first_child(const Document *) const = 0; + [[nodiscard]] virtual Element *last_child(const Document *) const = 0; + [[nodiscard]] virtual Element *previous_sibling(const Document *) const = 0; + [[nodiscard]] virtual Element *next_sibling(const Document *) const = 0; }; class TextRoot : public virtual Element { public: - [[nodiscard]] ElementType type(const Document *, - ElementIdentifier) const override { + [[nodiscard]] ElementType type(const Document *) const override { return ElementType::root; } - [[nodiscard]] virtual PageLayout page_layout(const Document *, - ElementIdentifier) const = 0; + [[nodiscard]] virtual PageLayout page_layout(const Document *) const = 0; - [[nodiscard]] virtual std::pair - first_master_page(const Document *, ElementIdentifier) const = 0; + [[nodiscard]] virtual abstract::Element * + first_master_page(const Document *) const = 0; }; class Slide : public virtual Element { public: - [[nodiscard]] ElementType type(const Document *, - ElementIdentifier) const override { + [[nodiscard]] ElementType type(const Document *) const override { return ElementType::slide; } - [[nodiscard]] virtual PageLayout page_layout(const Document *, - ElementIdentifier) const = 0; + [[nodiscard]] virtual PageLayout page_layout(const Document *) const = 0; - [[nodiscard]] virtual std::pair - master_page(const Document *, ElementIdentifier) const = 0; + [[nodiscard]] virtual Element *master_page(const Document *) const = 0; - [[nodiscard]] virtual std::string name(const Document *, - ElementIdentifier) const = 0; + [[nodiscard]] virtual std::string name(const Document *) const = 0; }; class Sheet : public virtual Element { public: - [[nodiscard]] ElementType type(const Document *, - ElementIdentifier) const override { + [[nodiscard]] ElementType type(const Document *) const override { return ElementType::sheet; } - [[nodiscard]] virtual std::string name(const Document *, - ElementIdentifier) const = 0; + [[nodiscard]] virtual std::string name(const Document *) const = 0; - [[nodiscard]] virtual TableDimensions dimensions(const Document *, - ElementIdentifier) const = 0; + [[nodiscard]] virtual TableDimensions dimensions(const Document *) const = 0; [[nodiscard]] virtual TableDimensions - content(const Document *, ElementIdentifier, - std::optional range) const = 0; - - [[nodiscard]] virtual Element *column(const Document *, ElementIdentifier, - ColumnIndex column) const = 0; - [[nodiscard]] virtual Element *row(const Document *, ElementIdentifier, - RowIndex row) const = 0; - [[nodiscard]] virtual Element *cell(const Document *, ElementIdentifier, - ColumnIndex column, - RowIndex row) const = 0; - - [[nodiscard]] virtual Element *first_shape(const Document *, - ElementIdentifier) const = 0; - - [[nodiscard]] virtual TableStyle style(const Document *, - ElementIdentifier) const = 0; + content(const Document *, std::optional range) const = 0; + + [[nodiscard]] virtual Element *column(const Document *, + std::uint32_t column) const = 0; + [[nodiscard]] virtual Element *row(const Document *, + std::uint32_t row) const = 0; + [[nodiscard]] virtual Element *cell(const Document *, std::uint32_t column, + std::uint32_t row) const = 0; + + [[nodiscard]] virtual Element *first_shape(const Document *) const = 0; + + [[nodiscard]] virtual TableStyle style(const Document *) const = 0; }; class Page : public virtual Element { public: - [[nodiscard]] ElementType type(const Document *, - ElementIdentifier) const override { + [[nodiscard]] ElementType type(const Document *) const override { return ElementType::page; } - [[nodiscard]] virtual PageLayout page_layout(const Document *, - ElementIdentifier) const = 0; + [[nodiscard]] virtual PageLayout page_layout(const Document *) const = 0; - [[nodiscard]] virtual std::pair - master_page(const Document *, ElementIdentifier) const = 0; + [[nodiscard]] virtual Element *master_page(const Document *) const = 0; - [[nodiscard]] virtual std::string name(const Document *, - ElementIdentifier) const = 0; + [[nodiscard]] virtual std::string name(const Document *) const = 0; }; class MasterPage : public virtual Element { public: - [[nodiscard]] ElementType type(const Document *, - ElementIdentifier) const override { + [[nodiscard]] ElementType type(const Document *) const override { return ElementType::master_page; } - [[nodiscard]] virtual PageLayout page_layout(const Document *, - ElementIdentifier) const = 0; + [[nodiscard]] virtual PageLayout page_layout(const Document *) const = 0; }; class LineBreak : public virtual Element { public: - [[nodiscard]] ElementType type(const Document *, - ElementIdentifier) const override { + [[nodiscard]] ElementType type(const Document *) const override { return ElementType::line_break; } - [[nodiscard]] virtual TextStyle style(const Document *, - ElementIdentifier) const = 0; + [[nodiscard]] virtual TextStyle style(const Document *) const = 0; }; class Paragraph : public virtual Element { public: - [[nodiscard]] ElementType type(const Document *, - ElementIdentifier) const override { + [[nodiscard]] ElementType type(const Document *) const override { return ElementType::paragraph; } - [[nodiscard]] virtual ParagraphStyle style(const Document *, - ElementIdentifier) const = 0; - [[nodiscard]] virtual TextStyle text_style(const Document *, - ElementIdentifier) const = 0; + [[nodiscard]] virtual ParagraphStyle style(const Document *) const = 0; + [[nodiscard]] virtual TextStyle text_style(const Document *) const = 0; }; class Span : public virtual Element { public: - [[nodiscard]] ElementType type(const Document *, - ElementIdentifier) const override { + [[nodiscard]] ElementType type(const Document *) const override { return ElementType::span; } - [[nodiscard]] virtual TextStyle style(const Document *document, - ElementIdentifier) const = 0; + [[nodiscard]] virtual TextStyle style(const Document *document) const = 0; }; class Text : public virtual Element { public: - [[nodiscard]] ElementType type(const Document *, - ElementIdentifier) const override { + [[nodiscard]] ElementType type(const Document *) const override { return ElementType::text; } - [[nodiscard]] virtual std::string content(const Document *, - ElementIdentifier) const = 0; - virtual void set_content(const Document *, ElementIdentifier, - const std::string &text) = 0; + [[nodiscard]] virtual std::string content(const Document *) const = 0; + virtual void set_content(const Document *, const std::string &text) = 0; - [[nodiscard]] virtual TextStyle style(const Document *, - ElementIdentifier) const = 0; + [[nodiscard]] virtual TextStyle style(const Document *) const = 0; }; class Link : public virtual Element { public: - [[nodiscard]] ElementType type(const Document *, - ElementIdentifier) const override { + [[nodiscard]] ElementType type(const Document *) const override { return ElementType::link; } - [[nodiscard]] virtual std::string href(const Document *, - ElementIdentifier) const = 0; + [[nodiscard]] virtual std::string href(const Document *) const = 0; }; class Bookmark : public virtual Element { public: - [[nodiscard]] ElementType type(const Document *, - ElementIdentifier) const override { + [[nodiscard]] ElementType type(const Document *) const override { return ElementType::bookmark; } - [[nodiscard]] virtual std::string name(const Document *, - ElementIdentifier) const = 0; + [[nodiscard]] virtual std::string name(const Document *) const = 0; }; class ListItem : public virtual Element { public: - [[nodiscard]] ElementType type(const Document *, - ElementIdentifier) const override { + [[nodiscard]] ElementType type(const Document *) const override { return ElementType::list_item; } - [[nodiscard]] virtual TextStyle style(const Document *, - ElementIdentifier) const = 0; + [[nodiscard]] virtual TextStyle style(const Document *) const = 0; }; class Table : public virtual Element { public: - [[nodiscard]] ElementType type(const Document *, - ElementIdentifier) const override { + [[nodiscard]] ElementType type(const Document *) const override { return ElementType::table; } - [[nodiscard]] virtual TableDimensions dimensions(const Document *, - ElementIdentifier) const = 0; + [[nodiscard]] virtual TableDimensions dimensions(const Document *) const = 0; - [[nodiscard]] virtual std::pair - first_column(const Document *, ElementIdentifier) const = 0; - [[nodiscard]] virtual std::pair - first_row(const Document *, ElementIdentifier) const = 0; + [[nodiscard]] virtual Element *first_column(const Document *) const = 0; + [[nodiscard]] virtual Element *first_row(const Document *) const = 0; - [[nodiscard]] virtual TableStyle style(const Document *, - ElementIdentifier) const = 0; + [[nodiscard]] virtual TableStyle style(const Document *) const = 0; }; class TableColumn : public virtual Element { public: - [[nodiscard]] ElementType type(const Document *, - ElementIdentifier) const override { + [[nodiscard]] ElementType type(const Document *) const override { return ElementType::table_column; } - [[nodiscard]] virtual TableColumnStyle style(const Document *, - ElementIdentifier) const = 0; + [[nodiscard]] virtual TableColumnStyle style(const Document *) const = 0; }; class TableRow : public virtual Element { public: - [[nodiscard]] ElementType type(const Document *, - ElementIdentifier) const override { + [[nodiscard]] ElementType type(const Document *) const override { return ElementType::table_row; } - [[nodiscard]] virtual TableRowStyle style(const Document *, - ElementIdentifier) const = 0; + [[nodiscard]] virtual TableRowStyle style(const Document *) const = 0; }; class TableCell : public virtual Element { public: - [[nodiscard]] ElementType type(const Document *, - ElementIdentifier) const override { + [[nodiscard]] ElementType type(const Document *) const override { return ElementType::table_cell; } - [[nodiscard]] virtual bool covered(const Document *, - ElementIdentifier) const = 0; - [[nodiscard]] virtual TableDimensions span(const Document *, - ElementIdentifier) const = 0; - [[nodiscard]] virtual ValueType value_type(const Document *, - ElementIdentifier) const = 0; + [[nodiscard]] virtual bool covered(const Document *) const = 0; + [[nodiscard]] virtual TableDimensions span(const Document *) const = 0; + [[nodiscard]] virtual ValueType value_type(const Document *) const = 0; - [[nodiscard]] virtual TableCellStyle style(const Document *, - ElementIdentifier) const = 0; + [[nodiscard]] virtual TableCellStyle style(const Document *) const = 0; }; class Frame : public virtual Element { public: - [[nodiscard]] ElementType type(const Document *, - ElementIdentifier) const override { + [[nodiscard]] ElementType type(const Document *) const override { return ElementType::frame; } - [[nodiscard]] virtual AnchorType anchor_type(const Document *, - ElementIdentifier) const = 0; + [[nodiscard]] virtual AnchorType anchor_type(const Document *) const = 0; [[nodiscard]] virtual std::optional - x(const Document *, ElementIdentifier) const = 0; + x(const Document *) const = 0; [[nodiscard]] virtual std::optional - y(const Document *, ElementIdentifier) const = 0; + y(const Document *) const = 0; [[nodiscard]] virtual std::optional - width(const Document *, ElementIdentifier) const = 0; + width(const Document *) const = 0; [[nodiscard]] virtual std::optional - height(const Document *, ElementIdentifier) const = 0; + height(const Document *) const = 0; [[nodiscard]] virtual std::optional - z_index(const Document *, ElementIdentifier) const = 0; + z_index(const Document *) const = 0; - [[nodiscard]] virtual GraphicStyle style(const Document *, - ElementIdentifier) const = 0; + [[nodiscard]] virtual GraphicStyle style(const Document *) const = 0; }; class Rect : public virtual Element { public: - [[nodiscard]] ElementType type(const Document *, - ElementIdentifier) const override { + [[nodiscard]] ElementType type(const Document *) const override { return ElementType::rect; } - [[nodiscard]] virtual std::string x(const Document *, - ElementIdentifier) const = 0; - [[nodiscard]] virtual std::string y(const Document *, - ElementIdentifier) const = 0; - [[nodiscard]] virtual std::string width(const Document *, - ElementIdentifier) const = 0; - [[nodiscard]] virtual std::string height(const Document *, - ElementIdentifier) const = 0; - - [[nodiscard]] virtual GraphicStyle style(const Document *, - ElementIdentifier) const = 0; + [[nodiscard]] virtual std::string x(const Document *) const = 0; + [[nodiscard]] virtual std::string y(const Document *) const = 0; + [[nodiscard]] virtual std::string width(const Document *) const = 0; + [[nodiscard]] virtual std::string height(const Document *) const = 0; + + [[nodiscard]] virtual GraphicStyle style(const Document *) const = 0; }; class Line : public virtual Element { public: - [[nodiscard]] ElementType type(const Document *, - ElementIdentifier) const override { + [[nodiscard]] ElementType type(const Document *) const override { return ElementType::line; } - [[nodiscard]] virtual std::string x1(const Document *, - ElementIdentifier) const = 0; - [[nodiscard]] virtual std::string y1(const Document *, - ElementIdentifier) const = 0; - [[nodiscard]] virtual std::string x2(const Document *, - ElementIdentifier) const = 0; - [[nodiscard]] virtual std::string y2(const Document *, - ElementIdentifier) const = 0; - - [[nodiscard]] virtual GraphicStyle style(const Document *, - ElementIdentifier) const = 0; + [[nodiscard]] virtual std::string x1(const Document *) const = 0; + [[nodiscard]] virtual std::string y1(const Document *) const = 0; + [[nodiscard]] virtual std::string x2(const Document *) const = 0; + [[nodiscard]] virtual std::string y2(const Document *) const = 0; + + [[nodiscard]] virtual GraphicStyle style(const Document *) const = 0; }; class Circle : public virtual Element { public: - [[nodiscard]] ElementType type(const Document *, - ElementIdentifier) const override { + [[nodiscard]] ElementType type(const Document *) const override { return ElementType::circle; } - [[nodiscard]] virtual std::string x(const Document *, - ElementIdentifier) const = 0; - [[nodiscard]] virtual std::string y(const Document *, - ElementIdentifier) const = 0; - [[nodiscard]] virtual std::string width(const Document *, - ElementIdentifier) const = 0; - [[nodiscard]] virtual std::string height(const Document *, - ElementIdentifier) const = 0; - - [[nodiscard]] virtual GraphicStyle style(const Document *, - ElementIdentifier) const = 0; + [[nodiscard]] virtual std::string x(const Document *) const = 0; + [[nodiscard]] virtual std::string y(const Document *) const = 0; + [[nodiscard]] virtual std::string width(const Document *) const = 0; + [[nodiscard]] virtual std::string height(const Document *) const = 0; + + [[nodiscard]] virtual GraphicStyle style(const Document *) const = 0; }; class CustomShape : public virtual Element { public: - [[nodiscard]] ElementType type(const Document *, - ElementIdentifier) const override { + [[nodiscard]] ElementType type(const Document *) const override { return ElementType::custom_shape; } [[nodiscard]] virtual std::optional - x(const Document *, ElementIdentifier) const = 0; + x(const Document *) const = 0; [[nodiscard]] virtual std::optional - y(const Document *, ElementIdentifier) const = 0; - [[nodiscard]] virtual std::string width(const Document *, - ElementIdentifier) const = 0; - [[nodiscard]] virtual std::string height(const Document *, - ElementIdentifier) const = 0; - - [[nodiscard]] virtual GraphicStyle style(const Document *, - ElementIdentifier) const = 0; + y(const Document *) const = 0; + [[nodiscard]] virtual std::string width(const Document *) const = 0; + [[nodiscard]] virtual std::string height(const Document *) const = 0; + + [[nodiscard]] virtual GraphicStyle style(const Document *) const = 0; }; class Image : public virtual Element { public: - [[nodiscard]] ElementType type(const Document *, - ElementIdentifier) const override { + [[nodiscard]] ElementType type(const Document *) const override { return ElementType::image; } - [[nodiscard]] virtual bool internal(const Document *, - ElementIdentifier) const = 0; + [[nodiscard]] virtual bool internal(const Document *) const = 0; [[nodiscard]] virtual std::optional - file(const Document *, ElementIdentifier) const = 0; - [[nodiscard]] virtual std::string href(const Document *, - ElementIdentifier) const = 0; + file(const Document *) const = 0; + [[nodiscard]] virtual std::string href(const Document *) const = 0; }; class SheetColumn : public virtual Element { public: - [[nodiscard]] ElementType type(const Document *, - ElementIdentifier) const override { + [[nodiscard]] ElementType type(const Document *) const override { return ElementType::table_column; } [[nodiscard]] virtual TableColumnStyle style(const Document *, - ColumnIndex) const = 0; + std::uint32_t column) const = 0; }; class SheetRow : public virtual Element { public: - [[nodiscard]] ElementType type(const Document *, - ElementIdentifier) const override { + [[nodiscard]] ElementType type(const Document *) const override { return ElementType::table_row; } - [[nodiscard]] virtual TableRowStyle style(const Document *, - RowIndex) const = 0; + [[nodiscard]] virtual TableRowStyle style(const Document *) const = 0; }; class SheetCell : public virtual Element { public: - [[nodiscard]] ElementType type(const Document *, - ElementIdentifier) const override { + [[nodiscard]] ElementType type(const Document *) const override { return ElementType::table_cell; } - [[nodiscard]] virtual bool covered(const Document *, ColumnIndex, - RowIndex) const = 0; - [[nodiscard]] virtual TableDimensions span(const Document *, ColumnIndex, - RowIndex) const = 0; - [[nodiscard]] virtual ValueType value_type(const Document *, ColumnIndex, - RowIndex) const = 0; + [[nodiscard]] virtual bool covered(const Document *, std::uint32_t column, + std::uint32_t row) const = 0; + [[nodiscard]] virtual TableDimensions + span(const Document *, std::uint32_t column, std::uint32_t row) const = 0; + [[nodiscard]] virtual ValueType value_type(const Document *, + std::uint32_t column, + std::uint32_t row) const = 0; - [[nodiscard]] virtual TableCellStyle style(const Document *, ColumnIndex, - RowIndex) const = 0; + [[nodiscard]] virtual TableCellStyle + style(const Document *, std::uint32_t column, std::uint32_t row) const = 0; }; } // namespace odr::internal::abstract diff --git a/src/odr/internal/common/document_element.cpp b/src/odr/internal/common/document_element.cpp index 8a0a7fa8..2a516d67 100644 --- a/src/odr/internal/common/document_element.cpp +++ b/src/odr/internal/common/document_element.cpp @@ -1,34 +1,28 @@ #include -#include namespace odr::internal::common { -std::pair -Element::parent(const abstract::Document *, ElementIdentifier) const { - return {m_parent, 0}; // TODO +abstract::Element *Element::parent(const abstract::Document *) const { + return m_parent; } -std::pair -Element::first_child(const abstract::Document *, ElementIdentifier) const { - return {m_first_child, 0}; // TODO +abstract::Element *Element::first_child(const abstract::Document *) const { + return m_first_child; } -std::pair -Element::last_child(const abstract::Document *, ElementIdentifier) const { - return {m_last_child, 0}; // TODO +abstract::Element *Element::last_child(const abstract::Document *) const { + return m_last_child; } -std::pair -Element::previous_sibling(const abstract::Document *, ElementIdentifier) const { - return {m_previous_sibling, 0}; // TODO +abstract::Element *Element::previous_sibling(const abstract::Document *) const { + return m_previous_sibling; } -std::pair -Element::next_sibling(const abstract::Document *, ElementIdentifier) const { - return {m_next_sibling, 0}; +abstract::Element *Element::next_sibling(const abstract::Document *) const { + return m_next_sibling; } -void Element::init_append_child(Element *element) { +void Element::append_child_(Element *element) { element->m_previous_sibling = m_last_child; element->m_parent = this; if (m_last_child == nullptr) { @@ -39,27 +33,15 @@ void Element::init_append_child(Element *element) { m_last_child = element; } -std::pair -Table::first_child(const abstract::Document *, ElementIdentifier) const { - return {}; +abstract::Element *Table::first_column(const abstract::Document *) const { + return m_first_column; } -std::pair -Table::last_child(const abstract::Document *, ElementIdentifier) const { - return {}; +abstract::Element *Table::first_row(const abstract::Document *) const { + return m_first_child; } -std::pair -Table::first_column(const abstract::Document *, ElementIdentifier) const { - return {m_first_column, 0}; // TODO -} - -std::pair -Table::first_row(const abstract::Document *, ElementIdentifier) const { - return {m_first_child, 0}; // TODO -} - -void Table::init_append_column(Element *element) { +void Table::append_column_(Element *element) { element->m_previous_sibling = m_last_column; element->m_parent = this; if (m_last_column == nullptr) { @@ -70,10 +52,6 @@ void Table::init_append_column(Element *element) { m_last_column = element; } -void Table::init_append_row(Element *element) { - Element::init_append_child(element); -} - -void Sheet::init_child(Element *element) { element->m_parent = this; } +void Table::append_row_(Element *element) { Element::append_child_(element); } } // namespace odr::internal::common diff --git a/src/odr/internal/common/document_element.hpp b/src/odr/internal/common/document_element.hpp index adfedc03..daac1346 100644 --- a/src/odr/internal/common/document_element.hpp +++ b/src/odr/internal/common/document_element.hpp @@ -3,6 +3,8 @@ #include +#include + #include namespace odr::internal::abstract { @@ -11,53 +13,46 @@ class Document; namespace odr::internal::common { -struct InternalElementContainer { - abstract::Element *element; - - ElementIdentifier parent; - ElementIdentifier first_child; - ElementIdentifier last_child; - ElementIdentifier previous_sibling; - ElementIdentifier next_sibling; -}; - class Element : public virtual abstract::Element { public: - [[nodiscard]] std::pair - parent(const abstract::Document *, ElementIdentifier) const override; - [[nodiscard]] std::pair - first_child(const abstract::Document *, ElementIdentifier) const override; - [[nodiscard]] std::pair - last_child(const abstract::Document *, ElementIdentifier) const override; - [[nodiscard]] std::pair - previous_sibling(const abstract::Document *, - ElementIdentifier) const override; - [[nodiscard]] std::pair - next_sibling(const abstract::Document *, ElementIdentifier) const override; - - void init_append_child(Element *element); + [[nodiscard]] abstract::Element * + parent(const abstract::Document *) const override; + [[nodiscard]] abstract::Element * + first_child(const abstract::Document *) const override; + [[nodiscard]] abstract::Element * + last_child(const abstract::Document *) const override; + [[nodiscard]] abstract::Element * + previous_sibling(const abstract::Document *) const override; + [[nodiscard]] abstract::Element * + next_sibling(const abstract::Document *) const override; + + void append_child_(Element *element); + + template + static const document_t &document_(const abstract::Document *document) { + const document_t *cast = dynamic_cast(document); + if (cast == nullptr) { + throw std::runtime_error("unknown document type"); + } + return *cast; + } Element *m_parent{}; Element *m_first_child{}; Element *m_last_child{}; - Element *m_next_sibling{}; Element *m_previous_sibling{}; + Element *m_next_sibling{}; }; class Table : public virtual Element, public abstract::Table { public: - [[nodiscard]] std::pair - first_child(const abstract::Document *, ElementIdentifier) const final; - [[nodiscard]] std::pair - last_child(const abstract::Document *, ElementIdentifier) const final; - - std::pair - first_column(const abstract::Document *, ElementIdentifier) const final; - std::pair - first_row(const abstract::Document *, ElementIdentifier) const final; + [[nodiscard]] abstract::Element * + first_column(const abstract::Document *) const final; + [[nodiscard]] abstract::Element * + first_row(const abstract::Document *) const final; - void init_append_column(Element *element); - void init_append_row(Element *element); + void append_column_(Element *element); + void append_row_(Element *element); Element *m_first_column{}; Element *m_last_column{}; @@ -65,7 +60,6 @@ class Table : public virtual Element, public abstract::Table { class Sheet : public virtual Element, public abstract::Sheet { public: - void init_child(Element *element); }; } // namespace odr::internal::common diff --git a/src/odr/internal/odf/odf_document.cpp b/src/odr/internal/odf/odf_document.cpp index f8573d4b..41980052 100644 --- a/src/odr/internal/odf/odf_document.cpp +++ b/src/odr/internal/odf/odf_document.cpp @@ -106,9 +106,6 @@ std::shared_ptr Document::files() const noexcept { return m_filesystem; } -std::pair -Document::root_element() const { - return {m_root_element, 0}; // TODO -} +abstract::Element *Document::root_element() const { return m_root_element; } } // namespace odr::internal::odf diff --git a/src/odr/internal/odf/odf_document.hpp b/src/odr/internal/odf/odf_document.hpp index 5a48896c..73976b84 100644 --- a/src/odr/internal/odf/odf_document.hpp +++ b/src/odr/internal/odf/odf_document.hpp @@ -36,8 +36,7 @@ class Document : public abstract::Document { [[nodiscard]] std::shared_ptr files() const noexcept final; - [[nodiscard]] std::pair - root_element() const final; + [[nodiscard]] abstract::Element *root_element() const final; protected: FileType m_file_type; diff --git a/src/odr/internal/odf/odf_element.cpp b/src/odr/internal/odf/odf_element.cpp index 50e48aa9..6463c4e5 100644 --- a/src/odr/internal/odf/odf_element.cpp +++ b/src/odr/internal/odf/odf_element.cpp @@ -48,10 +48,12 @@ Element::partial_style(const abstract::Document *document) const { common::ResolvedStyle Element::intermediate_style(const abstract::Document *document) const { - if (m_parent == nullptr) { + abstract::Element *parent = this->parent(document); + if (parent == nullptr) { return partial_style(document); } - auto base = dynamic_cast(m_parent)->intermediate_style(document); + common::ResolvedStyle base = + dynamic_cast(parent)->intermediate_style(document); base.override(partial_style(document)); return base; } @@ -70,31 +72,28 @@ const StyleRegistry *Element::style_(const abstract::Document *document) { Root::Root(pugi::xml_node node) : Element(node) {} -ElementType Root::type(const abstract::Document *, ElementIdentifier) const { +ElementType Root::type(const abstract::Document *) const { return ElementType::root; } TextRoot::TextRoot(pugi::xml_node node) : Root(node) {} -ElementType TextRoot::type(const abstract::Document *, - ElementIdentifier) const { +ElementType TextRoot::type(const abstract::Document *) const { return ElementType::root; } -PageLayout TextRoot::page_layout(const abstract::Document *document, - ElementIdentifier elementId) const { - if (auto master_page = dynamic_cast( - this->first_master_page(document, elementId).first)) { - return master_page->page_layout(document, elementId); +PageLayout TextRoot::page_layout(const abstract::Document *document) const { + if (auto master_page = + dynamic_cast(this->first_master_page(document))) { + return master_page->page_layout(document); } return {}; } -std::pair -TextRoot::first_master_page(const abstract::Document *document, - ElementIdentifier) const { +abstract::Element * +TextRoot::first_master_page(const abstract::Document *document) const { if (auto first_master_page = style_(document)->first_master_page()) { - return {first_master_page, 0}; // TODO + return first_master_page; } return {}; } @@ -105,8 +104,7 @@ DrawingRoot::DrawingRoot(pugi::xml_node node) : Root(node) {} MasterPage::MasterPage(pugi::xml_node node) : Element(node) {} -PageLayout MasterPage::page_layout(const abstract::Document *document, - ElementIdentifier) const { +PageLayout MasterPage::page_layout(const abstract::Document *document) const { if (auto attribute = m_node.attribute("style:page-layout-name")) { return style_(document)->page_layout(attribute.value()); } @@ -115,76 +113,66 @@ PageLayout MasterPage::page_layout(const abstract::Document *document, Slide::Slide(pugi::xml_node node) : Element(node) {} -PageLayout Slide::page_layout(const abstract::Document *document, - ElementIdentifier elementId) const { - if (auto master_page = dynamic_cast( - this->master_page(document, elementId).first)) { - return master_page->page_layout(document, elementId); +PageLayout Slide::page_layout(const abstract::Document *document) const { + if (auto master_page = + dynamic_cast(this->master_page(document))) { + return master_page->page_layout(document); } return {}; } -std::pair -Slide::master_page(const abstract::Document *document, - ElementIdentifier) const { +abstract::Element * +Slide::master_page(const abstract::Document *document) const { if (auto master_page_name_attr = m_node.attribute("draw:master-page-name")) { - return {style_(document)->master_page(master_page_name_attr.value()), - 0}; // TODO + return style_(document)->master_page(master_page_name_attr.value()); } return {}; } -std::string Slide::name(const abstract::Document *, ElementIdentifier) const { +std::string Slide::name(const abstract::Document *) const { return m_node.attribute("draw:name").value(); } Page::Page(pugi::xml_node node) : Element(node) {} -PageLayout Page::page_layout(const abstract::Document *document, - ElementIdentifier elementId) const { - if (auto master_page = dynamic_cast( - this->master_page(document, elementId).first)) { - return master_page->page_layout(document, elementId); +PageLayout Page::page_layout(const abstract::Document *document) const { + if (auto master_page = + dynamic_cast(this->master_page(document))) { + return master_page->page_layout(document); } return {}; } -std::pair -Page::master_page(const abstract::Document *document, ElementIdentifier) const { +abstract::Element *Page::master_page(const abstract::Document *document) const { if (auto master_page_name_attr = m_node.attribute("draw:master-page-name")) { - return {style_(document)->master_page(master_page_name_attr.value()), - 0}; // TODO + return style_(document)->master_page(master_page_name_attr.value()); } return {}; } -std::string Page::name(const abstract::Document *, ElementIdentifier) const { +std::string Page::name(const abstract::Document *) const { return m_node.attribute("draw:name").value(); } LineBreak::LineBreak(pugi::xml_node node) : Element(node) {} -TextStyle LineBreak::style(const abstract::Document *document, - ElementIdentifier) const { +TextStyle LineBreak::style(const abstract::Document *document) const { return intermediate_style(document).text_style; } Paragraph::Paragraph(pugi::xml_node node) : Element(node) {} -ParagraphStyle Paragraph::style(const abstract::Document *document, - ElementIdentifier) const { +ParagraphStyle Paragraph::style(const abstract::Document *document) const { return intermediate_style(document).paragraph_style; } -TextStyle Paragraph::text_style(const abstract::Document *document, - ElementIdentifier) const { +TextStyle Paragraph::text_style(const abstract::Document *document) const { return intermediate_style(document).text_style; } Span::Span(pugi::xml_node node) : Element(node) {} -TextStyle Span::style(const abstract::Document *document, - ElementIdentifier) const { +TextStyle Span::style(const abstract::Document *document) const { return intermediate_style(document).text_style; } @@ -214,7 +202,7 @@ Text::Text(pugi::xml_node first, pugi::xml_node last) } } -std::string Text::content(const abstract::Document *, ElementIdentifier) const { +std::string Text::content(const abstract::Document *) const { std::string result; for (auto node = m_node; node != m_last.next_sibling(); node = node.next_sibling()) { @@ -223,8 +211,7 @@ std::string Text::content(const abstract::Document *, ElementIdentifier) const { return result; } -void Text::set_content(const abstract::Document *, ElementIdentifier, - const std::string &text) { +void Text::set_content(const abstract::Document *, const std::string &text) { auto parent = m_node.parent(); auto old_start = m_node; @@ -252,40 +239,35 @@ void Text::set_content(const abstract::Document *, ElementIdentifier, // TODO set first and last } -TextStyle Text::style(const abstract::Document *document, - ElementIdentifier) const { +TextStyle Text::style(const abstract::Document *document) const { return intermediate_style(document).text_style; } Link::Link(pugi::xml_node node) : Element(node) {} -std::string Link::href(const abstract::Document *, ElementIdentifier) const { +std::string Link::href(const abstract::Document *) const { return m_node.attribute("xlink:href").value(); } Bookmark::Bookmark(pugi::xml_node node) : Element(node) {} -std::string Bookmark::name(const abstract::Document *, - ElementIdentifier) const { +std::string Bookmark::name(const abstract::Document *) const { return m_node.attribute("text:name").value(); } ListItem::ListItem(pugi::xml_node node) : Element(node) {} -TextStyle ListItem::style(const abstract::Document *document, - ElementIdentifier) const { +TextStyle ListItem::style(const abstract::Document *document) const { return intermediate_style(document).text_style; } Table::Table(pugi::xml_node node) : Element(node) {} -TableStyle Table::style(const abstract::Document *document, - ElementIdentifier) const { +TableStyle Table::style(const abstract::Document *document) const { return partial_style(document).table_style; } -TableDimensions Table::dimensions(const abstract::Document *, - ElementIdentifier) const { +TableDimensions Table::dimensions(const abstract::Document *) const { TableDimensions result; common::TableCursor cursor; @@ -311,32 +293,28 @@ TableDimensions Table::dimensions(const abstract::Document *, TableColumn::TableColumn(pugi::xml_node node) : Element(node) {} -TableColumnStyle TableColumn::style(const abstract::Document *document, - ElementIdentifier) const { +TableColumnStyle TableColumn::style(const abstract::Document *document) const { return partial_style(document).table_column_style; } TableRow::TableRow(pugi::xml_node node) : Element(node) {} -TableRowStyle TableRow::style(const abstract::Document *document, - ElementIdentifier) const { +TableRowStyle TableRow::style(const abstract::Document *document) const { return partial_style(document).table_row_style; } TableCell::TableCell(pugi::xml_node node) : Element(node) {} -bool TableCell::covered(const abstract::Document *, ElementIdentifier) const { +bool TableCell::covered(const abstract::Document *) const { return std::strcmp(m_node.name(), "table:covered-table-cell") == 0; } -TableDimensions TableCell::span(const abstract::Document *, - ElementIdentifier) const { +TableDimensions TableCell::span(const abstract::Document *) const { return {m_node.attribute("table:number-rows-spanned").as_uint(1), m_node.attribute("table:number-columns-spanned").as_uint(1)}; } -ValueType TableCell::value_type(const abstract::Document *, - ElementIdentifier) const { +ValueType TableCell::value_type(const abstract::Document *) const { auto value_type = m_node.attribute("office:value-type").value(); if (std::strcmp("float", value_type) == 0) { return ValueType::float_number; @@ -344,15 +322,13 @@ ValueType TableCell::value_type(const abstract::Document *, return ValueType::string; } -TableCellStyle TableCell::style(const abstract::Document *document, - ElementIdentifier) const { +TableCellStyle TableCell::style(const abstract::Document *document) const { return partial_style(document).table_cell_style; } Frame::Frame(pugi::xml_node node) : Element(node) {} -AnchorType Frame::anchor_type(const abstract::Document *, - ElementIdentifier) const { +AnchorType Frame::anchor_type(const abstract::Document *) const { auto anchor_type = m_node.attribute("text:anchor-type").value(); if (std::strcmp("as-char", anchor_type) == 0) { return AnchorType::as_char; @@ -369,173 +345,156 @@ AnchorType Frame::anchor_type(const abstract::Document *, return AnchorType::at_page; } -std::optional Frame::x(const abstract::Document *, - ElementIdentifier) const { +std::optional Frame::x(const abstract::Document *) const { if (auto attribute = m_node.attribute("svg:x")) { return attribute.value(); } return {}; } -std::optional Frame::y(const abstract::Document *, - ElementIdentifier) const { +std::optional Frame::y(const abstract::Document *) const { if (auto attribute = m_node.attribute("svg:y")) { return attribute.value(); } return {}; } -std::optional Frame::width(const abstract::Document *, - ElementIdentifier) const { +std::optional Frame::width(const abstract::Document *) const { if (auto attribute = m_node.attribute("svg:width")) { return attribute.value(); } return {}; } -std::optional Frame::height(const abstract::Document *, - ElementIdentifier) const { +std::optional Frame::height(const abstract::Document *) const { if (auto attribute = m_node.attribute("svg:height")) { return attribute.value(); } return {}; } -std::optional Frame::z_index(const abstract::Document *, - ElementIdentifier) const { +std::optional Frame::z_index(const abstract::Document *) const { if (auto attribute = m_node.attribute("draw:z-index")) { return attribute.value(); } return {}; } -GraphicStyle Frame::style(const abstract::Document *document, - ElementIdentifier) const { +GraphicStyle Frame::style(const abstract::Document *document) const { return intermediate_style(document).graphic_style; } Rect::Rect(pugi::xml_node node) : Element(node) {} -std::string Rect::x(const abstract::Document *, ElementIdentifier) const { +std::string Rect::x(const abstract::Document *) const { return m_node.attribute("svg:x").value(); } -std::string Rect::y(const abstract::Document *, ElementIdentifier) const { +std::string Rect::y(const abstract::Document *) const { return m_node.attribute("svg:y").value(); } -std::string Rect::width(const abstract::Document *, ElementIdentifier) const { +std::string Rect::width(const abstract::Document *) const { return m_node.attribute("svg:width").value(); } -std::string Rect::height(const abstract::Document *, ElementIdentifier) const { +std::string Rect::height(const abstract::Document *) const { return m_node.attribute("svg:height").value(); } -GraphicStyle Rect::style(const abstract::Document *document, - ElementIdentifier) const { +GraphicStyle Rect::style(const abstract::Document *document) const { return intermediate_style(document).graphic_style; } Line::Line(pugi::xml_node node) : Element(node) {} -std::string Line::x1(const abstract::Document *, ElementIdentifier) const { +std::string Line::x1(const abstract::Document *) const { return m_node.attribute("svg:x1").value(); } -std::string Line::y1(const abstract::Document *, ElementIdentifier) const { +std::string Line::y1(const abstract::Document *) const { return m_node.attribute("svg:y1").value(); } -std::string Line::x2(const abstract::Document *, ElementIdentifier) const { +std::string Line::x2(const abstract::Document *) const { return m_node.attribute("svg:x2").value(); } -std::string Line::y2(const abstract::Document *, ElementIdentifier) const { +std::string Line::y2(const abstract::Document *) const { return m_node.attribute("svg:y2").value(); } -GraphicStyle Line::style(const abstract::Document *document, - ElementIdentifier) const { +GraphicStyle Line::style(const abstract::Document *document) const { return intermediate_style(document).graphic_style; } Circle::Circle(pugi::xml_node node) : Element(node) {} -std::string Circle::x(const abstract::Document *, ElementIdentifier) const { +std::string Circle::x(const abstract::Document *) const { return m_node.attribute("svg:x").value(); } -std::string Circle::y(const abstract::Document *, ElementIdentifier) const { +std::string Circle::y(const abstract::Document *) const { return m_node.attribute("svg:y").value(); } -std::string Circle::width(const abstract::Document *, ElementIdentifier) const { +std::string Circle::width(const abstract::Document *) const { return m_node.attribute("svg:width").value(); } -std::string Circle::height(const abstract::Document *, - ElementIdentifier) const { +std::string Circle::height(const abstract::Document *) const { return m_node.attribute("svg:height").value(); } -GraphicStyle Circle::style(const abstract::Document *document, - ElementIdentifier) const { +GraphicStyle Circle::style(const abstract::Document *document) const { return intermediate_style(document).graphic_style; } CustomShape::CustomShape(pugi::xml_node node) : Element(node) {} -std::optional CustomShape::x(const abstract::Document *, - ElementIdentifier) const { +std::optional CustomShape::x(const abstract::Document *) const { return m_node.attribute("svg:x").value(); } -std::optional CustomShape::y(const abstract::Document *, - ElementIdentifier) const { +std::optional CustomShape::y(const abstract::Document *) const { return m_node.attribute("svg:y").value(); } -std::string CustomShape::width(const abstract::Document *, - ElementIdentifier) const { +std::string CustomShape::width(const abstract::Document *) const { return m_node.attribute("svg:width").value(); } -std::string CustomShape::height(const abstract::Document *, - ElementIdentifier) const { +std::string CustomShape::height(const abstract::Document *) const { return m_node.attribute("svg:height").value(); } -GraphicStyle CustomShape::style(const abstract::Document *document, - ElementIdentifier) const { +GraphicStyle CustomShape::style(const abstract::Document *document) const { return intermediate_style(document).graphic_style; } Image::Image(pugi::xml_node node) : Element(node) {} -bool Image::internal(const abstract::Document *document, - ElementIdentifier elementId) const { +bool Image::internal(const abstract::Document *document) const { auto doc = document_(document); if (!doc || !doc->files()) { return false; } try { - return doc->files()->is_file(href(document, elementId)); + return doc->files()->is_file(href(document)); } catch (...) { } return false; } -std::optional Image::file(const abstract::Document *document, - ElementIdentifier elementId) const { +std::optional Image::file(const abstract::Document *document) const { auto doc = document_(document); - if (!doc || !internal(document, elementId)) { + if (!doc || !internal(document)) { return {}; } - return File(doc->files()->open(href(document, elementId))); + return File(doc->files()->open(href(document))); } -std::string Image::href(const abstract::Document *, ElementIdentifier) const { +std::string Image::href(const abstract::Document *) const { return m_node.attribute("xlink:href").value(); } diff --git a/src/odr/internal/odf/odf_element.hpp b/src/odr/internal/odf/odf_element.hpp index 79fcbb42..0fb0f732 100644 --- a/src/odr/internal/odf/odf_element.hpp +++ b/src/odr/internal/odf/odf_element.hpp @@ -36,8 +36,7 @@ template class DefaultElement : public Element { public: explicit DefaultElement(pugi::xml_node node) : Element(node) {} - [[nodiscard]] ElementType type(const abstract::Document *, - ElementIdentifier) const final { + [[nodiscard]] ElementType type(const abstract::Document *) const final { return element_type; } }; @@ -46,22 +45,19 @@ class Root : public Element { public: explicit Root(pugi::xml_node); - [[nodiscard]] ElementType type(const abstract::Document *, - ElementIdentifier) const override; + [[nodiscard]] ElementType type(const abstract::Document *) const override; }; class TextRoot final : public Root, public abstract::TextRoot { public: explicit TextRoot(pugi::xml_node); - [[nodiscard]] ElementType type(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] ElementType type(const abstract::Document *) const final; - [[nodiscard]] PageLayout page_layout(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] PageLayout page_layout(const abstract::Document *) const final; - [[nodiscard]] std::pair - first_master_page(const abstract::Document *, ElementIdentifier) const final; + [[nodiscard]] abstract::Element * + first_master_page(const abstract::Document *) const final; }; class PresentationRoot final : public Root { @@ -78,63 +74,54 @@ class MasterPage final : public Element, public abstract::MasterPage { public: explicit MasterPage(pugi::xml_node); - [[nodiscard]] PageLayout page_layout(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] PageLayout page_layout(const abstract::Document *) const final; }; class Slide final : public Element, public abstract::Slide { public: explicit Slide(pugi::xml_node); - [[nodiscard]] PageLayout page_layout(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] PageLayout page_layout(const abstract::Document *) const final; - [[nodiscard]] std::pair - master_page(const abstract::Document *, ElementIdentifier) const final; + [[nodiscard]] abstract::Element * + master_page(const abstract::Document *) const final; - [[nodiscard]] std::string name(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] std::string name(const abstract::Document *) const final; }; class Page final : public Element, public abstract::Page { public: explicit Page(pugi::xml_node); - [[nodiscard]] PageLayout page_layout(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] PageLayout page_layout(const abstract::Document *) const final; - [[nodiscard]] std::pair - master_page(const abstract::Document *, ElementIdentifier) const final; + [[nodiscard]] abstract::Element * + master_page(const abstract::Document *) const final; - [[nodiscard]] std::string name(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] std::string name(const abstract::Document *) const final; }; class LineBreak final : public Element, public abstract::LineBreak { public: explicit LineBreak(pugi::xml_node); - [[nodiscard]] TextStyle style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] TextStyle style(const abstract::Document *) const final; }; class Paragraph final : public Element, public abstract::Paragraph { public: explicit Paragraph(pugi::xml_node); - [[nodiscard]] ParagraphStyle style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] ParagraphStyle style(const abstract::Document *) const final; - [[nodiscard]] TextStyle text_style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] TextStyle text_style(const abstract::Document *) const final; }; class Span final : public Element, public abstract::Span { public: explicit Span(pugi::xml_node); - [[nodiscard]] TextStyle style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] TextStyle style(const abstract::Document *) const final; }; class Text final : public Element, public abstract::Text { @@ -144,14 +131,11 @@ class Text final : public Element, public abstract::Text { explicit Text(pugi::xml_node); Text(pugi::xml_node first, pugi::xml_node last); - [[nodiscard]] std::string content(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] std::string content(const abstract::Document *) const final; - void set_content(const abstract::Document *, ElementIdentifier, - const std::string &text) final; + void set_content(const abstract::Document *, const std::string &text) final; - [[nodiscard]] TextStyle style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] TextStyle style(const abstract::Document *) const final; private: pugi::xml_node m_last; @@ -161,173 +145,141 @@ class Link final : public Element, public abstract::Link { public: explicit Link(pugi::xml_node); - [[nodiscard]] std::string href(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] std::string href(const abstract::Document *) const final; }; class Bookmark final : public Element, public abstract::Bookmark { public: explicit Bookmark(pugi::xml_node); - [[nodiscard]] std::string name(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] std::string name(const abstract::Document *) const final; }; class ListItem final : public Element, public abstract::ListItem { public: explicit ListItem(pugi::xml_node); - [[nodiscard]] TextStyle style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] TextStyle style(const abstract::Document *) const final; }; class Table : public Element, public common::Table { public: explicit Table(pugi::xml_node); - [[nodiscard]] TableStyle style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] TableStyle style(const abstract::Document *) const final; - [[nodiscard]] TableDimensions dimensions(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] TableDimensions + dimensions(const abstract::Document *) const final; }; class TableColumn final : public Element, public abstract::TableColumn { public: explicit TableColumn(pugi::xml_node); - [[nodiscard]] TableColumnStyle style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] TableColumnStyle style(const abstract::Document *) const final; }; class TableRow final : public Element, public abstract::TableRow { public: explicit TableRow(pugi::xml_node); - [[nodiscard]] TableRowStyle style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] TableRowStyle style(const abstract::Document *) const final; }; class TableCell final : public Element, public abstract::TableCell { public: explicit TableCell(pugi::xml_node); - [[nodiscard]] bool covered(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] bool covered(const abstract::Document *) const final; - [[nodiscard]] TableDimensions span(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] TableDimensions span(const abstract::Document *) const final; - [[nodiscard]] ValueType value_type(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] ValueType value_type(const abstract::Document *) const final; - [[nodiscard]] TableCellStyle style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] TableCellStyle style(const abstract::Document *) const final; }; class Frame final : public Element, public abstract::Frame { public: explicit Frame(pugi::xml_node); - [[nodiscard]] AnchorType anchor_type(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] AnchorType anchor_type(const abstract::Document *) const final; - [[nodiscard]] std::optional x(const abstract::Document *, - ElementIdentifier) const final; - [[nodiscard]] std::optional y(const abstract::Document *, - ElementIdentifier) const final; - [[nodiscard]] std::optional width(const abstract::Document *, - ElementIdentifier) const final; [[nodiscard]] std::optional - height(const abstract::Document *, ElementIdentifier) const final; + x(const abstract::Document *) const final; + [[nodiscard]] std::optional + y(const abstract::Document *) const final; + [[nodiscard]] std::optional + width(const abstract::Document *) const final; + [[nodiscard]] std::optional + height(const abstract::Document *) const final; [[nodiscard]] std::optional - z_index(const abstract::Document *, ElementIdentifier) const final; + z_index(const abstract::Document *) const final; - [[nodiscard]] GraphicStyle style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] GraphicStyle style(const abstract::Document *) const final; }; class Rect final : public Element, public abstract::Rect { public: explicit Rect(pugi::xml_node); - [[nodiscard]] std::string x(const abstract::Document *, - ElementIdentifier) const final; - [[nodiscard]] std::string y(const abstract::Document *, - ElementIdentifier) const final; - [[nodiscard]] std::string width(const abstract::Document *, - ElementIdentifier) const final; - [[nodiscard]] std::string height(const abstract::Document *, - ElementIdentifier) const final; - - [[nodiscard]] GraphicStyle style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] std::string x(const abstract::Document *) const final; + [[nodiscard]] std::string y(const abstract::Document *) const final; + [[nodiscard]] std::string width(const abstract::Document *) const final; + [[nodiscard]] std::string height(const abstract::Document *) const final; + + [[nodiscard]] GraphicStyle style(const abstract::Document *) const final; }; class Line final : public Element, public abstract::Line { public: explicit Line(pugi::xml_node); - [[nodiscard]] std::string x1(const abstract::Document *, - ElementIdentifier) const final; - [[nodiscard]] std::string y1(const abstract::Document *, - ElementIdentifier) const final; - [[nodiscard]] std::string x2(const abstract::Document *, - ElementIdentifier) const final; - [[nodiscard]] std::string y2(const abstract::Document *, - ElementIdentifier) const final; - - [[nodiscard]] GraphicStyle style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] std::string x1(const abstract::Document *) const final; + [[nodiscard]] std::string y1(const abstract::Document *) const final; + [[nodiscard]] std::string x2(const abstract::Document *) const final; + [[nodiscard]] std::string y2(const abstract::Document *) const final; + + [[nodiscard]] GraphicStyle style(const abstract::Document *) const final; }; class Circle final : public Element, public abstract::Circle { public: explicit Circle(pugi::xml_node); - [[nodiscard]] std::string x(const abstract::Document *, - ElementIdentifier) const final; - [[nodiscard]] std::string y(const abstract::Document *, - ElementIdentifier) const final; - [[nodiscard]] std::string width(const abstract::Document *, - ElementIdentifier) const final; - [[nodiscard]] std::string height(const abstract::Document *, - ElementIdentifier) const final; - - [[nodiscard]] GraphicStyle style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] std::string x(const abstract::Document *) const final; + [[nodiscard]] std::string y(const abstract::Document *) const final; + [[nodiscard]] std::string width(const abstract::Document *) const final; + [[nodiscard]] std::string height(const abstract::Document *) const final; + + [[nodiscard]] GraphicStyle style(const abstract::Document *) const final; }; class CustomShape final : public Element, public abstract::CustomShape { public: explicit CustomShape(pugi::xml_node); - [[nodiscard]] std::optional x(const abstract::Document *, - ElementIdentifier) const final; - [[nodiscard]] std::optional y(const abstract::Document *, - ElementIdentifier) const final; - [[nodiscard]] std::string width(const abstract::Document *, - ElementIdentifier) const final; - [[nodiscard]] std::string height(const abstract::Document *, - ElementIdentifier) const final; - - [[nodiscard]] GraphicStyle style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] std::optional + x(const abstract::Document *) const final; + [[nodiscard]] std::optional + y(const abstract::Document *) const final; + [[nodiscard]] std::string width(const abstract::Document *) const final; + [[nodiscard]] std::string height(const abstract::Document *) const final; + + [[nodiscard]] GraphicStyle style(const abstract::Document *) const final; }; class Image final : public Element, public abstract::Image { public: explicit Image(pugi::xml_node); - [[nodiscard]] bool internal(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] bool internal(const abstract::Document *) const final; - [[nodiscard]] std::optional file(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] std::optional + file(const abstract::Document *) const final; - [[nodiscard]] std::string href(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] std::string href(const abstract::Document *) const final; }; } // namespace odr::internal::odf diff --git a/src/odr/internal/odf/odf_parser.cpp b/src/odr/internal/odf/odf_parser.cpp index 9d76914c..b1ced48c 100644 --- a/src/odr/internal/odf/odf_parser.cpp +++ b/src/odr/internal/odf/odf_parser.cpp @@ -56,7 +56,7 @@ void odf::parse_element_children(Element *element, pugi::xml_node node, if (child == nullptr) { child_node = child_node.next_sibling(); } else { - element->init_append_child(child); + element->append_child_(child); child_node = next_sibling; } } @@ -66,7 +66,7 @@ void odf::parse_element_children(PresentationRoot *element, pugi::xml_node node, std::vector> &store) { for (auto child_node : node.children("draw:page")) { auto [child, _] = parse_element_tree(child_node, store); - element->init_append_child(child); + element->append_child_(child); } } @@ -74,7 +74,7 @@ void odf::parse_element_children(SpreadsheetRoot *element, pugi::xml_node node, std::vector> &store) { for (auto child_node : node.children("table:table")) { auto [child, _] = parse_element_tree(child_node, store); - element->init_append_child(child); + element->append_child_(child); } } @@ -82,7 +82,7 @@ void odf::parse_element_children(DrawingRoot *element, pugi::xml_node node, std::vector> &store) { for (auto child_node : node.children("draw:page")) { auto [child, _] = parse_element_tree(child_node, store); - element->init_append_child(child); + element->append_child_(child); } } @@ -123,14 +123,14 @@ std::tuple odf::parse_element_tree( ++i) { // TODO mark as repeated auto [column, _] = parse_element_tree(column_node, store); - table->init_append_column(column); + table->append_column_(column); } } for (auto row_node : node.children("table:table-row")) { // TODO log warning if repeated auto [row, _] = parse_element_tree(row_node, store); - table->init_append_row(row); + table->append_row_(row); } return std::make_tuple(table, node.next_sibling()); @@ -151,7 +151,7 @@ odf::parse_element_tree( for (auto cell_node : node.children()) { // TODO log warning if repeated auto [cell, _] = parse_any_element_tree(cell_node, store); - table_row->init_append_child(cell); + table_row->append_child_(cell); } return std::make_tuple(table_row, node.next_sibling()); diff --git a/src/odr/internal/odf/odf_spreadsheet.cpp b/src/odr/internal/odf/odf_spreadsheet.cpp index 5141c3c2..c7c4089a 100644 --- a/src/odr/internal/odf/odf_spreadsheet.cpp +++ b/src/odr/internal/odf/odf_spreadsheet.cpp @@ -14,8 +14,8 @@ class SheetColumn final : public Element, public abstract::TableColumn { public: explicit SheetColumn(pugi::xml_node node) : Element(node) {} - [[nodiscard]] TableColumnStyle style(const abstract::Document *document, - ElementIdentifier) const final { + [[nodiscard]] TableColumnStyle + style(const abstract::Document *document) const final { return partial_style(document).table_column_style; } }; @@ -24,8 +24,8 @@ class SheetRow final : public Element, public abstract::TableRow { public: explicit SheetRow(pugi::xml_node node) : Element(node) {} - [[nodiscard]] TableRowStyle style(const abstract::Document *document, - ElementIdentifier) const final { + [[nodiscard]] TableRowStyle + style(const abstract::Document *document) const final { return partial_style(document).table_row_style; } }; @@ -34,19 +34,16 @@ class SheetCell final : public Element, public abstract::TableCell { public: explicit SheetCell(pugi::xml_node node) : Element(node) {} - [[nodiscard]] bool covered(const abstract::Document *, - ElementIdentifier) const final { + [[nodiscard]] bool covered(const abstract::Document *) const final { return std::strcmp(m_node.name(), "table:covered-table-cell") == 0; } - [[nodiscard]] TableDimensions span(const abstract::Document *, - ElementIdentifier) const final { + [[nodiscard]] TableDimensions span(const abstract::Document *) const final { return {m_node.attribute("table:number-rows-spanned").as_uint(1), m_node.attribute("table:number-columns-spanned").as_uint(1)}; } - [[nodiscard]] ValueType value_type(const abstract::Document *, - ElementIdentifier) const final { + [[nodiscard]] ValueType value_type(const abstract::Document *) const final { auto value_type = m_node.attribute("office:value-type").value(); if (std::strcmp("float", value_type) == 0) { return ValueType::float_number; @@ -54,8 +51,8 @@ class SheetCell final : public Element, public abstract::TableCell { return ValueType::string; } - [[nodiscard]] TableCellStyle style(const abstract::Document *document, - ElementIdentifier) const final { + [[nodiscard]] TableCellStyle + style(const abstract::Document *document) const final { return partial_style(document).table_cell_style; } }; @@ -66,17 +63,16 @@ SpreadsheetRoot::SpreadsheetRoot(pugi::xml_node node) : Root(node) {} Sheet::Sheet(pugi::xml_node node) : Element(node) {} -std::string Sheet::name(const abstract::Document *, ElementIdentifier) const { +std::string Sheet::name(const abstract::Document *) const { return m_node.attribute("table:name").value(); } -TableDimensions Sheet::dimensions(const abstract::Document *, - ElementIdentifier) const { +TableDimensions Sheet::dimensions(const abstract::Document *) const { return m_dimensions; } TableDimensions -Sheet::content(const abstract::Document *, ElementIdentifier, +Sheet::content(const abstract::Document *, const std::optional range) const { TableDimensions result; @@ -108,8 +104,8 @@ Sheet::content(const abstract::Document *, ElementIdentifier, return result; } -abstract::Element *Sheet::column(const abstract::Document *, ElementIdentifier, - ColumnIndex column) const { +abstract::Element *Sheet::column(const abstract::Document *, + std::uint32_t column) const { if (auto it = util::map::lookup_greater_than(m_columns, column); it != std::end(m_columns)) { return it->second; @@ -117,8 +113,8 @@ abstract::Element *Sheet::column(const abstract::Document *, ElementIdentifier, return nullptr; } -abstract::Element *Sheet::row(const abstract::Document *, ElementIdentifier, - RowIndex row) const { +abstract::Element *Sheet::row(const abstract::Document *, + std::uint32_t row) const { if (auto it = util::map::lookup_greater_than(m_rows, row); it != std::end(m_rows)) { return it->second.element; @@ -126,8 +122,8 @@ abstract::Element *Sheet::row(const abstract::Document *, ElementIdentifier, return nullptr; } -abstract::Element *Sheet::cell(const abstract::Document *, ElementIdentifier, - ColumnIndex column, RowIndex row) const { +abstract::Element *Sheet::cell(const abstract::Document *, std::uint32_t column, + std::uint32_t row) const { if (auto row_it = util::map::lookup_greater_than(m_rows, row); row_it != std::end(m_rows)) { auto &cells = row_it->second.cells; @@ -140,34 +136,27 @@ abstract::Element *Sheet::cell(const abstract::Document *, ElementIdentifier, return nullptr; } -abstract::Element *Sheet::first_shape(const abstract::Document *, - ElementIdentifier) const { +abstract::Element *Sheet::first_shape(const abstract::Document *) const { return m_first_shape; } -TableStyle Sheet::style(const abstract::Document *document, - ElementIdentifier) const { +TableStyle Sheet::style(const abstract::Document *document) const { return partial_style(document).table_style; } -void Sheet::init_column(ColumnIndex column, std::uint32_t repeated, +void Sheet::init_column(std::uint32_t column, std::uint32_t repeated, Element *element) { - init_child(element); - m_columns[column + repeated] = element; } -void Sheet::init_row(RowIndex row, std::uint32_t repeated, Element *element) { - init_child(element); - +void Sheet::init_row(std::uint32_t row, std::uint32_t repeated, + Element *element) { m_rows[row + repeated].element = element; } -void Sheet::init_cell(ColumnIndex column, RowIndex row, +void Sheet::init_cell(std::uint32_t column, std::uint32_t row, std::uint32_t columns_repeated, std::uint32_t rows_repeated, Element *element) { - init_child(element); - m_rows[row + rows_repeated].cells[column + columns_repeated] = element; } diff --git a/src/odr/internal/odf/odf_spreadsheet.hpp b/src/odr/internal/odf/odf_spreadsheet.hpp index c7df998e..44bd2ffc 100644 --- a/src/odr/internal/odf/odf_spreadsheet.hpp +++ b/src/odr/internal/odf/odf_spreadsheet.hpp @@ -1,14 +1,15 @@ #ifndef ODR_INTERNAL_ODF_SPREADSHEET_H #define ODR_INTERNAL_ODF_SPREADSHEET_H -#include -#include #include #include #include #include #include #include + +#include +#include #include namespace pugi { @@ -27,30 +28,27 @@ class Sheet final : public Element, public common::Sheet { public: explicit Sheet(pugi::xml_node node); - [[nodiscard]] std::string name(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] std::string name(const abstract::Document *) const final; - [[nodiscard]] TableDimensions dimensions(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] TableDimensions + dimensions(const abstract::Document *) const final; [[nodiscard]] TableDimensions - content(const abstract::Document *, ElementIdentifier, + content(const abstract::Document *, const std::optional range) const final; [[nodiscard]] abstract::Element *column(const abstract::Document *, - ElementIdentifier, - ColumnIndex column) const final; - [[nodiscard]] abstract::Element * - row(const abstract::Document *, ElementIdentifier, RowIndex row) const final; + std::uint32_t column) const final; + [[nodiscard]] abstract::Element *row(const abstract::Document *, + std::uint32_t row) const final; [[nodiscard]] abstract::Element *cell(const abstract::Document *, - ElementIdentifier, ColumnIndex column, - RowIndex row) const final; + std::uint32_t column, + std::uint32_t row) const final; - [[nodiscard]] abstract::Element *first_shape(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] abstract::Element * + first_shape(const abstract::Document *) const final; - [[nodiscard]] TableStyle style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] TableStyle style(const abstract::Document *) const final; void init_column(std::uint32_t column, std::uint32_t repeated, Element *element); diff --git a/src/odr/internal/ooxml/presentation/ooxml_presentation_document.cpp b/src/odr/internal/ooxml/presentation/ooxml_presentation_document.cpp index 24439369..54a939da 100644 --- a/src/odr/internal/ooxml/presentation/ooxml_presentation_document.cpp +++ b/src/odr/internal/ooxml/presentation/ooxml_presentation_document.cpp @@ -1,8 +1,10 @@ +#include + #include #include + #include #include -#include #include #include @@ -12,9 +14,7 @@ Document::Document(std::shared_ptr filesystem) : m_filesystem{std::move(filesystem)} { m_document_xml = util::xml::parse(*m_filesystem, "ppt/presentation.xml"); - auto [root_element, elements] = parse_tree(m_document_xml.document_element()); - m_elements = std::move(elements); - m_root_element = root_element; + m_root_element = parse_tree(*this, m_document_xml.document_element()); for (auto relationships : parse_relationships(*m_filesystem, "ppt/presentation.xml")) { @@ -50,9 +50,10 @@ std::shared_ptr Document::files() const noexcept { return m_filesystem; } -std::pair -Document::root_element() const { - return {m_root_element, 0}; // TODO +abstract::Element *Document::root_element() const { return m_root_element; } + +void Document::register_element_(std::unique_ptr element) { + m_elements.push_back(std::move(element)); } } // namespace odr::internal::ooxml::presentation diff --git a/src/odr/internal/ooxml/presentation/ooxml_presentation_document.hpp b/src/odr/internal/ooxml/presentation/ooxml_presentation_document.hpp index 5652d7dc..b2f4aec5 100644 --- a/src/odr/internal/ooxml/presentation/ooxml_presentation_document.hpp +++ b/src/odr/internal/ooxml/presentation/ooxml_presentation_document.hpp @@ -3,8 +3,11 @@ #include #include -#include + #include +#include + +#include namespace odr::internal::ooxml::presentation { @@ -24,8 +27,9 @@ class Document final : public abstract::Document { [[nodiscard]] std::shared_ptr files() const noexcept final; - [[nodiscard]] std::pair - root_element() const final; + [[nodiscard]] abstract::Element *root_element() const final; + + void register_element_(std::unique_ptr element); private: std::shared_ptr m_filesystem; diff --git a/src/odr/internal/ooxml/presentation/ooxml_presentation_element.cpp b/src/odr/internal/ooxml/presentation/ooxml_presentation_element.cpp index f8151f7b..7f6483f6 100644 --- a/src/odr/internal/ooxml/presentation/ooxml_presentation_element.cpp +++ b/src/odr/internal/ooxml/presentation/ooxml_presentation_element.cpp @@ -1,12 +1,10 @@ +#include + #include -#include -#include -#include + #include #include -#include -#include -#include + #include namespace odr::internal::ooxml::presentation { @@ -24,10 +22,11 @@ common::ResolvedStyle Element::partial_style(const abstract::Document *) const { common::ResolvedStyle Element::intermediate_style(const abstract::Document *document) const { - if (m_parent == nullptr) { + abstract::Element *parent = this->parent(document); + if (parent == nullptr) { return partial_style(document); } - auto base = dynamic_cast(m_parent)->intermediate_style(document); + auto base = dynamic_cast(parent)->intermediate_style(document); base.override(partial_style(document)); return base; } @@ -41,17 +40,15 @@ pugi::xml_node Element::slide_(const abstract::Document *document, return document_(document)->m_slides_xml.at(id).document_element(); } -PageLayout Slide::page_layout(const abstract::Document *, - ElementIdentifier) const { +PageLayout Slide::page_layout(const abstract::Document *) const { return {}; // TODO } -std::pair -Slide::master_page(const abstract::Document *, ElementIdentifier) const { +abstract::Element *Slide::master_page(const abstract::Document *) const { return {}; // TODO } -std::string Slide::name(const abstract::Document *, ElementIdentifier) const { +std::string Slide::name(const abstract::Document *) const { return {}; // TODO } @@ -59,18 +56,15 @@ pugi::xml_node Slide::slide_node_(const abstract::Document *document) const { return slide_(document, m_node.attribute("r:id").value()); } -ParagraphStyle Paragraph::style(const abstract::Document *document, - ElementIdentifier) const { +ParagraphStyle Paragraph::style(const abstract::Document *document) const { return partial_style(document).paragraph_style; } -TextStyle Paragraph::text_style(const abstract::Document *document, - ElementIdentifier) const { +TextStyle Paragraph::text_style(const abstract::Document *document) const { return partial_style(document).text_style; } -TextStyle Span::style(const abstract::Document *document, - ElementIdentifier) const { +TextStyle Span::style(const abstract::Document *document) const { return partial_style(document).text_style; } @@ -79,7 +73,7 @@ Text::Text(pugi::xml_node node) : Text(node, node) {} Text::Text(pugi::xml_node first, pugi::xml_node last) : Element(first), m_last{last} {} -std::string Text::content(const abstract::Document *, ElementIdentifier) const { +std::string Text::content(const abstract::Document *) const { std::string result; for (auto node = m_node; node != m_last.next_sibling(); node = node.next_sibling()) { @@ -88,13 +82,11 @@ std::string Text::content(const abstract::Document *, ElementIdentifier) const { return result; } -void Text::set_content(const abstract::Document *, ElementIdentifier, - const std::string &) { +void Text::set_content(const abstract::Document *, const std::string &) { // TODO } -TextStyle Text::style(const abstract::Document *document, - ElementIdentifier) const { +TextStyle Text::style(const abstract::Document *document) const { return partial_style(document).text_style; } @@ -111,63 +103,50 @@ std::string Text::text_(const pugi::xml_node node) { return ""; } -TableDimensions TableElement::dimensions(const abstract::Document *, - ElementIdentifier) const { +TableDimensions TableElement::dimensions(const abstract::Document *) const { return {}; // TODO } -std::pair -TableElement::first_column(const abstract::Document *, - ElementIdentifier) const { +abstract::Element * +TableElement::first_column(const abstract::Document *) const { return {}; // TODO } -std::pair -TableElement::first_row(const abstract::Document *, ElementIdentifier) const { +abstract::Element *TableElement::first_row(const abstract::Document *) const { return {}; // TODO } -TableStyle TableElement::style(const abstract::Document *document, - ElementIdentifier) const { +TableStyle TableElement::style(const abstract::Document *document) const { return partial_style(document).table_style; } -TableColumnStyle TableColumn::style(const abstract::Document *document, - ElementIdentifier) const { +TableColumnStyle TableColumn::style(const abstract::Document *document) const { return partial_style(document).table_column_style; } -TableRowStyle TableRow::style(const abstract::Document *document, - ElementIdentifier) const { +TableRowStyle TableRow::style(const abstract::Document *document) const { return partial_style(document).table_row_style; } -bool TableCell::covered(const abstract::Document *, ElementIdentifier) const { - return false; -} +bool TableCell::covered(const abstract::Document *) const { return false; } -TableDimensions TableCell::span(const abstract::Document *, - ElementIdentifier) const { +TableDimensions TableCell::span(const abstract::Document *) const { return {1, 1}; // TODO } -ValueType TableCell::value_type(const abstract::Document *, - ElementIdentifier) const { +ValueType TableCell::value_type(const abstract::Document *) const { return ValueType::string; } -TableCellStyle TableCell::style(const abstract::Document *document, - ElementIdentifier) const { +TableCellStyle TableCell::style(const abstract::Document *document) const { return partial_style(document).table_cell_style; } -AnchorType Frame::anchor_type(const abstract::Document *, - ElementIdentifier) const { +AnchorType Frame::anchor_type(const abstract::Document *) const { return AnchorType::at_page; } -std::optional Frame::x(const abstract::Document *, - ElementIdentifier) const { +std::optional Frame::x(const abstract::Document *) const { if (auto x = read_emus_attribute( m_node.child("p:spPr").child("a:xfrm").child("a:off").attribute( "x"))) { @@ -176,8 +155,7 @@ std::optional Frame::x(const abstract::Document *, return {}; } -std::optional Frame::y(const abstract::Document *, - ElementIdentifier) const { +std::optional Frame::y(const abstract::Document *) const { if (auto y = read_emus_attribute( m_node.child("p:spPr").child("a:xfrm").child("a:off").attribute( "y"))) { @@ -186,8 +164,7 @@ std::optional Frame::y(const abstract::Document *, return {}; } -std::optional Frame::width(const abstract::Document *, - ElementIdentifier) const { +std::optional Frame::width(const abstract::Document *) const { if (auto cx = read_emus_attribute( m_node.child("p:spPr").child("a:xfrm").child("a:ext").attribute( "cx"))) { @@ -196,8 +173,7 @@ std::optional Frame::width(const abstract::Document *, return {}; } -std::optional Frame::height(const abstract::Document *, - ElementIdentifier) const { +std::optional Frame::height(const abstract::Document *) const { if (auto cy = read_emus_attribute( m_node.child("p:spPr").child("a:xfrm").child("a:ext").attribute( "cy"))) { @@ -206,27 +182,21 @@ std::optional Frame::height(const abstract::Document *, return {}; } -std::optional Frame::z_index(const abstract::Document *, - ElementIdentifier) const { +std::optional Frame::z_index(const abstract::Document *) const { return {}; // TODO } -GraphicStyle Frame::style(const abstract::Document *, ElementIdentifier) const { +GraphicStyle Frame::style(const abstract::Document *) const { return {}; // TODO } -bool ImageElement::internal(const abstract::Document *, - ElementIdentifier) const { - return false; -} +bool ImageElement::internal(const abstract::Document *) const { return false; } -std::optional ImageElement::file(const abstract::Document *, - ElementIdentifier) const { +std::optional ImageElement::file(const abstract::Document *) const { return {}; // TODO } -std::string ImageElement::href(const abstract::Document *, - ElementIdentifier) const { +std::string ImageElement::href(const abstract::Document *) const { return ""; // TODO } diff --git a/src/odr/internal/ooxml/presentation/ooxml_presentation_element.hpp b/src/odr/internal/ooxml/presentation/ooxml_presentation_element.hpp index ad32230f..8fdc3a9c 100644 --- a/src/odr/internal/ooxml/presentation/ooxml_presentation_element.hpp +++ b/src/odr/internal/ooxml/presentation/ooxml_presentation_element.hpp @@ -4,34 +4,34 @@ #include #include #include -#include + #include +#include + namespace odr::internal::ooxml::presentation { class Document; class Element : public common::Element { public: - explicit Element(pugi::xml_node node); + explicit Element(pugi::xml_node); - common::ResolvedStyle partial_style(const abstract::Document *document) const; - common::ResolvedStyle - intermediate_style(const abstract::Document *document) const; + common::ResolvedStyle partial_style(const abstract::Document *) const; + common::ResolvedStyle intermediate_style(const abstract::Document *) const; protected: - pugi::xml_node m_node; - - static const Document *document_(const abstract::Document *document); - static pugi::xml_node slide_(const abstract::Document *document, + static const Document *document_(const abstract::Document *); + static pugi::xml_node slide_(const abstract::Document *, const std::string &id); + + pugi::xml_node m_node; }; template class DefaultElement : public Element { public: using Element::Element; - [[nodiscard]] ElementType type(const abstract::Document *, - ElementIdentifier) const override { + [[nodiscard]] ElementType type(const abstract::Document *) const override { return element_type; } }; @@ -45,36 +45,31 @@ class Slide final : public Element, public abstract::Slide { public: using Element::Element; - [[nodiscard]] PageLayout page_layout(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] PageLayout page_layout(const abstract::Document *) const final; - [[nodiscard]] std::pair - master_page(const abstract::Document *, ElementIdentifier) const final; + [[nodiscard]] abstract::Element * + master_page(const abstract::Document *) const final; - [[nodiscard]] std::string name(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] std::string name(const abstract::Document *) const final; private: - pugi::xml_node slide_node_(const abstract::Document *document) const; + pugi::xml_node slide_node_(const abstract::Document *) const; }; class Paragraph final : public Element, public abstract::Paragraph { public: using Element::Element; - [[nodiscard]] ParagraphStyle style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] ParagraphStyle style(const abstract::Document *) const final; - [[nodiscard]] TextStyle text_style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] TextStyle text_style(const abstract::Document *) const final; }; class Span final : public Element, public abstract::Span { public: using Element::Element; - [[nodiscard]] TextStyle style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] TextStyle style(const abstract::Document *) const final; }; class Text final : public Element, public abstract::Text { @@ -82,14 +77,11 @@ class Text final : public Element, public abstract::Text { explicit Text(pugi::xml_node node); Text(pugi::xml_node first, pugi::xml_node last); - [[nodiscard]] std::string content(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] std::string content(const abstract::Document *) const final; - void set_content(const abstract::Document *, ElementIdentifier, - const std::string &content); + void set_content(const abstract::Document *, const std::string &content); - [[nodiscard]] TextStyle style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] TextStyle style(const abstract::Document *) const final; private: static std::string text_(const pugi::xml_node node); @@ -101,87 +93,76 @@ class TableElement : public Element, public abstract::Table { public: using Element::Element; - [[nodiscard]] TableDimensions dimensions(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] TableDimensions + dimensions(const abstract::Document *) const final; - [[nodiscard]] std::pair - first_column(const abstract::Document *, ElementIdentifier) const final; + [[nodiscard]] abstract::Element * + first_column(const abstract::Document *) const final; - [[nodiscard]] std::pair - first_row(const abstract::Document *, ElementIdentifier) const final; + [[nodiscard]] abstract::Element * + first_row(const abstract::Document *) const final; - [[nodiscard]] TableStyle style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] TableStyle style(const abstract::Document *) const final; }; class TableColumn final : public Element, public abstract::TableColumn { public: using Element::Element; - [[nodiscard]] TableColumnStyle style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] TableColumnStyle style(const abstract::Document *) const final; }; class TableRow final : public Element, public abstract::TableRow { public: using Element::Element; - [[nodiscard]] TableRowStyle style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] TableRowStyle style(const abstract::Document *) const final; }; class TableCell final : public Element, public abstract::TableCell { public: using Element::Element; - [[nodiscard]] bool covered(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] bool covered(const abstract::Document *) const final; - [[nodiscard]] TableDimensions span(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] TableDimensions span(const abstract::Document *) const final; - [[nodiscard]] ValueType value_type(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] ValueType value_type(const abstract::Document *) const final; - [[nodiscard]] TableCellStyle style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] TableCellStyle style(const abstract::Document *) const final; }; class Frame final : public Element, public abstract::Frame { public: using Element::Element; - [[nodiscard]] AnchorType anchor_type(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] AnchorType anchor_type(const abstract::Document *) const final; - [[nodiscard]] std::optional x(const abstract::Document *, - ElementIdentifier) const final; - [[nodiscard]] std::optional y(const abstract::Document *, - ElementIdentifier) const final; - [[nodiscard]] std::optional width(const abstract::Document *, - ElementIdentifier) const final; [[nodiscard]] std::optional - height(const abstract::Document *, ElementIdentifier) const final; + x(const abstract::Document *) const final; + [[nodiscard]] std::optional + y(const abstract::Document *) const final; + [[nodiscard]] std::optional + width(const abstract::Document *) const final; + [[nodiscard]] std::optional + height(const abstract::Document *) const final; [[nodiscard]] std::optional - z_index(const abstract::Document *, ElementIdentifier) const final; + z_index(const abstract::Document *) const final; - [[nodiscard]] GraphicStyle style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] GraphicStyle style(const abstract::Document *) const final; }; class ImageElement final : public Element, public abstract::Image { public: using Element::Element; - [[nodiscard]] bool internal(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] bool internal(const abstract::Document *) const final; - [[nodiscard]] std::optional file(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] std::optional + file(const abstract::Document *) const final; - [[nodiscard]] std::string href(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] std::string href(const abstract::Document *) const final; }; } // namespace odr::internal::ooxml::presentation diff --git a/src/odr/internal/ooxml/presentation/ooxml_presentation_parser.cpp b/src/odr/internal/ooxml/presentation/ooxml_presentation_parser.cpp index a33ae86e..db6ad230 100644 --- a/src/odr/internal/ooxml/presentation/ooxml_presentation_parser.cpp +++ b/src/odr/internal/ooxml/presentation/ooxml_presentation_parser.cpp @@ -1,47 +1,47 @@ -#include -#include #include + +#include +#include + +#include #include namespace odr::internal::ooxml::presentation { namespace { -template -std::tuple -parse_element_tree(pugi::xml_node node, - std::vector> &store); +template +std::tuple parse_element_tree(Document &document, + pugi::xml_node node); std::tuple -parse_any_element_tree(pugi::xml_node node, - std::vector> &store); +parse_any_element_tree(Document &document, pugi::xml_node node); -void parse_element_children(Element *element, pugi::xml_node node, - std::vector> &store) { +void parse_element_children(Document &document, Element *element, + pugi::xml_node node) { for (auto child_node = node.first_child(); child_node;) { - auto [child, next_sibling] = parse_any_element_tree(child_node, store); + auto [child, next_sibling] = parse_any_element_tree(document, child_node); if (child == nullptr) { child_node = child_node.next_sibling(); } else { - element->init_append_child(child); + element->append_child_(child); child_node = next_sibling; } } } -template -std::tuple -parse_element_tree(pugi::xml_node node, - std::vector> &store) { +template +std::tuple parse_element_tree(Document &document, + pugi::xml_node node) { if (!node) { return std::make_tuple(nullptr, pugi::xml_node()); } - auto element_unique = std::make_unique(node); + auto element_unique = std::make_unique(node); auto element = element_unique.get(); - store.push_back(std::move(element_unique)); + document.register_element_(std::move(element_unique)); - parse_element_children(element, node, store); + parse_element_children(document, element, node); return std::make_tuple(element, node.next_sibling()); } @@ -65,8 +65,7 @@ bool is_text_node(const pugi::xml_node node) { template <> std::tuple -parse_element_tree(pugi::xml_node first, - std::vector> &store) { +parse_element_tree(Document &document, pugi::xml_node first) { if (!first) { return std::make_tuple(nullptr, pugi::xml_node()); } @@ -77,16 +76,15 @@ parse_element_tree(pugi::xml_node first, auto element_unique = std::make_unique(first, last); auto element = element_unique.get(); - store.push_back(std::move(element_unique)); + document.register_element_(std::move(element_unique)); return std::make_tuple(element, last.next_sibling()); } std::tuple -parse_any_element_tree(pugi::xml_node node, - std::vector> &store) { +parse_any_element_tree(Document &document, pugi::xml_node node) { using Parser = std::function( - pugi::xml_node node, std::vector> & store)>; + Document & document, pugi::xml_node node)>; using Group = DefaultElement; @@ -106,7 +104,7 @@ parse_any_element_tree(pugi::xml_node node, if (auto constructor_it = parser_table.find(node.name()); constructor_it != std::end(parser_table)) { - return constructor_it->second(node, store); + return constructor_it->second(document, node); } return std::make_tuple(nullptr, pugi::xml_node()); @@ -118,12 +116,11 @@ parse_any_element_tree(pugi::xml_node node, namespace odr::internal::ooxml { -std::tuple>> -presentation::parse_tree(pugi::xml_node node) { - std::vector> store; - auto [root, _] = parse_any_element_tree(node, store); - return std::make_tuple(root, std::move(store)); +presentation::Element * +presentation::parse_tree(presentation::Document &document, + pugi::xml_node node) { + auto [root, _] = parse_any_element_tree(document, node); + return root; } } // namespace odr::internal::ooxml diff --git a/src/odr/internal/ooxml/presentation/ooxml_presentation_parser.hpp b/src/odr/internal/ooxml/presentation/ooxml_presentation_parser.hpp index a9fdad89..ca69f7af 100644 --- a/src/odr/internal/ooxml/presentation/ooxml_presentation_parser.hpp +++ b/src/odr/internal/ooxml/presentation/ooxml_presentation_parser.hpp @@ -1,16 +1,19 @@ #ifndef ODR_INTERNAL_OOXML_PRESENTATION_PARSER_HPP #define ODR_INTERNAL_OOXML_PRESENTATION_PARSER_HPP +#include + #include -#include #include #include +#include + namespace odr::internal::ooxml::presentation { +class Document; class Element; -std::tuple>> -parse_tree(pugi::xml_node node); +Element *parse_tree(Document &document, pugi::xml_node node); } // namespace odr::internal::ooxml::presentation diff --git a/src/odr/internal/ooxml/spreadsheet/ooxml_spreadsheet_document.cpp b/src/odr/internal/ooxml/spreadsheet/ooxml_spreadsheet_document.cpp index 34407f7d..23d778c7 100644 --- a/src/odr/internal/ooxml/spreadsheet/ooxml_spreadsheet_document.cpp +++ b/src/odr/internal/ooxml/spreadsheet/ooxml_spreadsheet_document.cpp @@ -1,7 +1,6 @@ #include #include -#include #include #include @@ -17,9 +16,7 @@ Document::Document(std::shared_ptr filesystem) m_workbook_xml = util::xml::parse(*m_filesystem, "xl/workbook.xml"); m_styles_xml = util::xml::parse(*m_filesystem, "xl/styles.xml"); - auto [root_element, elements] = parse_tree(m_workbook_xml.document_element()); - m_elements = std::move(elements); - m_root_element = root_element; + m_root_element = parse_tree(*this, m_workbook_xml.document_element()); m_style_registry = StyleRegistry(m_styles_xml.document_element()); @@ -80,9 +77,10 @@ std::shared_ptr Document::files() const noexcept { return m_filesystem; } -std::pair -Document::root_element() const { - return {m_root_element, 0}; // TODO +abstract::Element *Document::root_element() const { return m_root_element; } + +void Document::register_element_(std::unique_ptr element) { + m_elements.push_back(std::move(element)); } } // namespace odr::internal::ooxml::spreadsheet diff --git a/src/odr/internal/ooxml/spreadsheet/ooxml_spreadsheet_document.hpp b/src/odr/internal/ooxml/spreadsheet/ooxml_spreadsheet_document.hpp index 3bae1a53..53fcad4d 100644 --- a/src/odr/internal/ooxml/spreadsheet/ooxml_spreadsheet_document.hpp +++ b/src/odr/internal/ooxml/spreadsheet/ooxml_spreadsheet_document.hpp @@ -8,12 +8,12 @@ #include #include -#include - #include #include #include +#include + namespace odr::internal::abstract { class ReadableFilesystem; } // namespace odr::internal::abstract @@ -36,8 +36,9 @@ class Document final : public abstract::Document { [[nodiscard]] std::shared_ptr files() const noexcept final; - [[nodiscard]] std::pair - root_element() const final; + [[nodiscard]] abstract::Element *root_element() const final; + + void register_element_(std::unique_ptr element); private: struct Sheet final { diff --git a/src/odr/internal/ooxml/spreadsheet/ooxml_spreadsheet_element.cpp b/src/odr/internal/ooxml/spreadsheet/ooxml_spreadsheet_element.cpp index 6b863e8a..db32b54e 100644 --- a/src/odr/internal/ooxml/spreadsheet/ooxml_spreadsheet_element.cpp +++ b/src/odr/internal/ooxml/spreadsheet/ooxml_spreadsheet_element.cpp @@ -1,21 +1,14 @@ #include -#include - -#include #include -#include -#include #include #include #include -#include - #include #include -#include -#include + +#include namespace odr::internal::ooxml::spreadsheet { @@ -26,20 +19,18 @@ Element::Element(pugi::xml_node node) : m_node{node} { } } -common::ResolvedStyle Element::partial_style(const abstract::Document *, - ElementIdentifier) const { +common::ResolvedStyle Element::partial_style(const abstract::Document *) const { return {}; } common::ResolvedStyle -Element::intermediate_style(const abstract::Document *document, - ElementIdentifier elementId) const { - if (m_parent == nullptr) { - return partial_style(document, elementId); +Element::intermediate_style(const abstract::Document *document) const { + abstract::Element *parent = this->parent(document); + if (parent == nullptr) { + return partial_style(document); } - auto base = dynamic_cast(m_parent)->intermediate_style(document, - elementId); - base.override(partial_style(document, elementId)); + auto base = dynamic_cast(parent)->intermediate_style(document); + base.override(partial_style(document)); return base; } @@ -67,16 +58,15 @@ Element::shared_strings_(const abstract::Document *document) { return document_(document)->m_shared_strings; } -ElementType Sheet::type(const abstract::Document *, ElementIdentifier) const { +ElementType Sheet::type(const abstract::Document *) const { return ElementType::sheet; } -std::string Sheet::name(const abstract::Document *, ElementIdentifier) const { +std::string Sheet::name(const abstract::Document *) const { return m_node.attribute("name").value(); } -TableDimensions Sheet::dimensions(const abstract::Document *document, - ElementIdentifier) const { +TableDimensions Sheet::dimensions(const abstract::Document *document) const { if (auto dimension = sheet_node_(document).child("dimension").attribute("ref")) { try { @@ -89,35 +79,34 @@ TableDimensions Sheet::dimensions(const abstract::Document *document, } TableDimensions Sheet::content(const abstract::Document *document, - ElementIdentifier elementId, std::optional) const { - return dimensions(document, elementId); // TODO + return dimensions(document); // TODO } -abstract::Element *Sheet::column(const abstract::Document *, ElementIdentifier, - ColumnIndex) const { +abstract::Element *Sheet::column(const abstract::Document *, + std::uint32_t /*column*/) const { return nullptr; // TODO } -abstract::Element *Sheet::row(const abstract::Document *, ElementIdentifier, - RowIndex) const { +abstract::Element *Sheet::row(const abstract::Document *, + std::uint32_t /*row*/) const { return nullptr; // TODO } -abstract::Element *Sheet::cell(const abstract::Document *, ElementIdentifier, - ColumnIndex /*column*/, RowIndex /*row*/) const { +abstract::Element *Sheet::cell(const abstract::Document *, + std::uint32_t /*column*/, + std::uint32_t /*row*/) const { return nullptr; // TODO } -abstract::Element *Sheet::first_shape(const abstract::Document *, - ElementIdentifier) const { +abstract::Element *Sheet::first_shape(const abstract::Document *) const { return nullptr; // TODO } -TableStyle Sheet::style(const abstract::Document *document, - ElementIdentifier elementId) const { - return partial_style(document, elementId).table_style; +TableStyle Sheet::style(const abstract::Document *document) const { + return partial_style(document).table_style; } + pugi::xml_node Sheet::sheet_node_(const abstract::Document *document) const { return sheet_(document, m_node.attribute("r:id").value()); } @@ -126,8 +115,7 @@ pugi::xml_node Sheet::drawing_node_(const abstract::Document *document) const { return drawing_(document, m_node.attribute("r:id").value()); } -TableColumnStyle TableColumn::style(const abstract::Document *, - ElementIdentifier) const { +TableColumnStyle TableColumn::style(const abstract::Document *) const { TableColumnStyle result; if (auto width = m_node.attribute("width")) { result.width = Measure(width.as_float(), DynamicUnit("ch")); @@ -135,16 +123,17 @@ TableColumnStyle TableColumn::style(const abstract::Document *, return result; } -[[nodiscard]] std::uint32_t TableColumn::min_() const { +[[nodiscard]] std::uint32_t +TableColumn::min_(const abstract::Document *) const { return m_node.attribute("min").as_uint() - 1; } -[[nodiscard]] std::uint32_t TableColumn::max_() const { - return m_node.attribute("min").as_uint() - 1; +[[nodiscard]] std::uint32_t +TableColumn::max_(const abstract::Document *) const { + return m_node.attribute("max").as_uint() - 1; } -TableRowStyle TableRow::style(const abstract::Document *, - ElementIdentifier) const { +TableRowStyle TableRow::style(const abstract::Document *) const { TableRowStyle result; if (auto height = m_node.attribute("ht")) { result.height = Measure(height.as_float(), DynamicUnit("pt")); @@ -152,37 +141,32 @@ TableRowStyle TableRow::style(const abstract::Document *, return result; } -bool TableCell::covered(const abstract::Document *, ElementIdentifier) const { +bool TableCell::covered(const abstract::Document *) const { return false; // TODO } -ValueType TableCell::value_type(const abstract::Document *, - ElementIdentifier) const { +ValueType TableCell::value_type(const abstract::Document *) const { return ValueType::string; } common::ResolvedStyle -TableCell::partial_style(const abstract::Document *document, - ElementIdentifier) const { - if (auto id = m_node.attribute("s")) { - return style_registry_(document)->cell_style(id.as_uint()); +TableCell::partial_style(const abstract::Document *document) const { + if (auto style_id = m_node.attribute("s")) { + return style_registry_(document)->cell_style(style_id.as_uint()); } return {}; } -TableDimensions TableCell::span(const abstract::Document *, - ElementIdentifier) const { +TableDimensions TableCell::span(const abstract::Document *) const { return {1, 1}; } -TableCellStyle TableCell::style(const abstract::Document *document, - ElementIdentifier elementId) const { - return partial_style(document, elementId).table_cell_style; +TableCellStyle TableCell::style(const abstract::Document *document) const { + return partial_style(document).table_cell_style; } -TextStyle Span::style(const abstract::Document *document, - ElementIdentifier elementId) const { - return intermediate_style(document, elementId).text_style; +TextStyle Span::style(const abstract::Document *document) const { + return intermediate_style(document).text_style; } Text::Text(pugi::xml_node node) : Text(node, node) {} @@ -190,7 +174,7 @@ Text::Text(pugi::xml_node node) : Text(node, node) {} Text::Text(pugi::xml_node first, pugi::xml_node last) : Element(first), m_last{last} {} -std::string Text::content(const abstract::Document *, ElementIdentifier) const { +std::string Text::content(const abstract::Document *) const { std::string result; for (auto node = m_node; node != m_last.next_sibling(); node = node.next_sibling()) { @@ -199,14 +183,12 @@ std::string Text::content(const abstract::Document *, ElementIdentifier) const { return result; } -void Text::set_content(const abstract::Document *, ElementIdentifier, - const std::string &) { +void Text::set_content(const abstract::Document *, const std::string &) { // TODO } -TextStyle Text::style(const abstract::Document *document, - ElementIdentifier elementId) const { - return intermediate_style(document, elementId).text_style; +TextStyle Text::style(const abstract::Document *document) const { + return intermediate_style(document).text_style; } std::string Text::text_(const pugi::xml_node node) { @@ -219,13 +201,11 @@ std::string Text::text_(const pugi::xml_node node) { return ""; } -AnchorType Frame::anchor_type(const abstract::Document *, - ElementIdentifier) const { +AnchorType Frame::anchor_type(const abstract::Document *) const { return AnchorType::at_page; } -std::optional Frame::x(const abstract::Document *, - ElementIdentifier) const { +std::optional Frame::x(const abstract::Document *) const { if (auto x = read_emus_attribute(m_node.child("xdr:pic") .child("xdr:spPr") .child("a:xfrm") @@ -236,8 +216,7 @@ std::optional Frame::x(const abstract::Document *, return {}; } -std::optional Frame::y(const abstract::Document *, - ElementIdentifier) const { +std::optional Frame::y(const abstract::Document *) const { if (auto y = read_emus_attribute(m_node.child("xdr:pic") .child("xdr:spPr") .child("a:xfrm") @@ -248,8 +227,7 @@ std::optional Frame::y(const abstract::Document *, return {}; } -std::optional Frame::width(const abstract::Document *, - ElementIdentifier) const { +std::optional Frame::width(const abstract::Document *) const { if (auto width = read_emus_attribute(m_node.child("xdr:pic") .child("xdr:spPr") .child("a:xfrm") @@ -260,8 +238,7 @@ std::optional Frame::width(const abstract::Document *, return {}; } -std::optional Frame::height(const abstract::Document *, - ElementIdentifier) const { +std::optional Frame::height(const abstract::Document *) const { if (auto height = read_emus_attribute(m_node.child("xdr:pic") .child("xdr:spPr") .child("a:xfrm") @@ -272,39 +249,34 @@ std::optional Frame::height(const abstract::Document *, return {}; } -std::optional Frame::z_index(const abstract::Document *, - ElementIdentifier) const { +std::optional Frame::z_index(const abstract::Document *) const { return {}; } -GraphicStyle Frame::style(const abstract::Document *, ElementIdentifier) const { - return {}; -} +GraphicStyle Frame::style(const abstract::Document *) const { return {}; } -bool ImageElement::internal(const abstract::Document *document, - ElementIdentifier elementId) const { +bool ImageElement::internal(const abstract::Document *document) const { auto doc = document_(document); if (!doc || !doc->files()) { return false; } try { - return doc->files()->is_file(href(document, elementId)); + return doc->files()->is_file(href(document)); } catch (...) { } return false; } -std::optional ImageElement::file(const abstract::Document *document, - ElementIdentifier elementId) const { +std::optional +ImageElement::file(const abstract::Document *document) const { auto doc = document_(document); - if (!doc || !internal(document, elementId)) { + if (!doc || !internal(document)) { return {}; } - return File(doc->files()->open(href(document, elementId))); + return File(doc->files()->open(href(document))); } -std::string ImageElement::href(const abstract::Document *, - ElementIdentifier) const { +std::string ImageElement::href(const abstract::Document *) const { if (auto ref = m_node.attribute("r:embed")) { /* TODO auto relations = document_relations_(document); diff --git a/src/odr/internal/ooxml/spreadsheet/ooxml_spreadsheet_element.hpp b/src/odr/internal/ooxml/spreadsheet/ooxml_spreadsheet_element.hpp index 153dbeeb..be8224b4 100644 --- a/src/odr/internal/ooxml/spreadsheet/ooxml_spreadsheet_element.hpp +++ b/src/odr/internal/ooxml/spreadsheet/ooxml_spreadsheet_element.hpp @@ -18,10 +18,8 @@ class Element : public common::Element { public: explicit Element(pugi::xml_node node); - virtual common::ResolvedStyle partial_style(const abstract::Document *, - ElementIdentifier) const; - common::ResolvedStyle intermediate_style(const abstract::Document *, - ElementIdentifier) const; + virtual common::ResolvedStyle partial_style(const abstract::Document *) const; + common::ResolvedStyle intermediate_style(const abstract::Document *) const; protected: pugi::xml_node m_node; @@ -40,8 +38,7 @@ template class DefaultElement : public Element { public: using Element::Element; - [[nodiscard]] ElementType type(const abstract::Document *, - ElementIdentifier) const override { + [[nodiscard]] ElementType type(const abstract::Document *) const override { return element_type; } }; @@ -55,33 +52,29 @@ class Sheet final : public Element, public abstract::Sheet { public: using Element::Element; - [[nodiscard]] ElementType type(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] ElementType type(const abstract::Document *) const final; - [[nodiscard]] std::string name(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] std::string name(const abstract::Document *) const final; - [[nodiscard]] TableDimensions dimensions(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] TableDimensions + dimensions(const abstract::Document *) const final; [[nodiscard]] TableDimensions - content(const abstract::Document *, ElementIdentifier, + content(const abstract::Document *, std::optional) const final; [[nodiscard]] abstract::Element *column(const abstract::Document *, - ElementIdentifier, - ColumnIndex column) const final; - [[nodiscard]] abstract::Element * - row(const abstract::Document *, ElementIdentifier, RowIndex row) const final; + std::uint32_t column) const final; + [[nodiscard]] abstract::Element *row(const abstract::Document *, + std::uint32_t row) const final; [[nodiscard]] abstract::Element *cell(const abstract::Document *, - ElementIdentifier, ColumnIndex column, - RowIndex row) const final; + std::uint32_t column, + std::uint32_t row) const final; - [[nodiscard]] abstract::Element *first_shape(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] abstract::Element * + first_shape(const abstract::Document *) const final; - [[nodiscard]] TableStyle style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] TableStyle style(const abstract::Document *) const final; private: pugi::xml_node sheet_node_(const abstract::Document *) const; @@ -92,48 +85,40 @@ class TableColumn final : public Element, public abstract::TableColumn { public: using Element::Element; - [[nodiscard]] TableColumnStyle style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] TableColumnStyle style(const abstract::Document *) const final; private: - [[nodiscard]] std::uint32_t min_() const; - [[nodiscard]] std::uint32_t max_() const; + [[nodiscard]] std::uint32_t min_(const abstract::Document *) const; + [[nodiscard]] std::uint32_t max_(const abstract::Document *) const; }; class TableRow final : public Element, public abstract::TableRow { public: using Element::Element; - [[nodiscard]] TableRowStyle style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] TableRowStyle style(const abstract::Document *) const final; }; class TableCell final : public Element, public abstract::TableCell { public: using Element::Element; - [[nodiscard]] bool covered(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] bool covered(const abstract::Document *) const final; - [[nodiscard]] TableDimensions span(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] TableDimensions span(const abstract::Document *) const final; - [[nodiscard]] ValueType value_type(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] ValueType value_type(const abstract::Document *) const final; - common::ResolvedStyle partial_style(const abstract::Document *, - ElementIdentifier) const final; + common::ResolvedStyle partial_style(const abstract::Document *) const final; - [[nodiscard]] TableCellStyle style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] TableCellStyle style(const abstract::Document *) const final; }; class Span final : public Element, public abstract::Span { public: using Element::Element; - [[nodiscard]] TextStyle style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] TextStyle style(const abstract::Document *) const final; }; class Text final : public Element, public abstract::Text { @@ -141,56 +126,49 @@ class Text final : public Element, public abstract::Text { explicit Text(pugi::xml_node node); Text(pugi::xml_node first, pugi::xml_node last); - [[nodiscard]] std::string content(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] std::string content(const abstract::Document *) const final; - void set_content(const abstract::Document *, ElementIdentifier, - const std::string &) final; + void set_content(const abstract::Document *, const std::string &) final; - [[nodiscard]] TextStyle style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] TextStyle style(const abstract::Document *) const final; private: - static std::string text_(const pugi::xml_node node); - pugi::xml_node m_last; + + static std::string text_(const pugi::xml_node node); }; class Frame final : public Element, public abstract::Frame { public: using Element::Element; - [[nodiscard]] AnchorType anchor_type(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] AnchorType anchor_type(const abstract::Document *) const final; - [[nodiscard]] std::optional x(const abstract::Document *, - ElementIdentifier) const final; - [[nodiscard]] std::optional y(const abstract::Document *, - ElementIdentifier) const final; - [[nodiscard]] std::optional width(const abstract::Document *, - ElementIdentifier) const final; [[nodiscard]] std::optional - height(const abstract::Document *, ElementIdentifier) const final; + x(const abstract::Document *) const final; + [[nodiscard]] std::optional + y(const abstract::Document *) const final; + [[nodiscard]] std::optional + width(const abstract::Document *) const final; + [[nodiscard]] std::optional + height(const abstract::Document *) const final; [[nodiscard]] std::optional - z_index(const abstract::Document *, ElementIdentifier) const final; + z_index(const abstract::Document *) const final; - [[nodiscard]] GraphicStyle style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] GraphicStyle style(const abstract::Document *) const final; }; class ImageElement final : public Element, public abstract::Image { public: using Element::Element; - [[nodiscard]] bool internal(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] bool internal(const abstract::Document *) const final; - [[nodiscard]] std::optional file(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] std::optional + file(const abstract::Document *) const final; - [[nodiscard]] std::string href(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] std::string href(const abstract::Document *) const final; }; } // namespace odr::internal::ooxml::spreadsheet diff --git a/src/odr/internal/ooxml/spreadsheet/ooxml_spreadsheet_parser.cpp b/src/odr/internal/ooxml/spreadsheet/ooxml_spreadsheet_parser.cpp index 9393fe67..6e6c76b6 100644 --- a/src/odr/internal/ooxml/spreadsheet/ooxml_spreadsheet_parser.cpp +++ b/src/odr/internal/ooxml/spreadsheet/ooxml_spreadsheet_parser.cpp @@ -1,47 +1,46 @@ -#include -#include #include + +#include + +#include #include namespace odr::internal::ooxml::spreadsheet { namespace { -template -std::tuple -parse_element_tree(pugi::xml_node node, - std::vector> &store); +template +std::tuple parse_element_tree(Document &document, + pugi::xml_node node); std::tuple -parse_any_element_tree(pugi::xml_node node, - std::vector> &store); +parse_any_element_tree(Document &document, pugi::xml_node node); -void parse_element_children(Element *element, pugi::xml_node node, - std::vector> &store) { +void parse_element_children(Document &document, Element *element, + pugi::xml_node node) { for (auto child_node = node.first_child(); child_node;) { - auto [child, next_sibling] = parse_any_element_tree(child_node, store); + auto [child, next_sibling] = parse_any_element_tree(document, child_node); if (child == nullptr) { child_node = child_node.next_sibling(); } else { - element->init_append_child(child); + element->append_child_(child); child_node = next_sibling; } } } -template -std::tuple -parse_element_tree(pugi::xml_node node, - std::vector> &store) { +template +std::tuple parse_element_tree(Document &document, + pugi::xml_node node) { if (!node) { return std::make_tuple(nullptr, pugi::xml_node()); } - auto element_unique = std::make_unique(node); + auto element_unique = std::make_unique(node); auto element = element_unique.get(); - store.push_back(std::move(element_unique)); + document.register_element_(std::move(element_unique)); - parse_element_children(element, node, store); + parse_element_children(document, element, node); return std::make_tuple(element, node.next_sibling()); } @@ -65,8 +64,7 @@ bool is_text_node(const pugi::xml_node node) { template <> std::tuple -parse_element_tree(pugi::xml_node first, - std::vector> &store) { +parse_element_tree(Document &document, pugi::xml_node first) { if (!first) { return std::make_tuple(nullptr, pugi::xml_node()); } @@ -77,16 +75,15 @@ parse_element_tree(pugi::xml_node first, auto element_unique = std::make_unique(first, last); auto element = element_unique.get(); - store.push_back(std::move(element_unique)); + document.register_element_(std::move(element_unique)); return std::make_tuple(element, last.next_sibling()); } std::tuple -parse_any_element_tree(pugi::xml_node node, - std::vector> &store) { +parse_any_element_tree(Document &document, pugi::xml_node node) { using Parser = std::function( - pugi::xml_node node, std::vector> & store)>; + Document & document, pugi::xml_node node)>; static std::unordered_map parser_table{ {"workbook", parse_element_tree}, @@ -101,7 +98,7 @@ parse_any_element_tree(pugi::xml_node node, if (auto constructor_it = parser_table.find(node.name()); constructor_it != std::end(parser_table)) { - return constructor_it->second(node, store); + return constructor_it->second(document, node); } return std::make_tuple(nullptr, pugi::xml_node()); @@ -113,12 +110,11 @@ parse_any_element_tree(pugi::xml_node node, namespace odr::internal::ooxml { -std::tuple>> -spreadsheet::parse_tree(pugi::xml_node node) { +spreadsheet::Element *spreadsheet::parse_tree(Document &document, + pugi::xml_node node) { std::vector> store; - auto [root, _] = parse_any_element_tree(node, store); - return std::make_tuple(root, std::move(store)); + auto [root_id, _] = parse_any_element_tree(document, node); + return root_id; } } // namespace odr::internal::ooxml diff --git a/src/odr/internal/ooxml/spreadsheet/ooxml_spreadsheet_parser.hpp b/src/odr/internal/ooxml/spreadsheet/ooxml_spreadsheet_parser.hpp index 2e8c5bc5..9a6d11d2 100644 --- a/src/odr/internal/ooxml/spreadsheet/ooxml_spreadsheet_parser.hpp +++ b/src/odr/internal/ooxml/spreadsheet/ooxml_spreadsheet_parser.hpp @@ -1,16 +1,19 @@ #ifndef ODR_INTERNAL_OOXML_SPREADSHEET_PARSER_HPP #define ODR_INTERNAL_OOXML_SPREADSHEET_PARSER_HPP +#include + #include -#include #include #include +#include + namespace odr::internal::ooxml::spreadsheet { +class Document; class Element; -std::tuple>> -parse_tree(pugi::xml_node node); +Element *parse_tree(Document &document, pugi::xml_node node); } // namespace odr::internal::ooxml::spreadsheet diff --git a/src/odr/internal/ooxml/spreadsheet/ooxml_spreadsheet_style.hpp b/src/odr/internal/ooxml/spreadsheet/ooxml_spreadsheet_style.hpp index 1851ab48..2184ecb0 100644 --- a/src/odr/internal/ooxml/spreadsheet/ooxml_spreadsheet_style.hpp +++ b/src/odr/internal/ooxml/spreadsheet/ooxml_spreadsheet_style.hpp @@ -3,12 +3,12 @@ #include -#include - #include #include #include +#include + namespace odr::internal::ooxml::spreadsheet { class StyleRegistry final { diff --git a/src/odr/internal/ooxml/text/ooxml_text_document.cpp b/src/odr/internal/ooxml/text/ooxml_text_document.cpp index f0a0ac34..a943b984 100644 --- a/src/odr/internal/ooxml/text/ooxml_text_document.cpp +++ b/src/odr/internal/ooxml/text/ooxml_text_document.cpp @@ -1,7 +1,6 @@ #include #include -#include #include #include @@ -24,11 +23,8 @@ Document::Document(std::shared_ptr filesystem) m_document_relations = parse_relationships(*m_filesystem, "word/document.xml"); - auto [root_element, elements] = - parse_tree(m_document_xml.document_element().child("w:body")); - - m_elements = std::move(elements); - m_root_element = root_element; + m_root_element = + parse_tree(*this, m_document_xml.document_element().child("w:body")); m_style_registry = StyleRegistry(m_styles_xml.document_element()); } @@ -82,9 +78,10 @@ std::shared_ptr Document::files() const noexcept { return m_filesystem; } -std::pair -Document::root_element() const { - return {m_root_element, 0}; // TODO +abstract::Element *Document::root_element() const { return m_root_element; } + +void Document::register_element_(std::unique_ptr element) { + m_elements.push_back(std::move(element)); } } // namespace odr::internal::ooxml::text diff --git a/src/odr/internal/ooxml/text/ooxml_text_document.hpp b/src/odr/internal/ooxml/text/ooxml_text_document.hpp index 95695b63..daddf2ec 100644 --- a/src/odr/internal/ooxml/text/ooxml_text_document.hpp +++ b/src/odr/internal/ooxml/text/ooxml_text_document.hpp @@ -36,8 +36,9 @@ class Document final : public abstract::Document { [[nodiscard]] std::shared_ptr files() const noexcept final; - [[nodiscard]] std::pair - root_element() const final; + [[nodiscard]] abstract::Element *root_element() const final; + + void register_element_(std::unique_ptr element); private: std::shared_ptr m_filesystem; diff --git a/src/odr/internal/ooxml/text/ooxml_text_element.cpp b/src/odr/internal/ooxml/text/ooxml_text_element.cpp index 595ae92d..006d3029 100644 --- a/src/odr/internal/ooxml/text/ooxml_text_element.cpp +++ b/src/odr/internal/ooxml/text/ooxml_text_element.cpp @@ -1,24 +1,19 @@ #include #include -#include -#include -#include #include -#include #include -#include #include #include #include -#include - #include #include #include +#include + namespace odr::internal::ooxml::text { Element::Element(pugi::xml_node node) : m_node{node} { @@ -28,22 +23,20 @@ Element::Element(pugi::xml_node node) : m_node{node} { } } -common::ResolvedStyle Element::partial_style(const abstract::Document *, - ElementIdentifier) const { +common::ResolvedStyle Element::partial_style(const abstract::Document *) const { return {}; } common::ResolvedStyle -Element::intermediate_style(const abstract::Document *document, - ElementIdentifier elementId) const { +Element::intermediate_style(const abstract::Document *document) const { common::ResolvedStyle base; - if (m_parent == nullptr) { + abstract::Element *parent = this->parent(document); + if (parent == nullptr) { base = style_(document)->default_style()->resolved(); } else { - base = dynamic_cast(m_parent)->intermediate_style(document, - elementId); + base = dynamic_cast(parent)->intermediate_style(document); } - base.override(partial_style(document, elementId)); + base.override(partial_style(document)); return base; } @@ -60,59 +53,34 @@ Element::document_relations_(const abstract::Document *document) { return dynamic_cast(document)->m_document_relations; } -Root::Root(pugi::xml_node node) : Element(node) {} - -PageLayout Root::page_layout(const abstract::Document *, - ElementIdentifier) const { +PageLayout Root::page_layout(const abstract::Document *) const { return {}; // TODO } -std::pair -Root::first_master_page(const abstract::Document *, ElementIdentifier) const { +abstract::Element *Root::first_master_page(const abstract::Document *) const { return {}; // TODO } -Paragraph::Paragraph(pugi::xml_node node) : Element(node) {} - common::ResolvedStyle -Paragraph::partial_style(const abstract::Document *document, - ElementIdentifier) const { +Paragraph::partial_style(const abstract::Document *document) const { return style_(document)->partial_paragraph_style(m_node); } -ParagraphStyle Paragraph::style(const abstract::Document *document, - ElementIdentifier elementId) const { - return intermediate_style(document, elementId).paragraph_style; +ParagraphStyle Paragraph::style(const abstract::Document *document) const { + return intermediate_style(document).paragraph_style; } -TextStyle Paragraph::text_style(const abstract::Document *document, - ElementIdentifier elementId) const { - return intermediate_style(document, elementId).text_style; +TextStyle Paragraph::text_style(const abstract::Document *document) const { + return intermediate_style(document).text_style; } -Span::Span(pugi::xml_node node) : Element(node) {} - -common::ResolvedStyle Span::partial_style(const abstract::Document *document, - ElementIdentifier) const { +common::ResolvedStyle +Span::partial_style(const abstract::Document *document) const { return style_(document)->partial_text_style(m_node); } -TextStyle Span::style(const abstract::Document *document, - ElementIdentifier elementId) const { - return intermediate_style(document, elementId).text_style; -} - -std::string Text::text(const pugi::xml_node node) { - std::string name = node.name(); - - if (name == "w:t") { - return node.text().get(); - } - if (name == "w:tab") { - return "\t"; - } - - return ""; +TextStyle Span::style(const abstract::Document *document) const { + return intermediate_style(document).text_style; } Text::Text(pugi::xml_node node) : Text(node, node) {} @@ -125,17 +93,16 @@ Text::Text(pugi::xml_node first, pugi::xml_node last) } } -std::string Text::content(const abstract::Document *, ElementIdentifier) const { +std::string Text::content(const abstract::Document *) const { std::string result; for (auto node = m_node; node != m_last.next_sibling(); node = node.next_sibling()) { - result += text(node); + result += text_(node); } return result; } -void Text::set_content(const abstract::Document *, ElementIdentifier, - const std::string &text) { +void Text::set_content(const abstract::Document *, const std::string &text) { // TODO http://officeopenxml.com/WPtextSpacing.php // // use `xml:space` @@ -171,15 +138,24 @@ void Text::set_content(const abstract::Document *, ElementIdentifier, // TODO remove other } -TextStyle Text::style(const abstract::Document *document, - ElementIdentifier elementId) const { - return intermediate_style(document, elementId).text_style; +TextStyle Text::style(const abstract::Document *document) const { + return intermediate_style(document).text_style; } -Link::Link(pugi::xml_node node) : Element(node) {} +std::string Text::text_(const pugi::xml_node node) { + std::string name = node.name(); + + if (name == "w:t") { + return node.text().get(); + } + if (name == "w:tab") { + return "\t"; + } -std::string Link::href(const abstract::Document *document, - ElementIdentifier) const { + return ""; +} + +std::string Link::href(const abstract::Document *document) const { if (auto anchor = m_node.attribute("w:anchor")) { return std::string("#") + anchor.value(); } @@ -192,42 +168,27 @@ std::string Link::href(const abstract::Document *document, return ""; } -Bookmark::Bookmark(pugi::xml_node node) : Element(node) {} - -std::string Bookmark::name(const abstract::Document *, - ElementIdentifier) const { +std::string Bookmark::name(const abstract::Document *) const { return m_node.attribute("w:name").value(); } -List::List(pugi::xml_node node) : Element(node) {} - -ElementType List::type(const abstract::Document *, ElementIdentifier) const { +ElementType List::type(const abstract::Document *) const { return ElementType::list; } -ListItem::ListItem(pugi::xml_node node) : Element(node) {} - -TextStyle ListItem::style(const abstract::Document *document, - ElementIdentifier elementId) const { - return intermediate_style(document, elementId).text_style; +TextStyle ListItem::style(const abstract::Document *document) const { + return intermediate_style(document).text_style; } -Table::Table(pugi::xml_node node) : Element(node) {} - -TableDimensions Table::dimensions(const abstract::Document *, - ElementIdentifier) const { +TableDimensions Table::dimensions(const abstract::Document *) const { return {}; // TODO } -TableStyle Table::style(const abstract::Document *document, - ElementIdentifier) const { +TableStyle Table::style(const abstract::Document *document) const { return style_(document)->partial_table_style(m_node).table_style; } -TableColumn::TableColumn(pugi::xml_node node) : Element(node) {} - -TableColumnStyle TableColumn::style(const abstract::Document *, - ElementIdentifier) const { +TableColumnStyle TableColumn::style(const abstract::Document *) const { TableColumnStyle result; if (auto width = read_twips_attribute(m_node.attribute("w:w"))) { result.width = width; @@ -235,82 +196,64 @@ TableColumnStyle TableColumn::style(const abstract::Document *, return result; } -TableRow::TableRow(pugi::xml_node node) : Element(node) {} - -TableRowStyle TableRow::style(const abstract::Document *document, - ElementIdentifier) const { +TableRowStyle TableRow::style(const abstract::Document *document) const { return style_(document)->partial_table_row_style(m_node).table_row_style; } -TableCell::TableCell(pugi::xml_node node) : Element(node) {} +bool TableCell::covered(const abstract::Document *) const { return false; } -bool TableCell::covered(const abstract::Document *, ElementIdentifier) const { - return false; -} - -TableDimensions TableCell::span(const abstract::Document *, - ElementIdentifier) const { +TableDimensions TableCell::span(const abstract::Document *) const { return {1, 1}; } -ValueType TableCell::value_type(const abstract::Document *, - ElementIdentifier) const { +ValueType TableCell::value_type(const abstract::Document *) const { return ValueType::string; } -TableCellStyle TableCell::style(const abstract::Document *document, - ElementIdentifier) const { +TableCellStyle TableCell::style(const abstract::Document *document) const { return style_(document)->partial_table_cell_style(m_node).table_cell_style; } -Frame::Frame(pugi::xml_node node) : Element(node) {} - -AnchorType Frame::anchor_type(const abstract::Document *, - ElementIdentifier) const { +AnchorType Frame::anchor_type(const abstract::Document *) const { if (m_node.child("wp:inline")) { return AnchorType::as_char; } return AnchorType::as_char; // TODO default? } -std::optional Frame::x(const abstract::Document *, - ElementIdentifier) const { +std::optional Frame::x(const abstract::Document *) const { return {}; } -std::optional Frame::y(const abstract::Document *, - ElementIdentifier) const { +std::optional Frame::y(const abstract::Document *) const { return {}; } -std::optional Frame::width(const abstract::Document *, - ElementIdentifier) const { +std::optional +Frame::width(const abstract::Document *document) const { if (auto width = read_emus_attribute( - inner_node_().child("wp:extent").attribute("cx"))) { + inner_node_(document).child("wp:extent").attribute("cx"))) { return width->to_string(); } return {}; } -std::optional Frame::height(const abstract::Document *, - ElementIdentifier) const { +std::optional +Frame::height(const abstract::Document *document) const { if (auto height = read_emus_attribute( - inner_node_().child("wp:extent").attribute("cy"))) { + inner_node_(document).child("wp:extent").attribute("cy"))) { return height->to_string(); } return {}; } -std::optional Frame::z_index(const abstract::Document *, - ElementIdentifier) const { +std::optional Frame::z_index(const abstract::Document *) const { return {}; } -GraphicStyle Frame::style(const abstract::Document *, ElementIdentifier) const { - return {}; -} +GraphicStyle Frame::style(const abstract::Document *) const { return {}; } -pugi::xml_node Frame::inner_node_() const { +pugi::xml_node Frame::inner_node_(const abstract::Document *) const { if (auto anchor = m_node.child("wp:anchor")) { return anchor; } else if (auto inline_node = m_node.child("wp:inline")) { @@ -319,32 +262,27 @@ pugi::xml_node Frame::inner_node_() const { return {}; } -Image::Image(pugi::xml_node node) : Element(node) {} - -bool Image::internal(const abstract::Document *document, - ElementIdentifier elementId) const { +bool Image::internal(const abstract::Document *document) const { auto doc = document_(document); if (!doc || !doc->files()) { return false; } try { - return doc->files()->is_file(href(document, elementId)); + return doc->files()->is_file(href(document)); } catch (...) { } return false; } -std::optional Image::file(const abstract::Document *document, - ElementIdentifier elementId) const { +std::optional Image::file(const abstract::Document *document) const { auto doc = document_(document); - if (!doc || !internal(document, elementId)) { + if (!doc || !internal(document)) { return {}; } - return File(doc->files()->open(href(document, elementId))); + return File(doc->files()->open(href(document))); } -std::string Image::href(const abstract::Document *document, - ElementIdentifier) const { +std::string Image::href(const abstract::Document *document) const { if (auto ref = m_node.child("pic:pic") .child("pic:blipFill") .child("a:blip") diff --git a/src/odr/internal/ooxml/text/ooxml_text_element.hpp b/src/odr/internal/ooxml/text/ooxml_text_element.hpp index 09887f09..1b8c5299 100644 --- a/src/odr/internal/ooxml/text/ooxml_text_element.hpp +++ b/src/odr/internal/ooxml/text/ooxml_text_element.hpp @@ -19,10 +19,9 @@ class Element : public virtual common::Element { public: explicit Element(pugi::xml_node); - virtual common::ResolvedStyle partial_style(const abstract::Document *, - ElementIdentifier) const; - virtual common::ResolvedStyle intermediate_style(const abstract::Document *, - ElementIdentifier) const; + virtual common::ResolvedStyle partial_style(const abstract::Document *) const; + virtual common::ResolvedStyle + intermediate_style(const abstract::Document *) const; protected: pugi::xml_node m_node; @@ -37,184 +36,162 @@ class Element : public virtual common::Element { template class DefaultElement : public Element { public: - explicit DefaultElement(pugi::xml_node node) : Element(node) {} + using Element::Element; - [[nodiscard]] ElementType type(const abstract::Document *, - ElementIdentifier) const override { + [[nodiscard]] ElementType type(const abstract::Document *) const override { return _element_type; } }; class Root final : public Element, public abstract::TextRoot { public: - explicit Root(pugi::xml_node); + using Element::Element; - [[nodiscard]] PageLayout page_layout(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] PageLayout page_layout(const abstract::Document *) const final; - [[nodiscard]] std::pair - first_master_page(const abstract::Document *, ElementIdentifier) const final; + [[nodiscard]] abstract::Element * + first_master_page(const abstract::Document *) const final; }; class Paragraph : public Element, public abstract::Paragraph { public: - explicit Paragraph(pugi::xml_node); + using Element::Element; - common::ResolvedStyle partial_style(const abstract::Document *, - ElementIdentifier) const final; + common::ResolvedStyle partial_style(const abstract::Document *) const final; - [[nodiscard]] ParagraphStyle style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] ParagraphStyle style(const abstract::Document *) const final; - [[nodiscard]] TextStyle text_style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] TextStyle text_style(const abstract::Document *) const final; }; class Span final : public Element, public abstract::Span { public: - explicit Span(pugi::xml_node node); + using Element::Element; - common::ResolvedStyle partial_style(const abstract::Document *, - ElementIdentifier) const final; + common::ResolvedStyle partial_style(const abstract::Document *) const final; - [[nodiscard]] TextStyle style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] TextStyle style(const abstract::Document *) const final; }; class Text final : public Element, public abstract::Text { public: - static std::string text(const pugi::xml_node node); + using Element::Element; explicit Text(pugi::xml_node); Text(pugi::xml_node first, pugi::xml_node last); - [[nodiscard]] std::string content(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] std::string content(const abstract::Document *) const final; - void set_content(const abstract::Document *, ElementIdentifier, - const std::string &text) final; + void set_content(const abstract::Document *, const std::string &text) final; - [[nodiscard]] TextStyle style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] TextStyle style(const abstract::Document *) const final; private: pugi::xml_node m_last; + + static std::string text_(const pugi::xml_node node); + static pugi::xml_node last_(const abstract::Document *); }; class Link final : public Element, public abstract::Link { public: - explicit Link(pugi::xml_node); + using Element::Element; - [[nodiscard]] std::string href(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] std::string href(const abstract::Document *) const final; }; class Bookmark final : public Element, public abstract::Bookmark { public: - explicit Bookmark(pugi::xml_node); + using Element::Element; - [[nodiscard]] std::string name(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] std::string name(const abstract::Document *) const final; }; class List final : public Element { public: - explicit List(pugi::xml_node); + using Element::Element; - [[nodiscard]] ElementType type(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] ElementType type(const abstract::Document *) const final; }; class ListItem final : public Element, public abstract::ListItem { public: - explicit ListItem(pugi::xml_node); + using Element::Element; - [[nodiscard]] TextStyle style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] TextStyle style(const abstract::Document *) const final; }; class Table final : public Element, public common::Table { public: - explicit Table(pugi::xml_node); + using Element::Element; - [[nodiscard]] TableDimensions dimensions(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] TableDimensions + dimensions(const abstract::Document *) const final; - [[nodiscard]] TableStyle style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] TableStyle style(const abstract::Document *) const final; }; class TableColumn final : public Element, public abstract::TableColumn { public: - explicit TableColumn(pugi::xml_node); + using Element::Element; - [[nodiscard]] TableColumnStyle style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] TableColumnStyle style(const abstract::Document *) const final; }; class TableRow final : public Element, public abstract::TableRow { public: - explicit TableRow(pugi::xml_node); + using Element::Element; - [[nodiscard]] TableRowStyle style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] TableRowStyle style(const abstract::Document *) const final; }; class TableCell final : public Element, public abstract::TableCell { public: - explicit TableCell(pugi::xml_node); + using Element::Element; - [[nodiscard]] bool covered(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] bool covered(const abstract::Document *) const final; - [[nodiscard]] TableDimensions span(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] TableDimensions span(const abstract::Document *) const final; - [[nodiscard]] ValueType value_type(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] ValueType value_type(const abstract::Document *) const final; - [[nodiscard]] TableCellStyle style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] TableCellStyle style(const abstract::Document *) const final; }; class Frame final : public Element, public abstract::Frame { public: - explicit Frame(pugi::xml_node); + using Element::Element; - [[nodiscard]] AnchorType anchor_type(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] AnchorType anchor_type(const abstract::Document *) const final; - [[nodiscard]] std::optional x(const abstract::Document *, - ElementIdentifier) const final; - [[nodiscard]] std::optional y(const abstract::Document *, - ElementIdentifier) const final; - [[nodiscard]] std::optional width(const abstract::Document *, - ElementIdentifier) const final; [[nodiscard]] std::optional - height(const abstract::Document *, ElementIdentifier) const final; + x(const abstract::Document *) const final; + [[nodiscard]] std::optional + y(const abstract::Document *) const final; + [[nodiscard]] std::optional + width(const abstract::Document *) const final; + [[nodiscard]] std::optional + height(const abstract::Document *) const final; [[nodiscard]] std::optional - z_index(const abstract::Document *, ElementIdentifier) const final; + z_index(const abstract::Document *) const final; - [[nodiscard]] GraphicStyle style(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] GraphicStyle style(const abstract::Document *) const final; private: - [[nodiscard]] pugi::xml_node inner_node_() const; + [[nodiscard]] pugi::xml_node inner_node_(const abstract::Document *) const; }; class Image final : public Element, public abstract::Image { public: - explicit Image(pugi::xml_node); + using Element::Element; - [[nodiscard]] bool internal(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] bool internal(const abstract::Document *) const final; - [[nodiscard]] std::optional file(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] std::optional + file(const abstract::Document *) const final; - [[nodiscard]] std::string href(const abstract::Document *, - ElementIdentifier) const final; + [[nodiscard]] std::string href(const abstract::Document *) const final; }; } // namespace odr::internal::ooxml::text diff --git a/src/odr/internal/ooxml/text/ooxml_text_parser.cpp b/src/odr/internal/ooxml/text/ooxml_text_parser.cpp index f13a9220..19f3b373 100644 --- a/src/odr/internal/ooxml/text/ooxml_text_parser.cpp +++ b/src/odr/internal/ooxml/text/ooxml_text_parser.cpp @@ -1,47 +1,47 @@ -#include -#include #include + +#include +#include + +#include #include namespace odr::internal::ooxml::text { namespace { -template -std::tuple -parse_element_tree(pugi::xml_node node, - std::vector> &store); +template +std::tuple parse_element_tree(Document &document, + pugi::xml_node node); std::tuple -parse_any_element_tree(pugi::xml_node node, - std::vector> &store); +parse_any_element_tree(Document &document, pugi::xml_node node); -void parse_element_children(Element *element, pugi::xml_node node, - std::vector> &store) { +void parse_element_children(Document &document, Element *element, + pugi::xml_node node) { for (auto child_node = node.first_child(); child_node;) { - auto [child, next_sibling] = parse_any_element_tree(child_node, store); + auto [child, next_sibling] = parse_any_element_tree(document, child_node); if (child == nullptr) { child_node = child_node.next_sibling(); } else { - element->init_append_child(child); + element->append_child_(child); child_node = next_sibling; } } } -template -std::tuple -parse_element_tree(pugi::xml_node node, - std::vector> &store) { +template +std::tuple parse_element_tree(Document &document, + pugi::xml_node node) { if (!node) { return std::make_tuple(nullptr, pugi::xml_node()); } - auto element_unique = std::make_unique(node); + auto element_unique = std::make_unique(node); auto element = element_unique.get(); - store.push_back(std::move(element_unique)); + document.register_element_(std::move(element_unique)); - parse_element_children(element, node, store); + parse_element_children(document, element, node); return std::make_tuple(element, node.next_sibling()); } @@ -65,8 +65,7 @@ bool is_text_node(pugi::xml_node node) { template <> std::tuple -parse_element_tree(pugi::xml_node first, - std::vector> &store) { +parse_element_tree(Document &document, pugi::xml_node first) { if (!first) { return std::make_tuple(nullptr, pugi::xml_node()); } @@ -77,7 +76,7 @@ parse_element_tree(pugi::xml_node first, auto element_unique = std::make_unique(first, last); auto element = element_unique.get(); - store.push_back(std::move(element_unique)); + document.register_element_(std::move(element_unique)); return std::make_tuple(element, last.next_sibling()); } @@ -96,15 +95,14 @@ std::int32_t list_level(pugi::xml_node node) { template <> std::tuple -parse_element_tree(pugi::xml_node first, - std::vector> &store) { +parse_element_tree(Document &document, pugi::xml_node first) { if (!first) { return std::make_tuple(nullptr, pugi::xml_node()); } auto list_unique = std::make_unique(first); auto list = list_unique.get(); - store.push_back(std::move(list_unique)); + document.register_element_(std::move(list_unique)); pugi::xml_node node = first; for (; is_list_item(node); node = node.next_sibling()) { @@ -122,22 +120,22 @@ parse_element_tree(pugi::xml_node first, auto nested_list_unique = std::make_unique(node); auto nested_list = nested_list_unique.get(); - store.push_back(std::move(nested_list_unique)); + document.register_element_(std::move(nested_list_unique)); // list_item->init_append_child(nested_list); - base->init_append_child(nested_list); + base->append_child_(nested_list); base = nested_list; } auto list_item_unique = std::make_unique(node); auto list_item = list_item_unique.get(); - store.push_back(std::move(list_item_unique)); + document.register_element_(std::move(list_item_unique)); - base->init_append_child(list_item); + base->append_child_(list_item); - auto [element, _] = parse_element_tree(node, store); - list_item->init_append_child(element); + auto [element, _] = parse_element_tree(document, node); + list_item->append_child_(element); } return std::make_tuple(list, node); @@ -145,19 +143,18 @@ parse_element_tree(pugi::xml_node first, template <> std::tuple -parse_element_tree(pugi::xml_node node, - std::vector> &store) { +parse_element_tree(Document &document, pugi::xml_node node) { if (!node) { return std::make_tuple(nullptr, pugi::xml_node()); } auto table_row_unique = std::make_unique(node); auto table_row = table_row_unique.get(); - store.push_back(std::move(table_row_unique)); + document.register_element_(std::move(table_row_unique)); for (auto cell_node : node.children("w:tc")) { - auto [cell, _] = parse_element_tree(cell_node, store); - table_row->init_append_child(cell); + auto [cell, _] = parse_element_tree(document, cell_node); + table_row->append_child_(cell); } return std::make_tuple(table_row, node.next_sibling()); @@ -165,34 +162,32 @@ parse_element_tree(pugi::xml_node node, template <> std::tuple -parse_element_tree(pugi::xml_node node, - std::vector> &store) { +parse_element_tree
(Document &document, pugi::xml_node node) { if (!node) { return std::make_tuple(nullptr, pugi::xml_node()); } auto table_unique = std::make_unique
(node); auto table = table_unique.get(); - store.push_back(std::move(table_unique)); + document.register_element_(std::move(table_unique)); for (auto column_node : node.child("w:tblGrid").children("w:gridCol")) { - auto [column, _] = parse_element_tree(column_node, store); - table->init_append_column(column); + auto [column, _] = parse_element_tree(document, column_node); + table->append_column_(column); } for (auto row_node : node.children("w:tr")) { - auto [row, _] = parse_element_tree(row_node, store); - table->init_append_row(row); + auto [row, _] = parse_element_tree(document, row_node); + table->append_row_(row); } return std::make_tuple(table, node.next_sibling()); } std::tuple -parse_any_element_tree(pugi::xml_node node, - std::vector> &store) { +parse_any_element_tree(Document &document, pugi::xml_node node) { using Parser = std::function( - pugi::xml_node node, std::vector> & store)>; + Document & document, pugi::xml_node node)>; using Group = DefaultElement; @@ -218,12 +213,12 @@ parse_any_element_tree(pugi::xml_node node, }; if (is_list_item(node)) { - return parse_element_tree(node, store); + return parse_element_tree(document, node); } if (auto constructor_it = parser_table.find(node.name()); constructor_it != std::end(parser_table)) { - return constructor_it->second(node, store); + return constructor_it->second(document, node); } return std::make_tuple(nullptr, pugi::xml_node()); @@ -235,11 +230,9 @@ parse_any_element_tree(pugi::xml_node node, namespace odr::internal::ooxml { -std::tuple>> -text::parse_tree(pugi::xml_node node) { - std::vector> store; - auto [root, _] = parse_any_element_tree(node, store); - return std::make_tuple(root, std::move(store)); +text::Element *text::parse_tree(Document &document, pugi::xml_node node) { + auto [root, _] = parse_any_element_tree(document, node); + return root; } } // namespace odr::internal::ooxml diff --git a/src/odr/internal/ooxml/text/ooxml_text_parser.hpp b/src/odr/internal/ooxml/text/ooxml_text_parser.hpp index 55f5e1b0..fb4d3742 100644 --- a/src/odr/internal/ooxml/text/ooxml_text_parser.hpp +++ b/src/odr/internal/ooxml/text/ooxml_text_parser.hpp @@ -2,15 +2,16 @@ #define ODR_INTERNAL_OOXML_TEXT_PARSER_HPP #include -#include #include #include +#include + namespace odr::internal::ooxml::text { +class Document; class Element; -std::tuple>> -parse_tree(pugi::xml_node node); +Element *parse_tree(Document &document, pugi::xml_node node); } // namespace odr::internal::ooxml::text