This revision was automatically updated to reflect the committed changes.
Closed by commit rL367072: [clang-doc] Add option for user provided stylesheets 
(authored by DiegoAstiazaran, committed by ).
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D64938?vs=211841&id=211846#toc

Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D64938/new/

https://reviews.llvm.org/D64938

Files:
  clang-tools-extra/trunk/clang-doc/Generators.h
  clang-tools-extra/trunk/clang-doc/HTMLGenerator.cpp
  clang-tools-extra/trunk/clang-doc/MDGenerator.cpp
  clang-tools-extra/trunk/clang-doc/Representation.h
  clang-tools-extra/trunk/clang-doc/YAMLGenerator.cpp
  clang-tools-extra/trunk/clang-doc/tool/ClangDocMain.cpp
  clang-tools-extra/trunk/unittests/clang-doc/HTMLGeneratorTest.cpp
  clang-tools-extra/trunk/unittests/clang-doc/MDGeneratorTest.cpp
  clang-tools-extra/trunk/unittests/clang-doc/YAMLGeneratorTest.cpp

Index: clang-tools-extra/trunk/unittests/clang-doc/MDGeneratorTest.cpp
===================================================================
--- clang-tools-extra/trunk/unittests/clang-doc/MDGeneratorTest.cpp
+++ clang-tools-extra/trunk/unittests/clang-doc/MDGeneratorTest.cpp
@@ -38,7 +38,7 @@
   assert(G);
   std::string Buffer;
   llvm::raw_string_ostream Actual(Buffer);
-  auto Err = G->generateDocForInfo(&I, Actual);
+  auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext());
   assert(!Err);
   std::string Expected = R"raw(# namespace Namespace
 
@@ -101,7 +101,7 @@
   assert(G);
   std::string Buffer;
   llvm::raw_string_ostream Actual(Buffer);
-  auto Err = G->generateDocForInfo(&I, Actual);
+  auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext());
   assert(!Err);
   std::string Expected = R"raw(# class r
 
@@ -162,7 +162,7 @@
   assert(G);
   std::string Buffer;
   llvm::raw_string_ostream Actual(Buffer);
-  auto Err = G->generateDocForInfo(&I, Actual);
+  auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext());
   assert(!Err);
   std::string Expected = R"raw(### f
 
@@ -190,7 +190,7 @@
   assert(G);
   std::string Buffer;
   llvm::raw_string_ostream Actual(Buffer);
-  auto Err = G->generateDocForInfo(&I, Actual);
+  auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext());
   assert(!Err);
   std::string Expected = R"raw(| enum class e |
 
@@ -320,7 +320,7 @@
   assert(G);
   std::string Buffer;
   llvm::raw_string_ostream Actual(Buffer);
-  auto Err = G->generateDocForInfo(&I, Actual);
+  auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext());
   assert(!Err);
   std::string Expected =
       R"raw(### f
Index: clang-tools-extra/trunk/unittests/clang-doc/HTMLGeneratorTest.cpp
===================================================================
--- clang-tools-extra/trunk/unittests/clang-doc/HTMLGeneratorTest.cpp
+++ clang-tools-extra/trunk/unittests/clang-doc/HTMLGeneratorTest.cpp
@@ -21,6 +21,16 @@
   return std::move(G.get());
 }
 
+ClangDocContext
+getClangDocContext(std::vector<std::string> UserStylesheets = {}) {
+  ClangDocContext CDCtx;
+  CDCtx.UserStylesheets = {UserStylesheets.begin(), UserStylesheets.end()};
+  CDCtx.UserStylesheets.insert(
+      CDCtx.UserStylesheets.begin(),
+      "../share/clang/clang-doc-default-stylesheet.css");
+  return CDCtx;
+}
+
 TEST(HTMLGeneratorTest, emitNamespaceHTML) {
   NamespaceInfo I;
   I.Name = "Namespace";
@@ -38,12 +48,14 @@
   assert(G);
   std::string Buffer;
   llvm::raw_string_ostream Actual(Buffer);
-  auto Err = G->generateDocForInfo(&I, Actual);
+  ClangDocContext CDCtx = getClangDocContext({"user-provided-stylesheet.css"});
+  auto Err = G->generateDocForInfo(&I, Actual, CDCtx);
   assert(!Err);
   std::string Expected = R"raw(<!DOCTYPE html>
 <meta charset="utf-8"/>
 <title>namespace Namespace</title>
 <link rel="stylesheet" href="clang-doc-default-stylesheet.css"/>
+<link rel="stylesheet" href="user-provided-stylesheet.css"/>
 <div>
   <h1>namespace Namespace</h1>
   <h2>Namespaces</h2>
@@ -95,7 +107,8 @@
   assert(G);
   std::string Buffer;
   llvm::raw_string_ostream Actual(Buffer);
-  auto Err = G->generateDocForInfo(&I, Actual);
+  ClangDocContext CDCtx = getClangDocContext();
+  auto Err = G->generateDocForInfo(&I, Actual, CDCtx);
   assert(!Err);
   SmallString<16> PathToF;
   llvm::sys::path::native("../../../path/to/F.html", PathToF);
@@ -161,7 +174,8 @@
   assert(G);
   std::string Buffer;
   llvm::raw_string_ostream Actual(Buffer);
-  auto Err = G->generateDocForInfo(&I, Actual);
+  ClangDocContext CDCtx = getClangDocContext();
+  auto Err = G->generateDocForInfo(&I, Actual, CDCtx);
   assert(!Err);
   SmallString<16> PathToFloat;
   llvm::sys::path::native("path/to/float.html", PathToFloat);
@@ -203,7 +217,8 @@
   assert(G);
   std::string Buffer;
   llvm::raw_string_ostream Actual(Buffer);
-  auto Err = G->generateDocForInfo(&I, Actual);
+  ClangDocContext CDCtx = getClangDocContext();
+  auto Err = G->generateDocForInfo(&I, Actual, CDCtx);
   assert(!Err);
   std::string Expected = R"raw(<!DOCTYPE html>
 <meta charset="utf-8"/>
@@ -271,7 +286,8 @@
   assert(G);
   std::string Buffer;
   llvm::raw_string_ostream Actual(Buffer);
-  auto Err = G->generateDocForInfo(&I, Actual);
+  ClangDocContext CDCtx = getClangDocContext();
+  auto Err = G->generateDocForInfo(&I, Actual, CDCtx);
   assert(!Err);
   std::string Expected = R"raw(<!DOCTYPE html>
 <meta charset="utf-8"/>
Index: clang-tools-extra/trunk/unittests/clang-doc/YAMLGeneratorTest.cpp
===================================================================
--- clang-tools-extra/trunk/unittests/clang-doc/YAMLGeneratorTest.cpp
+++ clang-tools-extra/trunk/unittests/clang-doc/YAMLGeneratorTest.cpp
@@ -40,7 +40,7 @@
   assert(G);
   std::string Buffer;
   llvm::raw_string_ostream Actual(Buffer);
-  auto Err = G->generateDocForInfo(&I, Actual);
+  auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext());
   assert(!Err);
   std::string Expected =
       R"raw(---
@@ -94,7 +94,7 @@
   assert(G);
   std::string Buffer;
   llvm::raw_string_ostream Actual(Buffer);
-  auto Err = G->generateDocForInfo(&I, Actual);
+  auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext());
   assert(!Err);
   std::string Expected =
       R"raw(---
@@ -158,7 +158,7 @@
   assert(G);
   std::string Buffer;
   llvm::raw_string_ostream Actual(Buffer);
-  auto Err = G->generateDocForInfo(&I, Actual);
+  auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext());
   assert(!Err);
   std::string Expected =
       R"raw(---
@@ -206,7 +206,7 @@
   assert(G);
   std::string Buffer;
   llvm::raw_string_ostream Actual(Buffer);
-  auto Err = G->generateDocForInfo(&I, Actual);
+  auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext());
   assert(!Err);
   std::string Expected =
       R"raw(---
@@ -343,7 +343,7 @@
   assert(G);
   std::string Buffer;
   llvm::raw_string_ostream Actual(Buffer);
-  auto Err = G->generateDocForInfo(&I, Actual);
+  auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext());
   assert(!Err);
   std::string Expected =
       R"raw(---
Index: clang-tools-extra/trunk/clang-doc/tool/ClangDocMain.cpp
===================================================================
--- clang-tools-extra/trunk/clang-doc/tool/ClangDocMain.cpp
+++ clang-tools-extra/trunk/clang-doc/tool/ClangDocMain.cpp
@@ -62,6 +62,11 @@
     llvm::cl::desc("Use only doxygen-style comments to generate docs."),
     llvm::cl::init(false), llvm::cl::cat(ClangDocCategory));
 
+static llvm::cl::list<std::string> UserStylesheets(
+    "stylesheets", llvm::cl::CommaSeparated,
+    llvm::cl::desc("CSS stylesheets to extend the default styles."),
+    llvm::cl::cat(ClangDocCategory));
+
 enum OutputFormatTy {
   md,
   yaml,
@@ -201,12 +206,26 @@
                                   tooling::ArgumentInsertPosition::END),
         ArgAdjuster);
 
+  clang::doc::ClangDocContext CDCtx = {
+      Exec->get()->getExecutionContext(),
+      PublicOnly,
+      OutDirectory,
+      {UserStylesheets.begin(), UserStylesheets.end()}};
+
+  if (Format == "html") {
+    void *MainAddr = (void *)(intptr_t)GetExecutablePath;
+    std::string ClangDocPath = GetExecutablePath(argv[0], MainAddr);
+    llvm::SmallString<128> DefaultStylesheet;
+    llvm::sys::path::native(ClangDocPath, DefaultStylesheet);
+    DefaultStylesheet = llvm::sys::path::parent_path(DefaultStylesheet);
+    llvm::sys::path::append(DefaultStylesheet,
+                            "../share/clang/clang-doc-default-stylesheet.css");
+    CDCtx.UserStylesheets.insert(CDCtx.UserStylesheets.begin(),
+                                 DefaultStylesheet.str());
+  }
+
   // Mapping phase
   llvm::outs() << "Mapping decls...\n";
-  void *MainAddr = (void *)(intptr_t)GetExecutablePath;
-  std::string ClangDocPath = GetExecutablePath(argv[0], MainAddr);
-  clang::doc::ClangDocContext CDCtx = {Exec->get()->getExecutionContext(),
-                                       PublicOnly, OutDirectory, ClangDocPath};
   auto Err =
       Exec->get()->execute(doc::newMapperActionFactory(CDCtx), ArgAdjuster);
   if (Err) {
@@ -245,7 +264,7 @@
       continue;
     }
 
-    if (auto Err = G->get()->generateDocForInfo(I, InfoOS))
+    if (auto Err = G->get()->generateDocForInfo(I, InfoOS, CDCtx))
       llvm::errs() << toString(std::move(Err)) << "\n";
   }
 
Index: clang-tools-extra/trunk/clang-doc/Generators.h
===================================================================
--- clang-tools-extra/trunk/clang-doc/Generators.h
+++ clang-tools-extra/trunk/clang-doc/Generators.h
@@ -26,7 +26,8 @@
   virtual ~Generator() = default;
 
   // Write out the decl info in the specified format.
-  virtual llvm::Error generateDocForInfo(Info *I, llvm::raw_ostream &OS) = 0;
+  virtual llvm::Error generateDocForInfo(Info *I, llvm::raw_ostream &OS,
+                                         const ClangDocContext &CDCtx) = 0;
   virtual bool createResources(ClangDocContext CDCtx) = 0;
 };
 
Index: clang-tools-extra/trunk/clang-doc/HTMLGenerator.cpp
===================================================================
--- clang-tools-extra/trunk/clang-doc/HTMLGenerator.cpp
+++ clang-tools-extra/trunk/clang-doc/HTMLGenerator.cpp
@@ -222,6 +222,21 @@
 
 // HTML generation
 
+std::vector<std::unique_ptr<TagNode>>
+genStylesheetsHTML(StringRef InfoPath, const ClangDocContext &CDCtx) {
+  std::vector<std::unique_ptr<TagNode>> Out;
+  for (const auto &FilePath : CDCtx.UserStylesheets) {
+    auto LinkNode = llvm::make_unique<TagNode>(HTMLTag::TAG_LINK);
+    LinkNode->Attributes.try_emplace("rel", "stylesheet");
+    SmallString<128> StylesheetPath = computeRelativePath("", InfoPath);
+    llvm::sys::path::append(StylesheetPath,
+                            llvm::sys::path::filename(FilePath));
+    LinkNode->Attributes.try_emplace("href", StylesheetPath);
+    Out.emplace_back(std::move(LinkNode));
+  }
+  return Out;
+}
+
 static std::unique_ptr<TagNode> genLink(const Twine &Text, const Twine &Link) {
   auto LinkNode = llvm::make_unique<TagNode>(HTMLTag::TAG_A, Text);
   LinkNode->Attributes.try_emplace("href", Link.str());
@@ -529,13 +544,15 @@
 public:
   static const char *Format;
 
-  llvm::Error generateDocForInfo(Info *I, llvm::raw_ostream &OS) override;
+  llvm::Error generateDocForInfo(Info *I, llvm::raw_ostream &OS,
+                                 const ClangDocContext &CDCtx) override;
   bool createResources(ClangDocContext CDCtx) override;
 };
 
 const char *HTMLGenerator::Format = "html";
 
-llvm::Error HTMLGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS) {
+llvm::Error HTMLGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS,
+                                              const ClangDocContext &CDCtx) {
   HTMLFile F;
 
   auto MetaNode = llvm::make_unique<TagNode>(HTMLTag::TAG_META);
@@ -577,12 +594,9 @@
 
   F.Children.emplace_back(
       llvm::make_unique<TagNode>(HTMLTag::TAG_TITLE, InfoTitle));
-  auto LinkNode = llvm::make_unique<TagNode>(HTMLTag::TAG_LINK);
-  LinkNode->Attributes.try_emplace("rel", "stylesheet");
-  SmallString<128> StylesheetPath = computeRelativePath("", I->Path);
-  llvm::sys::path::append(StylesheetPath, "clang-doc-default-stylesheet.css");
-  LinkNode->Attributes.try_emplace("href", StylesheetPath);
-  F.Children.emplace_back(std::move(LinkNode));
+  std::vector<std::unique_ptr<TagNode>> StylesheetsNodes =
+      genStylesheetsHTML(I->Path, CDCtx);
+  AppendVector(std::move(StylesheetsNodes), F.Children);
   F.Children.emplace_back(std::move(MainContentNode));
   F.Render(OS);
 
@@ -591,22 +605,22 @@
 
 bool HTMLGenerator::createResources(ClangDocContext CDCtx) {
   llvm::outs() << "Generating stylesheet for docs...\n";
-  llvm::SmallString<128> StylesheetPathWrite;
-  llvm::sys::path::native(CDCtx.OutDirectory, StylesheetPathWrite);
-  llvm::sys::path::append(StylesheetPathWrite,
-                          "clang-doc-default-stylesheet.css");
-  llvm::SmallString<128> StylesheetPathRead;
-  llvm::sys::path::native(CDCtx.ClangDocPath, StylesheetPathRead);
-  StylesheetPathRead = llvm::sys::path::parent_path(StylesheetPathRead);
-  llvm::sys::path::append(StylesheetPathRead, "..", "share", "clang",
-                          "clang-doc-default-stylesheet.css");
-  std::error_code OK;
-  std::error_code FileErr =
-      llvm::sys::fs::copy_file(StylesheetPathRead, StylesheetPathWrite);
-  if (FileErr != OK) {
-    llvm::errs() << "Error creating stylesheet file: " << FileErr.message()
-                 << "\n";
-    return false;
+  for (const auto &FilePath : CDCtx.UserStylesheets) {
+    llvm::SmallString<128> StylesheetPathWrite;
+    llvm::sys::path::native(CDCtx.OutDirectory, StylesheetPathWrite);
+    llvm::sys::path::append(StylesheetPathWrite,
+                            llvm::sys::path::filename(FilePath));
+    llvm::SmallString<128> StylesheetPathRead;
+    llvm::sys::path::native(FilePath, StylesheetPathRead);
+    std::error_code OK;
+    std::error_code FileErr =
+        llvm::sys::fs::copy_file(StylesheetPathRead, StylesheetPathWrite);
+    if (FileErr != OK) {
+      llvm::errs() << "Error creating stylesheet file "
+                   << llvm::sys::path::filename(FilePath) << ": "
+                   << FileErr.message() << "\n";
+      return false;
+    }
   }
   return true;
 }
Index: clang-tools-extra/trunk/clang-doc/YAMLGenerator.cpp
===================================================================
--- clang-tools-extra/trunk/clang-doc/YAMLGenerator.cpp
+++ clang-tools-extra/trunk/clang-doc/YAMLGenerator.cpp
@@ -243,13 +243,15 @@
 public:
   static const char *Format;
 
-  llvm::Error generateDocForInfo(Info *I, llvm::raw_ostream &OS) override;
+  llvm::Error generateDocForInfo(Info *I, llvm::raw_ostream &OS,
+                                 const ClangDocContext &CDCtx) override;
   bool createResources(ClangDocContext CDCtx) override { return true; }
 };
 
 const char *YAMLGenerator::Format = "yaml";
 
-llvm::Error YAMLGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS) {
+llvm::Error YAMLGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS,
+                                              const ClangDocContext &CDCtx) {
   llvm::yaml::Output InfoYAML(OS);
   switch (I->IT) {
   case InfoType::IT_namespace:
Index: clang-tools-extra/trunk/clang-doc/MDGenerator.cpp
===================================================================
--- clang-tools-extra/trunk/clang-doc/MDGenerator.cpp
+++ clang-tools-extra/trunk/clang-doc/MDGenerator.cpp
@@ -250,13 +250,15 @@
 public:
   static const char *Format;
 
-  llvm::Error generateDocForInfo(Info *I, llvm::raw_ostream &OS) override;
+  llvm::Error generateDocForInfo(Info *I, llvm::raw_ostream &OS,
+                                 const ClangDocContext &CDCtx) override;
   bool createResources(ClangDocContext CDCtx) override { return true; }
 };
 
 const char *MDGenerator::Format = "md";
 
-llvm::Error MDGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS) {
+llvm::Error MDGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS,
+                                            const ClangDocContext &CDCtx) {
   switch (I->IT) {
   case InfoType::IT_namespace:
     genMarkdown(*static_cast<clang::doc::NamespaceInfo *>(I), OS);
Index: clang-tools-extra/trunk/clang-doc/Representation.h
===================================================================
--- clang-tools-extra/trunk/clang-doc/Representation.h
+++ clang-tools-extra/trunk/clang-doc/Representation.h
@@ -350,7 +350,7 @@
   tooling::ExecutionContext *ECtx;
   bool PublicOnly;
   std::string OutDirectory;
-  std::string ClangDocPath;
+  std::vector<std::string> UserStylesheets;
 };
 
 } // namespace doc
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to