#pragma once
#include "Entity.hpp"
#include <unordered_set>
#include <filesystem>
#include <fstream>
#include <string>
#include <list>
/**
* Markdown generator.
*
* @ingroup developer
*/
class MarkdownGenerator {
public:
/**
* Constructor.
*
* @param output Output directory.
* @param style Markdown style.
*/
MarkdownGenerator(const std::filesystem::path& output,
const std::string& style);
/**
* Generate documentation.
*
* @param root Root entity.
* @param cov Include code coverage report?
*/
void generate(const Entity& root, const bool cov);
/**
* Clean up after generation, removing files from old runs. Traverses the
* output directory, removing any Markdown files with 'generator: doxide' in
* their YAML frontmatter that were not generated by previous calls of
* `generate()`.
*/
void clean();
private:
/**
* Recursively generate documentation.
*
* @param output Output directory.
* @param entity Entity for which to generate documentation.
* @param cov Include code coverage report?
*/
void generate(const std::filesystem::path& output, const Entity& entity,
const bool cov);
/**
* Recursively generate coverage.
*
* @param output Output directory.
* @param entity Entity for which to generate coverage.
*/
void coverage(const std::filesystem::path& output, const Entity& entity);
/**
* Recursively generate coverage table data.
*
* @param entity Entity for which to generate coverage.
* @param root Root entity for the current page. This is used to determine
* which are rows should be visible initially.
* @param out Output stream.
*/
static void coverage_data(const Entity& entity, const Entity& root,
std::ofstream& out);
/**
* Recursively generate coverage table footer.
*
* @param entity Entity for which to generate coverage.
* @param root Root entity for the current page. This is used to determine
* which are rows should be visible initially.
* @param out Output stream.
*/
static void coverage_foot(const Entity& entity, const Entity& root,
std::ofstream& out);
/**
* Produce sunburst chart of code coverage for entity.
*
* @param entity Entity for which to generate sunburst.
* @param root Root entity for the current page. This is used to determine
* paths relative to the root.
* @param out Output stream.
*/
static void sunburst(const Entity& entity, const Entity& root,
std::ofstream& out);
/**
* Produce data for sunburst chart of code coverage for entity.
*
* @param entity Entity for which to generate sunburst.
* @param root Root entity for the current page. This is used to determine
* paths relative to the root.
* @param out Output stream.
*/
static void sunburst_data(const Entity& entity, const Entity& root,
std::ofstream& out);
/**
* Produce a relative path.
*/
static std::string relative(const std::filesystem::path& path,
const std::filesystem::path& base);
/**
* Can the file be written? To be overwritten, the file must either not
* exist, or exists but has 'generator: doxide' in its YAML frontmatter.
*/
static bool can_write(const std::filesystem::path& path);
/**
* Produce the YAML frontmatter for an entity.
*/
static std::string frontmatter(const Entity& entity);
/**
* Produce title for an entity.
*/
static std::string title(const Entity& entity);
/**
* Produce brief description for an entity.
*/
static std::string brief(const Entity& entity);
/**
* Reduce to a single line.
*/
static std::string line(const std::string& str);
/**
* Indent lines for current Markdown style.
*/
std::string indent(const std::string& str = "");
/**
* Sanitize for a string, escaping double quotes and backslashes.
*/
static std::string stringify(const std::string& str);
/**
* Sanitize for HTML, replacing special characters with entities. Also
* replaces some characters that might trigger Markdown formatting.
*/
static std::string htmlize(const std::string& str);
/**
* Sanitize for a file name or internal anchor.
*/
static std::string sanitize(const std::string& str);
/**
* Lookup color for given percentage.
*/
static const std::string& color(const double percent);
/**
* Lookup icon for given percentage.
*/
static const std::string& icon(const double percent);
/**
* Convert a list of entities to a list of pointers to entities, optionally
* sorting by name.
*
* @param entities List of entities.
* @param sort Sort by name?
*/
static std::list<const Entity*> view(const std::list<Entity>& entities,
const bool sort);
/**
* Output directory.
*/
std::filesystem::path output;
/**
* Markdown style.
*/
std::string style;
/**
* Set of files generated during the last call to generate().
*/
std::unordered_set<std::filesystem::path> files;
};