Skip to content

Commit d4dc571

Browse files
authored
[clang-doc] Allow setting a base directory for hosted pages (#132482)
Currently, when we set URLs from JS, we set them only using the protocol and host locations. This works fine when docs are served from the base directory of the site, but if you want to nest it under another directory, our JS fails to set the correct path, leading to broken links. This patch adds a --base option to specify the path prefix to use, which is set in the generated index_json.js file. index.json can then fill in the prefix appropriately when generating links in a browser. This flag has no effect for non HTML output. Given an index hosted at: www.docs.com/base_directory/index.html we used to generate the following link: www.docs.com/file.html Using --base base_directory we now generate: www.docs.com/base_directory/file.html This allows such links to work when hosting pages without using a custom index.js.
1 parent 1bfc610 commit d4dc571

File tree

8 files changed

+30
-16
lines changed

8 files changed

+30
-16
lines changed

clang-tools-extra/clang-doc/HTMLGenerator.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1078,6 +1078,11 @@ static llvm::Error serializeIndex(ClangDocContext &CDCtx) {
10781078
std::replace(RootPathEscaped.begin(), RootPathEscaped.end(), '\\', '/');
10791079
OS << "var RootPath = \"" << RootPathEscaped << "\";\n";
10801080

1081+
llvm::SmallString<128> Base(CDCtx.Base);
1082+
std::string BaseEscaped = Base.str().str();
1083+
std::replace(BaseEscaped.begin(), BaseEscaped.end(), '\\', '/');
1084+
OS << "var Base = \"" << BaseEscaped << "\";\n";
1085+
10811086
CDCtx.Idx.sort();
10821087
llvm::json::OStream J(OS, 2);
10831088
std::function<void(Index)> IndexToJSON = [&](const Index &I) {

clang-tools-extra/clang-doc/Representation.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -367,10 +367,10 @@ void Index::sort() {
367367
ClangDocContext::ClangDocContext(tooling::ExecutionContext *ECtx,
368368
StringRef ProjectName, bool PublicOnly,
369369
StringRef OutDirectory, StringRef SourceRoot,
370-
StringRef RepositoryUrl,
370+
StringRef RepositoryUrl, StringRef Base,
371371
std::vector<std::string> UserStylesheets)
372372
: ECtx(ECtx), ProjectName(ProjectName), PublicOnly(PublicOnly),
373-
OutDirectory(OutDirectory), UserStylesheets(UserStylesheets) {
373+
OutDirectory(OutDirectory), UserStylesheets(UserStylesheets), Base(Base) {
374374
llvm::SmallString<128> SourceRootDir(SourceRoot);
375375
if (SourceRoot.empty())
376376
// If no SourceRoot was provided the current path is used as the default

clang-tools-extra/clang-doc/Representation.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,7 @@ struct ClangDocContext {
507507
ClangDocContext() = default;
508508
ClangDocContext(tooling::ExecutionContext *ECtx, StringRef ProjectName,
509509
bool PublicOnly, StringRef OutDirectory, StringRef SourceRoot,
510-
StringRef RepositoryUrl,
510+
StringRef RepositoryUrl, StringRef Base,
511511
std::vector<std::string> UserStylesheets);
512512
tooling::ExecutionContext *ECtx;
513513
std::string ProjectName; // Name of project clang-doc is documenting.
@@ -523,6 +523,7 @@ struct ClangDocContext {
523523
std::vector<std::string> UserStylesheets;
524524
// JavaScript files that will be imported in all HTML files.
525525
std::vector<std::string> JsScripts;
526+
StringRef Base;
526527
Index Idx;
527528
};
528529

clang-tools-extra/clang-doc/assets/index.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
function genLink(Ref) {
22
// we treat the file paths different depending on if we're
33
// serving via a http server or viewing from a local
4-
var Path = window.location.protocol.startsWith("file") ?
5-
`${window.location.protocol}//${RootPath}/${Ref.Path}` :
6-
`${window.location.protocol}//${window.location.host}/${Ref.Path}`;
4+
var Path = window.location.protocol.startsWith("file")
5+
? `${window.location.protocol}//${RootPath}/${Ref.Path}`
6+
: `${window.location.protocol}//${window.location.host}/${
7+
Base}/${Ref.Path}`;
78
if (Ref.RefType === "namespace") {
89
Path = `${Path}/index.html`
910
} else if (Ref.Path === "") {

clang-tools-extra/clang-doc/tool/ClangDocMain.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ static llvm::cl::opt<std::string>
6767
llvm::cl::desc("Directory for outputting generated files."),
6868
llvm::cl::init("docs"), llvm::cl::cat(ClangDocCategory));
6969

70+
static llvm::cl::opt<std::string>
71+
BaseDirectory("base",
72+
llvm::cl::desc(R"(Base Directory for generated documentation.
73+
URLs will be rooted at this directory for HTML links.)"),
74+
llvm::cl::init(""), llvm::cl::cat(ClangDocCategory));
75+
7076
static llvm::cl::opt<bool>
7177
PublicOnly("public", llvm::cl::desc("Document only public declarations."),
7278
llvm::cl::init(false), llvm::cl::cat(ClangDocCategory));
@@ -141,8 +147,7 @@ llvm::Error getAssetFiles(clang::doc::ClangDocContext &CDCtx) {
141147
using DirIt = llvm::sys::fs::directory_iterator;
142148
std::error_code FileErr;
143149
llvm::SmallString<128> FilePath(UserAssetPath);
144-
for (DirIt DirStart = DirIt(UserAssetPath, FileErr),
145-
DirEnd;
150+
for (DirIt DirStart = DirIt(UserAssetPath, FileErr), DirEnd;
146151
!FileErr && DirStart != DirEnd; DirStart.increment(FileErr)) {
147152
FilePath = DirStart->path();
148153
if (llvm::sys::fs::is_regular_file(FilePath)) {
@@ -268,8 +273,8 @@ Example usage for a project using a compile commands database:
268273
OutDirectory,
269274
SourceRoot,
270275
RepositoryUrl,
271-
{UserStylesheets.begin(), UserStylesheets.end()}
272-
};
276+
BaseDirectory,
277+
{UserStylesheets.begin(), UserStylesheets.end()}};
273278

274279
if (Format == "html") {
275280
if (auto Err = getHtmlAssetFiles(argv[0], CDCtx)) {

clang-tools-extra/test/clang-doc/assets.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// RUN: rm -rf %t && mkdir %t
2-
// RUN: clang-doc --format=html --output=%t --asset=%S/Inputs/test-assets --executor=standalone %s
2+
// RUN: clang-doc --format=html --output=%t --asset=%S/Inputs/test-assets --executor=standalone %s --base base_dir
33
// RUN: FileCheck %s -input-file=%t/index.html -check-prefix=INDEX
44
// RUN: FileCheck %s -input-file=%t/test.css -check-prefix=CSS
55
// RUN: FileCheck %s -input-file=%t/test.js -check-prefix=JS
@@ -19,4 +19,4 @@
1919
// CSS-NEXT: padding: 0;
2020
// CSS-NEXT: }
2121

22-
// JS: console.log("Hello, world!");
22+
// JS: console.log("Hello, world!");
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// RUN: rm -rf %t && mkdir -p %t
2-
// RUN: clang-doc --format=html --executor=standalone %s --output=%t
2+
// RUN: clang-doc --format=html --executor=standalone %s --output=%t --base base_dir
33
// RUN: FileCheck %s -input-file=%t/index_json.js -check-prefix=JSON-INDEX
44

55
// JSON-INDEX: var RootPath = "{{.*}}test-path-abs.cpp.tmp";
6+
// JSON-INDEX-NEXT: var Base = "base_dir";
7+

clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ std::unique_ptr<Generator> getHTMLGenerator() {
2828

2929
ClangDocContext
3030
getClangDocContext(std::vector<std::string> UserStylesheets = {},
31-
StringRef RepositoryUrl = "") {
32-
ClangDocContext CDCtx{
33-
{}, "test-project", {}, {}, {}, RepositoryUrl, UserStylesheets};
31+
StringRef RepositoryUrl = "", StringRef Base = "") {
32+
ClangDocContext CDCtx{{}, "test-project", {}, {},
33+
{}, RepositoryUrl, Base, UserStylesheets};
3434
CDCtx.UserStylesheets.insert(
3535
CDCtx.UserStylesheets.begin(),
3636
"../share/clang/clang-doc-default-stylesheet.css");

0 commit comments

Comments
 (0)