+#ifndef __BIAWEB__
+#define __BIAWEB__
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <list>
+#include <memory>
+#include <ctime>
+#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 <mkdio.h>
+}
+// 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<SideBar> 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<char> (ftmp)),
+ (std::istreambuf_iterator<char> ())
+ );
+
+ 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<char> (tpl)),
+ (std::istreambuf_iterator<char> ()) );
+ 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<char[]> 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