Craft Language Parser
Two collaborating layers convert a .craft file into a loom node tree
(see About Docraft): a generic, engine-agnostic XML parser
(docraft::craft), and a loom-specific bridge that builds
DocraftLoomNodes from its output.
DocraftLoomCraftLanguageParser
The top-level driver — the only piece that understands <Document>
structure itself (<Header>/<Body>/<Footer>/<Settings>/
<Metadata>). Parses each section with DocraftCraftLanguageParser,
builds it into loom nodes via DocraftLoomTreeBuilder, and wraps the
result in a DocraftLoomPdfCreator (see Orchestrator) retrievable via
edit_creator().
-
class DocraftLoomCraftLanguageParser
Top-level driver that turns a full Craft-language document (
<Document>with a required<Body>and optional<Header>/<Footer>siblings) into a fully wireddocraft::loom::DocraftLoomPdfCreator.This is the only component that needs to know about the
<Document>structure itself:docraft::craft::DocraftCraftLanguageParserhas no per-tag registration forDocument/Settings/Metadata/Foreach/NewPage, so this class walks the<Document>element directly via pugixml, picks out itsHeader/Body/Footerchildren (each parsed generically from that point on viaDocraftCraftLanguageParser::parse_node), and applies a<Settings>sibling’s<Page>/<SectionRatios>/<Fonts>sub-tags (if present) to the resulting creator (each<Fonts><Font>variant is registered viaDocraftLoomPdfCreator:: register_font()). A<Metadata>sibling’s simple string subtags (DocumentTitle/Author/Creator/Producer/Subject/Keywords) are applied viaDocraftLoomPdfCreator::set_metadata();CreationDate/ModificationDate/Trapped/GtsPdfx/AutoKeywordsare still unrecognized (silently skipped).${variable}/${data(...)}templating (Text/Title/Subtitle content, Image src,<Foreach>’s ownmodel) is resolved by thedocraft::loom::craft::DocraftLoomTreeBuilderthis class drives internally, using whatever engine was given via set_template_engine().Public Functions
-
DocraftLoomCraftLanguageParser() = default
-
~DocraftLoomCraftLanguageParser() = default
Sets the template engine used to resolve
${variable}/${data(...)}expressions during the next parse()/load_from_file() call.If never called, an empty engine is used (no registered variables —
${...}expressions pass through unresolved).
-
void parse(const std::string &xml_string)
Parses a full Craft-language document from a string and builds/stores the resulting
DocraftLoomPdfCreator, retrievable viaedit_creator().- Parameters:
xml_string – XML source as string.
- Throws:
docraft::exception::DataFormatException – on malformed XML or a missing required
<Body>element.
-
void load_from_file(const std::filesystem::path &path)
Loads and parses a full Craft-language document from file, same as
parse().- Parameters:
path – Path to the
.craftXML file.
-
std::shared_ptr<loom::DocraftLoomPdfCreator> edit_creator()
Returns the fully-wired creator built by the last
parse()/load_from_file()call.Mirrors
DocraftLoomNode::edit_layout_box()’s non-const-accessor-for-mutable-access convention.
-
DocraftLoomCraftLanguageParser() = default
DocraftLoomTreeBuilder
The only component depending on both docraft::craft and
docraft::loom — converts a generic DocraftParsedElement tree into a
typed DocraftLoomNode tree, resolving ${...}/<Foreach> templating
per node as it builds (see Templating).
-
class DocraftLoomTreeBuilder : public docraft::loom::craft::DocraftLoomTableHandlerContext
Translates a generic
docraft::craft::DocraftParsedElementtree (produced bydocraft::craft::DocraftCraftLanguageParser, which has zero knowledge of loom) into an actual tree ofdocraft::loom::nodes::DocraftLoomNode.This is the only component depending on both
docraft::craftanddocraft::loom— keeping the craft parser itself fully engine-agnostic (see the plan’s “Craft parser: generic + a separate loom builder layer”).Public Functions
Constructs the builder.
- Parameters:
template_engine – Resolves
${variable}/${data("field")}in Text/Title/ Subtitle content, Image src, and<Foreach>’s ownmodelattribute. Defaults to a fresh, empty engine (no variables registered) if not given, so${...}expressions simply pass through unresolved rather than requiring a caller to always supply one.
Builds a loom node (and, recursively, its subtree) from a parsed element.
- Parameters:
element – The parsed element to translate. May be null (returns nullptr).
- Throws:
docraft::exception::DataFormatException – if
element->tag_nameis not a tag this builder recognizes.- Returns:
The built node, or nullptr if
elementis null orelement->common.visibleis explicitlyfalse(the subtree is simply not constructed, per the plan’s “visible is resolved by the builder” design).
-
void set_default_font_family(const std::string &font_family)
Sets the font family applied to Text/Title/Subtitle/PageNumber/table-cell nodes built afterwards that don’t carry their own
font_nameattribute (from<Settings><Fonts default="...">).Unset by default, in which case such nodes keep DocraftLoomText’s own hardcoded fallback.
DocraftCraftLanguageParser
Generic, engine-agnostic XML parser (pugixml-based). Holds one
IDocraftParser per recognized tag and produces a tag-agnostic
DocraftParsedElement tree with zero knowledge of layout or rendering.
-
class DocraftCraftLanguageParser
Parses the Craft Language into a generic
DocraftParsedElementtree.Fully engine-agnostic: zero dependency on any rendering/layout engine (in particular, no
docraft::loominclude anywhere). For each XML element, the registeredIDocraftParserproduces the tag-specific payload, common attributes are parsed once generically, and children are recursed into — except<Table>, whose row/cell structure is parsed entirely insideDocraftTableParseritself (seeParsedTableData), so it is not recursed into generically.Turning a parsed tree into actual loom nodes is the job of the separate
docraft::loom::craft::DocraftLoomTreeBuilder, not this class.Public Functions
-
DocraftCraftLanguageParser()
Constructs a parser and registers the default tag parsers.
-
~DocraftCraftLanguageParser() = default
-
DocraftCraftLanguageParser(const DocraftCraftLanguageParser&) = delete
-
DocraftCraftLanguageParser &operator=(const DocraftCraftLanguageParser&) = delete
-
std::shared_ptr<DocraftParsedElement> parse(const std::string &craft_language_source)
Parses craft language source (a single root element) as a string.
- Parameters:
craft_language_source – XML source as string.
- Returns:
The parsed tree rooted at the document’s root element.
-
std::shared_ptr<DocraftParsedElement> load_from_file(const std::string &file_path)
Loads and parses craft language source from file.
- Parameters:
file_path – Path to XML file.
- Returns:
The parsed tree rooted at the document’s root element.
-
std::shared_ptr<DocraftParsedElement> parse_node(const pugi::xml_node &xml_node)
Parses a single XML element (and, generically, its subtree) into a
DocraftParsedElement.- Parameters:
xml_node – XML node.
- Throws:
docraft::exception::DataFormatException – if no parser is registered for the element’s tag name.
docraft::exception::InvalidInputException – on structurally invalid nesting (e.g. a Text-like tag containing another Text-like child, or a non-Text child of a List).
- Returns:
The parsed element.
-
DocraftCraftLanguageParser()
IDocraftParser
Interface for single-tag parsers.
-
class IDocraftParser
Interface for Craft language tag parsers.
Implementations translate a single XML element into a tag-specific, plain data-transfer struct (e.g.
ParsedRectangleData), returned type-erased viastd::any. This interface has no dependency on any rendering/layout engine — common attributes (x/y/width/height/…) and child recursion are handled once, generically, byDocraftCraftLanguageParseritself, not by individual parsers.Subclassed by docraft::craft::parser::DocraftBlackLineParser, docraft::craft::parser::DocraftChartParser, docraft::craft::parser::DocraftCircleParser, docraft::craft::parser::DocraftCurveLineParser, docraft::craft::parser::DocraftForeachParser, docraft::craft::parser::DocraftImageParser, docraft::craft::parser::DocraftLayoutParser, docraft::craft::parser::DocraftLineParser, docraft::craft::parser::DocraftListParser, docraft::craft::parser::DocraftNewPageParser, docraft::craft::parser::DocraftPageNumberParser, docraft::craft::parser::DocraftParagraphParser, docraft::craft::parser::DocraftPolygonParser, docraft::craft::parser::DocraftRectangleParser, docraft::craft::parser::DocraftSectionParser, docraft::craft::parser::DocraftSeriesParser, docraft::craft::parser::DocraftTableParser, docraft::craft::parser::DocraftTextParser, docraft::craft::parser::DocraftTriangleParser, docraft::craft::parser::DocraftUListParser
Public Functions
-
virtual ~IDocraftParser() = default
Virtual destructor.
-
virtual std::any parse(const pugi::xml_node &craft_language_source) = 0
Parses an XML element into its tag-specific payload.
- Parameters:
craft_language_source – XML node to parse.
- Returns:
Type-erased
Parsed<Tag>Datastruct.
-
virtual std::vector<std::string_view> accepted_attributes() const = 0
Every attribute name this parser reads, beyond the common set.
DocraftCraftLanguageParserrejects any attribute on an element that is neither common nor listed here, so that a name the parser would silently drop is reported instead of quietly having no effect.Pure virtual on purpose: a new parser that forgets to declare its names fails to compile, where a default of “accept nothing” or “accept everything” would fail at runtime or not at all. Keep the list next to
parse()— adding an attribute there without adding it here makes the parser’s own tests fail.
-
virtual ~IDocraftParser() = default
Element Parsers
Each parser translates one XML tag into a Parsed<Tag>Data payload
attached to the corresponding DocraftParsedElement.
-
class DocraftTextParser : public docraft::craft::IDocraftParser
Parser for
<Text>,<Title>and<Subtitle>elements (all produce aParsedTextData, differing only in the tag-based defaults applied).Public Functions
-
virtual std::any parse(const pugi::xml_node &craft_language_source) override
Parses a text-like XML node.
- Parameters:
craft_language_source – XML node.
- Returns:
ParsedTextData.
-
virtual std::vector<std::string_view> accepted_attributes() const override
Attribute names this parser reads, beyond the common set.
-
virtual std::any parse(const pugi::xml_node &craft_language_source) override
-
class DocraftImageParser : public docraft::craft::IDocraftParser
Parser for image nodes.
Public Functions
-
virtual std::any parse(const pugi::xml_node &craft_language_source) override
Parses an image XML node.
- Parameters:
craft_language_source – XML node.
- Throws:
docraft::exception::InvalidInputException – if both
srcanddataare present, or if base64datais missing/invalid dimensions.- Returns:
ParsedImageData.
-
virtual std::vector<std::string_view> accepted_attributes() const override
Attribute names this parser reads, beyond the common set.
-
virtual std::any parse(const pugi::xml_node &craft_language_source) override
-
class DocraftRectangleParser : public docraft::craft::IDocraftParser
Parser for rectangle nodes.
Public Functions
-
virtual std::any parse(const pugi::xml_node &craft_language_source) override
Parses a rectangle XML node into a ParsedRectangleData.
- Parameters:
craft_language_source – XML node.
- Returns:
ParsedRectangleData.
-
virtual std::vector<std::string_view> accepted_attributes() const override
Attribute names this parser reads, beyond the common set.
-
virtual std::any parse(const pugi::xml_node &craft_language_source) override
-
class DocraftCircleParser : public docraft::craft::IDocraftParser
Parser for circle nodes.
Public Functions
-
virtual std::any parse(const pugi::xml_node &craft_language_source) override
Parses a circle XML node.
- Parameters:
craft_language_source – XML node.
- Returns:
ParsedCircleData.
-
virtual std::vector<std::string_view> accepted_attributes() const override
Attribute names this parser reads, beyond the common set.
-
virtual std::any parse(const pugi::xml_node &craft_language_source) override
-
class DocraftTriangleParser : public docraft::craft::IDocraftParser
Parser for triangle nodes.
Public Functions
-
virtual std::any parse(const pugi::xml_node &craft_language_source) override
Parses a triangle XML node.
- Parameters:
craft_language_source – XML node.
- Throws:
docraft::exception::InvalidInputException – if
pointsis present but does not have exactly 3 entries.- Returns:
ParsedTriangleData.
-
virtual std::vector<std::string_view> accepted_attributes() const override
Attribute names this parser reads, beyond the common set.
-
virtual std::any parse(const pugi::xml_node &craft_language_source) override
-
class DocraftLineParser : public docraft::craft::IDocraftParser
Parser for line nodes.
Public Functions
-
virtual std::any parse(const pugi::xml_node &craft_language_source) override
Parses a line XML node.
- Parameters:
craft_language_source – XML node.
- Returns:
ParsedLineData.
-
virtual std::vector<std::string_view> accepted_attributes() const override
Attribute names this parser reads, beyond the common set.
-
virtual std::any parse(const pugi::xml_node &craft_language_source) override
-
class DocraftPolygonParser : public docraft::craft::IDocraftParser
Parser for polygon nodes.
Public Functions
-
virtual std::any parse(const pugi::xml_node &craft_language_source) override
Parses a polygon XML node.
- Parameters:
craft_language_source – XML node.
- Returns:
ParsedPolygonData.
-
virtual std::vector<std::string_view> accepted_attributes() const override
Attribute names this parser reads, beyond the common set.
-
virtual std::any parse(const pugi::xml_node &craft_language_source) override
-
class DocraftTableParser : public docraft::craft::IDocraftParser
Parser for table nodes.
Public Functions
-
virtual std::any parse(const pugi::xml_node &craft_language_source) override
Parses a table XML node.
- Parameters:
craft_language_source – XML node.
- Returns:
ParsedTableData.
-
virtual std::vector<std::string_view> accepted_attributes() const override
Attribute names this parser reads, beyond the common set.
-
virtual std::any parse(const pugi::xml_node &craft_language_source) override
-
class DocraftListParser : public docraft::craft::IDocraftParser
Parser for ordered list nodes.
Public Functions
-
virtual std::any parse(const pugi::xml_node &craft_language_source) override
Parses a list XML node.
- Parameters:
craft_language_source – XML node.
- Returns:
ParsedListDatawith kind = kOrdered.
-
virtual std::vector<std::string_view> accepted_attributes() const override
Attribute names this parser reads, beyond the common set.
-
virtual std::any parse(const pugi::xml_node &craft_language_source) override
-
class DocraftUListParser : public docraft::craft::IDocraftParser
Parser for unordered list nodes.
Public Functions
-
virtual std::any parse(const pugi::xml_node &craft_language_source) override
Parses an unordered list XML node.
- Parameters:
craft_language_source – XML node.
- Returns:
ParsedListDatawith kind = kUnordered.
-
virtual std::vector<std::string_view> accepted_attributes() const override
Attribute names this parser reads, beyond the common set.
-
virtual std::any parse(const pugi::xml_node &craft_language_source) override
-
class DocraftLayoutParser : public docraft::craft::IDocraftParser
Parser for layout nodes.
Public Functions
-
virtual std::any parse(const pugi::xml_node &craft_language_source) override
Parses a layout XML node.
- Parameters:
craft_language_source – XML node.
- Returns:
ParsedLayoutData.
-
virtual std::vector<std::string_view> accepted_attributes() const override
Attribute names this parser reads, beyond the common set.
-
virtual std::any parse(const pugi::xml_node &craft_language_source) override
-
class DocraftParagraphParser : public docraft::craft::IDocraftParser
Parser for paragraph nodes.
Public Functions
-
virtual std::any parse(const pugi::xml_node &craft_language_source) override
Parses a paragraph XML node.
- Parameters:
craft_language_source – XML node.
- Returns:
ParsedParagraphData.
-
virtual std::vector<std::string_view> accepted_attributes() const override
Attribute names this parser reads, beyond the common set.
-
virtual std::any parse(const pugi::xml_node &craft_language_source) override
-
class DocraftBlackLineParser : public docraft::craft::IDocraftParser
Parser for blank line nodes.
Public Functions
-
virtual std::any parse(const pugi::xml_node &craft_language_source) override
Parses a blank line XML node.
- Parameters:
craft_language_source – XML node.
- Returns:
ParsedBlankLineData.
-
virtual std::vector<std::string_view> accepted_attributes() const override
Attribute names this parser reads, beyond the common set.
-
virtual std::any parse(const pugi::xml_node &craft_language_source) override
-
class DocraftNewPageParser : public docraft::craft::IDocraftParser
Parser for forced-page-break nodes.
Public Functions
-
virtual std::any parse(const pugi::xml_node &craft_language_source) override
Parses a
<NewPage>XML node.- Parameters:
craft_language_source – XML node.
- Returns:
ParsedNewPageData.
-
virtual std::vector<std::string_view> accepted_attributes() const override
Attribute names this parser reads, beyond the common set.
-
virtual std::any parse(const pugi::xml_node &craft_language_source) override
-
class DocraftPageNumberParser : public docraft::craft::IDocraftParser
Parser for page number nodes.
Public Functions
-
virtual std::any parse(const pugi::xml_node &craft_language_source) override
Parses a page number XML node.
- Parameters:
craft_language_source – XML node.
- Returns:
ParsedPageNumberData.
-
virtual std::vector<std::string_view> accepted_attributes() const override
Attribute names this parser reads, beyond the common set.
-
virtual std::any parse(const pugi::xml_node &craft_language_source) override
-
class DocraftSectionParser : public docraft::craft::IDocraftParser
Parser for
<Header>,<Body>and<Footer>elements (all produce aParsedSectionData— there is no tag-based default distinction between them, unlikeText/Title/Subtitle).Public Functions
-
virtual std::any parse(const pugi::xml_node &craft_language_source) override
Parses a section-like XML node.
- Parameters:
craft_language_source – XML node.
- Returns:
ParsedSectionData.
-
virtual std::vector<std::string_view> accepted_attributes() const override
Attribute names this parser reads, beyond the common set.
-
virtual std::any parse(const pugi::xml_node &craft_language_source) override
Note: <Header>/<Body>/<Footer> all parse through this single
DocraftSectionParser (producing ParsedSectionData) rather than one
class per tag; <Settings>/<Metadata> are not tag parsers at all —
they’re read directly by DocraftLoomCraftLanguageParser above.
-
class DocraftForeachParser : public docraft::craft::IDocraftParser
Parser for
<Foreach>elements.Public Functions
-
virtual std::any parse(const pugi::xml_node &craft_language_source) override
Parses a
<Foreach>XML node.- Parameters:
craft_language_source – XML node.
- Throws:
docraft::exception::InvalidInputException – if both or neither of
model/nare present, or ifnis negative.- Returns:
ParsedForeachData.
-
virtual std::vector<std::string_view> accepted_attributes() const override
Attribute names this parser reads, beyond the common set.
-
virtual std::any parse(const pugi::xml_node &craft_language_source) override