[LyX/2.5.x] Update tex2lyx support for babel-german

Juergen Spitzmueller <[email protected]>
Newsgroups gmane.editors.lyx.cvs
Message-ID <[email protected]>
commit 368222d1768542ac77215cebd04247fe97c6b81a
Author: Juergen Spitzmueller <[email protected]>
Date:   Thu Mar 5 10:14:34 2026 +0100

    Update tex2lyx support for babel-german
    
    This accounts for the changes in babel-german 3.0 regarding
    the meaning of "german" and supports the new language options
    
    (cherry picked from commit c39453011ed869601b6859783f10ef7ad3c67a3a)
---
 src/tex2lyx/Preamble.cpp                | 67 ++++++++++++++++++++++++++++-----
 src/tex2lyx/Preamble.h                  |  5 +++
 src/tex2lyx/test/test-structure.lyx.lyx |  6 +--
 src/tex2lyx/tex2lyx.h                   |  2 -
 src/tex2lyx/text.cpp                    |  4 +-
 status.25x                              |  2 +-
 6 files changed, 69 insertions(+), 17 deletions(-)

diff --git a/src/tex2lyx/Preamble.cpp b/src/tex2lyx/Preamble.cpp
index 3c5d998bd7..205f04870a 100644
--- a/src/tex2lyx/Preamble.cpp
+++ b/src/tex2lyx/Preamble.cpp
@@ -56,7 +56,10 @@ const char * const known_languages[] = {"acadian", "afrikaans", "albanian",
 "bulgarian", "canadian", "canadien", "catalan", "churchslavic", "classiclatin", "coptic",
 "croatian", "czech", "danish", "divehi", "dutch", "ecclesiasticlatin", "english", "esperanto",
 "estonian", "farsi", "finnish", "francais", "french", "frenchb", "frenchle", "frenchpro", "friulan",
-"galician", "german", "germanb", "georgian", "greek", "hebrew", "hindi", "hungarian", "icelandic",
+"galician", "german", "germanb", "german-at", "german-at-1901", "german-ch", "german-ch-1901",
+"german-de", "german-de-1901", "german-austria", "german-austria-1901", "german-switzerland",
+"german-switzerland-1901", "german-germany", "german-germany-1901",
+"georgian", "greek", "hebrew", "hindi", "hungarian", "icelandic",
 "indon", "indonesian", "interlingua", "irish", "italian", "japanese", "kannada", "kazakh", "khmer",
 "kurmanji", "lao", "latin", "latvian", "lithuanian", "lowersorbian", "lsorbian", "macedonian", "magyar",
 "malay", "malayalam", "marathi", "medievallatin", "meyalu", "mexican", "mongolian", "naustrian", "newzealand",
@@ -79,7 +82,10 @@ const char * const known_coded_languages[] = {"french", "afrikaans", "albanian",
 "bulgarian", "canadian", "canadien", "catalan", "churchslavonic", "latin-classic", "coptic",
 "croatian", "czech", "danish", "divehi", "dutch", "latin-ecclesiastic", "english", "esperanto",
 "estonian", "farsi", "finnish", "french", "french", "french", "french", "french", "friulan",
-"galician", "german", "german", "georgian", "greek", "hebrew", "hindi", "magyar", "icelandic",
+"galician", "german", "german", "naustrian", "austrian", "german-ch", "german-ch-old",
+"ngerman", "german", "naustrian", "austrian", "german-ch",
+"german-ch-old", "ngerman", "german",
+"georgian", "greek", "hebrew", "hindi", "magyar", "icelandic",
 "bahasa", "bahasa", "interlingua", "irish", "italian", "japanese", "kannada", "kazakh", "khmer",
 "kurmanji", "lao", "latin", "latvian", "lithuanian", "lowersorbian", "lowersorbian", "macedonian", "magyar",
 "bahasam", "malayalam", "marathi", "latin-medieval", "bahasam", "spanish-mexico", "mongolian", "naustrian", "newzealand",
@@ -91,6 +97,9 @@ const char * const known_coded_languages[] = {"french", "afrikaans", "albanian",
 "vietnamese", "welsh",
 0};
 
+/// legacy babel-german options that change semantics with glottonyms=auto
+const char * const known_legacy_german[] = {"naustrian", "ngerman", "nswissgerman", 0};
+
 /// languages with british quotes (.lyx names)
 const char * const known_british_quotes_languages[] = {"british", "welsh", 0};
 
@@ -949,7 +958,8 @@ string remove_braces(string const & value)
 } // anonymous namespace
 
 
-Preamble::Preamble() : one_language(true), explicit_babel(false),
+Preamble::Preamble() : one_language(true), default_language("english"),
+	explicit_babel(false), has_legacy_german(false),
 	title_layout_found(false), index_number(0), h_font_cjk_set(false)
 {
 	//h_backgroundcolor;
@@ -2082,9 +2092,13 @@ void Preamble::handle_package(Parser &p, string const & name,
 			// babel takes the last language of the option of its \usepackage
 			// call as document language. If there is no such language option, the
 			// last language in the documentclass options is used.
-			handle_opt(options, known_languages, h_language);
+			handle_opt(options, known_languages, default_language);
+			// Check whether we have naustrian, ngerman, or nswissgerman
+			// This is needed for babel german handling
+			string dummy;
+			has_legacy_german |= handle_opt(options, known_legacy_german, dummy);
 			// translate the babel name to a LyX name
-			h_language = babel2lyx(h_language);
+			h_language = babel2lyx(default_language);
 			if (h_language == "japanese") {
 				// For Japanese, the encoding isn't indicated in the source
 				// file, and there's really not much we can do. We could
@@ -2548,8 +2562,11 @@ bool Preamble::writeLyXHeader(ostream & os, bool subdoc, string const & outfiled
 		h_font_roman_osf = "false";
 	}
 	os << "\\maintain_unincluded_children " << h_maintain_unincluded_children << "\n"
-	   << "\\language " << h_language << "\n"
-	   << "\\language_package " << h_language_package << "\n"
+	   << "\\language " << h_language << "\n";
+	for (map<string, string>::const_iterator it = h_babel_options.begin();
+	     it != h_babel_options.end(); ++it)
+		os << "\\language_options_babel " << it->first << ' ' << it->second << '\n';
+	os << "\\language_package " << h_language_package << "\n"
 	   << "\\inputencoding " << h_inputencoding << "\n"
 	   << "\\fontencoding " << h_fontencoding << "\n"
 	   << "\\font_roman \"" << h_font_roman[0]
@@ -3272,8 +3289,14 @@ void Preamble::parse(Parser & p, string const & forceclass,
 			// The documentclass options are always parsed before the options
 			// of the babel call so that a language cannot overwrite the babel
 			// options.
-			handle_opt(opts, known_languages, h_language);
+			handle_opt(opts, known_languages, default_language);
+			// Check whether we have naustrian, ngerman, or nswissgerman
+			// This is needed for babel german handling
+			string dummy;
+			has_legacy_german = handle_opt(opts, known_legacy_german, dummy);
 			delete_opt(opts, known_languages);
+			// translate the babel name to a LyX name
+			h_language = babel2lyx(default_language);
 
 			// math indentation
 			if ((it = find(opts.begin(), opts.end(), "fleqn"))
@@ -3666,6 +3689,27 @@ void Preamble::parse(Parser & p, string const & forceclass,
 			continue;
 		}
 
+		if (t.cs() == "germansetup") {
+			string const arg = p.verbatim_item();
+			if (contains(arg, "glottonyms=legacy"))
+				has_legacy_german = true;
+			if (contains(arg, "glottonyms=contemporary"))
+				has_legacy_german = false;
+			if (default_language == "german")
+				// adopt main language name
+				h_language = babel2lyx(default_language);
+			if (!arg.empty()) {
+				// germansetup applies to all varieties
+				h_babel_options["austrian"] = arg;
+				h_babel_options["naustrian"] = arg;
+				h_babel_options["german"] = arg;
+				h_babel_options["ngerman"] = arg;
+				h_babel_options["german-ch"] = arg;
+				h_babel_options["german-ch-old"] = arg;
+			}
+			continue;
+		}
+
 		if (is_known(t.cs(), known_if_3arg_commands)) {
 			// prevent misparsing of \usepackage if it is used
 			// as an argument (see e.g. our own output of
@@ -3821,8 +3865,13 @@ string Preamble::parseEncoding(Parser & p, string const & forceclass)
 }
 
 
-string babel2lyx(string const & language)
+string Preamble::babel2lyx(string language)
 {
+	// with german, the semantics depends on the
+	// settings of glottonyms and the use of
+	// other options
+	if (language == "german" && !has_legacy_german)
+		language = "ngerman";
 	char const * const * where = is_known(language, known_languages);
 	if (where)
 		return known_coded_languages[where - known_languages];
diff --git a/src/tex2lyx/Preamble.h b/src/tex2lyx/Preamble.h
index b8fc1ebba9..3b3011478c 100644
--- a/src/tex2lyx/Preamble.h
+++ b/src/tex2lyx/Preamble.h
@@ -116,6 +116,8 @@ public:
 	           TeX2LyXDocClass & tc);
 	/// Parse the encoding from a preamble. *this is unusable afterwards.
 	std::string parseEncoding(Parser & p, std::string const & forceclass);
+	/// Translate babel language name to LyX language name
+	std::string babel2lyx(std::string language);
 	/// Writes the LyX file header from internal data
 	bool writeLyXHeader(std::ostream & os, bool subdoc,
 	                    std::string const & outfiledir);
@@ -152,6 +154,8 @@ private:
 	std::string default_language;
 	/// Was babel called explicitly?
 	bool explicit_babel;
+	/// Does "german" mean legacy German (1901 spelling)?
+	bool has_legacy_german;
 
 	/// was at least one title layout found?
 	bool title_layout_found;
@@ -215,6 +219,7 @@ private:
 	std::string h_justification;
 	std::string h_language;
 	std::string h_language_package;
+	std::map<std::string, std::string> h_babel_options;
 	std::string h_listings_params;
 	std::string h_maintain_unincluded_children;
 	std::string h_margins;
diff --git a/src/tex2lyx/test/test-structure.lyx.lyx b/src/tex2lyx/test/test-structure.lyx.lyx
index 2518d4c233..7b3158a6e8 100644
--- a/src/tex2lyx/test/test-structure.lyx.lyx
+++ b/src/tex2lyx/test/test-structure.lyx.lyx
@@ -1163,7 +1163,7 @@ blabla bla bla
 
 \begin_layout Standard
 switch to german:
-\lang german
+\lang ngerman
  Hallo! 
 \lang french
 some 
@@ -1171,13 +1171,13 @@ some
 french
 \emph default
 
-\lang german
+\lang ngerman
  back to english:
 \lang newzealand
  and some nested 
 \lang french
 french 
-\lang german
+\lang ngerman
 nested 
 \emph on
 german
diff --git a/src/tex2lyx/tex2lyx.h b/src/tex2lyx/tex2lyx.h
index b8c9dad1dd..f8021a65eb 100644
--- a/src/tex2lyx/tex2lyx.h
+++ b/src/tex2lyx/tex2lyx.h
@@ -35,8 +35,6 @@ public:
 	void setName(std::string const & name) { name_ = name; }
 };
 
-/// Translate babel language name to LyX language name
-extern std::string babel2lyx(std::string const & language);
 /// Translate LyX language name to babel language name
 extern std::string lyx2babel(std::string const & language);
 /// Translate polyglossia language name to LyX language name
diff --git a/src/tex2lyx/text.cpp b/src/tex2lyx/text.cpp
index b0aa48024a..a6e27222e3 100644
--- a/src/tex2lyx/text.cpp
+++ b/src/tex2lyx/text.cpp
@@ -5430,13 +5430,13 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
 			context.check_layout(os);
 			// save the language for the case that a
 			// \foreignlanguage is used
-			context.font.language = babel2lyx(p.verbatim_item());
+			context.font.language = preamble.babel2lyx(p.verbatim_item());
 			os << "\n\\lang " << context.font.language << "\n";
 			continue;
 		}
 
 		if (t.cs() == "foreignlanguage") {
-			string const lang = babel2lyx(p.verbatim_item());
+			string const lang = preamble.babel2lyx(p.verbatim_item());
 			parse_text_attributes(p, os, FLAG_ITEM, outer,
 			                      context, "\\lang",
 			                      context.font.language, lang);
diff --git a/status.25x b/status.25x
index 1a33f53c4c..b7d386df85 100644
--- a/status.25x
+++ b/status.25x
@@ -93,7 +93,7 @@ What's new
 
 * TEX2LYX
 
-
+- Update tex2lyx support for babel-german.
 
 * LYXHTML
 
-- 
lyx-cvs mailing list
[email protected]
https://lists.lyx.org/mailman/listinfo/lyx-cvs
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.