#include <string>
#include <list>
#include <memory>
+#include <iomanip>
#include <ctime>
+#include <fmt/format.h>
#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 <mkdio.h>
-}
// class to represent a biaweb document which can have a file name, title, description,
// keywords, content and sidebar items
namespace biaweb {
std::string meta_desc;
std::string meta_keywords;
std::string content;
- std::list<SideBar> sidebars;
+ std::list<SideBar> sidebars;
+ NavigationBit navbit;
std::time_t cdate;
std::time_t mdate;
bool is_index;
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)
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;
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) {
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) {
}
};
+ // 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) {
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<char> (tpl)),
- (std::istreambuf_iterator<char> ()) );
- 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<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());
+ 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 ();
}
}