mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-07 12:10:52 -06:00
Add abstract class to handle Handlebar-based documentation file generation
Apply Documented class to the InteractionHandler Update Ghoul
This commit is contained in:
Submodule ext/ghoul updated: 8afa0763b1...a2f58b3085
@@ -31,6 +31,7 @@
|
||||
#include <openspace/properties/stringproperty.h>
|
||||
#include <openspace/properties/scalar/boolproperty.h>
|
||||
#include <openspace/properties/scalar/floatproperty.h>
|
||||
#include <openspace/util/documented.h>
|
||||
#include <openspace/util/mouse.h>
|
||||
#include <openspace/util/keys.h>
|
||||
|
||||
@@ -48,8 +49,7 @@ class SceneGraphNode;
|
||||
namespace interaction {
|
||||
|
||||
|
||||
class InteractionHandler : public properties::PropertyOwner
|
||||
{
|
||||
class InteractionHandler : public properties::PropertyOwner, public Documented {
|
||||
public:
|
||||
InteractionHandler();
|
||||
~InteractionHandler();
|
||||
@@ -121,7 +121,7 @@ public:
|
||||
|
||||
void saveCameraStateToFile(const std::string& filepath);
|
||||
void restoreCameraStateFromFile(const std::string& filepath);
|
||||
void writeKeyboardDocumentation(const std::string& type, const std::string& file);
|
||||
// void writeKeyboardDocumentation(const std::string& type, const std::string& file);
|
||||
|
||||
private:
|
||||
using Synchronized = ghoul::Boolean;
|
||||
@@ -131,6 +131,8 @@ private:
|
||||
Synchronized synchronization;
|
||||
std::string documentation;
|
||||
};
|
||||
|
||||
std::string generateJson() const override;
|
||||
|
||||
void setInteractionMode(std::shared_ptr<InteractionMode> interactionMode);
|
||||
|
||||
|
||||
57
include/openspace/util/documented.h
Normal file
57
include/openspace/util/documented.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2017 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_CORE___DOCUMENTED___H__
|
||||
#define __OPENSPACE_CORE___DOCUMENTED___H__
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class Documented {
|
||||
public:
|
||||
struct HandlebarTemplate {
|
||||
std::string name;
|
||||
std::string filename;
|
||||
};
|
||||
|
||||
Documented(std::string name, std::string jsonName, std::vector<HandlebarTemplate> handlebarTemplates,
|
||||
std::string javascriptFilename);
|
||||
|
||||
void writeDocumentation(const std::string& filename);
|
||||
|
||||
protected:
|
||||
virtual std::string generateJson() const = 0;
|
||||
|
||||
private:
|
||||
const std::string _name;
|
||||
const std::string _jsonName;
|
||||
const std::vector<HandlebarTemplate> _handlebarTemplates;
|
||||
const std::string _javascriptFile;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_CORE___DOCUMENTED___H__
|
||||
@@ -138,6 +138,7 @@ set(OPENSPACE_SOURCE
|
||||
${OPENSPACE_BASE_DIR}/src/util/blockplaneintersectiongeometry.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/util/boxgeometry.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/util/camera.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/util/documented.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/util/factorymanager.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/util/keys.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/util/openspacemodule.cpp
|
||||
@@ -281,6 +282,7 @@ set(OPENSPACE_HEADER
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/blockplaneintersectiongeometry.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/boxgeometry.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/camera.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/documented.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/factorymanager.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/factorymanager.inl
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/util/keys.h
|
||||
|
||||
@@ -604,7 +604,8 @@ void OpenSpaceEngine::loadScene(const std::string& scenePath) {
|
||||
|
||||
if (hasType && hasFile) {
|
||||
file = absPath(file);
|
||||
interactionHandler().writeKeyboardDocumentation(type, file);
|
||||
interactionHandler().writeDocumentation(file);
|
||||
// interactionHandler().writeKeyboardDocumentation(type, file);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -59,10 +59,10 @@ namespace {
|
||||
|
||||
const char* MainTemplateFilename = "${OPENSPACE_DATA}/web/keybindings/main.hbs";
|
||||
const char* KeybindingTemplateFilename = "${OPENSPACE_DATA}/web/keybindings/keybinding.hbs";
|
||||
const char* HandlebarsFilename = "${OPENSPACE_DATA}/web/common/handlebars-v4.0.5.js";
|
||||
// const char* HandlebarsFilename = "${OPENSPACE_DATA}/web/common/handlebars-v4.0.5.js";
|
||||
const char* JsFilename = "${OPENSPACE_DATA}/web/keybindings/script.js";
|
||||
const char* BootstrapFilename = "${OPENSPACE_DATA}/web/common/bootstrap.min.css";
|
||||
const char* CssFilename = "${OPENSPACE_DATA}/web/common/style.css";
|
||||
// const char* BootstrapFilename = "${OPENSPACE_DATA}/web/common/bootstrap.min.css";
|
||||
// const char* CssFilename = "${OPENSPACE_DATA}/web/common/style.css";
|
||||
} // namespace
|
||||
|
||||
#include "interactionhandler_lua.inl"
|
||||
@@ -73,6 +73,15 @@ namespace interaction {
|
||||
// InteractionHandler
|
||||
InteractionHandler::InteractionHandler()
|
||||
: properties::PropertyOwner("Interaction")
|
||||
, Documented(
|
||||
"Documentation",
|
||||
"keybindings",
|
||||
{
|
||||
{ "keybindingTemplate", KeybindingTemplateFilename },
|
||||
{ "mainTemplate", MainTemplateFilename }
|
||||
},
|
||||
JsFilename
|
||||
)
|
||||
, _origin("origin", "Origin", "")
|
||||
, _rotationalFriction("rotationalFriction", "Rotational Friction", true)
|
||||
, _horizontalFriction("horizontalFriction", "Horizontal Friction", true)
|
||||
@@ -433,133 +442,163 @@ void InteractionHandler::bindKey(Key key, KeyModifier modifier,
|
||||
}
|
||||
|
||||
|
||||
void InteractionHandler::writeKeyboardDocumentation(const std::string& type,
|
||||
const std::string& file)
|
||||
{
|
||||
if (type == "text") {
|
||||
std::ofstream f;
|
||||
f.exceptions(~std::ofstream::goodbit);
|
||||
f.open(absPath(file));
|
||||
|
||||
for (const auto& p : _keyLua) {
|
||||
std::string remoteScriptingInfo;
|
||||
bool remoteScripting = p.second.synchronization;
|
||||
|
||||
if (!remoteScripting) {
|
||||
remoteScriptingInfo = " (LOCAL)";
|
||||
}
|
||||
f << std::to_string(p.first) << ": "
|
||||
<< p.second.command << remoteScriptingInfo << '\n'
|
||||
<< p.second.documentation << '\n';
|
||||
std::string InteractionHandler::generateJson() const {
|
||||
std::stringstream json;
|
||||
json << "[";
|
||||
bool first = true;
|
||||
for (const auto& p : _keyLua) {
|
||||
if (!first) {
|
||||
json << ",";
|
||||
}
|
||||
first = false;
|
||||
json << "{";
|
||||
json << "\"key\": \"" << std::to_string(p.first) << "\",";
|
||||
json << "\"script\": \"" << p.second.command << "\",";
|
||||
json << "\"remoteScripting\": " << (p.second.synchronization ? "true," : "false,");
|
||||
json << "\"documentation\": \"" << p.second.documentation << "\"";
|
||||
json << "}";
|
||||
}
|
||||
json << "]";
|
||||
|
||||
std::string jsonString = "";
|
||||
for (const char& c : json.str()) {
|
||||
if (c == '\'') {
|
||||
jsonString += "\\'";
|
||||
} else {
|
||||
jsonString += c;
|
||||
}
|
||||
}
|
||||
else if (type == "html") {
|
||||
std::ofstream f;
|
||||
f.exceptions(~std::ofstream::goodbit);
|
||||
f.open(absPath(file));
|
||||
|
||||
std::ifstream handlebarsInput(absPath(HandlebarsFilename));
|
||||
std::ifstream jsInput(absPath(JsFilename));
|
||||
|
||||
std::string jsContent;
|
||||
std::back_insert_iterator<std::string> jsInserter(jsContent);
|
||||
|
||||
std::copy(std::istreambuf_iterator<char>{handlebarsInput}, std::istreambuf_iterator<char>(), jsInserter);
|
||||
std::copy(std::istreambuf_iterator<char>{jsInput}, std::istreambuf_iterator<char>(), jsInserter);
|
||||
|
||||
std::ifstream bootstrapInput(absPath(BootstrapFilename));
|
||||
std::ifstream cssInput(absPath(CssFilename));
|
||||
|
||||
std::string cssContent;
|
||||
std::back_insert_iterator<std::string> cssInserter(cssContent);
|
||||
|
||||
std::copy(std::istreambuf_iterator<char>{bootstrapInput}, std::istreambuf_iterator<char>(), cssInserter);
|
||||
std::copy(std::istreambuf_iterator<char>{cssInput}, std::istreambuf_iterator<char>(), cssInserter);
|
||||
|
||||
std::ifstream mainTemplateInput(absPath(MainTemplateFilename));
|
||||
std::string mainTemplateContent{ std::istreambuf_iterator<char>{mainTemplateInput},
|
||||
std::istreambuf_iterator<char>{} };
|
||||
|
||||
std::ifstream keybindingTemplateInput(absPath(KeybindingTemplateFilename));
|
||||
std::string keybindingTemplateContent{ std::istreambuf_iterator<char>{keybindingTemplateInput},
|
||||
std::istreambuf_iterator<char>{} };
|
||||
|
||||
std::stringstream json;
|
||||
json << "[";
|
||||
bool first = true;
|
||||
for (const auto& p : _keyLua) {
|
||||
if (!first) {
|
||||
json << ",";
|
||||
}
|
||||
first = false;
|
||||
json << "{";
|
||||
json << "\"key\": \"" << std::to_string(p.first) << "\",";
|
||||
json << "\"script\": \"" << p.second.command << "\",";
|
||||
json << "\"remoteScripting\": " << (p.second.synchronization ? "true," : "false,");
|
||||
json << "\"documentation\": \"" << p.second.documentation << "\"";
|
||||
json << "}";
|
||||
}
|
||||
json << "]";
|
||||
|
||||
std::string jsonString = "";
|
||||
for (const char& c : json.str()) {
|
||||
if (c == '\'') {
|
||||
jsonString += "\\'";
|
||||
} else {
|
||||
jsonString += c;
|
||||
}
|
||||
}
|
||||
|
||||
std::string generationTime;
|
||||
try {
|
||||
generationTime = Time::now().ISO8601();
|
||||
}
|
||||
catch (...) {}
|
||||
|
||||
std::stringstream html;
|
||||
html << "<!DOCTYPE html>\n"
|
||||
<< "<html>\n"
|
||||
<< "\t<head>\n"
|
||||
<< "\t\t<script id=\"mainTemplate\" type=\"text/x-handlebars-template\">\n"
|
||||
<< mainTemplateContent << "\n"
|
||||
<< "\t\t</script>\n"
|
||||
<< "\t\t<script id=\"keybindingTemplate\" type=\"text/x-handlebars-template\">\n"
|
||||
<< keybindingTemplateContent << "\n"
|
||||
<< "\t\t</script>\n"
|
||||
<< "\t<script>\n"
|
||||
<< "var keybindings = JSON.parse('" << jsonString << "');\n"
|
||||
<< "var version = [" << OPENSPACE_VERSION_MAJOR << ", " << OPENSPACE_VERSION_MINOR << ", " << OPENSPACE_VERSION_PATCH << "];\n"
|
||||
<< "var generationTime = '" << generationTime << "';\n"
|
||||
<< jsContent << "\n"
|
||||
<< "\t</script>\n"
|
||||
<< "\t<style type=\"text/css\">\n"
|
||||
<< cssContent << "\n"
|
||||
<< "\t</style>\n"
|
||||
<< "\t\t<title>Documentation</title>\n"
|
||||
<< "\t</head>\n"
|
||||
<< "\t<body>\n"
|
||||
<< "\t<body>\n"
|
||||
<< "</html>\n";
|
||||
|
||||
f << html.str();
|
||||
|
||||
|
||||
/*
|
||||
for (const auto& p : _keyLua) {
|
||||
html << "\t\t<tr>\n"
|
||||
<< "\t\t\t<td>" << std::to_string(p.first) << "</td>\n"
|
||||
<< "\t\t\t<td>" << p.second.first << "</td>\n"
|
||||
<< "\t\t\t<td>" << (p.second.second ? "Yes" : "No") << "</td>\n"
|
||||
<< "\t\t</tr>\n";
|
||||
}*/
|
||||
}
|
||||
else {
|
||||
throw ghoul::RuntimeError(
|
||||
"Unsupported keyboard documentation type '" + type + "'",
|
||||
"InteractionHandler"
|
||||
);
|
||||
}
|
||||
return jsonString;
|
||||
}
|
||||
|
||||
//void InteractionHandler::writeKeyboardDocumentation(const std::string& type,
|
||||
// const std::string& file)
|
||||
//{
|
||||
// if (type == "text") {
|
||||
// std::ofstream f;
|
||||
// f.exceptions(~std::ofstream::goodbit);
|
||||
// f.open(absPath(file));
|
||||
//
|
||||
// for (const auto& p : _keyLua) {
|
||||
// std::string remoteScriptingInfo;
|
||||
// bool remoteScripting = p.second.synchronization;
|
||||
//
|
||||
// if (!remoteScripting) {
|
||||
// remoteScriptingInfo = " (LOCAL)";
|
||||
// }
|
||||
// f << std::to_string(p.first) << ": "
|
||||
// << p.second.command << remoteScriptingInfo << '\n'
|
||||
// << p.second.documentation << '\n';
|
||||
// }
|
||||
// }
|
||||
// else if (type == "html") {
|
||||
// std::ofstream f;
|
||||
// f.exceptions(~std::ofstream::goodbit);
|
||||
// f.open(absPath(file));
|
||||
//
|
||||
// std::ifstream handlebarsInput(absPath(HandlebarsFilename));
|
||||
// std::ifstream jsInput(absPath(JsFilename));
|
||||
//
|
||||
// std::string jsContent;
|
||||
// std::back_insert_iterator<std::string> jsInserter(jsContent);
|
||||
//
|
||||
// std::copy(std::istreambuf_iterator<char>{handlebarsInput}, std::istreambuf_iterator<char>(), jsInserter);
|
||||
// std::copy(std::istreambuf_iterator<char>{jsInput}, std::istreambuf_iterator<char>(), jsInserter);
|
||||
//
|
||||
// std::ifstream bootstrapInput(absPath(BootstrapFilename));
|
||||
// std::ifstream cssInput(absPath(CssFilename));
|
||||
//
|
||||
// std::string cssContent;
|
||||
// std::back_insert_iterator<std::string> cssInserter(cssContent);
|
||||
//
|
||||
// std::copy(std::istreambuf_iterator<char>{bootstrapInput}, std::istreambuf_iterator<char>(), cssInserter);
|
||||
// std::copy(std::istreambuf_iterator<char>{cssInput}, std::istreambuf_iterator<char>(), cssInserter);
|
||||
//
|
||||
// std::ifstream mainTemplateInput(absPath(MainTemplateFilename));
|
||||
// std::string mainTemplateContent{ std::istreambuf_iterator<char>{mainTemplateInput},
|
||||
// std::istreambuf_iterator<char>{} };
|
||||
//
|
||||
// std::ifstream keybindingTemplateInput(absPath(KeybindingTemplateFilename));
|
||||
// std::string keybindingTemplateContent{ std::istreambuf_iterator<char>{keybindingTemplateInput},
|
||||
// std::istreambuf_iterator<char>{} };
|
||||
//
|
||||
// std::stringstream json;
|
||||
// json << "[";
|
||||
// bool first = true;
|
||||
// for (const auto& p : _keyLua) {
|
||||
// if (!first) {
|
||||
// json << ",";
|
||||
// }
|
||||
// first = false;
|
||||
// json << "{";
|
||||
// json << "\"key\": \"" << std::to_string(p.first) << "\",";
|
||||
// json << "\"script\": \"" << p.second.command << "\",";
|
||||
// json << "\"remoteScripting\": " << (p.second.synchronization ? "true," : "false,");
|
||||
// json << "\"documentation\": \"" << p.second.documentation << "\"";
|
||||
// json << "}";
|
||||
// }
|
||||
// json << "]";
|
||||
//
|
||||
// std::string jsonString = "";
|
||||
// for (const char& c : json.str()) {
|
||||
// if (c == '\'') {
|
||||
// jsonString += "\\'";
|
||||
// } else {
|
||||
// jsonString += c;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// std::string generationTime;
|
||||
// try {
|
||||
// generationTime = Time::now().ISO8601();
|
||||
// }
|
||||
// catch (...) {}
|
||||
//
|
||||
// std::stringstream html;
|
||||
// html << "<!DOCTYPE html>\n"
|
||||
// << "<html>\n"
|
||||
// << "\t<head>\n"
|
||||
// << "\t\t<script id=\"mainTemplate\" type=\"text/x-handlebars-template\">\n"
|
||||
// << mainTemplateContent << "\n"
|
||||
// << "\t\t</script>\n"
|
||||
// << "\t\t<script id=\"keybindingTemplate\" type=\"text/x-handlebars-template\">\n"
|
||||
// << keybindingTemplateContent << "\n"
|
||||
// << "\t\t</script>\n"
|
||||
// << "\t<script>\n"
|
||||
// << "var keybindings = JSON.parse('" << jsonString << "');\n"
|
||||
// << "var version = [" << OPENSPACE_VERSION_MAJOR << ", " << OPENSPACE_VERSION_MINOR << ", " << OPENSPACE_VERSION_PATCH << "];\n"
|
||||
// << "var generationTime = '" << generationTime << "';\n"
|
||||
// << jsContent << "\n"
|
||||
// << "\t</script>\n"
|
||||
// << "\t<style type=\"text/css\">\n"
|
||||
// << cssContent << "\n"
|
||||
// << "\t</style>\n"
|
||||
// << "\t\t<title>Documentation</title>\n"
|
||||
// << "\t</head>\n"
|
||||
// << "\t<body>\n"
|
||||
// << "\t<body>\n"
|
||||
// << "</html>\n";
|
||||
//
|
||||
// f << html.str();
|
||||
//
|
||||
//
|
||||
// /*
|
||||
// for (const auto& p : _keyLua) {
|
||||
// html << "\t\t<tr>\n"
|
||||
// << "\t\t\t<td>" << std::to_string(p.first) << "</td>\n"
|
||||
// << "\t\t\t<td>" << p.second.first << "</td>\n"
|
||||
// << "\t\t\t<td>" << (p.second.second ? "Yes" : "No") << "</td>\n"
|
||||
// << "\t\t</tr>\n";
|
||||
// }*/
|
||||
// }
|
||||
// else {
|
||||
// throw ghoul::RuntimeError(
|
||||
// "Unsupported keyboard documentation type '" + type + "'",
|
||||
// "InteractionHandler"
|
||||
// );
|
||||
// }
|
||||
//}
|
||||
|
||||
scripting::LuaLibrary InteractionHandler::luaLibrary() {
|
||||
return{
|
||||
|
||||
136
src/util/documented.cpp
Normal file
136
src/util/documented.cpp
Normal file
@@ -0,0 +1,136 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2017 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/util/documented.h>
|
||||
|
||||
#include <openspace/openspace.h>
|
||||
#include <openspace/util/time.h>
|
||||
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/misc/invariants.h>
|
||||
|
||||
#include <fstream>
|
||||
|
||||
namespace {
|
||||
const char* HandlebarsFilename = "${OPENSPACE_DATA}/web/common/handlebars-v4.0.5.js";
|
||||
const char* BootstrapFilename = "${OPENSPACE_DATA}/web/common/bootstrap.min.css";
|
||||
const char* CssFilename = "${OPENSPACE_DATA}/web/common/style.css";
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
|
||||
Documented::Documented(std::string name,
|
||||
std::string jsonName,
|
||||
std::vector<HandlebarTemplate> handlebarTemplates,
|
||||
std::string javascriptFilename)
|
||||
: _name(std::move(name))
|
||||
, _jsonName(std::move(jsonName))
|
||||
, _handlebarTemplates(std::move(handlebarTemplates))
|
||||
, _javascriptFile(std::move(javascriptFilename))
|
||||
{
|
||||
ghoul_precondition(!_name.empty(), "name must not be empty");
|
||||
ghoul_precondition(!_jsonName.empty(), "jsonName must not be empty");
|
||||
ghoul_precondition(
|
||||
!_handlebarTemplates.empty(),
|
||||
"handlebarTemplates must not be empty"
|
||||
);
|
||||
ghoul_precondition(!_javascriptFile.empty(), "javascriptFilename must not be empty");
|
||||
}
|
||||
|
||||
void Documented::writeDocumentation(const std::string& filename) {
|
||||
std::ifstream handlebarsInput(absPath(HandlebarsFilename));
|
||||
std::ifstream jsInput(absPath(_javascriptFile));
|
||||
|
||||
std::string jsContent;
|
||||
std::back_insert_iterator<std::string> jsInserter(jsContent);
|
||||
|
||||
std::copy(std::istreambuf_iterator<char>{handlebarsInput}, std::istreambuf_iterator<char>(), jsInserter);
|
||||
std::copy(std::istreambuf_iterator<char>{jsInput}, std::istreambuf_iterator<char>(), jsInserter);
|
||||
|
||||
std::ifstream bootstrapInput(absPath(BootstrapFilename));
|
||||
std::ifstream cssInput(absPath(CssFilename));
|
||||
|
||||
std::string cssContent;
|
||||
std::back_insert_iterator<std::string> cssInserter(cssContent);
|
||||
|
||||
std::copy(std::istreambuf_iterator<char>{bootstrapInput}, std::istreambuf_iterator<char>(), cssInserter);
|
||||
std::copy(std::istreambuf_iterator<char>{cssInput}, std::istreambuf_iterator<char>(), cssInserter);
|
||||
|
||||
std::ofstream file;
|
||||
file.exceptions(~std::ofstream::goodbit);
|
||||
file.open(filename);
|
||||
|
||||
std::string json = generateJson();
|
||||
// We probably should escape backslashes here?
|
||||
|
||||
file << "<!DOCTYPE html>" << '\n'
|
||||
<< "<html>" << '\n'
|
||||
<< "\t" << "<head>" << '\n';
|
||||
|
||||
for (const HandlebarTemplate& t : _handlebarTemplates) {
|
||||
const char* Type = "text/x-handlebars-template";
|
||||
file << "\t\t"
|
||||
<< "<script id=\"" << t.name << "\" type=\"" << Type << "\">" << '\n';
|
||||
|
||||
std::ifstream templateFilename(absPath(t.filename));
|
||||
std::string templateContent(
|
||||
std::istreambuf_iterator<char>{templateFilename},
|
||||
std::istreambuf_iterator<char>{}
|
||||
);
|
||||
file << templateContent << '\n';
|
||||
file << "\t"
|
||||
<< "</script>" << '\n';
|
||||
}
|
||||
|
||||
const std::string Version =
|
||||
"[" +
|
||||
std::to_string(OPENSPACE_VERSION_MAJOR) + "," +
|
||||
std::to_string(OPENSPACE_VERSION_MINOR) + "," +
|
||||
std::to_string(OPENSPACE_VERSION_PATCH) +
|
||||
"]";
|
||||
|
||||
std::string generationTime;
|
||||
try {
|
||||
generationTime = Time::now().ISO8601();
|
||||
}
|
||||
catch (...) {}
|
||||
|
||||
file
|
||||
<< "\t" << "<script>" << '\n'
|
||||
<< "\t\t" << "var " << _jsonName << " = JSON.parse('" << json << "');" << '\n'
|
||||
<< "\t\t" << "var version = " << Version << ";" << '\n'
|
||||
<< "\t\t" << "var generationTime = '" << generationTime << "';" << '\n'
|
||||
<< "\t\t" << jsContent << '\n'
|
||||
<< "\t" << "</script>" << '\n'
|
||||
<< "\t" << "<style type=\"text/css\">" << '\n'
|
||||
<< "\t\t" << cssContent << '\n'
|
||||
<< "\t" << "</style>" << '\n'
|
||||
<< "\t\t" << "<title>" << _name << "</title>" << '\n'
|
||||
<< "\t" << "</head>" << '\n'
|
||||
<< "\t" << "<body>" << '\n'
|
||||
<< "\t" << "</body>" << '\n'
|
||||
<< "</html>" << '\n';
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
Reference in New Issue
Block a user