commit 1498501f075a1fd172d0189bc6a643af609b6fef
Author: Juergen Spitzmueller <[email protected]>
Date:   Sat Jan 24 07:16:53 2026 +0100

    Introduce AltLanguage to account for major language feature changes
    
    This allows to support the new babel-german syntax
---
 lib/chkconfig.ltx |  1 +
 lib/languages     | 89 +++++++++++++++++++++++++++++++++++++++++++++----------
 src/Language.cpp  | 64 +++++++++++++++++++++++++++++++--------
 src/Language.h    | 14 ++++++++-
 4 files changed, 139 insertions(+), 29 deletions(-)

diff --git a/lib/chkconfig.ltx b/lib/chkconfig.ltx
index d5f7feaa97..e70586a3dc 100644
--- a/lib/chkconfig.ltx
+++ b/lib/chkconfig.ltx
@@ -314,6 +314,7 @@
 \TestPackage{astron}
 \TestPackage{authordate1-4}
 \TestPackageAddVersion{babel}
+\TestPackage[german-de.ldf]{babel-german3}
 \TestPackage{beamerposter}
 \TestPackage{biblatex}
 \TestPackage{biblatex-chicago}
diff --git a/lib/languages b/lib/languages
index 91cc0b5406..8ddf2f2e41 100644
--- a/lib/languages
+++ b/lib/languages
@@ -38,6 +38,8 @@
 #       SpecialChar
 #          <SpecialChar definitions>
 #       End
+#       AltLanguage       <fallback language name>
+#       AltLangIfNot      <requirement>
 # End
 #
 #
@@ -152,6 +154,11 @@
 # * SupportedBy indicates whether a specific package provides localization
 #   for the given language. This is currently used for the cross-reference
 #   packages (cleveref, refstyle, zref).
+# * You can define a fallback language with AltLanguage (instead of Language)
+#   and request it in a Language via "AltLanguage <altlanguagename>" if the
+#   requirement specified in "AltLangIfNot <requirement>" is not met.
+#   AltLanguage inherits the settings of the corresponding Language if the
+#   latter is defined first.
 #
 ##########################################################################
 
@@ -370,8 +377,8 @@ End
 # Due to the variety, we use no country code.
 Language austrian
        GuiName          "German (Austria, old spelling)"
-       BabelName        austrian
-       BabelOptFormat   modifier
+       BabelName        german-at-1901
+       BabelOptFormat   \germansetup{$opts$}
        PolyglossiaName  german
        PolyglossiaOpts  "variant=austrian,spelling=old,babelshorthands=true"
        XindyName        german-duden
@@ -424,13 +431,22 @@ Language austrian
            LaTeXOutput  \"|
            LaTeXOutputUTF8 \"|
        End
+       AltLanguage austrian-legacy
+       AltLangIfNot babel-german3
+End
+
+# fallback for babel-german < 3.0
+AltLanguage austrian-legacy
+       HasGuiSupport    false
+       BabelName        austrian
+       BabelOptFormat   modifier
 End
 
 # In polyglossia, this is supported since release 1.33.4 (May 2014)
 Language naustrian
        GuiName          "German (Austria)"
-       BabelName        naustrian
-       BabelOptFormat   modifier
+       BabelName        german-at
+       BabelOptFormat   \germansetup{$opts$}
        PolyglossiaName  german
        PolyglossiaOpts  "variant=austrian,spelling=new,babelshorthands=true"
        XindyName        german-duden
@@ -482,6 +498,15 @@ Language naustrian
            LaTeXOutput  \"|
            LaTeXOutputUTF8 \"|
        End
+       AltLanguage naustrian-legacy
+       AltLangIfNot babel-german3
+End
+
+# fallback for babel-german < 3.0
+AltLanguage naustrian-legacy
+       HasGuiSupport    false
+       BabelName        naustrian
+       BabelOptFormat   modifier
 End
 
 Language azerbaijani
@@ -1072,8 +1097,8 @@ End
 # german does not use a country code (due to the variety)
 Language german
        GuiName          "German (old spelling)"
-       BabelName        german
-       BabelOptFormat   modifier
+       BabelName        german-de-1901
+       BabelOptFormat   \germansetup{$opts$}
        PolyglossiaName  german
        PolyglossiaOpts  "variant=german,spelling=old,babelshorthands=true"
        XindyName        german-duden
@@ -1083,10 +1108,6 @@ Language german
        DateFormats      "dd. MMMM yyyy|dd. MMM yyyy|dd.MM.yyyy"
        LangCode         de
        LangVariety      alt
-       PostBabelPreamble
-           % We use legacy babel-german terminology
-           \@ifundefined{germansetup}{}{\germansetup{glottonyms=legacy}}
-       EndPostBabelPreamble
        SupportedBy      cleveref,refstyle,zref
        SpecialChar extrasofthyphen
            Type        formatting
@@ -1130,13 +1151,22 @@ Language german
            LaTeXOutput  \"|
            LaTeXOutputUTF8 \"|
        End
+       AltLanguage german-legacy
+       AltLangIfNot babel-german3
+End
+
+# fallback for babel-german < 3.0
+AltLanguage german-legacy
+       HasGuiSupport    false
+       BabelName        german
+       BabelOptFormat   modifier
 End
 
 Language ngerman
        GuiName          "German"
        HasGuiSupport    true
-       BabelName        ngerman
-       BabelOptFormat   modifier
+       BabelName        german-de
+       BabelOptFormat   \germansetup{$opts$}
        PolyglossiaName  german
        PolyglossiaOpts  "variant=german,spelling=new,babelshorthands=true"
        XindyName        german-duden
@@ -1188,6 +1218,15 @@ Language ngerman
            LaTeXOutput  \"|
            LaTeXOutputUTF8 \"|
        End
+       AltLanguage ngerman-legacy
+       AltLangIfNot babel-german3
+End
+
+# fallback for babel-german < 3.0
+AltLanguage ngerman-legacy
+       HasGuiSupport    false
+       BabelName        ngerman
+       BabelOptFormat   modifier
 End
 
 # In Babel, this is supported since release 2.7 of babel-german (Dec 2013)
@@ -1196,8 +1235,8 @@ End
 # We introduce it with LyX 2.3 to give the support time to settle.
 Language german-ch
        GuiName          "German (Switzerland)"
-       BabelName        nswissgerman
-       BabelOptFormat   modifier
+       BabelName        german-ch
+       BabelOptFormat   \germansetup{$opts$}
        PolyglossiaName  german
        PolyglossiaOpts  "variant=swiss,spelling=new,babelshorthands=true"
        XindyName        german-duden
@@ -1249,6 +1288,15 @@ Language german-ch
            LaTeXOutput  \"|
            LaTeXOutputUTF8 \"|
        End
+       AltLanguage german-ch-legacy
+       AltLangIfNot babel-german3
+End
+
+# fallback for babel-german < 3.0
+AltLanguage german-ch-legacy
+       HasGuiSupport    false
+       BabelName        nswissgerman
+       BabelOptFormat   modifier
 End
 
 # In Babel, this is supported since release 2.7 of babel-german (Dec 2013)
@@ -1256,8 +1304,8 @@ End
 # We introduce it with LyX 2.3 to give the support time to settle.
 Language german-ch-old
        GuiName          "German (Switzerland, old spelling)"
-       BabelName        swissgerman
-       BabelOptFormat   modifier
+       BabelName        german-ch-1901
+       BabelOptFormat   \germansetup{$opts$}
        PolyglossiaName  german
        PolyglossiaOpts  "variant=swiss,spelling=old,babelshorthands=true"
        XindyName        german-duden
@@ -1309,6 +1357,15 @@ Language german-ch-old
            LaTeXOutput  \"|
            LaTeXOutputUTF8 \"|
        End
+       AltLanguage german-ch-old-legacy
+       AltLangIfNot babel-german3
+End
+
+# fallback for babel-german < 3.0
+AltLanguage german-ch-old-legacy
+       HasGuiSupport    false
+       BabelName        swissgerman
+       BabelOptFormat   modifier
 End
 
 Language greek
diff --git a/src/Language.cpp b/src/Language.cpp
index 1ce9be6be5..82f89199cf 100644
--- a/src/Language.cpp
+++ b/src/Language.cpp
@@ -17,6 +17,7 @@
 
 #include "BufferParams.h"
 #include "Encoding.h"
+#include "LaTeXFeatures.h"
 #include "LaTeXFonts.h"
 #include "LyXRC.h"
 
@@ -166,12 +167,16 @@ bool Language::readLanguage(Lexer & lex)
                LA_RTL,
                LA_SPECIALCHARS,
                LA_WORDWRAP,
-               LA_ACTIVECHARS
+               LA_ACTIVECHARS,
+               LA_ALTLANG,
+               LA_ALTLANG_IF_NOT
        };
 
        // Keep these sorted alphabetically!
        LexerKeyword languageTags[] = {
                { "activechars",          LA_ACTIVECHARS },
+               { "altlangifnot",         LA_ALTLANG_IF_NOT },
+               { "altlanguage",          LA_ALTLANG },
                { "babelname",            LA_BABELNAME },
                { "babeloptformat",       LA_BABELOPTFORMAT },
                { "babelopts",            LA_BABELOPTS },
@@ -250,6 +255,9 @@ bool Language::readLanguage(Lexer & lex)
                case LA_ACTIVECHARS:
                        lex >> active_chars_;
                        break;
+               case LA_ALTLANG:
+                       lex >> alt_lang_;
+                       break;
                case LA_ENCODING:
                        lex >> encodingStr_;
                        break;
@@ -296,6 +304,9 @@ bool Language::readLanguage(Lexer & lex)
                case LA_REQUIRES:
                        lex >> required_;
                        break;
+               case LA_ALTLANG_IF_NOT:
+                       lex >> alt_lang_if_not_;
+                       break;
                case LA_PROVIDES:
                        lex >> provides_;
                        break;
@@ -322,18 +333,13 @@ bool Language::readLanguage(Lexer & lex)
 }
 
 
-bool Language::read(Lexer & lex)
+bool Language::read(Lexer & lex, std::string const lang)
 {
+       lang_ = lang;
        encoding_ = nullptr;
        internal_enc_ = false;
        rightToLeft_ = false;
 
-       if (!lex.next()) {
-               lex.printError("No name given for language: `$$Token'.");
-               return false;
-       }
-
-       lang_ = lex.getString();
        LYXERR(Debug::INFO, "Reading language " << lang_);
        if (!readLanguage(lex)) {
                LYXERR0("Error parsing language `" << lang_ << '\'');
@@ -404,12 +410,29 @@ void Languages::read(FileName const & filename)
                default:
                        break;
                }
-               if (lex.getString() != "Language") {
+               string const token = lex.getString();
+               bool altlang = false;
+               if (token == "AltLanguage")
+                       altlang = true;
+               else if (token != "Language") {
                        lex.printError("Unknown Language tag `$$Token'");
                        continue;
                }
+               if (!lex.next()) {
+                       lex.printError("No name given for language: 
`$$Token'.");
+                       break;
+               }
+               string const lang = lex.getString();
                Language l;
-               l.read(lex);
+               if (altlang) {
+                       for (auto const & ll : languagelist_) {
+                               if (ll.second.altLang() == lang) {
+                                       l = ll.second;
+                                       break;
+                               }
+                       }
+               }
+               l.read(lex, lang);
                if (!lex)
                        break;
                if (l.lang() == "latex") {
@@ -422,8 +445,25 @@ void Languages::read(FileName const & filename)
                        LASSERT(ignore_language == nullptr, continue);
                        static const Language ignore_lang = l;
                        ignore_language = &ignore_lang;
-               } else
-                       languagelist_[l.lang()] = l;
+               } else {
+                       if (altlang)
+                               altlanguagelist_[l.lang()] = l;
+                       else
+                               languagelist_[l.lang()] = l;
+               }
+       }
+
+       // check fallbacks
+       for (auto const & l : languagelist_) {
+               if (!l.second.altLangIfNotProvided().empty() && 
!l.second.altLang().empty()) {
+                       if 
(!LaTeXFeatures::isAvailable(l.second.altLangIfNotProvided())
+                           && altlanguagelist_.find(l.second.altLang()) != 
altlanguagelist_.end()) {
+                               // use alt. lang and set its name to that of 
orig lang
+                               Language altlang = 
altlanguagelist_[l.second.altLang()];
+                               altlang.setLanguageName(l.first);
+                               languagelist_[l.first] = altlang;
+                       }
+               }
        }
 
        default_language = getLanguage("english");
diff --git a/src/Language.h b/src/Language.h
index c7d17247b1..6acdef619e 100644
--- a/src/Language.h
+++ b/src/Language.h
@@ -44,6 +44,8 @@ public:
                                 use_babel_provide_(0){}
        /// LyX language name
        std::string const lang() const { return lang_; }
+       /// Change language name; needed for AltLang
+       void setLanguageName(std::string const & l) { lang_ = l; }
        /// Babel language name
        std::string const babel() const { return babel_; }
        /// babel language options
@@ -66,6 +68,10 @@ public:
        std::string const quoteStyle() const { return quote_style_; }
        /// active characters
        std::string const activeChars() const { return active_chars_; }
+       /// fallback language
+       std::string const altLang() const { return alt_lang_; }
+       /// requirement (package, function)
+       std::string const altLangIfNotProvided() const { return 
alt_lang_if_not_; }
        /// requirement (package, function)
        std::string const required() const { return required_; }
        /// provides feature
@@ -116,7 +122,7 @@ public:
        /// Is this language supported by a specific package?
        bool supportedBy(std::string const & package) const;
        ///
-       bool read(support::Lexer & lex);
+       bool read(support::Lexer & lex, std::string const lang);
        ///
        bool readLanguage(support::Lexer & lex);
        ///
@@ -149,6 +155,10 @@ private:
        ///
        trivstring active_chars_;
        ///
+       trivstring alt_lang_;
+       ///
+       trivstring alt_lang_if_not_;
+       ///
        trivstring required_;
        ///
        trivstring provides_;
@@ -231,6 +241,8 @@ public:
 private:
        ///
        LanguageList languagelist_;
+       ///
+       LanguageList altlanguagelist_;
 };
 
 /// Global singleton instance.
-- 
lyx-cvs mailing list
[email protected]
https://lists.lyx.org/mailman/listinfo/lyx-cvs

Reply via email to