Skip to content

Commit decaf3e

Browse files
committed
feat: embedded option
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.
1 parent 1d253d7 commit decaf3e

File tree

191 files changed

+5726
-5223
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

191 files changed

+5726
-5223
lines changed

docs/mrdocs.schema.json

+5
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@
5050
"title": "Detect SFINAE expressions",
5151
"type": "boolean"
5252
},
53+
"embedded": {
54+
"default": false,
55+
"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.",
56+
"type": "boolean"
57+
},
5358
"filters": {
5459
"properties": {
5560
"symbols": {

share/mrdocs/addons/generator/adoc/layouts/overload-set.adoc.hbs renamed to share/mrdocs/addons/generator/adoc/layouts/index-overload-set.adoc.hbs

+9-9
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
{{#if relfileprefix}}:relfileprefix: {{relfileprefix}}{{/if}}
33
[#{{sectionref}}]
44

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

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

@@ -12,7 +12,7 @@
1212

1313
{{/if}}
1414

15-
=={{#unless is_multipage}}={{/unless}} Synopsis
15+
=={{#unless @root.config.multipage}}={{/unless}} Synopsis
1616

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

@@ -23,14 +23,14 @@
2323
{{/each}}
2424
2525
{{#if symbol.members.[0].doc.description}}
26-
=={{#unless is_multipage}}={{/unless}} Description
26+
=={{#unless @root.config.multipage}}={{/unless}} Description
2727
2828
{{symbol.members.[0].doc.description}}
2929
{{/if}}
3030
3131
{{#with (flattenUnique symbol.members "doc.exceptions" "exception") as |allExceptions|}}
3232
{{#if (ne (len allExceptions) 0)}}
33-
=={{#unless is_multipage}}={{/unless}} Exceptions
33+
=={{#unless @root.config.multipage}}={{/unless}} Exceptions
3434
3535
|===
3636
| Name | Thrown on
@@ -44,15 +44,15 @@
4444
{{/with}}
4545
4646
{{#if symbol.members.[0].doc.returns}}
47-
=={{#unless is_multipage}}={{/unless}} Return Value
47+
=={{#unless @root.config.multipage}}={{/unless}} Return Value
4848
4949
{{symbol.members.[0].doc.returns}}
5050
5151
{{/if}}
5252
5353
{{#with (flattenUnique symbol.members "doc.params" "name") as |allParams|}}
5454
{{#if (ne (len allParams) 0)}}
55-
=={{#unless is_multipage}}={{/unless}} Parameters
55+
=={{#unless @root.config.multipage}}={{/unless}} Parameters
5656
5757
|===
5858
| Name | Description {{! TODO: | Type? }}
@@ -66,7 +66,7 @@
6666
{{/with}}
6767
6868
{{#if symbol.members.[0].doc.preconditions}}
69-
=={{#unless is_multipage}}={{/unless}} Preconditions
69+
=={{#unless @root.config.multipage}}={{/unless}} Preconditions
7070
7171
{{#each symbol.members.[0].doc.preconditions}}
7272
{{.}}
@@ -75,7 +75,7 @@
7575
{{/if}}
7676
7777
{{#if symbol.members.[0].doc.postconditions}}
78-
=={{#unless is_multipage}}={{/unless}} Postconditions
78+
=={{#unless @root.config.multipage}}={{/unless}} Postconditions
7979
8080
{{#each symbol.members.[0].doc.postconditions}}
8181
{{.}}
@@ -84,7 +84,7 @@
8484
{{/if}}
8585
8686
{{#if symbol.members.[0].doc.see}}
87-
=={{#unless is_multipage}}={{/unless}} See Also
87+
=={{#unless @root.config.multipage}}={{/unless}} See Also
8888
8989
{{#each symbol.members.[0].doc.see}}
9090
{{.}}
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{{! The section with a symbol in single page output or the symbol page in multi page output }}
22
{{#if relfileprefix}}:relfileprefix: {{relfileprefix}}{{/if}}
3-
[#{{sectionref}}]
43

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

share/mrdocs/addons/generator/adoc/layouts/single-footer.adoc.hbs

-3
This file was deleted.

share/mrdocs/addons/generator/adoc/layouts/single-header.adoc.hbs

-3
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{{! The wrapper for single page documentation or symbols in a multipage documentation }}
2+
{{#unless @root.config.multipage }}
3+
= Reference
4+
:mrdocs:
5+
{{/unless}}
6+
{{! Content generated with index.hbs }}
7+
{{contents}}
8+
9+
[.small]#Created with https://www.mrdocs.com[MrDocs]#

share/mrdocs/addons/generator/html/layouts/overload-set.html.hbs renamed to share/mrdocs/addons/generator/html/layouts/index-overload-set.html.hbs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{{! A page when the symbol type is "overloads" }}
22
{{#if relfileprefix}}<meta name="relfileprefix" content="{{relfileprefix}}">{{/if}}
3-
<div id="{{#if (is_multipage)}}{{symbol.id}}{{else}}{{symbol.ref}}{{/if}}">
3+
<div id="{{#if @root.config.multipage}}{{symbol.id}}{{else}}{{symbol.ref}}{{/if}}">
44

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

share/mrdocs/addons/generator/html/layouts/single-footer.html.hbs

-5
This file was deleted.

share/mrdocs/addons/generator/html/layouts/single-header.html.hbs

-6
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{{! The wrapper for single page documentation or symbols in a multipage documentation }}
2+
<html lang="en">
3+
<head>
4+
<title>Reference{{#if symbol}}: {{symbol.name}}{{/if}}</title>
5+
</head>
6+
<body>
7+
<div>
8+
{{! Content generated with index.hbs }}
9+
{{contents}}
10+
</div>
11+
<div>
12+
<h4>Created with <a href="https://www.mrdocs.com">MrDocs</a></h4>
13+
</div>
14+
</body>
15+
</html>

src/lib/Gen/hbs/Builder.cpp

+92-42
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ Builder(
5757
hbs_.registerPartial(
5858
path.generic_string(), *text);
5959
return Error::success();
60-
}).maybeThrow();
60+
}).maybeThrow();
6161

6262
// Load JavaScript helpers
6363
std::string helpersPath = files::appendPath(
@@ -143,23 +143,8 @@ callTemplate(
143143
return *exp;
144144
}
145145

146-
Expected<std::string>
147-
Builder::
148-
renderSinglePageHeader()
149-
{
150-
return callTemplate(fmt::format("single-header.{}.hbs", domCorpus.fileExtension), {});
151-
}
152-
153-
Expected<std::string>
154-
Builder::
155-
renderSinglePageFooter()
156-
{
157-
return callTemplate(fmt::format("single-footer.{}.hbs", domCorpus.fileExtension), {});
158-
}
159-
160146
//------------------------------------------------
161147

162-
163148
std::string
164149
Builder::
165150
getRelPrefix(std::size_t depth)
@@ -177,58 +162,123 @@ getRelPrefix(std::size_t depth)
177162
return rel_prefix;
178163
}
179164

180-
dom::Value
165+
dom::Object
181166
Builder::
182167
createContext(
183168
Info const& I)
184169
{
185-
dom::Object::storage_type props;
186-
props.emplace_back("symbol",
187-
domCorpus.get(I.id));
188-
props.emplace_back("relfileprefix",
189-
getRelPrefix(I.Namespace.size()));
190-
props.emplace_back("config", domCorpus->config.object());
191-
props.emplace_back("sectionref",
192-
domCorpus.names_.getQualified(I.id, '-'));
193-
return dom::Object(std::move(props));
170+
dom::Object ctx;
171+
ctx.set("symbol", domCorpus.get(I.id));
172+
ctx.set("relfileprefix", getRelPrefix(I.Namespace.size()));
173+
ctx.set("config", domCorpus->config.object());
174+
ctx.set("sectionref", domCorpus.names_.getQualified(I.id, '-'));
175+
return ctx;
194176
}
195177

196-
dom::Value
178+
dom::Object
197179
Builder::
198180
createContext(
199181
OverloadSet const& OS)
200182
{
201-
dom::Object::storage_type props;
202-
props.emplace_back("symbol",
203-
domCorpus.getOverloads(OS));
183+
dom::Object ctx;
184+
ctx.set("symbol", domCorpus.getOverloads(OS));
204185
const Info& Parent = domCorpus->get(OS.Parent);
205-
props.emplace_back("relfileprefix",
206-
getRelPrefix(Parent.Namespace.size() + 1));
207-
props.emplace_back("config", domCorpus->config.object());
208-
props.emplace_back("sectionref",
209-
domCorpus.names_.getQualified(OS, '-'));
210-
return dom::Object(std::move(props));
186+
ctx.set("relfileprefix", getRelPrefix(Parent.Namespace.size() + 1));
187+
ctx.set("config", domCorpus->config.object());
188+
ctx.set("sectionref", domCorpus.names_.getQualified(OS, '-'));
189+
return ctx;
211190
}
212191

213192
template<class T>
214193
Expected<std::string>
215194
Builder::
216195
operator()(T const& I)
217196
{
218-
return callTemplate(
219-
fmt::format("single-symbol.{}.hbs", domCorpus.fileExtension),
220-
createContext(I));
197+
auto const templateFile = fmt::format("index.{}.hbs", domCorpus.fileExtension);
198+
dom::Object ctx = createContext(I);
199+
200+
auto& config = domCorpus->config;
201+
bool isSinglePage = !config->multipage;
202+
if (config->embedded ||
203+
isSinglePage)
204+
{
205+
return callTemplate(templateFile, ctx);
206+
}
207+
208+
auto const wrapperFile = fmt::format("wrapper.{}.hbs", domCorpus.fileExtension);
209+
dom::Object wrapperCtx = createFrame(ctx);
210+
wrapperCtx.set("contents", dom::makeInvocable([this, &I, templateFile](
211+
dom::Value const& options) -> Expected<dom::Value>
212+
{
213+
// Helper to write contents directly to stream
214+
return callTemplate(templateFile, createContext(I));
215+
}));
216+
return callTemplate(wrapperFile, wrapperCtx);
221217
}
222218

223219
Expected<std::string>
224220
Builder::
225221
operator()(OverloadSet const& OS)
226222
{
227-
return callTemplate(
228-
fmt::format("overload-set.{}.hbs", domCorpus.fileExtension),
229-
createContext(OS));
223+
auto const templateFile = fmt::format("index-overload-set.{}.hbs", domCorpus.fileExtension);
224+
dom::Object ctx = createContext(OS);
225+
226+
auto& config = domCorpus->config;
227+
bool isSinglePage = !config->multipage;
228+
if (config->embedded ||
229+
isSinglePage)
230+
{
231+
return callTemplate(templateFile, ctx);
232+
}
233+
234+
auto const wrapperFile = fmt::format("wrapper.{}.hbs", domCorpus.fileExtension);
235+
dom::Object wrapperCtx = createFrame(ctx);
236+
wrapperCtx.set("contents", dom::makeInvocable([this, &OS, templateFile](
237+
dom::Value const& options) -> Expected<dom::Value>
238+
{
239+
// Helper to write contents directly to stream
240+
return callTemplate(templateFile, createContext(OS));
241+
}));
242+
return callTemplate(wrapperFile, wrapperCtx);
230243
}
231244

245+
Expected<void>
246+
Builder::
247+
wrapPage(
248+
std::ostream& out,
249+
std::istream& in)
250+
{
251+
auto const wrapperFile = fmt::format("wrapper.{}.hbs", domCorpus.fileExtension);
252+
dom::Object ctx;
253+
ctx.set("contents", dom::makeInvocable([&in](
254+
dom::Value const& options) -> Expected<dom::Value>
255+
{
256+
// Helper to write contents directly to stream
257+
// AFREITAS: custom functions should set options["write"]
258+
// to avoid creating a string.
259+
return std::string(
260+
std::istreambuf_iterator<char>(in),
261+
std::istreambuf_iterator<char>());
262+
}));
263+
// Render directly to ostream
264+
Config const& config = domCorpus->config;
265+
auto layoutDir = files::appendPath(config->addons,
266+
"generator", domCorpus.fileExtension, "layouts");
267+
auto pathName = files::appendPath(layoutDir, wrapperFile);
268+
MRDOCS_TRY(auto fileText, files::getFileText(pathName));
269+
HandlebarsOptions options;
270+
options.noEscape = true;
271+
OutputRef outRef(out);
272+
Expected<void, HandlebarsError> exp =
273+
hbs_.try_render_to(outRef, fileText, ctx, options);
274+
if (!exp)
275+
{
276+
return Unexpected(Error(exp.error().what()));
277+
}
278+
return {};
279+
}
280+
281+
232282
// Define Builder::operator() for each Info type
233283
#define DEFINE(T) template Expected<std::string> \
234284
Builder::operator()<T>(T const&)

src/lib/Gen/hbs/Builder.hpp

+9-10
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,12 @@ class Builder
5454
Expected<std::string>
5555
operator()(OverloadSet const&);
5656

57-
/** Render the header for a single page.
57+
/** Wrap the contents of a page in the page template.
5858
*/
59-
Expected<std::string>
60-
renderSinglePageHeader();
61-
62-
/** Render the footer for a single page.
63-
*/
64-
Expected<std::string>
65-
renderSinglePageFooter();
59+
Expected<void>
60+
wrapPage(
61+
std::ostream& out,
62+
std::istream& in);
6663

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

7876
/// @copydoc createContext(Info const&)
79-
dom::Value createContext(OverloadSet const& OS);
77+
dom::Object
78+
createContext(OverloadSet const& OS);
8079

8180
/** Render a Handlebars template from the templates directory.
8281
*/

0 commit comments

Comments
 (0)