mirror of
https://github.com/Relintai/rcpp_framework.git
synced 2025-05-02 13:47:56 +02:00
Removed bbcpp.
This commit is contained in:
parent
6c56380d90
commit
ba90610e3e
222
core/utils.cpp
222
core/utils.cpp
@ -23,26 +23,6 @@ void Utils::markdown_to_html(std::string *str) {
|
|||||||
(*str) = htmlOutput;
|
(*str) = htmlOutput;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Utils::bbcode_evaluate_simple(std::string *str) {
|
|
||||||
bbcpp::BBDocumentPtr doc = bbcode((*str));
|
|
||||||
|
|
||||||
bbcpp::BBNodeList n = doc->getChildren();
|
|
||||||
|
|
||||||
str->clear();
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < n.size(); ++i) {
|
|
||||||
eval_node(str, n[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bbcpp::BBDocumentPtr Utils::bbcode(const std::string &str) {
|
|
||||||
bbcpp::BBDocumentPtr doc = bbcpp::BBDocument::create();
|
|
||||||
|
|
||||||
doc->load(str);
|
|
||||||
|
|
||||||
return doc;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Utils::str_replace(std::string *str, const std::string &from, const std::string &to) {
|
void Utils::str_replace(std::string *str, const std::string &from, const std::string &to) {
|
||||||
if (from.empty())
|
if (from.empty())
|
||||||
return;
|
return;
|
||||||
@ -53,205 +33,3 @@ void Utils::str_replace(std::string *str, const std::string &from, const std::st
|
|||||||
start_pos += to.length();
|
start_pos += to.length();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Utils::eval_node(std::string *str, bbcpp::BBNodePtr node) {
|
|
||||||
switch (node->getNodeType()) {
|
|
||||||
case bbcpp::BBNode::NodeType::TEXT: {
|
|
||||||
bbcpp::BBTextPtr t = node->downCast<bbcpp::BBTextPtr>();
|
|
||||||
|
|
||||||
(*str) += t->getText();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case bbcpp::BBNode::NodeType::ELEMENT: {
|
|
||||||
bbcpp::BBElementPtr e = node->downCast<bbcpp::BBElementPtr>();
|
|
||||||
|
|
||||||
eval_element(str, e);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case bbcpp::BBNode::NodeType::ATTRIBUTE:
|
|
||||||
break;
|
|
||||||
case bbcpp::BBNode::NodeType::DOCUMENT:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
bbcpp::BBNodeList n = node->getChildren();
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < n.size(); ++i) {
|
|
||||||
eval_node(str, n[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Utils::eval_element(std::string *str, bbcpp::BBElementPtr element) {
|
|
||||||
switch (element->getElementType()) {
|
|
||||||
case bbcpp::BBElement::ElementType::SIMPLE: {
|
|
||||||
|
|
||||||
if (element->getNodeName() == "b") {
|
|
||||||
(*str) += "<span style=\"font-weight: bold;\">";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element->getNodeName() == "i") {
|
|
||||||
(*str) += "<span style=\"font-style: italic;\">";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element->getNodeName() == "u") {
|
|
||||||
(*str) += "<span style=\"text-decoration: underline;\">";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element->getNodeName() == "s") {
|
|
||||||
(*str) += "<span style=\"text-decoration: line-through;\">";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element->getNodeName() == "center") {
|
|
||||||
(*str) += "<span style=\"text-decoration: line-through;\">";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element->getNodeName() == "center") {
|
|
||||||
(*str) += "<span style=\"text-align: center;\">";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element->getNodeName() == "left") {
|
|
||||||
(*str) += "<span style=\"text-align: left;\">";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element->getNodeName() == "right") {
|
|
||||||
(*str) += "<span style=\"text-align: right;\">";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element->getNodeName() == "quote") {
|
|
||||||
(*str) += "<blockquote>";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element->getNodeName() == "spoiler") {
|
|
||||||
(*str) += "<details>";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element->getNodeName() == "summary") {
|
|
||||||
(*str) += "<summary>";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case bbcpp::BBElement::ElementType::VALUE: {
|
|
||||||
//nyi
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case bbcpp::BBElement::ElementType::PARAMETER: {
|
|
||||||
if (element->getNodeName() == "style") {
|
|
||||||
|
|
||||||
bbcpp::ParameterMap m = element->getParameters();
|
|
||||||
|
|
||||||
(*str) += "<span style=\"";
|
|
||||||
|
|
||||||
std::string p = m["size"];
|
|
||||||
|
|
||||||
if (p != "") {
|
|
||||||
(*str) += "font-size: " + p + ";";
|
|
||||||
}
|
|
||||||
|
|
||||||
p = m["color"];
|
|
||||||
|
|
||||||
if (p != "") {
|
|
||||||
(*str) += "color: " + p + ";";
|
|
||||||
}
|
|
||||||
|
|
||||||
(*str) += "\">";
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element->getNodeName() == "quote") {
|
|
||||||
|
|
||||||
bbcpp::ParameterMap m = element->getParameters();
|
|
||||||
|
|
||||||
(*str) += "<span style=\"";
|
|
||||||
|
|
||||||
std::string p = m["name"];
|
|
||||||
|
|
||||||
if (p != "") {
|
|
||||||
(*str) += "<blockquote cite=\"" + p + "\">";
|
|
||||||
} else {
|
|
||||||
(*str) += "<blockquote>";
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case bbcpp::BBElement::ElementType::CLOSING: {
|
|
||||||
if (element->getNodeName() == "b") {
|
|
||||||
(*str) += "</span>";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element->getNodeName() == "i") {
|
|
||||||
(*str) += "</span>";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element->getNodeName() == "u") {
|
|
||||||
(*str) += "</span>";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element->getNodeName() == "s") {
|
|
||||||
(*str) += "</span>";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element->getNodeName() == "size") {
|
|
||||||
(*str) += "</span>";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element->getNodeName() == "color") {
|
|
||||||
(*str) += "</span>";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element->getNodeName() == "center") {
|
|
||||||
(*str) += "</span>";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element->getNodeName() == "left") {
|
|
||||||
(*str) += "</span>";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element->getNodeName() == "right") {
|
|
||||||
(*str) += "</span>";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element->getNodeName() == "quote") {
|
|
||||||
(*str) += "</blockquote>";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element->getNodeName() == "spoiler") {
|
|
||||||
(*str) += "</details>";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element->getNodeName() == "summary") {
|
|
||||||
(*str) += "</summary>";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,9 +3,6 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <bbcpp/BBDocument.h>
|
|
||||||
|
|
||||||
|
|
||||||
class Utils {
|
class Utils {
|
||||||
public:
|
public:
|
||||||
static void newline_to_br(std::string *str);
|
static void newline_to_br(std::string *str);
|
||||||
@ -13,13 +10,8 @@ class Utils {
|
|||||||
|
|
||||||
static void markdown_to_html(std::string *str);
|
static void markdown_to_html(std::string *str);
|
||||||
|
|
||||||
static void bbcode_evaluate_simple(std::string *str);
|
|
||||||
static bbcpp::BBDocumentPtr bbcode(const std::string &str);
|
|
||||||
|
|
||||||
static void str_replace(std::string *str, const std::string& from, const std::string& to);
|
static void str_replace(std::string *str, const std::string& from, const std::string& to);
|
||||||
protected:
|
protected:
|
||||||
static void eval_node(std::string *str, bbcpp::BBNodePtr node);
|
|
||||||
static void eval_element(std::string *str, bbcpp::BBElementPtr node);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,114 +0,0 @@
|
|||||||
#include <cstring>
|
|
||||||
#include <cctype>
|
|
||||||
#include "BBDocument.h"
|
|
||||||
|
|
||||||
namespace bbcpp
|
|
||||||
{
|
|
||||||
|
|
||||||
BBNode::BBNode(NodeType nodeType, const std::string& name)
|
|
||||||
: _name(name), _nodeType(nodeType)
|
|
||||||
{
|
|
||||||
// nothing to do
|
|
||||||
}
|
|
||||||
|
|
||||||
BBText &BBDocument::newText(const std::string &text)
|
|
||||||
{
|
|
||||||
// first try to append this text to the item on top of the stack
|
|
||||||
// if that is a BBText object, if not, then see if the last element
|
|
||||||
// pushed to BBDocument is a text item, and if so append this to that
|
|
||||||
// text
|
|
||||||
if (_stack.size() > 0 && _stack.top()->getChildren().size() > 0)
|
|
||||||
{
|
|
||||||
auto totalChildCnt = _stack.top()->getChildren().size();
|
|
||||||
auto textnode = _stack.top()->getChildren().at(totalChildCnt - 1)->downCast<BBTextPtr>(false);
|
|
||||||
if (textnode)
|
|
||||||
{
|
|
||||||
textnode->append(text);
|
|
||||||
return *textnode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_children.size() > 0)
|
|
||||||
{
|
|
||||||
auto textnode = _children.back()->downCast<BBTextPtr>(false);
|
|
||||||
if (textnode)
|
|
||||||
{
|
|
||||||
textnode->append(text);
|
|
||||||
return *textnode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ok, there was no previous text element so we wil either add this text
|
|
||||||
// element as a child of the top item OR we'll add it to the BBDocucment
|
|
||||||
// object
|
|
||||||
auto textNode = std::make_shared<BBText>(text);
|
|
||||||
if (_stack.size() > 0)
|
|
||||||
{
|
|
||||||
_stack.top()->appendChild(textNode);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// add this node to the document-node if needed
|
|
||||||
appendChild(textNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
return *textNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
BBElement& BBDocument::newElement(const std::string &name)
|
|
||||||
{
|
|
||||||
auto newNode = std::make_shared<BBElement>(name);
|
|
||||||
if (_stack.size() > 0)
|
|
||||||
{
|
|
||||||
_stack.top()->appendChild(newNode);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// add this node to the document-node if needed
|
|
||||||
appendChild(newNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
_stack.push(newNode);
|
|
||||||
return *newNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
BBElement& BBDocument::newClosingElement(const std::string& name)
|
|
||||||
{
|
|
||||||
auto newNode = std::make_shared<BBElement>(name, BBElement::CLOSING);
|
|
||||||
if (_stack.size() > 0)
|
|
||||||
{
|
|
||||||
_stack.top()->appendChild(newNode);
|
|
||||||
_stack.pop();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
appendChild(newNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
return *newNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
BBElement& BBDocument::newKeyValueElement(const std::string& name, const ParameterMap& pairs)
|
|
||||||
{
|
|
||||||
auto newNode = std::make_shared<BBElement>(name, BBElement::PARAMETER);
|
|
||||||
if (_stack.size() > 0)
|
|
||||||
{
|
|
||||||
_stack.top()->appendChild(newNode);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// add this node to the document-node if needed
|
|
||||||
appendChild(newNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& kv : pairs)
|
|
||||||
{
|
|
||||||
newNode->setOrAddParameter(kv.first, kv.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
_stack.push(newNode);
|
|
||||||
return *newNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace
|
|
@ -1,605 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <stack>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <sstream>
|
|
||||||
#include <iostream>
|
|
||||||
#include <map>
|
|
||||||
#include <iterator>
|
|
||||||
#include <cctype>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
namespace bbcpp
|
|
||||||
{
|
|
||||||
|
|
||||||
inline bool IsDigit(char c)
|
|
||||||
{
|
|
||||||
return ('0' <= c && c <= '9');
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool IsAlpha(char c)
|
|
||||||
{
|
|
||||||
static const char alpha[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
||||||
return (std::strchr(alpha, c) != nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool IsAlNum(char c)
|
|
||||||
{
|
|
||||||
return IsAlpha(c) || IsDigit(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool IsSpace(char c)
|
|
||||||
{
|
|
||||||
return std::isspace(static_cast<unsigned char>(c)) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
class BBNode;
|
|
||||||
class BBText;
|
|
||||||
class BBElement;
|
|
||||||
class BBDocument;
|
|
||||||
|
|
||||||
using BBNodePtr = std::shared_ptr<BBNode>;
|
|
||||||
using BBTextPtr = std::shared_ptr<BBText>;
|
|
||||||
using BBElementPtr = std::shared_ptr<BBElement>;
|
|
||||||
|
|
||||||
using BBNodeWeakPtr = std::weak_ptr<BBNode>;
|
|
||||||
using BBNodeList = std::vector<BBNodePtr>;
|
|
||||||
using BBNodeStack = std::stack<BBNodePtr>;
|
|
||||||
using BBDocumentPtr = std::shared_ptr<BBDocument>;
|
|
||||||
|
|
||||||
using ParameterMap = std::map<std::string, std::string>;
|
|
||||||
|
|
||||||
class BBNode : public std::enable_shared_from_this<BBNode>
|
|
||||||
{
|
|
||||||
template<typename NewTypePtrT>
|
|
||||||
NewTypePtrT cast(BBNodePtr node, bool bThrowOnFail)
|
|
||||||
{
|
|
||||||
if (node == nullptr && !bThrowOnFail)
|
|
||||||
{
|
|
||||||
return NewTypePtrT();
|
|
||||||
}
|
|
||||||
else if (node == nullptr)
|
|
||||||
{
|
|
||||||
throw std::invalid_argument("Cannot downcast BBNode, object is null");
|
|
||||||
}
|
|
||||||
|
|
||||||
NewTypePtrT newobj = std::dynamic_pointer_cast<typename NewTypePtrT::element_type, BBNode>(node);
|
|
||||||
|
|
||||||
if (newobj == nullptr && bThrowOnFail)
|
|
||||||
{
|
|
||||||
throw std::invalid_argument("Cannot downcast, object is not correct type");
|
|
||||||
}
|
|
||||||
|
|
||||||
return newobj;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename NewTypePtrT>
|
|
||||||
NewTypePtrT cast(BBNodePtr node, bool bThrowOnFail) const
|
|
||||||
{
|
|
||||||
if (node == nullptr && !bThrowOnFail)
|
|
||||||
{
|
|
||||||
return NewTypePtrT();
|
|
||||||
}
|
|
||||||
else if (node == nullptr)
|
|
||||||
{
|
|
||||||
throw std::invalid_argument("Cannot downcast, BBNode object is null");
|
|
||||||
}
|
|
||||||
|
|
||||||
NewTypePtrT newobj = std::dynamic_pointer_cast<typename NewTypePtrT::element_type, BBNode>(node);
|
|
||||||
|
|
||||||
if (newobj == nullptr && bThrowOnFail)
|
|
||||||
{
|
|
||||||
throw std::invalid_argument("Cannot downcast, object is not correct type");
|
|
||||||
}
|
|
||||||
|
|
||||||
return newobj;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
enum class NodeType
|
|
||||||
{
|
|
||||||
DOCUMENT,
|
|
||||||
ELEMENT, // [b]bold[/b], [QUOTE], [QUOTE=Username;1234], [QUOTE user=Bob]
|
|
||||||
TEXT, // plain text
|
|
||||||
ATTRIBUTE
|
|
||||||
};
|
|
||||||
|
|
||||||
BBNode(NodeType nodeType, const std::string& name);
|
|
||||||
virtual ~BBNode() = default;
|
|
||||||
|
|
||||||
const std::string& getNodeName() const { return _name; }
|
|
||||||
NodeType getNodeType() const { return _nodeType; }
|
|
||||||
BBNodePtr getParent() const { return BBNodePtr(_parent); }
|
|
||||||
|
|
||||||
const BBNodeList& getChildren() const { return _children; }
|
|
||||||
|
|
||||||
virtual void appendChild(BBNodePtr node)
|
|
||||||
{
|
|
||||||
_children.push_back(node);
|
|
||||||
node->_parent = shared_from_this();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename NewTypePtrT>
|
|
||||||
NewTypePtrT downCast(bool bThrowOnFail = true)
|
|
||||||
{
|
|
||||||
return cast<NewTypePtrT>(shared_from_this(), bThrowOnFail);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename NewTypePtrT>
|
|
||||||
NewTypePtrT downCast(bool bThrowOnFail = true) const
|
|
||||||
{
|
|
||||||
return cast<NewTypePtrT>(shared_from_this(), bThrowOnFail);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
std::string _name;
|
|
||||||
NodeType _nodeType;
|
|
||||||
BBNodeWeakPtr _parent;
|
|
||||||
BBNodeList _children;
|
|
||||||
|
|
||||||
friend class BBText;
|
|
||||||
friend class BBDocument;
|
|
||||||
friend class BBElement;
|
|
||||||
};
|
|
||||||
|
|
||||||
class BBText : public BBNode
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
BBText(const std::string& value)
|
|
||||||
: BBNode(BBNode::NodeType::TEXT, value)
|
|
||||||
{
|
|
||||||
// nothing to do
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~BBText() = default;
|
|
||||||
|
|
||||||
virtual const std::string getText() const { return _name; }
|
|
||||||
|
|
||||||
void append(const std::string& text)
|
|
||||||
{
|
|
||||||
_name.append(text);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class BBElement : public BBNode
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum ElementType
|
|
||||||
{
|
|
||||||
SIMPLE, // [b]bold[/b], [code]print("hello")[/code]
|
|
||||||
VALUE, // [QUOTE=Username;12345]This is a quote[/QUOTE] (mostly used by vBulletin)
|
|
||||||
PARAMETER, // [QUOTE user=Bob userid=1234]This is a quote[/QUOTE]
|
|
||||||
CLOSING // [/b], [/code]
|
|
||||||
};
|
|
||||||
|
|
||||||
BBElement(const std::string& name, ElementType et = BBElement::SIMPLE)
|
|
||||||
: BBNode(BBNode::NodeType::ELEMENT, name),
|
|
||||||
_elementType(et)
|
|
||||||
{
|
|
||||||
// nothing to do
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~BBElement() = default;
|
|
||||||
|
|
||||||
const ElementType getElementType() const { return _elementType; }
|
|
||||||
|
|
||||||
void setOrAddParameter(const std::string& key, const std::string& value, bool addIfNotExists = true)
|
|
||||||
{
|
|
||||||
_parameters.insert({key,value});
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string getParameter(const std::string& key, bool bDoThrow = true)
|
|
||||||
{
|
|
||||||
if (_parameters.find(key) == _parameters.end() && bDoThrow)
|
|
||||||
{
|
|
||||||
throw std::invalid_argument("Undefine attribute '" + key + "'");
|
|
||||||
}
|
|
||||||
|
|
||||||
return _parameters.at(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
const ParameterMap& getParameters() const { return _parameters; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
ElementType _elementType = BBElement::SIMPLE;
|
|
||||||
ParameterMap _parameters;
|
|
||||||
};
|
|
||||||
|
|
||||||
class BBDocument : public BBNode
|
|
||||||
{
|
|
||||||
BBDocument()
|
|
||||||
: BBNode(BBNode::NodeType::DOCUMENT, "#document")
|
|
||||||
{
|
|
||||||
// nothing to do
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename citerator>
|
|
||||||
citerator parseText(citerator begin, citerator end)
|
|
||||||
{
|
|
||||||
auto endingChar = begin;
|
|
||||||
|
|
||||||
for (auto it = begin; it != end; it++)
|
|
||||||
{
|
|
||||||
if (*it == '[')
|
|
||||||
{
|
|
||||||
endingChar = it;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (endingChar == begin)
|
|
||||||
{
|
|
||||||
endingChar = end;
|
|
||||||
}
|
|
||||||
|
|
||||||
newText(std::string(begin, endingChar));
|
|
||||||
|
|
||||||
return endingChar;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename citerator>
|
|
||||||
citerator parseElementName(citerator begin, citerator end, std::string& buf)
|
|
||||||
{
|
|
||||||
auto start = begin;
|
|
||||||
std::stringstream str;
|
|
||||||
|
|
||||||
for (auto it = start; it != end; it++)
|
|
||||||
{
|
|
||||||
// TODO: alphanumeric names only?
|
|
||||||
if (bbcpp::IsAlNum((char)*it))
|
|
||||||
{
|
|
||||||
str << *it;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
buf.assign(str.str());
|
|
||||||
return it;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return start;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename citerator>
|
|
||||||
citerator parseValue(citerator begin, citerator end, std::string& value)
|
|
||||||
{
|
|
||||||
auto start = begin;
|
|
||||||
while (bbcpp::IsSpace(*start) && start != end)
|
|
||||||
{
|
|
||||||
start++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (start == end)
|
|
||||||
{
|
|
||||||
// we got to the end and there was nothing but spaces
|
|
||||||
// so return our starting point so the caller can create
|
|
||||||
// a text node with those spaces
|
|
||||||
return end;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::stringstream temp;
|
|
||||||
|
|
||||||
for (auto it = start; it != end; it++)
|
|
||||||
{
|
|
||||||
if (bbcpp::IsAlNum(*it))
|
|
||||||
{
|
|
||||||
temp << *it;
|
|
||||||
}
|
|
||||||
else if (*it == ']')
|
|
||||||
{
|
|
||||||
value.assign(temp.str());
|
|
||||||
return it;
|
|
||||||
}
|
|
||||||
else if(*it == '#')
|
|
||||||
{
|
|
||||||
//is color
|
|
||||||
temp << *it;
|
|
||||||
}
|
|
||||||
else if (*it == ':' || *it == '/' || *it == '.' || *it == '&'
|
|
||||||
|| *it == '?' || *it == '$' || *it == '-' || *it == '+'
|
|
||||||
|| *it == '*' || *it == '(' || *it == ')' || *it == ',')
|
|
||||||
{
|
|
||||||
//is url
|
|
||||||
temp << *it;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// some invalid character, so return the point where
|
|
||||||
// we stopped parsing
|
|
||||||
return it;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we get here then we're at the end, so we return the starting
|
|
||||||
// point so the callerd can create a text node
|
|
||||||
return end;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename citerator>
|
|
||||||
citerator parseKey(citerator begin, citerator end, std::string& keyname)
|
|
||||||
{
|
|
||||||
auto start = begin;
|
|
||||||
while (bbcpp::IsSpace(*start) && start != end)
|
|
||||||
{
|
|
||||||
start++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (start == end)
|
|
||||||
{
|
|
||||||
// we got to the end and there was nothing but spaces
|
|
||||||
// so return our end point so the caller can create
|
|
||||||
// a text node with those spaces
|
|
||||||
return start;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::stringstream temp;
|
|
||||||
|
|
||||||
// TODO: need to handle spaces after the key name and before
|
|
||||||
// the equal sign (ie. "[style color =red]")
|
|
||||||
for (auto it = start; it != end; it++)
|
|
||||||
{
|
|
||||||
if (bbcpp::IsAlNum(*it))
|
|
||||||
{
|
|
||||||
temp << *it;
|
|
||||||
}
|
|
||||||
else if (*it == '=')
|
|
||||||
{
|
|
||||||
keyname.assign(temp.str());
|
|
||||||
return it;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// some invalid character, so return the point where
|
|
||||||
// we stopped parsing
|
|
||||||
return it;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we get here then we're at the end, so we return the starting
|
|
||||||
// point so the callerd can create a text node
|
|
||||||
return end;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename citerator>
|
|
||||||
citerator parseKeyValuePairs(citerator begin, citerator end, ParameterMap& pairs)
|
|
||||||
{
|
|
||||||
auto current = begin;
|
|
||||||
std::string tempKey;
|
|
||||||
std::string tempVal;
|
|
||||||
|
|
||||||
while (current != end)
|
|
||||||
{
|
|
||||||
current = parseKey(current, end, tempKey);
|
|
||||||
if (tempKey.empty())
|
|
||||||
{
|
|
||||||
pairs.clear();
|
|
||||||
return current;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*current != '=')
|
|
||||||
{
|
|
||||||
pairs.clear();
|
|
||||||
return current;
|
|
||||||
}
|
|
||||||
|
|
||||||
current = std::next(current);
|
|
||||||
current = parseValue(current, end, tempVal);
|
|
||||||
|
|
||||||
if (tempKey.empty() || tempVal.empty())
|
|
||||||
{
|
|
||||||
pairs.clear();
|
|
||||||
return current;
|
|
||||||
}
|
|
||||||
|
|
||||||
pairs.insert(std::make_pair(tempKey, tempVal));
|
|
||||||
if (*current == ']')
|
|
||||||
{
|
|
||||||
// this is the only valid condition for key/value pairs so we do
|
|
||||||
// not want to clear `pairs` like in the other cases
|
|
||||||
return current;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return end;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename citerator>
|
|
||||||
citerator parseElement(citerator begin, citerator end)
|
|
||||||
{
|
|
||||||
bool closingTag = false;
|
|
||||||
|
|
||||||
// the first non-[ and non-/ character
|
|
||||||
auto nameStart = std::next(begin);
|
|
||||||
|
|
||||||
std::string elementName;
|
|
||||||
|
|
||||||
// this might be a closing tag so mark it
|
|
||||||
if (*nameStart == '/')
|
|
||||||
{
|
|
||||||
closingTag = true;
|
|
||||||
nameStart = std::next(nameStart);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto nameEnd = parseElementName(nameStart, end, elementName);
|
|
||||||
|
|
||||||
// no valid name was found, so bail out
|
|
||||||
if (elementName.empty())
|
|
||||||
{
|
|
||||||
newText(std::string{*begin});
|
|
||||||
return nameEnd;
|
|
||||||
}
|
|
||||||
else if (nameEnd == end)
|
|
||||||
{
|
|
||||||
newText(std::string(begin,end));
|
|
||||||
return end;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*nameEnd == ']')
|
|
||||||
{
|
|
||||||
// end of element
|
|
||||||
}
|
|
||||||
else if (*nameEnd == '=')
|
|
||||||
{
|
|
||||||
// possibly a QUOTE value element
|
|
||||||
// possibly key-value pairs of a QUOTE
|
|
||||||
ParameterMap pairs;
|
|
||||||
|
|
||||||
auto kvEnd = parseKeyValuePairs(nameStart, end, pairs);
|
|
||||||
if (pairs.size() == 0)
|
|
||||||
{
|
|
||||||
newText(std::string(begin, kvEnd));
|
|
||||||
return kvEnd;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
newKeyValueElement(elementName, pairs);
|
|
||||||
// TODO: add 'pairs'
|
|
||||||
return std::next(kvEnd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (*nameEnd == ' ')
|
|
||||||
{
|
|
||||||
// possibly key-value pairs of a QUOTE
|
|
||||||
ParameterMap pairs;
|
|
||||||
|
|
||||||
auto kvEnd = parseKeyValuePairs(nameEnd, end, pairs);
|
|
||||||
if (pairs.size() == 0)
|
|
||||||
{
|
|
||||||
newText(std::string(begin, kvEnd));
|
|
||||||
return kvEnd;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
newKeyValueElement(elementName, pairs);
|
|
||||||
// TODO: add 'pairs'
|
|
||||||
return std::next(kvEnd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// some invalid char proceeded the element name, so it's not actually a
|
|
||||||
// valid element, so create it as text and move on
|
|
||||||
newText(std::string(begin,nameEnd));
|
|
||||||
return nameEnd;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (closingTag)
|
|
||||||
{
|
|
||||||
newClosingElement(elementName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
newElement(elementName);
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::next(nameEnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
static BBDocumentPtr create()
|
|
||||||
{
|
|
||||||
BBDocumentPtr doc = BBDocumentPtr(new BBDocument());
|
|
||||||
return doc;
|
|
||||||
}
|
|
||||||
|
|
||||||
void load(const std::string& bbcode)
|
|
||||||
{
|
|
||||||
load(bbcode.begin(), bbcode.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Iterator>
|
|
||||||
void load(Iterator begin, Iterator end)
|
|
||||||
{
|
|
||||||
std::string buffer;
|
|
||||||
auto bUnknownNodeType = true;
|
|
||||||
auto current = begin;
|
|
||||||
auto nodeType = BBNode::NodeType::TEXT;
|
|
||||||
|
|
||||||
Iterator temp;
|
|
||||||
|
|
||||||
while (current != end)
|
|
||||||
{
|
|
||||||
if (bUnknownNodeType)
|
|
||||||
{
|
|
||||||
if (*current == '[')
|
|
||||||
{
|
|
||||||
nodeType = BBNode::NodeType::ELEMENT;
|
|
||||||
bUnknownNodeType = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nodeType = BBNode::NodeType::TEXT;
|
|
||||||
bUnknownNodeType = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!bUnknownNodeType)
|
|
||||||
{
|
|
||||||
switch (nodeType)
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
throw std::runtime_error("Unknown node type in BBDocument::load()");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BBNode::NodeType::TEXT:
|
|
||||||
{
|
|
||||||
current = parseText(current, end);
|
|
||||||
bUnknownNodeType = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BBNode::NodeType::ELEMENT:
|
|
||||||
{
|
|
||||||
temp = parseElement(current, end);
|
|
||||||
if (temp == current)
|
|
||||||
{
|
|
||||||
// nothing was parsed, treat as text
|
|
||||||
nodeType = BBNode::NodeType::TEXT;
|
|
||||||
bUnknownNodeType = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
current = temp;
|
|
||||||
bUnknownNodeType = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
BBNodeStack _stack;
|
|
||||||
|
|
||||||
BBText& newText(const std::string& text = std::string());
|
|
||||||
BBElement& newElement(const std::string& name);
|
|
||||||
BBElement& newClosingElement(const std::string& name);
|
|
||||||
BBElement& newKeyValueElement(const std::string& name, const ParameterMap& pairs);
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& os, const ParameterMap& params)
|
|
||||||
{
|
|
||||||
bool first = true;
|
|
||||||
os << "{ ";
|
|
||||||
for (auto& p : params)
|
|
||||||
{
|
|
||||||
os << (first ? "" : ", ") << "{" << p.first << "=" << p.second << "}";
|
|
||||||
if (first)
|
|
||||||
{
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (os << " }");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace
|
|
@ -1,21 +0,0 @@
|
|||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2016
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
@ -1,105 +0,0 @@
|
|||||||
# bbcpp
|
|
||||||
|
|
||||||
[![Build Status][travis-img]][travis]
|
|
||||||
[![Build Status][appveyor-img]][appveyor]
|
|
||||||
|
|
||||||
|
|
||||||
## Introduction
|
|
||||||
|
|
||||||
bbcpp is a C++ library for parsing BBCode, or Bulletin Board Code, a markup language used to format posts in many message boards.
|
|
||||||
|
|
||||||
This library parses BBCode into a tree data structure that can be used to format output. However, this library does not include any output classes, though a basic HTML output class will likely be included.
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
auto doc = BBDocument::create();
|
|
||||||
doc->load("This is [b]an example[/b] of some text.");
|
|
||||||
```
|
|
||||||
|
|
||||||
## Element Types
|
|
||||||
|
|
||||||
#### Examples:
|
|
||||||
[B] - Bold text
|
|
||||||
[I] - Italicized text
|
|
||||||
[QUOTE] - Blockquote text (without specifiers as discussed below)
|
|
||||||
|
|
||||||
## Value Elements
|
|
||||||
|
|
||||||
#### Examples
|
|
||||||
[COLOR="green"]
|
|
||||||
[FONT="Arial Narrow"]
|
|
||||||
[SIZE="5"]
|
|
||||||
[EMAIL="billgates@microsoft.com"]
|
|
||||||
|
|
||||||
## The `QUOTE` Element
|
|
||||||
|
|
||||||
The **bbcpp** parser will accept three different formats for the `QUOTE` tag:
|
|
||||||
|
|
||||||
1. `[QUOTE user=Username postid=1234]`: A key-value pair of values. In theory they are space delimited unless quoted. (Used with phpBB)
|
|
||||||
1. `[QUOTE="username, post: 1799684, member: 11733"]`: Another key-value pair format except the first argument is assumed to be the username. (Used with XenForo)
|
|
||||||
1. `[QUOTE=Username;1234]`: `Username` is the name of the user being quoted and `1234` is the postid. (Used with vBulletin)
|
|
||||||
|
|
||||||
### `FONT`
|
|
||||||
|
|
||||||
### `COLOR`
|
|
||||||
|
|
||||||
### `LIST`/`[*]`
|
|
||||||
|
|
||||||
### `IMG`
|
|
||||||
|
|
||||||
### `URL`
|
|
||||||
|
|
||||||
## BBNode Tree
|
|
||||||
|
|
||||||
The following are examples of the node tree built during parsing.
|
|
||||||
|
|
||||||
#### Example 1
|
|
||||||
|
|
||||||
> `This is [b]an example[/b] of some text`
|
|
||||||
|
|
||||||
```
|
|
||||||
#document
|
|
||||||
│-- @"This is"
|
|
||||||
│-- [b]
|
|
||||||
│ │-- @"an example"
|
|
||||||
│ │-- [/b]
|
|
||||||
│-- @"of some text"
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Example 2
|
|
||||||
|
|
||||||
> `[QUOTE]This is [b]important[/b] news![/QUOTE]` <br/><br/>
|
|
||||||
> `Indeed it is!`
|
|
||||||
|
|
||||||
```
|
|
||||||
#document
|
|
||||||
│-- [QUOTE]
|
|
||||||
│ │-- @"This is "
|
|
||||||
│ │-- [b]
|
|
||||||
| | |-- @"important"
|
|
||||||
| | |-- [/b]
|
|
||||||
│ │-- @"news!"
|
|
||||||
│ │-- [/QUOTE]
|
|
||||||
│-- @"\n\nIndeed it is!"
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Example 3
|
|
||||||
> `[QUOTE user=Joe userid=1 postid=1234]This is another quote![/QUOTE]`<br/><br/>
|
|
||||||
> `I'm quoting you!`
|
|
||||||
|
|
||||||
```
|
|
||||||
#document
|
|
||||||
│-- [QUOTE]
|
|
||||||
| |-- {user=Joe}
|
|
||||||
| |-- {userid=1}
|
|
||||||
| |-- {postid=1234}
|
|
||||||
│ │-- @"This is another quote!"
|
|
||||||
│ │-- [/QUOTE]
|
|
||||||
│-- @"\n\nI'm quoting you!"
|
|
||||||
```
|
|
||||||
[travis-img]: https://travis-ci.org/zethon/bbcpp.svg?branch=master
|
|
||||||
[travis]: https://travis-ci.org/zethon/bbcpp
|
|
||||||
|
|
||||||
[appveyor-img]: https://ci.appveyor.com/api/projects/status/i7p4q2d0vvoyv8aq?svg=true
|
|
||||||
[appveyor]: https://ci.appveyor.com/project/zethon/bbcpp
|
|
@ -1,11 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
Import("env")
|
|
||||||
|
|
||||||
core_sources = []
|
|
||||||
|
|
||||||
env.add_source_files(core_sources, "*.cpp")
|
|
||||||
|
|
||||||
# Build it all as a library
|
|
||||||
lib = env.add_library("lib_bbcpp", core_sources)
|
|
||||||
env.Prepend(LIBS=[lib])
|
|
@ -1,131 +0,0 @@
|
|||||||
#include "BBDocument.h"
|
|
||||||
#include "bbcpputils.h"
|
|
||||||
|
|
||||||
namespace bbcpp
|
|
||||||
{
|
|
||||||
|
|
||||||
std::string nodeTypeToString(BBNode::NodeType type)
|
|
||||||
{
|
|
||||||
std::string retval = "Unknown";
|
|
||||||
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case BBNode::NodeType::DOCUMENT:
|
|
||||||
retval = "Document";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BBNode::NodeType::ELEMENT:
|
|
||||||
retval = "Element";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BBNode::NodeType::TEXT:
|
|
||||||
retval = "Text";
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper Functions
|
|
||||||
std::string getIndentString(const unsigned int indent)
|
|
||||||
{
|
|
||||||
std::stringstream output;
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < indent; i++)
|
|
||||||
{
|
|
||||||
output << "| ";
|
|
||||||
}
|
|
||||||
|
|
||||||
output << "|-- ";
|
|
||||||
return output.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
void printChildren(const BBNode& parent, unsigned int indent)
|
|
||||||
{
|
|
||||||
for (const auto node : parent.getChildren())
|
|
||||||
{
|
|
||||||
switch (node->getNodeType())
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BBNode::NodeType::ELEMENT:
|
|
||||||
{
|
|
||||||
const auto element = node->downCast<BBElementPtr>();
|
|
||||||
std::cout
|
|
||||||
<< getIndentString(indent)
|
|
||||||
<< "["
|
|
||||||
<< (element->getElementType() == BBElement::CLOSING ? "/" : "")
|
|
||||||
<< element->getNodeName() << "]"
|
|
||||||
<< std::endl;
|
|
||||||
|
|
||||||
if (element->getElementType() == BBElement::PARAMETER)
|
|
||||||
{
|
|
||||||
std::cout
|
|
||||||
<< getIndentString(indent + 1)
|
|
||||||
<< element->getParameters()
|
|
||||||
<< std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BBNode::NodeType::TEXT:
|
|
||||||
{
|
|
||||||
const auto textnode = node->downCast<BBTextPtr>();
|
|
||||||
std::cout << getIndentString(indent)
|
|
||||||
<< "@\"" << textnode->getText() << "\""
|
|
||||||
<< std::endl;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
printChildren(*node, indent+1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void printDocument(const BBDocument& doc)
|
|
||||||
{
|
|
||||||
std::cout << "#document" << std::endl;
|
|
||||||
|
|
||||||
auto indent = 0u;
|
|
||||||
printChildren(doc, indent);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string getRawString(const BBNode& parent)
|
|
||||||
{
|
|
||||||
std::string root = "";
|
|
||||||
for (const auto node : parent.getChildren())
|
|
||||||
{
|
|
||||||
switch (node->getNodeType())
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BBNode::NodeType::ELEMENT:
|
|
||||||
{
|
|
||||||
const auto element = node->downCast<BBElementPtr>();
|
|
||||||
|
|
||||||
if (element->getElementType() == BBElement::PARAMETER)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BBNode::NodeType::TEXT:
|
|
||||||
{
|
|
||||||
const auto textnode = node->downCast<BBTextPtr>();
|
|
||||||
root += textnode->getText();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
root += getRawString(*node);
|
|
||||||
}
|
|
||||||
|
|
||||||
return root;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
@ -1,15 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "BBDocument.h"
|
|
||||||
|
|
||||||
namespace bbcpp
|
|
||||||
{
|
|
||||||
|
|
||||||
// Helper Functions
|
|
||||||
std::string nodeTypeToString(BBNode::NodeType type);
|
|
||||||
std::string getIndentString(const unsigned int indent);
|
|
||||||
void printChildren(const BBNode& parent, unsigned int indent);
|
|
||||||
void printDocument(const BBDocument& doc);
|
|
||||||
std::string getRawString(const BBNode& node);
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user