Skip to content
This repository has been archived by the owner on Oct 20, 2022. It is now read-only.

Commit

Permalink
Add a load Inja callback that loads the JSON data for a given refid.
Browse files Browse the repository at this point in the history
In certain contexts, Doxygen omits information about template parameters. For
example, in the Doxygen data for a group, information on the template
parameters of classes in that group is not available. This omission is quite
unfortunate, as it's rather vital, and it makes it impossible to properly
render the declarations of classes within a group.

Fortunately, the template parameter information is available in the data file
for the class itself. We can always find that data file, because we always have
its refid.

So, if we are able to load a Doxygen data file by refid as JSON within
Doxybook, we can always get access to the template parameters of a class, or any
other missing information.

To load the data for a refid, we need:

* A `Doxygen` object, to find the `Node` for the refid in the `Node` cache.
* A `JsonConverter` object, to load the data from the `Node`.

We must add all Inja callbacks before we load the templates. The templates are
loaded in the constructor of `Renderer` objects, so we typically add our Inja
callbacks in that constructor.

However, `Renderer` objects have access to neither a `Doxygen` object nor a
`JsonConverter` object. Moving the template loading logic to a place that does
have access to a `Doxygen` and `JsonConverter` object would be a big and
undesirable change.

`Renderer` objects are contained in `Generator` objects, which also contain a
reference to an `JsonConverter` object. A reference to a `Doxygen` object
was added to `Generator`, which was fairly straightforward. There's always a
`Doxygen` object around when a `Generator` is constructed, and `Generator` has
a number of methods that need to be passed a `Doxygen` object anyways.

A reference to both a `Doxygen` and `JsonConverter` was also added to `Renderer`
objects; `Generator` passes them through upon construction of a `Renderer.
  • Loading branch information
brycelelbach committed Jun 5, 2021
1 parent e2083f2 commit 8704496
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 35 deletions.
14 changes: 8 additions & 6 deletions include/Doxybook/Generator.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once
#include "JsonConverter.hpp"
#include "Doxygen.hpp"
#include "Renderer.hpp"
#include <string>
#include <unordered_set>
Expand All @@ -16,15 +17,15 @@ namespace Doxybook2 {
};

explicit Generator(const Config& config,
const Doxygen& doxygen,
const JsonConverter& jsonConverter,
const std::optional<std::string>& templatesPath);

void print(const Doxygen& doxygen, const Filter& filter, const Filter& skip);
void json(const Doxygen& doxygen, const Filter& filter, const Filter& skip);
void manifest(const Doxygen& doxygen);
void printIndex(const Doxygen& doxygen, FolderCategory type, const Filter& filter, const Filter& skip);
void summary(const Doxygen& doxygen,
const std::string& inputFile,
void print(const Filter& filter, const Filter& skip);
void json(const Filter& filter, const Filter& skip);
void manifest();
void printIndex(FolderCategory type, const Filter& filter, const Filter& skip);
void summary(const std::string& inputFile,
const std::string& outputFile,
const std::vector<SummarySection>& sections);

Expand All @@ -43,6 +44,7 @@ namespace Doxybook2 {
bool shouldInclude(const Node& node);

const Config& config;
const Doxygen& doxygen;
const JsonConverter& jsonConverter;
Renderer renderer;
};
Expand Down
6 changes: 5 additions & 1 deletion include/Doxybook/Renderer.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#pragma once
#include "Config.hpp"
#include "JsonConverter.hpp"
#include "Doxygen.hpp"
#include <memory>
#include <nlohmann/json.hpp>
#include <optional>
Expand All @@ -14,14 +16,16 @@ namespace inja {
namespace Doxybook2 {
class Renderer {
public:
explicit Renderer(const Config& config, const std::optional<std::string>& templatesPath = std::nullopt);
explicit Renderer(const Config& config, const Doxygen& doxygen, const JsonConverter& jsonConverter, const std::optional<std::string>& templatesPath = std::nullopt);
~Renderer();

void render(const std::string& name, const std::string& path, const nlohmann::json& data) const;
std::string render(const std::string& name, const nlohmann::json& data) const;

private:
const Config& config;
const Doxygen& doxygen;
const JsonConverter& jsonConverter;

std::unique_ptr<inja::Environment> env;
std::unordered_map<std::string, std::unique_ptr<inja::Template>> templates;
Expand Down
17 changes: 9 additions & 8 deletions src/Doxybook/Generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <Doxybook/Path.hpp>
#include <Doxybook/Renderer.hpp>
#include <Doxybook/Utils.hpp>
#include <inja/inja.hpp>
#include <filesystem>
#include <fstream>

Expand Down Expand Up @@ -38,13 +39,14 @@ std::string Doxybook2::Generator::kindToTemplateName(const Kind kind) {
}

Doxybook2::Generator::Generator(const Config& config,
const Doxygen& doxygen,
const JsonConverter& jsonConverter,
const std::optional<std::string>& templatesPath)
: config(config), jsonConverter(jsonConverter), renderer(config, templatesPath) {
: config(config), doxygen(doxygen), jsonConverter(jsonConverter),
renderer(config, doxygen, jsonConverter, templatesPath) {
}

void Doxybook2::Generator::summary(const Doxygen& doxygen,
const std::string& inputFile,
void Doxybook2::Generator::summary(const std::string& inputFile,
const std::string& outputFile,
const std::vector<SummarySection>& sections) {

Expand Down Expand Up @@ -163,15 +165,15 @@ void Doxybook2::Generator::jsonRecursively(const Node& parent, const Filter& fil
}
}

void Doxybook2::Generator::print(const Doxygen& doxygen, const Filter& filter, const Filter& skip) {
void Doxybook2::Generator::print(const Filter& filter, const Filter& skip) {
printRecursively(doxygen.getIndex(), filter, skip);
}

void Doxybook2::Generator::json(const Doxygen& doxygen, const Filter& filter, const Filter& skip) {
void Doxybook2::Generator::json(const Filter& filter, const Filter& skip) {
jsonRecursively(doxygen.getIndex(), filter, skip);
}

void Doxybook2::Generator::manifest(const Doxygen& doxygen) {
void Doxybook2::Generator::manifest() {
auto data = manifestRecursively(doxygen.getIndex());
const auto path = Path::join(config.outputDir, "manifest.json");

Expand Down Expand Up @@ -207,8 +209,7 @@ nlohmann::json Doxybook2::Generator::manifestRecursively(const Node& node) {
return ret;
}

void Doxybook2::Generator::printIndex(const Doxygen& doxygen,
const FolderCategory type,
void Doxybook2::Generator::printIndex(const FolderCategory type,
const Filter& filter,
const Filter& skip) {
const auto path = typeToIndexName(config, type) + "." + config.fileExt;
Expand Down
15 changes: 12 additions & 3 deletions src/Doxybook/Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,13 @@ static std::string basename(const std::string& path) {
return str.substr(0, found);
}

Doxybook2::Renderer::Renderer(const Config& config, const std::optional<std::string>& templatesPath)
: config(config), env(std::make_unique<inja::Environment>(
templatesPath.has_value() ? trimPath(*templatesPath) + SEPARATOR : "./")) {
Doxybook2::Renderer::Renderer(const Config& config,
const Doxygen& doxygen,
const JsonConverter& jsonConverter,
const std::optional<std::string>& templatesPath)
: config(config), doxygen(doxygen), jsonConverter(jsonConverter),
env(std::make_unique<inja::Environment>(
templatesPath.has_value() ? trimPath(*templatesPath) + SEPARATOR : "./")) {

env->add_callback("isEmpty", 1, [](inja::Arguments& args) -> bool {
const auto arg = args.at(0)->get<std::string>();
Expand Down Expand Up @@ -153,6 +157,10 @@ Doxybook2::Renderer::Renderer(const Config& config, const std::optional<std::str
const auto data = args.at(1)->get<nlohmann::json>();
return this->render(name, data);
});
env->add_callback("load", 1, [&](inja::Arguments& args) -> nlohmann::json {
const auto refid = args.at(0)->get<std::string>();
return jsonConverter.getAsJson(*doxygen.find(refid));
});
env->add_callback("replace", 3, [=](inja::Arguments& args) -> nlohmann::json {
auto str = args.at(0)->get<std::string>();
const auto what = args.at(1)->get<std::string>();
Expand Down Expand Up @@ -357,3 +365,4 @@ std::string Doxybook2::Renderer::render(const std::string& name, const nlohmann:
}
return ss.str();
}

33 changes: 16 additions & 17 deletions src/DoxybookCli/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ int main(const int argc, char* argv[]) {
templatesPath = args["templates"].as<std::string>();
}

Generator generator(config, jsonConverter, templatesPath);
Generator generator(config, doxygen, jsonConverter, templatesPath);

const auto shouldGenerate = [&](const FolderCategory category) {
return std::find(config.foldersToGenerate.begin(), config.foldersToGenerate.end(), category) !=
Expand Down Expand Up @@ -180,11 +180,11 @@ int main(const int argc, char* argv[]) {
Log::i("Rendering...");

if (args["json"]) {
generator.json(doxygen, LANGUAGE_FILTER, {});
generator.json(doxygen, INDEX_FILES_FILTER, {});
generator.json(doxygen, INDEX_PAGES_FILTER, {});
generator.json(LANGUAGE_FILTER, {});
generator.json(INDEX_FILES_FILTER, {});
generator.json(INDEX_PAGES_FILTER, {});

generator.manifest(doxygen);
generator.manifest();
} else {
if (args["summary-input"] && args["summary-output"]) {
std::vector<Generator::SummarySection> sections;
Expand All @@ -207,8 +207,7 @@ int main(const int argc, char* argv[]) {
sections.push_back({FolderCategory::EXAMPLES, INDEX_EXAMPLES_FILTER, {}});
}

generator.summary(doxygen,
args["summary-input"].as<std::string>(),
generator.summary(args["summary-input"].as<std::string>(),
args["summary-output"].as<std::string>(),
sections);
}
Expand All @@ -227,36 +226,36 @@ int main(const int argc, char* argv[]) {
languageFilder.insert(Kind::MODULE);
}
if (!languageFilder.empty()) {
generator.print(doxygen, languageFilder, {});
generator.print(languageFilder, {});
}

if (shouldGenerate(FolderCategory::FILES)) {
generator.print(doxygen, INDEX_FILES_FILTER, {});
generator.print(INDEX_FILES_FILTER, {});
}
if (shouldGenerate(FolderCategory::PAGES)) {
generator.print(doxygen, INDEX_PAGES_FILTER, {});
generator.print(INDEX_PAGES_FILTER, {});
}
if (shouldGenerate(FolderCategory::EXAMPLES)) {
generator.print(doxygen, INDEX_EXAMPLES_FILTER, {});
generator.print(INDEX_EXAMPLES_FILTER, {});
}

if (shouldGenerate(FolderCategory::CLASSES)) {
generator.printIndex(doxygen, FolderCategory::CLASSES, INDEX_CLASS_FILTER, {});
generator.printIndex(FolderCategory::CLASSES, INDEX_CLASS_FILTER, {});
}
if (shouldGenerate(FolderCategory::NAMESPACES)) {
generator.printIndex(doxygen, FolderCategory::NAMESPACES, INDEX_NAMESPACES_FILTER, {});
generator.printIndex(FolderCategory::NAMESPACES, INDEX_NAMESPACES_FILTER, {});
}
if (shouldGenerate(FolderCategory::MODULES)) {
generator.printIndex(doxygen, FolderCategory::MODULES, INDEX_MODULES_FILTER, {});
generator.printIndex(FolderCategory::MODULES, INDEX_MODULES_FILTER, {});
}
if (shouldGenerate(FolderCategory::FILES)) {
generator.printIndex(doxygen, FolderCategory::FILES, INDEX_FILES_FILTER, {});
generator.printIndex(FolderCategory::FILES, INDEX_FILES_FILTER, {});
}
if (shouldGenerate(FolderCategory::PAGES)) {
generator.printIndex(doxygen, FolderCategory::PAGES, INDEX_PAGES_FILTER, {});
generator.printIndex(FolderCategory::PAGES, INDEX_PAGES_FILTER, {});
}
if (shouldGenerate(FolderCategory::EXAMPLES)) {
generator.printIndex(doxygen, FolderCategory::EXAMPLES, INDEX_EXAMPLES_FILTER, {});
generator.printIndex(FolderCategory::EXAMPLES, INDEX_EXAMPLES_FILTER, {});
}
}
} else {
Expand Down

0 comments on commit 8704496

Please # to comment.