From c51ebd9bbc01a23babccb7854623888093b3b8fe Mon Sep 17 00:00:00 2001 From: Guillaume Munch Date: Mon, 12 Oct 2015 23:31:15 +0100 Subject: [PATCH] Remove a deep copy of MathData in lyx::write This deep copy used to mess with the unique identifier: what TexRow saw was different from the original uid. There may also be performance improvements. (Using Georg's suggestion) --- src/mathed/InsetMathString.cpp | 92 +------------------------ src/mathed/MathExtern.cpp | 119 +++++++++++++++++++++++++++++++-- src/mathed/MathExtern.h | 3 + 3 files changed, 120 insertions(+), 94 deletions(-) diff --git a/src/mathed/InsetMathString.cpp b/src/mathed/InsetMathString.cpp index 53aba58989..d38a15e19c 100644 --- a/src/mathed/InsetMathString.cpp +++ b/src/mathed/InsetMathString.cpp @@ -11,7 +11,9 @@ #include #include "InsetMathString.h" + #include "MathFactory.h" +#include "MathExtern.h" #include "MathStream.h" #include "MathSupport.h" @@ -100,95 +102,7 @@ void InsetMathString::mathmlize(MathStream &) const void InsetMathString::write(WriteStream & os) const { - if (!os.latex() || os.lockedMode()) { - os << (os.asciiOnly() ? escape(str_) : str_); - return; - } - - docstring::const_iterator cit = str_.begin(); - docstring::const_iterator end = str_.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); - } + writeString(str_, os); } diff --git a/src/mathed/MathExtern.cpp b/src/mathed/MathExtern.cpp index b98097a7b5..7fbb4af732 100644 --- a/src/mathed/MathExtern.cpp +++ b/src/mathed/MathExtern.cpp @@ -35,12 +35,16 @@ #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 #include @@ -1382,17 +1386,122 @@ 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) { - // wi.startOuterRow(); - (*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.lockedMode()) { + os << (os.asciiOnly() ? escape(s) : s); + 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) diff --git a/src/mathed/MathExtern.h b/src/mathed/MathExtern.h index fba3ecbe9e..b6707f92a9 100644 --- a/src/mathed/MathExtern.h +++ b/src/mathed/MathExtern.h @@ -38,6 +38,9 @@ void octave(MathData const &, OctaveStream &); bool extractNumber(MathData const & ar, int & i); bool extractNumber(MathData const & ar, double & i); +/// Write \p s (which may contain math or text contents in LaTeX syntax) to \p os +void writeString(docstring const & s, WriteStream & os); + MathData pipeThroughExtern(std::string const & language, docstring const & extra, MathData const & ar);