freemind-mindgen/mindgen_funcs.cpp

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