X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fmathed%2FMathExtern.cpp;h=e911f0babf24bc71897915e824440da90a4de811;hb=f6282dfec7c7d53fd92d7270f8806a39a9c5d75b;hp=2ac732bd7e01462287d8c45c9f926077baf8892a;hpb=ff91db5eceafd01668541d742d3ab549ae19cb82;p=lyx.git diff --git a/src/mathed/MathExtern.cpp b/src/mathed/MathExtern.cpp index 2ac732bd7e..e911f0babf 100644 --- a/src/mathed/MathExtern.cpp +++ b/src/mathed/MathExtern.cpp @@ -35,11 +35,17 @@ #include "MathParser.h" #include "MathStream.h" +#include "Encoding.h" + #include "support/debug.h" #include "support/docstream.h" #include "support/FileName.h" #include "support/filetools.h" +#include "support/gettext.h" #include "support/lstrings.h" +#include "support/TempFile.h" +#include "support/textutils.h" +#include "support/unique_ptr.h" #include #include @@ -109,7 +115,7 @@ bool extractScript(MathData & ar, // try to extract an "argument" to some function. // returns position behind the argument MathData::iterator extractArgument(MathData & ar, - MathData::iterator pos, MathData::iterator last, + MathData::iterator pos, MathData::iterator last, ExternalMath kind, bool function = false) { // nothing to get here @@ -205,7 +211,7 @@ void extractMatrices(MathData & ar) continue; if (!arr.front()->asGridInset()) continue; - ar[i] = MathAtom(new InsetMathMatrix(*(arr.front()->asGridInset()), + ar[i] = MathAtom(new InsetMathMatrix(*(arr.front()->asGridInset()), inset->left_, inset->right_)); } @@ -365,7 +371,7 @@ void splitScripts(MathData & ar) // create extra script inset and move superscript over InsetMathScript * p = ar[i].nucleus()->asScriptInset(); - auto_ptr q(new InsetMathScript(buf, true)); + auto q = make_unique(buf, true); swap(q->up(), p->up()); p->removeScript(true); @@ -593,10 +599,10 @@ void extractFunctions(MathData & ar, ExternalMath kind) extractScript(exp, jt, ar.end(), true); // create a proper inset as replacement - auto_ptr p(new InsetMathExFunc(buf, name)); + auto p = make_unique(buf, name); // jt points to the "argument". Get hold of this. - MathData::iterator st = + MathData::iterator st = extractArgument(p->cell(0), jt, ar.end(), kind, true); // replace the function name by a real function inset @@ -678,7 +684,7 @@ void extractIntegrals(MathData & ar, ExternalMath kind) continue; // core ist part from behind the scripts to the 'd' - auto_ptr p(new InsetMathExInt(buf, from_ascii("int"))); + auto p = make_unique(buf, from_ascii("int")); // handle scripts if available if (!testIntSymbol(*it)) { @@ -763,7 +769,7 @@ void extractSums(MathData & ar) continue; // create a proper inset as replacement - auto_ptr p(new InsetMathExInt(buf, from_ascii("sum"))); + auto p = make_unique(buf, from_ascii("sum")); // collect lower bound and summation index InsetMathScript const * sub = ar[i]->asScriptInset(); @@ -851,7 +857,7 @@ void extractDiff(MathData & ar) } // create a proper diff inset - auto_ptr diff(new InsetMathDiff(buf)); + auto diff = make_unique(buf); // collect function, let jt point behind last used item MathData::iterator jt = it + 1; @@ -890,6 +896,10 @@ void extractDiff(MathData & ar) int mult = 1; if (extractNumber(script->up(), mult)) { //lyxerr << "mult: " << mult << endl; + if (mult < 0 || mult > 1000) { + lyxerr << "Cannot differentiate less than 0 or more than 1000 times !" << endl; + continue; + } for (int i = 0; i < mult; ++i) diff->addDer(MathData(buf, dt + 1, st)); } @@ -977,8 +987,8 @@ void extractStructure(MathData & ar, ExternalMath kind) extractSums(ar); extractNumbers(ar); extractMatrices(ar); - extractFunctions(ar, kind); if (kind != MATHML && kind != HTML) { + extractFunctions(ar, kind); extractDets(ar); extractDiff(ar); extractExps(ar); @@ -995,7 +1005,13 @@ namespace { { // In order to avoid parsing problems with command interpreters // we pass input data through a file - FileName const cas_tmpfile = FileName::tempName("casinput"); + // Since the CAS is supposed to read the temp file we need + // to unlock it on windows (bug 10262). + unique_ptr tempfile(new TempFile("casinput")); + tempfile->setAutoRemove(false); + FileName const cas_tmpfile = tempfile->name(); + tempfile.reset(); + if (cas_tmpfile.empty()) { lyxerr << "Warning: cannot create temporary file." << endl; @@ -1100,7 +1116,7 @@ namespace { if (tmp.size() < 2) return MathData(); - out = subst(tmp[1], "\\>", string()); + out = subst(subst(tmp[1], "\\>", string()), "{\\it ", "\\mathit{"); lyxerr << "output: '" << out << "'" << endl; // Ugly code that tries to make the result prettier @@ -1118,7 +1134,6 @@ namespace { + out.substr(k + 1); //lyxerr << "output: " << out << endl; i = out.find("\\mathchoice", i); - break; } i = out.find("\\over"); @@ -1196,7 +1211,7 @@ namespace { istringstream is(out); string line; getline(is, line); - if (line.find("on line") != 0) + if (!prefixIs(line, "on line")) break; // error message not identified getline(is, line); size_t pos = line.find('^'); @@ -1376,22 +1391,163 @@ namespace { return res; } -} +} // namespace -} // anon namespace +} // namespace void write(MathData const & dat, WriteStream & wi) { - MathData ar = dat; - extractStrings(ar); wi.firstitem() = true; - for (MathData::const_iterator it = ar.begin(); it != ar.end(); ++it) { - (*it)->write(wi); + docstring s; + for (MathData::const_iterator it = dat.begin(); it != dat.end(); ++it) { + InsetMathChar const * const c = (*it)->asCharInset(); + if (c) + s += c->getChar(); + else { + if (!s.empty()) { + writeString(s, wi); + s.clear(); + } + (*it)->write(wi); + wi.firstitem() = false; + } + } + if (!s.empty()) { + writeString(s, wi); wi.firstitem() = false; } } +void writeString(docstring const & s, WriteStream & os) +{ + if (!os.latex()) { + os << (os.asciiOnly() ? escape(s) : s); + return; + } + + if (os.lockedMode()) { + bool space; + docstring cmd; + for (char_type c : s) { + try { + Encodings::latexMathChar(c, true, os.encoding(), cmd, space); + os << cmd; + os.pendingSpace(space); + } catch (EncodingException const & e) { + switch (os.output()) { + case WriteStream::wsDryrun: { + os << "<" << _("LyX Warning: ") + << _("uncodable character") << " '"; + os << docstring(1, e.failed_char); + os << "'>"; + break; + } + case WriteStream::wsPreview: { + // indicate the encoding error by a boxed '?' + os << "{\\fboxsep=1pt\\fbox{?}}"; + LYXERR0("Uncodable character" << " '" + << docstring(1, e.failed_char) + << "'"); + break; + } + case WriteStream::wsDefault: + default: + // throw again + throw(e); + } + } + } + return; + } + + docstring::const_iterator cit = s.begin(); + docstring::const_iterator end = s.end(); + + // We may already be inside an \ensuremath command. + bool in_forced_mode = os.pendingBrace(); + + // We will take care of matching braces. + os.pendingBrace(false); + + while (cit != end) { + bool mathmode = in_forced_mode ? os.textMode() : !os.textMode(); + char_type const c = *cit; + docstring command(1, c); + try { + bool termination = false; + if (isASCII(c) || + Encodings::latexMathChar(c, mathmode, os.encoding(), command, termination)) { + if (os.textMode()) { + if (in_forced_mode) { + // we were inside \lyxmathsym + os << '}'; + os.textMode(false); + in_forced_mode = false; + } + if (!isASCII(c) && os.textMode()) { + os << "\\ensuremath{"; + os.textMode(false); + in_forced_mode = true; + } + } else if (isASCII(c) && in_forced_mode) { + // we were inside \ensuremath + os << '}'; + os.textMode(true); + in_forced_mode = false; + } + } else if (!os.textMode()) { + if (in_forced_mode) { + // we were inside \ensuremath + os << '}'; + in_forced_mode = false; + } else { + os << "\\lyxmathsym{"; + in_forced_mode = true; + } + os.textMode(true); + } + os << command; + // We may need a space if the command contains a macro + // and the last char is ASCII. + if (termination) + os.pendingSpace(true); + } catch (EncodingException const & e) { + switch (os.output()) { + case WriteStream::wsDryrun: { + os << "<" << _("LyX Warning: ") + << _("uncodable character") << " '"; + os << docstring(1, e.failed_char); + os << "'>"; + break; + } + case WriteStream::wsPreview: { + // indicate the encoding error by a boxed '?' + os << "{\\fboxsep=1pt\\fbox{?}}"; + LYXERR0("Uncodable character" << " '" + << docstring(1, e.failed_char) + << "'"); + break; + } + case WriteStream::wsDefault: + default: + // throw again + throw(e); + } + } + ++cit; + } + + if (in_forced_mode && os.textMode()) { + // We have to care for closing \lyxmathsym + os << '}'; + os.textMode(false); + } else { + os.pendingBrace(in_forced_mode); + } +} + + void normalize(MathData const & ar, NormalStream & os) { for (MathData::const_iterator it = ar.begin(); it != ar.end(); ++it) @@ -1472,7 +1628,8 @@ bool extractNumber(MathData const & ar, int & i) { idocstringstream is(charSequence(ar.begin(), ar.end())); is >> i; - return is; + // Do not convert is implicitly to bool, since that is forbidden in C++11. + return !is.fail(); } @@ -1480,7 +1637,8 @@ bool extractNumber(MathData const & ar, double & d) { idocstringstream is(charSequence(ar.begin(), ar.end())); is >> d; - return is; + // Do not convert is implicitly to bool, since that is forbidden in C++11. + return !is.fail(); }