X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FParagraph.cpp;h=81deac4f393a180862e33f1d0a76661f671bf6eb;hb=f6f32ca0ee1d341e39f202e2921ccbd4d5537f5b;hp=50b0bcfb00dca066acc1493986449a87547d0c96;hpb=d866717ef7503a1373dd1cb3925e1ac97b079192;p=lyx.git diff --git a/src/Paragraph.cpp b/src/Paragraph.cpp index 50b0bcfb00..81deac4f39 100644 --- a/src/Paragraph.cpp +++ b/src/Paragraph.cpp @@ -112,7 +112,7 @@ public: if (range_.first > pos) { range_.first += offset; range_.last += offset; - } else if (range_.last > pos) { + } else if (range_.last >= pos) { range_.last += offset; } } @@ -336,6 +336,7 @@ public: Change const & running_change, Layout const & style, pos_type & i, + pos_type end_pos, unsigned int & column); /// @@ -354,6 +355,7 @@ public: bool latexSpecialPhrase( otexstream & os, pos_type & i, + pos_type end_pos, unsigned int & column, OutputParams const & runparams); @@ -1089,7 +1091,7 @@ void Paragraph::Private::latexInset(BufferParams const & bparams, // ArabTeX, though, cannot handle this special behavior, it seems. bool arabtex = basefont.language()->lang() == "arabic_arabtex" || running_font.language()->lang() == "arabic_arabtex"; - if (open_font && inset->noFontChange()) { + if (open_font && !inset->inheritFont()) { bool closeLanguage = arabtex || basefont.isRightToLeft() == running_font.isRightToLeft(); unsigned int count = running_font.latexWriteEndChanges(os, @@ -1115,6 +1117,8 @@ void Paragraph::Private::latexInset(BufferParams const & bparams, int prev_rows = os.texrow().rows(); try { + runparams.lastid = id_; + runparams.lastpos = i; inset->latex(os, runparams); } catch (EncodingException & e) { // add location information and throw again. @@ -1148,15 +1152,18 @@ void Paragraph::Private::latexSpecialChar(otexstream & os, Change const & running_change, Layout const & style, pos_type & i, + pos_type end_pos, unsigned int & column) { char_type const c = text_[i]; if (style.pass_thru || runparams.pass_thru) { - if (c != '\0') - // FIXME UNICODE: This can fail if c cannot - // be encoded in the current encoding. + if (c != '\0') { + Encoding const * const enc = runparams.encoding; + if (enc && enc->latexChar(c, true).empty()) + throw EncodingException(c); os.put(c); + } return; } @@ -1237,7 +1244,7 @@ void Paragraph::Private::latexSpecialChar(otexstream & os, default: // LyX, LaTeX etc. - if (latexSpecialPhrase(os, i, column, runparams)) + if (latexSpecialPhrase(os, i, end_pos, column, runparams)) return; if (c == '\0') @@ -1323,7 +1330,10 @@ bool Paragraph::Private::latexSpecialTypewriter(char_type const c, otexstream & } -bool Paragraph::Private::latexSpecialPhrase(otexstream & os, pos_type & i, +/// \param end_pos +/// If [start_pos, end_pos) does not include entirely the special phrase, then +/// do not apply the macro transformation. +bool Paragraph::Private::latexSpecialPhrase(otexstream & os, pos_type & i, pos_type end_pos, unsigned int & column, OutputParams const & runparams) { // FIXME: if we have "LaTeX" with a font @@ -1333,7 +1343,8 @@ bool Paragraph::Private::latexSpecialPhrase(otexstream & os, pos_type & i, // "words" for some definition of word for (size_t pnr = 0; pnr < phrases_nr; ++pnr) { - if (!isTextAt(special_phrases[pnr].phrase, i)) + if (!isTextAt(special_phrases[pnr].phrase, i) + || (end_pos != -1 && i + int(special_phrases[pnr].phrase.size()) > end_pos)) continue; if (runparams.moving_arg) os << "\\protect"; @@ -2364,8 +2375,8 @@ void Paragraph::latex(BufferParams const & bparams, runparams); } - Change const & change = runparams.inDeletedInset ? runparams.changeOfDeletedInset - : lookupChange(i); + Change const & change = runparams.inDeletedInset + ? runparams.changeOfDeletedInset : lookupChange(i); if (bparams.outputChanges && runningChange != change) { if (open_font) { @@ -2499,7 +2510,7 @@ void Paragraph::latex(BufferParams const & bparams, if (i >= start_pos && (end_pos == -1 || i < end_pos)) { try { d->latexSpecialChar(os, rp, running_font, runningChange, - style, i, column); + style, i, end_pos, column); } catch (EncodingException & e) { if (runparams.dryrun) { os << "<" << _("LyX Warning: ") @@ -2839,6 +2850,14 @@ bool Paragraph::isWordSeparator(pos_type pos) const if (pos == size()) return true; char_type const c = d->text_[pos]; + // if we have a hard hyphen (no en- or emdash), + // we pass this to the spell checker + if (c == '-') { + int j = pos + 1; + if ((j == size() || d->text_[j] != '-') + && (pos == 0 || d->text_[pos - 1] != '-')) + return false; + } // We want to pass the ' and escape chars to the spellchecker static docstring const quote = from_utf8(lyxrc.spellchecker_esc_chars + '\''); return (!isLetterChar(c) && !isDigitASCII(c) && !contains(quote, c)); @@ -3333,12 +3352,12 @@ int Paragraph::find(docstring const & str, bool cs, bool mw, int i = 0; pos_type const parsize = d->text_.size(); for (i = 0; i < strsize && pos < parsize; ++i, ++pos) { - // Ignore ligature break and hyphenation chars while searching + // Ignore "invisible" letters such as ligature breaks + // and hyphenation chars while searching while (pos < parsize - 1 && isInset(pos)) { - const InsetSpecialChar *isc = dynamic_cast(getInset(pos)); - if (isc == 0 - || (isc->kind() != InsetSpecialChar::HYPHENATION - && isc->kind() != InsetSpecialChar::LIGATURE_BREAK)) + odocstringstream os; + getInset(pos)->toString(os); + if (!getInset(pos)->isLetter() || !os.str().empty()) break; pos++; } @@ -3632,6 +3651,7 @@ SpellChecker::Result Paragraph::spellCheck(pos_type & from, pos_type & to, return result; if (needsSpellCheck() || check_learned) { + pos_type end = to; if (!d->ignoreWord(word)) { bool const trailing_dot = to < size() && d->text_[to] == '.'; result = speller->check(wl); @@ -3643,28 +3663,33 @@ SpellChecker::Result Paragraph::spellCheck(pos_type & from, pos_type & to, word << "\" [" << from << ".." << to << "]"); } else { - // spell check with dot appended failed + // spell check with dot appended failed too // restore original word/lang value word = asString(from, to, AS_STR_INSETS | AS_STR_SKIPDELETE); wl = WordLangTuple(word, lang); } } } - d->setMisspelled(from, to, result); + if (!SpellChecker::misspelled(result)) { + // area up to the begin of the next word is not misspelled + while (end < size() && isWordSeparator(end)) + ++end; + } + d->setMisspelled(from, end, result); } else { result = d->speller_state_.getState(from); } - bool const misspelled_ = SpellChecker::misspelled(result) ; - if (misspelled_ && do_suggestion) - speller->suggest(wl, suggestions); - else if (misspelled_) + if (do_suggestion) + suggestions.clear(); + + if (SpellChecker::misspelled(result)) { LYXERR(Debug::GUI, "misspelled word: \"" << word << "\" [" << from << ".." << to << "]"); - else - suggestions.clear(); - + if (do_suggestion) + speller->suggest(wl, suggestions); + } return result; }