From 9dd960dd37c92af1ca6531c72b82849ea59a354c Mon Sep 17 00:00:00 2001 From: Harishankar Date: Fri, 15 May 2020 22:30:57 +0530 Subject: [PATCH 1/1] First Commit First commit of BiaWeb2 project --- CMakeLists.txt | 6 + biaweb | Bin 0 -> 219464 bytes biaweb.cpp | 58 +++++++++ biawebdocument.hpp | 202 +++++++++++++++++++++++++++++ biawebdocumenttree.hpp | 160 +++++++++++++++++++++++ biawebsidebar.hpp | 129 ++++++++++++++++++ biawebutil.hpp | 42 ++++++ templates/main.tpl.html | 75 +++++++++++ templates/sidebar.tpl.html | 4 + templates/sidebaritem.tpl.html | 1 + templates/sidebarlinkitem.tpl.html | 1 + 11 files changed, 678 insertions(+) create mode 100644 CMakeLists.txt create mode 100755 biaweb create mode 100644 biaweb.cpp create mode 100644 biawebdocument.hpp create mode 100644 biawebdocumenttree.hpp create mode 100644 biawebsidebar.hpp create mode 100644 biawebutil.hpp create mode 100644 templates/main.tpl.html create mode 100644 templates/sidebar.tpl.html create mode 100644 templates/sidebaritem.tpl.html create mode 100644 templates/sidebarlinkitem.tpl.html diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..cc14265 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required (VERSION 3.0) +project (biaweb2 CXX) +set (CMAKE_CXX_STANDARD 17) +add_executable (biaweb biaweb.cpp) +target_link_libraries (biaweb markdown) + diff --git a/biaweb b/biaweb new file mode 100755 index 0000000000000000000000000000000000000000..3681f1ba6b83cad49986fc936f20a5b9588348d9 GIT binary patch literal 219464 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 P#F>8gXM+oZKllC*4KGBX literal 0 HcmV?d00001 diff --git a/biaweb.cpp b/biaweb.cpp new file mode 100644 index 0000000..a50bf01 --- /dev/null +++ b/biaweb.cpp @@ -0,0 +1,58 @@ +#include +#include +#include "biawebdocumenttree.hpp" +using namespace biaweb; + +int main (int argc, char *argv[]) { + + if (argc == 2) + { + std::shared_ptr tree (new DocumentTree (argv[1])); + + std::shared_ptr a1 (new DocumentTree("Child a1")); + std::shared_ptr a2 (new DocumentTree("Child a2")); + std::shared_ptr a3 (new DocumentTree("Child a3")); + std::shared_ptr a4 (new DocumentTree("Child a4")); + a3.get()->add_child (a4.get()); + a1.get()->add_child (a2.get()); + a1.get()->add_child (a3.get()); + tree.get()->add_child (a1.get()); + std::cout << a3.get()->stub_hierarchy () << a3.get()->get_stub () << std::endl; + tree.get()->visualize_tree (); + tree.get()->create_index (); + } + else + std::cout << "Usage: " << argv[0] << "

" << std::endl; + + // Document doc; + // SideBar items; + // std::string title, contents, sidetitle; + // std::cout << "Enter document title: "; + // std::getline (std::cin, title); + // std::cout << "Enter markdown file of document: "; + // std::getline (std::cin, contents); + // while (1) { + // std::string name, url; + // std::cout << "Enter a sidebar item text (empty to end): "; + // std::getline (std::cin, name); + // if (name.empty()) break; + // std::cout << "Enter a sidebar item URL: "; + // std::getline (std::cin, url); + // SideBarItem item (name, url); + // items.add_sidebar_item (item); + // } + // std::cout << "Enter heading for sidebar: "; + // std::getline (std::cin, sidetitle); + // items.set_title (sidetitle); + // doc.set_title (title); + // std::ifstream f (contents); + // std::string markdown_contents ( (std::istreambuf_iterator (f)), + // (std::istreambuf_iterator ()) ); + + // doc.set_markdown_content (markdown_contents); + // doc.add_side_bar (items); + + // doc.output_to_html (); + + return 0; +} diff --git a/biawebdocument.hpp b/biawebdocument.hpp new file mode 100644 index 0000000..f001373 --- /dev/null +++ b/biawebdocument.hpp @@ -0,0 +1,202 @@ +#ifndef __BIAWEB__ +#define __BIAWEB__ +#include +#include +#include +#include +#include +#include +#include "biawebutil.hpp" +#include "biawebsidebar.hpp" + +// "discount" markdown library is a C library and hence requires to be wrapped in +// extern "C" +extern "C" { + #include +} +// class to represent a biaweb document which can have a file name, title, description, +// keywords, content and sidebar items +namespace biaweb { + class Document + { + protected: + std::string filename; + std::string title; + std::string meta_desc; + std::string meta_keywords; + std::string content; + std::list sidebars; + std::time_t cdate; + std::time_t mdate; + bool is_index; + + public: + Document (std::string title = "", std::string meta_desc = "", + std::string meta_keywords = "", std::string content = "", + bool is_index = false, std::time_t cdate= std::time(nullptr), + std::time_t mdate = std::time(nullptr)) + { + this->title = title; + this->meta_desc = meta_desc; + this->meta_keywords = meta_keywords; + this->content = content; + this->is_index = is_index; + if (is_index) + this->filename = convert_title (title); + else + this->filename = "index"; + this->cdate = cdate; + this->mdate = mdate; + } + + // set whether this is the index document + void set_index (bool index = true) { + this->is_index = index; + } + + // get whether this is the index document + bool get_index () { + return this->is_index; + } + + // set the document modification date + void set_modified_date (std::time_t modif) { + this->mdate = modif; + } + + // get the document modification date + std::time_t get_modified_date () { + return this->mdate; + } + + // set the document creation date + void set_creation_date (std::time_t creat) { + this->cdate = creat; + } + + // get the document creation date + std::time_t get_creation_date () { + return this->cdate; + } + + // output the document to HTML using the template + void output_to_html (std::string path); + + // set the content portion of document as raw HTML content + void set_content (std::string content) { + this->content = content; + } + + // read the contents of marked marked-up content string "str" into the + // contents after converting to HTML. + void set_markdown_content (std::string str); + + void set_meta_keywords(std::string meta_keywords) { + this->meta_keywords = meta_keywords; + } + + void set_meta_desc(std::string meta_desc) { + this->meta_desc = meta_desc; + } + + void set_title(std::string title) { + this->title = title; + if (this->is_index) + this->filename = "index"; + else + this->filename = convert_title (title); + } + + std::string get_content () { + return this->content; + } + + std::string get_meta_keywords() { + return this->meta_keywords; + } + + std::string get_meta_desc() { + return this->meta_desc; + } + + std::string get_title() { + return this->title; + } + + void add_side_bar (SideBar bar) { + sidebars.insert (sidebars.cend(), bar); + } + }; + + void Document::set_markdown_content (std::string str) { + // discount is a C library and it doesn't work well with C++ streams + // and there seems no way to get the output of any of these functions + // into an std::string. + // the only option seems to be to write the output of the markdown() + // function to a temporary working file and then read it back into C++ + // with the normal std::ifstream and feed it into the std::string + // till a cleaner solution can be found. + MMIOT *doc; + doc = mkd_string (str.c_str(), str.size(), 0); + FILE *f = fopen (".biaweb.tmp", "w"); + markdown (doc, f, 0); + fclose (f); + std::ifstream ftmp (".biaweb.tmp"); + std::string tmpl ( (std::istreambuf_iterator (ftmp)), + (std::istreambuf_iterator ()) + ); + + while (! ftmp.eof ()) + { + std::string line; + ftmp >> line; + tmpl.append (line); + tmpl.append (" "); + } + ftmp.close (); + remove (".biaweb.tmp"); + this->content.append (tmpl); + mkd_cleanup (doc); + } + + void Document::output_to_html (std::string path) + { + std::ifstream tpl; + tpl.open ("templates/main.tpl.html", std::ios_base::openmode::_S_in); + std::string main_tpl ( (std::istreambuf_iterator (tpl)), + (std::istreambuf_iterator ()) ); + tpl.close (); + // first render the sidebars + std::string sidebartext; + for (SideBar bar : sidebars) { + sidebartext += bar.to_html (); + } + + char ctm_str[100], mtm_str[100]; + std::time_t creat = this->cdate; + std::time_t modif = this->cdate; + std::strftime (ctm_str, sizeof (ctm_str), + "%d %b %Y, %H:%M", std::localtime (&creat)); + std::strftime (mtm_str, sizeof (mtm_str), + "%d %b %Y, %H:%M", std::localtime (&modif)); + + // Allocate enough space for the output buffer + std::unique_ptr final_templ( + new char[main_tpl.size()+ + this->title.size()+ + this->content.size() + + this->meta_desc.size() + + this->meta_keywords.size () + + 200 + + sidebartext.size()]); + std::sprintf (final_templ.get (), main_tpl.c_str(), this->title.c_str(), + ctm_str, mtm_str, + this->content.c_str(), sidebartext.c_str()); + + std::ofstream f (path + "/" + this->filename + ".html"); + f << final_templ.get (); + f.close (); + } +} + +#endif diff --git a/biawebdocumenttree.hpp b/biawebdocumenttree.hpp new file mode 100644 index 0000000..9c91ed9 --- /dev/null +++ b/biawebdocumenttree.hpp @@ -0,0 +1,160 @@ +#ifndef __BIAWEBDOCUMENTTREE__ +#define __BIAWEBDOCUMENTTREE__ +#include +#include +#include +#include +#include "biawebdocument.hpp" + +// to implement a document tree - both with or without subtrees +namespace biaweb { + class DocumentTree { + protected: + // the pointer to the parent tree if there is one or nullptr + DocumentTree* parent; + // child trees + std::list children; + // title of this tree + std::string title; + // file stub of this tree + std::string stub; + // list of documents in this tree + std::list docs; + // set the parent - protected function as this has to be + // called only by add_child + void set_parent (DocumentTree *parent) { + this->parent = parent; + } + + public: + // create new top level document tree + DocumentTree (std::string title, std::string stub = "") { + this->title = title; + // if stub is not empty set it + if (stub != "") + this->stub = stub; + // make the stub from the title + else + this->stub = convert_title (title); + this->parent = nullptr; + } + + // create the document index for this tree + void create_index (); + + // set the title + void set_title (std::string title) { + this->title = title; + // if no stub is set + if (this->stub == "") + this->stub = convert_title (title); + } + + // set the stub either from a text or convert the title to stub + // if no stub is set explicitly + void set_stub (std::string stub) { + if (stub != "") + this->stub = stub; + else + this->stub = convert_title (this->title); + } + + std::string get_title () { + return this->title; + } + + std::string get_stub () { + return this->stub; + } + + // get the child level of this tree + unsigned int get_level (); + + // get the stub hierarchy + std::string stub_hierarchy () { + std::list levels; + DocumentTree *par = this->get_parent(); + while (par!= nullptr) { + levels.push_front (par->get_stub()); + par = par->get_parent (); + } + std::string stub_str; + for (std::string level : levels) { + stub_str += level + "/"; + } + return stub_str; + } + + // add a child tree to this tree + void add_child (DocumentTree *child) { + child->set_parent (this); + this->children.push_back (*child); + } + + // add a document to this tree + void add_document (Document *doc) { + this->docs.push_back (*doc); + } + + // print a visual representation of this tree with levels + void visualize_tree (); + + // get a pointer to the parent of this tree + DocumentTree *get_parent () { + return this->parent; + } + }; + + // get the tree level - 0 if top level + unsigned int DocumentTree::get_level () { + unsigned int lev = 0; + DocumentTree *par = this->get_parent (); + while (par != nullptr) { + lev ++; + par = par->get_parent (); + } + return lev; + } + + // print the representation of this tree + void DocumentTree::visualize_tree () { + // print the tree level + std::cout << std::setw(3) << std::left << this->get_level (); + // indent as per the level + for (unsigned int i = 0; i < this->get_level(); i ++) + std::cout << "+--"; + // print the title of this tree + std::cout << this->title << std::endl; + // recurse through the child trees if any and so on + for (DocumentTree child : children) + child.visualize_tree (); + } + + // create the tree index - the index file for this tree + void DocumentTree::create_index () { + std::unique_ptr index (new Document (this->title)); + index.get()->set_index (); + // set the file name + std::string filepath = this->stub_hierarchy () + + this->stub; + // create the sidebar + std::unique_ptr bar (new SideBar ()); + bar.get()->set_title (this->title); + for (DocumentTree tree : this->children) { + SideBarItem item (tree.get_title(), filepath + "/" + + tree.stub + "/" + "index.html"); + bar.get()->add_sidebar_item (item); + } + index.get()->add_side_bar (*bar.get()); + + // create the path and then the index file + std::filesystem::create_directories (filepath); + index->output_to_html (filepath); + + // create index for children + for (DocumentTree tree : this->children) + tree.create_index (); + } +} + +#endif diff --git a/biawebsidebar.hpp b/biawebsidebar.hpp new file mode 100644 index 0000000..5b73b75 --- /dev/null +++ b/biawebsidebar.hpp @@ -0,0 +1,129 @@ +#ifndef __BIAWEBSIDEBAR__ +#define __BIAWEBSIDEBAR__ +#include +#include +#include +#include +#include "biawebutil.hpp" + +// classes to describe the sidebar and sidebar item containers which form part of +// main document +namespace biaweb { + // class to represent a sidebar item which can contain a text and link or only + // text + class SideBarItem { + protected: + // sidebar text and url + std::string sidebar_text; + std::string sidebar_url; + public: + std::string get_sidebar_text () { + return this->sidebar_text; + } + void set_sidebar_text (std::string text) { + this->sidebar_text = text; + } + std::string get_sidebar_url () { + return this->sidebar_url; + } + void set_sidebar_url (std::string url) { + this->sidebar_url = url; + } + std::string to_html (); + + SideBarItem (std::string text = "", std::string url = "") { + this->sidebar_text = text; + this->sidebar_url = url; + } + }; + + std::string SideBarItem::to_html () { + std::string html; + // if url is not empty it is a link item so load the sidebar link template + if (! this->sidebar_url.empty ()) { + if (!this->sidebar_text.empty ()) + { + std::ifstream tpl_linkitem ("templates/sidebarlinkitem.tpl.html"); + std::string tpl_linkitem_str ( (std::istreambuf_iterator (tpl_linkitem)), + (std::istreambuf_iterator ())); + tpl_linkitem.close (); + std::unique_ptr linktxt (new char[tpl_linkitem_str.size() + + this->sidebar_text.size () + + this->sidebar_url.size ()] ); + std::sprintf (linktxt.get(), tpl_linkitem_str.c_str (), + this->sidebar_url.c_str (), + this->sidebar_text.c_str ()); + html.append (linktxt.get ()); + } + // no text or url - item is empty - so it should be blank + else + html = ""; + } + // Non link item. Load the normal sidebar item template. + else + { + std::ifstream tpl_item ("templates/sidebaritem.tpl.html"); + std::string tpl_item_str ( (std::istreambuf_iterator (tpl_item)), + (std::istreambuf_iterator ())); + tpl_item.close (); + std::unique_ptr txt (new char [tpl_item_str.size () + + this->sidebar_text.size ()]); + std::sprintf (txt.get (), tpl_item_str.c_str(), this->sidebar_text.c_str()); + html.append (txt.get ()); + } + return html; + } + + // Class to represent a sidebar, which contains one heading and a list of items + // either links or non-link items. + class SideBar { + protected: + std::string sidebar_title; + std::list items; + + public: + void set_title (std::string title) { + this->sidebar_title = title; + } + + void add_sidebar_item (SideBarItem item) { + items.insert (items.cend(), item); + } + + // render the sidebar + std::string to_html () ; + }; + + // render the sidebar to HTML representation from the template. + std::string SideBar::to_html () { + std::ifstream sidetpl ("templates/sidebar.tpl.html"); + std::string sidetpl_str ( ( std::istreambuf_iterator (sidetpl)) , + (std::istreambuf_iterator ())); + sidetpl.close (); + std::string listitem; + // first get the sidebar items and render them to HTML + for (SideBarItem item : items) { + listitem += item.to_html (); + } + + std::unique_ptr tpl_final (new char[sidetpl_str.size() + + this->sidebar_title.size () + + listitem.size () ]); + + std::string html; + // if there are items, sidebar should be rendered + if (items.size () > 0) + { + std::sprintf (tpl_final.get (), sidetpl_str.c_str(), + this->sidebar_title.c_str(), listitem.c_str()) ; + html.append ( tpl_final.get ()); + } + // no items in the sidebar, render as empty string (even if it has a heading) + // since heading becomes meaningless without items + else + html = ""; + return html; + } +} + +#endif diff --git a/biawebutil.hpp b/biawebutil.hpp new file mode 100644 index 0000000..36aa0df --- /dev/null +++ b/biawebutil.hpp @@ -0,0 +1,42 @@ +#ifndef __BIAWEBUTIL__ +#define __BIAWEBUTIL__ +#include + +// utility functions for Biaweb that don't fit into any class and can be used by +// any class +namespace biaweb { + // convert a document title to a file title - strip out the non-alpha + // chars and spaces + std::string convert_title (std::string title) + { + std::string output; + for (char c : title) { + if (isalnum (c)) + output.append (1, c); + else if (isspace (c)) + output.append (1, '_'); + } + return output; + } + + // escape HTML special characters + std::string escape_html (std::string source) + { + std::string replace_buf; + replace_buf.reserve (source.size()); + for (char p : source) + { + switch (p) + { + case '&' : replace_buf.append ("&"); break; + case '<' : replace_buf.append ("<"); break; + case '>' : replace_buf.append (">"); break; + case '\"': replace_buf.append ("""); break; + case '\'': replace_buf.append ("'"); break; + default : replace_buf.append (1, p); + } + } + return replace_buf; + } +} +#endif \ No newline at end of file diff --git a/templates/main.tpl.html b/templates/main.tpl.html new file mode 100644 index 0000000..197cb80 --- /dev/null +++ b/templates/main.tpl.html @@ -0,0 +1,75 @@ + + + +%s + + + + + +
+ +
+
Created on: %s, last modified: %s
+ %s +
+ + +
+ + + diff --git a/templates/sidebar.tpl.html b/templates/sidebar.tpl.html new file mode 100644 index 0000000..a2e7c05 --- /dev/null +++ b/templates/sidebar.tpl.html @@ -0,0 +1,4 @@ +

%s

+
    +%s +
\ No newline at end of file diff --git a/templates/sidebaritem.tpl.html b/templates/sidebaritem.tpl.html new file mode 100644 index 0000000..c6209ee --- /dev/null +++ b/templates/sidebaritem.tpl.html @@ -0,0 +1 @@ +
  • %s
  • \ No newline at end of file diff --git a/templates/sidebarlinkitem.tpl.html b/templates/sidebarlinkitem.tpl.html new file mode 100644 index 0000000..07afc4b --- /dev/null +++ b/templates/sidebarlinkitem.tpl.html @@ -0,0 +1 @@ +
    \ No newline at end of file -- 2.20.1
  • %s