DocBook: fix handling of index end-of-range.

This commit is contained in:
Thibaut Cuvelier 2020-08-29 23:41:28 +02:00
parent 78a361778f
commit a8da31e5e0
4 changed files with 57 additions and 47 deletions

View File

@ -205,9 +205,9 @@ I am a second line of code.
<para>Then several terms for the first index: <indexterm type="idx"><primary>Term</primary><secondary>to</secondary><tertiary>index</tertiary></indexterm>. </para>
<para>With a see: <indexterm type="idx"><primary>Term</primary><see>index</see></indexterm>. With a see also: <indexterm type="idx"><primary>Term</primary><seealso>index</seealso></indexterm>. </para>
<para>Several terms with a see: <indexterm type="idx"><primary>Term</primary><secondary>to</secondary><tertiary>index</tertiary><see>index</see></indexterm>. Several terms with a see also: <indexterm type="idx"><primary>Term</primary><secondary>to</secondary><tertiary>index</tertiary><seealso>index</seealso></indexterm>. </para>
<para>A start of range: <indexterm type="idx" class="startofrange" xml:id="Term-to-index"><primary>Term to index</primary></indexterm>. The corresponding end of range: <indexterm type="idx" class="endofrange" startref="Term-to-index"><primary>Term to index</primary></indexterm>.</para>
<para>Several terms with a start of range: <indexterm type="idx" class="startofrange" xml:id="Term.to.index"><primary>Term</primary><secondary>to</secondary><tertiary>index</tertiary></indexterm>. The corresponding end of range: <indexterm type="idx" class="endofrange" startref="Term.to.index"><primary>Term</primary><secondary>to</secondary><tertiary>index</tertiary></indexterm>.</para>
<para>These terms already appeared before! Start of range: <indexterm type="idx" class="startofrange" xml:id="Term.to.index-0"><primary>Term</primary><secondary>to</secondary><tertiary>index</tertiary></indexterm>. The corresponding end of range: <indexterm type="idx" class="endofrange" startref="Term.to.index-0"><primary>Term</primary><secondary>to</secondary><tertiary>index</tertiary></indexterm>.</para>
<para>A start of range: <indexterm type="idx" class="startofrange" xml:id="Term-to-index"><primary>Term to index</primary></indexterm>. The corresponding end of range: <indexterm class="endofrange" startref="Term-to-index" />.</para>
<para>Several terms with a start of range: <indexterm type="idx" class="startofrange" xml:id="Term.to.index"><primary>Term</primary><secondary>to</secondary><tertiary>index</tertiary></indexterm>. The corresponding end of range: <indexterm class="endofrange" startref="Term.to.index" />.</para>
<para>These terms already appeared before! Start of range: <indexterm type="idx" class="startofrange" xml:id="Term.to.index-0"><primary>Term</primary><secondary>to</secondary><tertiary>index</tertiary></indexterm>. The corresponding end of range: <indexterm class="endofrange" startref="Term.to.index-0" />.</para>
</section>
<section>
<title>I am the eight section and I deal with star sections</title>

View File

@ -287,14 +287,17 @@ void InsetIndex::docbook(XMLStream & xs, OutputParams const & runparams) const
// Hence the thread-local storage, as the numbers must strictly be unique, and thus cannot be shared across
// a paragraph (making the solution used for HTML worthless). This solution is very similar to the one used in
// xml::cleanID.
docstring attrs = indexType;
if (hasStartRange || hasEndRange) {
// indexType can only be used for singular and startofrange types!
docstring attrs;
if (!hasStartRange && !hasEndRange) {
attrs = indexType;
} else {
// Append an ID if uniqueness is not guaranteed across the document.
static QThreadStorage<set<docstring>> tKnownTermLists;
static QThreadStorage<int> tID;
set<docstring> & knownTermLists = tKnownTermLists.localData();
int & ID = tID.localData();
set<docstring> &knownTermLists = tKnownTermLists.localData();
int &ID = tID.localData();
if (!tID.hasLocalData()) {
tID.localData() = 0;
@ -319,47 +322,51 @@ void InsetIndex::docbook(XMLStream & xs, OutputParams const & runparams) const
// Generate the attributes.
docstring id = xml::cleanID(newIndexTerms);
if (hasStartRange) {
attrs += " class=\"startofrange\" xml:id=\"" + id + "\"";
attrs = indexType + " class=\"startofrange\" xml:id=\"" + id + "\"";
} else {
attrs += " class=\"endofrange\" startref=\"" + id + "\"";
attrs = " class=\"endofrange\" startref=\"" + id + "\"";
}
}
// Handle the index terms (including the specific index for this entry).
xs << xml::StartTag("indexterm", attrs);
if (terms.size() > 0) { // hasEndRange has no content.
xs << xml::StartTag("primary");
xs << terms[0];
xs << xml::EndTag("primary");
}
if (terms.size() > 1) {
xs << xml::StartTag("secondary");
xs << terms[1];
xs << xml::EndTag("secondary");
}
if (terms.size() > 2) {
xs << xml::StartTag("tertiary");
xs << terms[2];
xs << xml::EndTag("tertiary");
}
// Handle see and see also.
if (!see.empty()) {
xs << xml::StartTag("see");
xs << see;
xs << xml::EndTag("see");
}
if (!seeAlsoes.empty()) {
for (auto & entry : seeAlsoes) {
xs << xml::StartTag("seealso");
xs << entry;
xs << xml::EndTag("seealso");
if (hasEndRange) {
xs << xml::CompTag("indexterm", attrs);
} else {
xs << xml::StartTag("indexterm", attrs);
if (!terms.empty()) { // hasEndRange has no content.
xs << xml::StartTag("primary");
xs << terms[0];
xs << xml::EndTag("primary");
}
if (terms.size() > 1) {
xs << xml::StartTag("secondary");
xs << terms[1];
xs << xml::EndTag("secondary");
}
if (terms.size() > 2) {
xs << xml::StartTag("tertiary");
xs << terms[2];
xs << xml::EndTag("tertiary");
}
}
// Close the entry.
xs << xml::EndTag("indexterm");
// Handle see and see also.
if (!see.empty()) {
xs << xml::StartTag("see");
xs << see;
xs << xml::EndTag("see");
}
if (!seeAlsoes.empty()) {
for (auto &entry : seeAlsoes) {
xs << xml::StartTag("seealso");
xs << entry;
xs << xml::EndTag("seealso");
}
}
// Close the entry.
xs << xml::EndTag("indexterm");
}
}
}

View File

@ -140,11 +140,11 @@ docstring EndTag::writeEndTag() const
docstring CompTag::writeTag() const
{
docstring output = '<' + from_utf8(tag_);
docstring output = '<' + tag_;
if (!attr_.empty()) {
// Erase the beginning of the attributes if it contains space characters: this function deals with that
// automatically.
docstring attributes = escapeString(from_utf8(attr_), XMLStream::ESCAPE_NONE);
docstring attributes = escapeString(attr_, XMLStream::ESCAPE_NONE);
attributes.erase(attributes.begin(), std::find_if(attributes.begin(), attributes.end(),
[](int c) {return !std::isspace(c);}));
if (!attributes.empty()) {

View File

@ -240,16 +240,19 @@ struct CompTag
{
///
explicit CompTag(std::string const & tag)
: tag_(tag) {}
: tag_(from_utf8(tag)) {}
///
explicit CompTag(std::string const & tag, std::string const & attr)
: tag_(tag), attr_(attr) {}
: tag_(from_utf8(tag)), attr_(from_utf8(attr)) {}
///
explicit CompTag(std::string const & tag, docstring const & attr)
: tag_(from_utf8(tag)), attr_(attr) {}
/// <tag_ attr_ />
docstring writeTag() const;
///
std::string tag_;
docstring tag_;
///
std::string attr_;
docstring attr_;
};