X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FParagraph.cpp;h=4ce94415f796f23e1f83a60a378e1257d1d77145;hb=fd5adacef25eb40f813dedd961920c353448213a;hp=10131efc7350b7a8e4815ad7164444d97bca6932;hpb=fbc64ea7ee115bdc4a55c214f28de2166d71f6a2;p=features.git diff --git a/src/Paragraph.cpp b/src/Paragraph.cpp index 10131efc73..4ce94415f7 100644 --- a/src/Paragraph.cpp +++ b/src/Paragraph.cpp @@ -1209,26 +1209,41 @@ void Paragraph::Private::latexSpecialChar(otexstream & os, { char_type const c = owner_->getUChar(bparams, runparams, i); - if (style.pass_thru || runparams.pass_thru || (runparams.for_searchAdv != OutputParams::NoSearch) + if (style.pass_thru || runparams.pass_thru || runparams.find_effective() || contains(style.pass_thru_chars, c) || contains(runparams.pass_thru_chars, c)) { - if (runparams.for_searchAdv != OutputParams::NoSearch) { - if (c == '\\') + if (runparams.find_effective()) { + switch (c) { + case '\\': os << "\\\\"; - else if (c == '{') + return; + case '{': os << "\\braceleft "; - else if (c == '}') + return; + case '}': os << "\\braceright "; - else if (c != '\0') + return; + case '$': + os << "\\lyxdollar "; + return; + case '~': + os << "\\lyxtilde "; + return; + case ' ': + case '\0': + break; + default: os.put(c); + return; + } } else if (c != '\0') { Encoding const * const enc = runparams.encoding; if (enc && !enc->encodable(c)) throw EncodingException(c); os.put(c); + return; } - return; } // TIPA uses its own T3 encoding @@ -1240,7 +1255,7 @@ void Paragraph::Private::latexSpecialChar(otexstream & os, // non-standard font encoding. If we are using such a language, // we do not output special T1 chars. if (!runparams.inIPA && !running_font.language()->internalFontEncoding() - && !runparams.isFullUnicode() && bparams.main_font_encoding() == "T1" + && !runparams.isFullUnicode() && runparams.main_fontenc == "T1" && latexSpecialT1(c, os, i, column)) return; // NOTE: "fontspec" (non-TeX fonts) sets the font encoding to "TU" (untill 2017 "EU1" or "EU2") @@ -1532,12 +1547,12 @@ void Paragraph::Private::validate(LaTeXFeatures & features) const if (c == 0x0022) { if (features.runparams().isFullUnicode() && bp.useNonTeXFonts) features.require("textquotedblp"); - else if (bp.main_font_encoding() != "T1" + else if (features.runparams().main_fontenc != "T1" || ((&owner_->getFontSettings(bp, i))->language()->internalFontEncoding())) features.require("textquotedbl"); - } else if (ci.textfeature() && contains(ci.textpreamble(), '=')) { + } else if (ci.textFeature() && contains(ci.textPreamble(), '=')) { // features that depend on the font or input encoding - string feats = ci.textpreamble(); + string feats = ci.textPreamble(); string fontenc = (&owner_->getFontSettings(bp, i))->language()->fontenc(bp); if (fontenc.empty()) fontenc = features.runparams().main_fontenc; @@ -1912,7 +1927,8 @@ FontSpan Paragraph::fontSpan(pos_type pos) const // This should not happen, but if so, we take no chances. LYXERR0("Paragraph::fontSpan: position not found in fontinfo table!"); - LASSERT(false, return FontSpan(pos, pos)); + LASSERT(false, /**/); + return FontSpan(pos, pos); } @@ -2269,6 +2285,12 @@ bool Paragraph::isPassThru() const } +bool Paragraph::parbreakIsNewline() const +{ + return inInset().getLayout().parbreakIsNewline() || d->layout_->parbreak_is_newline; +} + + bool Paragraph::isPartOfTextSequence() const { for (pos_type i = 0; i < size(); ++i) { @@ -2355,14 +2377,23 @@ int Paragraph::Private::startTeXParParams(BufferParams const & bparams, // 1. that cannot have indentation or are indented always, // 2. that are not part of the immediate text sequence (e.g., contain only floats), // 3. that are PassThru, - // 4. that are centered, - // 5. or start with a vspace. - if (canindent && params_.noindent() && owner_->isPartOfTextSequence() - && !layout_->pass_thru && curAlign != LYX_ALIGN_CENTER - && !owner_->empty() - && (!owner_->isInset(0) || owner_->getInset(0)->lyxCode() != VSPACE_CODE)) { - os << "\\noindent" << termcmd; - column += 10; + // 4. or that are centered. + if (canindent && params_.noindent() + && owner_->isPartOfTextSequence() + && !layout_->pass_thru + && curAlign != LYX_ALIGN_CENTER) { + if (!owner_->empty() + && owner_->getInset(0) + && owner_->getInset(0)->lyxCode() == VSPACE_CODE) + // If the paragraph starts with a vspace, the \\noindent + // needs to come after that (as it leaves vmode). + // If the paragraph consists only of the vspace, + // \\noindent is not needed at all. + runparams.need_noindent = owner_->size() > 1; + else { + os << "\\noindent" << termcmd; + column += 10; + } } if (curAlign == layout_->align) @@ -2495,7 +2526,7 @@ void Paragraph::latex(BufferParams const & bparams, OutputParams const & runparams, int start_pos, int end_pos, bool force) const { - LYXERR(Debug::LATEX, "Paragraph::latex... " << this); + LYXERR(Debug::OUTFILE, "Paragraph::latex... " << this); // FIXME This check should not be needed. Perhaps issue an // error if it triggers. @@ -2524,10 +2555,10 @@ void Paragraph::latex(BufferParams const & bparams, pos_type body_pos = beginOfBody(); unsigned int column = 0; - // If we are inside an non inheritFont() inset, the real outerfont is local_font - Font const real_outerfont = (!inInset().inheritFont() - && runparams.local_font != nullptr) - ? Font(runparams.local_font->fontInfo()) : outerfont; + // If we are inside an non inheritFont() inset, + // the outerfont is the buffer's main font + Font const real_outerfont = + inInset().inheritFont() ? outerfont : Font(bparams.getFont()); if (body_pos > 0) { // the optional argument is kept in curly brackets in @@ -2595,7 +2626,7 @@ void Paragraph::latex(BufferParams const & bparams, runparams); runningChange = Change(Change::UNCHANGED); - os << (isEnvSeparator(i) ? "}]~" : "}] "); + os << ((isEnvSeparator(i) && !runparams.find_effective()) ? "}]~" : "}] "); column +=3; } // For InTitle commands, we have already opened a group @@ -2625,10 +2656,10 @@ void Paragraph::latex(BufferParams const & bparams, // Check whether a display math inset follows bool output_changes; - if (runparams.for_searchAdv == OutputParams::NoSearch) + if (!runparams.find_effective()) output_changes = bparams.output_changes; else - output_changes = (runparams.for_searchAdv == OutputParams::SearchWithDeleted); + output_changes = runparams.find_with_deleted(); if (c == META_INSET && i >= start_pos && (end_pos == -1 || i < end_pos)) { if (isDeleted(i)) @@ -2758,9 +2789,11 @@ void Paragraph::latex(BufferParams const & bparams, os << '}'; column += 1; } - if (closeLanguage) + if (closeLanguage) { // Force language closing current_font.setLanguage(basefont.language()); + langClosed = true; + } Font const nextfont = (i == body_pos-1) ? basefont : current_font; bool needPar = false; column += running_font.latexWriteEndChanges( @@ -2773,12 +2806,12 @@ void Paragraph::latex(BufferParams const & bparams, column += Changes::latexMarkChange(os, bparams, Change(Change::UNCHANGED), Change(Change::DELETED), rp); } - open_font = false; // Has the language been closed in the latexWriteEndChanges() call above? - langClosed = running_font.language() != basefont.language() + langClosed |= running_font.language() != basefont.language() && running_font.language() != nextfont.language() && (running_font.language()->encoding()->package() != Encoding::CJK); running_font = basefont; + open_font &= !langClosed; } // if necessary, close language environment before opening CJK @@ -2791,7 +2824,8 @@ void Paragraph::latex(BufferParams const & bparams, string end_tag = subst(lang_end_command, "$$lang", running_lang); os << from_ascii(end_tag); column += end_tag.length(); - popLanguageName(); + if (!languageStackEmpty()) + popLanguageName(); } // Switch file encoding if necessary (and allowed) @@ -2877,9 +2911,14 @@ void Paragraph::latex(BufferParams const & bparams, column += Changes::latexMarkChange(os, bparams, Change(Change::UNCHANGED), change, rp); } - } else { + } else {// if fontswitch_inset + if (current_font != running_font || !langClosed) + // font is still open in fontswitch_insets if we have + // a non-lang font difference or if the language + // is the only difference but has not been forcedly + // closed meanwhile + open_font = true; running_font = current_font; - open_font = !langClosed; } } @@ -2948,7 +2987,7 @@ void Paragraph::latex(BufferParams const & bparams, d->latexInset(bparams, os, rp, running_font, basefont, real_outerfont, open_font, runningChange, style, i, column, fontswitch_inset, - closeLanguage, lang_switched_at_inset); + closeLanguage, (lang_switched_at_inset || langClosed)); if (fontswitch_inset) { if (open_font) { bool needPar = false; @@ -3111,7 +3150,7 @@ void Paragraph::latex(BufferParams const & bparams, os << setEncoding(prev_encoding->iconvName()); } - LYXERR(Debug::LATEX, "Paragraph::latex... done " << this); + LYXERR(Debug::OUTFILE, "Paragraph::latex... done " << this); } @@ -3981,6 +4020,8 @@ docstring Paragraph::simpleLyXHTMLOnePar(Buffer const & buf, runparams, i); if (c == ' ' && (style.free_spacing || runparams.free_spacing)) xs << XMLStream::ESCAPE_NONE << " "; + else if (c == '\'') + xs << XMLStream::ESCAPE_NONE << "’"; else xs << c; } @@ -4099,27 +4140,12 @@ bool Paragraph::needsCProtection(bool const fragile) const } // now check whether we have insets that need cprotection - pos_type size = pos_type(d->text_.size()); - for (pos_type i = 0; i < size; ++i) { - if (!isInset(i)) + for (auto const & icit : d->insetlist_) { + Inset const * ins = icit.inset; + if (!ins) continue; - Inset const * ins = getInset(i); if (ins->needsCProtection(maintext, fragile)) return true; - // Now check math environments - InsetMath const * im = getInset(i)->asInsetMath(); - if (!im || im->cell(0).empty()) - continue; - switch(im->cell(0)[0]->lyxCode()) { - case MATH_AMSARRAY_CODE: - case MATH_SUBSTACK_CODE: - case MATH_ENV_CODE: - case MATH_XYMATRIX_CODE: - // these need cprotection - return true; - default: - break; - } } return false; @@ -4559,7 +4585,6 @@ void Paragraph::changeCase(BufferParams const & bparams, pos_type pos, } } - int Paragraph::find(docstring const & str, bool cs, bool mw, pos_type start_pos, bool del) const { @@ -4584,7 +4609,14 @@ int Paragraph::find(docstring const & str, bool cs, bool mw, if (!inset->isLetter() && !inset->isChar()) break; odocstringstream os; - inset->toString(os); + if (inset->lyxCode() == lyx::QUOTE_CODE) { + OutputParams op(0); + op.find_set_feature(OutputParams::SearchQuick); + inset->plaintext(os, op); + } + else { + inset->toString(os); + } docstring const insetstring = os.str(); if (!insetstring.empty()) { int const insetstringsize = insetstring.length(); @@ -4600,9 +4632,10 @@ int Paragraph::find(docstring const & str, bool cs, bool mw, } if (nonmatch || i == strsize) break; - if (cs && str[i] != d->text_[pos]) + char_type dp = d->text_[pos]; + if (cs && str[i] != dp) break; - if (!cs && uppercase(str[i]) != uppercase(d->text_[pos])) + if (!cs && uppercase(str[i]) != uppercase(dp)) break; } @@ -4849,6 +4882,19 @@ Language * Paragraph::Private::getSpellLanguage(pos_type const from) const void Paragraph::requestSpellCheck(pos_type pos) { d->requestSpellCheck(pos); + if (pos == -1) { + // Also request spellcheck within (text) insets + for (auto const & insets : insetList()) { + if (!insets.inset->asInsetText()) + continue; + ParagraphList & inset_pars = + insets.inset->asInsetText()->paragraphs(); + ParagraphList::iterator pit = inset_pars.begin(); + ParagraphList::iterator pend = inset_pars.end(); + for (; pit != pend; ++pit) + pit->requestSpellCheck(); + } + } }