diff --git a/autotests/export/docbook/index.lyx b/autotests/export/docbook/index.lyx index 875e6336e4..4c03f989e0 100644 --- a/autotests/export/docbook/index.lyx +++ b/autotests/export/docbook/index.lyx @@ -1,5 +1,5 @@ #LyX 2.4 created this file. For more info see https://www.lyx.org/ -\lyxformat 608 +\lyxformat 609 \begin_document \begin_header \save_transient_properties true @@ -89,9 +89,36 @@ Index tests \end_layout +\begin_layout Standard +\begin_inset Index idx +range none +pageformat default +status open + +\begin_layout Plain Layout +Primary +\begin_inset IndexMacro subindex +status open + +\begin_layout Plain Layout +Secondary +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + \begin_layout Standard Text \begin_inset Index idx +range none +pageformat default status open \begin_layout Plain Layout @@ -102,6 +129,8 @@ Text \begin_inset Index idx +range none +pageformat default status open \begin_layout Plain Layout @@ -112,6 +141,8 @@ SortedAs@Text \begin_inset Index idx +range none +pageformat default status open \begin_layout Plain Layout @@ -122,6 +153,8 @@ Primary!Secondary \begin_inset Index idx +range none +pageformat default status open \begin_layout Plain Layout @@ -132,6 +165,8 @@ SortedPrimary@Primary!Secondary \begin_inset Index idx +range none +pageformat default status open \begin_layout Plain Layout @@ -143,5 +178,127 @@ Primary!Secondary!Tertiary . \end_layout +\begin_layout Standard +Text +\begin_inset Index idx +range none +pageformat default +status open + +\begin_layout Plain Layout +Text +\end_layout + +\end_inset + + +\begin_inset Index idx +range none +pageformat default +status open + +\begin_layout Plain Layout +\begin_inset IndexMacro sortkey +status open + +\begin_layout Plain Layout +SortedAs +\end_layout + +\end_inset + +Text +\end_layout + +\end_inset + + +\begin_inset Index idx +range none +pageformat default +status open + +\begin_layout Plain Layout +Primary +\begin_inset IndexMacro subindex +status open + +\begin_layout Plain Layout +Secondary +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +range none +pageformat default +status open + +\begin_layout Plain Layout +\begin_inset IndexMacro sortkey +status open + +\begin_layout Plain Layout +SortedPrimary +\end_layout + +\end_inset + +Primary +\begin_inset IndexMacro subindex +status open + +\begin_layout Plain Layout +Secondary +\end_layout + +\end_inset + + +\end_layout + +\end_inset + + +\begin_inset Index idx +range none +pageformat default +status open + +\begin_layout Plain Layout +Primary +\begin_inset IndexMacro subindex +status open + +\begin_layout Plain Layout +Secondary +\end_layout + +\end_inset + + +\begin_inset IndexMacro subindex +status open + +\begin_layout Plain Layout +Tertiary +\end_layout + +\end_inset + + +\end_layout + +\end_inset + +. +\end_layout + \end_body \end_document diff --git a/autotests/export/docbook/index.xml b/autotests/export/docbook/index.xml index 21e73c597f..d80aa38a09 100644 --- a/autotests/export/docbook/index.xml +++ b/autotests/export/docbook/index.xml @@ -3,5 +3,7 @@ See https://www.lyx.org/ for more information -->
Index tests +PrimarySecondary +TextTextTextPrimarySecondaryPrimarySecondaryPrimarySecondaryTertiary. TextTextTextPrimarySecondaryPrimarySecondaryPrimarySecondaryTertiary.
\ No newline at end of file diff --git a/src/insets/InsetIndex.cpp b/src/insets/InsetIndex.cpp index 8b69b6f328..aa49362c50 100644 --- a/src/insets/InsetIndex.cpp +++ b/src/insets/InsetIndex.cpp @@ -307,6 +307,11 @@ void InsetIndex::processLatexSorting(otexstream & os, OutputParams const & runpa void InsetIndex::docbook(XMLStream & xs, OutputParams const & runparams) const { + // Two ways of processing this inset are implemented: + // - the legacy one, based on parsing the raw LaTeX (before LyX 2.4) -- unlikely to be deprecated + // - the modern one, based on precise insets for indexing features + // Like the LaTeX implementation, consider the user chooses either of those options. + // Get the content of the inset as LaTeX, as some things may be encoded as ERT (like {}). // TODO: if there is an ERT within the index term, its conversion should be tried, in case it becomes useful; // otherwise, ERTs should become comments. For now, they are just copied as-is, which is barely satisfactory. @@ -334,24 +339,42 @@ void InsetIndex::docbook(XMLStream & xs, OutputParams const & runparams) const docstring indexTerms = latexString.substr(0, positionVerticalBar); docstring command; if (positionVerticalBar != lyx::docstring::npos) { - command = latexString.substr(positionVerticalBar + 1); + command = latexString.substr(positionVerticalBar + 1); } // Handle sorting issues, with @. - vector sortingElements = getVectorFromString(indexTerms, from_ascii("@"), false); docstring sortAs; - if (sortingElements.size() == 2) { - sortAs = sortingElements[0]; - indexTerms = sortingElements[1]; + if (hasSortKey()) { + sortAs = getSortkeyAsText(runparams); + // indexTerms may contain a sort key if the user has both the inset and the manual key. + } else { + vector sortingElements = getVectorFromString(indexTerms, from_ascii("@"), false); + if (sortingElements.size() == 2) { + sortAs = sortingElements[0]; + indexTerms = sortingElements[1]; + } } // Handle primary, secondary, and tertiary terms (entries, subentries, and subsubentries, for LaTeX). - vector terms = getVectorFromString(indexTerms, from_ascii("!"), false); + vector terms; + if (const vector potential_terms = getSubentriesAsText(runparams); !potential_terms.empty()) { + terms = potential_terms; + // The main term is not present in the vector, as it's not a subentry. The main index term is inserted raw in + // the index inset. Considering that the user either uses the new or the legacy mechanism, the main term is the + // full string within this inset (i.e. without the subinsets). + terms.insert(terms.begin(), latexString); + } else { + terms = getVectorFromString(indexTerms, from_ascii("!"), false); + } - // Handle ranges. Happily, (| and |) can only be at the end of the string! - bool hasStartRange = latexString.find(from_ascii("|(")) != lyx::docstring::npos; - bool hasEndRange = latexString.find(from_ascii("|)")) != lyx::docstring::npos; - if (hasStartRange || hasEndRange) { + // Handle ranges. Happily, in the raw LaTeX mode, (| and |) can only be at the end of the string! + bool hasInsetRange = params_.range != InsetIndexParams::PageRange::None; + bool hasStartRange = params_.range == InsetIndexParams::PageRange::Start || + latexString.find(from_ascii("|(")) != lyx::docstring::npos; + bool hasEndRange = params_.range == InsetIndexParams::PageRange::End || + latexString.find(from_ascii("|)")) != lyx::docstring::npos; + + if (hasInsetRange) { // Remove the ranges from the command if they do not appear at the beginning. size_t index = 0; while ((index = command.find(from_utf8("|("), index)) != std::string::npos) @@ -367,9 +390,10 @@ void InsetIndex::docbook(XMLStream & xs, OutputParams const & runparams) const // Handle see and seealso. As "see" is a prefix of "seealso", the order of the comparisons is important. // Both commands are mutually exclusive! - docstring see = from_utf8(""); - vector seeAlsoes; - if (command.substr(0, 3) == "see") { + docstring see = getSeeAsText(runparams); + vector seeAlsoes = getSeeAlsoesAsText(runparams); + + if (see.empty() && seeAlsoes.empty() && command.substr(0, 3) == "see") { // Unescape brackets. size_t index = 0; while ((index = command.find(from_utf8("\\{"), index)) != std::string::npos) @@ -615,6 +639,24 @@ void InsetIndex::getSortkey(otexstream & os, OutputParams const & runparams) con } +docstring InsetIndex::getSortkeyAsText(OutputParams const & runparams) const +{ + Paragraph const & par = paragraphs().front(); + InsetList::const_iterator it = par.insetList().begin(); + for (; it != par.insetList().end(); ++it) { + Inset & inset = *it->inset; + if (inset.lyxCode() == INDEXMACRO_SORTKEY_CODE) { + otexstringstream os; + InsetIndexMacro const & iim = + static_cast(inset); + iim.getLatex(os, runparams); + return os.str(); + } + } + return from_ascii(""); +} + + void InsetIndex::getSubentries(otexstream & os, OutputParams const & runparams) const { Paragraph const & par = paragraphs().front(); @@ -637,6 +679,34 @@ void InsetIndex::getSubentries(otexstream & os, OutputParams const & runparams) } +std::vector InsetIndex::getSubentriesAsText(OutputParams const & runparams) const +{ + std::vector subentries; + + Paragraph const & par = paragraphs().front(); + InsetList::const_iterator it = par.insetList().begin(); + int i = 0; + for (; it != par.insetList().end(); ++it) { + Inset & inset = *it->inset; + if (inset.lyxCode() == INDEXMACRO_CODE) { + InsetIndexMacro const & iim = + static_cast(inset); + if (iim.params().type == InsetIndexMacroParams::Subindex) { + ++i; + if (i > 2) + break; + + otexstringstream os; + iim.getLatex(os, runparams); + subentries.emplace_back(os.str()); + } + } + } + + return subentries; +} + + void InsetIndex::getSeeRefs(otexstream & os, OutputParams const & runparams) const { Paragraph const & par = paragraphs().front(); @@ -656,6 +726,49 @@ void InsetIndex::getSeeRefs(otexstream & os, OutputParams const & runparams) con } +docstring InsetIndex::getSeeAsText(OutputParams const & runparams) const +{ + Paragraph const & par = paragraphs().front(); + InsetList::const_iterator it = par.insetList().begin(); + for (; it != par.insetList().end(); ++it) { + Inset & inset = *it->inset; + if (inset.lyxCode() == INDEXMACRO_CODE) { + InsetIndexMacro const & iim = + static_cast(inset); + if (iim.params().type == InsetIndexMacroParams::See) { + otexstringstream os; + iim.getLatex(os, runparams); + return os.str(); + } + } + } + return from_ascii(""); +} + + +std::vector InsetIndex::getSeeAlsoesAsText(OutputParams const & runparams) const +{ + std::vector seeAlsoes; + + Paragraph const & par = paragraphs().front(); + InsetList::const_iterator it = par.insetList().begin(); + for (; it != par.insetList().end(); ++it) { + Inset & inset = *it->inset; + if (inset.lyxCode() == INDEXMACRO_CODE) { + InsetIndexMacro const & iim = + static_cast(inset); + if (iim.params().type == InsetIndexMacroParams::Seealso) { + otexstringstream os; + iim.getLatex(os, runparams); + seeAlsoes.emplace_back(os.str()); + } + } + } + + return seeAlsoes; +} + + bool InsetIndex::hasSeeRef() const { Paragraph const & par = paragraphs().front(); diff --git a/src/insets/InsetIndex.h b/src/insets/InsetIndex.h index 97a82babf5..3a22b3b772 100644 --- a/src/insets/InsetIndex.h +++ b/src/insets/InsetIndex.h @@ -94,10 +94,18 @@ private: /// void getSortkey(otexstream &, OutputParams const &) const; /// + docstring getSortkeyAsText(OutputParams const &) const; + /// void getSubentries(otexstream &, OutputParams const &) const; /// + std::vector getSubentriesAsText(OutputParams const &) const; + /// void getSeeRefs(otexstream &, OutputParams const &) const; /// + docstring getSeeAsText(OutputParams const & runparams) const; + /// + std::vector getSeeAlsoesAsText(OutputParams const & runparams) const; + /// bool hasSeeRef() const; /// bool hasSortKey() const;