From 038cc706500567634c68d71342e8be54cf0e81bd Mon Sep 17 00:00:00 2001 From: Michael Schmitt Date: Tue, 8 May 2007 17:46:03 +0000 Subject: [PATCH] change tracking: introduce 'semantic' TeX commands \lyxinserted and \lyxdeleted in order to decouple change tracking output from dvipost. Raise user warning if dvipost is not installed (i.e. no changes are shown in TeX output) git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@18237 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/Buffer.cpp | 29 +++++++++++++++++++-- src/BufferParams.cpp | 10 -------- src/BufferParams.h | 9 +++---- src/BufferView.cpp | 17 +++++++++++- src/Changes.cpp | 58 ++++++++++++++++++----------------------- src/Changes.h | 6 +++-- src/LaTeXFeatures.cpp | 25 ++++++++++++++++++ src/Paragraph.cpp | 60 +++++++++++++++++++------------------------ 8 files changed, 126 insertions(+), 88 deletions(-) diff --git a/src/Buffer.cpp b/src/Buffer.cpp index b5125c3454..33b6d2cb5b 100644 --- a/src/Buffer.cpp +++ b/src/Buffer.cpp @@ -505,6 +505,22 @@ bool Buffer::readDocument(Lexer & lex) params().textclass = 0; } + if (params().outputChanges) { + if (!LaTeXFeatures::isAvailable("dvipost")) { + Alert::warning(_("Changes not shown in LaTeX output"), + _("Changes will not be highlighted in LaTeX output, " + "because dvipost is not installed.\n" + "If you are familiar with TeX, consider redefining " + "\\lyxinserted and \\lyxdeleted in the LaTeX preamble.")); + } else { + Alert::warning(_("Changes not shown in LaTeX output"), + _("Changes will not be highlighted in LaTeX output " + "when using pdflatex.\n" + "If you are familiar with TeX, consider redefining " + "\\lyxinserted and \\lyxdeleted in the LaTeX preamble.")); + } + } + bool const res = text().read(*this, lex, errorList); for_each(text().paragraphs().begin(), text().paragraphs().end(), @@ -1198,8 +1214,17 @@ void Buffer::validate(LaTeXFeatures & features) const { TextClass const & tclass = params().getTextClass(); - if (features.isAvailable("dvipost") && params().outputChanges) - features.require("dvipost"); + if (params().outputChanges) { + if (features.runparams().flavor == OutputParams::LATEX) { + if (LaTeXFeatures::isAvailable("dvipost")) { + features.require("dvipost"); + } else { + features.require("ct-none"); + } + } else if (features.runparams().flavor == OutputParams::PDFLATEX ) { + features.require("ct-none"); + } + } // AMS Style is at document level if (params().use_amsmath == BufferParams::package_on diff --git a/src/BufferParams.cpp b/src/BufferParams.cpp index 8947763561..d21f5117e0 100644 --- a/src/BufferParams.cpp +++ b/src/BufferParams.cpp @@ -1176,16 +1176,6 @@ bool BufferParams::writeLaTeX(odocstream & os, LaTeXFeatures & features, lyxpreamble += "\\makeatother\n"; - // dvipost settings come after everything else - if (features.isAvailable("dvipost") && outputChanges) { - lyxpreamble += - "\\dvipostlayout\n" - "\\dvipost{osstart color push Red}\n" - "\\dvipost{osend color pop}\n" - "\\dvipost{cbstart color push Blue}\n" - "\\dvipost{cbend color pop}\n"; - } - int const nlines = int(lyx::count(lyxpreamble.begin(), lyxpreamble.end(), '\n')); for (int j = 0; j != nlines; ++j) { diff --git a/src/BufferParams.h b/src/BufferParams.h index 6872c9b9db..64af381d16 100644 --- a/src/BufferParams.h +++ b/src/BufferParams.h @@ -229,12 +229,9 @@ public: bool use_bibtopic; /// revision tracking for this buffer ? bool trackChanges; - /** This param decides whether change tracking marks should be output - * (using the dvipost package) or if the current "state" of the - * document should be output instead. Since dvipost needs dvi - * specials, it only works with dvi/ps output (the param will be - * ignored with other output flavors and disabled when dvipost is - * not installed). + /** This param decides whether change tracking marks should be used + * in output (irrespective of how these marks are actually defined; + * for instance, they may differ for DVI and PDF generation) */ bool outputChanges; /// Time ago we agreed that this was a buffer property [ale990407] diff --git a/src/BufferView.cpp b/src/BufferView.cpp index abaf74fde4..b4022ab5f0 100644 --- a/src/BufferView.cpp +++ b/src/BufferView.cpp @@ -706,7 +706,7 @@ FuncStatus BufferView::getStatus(FuncRequest const & cmd) break; case LFUN_CHANGES_OUTPUT: - flag.enabled(buffer_ && LaTeXFeatures::isAvailable("dvipost")); + flag.enabled(buffer_); flag.setOnOff(buffer_->params().outputChanges); break; @@ -889,6 +889,21 @@ Update::flags BufferView::dispatch(FuncRequest const & cmd) case LFUN_CHANGES_OUTPUT: buffer_->params().outputChanges = !buffer_->params().outputChanges; + if (buffer_->params().outputChanges) { + if (!LaTeXFeatures::isAvailable("dvipost")) { + Alert::warning(_("Changes not shown in LaTeX output"), + _("Changes will not be highlighted in LaTeX output, " + "because dvipost is not installed.\n" + "If you are familiar with TeX, consider redefining " + "\\lyxinserted and \\lyxdeleted in the LaTeX preamble.")); + } else { + Alert::warning(_("Changes not shown in LaTeX output"), + _("Changes will not be highlighted in LaTeX output " + "when using pdflatex.\n" + "If you are familiar with TeX, consider redefining " + "\\lyxinserted and \\lyxdeleted in the LaTeX preamble.")); + } + } break; case LFUN_CHANGE_NEXT: diff --git a/src/Changes.cpp b/src/Changes.cpp index a7cd525dde..fec558e56e 100644 --- a/src/Changes.cpp +++ b/src/Changes.cpp @@ -15,6 +15,9 @@ #include "Changes.h" #include "debug.h" +#include "Author.h" +#include "BufferParams.h" +#include "LaTeXFeatures.h" #include @@ -291,46 +294,35 @@ void Changes::merge() } -int Changes::latexMarkChange(odocstream & os, - Change::Type const oldChangeType, Change::Type const changeType, - bool const & output) +int Changes::latexMarkChange(odocstream & os, BufferParams const & bparams, + Change const & oldChange, Change const & change) { - if (!output || oldChangeType == changeType) + if (!bparams.outputChanges || oldChange == change) return 0; - static docstring const start(from_ascii("\\changestart{}")); - static docstring const end(from_ascii("\\changeend{}")); - static docstring const son(from_ascii("\\overstrikeon{}")); - static docstring const soff(from_ascii("\\overstrikeoff{}")); - int column = 0; - if (oldChangeType == Change::DELETED) { - os << soff; - column += soff.length(); + if (oldChange.type != Change::UNCHANGED) { + os << '}'; // close \lyxinserted or \lyxdeleted + column++; } - switch (changeType) { - case Change::UNCHANGED: - os << end; - column += end.length(); - break; - - case Change::DELETED: - if (oldChangeType == Change::UNCHANGED) { - os << start; - column += start.length(); - } - os << son; - column += son.length(); - break; - - case Change::INSERTED: - if (oldChangeType == Change::UNCHANGED) { - os << start; - column += start.length(); - } - break; + docstring chgTime; + chgTime += ctime(&change.changetime); + chgTime.erase(chgTime.end() - 1); // remove trailing '\n' + + if (change.type == Change::DELETED) { + docstring str = "\\lyxdeleted{" + + bparams.authors().get(change.author).name() + "}{" + + chgTime + "}{"; + os << str; + column += str.size(); + } else if (change.type == Change::INSERTED) { + docstring str = "\\lyxinserted{" + + bparams.authors().get(change.author).name() + "}{" + + chgTime + "}{"; + os << str; + column += str.size(); } return column; diff --git a/src/Changes.h b/src/Changes.h index b50c00e02c..d7041480cb 100644 --- a/src/Changes.h +++ b/src/Changes.h @@ -49,6 +49,8 @@ public: bool operator==(Change const & l, Change const & r); bool operator!=(Change const & l, Change const & r); +class BufferParams; + class Changes { public: /// set the pos to the given change @@ -76,8 +78,8 @@ public: /// output latex to mark a transition between two change types /// returns length of text outputted - static int latexMarkChange(odocstream & os, Change::Type oldChangeType, - Change::Type changeType, bool const & output); + static int latexMarkChange(odocstream & os, BufferParams const & bparams, + Change const & oldChange, Change const & change); /// output .lyx file format for transitions between changes static void lyxMarkChange(std::ostream & os, int & column, diff --git a/src/LaTeXFeatures.cpp b/src/LaTeXFeatures.cpp index 888c62da9c..69546187dc 100644 --- a/src/LaTeXFeatures.cpp +++ b/src/LaTeXFeatures.cpp @@ -171,6 +171,25 @@ static string const lyxdot_def = "%% A simple dot to overcome graphicx limitations\n" "\\newcommand{\\lyxdot}{.}\n"; +static string const changetracking_dvipost_def = + "%% Change tracking with dvipost\n" + "\\dvipostlayout\n" + "\\dvipost{osstart color push Red}\n" + "\\dvipost{osend color pop}\n" + "\\dvipost{cbstart color push Blue}\n" + "\\dvipost{cbend color pop}\n" + "\\newcommand{\\lyxinserted}[3]{\\changestart#3\\changeend}\n" + "\\newcommand{\\lyxdeleted}[3]{%\n" + "\\changestart\\overstrikeon#3\\overstrikeoff\\changeend}\n"; + +// TODO +//static string const changetracking_soul_def = +// "\\newcommand{\\lyxinserted}[3]{\\uwave{\\textcolor{blue}{#3}}}\n" +// "\\newcommand{\\lyxdeleted}[3]{\\sout{\\textcolor{red}{#3}}}"; + +static string const changetracking_none_def = + "\\newcommand{\\lyxinserted}[3]{#3}\n" + "\\newcommand{\\lyxdeleted}[3]{}"; ///////////////////////////////////////////////////////////////////// @@ -620,6 +639,12 @@ string const LaTeXFeatures::getMacros() const // floats getFloatDefinitions(macros); + // change tracking + if (mustProvide("dvipost")) + macros << changetracking_dvipost_def; + if (mustProvide("ct-none")) + macros << changetracking_none_def; + return macros.str(); } diff --git a/src/Paragraph.cpp b/src/Paragraph.cpp index 8f4f196ab3..ebe0e840c9 100644 --- a/src/Paragraph.cpp +++ b/src/Paragraph.cpp @@ -194,7 +194,7 @@ public: Font & basefont, Font const & outerfont, bool & open_font, - Change::Type & running_change, + Change & running_change, Layout const & style, pos_type & i, unsigned int & column, value_type const c); @@ -665,7 +665,7 @@ void Paragraph::Pimpl::simpleTeXSpecialChars(Buffer const & buf, Font & basefont, Font const & outerfont, bool & open_font, - Change::Type & running_change, + Change & running_change, Layout const & style, pos_type & i, unsigned int & column, @@ -724,18 +724,10 @@ void Paragraph::Pimpl::simpleTeXSpecialChars(Buffer const & buf, break; } - // output change tracking marks only if desired, - // if dvipost is installed, - // and with dvi/ps (other formats don't work) - LaTeXFeatures features(buf, bparams, runparams); - bool const output = bparams.outputChanges - && runparams.flavor == OutputParams::LATEX - && features.isAvailable("dvipost"); - if (inset->canTrackChanges()) { - column += Changes::latexMarkChange(os, running_change, - Change::UNCHANGED, output); - running_change = Change::UNCHANGED; + column += Changes::latexMarkChange(os, bparams, running_change, + Change(Change::UNCHANGED)); + running_change = Change(Change::UNCHANGED); } bool close = false; @@ -1930,13 +1922,6 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf, // of the body. Font basefont; - // output change tracking marks only if desired, - // if dvipost is installed, - // and with dvi/ps (other formats don't work) - bool const output = bparams.outputChanges - && runparams.flavor == OutputParams::LATEX - && LaTeXFeatures::isAvailable("dvipost"); - // Maybe we have to create a optional argument. pos_type body_pos = beginOfBody(); unsigned int column = 0; @@ -1956,7 +1941,7 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf, // Do we have an open font change? bool open_font = false; - Change::Type runningChangeType = Change::UNCHANGED; + Change runningChange = Change(Change::UNCHANGED); texrow.start(id(), 0); @@ -1984,9 +1969,9 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf, basefont = getLayoutFont(bparams, outerfont); running_font = basefont; - column += Changes::latexMarkChange(os, - runningChangeType, Change::UNCHANGED, output); - runningChangeType = Change::UNCHANGED; + column += Changes::latexMarkChange(os, bparams, + runningChange, Change(Change::UNCHANGED)); + runningChange = Change(Change::UNCHANGED); os << "}] "; column +=3; @@ -2002,21 +1987,29 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf, runparams.moving_arg); } - Change::Type changeType = pimpl_->lookupChange(i).type; + Change const & change = pimpl_->lookupChange(i); + + if (bparams.outputChanges && runningChange != change) { + if (open_font) { + column += running_font.latexWriteEndChanges( + os, bparams, runparams, basefont, basefont); + open_font = false; + } + basefont = getLayoutFont(bparams, outerfont); + running_font = basefont; + + column += Changes::latexMarkChange(os, bparams, runningChange, change); + runningChange = change; + } // do not output text which is marked deleted // if change tracking output is disabled - if (!output && changeType == Change::DELETED) { - runningChangeType = changeType; + if (!bparams.outputChanges && change.type == Change::DELETED) { continue; } ++column; - column += Changes::latexMarkChange(os, runningChangeType, - changeType, output); - runningChangeType = changeType; - value_type const c = getChar(i); // Fully instantiated font @@ -2086,7 +2079,7 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf, pimpl_->simpleTeXSpecialChars(buf, bparams, os, texrow, rp, running_font, basefont, outerfont, open_font, - runningChangeType, *style, i, column, c); + runningChange, *style, i, column, c); } // If we have an open font definition, we have to close it @@ -2112,8 +2105,7 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf, #endif } - column += Changes::latexMarkChange(os, - runningChangeType, Change::UNCHANGED, output); + column += Changes::latexMarkChange(os, bparams, runningChange, Change(Change::UNCHANGED)); // Needed if there is an optional argument but no contents. if (body_pos > 0 && body_pos == size()) { -- 2.39.5