X-Git-Url: https://harishankar.org/repos/?p=biaweb2.git;a=blobdiff_plain;f=biawebdocument.hpp;h=39721076dbe33eca14b68e7bf67e3b13e51788d5;hp=0c0b74ca33027d64b8043480156ade99a14b8a9c;hb=HEAD;hpb=abd61eb094efbfca05e6fe0f1dd34a3e8e7de7a2 diff --git a/biawebdocument.hpp b/biawebdocument.hpp index 0c0b74c..3972107 100644 --- a/biawebdocument.hpp +++ b/biawebdocument.hpp @@ -5,15 +5,15 @@ #include #include #include +#include #include +#include #include "biawebutil.hpp" #include "biawebsidebar.hpp" +#include "biawebstrings.hpp" +#include "biawebnavigationbit.hpp" +#include "biawebtemplate.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 { @@ -25,7 +25,8 @@ namespace biaweb { std::string meta_desc; std::string meta_keywords; std::string content; - std::list sidebars; + std::list sidebars; + NavigationBit navbit; std::time_t cdate; std::time_t mdate; bool is_index; @@ -36,9 +37,9 @@ namespace biaweb { 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->title = escape_html (title); + this->meta_desc = escape_html (meta_desc); + this->meta_keywords = escape_html (meta_keywords); this->content = content; this->is_index = is_index; if (! is_index) @@ -49,6 +50,20 @@ namespace biaweb { this->mdate = mdate; } + // Constructor to parse the document from a stream instead of manually creating it + // File should be of the format + // first line: title + // second line: Description + // third line: Keywords + // fourth line: (creation date) YYYY-MM-DD HH:II TZ format + // fourth line onwards: Markdown contents + Document (std::istream &file) ; + + // set the navigation bit + void set_navigation_bit (NavigationBit navbit) { + this->navbit = navbit; + } + // set whether this is the index document void set_index (bool index = true) { this->is_index = index; @@ -86,8 +101,8 @@ namespace biaweb { return this->cdate; } - // output the document to HTML using the template - void output_to_html (std::string path); + // output the document to HTML using the template specified + void output_to_html (Template *t, std::string path); // set the content portion of document as raw HTML content void set_content (std::string content) { @@ -99,11 +114,11 @@ namespace biaweb { void set_markdown_content (std::string str); void set_meta_keywords(std::string meta_keywords) { - this->meta_keywords = meta_keywords; + this->meta_keywords = escape_html (meta_keywords); } void set_meta_desc(std::string meta_desc) { - this->meta_desc = meta_desc; + this->meta_desc = escape_html (meta_desc); } void set_title(std::string title) { @@ -135,73 +150,85 @@ namespace biaweb { } }; + // Parse and construct a document from a stream instead of individual fields + Document::Document (std::istream &infile) { + infile.seekg (0); + // parse the title, description, keywords, creation time and and contents + std::string title, description, keywords, creattime, contents; + // read the title + std::getline (infile, title); + if (infile.eof ()) return; + this->title = escape_html (title); + this->filename = convert_title (title); + // read description + std::getline (infile, description); + if (infile.eof ()) return; + this->meta_desc = escape_html (description); + // read the keywords + std::getline (infile, keywords); + if (infile.eof ()) return; + this->meta_keywords = escape_html (keywords); + // read the creation date/time and also set the modification time + // to creation date/time by default + std::getline (infile, creattime); + if (infile.eof ()) return; + std::stringstream s (creattime); + std::tm t; + s >> std::get_time (&t, DATE_IN_FORMAT); + if (s.fail ()) + std::cout << WARNING_PARSE_FAILED << this->filename << "\n"; + + this->cdate = mktime (&t); + this->mdate = this->cdate; + // read the rest of contents + std::string line; + while (! infile.eof ()) { + std::getline (infile, line); + contents.append (line + "\n"); + } + this->set_markdown_content (contents); + } + 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); + this->content = convert_to_markdown (str); } - void Document::output_to_html (std::string path) + // output the document using the provided template + void Document::output_to_html (Template *t, 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 (); + std::string templstr = t->get_main_tpl (); + + // read the style template file + std::string stylesheet = t->get_style_tpl (); // 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()); + sidebartext += bar.to_html (t); + } + + // render the navigation bit + std::string navbit_str = this->navbit.to_html (t); + + // time of creation and modification + struct std::tm c, m; + c = *std::localtime (&this->cdate); + m = *std::localtime (&this->mdate); + + // format the template with the values + std::string outputhtml = fmt::format (templstr, + fmt::arg ("title", this->title), + fmt::arg ("keywords", this->meta_keywords), + fmt::arg ("stylesheet", stylesheet), + fmt::arg ("description", this->meta_desc), + fmt::arg ("cdate", c), + fmt::arg ("mdate", m), + fmt::arg ("navbit", navbit_str), + fmt::arg ("contents", this->content), + fmt::arg ("sidebar", sidebartext) + ); std::ofstream f (path + "/" + this->filename + ".html"); - f << final_templ.get (); + f << outputhtml; f.close (); } }