346 lines
7.2 KiB
C++
346 lines
7.2 KiB
C++
#include <cctype>
|
|
#include <cstring>
|
|
#include <iostream>
|
|
#include <map>
|
|
#include <vector>
|
|
|
|
#include "mindgen_funcs.h"
|
|
|
|
using namespace std;
|
|
|
|
struct tag_struct
|
|
{
|
|
string name;
|
|
map<string, string> params;
|
|
bool is_closed;
|
|
bool is_closing;
|
|
};
|
|
|
|
void indent(ostream& _out, int _count);
|
|
void write_initial_html(ostream& _out, int _part);
|
|
void write_node_recursive(ostream& _out, const MindNode* _root, int _indent_count);
|
|
void get_tag(istream& _in, string& _content);
|
|
void generate_map(string& _content, tag_struct& _tag);
|
|
|
|
// DEFININTIONS
|
|
void
|
|
indent(ostream& out, int count)
|
|
{
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
out << "\t";
|
|
}
|
|
}
|
|
|
|
void
|
|
write_initial_html(ostream& out, int part)
|
|
{
|
|
switch (part)
|
|
{
|
|
case 0:
|
|
out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl;
|
|
out << "<?xml-stylesheet href=\"files/treestyles.css\" type=\"text/css\"?>" << endl;
|
|
out << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">" << endl;
|
|
out << "<html xmlns=\"http://www.w3.org/1999/xhtml\">" << endl;
|
|
out << "\t<head>" << endl;
|
|
out << "\t\t<meta content=\"text/html; charset=UTF-8\" http-equiv=\"Content-Type\" />" << endl;
|
|
out << "\t\t<title>";
|
|
break;
|
|
|
|
case 1:
|
|
out << "</title>" << endl;
|
|
out << "\t\t<link rel=\"stylesheet\" href=\"files/treestyles.css\" type=\"text/css\" />" << endl;
|
|
out << "\t\t<script type=\"text/javascript\" src=\"files/marktree.js\"></script>" << endl;
|
|
out << "\t</head>" << endl;
|
|
out << "\t<body>" << endl;
|
|
out << "\t\t<div class=\"basetop\">" << endl;
|
|
out << "\t\t\t<a onclick=\"expandAll(document.getElementById('base'))\" href=\"#\">Expand</a>" << endl;
|
|
out << "\t\t\t-" << endl;
|
|
out << "\t\t\t<a onclick=\"collapseAll(document.getElementById('base'))\" href=\"#\">Collapse</a>" << endl;
|
|
out << "\t\t</div>" << endl;
|
|
out << "\t\t<div class=\"basetext\" id=\"base\">" << endl;
|
|
out << "\t\t\t<ul>" << endl;
|
|
break;
|
|
|
|
case 2:
|
|
out << "\t\t\t</ul>" << endl;
|
|
out << "\t\t</div>" << endl;
|
|
out << "\t</body>" << endl;
|
|
out << "</html>" << endl;
|
|
break;
|
|
}
|
|
}
|
|
|
|
void
|
|
write_node_recursive(ostream& out, const MindNode* root, int indent_count)
|
|
{
|
|
while (NULL != root)
|
|
{
|
|
indent(out, indent_count);
|
|
if (NULL == root->getFirstChild())
|
|
{
|
|
out << "<li class=\"basic\" id=\"FM" << root->getID() << "FM\">" << endl;
|
|
}
|
|
else
|
|
{
|
|
out << "<li class=\"col\" id=\"FM" << root->getID() << "FM\">" << endl;
|
|
}
|
|
|
|
// If there are icons - print them
|
|
if (!root->getIcons().empty())
|
|
{
|
|
vector<string> icons = root->getIcons();
|
|
for (vector<string>::iterator it = icons.begin(); it != icons.end(); ++it)
|
|
{
|
|
indent(out, indent_count + 1);
|
|
out << "<img src=\"files/icons/" << *it << ".png\"/>" << endl;
|
|
}
|
|
}
|
|
|
|
indent(out, indent_count + 1);
|
|
out << "<div class=\"nodecontent\">" << endl;
|
|
|
|
indent(out, indent_count + 2);
|
|
if (!root->getLink().empty())
|
|
{
|
|
out << "<a href=\"" << root->getLink() << "\">";
|
|
}
|
|
|
|
out << root->getText();
|
|
|
|
if (!root->getLink().empty())
|
|
{
|
|
out << "</a>" << endl;
|
|
indent(out, indent_count + 2);
|
|
out << "<a href=\"" << root->getLink() << "\">" << endl;
|
|
|
|
indent(out, indent_count + 3);
|
|
out << "<img src=\"files/ilink.png\" style=\"border-width:0\" />" << endl;
|
|
|
|
indent(out, indent_count + 2);
|
|
out << "</a>";
|
|
}
|
|
|
|
out << endl;
|
|
|
|
indent(out, indent_count + 1);
|
|
out << "</div>" << endl;
|
|
|
|
if (NULL != root->getFirstChild())
|
|
{
|
|
indent(out, indent_count + 1);
|
|
out << "<ul class=\"subexp\">" << endl;
|
|
write_node_recursive(out, root->getFirstChild(), indent_count + 2);
|
|
|
|
indent(out, indent_count + 1);
|
|
out << "</ul>" << endl;
|
|
}
|
|
indent(out, indent_count);
|
|
out << "</li>" << endl;
|
|
|
|
root = root->getNextNode();
|
|
}
|
|
}
|
|
|
|
void
|
|
get_tag(istream& in, string& content)
|
|
{
|
|
char symbol;
|
|
|
|
in.get(symbol);
|
|
while ('>' != symbol)
|
|
{
|
|
content += symbol;
|
|
in.get(symbol);
|
|
}
|
|
}
|
|
|
|
void
|
|
generate_map(string& content, tag_struct& tag)
|
|
{
|
|
size_t index;
|
|
string name;
|
|
string value;
|
|
|
|
tag.params.clear();
|
|
tag.name.clear();
|
|
tag.is_closed = false;
|
|
tag.is_closing = false;
|
|
|
|
// Removes header / trailer slashes and skips comments
|
|
if ('/' == content[0])
|
|
{
|
|
tag.is_closing = true;
|
|
content.erase(0, 1);
|
|
}
|
|
if ('/' == content[content.size() - 1])
|
|
{
|
|
tag.is_closed = true;
|
|
content.erase(content.size() - 1, 1);
|
|
}
|
|
if ('!' == content[0])
|
|
{
|
|
return;
|
|
}
|
|
|
|
// First word is the name
|
|
index = content.find(' ');
|
|
tag.name = content.substr(0, index);
|
|
if (string::npos == index)
|
|
{
|
|
content.clear();
|
|
}
|
|
else
|
|
{
|
|
content.erase(0, index + 1);
|
|
}
|
|
// If we have more than just a name
|
|
while (!content.empty())
|
|
{
|
|
index = content.find('=');
|
|
name = content.substr(0, index);
|
|
content.erase(0, index + 2);
|
|
|
|
index = content.find('"');
|
|
value = content.substr(0, index);
|
|
content.erase(0, index + 1);
|
|
tag.params.insert(pair<string, string>(name, value));
|
|
if (!content.empty())
|
|
{
|
|
content.erase(0, 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
// HEADER FUNCS
|
|
|
|
int
|
|
parse_mindmap(istream& in, MindNode** root)
|
|
{
|
|
char parse = '\0';
|
|
string search;
|
|
string content;
|
|
tag_struct current_tag;
|
|
|
|
MindNode* current_node = NULL;
|
|
|
|
while (!in.eof())
|
|
{
|
|
// Find Next Tag
|
|
in.get(parse);
|
|
while ((parse != '<') && (!in.eof()))
|
|
{
|
|
in.get(parse);
|
|
}
|
|
if (in.eof())
|
|
{
|
|
break;
|
|
}
|
|
|
|
content = "";
|
|
get_tag(in, content);
|
|
generate_map(content, current_tag);
|
|
|
|
// Map parse
|
|
if ("map" == current_tag.name)
|
|
{
|
|
if (NULL != current_node)
|
|
{
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
// Node Parse
|
|
if ("node" == current_tag.name)
|
|
{
|
|
if (current_tag.is_closing)
|
|
{
|
|
current_node = current_node->getParent();
|
|
}
|
|
else
|
|
{
|
|
MindNode* node_new = new MindNode();
|
|
|
|
if (current_tag.params.end() != current_tag.params.find("ID"))
|
|
{
|
|
node_new->setID(current_tag.params.find("ID")->second);
|
|
}
|
|
|
|
if (current_tag.params.end() != current_tag.params.find("TEXT"))
|
|
{
|
|
node_new->setText(current_tag.params.find("TEXT")->second);
|
|
}
|
|
|
|
if (current_tag.params.end() != current_tag.params.find("LINK"))
|
|
{
|
|
node_new->setLink(current_tag.params.find("LINK")->second);
|
|
}
|
|
|
|
if (NULL == current_node)
|
|
{
|
|
*root = node_new;
|
|
}
|
|
else
|
|
{
|
|
node_new->setParent(current_node);
|
|
|
|
if(NULL == current_node->getFirstChild())
|
|
{
|
|
current_node->setFirstChild(node_new);
|
|
}
|
|
else
|
|
{
|
|
MindNode* last_child = current_node->getFirstChild();
|
|
while(NULL != last_child->getNextNode())
|
|
{
|
|
last_child = last_child->getNextNode();
|
|
}
|
|
last_child->setNextNode(node_new);
|
|
}
|
|
}
|
|
current_node = node_new;
|
|
|
|
if (current_tag.is_closed)
|
|
{
|
|
current_node = current_node->getParent();
|
|
}
|
|
}
|
|
}
|
|
|
|
if ("icon" == current_tag.name)
|
|
{
|
|
if (current_tag.params.end() != current_tag.params.find("BUILTIN"))
|
|
{
|
|
current_node->addIcon(current_tag.params.find("BUILTIN")->second);
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void
|
|
write_html(ostream& out, const MindNode* root)
|
|
{
|
|
if (NULL == root)
|
|
{
|
|
cerr << "Error at \"" << __FILE__ << "\" on line " << __LINE__ << endl;
|
|
cerr << "Root node is NULL" << endl;
|
|
return;
|
|
}
|
|
|
|
// Write first part html
|
|
write_initial_html(out, 0);
|
|
|
|
// Write title
|
|
out << root->getText();
|
|
|
|
// Write next part html
|
|
write_initial_html(out, 1);
|
|
|
|
// Write node structure
|
|
write_node_recursive(out, root, 4);
|
|
|
|
// Write last part html
|
|
write_initial_html(out, 2);
|
|
}
|