[LyX/master] Provide reversed style specifier for citation commands

Juergen Spitzmueller spitz at lyx.org
Sat Jul 13 15:22:10 UTC 2024


commit 6603c5362fe106dd074453388ded953c40998618
Author: Juergen Spitzmueller <spitz at lyx.org>
Date:   Sat Jul 13 17:20:29 2024 +0200

    Provide reversed style specifier for citation commands
    
    This lets you exclude given variants for specific citation styles only
---
 lib/citeengines/biblatex-chicago.citeengine |  4 +++-
 lib/citeengines/biblatex-natbib.citeengine  |  6 ++++--
 lib/citeengines/biblatex.citeengine         |  8 +++++---
 lib/doc/Customization.lyx                   | 23 ++++++++++++++++++++++-
 lib/doc/de/Customization.lyx                | 17 +++++++++++++++++
 src/BiblioInfo.cpp                          | 21 +++++++++------------
 src/BufferParams.cpp                        | 27 +++++++++++++++++++++++++++
 src/BufferParams.h                          |  2 ++
 src/Citation.h                              |  2 ++
 src/TextClass.cpp                           |  7 ++++++-
 src/frontends/qt/GuiCitation.cpp            | 13 +++++++++++--
 src/frontends/qt/Menus.cpp                  | 11 +++--------
 src/insets/InsetCitation.cpp                |  9 +--------
 13 files changed, 112 insertions(+), 38 deletions(-)

diff --git a/lib/citeengines/biblatex-chicago.citeengine b/lib/citeengines/biblatex-chicago.citeengine
index 2a5b8171a1..916ede34c6 100644
--- a/lib/citeengines/biblatex-chicago.citeengine
+++ b/lib/citeengines/biblatex-chicago.citeengine
@@ -30,7 +30,9 @@ MaxCiteNames 3
 # style at LyXName|alias*<!_stardesc!_stardesctooltip>[][]=latexcmd
 # 
 # * style:    A (comma-separated) list of citestyles to which
-#             this command is specific.
+#             this command is specific. If preceeded by '!',
+#             the list indicates citestyles for which the command
+#             is _not_ supported.
 # * LyXName:  The LyX name as output in the LyX file. For
 #             portability reasons, we try to use the same
 #             name for same-formatted commands in the
diff --git a/lib/citeengines/biblatex-natbib.citeengine b/lib/citeengines/biblatex-natbib.citeengine
index 8c034b9bed..c487810b90 100644
--- a/lib/citeengines/biblatex-natbib.citeengine
+++ b/lib/citeengines/biblatex-natbib.citeengine
@@ -34,7 +34,9 @@ MaxCiteNames 3
 # style at LyXName|alias*<!_stardesc!_stardesctooltip>[][]=latexcmd
 # 
 # * style:    A (comma-separated) list of citestyles to which
-#             this command is specific.
+#             this command is specific. If preceeded by '!',
+#             the list indicates citestyles for which the command
+#             is _not_ supported.
 # * LyXName:  The LyX name as output in the LyX file. For
 #             portability reasons, we try to use the same
 #             name for same-formatted commands in the
@@ -92,7 +94,7 @@ CiteEngine authoryear
 	Footcite$[][]=smartcite
 	Autocite$[][]
 	citetitle*<!_citetitlestar!_citetitlestartooltip>[][]
-	fullcite[][]
+	!mla,mla-strict,mla-new,mla7 at fullcite[][]
 	footfullcite[][]
 	nocite
 	keyonly
diff --git a/lib/citeengines/biblatex.citeengine b/lib/citeengines/biblatex.citeengine
index 0d77bc811c..92199df9fc 100644
--- a/lib/citeengines/biblatex.citeengine
+++ b/lib/citeengines/biblatex.citeengine
@@ -30,7 +30,9 @@ MaxCiteNames 3
 # style at LyXName|alias*<!_stardesc!_stardesctooltip>[][]=latexcmd
 # 
 # * style:    A (comma-separated) list of citestyles to which
-#             this command is specific.
+#             this command is specific. If preceeded by '!',
+#             the list indicates citestyles for which the command
+#             is _not_ supported.
 # * LyXName:  The LyX name as output in the LyX file. For
 #             portability reasons, we try to use the same
 #             name for same-formatted commands in the
@@ -74,7 +76,7 @@ MaxCiteNames 3
 #
 CiteEngine authoryear
 	Cite$|citealt,citealp[][]
-	Citet$[][]=textcite
+	!mla,mla-strict,mla-new,mla7 at Citet$[][]=textcite
 	Citep$[][]=parencite
 	apa,apa6 at nptextcite$[][]
 	Citeauthor*<!_citeauthorstar!_citeauthorstartooltip>[][]
@@ -84,7 +86,7 @@ CiteEngine authoryear
 	Footcite$[][]=smartcite
 	Autocite$[][]
 	citetitle*<!_citetitlestar!_citetitlestartooltip>[][]
-	fullcite[][]
+	!mla,mla-strict,mla-new,mla7 at fullcite[][]
 	footfullcite[][]
 	nocite
 	keyonly
diff --git a/lib/doc/Customization.lyx b/lib/doc/Customization.lyx
index 238404bc3b..5c1dbafc5e 100644
--- a/lib/doc/Customization.lyx
+++ b/lib/doc/Customization.lyx
@@ -24612,7 +24612,7 @@ LyXName|alias$*<!_stardesc!_stardesctooltip>[][]=latexcmd
 
 \begin_layout Itemize
 
-\change_inserted -712698321 1720682930
+\change_inserted -712698321 1720883627
 \begin_inset Flex Code
 status collapsed
 
@@ -24668,6 +24668,27 @@ nptextcite
 apa
 \emph default
  citation style can be defined.
+ If the list is prepended by an exclamation mark (
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+
+\change_inserted -712698321 1720883593
+!
+\change_unchanged
+
+\end_layout
+
+\end_inset
+
+),
+ the meaning is reversed:
+ it means that the style is used in all 
+\emph on
+but
+\emph default
+ the listed styles.
 \end_layout
 
 \begin_layout Itemize
diff --git a/lib/doc/de/Customization.lyx b/lib/doc/de/Customization.lyx
index 162aa3dd8b..18e3a342bd 100644
--- a/lib/doc/de/Customization.lyx
+++ b/lib/doc/de/Customization.lyx
@@ -23501,6 +23501,23 @@ nptextcite
 apa
 \emph default
  verfügbar ist.
+ Wenn der Liste ein Ausrufezeichen (
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+!
+\end_layout
+
+\end_inset
+
+) vorangestellt ist,
+ ist die Bedeutung umgekehrt:
+ der Befehl gilt dann in allen 
+\emph on
+außer
+\emph default
+ den aufgelisteten Stilen.
 \end_layout
 
 \begin_layout Itemize
diff --git a/src/BiblioInfo.cpp b/src/BiblioInfo.cpp
index 2db4041bc6..1292ef3303 100644
--- a/src/BiblioInfo.cpp
+++ b/src/BiblioInfo.cpp
@@ -1600,20 +1600,17 @@ BiblioInfo::CiteStringMap const BiblioInfo::getCiteStrings(
 	if (empty())
 		return vector<pair<docstring,docstring>>();
 
+	vector<CitationStyle> realStyles;
+	for (size_t i = 0; i != styles.size(); ++i) {
+		// exclude variants that are not supported in the current style
+		if (buf.masterParams().isActiveBiblatexCiteStyle(styles[i]))
+			realStyles.push_back(styles[i]);
+	}
+
 	string style;
-	CiteStringMap csm(styles.size());
+	CiteStringMap csm(realStyles.size());
 	for (size_t i = 0; i != csm.size(); ++i) {
-		bool ours = false;
-		// exclude variants that are not supported in the current style
-		for (string const & s: styles[i].styles) {
-			if (s == buf.masterParams().biblatex_citestyle) {
-				ours = true;
-				break;
-			}
-		}
-		if (!styles[i].styles.empty() && !ours)
-			continue;
-		style = styles[i].name;
+		style = realStyles[i].name;
 		csm[i] = make_pair(from_ascii(style), getLabel(keys, buf, style, ci));
 	}
 
diff --git a/src/BufferParams.cpp b/src/BufferParams.cpp
index c4493d42ca..43b08f9d1b 100644
--- a/src/BufferParams.cpp
+++ b/src/BufferParams.cpp
@@ -3789,6 +3789,33 @@ vector<CitationStyle> BufferParams::citeStyles() const
 }
 
 
+bool BufferParams::isActiveBiblatexCiteStyle(CitationStyle const & cs) const
+{
+	if (!useBiblatex())
+		return false;
+
+	if (cs.styles.empty() && cs.nostyles.empty())
+		// no restrictions
+		return true;
+
+	// exclude variants that are excluded in the current style
+	for (string const & s: cs.nostyles) {
+		if (s == biblatex_citestyle)
+			// explicitly excluded style
+			return false;
+	}
+	if (cs.styles.empty())
+		// not excluded
+		return true;
+
+	// only include variants that are supported in the current style
+	for (string const & s: cs.styles) {
+		if (s == biblatex_citestyle)
+			return true;
+	}
+	return false;
+}
+
 string const BufferParams::getBibtexCommand(string const cmd, bool const warn) const
 {
 	// split from options
diff --git a/src/BufferParams.h b/src/BufferParams.h
index 92c1418da1..2178d65677 100644
--- a/src/BufferParams.h
+++ b/src/BufferParams.h
@@ -527,6 +527,8 @@ public:
 	std::vector<std::string> citeCommands() const;
 	/// the available citation styles
 	std::vector<CitationStyle> citeStyles() const;
+	/// is the biblatex citestyle active in the current context?
+	bool isActiveBiblatexCiteStyle(CitationStyle const & cs) const;
 
 	/// Return the actual bibtex command (lyxrc or buffer param)
 	std::string const bibtexCommand(bool const warn = false) const;
diff --git a/src/Citation.h b/src/Citation.h
index 02e8d4ba3c..747599d5f8 100644
--- a/src/Citation.h
+++ b/src/Citation.h
@@ -45,6 +45,8 @@ public:
 	std::string startooltip;
 	/// Styles that supports the command
 	std::vector <std::string> styles;
+	/// Styles that do not supports the command
+	std::vector <std::string> nostyles;
 	/// upper casing author prefixes (van -> Van)
 	bool forceUpperCase;
 	/// starred version (full author list by default)
diff --git a/src/TextClass.cpp b/src/TextClass.cpp
index da58054fb3..933489743d 100644
--- a/src/TextClass.cpp
+++ b/src/TextClass.cpp
@@ -1224,7 +1224,12 @@ bool TextClass::readCiteEngine(Lexer & lexrc, ReadType rt, bool const add)
 		// split off style prefix if there
 		if (contains(lyx_cmd, '@')) {
 			lyx_cmd = split(lyx_cmd, style, '@');
-			cs.styles = getVectorFromString(style);
+			// a '!' prefix indicates nostyle
+			if (prefixIs(style, "!")) {
+				style = style.substr(1);
+				cs.nostyles = getVectorFromString(style);
+			} else
+				cs.styles = getVectorFromString(style);
 		}
 		char fchar = lyx_cmd[0];
 		if (isUpperCase(fchar)) {
diff --git a/src/frontends/qt/GuiCitation.cpp b/src/frontends/qt/GuiCitation.cpp
index de39ce7698..ea10d171e4 100644
--- a/src/frontends/qt/GuiCitation.cpp
+++ b/src/frontends/qt/GuiCitation.cpp
@@ -939,8 +939,17 @@ void GuiCitation::setCitedKeys()
 bool GuiCitation::initialiseParams(string const & sdata)
 {
 	InsetCommand::string2params(sdata, params_);
-	citeCmds_ = documentBuffer().params().citeCommands();
-	citeStyles_ = documentBuffer().params().citeStyles();
+	citeStyles_.clear();
+	citeCmds_.clear();
+	vector<string> const cmds = documentBuffer().params().citeCommands();
+	vector<CitationStyle> const styles = documentBuffer().params().citeStyles();
+	for (size_t i = 0; i != styles.size(); ++i) {
+		// only include variants that are supported in the current style
+		if (documentBuffer().params().isActiveBiblatexCiteStyle(styles[i])) {
+			citeStyles_.push_back(styles[i]);
+			citeCmds_.push_back(cmds[i]);
+		}
+	}
 	init();
 	return true;
 }
diff --git a/src/frontends/qt/Menus.cpp b/src/frontends/qt/Menus.cpp
index 16466b564e..30575bb2eb 100644
--- a/src/frontends/qt/Menus.cpp
+++ b/src/frontends/qt/Menus.cpp
@@ -1749,16 +1749,11 @@ void MenuDefinition::expandCiteStyles(BufferView const * bv)
 	for (int ii = 1; cit != end; ++cit, ++ii) {
 		docstring label = cit->second;
 		CitationStyle ccs = citeStyleList[ii - 1];
-		bool ours = false;
 		// exclude variants that are not supported in the current style
-		for (string const & s: ccs.styles) {
-			if (s == bp.biblatex_citestyle) {
-				ours = true;
-				break;
-			}
+		while (!bp.isActiveBiblatexCiteStyle(ccs)) {
+			++ii;
+			ccs = citeStyleList[ii - 1];
 		}
-		if (!ccs.styles.empty() && !ours)
-			continue;
 		ccs.forceUpperCase &= force;
 		ccs.hasStarredVersion &= star;
 		addWithStatusCheck(MenuItem(MenuItem::Command, toqstr(label),
diff --git a/src/insets/InsetCitation.cpp b/src/insets/InsetCitation.cpp
index c7933b8850..bf5f3526e5 100644
--- a/src/insets/InsetCitation.cpp
+++ b/src/insets/InsetCitation.cpp
@@ -380,15 +380,8 @@ CitationStyle asValidLatexCommand(BufferParams const & bp, string const & input,
 	for (; it != end; ++it) {
 		CitationStyle this_cs = *it;
 		if (this_cs.name == normalized_input) {
-			bool ours = false;
 			// exclude variants that are not supported in the current style
-			for (string const & s: this_cs.styles) {
-				if (s == bp.biblatex_citestyle) {
-					ours = true;
-					break;
-				}
-			}
-			if (!this_cs.styles.empty() && !ours) {
+			if (!bp.isActiveBiblatexCiteStyle(this_cs)) {
 				// citation not supported with current style
 				// reset to \cite
 				normalized_input = "cite";


More information about the lyx-cvs mailing list