commit 5b85e9467b374c4dfb96e33e38ca23158fe0308c
Author: Juergen Spitzmueller <[email protected]>
Date:   Mon Nov 24 14:12:32 2025 +0100

    Implement SpecialChar to languages
    
    This allows us to support language-specific special-characters
    or specific character macros (such as babel shorthands).
    
    Concrete implementations will follow later.
---
 lib/doc/Customization.lyx       | 93 +++++++++++++++++++++++++++++++++++++++--
 lib/doc/de/Customization.lyx    | 69 +++++++++++++++++++++++++++++-
 lib/languages                   |  3 ++
 src/Language.cpp                | 29 +++++++++++++
 src/Language.h                  | 12 ++++++
 src/SpecialChar.cpp             | 65 ++++++++++++++++++++++++++++
 src/SpecialChar.h               | 20 +++++++++
 src/Text.cpp                    |  8 ++--
 src/frontends/qt/Menus.cpp      | 27 ++++++++----
 src/insets/InsetInfo.cpp        |  2 +-
 src/insets/InsetSpecialChar.cpp | 17 ++++++--
 src/insets/InsetSpecialChar.h   |  7 +++-
 12 files changed, 330 insertions(+), 22 deletions(-)

diff --git a/lib/doc/Customization.lyx b/lib/doc/Customization.lyx
index c0839cbd00..b36cc59af5 100644
--- a/lib/doc/Customization.lyx
+++ b/lib/doc/Customization.lyx
@@ -24348,7 +24348,7 @@ name "subsec:SpecialChars"
 
 \begin_layout Standard
 
-\change_inserted -712698321 1761578930
+\change_inserted -712698321 1763989788
 Here is how special characters,
  formatting commands and logos that need specific \SpecialChar LaTeX
 ,
@@ -24383,9 +24383,36 @@ Input stdspecialchars.inc
 
 \begin_layout Standard
 
-\change_inserted -712698321 1761552239
+\change_inserted -712698321 1763989781
 to your layout file.
- The definition always starts with 
+\end_layout
+
+\begin_layout Standard
+
+\change_inserted -712698321 1763989822
+Also,
+ some language definitions provide definitions for language-specific special 
characters (such as so-called babel shorthands).
+ Those can be overwritten by using the 
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+
+\change_inserted -712698321 1763989822
+IgnoreLanguage
+\change_unchanged
+
+\end_layout
+
+\end_inset
+
+ flag (see below).
+\end_layout
+
+\begin_layout Standard
+
+\change_inserted -712698321 1761552239
+The definition always starts with 
 \begin_inset Flex Code
 status collapsed
 
@@ -24516,7 +24543,7 @@ nolink "false"
 
 \begin_layout Description
 
-\change_inserted -712698321 1761553280
+\change_inserted -712698321 1763989431
 \begin_inset Flex Code
 status collapsed
 
@@ -24569,6 +24596,54 @@ status collapsed
 
 \begin_layout Description
 
+\change_inserted -712698321 1763989695
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+
+\change_inserted -712698321 1763989442
+IgnoreLanguage
+\end_layout
+
+\end_inset
+
+ [
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+
+\change_inserted -712698321 1763989432
+
+\emph on
+0
+\end_layout
+
+\end_inset
+
+
+\begin_inset space \thinspace{}
+\end_inset
+
+
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+
+\change_inserted -712698321 1763989432
+1
+\end_layout
+
+\end_inset
+
+] If you set this to true,
+ the definition will not be overwritten by language-specific definitions.
+\end_layout
+
+\begin_layout Description
+
 \change_inserted -712698321 1761552940
 \begin_inset Flex Code
 status collapsed
@@ -24980,6 +25055,8 @@ status collapsed
 
 \change_inserted -712698321 1762780991
 LaTeXOutput
+\change_unchanged
+
 \end_layout
 
 \end_inset
@@ -24999,6 +25076,8 @@ status collapsed
 
 \backslash
 
+\change_unchanged
+
 \end_layout
 
 \end_inset
@@ -25014,6 +25093,8 @@ status collapsed
 \end_inset
 
 
+\change_unchanged
+
 \end_layout
 
 \end_inset
@@ -25030,6 +25111,8 @@ status collapsed
 
 \backslash
 
+\change_unchanged
+
 \end_layout
 
 \end_inset
@@ -25049,6 +25132,8 @@ status collapsed
 \end_inset
 
 
+\change_unchanged
+
 \end_layout
 
 \end_inset
diff --git a/lib/doc/de/Customization.lyx b/lib/doc/de/Customization.lyx
index af5afa9e1c..67c26a2ee4 100644
--- a/lib/doc/de/Customization.lyx
+++ b/lib/doc/de/Customization.lyx
@@ -23414,7 +23414,7 @@ stdspecialchars.inc
 
 ,
  die für jede Klasse automatisch geladen wird.
- Wenn Sie allerdings Standarddefinitionen modifizieren wollen,
+ Wenn Sie jedoch Standarddefinitionen modifizieren wollen,
  müssen Sie die Datei zuvor manuell laden,
  indem Sie diese Zeile in die Layout-Datei einfügen:
 \end_layout
@@ -23423,6 +23423,23 @@ stdspecialchars.inc
 Input stdspecialchars.inc
 \end_layout
 
+\begin_layout Standard
+Außerdem enthalten einige Sprachdefinitionen Definitionen für 
sprachspezifische Sonderzeichen (bspw.
+ sogenannte Babel-Shorthands).
+ Wenn Sie diese überschreiben wollen,
+ nutzen Sie die Option 
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+IgnoreLanguage
+\end_layout
+
+\end_inset
+
+ (siehe unten).
+\end_layout
+
 \begin_layout Standard
 Die Definitionen beginnen immer mit 
 \begin_inset Flex Code
@@ -23566,6 +23583,56 @@ status collapsed
 \begin_inset Flex Code
 status collapsed
 
+\begin_layout Plain Layout
+IgnoreLanguage
+\end_layout
+
+\end_inset
+
+ [
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+
+\emph on
+0
+\end_layout
+
+\end_inset
+
+
+\begin_inset space \thinspace{}
+\end_inset
+
+
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+1
+\end_layout
+
+\end_inset
+
+] Wenn Sie diesen Wert auf 
+\begin_inset Flex Code
+status collapsed
+
+\begin_layout Plain Layout
+1
+\end_layout
+
+\end_inset
+
+ setzen,
+ wird die Definition nicht durch sprachspezifische Definitionen überschrieben.
+\end_layout
+
+\begin_layout Description
+\begin_inset Flex Code
+status collapsed
+
 \begin_layout Plain Layout
 IsChar
 \end_layout
diff --git a/lib/languages b/lib/languages
index ab2fe12113..457a7ab65f 100644
--- a/lib/languages
+++ b/lib/languages
@@ -35,6 +35,9 @@
 #      Requires           <requirement>
 #      Provides           <babel language feature>
 #       SupportedBy        <package,package,...>
+#       SpecialChar
+#          <SpecialChar definitions>
+#       End
 # End
 #
 #
diff --git a/src/Language.cpp b/src/Language.cpp
index 4c15d2d01e..1ce9be6be5 100644
--- a/src/Language.cpp
+++ b/src/Language.cpp
@@ -164,6 +164,7 @@ bool Language::readLanguage(Lexer & lex)
                LA_SUPPORTED_BY,
                LA_QUOTESTYLE,
                LA_RTL,
+               LA_SPECIALCHARS,
                LA_WORDWRAP,
                LA_ACTIVECHARS
        };
@@ -193,6 +194,7 @@ bool Language::readLanguage(Lexer & lex)
                { "quotestyle",           LA_QUOTESTYLE },
                { "requires",             LA_REQUIRES },
                { "rtl",                  LA_RTL },
+               { "specialchar",          LA_SPECIALCHARS },
                { "supportedby",          LA_SUPPORTED_BY },
                { "wordwrap",             LA_WORDWRAP },
                { "xindyname",            LA_XINDYNAME }
@@ -297,6 +299,9 @@ bool Language::readLanguage(Lexer & lex)
                case LA_PROVIDES:
                        lex >> provides_;
                        break;
+               case LA_SPECIALCHARS:
+                       readSpecialChars(lex);
+                       break;
                case LA_SUPPORTED_BY: {
                        lex.eatLine();
                        vector<string> const fe =
@@ -361,6 +366,30 @@ void 
Language::readLayoutTranslations(Language::TranslationMap const & trans, bo
 }
 
 
+void Language::readSpecialChars(Lexer & lexrc)
+{
+       std::string name;
+       if (lexrc.next())
+               name = lexrc.getString();
+       else {
+               lexrc.printError("No type given for SpecialChar: `$$Token'.");
+               return;
+       }
+       SpecialChar sc;
+       if (special_chars_.find(name) != special_chars_.end())
+               sc = special_chars_[name];
+
+       special_chars_[name] = specialchars.readSpecialChars(lexrc, sc);
+       lexrc.popTable();
+}
+
+
+bool Language::isKnownSpecialChar(string const & name) const
+{
+       return special_chars_.find(name) != special_chars_.end();
+}
+
+
 void Languages::read(FileName const & filename)
 {
        Lexer lex;
diff --git a/src/Language.h b/src/Language.h
index c7e2c5c7ad..c7d17247b1 100644
--- a/src/Language.h
+++ b/src/Language.h
@@ -15,6 +15,8 @@
 #ifndef LANGUAGE_H
 #define LANGUAGE_H
 
+#include "SpecialChar.h"
+
 #include "support/docstring.h"
 
 #include <map>
@@ -83,6 +85,8 @@ public:
         * appears in the exported document, since the output must not depend
         * on installed locales. Non-ASCII keys are not translated. */
        docstring const translateLayout(std::string const & msg) const;
+       ///
+       void readSpecialChars(support::Lexer &);
        /// default encoding
        Encoding const * encoding() const { return encoding_; }
        ///
@@ -119,6 +123,10 @@ public:
        typedef std::map<trivstring, trivdocstring> TranslationMap;
        ///
        void readLayoutTranslations(TranslationMap const & trans, bool replace);
+       /// Special characters
+       std::map<std::string, SpecialChar> specialChars() { return 
special_chars_; }
+       ///
+       bool isKnownSpecialChar(std::string const &) const;
        // for the use in std::map
        friend bool operator<(Language const & p, Language const & q);
 private:
@@ -178,6 +186,8 @@ private:
        TranslationMap layoutTranslations_;
        ///
        int use_babel_provide_;
+       /// Special characters
+       std::map<std::string, SpecialChar> special_chars_;
 };
 
 
@@ -215,6 +225,8 @@ public:
        const_iterator end() const { return languagelist_.end(); }
        ///
        bool haveOtherForceProvide() const;
+       /// Special characters
+       std::map<std::string, SpecialChar> special_chars_;
 
 private:
        ///
diff --git a/src/SpecialChar.cpp b/src/SpecialChar.cpp
index 4ef1786e01..99035e0222 100644
--- a/src/SpecialChar.cpp
+++ b/src/SpecialChar.cpp
@@ -26,6 +26,49 @@ namespace lyx {
 
 SpecialChars specialchars;
 
+SpecialChar & SpecialChar::resolve(SpecialChar const & sc)
+{
+       if (sc.ignore_lang)
+               // we ignore the language variant
+               return const_cast<SpecialChar&>(sc);
+
+       // inherit all non-default values
+       if (lyx_output_default && !sc.lyx_output_default)
+               lyx_output = sc.lyx_output;
+       if (latex_output_default && !sc.latex_output_default)
+               latex_output = sc.latex_output;
+       if (latex_output_rtl_default && !sc.latex_output_rtl_default)
+               latex_output_rtl = sc.latex_output_rtl;
+       if (latex_output_utf8_default && !sc.latex_output_utf8_default)
+               latex_output_utf8 = sc.latex_output_utf8;
+       if (plaintext_output_default && !sc.plaintext_output_default)
+               plaintext_output = sc.plaintext_output;
+       if (xhtml_output_default && !sc.xhtml_output_default)
+               xhtml_output = sc.xhtml_output;
+       if (tooltip_default && !sc.tooltip_default)
+               tooltip = sc.tooltip;
+       if (menustring_default && !sc.menustring_default)
+               menustring = sc.menustring;
+       if (req_default && !sc.req_default)
+               req = sc.req;
+       if (type_default && !sc.type_default)
+               type = sc.type;
+       if (can_break_after_default && !sc.can_break_after_default)
+               can_break_after = sc.can_break_after;
+       if (is_letter_default && !sc.is_letter_default)
+               is_letter = sc.is_letter;
+       if (is_char_default && !sc.is_char_default)
+               is_char = sc.is_char;
+       if (need_protect_default && !sc.need_protect_default)
+               need_protect = sc.need_protect;
+       if (force_ltr_default && !sc.force_ltr_default)
+               force_ltr = sc.force_ltr;
+       if (font_default && !sc.font_default)
+               font = sc.font;
+       return *this;
+}
+
+
 SpecialChar SpecialChars::readSpecialChars(Lexer & lexrc, SpecialChar & sc) 
const
 {
        enum {
@@ -39,6 +82,7 @@ SpecialChar SpecialChars::readSpecialChars(Lexer & lexrc, 
SpecialChar & sc) cons
                SC_MENUSTRING,
                SC_REQUIRES,
                SC_FORCE_LTR,
+               SC_IGNORE_LANG,
                SC_IS_CHAR,
                SC_IS_LETTER,
                SC_CAN_BREAK_AFTER,
@@ -53,6 +97,7 @@ SpecialChar SpecialChars::readSpecialChars(Lexer & lexrc, 
SpecialChar & sc) cons
                {"end",             SC_END },
                {"font",            SC_FONT },
                {"forceltr",        SC_FORCE_LTR },
+               {"ignorelanguage",  SC_IGNORE_LANG },
                {"ischar",          SC_IS_CHAR },
                {"isletter",        SC_IS_LETTER },
                {"latexoutput",     SC_LATEX_OUTPUT },
@@ -83,26 +128,36 @@ SpecialChar SpecialChars::readSpecialChars(Lexer & lexrc, 
SpecialChar & sc) cons
                case SC_CAN_BREAK_AFTER:
                        lexrc.next();
                        sc.can_break_after = lexrc.getBool();
+                       sc.can_break_after_default = false;
+                       break;
+               case SC_IGNORE_LANG:
+                       lexrc.next();
+                       sc.ignore_lang = lexrc.getBool();
                        break;
                case SC_FORCE_LTR:
                        lexrc.next();
                        sc.force_ltr = lexrc.getBool();
+                       sc.force_ltr_default = false;
                        break;
                case SC_IS_CHAR:
                        lexrc.next();
                        sc.is_char = lexrc.getBool();
+                       sc.is_char_default = false;
                        break;
                case SC_IS_LETTER:
                        lexrc.next();
                        sc.is_letter = lexrc.getBool();
+                       sc.is_letter_default = false;
                        break;
                case SC_NEED_PROTECT:
                        lexrc.next();
                        sc.need_protect = lexrc.getBool();
+                       sc.need_protect_default = false;
                        break;
                case SC_MENUSTRING:
                        lexrc.eatLine();
                        sc.menustring = trim(lexrc.getString(), "\"");
+                       sc.menustring_default = false;
                        break;
                case SC_LATEX_OUTPUT: {
                        lexrc.next(true);
@@ -111,6 +166,7 @@ SpecialChar SpecialChars::readSpecialChars(Lexer & lexrc, 
SpecialChar & sc) cons
                                sc.latex_output = docstring(1, hexToInt(res));
                        else
                                sc.latex_output = rtrim(lexrc.getDocString());
+                       sc.latex_output_default = false;
                        break;
                }
                case SC_LATEX_OUTPUT_RTL: {
@@ -120,6 +176,7 @@ SpecialChar SpecialChars::readSpecialChars(Lexer & lexrc, 
SpecialChar & sc) cons
                                sc.latex_output_rtl = docstring(1, 
hexToInt(res));
                        else
                                sc.latex_output_rtl = 
rtrim(lexrc.getDocString());
+                       sc.latex_output_rtl_default = false;
                        break;
                }
                case SC_LATEX_OUTPUT_UTF8: {
@@ -129,6 +186,7 @@ SpecialChar SpecialChars::readSpecialChars(Lexer & lexrc, 
SpecialChar & sc) cons
                                sc.latex_output_utf8 = docstring(1, 
hexToInt(res));
                        else
                                sc.latex_output_utf8 = 
rtrim(lexrc.getDocString());
+                       sc.latex_output_utf8_default = false;
                        break;
                }
                case SC_LYX_OUTPUT: {
@@ -138,6 +196,7 @@ SpecialChar SpecialChars::readSpecialChars(Lexer & lexrc, 
SpecialChar & sc) cons
                                sc.lyx_output = docstring(1, hexToInt(res));
                        else
                                sc.lyx_output = rtrim(lexrc.getDocString());
+                       sc.lyx_output_default = false;
                        break;
                }
                case SC_PLAINTEXT_OUTPUT: {
@@ -147,26 +206,32 @@ SpecialChar SpecialChars::readSpecialChars(Lexer & lexrc, 
SpecialChar & sc) cons
                                sc.plaintext_output = docstring(1, 
hexToInt(res));
                        else
                                sc.plaintext_output = 
rtrim(lexrc.getDocString());
+                       sc.plaintext_output_default = false;
                        break;
                }
                case SC_REQUIRES:
                        lexrc.eatLine();
                        sc.req = lexrc.getString();
+                       sc.req_default = false;
                        break;
                case SC_TOOLTIP:
                        lexrc.next();
                        sc.tooltip = rtrim(lexrc.getDocString());
+                       sc.tooltip_default = false;
                        break;
                case SC_TYPE:
                        lexrc.next();
                        sc.type = lowercase(lexrc.getString());
+                       sc.type_default = false;
                        break;
                case SC_XHTML_OUTPUT:
                        lexrc.next();
                        sc.xhtml_output = rtrim(lexrc.getDocString());
+                       sc.xhtml_output_default = false;
                        break;
                case SC_FONT:
                        sc.font = lyxRead(lexrc, sc.font);
+                       sc.font_default = false;
                        break;
                case SC_END:
                        getout = true;
diff --git a/src/SpecialChar.h b/src/SpecialChar.h
index 3dc963c18d..992e2a1851 100644
--- a/src/SpecialChar.h
+++ b/src/SpecialChar.h
@@ -42,7 +42,27 @@ public:
        bool is_char = false;
        bool need_protect = false;
        bool force_ltr = false;
+       bool ignore_lang = false;
        FontInfo font;
+       // store whether we have default settings
+       bool lyx_output_default = true;
+       bool latex_output_default = true;
+       bool latex_output_rtl_default = true;
+       bool latex_output_utf8_default = true;
+       bool plaintext_output_default = true;
+       bool xhtml_output_default = true;
+       bool tooltip_default = true;
+       bool menustring_default = true;
+       bool req_default = true;
+       bool type_default = true;
+       bool can_break_after_default = true;
+       bool is_letter_default = true;
+       bool is_char_default = true;
+       bool need_protect_default = true;
+       bool force_ltr_default = true;
+       bool font_default = true;
+       ///
+       SpecialChar & resolve(SpecialChar const &);
 };
 
 class SpecialChars
diff --git a/src/Text.cpp b/src/Text.cpp
index 5b1a3dbd5c..20adeeab2a 100644
--- a/src/Text.cpp
+++ b/src/Text.cpp
@@ -932,7 +932,8 @@ void Text::insertStringAsLines(Cursor & cur, docstring 
const & str,
                                space_inserted = true;
                        }
                } else if (specialchars.find(ch) != specialchars.end()
-                          && (par.insertInset(pos, new 
InsetSpecialChar(cur.buffer(), specialchars.find(ch)->second),
+                          && (par.insertInset(pos, new 
InsetSpecialChar(cur.buffer(), cur.current_font.language(),
+                                                                        
specialchars.find(ch)->second),
                                               font, bparams.track_changes
                                               ? Change(Change::INSERTED)
                                               : Change(Change::UNCHANGED)))) {
@@ -3544,7 +3545,7 @@ void specialChar(Cursor & cur, string const & kind)
 {
        cur.recordUndo();
        cap::replaceSelection(cur);
-       InsetSpecialChar * sc = new InsetSpecialChar(cur.buffer(), kind);
+       InsetSpecialChar * sc = new InsetSpecialChar(cur.buffer(), 
cur.current_font.language(), kind);
        sc->update();
        cur.insert(sc);
        cur.posForward();
@@ -6688,7 +6689,8 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & 
cmd,
        case LFUN_SPECIALCHAR_INSERT: {
                string const arg = cmd.getArg(0);
                code = SPECIALCHAR_CODE;
-               enable = 
cur.buffer()->params().documentClass().isKnownSpecialChar(arg);
+               enable = 
cur.buffer()->params().documentClass().isKnownSpecialChar(arg)
+                       || (cur.inTexted() && 
const_cast<Language*>(cur.current_font.language())->isKnownSpecialChar(arg));
                break;
        }
        case LFUN_SPACE_INSERT:
diff --git a/src/frontends/qt/Menus.cpp b/src/frontends/qt/Menus.cpp
index a6553b11d8..91ac59faf9 100644
--- a/src/frontends/qt/Menus.cpp
+++ b/src/frontends/qt/Menus.cpp
@@ -385,7 +385,7 @@ public:
        void expandToc2(Toc const & toc_list, size_t from, size_t to, int 
depth, const string & toc_type);
        void expandToc(Buffer const * buf);
        void expandPasteRecent(Buffer const * buf);
-       void expandSpecialChars(Buffer const * buf, string const & type);
+       void expandSpecialChars(BufferView const * bv, string const & type);
        void expandTextBreaks(BufferView const * bv, bool modify = false);
        void expandToolbars();
        void expandBranches(Buffer const * buf);
@@ -1562,11 +1562,24 @@ void MenuDefinition::expandPasteRecent(Buffer const * 
buf)
 }
 
 
-void MenuDefinition::expandSpecialChars(Buffer const * buf, string const & 
type)
+void MenuDefinition::expandSpecialChars(BufferView const * bv, string const & 
type)
 {
-       if (!buf)
+       if (!bv)
                return;
-       for (auto const & [key, value] : 
buf->params().documentClass().specialChars()) {
+       for (auto const & [key, value] : 
bv->buffer().params().documentClass().specialChars()) {
+               if (value.type != type)
+                       continue;
+               add(MenuItem(MenuItem::Command, qt_(value.menustring),
+                           FuncRequest(LFUN_SPECIALCHAR_INSERT, key)));
+       }
+       if (!bv->cursor().inTexted())
+               return;
+       Language * lang = 
const_cast<Language*>(bv->cursor().current_font.language());
+       if (!lang)
+               return;
+       for (auto const & [key, value] : lang->specialChars()) {
+               if 
(bv->buffer().params().documentClass().isKnownSpecialChar(key))
+                       continue;
                if (value.type != type)
                        continue;
                add(MenuItem(MenuItem::Command, qt_(value.menustring),
@@ -2582,15 +2595,15 @@ void Menus::Impl::expand(MenuDefinition const & 
frommenu,
                        break;
 
                case MenuItem::SpecialChars:
-                       tomenu.expandSpecialChars(buf, "specialchar");
+                       tomenu.expandSpecialChars(bv, "specialchar");
                        break;
 
                case MenuItem::SpecialCharsFormatting:
-                       tomenu.expandSpecialChars(buf, "formatting");
+                       tomenu.expandSpecialChars(bv, "formatting");
                        break;
 
                case MenuItem::SpecialCharsLogos:
-                       tomenu.expandSpecialChars(buf, "logo");
+                       tomenu.expandSpecialChars(bv, "logo");
                        break;
 
                case MenuItem::TextBreaks:
diff --git a/src/insets/InsetInfo.cpp b/src/insets/InsetInfo.cpp
index f064c7dd4d..43c79f9fec 100644
--- a/src/insets/InsetInfo.cpp
+++ b/src/insets/InsetInfo.cpp
@@ -1081,7 +1081,7 @@ void InsetInfo::build()
                for (docstring const & name : names) {
                        // do not insert > for the top level menu item
                        if (&name != &names.front())
-                               par.insertInset(par.size(), new 
InsetSpecialChar(&buffer(), "menuseparator"),
+                               par.insertInset(par.size(), new 
InsetSpecialChar(&buffer(), params_.lang, "menuseparator"),
                                                f, Change(Change::UNCHANGED));
                        //FIXME: add proper underlines here. This
                        // involves rewriting searchMenu used above to
diff --git a/src/insets/InsetSpecialChar.cpp b/src/insets/InsetSpecialChar.cpp
index bd14085a6d..872b07e80f 100644
--- a/src/insets/InsetSpecialChar.cpp
+++ b/src/insets/InsetSpecialChar.cpp
@@ -23,6 +23,8 @@
 #include "Language.h"
 #include "LaTeXFeatures.h"
 #include "MetricsInfo.h"
+#include "Paragraph.h"
+#include "ParIterator.h"
 #include "xml.h"
 #include "texstream.h"
 
@@ -45,8 +47,8 @@ namespace lyx {
 using support::Lexer;
 
 
-InsetSpecialChar::InsetSpecialChar(Buffer * buf, string const & k)
-       : Inset(buf), kind_(k), unknown_(false)
+InsetSpecialChar::InsetSpecialChar(Buffer * buf, Language const * lang, string 
const & k)
+       : Inset(buf), kind_(k), unknown_(false), 
lang_(const_cast<Language*>(lang))
 {
        if (buf)
                update();
@@ -318,17 +320,24 @@ docstring InsetSpecialChar::xhtml(XMLStream & xs, 
OutputParams const &) const
 
 void InsetSpecialChar::update()
 {
-       if (!buffer().masterParams().documentClass().isKnownSpecialChar(kind_))
+       bool const local = lang_ && lang_->isKnownSpecialChar(kind_);
+       if (!local && 
!buffer().masterParams().documentClass().isKnownSpecialChar(kind_))
                unknown_ = true;
        else {
                sc_ = 
buffer().masterParams().documentClass().specialChars()[kind_];
+               if (local) {
+                       SpecialChar lsc = lang_->specialChars()[kind_];
+                       sc_ = lsc.resolve(sc_);
+               }
                unknown_ = false;
        }
 }
 
 
-void InsetSpecialChar::updateBuffer(ParIterator const & /* it*/, UpdateType /* 
utype*/, bool const /*deleted*/)
+void InsetSpecialChar::updateBuffer(ParIterator const & it, UpdateType /* 
utype*/, bool const /*deleted*/)
 {
+       BufferParams const & bp = buffer().params();
+       lang_ = const_cast<Language *>(it.paragraph().getFontSettings(bp, 
it.pos()).language());
        update();
 }
 
diff --git a/src/insets/InsetSpecialChar.h b/src/insets/InsetSpecialChar.h
index 4440bd2775..8e2441c568 100644
--- a/src/insets/InsetSpecialChar.h
+++ b/src/insets/InsetSpecialChar.h
@@ -16,6 +16,7 @@
 
 
 #include "Inset.h"
+#include "Font.h"
 
 #include "TextClass.h"
 
@@ -57,9 +58,9 @@ public:
        };
 
        ///
-       InsetSpecialChar() : Inset(nullptr), kind_("softhyphen"), 
unknown_(false) {}
+       InsetSpecialChar() : Inset(nullptr), kind_("softhyphen"), 
unknown_(false), lang_(nullptr){}
        ///
-       explicit InsetSpecialChar(Buffer * buf, std::string const & k);
+       explicit InsetSpecialChar(Buffer * buf, Language const * lang, 
std::string const & k);
        ///
        docstring toolTip(BufferView const & bv, int x, int y) const override;
        /// some special chars allow line breaking after them
@@ -117,6 +118,8 @@ private:
        SpecialChar sc_;
        /// Is this known?
        bool unknown_;
+       ///
+       Language * lang_;
 };
 
 
-- 
lyx-cvs mailing list
[email protected]
https://lists.lyx.org/mailman/listinfo/lyx-cvs

Reply via email to