Small html cleanup

This commit is contained in:
James Grogan 2022-12-01 11:49:57 +00:00
parent c102ebb6da
commit 31b479e9f6
27 changed files with 330 additions and 252 deletions

View file

@ -8,5 +8,5 @@ target_include_directories(console PUBLIC
"${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}"
) )
set_property(TARGET console PROPERTY FOLDER src) set_property(TARGET console PROPERTY FOLDER src)
target_link_libraries(console PUBLIC core audio network database web graphics) target_link_libraries(console PUBLIC core audio network database web graphics publishing)
set_target_properties( console PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON ) set_target_properties( console PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON )

View file

@ -22,6 +22,7 @@ list(APPEND publishing_LIB_INCLUDES
pdf/PdfStream.cpp pdf/PdfStream.cpp
pdf/PdfXRefTable.cpp pdf/PdfXRefTable.cpp
pdf/PdfWriter.cpp pdf/PdfWriter.cpp
DocumentConverter.cpp
) )
add_library(publishing SHARED ${publishing_LIB_INCLUDES} ${publishing_INCLUDES} ${publishing_HEADERS}) add_library(publishing SHARED ${publishing_LIB_INCLUDES} ${publishing_INCLUDES} ${publishing_HEADERS})
@ -31,6 +32,6 @@ target_include_directories(publishing PUBLIC
"${CMAKE_CURRENT_SOURCE_DIR}/pdf" "${CMAKE_CURRENT_SOURCE_DIR}/pdf"
) )
set_target_properties( publishing PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON ) set_target_properties( publishing PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON )
target_link_libraries( publishing PUBLIC core) target_link_libraries( publishing PUBLIC core web)
set_property(TARGET publishing PROPERTY FOLDER src) set_property(TARGET publishing PROPERTY FOLDER src)

View file

@ -67,7 +67,7 @@ void DocumentConverter::markdownToHtml(File* input, File* output)
auto html_document = parser.getHtml(); auto html_document = parser.getHtml();
HtmlWriter writer; HtmlWriter writer;
std::string html_string = writer.ToString(html_document); std::string html_string = writer.toString(html_document.get());
output->open(File::AccessMode::Write); output->open(File::AccessMode::Write);
*(output->getOutHandle()) << html_string; *(output->getOutHandle()) << html_string;

View file

@ -17,7 +17,7 @@ list(APPEND web_LIB_INCLUDES
html/HtmlElement.cpp html/HtmlElement.cpp
html/elements/HtmlHeadElement.cpp html/elements/HtmlHeadElement.cpp
html/elements/HtmlBodyElement.cpp html/elements/HtmlBodyElement.cpp
DocumentConverter.cpp) )
# add the executable # add the executable
add_library(web SHARED ${web_LIB_INCLUDES}) add_library(web SHARED ${web_LIB_INCLUDES})

View file

@ -3,20 +3,23 @@
#include "HtmlHeadElement.h" #include "HtmlHeadElement.h"
#include "HtmlBodyElement.h" #include "HtmlBodyElement.h"
#include <iostream>
HtmlDocument::HtmlDocument() HtmlDocument::HtmlDocument()
: XmlDocument() : XmlDocument()
{ {
auto root = XmlElement::Create("html"); auto root = XmlElement::Create("html");
SetRoot(std::move(root));
setRoot(std::move(root));
auto header = std::make_unique<HtmlHeadElement>(); auto header = std::make_unique<HtmlHeadElement>();
GetRoot()->AddChild(std::move(header)); getRoot()->addChild(std::move(header));
auto body = std::make_unique<HtmlBodyElement>(); auto body = std::make_unique<HtmlBodyElement>();
GetRoot()->AddChild(std::move(body)); getRoot()->addChild(std::move(body));
} }
std::shared_ptr<HtmlDocument> HtmlDocument::Create() std::unique_ptr<HtmlDocument> HtmlDocument::Create()
{ {
return std::make_shared<HtmlDocument>(); return std::make_unique<HtmlDocument>();
} }

View file

@ -1,15 +1,17 @@
#pragma once #pragma once
#include <memory>
#include "XmlDocument.h" #include "XmlDocument.h"
#include <memory>
class HtmlDocument : public XmlDocument class HtmlDocument : public XmlDocument
{ {
public: public:
HtmlDocument(); HtmlDocument();
static std::shared_ptr<HtmlDocument> Create(); virtual ~HtmlDocument() = default;
static std::unique_ptr<HtmlDocument> Create();
}; };
using HtmlDocumentPtr = std::shared_ptr<HtmlDocument>; using HtmlDocumentPtr = std::unique_ptr<HtmlDocument>;

View file

@ -1,23 +1,29 @@
#include "HtmlWriter.h" #include "HtmlWriter.h"
#include "HtmlDocument.h"
#include "XmlElement.h"
#include "XmlAttribute.h"
#include <iostream>
HtmlWriter::HtmlWriter() HtmlWriter::HtmlWriter()
{ {
} }
std::string HtmlWriter::ToString(XmlElement* element, unsigned depth) std::string HtmlWriter::toString(XmlElement* element, unsigned depth)
{ {
const auto prefix = std::string(2*depth, ' '); const auto prefix = std::string(2*depth, ' ');
auto content = prefix + "<" + element->GetTagName(); auto content = prefix + "<" + element->getTagName();
for (std::size_t idx=0; idx< element->GetNumAttributes(); idx++) for (std::size_t idx=0; idx< element->getNumAttributes(); idx++)
{ {
auto attribute = element->GetAttribute(idx); auto attribute = element->getAttribute(idx);
content += " " + attribute->GetName() + "=\"" + attribute->GetValue() + "\""; content += " " + attribute->getName() + "=\"" + attribute->getValue() + "\"";
} }
const auto num_children = element->GetNumChildren(); const auto num_children = element->getNumChildren();
if (num_children == 0 && element->GetText().empty()) if (num_children == 0 && element->getText().empty())
{ {
content += "/>\n"; content += "/>\n";
return content; return content;
@ -27,36 +33,35 @@ std::string HtmlWriter::ToString(XmlElement* element, unsigned depth)
content += ">"; content += ">";
} }
if (!element->GetText().empty()) if (!element->getText().empty())
{ {
content += element->GetText(); content += element->getText();
} }
if (num_children>0) if (num_children>0)
{ {
content += "\n"; content += "\n";
} }
for (std::size_t idx=0; idx< element->GetNumChildren(); idx++) for (std::size_t idx=0; idx< element->getNumChildren(); idx++)
{ {
auto child = element->GetChild(idx); auto child = element->getChild(idx);
content += ToString(child, depth+1); content += toString(child, depth+1);
} }
if (num_children>0) if (num_children>0)
{ {
content += prefix; content += prefix;
} }
content += "</" + element->GetTagName() + ">\n"; content += "</" + element->getTagName() + ">\n";
return content; return content;
} }
std::string HtmlWriter::ToString(HtmlDocumentPtr document) std::string HtmlWriter::toString(HtmlDocument* document)
{ {
std::string content = "<!DOCTYPE html>\n"; std::string content = "<!DOCTYPE html>\n";
if (auto root = document->getRoot())
if (auto root = document->GetRoot())
{ {
content += ToString(root); content += toString(root);
} }
return content; return content;
} }

View file

@ -1,15 +1,17 @@
#pragma once #pragma once
#include "HtmlDocument.h" #include <string>
class HtmlDocument;
class XmlElement;
class HtmlWriter class HtmlWriter
{ {
public: public:
HtmlWriter(); HtmlWriter();
std::string ToString(HtmlDocumentPtr document); std::string toString(HtmlDocument* document);
private: private:
std::string ToString(XmlElement* element, unsigned depth=0); std::string toString(XmlElement* element, unsigned depth=0);
}; };

View file

@ -26,5 +26,5 @@ void MarkdownParser::run(const std::string& content)
HtmlDocumentPtr MarkdownParser::getHtml() HtmlDocumentPtr MarkdownParser::getHtml()
{ {
return mHtmlDocument; return std::move(mHtmlDocument);
} }

View file

@ -1,32 +1,42 @@
#include "XmlDocument.h" #include "XmlDocument.h"
#include "XmlProlog.h"
#include "XmlElement.h"
#include <iostream>
XmlDocument::XmlDocument() XmlDocument::XmlDocument()
:mProlog(XmlProlog::Create("xml")) :mProlog(XmlProlog::Create("xml"))
{ {
} }
XmlDocumentUPtr XmlDocument::Create() XmlDocument::~XmlDocument()
{
}
XmlDocumentPtr XmlDocument::Create()
{ {
return std::make_unique<XmlDocument>(); return std::make_unique<XmlDocument>();
} }
void XmlDocument::SetProlog(XmlPrologUPtr prolog) void XmlDocument::setProlog(XmlPrologPtr prolog)
{ {
mProlog = std::move(prolog); mProlog = std::move(prolog);
} }
XmlProlog* XmlDocument::GetProlog() const XmlProlog* XmlDocument::getProlog() const
{ {
return mProlog.get(); return mProlog.get();
} }
void XmlDocument::SetRoot(XmlElementUPtr root) void XmlDocument::setRoot(XmlElementPtr root)
{ {
mRoot = std::move(root); mRoot = std::move(root);
} }
XmlElement* XmlDocument::GetRoot() const XmlElement* XmlDocument::getRoot() const
{ {
return mRoot.get(); return mRoot.get();
} }

View file

@ -2,25 +2,30 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include "xml-elements/XmlElement.h" #include "XmlElement.h"
#include "xml-elements/XmlProlog.h" #include "XmlProlog.h"
class XmlElement;
class XmlProlog;
using XmlPrologPtr = std::unique_ptr<XmlProlog>;
using XmlElementPtr = std::unique_ptr<XmlElement>;
class XmlDocument class XmlDocument
{ {
XmlPrologUPtr mProlog;
XmlElementUPtr mRoot;
public: public:
XmlDocument(); XmlDocument();
virtual ~XmlDocument();
static std::unique_ptr<XmlDocument> Create(); static std::unique_ptr<XmlDocument> Create();
XmlProlog* GetProlog() const; XmlProlog* getProlog() const;
XmlElement* GetRoot() const; XmlElement* getRoot() const;
void SetProlog(XmlPrologUPtr prolog); void setProlog(XmlPrologPtr prolog);
void SetRoot(XmlElementUPtr root); void setRoot(XmlElementPtr root);
private:
XmlPrologPtr mProlog;
XmlElementPtr mRoot;
}; };
using XmlDocumentPtr = std::shared_ptr<XmlDocument>; using XmlDocumentPtr = std::unique_ptr<XmlDocument>;
using XmlDocumentUPtr = std::unique_ptr<XmlDocument>;

View file

@ -1,5 +1,11 @@
#include "XmlParser.h" #include "XmlParser.h"
#include "StringUtils.h" #include "StringUtils.h"
#include "XmlDocument.h"
#include "XmlElement.h"
#include "XmlAttribute.h"
#include <iostream> #include <iostream>
using LS = XmlParser::LineState; using LS = XmlParser::LineState;
@ -14,64 +20,64 @@ XmlParser::XmlParser()
} }
void XmlParser::ProcessLine(const std::string& input) void XmlParser::processLine(const std::string& input)
{ {
for (std::size_t idx=0; idx<input.size(); idx++) for (std::size_t idx=0; idx<input.size(); idx++)
{ {
switch (input[idx]) switch (input[idx])
{ {
case StringUtils::LEFT_BRACKET: case StringUtils::LEFT_BRACKET:
OnLeftBracket(); onLeftBracket();
break; break;
case StringUtils::RIGHT_BRACKET: case StringUtils::RIGHT_BRACKET:
OnRightBracket(); onRightBracket();
break; break;
case StringUtils::QUESTION_MARK: case StringUtils::QUESTION_MARK:
OnQuestionMark(); onQuestionMark();
break; break;
case StringUtils::FORWARD_SLASH: case StringUtils::FORWARD_SLASH:
OnForwardSlash(); onForwardSlash();
break; break;
case StringUtils::EQUALS: case StringUtils::EQUALS:
OnEquals(); onEquals();
break; break;
case StringUtils::DOUBLE_QUOTE: case StringUtils::DOUBLE_QUOTE:
OnDoubleQuote(); onDoubleQuote();
break; break;
default: default:
OnChar(input[idx]); onChar(input[idx]);
break; break;
} }
} }
} }
void XmlParser::OnChar(char c) void XmlParser::onChar(char c)
{ {
if(StringUtils::IsAlphaNumeric(c)) if(StringUtils::IsAlphaNumeric(c))
{ {
OnAlphaNumeric(c); onAlphaNumeric(c);
} }
else if(StringUtils::IsSpace(c)) else if(StringUtils::IsSpace(c))
{ {
OnSpace(c); onSpace(c);
} }
else else
{ {
OnNonAlphaNumeric(c); onNonAlphaNumeric(c);
} }
} }
void XmlParser::OnAlphaNumeric(char c) void XmlParser::onAlphaNumeric(char c)
{ {
switch(mLineState) switch(mLineState)
{ {
case LS::Await_Tag_Open: case LS::Await_Tag_Open:
OnTextStart(c); onTextStart(c);
break; break;
case LS::Await_Tag_Follower: case LS::Await_Tag_Follower:
case LS::Await_Tag_Name: case LS::Await_Tag_Name:
{ {
OnTagNameStart(c); onTagNameStart(c);
break; break;
} }
case LS::Await_Tag_Name_End: case LS::Await_Tag_Name_End:
@ -81,7 +87,7 @@ void XmlParser::OnAlphaNumeric(char c)
} }
case LS::Await_Attribute_Name: case LS::Await_Attribute_Name:
{ {
OnAttributeNameStart(c); onAttributeNameStart(c);
break; break;
} }
case LS::Await_Attribute_Name_End: case LS::Await_Attribute_Name_End:
@ -108,7 +114,7 @@ void XmlParser::OnAlphaNumeric(char c)
} }
} }
void XmlParser::OnNonAlphaNumeric(char c) void XmlParser::onNonAlphaNumeric(char c)
{ {
switch(mLineState) switch(mLineState)
{ {
@ -137,15 +143,15 @@ void XmlParser::OnNonAlphaNumeric(char c)
} }
} }
void XmlParser::OnSpace(char c) void XmlParser::onSpace(char c)
{ {
switch(mLineState) switch(mLineState)
{ {
case LS::Await_Tag_Name_End: case LS::Await_Tag_Name_End:
OnTagNameEnd(); onTagNameEnd();
break; break;
case LS::Await_Attribute_Name_End: case LS::Await_Attribute_Name_End:
OnAttributeNameEnd(); onAttributeNameEnd();
break; break;
case LS::Await_Text_End: case LS::Await_Text_End:
mWorkingText.push_back(c); mWorkingText.push_back(c);
@ -158,28 +164,28 @@ void XmlParser::OnSpace(char c)
} }
} }
void XmlParser::OnLeftBracket() void XmlParser::onLeftBracket()
{ {
switch(mLineState) switch(mLineState)
{ {
case LS::Await_Tag_Open: case LS::Await_Tag_Open:
{ {
OnTagOpen(); onTagOpen();
break; break;
} }
case LS::Await_Text_End: case LS::Await_Text_End:
{ {
OnTextEnd(); onTextEnd();
OnTagOpen(); onTagOpen();
break; break;
} }
default: default:
OnNonAlphaNumeric(StringUtils::LEFT_BRACKET); onNonAlphaNumeric(StringUtils::LEFT_BRACKET);
break; break;
} }
} }
void XmlParser::OnRightBracket() void XmlParser::onRightBracket()
{ {
switch(mLineState) switch(mLineState)
{ {
@ -188,31 +194,31 @@ void XmlParser::OnRightBracket()
case LS::Await_Attribute_Name_End: case LS::Await_Attribute_Name_End:
case LS::Await_Attribute_Value: case LS::Await_Attribute_Value:
{ {
OnTagClose(); onTagClose();
break; break;
} }
default: default:
OnNonAlphaNumeric(StringUtils::RIGHT_BRACKET); onNonAlphaNumeric(StringUtils::RIGHT_BRACKET);
break; break;
} }
} }
void XmlParser::OnQuestionMark() void XmlParser::onQuestionMark()
{ {
if(mLineState == LS::Await_Tag_Follower) if(mLineState == LS::Await_Tag_Follower)
{ {
if(mDocumentState == DS::Await_Prolog) if(mDocumentState == DS::Await_Prolog)
{ {
OnStartProlog(); onStartProlog();
} }
} }
else if(mDocumentState != DS::Build_Prolog) else if(mDocumentState != DS::Build_Prolog)
{ {
OnNonAlphaNumeric(StringUtils::QUESTION_MARK); onNonAlphaNumeric(StringUtils::QUESTION_MARK);
} }
} }
void XmlParser::OnForwardSlash() void XmlParser::onForwardSlash()
{ {
if(mLineState == LS::Await_Tag_Follower) if(mLineState == LS::Await_Tag_Follower)
{ {
@ -223,36 +229,36 @@ void XmlParser::OnForwardSlash()
} }
} }
void XmlParser::OnEquals() void XmlParser::onEquals()
{ {
if(mLineState == LS::Await_Attribute_Name_End) if(mLineState == LS::Await_Attribute_Name_End)
{ {
OnAttributeNameEnd(); onAttributeNameEnd();
} }
else else
{ {
OnNonAlphaNumeric(StringUtils::EQUALS); onNonAlphaNumeric(StringUtils::EQUALS);
} }
} }
void XmlParser::OnDoubleQuote() void XmlParser::onDoubleQuote()
{ {
if(mLineState == LS::Await_Attribute_Value) if(mLineState == LS::Await_Attribute_Value)
{ {
OnAttributeValueStart(); onAttributeValueStart();
} }
else if(mLineState == LS::Await_Attribute_Value_End) else if(mLineState == LS::Await_Attribute_Value_End)
{ {
OnAttributeValueEnd(); onAttributeValueEnd();
} }
} }
void XmlParser::OnTagOpen() void XmlParser::onTagOpen()
{ {
mLineState = LS::Await_Tag_Follower; mLineState = LS::Await_Tag_Follower;
} }
void XmlParser::OnTagClose() void XmlParser::onTagClose()
{ {
if(mDocumentState == DS::Build_Prolog) if(mDocumentState == DS::Build_Prolog)
{ {
@ -262,7 +268,7 @@ void XmlParser::OnTagClose()
{ {
if(mLineState == LS::Await_Tag_Name_End) if(mLineState == LS::Await_Tag_Name_End)
{ {
OnTagNameEnd(); onTagNameEnd();
} }
onElementTagEnd(); onElementTagEnd();
} }
@ -277,15 +283,15 @@ void XmlParser::OnTagClose()
} }
} }
void XmlParser::OnTextStart(char c) void XmlParser::onTextStart(char c)
{ {
mWorkingText = c; mWorkingText = c;
mLineState = LS::Await_Text_End; mLineState = LS::Await_Text_End;
} }
void XmlParser::OnTextEnd() void XmlParser::onTextEnd()
{ {
mWorkingElements.top()->SetText(mWorkingText); mWorkingElements.top()->setText(mWorkingText);
} }
void XmlParser::onElementTagEnd() void XmlParser::onElementTagEnd()
@ -294,7 +300,7 @@ void XmlParser::onElementTagEnd()
mLineState = LS::Await_Tag_Open; mLineState = LS::Await_Tag_Open;
} }
void XmlParser::OnTagNameStart(char c) void XmlParser::onTagNameStart(char c)
{ {
mWorkingTagName = c; mWorkingTagName = c;
mLineState = LS::Await_Tag_Name_End; mLineState = LS::Await_Tag_Name_End;
@ -304,11 +310,11 @@ void XmlParser::OnTagNameStart(char c)
} }
} }
void XmlParser::OnTagNameEnd() void XmlParser::onTagNameEnd()
{ {
if(mDocumentState == DS::Build_Prolog) if(mDocumentState == DS::Build_Prolog)
{ {
mDocument->GetProlog()->SetTagName(mWorkingTagName); mDocument->getProlog()->setTagName(mWorkingTagName);
mLineState = LS::Await_Attribute_Name; mLineState = LS::Await_Attribute_Name;
} }
else if(mDocumentState == DS::Build_Element) else if(mDocumentState == DS::Build_Element)
@ -316,59 +322,59 @@ void XmlParser::OnTagNameEnd()
auto new_element = XmlElement::Create(mWorkingTagName); auto new_element = XmlElement::Create(mWorkingTagName);
auto working_element = new_element.get(); auto working_element = new_element.get();
if (!mDocument->GetRoot()) if (!mDocument->getRoot())
{ {
mDocument->SetRoot(std::move(new_element)); mDocument->setRoot(std::move(new_element));
} }
else else
{ {
mWorkingElements.top()->AddChild(std::move(new_element)); mWorkingElements.top()->addChild(std::move(new_element));
} }
mWorkingElements.push(working_element); mWorkingElements.push(working_element);
mLineState = LS::Await_Attribute_Name; mLineState = LS::Await_Attribute_Name;
} }
} }
void XmlParser::OnAttributeNameStart(char c) void XmlParser::onAttributeNameStart(char c)
{ {
mWorkingAttributeName = c; mWorkingAttributeName = c;
mLineState = LS::Await_Attribute_Name_End; mLineState = LS::Await_Attribute_Name_End;
} }
void XmlParser::OnAttributeNameEnd() void XmlParser::onAttributeNameEnd()
{ {
auto attribute = XmlAttribute::Create(mWorkingAttributeName); auto attribute = XmlAttribute::Create(mWorkingAttributeName);
if(mDocumentState == DS::Build_Prolog) if(mDocumentState == DS::Build_Prolog)
{ {
mDocument->GetProlog()->AddAttribute(std::move(attribute)); mDocument->getProlog()->addAttribute(std::move(attribute));
} }
else if(mDocumentState == DS::Build_Element) else if(mDocumentState == DS::Build_Element)
{ {
mWorkingElements.top()->AddAttribute(std::move(attribute)); mWorkingElements.top()->addAttribute(std::move(attribute));
} }
mLineState = LS::Await_Attribute_Value; mLineState = LS::Await_Attribute_Value;
} }
void XmlParser::OnAttributeValueStart() void XmlParser::onAttributeValueStart()
{ {
mWorkingAttributeValue = ""; mWorkingAttributeValue = "";
mLineState = LS::Await_Attribute_Value_End; mLineState = LS::Await_Attribute_Value_End;
} }
void XmlParser::OnAttributeValueEnd() void XmlParser::onAttributeValueEnd()
{ {
if(mDocumentState == DS::Build_Prolog) if(mDocumentState == DS::Build_Prolog)
{ {
mDocument->GetProlog()->GetAttribute(mWorkingAttributeName)->SetValue(mWorkingAttributeValue); mDocument->getProlog()->getAttribute(mWorkingAttributeName)->setValue(mWorkingAttributeValue);
} }
else if(mDocumentState == DS::Build_Element) else if(mDocumentState == DS::Build_Element)
{ {
mWorkingElements.top()->GetAttribute(mWorkingAttributeName)->SetValue(mWorkingAttributeValue); mWorkingElements.top()->getAttribute(mWorkingAttributeName)->setValue(mWorkingAttributeValue);
} }
mLineState = LS::Await_Attribute_Name; mLineState = LS::Await_Attribute_Name;
} }
void XmlParser::OnStartProlog() void XmlParser::onStartProlog()
{ {
mDocumentState = DS::Build_Prolog; mDocumentState = DS::Build_Prolog;
mLineState = LS::Await_Tag_Name_End; mLineState = LS::Await_Tag_Name_End;
@ -376,12 +382,12 @@ void XmlParser::OnStartProlog()
void XmlParser::onFinishProlog() void XmlParser::onFinishProlog()
{ {
mDocument->GetProlog()->Update(); mDocument->getProlog()->update();
mDocumentState = DS::Await_Element; mDocumentState = DS::Await_Element;
mLineState = LS::Await_Tag_Open; mLineState = LS::Await_Tag_Open;
} }
XmlDocumentPtr XmlParser::GetDocument() const XmlDocumentPtr XmlParser::getDocument()
{ {
return mDocument; return std::move(mDocument);
} }

View file

@ -2,7 +2,12 @@
#include <string> #include <string>
#include <stack> #include <stack>
#include "XmlDocument.h" #include <memory>
class XmlDocument;
using XmlDocumentPtr = std::unique_ptr<XmlDocument>;
class XmlElement;
class XmlParser class XmlParser
{ {
@ -29,72 +34,70 @@ public:
Await_Text_End Await_Text_End
}; };
private:
DocumentState mDocumentState;
LineState mLineState;
XmlDocumentPtr mDocument;
std::stack<XmlElement*> mWorkingElements;
std::string mWorkingAttributeName;
std::string mWorkingTagName;
std::string mWorkingAttributeValue;
std::string mWorkingText;
public: public:
XmlParser(); XmlParser();
void ProcessLine(const std::string& input); void processLine(const std::string& input);
XmlDocumentPtr GetDocument() const; XmlDocumentPtr getDocument();
private: private:
void onLeftBracket();
void OnLeftBracket(); void onRightBracket();
void OnRightBracket(); void onQuestionMark();
void OnQuestionMark(); void onForwardSlash();
void OnForwardSlash(); void onChar(char c);
void OnChar(char c); void onSpace(char c);
void OnSpace(char c); void onAlphaNumeric(char c);
void OnAlphaNumeric(char c); void onNonAlphaNumeric(char c);
void OnNonAlphaNumeric(char c); void onEquals();
void OnEquals(); void onDoubleQuote();
void OnDoubleQuote(); void onTagOpen();
void OnTagOpen(); void onTagNameStart(char c);
void OnTagNameStart(char c); void onTagNameEnd();
void OnTagNameEnd(); void onTagClose();
void OnTagClose(); void onTextStart(char c);
void OnTextStart(char c); void onTextEnd();
void OnTextEnd(); void onAttributeNameStart(char c);
void OnAttributeNameStart(char c); void onAttributeNameEnd();
void OnAttributeNameEnd(); void onAttributeValueStart();
void OnAttributeValueStart(); void onAttributeValueEnd();
void OnAttributeValueEnd(); void onPrologId();
void OnPrologId(); void onStartProlog();
void OnStartProlog();
void onFinishProlog(); void onFinishProlog();
void onElementTagEnd(); void onElementTagEnd();
private:
DocumentState mDocumentState;
LineState mLineState;
XmlDocumentPtr mDocument;
std::stack<XmlElement*> mWorkingElements;
std::string mWorkingAttributeName;
std::string mWorkingTagName;
std::string mWorkingAttributeValue;
std::string mWorkingText;
}; };

View file

@ -1,19 +1,21 @@
#include "XmlWriter.h" #include "XmlWriter.h"
#include "XmlDocument.h"
#include "XmlAttribute.h"
std::string XmlWriter::ToString(XmlElement* element, unsigned depth) std::string XmlWriter::toString(XmlElement* element, unsigned depth)
{ {
const auto prefix = std::string(2*depth, ' '); const auto prefix = std::string(2*depth, ' ');
auto content = prefix + "<" + element->GetTagName(); auto content = prefix + "<" + element->getTagName();
for (std::size_t idx=0; idx< element->GetNumAttributes(); idx++) for (std::size_t idx=0; idx< element->getNumAttributes(); idx++)
{ {
auto attribute = element->GetAttribute(idx); auto attribute = element->getAttribute(idx);
content += " " + attribute->GetName() + "=\"" + attribute->GetValue() + "\""; content += " " + attribute->getName() + "=\"" + attribute->getValue() + "\"";
} }
const auto num_children = element->GetNumChildren(); const auto num_children = element->getNumChildren();
if (num_children == 0 && element->GetText().empty()) if (num_children == 0 && element->getText().empty())
{ {
content += "/>\n"; content += "/>\n";
return content; return content;
@ -23,46 +25,46 @@ std::string XmlWriter::ToString(XmlElement* element, unsigned depth)
content += ">"; content += ">";
} }
if (!element->GetText().empty()) if (!element->getText().empty())
{ {
content += element->GetText(); content += element->getText();
} }
if (num_children>0) if (num_children>0)
{ {
content += "\n"; content += "\n";
} }
for (std::size_t idx=0; idx< element->GetNumChildren(); idx++) for (std::size_t idx=0; idx< element->getNumChildren(); idx++)
{ {
auto child = element->GetChild(idx); auto child = element->getChild(idx);
content += ToString(child, depth+1); content += toString(child, depth+1);
} }
if (num_children>0) if (num_children>0)
{ {
content += prefix; content += prefix;
} }
content += "</" + element->GetTagName() + ">\n"; content += "</" + element->getTagName() + ">\n";
return content; return content;
} }
std::string XmlWriter::ToString(XmlDocument* document) std::string XmlWriter::toString(XmlDocument* document)
{ {
std::string content; std::string content;
if (auto prolog = document->GetProlog()) if (auto prolog = document->getProlog())
{ {
content += "<?xml"; content += "<?xml";
for (std::size_t idx=0; idx< prolog->GetNumAttributes(); idx++) for (std::size_t idx=0; idx< prolog->getNumAttributes(); idx++)
{ {
auto attribute = prolog->GetAttribute(idx); auto attribute = prolog->getAttribute(idx);
content += " " + attribute->GetName() + "=\"" + attribute->GetValue() + "\""; content += " " + attribute->getName() + "=\"" + attribute->getValue() + "\"";
} }
content += "?>\n"; content += "?>\n";
} }
if (auto root = document->GetRoot()) if (auto root = document->getRoot())
{ {
content += ToString(root); content += toString(root);
} }
return content; return content;
} }

View file

@ -1,15 +1,17 @@
#pragma once #pragma once
#include "XmlDocument.h"
#include <string> #include <string>
class XmlDocument;
class XmlElement;
class XmlWriter class XmlWriter
{ {
public: public:
XmlWriter() = default; XmlWriter() = default;
std::string ToString(XmlDocument* document); std::string toString(XmlDocument* document);
private: private:
std::string ToString(XmlElement* element, unsigned depth=0); std::string toString(XmlElement* element, unsigned depth=0);
}; };

View file

@ -1,6 +1,5 @@
#include "XmlAttribute.h" #include "XmlAttribute.h"
XmlAttribute::XmlAttribute(const std::string& name) XmlAttribute::XmlAttribute(const std::string& name)
: mName(name), : mName(name),
mValue() mValue()
@ -8,22 +7,22 @@ XmlAttribute::XmlAttribute(const std::string& name)
} }
XmlAttributeUPtr XmlAttribute::Create(const std::string& name) XmlAttributePtr XmlAttribute::Create(const std::string& name)
{ {
return std::make_unique<XmlAttribute>(name); return std::make_unique<XmlAttribute>(name);
} }
void XmlAttribute::SetValue(const std::string& value) const std::string& XmlAttribute::getName() const
{
mValue = value;
}
std::string XmlAttribute::GetName() const
{ {
return mName; return mName;
} }
std::string XmlAttribute::GetValue() const const std::string& XmlAttribute::getValue() const
{ {
return mValue; return mValue;
} }
void XmlAttribute::setValue(const std::string& value)
{
mValue = value;
}

View file

@ -1,26 +1,23 @@
#pragma once #pragma once
#include <memory> #include <memory>
#include <vector>
#include <string> #include <string>
class XmlAttribute class XmlAttribute
{ {
private:
std::string mName;
std::string mValue;
public: public:
XmlAttribute(const std::string& name); XmlAttribute(const std::string& name);
static std::unique_ptr<XmlAttribute> Create(const std::string& name); static std::unique_ptr<XmlAttribute> Create(const std::string& name);
void SetValue(const std::string& value); const std::string& getName() const;
std::string GetName() const; const std::string& getValue() const;
std::string GetValue() const; void setValue(const std::string& value);
private:
std::string mName;
std::string mValue;
}; };
using XmlAttributePtr = std::shared_ptr<XmlAttribute>; using XmlAttributePtr = std::unique_ptr<XmlAttribute>;
using XmlAttributeUPtr = std::unique_ptr<XmlAttribute>;

View file

@ -1,5 +1,6 @@
#include "XmlElement.h" #include "XmlElement.h"
#include "XmlAttribute.h"
XmlElement::XmlElement(const std::string& tagName) XmlElement::XmlElement(const std::string& tagName)
: mTagName(tagName), : mTagName(tagName),
@ -8,46 +9,51 @@ XmlElement::XmlElement(const std::string& tagName)
} }
XmlElementUPtr XmlElement::Create(const std::string& tagName) XmlElement::~XmlElement()
{
}
XmlElementPtr XmlElement::Create(const std::string& tagName)
{ {
return std::make_unique<XmlElement>(tagName); return std::make_unique<XmlElement>(tagName);
} }
void XmlElement::SetTagName(const std::string& tagName) void XmlElement::setTagName(const std::string& tagName)
{ {
mTagName = tagName; mTagName = tagName;
} }
void XmlElement::AddChild(XmlElementUPtr child) void XmlElement::addChild(XmlElementPtr child)
{ {
mChildren.push_back(std::move(child)); mChildren.push_back(std::move(child));
} }
void XmlElement::AddAttribute(XmlAttributeUPtr attribute) void XmlElement::addAttribute(XmlAttributePtr attribute)
{ {
mAttributes.push_back(std::move(attribute)); mAttributes.push_back(std::move(attribute));
} }
std::string XmlElement::GetTagName() const const std::string& XmlElement::getTagName() const
{ {
return mTagName; return mTagName;
} }
std::string XmlElement::GetText() const const std::string& XmlElement::getText() const
{ {
return mText; return mText;
} }
void XmlElement::SetText(const std::string& text) void XmlElement::setText(const std::string& text)
{ {
mText = text; mText = text;
} }
XmlAttribute* XmlElement::GetAttribute(const std::string& attributeName) const XmlAttribute* XmlElement::getAttribute(const std::string& attributeName) const
{ {
for(const auto& attribute : mAttributes) for(const auto& attribute : mAttributes)
{ {
if(attribute->GetName() == attributeName) if(attribute->getName() == attributeName)
{ {
return attribute.get(); return attribute.get();
} }
@ -55,7 +61,7 @@ XmlAttribute* XmlElement::GetAttribute(const std::string& attributeName) const
return nullptr; return nullptr;
} }
XmlAttribute* XmlElement::GetAttribute(std::size_t index) const XmlAttribute* XmlElement::getAttribute(std::size_t index) const
{ {
if(index < mAttributes.size()) if(index < mAttributes.size())
{ {
@ -64,17 +70,17 @@ XmlAttribute* XmlElement::GetAttribute(std::size_t index) const
return nullptr; return nullptr;
} }
std::size_t XmlElement::GetNumAttributes() const std::size_t XmlElement::getNumAttributes() const
{ {
return mAttributes.size(); return mAttributes.size();
} }
std::size_t XmlElement::GetNumChildren() const std::size_t XmlElement::getNumChildren() const
{ {
return mChildren.size(); return mChildren.size();
} }
XmlElement* XmlElement::GetChild(std::size_t index) const XmlElement* XmlElement::getChild(std::size_t index) const
{ {
return mChildren[index].get(); return mChildren[index].get();
} }

View file

@ -1,40 +1,43 @@
#pragma once #pragma once
#include "XmlAttribute.h"
#include <memory> #include <memory>
#include <vector> #include <vector>
#include <string> #include <string>
class XmlAttribute;
using XmlAttributePtr = std::unique_ptr<XmlAttribute>;
class XmlElement class XmlElement
{ {
public: public:
XmlElement(const std::string& tagName); XmlElement(const std::string& tagName);
virtual ~XmlElement() = default; virtual ~XmlElement();
static std::unique_ptr<XmlElement> Create(const std::string& tagName); static std::unique_ptr<XmlElement> Create(const std::string& tagName);
void AddAttribute(XmlAttributeUPtr attribute); void addAttribute(XmlAttributePtr attribute);
void AddChild(std::unique_ptr<XmlElement> child); void addChild(std::unique_ptr<XmlElement> child);
std::string GetTagName() const; const std::string& getTagName() const;
std::string GetText() const; const std::string& getText() const;
XmlAttribute* GetAttribute(const std::string& attribute) const; XmlAttribute* getAttribute(const std::string& attribute) const;
XmlAttribute* GetAttribute(std::size_t index) const; XmlAttribute* getAttribute(std::size_t index) const;
std::size_t GetNumAttributes() const; std::size_t getNumAttributes() const;
std::size_t GetNumChildren() const; std::size_t getNumChildren() const;
XmlElement* GetChild(std::size_t index) const; XmlElement* getChild(std::size_t index) const;
void SetText(const std::string& text); void setText(const std::string& text);
void SetTagName(const std::string& tagName); void setTagName(const std::string& tagName);
protected: protected:
std::string mTagName; std::string mTagName;
std::vector<XmlAttributeUPtr> mAttributes;
std::vector<std::unique_ptr<XmlElement> > mChildren;
std::string mText; std::string mText;
std::vector<XmlAttributePtr> mAttributes;
std::vector<std::unique_ptr<XmlElement> > mChildren;
}; };
using XmlElementPtr = std::shared_ptr<XmlElement>; using XmlElementPtr = std::unique_ptr<XmlElement>;
using XmlElementUPtr = std::unique_ptr<XmlElement>;

View file

@ -1,5 +1,6 @@
#include "XmlProlog.h" #include "XmlProlog.h"
#include "XmlAttribute.h"
XmlProlog::XmlProlog(const std::string& tagName) XmlProlog::XmlProlog(const std::string& tagName)
: XmlElement(tagName), : XmlElement(tagName),
@ -9,22 +10,22 @@ XmlProlog::XmlProlog(const std::string& tagName)
} }
XmlPrologUPtr XmlProlog::Create(const std::string& tagName) XmlPrologPtr XmlProlog::Create(const std::string& tagName)
{ {
return std::make_unique<XmlProlog>(tagName); return std::make_unique<XmlProlog>(tagName);
} }
XmlProlog::Encoding XmlProlog::GetEncoding() const XmlProlog::Encoding XmlProlog::getEncoding() const
{ {
return mEncoding; return mEncoding;
} }
XmlProlog::Version XmlProlog::GetVersion() const XmlProlog::Version XmlProlog::getVersion() const
{ {
return mVersion; return mVersion;
} }
void XmlProlog::SetEncoding(const std::string& encoding) void XmlProlog::setEncoding(const std::string& encoding)
{ {
if(encoding == "UTF-8") if(encoding == "UTF-8")
{ {
@ -32,7 +33,7 @@ void XmlProlog::SetEncoding(const std::string& encoding)
} }
} }
void XmlProlog::SetVersion(const std::string& version) void XmlProlog::setVersion(const std::string& version)
{ {
if(version == "1.0") if(version == "1.0")
{ {
@ -40,15 +41,15 @@ void XmlProlog::SetVersion(const std::string& version)
} }
} }
void XmlProlog::Update() void XmlProlog::update()
{ {
if(const auto version = GetAttribute("version")) if(const auto version = getAttribute("version"))
{ {
SetVersion(version->GetValue()); setVersion(version->getValue());
} }
if(const auto encoding = GetAttribute("encoding")) if(const auto encoding = getAttribute("encoding"))
{ {
SetEncoding(encoding->GetValue()); setEncoding(encoding->getValue());
} }
} }

View file

@ -1,9 +1,10 @@
#pragma once #pragma once
#include <memory>
#include <vector>
#include "XmlElement.h" #include "XmlElement.h"
#include <memory>
#include <vector>
class XmlProlog : public XmlElement class XmlProlog : public XmlElement
{ {
public: public:
@ -15,23 +16,21 @@ public:
UTF8 UTF8
}; };
private:
Version mVersion;
Encoding mEncoding;
public: public:
XmlProlog(const std::string& tagName); XmlProlog(const std::string& tagName);
static std::unique_ptr<XmlProlog> Create(const std::string& tagName); static std::unique_ptr<XmlProlog> Create(const std::string& tagName);
Encoding GetEncoding() const; Encoding getEncoding() const;
Version GetVersion() const; Version getVersion() const;
void SetEncoding(const std::string& encoding); void setEncoding(const std::string& encoding);
void SetVersion(const std::string& version); void setVersion(const std::string& version);
void Update(); void update();
private:
Version mVersion;
Encoding mEncoding;
}; };
using XmlPrologPtr = std::shared_ptr<XmlProlog>; using XmlPrologPtr = std::unique_ptr<XmlProlog>;
using XmlPrologUPtr = std::unique_ptr<XmlProlog>;

View file

@ -17,4 +17,14 @@ I'm a bullet point list:
* Second point * Second point
* Third point * Third point
With a [hyperlink](www.imahyperlink.com) embedded. With a [hyperlink](www.imahyperlink.com) embedded.
# I'm another level one header
I'm some inline math $a = b + c$ and I'm some standalone math:
$$
d = e + f
$$
![This is an image](https://myoctocat.com/assets/images/base-octocat.svg)

View file

@ -1,5 +1,6 @@
set(PUBLISHING_UNIT_TEST_FILES set(PUBLISHING_UNIT_TEST_FILES
publishing/TestPdfWriter.cpp publishing/TestPdfWriter.cpp
publishing/TestDocumentConverter.cpp
PARENT_SCOPE PARENT_SCOPE
) )

View file

@ -0,0 +1,19 @@
#include "PdfDocument.h"
#include "PdfWriter.h"
#include "PdfObject.h"
#include "File.h"
#include "TestFramework.h"
#include "TestUtils.h"
TEST_CASE(TestDocumentConverterMarkdownToPdf, "publishing")
{
auto document = std::make_unique<PdfDocument>();
PdfWriter writer;
const auto output = writer.ToString(document);
File pdf_file(TestUtils::getTestOutputDir() / "TestDocumentConverterMarkdownToPdf.pdf");
pdf_file.open(File::AccessMode::Write);
pdf_file.writeText(output);
}

View file

@ -16,7 +16,7 @@ TEST_CASE(TestMarkdownParser, "web")
auto html = parser.getHtml(); auto html = parser.getHtml();
HtmlWriter writer; HtmlWriter writer;
const auto html_string = writer.ToString(html); const auto html_string = writer.toString(html.get());
File html_file(TestUtils::getTestOutputDir() / "TestMarkdownParserOut.html"); File html_file(TestUtils::getTestOutputDir() / "TestMarkdownParserOut.html");
html_file.writeText(html_string); html_file.writeText(html_string);

View file

@ -3,6 +3,8 @@
#include "XmlParser.h" #include "XmlParser.h"
#include "XmlWriter.h" #include "XmlWriter.h"
#include "XmlDocument.h"
#include "File.h" #include "File.h"
#include "TestFramework.h" #include "TestFramework.h"
@ -18,12 +20,12 @@ TEST_CASE(TestXmlParser, "web")
{ {
std::string line; std::string line;
std::getline(xml_file, line); std::getline(xml_file, line);
parser.ProcessLine(line); parser.processLine(line);
} }
xml_file.close(); xml_file.close();
XmlWriter writer; XmlWriter writer;
auto content = writer.ToString(parser.GetDocument().get()); auto content = writer.toString(parser.getDocument().get());
auto outFile = std::make_unique<File>(TestUtils::getTestOutputDir() / "test_out.xml"); auto outFile = std::make_unique<File>(TestUtils::getTestOutputDir() / "test_out.xml");
outFile->writeText(content); outFile->writeText(content);