First Commit
[biaweb2.git] / biawebdocumenttree.hpp
1 #ifndef __BIAWEBDOCUMENTTREE__
2 #define __BIAWEBDOCUMENTTREE__
3 #include <memory>
4 #include <list>
5 #include <iostream>
6 #include <filesystem>
7 #include "biawebdocument.hpp"
8
9 // to implement a document tree - both with or without subtrees
10 namespace biaweb {
11 class DocumentTree {
12 protected:
13 // the pointer to the parent tree if there is one or nullptr
14 DocumentTree* parent;
15 // child trees
16 std::list<DocumentTree> children;
17 // title of this tree
18 std::string title;
19 // file stub of this tree
20 std::string stub;
21 // list of documents in this tree
22 std::list<Document> docs;
23 // set the parent - protected function as this has to be
24 // called only by add_child
25 void set_parent (DocumentTree *parent) {
26 this->parent = parent;
27 }
28
29 public:
30 // create new top level document tree
31 DocumentTree (std::string title, std::string stub = "") {
32 this->title = title;
33 // if stub is not empty set it
34 if (stub != "")
35 this->stub = stub;
36 // make the stub from the title
37 else
38 this->stub = convert_title (title);
39 this->parent = nullptr;
40 }
41
42 // create the document index for this tree
43 void create_index ();
44
45 // set the title
46 void set_title (std::string title) {
47 this->title = title;
48 // if no stub is set
49 if (this->stub == "")
50 this->stub = convert_title (title);
51 }
52
53 // set the stub either from a text or convert the title to stub
54 // if no stub is set explicitly
55 void set_stub (std::string stub) {
56 if (stub != "")
57 this->stub = stub;
58 else
59 this->stub = convert_title (this->title);
60 }
61
62 std::string get_title () {
63 return this->title;
64 }
65
66 std::string get_stub () {
67 return this->stub;
68 }
69
70 // get the child level of this tree
71 unsigned int get_level ();
72
73 // get the stub hierarchy
74 std::string stub_hierarchy () {
75 std::list<std::string> levels;
76 DocumentTree *par = this->get_parent();
77 while (par!= nullptr) {
78 levels.push_front (par->get_stub());
79 par = par->get_parent ();
80 }
81 std::string stub_str;
82 for (std::string level : levels) {
83 stub_str += level + "/";
84 }
85 return stub_str;
86 }
87
88 // add a child tree to this tree
89 void add_child (DocumentTree *child) {
90 child->set_parent (this);
91 this->children.push_back (*child);
92 }
93
94 // add a document to this tree
95 void add_document (Document *doc) {
96 this->docs.push_back (*doc);
97 }
98
99 // print a visual representation of this tree with levels
100 void visualize_tree ();
101
102 // get a pointer to the parent of this tree
103 DocumentTree *get_parent () {
104 return this->parent;
105 }
106 };
107
108 // get the tree level - 0 if top level
109 unsigned int DocumentTree::get_level () {
110 unsigned int lev = 0;
111 DocumentTree *par = this->get_parent ();
112 while (par != nullptr) {
113 lev ++;
114 par = par->get_parent ();
115 }
116 return lev;
117 }
118
119 // print the representation of this tree
120 void DocumentTree::visualize_tree () {
121 // print the tree level
122 std::cout << std::setw(3) << std::left << this->get_level ();
123 // indent as per the level
124 for (unsigned int i = 0; i < this->get_level(); i ++)
125 std::cout << "+--";
126 // print the title of this tree
127 std::cout << this->title << std::endl;
128 // recurse through the child trees if any and so on
129 for (DocumentTree child : children)
130 child.visualize_tree ();
131 }
132
133 // create the tree index - the index file for this tree
134 void DocumentTree::create_index () {
135 std::unique_ptr<Document> index (new Document (this->title));
136 index.get()->set_index ();
137 // set the file name
138 std::string filepath = this->stub_hierarchy () +
139 this->stub;
140 // create the sidebar
141 std::unique_ptr<SideBar> bar (new SideBar ());
142 bar.get()->set_title (this->title);
143 for (DocumentTree tree : this->children) {
144 SideBarItem item (tree.get_title(), filepath + "/" +
145 tree.stub + "/" + "index.html");
146 bar.get()->add_sidebar_item (item);
147 }
148 index.get()->add_side_bar (*bar.get());
149
150 // create the path and then the index file
151 std::filesystem::create_directories (filepath);
152 index->output_to_html (filepath);
153
154 // create index for children
155 for (DocumentTree tree : this->children)
156 tree.create_index ();
157 }
158 }
159
160 #endif