Skip to content

Commit

Permalink
feat: embedded option
Browse files Browse the repository at this point in the history
Like the asciidoc option, this option can be used to generate pages without the surrounding tags to include them in other documentation pages, like the mrdocs website.
  • Loading branch information
alandefreitas committed Nov 14, 2024
1 parent 1d253d7 commit decaf3e
Show file tree
Hide file tree
Showing 191 changed files with 5,726 additions and 5,223 deletions.
5 changes: 5 additions & 0 deletions docs/mrdocs.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@
"title": "Detect SFINAE expressions",
"type": "boolean"
},
"embedded": {
"default": false,
"title": "Output an embeddable document, which excludes the header, the footer, and everything outside the body of the document. This option is useful for producing documents that can be inserted into an external template.",
"type": "boolean"
},
"filters": {
"properties": {
"symbols": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
{{#if relfileprefix}}:relfileprefix: {{relfileprefix}}{{/if}}
[#{{sectionref}}]

={{#unless is_multipage}}={{/unless}} {{#if symbol.name}}{{>types/nested-name-specifier symbol=symbol.parent includeNamespace=true}}{{symbol.name}}{{else}}Unnamed overload set{{/if}}
={{#unless @root.config.multipage}}={{/unless}} {{#if symbol.name}}{{>types/nested-name-specifier symbol=symbol.parent includeNamespace=true}}{{symbol.name}}{{else}}Unnamed overload set{{/if}}

{{#if symbol.members.[0]}}

Expand All @@ -12,7 +12,7 @@

{{/if}}

=={{#unless is_multipage}}={{/unless}} Synopsis
=={{#unless @root.config.multipage}}={{/unless}} Synopsis

{{#each symbol.members as | member |}}

Expand All @@ -23,14 +23,14 @@
{{/each}}
{{#if symbol.members.[0].doc.description}}
=={{#unless is_multipage}}={{/unless}} Description
=={{#unless @root.config.multipage}}={{/unless}} Description
{{symbol.members.[0].doc.description}}
{{/if}}
{{#with (flattenUnique symbol.members "doc.exceptions" "exception") as |allExceptions|}}
{{#if (ne (len allExceptions) 0)}}
=={{#unless is_multipage}}={{/unless}} Exceptions
=={{#unless @root.config.multipage}}={{/unless}} Exceptions
|===
| Name | Thrown on
Expand All @@ -44,15 +44,15 @@
{{/with}}
{{#if symbol.members.[0].doc.returns}}
=={{#unless is_multipage}}={{/unless}} Return Value
=={{#unless @root.config.multipage}}={{/unless}} Return Value
{{symbol.members.[0].doc.returns}}
{{/if}}
{{#with (flattenUnique symbol.members "doc.params" "name") as |allParams|}}
{{#if (ne (len allParams) 0)}}
=={{#unless is_multipage}}={{/unless}} Parameters
=={{#unless @root.config.multipage}}={{/unless}} Parameters
|===
| Name | Description {{! TODO: | Type? }}
Expand All @@ -66,7 +66,7 @@
{{/with}}
{{#if symbol.members.[0].doc.preconditions}}
=={{#unless is_multipage}}={{/unless}} Preconditions
=={{#unless @root.config.multipage}}={{/unless}} Preconditions
{{#each symbol.members.[0].doc.preconditions}}
{{.}}
Expand All @@ -75,7 +75,7 @@
{{/if}}
{{#if symbol.members.[0].doc.postconditions}}
=={{#unless is_multipage}}={{/unless}} Postconditions
=={{#unless @root.config.multipage}}={{/unless}} Postconditions
{{#each symbol.members.[0].doc.postconditions}}
{{.}}
Expand All @@ -84,7 +84,7 @@
{{/if}}
{{#if symbol.members.[0].doc.see}}
=={{#unless is_multipage}}={{/unless}} See Also
=={{#unless @root.config.multipage}}={{/unless}} See Also
{{#each symbol.members.[0].doc.see}}
{{.}}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{{! The section with a symbol in single page output or the symbol page in multi page output }}
{{#if relfileprefix}}:relfileprefix: {{relfileprefix}}{{/if}}
[#{{sectionref}}]

[#{{sectionref}}]
{{> (concat 'symbols' '/' (lookup symbol 'kind')) symbol=symbol}}

This file was deleted.

This file was deleted.

9 changes: 9 additions & 0 deletions share/mrdocs/addons/generator/adoc/layouts/wrapper.adoc.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{{! The wrapper for single page documentation or symbols in a multipage documentation }}
{{#unless @root.config.multipage }}
= Reference
:mrdocs:
{{/unless}}
{{! Content generated with index.hbs }}
{{contents}}

[.small]#Created with https://www.mrdocs.com[MrDocs]#
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{{! A page when the symbol type is "overloads" }}
{{#if relfileprefix}}<meta name="relfileprefix" content="{{relfileprefix}}">{{/if}}
<div id="{{#if (is_multipage)}}{{symbol.id}}{{else}}{{symbol.ref}}{{/if}}">
<div id="{{#if @root.config.multipage}}{{symbol.id}}{{else}}{{symbol.ref}}{{/if}}">

<h1>{{#if symbol.name}}Overload set {{>types/nested-name-specifier symbol=symbol.parent}}{{symbol.name}}{{else}}Unnamed overload set{{/if}}</h1>

Expand Down

This file was deleted.

This file was deleted.

15 changes: 15 additions & 0 deletions share/mrdocs/addons/generator/html/layouts/wrapper.html.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{{! The wrapper for single page documentation or symbols in a multipage documentation }}
<html lang="en">
<head>
<title>Reference{{#if symbol}}: {{symbol.name}}{{/if}}</title>
</head>
<body>
<div>
{{! Content generated with index.hbs }}
{{contents}}
</div>
<div>
<h4>Created with <a href="https://www.mrdocs.com">MrDocs</a></h4>
</div>
</body>
</html>
134 changes: 92 additions & 42 deletions src/lib/Gen/hbs/Builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ Builder(
hbs_.registerPartial(
path.generic_string(), *text);
return Error::success();
}).maybeThrow();
}).maybeThrow();

// Load JavaScript helpers
std::string helpersPath = files::appendPath(
Expand Down Expand Up @@ -143,23 +143,8 @@ callTemplate(
return *exp;
}

Expected<std::string>
Builder::
renderSinglePageHeader()
{
return callTemplate(fmt::format("single-header.{}.hbs", domCorpus.fileExtension), {});
}

Expected<std::string>
Builder::
renderSinglePageFooter()
{
return callTemplate(fmt::format("single-footer.{}.hbs", domCorpus.fileExtension), {});
}

//------------------------------------------------


std::string
Builder::
getRelPrefix(std::size_t depth)
Expand All @@ -177,58 +162,123 @@ getRelPrefix(std::size_t depth)
return rel_prefix;
}

dom::Value
dom::Object
Builder::
createContext(
Info const& I)
{
dom::Object::storage_type props;
props.emplace_back("symbol",
domCorpus.get(I.id));
props.emplace_back("relfileprefix",
getRelPrefix(I.Namespace.size()));
props.emplace_back("config", domCorpus->config.object());
props.emplace_back("sectionref",
domCorpus.names_.getQualified(I.id, '-'));
return dom::Object(std::move(props));
dom::Object ctx;
ctx.set("symbol", domCorpus.get(I.id));
ctx.set("relfileprefix", getRelPrefix(I.Namespace.size()));
ctx.set("config", domCorpus->config.object());
ctx.set("sectionref", domCorpus.names_.getQualified(I.id, '-'));
return ctx;
}

dom::Value
dom::Object
Builder::
createContext(
OverloadSet const& OS)
{
dom::Object::storage_type props;
props.emplace_back("symbol",
domCorpus.getOverloads(OS));
dom::Object ctx;
ctx.set("symbol", domCorpus.getOverloads(OS));
const Info& Parent = domCorpus->get(OS.Parent);
props.emplace_back("relfileprefix",
getRelPrefix(Parent.Namespace.size() + 1));
props.emplace_back("config", domCorpus->config.object());
props.emplace_back("sectionref",
domCorpus.names_.getQualified(OS, '-'));
return dom::Object(std::move(props));
ctx.set("relfileprefix", getRelPrefix(Parent.Namespace.size() + 1));
ctx.set("config", domCorpus->config.object());
ctx.set("sectionref", domCorpus.names_.getQualified(OS, '-'));
return ctx;
}

template<class T>
Expected<std::string>
Builder::
operator()(T const& I)
{
return callTemplate(
fmt::format("single-symbol.{}.hbs", domCorpus.fileExtension),
createContext(I));
auto const templateFile = fmt::format("index.{}.hbs", domCorpus.fileExtension);
dom::Object ctx = createContext(I);

auto& config = domCorpus->config;
bool isSinglePage = !config->multipage;
if (config->embedded ||
isSinglePage)
{
return callTemplate(templateFile, ctx);
}

auto const wrapperFile = fmt::format("wrapper.{}.hbs", domCorpus.fileExtension);
dom::Object wrapperCtx = createFrame(ctx);
wrapperCtx.set("contents", dom::makeInvocable([this, &I, templateFile](
dom::Value const& options) -> Expected<dom::Value>
{
// Helper to write contents directly to stream
return callTemplate(templateFile, createContext(I));
}));
return callTemplate(wrapperFile, wrapperCtx);
}

Expected<std::string>
Builder::
operator()(OverloadSet const& OS)
{
return callTemplate(
fmt::format("overload-set.{}.hbs", domCorpus.fileExtension),
createContext(OS));
auto const templateFile = fmt::format("index-overload-set.{}.hbs", domCorpus.fileExtension);
dom::Object ctx = createContext(OS);

auto& config = domCorpus->config;
bool isSinglePage = !config->multipage;
if (config->embedded ||
isSinglePage)
{
return callTemplate(templateFile, ctx);
}

auto const wrapperFile = fmt::format("wrapper.{}.hbs", domCorpus.fileExtension);
dom::Object wrapperCtx = createFrame(ctx);
wrapperCtx.set("contents", dom::makeInvocable([this, &OS, templateFile](
dom::Value const& options) -> Expected<dom::Value>
{
// Helper to write contents directly to stream
return callTemplate(templateFile, createContext(OS));
}));
return callTemplate(wrapperFile, wrapperCtx);
}

Expected<void>
Builder::
wrapPage(
std::ostream& out,
std::istream& in)
{
auto const wrapperFile = fmt::format("wrapper.{}.hbs", domCorpus.fileExtension);
dom::Object ctx;
ctx.set("contents", dom::makeInvocable([&in](
dom::Value const& options) -> Expected<dom::Value>
{
// Helper to write contents directly to stream
// AFREITAS: custom functions should set options["write"]
// to avoid creating a string.
return std::string(
std::istreambuf_iterator<char>(in),
std::istreambuf_iterator<char>());
}));
// Render directly to ostream
Config const& config = domCorpus->config;
auto layoutDir = files::appendPath(config->addons,
"generator", domCorpus.fileExtension, "layouts");
auto pathName = files::appendPath(layoutDir, wrapperFile);
MRDOCS_TRY(auto fileText, files::getFileText(pathName));
HandlebarsOptions options;
options.noEscape = true;
OutputRef outRef(out);
Expected<void, HandlebarsError> exp =
hbs_.try_render_to(outRef, fileText, ctx, options);
if (!exp)
{
return Unexpected(Error(exp.error().what()));
}
return {};
}


// Define Builder::operator() for each Info type
#define DEFINE(T) template Expected<std::string> \
Builder::operator()<T>(T const&)
Expand Down
19 changes: 9 additions & 10 deletions src/lib/Gen/hbs/Builder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,12 @@ class Builder
Expected<std::string>
operator()(OverloadSet const&);

/** Render the header for a single page.
/** Wrap the contents of a page in the page template.
*/
Expected<std::string>
renderSinglePageHeader();

/** Render the footer for a single page.
*/
Expected<std::string>
renderSinglePageFooter();
Expected<void>
wrapPage(
std::ostream& out,
std::istream& in);

private:
/** Create a handlebars context with the symbol and helper information.
Expand All @@ -73,10 +70,12 @@ class Builder
It also includes a sectionref helper that describes
the section where the symbol is located.
*/
dom::Value createContext(Info const& I);
dom::Object
createContext(Info const& I);

/// @copydoc createContext(Info const&)
dom::Value createContext(OverloadSet const& OS);
dom::Object
createContext(OverloadSet const& OS);

/** Render a Handlebars template from the templates directory.
*/
Expand Down
Loading

0 comments on commit decaf3e

Please sign in to comment.