Removed bbcpp.

This commit is contained in:
Relintai 2020-12-27 03:36:56 +01:00
parent 6c56380d90
commit ba90610e3e
9 changed files with 0 additions and 1232 deletions

View File

@ -23,26 +23,6 @@ void Utils::markdown_to_html(std::string *str) {
(*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) {
if (from.empty())
return;
@ -53,205 +33,3 @@ void Utils::str_replace(std::string *str, const std::string &from, const std::st
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;
}
}
}

View File

@ -3,9 +3,6 @@
#include <string>
#include <bbcpp/BBDocument.h>
class Utils {
public:
static void newline_to_br(std::string *str);
@ -13,13 +10,8 @@ class Utils {
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);
protected:
static void eval_node(std::string *str, bbcpp::BBNodePtr node);
static void eval_element(std::string *str, bbcpp::BBElementPtr node);
};

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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])

View File

@ -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

View File

@ -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);
}