Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

show-namespaces option #854

Merged
merged 3 commits into from
Feb 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion docs/mrdocs.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,16 @@
"title": "Detect and reduce SFINAE expressions",
"type": "boolean"
},
"show-namespaces": {
"default": true,
"description": "When set to true, MrDocs creates a page for each namespace in the documentation.",
"enum": [
true,
false
],
"title": "Show namespace pages in the documentation",
"type": "boolean"
},
"sort-members": {
"default": true,
"description": "When set to `true`, sort the members of a record or namespace by name and parameters. When set to `false`, the members are included in the declaration order they are extracted.",
Expand Down Expand Up @@ -385,7 +395,7 @@
"type": "array"
},
"tagfile": {
"default": "<output>/reference.tag.xml",
"default": "<output-dir>/reference.tag.xml",
"description": "Specifies the full path (filename) where the generated tagfile should be saved. If left empty, no tagfile will be generated.",
"title": "Path for the tagfile",
"type": "string"
Expand Down
19 changes: 9 additions & 10 deletions docs/website/render.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,17 @@ target_compile_features(${sourceBasename} PRIVATE cxx_std_23)
// Run mrdocs to generate documentation
const mrdocsConfig = path.join(absSnippetsDir, 'mrdocs.yml')
const mrdocsInput = cmakeListsPath
const mrdocsOutput = path.join(absSnippetsDir, 'output')
const mrdocsOutput = path.join(absSnippetsDir, 'output', 'reference.html')
const args = [
mrdocsExecutable,
`--config=${mrdocsConfig}`,
mrdocsInput,
`--output=${mrdocsOutput}`,
'--multipage=true',
'--multipage=false',
'--generator=html',
'--embedded=true',
'--show-namespaces=false',
'--tagfile=',
];
const command = args.join(' ');
console.log(`Running command: ${command}`)
Expand All @@ -87,22 +89,19 @@ target_compile_features(${sourceBasename} PRIVATE cxx_std_23)
}

// Look load symbol page in the output directory
const documentationFilename = `${sourceBasename}.html`
const documentationPath = path.join(mrdocsOutput, documentationFilename)
if (!fs.existsSync(documentationPath)) {
console.log(`Documentation file ${documentationFilename} not found in ${mrdocsOutput}`)
if (!fs.existsSync(mrdocsOutput)) {
console.log(`Documentation file not found in ${mrdocsOutput}`)
console.log('Failed to generate website panel documentation')
process.exit(1)
}
panel.documentation = fs.readFileSync(documentationPath, 'utf8');
panel.documentation = fs.readFileSync(mrdocsOutput, 'utf8');

// Also inject the contents of the source file as highlighted C++
const snippetContents = fs.readFileSync(sourcePath, 'utf8');
const highlightedSnippet = hljs.highlight(snippetContents, {language: 'cpp'}).value;
panel.snippet = highlightedSnippet;
panel.snippet = hljs.highlight(snippetContents, {language: 'cpp'}).value;

// Delete these temporary files
fs.rmSync(mrdocsOutput, {recursive: true});
fs.unlinkSync(mrdocsOutput);
fs.unlinkSync(cmakeListsPath);

console.log(`Documentation generated successfully for panel ${panel.source}`)
Expand Down
2 changes: 2 additions & 0 deletions docs/website/snippets/mrdocs.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
source-root: .
input:
- .
show-namespaces: false
multipage: false
3 changes: 2 additions & 1 deletion src/lib/Gen/hbs/HandlebarsCorpus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ HandlebarsCorpus::
construct(Info const& I) const
{
dom::Object obj = this->DomCorpus::construct(I);
if (shouldGenerate(I))
if (shouldGenerate(I, getCorpus().config))
{
obj.set("url", getURL(I));
obj.set("anchor", names_.getQualified(I.id, '-'));
Expand All @@ -132,6 +132,7 @@ construct(Info const& I) const
// for the primary template if it's part of the corpus.
if (Info const* primaryInfo = findAlternativeURLInfo(getCorpus(), I))
{
MRDOCS_ASSERT(shouldGenerate(*primaryInfo, getCorpus().config));
obj.set("url", getURL(*primaryInfo));
obj.set("anchor", names_.getQualified(primaryInfo->id, '-'));
}
Expand Down
70 changes: 35 additions & 35 deletions src/lib/Gen/hbs/MultiPageVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,47 +21,47 @@ void
MultiPageVisitor::
operator()(T const& I)
{
MRDOCS_CHECK_OR(shouldGenerate(I));

// Increment the count
count_.fetch_add(1, std::memory_order_relaxed);

ex_.async([this, &I](Builder& builder)
{
// ===================================
// Open the output file
// ===================================
std::string const path = files::appendPath(outputPath_, builder.domCorpus.getURL(I));
std::string const dir = files::getParentDir(path);
if (auto exp = files::createDirectory(dir); !exp)
if (shouldGenerate(I, corpus_.config))
{
exp.error().Throw();
}
std::ofstream os;
try
{
os.open(path,
std::ios_base::binary |
std::ios_base::out |
std::ios_base::trunc // | std::ios_base::noreplace
);
if (!os.is_open()) {
formatError(R"(std::ofstream("{}") failed)", path)
// ===================================
// Open the output file
// ===================================
std::string const path = files::appendPath(outputPath_, builder.domCorpus.getURL(I));
std::string const dir = files::getParentDir(path);
if (auto exp = files::createDirectory(dir); !exp)
{
exp.error().Throw();
}
std::ofstream os;
try
{
os.open(path,
std::ios_base::binary |
std::ios_base::out |
std::ios_base::trunc // | std::ios_base::noreplace
);
if (!os.is_open()) {
formatError(R"(std::ofstream("{}") failed)", path)
.Throw();
}
}
catch (std::exception const& ex)
{
formatError(R"(std::ofstream("{}") threw "{}")", path, ex.what())
.Throw();
}
}
catch (std::exception const& ex)
{
formatError(R"(std::ofstream("{}") threw "{}")", path, ex.what())
.Throw();
}

// ===================================
// Generate the output
// ===================================
if (auto exp = builder(os, I); !exp)
{
exp.error().Throw();
// ===================================
// Generate the output
// ===================================
if (auto exp = builder(os, I); !exp)
{
exp.error().Throw();
}

count_.fetch_add(1, std::memory_order_relaxed);
}

// ===================================
Expand Down
29 changes: 16 additions & 13 deletions src/lib/Gen/hbs/SinglePageVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,24 @@ void
SinglePageVisitor::
operator()(T const& I)
{
MRDOCS_CHECK_OR(shouldGenerate(I));
ex_.async([this, &I, symbolIdx = numSymbols_++](Builder& builder)
if (shouldGenerate(I, corpus_.config))
{
// Output to an independent string first (async), then write to
// the shared stream (sync)
std::stringstream ss;
if(auto r = builder(ss, I))
ex_.async([this, &I, symbolIdx = numSymbols_++](Builder& builder)
{
writePage(ss.str(), symbolIdx);
}
else
{
r.error().Throw();
}
});

// Output to an independent string first (async), then write to
// the shared stream (sync)
std::stringstream ss;
if(auto r = builder(ss, I))
{
writePage(ss.str(), symbolIdx);
}
else
{
r.error().Throw();
}
});
}
Corpus::TraverseOptions opts = {.skipInherited = std::same_as<T, RecordInfo>};
corpus_.traverse(opts, I, *this);
}
Expand Down
14 changes: 9 additions & 5 deletions src/lib/Gen/hbs/VisitorHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
namespace clang::mrdocs::hbs {

bool
shouldGenerate(Info const& I)
shouldGenerate(Info const& I, Config const& config)
{
if (I.isSpecialization())
{
Expand All @@ -38,6 +38,10 @@ shouldGenerate(Info const& I)
// See the requirements in ConfigOptions.json.
return false;
}
if (!config->showNamespaces && I.isNamespace())
{
return false;
}
return true;
}

Expand Down Expand Up @@ -91,7 +95,7 @@ findPrimarySiblingWithUrl(Corpus const& c, Info const& I, Info const& parent)
for (Info const* sibling: sameNameSiblings)
{
if (!sibling ||
!shouldGenerate(*sibling))
!shouldGenerate(*sibling, c.config))
{
continue;
}
Expand Down Expand Up @@ -135,7 +139,7 @@ findDirectPrimarySiblingWithUrl(Corpus const& c, Info const& I)
// in the parent scope for which we want to generate the URL
Info const* parent = c.find(I.Parent);
MRDOCS_CHECK_OR(parent, nullptr);
if (!shouldGenerate(*parent))
if (!shouldGenerate(*parent, c.config))
{
parent = findPrimarySiblingWithUrl(c, *parent);
MRDOCS_CHECK_OR(parent, nullptr);
Expand Down Expand Up @@ -198,7 +202,7 @@ findResolvedPrimarySiblingWithUrl(Corpus const& c, Info const& I)
// a dependency for which there's no URL, we attempt to
// find the primary sibling for the parent so we take
// the URL from it.
if (!shouldGenerate(*parent))
if (!shouldGenerate(*parent, c.config))
{
parent = findPrimarySiblingWithUrl(c, *parent);
MRDOCS_CHECK_OR(parent, nullptr);
Expand Down Expand Up @@ -236,7 +240,7 @@ findParentWithUrl(Corpus const& c, Info const& I)
Info const* parent = c.find(I.Parent);
MRDOCS_CHECK_OR(parent, nullptr);
MRDOCS_CHECK_OR(!parent->isNamespace(), nullptr);
if (shouldGenerate(*parent))
if (shouldGenerate(*parent, c.config))
{
return parent;
}
Expand Down
3 changes: 2 additions & 1 deletion src/lib/Gen/hbs/VisitorHelpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#define MRDOCS_LIB_GEN_HBS_VISITORHELPERS_HPP

#include <mrdocs/Metadata/Info.hpp>
#include <mrdocs/Config.hpp>

namespace clang::mrdocs::hbs {

Expand All @@ -22,7 +23,7 @@ namespace clang::mrdocs::hbs {
*/
MRDOCS_DECL
bool
shouldGenerate(Info const& I);
shouldGenerate(Info const& I, Config const& config);

/** Find an Info type whose URL we can use for the specified Info

Expand Down
18 changes: 17 additions & 1 deletion src/lib/Lib/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,23 @@ struct PublicSettingsVisitor {
std::string_view valueSv(value);
if (!value.empty())
{
res = files::getParentDir(value);
bool const valueIsDir =
[&value]() {
if (files::exists(value))
{
return files::isDirectory(value);
}
std::string_view const filename = files::getFileName(value);
return filename.find('.') == std::string::npos;
}();
if (valueIsDir)
{
res = value;
}
else
{
res = files::getParentDir(value);
}
found = true;
return;
}
Expand Down
11 changes: 9 additions & 2 deletions src/lib/Lib/ConfigOptions.json
Original file line number Diff line number Diff line change
Expand Up @@ -300,8 +300,8 @@
"brief": "Path for the tagfile",
"details": "Specifies the full path (filename) where the generated tagfile should be saved. If left empty, no tagfile will be generated.",
"type": "file-path",
"default": "<output>/reference.tag.xml",
"relative-to": "<output>",
"default": "<output-dir>/reference.tag.xml",
"relative-to": "<output-dir>",
"must-exist": false,
"should-exist": false
},
Expand All @@ -318,6 +318,13 @@
"details": "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": "bool",
"default": false
},
{
"name": "show-namespaces",
"brief": "Show namespace pages in the documentation",
"details": "When set to true, MrDocs creates a page for each namespace in the documentation.",
"type": "bool",
"default": true
}
]
},
Expand Down
16 changes: 7 additions & 9 deletions src/lib/Lib/TagfileWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@

#include <mrdocs/Support/Path.hpp>

namespace clang {
namespace mrdocs {
namespace clang::mrdocs {

//------------------------------------------------
//
Expand Down Expand Up @@ -82,7 +81,7 @@ operator()(T const& I)
{
if constexpr (std::derived_from<T, Info>)
{
if (!hbs::shouldGenerate(I))
if (!hbs::shouldGenerate(I, corpus_.getCorpus().config))
{
return;
}
Expand Down Expand Up @@ -113,14 +112,14 @@ writeNamespace(
{
// Check if this namespace contains only other namespaces
bool onlyNamespaces = true;
corpus_->traverse(I, [&](Info const& I)
corpus_->traverse(I, [&](Info const& U)
{
if (!hbs::shouldGenerate(I))
if (!hbs::shouldGenerate(U, corpus_.getCorpus().config))
{
return;
}

if (I.Kind != InfoKind::Namespace)
if (U.Kind != InfoKind::Namespace)
{
onlyNamespaces = false;
}
Expand All @@ -139,7 +138,7 @@ writeNamespace(
// Write the class-like members of this namespace
corpus_->traverse(I, [this]<typename U>(U const& J)
{
if (!hbs::shouldGenerate(J))
if (!hbs::shouldGenerate(J, corpus_.getCorpus().config))
{
return;
}
Expand Down Expand Up @@ -281,5 +280,4 @@ generateFileAndAnchor(T const& I)
return {url.substr(0, pos), url.substr(pos + 1)};
}

} // mrdocs
} // clang
} // clang::mrdocs
Loading