From 98080ca0d548b754433a99f9f097054134117184 Mon Sep 17 00:00:00 2001 From: Juergen Spitzmueller Date: Tue, 2 Apr 2024 08:15:53 +0200 Subject: [PATCH] Fix label escaping in InsetMathRef (#12980) This was completely broken: the IDs have been escaped in the LyX file (which they absolutely shouldn't) but not in all LaTeX output (which they should). --- src/insets/InsetCommandParams.cpp | 9 ++++++--- src/insets/InsetCommandParams.h | 2 +- src/mathed/InsetMathRef.cpp | 22 ++++++++++++---------- src/mathed/MathExtern.cpp | 15 ++++++++++----- src/mathed/MathFactory.cpp | 2 +- 5 files changed, 30 insertions(+), 20 deletions(-) diff --git a/src/insets/InsetCommandParams.cpp b/src/insets/InsetCommandParams.cpp index 034f9d59c8..9c3552a4b7 100644 --- a/src/insets/InsetCommandParams.cpp +++ b/src/insets/InsetCommandParams.cpp @@ -569,7 +569,7 @@ docstring InsetCommandParams::prepareCommand(OutputParams const & runparams, } -docstring InsetCommandParams::getCommand(OutputParams const & runparams, bool starred) const +docstring InsetCommandParams::getCommand(OutputParams const & runparams, bool starred, bool unhandled) const { docstring s = '\\' + from_ascii(cmdName_); if (starred) @@ -579,20 +579,23 @@ docstring InsetCommandParams::getCommand(OutputParams const & runparams, bool st ParamInfo::const_iterator end = info_.end(); for (; it != end; ++it) { std::string const & name = it->name(); + ParamInfo::ParamHandling handling = unhandled ? + ParamInfo::HANDLING_NONE + : it->handling(); switch (it->type()) { case ParamInfo::LYX_INTERNAL: break; case ParamInfo::LATEX_REQUIRED: { docstring const data = - prepareCommand(runparams, (*this)[name], it->handling()); + prepareCommand(runparams, (*this)[name], handling); s += '{' + data + '}'; noparam = false; break; } case ParamInfo::LATEX_OPTIONAL: { docstring data = - prepareCommand(runparams, (*this)[name], it->handling()); + prepareCommand(runparams, (*this)[name], handling); if (!data.empty()) { s += '[' + protectArgument(data) + ']'; noparam = false; diff --git a/src/insets/InsetCommandParams.h b/src/insets/InsetCommandParams.h index 134b46a604..f05fb61ddc 100644 --- a/src/insets/InsetCommandParams.h +++ b/src/insets/InsetCommandParams.h @@ -136,7 +136,7 @@ public: /// void Write(std::ostream & os, Buffer const * buf) const; /// Build the complete LaTeX command - docstring getCommand(OutputParams const &, bool starred = false) const; + docstring getCommand(OutputParams const &, bool starred = false, bool unhandled = false) const; /// Return the command name std::string const & getCmdName() const { return cmdName_; } /// Set the name to \p n. This must be a known name. All parameters diff --git a/src/mathed/InsetMathRef.cpp b/src/mathed/InsetMathRef.cpp index ad2e499167..082a341cf4 100644 --- a/src/mathed/InsetMathRef.cpp +++ b/src/mathed/InsetMathRef.cpp @@ -76,7 +76,7 @@ void InsetMathRef::doDispatch(Cursor & cur, FuncRequest & cmd) switch (cmd.action()) { case LFUN_INSET_MODIFY: { string const arg0 = cmd.getArg(0); - string const arg1 = cmd.getArg(1); + string const arg1 = cmd.getArg(1); if (arg0 == "ref") { if (arg1 == "changetarget") { string const oldtarget = cmd.getArg(2); @@ -295,25 +295,27 @@ void InsetMathRef::write(TeXMathStream & os) const LYXERR0("Unassigned buffer_ in InsetMathRef::write!"); LYXERR0("LaTeX output may be wrong!"); } + // are we writing to the LyX file? + if (!os.latex()) { + // if so, then this is easy + InsetMathCommand::write(os); + return; + } bool const use_refstyle = buffer_ && buffer().params().use_refstyle; bool special_case = cmd == "formatted" || cmd == "labelonly" || (cmd == "eqref" && use_refstyle); - // are we writing to the LyX file or not in a special case? - if (!os.latex() || !special_case) { - // if so, then this is easy - InsetMathCommand::write(os); - return; - } // we need to translate 'formatted' to prettyref or refstyle-type // commands and just output the label with labelonly // most of this is borrowed from InsetRef and should be kept in // sync with that. ModeSpecifier specifier(os, currentMode(), lockedMode(), asciiOnly()); MathEnsurer ensurer(os, false); - - if (use_refstyle && cmd == "eqref") { + if (!special_case) { + os << from_ascii("\\") << cmd << "{" << cell(0) << from_ascii("}"); + } + else if (use_refstyle && cmd == "eqref") { // we advertise this as printing "(n)", so we'll do that, at least // for refstyle, since refstlye's own \eqref prints, by default, // "equation n". if one wants \eqref, one can get it by using a @@ -324,7 +326,7 @@ void InsetMathRef::write(TeXMathStream & os) const if (!use_refstyle) os << "\\prettyref{" << cell(0) << "}"; else { - odocstringstream ods; + odocstringstream ods; // get the label we are referencing for (auto const & d : cell(0)) { ods << d; diff --git a/src/mathed/MathExtern.cpp b/src/mathed/MathExtern.cpp index e273aac791..610878455e 100644 --- a/src/mathed/MathExtern.cpp +++ b/src/mathed/MathExtern.cpp @@ -1463,18 +1463,23 @@ void write(MathData const & dat, TeXMathStream & wi) void writeString(docstring const & s, TeXMathStream & os) { if (!os.latex()) { - os << (os.asciiOnly() ? escape(s) : s); + os << s; return; } - else if (os.output() == TeXMathStream::wsSearchAdv) { - os << s; + + docstring str = s; + if (os.asciiOnly()) + str = escape(s); + + if (os.output() == TeXMathStream::wsSearchAdv) { + os << str; return; } if (os.lockedMode()) { bool space; docstring cmd; - for (char_type c : s) { + for (char_type c : str) { try { Encodings::latexMathChar(c, true, os.encoding(), cmd, space); os << cmd; @@ -1512,7 +1517,7 @@ void writeString(docstring const & s, TeXMathStream & os) // We will take care of matching braces. os.pendingBrace(false); - for (char_type const c : s) { + for (char_type const c : str) { bool mathmode = in_forced_mode ? os.textMode() : !os.textMode(); docstring command(1, c); try { diff --git a/src/mathed/MathFactory.cpp b/src/mathed/MathFactory.cpp index 66535beb8d..299cf00c05 100644 --- a/src/mathed/MathFactory.cpp +++ b/src/mathed/MathFactory.cpp @@ -703,7 +703,7 @@ bool createInsetMath_fromDialogStr(docstring const & str, MathData & ar) InsetCommand::string2params(to_utf8(str), icp); Encoding const * const utf8 = encodings.fromLyXName("utf8"); OutputParams op(utf8); - mathed_parse_cell(ar, icp.getCommand(op)); + mathed_parse_cell(ar, icp.getCommand(op, false, true)); } else if (name == "mathspace") { InsetSpaceParams isp(true); InsetSpace::string2params(to_utf8(str), isp); -- 2.39.5