docbook: Factor out code to write valid DocBook IDs
Attributes in XML may contain alphanumeric characters, underscores, colons and dots. When DocBook is chunked, the dot is often used as a path separator. To generate a valid ID, we take the title of the section, transform all non-alphanumeric characters to underscores and then add a prefix separated with dots. We also add the document name as a prefix, in order to 'xinclude' eg. cmake.docbook and ctest.docbook in the same document. IDs are written in multiple places, so the code is factored to a function.
This commit is contained in:
parent
cffa899a47
commit
dbfe335099
|
@ -11,6 +11,8 @@
|
||||||
============================================================================*/
|
============================================================================*/
|
||||||
#include "cmDocumentationFormatterDocbook.h"
|
#include "cmDocumentationFormatterDocbook.h"
|
||||||
#include "cmDocumentationSection.h"
|
#include "cmDocumentationSection.h"
|
||||||
|
#include <algorithm>
|
||||||
|
#include <ctype.h> // for isalnum
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
// this function is a copy of the one in the HTML formatter
|
// this function is a copy of the one in the HTML formatter
|
||||||
|
@ -107,21 +109,9 @@ void cmDocumentationFormatterDocbook
|
||||||
{
|
{
|
||||||
if(name)
|
if(name)
|
||||||
{
|
{
|
||||||
std::string id = "section_";
|
os << "<sect1 id=\"";
|
||||||
id += name;
|
this->PrintId(os, 0, name);
|
||||||
if (this->EmittedLinkIds.find(id) == this->EmittedLinkIds.end())
|
os << "\">\n<title>" << name << "</title>\n";
|
||||||
{
|
|
||||||
this->EmittedLinkIds.insert(id);
|
|
||||||
os << "<sect1 id=\"section_" << name << "\">\n"
|
|
||||||
"<title>\n" << name << "</title>\n";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
static unsigned int i=0;
|
|
||||||
i++;
|
|
||||||
os << "<sect1 id=\"section_" << name << i << "\">\n"
|
|
||||||
"<title>\n" << name << "</title>\n";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string prefix = this->ComputeSectionLinkPrefix(name);
|
std::string prefix = this->ComputeSectionLinkPrefix(name);
|
||||||
|
@ -138,28 +128,8 @@ void cmDocumentationFormatterDocbook
|
||||||
{
|
{
|
||||||
if(op->Name.size())
|
if(op->Name.size())
|
||||||
{
|
{
|
||||||
os << " <para id=\"" << prefix << "_";
|
os << " <para id=\"";
|
||||||
cmDocumentationPrintDocbookEscapes(os, op->Name.c_str());
|
this->PrintId(os, prefix.c_str(), op->Name);
|
||||||
|
|
||||||
// make sure that each id exists only once. Since it seems
|
|
||||||
// not easily possible to determine which link refers to which id,
|
|
||||||
// we have at least to make sure that the duplicated id's get a
|
|
||||||
// different name (by appending an increasing number), Alex
|
|
||||||
std::string id = prefix;
|
|
||||||
id += "_";
|
|
||||||
id += op->Name;
|
|
||||||
if (this->EmittedLinkIds.find(id) == this->EmittedLinkIds.end())
|
|
||||||
{
|
|
||||||
this->EmittedLinkIds.insert(id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
static unsigned int i=0;
|
|
||||||
i++;
|
|
||||||
os << i;
|
|
||||||
}
|
|
||||||
// continue as normal...
|
|
||||||
|
|
||||||
os << "\"><sect2><title>";
|
os << "\"><sect2><title>";
|
||||||
cmDocumentationPrintDocbookEscapes(os, op->Name.c_str());
|
cmDocumentationPrintDocbookEscapes(os, op->Name.c_str());
|
||||||
os << "</title></sect2> ";
|
os << "</title></sect2> ";
|
||||||
|
@ -213,6 +183,8 @@ void cmDocumentationFormatterDocbook::PrintHeader(const char* docname,
|
||||||
const char* appname,
|
const char* appname,
|
||||||
std::ostream& os)
|
std::ostream& os)
|
||||||
{
|
{
|
||||||
|
this->docname = docname;
|
||||||
|
|
||||||
// this one is used to ensure that we don't create multiple link targets
|
// 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
|
// with the same name. We can clear it here since we are at the
|
||||||
// start of a document here.
|
// start of a document here.
|
||||||
|
@ -235,3 +207,28 @@ void cmDocumentationFormatterDocbook::PrintFooter(std::ostream& os)
|
||||||
os << "</article>\n";
|
os << "</article>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmDocumentationFormatterDocbook
|
||||||
|
::PrintId(std::ostream& os, const char* prefix, std::string id)
|
||||||
|
{
|
||||||
|
std::replace_if(id.begin(), id.end(), std::not1(std::ptr_fun(isalnum)), '_');
|
||||||
|
if(prefix)
|
||||||
|
{
|
||||||
|
id = std::string(prefix) + "." + id;
|
||||||
|
}
|
||||||
|
os << this->docname << '.' << id;
|
||||||
|
|
||||||
|
// make sure that each id exists only once. Since it seems
|
||||||
|
// not easily possible to determine which link refers to which id,
|
||||||
|
// we have at least to make sure that the duplicated id's get a
|
||||||
|
// different name (by appending an increasing number), Alex
|
||||||
|
if (this->EmittedLinkIds.find(id) == this->EmittedLinkIds.end())
|
||||||
|
{
|
||||||
|
this->EmittedLinkIds.insert(id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
static unsigned int i=0;
|
||||||
|
os << i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -35,7 +35,9 @@ public:
|
||||||
virtual void PrintPreformatted(std::ostream& os, const char* text);
|
virtual void PrintPreformatted(std::ostream& os, const char* text);
|
||||||
virtual void PrintParagraph(std::ostream& os, const char* text);
|
virtual void PrintParagraph(std::ostream& os, const char* text);
|
||||||
private:
|
private:
|
||||||
|
void PrintId(std::ostream& os, const char* prefix, std::string id);
|
||||||
std::set<std::string> EmittedLinkIds;
|
std::set<std::string> EmittedLinkIds;
|
||||||
|
std::string docname;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue