[clang-tools-extra] r369139 - [clang-doc] Redesign of generated HTML files

Diego Astiazaran via cfe-commits cfe-commits at lists.llvm.org
Fri Aug 16 11:38:11 PDT 2019


Author: diegoastiazaran
Date: Fri Aug 16 11:38:11 2019
New Revision: 369139

URL: http://llvm.org/viewvc/llvm-project?rev=369139&view=rev
Log:
[clang-doc] Redesign of generated HTML files

The new design includes a header (contains the project name), a main section, and a footer.
The main section is divided into three subsections. Left, middle, right. The left section contains the general index, the middle contains the info's data, and the right contains the index for the info's content.
The CSS has been updated.
A flag --project-name is added.
The Attributes attribute of the TagNode struct is now a vector of pairs because these attributes should be rendered in the insertion order.
The functions (cpp and js) that converts an Index tree structure into HTML were slightly modified; the first ul tag created is now a ol tag. The inner lists are still ul.

Differential Revision: https://reviews.llvm.org/D66353

Modified:
    clang-tools-extra/trunk/clang-doc/HTMLGenerator.cpp
    clang-tools-extra/trunk/clang-doc/Representation.cpp
    clang-tools-extra/trunk/clang-doc/Representation.h
    clang-tools-extra/trunk/clang-doc/assets/clang-doc-default-stylesheet.css
    clang-tools-extra/trunk/clang-doc/assets/index.js
    clang-tools-extra/trunk/clang-doc/tool/ClangDocMain.cpp
    clang-tools-extra/trunk/docs/clang-doc.rst
    clang-tools-extra/trunk/unittests/clang-doc/HTMLGeneratorTest.cpp

Modified: clang-tools-extra/trunk/clang-doc/HTMLGenerator.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-doc/HTMLGenerator.cpp?rev=369139&r1=369138&r2=369139&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-doc/HTMLGenerator.cpp (original)
+++ clang-tools-extra/trunk/clang-doc/HTMLGenerator.cpp Fri Aug 16 11:38:11 2019
@@ -8,6 +8,7 @@
 
 #include "Generators.h"
 #include "Representation.h"
+#include "clang/Basic/Version.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/FileSystem.h"
@@ -29,12 +30,16 @@ public:
   enum TagType {
     TAG_A,
     TAG_DIV,
+    TAG_FOOTER,
     TAG_H1,
     TAG_H2,
     TAG_H3,
+    TAG_HEADER,
     TAG_LI,
     TAG_LINK,
+    TAG_MAIN,
     TAG_META,
+    TAG_OL,
     TAG_P,
     TAG_SCRIPT,
     TAG_SPAN,
@@ -84,7 +89,7 @@ struct TagNode : public HTMLNode {
 
   HTMLTag Tag; // Name of HTML Tag (p, div, h1)
   std::vector<std::unique_ptr<HTMLNode>> Children; // List of child nodes
-  llvm::StringMap<llvm::SmallString<16>>
+  std::vector<std::pair<llvm::SmallString<16>, llvm::SmallString<16>>>
       Attributes; // List of key-value attributes for tag
 
   void Render(llvm::raw_ostream &OS, int IndentationLevel) override;
@@ -112,10 +117,14 @@ bool HTMLTag::IsSelfClosing() const {
     return true;
   case HTMLTag::TAG_A:
   case HTMLTag::TAG_DIV:
+  case HTMLTag::TAG_FOOTER:
   case HTMLTag::TAG_H1:
   case HTMLTag::TAG_H2:
   case HTMLTag::TAG_H3:
+  case HTMLTag::TAG_HEADER:
   case HTMLTag::TAG_LI:
+  case HTMLTag::TAG_MAIN:
+  case HTMLTag::TAG_OL:
   case HTMLTag::TAG_P:
   case HTMLTag::TAG_SCRIPT:
   case HTMLTag::TAG_SPAN:
@@ -132,18 +141,26 @@ llvm::SmallString<16> HTMLTag::ToString(
     return llvm::SmallString<16>("a");
   case HTMLTag::TAG_DIV:
     return llvm::SmallString<16>("div");
+  case HTMLTag::TAG_FOOTER:
+    return llvm::SmallString<16>("footer");
   case HTMLTag::TAG_H1:
     return llvm::SmallString<16>("h1");
   case HTMLTag::TAG_H2:
     return llvm::SmallString<16>("h2");
   case HTMLTag::TAG_H3:
     return llvm::SmallString<16>("h3");
+  case HTMLTag::TAG_HEADER:
+    return llvm::SmallString<16>("header");
   case HTMLTag::TAG_LI:
     return llvm::SmallString<16>("li");
   case HTMLTag::TAG_LINK:
     return llvm::SmallString<16>("link");
+  case HTMLTag::TAG_MAIN:
+    return llvm::SmallString<16>("main");
   case HTMLTag::TAG_META:
     return llvm::SmallString<16>("meta");
+  case HTMLTag::TAG_OL:
+    return llvm::SmallString<16>("ol");
   case HTMLTag::TAG_P:
     return llvm::SmallString<16>("p");
   case HTMLTag::TAG_SCRIPT:
@@ -174,7 +191,7 @@ void TagNode::Render(llvm::raw_ostream &
   OS.indent(IndentationLevel * 2);
   OS << "<" << Tag.ToString();
   for (const auto &A : Attributes)
-    OS << " " << A.getKey() << "=\"" << A.getValue() << "\"";
+    OS << " " << A.first << "=\"" << A.second << "\"";
   if (Tag.IsSelfClosing()) {
     OS << "/>";
     return;
@@ -255,13 +272,13 @@ genStylesheetsHTML(StringRef InfoPath, c
   std::vector<std::unique_ptr<TagNode>> Out;
   for (const auto &FilePath : CDCtx.UserStylesheets) {
     auto LinkNode = std::make_unique<TagNode>(HTMLTag::TAG_LINK);
-    LinkNode->Attributes.try_emplace("rel", "stylesheet");
+    LinkNode->Attributes.emplace_back("rel", "stylesheet");
     SmallString<128> StylesheetPath = computeRelativePath("", InfoPath);
     llvm::sys::path::append(StylesheetPath,
                             llvm::sys::path::filename(FilePath));
     // Paths in HTML must be in posix-style
     llvm::sys::path::native(StylesheetPath, llvm::sys::path::Style::posix);
-    LinkNode->Attributes.try_emplace("href", StylesheetPath);
+    LinkNode->Attributes.emplace_back("href", StylesheetPath);
     Out.emplace_back(std::move(LinkNode));
   }
   return Out;
@@ -276,7 +293,7 @@ genJsScriptsHTML(StringRef InfoPath, con
     llvm::sys::path::append(ScriptPath, llvm::sys::path::filename(FilePath));
     // Paths in HTML must be in posix-style
     llvm::sys::path::native(ScriptPath, llvm::sys::path::Style::posix);
-    ScriptNode->Attributes.try_emplace("src", ScriptPath);
+    ScriptNode->Attributes.emplace_back("src", ScriptPath);
     Out.emplace_back(std::move(ScriptNode));
   }
   return Out;
@@ -284,7 +301,7 @@ genJsScriptsHTML(StringRef InfoPath, con
 
 static std::unique_ptr<TagNode> genLink(const Twine &Text, const Twine &Link) {
   auto LinkNode = std::make_unique<TagNode>(HTMLTag::TAG_A, Text);
-  LinkNode->Attributes.try_emplace("href", Link.str());
+  LinkNode->Attributes.emplace_back("href", Link.str());
   return LinkNode;
 }
 
@@ -333,7 +350,7 @@ genEnumsBlock(const std::vector<EnumInfo
 
   std::vector<std::unique_ptr<TagNode>> Out;
   Out.emplace_back(std::make_unique<TagNode>(HTMLTag::TAG_H2, "Enums"));
-  Out.back()->Attributes.try_emplace("id", "Enums");
+  Out.back()->Attributes.emplace_back("id", "Enums");
   Out.emplace_back(std::make_unique<TagNode>(HTMLTag::TAG_DIV));
   auto &DivBody = Out.back();
   for (const auto &E : Enums) {
@@ -362,7 +379,7 @@ genFunctionsBlock(const std::vector<Func
 
   std::vector<std::unique_ptr<TagNode>> Out;
   Out.emplace_back(std::make_unique<TagNode>(HTMLTag::TAG_H2, "Functions"));
-  Out.back()->Attributes.try_emplace("id", "Functions");
+  Out.back()->Attributes.emplace_back("id", "Functions");
   Out.emplace_back(std::make_unique<TagNode>(HTMLTag::TAG_DIV));
   auto &DivBody = Out.back();
   for (const auto &F : Functions) {
@@ -381,7 +398,7 @@ genRecordMembersBlock(const llvm::SmallV
 
   std::vector<std::unique_ptr<TagNode>> Out;
   Out.emplace_back(std::make_unique<TagNode>(HTMLTag::TAG_H2, "Members"));
-  Out.back()->Attributes.try_emplace("id", "Members");
+  Out.back()->Attributes.emplace_back("id", "Members");
   Out.emplace_back(std::make_unique<TagNode>(HTMLTag::TAG_UL));
   auto &ULBody = Out.back();
   for (const auto &M : Members) {
@@ -405,7 +422,7 @@ genReferencesBlock(const std::vector<Ref
 
   std::vector<std::unique_ptr<TagNode>> Out;
   Out.emplace_back(std::make_unique<TagNode>(HTMLTag::TAG_H2, Title));
-  Out.back()->Attributes.try_emplace("id", Title);
+  Out.back()->Attributes.emplace_back("id", Title);
   Out.emplace_back(std::make_unique<TagNode>(HTMLTag::TAG_UL));
   auto &ULBody = Out.back();
   for (const auto &R : References) {
@@ -431,23 +448,29 @@ writeFileDefinition(const Location &L,
       std::make_unique<TagNode>(HTMLTag::TAG_A, std::to_string(L.LineNumber));
   // The links to a specific line in the source code use the github /
   // googlesource notation so it won't work for all hosting pages.
-  LocNumberNode->Attributes.try_emplace(
+  LocNumberNode->Attributes.emplace_back(
       "href", (FileURL + "#" + std::to_string(L.LineNumber)).str());
   Node->Children.emplace_back(std::move(LocNumberNode));
   Node->Children.emplace_back(std::make_unique<TextNode>(" of file "));
   auto LocFileNode = std::make_unique<TagNode>(
       HTMLTag::TAG_A, llvm::sys::path::filename(FileURL));
-  LocFileNode->Attributes.try_emplace("href", FileURL);
+  LocFileNode->Attributes.emplace_back("href", FileURL);
   Node->Children.emplace_back(std::move(LocFileNode));
   return Node;
 }
 
 static std::vector<std::unique_ptr<TagNode>>
-genCommonFileNodes(StringRef Title, StringRef InfoPath,
-                   const ClangDocContext &CDCtx) {
+genHTML(const Index &Index, StringRef InfoPath, bool IsOutermostList);
+
+// Generates a list of child nodes for the HTML head tag
+// It contains a meta node, link nodes to import CSS files, and script nodes to
+// import JS files
+static std::vector<std::unique_ptr<TagNode>>
+genFileHeadNodes(StringRef Title, StringRef InfoPath,
+                 const ClangDocContext &CDCtx) {
   std::vector<std::unique_ptr<TagNode>> Out;
   auto MetaNode = std::make_unique<TagNode>(HTMLTag::TAG_META);
-  MetaNode->Attributes.try_emplace("charset", "utf-8");
+  MetaNode->Attributes.emplace_back("charset", "utf-8");
   Out.emplace_back(std::move(MetaNode));
   Out.emplace_back(std::make_unique<TagNode>(HTMLTag::TAG_TITLE, Title));
   std::vector<std::unique_ptr<TagNode>> StylesheetsNodes =
@@ -456,14 +479,87 @@ genCommonFileNodes(StringRef Title, Stri
   std::vector<std::unique_ptr<TagNode>> JsNodes =
       genJsScriptsHTML(InfoPath, CDCtx);
   AppendVector(std::move(JsNodes), Out);
-  // An empty <div> is generated but the index will be then rendered here
-  auto IndexNode = std::make_unique<TagNode>(HTMLTag::TAG_DIV);
-  IndexNode->Attributes.try_emplace("id", "index");
-  IndexNode->Attributes.try_emplace("path", InfoPath);
-  Out.emplace_back(std::move(IndexNode));
   return Out;
 }
 
+// Generates a header HTML node that can be used for any file
+// It contains the project name
+static std::unique_ptr<TagNode> genFileHeaderNode(StringRef ProjectName) {
+  auto HeaderNode = std::make_unique<TagNode>(HTMLTag::TAG_HEADER, ProjectName);
+  HeaderNode->Attributes.emplace_back("id", "project-title");
+  return HeaderNode;
+}
+
+// Generates a main HTML node that has all the main content of an info file
+// It contains both indexes and the info's documented information
+// This function should only be used for the info files (not for the file that
+// only has the general index)
+static std::unique_ptr<TagNode> genInfoFileMainNode(
+    StringRef InfoPath,
+    std::vector<std::unique_ptr<TagNode>> &MainContentInnerNodes,
+    const Index &InfoIndex) {
+  auto MainNode = std::make_unique<TagNode>(HTMLTag::TAG_MAIN);
+
+  auto LeftSidebarNode = std::make_unique<TagNode>(HTMLTag::TAG_DIV);
+  LeftSidebarNode->Attributes.emplace_back("id", "sidebar-left");
+  LeftSidebarNode->Attributes.emplace_back("path", InfoPath);
+  LeftSidebarNode->Attributes.emplace_back(
+      "class", "col-xs-6 col-sm-3 col-md-2 sidebar sidebar-offcanvas-left");
+
+  auto MainContentNode = std::make_unique<TagNode>(HTMLTag::TAG_DIV);
+  MainContentNode->Attributes.emplace_back("id", "main-content");
+  MainContentNode->Attributes.emplace_back(
+      "class", "col-xs-12 col-sm-9 col-md-8 main-content");
+  AppendVector(std::move(MainContentInnerNodes), MainContentNode->Children);
+
+  auto RightSidebarNode = std::make_unique<TagNode>(HTMLTag::TAG_DIV);
+  RightSidebarNode->Attributes.emplace_back("id", "sidebar-right");
+  RightSidebarNode->Attributes.emplace_back(
+      "class", "col-xs-6 col-sm-6 col-md-2 sidebar sidebar-offcanvas-right");
+  std::vector<std::unique_ptr<TagNode>> InfoIndexHTML =
+      genHTML(InfoIndex, InfoPath, true);
+  AppendVector(std::move(InfoIndexHTML), RightSidebarNode->Children);
+
+  MainNode->Children.emplace_back(std::move(LeftSidebarNode));
+  MainNode->Children.emplace_back(std::move(MainContentNode));
+  MainNode->Children.emplace_back(std::move(RightSidebarNode));
+
+  return MainNode;
+}
+
+// Generates a footer HTML node that can be used for any file
+// It contains clang-doc's version
+static std::unique_ptr<TagNode> genFileFooterNode() {
+  auto FooterNode = std::make_unique<TagNode>(HTMLTag::TAG_FOOTER);
+  auto SpanNode = std::make_unique<TagNode>(
+      HTMLTag::TAG_SPAN, clang::getClangToolFullVersion("clang-doc"));
+  SpanNode->Attributes.emplace_back("class", "no-break");
+  FooterNode->Children.emplace_back(std::move(SpanNode));
+  return FooterNode;
+}
+
+// Generates a complete HTMLFile for an Info
+static HTMLFile
+genInfoFile(StringRef Title, StringRef InfoPath,
+            std::vector<std::unique_ptr<TagNode>> &MainContentNodes,
+            const Index &InfoIndex, const ClangDocContext &CDCtx) {
+  HTMLFile F;
+
+  std::vector<std::unique_ptr<TagNode>> HeadNodes =
+      genFileHeadNodes(Title, InfoPath, CDCtx);
+  std::unique_ptr<TagNode> HeaderNode = genFileHeaderNode(CDCtx.ProjectName);
+  std::unique_ptr<TagNode> MainNode =
+      genInfoFileMainNode(InfoPath, MainContentNodes, InfoIndex);
+  std::unique_ptr<TagNode> FooterNode = genFileFooterNode();
+
+  AppendVector(std::move(HeadNodes), F.Children);
+  F.Children.emplace_back(std::move(HeaderNode));
+  F.Children.emplace_back(std::move(MainNode));
+  F.Children.emplace_back(std::move(FooterNode));
+
+  return F;
+}
+
 template <typename T,
           typename = std::enable_if<std::is_base_of<T, Info>::value>>
 static Index genInfoIndexItem(const std::vector<T> &Infos, StringRef Title) {
@@ -474,8 +570,8 @@ static Index genInfoIndexItem(const std:
   return Idx;
 }
 
-static std::vector<std::unique_ptr<TagNode>> genHTML(const Index &Index,
-                                                     StringRef InfoPath) {
+static std::vector<std::unique_ptr<TagNode>>
+genHTML(const Index &Index, StringRef InfoPath, bool IsOutermostList) {
   std::vector<std::unique_ptr<TagNode>> Out;
   if (!Index.Name.empty()) {
     Out.emplace_back(std::make_unique<TagNode>(HTMLTag::TAG_SPAN));
@@ -488,11 +584,13 @@ static std::vector<std::unique_ptr<TagNo
   }
   if (Index.Children.empty())
     return Out;
-  Out.emplace_back(std::make_unique<TagNode>(HTMLTag::TAG_UL));
+  // Only the outermost list should use ol, the others should use ul
+  HTMLTag ListHTMLTag = IsOutermostList ? HTMLTag::TAG_OL : HTMLTag::TAG_UL;
+  Out.emplace_back(std::make_unique<TagNode>(ListHTMLTag));
   const auto &UlBody = Out.back();
   for (const auto &C : Index.Children) {
     auto LiBody = std::make_unique<TagNode>(HTMLTag::TAG_LI);
-    std::vector<std::unique_ptr<TagNode>> Nodes = genHTML(C, InfoPath);
+    std::vector<std::unique_ptr<TagNode>> Nodes = genHTML(C, InfoPath, false);
     AppendVector(std::move(Nodes), LiBody->Children);
     UlBody->Children.emplace_back(std::move(LiBody));
   }
@@ -546,8 +644,8 @@ genHTML(const EnumInfo &I, const ClangDo
 
   Out.emplace_back(
       std::make_unique<TagNode>(HTMLTag::TAG_H3, EnumType + I.Name));
-  Out.back()->Attributes.try_emplace("id",
-                                     llvm::toHex(llvm::toStringRef(I.USR)));
+  Out.back()->Attributes.emplace_back("id",
+                                      llvm::toHex(llvm::toStringRef(I.USR)));
 
   std::unique_ptr<TagNode> Node = genEnumMembersBlock(I.Members);
   if (Node)
@@ -575,8 +673,8 @@ genHTML(const FunctionInfo &I, const Cla
   Out.emplace_back(std::make_unique<TagNode>(HTMLTag::TAG_H3, I.Name));
   // USR is used as id for functions instead of name to disambiguate function
   // overloads.
-  Out.back()->Attributes.try_emplace("id",
-                                     llvm::toHex(llvm::toStringRef(I.USR)));
+  Out.back()->Attributes.emplace_back("id",
+                                      llvm::toHex(llvm::toStringRef(I.USR)));
 
   Out.emplace_back(std::make_unique<TagNode>(HTMLTag::TAG_P));
   auto &FunctionHeader = Out.back();
@@ -738,48 +836,32 @@ const char *HTMLGenerator::Format = "htm
 
 llvm::Error HTMLGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS,
                                               const ClangDocContext &CDCtx) {
-  HTMLFile F;
   std::string InfoTitle;
-  auto MainContentNode = std::make_unique<TagNode>(HTMLTag::TAG_DIV);
+  std::vector<std::unique_ptr<TagNode>> MainContentNodes;
   Index InfoIndex;
   switch (I->IT) {
-  case InfoType::IT_namespace: {
-    std::vector<std::unique_ptr<TagNode>> Nodes =
-        genHTML(*static_cast<clang::doc::NamespaceInfo *>(I), InfoIndex, CDCtx,
-                InfoTitle);
-    AppendVector(std::move(Nodes), MainContentNode->Children);
+  case InfoType::IT_namespace:
+    MainContentNodes = genHTML(*static_cast<clang::doc::NamespaceInfo *>(I),
+                               InfoIndex, CDCtx, InfoTitle);
     break;
-  }
-  case InfoType::IT_record: {
-    std::vector<std::unique_ptr<TagNode>> Nodes = genHTML(
-        *static_cast<clang::doc::RecordInfo *>(I), InfoIndex, CDCtx, InfoTitle);
-    AppendVector(std::move(Nodes), MainContentNode->Children);
+  case InfoType::IT_record:
+    MainContentNodes = genHTML(*static_cast<clang::doc::RecordInfo *>(I),
+                               InfoIndex, CDCtx, InfoTitle);
     break;
-  }
-  case InfoType::IT_enum: {
-    std::vector<std::unique_ptr<TagNode>> Nodes =
-        genHTML(*static_cast<clang::doc::EnumInfo *>(I), CDCtx);
-    AppendVector(std::move(Nodes), MainContentNode->Children);
+  case InfoType::IT_enum:
+    MainContentNodes = genHTML(*static_cast<clang::doc::EnumInfo *>(I), CDCtx);
     break;
-  }
-  case InfoType::IT_function: {
-    std::vector<std::unique_ptr<TagNode>> Nodes =
+  case InfoType::IT_function:
+    MainContentNodes =
         genHTML(*static_cast<clang::doc::FunctionInfo *>(I), CDCtx, "");
-    AppendVector(std::move(Nodes), MainContentNode->Children);
     break;
-  }
   case InfoType::IT_default:
     return llvm::make_error<llvm::StringError>("Unexpected info type.\n",
                                                llvm::inconvertibleErrorCode());
   }
 
-  std::vector<std::unique_ptr<TagNode>> BasicNodes =
-      genCommonFileNodes(InfoTitle, I->Path, CDCtx);
-  AppendVector(std::move(BasicNodes), F.Children);
-  std::vector<std::unique_ptr<TagNode>> InfoIndexHTML =
-      genHTML(InfoIndex, I->Path);
-  AppendVector(std::move(InfoIndexHTML), F.Children);
-  F.Children.emplace_back(std::move(MainContentNode));
+  HTMLFile F =
+      genInfoFile(InfoTitle, I->Path, MainContentNodes, InfoIndex, CDCtx);
   F.Render(OS);
 
   return llvm::Error::success();
@@ -832,6 +914,24 @@ static bool SerializeIndex(ClangDocConte
   return true;
 }
 
+// Generates a main HTML node that has the main content of the file that shows
+// only the general index
+// It contains the general index with links to all the generated files
+static std::unique_ptr<TagNode> genIndexFileMainNode() {
+  auto MainNode = std::make_unique<TagNode>(HTMLTag::TAG_MAIN);
+
+  auto LeftSidebarNode = std::make_unique<TagNode>(HTMLTag::TAG_DIV);
+  LeftSidebarNode->Attributes.emplace_back("id", "sidebar-left");
+  LeftSidebarNode->Attributes.emplace_back("path", "");
+  LeftSidebarNode->Attributes.emplace_back(
+      "class", "col-xs-6 col-sm-3 col-md-2 sidebar sidebar-offcanvas-left");
+  LeftSidebarNode->Attributes.emplace_back("style", "flex: 0 100%;");
+
+  MainNode->Children.emplace_back(std::move(LeftSidebarNode));
+
+  return MainNode;
+}
+
 static bool GenIndex(const ClangDocContext &CDCtx) {
   std::error_code FileErr, OK;
   llvm::SmallString<128> IndexPath;
@@ -842,11 +942,22 @@ static bool GenIndex(const ClangDocConte
     llvm::errs() << "Error creating main index: " << FileErr.message() << "\n";
     return false;
   }
+
   HTMLFile F;
-  std::vector<std::unique_ptr<TagNode>> BasicNodes =
-      genCommonFileNodes("Index", "", CDCtx);
-  AppendVector(std::move(BasicNodes), F.Children);
+
+  std::vector<std::unique_ptr<TagNode>> HeadNodes =
+      genFileHeadNodes("Index", "", CDCtx);
+  std::unique_ptr<TagNode> HeaderNode = genFileHeaderNode(CDCtx.ProjectName);
+  std::unique_ptr<TagNode> MainNode = genIndexFileMainNode();
+  std::unique_ptr<TagNode> FooterNode = genFileFooterNode();
+
+  AppendVector(std::move(HeadNodes), F.Children);
+  F.Children.emplace_back(std::move(HeaderNode));
+  F.Children.emplace_back(std::move(MainNode));
+  F.Children.emplace_back(std::move(FooterNode));
+
   F.Render(IndexOS);
+
   return true;
 }
 

Modified: clang-tools-extra/trunk/clang-doc/Representation.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-doc/Representation.cpp?rev=369139&r1=369138&r2=369139&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-doc/Representation.cpp (original)
+++ clang-tools-extra/trunk/clang-doc/Representation.cpp Fri Aug 16 11:38:11 2019
@@ -274,12 +274,14 @@ void Index::sort() {
 }
 
 ClangDocContext::ClangDocContext(tooling::ExecutionContext *ECtx,
-                                 bool PublicOnly, StringRef OutDirectory,
-                                 StringRef SourceRoot, StringRef RepositoryUrl,
+                                 StringRef ProjectName, bool PublicOnly,
+                                 StringRef OutDirectory, StringRef SourceRoot,
+                                 StringRef RepositoryUrl,
                                  std::vector<std::string> UserStylesheets,
                                  std::vector<std::string> JsScripts)
-    : ECtx(ECtx), PublicOnly(PublicOnly), OutDirectory(OutDirectory),
-      UserStylesheets(UserStylesheets), JsScripts(JsScripts) {
+    : ECtx(ECtx), ProjectName(ProjectName), PublicOnly(PublicOnly),
+      OutDirectory(OutDirectory), UserStylesheets(UserStylesheets),
+      JsScripts(JsScripts) {
   llvm::SmallString<128> SourceRootDir(SourceRoot);
   if (SourceRoot.empty())
     // If no SourceRoot was provided the current path is used as the default

Modified: clang-tools-extra/trunk/clang-doc/Representation.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-doc/Representation.h?rev=369139&r1=369138&r2=369139&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-doc/Representation.h (original)
+++ clang-tools-extra/trunk/clang-doc/Representation.h Fri Aug 16 11:38:11 2019
@@ -413,12 +413,13 @@ mergeInfos(std::vector<std::unique_ptr<I
 
 struct ClangDocContext {
   ClangDocContext() = default;
-  ClangDocContext(tooling::ExecutionContext *ECtx, bool PublicOnly,
-                  StringRef OutDirectory, StringRef SourceRoot,
+  ClangDocContext(tooling::ExecutionContext *ECtx, StringRef ProjectName,
+                  bool PublicOnly, StringRef OutDirectory, StringRef SourceRoot,
                   StringRef RepositoryUrl,
                   std::vector<std::string> UserStylesheets,
                   std::vector<std::string> JsScripts);
   tooling::ExecutionContext *ECtx;
+  std::string ProjectName; // Name of project clang-doc is documenting.
   bool PublicOnly; // Indicates if only public declarations are documented.
   std::string OutDirectory; // Directory for outputting generated files.
   std::string SourceRoot;   // Directory where processed files are stored. Links

Modified: clang-tools-extra/trunk/clang-doc/assets/clang-doc-default-stylesheet.css
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-doc/assets/clang-doc-default-stylesheet.css?rev=369139&r1=369138&r2=369139&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-doc/assets/clang-doc-default-stylesheet.css (original)
+++ clang-tools-extra/trunk/clang-doc/assets/clang-doc-default-stylesheet.css Fri Aug 16 11:38:11 2019
@@ -1,205 +1,969 @@
-body,div {
+.dark-primary-color    { background: #1976D2; }
+.default-primary-color { background: #2196F3; }
+.light-primary-color   { background: #BBDEFB; }
+.text-primary-color    { color: #FFFFFF; }
+.accent-color          { background: #00BCD4; }
+.primary-text-color    { color: #212121; }
+.secondary-text-color  { color: #727272; }
+.divider-color         { border-color: #B6B6B6; }
+
+/* for layout */
+html,
+body {
   margin: 0;
   padding: 0;
+  height: 100%;
+  width: 100%;
+  overflow: hidden;
+  box-sizing: border-box;
 }
 
-body[no-overflow] {
-  overflow: hidden;
+*, *:before, *:after {
+  box-sizing: inherit;
 }
 
-li>p:first-child {
-  margin-top: 0;
+body {
+  display: flex;
+  flex-direction: column;
+  min-height: 100vh;
+}
+
+header {
+  flex: 0 0 50px;
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  padding-left: 30px;
 }
 
-li>p:last-child {
-  margin-bottom: 0;
+header ol {
+  list-style: none;
+  margin: 0;
+  padding: 0;
 }
 
-html {
-  -webkit-box-sizing: border-box;
-  box-sizing: border-box;
+header ol li {
+  display: inline;
 }
 
-*,*::before,*::after {
-  -webkit-box-sizing: inherit;
-  box-sizing: inherit;
+header form {
+  display: flex;
+  flex: 1;
+  justify-content: flex-end;
+  padding-right: 30px;
 }
 
-body,html {
-  color: #202124;
-  font: 400 16px/24px Roboto,sans-serif;
-  -moz-osx-font-smoothing: grayscale;
-  -webkit-font-smoothing: antialiased;
-  height: 100%;
-  margin: 36px;
-  -webkit-text-size-adjust: 100%;
-  -moz-text-size-adjust: 100%;
-  -ms-text-size-adjust: 100%;
-  text-size-adjust: 100%;
+header#header-search-sidebar {
+  height: 50px;
+  margin-bottom: 25px;
 }
 
-body[devsite-framebox] {
-  overflow: hidden;
+footer {
+  flex: 0 0 16px;
+  text-align: center;
+  padding: 16px 20px;
+}
+
+main {
+  flex: 1;
+  display: flex;
+  flex-direction: row;
   padding: 20px;
+  min-height: 0;
 }
 
-body[sitemask--active] {
-  overflow: hidden;
+.sidebar-offcanvas-left {
+  flex: 0 1 230px;
+  overflow-y: scroll;
+  padding: 20px 0 15px 30px;
+  margin: 5px 20px 0 0;
+  visibility: visible; /* shown by Javascript after scroll position restore */
 }
 
-p {
-  margin: 16px 0;
+::-webkit-scrollbar-button{ display: none; height: 13px; border-radius: 0px; background-color: #AAA; }
+::-webkit-scrollbar-button:hover{ background-color: #AAA; }
+::-webkit-scrollbar-thumb{ background-color: #CCC; }
+::-webkit-scrollbar-thumb:hover{ background-color: #CCC; }
+::-webkit-scrollbar{ width: 4px; }
+/* ::-webkit-overflow-scrolling: touch; */
+
+.main-content::-webkit-scrollbar{ width: 8px; }
+
+.main-content {
+  flex: 1;
+  overflow-y: scroll;
+  padding: 10px 20px 0 20px;
+  visibility: visible; /* shown by Javascript after scroll position restore */
+}
+
+.sidebar-offcanvas-right {
+  flex: 0 1 12em;
+  overflow-y: scroll;
+  padding: 20px 15px 15px 15px;
+  margin-top: 5px;
+  margin-right: 20px;
+  visibility: visible; /* shown by Javascript after scroll position restore */
+}
+/* end for layout */
+
+body {
+  -webkit-text-size-adjust: 100%;
+  overflow-x: hidden;
+  font-family: Roboto, sans-serif;
+  font-size: 16px;
+  line-height: 1.42857143;
+  color: #111111;
+  background-color: #fff;
+}
+
+/* some of this is to reset bootstrap */
+nav.navbar {
+  background-color: inherit;
+  min-height: 50px;
+  border: 0;
+}
+
+ at media (max-width: 768px) {
+  .hidden-xs {
+    display: none !important;
+  }
+}
+
+ at media (min-width: 769px) {
+  .hidden-l {
+    display: none !important;
+  }
+}
+
+nav.navbar .row {
+  padding-top: 8px;
+}
+
+nav .container {
+  white-space: nowrap;
+}
+
+header {
+  background-color: #eeeeee;
+  box-shadow: 0 3px 5px rgba(0,0,0,0.1);
+}
+
+header#project-title {
+  background-color: #fff;
+  font-size: 200%;
+  padding-top: 0.25em;
+  padding-bottom: 0.25em;
+  /* padding: 0em; */
+}
+
+header.header-fixed nav.navbar-fixed-top {
+  box-shadow: 0 3px 5px rgba(0,0,0,0.1);
+}
+
+header.container-fluid {
   padding: 0;
 }
 
-:link,:visited {
-  color: #039be5;
-  outline: 0;
+header .masthead {
+  padding-top: 64px;
+}
+
+header .contents {
+  padding: 0;
+}
+
+ at media screen and (max-width:768px) {
+  header .contents {
+    padding-left: 15px;
+    padding-right: 15px;
+  }
+}
+
+a {
   text-decoration: none;
 }
 
-ul {
+.body {
+  margin-top: 90px;
+}
+
+section {
+  margin-bottom: 36px;
+}
+
+dl {
   margin: 0;
-  padding-left: 40px;
 }
 
-ul {
-  list-style: disc outside;
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+  font-family: Roboto, sans-serif;
+  font-weight: 400;
+  margin-top: 1.5em;
+  color: #111111;
 }
 
-li,li p {
-  margin: 12px 0;
-  padding: 0;
+h1.title {
+  overflow: hidden;
+  text-overflow: ellipsis;
 }
 
-*[visually-hidden] {
-  opacity: 0 !important;
-  pointer-events: none !important;
-  visibility: hidden !important;
+h1 {
+  font-size: 37px;
+  margin-top: 0;
+  margin-bottom: 0.67em;
 }
 
-*[hidden] {
-  display: none !important;
+h2 {
+  font-size: 28px;
 }
 
-[render-hidden] {
-  display: inline !important;
-  position: absolute !important;
-  visibility: hidden !important;
+h5 {
+  font-size: 16px;
 }
 
-*[no-scroll] {
-  overflow: hidden;
+.subtitle {
+  font-size: 17px;
+  min-height: 1.4em;
+}
+
+.title-description .subtitle {
+  white-space: nowrap;
+  overflow-x: hidden;
+  text-overflow: ellipsis;
+}
+
+p {
+  margin-bottom: 1em;
+  margin-top: 0;
+}
+
+a {
+  color: #0175C2;
+}
+
+a:hover {
+  color: #13B9FD;
+}
+
+pre.prettyprint {
+  font-family: 'Source Code Pro', Menlo, monospace;
+  color: black;
+  border-radius: 0;
+  font-size: 15px;
+  word-wrap: normal;
+  line-height: 1.4;
+  border: 0;
+  margin: 16px 0 16px 0;
+  padding: 8px;
+}
+
+pre code {
+  white-space: pre;
+  word-wrap: initial;
+  font-size: 100%
+}
+
+.fixed {
+  white-space: pre;
+}
+
+pre {
+  border: 1px solid #ddd;
+  background-color: #eee;
+  font-size: 14px;
+}
+
+code {
+  font-family: 'Source Code Pro', Menlo, monospace;
+  /* overriding bootstrap */
+  color: inherit;
+  padding: 0.2em 0.4em;
+  font-size: 85%;
+  background-color: rgba(27,31,35,0.05);
+  border-radius: 3px;
 }
 
- at supports (display: flex) {
-  body[ready] .devsite-wrapper {
-    display: -webkit-box;
-    display: -ms-flexbox;
-    display: flex;
-    -webkit-box-orient: vertical;
-    -webkit-box-direction: normal;
-    -ms-flex-direction: column;
-    flex-direction: column;
+ at media(max-width: 768px) {
+  nav .container {
+    width: 100%
+  }
+
+  h1 {
+    font-size: 24px;
+  }
+
+  pre {
+    margin: 16px 0;
   }
 }
 
- at media screen and (max-width: 840px) {
-  body[devsite-book-nav--open] {
-    overflow: hidden;
+ at media (min-width: 768px) {
+  ul.subnav li {
+    font-size: 17px;
   }
 }
 
-h1,h2,h3,h4,h5,h6 {
-  overflow: hidden;
-  padding: 0;
+header h1 {
+  font-weight: 400;
+  margin-bottom: 16px;
+}
+
+header a,
+header p,
+header li {
+  color: #111111;
+}
+
+header a:hover {
+  color: #0175C2;
+}
+
+header h1 .kind {
+  color: #555;
+}
+
+dt {
+  font-weight: normal;
+}
+
+dd {
+  color: #212121;
+  margin-bottom: 1em;
+  margin-left: 0;
+}
+
+dd.callable, dd.constant, dd.property {
+  margin-bottom: 24px;
+}
+
+dd p {
+  overflow-x: hidden;
   text-overflow: ellipsis;
+  margin-bottom: 0;
 }
 
-h1 {
-  color: #80868b;
-  font: 300 34px/40px Roboto,sans-serif;
-  letter-spacing: -0.01em;
-  margin: 40px 0 20px;
+/* indents wrapped lines */
+section.summary dt {
+  margin-left: 24px;
+  text-indent: -24px;
 }
 
-[layout=docs] h2 {
-  border-bottom: 1px solid #e8eaed;
-  padding-bottom: 3px;
+.dl-horizontal dd {
+  margin-left: initial;
 }
 
-h2 {
-  font: 300 24px/32px Roboto,sans-serif;
-  letter-spacing: -0.01em;
-  margin: 40px 0 20px;
+dl.dl-horizontal dt {
+  font-style: normal;
+  text-align: left;
+  color: #727272;
+  margin-right: 20px;
+  width: initial;
 }
 
-h3 {
-  font: 400 20px/32px Roboto,sans-serif;
-  margin: 32px 0 16px;
+dt .name {
+  font-weight: 500;
 }
 
-h4,h5,h6 {
-  margin: 32px 0 16px;
+dl dt.callable .name {
+  float: none;
+  width: auto;
 }
 
-h4 {
-  font: 500 16px/24px Roboto,sans-serif;
+.parameter {
+  white-space: nowrap;
 }
 
-h5 {
-  font: 700 14px/24px Roboto,sans-serif;
+.type-parameter {
+  white-space: nowrap;
 }
 
-h6 {
-  font: 500 14px/24px Roboto,sans-serif;
+.multi-line-signature .type-parameter .parameter {
+  margin-left: 0px;
+  display: unset;
 }
 
-h1+h1,h1+h2,h1+h3,h1+h4,h1+h5,h1+h6,h2+h1,h2+h2,h2+h3,h2+h4,h2+h5,h2+h6,h3+h1,h3+h2,h3+h3,h3+h4,h3+h5,h3+h6,h4+h1,h4+h2,h4+h3,h4+h4,h4+h5,h4+h6,h5+h1,h5+h2,h5+h3,h5+h4,h5+h5,h5+h6,h6+h1,h6+h2,h6+h3,h6+h4,h6+h5,h6+h6 {
-  margin-top: 0;
+.signature {
+  color: #727272;
 }
 
- at media screen and (max-width: 600px) {
-  h1 {
-    font: 300 24px/32px Roboto,sans-serif;
+.signature a {
+  /* 50% mix of default-primary-color and primary-text-color. */
+  color: #4674a2;
+}
+
+.optional {
+  font-style: italic;
+}
+
+.undocumented {
+  font-style: italic;
+}
+
+.is-const {
+  font-style: italic;
+}
+
+.deprecated {
+  text-decoration: line-through;
+}
+
+.category.linked {
+  font-weight: bold;
+  opacity: 1;
+}
+
+/* Colors for category based on categoryOrder in dartdoc_options.config. */
+.category.cp-0 {
+  background-color: #54b7c4
+}
+
+.category.cp-1 {
+  background-color: #54c47f
+}
+
+.category.cp-2 {
+  background-color: #c4c254
+}
+
+.category.cp-3 {
+  background-color: #c49f54
+}
+
+.category.cp-4 {
+  background-color: #c45465
+}
+
+.category.cp-5 {
+  background-color: #c454c4
+}
+
+.category a {
+  color: white;
+}
+
+.category {
+  padding: 2px 4px;
+  font-size: 12px;
+  border-radius: 4px;
+  background-color: #999;
+  text-transform: uppercase;
+  color: white;
+  opacity: .5;
+}
+
+h1 .category {
+  vertical-align: middle;
+}
+
+.source-link {
+  padding: 18px 4px;
+  vertical-align: middle;
+}
+
+.source-link .material-icons {
+  font-size: 18px;
+}
+
+ at media (max-width: 768px) {
+  .source-link {
+    padding: 7px 2px;
+    font-size: 10px;
   }
 }
 
-[scrollbars]::-webkit-scrollbar {
-  height: 8px;
-  width: 8px;
+#external-links {
+  float: right;
 }
 
-[scrollbars]::-webkit-scrollbar-thumb {
-  background: rgba(128,134,139,.26);
-  border-radius: 8px;
+.btn-group {
+  position: relative;
+  display: inline-flex;
+  vertical-align: middle;
 }
 
-[no-horizontal-scrollbars]::-webkit-scrollbar {
-  height: 0;
-  width: 0;
+p.firstline {
+  font-weight: bold;
 }
 
-[scrollbars]::-webkit-scrollbar-corner {
-  background: 0;
+footer {
+  color: #fff;
+  background-color: #111111;
+  width: 100%;
 }
 
-[background] h2 {
+footer p {
+  margin: 0;
+}
+
+footer .no-break {
+  white-space: nowrap;
+}
+
+footer .container,
+footer .container-fluid {
+  padding-left: 0;
+  padding-right: 0;
+}
+
+footer a, footer a:hover {
   color: #fff;
 }
 
- at media print {
-  body,  html,  :link,  :visited,  h1,  h2,  h3,  h4,  h5,  h6 {
-    color: #000 !important;
-    padding-left: 0 !important;
-    padding-right: 0 !important;
+.markdown.desc {
+  max-width: 700px;
+}
+
+.markdown h1 {
+  font-size: 24px;
+  margin-bottom: 8px;
+}
+
+.markdown h2 {
+  font-size: 20px;
+  margin-top: 24px;
+  margin-bottom: 8px;
+}
+
+.markdown h3 {
+  font-size: 18px;
+  margin-bottom: 8px;
+}
+
+.markdown h4 {
+  font-size: 16px;
+  margin-bottom: 0;
+}
+
+.markdown li p {
+  margin: 0;
+}
+
+.gt-separated {
+  list-style: none;
+  padding: 0;
+  margin: 0;
+}
+
+.gt-separated li {
+  display: inline-block;
+}
+
+.gt-separated li:before {
+  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><path fill='%23DDDDDD' d='M6.7,4L5.7,4.9L8.8,8l-3.1,3.1L6.7,12l4-4L6.7,4z'/></svg>");
+  background-position: center;
+  content: "\00a0";
+  margin: 0 6px 0 4px;
+  padding: 0 3px 0 0;
+}
+
+.gt-separated.dark li:before {
+  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><path fill='%23727272' d='M6.7,4L5.7,4.9L8.8,8l-3.1,3.1L6.7,12l4-4L6.7,4z'/></svg>");
+}
+
+.gt-separated li:first-child:before {
+  background-image: none;
+  content: "";
+  margin: 0;
+}
+
+/* The slug line under a declaration for things like "const", "read-only", etc. */
+.features {
+  font-style: italic;
+  color: #727272;
+}
+
+.multi-line-signature {
+  font-size: 17px;
+  color: #727272;
+}
+
+.multi-line-signature .parameter {
+  margin-left: 24px;
+  display: block;
+}
+
+.breadcrumbs {
+  padding: 0;
+  margin: 8px 0 8px 0;
+  white-space: nowrap;
+  line-height: 1;
+}
+
+ at media screen and (min-width: 768px) {
+  nav ol.breadcrumbs {
+    float: left;
   }
+}
 
-  :link,  :visited {
-    text-decoration: underline;
+ at media screen and (max-width: 768px) {
+  .breadcrumbs {
+    margin: 0 0 24px 0;
+    overflow-x: hidden;
   }
 }
 
- at page {
-  margin: .75in;
+.self-crumb {
+  color: #555;
+}
+
+.self-name {
+  color: #555;
+  display: none;
 }
+
+.annotation-list {
+  list-style: none;
+  padding: 0;
+  display: inline;
+}
+
+.comma-separated {
+  list-style: none;
+  padding: 0;
+  display: inline;
+}
+
+.comma-separated li {
+  display: inline;
+}
+
+.comma-separated li:after {
+  content: ", ";
+}
+
+.comma-separated li:last-child:after {
+  content: "";
+}
+
+.end-with-period li:last-child:after {
+  content: ".";
+}
+
+.container > section:first-child {
+  border: 0;
+}
+
+.constructor-modifier {
+  font-style: italic;
+}
+
+section.multi-line-signature div.parameters {
+  margin-left: 24px;
+}
+
+/* subnav styles */
+
+ul.subnav {
+  overflow: auto;
+  white-space: nowrap;
+  padding-left: 0;
+  min-height: 25px;
+}
+
+ul.subnav::-webkit-scrollbar {
+  display: none;
+}
+
+ul.subnav li {
+  display: inline-block;
+  text-transform: uppercase;
+}
+
+ul.subnav li a {
+  color: #111;
+}
+
+ul.subnav li {
+  margin-right: 24px;
+}
+
+ul.subnav li:last-of-type {
+  margin-right: 0;
+}
+
+ at media(max-width: 768px) {
+  ul.subnav li {
+    margin-right: 16px;
+  }
+}
+
+/* sidebar styles */
+
+.sidebar ol {
+  list-style: none;
+  line-height: 22px;
+  margin-top: 0;
+  margin-bottom: 0;
+  padding: 0 0 15px 0;
+}
+
+.sidebar h5 a,
+.sidebar h5 a:hover {
+  color: #727272;
+}
+
+.sidebar h5,
+.sidebar ol li {
+  text-overflow: ellipsis;
+  overflow: hidden;
+  padding: 3px 0;
+}
+
+.sidebar h5 {
+  color: #727272;
+  font-size: 18px;
+  margin: 0 0 25px 0;
+  padding-top: 0;
+}
+
+.sidebar ol li.section-title {
+  font-size: 18px;
+  font-weight: normal;
+  text-transform: uppercase;
+  padding-top: 25px;
+}
+
+.sidebar ol li.section-subtitle a {
+  color: inherit;
+}
+
+.sidebar ol li.section-subtitle {
+  font-weight: 400;
+  text-transform: uppercase;
+}
+
+.sidebar ol li.section-subitem {
+  margin-left: 12px;
+}
+
+.sidebar ol li:first-child {
+  padding-top: 0;
+  margin-top: 0;
+}
+
+button {
+  padding: 0;
+}
+
+#sidenav-left-toggle {
+  display: none;
+  vertical-align: text-bottom;
+  padding: 0;
+}
+
+/* left-nav disappears, and can transition in from the left */
+ at media screen and (max-width:768px) {
+  #sidenav-left-toggle {
+    display: inline;
+    background: no-repeat url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'><path fill='%23111' d='M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z'/></svg>");
+    background-position: center;
+    width: 24px;
+    height: 24px;
+    border: none;
+    margin-right: 24px;
+  }
+
+  #overlay-under-drawer.active {
+    opacity: 0.4;
+    height: 100%;
+    z-index: 1999;
+    position: fixed;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    background-color: black;
+    display: block;
+  }
+
+  .sidebar-offcanvas-left {
+    left: -100%;
+    position: fixed;
+    -webkit-transition:all .25s ease-out;
+    -o-transition:all .25s ease-out;
+    transition:all .25s ease-out;
+    z-index: 2000;
+    top: 0;
+    width: 280px; /* works all the way down to an iphone 4 */
+    height: 90%;
+    background-color: white;
+    overflow-y: scroll; /* TODO: how to hide scroll bars? */
+    padding: 10px;
+    margin: 10px 10px;
+    box-shadow: 5px 5px 5px 5px #444444;
+    visibility: hidden; /* shown by Javascript after scroll position restore */
+  }
+
+  ol#sidebar-nav {
+    font-size: 18px;
+    white-space: pre-line;
+  }
+
+  .sidebar-offcanvas-left.active {
+    left: 0; /* this animates our drawer into the page */
+  }
+
+  .self-name {
+    display: inline-block;
+  }
+}
+
+.sidebar-offcanvas-left h5 {
+  margin-bottom: 10px;
+}
+
+.sidebar-offcanvas-left h5:last-of-type {
+  border: 0;
+  margin-bottom: 25px;
+}
+
+/* the right nav disappears out of view when the window shrinks */
+ at media screen and (max-width: 992px) {
+  .sidebar-offcanvas-right {
+     display: none;
+   }
+}
+
+#overlay-under-drawer {
+  display: none;
+}
+
+/* find-as-you-type search box */
+
+/* override bootstrap defaults */
+.form-control {
+  border-radius: 0;
+  border: 0;
+}
+
+ at media screen and (max-width: 768px) {
+  form.search {
+    display: none;
+  }
+}
+
+.typeahead,
+.tt-query,
+.tt-hint {
+  width: 200px;
+  height: 20px;
+  padding: 2px 7px 1px 7px;
+  line-height: 20px;
+  outline: none;
+}
+
+.typeahead {
+  background-color: #fff;
+  border-radius: 2px;
+}
+
+.tt-query {
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+     -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+}
+
+.tt-hint {
+  color: #999
+}
+
+.navbar-right .tt-menu {
+  right:0;
+  left: inherit !important;
+  width: 422px;
+  max-height: 250px;
+  overflow-y: scroll;
+}
+
+.tt-menu {
+  font-size: 14px;
+  margin: 0;
+  padding: 8px 0;
+  background-color: #fff;
+  border: 1px solid #ccc;
+  border: 1px solid rgba(0, 0, 0, 0.2);
+  -webkit-box-shadow: 0 5px 10px rgba(0,0,0,.2);
+     -moz-box-shadow: 0 5px 10px rgba(0,0,0,.2);
+          box-shadow: 0 5px 10px rgba(0,0,0,.2);
+}
+
+.tt-suggestion {
+  padding: 3px 20px;
+  color: #212121;
+}
+
+.tt-suggestion:hover {
+  cursor: pointer;
+  color: #fff;
+  background-color: #0097cf;
+}
+
+.tt-suggestion:hover .search-from-lib {
+  color: #ddd;
+}
+
+.tt-suggestion.tt-cursor {
+  color: #fff;
+  background-color: #0097cf;
+}
+
+.tt-suggestion.tt-cursor .search-from-lib {
+  color: #ddd;
+}
+
+.tt-suggestion p {
+  margin: 0;
+}
+
+.search-from-lib {
+  font-style: italic;
+  color: gray;
+}
+
+#search-box {
+  background-color: #ffffff;
+}
+
+.search-body {
+  border: 1px solid #7f7f7f;
+  max-width: 400px;
+  box-shadow: 3px 3px 5px rgba(0,0,0,0.1);
+}
+
+section#setter {
+  border-top: 1px solid #ddd;
+  padding-top: 36px;
+}
+
+li.inherited a {
+  opacity: 0.65;
+  font-style: italic;
+}
+
+#instance-methods dt.inherited .name,
+#instance-properties dt.inherited .name,
+#operators dt.inherited .name {
+  font-weight: 300;
+  font-style: italic;
+}
+
+#instance-methods dt.inherited .signature,
+#instance-properties dt.inherited .signature,
+#operators dt.inherited .signature {
+  font-weight: 300;
+}
+
+ at media print {
+  .subnav, .sidebar {
+    display:none;
+  }
+
+  a[href]:after {
+   content:"" !important;
+  }
+}
\ No newline at end of file

Modified: clang-tools-extra/trunk/clang-doc/assets/index.js
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-doc/assets/index.js?rev=369139&r1=369138&r2=369139&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-doc/assets/index.js (original)
+++ clang-tools-extra/trunk/clang-doc/assets/index.js Fri Aug 16 11:38:11 2019
@@ -39,7 +39,7 @@ function genLink(Ref, CurrentDirectory)
   return ANode;
 }
 
-function genHTMLOfIndex(Index, CurrentDirectory) {
+function genHTMLOfIndex(Index, CurrentDirectory, IsOutermostList) {
   // Out will store the HTML elements that Index requires to be generated
   var Out = [];
   if (Index.Name) {
@@ -50,24 +50,26 @@ function genHTMLOfIndex(Index, CurrentDi
   }
   if (Index.Children.length == 0)
     return Out;
-  var UlNode = document.createElement("ul");
+  // Only the outermost list should use ol, the others should use ul
+  var ListNodeName = IsOutermostList ? "ol" : "ul";
+  var ListNode = document.createElement(ListNodeName);
   for (Child of Index.Children) {
     var LiNode = document.createElement("li");
-    ChildNodes = genHTMLOfIndex(Child, CurrentDirectory);
+    ChildNodes = genHTMLOfIndex(Child, CurrentDirectory, false);
     for (Node of ChildNodes)
       LiNode.appendChild(Node);
-    UlNode.appendChild(LiNode);
+    ListNode.appendChild(LiNode);
   }
-  Out.push(UlNode);
+  Out.push(ListNode);
   return Out;
 }
 
 function createIndex(Index) {
   // Get the DOM element where the index will be created
-  var IndexDiv = document.getElementById("index");
+  var IndexDiv = document.getElementById("sidebar-left");
   // Get the relative path of this file
   CurrentDirectory = IndexDiv.getAttribute("path");
-  var IndexNodes = genHTMLOfIndex(Index, CurrentDirectory);
+  var IndexNodes = genHTMLOfIndex(Index, CurrentDirectory, true);
   for (Node of IndexNodes)
     IndexDiv.appendChild(Node);
 }

Modified: clang-tools-extra/trunk/clang-doc/tool/ClangDocMain.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-doc/tool/ClangDocMain.cpp?rev=369139&r1=369138&r2=369139&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-doc/tool/ClangDocMain.cpp (original)
+++ clang-tools-extra/trunk/clang-doc/tool/ClangDocMain.cpp Fri Aug 16 11:38:11 2019
@@ -52,6 +52,10 @@ using namespace clang;
 static llvm::cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
 static llvm::cl::OptionCategory ClangDocCategory("clang-doc options");
 
+static llvm::cl::opt<std::string>
+    ProjectName("project-name", llvm::cl::desc("Name of project."),
+                llvm::cl::cat(ClangDocCategory));
+
 static llvm::cl::opt<bool> IgnoreMappingFailures(
     "ignore-map-errors",
     llvm::cl::desc("Continue if files are not mapped correctly."),
@@ -205,6 +209,7 @@ int main(int argc, const char **argv) {
 
   clang::doc::ClangDocContext CDCtx = {
       Exec->get()->getExecutionContext(),
+      ProjectName,
       PublicOnly,
       OutDirectory,
       SourceRoot,

Modified: clang-tools-extra/trunk/docs/clang-doc.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-doc.rst?rev=369139&r1=369138&r2=369139&view=diff
==============================================================================
--- clang-tools-extra/trunk/docs/clang-doc.rst (original)
+++ clang-tools-extra/trunk/docs/clang-doc.rst Fri Aug 16 11:38:11 2019
@@ -89,6 +89,7 @@ Options
     --ignore-map-errors         - Continue if files are not mapped correctly.
     --output=<string>           - Directory for outputting generated files.
     -p=<string>                 - Build path
+    --project-name=<string>     - Name of project.
     --public                    - Document only public declarations.
     --repository=<string>       -
                                   URL of repository that hosts code.

Modified: clang-tools-extra/trunk/unittests/clang-doc/HTMLGeneratorTest.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-doc/HTMLGeneratorTest.cpp?rev=369139&r1=369138&r2=369139&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clang-doc/HTMLGeneratorTest.cpp (original)
+++ clang-tools-extra/trunk/unittests/clang-doc/HTMLGeneratorTest.cpp Fri Aug 16 11:38:11 2019
@@ -10,11 +10,15 @@
 #include "Generators.h"
 #include "Representation.h"
 #include "Serialize.h"
+#include "clang/Basic/Version.h"
 #include "gtest/gtest.h"
 
 namespace clang {
 namespace doc {
 
+static const std::string ClangDocVersion =
+    clang::getClangToolFullVersion("clang-doc");
+
 std::unique_ptr<Generator> getHTMLGenerator() {
   auto G = doc::findGeneratorByName("html");
   if (!G)
@@ -25,7 +29,8 @@ std::unique_ptr<Generator> getHTMLGenera
 ClangDocContext
 getClangDocContext(std::vector<std::string> UserStylesheets = {},
                    StringRef RepositoryUrl = "") {
-  ClangDocContext CDCtx{{}, {}, {}, {}, RepositoryUrl, UserStylesheets, {}};
+  ClangDocContext CDCtx{
+      {}, "test-project", {}, {}, {}, RepositoryUrl, UserStylesheets, {}};
   CDCtx.UserStylesheets.insert(
       CDCtx.UserStylesheets.begin(),
       "../share/clang/clang-doc-default-stylesheet.css");
@@ -61,67 +66,76 @@ TEST(HTMLGeneratorTest, emitNamespaceHTM
 <link rel="stylesheet" href="clang-doc-default-stylesheet.css"/>
 <link rel="stylesheet" href="user-provided-stylesheet.css"/>
 <script src="index.js"></script>
-<div id="index" path=""></div>
-<ul>
-  <li>
-    <span>
-      <a href="#Namespaces">Namespaces</a>
-    </span>
-  </li>
-  <li>
-    <span>
-      <a href="#Records">Records</a>
-    </span>
-  </li>
-  <li>
-    <span>
-      <a href="#Functions">Functions</a>
-    </span>
+<header id="project-title">test-project</header>
+<main>
+  <div id="sidebar-left" path="" class="col-xs-6 col-sm-3 col-md-2 sidebar sidebar-offcanvas-left"></div>
+  <div id="main-content" class="col-xs-12 col-sm-9 col-md-8 main-content">
+    <h1>namespace Namespace</h1>
+    <h2 id="Namespaces">Namespaces</h2>
     <ul>
       <li>
-        <span>
-          <a href="#0000000000000000000000000000000000000000">OneFunction</a>
-        </span>
+        <a href="Namespace/ChildNamespace.html">ChildNamespace</a>
       </li>
     </ul>
-  </li>
-  <li>
-    <span>
-      <a href="#Enums">Enums</a>
-    </span>
+    <h2 id="Records">Records</h2>
     <ul>
       <li>
-        <span>
-          <a href="#0000000000000000000000000000000000000000">OneEnum</a>
-        </span>
+        <a href="Namespace/ChildStruct.html">ChildStruct</a>
       </li>
     </ul>
-  </li>
-</ul>
-<div>
-  <h1>namespace Namespace</h1>
-  <h2 id="Namespaces">Namespaces</h2>
-  <ul>
-    <li>
-      <a href="Namespace/ChildNamespace.html">ChildNamespace</a>
-    </li>
-  </ul>
-  <h2 id="Records">Records</h2>
-  <ul>
-    <li>
-      <a href="Namespace/ChildStruct.html">ChildStruct</a>
-    </li>
-  </ul>
-  <h2 id="Functions">Functions</h2>
-  <div>
-    <h3 id="0000000000000000000000000000000000000000">OneFunction</h3>
-    <p>OneFunction()</p>
+    <h2 id="Functions">Functions</h2>
+    <div>
+      <h3 id="0000000000000000000000000000000000000000">OneFunction</h3>
+      <p>OneFunction()</p>
+    </div>
+    <h2 id="Enums">Enums</h2>
+    <div>
+      <h3 id="0000000000000000000000000000000000000000">enum OneEnum</h3>
+    </div>
   </div>
-  <h2 id="Enums">Enums</h2>
-  <div>
-    <h3 id="0000000000000000000000000000000000000000">enum OneEnum</h3>
+  <div id="sidebar-right" class="col-xs-6 col-sm-6 col-md-2 sidebar sidebar-offcanvas-right">
+    <ol>
+      <li>
+        <span>
+          <a href="#Namespaces">Namespaces</a>
+        </span>
+      </li>
+      <li>
+        <span>
+          <a href="#Records">Records</a>
+        </span>
+      </li>
+      <li>
+        <span>
+          <a href="#Functions">Functions</a>
+        </span>
+        <ul>
+          <li>
+            <span>
+              <a href="#0000000000000000000000000000000000000000">OneFunction</a>
+            </span>
+          </li>
+        </ul>
+      </li>
+      <li>
+        <span>
+          <a href="#Enums">Enums</a>
+        </span>
+        <ul>
+          <li>
+            <span>
+              <a href="#0000000000000000000000000000000000000000">OneEnum</a>
+            </span>
+          </li>
+        </ul>
+      </li>
+    </ol>
   </div>
-</div>
+</main>
+<footer>
+  <span class="no-break">)raw" +
+                         ClangDocVersion + R"raw(</span>
+</footer>
 )raw";
 
   EXPECT_EQ(Expected, Actual.str());
@@ -162,80 +176,89 @@ TEST(HTMLGeneratorTest, emitRecordHTML)
 <title>class r</title>
 <link rel="stylesheet" href="../../../clang-doc-default-stylesheet.css"/>
 <script src="../../../index.js"></script>
-<div id="index" path="X/Y/Z"></div>
-<ul>
-  <li>
-    <span>
-      <a href="#Members">Members</a>
-    </span>
-  </li>
-  <li>
-    <span>
-      <a href="#Records">Records</a>
-    </span>
-  </li>
-  <li>
-    <span>
-      <a href="#Functions">Functions</a>
-    </span>
+<header id="project-title">test-project</header>
+<main>
+  <div id="sidebar-left" path="X/Y/Z" class="col-xs-6 col-sm-3 col-md-2 sidebar sidebar-offcanvas-left"></div>
+  <div id="main-content" class="col-xs-12 col-sm-9 col-md-8 main-content">
+    <h1>class r</h1>
+    <p>
+      Defined at line 
+      <a href="http://www.repository.com/dir/test.cpp#10">10</a>
+       of file 
+      <a href="http://www.repository.com/dir/test.cpp">test.cpp</a>
+    </p>
+    <p>
+      Inherits from 
+      <a href="../../../path/to/F.html">F</a>
+      , G
+    </p>
+    <h2 id="Members">Members</h2>
     <ul>
       <li>
-        <span>
-          <a href="#0000000000000000000000000000000000000000">OneFunction</a>
-        </span>
+        private 
+        <a href="../int.html">int</a>
+         X
       </li>
     </ul>
-  </li>
-  <li>
-    <span>
-      <a href="#Enums">Enums</a>
-    </span>
+    <h2 id="Records">Records</h2>
     <ul>
       <li>
-        <span>
-          <a href="#0000000000000000000000000000000000000000">OneEnum</a>
-        </span>
+        <a href="r/ChildStruct.html">ChildStruct</a>
       </li>
     </ul>
-  </li>
-</ul>
-<div>
-  <h1>class r</h1>
-  <p>
-    Defined at line 
-    <a href="http://www.repository.com/dir/test.cpp#10">10</a>
-     of file 
-    <a href="http://www.repository.com/dir/test.cpp">test.cpp</a>
-  </p>
-  <p>
-    Inherits from 
-    <a href="../../../path/to/F.html">F</a>
-    , G
-  </p>
-  <h2 id="Members">Members</h2>
-  <ul>
-    <li>
-      private 
-      <a href="../int.html">int</a>
-       X
-    </li>
-  </ul>
-  <h2 id="Records">Records</h2>
-  <ul>
-    <li>
-      <a href="r/ChildStruct.html">ChildStruct</a>
-    </li>
-  </ul>
-  <h2 id="Functions">Functions</h2>
-  <div>
-    <h3 id="0000000000000000000000000000000000000000">OneFunction</h3>
-    <p>public OneFunction()</p>
+    <h2 id="Functions">Functions</h2>
+    <div>
+      <h3 id="0000000000000000000000000000000000000000">OneFunction</h3>
+      <p>public OneFunction()</p>
+    </div>
+    <h2 id="Enums">Enums</h2>
+    <div>
+      <h3 id="0000000000000000000000000000000000000000">enum OneEnum</h3>
+    </div>
   </div>
-  <h2 id="Enums">Enums</h2>
-  <div>
-    <h3 id="0000000000000000000000000000000000000000">enum OneEnum</h3>
+  <div id="sidebar-right" class="col-xs-6 col-sm-6 col-md-2 sidebar sidebar-offcanvas-right">
+    <ol>
+      <li>
+        <span>
+          <a href="#Members">Members</a>
+        </span>
+      </li>
+      <li>
+        <span>
+          <a href="#Records">Records</a>
+        </span>
+      </li>
+      <li>
+        <span>
+          <a href="#Functions">Functions</a>
+        </span>
+        <ul>
+          <li>
+            <span>
+              <a href="#0000000000000000000000000000000000000000">OneFunction</a>
+            </span>
+          </li>
+        </ul>
+      </li>
+      <li>
+        <span>
+          <a href="#Enums">Enums</a>
+        </span>
+        <ul>
+          <li>
+            <span>
+              <a href="#0000000000000000000000000000000000000000">OneEnum</a>
+            </span>
+          </li>
+        </ul>
+      </li>
+    </ol>
   </div>
-</div>
+</main>
+<footer>
+  <span class="no-break">)raw" +
+                         ClangDocVersion + R"raw(</span>
+</footer>
 )raw";
 
   EXPECT_EQ(Expected, Actual.str());
@@ -270,17 +293,25 @@ TEST(HTMLGeneratorTest, emitFunctionHTML
 <title></title>
 <link rel="stylesheet" href="clang-doc-default-stylesheet.css"/>
 <script src="index.js"></script>
-<div id="index" path=""></div>
-<div>
-  <h3 id="0000000000000000000000000000000000000000">f</h3>
-  <p>
-    <a href="path/to/float.html">float</a>
-     f(
-    <a href="path/to/int.html">int</a>
-     P)
-  </p>
-  <p>Defined at line 10 of file dir/test.cpp</p>
-</div>
+<header id="project-title">test-project</header>
+<main>
+  <div id="sidebar-left" path="" class="col-xs-6 col-sm-3 col-md-2 sidebar sidebar-offcanvas-left"></div>
+  <div id="main-content" class="col-xs-12 col-sm-9 col-md-8 main-content">
+    <h3 id="0000000000000000000000000000000000000000">f</h3>
+    <p>
+      <a href="path/to/float.html">float</a>
+       f(
+      <a href="path/to/int.html">int</a>
+       P)
+    </p>
+    <p>Defined at line 10 of file dir/test.cpp</p>
+  </div>
+  <div id="sidebar-right" class="col-xs-6 col-sm-6 col-md-2 sidebar sidebar-offcanvas-right"></div>
+</main>
+<footer>
+  <span class="no-break">)raw" +
+                         ClangDocVersion + R"raw(</span>
+</footer>
 )raw";
 
   EXPECT_EQ(Expected, Actual.str());
@@ -309,19 +340,27 @@ TEST(HTMLGeneratorTest, emitEnumHTML) {
 <title></title>
 <link rel="stylesheet" href="clang-doc-default-stylesheet.css"/>
 <script src="index.js"></script>
-<div id="index" path=""></div>
-<div>
-  <h3 id="0000000000000000000000000000000000000000">enum class e</h3>
-  <ul>
-    <li>X</li>
-  </ul>
-  <p>
-    Defined at line 
-    <a href="https://www.repository.com/test.cpp#10">10</a>
-     of file 
-    <a href="https://www.repository.com/test.cpp">test.cpp</a>
-  </p>
-</div>
+<header id="project-title">test-project</header>
+<main>
+  <div id="sidebar-left" path="" class="col-xs-6 col-sm-3 col-md-2 sidebar sidebar-offcanvas-left"></div>
+  <div id="main-content" class="col-xs-12 col-sm-9 col-md-8 main-content">
+    <h3 id="0000000000000000000000000000000000000000">enum class e</h3>
+    <ul>
+      <li>X</li>
+    </ul>
+    <p>
+      Defined at line 
+      <a href="https://www.repository.com/test.cpp#10">10</a>
+       of file 
+      <a href="https://www.repository.com/test.cpp">test.cpp</a>
+    </p>
+  </div>
+  <div id="sidebar-right" class="col-xs-6 col-sm-6 col-md-2 sidebar sidebar-offcanvas-right"></div>
+</main>
+<footer>
+  <span class="no-break">)raw" +
+                         ClangDocVersion + R"raw(</span>
+</footer>
 )raw";
 
   EXPECT_EQ(Expected, Actual.str());
@@ -386,19 +425,27 @@ TEST(HTMLGeneratorTest, emitCommentHTML)
 <title></title>
 <link rel="stylesheet" href="clang-doc-default-stylesheet.css"/>
 <script src="index.js"></script>
-<div id="index" path=""></div>
-<div>
-  <h3 id="0000000000000000000000000000000000000000">f</h3>
-  <p>void f(int I, int J)</p>
-  <p>Defined at line 10 of file test.cpp</p>
-  <div>
+<header id="project-title">test-project</header>
+<main>
+  <div id="sidebar-left" path="" class="col-xs-6 col-sm-3 col-md-2 sidebar sidebar-offcanvas-left"></div>
+  <div id="main-content" class="col-xs-12 col-sm-9 col-md-8 main-content">
+    <h3 id="0000000000000000000000000000000000000000">f</h3>
+    <p>void f(int I, int J)</p>
+    <p>Defined at line 10 of file test.cpp</p>
     <div>
-      <p> Brief description.</p>
-      <p> Extended description that continues onto the next line.</p>
-      <p> Comment with html entities: &, <, >, ", '.</p>
+      <div>
+        <p> Brief description.</p>
+        <p> Extended description that continues onto the next line.</p>
+        <p> Comment with html entities: &, <, >, ", '.</p>
+      </div>
     </div>
   </div>
-</div>
+  <div id="sidebar-right" class="col-xs-6 col-sm-6 col-md-2 sidebar sidebar-offcanvas-right"></div>
+</main>
+<footer>
+  <span class="no-break">)raw" +
+                         ClangDocVersion + R"raw(</span>
+</footer>
 )raw";
 
   EXPECT_EQ(Expected, Actual.str());




More information about the cfe-commits mailing list