yei
This commit is contained in:
parent
f1ed623905
commit
f4c8c653a5
28
TestWebGen.sln
Normal file
28
TestWebGen.sln
Normal file
@ -0,0 +1,28 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.25420.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestWebGen", "TestWebGen\TestWebGen.vcxproj", "{13843C6A-4801-49A1-98AC-A04441D29730}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{13843C6A-4801-49A1-98AC-A04441D29730}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{13843C6A-4801-49A1-98AC-A04441D29730}.Debug|x64.Build.0 = Debug|x64
|
||||
{13843C6A-4801-49A1-98AC-A04441D29730}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{13843C6A-4801-49A1-98AC-A04441D29730}.Debug|x86.Build.0 = Debug|Win32
|
||||
{13843C6A-4801-49A1-98AC-A04441D29730}.Release|x64.ActiveCfg = Release|x64
|
||||
{13843C6A-4801-49A1-98AC-A04441D29730}.Release|x64.Build.0 = Release|x64
|
||||
{13843C6A-4801-49A1-98AC-A04441D29730}.Release|x86.ActiveCfg = Release|Win32
|
||||
{13843C6A-4801-49A1-98AC-A04441D29730}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
10
TestWebGen/CTML.h
Normal file
10
TestWebGen/CTML.h
Normal file
@ -0,0 +1,10 @@
|
||||
/*
|
||||
CTML - written by Tinfoilboy
|
||||
uses the MIT License (https://github.com/tinfoilboy/CFML/blob/master/LICENSE)
|
||||
*/
|
||||
#pragma once
|
||||
namespace CTML {
|
||||
static int INDENT_SPACES = 4;
|
||||
}
|
||||
#include "Node.h"
|
||||
#include "Document.h"
|
79
TestWebGen/Document.h
Normal file
79
TestWebGen/Document.h
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
CTML - written by Tinfoilboy
|
||||
uses the MIT License (https://github.com/tinfoilboy/CFML/blob/master/LICENSE)
|
||||
*/
|
||||
#pragma once
|
||||
#include "Node.h"
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
|
||||
namespace CTML {
|
||||
class Document {
|
||||
// the doctype of this document
|
||||
Node m_doctype;
|
||||
// the head tag of this document
|
||||
Node m_head;
|
||||
// the body tag of this document
|
||||
Node m_body;
|
||||
public:
|
||||
// the default constructor for a document
|
||||
Document() {
|
||||
// create and set the doctype to html
|
||||
this->m_doctype = Node("", "html");
|
||||
this->m_doctype.SetType(NodeType::DOCUMENT_TYPE);
|
||||
// create the head tag
|
||||
this->m_head = Node("head");
|
||||
// create the body tag
|
||||
this->m_body = Node("body");
|
||||
}
|
||||
|
||||
// add a node to the head element
|
||||
void AddNodeToHead(Node node) {
|
||||
this->m_head.AppendChild(node);
|
||||
}
|
||||
|
||||
// add a node to the body element
|
||||
void AddNodeToBody(Node node) {
|
||||
this->m_body.AppendChild(node);
|
||||
}
|
||||
|
||||
// gets the current document as a string
|
||||
std::string ToString(const Readability& readability) const {
|
||||
bool isMultiline = (readability == Readability::MULTILINE || readability == Readability::MULTILINE_BR);
|
||||
std::string doc = "";
|
||||
// add the doctype to the string
|
||||
doc += m_doctype.ToString(readability, 0);
|
||||
// every document needs an html tag, add it
|
||||
doc += "<html>";
|
||||
// if we want readability, append a newline to the html beginning tag
|
||||
doc += ((isMultiline) ? "\n" : "");
|
||||
// append the head tag and its children
|
||||
doc += m_head.ToString(readability, 1) + ((isMultiline) ? "\n" : "");
|
||||
// append the body tag and its children
|
||||
doc += m_body.ToString(readability, 1) + ((isMultiline) ? "\n" : "");
|
||||
// close the html tag
|
||||
doc += "</html>";
|
||||
return doc;
|
||||
}
|
||||
|
||||
// get the current document as a tree represented in a string
|
||||
std::string ToTree() const {
|
||||
std::string treeStr = "";
|
||||
treeStr += "html\n";
|
||||
treeStr += m_head.GetTreeString(0);
|
||||
treeStr += m_body.GetTreeString(0);
|
||||
return treeStr;
|
||||
}
|
||||
|
||||
// write the current document to a file
|
||||
bool WriteToFile(const std::string& filePath, const Readability& readability) const {
|
||||
std::ofstream file(filePath.c_str());
|
||||
if (file.is_open()) {
|
||||
file << this->ToString(readability);
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
8
TestWebGen/EnvironmentScanGrabTool.h
Normal file
8
TestWebGen/EnvironmentScanGrabTool.h
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
class EnvironmentScanGrabTool
|
||||
{
|
||||
public:
|
||||
EnvironmentScanGrabTool();
|
||||
~EnvironmentScanGrabTool();
|
||||
};
|
||||
|
12
TestWebGen/EnvironmentScanTool.cpp
Normal file
12
TestWebGen/EnvironmentScanTool.cpp
Normal file
@ -0,0 +1,12 @@
|
||||
#include "stdafx.h"
|
||||
#include "EnvironmentScanGrabTool.h"
|
||||
|
||||
|
||||
EnvironmentScanGrabTool::EnvironmentScanGrabTool()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
EnvironmentScanGrabTool::~EnvironmentScanGrabTool()
|
||||
{
|
||||
}
|
185
TestWebGen/GeneralBuilder.cpp
Normal file
185
TestWebGen/GeneralBuilder.cpp
Normal file
@ -0,0 +1,185 @@
|
||||
#pragma once
|
||||
#include "stdafx.h"
|
||||
#include "GeneralBuilder.h"
|
||||
#include "ThePraDev.h"
|
||||
|
||||
GeneralBuilder::GeneralBuilder()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
GeneralBuilder::~GeneralBuilder()
|
||||
{
|
||||
}
|
||||
|
||||
list<Document> GeneralBuilder::BuildThePraSite(Sites site)
|
||||
{
|
||||
Utilities tool{Utilities()};
|
||||
string cPath{tool.GetCurrentPath()};
|
||||
switch (site)
|
||||
{
|
||||
case DEV:
|
||||
{
|
||||
ThePraDev a{ThePraDev()};
|
||||
string link = "https://www.thepra-dev.com/", html = ".html";
|
||||
|
||||
Document index = Document();
|
||||
Head(index, link + "index" + html, "ThePra WebSite");
|
||||
Body(index, cPath + a.contentLinks[0], site);
|
||||
|
||||
Document code = Document();
|
||||
Head(code, link + "code" + html, "ThePra Code");
|
||||
Body(code, cPath + a.contentLinks[1], site);
|
||||
|
||||
Document blog = Document();
|
||||
Head(blog, link + "blog" + html, "ThePra Blog");
|
||||
Body(blog, cPath + a.contentLinks[2], site);
|
||||
|
||||
Document about = Document();
|
||||
Head(about, link + "about" + html, "ThePra About");
|
||||
Body(about, cPath + a.contentLinks[3], site);
|
||||
|
||||
Document contact = Document();
|
||||
Head(contact, link + "contact" + html, "ThePra Contact");
|
||||
Body(contact, cPath + a.contentLinks[4], site);
|
||||
|
||||
return{index,code,blog,about,contact};
|
||||
}
|
||||
break;
|
||||
case ART:
|
||||
{
|
||||
string link = "http://art.thepra-dev.com/", html = ".html";
|
||||
|
||||
Document index = Document();
|
||||
Head(index, link + "index" + html, "title");
|
||||
Body(index, cPath, site);
|
||||
|
||||
Document aboutme = Document();
|
||||
Head(aboutme, link + "aboutme" + html, "title");
|
||||
Body(aboutme, cPath, site);
|
||||
|
||||
Document twitch = Document();
|
||||
Head(twitch, link + "twitch" + html, "title");
|
||||
Body(twitch, cPath, site);
|
||||
|
||||
Document twitter = Document();
|
||||
Head(twitter, link + "twitter" + html, "title");
|
||||
Body(twitter, cPath, site);
|
||||
|
||||
Document youtubePosts = Document();
|
||||
Head(youtubePosts, link + "youtubePosts" + html, "title");
|
||||
Body(youtubePosts, cPath, site);
|
||||
|
||||
return{index,aboutme,twitch,twitter,youtubePosts};
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return list<Document>();
|
||||
}
|
||||
|
||||
void GeneralBuilder::Head(Document &file,
|
||||
string canonicalURL,
|
||||
string title,
|
||||
Levels level,
|
||||
string description,
|
||||
list<string> cssStyles)
|
||||
{
|
||||
string whichLevel = ChooseLevel(level);
|
||||
// ESSENTIAL
|
||||
Node charset = Node(meta).SetAttribute("charset", "utf-8").UseClosingTag(false);
|
||||
Node edge = Node(meta).SetAttribute(http_equiv, "x-ua-compatible").SetAttribute(content, "ie=edge").UseClosingTag(false);
|
||||
Node viewport = Node(meta).SetAttribute(name, "viewport").SetAttribute(content, "width=device-width, initial-scale=1").UseClosingTag(false);
|
||||
Node titleP = Node("title", title);
|
||||
// OTHER
|
||||
Node canon = Node(link).SetAttribute(rel, "canonical").SetAttribute(href, canonicalURL).UseClosingTag(false);
|
||||
Node base = Node("base").SetAttribute(href, canonicalURL).UseClosingTag(false);
|
||||
Node contentSecurityPolicy = Node(meta).SetAttribute(http_equiv, "Content-Security-Policy").SetAttribute(content, "default-src 'self'").UseClosingTag(false);
|
||||
Node descriptionP = Node(meta).SetAttribute(name, "description").SetAttribute(content, description).UseClosingTag(false);
|
||||
Node robots = Node(meta).SetAttribute(name, "robots").SetAttribute(content, "index,follow,noodp").UseClosingTag(false);
|
||||
Node googleBot = Node(meta).SetAttribute(name, "googlebot").SetAttribute(content, "index,follow").UseClosingTag(false);
|
||||
Node referrer = Node(meta).SetAttribute(name, "referrer").SetAttribute(content, "no-referrer").UseClosingTag(false);
|
||||
Node icon = Node(link).SetAttribute(rel, "icon").SetAttribute(href, whichLevel + "icon/favicon.png").SetAttribute("type", "image/png").UseClosingTag(false);
|
||||
|
||||
file.AddNodeToHead(charset);
|
||||
file.AddNodeToHead(edge);
|
||||
file.AddNodeToHead(viewport);
|
||||
file.AddNodeToHead(titleP);
|
||||
file.AddNodeToHead(base);
|
||||
file.AddNodeToHead(canon);
|
||||
if (cssStyles.front() == "")
|
||||
{
|
||||
Node style = Node(link).SetAttribute(rel, "stylesheet").SetAttribute(href, whichLevel + "style.css").UseClosingTag(false);
|
||||
file.AddNodeToHead(style);
|
||||
}
|
||||
else
|
||||
{
|
||||
for each (string s in cssStyles)
|
||||
{
|
||||
Node style = Node(link).SetAttribute(rel, "stylesheet").SetAttribute(href, whichLevel + s).UseClosingTag(false);
|
||||
file.AddNodeToHead(style);
|
||||
}
|
||||
}
|
||||
file.AddNodeToHead(contentSecurityPolicy);
|
||||
file.AddNodeToHead(descriptionP);
|
||||
file.AddNodeToHead(robots);
|
||||
file.AddNodeToHead(googleBot);
|
||||
file.AddNodeToHead(referrer);
|
||||
file.AddNodeToHead(icon);
|
||||
}
|
||||
|
||||
|
||||
void GeneralBuilder::Body(Document &file, string cPath, Sites site, PageType type)
|
||||
{
|
||||
switch (site)
|
||||
{
|
||||
case DEV:
|
||||
{
|
||||
ThePraDev::BuildBody(file, cPath, ROOT, type);
|
||||
}
|
||||
case ART:
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
default:// I'm drunk
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GeneralBuilder::BuildHTMLFiles(Sites site, list<Document> rootFiles, list<Document> postFiles)
|
||||
{
|
||||
string cDevOutputPath{Utilities::GetCurrentPath() + "\\output_thepradev\\"};
|
||||
string postcDevOutputPath{cDevOutputPath + "postsContent\\"};
|
||||
path dir = current_path();
|
||||
cout << dir.string() << endl;
|
||||
for (auto& p : directory_iterator(dir))
|
||||
{
|
||||
path asd = p.path();
|
||||
|
||||
if (!is_directory(p))
|
||||
cout << p.path().filename().string() << endl;
|
||||
}
|
||||
switch (site)
|
||||
{
|
||||
case Utilities::DEV:
|
||||
{
|
||||
dir.append("thepradev");
|
||||
path contentDir{dir.append("content")};
|
||||
path postsContentDir{dir.append("postsContent")};
|
||||
|
||||
}
|
||||
break;
|
||||
case Utilities::ART:
|
||||
{
|
||||
dir.append("thepraart\\");
|
||||
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
28
TestWebGen/GeneralBuilder.h
Normal file
28
TestWebGen/GeneralBuilder.h
Normal file
@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
#include "CTML.h"
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include "Utilities.h"
|
||||
#include <filesystem>
|
||||
using namespace CTML;
|
||||
using namespace std;
|
||||
|
||||
class GeneralBuilder : Utilities
|
||||
{
|
||||
public:
|
||||
GeneralBuilder();
|
||||
~GeneralBuilder();
|
||||
list<Document> BuildThePraSite(Sites site);
|
||||
void Head(Document &file,
|
||||
string canonicalURL,
|
||||
string title,
|
||||
Levels level = ROOT,
|
||||
string description = "",
|
||||
list<string> cssStyles = {""});
|
||||
void Body(Document &file,
|
||||
string cPath,
|
||||
Sites site,
|
||||
PageType type = NORMAL);
|
||||
void BuildHTMLFiles(Sites site, list<Document> rootFiles, list<Document> postFiles = {{}});
|
||||
};
|
||||
|
359
TestWebGen/Node.h
Normal file
359
TestWebGen/Node.h
Normal file
@ -0,0 +1,359 @@
|
||||
/*
|
||||
CTML - written by Tinfoilboy
|
||||
uses the MIT License (https://github.com/tinfoilboy/CFML/blob/master/LICENSE)
|
||||
*/
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
|
||||
namespace CTML {
|
||||
// the types of nodes used for the html
|
||||
// DOCUMENT_TYPE doesn't use the element name, but uses
|
||||
// the content to determine the document type to use
|
||||
// ELEMENT is just a normal element
|
||||
enum class NodeType { DOCUMENT_TYPE, ELEMENT };
|
||||
|
||||
// a few enums for readability of the HTML
|
||||
// SINGLE_LINE returns the string as one line
|
||||
// MULTILINE returns the string as multiple lines, which is good for file outputs or readability.
|
||||
// MULTILINE_BR is essentially the same as MULTILINE, but the difference is that newlines in the content of the node are formatted to use <br> tags.
|
||||
enum class Readability { SINGLE_LINE, MULTILINE, MULTILINE_BR };
|
||||
|
||||
// the state of the Node name parser
|
||||
// NONE means that nothing is being parsed
|
||||
// CLASS means that a class attribute is being parsed
|
||||
// ID means that an ID is being parsed for the node
|
||||
enum class NodeParser { NONE, CLASS, ID };
|
||||
|
||||
class Node {
|
||||
// the type of node this
|
||||
NodeType m_type;
|
||||
// the name of this node, e.g. div, a, span, e.t.c.
|
||||
std::string m_name;
|
||||
// the classes for this node
|
||||
std::string m_classes;
|
||||
// the ids for this node
|
||||
std::string m_id;
|
||||
// the content of this node
|
||||
std::string m_content;
|
||||
// determines whether or not to add a closing tag (ie. </name>)
|
||||
// if this is false, it also doesn't add content to the tag
|
||||
// as there is nowhere to place content
|
||||
bool m_closeTag = true;
|
||||
// the child elements of this node
|
||||
std::vector<Node> m_children;
|
||||
// an unordered_map of attributes, name is the attribute name and the value is the attribute value
|
||||
std::unordered_map<std::string, std::string> m_attributes;
|
||||
public:
|
||||
// default constructor, does nothing
|
||||
Node() = default;
|
||||
|
||||
// create a node with the name specified
|
||||
Node(const std::string& name) {
|
||||
this->m_type = NodeType::ELEMENT;
|
||||
this->SetName(name);
|
||||
}
|
||||
|
||||
// create a node with the name specified, also containing the following content
|
||||
Node(const std::string& name, const std::string& content) {
|
||||
this->m_type = NodeType::ELEMENT;
|
||||
this->SetName(name);
|
||||
this->m_content = content;
|
||||
}
|
||||
|
||||
// return this node as an html string
|
||||
std::string ToString(Readability readability, int indentLevel) const {
|
||||
// the element string that will be returned
|
||||
std::string elem = "";
|
||||
// the four space indent.
|
||||
std::string indent = "";
|
||||
std::string indentContent = "";
|
||||
// if the readabilty points is either multiline types, this would be true
|
||||
bool isMultiline = (readability == Readability::MULTILINE || readability == Readability::MULTILINE_BR);
|
||||
// increment the indent string by four spaces based on the indentLevel
|
||||
// but only if the readabilty is MULTILINE OR MULTILINE_BR
|
||||
if (isMultiline) {
|
||||
for (int i = 0; i < indentLevel; i++) {
|
||||
indent = std::string(INDENT_SPACES * indentLevel, ' ');
|
||||
}
|
||||
// set the m_content indent level to the indent level plus four more spaces
|
||||
indentContent = std::string(INDENT_SPACES * (indentLevel + 1), ' ');
|
||||
}
|
||||
if (this->m_type == NodeType::ELEMENT) {
|
||||
// construct the first part of the element string, the tag beginning
|
||||
elem = ((isMultiline) ? indent : "") + "<" + m_name + "";
|
||||
// add the class list if it isn't empty
|
||||
if (!m_classes.empty()) {
|
||||
std::string classTag = "class=\"";
|
||||
elem += " " + classTag + m_classes + "\"";
|
||||
}
|
||||
// add the id list if it isn't empty
|
||||
if (!m_id.empty()) {
|
||||
std::string idTag = "id=\"";
|
||||
elem += " " + idTag + m_id + "\"";
|
||||
}
|
||||
// make an iterator for each attribute
|
||||
for (const auto& attr : m_attributes) {
|
||||
elem += " " + attr.first + "=\"" + attr.second + "\"";
|
||||
}
|
||||
// close the beginning tag
|
||||
elem += ">";
|
||||
// only add the content, as well as the closing tag if it is
|
||||
// specified to do so
|
||||
if (m_closeTag)
|
||||
{
|
||||
// if multiline is specified and the content/children aren't empty, add a newline
|
||||
if (isMultiline && (!m_content.empty() || !m_children.empty()))
|
||||
elem += "\n";
|
||||
// if we have m_content to append
|
||||
if (!m_content.empty()) {
|
||||
// format the elements content based on the readability, as well as the indent level for content
|
||||
elem += _GetFormattedContent(readability, indentContent);
|
||||
}
|
||||
// get every child node from the m_children list
|
||||
for (std::size_t i = 0; i < m_children.size(); ++i) {
|
||||
const auto& childNode = m_children[i];
|
||||
// append the child node to the elem string.
|
||||
// if this is not the last child node append a newline if multiline
|
||||
elem += childNode.ToString(readability, indentLevel + 1) + ((i != m_children.size() - 1 && isMultiline) ? "\n" : "");
|
||||
}
|
||||
// if multiline is specified and the content/children aren't empty, add a newline and indent
|
||||
elem += ((isMultiline && (!m_content.empty() || !m_children.empty())) ? "\n" + indent : "") + "</" + m_name + ">";
|
||||
}
|
||||
}
|
||||
else if (this->m_type == NodeType::DOCUMENT_TYPE) {
|
||||
// just construct the docm_type from the m_content given, if readability is wanted, add a newline
|
||||
elem += "<!DOCTYPE " + m_content + ">" + ((isMultiline) ? "\n" : "");
|
||||
}
|
||||
return elem;
|
||||
}
|
||||
|
||||
std::string GetTreeString(int indentLevel) const {
|
||||
// the tree string
|
||||
std::string tree;
|
||||
// indent level
|
||||
std::string indent(INDENT_SPACES * indentLevel, ' ');
|
||||
// turn the class list into actual classes for the elements
|
||||
std::string classList = m_classes;
|
||||
std::replace(classList.begin(), classList.end(), ' ', '.');
|
||||
// if the class list isn't empty, prepend a period
|
||||
if (!classList.empty())
|
||||
classList = '.' + classList;
|
||||
// add the current element to the tree
|
||||
tree += indent + " |_ " + this->m_name + classList + '\n';
|
||||
// for each child
|
||||
for (const auto& child : m_children) {
|
||||
tree += child.GetTreeString(indentLevel + 1) + '\n';
|
||||
}
|
||||
return tree;
|
||||
}
|
||||
|
||||
Node& SetName(const std::string& name) {
|
||||
// the index of a period
|
||||
const auto periodIndex = name.find('.');
|
||||
// the index of a pound sign
|
||||
const auto poundIndex = name.find('#');
|
||||
// if there are classes in the name
|
||||
if (periodIndex != std::string::npos || poundIndex != std::string::npos) {
|
||||
// if the pound index comes before the period index
|
||||
bool poundBefore = (poundIndex != std::string::npos && poundIndex < periodIndex);
|
||||
// get the first index for parsing
|
||||
// if pound comes first, or there are no periods, use the first pound index first
|
||||
// else use the first period index
|
||||
const auto ind = ((poundBefore || (periodIndex == std::string::npos && poundIndex != std::string::npos)) ? poundIndex : periodIndex);
|
||||
// get the element name
|
||||
std::string elemName = name.substr(0, ind);
|
||||
// parse the current ids and classes
|
||||
_ParseClassesAndIDS(name.substr(ind));
|
||||
// set the element name to the built element name
|
||||
this->m_name = elemName;
|
||||
}
|
||||
else {
|
||||
this->m_name = name;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string GetAttribute(const std::string& name) const {
|
||||
// the class attribute is tracked with m_classes, so we return that instead of m_attributes[name]
|
||||
if (name != "class" && name != "id" && m_attributes.count(name) > 0)
|
||||
return m_attributes.at(name);
|
||||
else if (name == "class")
|
||||
return m_classes;
|
||||
else if (name == "id")
|
||||
return m_id;
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string GetSelector() const {
|
||||
std::string classesPeriod = _ReplaceAllOccurrences(m_classes, " ", ".");
|
||||
return m_name + classesPeriod + "#" + m_id;
|
||||
}
|
||||
|
||||
Node& SetAttribute(std::string name, std::string value) {
|
||||
// setting the "class" attribute would make there be two class attributes on the element
|
||||
// so therefore, if the name of this is class, we just override "m_classes"
|
||||
if (name != "class" && name != "id")
|
||||
m_attributes[name] = value;
|
||||
else if (name == "class")
|
||||
m_classes = value;
|
||||
else if (name == "id")
|
||||
m_id = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Node& SetType(NodeType type) {
|
||||
this->m_type = type;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Node& SetContent(const std::string& text) {
|
||||
this->m_content = text;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Node& ToggleClass(const std::string& className) {
|
||||
size_t findIndex = m_classes.find(className);
|
||||
if (findIndex == std::string::npos) {
|
||||
// append the class
|
||||
m_classes += ((!m_classes.empty()) ? " " : "") + className;
|
||||
}
|
||||
else {
|
||||
// remove the class
|
||||
m_classes.erase(findIndex, className.size());
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Node& AppendChild(Node child) {
|
||||
m_children.push_back(child);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Node& UseClosingTag(bool close) {
|
||||
this->m_closeTag = close;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string _GetFormattedContent(Readability readability, const std::string& indent) const {
|
||||
std::string result;
|
||||
std::istringstream iss(m_content);
|
||||
// if we are using either variant of multiple lines, run this.
|
||||
if (readability == Readability::MULTILINE || readability == Readability::MULTILINE_BR) {
|
||||
// the newline string, differs between MULTILINE and MULTILINE_BR
|
||||
std::string newline = ((readability == Readability::MULTILINE_BR) ? "\n" + indent + "<br>\n" : "\n");
|
||||
// the current line iterated
|
||||
int curLine = 0;
|
||||
// iterate through each line in this node
|
||||
for (std::string line; std::getline(iss, line);)
|
||||
{
|
||||
result += ((curLine > 0) ? newline : "") + indent + line;
|
||||
curLine++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// iterate through each line in this node
|
||||
for (std::string line; std::getline(iss, line);)
|
||||
{
|
||||
result += line;
|
||||
}
|
||||
}
|
||||
// replaces all instances of "<" in the content with "<", to escape rogue HTML
|
||||
//result = _ReplaceAllOccurrences(result, "<", "<");
|
||||
// replaces all instances of ">" in the content with ">" to escape rogue HTML
|
||||
//result = _ReplaceAllOccurrences(result, ">", ">");
|
||||
// return the result of the content
|
||||
return result;
|
||||
}
|
||||
std::string _ReplaceAllOccurrences(std::string replacer, const std::string& replacable, const std::string& replace) const {
|
||||
// the start of the current replacable string
|
||||
size_t start = 0;
|
||||
// try and find each occurrence of replaceable until it can't be found
|
||||
while ((start = replacer.find(replacable, start)) != std::string::npos) {
|
||||
// replace the actual string
|
||||
replacer.replace(start, replacable.length(), replace);
|
||||
// add to the start so that find can be run again
|
||||
start += replace.length();
|
||||
}
|
||||
// return the replaced string
|
||||
return replacer;
|
||||
}
|
||||
int _CountOccurrences(std::string finder, const std::string& findable) const {
|
||||
// the occurrences of the string
|
||||
int occurrences = 0;
|
||||
// the start of the current replacable string
|
||||
size_t start = 0;
|
||||
// try and find each occurrence of replaceable until it can't be found
|
||||
while ((start = finder.find(findable, start)) != std::string::npos) {
|
||||
// replace the actual string
|
||||
occurrences++;
|
||||
// add to the start so that find can be run again
|
||||
start += findable.length();
|
||||
}
|
||||
// return the replaced string
|
||||
return occurrences;
|
||||
}
|
||||
void _ParseClassesAndIDS(std::string classesAndIDs) {
|
||||
// what is currently being parsed
|
||||
// zero for nothing
|
||||
// one for class
|
||||
// two for id
|
||||
NodeParser currentlyParsing = NodeParser::NONE;
|
||||
// the string for the class or ID
|
||||
std::string attrString;
|
||||
// iterate through each character in the string
|
||||
for (unsigned int i = 0; i < classesAndIDs.size(); i++) {
|
||||
// the current character being iterated
|
||||
char curChar = classesAndIDs[i];
|
||||
if (currentlyParsing == NodeParser::NONE) {
|
||||
// if the current character is a period, set the current parsing to class
|
||||
// else if the current character is a pound sign, set the current parsing to id
|
||||
if (curChar == '.') {
|
||||
currentlyParsing = NodeParser::CLASS;
|
||||
}
|
||||
else if (curChar == '#') {
|
||||
currentlyParsing = NodeParser::ID;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// if the current character is a period, set the current parsing to class
|
||||
// else if the current character is a pound sign, set the current parsing to id
|
||||
if (curChar == '.' || curChar == '#') {
|
||||
if (currentlyParsing == NodeParser::CLASS)
|
||||
m_classes += attrString + " ";
|
||||
else
|
||||
// if we hit an id, we just reset the id
|
||||
// this is because HTML only allows for a single id on each element
|
||||
m_id = attrString;
|
||||
attrString.clear();
|
||||
currentlyParsing = ((curChar == '.') ? NodeParser::CLASS : NodeParser::ID);
|
||||
}
|
||||
else {
|
||||
// add the current character to the class or id string
|
||||
attrString += curChar;
|
||||
}
|
||||
}
|
||||
// if we are at the last character, and are still parsing something, add it to the respective attr
|
||||
if (currentlyParsing != NodeParser::NONE && i == classesAndIDs.size() - 1) {
|
||||
if (currentlyParsing == NodeParser::CLASS)
|
||||
m_classes += attrString;
|
||||
else
|
||||
// if we hit an id, we just reset the id
|
||||
// this is because HTML only allows for a single id on each element
|
||||
m_id = attrString;
|
||||
attrString.clear();
|
||||
}
|
||||
}
|
||||
// if there is an extra space at the end of m_classes, remove it
|
||||
if (!m_classes.empty()) {
|
||||
if (isspace(m_classes.at(m_classes.size() - 1)))
|
||||
m_classes = m_classes.substr(0, m_classes.size() - 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
40
TestWebGen/ReadMe.txt
Normal file
40
TestWebGen/ReadMe.txt
Normal file
@ -0,0 +1,40 @@
|
||||
========================================================================
|
||||
CONSOLE APPLICATION : TestWebGen Project Overview
|
||||
========================================================================
|
||||
|
||||
AppWizard has created this TestWebGen application for you.
|
||||
|
||||
This file contains a summary of what you will find in each of the files that
|
||||
make up your TestWebGen application.
|
||||
|
||||
|
||||
TestWebGen.vcxproj
|
||||
This is the main project file for VC++ projects generated using an Application Wizard.
|
||||
It contains information about the version of Visual C++ that generated the file, and
|
||||
information about the platforms, configurations, and project features selected with the
|
||||
Application Wizard.
|
||||
|
||||
TestWebGen.vcxproj.filters
|
||||
This is the filters file for VC++ projects generated using an Application Wizard.
|
||||
It contains information about the association between the files in your project
|
||||
and the filters. This association is used in the IDE to show grouping of files with
|
||||
similar extensions under a specific node (for e.g. ".cpp" files are associated with the
|
||||
"Source Files" filter).
|
||||
|
||||
TestWebGen.cpp
|
||||
This is the main application source file.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
Other standard files:
|
||||
|
||||
StdAfx.h, StdAfx.cpp
|
||||
These files are used to build a precompiled header (PCH) file
|
||||
named TestWebGen.pch and a precompiled types file named StdAfx.obj.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
Other notes:
|
||||
|
||||
AppWizard uses "TODO:" comments to indicate parts of the source code you
|
||||
should add to or customize.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
47
TestWebGen/TestWebGen.cpp
Normal file
47
TestWebGen/TestWebGen.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
// TestWebGen.cpp : Defines the entry point for the console application.
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include <iostream>
|
||||
#include "GeneralBuilder.h"
|
||||
#include <stdio.h>
|
||||
#include <experimental\filesystem>
|
||||
#include "Utilities.h"
|
||||
#include "ThePraDev.h"
|
||||
|
||||
using namespace std::experimental::filesystem::v1;
|
||||
|
||||
|
||||
using namespace std;
|
||||
using namespace CTML;
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
ThePraDev n{ThePraDev()};
|
||||
string cDevOutputPath{Utilities::GetCurrentPath()+ "\\output_thepradev\\"};
|
||||
string postcDevOutputPath{cDevOutputPath + "postsContent\\"};
|
||||
path dir = canonical(".");
|
||||
cout << dir.append("thepradev").append("a")<<endl;
|
||||
/*for (auto& p : directory_iterator(dir))
|
||||
{
|
||||
path asd = p.path();
|
||||
|
||||
if (!is_directory(p))
|
||||
cout << asd.append("thepradev") << endl;
|
||||
}*/
|
||||
|
||||
|
||||
/*int i = 0;
|
||||
list<Document> wholeSite = list<Document>();
|
||||
GeneralBuilder dev;
|
||||
wholeSite = dev.BuildThePraSite(Utilities::DEV);
|
||||
for each (Document page in wholeSite)
|
||||
{
|
||||
page.WriteToFile(cDevOutputPath + n.pages[i++], Readability::MULTILINE);
|
||||
}*/
|
||||
cout << "DONE";
|
||||
getchar();
|
||||
return 0;
|
||||
}
|
||||
|
181
TestWebGen/TestWebGen.vcxproj
Normal file
181
TestWebGen/TestWebGen.vcxproj
Normal file
@ -0,0 +1,181 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{13843C6A-4801-49A1-98AC-A04441D29730}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>TestWebGen</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>C:\Program Files\boost\boost_1_63_0;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>C:\Program Files\boost\boost_1_63_0\libs\filesystem;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="ReadMe.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="CTML.h" />
|
||||
<ClInclude Include="Document.h" />
|
||||
<ClInclude Include="EnvironmentScanGrabTool.h" />
|
||||
<ClInclude Include="Node.h" />
|
||||
<ClInclude Include="stdafx.h" />
|
||||
<ClInclude Include="Utilities.h" />
|
||||
<ClInclude Include="targetver.h" />
|
||||
<ClInclude Include="GeneralBuilder.h" />
|
||||
<ClInclude Include="ThePraDev.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="EnvironmentScanTool.cpp" />
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TestWebGen.cpp" />
|
||||
<ClCompile Include="GeneralBuilder.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\packages\dirent.1.13.1\build\native\dirent.targets" Condition="Exists('..\packages\dirent.1.13.1\build\native\dirent.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\dirent.1.13.1\build\native\dirent.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\dirent.1.13.1\build\native\dirent.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
66
TestWebGen/TestWebGen.vcxproj.filters
Normal file
66
TestWebGen/TestWebGen.vcxproj.filters
Normal file
@ -0,0 +1,66 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="ReadMe.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="stdafx.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="targetver.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GeneralBuilder.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ThePraDev.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="EnvironmentScanGrabTool.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CTML.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Document.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Node.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Utilities.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TestWebGen.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeneralBuilder.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="EnvironmentScanTool.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
</Project>
|
195
TestWebGen/ThePraDev.h
Normal file
195
TestWebGen/ThePraDev.h
Normal file
@ -0,0 +1,195 @@
|
||||
#pragma once
|
||||
#include "Utilities.h"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
class ThePraDev : Utilities
|
||||
{
|
||||
public:
|
||||
string index = "index.html";
|
||||
string code = "code.html";
|
||||
string blog = "blog.html";
|
||||
string about = "about.html";
|
||||
string contact = "contact.html";
|
||||
|
||||
string Home = "Home";
|
||||
string Code = "Code";
|
||||
string Blog = "Blog";
|
||||
string About = "About";
|
||||
string Contact = "Contact";
|
||||
string Menu = "Menu";
|
||||
string contentFolder = "\\thepradev\\content\\";
|
||||
string contentLinks[5]{
|
||||
contentFolder + "index.txt",
|
||||
contentFolder + "code.txt",
|
||||
contentFolder + "blog.txt",
|
||||
contentFolder + "about.txt",
|
||||
contentFolder + "contact.txt"
|
||||
};
|
||||
string pages[5]{
|
||||
"index.html",
|
||||
"code.html",
|
||||
"blog.html",
|
||||
"about.html",
|
||||
"contact.html"
|
||||
};
|
||||
|
||||
static void BuildBody(Document &file,string cPath, Levels level, PageType ptype = NORMAL);
|
||||
|
||||
private:
|
||||
static list<Node> NavigationBar(Levels level, DeskOrMob mtype);
|
||||
static list<Node> SingleMainContent(Levels level,string cPath, DeskOrMob mtype, list<string> content = {""});
|
||||
static Node Extra(Levels level);
|
||||
static Node Player(Levels level);
|
||||
};
|
||||
|
||||
|
||||
inline void ThePraDev::BuildBody(Document &file,string cPath, Levels level, PageType ptype)
|
||||
{
|
||||
list<Node> navBar = NavigationBar(level, D);
|
||||
list<Node> navBarM = NavigationBar(level, M);
|
||||
list<Node> main = SingleMainContent(level, cPath, D);
|
||||
list<Node> mainM = SingleMainContent(level, cPath, M);
|
||||
|
||||
Node desktop = Node("section#desktop");
|
||||
Node mobile = Node("section#mobile");
|
||||
|
||||
for each (Node item in navBar)
|
||||
{
|
||||
desktop.AppendChild(item);
|
||||
}
|
||||
for each (Node item in navBarM)
|
||||
{
|
||||
mobile.AppendChild(item);
|
||||
}
|
||||
for each (Node item in main)
|
||||
{
|
||||
desktop.AppendChild(item);
|
||||
}
|
||||
for each (Node item in mainM)
|
||||
{
|
||||
mobile.AppendChild(item);
|
||||
}
|
||||
|
||||
file.AddNodeToBody(desktop);
|
||||
file.AddNodeToBody(mobile);
|
||||
}
|
||||
|
||||
inline list<Node> ThePraDev::NavigationBar(Levels level, DeskOrMob mtype)
|
||||
{
|
||||
ThePraDev a;
|
||||
string whichLevel = ChooseLevel(level);
|
||||
switch (mtype)
|
||||
{
|
||||
case D:
|
||||
{
|
||||
Node elem0 = Node("div.navigation_bar");
|
||||
Node elem1 = Node("img").SetAttribute(a.src, whichLevel + "icon/up.png").SetAttribute(a.alt, "Upper Decoration").UseClosingTag(false);
|
||||
Node elem2 = Node("ul.bortrr.borbrr");
|
||||
Node elem3 = Node("li.bortrr").AppendChild(Node(a.a, a.Home).SetAttribute(a.href, whichLevel + a.index));
|
||||
Node elem4 = Node(a.li).AppendChild(Node(a.a, a.Code).SetAttribute(a.href, whichLevel + a.code));
|
||||
Node elem5 = Node(a.li).AppendChild(Node(a.a, a.Blog).SetAttribute(a.href, whichLevel + a.blog));
|
||||
Node elem6 = Node(a.li).AppendChild(Node(a.a, a.About).SetAttribute(a.href, whichLevel + a.about));
|
||||
Node elem7 = Node(a.li).AppendChild(Node(a.a, a.Contact).SetAttribute(a.href, whichLevel + a.contact));
|
||||
Node elem8 = Extra(level);
|
||||
Node elem9 = Node("img").SetAttribute(a.src, whichLevel + "icon/down.png").SetAttribute(a.alt, "Down Decoration").UseClosingTag(false);
|
||||
|
||||
elem0.AppendChild(elem1)
|
||||
.AppendChild(elem2
|
||||
.AppendChild(elem3)
|
||||
.AppendChild(elem4)
|
||||
.AppendChild(elem5)
|
||||
.AppendChild(elem6)
|
||||
.AppendChild(elem7)
|
||||
.AppendChild(elem8))
|
||||
.AppendChild(elem9);
|
||||
|
||||
return{{elem0}};
|
||||
}
|
||||
break;
|
||||
case M:
|
||||
{
|
||||
Node elem0 = Node("div.navigation_barm");
|
||||
Node elem1 = Node("img.immagini_laterali").SetAttribute(a.src, whichLevel + "icon/left.png").SetAttribute(a.alt, "Upper Left Decoration").UseClosingTag(false);
|
||||
Node elem2 = Node("div.navigation_barminner");
|
||||
|
||||
Node elem3 = Node("nav._nav");
|
||||
Node elem4 = Node("laber.toggle").SetAttribute("for", "drop").SetContent(a.Menu);
|
||||
Node elem5 = Node("input#drop").SetAttribute("type", "checkbox").UseClosingTag(false);
|
||||
Node elem6 = Node("ul.menu");
|
||||
Node elem7 = Node(a.li).AppendChild(Node(a.a, a.Home).SetAttribute(a.href, whichLevel + a.index));
|
||||
Node elem8 = Node(a.li).AppendChild(Node(a.a, a.Code).SetAttribute(a.href, whichLevel + a.code));
|
||||
Node elem9 = Node(a.li).AppendChild(Node(a.a, a.Blog).SetAttribute(a.href, whichLevel + a.blog));
|
||||
Node elem10 = Node(a.li).AppendChild(Node(a.a, a.About).SetAttribute(a.href, whichLevel + a.about));
|
||||
Node elem11 = Node(a.li).AppendChild(Node(a.a, a.Contact).SetAttribute(a.href, whichLevel + a.contact));
|
||||
|
||||
Node elem12 = Node("img.immagini_laterali").SetAttribute(a.src, whichLevel + "icon/right.png").SetAttribute(a.alt, "Upper Right Decoration").UseClosingTag(false);
|
||||
|
||||
elem0.AppendChild(elem1)
|
||||
.AppendChild(elem2
|
||||
.AppendChild(elem3
|
||||
.AppendChild(elem4)
|
||||
.AppendChild(elem5)
|
||||
.AppendChild(elem6
|
||||
.AppendChild(elem7)
|
||||
.AppendChild(elem8)
|
||||
.AppendChild(elem9)
|
||||
.AppendChild(elem10)
|
||||
.AppendChild(elem11))))
|
||||
.AppendChild(elem12);
|
||||
|
||||
return{{elem0}};
|
||||
}
|
||||
break;
|
||||
default: return{{}};
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inline list<Node> ThePraDev::SingleMainContent(Levels level,string cPath, DeskOrMob mtype, list<string> content)
|
||||
{
|
||||
ThePraDev a;
|
||||
string whichLevel = ChooseLevel(level);
|
||||
Node mainC = Node("div#main");
|
||||
Node mainMC = mainC;
|
||||
string STRING;
|
||||
string contentDesktop = "";
|
||||
string contentMobile = "";
|
||||
|
||||
FullFillContent(cPath, &contentDesktop, &contentMobile);
|
||||
|
||||
mainC.SetContent(contentDesktop);
|
||||
mainMC.SetContent(contentMobile);
|
||||
/*for each (string item in contentTest)
|
||||
{
|
||||
mainC.SetContent(item+"\n");
|
||||
}*/
|
||||
if (mtype == D)
|
||||
return{mainC};
|
||||
else return{mainMC};
|
||||
}
|
||||
inline Node ThePraDev::Extra(Levels level)
|
||||
{
|
||||
ThePraDev a;
|
||||
string whichLevel = ChooseLevel(level);
|
||||
Node extra = Node("li.borbrr")
|
||||
.AppendChild(Node(a.a, "+ Extra +"))
|
||||
.AppendChild(Node("ul.borbrr")
|
||||
.AppendChild(Node("li.colbk")
|
||||
.AppendChild(Node("img.fiximgmenu").SetAttribute(a.src, whichLevel + "icon/signbot.gif").SetAttribute(a.alt, "MotD").UseClosingTag(false)))
|
||||
.AppendChild(Node(a.li)
|
||||
.AppendChild(Player(level))));
|
||||
return extra;
|
||||
}
|
||||
|
||||
inline Node ThePraDev::Player(Levels level)
|
||||
{
|
||||
ThePraDev a;
|
||||
string whichLevel = ChooseLevel(level);
|
||||
Node player = Node("div.player")
|
||||
.AppendChild(Node("audio").SetAttribute("controls", "controls").SetAttribute("preload", "auto")
|
||||
.AppendChild(Node("source").SetAttribute(a.src, whichLevel + "videoplayback.ogg").SetAttribute("type", "audio/ogg").SetContent("Your browser does not support the audio element.")));
|
||||
return player;
|
||||
}
|
||||
|
108
TestWebGen/Utilities.h
Normal file
108
TestWebGen/Utilities.h
Normal file
@ -0,0 +1,108 @@
|
||||
#pragma once
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <experimental/filesystem>
|
||||
using namespace std;
|
||||
using namespace std::experimental::filesystem::v1;
|
||||
|
||||
class Utilities
|
||||
{
|
||||
protected:
|
||||
const string meta = "meta";
|
||||
const string link = "link";
|
||||
const string rel = "rel";
|
||||
const string href = "href";
|
||||
const string http_equiv = "http-equiv";
|
||||
const string content = "content";
|
||||
const string name = "name";
|
||||
const string li = "li";
|
||||
const string ul = "ul";
|
||||
const string a = "a";
|
||||
const string src = "src";
|
||||
const string alt = "alt";
|
||||
|
||||
public:
|
||||
static enum DeskOrMob
|
||||
{
|
||||
D, //Desktop part of the page
|
||||
M //Mobile part of the page
|
||||
};
|
||||
DeskOrMob setDM = D;
|
||||
enum Levels
|
||||
{
|
||||
ROOT,//Content at the index.html directory level
|
||||
LEVEL1,//Content at the first directory
|
||||
LEVEL2//Content at the second directory
|
||||
};
|
||||
enum Sites
|
||||
{
|
||||
DEV,//Build the thepra-dev.com
|
||||
ART//Build the art.thepra-dev.com
|
||||
};
|
||||
enum PageType
|
||||
{
|
||||
NORMAL,
|
||||
POST
|
||||
};
|
||||
|
||||
static string ChooseLevel(Levels level);
|
||||
static void FullFillContent(string link, string* desktop, string* mobile);
|
||||
static string GetCurrentPath();
|
||||
};
|
||||
|
||||
inline string Utilities::ChooseLevel(Levels level)
|
||||
{
|
||||
switch (level)
|
||||
{
|
||||
case Utilities::ROOT:return "";
|
||||
break;
|
||||
case Utilities::LEVEL1:return "../";
|
||||
break;
|
||||
case Utilities::LEVEL2:return "../../";
|
||||
default:return "";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
inline void Utilities::FullFillContent(string link, string* desktop, string* mobile)
|
||||
{
|
||||
|
||||
//link = "C:\\content\\index.txt"; //TODO find out a general way to scan the folder env
|
||||
Utilities a = Utilities();
|
||||
string line = "";
|
||||
std::ifstream infile;
|
||||
infile.open(link);
|
||||
while (!infile.eof())
|
||||
{
|
||||
std::getline(infile, line);
|
||||
if (line == "desktop")
|
||||
{
|
||||
line = "";
|
||||
a.setDM = D;
|
||||
}
|
||||
if (a.setDM == D)
|
||||
{
|
||||
if (line == "mobile")
|
||||
{
|
||||
line = "";
|
||||
a.setDM = M;
|
||||
}
|
||||
*desktop += line + "\n";
|
||||
}
|
||||
if (a.setDM == M)
|
||||
{
|
||||
*mobile += line + "\n";
|
||||
}
|
||||
}
|
||||
infile.close();
|
||||
}
|
||||
|
||||
inline string Utilities::GetCurrentPath()
|
||||
{
|
||||
path current = current_path();
|
||||
string pathString = current.string();
|
||||
//cout << pathString << endl;
|
||||
return pathString;
|
||||
}
|
||||
|
4
TestWebGen/packages.config
Normal file
4
TestWebGen/packages.config
Normal file
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="dirent" version="1.13.1" targetFramework="native" />
|
||||
</packages>
|
8
TestWebGen/stdafx.cpp
Normal file
8
TestWebGen/stdafx.cpp
Normal file
@ -0,0 +1,8 @@
|
||||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// TestWebGen.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
// TODO: reference any additional headers you need in STDAFX.H
|
||||
// and not in this file
|
15
TestWebGen/stdafx.h
Normal file
15
TestWebGen/stdafx.h
Normal file
@ -0,0 +1,15 @@
|
||||
// stdafx.h : include file for standard system include files,
|
||||
// or project specific include files that are used frequently, but
|
||||
// are changed infrequently
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "targetver.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <tchar.h>
|
||||
|
||||
|
||||
|
||||
// TODO: reference additional headers your program requires here
|
8
TestWebGen/targetver.h
Normal file
8
TestWebGen/targetver.h
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
// Including SDKDDKVer.h defines the highest available Windows platform.
|
||||
|
||||
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
|
||||
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
|
||||
|
||||
#include <SDKDDKVer.h>
|
96
TestWebGen/tests.cpp
Normal file
96
TestWebGen/tests.cpp
Normal file
@ -0,0 +1,96 @@
|
||||
#include "stdafx.h"
|
||||
#include <iostream>
|
||||
#include "CTML.h"
|
||||
#include <chrono>
|
||||
|
||||
// std chrono has the worst namespace abuse i've ever seen, so therefore, i'm typedeffing
|
||||
typedef std::chrono::high_resolution_clock high_res_clock;
|
||||
typedef std::chrono::milliseconds millis;
|
||||
|
||||
using namespace CTML;
|
||||
|
||||
// tests if two strings are equivelent to each other
|
||||
bool assert_strings_equal(const std::string& left, const std::string& right) {
|
||||
return (left == right);
|
||||
}
|
||||
|
||||
// this test ensures that HTML inside of the content is escaped correctly.
|
||||
void run_escape_test() {
|
||||
// what the node's to string should be equal to
|
||||
const auto htmlString = "<a class=\"button\"><script>alert(\"ha ha hacked!\")</script></a>";
|
||||
Node node("a.button", "<script>alert(\"ha ha hacked!\")</script>");
|
||||
// the node's string output
|
||||
const auto nodeString = node.ToString(Readability::SINGLE_LINE, 0);
|
||||
auto test = assert_strings_equal(htmlString, nodeString);
|
||||
std::cout << "Escape Test " << ((test) ? "passed!" : "failed!") << std::endl <<
|
||||
"HTML Output: " << nodeString << std::endl <<
|
||||
// use a double end line at the end for spacing between tests
|
||||
"Expected Output: " << htmlString << std::endl << std::endl;
|
||||
}
|
||||
|
||||
// this test ensures that the HTML document created is equal to a correct HTML5 document
|
||||
void run_document_test() {
|
||||
// what the document's to string should be equal to
|
||||
const auto htmlString = "<!DOCTYPE html><html><head></head><body><h1><test!></h1></body></html>";
|
||||
Document doc;
|
||||
// the string output of the document
|
||||
doc.AddNodeToBody(Node("h1", "<test!>"));
|
||||
const auto docString = doc.ToString(Readability::SINGLE_LINE);
|
||||
auto test = assert_strings_equal(htmlString, docString);
|
||||
std::cout << "Document Test " << ((test) ? "passed!" : "failed!") << std::endl <<
|
||||
"HTML Output: " << docString << std::endl <<
|
||||
// use a double end line at the end for spacing between tests
|
||||
"Expected Output: " << htmlString << std::endl << std::endl;
|
||||
}
|
||||
|
||||
// this test checks if the classes provided are correctly stored
|
||||
void run_class_test() {
|
||||
const auto classString = "test classes are fun";
|
||||
Node testNode("a#test.test.classes.are.fun");
|
||||
// get the test node's classlist.
|
||||
const auto classList = testNode.GetAttribute("class");
|
||||
bool test = assert_strings_equal(classString, classList);
|
||||
std::cout << "Class Test " << ((test) ? "passed!" : "failed!") << std::endl <<
|
||||
"Class Output: " << classList << std::endl <<
|
||||
// use a double end line at the end for spacing between tests
|
||||
"Expected Output: " << classString << std::endl << std::endl;
|
||||
}
|
||||
|
||||
// this test checks if the attributes provided are correctly stored and gotten
|
||||
void run_attribute_test() {
|
||||
const auto attrOutput = "testAttr1";
|
||||
const auto attr2Output = "testAttr2";
|
||||
const auto attr3Output = "";
|
||||
Node testNode("a");
|
||||
// set two attributes on the node
|
||||
testNode.SetAttribute("attr1", "testAttr1").SetAttribute("attr2", "testAttr2");
|
||||
// get each attribute's output
|
||||
const auto attrOut = testNode.GetAttribute("attr1");
|
||||
const auto attr2Out = testNode.GetAttribute("attr2");
|
||||
const auto attr3Out = testNode.GetAttribute("attr3");
|
||||
// test each string
|
||||
auto test1 = assert_strings_equal(attrOutput, attrOut);
|
||||
auto test2 = assert_strings_equal(attr2Output, attr2Out);
|
||||
auto test3 = assert_strings_equal(attr3Output, attr3Out);
|
||||
std::cout << "Class Test " << ((test1 && test2 && test3) ? "passed!" : "failed!") << std::endl <<
|
||||
"Attr 1 Output: " << attrOut << std::endl <<
|
||||
"Expected Output: " << attrOutput << std::endl <<
|
||||
"Attr 2 Output: " << attr2Out << std::endl <<
|
||||
"Expected Output: " << attr2Output << std::endl <<
|
||||
"Attr 3 Output: " << attr3Out << std::endl <<
|
||||
// use a double end line at the end for spacing between tests
|
||||
"Expected Output: " << attr3Output << std::endl << std::endl;
|
||||
|
||||
}
|
||||
|
||||
int main() {
|
||||
high_res_clock::time_point begin = high_res_clock::now();
|
||||
run_escape_test();
|
||||
run_document_test();
|
||||
run_class_test();
|
||||
run_attribute_test();
|
||||
high_res_clock::time_point end = high_res_clock::now();
|
||||
millis ms = std::chrono::duration_cast<millis>(end - begin);
|
||||
std::cout << "Tests ran in " << ms.count() << "ms" << std::endl;
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user