From 961e393b954efd59c1e80be611b726c34adec088 Mon Sep 17 00:00:00 2001 From: Kornel Benko Date: Fri, 22 Jan 2021 21:11:28 +0100 Subject: [PATCH] FindAdv: Make search for text in deleted regions configurable. The function call 'search-ignore deleted false' makes findadv to search also deleted parts, while 'search-ignore deleted true' will omit these parts. --- src/OutputParams.h | 8 ++++++- src/Paragraph.cpp | 17 +++++++++----- src/insets/InsetBibtex.cpp | 2 +- src/insets/InsetInclude.cpp | 4 ++-- src/insets/InsetIndex.cpp | 2 +- src/insets/InsetSpace.cpp | 44 ++++++++++++++++++------------------ src/lyxfind.cpp | 45 +++++++++++++++++++++++++++++++------ src/output_latex.cpp | 40 ++++++++++++++++++++------------- 8 files changed, 107 insertions(+), 55 deletions(-) diff --git a/src/OutputParams.h b/src/OutputParams.h index c04ada1a30..5113e0a6d2 100644 --- a/src/OutputParams.h +++ b/src/OutputParams.h @@ -395,7 +395,13 @@ public: bool for_tooltip = false; /// Are we generating this material for use by advanced search? - bool for_search = false; + enum Search { + NoSearch, + SearchWithDeleted, + SearchWithoutDeleted + }; + + enum Search for_searchAdv = NoSearch; /// Are we generating this material for instant preview? bool for_preview = false; diff --git a/src/Paragraph.cpp b/src/Paragraph.cpp index d5bfb76320..abe1394ae1 100644 --- a/src/Paragraph.cpp +++ b/src/Paragraph.cpp @@ -1129,10 +1129,10 @@ void Paragraph::Private::latexSpecialChar(otexstream & os, { char_type const c = owner_->getUChar(bparams, runparams, i); - if (style.pass_thru || runparams.pass_thru || runparams.for_search + if (style.pass_thru || runparams.pass_thru || (runparams.for_searchAdv != OutputParams::NoSearch) || contains(style.pass_thru_chars, c) || contains(runparams.pass_thru_chars, c)) { - if (runparams.for_search) { + if (runparams.for_searchAdv != OutputParams::NoSearch) { if (c == '\\') os << "\\\\"; else if (c == '{') @@ -2517,6 +2517,11 @@ void Paragraph::latex(BufferParams const & bparams, char_type const c = d->text_[i]; // Check whether a display math inset follows + bool output_changes; + if (runparams.for_searchAdv == OutputParams::NoSearch) + output_changes = bparams.output_changes; + else + output_changes = (runparams.for_searchAdv == OutputParams::SearchWithDeleted); if (c == META_INSET && i >= start_pos && (end_pos == -1 || i < end_pos)) { if (isDeleted(i)) @@ -2532,7 +2537,7 @@ void Paragraph::latex(BufferParams const & bparams, // cannot set it here because it is a counter. deleted_display_math = isDeleted(i); } - if (bparams.output_changes && deleted_display_math + if (output_changes && deleted_display_math && runningChange == change && change.type == Change::DELETED && !os.afterParbreak()) { @@ -2555,7 +2560,7 @@ void Paragraph::latex(BufferParams const & bparams, } } - if (bparams.output_changes && runningChange != change) { + if (output_changes && runningChange != change) { if (!alien_script.empty()) { column += 1; os << "}"; @@ -2578,7 +2583,7 @@ void Paragraph::latex(BufferParams const & bparams, // do not output text which is marked deleted // if change tracking output is disabled - if (!bparams.output_changes && change.deleted()) { + if (!output_changes && change.deleted()) { continue; } @@ -2592,7 +2597,7 @@ void Paragraph::latex(BufferParams const & bparams, : current_font; Font const last_font = running_font; - bool const in_ct_deletion = (bparams.output_changes + bool const in_ct_deletion = (output_changes && runningChange == change && change.type == Change::DELETED && !os.afterParbreak()); diff --git a/src/insets/InsetBibtex.cpp b/src/insets/InsetBibtex.cpp index 6566c4e521..5f6b967680 100644 --- a/src/insets/InsetBibtex.cpp +++ b/src/insets/InsetBibtex.cpp @@ -983,7 +983,7 @@ int InsetBibtex::plaintext(odocstringstream & os, // We could output more information here, e.g., what databases are included // and information about options. But I don't necessarily see any reason to // do this right now. - if (op.for_tooltip || op.for_toc || op.for_search) { + if (op.for_tooltip || op.for_toc || op.for_searchAdv != OutputParams::NoSearch) { os << '[' << reflabel << ']' << '\n'; return PLAINTEXT_NEWLINE; } diff --git a/src/insets/InsetInclude.cpp b/src/insets/InsetInclude.cpp index 467cd110af..aeae2fb17d 100644 --- a/src/insets/InsetInclude.cpp +++ b/src/insets/InsetInclude.cpp @@ -1006,14 +1006,14 @@ int InsetInclude::plaintext(odocstringstream & os, { // just write the filename if we're making a tooltip or toc entry, // or are generating this for advanced search - if (op.for_tooltip || op.for_toc || op.for_search) { + if (op.for_tooltip || op.for_toc || op.for_searchAdv != OutputParams::NoSearch) { os << '[' << screenLabel() << '\n' << ltrim(getParam("filename")) << "\n]"; return PLAINTEXT_NEWLINE + 1; // one char on a separate line } if (isVerbatim(params()) || isListings(params())) { - if (op.for_search) { + if (op.for_searchAdv != OutputParams::NoSearch) { os << '[' << screenLabel() << ']'; } else { diff --git a/src/insets/InsetIndex.cpp b/src/insets/InsetIndex.cpp index 7790ad91fb..7b4bb88013 100644 --- a/src/insets/InsetIndex.cpp +++ b/src/insets/InsetIndex.cpp @@ -83,7 +83,7 @@ void InsetIndex::latex(otexstream & ios, OutputParams const & runparams_in) cons odocstringstream ourlatex; otexstream ots(ourlatex); InsetText::latex(ots, runparams); - if (runparams.for_search) { + if (runparams.for_searchAdv != OutputParams::NoSearch) { // No need for special handling, if we are only searching for some patterns os << ourlatex.str() << "}"; return; diff --git a/src/insets/InsetSpace.cpp b/src/insets/InsetSpace.cpp index 2deea3097e..95855961f9 100644 --- a/src/insets/InsetSpace.cpp +++ b/src/insets/InsetSpace.cpp @@ -579,27 +579,27 @@ void InsetSpace::latex(otexstream & os, OutputParams const & runparams) const { switch (params_.kind) { case InsetSpaceParams::NORMAL: - os << (runparams.free_spacing && !runparams.for_search ? " " : "\\ "); + os << (runparams.free_spacing && (runparams.for_searchAdv == OutputParams::NoSearch) ? " " : "\\ "); break; case InsetSpaceParams::PROTECTED: if (runparams.local_font && runparams.local_font->language()->lang() == "polutonikogreek") // in babel's polutonikogreek, ~ is active - os << (runparams.free_spacing && !runparams.for_search ? " " : "\\nobreakspace{}"); + os << (runparams.free_spacing && (runparams.for_searchAdv == OutputParams::NoSearch) ? " " : "\\nobreakspace{}"); else - os << (runparams.free_spacing && !runparams.for_search ? ' ' : '~'); + os << (runparams.free_spacing && (runparams.for_searchAdv == OutputParams::NoSearch) ? ' ' : '~'); break; case InsetSpaceParams::VISIBLE: - os << (runparams.free_spacing && !runparams.for_search ? " " : "\\textvisiblespace{}"); + os << (runparams.free_spacing && (runparams.for_searchAdv == OutputParams::NoSearch) ? " " : "\\textvisiblespace{}"); break; case InsetSpaceParams::THIN: - if (runparams.for_search) + if (runparams.for_searchAdv != OutputParams::NoSearch) os << "\\thinspace{}"; else os << (runparams.free_spacing ? " " : "\\,"); break; case InsetSpaceParams::MEDIUM: - if (runparams.for_search) + if (runparams.for_searchAdv != OutputParams::NoSearch) os << "\\medspace{}"; else if (params_.math) os << (runparams.free_spacing ? " " : "\\:"); @@ -607,7 +607,7 @@ void InsetSpace::latex(otexstream & os, OutputParams const & runparams) const os << (runparams.free_spacing ? " " : "\\medspace{}"); break; case InsetSpaceParams::THICK: - if (runparams.for_search) + if (runparams.for_searchAdv != OutputParams::NoSearch) os << "\\thickspace{}"; else if (params_.math) os << (runparams.free_spacing ? " " : "\\;"); @@ -615,49 +615,49 @@ void InsetSpace::latex(otexstream & os, OutputParams const & runparams) const os << (runparams.free_spacing ? " " : "\\thickspace{}"); break; case InsetSpaceParams::QUAD: - os << (runparams.free_spacing && !runparams.for_search ? " " : "\\quad{}"); + os << (runparams.free_spacing && (runparams.for_searchAdv != OutputParams::NoSearch) ? " " : "\\quad{}"); break; case InsetSpaceParams::QQUAD: - os << (runparams.free_spacing && !runparams.for_search ? " " : "\\qquad{}"); + os << (runparams.free_spacing && (runparams.for_searchAdv != OutputParams::NoSearch) ? " " : "\\qquad{}"); break; case InsetSpaceParams::ENSPACE: - os << (runparams.free_spacing && !runparams.for_search ? " " : "\\enspace{}"); + os << (runparams.free_spacing && (runparams.for_searchAdv != OutputParams::NoSearch) ? " " : "\\enspace{}"); break; case InsetSpaceParams::ENSKIP: - os << (runparams.free_spacing && !runparams.for_search ? " " : "\\enskip{}"); + os << (runparams.free_spacing && (runparams.for_searchAdv != OutputParams::NoSearch) ? " " : "\\enskip{}"); break; case InsetSpaceParams::NEGTHIN: - os << (runparams.free_spacing && !runparams.for_search ? " " : "\\negthinspace{}"); + os << (runparams.free_spacing && (runparams.for_searchAdv != OutputParams::NoSearch) ? " " : "\\negthinspace{}"); break; case InsetSpaceParams::NEGMEDIUM: - os << (runparams.free_spacing && !runparams.for_search ? " " : "\\negmedspace{}"); + os << (runparams.free_spacing && (runparams.for_searchAdv != OutputParams::NoSearch) ? " " : "\\negmedspace{}"); break; case InsetSpaceParams::NEGTHICK: - os << (runparams.free_spacing && !runparams.for_search ? " " : "\\negthickspace{}"); + os << (runparams.free_spacing && (runparams.for_searchAdv != OutputParams::NoSearch) ? " " : "\\negthickspace{}"); break; case InsetSpaceParams::HFILL: - os << (runparams.free_spacing && !runparams.for_search ? " " : "\\hfill{}"); + os << (runparams.free_spacing && (runparams.for_searchAdv != OutputParams::NoSearch) ? " " : "\\hfill{}"); break; case InsetSpaceParams::HFILL_PROTECTED: - os << (runparams.free_spacing && !runparams.for_search ? " " : "\\hspace*{\\fill}"); + os << (runparams.free_spacing && (runparams.for_searchAdv != OutputParams::NoSearch) ? " " : "\\hspace*{\\fill}"); break; case InsetSpaceParams::DOTFILL: - os << (runparams.free_spacing && !runparams.for_search ? " " : "\\dotfill{}"); + os << (runparams.free_spacing && (runparams.for_searchAdv != OutputParams::NoSearch) ? " " : "\\dotfill{}"); break; case InsetSpaceParams::HRULEFILL: - os << (runparams.free_spacing && !runparams.for_search ? " " : "\\hrulefill{}"); + os << (runparams.free_spacing && (runparams.for_searchAdv != OutputParams::NoSearch) ? " " : "\\hrulefill{}"); break; case InsetSpaceParams::LEFTARROWFILL: - os << (runparams.free_spacing && !runparams.for_search ? " " : "\\leftarrowfill{}"); + os << (runparams.free_spacing && (runparams.for_searchAdv != OutputParams::NoSearch) ? " " : "\\leftarrowfill{}"); break; case InsetSpaceParams::RIGHTARROWFILL: - os << (runparams.free_spacing && !runparams.for_search ? " " : "\\rightarrowfill{}"); + os << (runparams.free_spacing && (runparams.for_searchAdv != OutputParams::NoSearch) ? " " : "\\rightarrowfill{}"); break; case InsetSpaceParams::UPBRACEFILL: - os << (runparams.free_spacing && !runparams.for_search ? " " : "\\upbracefill{}"); + os << (runparams.free_spacing && (runparams.for_searchAdv != OutputParams::NoSearch) ? " " : "\\upbracefill{}"); break; case InsetSpaceParams::DOWNBRACEFILL: - os << (runparams.free_spacing && !runparams.for_search ? " " : "\\downbracefill{}"); + os << (runparams.free_spacing && (runparams.for_searchAdv != OutputParams::NoSearch) ? " " : "\\downbracefill{}"); break; case InsetSpaceParams::CUSTOM: if (runparams.free_spacing) diff --git a/src/lyxfind.cpp b/src/lyxfind.cpp index be529ca19a..33a83e8ebd 100644 --- a/src/lyxfind.cpp +++ b/src/lyxfind.cpp @@ -100,6 +100,10 @@ class IgnoreFormats { /// bool getLanguage() const { return ignoreLanguage_; } /// + bool getDeleted() const { return ignoreDeleted_; } + /// + void setIgnoreDeleted(bool value); + /// void setIgnoreFormat(string const & type, bool value); private: @@ -123,6 +127,8 @@ private: bool ignoreColor_ = false; /// bool ignoreLanguage_ = false; + /// + bool ignoreDeleted_ = false; }; @@ -161,6 +167,9 @@ void IgnoreFormats::setIgnoreFormat(string const & type, bool value) else if (type == "strike") { ignoreStrikeOut_ = value; } + else if (type == "deleted") { + ignoreDeleted_ = value; + } } // The global variable that can be changed from outside @@ -897,7 +906,10 @@ static docstring buffer_to_latex(Buffer & buffer) runparams.linelen = 10000; //lyxrc.plaintext_linelen; // No side effect of file copying and image conversion runparams.dryrun = true; - runparams.for_search = true; + if (ignoreFormats.getDeleted()) + runparams.for_searchAdv = OutputParams::SearchWithoutDeleted; + else + runparams.for_searchAdv = OutputParams::SearchWithDeleted; pit_type const endpit = buffer.paragraphs().size(); for (pit_type pit = 0; pit != endpit; ++pit) { TeXOnePar(buffer, buffer.text(), pit, os, runparams); @@ -919,16 +931,23 @@ static docstring stringifySearchBuffer(Buffer & buffer, FindAndReplaceOptions co runparams.flavor = Flavor::XeTeX; runparams.linelen = 10000; //lyxrc.plaintext_linelen; runparams.dryrun = true; - runparams.for_search = true; + int option = AS_STR_INSETS |AS_STR_PLAINTEXT; + if (ignoreFormats.getDeleted()) { + option |= AS_STR_SKIPDELETE; + runparams.for_searchAdv = OutputParams::SearchWithoutDeleted; + } + else { + runparams.for_searchAdv = OutputParams::SearchWithDeleted; + } for (pos_type pit = pos_type(0); pit < (pos_type)buffer.paragraphs().size(); ++pit) { Paragraph const & par = buffer.paragraphs().at(pit); LYXERR(Debug::FIND, "Adding to search string: '" << par.asString(pos_type(0), par.size(), - AS_STR_INSETS | AS_STR_SKIPDELETE | AS_STR_PLAINTEXT, + option, &runparams) << "'"); str += par.asString(pos_type(0), par.size(), - AS_STR_INSETS | AS_STR_SKIPDELETE | AS_STR_PLAINTEXT, + option, &runparams); } // Even in ignore-format we have to remove "\text{}, \lyxmathsym{}" parts @@ -3310,11 +3329,18 @@ docstring stringifyFromCursor(DocIterator const & cur, int len) runparams.linelen = 10000; //lyxrc.plaintext_linelen; // No side effect of file copying and image conversion runparams.dryrun = true; - runparams.for_search = true; + int option = AS_STR_INSETS | AS_STR_PLAINTEXT; + if (ignoreFormats.getDeleted()) { + option |= AS_STR_SKIPDELETE; + runparams.for_searchAdv = OutputParams::SearchWithoutDeleted; + } + else { + runparams.for_searchAdv = OutputParams::SearchWithDeleted; + } LYXERR(Debug::FIND, "Stringifying with cur: " << cur << ", from pos: " << cur.pos() << ", end: " << end); return par.asString(cur.pos(), end, - AS_STR_INSETS | AS_STR_SKIPDELETE | AS_STR_PLAINTEXT, + option, &runparams); } else if (cur.inMathed()) { CursorSlice cs = cur.top(); @@ -3358,7 +3384,12 @@ docstring latexifyFromCursor(DocIterator const & cur, int len) runparams.linelen = 8000; //lyxrc.plaintext_linelen; // No side effect of file copying and image conversion runparams.dryrun = true; - runparams.for_search = true; + if (ignoreFormats.getDeleted()) { + runparams.for_searchAdv = OutputParams::SearchWithoutDeleted; + } + else { + runparams.for_searchAdv = OutputParams::SearchWithDeleted; + } if (cur.inTexted()) { // @TODO what about searching beyond/across paragraph breaks ? diff --git a/src/output_latex.cpp b/src/output_latex.cpp index 2f5d964a47..e98936de42 100644 --- a/src/output_latex.cpp +++ b/src/output_latex.cpp @@ -438,6 +438,11 @@ void TeXEnvironment(Buffer const & buf, Text const & text, // Do not output empty environments if the whole paragraph has // been deleted with ct and changes are not output. + bool output_changes; + if (runparams.for_searchAdv == OutputParams::NoSearch) + output_changes = buf.params().output_changes; + else + output_changes = (runparams.for_searchAdv == OutputParams::SearchWithDeleted); if (size_t(pit + 1) < paragraphs.size()) { ParagraphList::const_iterator nextpar = paragraphs.iterator_at(pit + 1); Paragraph const & cpar = paragraphs.at(pit); @@ -445,8 +450,8 @@ void TeXEnvironment(Buffer const & buf, Text const & text, || par->params().depth() == nextpar->params().depth() || par->params().leftIndent() == nextpar->params().leftIndent()) && !cpar.empty() - && cpar.isDeleted(0, cpar.size()) && !buf.params().output_changes) { - if (!buf.params().output_changes && !cpar.parEndChange().deleted()) + && cpar.isDeleted(0, cpar.size()) && !output_changes) { + if (!output_changes && !cpar.parEndChange().deleted()) os << '\n' << '\n'; continue; } @@ -549,7 +554,7 @@ void getArgInsets(otexstream & os, OutputParams const & runparams, Layout::LaTeX } } } - if (runparams.for_search && argnr > 1) { + if ((runparams.for_searchAdv != OutputParams::NoSearch) && argnr > 1) { // Mark end of arguments for findadv() only os << "\\endarguments{}"; } @@ -709,7 +714,7 @@ void parStartCommand(Paragraph const & par, otexstream & os, break; case LATEX_ITEM_ENVIRONMENT: case LATEX_LIST_ENVIRONMENT: - if (runparams.for_search) { + if (runparams.for_searchAdv != OutputParams::NoSearch) { os << "\\" + style.itemcommand() << "{" << style.latexname() << "}"; } else { @@ -721,7 +726,7 @@ void parStartCommand(Paragraph const & par, otexstream & os, } break; case LATEX_ENVIRONMENT: - if (runparams.for_search) { + if (runparams.for_searchAdv != OutputParams::NoSearch) { os << "\\latexenvironment{" << style.latexname() << "}{"; } break; @@ -759,7 +764,7 @@ void TeXOnePar(Buffer const & buf, // Do not output empty commands if the whole paragraph has // been deleted with ct and changes are not output. - if (style.latextype != LATEX_ENVIRONMENT + if ((runparams_in.for_searchAdv != OutputParams::SearchWithDeleted) && style.latextype != LATEX_ENVIRONMENT && !par.empty() && par.isDeleted(0, par.size()) && !bparams.output_changes) return; @@ -897,7 +902,7 @@ void TeXOnePar(Buffer const & buf, } } Language const * const prev_language = - runparams_in.for_search + runparams_in.for_searchAdv != OutputParams::NoSearch ? languages.getLanguage("ignore") : (prior_nontitle_par && !prior_nontitle_par->isPassThru()) ? (use_prev_env_language @@ -947,7 +952,7 @@ void TeXOnePar(Buffer const & buf, && outer_language->rightToLeft() && !par_language->rightToLeft(); bool const localswitch = - (runparams_in.for_search + (runparams_in.for_searchAdv != OutputParams::NoSearch || text.inset().forceLocalFontSwitch() || (using_begin_end && text.inset().forcePlainLayout()) || in_polyglossia_rtl_env) @@ -962,7 +967,7 @@ void TeXOnePar(Buffer const & buf, bool const localswitch_needed = localswitch && par_lang != outer_lang; // localswitches need to be closed and reopened at each par - if (runparams_in.for_search || ((par_lang != prev_lang || localswitch_needed) + if ((runparams_in.for_searchAdv != OutputParams::NoSearch) || ((par_lang != prev_lang || localswitch_needed) // check if we already put language command in TeXEnvironment() && !(style.isEnvironment() && (pit == 0 || (priorpar->layout() != par.layout() @@ -1030,7 +1035,7 @@ void TeXOnePar(Buffer const & buf, // With CJK, the CJK tag has to be closed first (see below) if ((runparams.encoding->package() != Encoding::CJK || bparams.useNonTeXFonts - || runparams.for_search) + || (runparams.for_searchAdv != OutputParams::NoSearch)) && (par_lang != openLanguageName(state) || localswitch || intitle_command) && !par_lang.empty()) { string bc = use_polyglossia ? @@ -1271,7 +1276,7 @@ void TeXOnePar(Buffer const & buf, // when the paragraph uses CJK, the language has to be closed earlier if ((font.language()->encoding()->package() != Encoding::CJK) || bparams.useNonTeXFonts - || runparams_in.for_search) { + || (runparams_in.for_searchAdv != OutputParams::NoSearch)) { if (lang_end_command.empty()) { // If this is a child, we should restore the // master language after the last paragraph. @@ -1659,6 +1664,11 @@ void latexParagraphs(Buffer const & buf, // Do not output empty environments if the whole paragraph has // been deleted with ct and changes are not output. + bool output_changes; + if (runparams.for_searchAdv == OutputParams::NoSearch) + output_changes = bparams.output_changes; + else + output_changes = (runparams.for_searchAdv == OutputParams::SearchWithDeleted); if (size_t(pit + 1) < paragraphs.size()) { ParagraphList::const_iterator nextpar = paragraphs.iterator_at(pit + 1); Paragraph const & cpar = paragraphs.at(pit); @@ -1666,7 +1676,7 @@ void latexParagraphs(Buffer const & buf, || par->params().depth() == nextpar->params().depth() || par->params().leftIndent() == nextpar->params().leftIndent()) && !cpar.empty() - && cpar.isDeleted(0, cpar.size()) && !bparams.output_changes) { + && cpar.isDeleted(0, cpar.size()) && !output_changes) { if (!cpar.parEndChange().deleted()) os << '\n' << '\n'; continue; @@ -1674,8 +1684,8 @@ void latexParagraphs(Buffer const & buf, } else { // This is the last par Paragraph const & cpar = paragraphs.at(pit); - if (!cpar.empty() - && cpar.isDeleted(0, cpar.size()) && !bparams.output_changes) { + if ( !cpar.empty() + && cpar.isDeleted(0, cpar.size()) && !output_changes) { if (!cpar.parEndChange().deleted()) os << '\n' << '\n'; continue; @@ -1800,7 +1810,7 @@ pair switchEncoding(odocstream & os, BufferParams const & bparams, || oldEnc.package() == Encoding::japanese || oldEnc.package() == Encoding::none || newEnc.package() == Encoding::none - || runparams.for_search) + || (runparams.for_searchAdv != OutputParams::NoSearch)) return make_pair(false, 0); // FIXME We ignore encoding switches from/to encodings that do // neither support the inputenc package nor the CJK package here. -- 2.39.2