From 5dc9568f8d7e1eea485658a9a6d2e0f12114ddaa Mon Sep 17 00:00:00 2001 From: Georg Baum Date: Tue, 27 May 2014 22:10:02 +0200 Subject: [PATCH] Native support for \smash[t] and \smash[b] This is a follow-up of bug #8967. The implementation is self-explaining, the only part which needs a comment is lyx2lyx: Since a 100% correct solution is not possible, it has been decided not to switch amsmath off in the forward conversion if no other ams command than \smash[t] and \smash[b] is used, but to consider it a bug that older versions do not load amsmath automatically for these commands. In the backward direction it is easy to keep the document compilable, so just do that. --- development/FORMAT | 5 ++ lib/Makefile.am | 2 + lib/images/math/smashb.png | Bin 0 -> 227 bytes lib/images/math/smasht.png | Bin 0 -> 227 bytes lib/lyx2lyx/LyX.py | 2 +- lib/lyx2lyx/lyx_2_2.py | 36 +++++++++++++++ lib/ui/stdtoolbars.inc | 2 + src/mathed/InsetMathPhantom.cpp | 43 +++++++++++++++--- src/mathed/InsetMathPhantom.h | 2 + src/mathed/MathFactory.cpp | 5 ++ src/mathed/MathParser.cpp | 24 ++++++---- src/tex2lyx/test/CJK.lyx.lyx | 2 +- src/tex2lyx/test/CJKutf8.lyx.lyx | 2 +- src/tex2lyx/test/DummyDocument.lyx.lyx | 2 +- src/tex2lyx/test/Dummy~Document.lyx.lyx | 2 +- src/tex2lyx/test/XeTeX-polyglossia.lyx.lyx | 2 +- src/tex2lyx/test/algo2e.lyx.lyx | 2 +- .../test/box-color-size-space-align.lyx.lyx | 2 +- src/tex2lyx/test/test-insets.lyx.lyx | 2 +- src/tex2lyx/test/test-modules.lyx.lyx | 2 +- .../test/test-refstyle-theorems.lyx.lyx | 2 +- src/tex2lyx/test/test-structure.lyx.lyx | 2 +- src/tex2lyx/test/test.lyx.lyx | 2 +- src/tex2lyx/test/verbatim.lyx.lyx | 2 +- src/version.h | 4 +- 25 files changed, 120 insertions(+), 31 deletions(-) create mode 100644 lib/images/math/smashb.png create mode 100644 lib/images/math/smasht.png diff --git a/development/FORMAT b/development/FORMAT index 74cd8ce697..51bc639c95 100644 --- a/development/FORMAT +++ b/development/FORMAT @@ -11,6 +11,11 @@ adjustments are made to tex2lyx and bugs are fixed in lyx2lyx. ----------------------- +2013-05-27 Georg Baum + * Format incremented to 476 + Native support for \smash[t] and \smash[b] with automatic amsmath + loading + 2014-05-05 Enrico Forestieri * Format incremented to 475 New Separator insets. The parbreak separator introduces a LaTeX diff --git a/lib/Makefile.am b/lib/Makefile.am index 6188f87e12..1aaec8b9d1 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -1180,6 +1180,8 @@ dist_imagesmath_DATA = \ images/math/smallsetminus.png \ images/math/smallsmile.png \ images/math/smash.png \ + images/math/smashb.png \ + images/math/smasht.png \ images/math/smile.png \ images/math/smiley.png \ images/math/space.png \ diff --git a/lib/images/math/smashb.png b/lib/images/math/smashb.png new file mode 100644 index 0000000000000000000000000000000000000000..f64629e581549375eb3c3f8a3c1fb540531f2554 GIT binary patch literal 227 zcmeAS@N?(olHy`uVBq!ia0vp@KrGC`1|+@B+ouC5wj^(N7l!{JxM1({$v_d#0*}aI z1_o|n5N2eUHAey{$X?><>&kwQRf1PbbIzIvFMvV?o-U3d8t1o8cH}#tz`-K<@Bj0+ zuF>8HB9eFJa2$*bn3xiOIM?_}#%Zri{xe;(n7yRkYNvX5%oQm0>S}M1nc%IoHSEcx z1-VP}d_3CIZrzJBPD@J>TmANBUd)`8!g9Rbr_z$9Jzp|WV*R7};dQ@+<5I6RKi-f$ Rrx$29gQu&X%Q~loCIDz}PtX7W literal 0 HcmV?d00001 diff --git a/lib/images/math/smasht.png b/lib/images/math/smasht.png new file mode 100644 index 0000000000000000000000000000000000000000..b957c48e2bd67f77ffa67b1f971931352728b04f GIT binary patch literal 227 zcmeAS@N?(olHy`uVBq!ia0vp@KrGC`1|+@B+ouC5wj^(N7l!{JxM1({$v_d#0*}aI z1_o|n5N2eUHAey{$X?><>&kwQRf1R3%GmzXSD;XVr;B5V#`&$2J%tV^aIn1m^Z)!@ zZ?lOxVTW3svfl^_n%+Am()`e=dXD8*_O_r~%sMQ&dD{w%=CcWE$67D+@;_A;Tg12|Q~Uq57$;eET;CG9 R+yZDfgQu&X%Q~loCIIP`PHO-F literal 0 HcmV?d00001 diff --git a/lib/lyx2lyx/LyX.py b/lib/lyx2lyx/LyX.py index e7b2186706..e37691f273 100644 --- a/lib/lyx2lyx/LyX.py +++ b/lib/lyx2lyx/LyX.py @@ -85,7 +85,7 @@ format_relation = [("0_06", [200], minor_versions("0.6" , 4)), ("1_6", range(277,346), minor_versions("1.6" , 10)), ("2_0", range(346,414), minor_versions("2.0", 8)), ("2_1", range(414,475), minor_versions("2.1", 0)), - ("2_2", range(475,476), minor_versions("2.2", 0)) + ("2_2", range(475,477), minor_versions("2.2", 0)) ] #################################################################### diff --git a/lib/lyx2lyx/lyx_2_2.py b/lib/lyx2lyx/lyx_2_2.py index 64ff1086b4..517c8978d5 100644 --- a/lib/lyx2lyx/lyx_2_2.py +++ b/lib/lyx2lyx/lyx_2_2.py @@ -244,6 +244,37 @@ def revert_separator(document): i = i + 1 +def revert_smash(document): + " Set amsmath to on if smash commands are used " + + commands = ["smash[t]", "smash[b]"] + i = find_token(document.header, "\\use_package amsmath", 0) + if i == -1: + document.warning("Malformed LyX document: Can't find \\use_package amsmath.") + return; + value = get_value(document.header, "\\use_package amsmath", i).split()[1] + if value != "1": + # nothing to do if package is not auto but on or off + return; + j = 0 + while True: + j = find_token(document.body, '\\begin_inset Formula', j) + if j == -1: + return + k = find_end_of_inset(document.body, j) + if k == -1: + document.warning("Malformed LyX document: Can't find end of Formula inset at line " + str(j)) + j += 1 + continue + code = "\n".join(document.body[j:k]) + for c in commands: + if code.find("\\%s" % c) != -1: + # set amsmath to on, since it is loaded by the newer format + document.header[i] = "\\use_package amsmath 2" + return + j = k + + ## # Conversion hub # @@ -251,9 +282,14 @@ def revert_separator(document): supported_versions = ["2.2.0","2.2"] convert = [ [475, [convert_separator]], + # nothing to do for 476: We consider it a bug that older versions + # did not load amsmath automatically for these commands, and do not + # want to hardcode amsmath off. + [476, []], ] revert = [ + [475, [revert_smash]], [474, [revert_separator]] ] diff --git a/lib/ui/stdtoolbars.inc b/lib/ui/stdtoolbars.inc index e8ce0b9b39..163beab99b 100644 --- a/lib/ui/stdtoolbars.inc +++ b/lib/ui/stdtoolbars.inc @@ -353,6 +353,8 @@ ToolbarSet Item "Horizontal phantom \\hphantom" "math-insert \hphantom" Item "Vertical phantom \\vphantom" "math-insert \vphantom" Item "Smash \\smash" "math-insert \smash" + Item "Top smash \\smasht" "math-insert \smasht" + Item "Bottom smash \\smashb" "math-insert \smashb" Item "Left overlap \\mathllap" "math-insert \mathllap" Item "Center overlap \\mathclap" "math-insert \mathclap" Item "Right overlap \\mathrlap" "math-insert \mathrlap" diff --git a/src/mathed/InsetMathPhantom.cpp b/src/mathed/InsetMathPhantom.cpp index b8c965b21c..9d6295bb06 100644 --- a/src/mathed/InsetMathPhantom.cpp +++ b/src/mathed/InsetMathPhantom.cpp @@ -197,7 +197,7 @@ void InsetMathPhantom::draw(PainterInfo & pi, int x, int y) const pi.pain.line(x1, y2, x3, y2, Color_added_space); } - else if (kind_ == smash) { + else if (kind_ == smash || kind_ == smasht || kind_ == smashb) { // y1--------- // | // y2----- \ | / @@ -222,15 +222,24 @@ void InsetMathPhantom::draw(PainterInfo & pi, int x, int y) const int const y4 = std::min(y5, y3 + arrow_size); // top arrow - pi.pain.line(x1, y2, x2, y3, Color_added_space); - pi.pain.line(x3, y2, x2, y3, Color_added_space); + if (kind_ != smashb) { + pi.pain.line(x1, y2, x2, y3, Color_added_space); + pi.pain.line(x3, y2, x2, y3, Color_added_space); + } // bottom arrow - pi.pain.line(x1, y4, x2, y3, Color_added_space); - pi.pain.line(x3, y4, x2, y3, Color_added_space); + if (kind_ != smasht) { + pi.pain.line(x1, y4, x2, y3, Color_added_space); + pi.pain.line(x3, y4, x2, y3, Color_added_space); + } // joining line - pi.pain.line(x2, y1, x2, y5, Color_added_space); + if (kind_ == smasht) + pi.pain.line(x2, y1, x2, y3, Color_added_space); + else if (kind_ == smashb) + pi.pain.line(x2, y3, x2, y5, Color_added_space); + else + pi.pain.line(x2, y1, x2, y5, Color_added_space); } drawMarkers(pi, x, y); @@ -255,6 +264,12 @@ void InsetMathPhantom::write(WriteStream & os) const case smash: os << "\\smash{"; break; + case smasht: + os << "\\smash[t]{"; + break; + case smashb: + os << "\\smash[b]{"; + break; case mathclap: os << "\\mathclap{"; break; @@ -284,6 +299,12 @@ void InsetMathPhantom::normalize(NormalStream & os) const case smash: os << "[smash "; break; + case smasht: + os << "[smasht "; + break; + case smashb: + os << "[smashb "; + break; case mathclap: os << "[mathclap "; break; @@ -313,6 +334,12 @@ void InsetMathPhantom::infoize(odocstream & os) const case smash: os << "Smash"; break; + case smasht: + os << "Smashtop"; + break; + case smashb: + os << "Smashbottom"; + break; case mathllap: os << "Mathllap"; break; @@ -335,6 +362,10 @@ void InsetMathPhantom::validate(LaTeXFeatures & features) const case hphantom: case smash: break; + case smasht: + case smashb: + features.require("amsmath"); + break; case mathclap: case mathllap: case mathrlap: diff --git a/src/mathed/InsetMathPhantom.h b/src/mathed/InsetMathPhantom.h index 8221171b1d..63b8ea28de 100644 --- a/src/mathed/InsetMathPhantom.h +++ b/src/mathed/InsetMathPhantom.h @@ -25,6 +25,8 @@ public: vphantom, hphantom, smash, + smasht, + smashb, mathclap, mathllap, mathrlap diff --git a/src/mathed/MathFactory.cpp b/src/mathed/MathFactory.cpp index d19899866f..85fdf47856 100644 --- a/src/mathed/MathFactory.cpp +++ b/src/mathed/MathFactory.cpp @@ -561,6 +561,11 @@ MathAtom createInsetMath(docstring const & s, Buffer * buf) return MathAtom(new InsetMathCancelto(buf)); if (s == "smash") return MathAtom(new InsetMathPhantom(buf, InsetMathPhantom::smash)); + // The following 2 string values are only for math toolbar use, no LaTeX names + if (s == "smashb") + return MathAtom(new InsetMathPhantom(buf, InsetMathPhantom::smashb)); + if (s == "smasht") + return MathAtom(new InsetMathPhantom(buf, InsetMathPhantom::smasht)); if (s == "mathclap") return MathAtom(new InsetMathPhantom(buf, InsetMathPhantom::mathclap)); if (s == "mathllap") diff --git a/src/mathed/MathParser.cpp b/src/mathed/MathParser.cpp index 1c7f2ff0ad..234bfd8728 100644 --- a/src/mathed/MathParser.cpp +++ b/src/mathed/MathParser.cpp @@ -1849,16 +1849,22 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags, skipSpaces(); if (nextToken().asInput() == "[") { // Since the phantom inset cannot handle optional arguments - // we must not create an InsetMathPhantom (bug 8967). + // other than b and t, we must not create an InsetMathPhantom + // if opt is different from b and t (bug 8967). docstring const opt = parse_verbatim_option(); - docstring const arg = parse_verbatim_item(); - cell->push_back(MathAtom(new MathMacro(buf, t.cs()))); - MathData ar; - mathed_parse_cell(ar, '[' + opt + ']', mode_); - cell->append(ar); - ar = MathData(); - mathed_parse_cell(ar, '{' + arg + '}', mode_); - cell->append(ar); + if (opt == "t" || opt == "b") { + cell->push_back(createInsetMath(t.cs() + opt, buf)); + parse(cell->back().nucleus()->cell(0), FLAG_ITEM, mode); + } else { + docstring const arg = parse_verbatim_item(); + cell->push_back(MathAtom(new MathMacro(buf, t.cs()))); + MathData ar; + mathed_parse_cell(ar, '[' + opt + ']', mode_); + cell->append(ar); + ar = MathData(); + mathed_parse_cell(ar, '{' + arg + '}', mode_); + cell->append(ar); + } } else { cell->push_back(createInsetMath(t.cs(), buf)); diff --git a/src/tex2lyx/test/CJK.lyx.lyx b/src/tex2lyx/test/CJK.lyx.lyx index a113614ef5..f934830c68 100644 --- a/src/tex2lyx/test/CJK.lyx.lyx +++ b/src/tex2lyx/test/CJK.lyx.lyx @@ -1,5 +1,5 @@ #LyX file created by tex2lyx 2.2 -\lyxformat 475 +\lyxformat 476 \begin_document \begin_header \textclass article diff --git a/src/tex2lyx/test/CJKutf8.lyx.lyx b/src/tex2lyx/test/CJKutf8.lyx.lyx index 6330530e56..0834a8e3c0 100644 --- a/src/tex2lyx/test/CJKutf8.lyx.lyx +++ b/src/tex2lyx/test/CJKutf8.lyx.lyx @@ -1,5 +1,5 @@ #LyX file created by tex2lyx 2.2 -\lyxformat 475 +\lyxformat 476 \begin_document \begin_header \textclass article diff --git a/src/tex2lyx/test/DummyDocument.lyx.lyx b/src/tex2lyx/test/DummyDocument.lyx.lyx index 58a18f2b6a..50b105eb1d 100644 --- a/src/tex2lyx/test/DummyDocument.lyx.lyx +++ b/src/tex2lyx/test/DummyDocument.lyx.lyx @@ -1,5 +1,5 @@ #LyX file created by tex2lyx 2.2 -\lyxformat 475 +\lyxformat 476 \begin_document \begin_header \textclass article diff --git a/src/tex2lyx/test/Dummy~Document.lyx.lyx b/src/tex2lyx/test/Dummy~Document.lyx.lyx index 7e97f2b2d9..f379c6ef69 100644 --- a/src/tex2lyx/test/Dummy~Document.lyx.lyx +++ b/src/tex2lyx/test/Dummy~Document.lyx.lyx @@ -1,5 +1,5 @@ #LyX file created by tex2lyx 2.2 -\lyxformat 475 +\lyxformat 476 \begin_document \begin_header \textclass article diff --git a/src/tex2lyx/test/XeTeX-polyglossia.lyx.lyx b/src/tex2lyx/test/XeTeX-polyglossia.lyx.lyx index 8864033a97..2917ee21ed 100644 --- a/src/tex2lyx/test/XeTeX-polyglossia.lyx.lyx +++ b/src/tex2lyx/test/XeTeX-polyglossia.lyx.lyx @@ -1,5 +1,5 @@ #LyX file created by tex2lyx 2.2 -\lyxformat 475 +\lyxformat 476 \begin_document \begin_header \textclass article diff --git a/src/tex2lyx/test/algo2e.lyx.lyx b/src/tex2lyx/test/algo2e.lyx.lyx index 5b8db5b245..e3ac0cb2b6 100644 --- a/src/tex2lyx/test/algo2e.lyx.lyx +++ b/src/tex2lyx/test/algo2e.lyx.lyx @@ -1,5 +1,5 @@ #LyX file created by tex2lyx 2.2 -\lyxformat 475 +\lyxformat 476 \begin_document \begin_header \textclass article diff --git a/src/tex2lyx/test/box-color-size-space-align.lyx.lyx b/src/tex2lyx/test/box-color-size-space-align.lyx.lyx index f4c97b1571..4199340333 100644 --- a/src/tex2lyx/test/box-color-size-space-align.lyx.lyx +++ b/src/tex2lyx/test/box-color-size-space-align.lyx.lyx @@ -1,5 +1,5 @@ #LyX file created by tex2lyx 2.2 -\lyxformat 475 +\lyxformat 476 \begin_document \begin_header \textclass article diff --git a/src/tex2lyx/test/test-insets.lyx.lyx b/src/tex2lyx/test/test-insets.lyx.lyx index bc8e98fb33..69a2da3cd2 100644 --- a/src/tex2lyx/test/test-insets.lyx.lyx +++ b/src/tex2lyx/test/test-insets.lyx.lyx @@ -1,5 +1,5 @@ #LyX file created by tex2lyx 2.2 -\lyxformat 475 +\lyxformat 476 \begin_document \begin_header \textclass article diff --git a/src/tex2lyx/test/test-modules.lyx.lyx b/src/tex2lyx/test/test-modules.lyx.lyx index 0510527229..6ca4148b52 100644 --- a/src/tex2lyx/test/test-modules.lyx.lyx +++ b/src/tex2lyx/test/test-modules.lyx.lyx @@ -1,5 +1,5 @@ #LyX file created by tex2lyx 2.2 -\lyxformat 475 +\lyxformat 476 \begin_document \begin_header \textclass amsart diff --git a/src/tex2lyx/test/test-refstyle-theorems.lyx.lyx b/src/tex2lyx/test/test-refstyle-theorems.lyx.lyx index bb8ec56181..01ddac15d9 100644 --- a/src/tex2lyx/test/test-refstyle-theorems.lyx.lyx +++ b/src/tex2lyx/test/test-refstyle-theorems.lyx.lyx @@ -1,5 +1,5 @@ #LyX file created by tex2lyx 2.2 -\lyxformat 475 +\lyxformat 476 \begin_document \begin_header \textclass book diff --git a/src/tex2lyx/test/test-structure.lyx.lyx b/src/tex2lyx/test/test-structure.lyx.lyx index 2752a27203..7bacf5335d 100644 --- a/src/tex2lyx/test/test-structure.lyx.lyx +++ b/src/tex2lyx/test/test-structure.lyx.lyx @@ -1,5 +1,5 @@ #LyX file created by tex2lyx 2.2 -\lyxformat 475 +\lyxformat 476 \begin_document \begin_header \textclass article diff --git a/src/tex2lyx/test/test.lyx.lyx b/src/tex2lyx/test/test.lyx.lyx index 344470a33c..2d5371b2f9 100644 --- a/src/tex2lyx/test/test.lyx.lyx +++ b/src/tex2lyx/test/test.lyx.lyx @@ -1,5 +1,5 @@ #LyX file created by tex2lyx 2.2 -\lyxformat 475 +\lyxformat 476 \begin_document \begin_header \textclass article diff --git a/src/tex2lyx/test/verbatim.lyx.lyx b/src/tex2lyx/test/verbatim.lyx.lyx index 68fbf23256..4435064bec 100644 --- a/src/tex2lyx/test/verbatim.lyx.lyx +++ b/src/tex2lyx/test/verbatim.lyx.lyx @@ -1,5 +1,5 @@ #LyX file created by tex2lyx 2.2 -\lyxformat 475 +\lyxformat 476 \begin_document \begin_header \textclass article diff --git a/src/version.h b/src/version.h index e98f3a0d8b..be963857e5 100644 --- a/src/version.h +++ b/src/version.h @@ -30,8 +30,8 @@ extern char const * const lyx_version_info; // Do not remove the comment below, so we get merge conflict in // independent branches. Instead add your own. -#define LYX_FORMAT_LYX 475 // ef: new separator inset -#define LYX_FORMAT_TEX2LYX 475 +#define LYX_FORMAT_LYX 476 // gb: \smash[t] and \smash[b] +#define LYX_FORMAT_TEX2LYX 476 #if LYX_FORMAT_TEX2LYX != LYX_FORMAT_LYX #ifndef _MSC_VER -- 2.39.2