Browse Source

ENH: Improve generated documentation formatting

Applying patch provided in issue #7797.

Fixes to man-pages:
  - Character '-' must be espaced as '\-'
  - Surround preformatted text with '.nf' and '.fi' to adjust filling
  - Give every page a NAME section for indexing by mandb
  - Pass the man page filename without extension to .TH in its header

Also added a title to the HTML header.
Brad King 17 years ago
parent
commit
5a82a0b108

+ 113 - 10
Source/cmDocumentation.cxx

@@ -201,6 +201,26 @@ static const char *cmDocumentationCopyright[][3] =
   {0, 0, 0}
 };
 
+//----------------------------------------------------------------------------
+#define DOCUMENT_INTRO(type, default_name, desc) \
+  static char const *cmDocumentation##type##Intro[2] = { default_name, desc };
+#define GET_DOCUMENT_INTRO(type) cmDocumentation##type##Intro
+
+DOCUMENT_INTRO(Modules, "cmakemodules",
+  "Reference of available CMake modules.");
+DOCUMENT_INTRO(CustomModules, "cmakecustommodules",
+  "Reference of available CMake custom modules.");
+DOCUMENT_INTRO(Policies, "cmakepolicies",
+  "Reference of CMake policies.");
+DOCUMENT_INTRO(Properties, "cmakeprops",
+  "Reference of CMake properties.");
+DOCUMENT_INTRO(Variables, "cmakevars",
+  "Reference of CMake variables.");
+DOCUMENT_INTRO(Commands, "cmakecommands",
+  "Reference of available CMake commands.");
+DOCUMENT_INTRO(CompatCommands, "cmakecompat",
+  "Reference of CMake compatibility commands.");
+
 //----------------------------------------------------------------------------
 cmDocumentation::cmDocumentation()
 :CurrentFormatter(0)
@@ -321,7 +341,27 @@ void cmDocumentation::ClearSections()
 }
 
 //----------------------------------------------------------------------------
-bool cmDocumentation::PrintDocumentation(Type ht, std::ostream& os)
+void cmDocumentation::AddDocumentIntroToPrint(const char* intro[2])
+{
+  const char* docname;
+  if (intro && (docname = this->GetDocName(false)))
+    {
+    cmDocumentationSection* section;
+    std::string desc("");
+
+    desc += docname;
+    desc += " - ";
+    desc += intro[1];
+
+    section = new cmDocumentationSection("Introduction", "NAME");
+    section->Append(0, desc.c_str(), 0);
+    this->PrintSections.push_back(section);
+    }
+}
+
+//----------------------------------------------------------------------------
+bool cmDocumentation::PrintDocumentation(Type ht, std::ostream& os,
+                                         const char* docname)
 {
   if ((this->CurrentFormatter->GetForm() != HTMLForm) 
        && (this->CurrentFormatter->GetForm() != DocbookForm)
@@ -330,6 +370,16 @@ bool cmDocumentation::PrintDocumentation(Type ht, std::ostream& os)
     this->PrintVersion(os);
     }
 
+  // Handle Document Name. docname==0 disables intro.
+  this->SetDocName("");
+  if (docname)
+    {
+    if (*docname)
+      this->SetDocName(docname);
+    else // empty string was given. select default if possible
+      this->SetDocName(this->GetDefaultDocName(ht));
+    }
+
   switch (ht)
     {
     case cmDocumentation::Usage:
@@ -595,6 +645,7 @@ bool cmDocumentation::PrintRequestedDocumentation(std::ostream& os)
     // given stream.
     std::ofstream* fout = 0;
     std::ostream* s = &os;
+    std::string docname("");
     if(i->Filename.length() > 0)
       {
       fout = new std::ofstream(i->Filename.c_str(), std::ios::out);
@@ -606,10 +657,14 @@ bool cmDocumentation::PrintRequestedDocumentation(std::ostream& os)
         {
         result = false;
         }
+      if(i->Filename != "-")
+        {
+        docname = cmSystemTools::GetFilenameWithoutLastExtension(i->Filename);
+        }
       }
     
     // Print this documentation type to the stream.
-    if(!this->PrintDocumentation(i->HelpType, *s) || !*s)
+    if(!this->PrintDocumentation(i->HelpType, *s, docname.c_str()) || !*s)
       {
       result = false;
       }
@@ -869,6 +924,12 @@ void cmDocumentation::SetName(const char* name)
   this->NameString = name?name:"";
 }
 
+//----------------------------------------------------------------------------
+void cmDocumentation::SetDocName(const char *docname)
+{
+  this->DocName = docname?docname:"";
+}
+
 //----------------------------------------------------------------------------
 void cmDocumentation::SetSection(const char *name, 
                                  cmDocumentationSection *section)
@@ -1233,7 +1294,7 @@ bool cmDocumentation::PrintDocumentationUsage(std::ostream& os)
 bool cmDocumentation::PrintDocumentationFull(std::ostream& os)
 {
   this->CreateFullDocumentation();
-  this->CurrentFormatter->PrintHeader(GetNameString(), os);
+  this->CurrentFormatter->PrintHeader(GetNameString(), GetNameString(), os);
   this->Print(os);
   this->CurrentFormatter->PrintFooter(os);
   return true;
@@ -1244,11 +1305,12 @@ bool cmDocumentation::PrintDocumentationModules(std::ostream& os)
 {
   this->ClearSections();
   this->CreateModulesSection();
+  this->AddDocumentIntroToPrint(GET_DOCUMENT_INTRO(Modules));
   this->AddSectionToPrint("Description");
   this->AddSectionToPrint("Modules");
   this->AddSectionToPrint("Copyright");
   this->AddSectionToPrint("See Also");
-  this->CurrentFormatter->PrintHeader(this->GetNameString(), os);
+  this->CurrentFormatter->PrintHeader(GetDocName(), GetNameString(), os);
   this->Print(os);
   this->CurrentFormatter->PrintFooter(os);
   return true;
@@ -1259,13 +1321,14 @@ bool cmDocumentation::PrintDocumentationCustomModules(std::ostream& os)
 {
   this->ClearSections();
   this->CreateCustomModulesSection();
+  this->AddDocumentIntroToPrint(GET_DOCUMENT_INTRO(CustomModules));
   this->AddSectionToPrint("Description");
   this->AddSectionToPrint("Custom CMake Modules");
 // the custom modules are most probably not under Kitware's copyright, Alex
 //  this->AddSectionToPrint("Copyright");
   this->AddSectionToPrint("See Also");
 
-  this->CurrentFormatter->PrintHeader(this->GetNameString(), os);
+  this->CurrentFormatter->PrintHeader(GetDocName(), GetNameString(), os);
   this->Print(os);
   this->CurrentFormatter->PrintFooter(os);
   return true;
@@ -1275,12 +1338,13 @@ bool cmDocumentation::PrintDocumentationCustomModules(std::ostream& os)
 bool cmDocumentation::PrintDocumentationPolicies(std::ostream& os)
 {
   this->ClearSections();
+  this->AddDocumentIntroToPrint(GET_DOCUMENT_INTRO(Policies));
   this->AddSectionToPrint("Description");
   this->AddSectionToPrint("Policies");
   this->AddSectionToPrint("Copyright");
   this->AddSectionToPrint("See Also");
 
-  this->CurrentFormatter->PrintHeader(this->GetNameString(), os);
+  this->CurrentFormatter->PrintHeader(GetDocName(), GetNameString(), os);
   this->Print(os);
   this->CurrentFormatter->PrintFooter(os);
   return true;
@@ -1290,6 +1354,7 @@ bool cmDocumentation::PrintDocumentationPolicies(std::ostream& os)
 bool cmDocumentation::PrintDocumentationProperties(std::ostream& os)
 {
   this->ClearSections();
+  this->AddDocumentIntroToPrint(GET_DOCUMENT_INTRO(Properties));
   this->AddSectionToPrint("Properties Description");
   for (std::vector<std::string>::iterator i = 
          this->PropertySections.begin();
@@ -1299,7 +1364,7 @@ bool cmDocumentation::PrintDocumentationProperties(std::ostream& os)
     }
   this->AddSectionToPrint("Copyright");
   this->AddSectionToPrint("Standard See Also");
-  this->CurrentFormatter->PrintHeader(this->GetNameString(), os);
+  this->CurrentFormatter->PrintHeader(GetDocName(), GetNameString(), os);
   this->Print(os);
   this->CurrentFormatter->PrintFooter(os);
   return true;
@@ -1309,6 +1374,7 @@ bool cmDocumentation::PrintDocumentationProperties(std::ostream& os)
 bool cmDocumentation::PrintDocumentationVariables(std::ostream& os)
 {
   this->ClearSections();
+  this->AddDocumentIntroToPrint(GET_DOCUMENT_INTRO(Variables));
   for (std::vector<std::string>::iterator i = 
          this->VariableSections.begin();
        i != this->VariableSections.end(); ++i)
@@ -1317,7 +1383,7 @@ bool cmDocumentation::PrintDocumentationVariables(std::ostream& os)
     }
   this->AddSectionToPrint("Copyright");
   this->AddSectionToPrint("Standard See Also");
-  this->CurrentFormatter->PrintHeader(this->GetNameString(), os);
+  this->CurrentFormatter->PrintHeader(GetDocName(), GetNameString(), os);
   this->Print(os);
   this->CurrentFormatter->PrintFooter(os);
   return true;
@@ -1327,10 +1393,11 @@ bool cmDocumentation::PrintDocumentationVariables(std::ostream& os)
 bool cmDocumentation::PrintDocumentationCurrentCommands(std::ostream& os)
 {
   this->ClearSections();
+  this->AddDocumentIntroToPrint(GET_DOCUMENT_INTRO(Commands));
   this->AddSectionToPrint("Commands");
   this->AddSectionToPrint("Copyright");
   this->AddSectionToPrint("Standard See Also");
-  this->CurrentFormatter->PrintHeader(this->GetNameString(), os);
+  this->CurrentFormatter->PrintHeader(GetDocName(), GetNameString(), os);
   this->Print(os);
   this->CurrentFormatter->PrintFooter(os);
   return true;
@@ -1340,11 +1407,12 @@ bool cmDocumentation::PrintDocumentationCurrentCommands(std::ostream& os)
 bool cmDocumentation::PrintDocumentationCompatCommands(std::ostream& os)
 {
   this->ClearSections();
+  this->AddDocumentIntroToPrint(GET_DOCUMENT_INTRO(CompatCommands));
   this->AddSectionToPrint("Compatibility Commands Description");
   this->AddSectionToPrint("Compatibility Commands");
   this->AddSectionToPrint("Copyright");
   this->AddSectionToPrint("Standard See Also");
-  this->CurrentFormatter->PrintHeader(GetNameString(), os);
+  this->CurrentFormatter->PrintHeader(GetDocName(), GetNameString(), os);
   this->Print(os);
   this->CurrentFormatter->PrintFooter(os);
   return true;
@@ -1465,6 +1533,41 @@ const char* cmDocumentation::GetNameString() const
     }
 }
 
+//----------------------------------------------------------------------------
+const char* cmDocumentation::GetDocName(bool fallbackToNameString) const
+{
+  if (this->DocName.length() > 0)
+    {
+    return this->DocName.c_str();
+    }
+  else if (fallbackToNameString)
+    {
+    return this->GetNameString();
+    }
+  else
+    return 0;
+}
+
+//----------------------------------------------------------------------------
+#define CASE_DEFAULT_DOCNAME(doctype) \
+  case cmDocumentation::doctype : \
+    return GET_DOCUMENT_INTRO(doctype)[0];
+const char* cmDocumentation::GetDefaultDocName(Type ht) const
+{
+  switch (ht)
+    {
+    CASE_DEFAULT_DOCNAME(Modules)
+    CASE_DEFAULT_DOCNAME(CustomModules)
+    CASE_DEFAULT_DOCNAME(Policies)
+    CASE_DEFAULT_DOCNAME(Properties)
+    CASE_DEFAULT_DOCNAME(Variables)
+    CASE_DEFAULT_DOCNAME(Commands)
+    CASE_DEFAULT_DOCNAME(CompatCommands)
+    default: break;
+    }
+  return 0;
+}
+
 //----------------------------------------------------------------------------
 bool cmDocumentation::IsOption(const char* arg) const
 {

+ 7 - 1
Source/cmDocumentation.h

@@ -61,7 +61,7 @@ public:
   bool PrintRequestedDocumentation(std::ostream& os);
   
   /** Print help of the given type.  */
-  bool PrintDocumentation(Type ht, std::ostream& os);
+  bool PrintDocumentation(Type ht, std::ostream& os, const char* docname=0);
   
   /** Set the program name for standard document generation.  */
   void SetName(const char* name);
@@ -124,6 +124,7 @@ public:
 
 private:
   void SetForm(Form f);
+  void SetDocName(const char* docname);
 
   bool CreateSingleModule(const char* fname, 
                           const char* moduleName,
@@ -134,6 +135,8 @@ private:
   bool CreateCustomModulesSection();
   void CreateFullDocumentation();
 
+  void AddDocumentIntroToPrint(const char* intro[2]);
+
   bool PrintCopyright(std::ostream& os);
   bool PrintVersion(std::ostream& os);
   bool PrintDocumentationGeneric(std::ostream& os, const char *section);
@@ -157,9 +160,12 @@ private:
 
 
   const char* GetNameString() const;
+  const char* GetDocName(bool fallbackToNameString = true) const;
+  const char* GetDefaultDocName(Type ht) const;
   bool IsOption(const char* arg) const;
 
   std::string NameString;
+  std::string DocName;
   std::map<std::string,cmDocumentationSection*> AllSections;
   
   std::string SeeAlsoString;

+ 2 - 1
Source/cmDocumentationFormatter.cxx

@@ -118,7 +118,8 @@ cmDocumentationFormatter::ComputeSectionLinkPrefix(std::string const& name)
     {
     return "module";
     }
-  else if(name.find("Name") != name.npos)
+  else if(name.find("Name") != name.npos ||
+          name.find("Introduction") != name.npos)
     {
     return "name";
     }

+ 3 - 1
Source/cmDocumentationFormatter.h

@@ -52,7 +52,9 @@ public:
 
   virtual cmDocumentationEnums::Form GetForm() const = 0;
   
-  virtual void PrintHeader(const char* /*name*/, std::ostream& /*os*/) {}
+  virtual void PrintHeader(const char* /*docname*/,
+                           const char* /*appname*/,
+                           std::ostream& /*os*/) {}
   virtual void PrintFooter(std::ostream& /*os*/) {}
   virtual void PrintSection(std::ostream& os,
                     const cmDocumentationSection& section,

+ 4 - 3
Source/cmDocumentationFormatterDocbook.cxx

@@ -229,8 +229,9 @@ void cmDocumentationFormatterDocbook::PrintParagraph(std::ostream& os,
 }
 
 //----------------------------------------------------------------------------
-void cmDocumentationFormatterDocbook::PrintHeader(const char* name, 
-                                               std::ostream& os)
+void cmDocumentationFormatterDocbook::PrintHeader(const char* docname,
+                                                  const char* appname,
+                                                  std::ostream& os)
 {
   // this one is used to ensure that we don't create multiple link targets
   // with the same name. We can clear it here since we are at the 
@@ -244,7 +245,7 @@ void cmDocumentationFormatterDocbook::PrintHeader(const char* name,
         "<!ENTITY % English \"INCLUDE\"> ]>\n"
         "<article>\n"
         "<articleinfo>\n"
-        "<title>" << name << "</title>\n"
+        "<title>" << docname << " - " << appname << "</title>\n"
         "</articleinfo>\n";
 }
 

+ 2 - 1
Source/cmDocumentationFormatterDocbook.h

@@ -31,7 +31,8 @@ public:
   virtual cmDocumentationEnums::Form GetForm() const
                                   { return cmDocumentationEnums::DocbookForm;}
 
-  virtual void PrintHeader(const char* name, std::ostream& os);
+  virtual void PrintHeader(const char* docname, const char* appname,
+                           std::ostream& os);
   virtual void PrintFooter(std::ostream& os);
   virtual void PrintSection(std::ostream& os,
                             const cmDocumentationSection& section,

+ 5 - 2
Source/cmDocumentationFormatterHTML.cxx

@@ -202,10 +202,13 @@ void cmDocumentationFormatterHTML::PrintParagraph(std::ostream& os,
 }
 
 //----------------------------------------------------------------------------
-void cmDocumentationFormatterHTML::PrintHeader(const char* /*name*/, 
+void cmDocumentationFormatterHTML::PrintHeader(const char* docname,
+                                               const char* appname,
                                                std::ostream& os)
 {
-  os << "<html><body>\n";
+  os << "<html><head><title>";
+  os << docname << " - " << appname;
+  os << "</title></head><body>\n";
 }
 
 //----------------------------------------------------------------------------

+ 2 - 1
Source/cmDocumentationFormatterHTML.h

@@ -30,7 +30,8 @@ public:
   virtual cmDocumentationEnums::Form GetForm() const
                                       { return cmDocumentationEnums::HTMLForm;}
 
-  virtual void PrintHeader(const char* name, std::ostream& os);
+  virtual void PrintHeader(const char* docname, const char* appname,
+                           std::ostream& os);
   virtual void PrintFooter(std::ostream& os);
   virtual void PrintSection(std::ostream& os,
                     const cmDocumentationSection& section,

+ 20 - 6
Source/cmDocumentationFormatterMan.cxx

@@ -57,30 +57,44 @@ void cmDocumentationFormatterMan
     }
 }
 
+void cmDocumentationFormatterMan::EscapeText(std::string& man_text)
+{
+  cmSystemTools::ReplaceString(man_text, "\\", "\\\\");
+  cmSystemTools::ReplaceString(man_text, "-", "\\-");
+}
+
 void cmDocumentationFormatterMan::PrintPreformatted(std::ostream& os, 
                                                     const char* text)
 {
   std::string man_text = text;
-  cmSystemTools::ReplaceString(man_text, "\\", "\\\\");
-  os << man_text << "\n";
+  this->EscapeText(man_text);
+  os << ".nf\n" << man_text;
+  if (*text && man_text.at(man_text.length()-1) != '\n')
+      os << "\n";
+  os << ".fi\n";
 }
 
 void cmDocumentationFormatterMan::PrintParagraph(std::ostream& os, 
                                                  const char* text)
 {
   std::string man_text = text;
-  cmSystemTools::ReplaceString(man_text, "\\", "\\\\");
+  this->EscapeText(man_text);
   os << man_text << "\n\n";
 }
 
 
 //----------------------------------------------------------------------------
-void cmDocumentationFormatterMan::PrintHeader(const char* name, 
+void cmDocumentationFormatterMan::PrintHeader(const char* docname,
+                                              const char* appname,
                                               std::ostream& os)
 {
-  os << ".TH " << name << " 1 \""
+  std::string s_docname(docname), s_appname(appname);
+
+  this->EscapeText(s_docname);
+  this->EscapeText(s_appname);
+  os << ".TH " << s_docname << " 1 \""
     << cmSystemTools::GetCurrentDateTime("%B %d, %Y").c_str()
-    << "\" \"" << name
+    << "\" \"" << s_appname
     << " " << cmVersion::GetCMakeVersion()
     << "\"\n";
 }

+ 5 - 1
Source/cmDocumentationFormatterMan.h

@@ -30,12 +30,16 @@ public:
   virtual cmDocumentationEnums::Form GetForm() const
                                       { return cmDocumentationEnums::ManForm;}
 
-  virtual void PrintHeader(const char* name, std::ostream& os);
+  virtual void PrintHeader(const char* docname, const char* appname,
+                           std::ostream& os);
   virtual void PrintSection(std::ostream& os,
                     const cmDocumentationSection& section,
                     const char* name);
   virtual void PrintPreformatted(std::ostream& os, const char* text);
   virtual void PrintParagraph(std::ostream& os, const char* text);
+
+private:
+  void EscapeText(std::string& man_text);
 };
 
 #endif