commit 261e7ae9ce7e6a1ffc4932ff9c33107588a9a4ac
Author: Enrico Forestieri <for...@lyx.org>
Date:   Mon Oct 17 03:25:35 2016 +0200

    Strike out (in the output) deleted display math with track-changes
    
    Showing deleted display math by enabling "Show Changes in Output" was
    only possible with dvi (through dvipost). Although LyX strikes out
    such formulas on screen, it was impossible obtaining an output
    directly using pdflatex (or other engines producing pdf) because
    ulem cannot cope with display math material and gives errors.
    The solution is to strike out by ourselves such deleted formulas.
    I took into account several options. One of them would produce
    an output similar to dvipost (which strikes out each element), but
    would have required much more changes in the output routines.
    Eventually, I opted for using tikz, which gives a more clean
    output (as it requires to simply adding a preamble and a postamble
    to the latex code of any displayed math, instead of a mark up
    tailored to each particular math construct). The look of the pdf
    output is similar to the way LyX strikes out the equations on screen.
---
 src/LaTeXFeatures.cpp        |   23 ++++++++++++++++++++---
 src/LaTeXFeatures.h          |    6 ++++++
 src/Paragraph.cpp            |    2 ++
 src/mathed/InsetMathHull.cpp |   39 ++++++++++++++++++++++++++++++++++++---
 src/mathed/InsetMathNest.cpp |    5 +++++
 src/mathed/MathStream.cpp    |    2 +-
 src/mathed/MathStream.h      |    6 ++++++
 7 files changed, 76 insertions(+), 7 deletions(-)

diff --git a/src/LaTeXFeatures.cpp b/src/LaTeXFeatures.cpp
index cab81ca..79ff587 100644
--- a/src/LaTeXFeatures.cpp
+++ b/src/LaTeXFeatures.cpp
@@ -193,12 +193,25 @@ static docstring const changetracking_dvipost_def = 
from_ascii(
 static docstring const changetracking_xcolor_ulem_def = from_ascii(
        "%% Change tracking with ulem\n"
        "\\DeclareRobustCommand{\\lyxadded}[3]{{\\color{lyxadded}{}#3}}\n"
-       
"\\DeclareRobustCommand{\\lyxdeleted}[3]{{\\color{lyxdeleted}\\sout{#3}}}\n");
+       
"\\DeclareRobustCommand{\\lyxdeleted}[3]{{\\color{lyxdeleted}\\lyxsout{#3}}}\n"
+       
"\\DeclareRobustCommand{\\lyxsout}[1]{\\ifx\\\\#1\\else\\sout{#1}\\fi}\n");
 
 static docstring const changetracking_xcolor_ulem_hyperref_def = from_ascii(
        "%% Change tracking with ulem\n"
        
"\\DeclareRobustCommand{\\lyxadded}[3]{{\\texorpdfstring{\\color{lyxadded}{}}{}#3}}\n"
-       
"\\DeclareRobustCommand{\\lyxdeleted}[3]{{\\texorpdfstring{\\color{lyxdeleted}\\sout{#3}}{}}}\n");
+       
"\\DeclareRobustCommand{\\lyxdeleted}[3]{{\\texorpdfstring{\\color{lyxdeleted}\\lyxsout{#3}}{}}}\n"
+       
"\\DeclareRobustCommand{\\lyxsout}[1]{\\ifx\\\\#1\\else\\sout{#1}\\fi}\n");
+
+static docstring const changetracking_tikz_math_sout_def = from_ascii(
+       "%% Strike out display math with tikz\n"
+       "\\usepackage{tikz}\n"
+       "\\usetikzlibrary{calc}\n"
+       "\\newcommand{\\lyxmathsout}[1]{\n"
+       "  \\tikz[baseline=(math.base)]{\n"
+       "    \\node[inner sep=0pt,outer sep=0pt](math){#1};\n"
+       "    \\draw($(math.south west)+(2em,.5em)$)--($(math.north 
east)-(2em,.5em)$);\n"
+       "  }\n"
+       "}\n");
 
 static docstring const changetracking_none_def = from_ascii(
        "\\newcommand{\\lyxadded}[3]{#3}\n"
@@ -390,7 +403,8 @@ static docstring const lyxstrikeout_style = from_ascii(
 
 LaTeXFeatures::LaTeXFeatures(Buffer const & b, BufferParams const & p,
                             OutputParams const & r)
-       : buffer_(&b), params_(p), runparams_(r), in_float_(false)
+       : buffer_(&b), params_(p), runparams_(r), in_float_(false),
+         in_deleted_inset_(false)
 {}
 
 
@@ -1353,6 +1367,9 @@ TexString LaTeXFeatures::getMacros() const
                        macros << changetracking_xcolor_ulem_def;
        }
 
+       if (mustProvide("ct-tikz-math-sout"))
+                       macros << changetracking_tikz_math_sout_def;
+
        if (mustProvide("ct-none"))
                macros << changetracking_none_def;
 
diff --git a/src/LaTeXFeatures.h b/src/LaTeXFeatures.h
index 4179856..ec807c3 100644
--- a/src/LaTeXFeatures.h
+++ b/src/LaTeXFeatures.h
@@ -154,6 +154,10 @@ public:
        bool inFloat() const { return in_float_; }
        /// are we in a float?
        void inFloat(bool const b) { in_float_ = b; }
+       /// are we in a deleted inset?
+       bool inDeletedInset() const { return in_deleted_inset_; }
+       /// are we in a deleted inset?
+       void inDeletedInset(bool const b) { in_deleted_inset_ = b; }
        /// Runparams that will be used for exporting this file.
        OutputParams const & runparams() const { return runparams_; }
        /// Resolve alternatives like "esint|amsmath|wasysym"
@@ -209,6 +213,8 @@ private:
        ///
        bool in_float_;
        ///
+       bool in_deleted_inset_;
+       ///
        docstring htmltitle_;
 };
 
diff --git a/src/Paragraph.cpp b/src/Paragraph.cpp
index b98d06b..ce95ad8 100644
--- a/src/Paragraph.cpp
+++ b/src/Paragraph.cpp
@@ -1439,7 +1439,9 @@ void Paragraph::Private::validate(LaTeXFeatures & 
features) const
        InsetList::const_iterator iend = insetlist_.end();
        for (; icit != iend; ++icit) {
                if (icit->inset) {
+                       features.inDeletedInset(owner_->isDeleted(icit->pos));
                        icit->inset->validate(features);
+                       features.inDeletedInset(false);
                        if (layout_->needprotect &&
                            icit->inset->lyxCode() == FOOT_CODE)
                                features.require("NeedLyXFootnoteCode");
diff --git a/src/mathed/InsetMathHull.cpp b/src/mathed/InsetMathHull.cpp
index 76b3613..61c044a 100644
--- a/src/mathed/InsetMathHull.cpp
+++ b/src/mathed/InsetMathHull.cpp
@@ -953,7 +953,26 @@ void InsetMathHull::validate(LaTeXFeatures & features) 
const
                if (ams())
                        features.require("amsmath");
 
-               if (type_ == hullRegexp) {
+               switch(type_) {
+               case hullNone:
+               case hullSimple:
+               case hullAlignAt:
+               case hullXAlignAt:
+               case hullXXAlignAt:
+               case hullUnknown:
+                       break;
+
+               case hullEquation:
+               case hullEqnArray:
+               case hullAlign:
+               case hullFlAlign:
+               case hullGather:
+               case hullMultline:
+                       if (features.inDeletedInset() && 
!features.mustProvide("ct-dvipost"))
+                               features.require("ct-tikz-math-sout");
+                       break;
+
+               case hullRegexp:
                        features.require("color");
                        docstring frcol = 
from_utf8(lcolor.getLaTeXName(Color_regexpframe));
                        docstring bgcol = from_ascii("white");
@@ -963,6 +982,7 @@ void InsetMathHull::validate(LaTeXFeatures & features) const
                                + bgcol + "}{\\ensuremath{\\mathtt{#1}}}}");
                        features.addPreambleSnippet(
                                from_ascii("\\newcommand{\\endregexp}{}"));
+                       break;
                }
 
                // Validation is necessary only if not using AMS math.
@@ -1001,6 +1021,8 @@ void InsetMathHull::header_write(WriteStream & os) const
                break;
 
        case hullEquation:
+               if (os.strikeoutMath())
+                       os << 
"\\\\\\\\\n\\lyxmathsout{\\parbox{\\columnwidth}{";
                os << "\n";
                os.startOuterRow();
                if (n)
@@ -1014,6 +1036,8 @@ void InsetMathHull::header_write(WriteStream & os) const
        case hullFlAlign:
        case hullGather:
        case hullMultline:
+               if (os.strikeoutMath())
+                       os << 
"\\\\\\\\\n\\lyxmathsout{\\parbox{\\columnwidth}{";
                os << "\n";
                os.startOuterRow();
                os << "\\begin{" << hullName(type_) << star(n) << "}\n";
@@ -1067,18 +1091,27 @@ void InsetMathHull::footer_write(WriteStream & os) const
                        os << "\\end{equation" << star(n) << "}\n";
                else
                        os << "\\]\n";
+               if (os.strikeoutMath())
+                       os << "}}\\\\\n";
                break;
 
        case hullEqnArray:
        case hullAlign:
        case hullFlAlign:
-       case hullAlignAt:
-       case hullXAlignAt:
        case hullGather:
        case hullMultline:
                os << "\n";
                os.startOuterRow();
                os << "\\end{" << hullName(type_) << star(n) << "}\n";
+               if (os.strikeoutMath())
+                       os << "}}\\\\\n";
+               break;
+
+       case hullAlignAt:
+       case hullXAlignAt:
+               os << "\n";
+               os.startOuterRow();
+               os << "\\end{" << hullName(type_) << star(n) << "}\n";
                break;
 
        case hullXXAlignAt:
diff --git a/src/mathed/InsetMathNest.cpp b/src/mathed/InsetMathNest.cpp
index ee3b92d..07e8812 100644
--- a/src/mathed/InsetMathNest.cpp
+++ b/src/mathed/InsetMathNest.cpp
@@ -48,6 +48,7 @@
 #include "Encoding.h"
 #include "FuncRequest.h"
 #include "FuncStatus.h"
+#include "LaTeXFeatures.h"
 #include "LyX.h"
 #include "LyXRC.h"
 #include "MetricsInfo.h"
@@ -406,6 +407,10 @@ void InsetMathNest::latex(otexstream & os, OutputParams 
const & runparams) const
        WriteStream wi(os, runparams.moving_arg, true,
                        runparams.dryrun ? WriteStream::wsDryrun : 
WriteStream::wsDefault,
                        runparams.encoding);
+       wi.strikeoutMath(runparams.inDeletedInset
+                        && (!LaTeXFeatures::isAvailable("dvipost")
+                               || (runparams.flavor != OutputParams::LATEX
+                                   && runparams.flavor != 
OutputParams::DVILUATEX)));
        wi.canBreakLine(os.canBreakLine());
        Changer dummy = wi.changeRowEntry(TexRow::textEntry(runparams.lastid,
                                                            runparams.lastpos));
diff --git a/src/mathed/MathStream.cpp b/src/mathed/MathStream.cpp
index eb567ff..16a7a17 100644
--- a/src/mathed/MathStream.cpp
+++ b/src/mathed/MathStream.cpp
@@ -130,7 +130,7 @@ WriteStream::WriteStream(otexrowstream & os, bool fragile, 
bool latex,
        : os_(os), fragile_(fragile), firstitem_(false), latex_(latex),
          output_(output), pendingspace_(false), pendingbrace_(false),
          textmode_(false), locked_(0), ascii_(0), canbreakline_(true),
-         line_(0), encoding_(encoding),
+         mathsout_(false), line_(0), encoding_(encoding),
          row_entry_(make_unique<RowEntry>(TexRow::row_none))
 {}
 
diff --git a/src/mathed/MathStream.h b/src/mathed/MathStream.h
index fe5c259..e492ea3 100644
--- a/src/mathed/MathStream.h
+++ b/src/mathed/MathStream.h
@@ -66,6 +66,10 @@ public:
        void canBreakLine(bool breakline) { canbreakline_ = breakline; }
        /// tell whether we can write an immediately following newline char
        bool canBreakLine() const { return canbreakline_; }
+       /// record whether we have to take care for striking out display math
+       void strikeoutMath(bool mathsout) { mathsout_ = mathsout; }
+       /// tell whether we have to take care for striking out display math
+       bool strikeoutMath() const { return mathsout_; }
        /// writes space if next thing is isalpha()
        void pendingSpace(bool how);
        /// writes space if next thing is isalpha()
@@ -117,6 +121,8 @@ private:
        bool ascii_;
        /// are we allowed to output an immediately following newline?
        bool canbreakline_;
+       /// should we take care for striking out display math?
+       bool mathsout_;
        ///
        int line_;
        ///

Reply via email to