[LyX features/features/indexmacros] LyXHTML: implement index ranges

Thibaut Cuvelier tcuvelier at lyx.org
Wed Aug 31 23:34:43 UTC 2022


The branch, features/indexmacros, has been updated.

- Log -----------------------------------------------------------------

commit 92ba7584415cacbea639dbca0199c9fd510ca617
Author: Thibaut Cuvelier <tcuvelier at lyx.org>
Date:   Thu Sep 1 02:22:50 2022 +0200

    LyXHTML: implement index ranges

diff --git a/src/insets/InsetIndex.cpp b/src/insets/InsetIndex.cpp
index d17b059..b4a143e 100644
--- a/src/insets/InsetIndex.cpp
+++ b/src/insets/InsetIndex.cpp
@@ -360,10 +360,10 @@ void InsetIndex::docbook(XMLStream & xs, OutputParams const & runparams) const
 	}
 
 	// 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 ||
+	const bool hasInsetRange = params_.range != InsetIndexParams::PageRange::None;
+	const bool hasStartRange = params_.range == InsetIndexParams::PageRange::Start ||
 			latexString.find(from_ascii("|(")) != lyx::docstring::npos;
-	bool hasEndRange = params_.range == InsetIndexParams::PageRange::End ||
+	const bool hasEndRange = params_.range == InsetIndexParams::PageRange::End ||
 			latexString.find(from_ascii("|)")) != lyx::docstring::npos;
 
 	if (hasInsetRange) {
@@ -1566,7 +1566,7 @@ IndexNode* buildIndexTree(vector<IndexEntry>& entries)
 	return index_root;
 }
 
-void outputIndexPage(XMLStream & xs, const IndexNode* root_node, unsigned depth = 0)
+void outputIndexPage(XMLStream & xs, const IndexNode* root_node, unsigned depth = 0) // NOLINT(misc-no-recursion)
 {
 	LASSERT(root_node->entries.size() + root_node->children.size() > 0, return);
 
@@ -1576,16 +1576,49 @@ void outputIndexPage(XMLStream & xs, const IndexNode* root_node, unsigned depth
 	// By tree assumption, all the entries at this node have the same set of terms.
 
 	if (!root_node->entries.empty()) {
-		xs << XMLStream::ESCAPE_NONE << " — ";
+		xs << XMLStream::ESCAPE_NONE << " — "; // Em dash, i.e. long (---).
 		unsigned entry_number = 1;
 
-		for (unsigned i = 0; i < root_node->entries.size(); ++i) {
-			const IndexEntry &entry = root_node->entries[i];
-
+		auto writeLinkToEntry = [&xs](const IndexEntry &entry, unsigned entry_number) {
 			std::string const link_attr = "href='#" + entry.inset()->paragraphs()[0].magicLabel() + "'";
 			xs << xml::StartTag("a", link_attr);
 			xs << from_ascii(std::to_string(entry_number));
 			xs << xml::EndTag("a");
+		};
+
+		for (unsigned i = 0; i < root_node->entries.size(); ++i) {
+			const IndexEntry &entry = root_node->entries[i];
+
+			switch (entry.inset()->params().range) {
+				case InsetIndexParams::PageRange::None:
+					writeLinkToEntry(entry, entry_number);
+					break;
+				case InsetIndexParams::PageRange::Start: {
+					// Try to find the end of the range, if it is just after. Otherwise, the output will be slightly
+					// scrambled, but understandable. Doing better would mean implementing more of the indexing logic here
+					// and more complex indexing here (skipping the end is not just incrementing i). Worst case output:
+					//     1--, 2, --3
+					const bool nextEntryIsEnd = i + 1 < root_node->entries.size() &&
+					                            root_node->entries[i + 1].inset()->params().range ==
+					                            InsetIndexParams::PageRange::End;
+					// No need to check if both entries are for the same terms: they are in the same IndexNode.
+
+					writeLinkToEntry(entry, entry_number);
+					xs << XMLStream::ESCAPE_NONE << " – "; // En dash, i.e. semi-long (--).
+
+					if (nextEntryIsEnd) {
+						// Skip the next entry in the loop, write it right now, after the dash.
+						entry_number += 1;
+						i += 1;
+						writeLinkToEntry(root_node->entries[i], entry_number);
+					}
+				}
+					break;
+				case InsetIndexParams::PageRange::End:
+					// This range end was not caught by the range start, do it now to avoid losing content.
+					xs << XMLStream::ESCAPE_NONE << " – "; // En dash, i.e. semi-long (--).
+					writeLinkToEntry(root_node->entries[i], entry_number);
+			}
 
 			if (i < root_node->entries.size() - 1) {
 				xs << ", ";

-----------------------------------------------------------------------

Summary of changes:
 src/insets/InsetIndex.cpp |   49 +++++++++++++++++++++++++++++++++++++-------
 1 files changed, 41 insertions(+), 8 deletions(-)


hooks/post-receive
-- 
Repository for new features


More information about the lyx-cvs mailing list