]> git.lyx.org Git - lyx.git/blobdiff - src/Paragraph.cpp
Reduce horizontal spacing for simple inline equations
[lyx.git] / src / Paragraph.cpp
index 5cea164d63ded34e5511c87809d5746319cb65e9..7b0b3552ddda4fb7eebf201f25917a3026def7ce 100644 (file)
@@ -40,6 +40,7 @@
 #include "ParagraphParameters.h"
 #include "SpellChecker.h"
 #include "sgml.h"
+#include "texstream.h"
 #include "TextClass.h"
 #include "TexRow.h"
 #include "Text.h"
@@ -52,6 +53,8 @@
 #include "insets/InsetLabel.h"
 #include "insets/InsetSpecialChar.h"
 
+#include "mathed/InsetMathHull.h"
+
 #include "support/debug.h"
 #include "support/docstring_list.h"
 #include "support/ExceptionMessage.h"
@@ -60,6 +63,7 @@
 #include "support/lstrings.h"
 #include "support/textutils.h"
 
+#include <atomic>
 #include <sstream>
 #include <vector>
 
@@ -282,10 +286,11 @@ private:
 
 class Paragraph::Private
 {
-       // Enforce our own "copy" constructor by declaring the standard one and
-       // the assignment operator private without implementing them.
-       Private(Private const &);
-       Private & operator=(Private const &);
+       // Enforce our own "copy" constructor
+       Private(Private const &) = delete;
+       Private & operator=(Private const &) = delete;
+       // Unique ID generator
+       static int make_id();
 public:
        ///
        Private(Paragraph * owner, Layout const & layout);
@@ -358,6 +363,12 @@ public:
                pos_type i,
                unsigned int & column);
        ///
+       bool latexSpecialTU(
+               char_type const c,
+               otexstream & os,
+               pos_type i,
+               unsigned int & column);
+       ///
        bool latexSpecialT3(
                char_type const c,
                otexstream & os,
@@ -505,35 +516,37 @@ Paragraph::Private::Private(Paragraph * owner, Layout const & layout)
 }
 
 
-// Initialization of the counter for the paragraph id's,
-//
-// FIXME: There should be a more intelligent way to generate and use the
-// paragraph ids per buffer instead a global static counter for all InsetText
-// in the running program.
-// However, this per-session id is used in LFUN_PARAGRAPH_GOTO to
-// switch to a different buffer, as used in the outliner for instance.
-static int paragraph_id = -1;
+//static
+int Paragraph::Private::make_id()
+{
+       // The id is unique per session across buffers because it is used in
+       // LFUN_PARAGRAPH_GOTO to switch to a different buffer, for instance in the
+       // outliner.
+       // (thread-safe)
+       static atomic_uint next_id(0);
+       return next_id++;
+}
+
 
 Paragraph::Private::Private(Private const & p, Paragraph * owner)
        : owner_(owner), inset_owner_(p.inset_owner_), fontlist_(p.fontlist_),
+         id_(make_id()),
          params_(p.params_), changes_(p.changes_), insetlist_(p.insetlist_),
          begin_of_body_(p.begin_of_body_), text_(p.text_), words_(p.words_),
          layout_(p.layout_)
 {
-       id_ = ++paragraph_id;
        requestSpellCheck(p.text_.size());
 }
 
 
 Paragraph::Private::Private(Private const & p, Paragraph * owner,
        pos_type beg, pos_type end)
-       : owner_(owner), inset_owner_(p.inset_owner_),
+       : owner_(owner), inset_owner_(p.inset_owner_), id_(make_id()),
          params_(p.params_), changes_(p.changes_),
          insetlist_(p.insetlist_, beg, end),
          begin_of_body_(p.begin_of_body_), words_(p.words_),
          layout_(p.layout_)
 {
-       id_ = ++paragraph_id;
        if (beg >= pos_type(p.text_.size()))
                return;
        text_ = p.text_.substr(beg, end - beg);
@@ -555,10 +568,22 @@ Paragraph::Private::Private(Private const & p, Paragraph * owner,
 }
 
 
-void Paragraph::addChangesToToc(DocIterator const & cdit,
-       Buffer const & buf, bool output_active) const
+void Paragraph::addChangesToToc(DocIterator const & cdit, Buffer const & buf,
+                                bool output_active, TocBackend & backend) const
+{
+       d->changes_.addToToc(cdit, buf, output_active, backend);
+}
+
+
+void Paragraph::addChangesToBuffer(Buffer const & buf) const
 {
-       d->changes_.addToToc(cdit, buf, output_active);
+       d->changes_.updateBuffer(buf);
+}
+
+
+bool Paragraph::isChangeUpdateRequired() const
+{
+       return d->changes_.isUpdateRequired();
 }
 
 
@@ -1060,7 +1085,7 @@ void Paragraph::Private::latexInset(BufferParams const & bparams,
            // decorations at all
            && inset->lyxCode() != ERT_CODE) {
                if (running_font.language()->lang() == "farsi")
-                       os << "\\beginL{}";
+                       os << "\\beginL" << termcmd;
                else
                        os << "\\L{";
                close = true;
@@ -1101,7 +1126,7 @@ void Paragraph::Private::latexInset(BufferParams const & bparams,
                }
        }
 
-       int prev_rows = os.texrow().rows();
+       size_t const previous_row_count = os.texrow().rows();
 
        try {
                runparams.lastid = id_;
@@ -1116,12 +1141,12 @@ void Paragraph::Private::latexInset(BufferParams const & bparams,
 
        if (close) {
                if (running_font.language()->lang() == "farsi")
-                               os << "\\endL{}";
+                               os << "\\endL" << termcmd;
                        else
                                os << '}';
        }
 
-       if (os.texrow().rows() > prev_rows) {
+       if (os.texrow().rows() > previous_row_count) {
                os.texrow().start(owner_->id(), i + 1);
                column = 0;
        } else {
@@ -1169,30 +1194,37 @@ 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()
-           && bparams.font_encoding() == "T1" && latexSpecialT1(c, os, i, column))
+           && !runparams.isFullUnicode() && bparams.main_font_encoding() == "T1"
+           && latexSpecialT1(c, os, i, column))
                return;
+       // NOTE: XeTeX and LuaTeX use EU1/2 (pre 2017) or TU (as of 2017) encoding
+       else if (!runparams.inIPA && !running_font.language()->internalFontEncoding()
+                && runparams.isFullUnicode() && latexSpecialTU(c, os, i, column))
+                    return;
 
        // Otherwise, we use what LaTeX provides us.
        switch (c) {
        case '\\':
-               os << "\\textbackslash{}";
+               os << "\\textbackslash" << termcmd;
                column += 15;
                break;
        case '<':
-               os << "\\textless{}";
+               os << "\\textless" << termcmd;
                column += 10;
                break;
        case '>':
-               os << "\\textgreater{}";
+               os << "\\textgreater" << termcmd;
                column += 13;
                break;
        case '|':
-               os << "\\textbar{}";
+               os << "\\textbar" << termcmd;
                column += 9;
                break;
        case '-':
                os << '-';
-               if (i + 1 < end_pos && text_[i+1] == '-') {
+               if (i + 1 < static_cast<pos_type>(text_.size()) &&
+                   (end_pos == -1 || i + 1 < end_pos) &&
+                   text_[i+1] == '-') {
                        // Prevent "--" becoming an endash and "---" becoming
                        // an emdash.
                        // Within \ttfamily, "--" is merged to "-" (no endash)
@@ -1202,7 +1234,7 @@ void Paragraph::Private::latexSpecialChar(otexstream & os,
                }
                break;
        case '\"':
-               os << "\\char`\\\"{}";
+               os << "\\char34" << termcmd;
                column += 9;
                break;
 
@@ -1215,12 +1247,12 @@ void Paragraph::Private::latexSpecialChar(otexstream & os,
                break;
 
        case '~':
-               os << "\\textasciitilde{}";
+               os << "\\textasciitilde" << termcmd;
                column += 16;
                break;
 
        case '^':
-               os << "\\textasciicircum{}";
+               os << "\\textasciicircum" << termcmd;
                column += 17;
                break;
 
@@ -1242,6 +1274,21 @@ void Paragraph::Private::latexSpecialChar(otexstream & os,
                // written. (Asger)
                break;
 
+       case 0x2013:
+       case 0x2014:
+               if (bparams.use_dash_ligatures && !bparams.useNonTeXFonts) {
+                       if (c == 0x2013) {
+                               // en-dash
+                               os << "--";
+                               column +=2;
+                       } else {
+                               // em-dash
+                               os << "---";
+                               column +=3;
+                       }
+                       break;
+               }
+               // fall through
        default:
                if (c == '\0')
                        return;
@@ -1318,7 +1365,7 @@ bool Paragraph::Private::latexSpecialT1(char_type const c, otexstream & os,
                // but we should avoid ligatures
                if (i + 1 >= int(text_.size()) || text_[i + 1] != c)
                        return true;
-               os << "\\textcompwordmark{}";
+               os << "\\textcompwordmark" << termcmd;
                column += 19;
                return true;
        case '|':
@@ -1326,7 +1373,7 @@ bool Paragraph::Private::latexSpecialT1(char_type const c, otexstream & os,
                return true;
        case '\"':
                // soul.sty breaks with \char`\"
-               os << "\\textquotedbl{}";
+               os << "\\textquotedbl" << termcmd;
                column += 14;
                return true;
        default:
@@ -1335,6 +1382,14 @@ bool Paragraph::Private::latexSpecialT1(char_type const c, otexstream & os,
 }
 
 
+bool Paragraph::Private::latexSpecialTU(char_type const c, otexstream & os,
+       pos_type i, unsigned int & column)
+{
+       // TU encoding is currently on par with T1.
+       return latexSpecialT1(c, os, i, column);
+}
+
+
 bool Paragraph::Private::latexSpecialT3(char_type const c, otexstream & os,
        pos_type /*i*/, unsigned int & column)
 {
@@ -1346,7 +1401,7 @@ bool Paragraph::Private::latexSpecialT3(char_type const c, otexstream & os,
                os.put(c);
                return true;
        case '|':
-               os << "\\textvertline{}";
+               os << "\\textvertline" << termcmd;
                column += 14;
                return true;
        default:
@@ -1363,13 +1418,12 @@ void Paragraph::Private::validate(LaTeXFeatures & features) const
                BufferParams const & bp = features.runparams().is_child
                        ? buf.masterParams() : buf.params();
                Font f;
-               TexRow texrow;
                // Using a string stream here circumvents the encoding
                // switching machinery of odocstream. Therefore the
                // output is wrong if this paragraph contains content
                // that needs to switch encoding.
-               odocstringstream ods;
-               otexstream os(ods, texrow);
+               otexstringstream os;
+               os << layout_->preamble();
                if (is_command) {
                        os << '\\' << from_ascii(layout_->latexname());
                        // we have to provide all the optional arguments here, even though
@@ -1382,20 +1436,19 @@ void Paragraph::Private::validate(LaTeXFeatures & features) const
                        }
                        os << from_ascii(layout_->latexparam());
                }
-               docstring::size_type const length = ods.str().length();
+               size_t const length = os.length();
                // this will output "{" at the beginning, but not at the end
                owner_->latex(bp, f, os, features.runparams(), 0, -1, true);
-               if (ods.str().length() > length) {
+               if (os.length() > length) {
                        if (is_command) {
-                               ods << '}';
+                               os << '}';
                                if (!layout_->postcommandargs().empty()) {
                                        OutputParams rp = features.runparams();
                                        rp.local_font = &owner_->getFirstFontSettings(bp);
                                        latexArgInsets(*owner_, os, rp, layout_->postcommandargs(), "post:");
                                }
                        }
-                       string const snippet = to_utf8(ods.str());
-                       features.addPreambleSnippet(snippet);
+                       features.addPreambleSnippet(os.release(), true);
                }
        }
 
@@ -1423,10 +1476,12 @@ void Paragraph::Private::validate(LaTeXFeatures & features) const
        InsetList::const_iterator iend = insetlist_.end();
        for (; icit != iend; ++icit) {
                if (icit->inset) {
+                       features.inDeletedInset(owner_->isDeleted(icit->pos));
                        icit->inset->validate(features);
+                       features.inDeletedInset(false);
                        if (layout_->needprotect &&
                            icit->inset->lyxCode() == FOOT_CODE)
-                               features.require("footmisc");
+                               features.require("NeedLyXFootnoteCode");
                }
        }
 
@@ -1731,7 +1786,10 @@ Font const & Paragraph::getFontSettings(BufferParams const & bparams,
 
 FontSpan Paragraph::fontSpan(pos_type pos) const
 {
-       LBUFERR(pos < size());
+       LBUFERR(pos <= size());
+
+       if (pos == size())
+               return FontSpan(pos, pos);
 
        pos_type start = 0;
        FontList::const_iterator cit = d->fontlist_.begin();
@@ -1820,14 +1878,6 @@ Font const Paragraph::getLayoutFont
 }
 
 
-/// Returns the height of the highest font in range
-FontSize Paragraph::highestFontInRange
-       (pos_type startpos, pos_type endpos, FontSize def_size) const
-{
-       return d->fontlist_.highestInRange(startpos, endpos, def_size);
-}
-
-
 char_type Paragraph::getUChar(BufferParams const & bparams, pos_type pos) const
 {
        char_type c = d->text_[pos];
@@ -1933,7 +1983,7 @@ depth_type Paragraph::getMaxDepthAfter() const
 }
 
 
-char Paragraph::getAlign() const
+LyXAlignment Paragraph::getAlign() const
 {
        if (d->params_.align() == LYX_ALIGN_LAYOUT)
                return d->layout_->align;
@@ -2374,6 +2424,25 @@ void Paragraph::latex(BufferParams const & bparams,
                                                            runparams);
                }
 
+               runparams.wasDisplayMath = runparams.inDisplayMath;
+               runparams.inDisplayMath = false;
+               bool deleted_display_math = false;
+
+               // Check whether a display math inset follows
+               if (d->text_[i] == META_INSET
+                   && i >= start_pos && (end_pos == -1 || i < end_pos)) {
+                       InsetMath const * im = getInset(i)->asInsetMath();
+                       if (im && im->asHullInset()
+                           && im->asHullInset()->outerDisplay()) {
+                               runparams.inDisplayMath = true;
+                               // runparams.inDeletedInset will be set by
+                               // latexInset later, but we need this info
+                               // before it is called. On the other hand, we
+                               // cannot set it here because it is a counter.
+                               deleted_display_math = isDeleted(i);
+                       }
+               }
+
                Change const & change = runparams.inDeletedInset
                        ? runparams.changeOfDeletedInset : lookupChange(i);
 
@@ -2385,7 +2454,6 @@ void Paragraph::latex(BufferParams const & bparams,
                        }
                        basefont = getLayoutFont(bparams, outerfont);
                        running_font = basefont;
-
                        column += Changes::latexMarkChange(os, bparams, runningChange,
                                                           change, runparams);
                        runningChange = change;
@@ -2400,18 +2468,18 @@ void Paragraph::latex(BufferParams const & bparams,
                ++column;
 
                // Fully instantiated font
-               Font const font = getFont(bparams, i, outerfont);
+               Font const current_font = getFont(bparams, i, outerfont);
 
                Font const last_font = running_font;
 
                // Do we need to close the previous font?
                if (open_font &&
-                   (font != running_font ||
-                    font.language() != running_font.language()))
+                   (current_font != running_font ||
+                    current_font.language() != running_font.language()))
                {
                        column += running_font.latexWriteEndChanges(
                                        os, bparams, runparams, basefont,
-                                       (i == body_pos-1) ? basefont : font);
+                                       (i == body_pos-1) ? basefont : current_font);
                        running_font = basefont;
                        open_font = false;
                }
@@ -2422,39 +2490,63 @@ void Paragraph::latex(BufferParams const & bparams,
                string const lang_end_command = runparams.use_polyglossia ?
                        "\\end{$$lang}" : lyxrc.language_command_end;
                if (!running_lang.empty() &&
-                   font.language()->encoding()->package() == Encoding::CJK) {
+                   current_font.language()->encoding()->package() == Encoding::CJK) {
                                string end_tag = subst(lang_end_command,
                                                        "$$lang",
                                                        running_lang);
                                os << from_ascii(end_tag);
                                column += end_tag.length();
+                               if (runparams.use_polyglossia)
+                                       popPolyglossiaLang();
                }
 
                // Switch file encoding if necessary (and allowed)
                if (!runparams.pass_thru && !style.pass_thru &&
                    runparams.encoding->package() != Encoding::none &&
-                   font.language()->encoding()->package() != Encoding::none) {
+                   current_font.language()->encoding()->package() != Encoding::none) {
                        pair<bool, int> const enc_switch =
                                switchEncoding(os.os(), bparams, runparams,
-                                       *(font.language()->encoding()));
+                                       *(current_font.language()->encoding()));
                        if (enc_switch.first) {
                                column += enc_switch.second;
-                               runparams.encoding = font.language()->encoding();
+                               runparams.encoding = current_font.language()->encoding();
                        }
                }
 
                char_type const c = d->text_[i];
 
+               // A display math inset inside an ulem command will be output
+               // as a box of width \columnwidth, so we have to either disable
+               // indentation if the inset starts a paragraph, or start a new
+               // line to accommodate such box. This has to be done before
+               // writing any font changing commands.
+               if (runparams.inDisplayMath && !deleted_display_math
+                   && runparams.inulemcmd) {
+                       if (os.afterParbreak())
+                               os << "\\noindent";
+                       else
+                               os << "\\\\\n";
+               }
+
                // Do we need to change font?
-               if ((font != running_font ||
-                    font.language() != running_font.language()) &&
+               if ((current_font != running_font ||
+                    current_font.language() != running_font.language()) &&
                        i != body_pos - 1)
                {
                        odocstringstream ods;
-                       column += font.latexWriteStartChanges(ods, bparams,
+                       column += current_font.latexWriteStartChanges(ods, bparams,
                                                              runparams, basefont,
                                                              last_font);
-                       running_font = font;
+                       // Check again for display math in ulem commands as a
+                       // font change may also occur just before a math inset.
+                       if (runparams.inDisplayMath && !deleted_display_math
+                           && runparams.inulemcmd) {
+                               if (os.afterParbreak())
+                                       os << "\\noindent";
+                               else
+                                       os << "\\\\\n";
+                       }
+                       running_font = current_font;
                        open_font = true;
                        docstring fontchange = ods.str();
                        // check whether the fontchange ends with a \\textcolor
@@ -2480,7 +2572,7 @@ void Paragraph::latex(BufferParams const & bparams,
                        // style.pass_thru is false.
                        if (i != body_pos - 1) {
                                if (d->simpleTeXBlanks(runparams, os,
-                                               i, column, font, style)) {
+                                               i, column, current_font, style)) {
                                        // A surrogate pair was output. We
                                        // must not call latexSpecialChar
                                        // in this iteration, since it would output
@@ -2493,7 +2585,7 @@ void Paragraph::latex(BufferParams const & bparams,
 
                OutputParams rp = runparams;
                rp.free_spacing = style.free_spacing;
-               rp.local_font = &font;
+               rp.local_font = &current_font;
                rp.intitle = style.intitle;
 
                // Two major modes:  LaTeX or plain
@@ -2505,12 +2597,12 @@ void Paragraph::latex(BufferParams const & bparams,
                                                basefont, outerfont, open_font,
                                                runningChange, style, i, column);
                        }
-               } else {
-                       if (i >= start_pos && (end_pos == -1 || i < end_pos)) {
-                               try {
-                                       d->latexSpecialChar(os, bparams, rp, running_font, runningChange,
-                                                           style, i, end_pos, column);
-                               } catch (EncodingException & e) {
+               } else if (i >= start_pos && (end_pos == -1 || i < end_pos)) {
+                       try {
+                               d->latexSpecialChar(os, bparams, rp,
+                                                   running_font, runningChange,
+                                                   style, i, end_pos, column);
+                       } catch (EncodingException & e) {
                                if (runparams.dryrun) {
                                        os << "<" << _("LyX Warning: ")
                                           << _("uncodable character") << " '";
@@ -2524,11 +2616,15 @@ void Paragraph::latex(BufferParams const & bparams,
                                }
                        }
                }
-               }
 
                // Set the encoding to that returned from latexSpecialChar (see
                // comment for encoding member in OutputParams.h)
                runparams.encoding = rp.encoding;
+
+               // Also carry on the info on a closed ulem command for insets
+               // such as Note that do not produce any output, so that no
+               // command is ever executed but its opening was recorded.
+               runparams.inulemcmd = rp.inulemcmd;
        }
 
        // If we have an open font definition, we have to close it
@@ -2567,8 +2663,7 @@ void Paragraph::latex(BufferParams const & bparams,
        if (allowcust && d->endTeXParParams(bparams, os, runparams)
            && runparams.encoding != prev_encoding) {
                runparams.encoding = prev_encoding;
-               if (!runparams.isFullUnicode())
-                       os << setEncoding(prev_encoding->iconvName());
+               os << setEncoding(prev_encoding->iconvName());
        }
 
        LYXERR(Debug::LATEX, "Paragraph::latex... done " << this);
@@ -2745,6 +2840,7 @@ docstring Paragraph::simpleLyXHTMLOnePar(Buffer const & buf,
                                    XHTMLStream & xs,
                                    OutputParams const & runparams,
                                    Font const & outerfont,
+                                   bool start_paragraph, bool close_paragraph,
                                    pos_type initial) const
 {
        docstring retval;
@@ -2766,7 +2862,8 @@ docstring Paragraph::simpleLyXHTMLOnePar(Buffer const & buf,
 
        Layout const & style = *d->layout_;
 
-       xs.startParagraph(allowEmpty());
+       if (start_paragraph)
+               xs.startDivision(allowEmpty());
 
        FontInfo font_old =
                style.labeltype == LABEL_MANUAL ? style.labelfont : style.font;
@@ -3052,7 +3149,9 @@ docstring Paragraph::simpleLyXHTMLOnePar(Buffer const & buf,
                        if (!runparams.for_toc || inset->isInToc()) {
                                OutputParams np = runparams;
                                np.local_font = &font;
-                               if (!inset->getLayout().htmlisblock())
+                               // If the paragraph has size 1, then we are in the "special
+                               // case" where we do not output the containing paragraph info
+                               if (!inset->getLayout().htmlisblock() && size() != 1)
                                        np.html_in_par = true;
                                retval += inset->xhtml(xs, np);
                        }
@@ -3063,8 +3162,13 @@ docstring Paragraph::simpleLyXHTMLOnePar(Buffer const & buf,
                font_old = font.fontInfo();
        }
 
+       // FIXME XHTML
+       // I'm worried about what happens if a branch, say, is itself
+       // wrapped in some font stuff. I think that will not work.
        xs.closeFontTags();
-       xs.endParagraph();
+       if (close_paragraph)
+               xs.endDivision();
+
        return retval;
 }
 
@@ -3078,6 +3182,11 @@ bool Paragraph::isHfill(pos_type pos) const
 
 bool Paragraph::isNewline(pos_type pos) const
 {
+       // U+2028 LINE SEPARATOR
+       // U+2029 PARAGRAPH SEPARATOR
+       char_type const c = d->text_[pos];
+       if (c == 0x2028 || c == 0x2029)
+               return true;
        Inset const * inset = getInset(pos);
        return inset && inset->lyxCode() == NEWLINE_CODE;
 }
@@ -3259,19 +3368,17 @@ docstring Paragraph::asString(pos_type beg, pos_type end, int options, const Out
 
 
 void Paragraph::forOutliner(docstring & os, size_t const maxlen,
-                                                       bool const shorten) const
+                            bool const shorten, bool const label) const
 {
        size_t tmplen = shorten ? maxlen + 1 : maxlen;
-       if (!d->params_.labelString().empty())
-               os += d->params_.labelString() + ' ';
+       if (label && !labelString().empty())
+               os += labelString() + ' ';
        for (pos_type i = 0; i < size() && os.length() < tmplen; ++i) {
                if (isDeleted(i))
                        continue;
                char_type const c = d->text_[i];
                if (isPrintable(c))
                        os += c;
-               else if (c == '\t' || c == '\n')
-                       os += ' ';
                else if (c == META_INSET)
                        getInset(i)->forOutliner(os, tmplen, false);
        }
@@ -3462,6 +3569,12 @@ void Paragraph::setBuffer(Buffer & b)
 }
 
 
+void Paragraph::resetBuffer()
+{
+       d->insetlist_.resetBuffer();
+}
+
+
 Inset * Paragraph::releaseInset(pos_type pos)
 {
        Inset * inset = d->insetlist_.release(pos);
@@ -3627,11 +3740,11 @@ void Paragraph::deregisterWords()
        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);
+               WordList & wl = theWordList(itl->first);
                Private::Words::const_iterator it = (itl->second).begin();
                Private::Words::const_iterator et = (itl->second).end();
                for (; it != et; ++it)
-                       wl->remove(*it);
+                       wl.remove(*it);
        }
        d->words_.clear();
 }
@@ -3707,11 +3820,11 @@ void Paragraph::registerWords()
        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);
+               WordList & wl = theWordList(itl->first);
                Private::Words::const_iterator it = (itl->second).begin();
                Private::Words::const_iterator et = (itl->second).end();
                for (; it != et; ++it)
-                       wl->insert(*it);
+                       wl.insert(*it);
        }
 }