]> git.lyx.org Git - lyx.git/blobdiff - src/Paragraph.cpp
Workaround for #6865: smarter FontList::setMisspelled implementation
[lyx.git] / src / Paragraph.cpp
index c47718c3d5a8eedf9d14d8040b1d10769600465a..86b3d5ab0801592073cc9c1fa9685e141d5c591b 100644 (file)
@@ -208,8 +208,9 @@ public:
        TextContainer text_;
        
        typedef set<docstring> Words;
+       typedef map<Language, Words> LangWordsMap;
        ///
-       map<Language, Words> words_;
+       LangWordsMap words_;
        ///
        Layout const * layout_;
 };
@@ -583,7 +584,7 @@ bool Paragraph::Private::simpleTeXBlanks(OutputParams const & runparams,
                                       Font const & font,
                                       Layout const & style)
 {
-       if (style.pass_thru || runparams.verbatim)
+       if (style.pass_thru || runparams.pass_thru)
                return false;
 
        if (i + 1 < int(text_.size())) {
@@ -715,19 +716,18 @@ bool Paragraph::Private::isTextAt(string const & str, pos_type pos) const
 }
 
 
-void Paragraph::Private::latexInset(
-                                            BufferParams const & bparams,
-                                            odocstream & os,
-                                            TexRow & texrow,
-                                            OutputParams & runparams,
-                                            Font & running_font,
-                                            Font & basefont,
-                                            Font const & outerfont,
-                                            bool & open_font,
-                                            Change & running_change,
-                                            Layout const & style,
-                                            pos_type & i,
-                                            unsigned int & column)
+void Paragraph::Private::latexInset(BufferParams const & bparams,
+                                   odocstream & os,
+                                   TexRow & texrow,
+                                   OutputParams & runparams,
+                                   Font & running_font,
+                                   Font & basefont,
+                                   Font const & outerfont,
+                                   bool & open_font,
+                                   Change & running_change,
+                                   Layout const & style,
+                                   pos_type & i,
+                                   unsigned int & column)
 {
        Inset * inset = owner_->getInset(i);
        LASSERT(inset, /**/);
@@ -846,9 +846,7 @@ void Paragraph::Private::latexInset(
        }
 
        if (tmp) {
-               for (int j = 0; j < tmp; ++j)
-                       texrow.newline();
-
+               texrow.newlines(tmp);
                texrow.start(owner_->id(), i + 1);
                column = 0;
        } else {
@@ -871,7 +869,7 @@ void Paragraph::Private::latexSpecialChar(
 {
        char_type const c = text_[i];
 
-       if (style.pass_thru) {
+       if (style.pass_thru || runparams.pass_thru) {
                if (c != '\0')
                        // FIXME UNICODE: This can fail if c cannot
                        // be encoded in the current encoding.
@@ -879,13 +877,6 @@ void Paragraph::Private::latexSpecialChar(
                return;
        }
 
-       if (runparams.verbatim) {
-               // FIXME UNICODE: This can fail if c cannot
-               // be encoded in the current encoding.
-               os.put(c);
-               return;
-       }
-
        // If T1 font encoding is used, use the special
        // characters it provides.
        // NOTE: some languages reset the font encoding
@@ -1080,10 +1071,16 @@ void Paragraph::Private::validate(LaTeXFeatures & features) const
                Font f;
                TexRow tr;
                odocstringstream ods;
-               owner_->latex(bp, f, ods, tr, features.runparams());
-               docstring d = ods.str();
-               if (!d.empty())
-                       features.addPreambleSnippet(to_utf8(d));
+               // we have to provide all the optional arguments here, even though
+               // the last one is the only one we care about.
+               owner_->latex(bp, f, ods, tr, features.runparams(), 0, -1, true);
+               docstring const d = ods.str();
+               if (!d.empty()) {
+                       // this will have "{" at the beginning, but not at the end
+                       string const content = to_utf8(d);
+                       string const cmd = layout_->latexname();
+                       features.addPreambleSnippet("\\" + cmd + content + "}");
+               }
        }
        
        if (features.runparams().flavor == OutputParams::HTML 
@@ -1850,6 +1847,7 @@ int Paragraph::Private::startTeXParParams(BufferParams const & bparams,
        case LYX_ALIGN_BLOCK:
        case LYX_ALIGN_LAYOUT:
        case LYX_ALIGN_SPECIAL:
+       case LYX_ALIGN_DECIMAL:
                break;
        case LYX_ALIGN_LEFT:
        case LYX_ALIGN_RIGHT:
@@ -1870,6 +1868,7 @@ int Paragraph::Private::startTeXParParams(BufferParams const & bparams,
        case LYX_ALIGN_BLOCK:
        case LYX_ALIGN_LAYOUT:
        case LYX_ALIGN_SPECIAL:
+       case LYX_ALIGN_DECIMAL:
                break;
        case LYX_ALIGN_LEFT: {
                string output;
@@ -1918,6 +1917,7 @@ int Paragraph::Private::endTeXParParams(BufferParams const & bparams,
        case LYX_ALIGN_BLOCK:
        case LYX_ALIGN_LAYOUT:
        case LYX_ALIGN_SPECIAL:
+       case LYX_ALIGN_DECIMAL:
                break;
        case LYX_ALIGN_LEFT:
        case LYX_ALIGN_RIGHT:
@@ -1938,6 +1938,7 @@ int Paragraph::Private::endTeXParParams(BufferParams const & bparams,
        case LYX_ALIGN_BLOCK:
        case LYX_ALIGN_LAYOUT:
        case LYX_ALIGN_SPECIAL:
+       case LYX_ALIGN_DECIMAL:
                break;
        case LYX_ALIGN_LEFT: {
                string output;
@@ -1971,26 +1972,24 @@ int Paragraph::Private::endTeXParParams(BufferParams const & bparams,
 
 
 // This one spits out the text of the paragraph
-bool Paragraph::latex(BufferParams const & bparams,
+void Paragraph::latex(BufferParams const & bparams,
        Font const & outerfont,
        odocstream & os, TexRow & texrow,
        OutputParams const & runparams,
-       int start_pos, int end_pos) const
+       int start_pos, int end_pos, bool force) const
 {
        LYXERR(Debug::LATEX, "Paragraph::latex...     " << this);
 
-       if (layout().inpreamble)
-               return true;
-
-       bool return_value = false;
-
-       bool const allowcust = allowParagraphCustomization();
-
        // FIXME This check should not be needed. Perhaps issue an
        // error if it triggers.
        Layout const & style = inInset().forcePlainLayout() ?
                bparams.documentClass().plainLayout() : *d->layout_;
 
+       if (!force && style.inpreamble)
+               return;
+
+       bool const allowcust = allowParagraphCustomization();
+
        // Current base font for all inherited font changes, without any
        // change caused by an individual character, except for the language:
        // It is set to the language of the first character.
@@ -2120,7 +2119,7 @@ bool Paragraph::latex(BufferParams const & bparams,
                }
 
                // Switch file encoding if necessary (and allowed)
-               if (!runparams.verbatim && 
+               if (!runparams.pass_thru && !style.pass_thru &&
                    runparams.encoding->package() != Encoding::none &&
                    font.language()->encoding()->package() != Encoding::none) {
                        pair<bool, int> const enc_switch = switchEncoding(os, bparams,
@@ -2225,9 +2224,8 @@ bool Paragraph::latex(BufferParams const & bparams,
        if (open_font) {
 #ifdef FIXED_LANGUAGE_END_DETECTION
                if (next_) {
-                       running_font
-                               .latexWriteEndChanges(os, bparams, runparams,
-                                       basefont,
+                       running_font.latexWriteEndChanges(os, bparams,
+                                       runparams, basefont,
                                        next_->getFont(bparams, 0, outerfont));
                } else {
                        running_font.latexWriteEndChanges(os, bparams,
@@ -2248,7 +2246,6 @@ bool Paragraph::latex(BufferParams const & bparams,
        // Needed if there is an optional argument but no contents.
        if (body_pos > 0 && body_pos == size()) {
                os << "}]~";
-               return_value = false;
        }
 
        if (allowcust && d->endTeXParParams(bparams, os, texrow, runparams)
@@ -2259,7 +2256,6 @@ bool Paragraph::latex(BufferParams const & bparams,
        }
 
        LYXERR(Debug::LATEX, "Paragraph::latex... done " << this);
-       return return_value;
 }
 
 
@@ -3070,11 +3066,13 @@ bool Paragraph::isSeparator(pos_type pos) const
 
 void Paragraph::deregisterWords()
 {
-       map<Language, Private::Words>::const_iterator itl;
-       Private::Words::const_iterator it;
-       for (itl = d->words_.begin(); itl != d->words_.end(); ++itl) {
+       Private::LangWordsMap::const_iterator itl = d->words_.begin();
+       Private::LangWordsMap::const_iterator ite = d->words_.end();
+       for (; itl != ite; ++itl) {
                WordList * wl = theWordList(itl->first);
-               for (it = (itl->second).begin(); it != (itl->second).end(); ++it)
+               Private::Words::const_iterator it = (itl->second).begin();
+               Private::Words::const_iterator et = (itl->second).end();
+               for (; it != et; ++it)
                        wl->remove(*it);
        }
        d->words_.clear();
@@ -3120,13 +3118,16 @@ void Paragraph::locateWord(pos_type & from, pos_type & to,
 
 void Paragraph::collectWords()
 {
+       // This is the value that needs to be exposed in the preferences
+       // to resolve bug #6760.
+       static int minlength = 6;
        pos_type n = size();
        for (pos_type pos = 0; pos < n; ++pos) {
                if (isWordSeparator(pos))
                        continue;
                pos_type from = pos;
                locateWord(from, pos, WHOLE_WORD);
-               if (pos - from >= 6) {
+               if (pos - from >= minlength) {
                        docstring word = asString(from, pos, AS_STR_NONE);
                        FontList::const_iterator cit = d->fontlist_.fontIterator(pos);
                        if (cit == d->fontlist_.end())
@@ -3140,11 +3141,13 @@ void Paragraph::collectWords()
 
 void Paragraph::registerWords()
 {
-       map<Language, Private::Words>::const_iterator itl;
-       Private::Words::const_iterator it;
-       for (itl = d->words_.begin(); itl != d->words_.end(); ++itl) {
+       Private::LangWordsMap::const_iterator itl = d->words_.begin();
+       Private::LangWordsMap::const_iterator ite = d->words_.end();
+       for (; itl != ite; ++itl) {
                WordList * wl = theWordList(itl->first);
-               for (it = (itl->second).begin(); it != (itl->second).end(); ++it)
+               Private::Words::const_iterator it = (itl->second).begin();
+               Private::Words::const_iterator et = (itl->second).end();
+               for (; it != et; ++it)
                        wl->insert(*it);
        }
 }
@@ -3158,19 +3161,19 @@ void Paragraph::updateWords()
 }
 
 
-bool Paragraph::spellCheck(pos_type & from, pos_type & to, WordLangTuple & wl,
+SpellChecker::Result Paragraph::spellCheck(pos_type & from, pos_type & to, WordLangTuple & wl,
        docstring_list & suggestions, bool do_suggestion) const
 {
        SpellChecker * speller = theSpellChecker();
        if (!speller)
-               return false;
+               return SpellChecker::WORD_OK;
 
        if (!d->layout_->spellcheck || !inInset().allowSpellCheck())
-               return false;
+               return SpellChecker::WORD_OK;
 
        locateWord(from, to, WHOLE_WORD);
        if (from == to || from >= pos_type(d->text_.size()))
-               return false;
+               return SpellChecker::WORD_OK;
 
        docstring word = asString(from, to, AS_STR_INSETS);
        // Ignore words with digits
@@ -3189,29 +3192,19 @@ bool Paragraph::spellCheck(pos_type & from, pos_type & to, WordLangTuple & wl,
        }
        wl = WordLangTuple(word, lang);
        SpellChecker::Result res = ignored ?
-               SpellChecker::OK : speller->check(wl);
-#if 0
-// FIXME: the code below makes aspell abort if a word in an unknown
-//       language is checked.
-       // Just ignore any error that the spellchecker reports.
-       // FIXME: we should through out an exception and catch it in the GUI to
-       // display the error.
-       if (!speller->error().empty())
-               return false;
-#endif
+               SpellChecker::WORD_OK : speller->check(wl);
 
-       bool const misspelled = res != SpellChecker::OK
-               && res != SpellChecker::IGNORED_WORD;
+       bool const misspelled_ = SpellChecker::misspelled(res) ;
 
        if (lyxrc.spellcheck_continuously)
-               d->fontlist_.setMisspelled(from, to, misspelled);
+               d->fontlist_.setMisspelled(from, to, misspelled_);
 
-       if (misspelled && do_suggestion)
+       if (misspelled_ && do_suggestion)
                speller->suggest(wl, suggestions);
        else
                suggestions.clear();
 
-       return misspelled;
+       return res;
 }
 
 
@@ -3221,7 +3214,8 @@ bool Paragraph::isMisspelled(pos_type pos) const
        pos_type to = pos;
        WordLangTuple wl;
        docstring_list suggestions;
-       return spellCheck(from, to, wl, suggestions, false);
+       SpellChecker::Result res = spellCheck(from, to, wl, suggestions, false);
+       return SpellChecker::misspelled(res) ;
 }