#ifndef MACRODOWN_NODES_H
#define MACRODOWN_NODES_H
#include <string>
#include <vector>
#include <memory>
#include <variant>
namespace macrodown
{
struct Node; // Forward declaration
struct Text
{
std::string content;
};
struct Macro
{
std::string name;
std::vector<std::unique_ptr<Node>> arguments;
bool is_special = false;
};
struct Group
{
std::vector<std::unique_ptr<Node>> children;
void addChild(std::unique_ptr<Node> node);
};
struct Node
{
using Data = std::variant<Text, Macro, Group>;
Data data;
Node(Text t) : data(std::move(t)) {}
Node(Macro m) : data(std::move(m)) {}
Node(Group g) : data(std::move(g)) {}
// Call function on each node in the tree. Callback function takes
// const Node& as argument.
template<typename Callback>
void forEach(Callback f) const
{
f(*this);
if(std::holds_alternative<Group>(data))
{
for(const std::unique_ptr<Node>& child:
std::get<Group>(data).children)
{
child->forEach(f);
}
}
else if(std::holds_alternative<Macro>(data))
{
for(const std::unique_ptr<Node>& arg:
std::get<Macro>(data).arguments)
{
arg->forEach(f);
}
}
}
};
// Inline implementation to avoid circular dependency issues in headers
inline void Group::addChild(std::unique_ptr<Node> node)
{
children.push_back(std::move(node));
}
} // namespace macrodown
#endif // MACRODOWN_NODES_H