]> git.lyx.org Git - lyx.git/blobdiff - src/Encoding.cpp
fix View Source for literate documents
[lyx.git] / src / Encoding.cpp
index 99d216f418c2048e70b2422bd49574d4613d13e1..afaff6db41397086b25075aec473695b6e596f0b 100644 (file)
@@ -14,6 +14,8 @@
 
 #include "Encoding.h"
 
+#include "Buffer.h"
+#include "InsetIterator.h"
 #include "LaTeXFeatures.h"
 #include "Lexer.h"
 #include "LyXRC.h"
@@ -34,6 +36,10 @@ namespace lyx {
 
 Encodings encodings;
 
+Encodings::MathCommandSet Encodings::mathcmd;
+Encodings::TextCommandSet Encodings::textcmd;
+Encodings::MathSymbolSet  Encodings::mathsym;
+
 namespace {
 
 char_type arabic_table[172][4] = {
@@ -250,6 +256,9 @@ CharInfoMap unicodesymbols;
 typedef std::set<char_type> CharSet;
 CharSet forced;
 
+typedef std::set<char_type> MathAlphaSet;
+MathAlphaSet mathalpha;
+
 
 /// The highest code point in UCS4 encoding (1<<20 + 1<<16)
 char_type const max_ucs4 = 0x110000;
@@ -377,25 +386,35 @@ vector<char_type> Encoding::symbolsList() const
 }
 
 
-bool Encodings::latexMathChar(char_type c, Encoding const * encoding,
-                               docstring & command)
+bool Encodings::latexMathChar(char_type c, bool mathmode,
+                       Encoding const * encoding, docstring & command)
 {
-       if (encoding) {
+       if (encoding)
                command = encoding->latexChar(c, true);
-               if (!command.empty())
-                       return false;
-       }
+
        CharInfoMap::const_iterator const it = unicodesymbols.find(c);
-       if (it == unicodesymbols.end())
-               throw EncodingException(c);
-       if (it->second.mathcommand.empty()) {
-               if (it->second.textcommand.empty())
+       if (it == unicodesymbols.end()) {
+               if (!encoding || command.empty())
                        throw EncodingException(c);
-               command = it->second.textcommand;
+               if (mathmode)
+                       addMathSym(c);
                return false;
        }
-       command = it->second.mathcommand;
-       return true;
+       // at least one of mathcommand and textcommand is nonempty
+       bool use_math = (mathmode && !it->second.mathcommand.empty()) ||
+                       (!mathmode && it->second.textcommand.empty());
+       if (use_math) {
+               command = it->second.mathcommand;
+               addMathCmd(c);
+       } else {
+               if (!encoding || command.empty()) {
+                       command = it->second.textcommand;
+                       addTextCmd(c);
+               }
+               if (mathmode)
+                       addMathSym(c);
+       }
+       return use_math;
 }
 
 
@@ -492,33 +511,61 @@ docstring Encodings::fromLaTeXCommand(docstring const & cmd, docstring & rem)
 }
 
 
+void Encodings::initUnicodeMath(Buffer const & buffer)
+{
+       mathcmd.clear();
+       textcmd.clear();
+       mathsym.clear();
+
+       Inset & inset = buffer.inset();
+       InsetIterator it = inset_iterator_begin(inset);
+       InsetIterator const end = inset_iterator_end(inset);
+
+       for (; it != end; ++it)
+               it->initUnicodeMath();
+}
+
+
 void Encodings::validate(char_type c, LaTeXFeatures & features, bool for_mathed)
 {
        CharInfoMap::const_iterator const it = unicodesymbols.find(c);
        if (it != unicodesymbols.end()) {
-               // at least one of mathcommand and textcommand is nonempty
-               bool const use_math = (for_mathed && !it->second.mathcommand.empty()) ||
+               // In mathed, c could be used both in textmode and mathmode
+               bool const use_math = (for_mathed && isMathCmd(c)) ||
                                      (!for_mathed && it->second.textcommand.empty());
+               bool const use_text = (for_mathed && isTextCmd(c)) ||
+                                     (!for_mathed && !it->second.textcommand.empty());
                if (use_math) {
                        if (!it->second.mathpreamble.empty()) {
-                               if (it->second.mathfeature)
-                                       features.require(it->second.mathpreamble);
-                               else
+                               if (it->second.mathfeature) {
+                                       string feats = it->second.mathpreamble;
+                                       while (!feats.empty()) {
+                                               string feat;
+                                               feats = split(feats, feat, ',');
+                                               features.require(feat);
+                                       }
+                               } else
                                        features.addPreambleSnippet(it->second.mathpreamble);
                        }
-               } else {
+               }
+               if (use_text) {
                        if (!it->second.textpreamble.empty()) {
-                               if (it->second.textfeature)
-                                       features.require(it->second.textpreamble);
-                               else
+                               if (it->second.textfeature) {
+                                       string feats = it->second.textpreamble;
+                                       while (!feats.empty()) {
+                                               string feat;
+                                               feats = split(feats, feat, ',');
+                                               features.require(feat);
+                                       }
+                               } else
                                        features.addPreambleSnippet(it->second.textpreamble);
                        }
-                       if (for_mathed) {
-                               features.require("relsize");
-                               features.require("lyxmathsym");
-                       }
                }
        }
+       if (for_mathed && isMathSym(c)) {
+               features.require("relsize");
+               features.require("lyxmathsym");
+       }
 }
 
 
@@ -592,6 +639,12 @@ bool Encodings::isForced(char_type c)
 }
 
 
+bool Encodings::isMathAlpha(char_type c)
+{
+       return mathalpha.count(c);
+}
+
+
 Encoding const * Encodings::fromLyXName(string const & name) const
 {
        EncodingList::const_iterator const it = encodinglist.find(name);
@@ -661,16 +714,19 @@ void Encodings::read(FileName const & encfile, FileName const & symbolsfile)
                while (!flags.empty()) {
                        string flag;
                        flags = split(flags, flag, ',');
-                       if (flag == "combining")
+                       if (flag == "combining") {
                                info.combining = true;
-                       else if (flag == "force") {
+                       else if (flag == "force") {
                                info.force = true;
                                forced.insert(symbol);
-                       } else
+                       } else if (flag == "mathalpha") {
+                               mathalpha.insert(symbol);
+                       } else {
                                lyxerr << "Ignoring unknown flag `" << flag
                                       << "' for symbol `0x"
                                       << hex << symbol << dec
                                       << "'." << endl;
+                       }
                }
                // mathcommand and mathpreamble have been added for 1.6.0.
                // make them optional so that old files still work.