]> git.lyx.org Git - lyx.git/blobdiff - src/paragraph.C
Fixed rowbreaking for "character"-insets and ignore all paragraph attributes
[lyx.git] / src / paragraph.C
index 3a3402bc55d2a0806ddcb388f34e2d3674b11d43..2e3a09feb90743f57049f9464cc9308d89bdad66 100644 (file)
 /* This file is part of
- * ======================================================
+ * ====================================================== 
  * 
  *           LyX, The Document Processor
  *      
  *           Copyright 1995 Matthias Ettrich
- *           Copyright 1995-1999 The LyX Team. 
+ *           Copyright 1995-2001 The LyX Team. 
  *
- * ======================================================*/
+ * ====================================================== */
 
 #include <config.h>
 
 #ifdef __GNUG__
-#pragma implementation "lyxparagraph.h"
+#pragma implementation
 #endif
 
-#include "lyxparagraph.h"
+#include "paragraph.h"
+#include "paragraph_pimpl.h"
 #include "lyxrc.h"
 #include "layout.h"
+#include "language.h"
 #include "tex-strings.h"
+#include "buffer.h"
 #include "bufferparams.h"
-#include "support/FileInfo.h"
 #include "debug.h"
 #include "LaTeXFeatures.h"
-#include "insets/insetinclude.h"
-#include "support/filetools.h"
 #include "lyx_gui_misc.h"
 #include "texrow.h"
+#include "BufferView.h"
+#include "encoding.h"
+#include "ParameterStruct.h"
+#include "gettext.h"
+#include "lyxtextclasslist.h"
 
-#ifndef NEW_TEXT
-#define INITIAL_SIZE_PAR 10 /*Number of bytes in one paragraph*/
-#define STEP_SIZE_PAR 10 /*Number of bytes added when reallocated*/
-#endif
+#include "insets/insetinclude.h"
+#include "insets/insetbib.h"
+#include "insets/insettext.h"
+
+#include "support/filetools.h"
+#include "support/lstrings.h"
+#include "support/lyxmanip.h"
+#include "support/FileInfo.h"
+#include "support/LAssert.h"
+#include "support/textutils.h"
+
+#include <algorithm>
+#include <fstream>
+#include <csignal>
+
+using std::ostream;
+using std::endl;
+using std::fstream;
+using std::ios;
+using std::lower_bound;
+using std::upper_bound;
+using std::reverse;
+
+using lyx::pos_type;
+using lyx::layout_type;
 
-extern void addNewlineAndDepth(string & file, int const depth); // Jug 990923
-extern unsigned char GetCurrentTextClass(); // this should be fixed/removed
 int tex_code_break_column = 72;  // needs non-zero initialization. set later.
-// this is a bad idea, but how can LyXParagraph find its buffer to get
+// this is a bad idea, but how can Paragraph find its buffer to get
 // parameters? (JMarc)
-extern BufferView * current_view;
-extern LyXRC * lyxrc;
 
+extern string bibitemWidest(Buffer const *);
 
-// ale970405
-extern string bibitemWidthest();
+// this is a minibuffer
 
-/* this is a minibuffer */
-static char minibuffer_char;
-static LyXFont minibuffer_font;
-static Inset * minibuffer_inset;
+namespace {
 
+char minibuffer_char;
+LyXFont minibuffer_font;
+Inset * minibuffer_inset;
 
-// Initialization of the counter for the paragraph id's,
-// declared in lyxparagraph.h
-unsigned int LyXParagraph::paragraph_id = 0;
+} // namespace anon
 
 
-LyXParagraph::LyXParagraph()
+extern BufferView * current_view;
+
+
+Paragraph::Paragraph()
+       : layout(0), pimpl_(new Paragraph::Pimpl(this))
 {
-#ifndef NEW_TEXT
-       size = INITIAL_SIZE_PAR;
-       text = new char[size];
-       last = 0;
-#endif
-       for (int i = 0; i < 10; ++i) setCounter(i , 0);
-       appendix = false;
+       for (int i = 0; i < 10; ++i)
+               setCounter(i, 0);
+       next_ = 0;
+       previous_ = 0;
        enumdepth = 0;
        itemdepth = 0;
-       next = 0;
-       previous = 0;
-#ifndef NEW_TABLE
-       fonttable = 0;
-       insettable = 0;
-#endif
-       footnoteflag = LyXParagraph::NO_FOOTNOTE;
+       bibkey = 0; // ale970302
+       clear();
+}
+
+
+// This constructor inserts the new paragraph in a list.
+Paragraph::Paragraph(Paragraph * par)
+       : layout(0), pimpl_(new Paragraph::Pimpl(this))
+{
+       for (int i = 0; i < 10; ++i)
+               setCounter(i, 0);
+       enumdepth = 0;
+       itemdepth = 0;
+
+       // double linked list begin
+       next_ = par->next_;
+       if (next_)
+               next_->previous_ = this;
+       previous_ = par;
+       previous_->next_ = this;
+       // end
 
-       align = LYX_ALIGN_BLOCK;
+       bibkey = 0; // ale970302        
 
-       /* table stuff -- begin*/ 
-       table = 0;
-       /* table stuff -- end*/ 
-       id = paragraph_id++;
-        bibkey = 0; // ale970302
-       Clear();
+       clear();
 }
 
 
-/* this konstruktor inserts the new paragraph in a list */ 
-LyXParagraph::LyXParagraph(LyXParagraph * par)
+Paragraph::Paragraph(Paragraph const & lp, bool same_ids)
+       : layout(0), pimpl_(new Paragraph::Pimpl(*lp.pimpl_, this, same_ids))
 {
-#ifndef NEW_TEXT
-       size = INITIAL_SIZE_PAR;
-       text = new char[size];
-       last = 0;
-#endif
-       for (int i = 0; i < 10; ++i) setCounter(i, 0);
-       appendix = false;
+       for (int i = 0; i < 10; ++i)
+               setCounter(i, 0);
        enumdepth = 0;
        itemdepth = 0;
-       next = par->next;
-       if (next)
-               next->previous = this;
-       previous = par;
-       previous->next = this;
-#ifndef NEW_TABLE
-       fonttable = 0;
-       insettable = 0;
-#endif
-       footnoteflag = LyXParagraph::NO_FOOTNOTE;
-       footnotekind = LyXParagraph::FOOTNOTE;
-       
-       /* table stuff -- begin*/ 
-       table = 0;
-       /* table stuff -- end*/ 
-       id = paragraph_id++;
-
-        bibkey = 0; // ale970302        
-    
-       Clear();
-}
+       next_     = 0;
+       previous_ = 0;
 
-/// Used by the spellchecker
-#ifdef NEW_TEXT
-bool LyXParagraph::IsLetter(LyXParagraph::size_type pos) {
-#else
-bool LyXParagraph::IsLetter(int pos) {
-#endif
-       unsigned char c = GetChar(pos);
-       if (IsLetterChar(c))
-               return true;
-       // '\0' is not a letter, allthough every string contains "" (below)
-       if( c == '\0')
-               return false;
-       // We want to pass the ' and escape chars to ispell
-       string extra = lyxrc->isp_esc_chars + '\'';
-       char ch[2];
-       ch[0] = c;
-       ch[1] = 0;
-       return contains(extra, ch);
+       // this is because of the dummy layout of the paragraphs that
+       // follow footnotes
+       layout = lp.layout;
+
+       // ale970302
+       if (lp.bibkey) {
+               bibkey = static_cast<InsetBibKey *>
+                       (lp.bibkey->clone(*current_view->buffer()));
+       } else {
+               bibkey = 0;
+       }
+       
+       // copy everything behind the break-position to the new paragraph
+       insetlist = lp.insetlist;
+       for (InsetList::iterator it = insetlist.begin();
+            it != insetlist.end(); ++it)
+       {
+               it->inset = it->inset->clone(*current_view->buffer(), same_ids);
+               // tell the new inset who is the boss now
+               it->inset->parOwner(this);
+       }
 }
 
 
-void LyXParagraph::writeFile(FILE * file, BufferParams & params,
-                            char footflag, char dth)
+// the destructor removes the new paragraph from the list
+Paragraph::~Paragraph()
 {
-       LyXFont font1, font2;
-       Inset * inset;
-       int column = 0;
-       int h = 0;
-       char c = 0;
+       if (previous_)
+               previous_->next_ = next_;
+       if (next_)
+               next_->previous_ = previous_;
 
-       if (footnoteflag != LyXParagraph::NO_FOOTNOTE
-           || !previous
-           || previous->footnoteflag == LyXParagraph::NO_FOOTNOTE){
-               
-               /* The beginning or the end of a footnote environment? */ 
-               if (footflag != footnoteflag) {
-                       footflag = footnoteflag;
-                       if (footflag) {
-                               fprintf(file, "\n\\begin_float %s ", 
-                                       string_footnotekinds[footnotekind]);
-                       }
-                       else {
-                               fprintf(file, "\n\\end_float ");
-                       }
-               }
+       for (InsetList::iterator it = insetlist.begin();
+            it != insetlist.end(); ++it) {
+               delete it->inset;
+       }
 
-               /* The beginning or end of a deeper (i.e. nested) area? */
-               if (dth != depth) {
-                       if (depth > dth) {
-                               while (depth > dth) {
-                                       fprintf(file, "\n\\begin_deeper ");
-                                       dth++;
-                               }
-                       }
-                       else {
-                               while (depth < dth) {
-                                       fprintf(file, "\n\\end_deeper ");
-                                       dth--;
-                               }
-                       }
-               }
+       // ale970302
+       delete bibkey;
 
-               /* First write the layout */ 
-               fprintf(file, "\n\\layout %s\n",
-                       textclasslist.NameOfLayout(params.textclass,layout)
-                       .c_str());
-
-               /* maybe some vertical spaces */ 
-               if (added_space_top.kind() != VSpace::NONE)
-                       fprintf(file, "\\added_space_top %s ", 
-                               added_space_top.asLyXCommand().c_str());
-               if (added_space_bottom.kind() != VSpace::NONE)
-                       fprintf(file, "\\added_space_bottom %s ",
-                               added_space_bottom.asLyXCommand().c_str());
-                       
-               /* The labelwidth string used in lists */
-               if (!labelwidthstring.empty())
-                       fprintf(file, "\\labelwidthstring %s\n",
-                               labelwidthstring.c_str());
-
-               /* Lines above or below? */
-               if (line_top)
-                       fprintf(file, "\\line_top ");
-               if (line_bottom)
-                       fprintf(file, "\\line_bottom ");
-
-               /* Pagebreaks above or below? */
-               if (pagebreak_top)
-                       fprintf(file, "\\pagebreak_top ");
-               if (pagebreak_bottom)
-                       fprintf(file, "\\pagebreak_bottom ");
-                       
-               /* Start of appendix? */
-               if (start_of_appendix)
-                       fprintf(file, "\\start_of_appendix ");
+       delete pimpl_;
+       //
+       //lyxerr << "Paragraph::paragraph_id = "
+       //       << Paragraph::paragraph_id << endl;
+}
 
-               /* Noindent? */
-               if (noindent)
-                       fprintf(file, "\\noindent ");
-                       
-               /* Alignment? */
-               if (align != LYX_ALIGN_LAYOUT) {
-                       switch (align) {
-                       case LYX_ALIGN_LEFT: h = 1; break;
-                       case LYX_ALIGN_RIGHT: h = 2; break;
-                       case LYX_ALIGN_CENTER: h = 3; break;
-                       default: h = 0; break;
+
+void Paragraph::writeFile(Buffer const * buf, ostream & os,
+                          BufferParams const & bparams,
+                          depth_type dth) const
+{
+       // The beginning or end of a deeper (i.e. nested) area?
+       if (dth != params().depth()) {
+               if (params().depth() > dth) {
+                       while (params().depth() > dth) {
+                               os << "\n\\begin_deeper ";
+                               ++dth;
+                       }
+               } else {
+                       while (params().depth() < dth) {
+                               os << "\n\\end_deeper ";
+                               --dth;
                        }
-                       fprintf(file, "\\align %s ", string_align[h]);
                }
-                if (pextra_type != PEXTRA_NONE) {
-                        fprintf(file, "\\pextra_type %d", pextra_type);
-                        if (pextra_type == PEXTRA_MINIPAGE) {
-                               fprintf(file, " \\pextra_alignment %d",
-                                       pextra_alignment);
-                               if (pextra_hfill)
-                                       fprintf(file, " \\pextra_hfill %d",
-                                               pextra_hfill);
-                               if (pextra_start_minipage)
-                                       fprintf(file,
-                                               " \\pextra_start_minipage %d",
-                                               pextra_start_minipage);
-                        }
-                        if (!pextra_width.empty()) {
-                               fprintf(file, " \\pextra_width %s",
-                                        VSpace(pextra_width)
-                                       .asLyXCommand().c_str());
-                        } else if (!pextra_widthp.empty()) {
-                               fprintf(file, " \\pextra_widthp %s",
-                                       pextra_widthp.c_str());
-                        }
-                        fprintf(file,"\n");
-                }
-       }
-       else {
-               /* Dummy layout. This means that a footnote ended */
-               fprintf(file, "\n\\end_float ");
-               footflag = LyXParagraph::NO_FOOTNOTE;
        }
-               
-       /* It might be a table */ 
-       if (table){
-               fprintf(file, "\\LyXTable\n");
-               table->Write(file);
+       
+       // First write the layout
+       os << "\n\\layout "
+          << textclasslist.NameOfLayout(bparams.textclass, layout)
+          << "\n";
+       
+       // Maybe some vertical spaces.
+       if (params().spaceTop().kind() != VSpace::NONE)
+               os << "\\added_space_top "
+                  << params().spaceTop().asLyXCommand() << " ";
+       if (params().spaceBottom().kind() != VSpace::NONE)
+               os << "\\added_space_bottom "
+                  << params().spaceBottom().asLyXCommand() << " ";
+       
+       // Maybe the paragraph has special spacing
+       params().spacing().writeFile(os, true);
+       
+       // The labelwidth string used in lists.
+       if (!params().labelWidthString().empty())
+               os << "\\labelwidthstring "
+                  << params().labelWidthString() << '\n';
+       
+       // Lines above or below?
+       if (params().lineTop())
+               os << "\\line_top ";
+       if (params().lineBottom())
+               os << "\\line_bottom ";
+       
+       // Pagebreaks above or below?
+       if (params().pagebreakTop())
+               os << "\\pagebreak_top ";
+       if (params().pagebreakBottom())
+               os << "\\pagebreak_bottom ";
+       
+       // Start of appendix?
+       if (params().startOfAppendix())
+               os << "\\start_of_appendix ";
+       
+       // Noindent?
+       if (params().noindent())
+               os << "\\noindent ";
+       
+       // Alignment?
+       if (params().align() != LYX_ALIGN_LAYOUT) {
+               int h = 0;
+               switch (params().align()) {
+               case LYX_ALIGN_LEFT: h = 1; break;
+               case LYX_ALIGN_RIGHT: h = 2; break;
+               case LYX_ALIGN_CENTER: h = 3; break;
+               default: h = 0; break;
+               }
+               os << "\\align " << string_align[h] << " ";
        }
-
+       
        // bibitem  ale970302
        if (bibkey)
-               bibkey->Write(file);
-
-       font1 = LyXFont(LyXFont::ALL_INHERIT);
-
-       column = 0;
-#ifdef NEW_TEXT
-       for (size_type i = 0; i < size(); i++) {
-               if (!i){
-                       fprintf(file, "\n");
-                       column = 0;
-               }
-#else
-       for (int i = 0; i < last; i++) {
-               if (!i){
-                       fprintf(file, "\n");
+               bibkey->write(buf, os);
+       
+       LyXFont font1(LyXFont::ALL_INHERIT, bparams.language);
+       
+       int column = 0;
+       for (pos_type i = 0; i < size(); ++i) {
+               if (!i) {
+                       os << "\n";
                        column = 0;
                }
-#endif
                
                // Write font changes
-               font2 = GetFontSettings(i);
+               LyXFont font2 = getFontSettings(bparams, i);
                if (font2 != font1) {
-                       font2.lyxWriteChanges(font1, file);
+#ifndef INHERIT_LANGUAGE
+                       font2.lyxWriteChanges(font1, os);
+#else
+                       font2.lyxWriteChanges(font1, bparams.language, os);
+#endif
                        column = 0;
                        font1 = font2;
                }
-
-               c = GetChar(i);
+               
+               value_type const c = getChar(i);
                switch (c) {
-               case LYX_META_INSET:
-                       inset = GetInset(i);
+               case META_INSET:
+               {
+                       Inset const * inset = getInset(i);
                        if (inset)
-                               if (inset->DirectWrite()) {
+                               if (inset->directWrite()) {
                                        // international char, let it write
                                        // code directly so it's shorter in
                                        // the file
-                                       inset->Write(file);
+                                       inset->write(buf, os);
                                } else {
-                                       fprintf(file, "\n\\begin_inset ");
-                                       inset->Write(file);
-                                       fprintf(file, "\n\\end_inset \n");
-                                       fprintf(file, "\n");
+                                       os << "\n\\begin_inset ";
+                                       inset->write(buf, os);
+                                       os << "\n\\end_inset \n\n";
                                        column = 0;
                                }
-                       break;
-               case LYX_META_NEWLINE: 
-                       fprintf(file, "\n\\newline \n");
-                       column = 0;
-                       break;
-               case LYX_META_HFILL: 
-                       fprintf(file, "\n\\hfill \n");
+               }
+               break;
+               case META_NEWLINE: 
+                       os << "\n\\newline \n";
                        column = 0;
                        break;
-               case LYX_META_PROTECTED_SEPARATOR
-                       fprintf(file, "\n\\protected_separator \n");
+               case META_HFILL
+                       os << "\n\\hfill \n";
                        column = 0;
                        break;
-               case '\\': 
-                       fprintf(file, "\n\\backslash \n");
+               case '\\':
+                       os << "\n\\backslash \n";
                        column = 0;
                        break;
                case '.':
-#ifdef NEW_TEXT
-                       if (i + 1 < size() && GetChar(i + 1) == ' ') {
-                               fprintf(file, ".\n");
-                               column = 0;
-                       } else
-                               fprintf(file, ".");
-#else
-                       if (i + 1 < last && GetChar(i + 1) == ' ') {
-                               fprintf(file, ".\n");
+                       if (i + 1 < size() && getChar(i + 1) == ' ') {
+                               os << ".\n";
                                column = 0;
                        } else
-                               fprintf(file, ".");
-#endif
+                               os << ".";
                        break;
                default:
-                       if ((column > 70 && c==' ')
-                           || column > 79){
-                               fprintf(file, "\n");
+                       if ((column > 70 && c == ' ')
+                           || column > 79) {
+                               os << "\n";
                                column = 0;
                        }
                        // this check is to amend a bug. LyX sometimes
                        // inserts '\0' this could cause problems.
                        if (c != '\0')
-                               fprintf(file, "%c", c);
+                               os << c;
                        else
-                               lyxerr << "ERROR (LyXParagraph::writeFile):"
+                               lyxerr << "ERROR (Paragraph::writeFile):"
                                        " NULL char in structure." << endl;
-                       column++;
+                       ++column;
                        break;
                }
        }
-
+       
        // now write the next paragraph
-       if (next)
-               next->writeFile(file, params, footflag, dth);
+       if (next_)
+               next_->writeFile(buf, os, bparams, dth);
 }
 
 
-void LyXParagraph::validate(LaTeXFeatures & features)
+void Paragraph::validate(LaTeXFeatures & features) const
 {
-       // this will be useful later
-       LyXLayout const & layout = textclasslist.Style(GetCurrentTextClass(), 
-                                          GetLayout());
-       
+       BufferParams const & bparams = features.bufferParams();
+
        // check the params.
-       if (line_top || line_bottom)
-               features.lyxline = true;
+       if (params().lineTop() || params().lineBottom())
+               features.require("lyxline");
+       if (!params().spacing().isDefault())
+               features.require("setspace");
        
        // then the layouts
-       features.layout[GetLayout()] = true;
+       features.useLayout(getLayout());
 
-#ifdef NEW_TABLE
-       for (FontList::const_iterator cit = fontlist.begin();
-            cit != fontlist.end(); ++cit) {
-               if ((*cit).font.noun() == LyXFont::ON) {
-                       lyxerr[Debug::LATEX] << "font.noun: "
-                                            << (*cit).font.noun()
-                                            << endl;
-                       features.noun = true;
-                       lyxerr[Debug::LATEX] << "Noun enabled. Font: "
-                                            << (*cit).font.stateText()
-                                            << endl;
-               }
-               switch ((*cit).font.color()) {
-               case LyXFont::NONE:
-               case LyXFont::INHERIT_COLOR:
-               case LyXFont::IGNORE_COLOR:  break;
-               default:
-                       features.color = true;
-                       lyxerr[Debug::LATEX] << "Color enabled. Font: "
-                                            << (*cit).font.stateText()
-                                            << endl;
-               }
-       }
-#else
        // then the fonts
-       FontTable * tmpfonttable = fonttable;
-       while (tmpfonttable) {
-               if (tmpfonttable->font.noun() == LyXFont::ON) {
-                       lyxerr[Debug::LATEX] << "font.noun: " 
-                                            << tmpfonttable->font.noun()
+       Language const * doc_language = bparams.language;
+       
+       for (Pimpl::FontList::const_iterator cit = pimpl_->fontlist.begin();
+            cit != pimpl_->fontlist.end(); ++cit) {
+               if (cit->font().noun() == LyXFont::ON) {
+                       lyxerr[Debug::LATEX] << "font.noun: "
+                                            << cit->font().noun()
                                             << endl;
-                       features.noun = true;
+                       features.require("noun");
                        lyxerr[Debug::LATEX] << "Noun enabled. Font: "
-                                            << tmpfonttable->font.stateText()
+                                            << cit->font().stateText(0)
                                             << endl;
                }
-               switch (tmpfonttable->font.color()) {
-               case LyXFont::NONE: 
-               case LyXFont::INHERIT_COLOR:
-               case LyXFont::IGNORE_COLOR:
+               switch (cit->font().color()) {
+               case LColor::none:
+               case LColor::inherit:
+               case LColor::ignore:
+                       // probably we should put here all interface colors used for
+                       // font displaying! For now I just add this ones I know of (Jug)
+               case LColor::latex:
+               case LColor::note:
                        break;
                default:
-                       features.color = true;
+                       features.require("color");
                        lyxerr[Debug::LATEX] << "Color enabled. Font: "
-                                            << tmpfonttable->font.stateText()
+                                            << cit->font().stateText(0)
                                             << endl;
                }
-               tmpfonttable = tmpfonttable->next;
-       }
+
+               Language const * language = cit->font().language();
+               if (language->babel() != doc_language->babel() &&
+                   language != ignore_language &&
+#ifdef INHERIT_LANGUAGE
+                   language != inherit_language &&
 #endif
-#ifdef NEW_TABLE
-       for (InsetList::const_iterator cit = insetlist.begin();
-            cit != insetlist.end(); ++cit) {
-               (*cit).inset->Validate(features);
+                   language != latex_language)
+               {
+                       features.useLanguage(language);
+                       lyxerr[Debug::LATEX] << "Found language "
+                                            << language->babel() << endl;
+               }
        }
-#else
+
        // then the insets
-       InsetTable * tmpinsettable = insettable;
-       while (tmpinsettable) {
-               if (tmpinsettable->inset) {
-                       tmpinsettable->inset->Validate(features);
+       LyXLayout const & layout =
+             textclasslist.Style(bparams.textclass, getLayout());
+
+       for (InsetList::const_iterator cit = insetlist.begin();
+            cit != insetlist.end(); ++cit) {
+               if (cit->inset) {
+                       cit->inset->validate(features);
+                       if (layout.needprotect &&
+                           cit->inset->lyxCode() == Inset::FOOT_CODE)
+                               features.require("NeedLyXFootnoteCode");
                }
-               tmpinsettable = tmpinsettable->next;
        }
-#endif
-        if (table && table->IsLongTable())
-               features.longtable = true;
-        if (pextra_type == PEXTRA_INDENT)
-                features.LyXParagraphIndent = true;
-        if (pextra_type == PEXTRA_FLOATFLT)
-                features.floatflt = true;
-        if (layout.needprotect 
-           && next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE)
-               features.NeedLyXFootnoteCode = true;
-        if ((current_view->currentBuffer()->params.paragraph_separation == LYX_PARSEP_INDENT) &&
-            (pextra_type == PEXTRA_MINIPAGE))
-               features.NeedLyXMinipageIndent = true;
-        if (table && table->NeedRotating())
-               features.rotating = true;
-       if (footnoteflag != NO_FOOTNOTE && footnotekind == ALGORITHM)
-               features.algorithm = true;
 }
 
 
-/* first few functions needed for cut and paste and paragraph breaking */
-#ifdef NEW_TEXT
-void LyXParagraph::CopyIntoMinibuffer(LyXParagraph::size_type pos)
-#else 
-void LyXParagraph::CopyIntoMinibuffer(int pos)
-#endif
+// First few functions needed for cut and paste and paragraph breaking.
+void Paragraph::copyIntoMinibuffer(Buffer const & buffer, pos_type pos) const
 {
-       minibuffer_char = GetChar(pos);
-       minibuffer_font = GetFontSettings(pos);
+       BufferParams bparams = buffer.params;
+
+       minibuffer_char = getChar(pos);
+       minibuffer_font = getFontSettings(bparams, pos);
        minibuffer_inset = 0;
-       if (minibuffer_char == LYX_META_INSET) {
-               if (GetInset(pos)) {
-                       minibuffer_inset = GetInset(pos)->Clone();
+       if (minibuffer_char == Paragraph::META_INSET) {
+               if (getInset(pos)) {
+                       minibuffer_inset = getInset(pos)->clone(buffer);
                } else {
                        minibuffer_inset = 0;
                        minibuffer_char = ' ';
@@ -485,39 +423,28 @@ void LyXParagraph::CopyIntoMinibuffer(int pos)
        }
 }
 
-#ifdef NEW_TEXT
-void LyXParagraph::CutIntoMinibuffer(LyXParagraph::size_type pos)
-#else
-void LyXParagraph::CutIntoMinibuffer(int pos)
-#endif
+
+void Paragraph::cutIntoMinibuffer(BufferParams const & bparams, pos_type pos)
 {
-       minibuffer_char = GetChar(pos);
-       minibuffer_font = GetFontSettings(pos);
+       minibuffer_char = getChar(pos);
+       minibuffer_font = getFontSettings(bparams, pos);
        minibuffer_inset = 0;
-       if (minibuffer_char == LYX_META_INSET) {
-               if (GetInset(pos)) {
-                       minibuffer_inset = GetInset(pos);
+       if (minibuffer_char == Paragraph::META_INSET) {
+               if (getInset(pos)) {
+                       minibuffer_inset = getInset(pos);
                        // This is a little hack since I want exactly
                        // the inset, not just a clone. Otherwise
                        // the inset would be deleted when calling Erase(pos)
-#ifdef NEW_TABLE
-                       for (InsetList::iterator it = insetlist.begin();
-                            it != insetlist.end(); ++it) {
-                               if ((*it).pos == pos) {
-                                       (*it).inset = 0;
-                                       break;
-                               }
-                       }
-#else
-                       /* find the entry */ 
-                       InsetTable * tmpi = insettable;
-                       while (tmpi && tmpi->pos != pos) {
-                               tmpi=tmpi->next;
-                       }
-                       if (tmpi) {  /* This should always be true */
-                               tmpi->inset = 0;
-                       }
-#endif
+                       // find the entry
+                       InsetTable search_elem(pos, 0);
+                       InsetList::iterator it =
+                               lower_bound(insetlist.begin(),
+                                           insetlist.end(),
+                                           search_elem, Pimpl::matchIT());
+                       if (it != insetlist.end() && it->pos == pos)
+                               it->inset = 0;
+                       // the inset is not in a paragraph anymore
+                       minibuffer_inset->parOwner(0);
                } else {
                        minibuffer_inset = 0;
                        minibuffer_char = ' ';
@@ -526,607 +453,172 @@ void LyXParagraph::CutIntoMinibuffer(int pos)
 
        }
 
-       /* Erase(pos); now the caller is responsible for that*/
+       // Erase(pos); now the caller is responsible for that.
 }
 
 
-#ifdef NEW_TEXT
-void LyXParagraph::InsertFromMinibuffer(LyXParagraph::size_type pos)
-#else
-void LyXParagraph::InsertFromMinibuffer(int pos)
-#endif
+bool Paragraph::insertFromMinibuffer(pos_type pos)
 {
-       InsertChar(pos, minibuffer_char);
-       SetFont(pos, minibuffer_font);
-       if (minibuffer_char == LYX_META_INSET)
-               InsertInset(pos, minibuffer_inset);
+       if (minibuffer_char == Paragraph::META_INSET) {
+               if (!insetAllowed(minibuffer_inset->lyxCode())) {
+                       return false;
+               }
+               insertInset(pos, minibuffer_inset, minibuffer_font);
+       } else {
+               LyXFont f = minibuffer_font;
+               if (!checkInsertChar(f)) {
+                       return false;
+               }
+               insertChar(pos, minibuffer_char, f);
+       }
+       return true;
 }
 
-/* end of minibuffer */ 
+// end of minibuffer
 
 
 
-void LyXParagraph::Clear()
+void Paragraph::clear()
 {
-       line_top = false;
-       line_bottom = false;
-   
-       pagebreak_top = false;
-       pagebreak_bottom = false;
-
-       added_space_top = VSpace(VSpace::NONE);
-       added_space_bottom = VSpace(VSpace::NONE);
-
-       align = LYX_ALIGN_LAYOUT;
-       depth = 0;
-       noindent = false;
-
-        pextra_type = PEXTRA_NONE;
-        pextra_width.clear();
-        pextra_widthp.clear();
-        pextra_alignment = MINIPAGE_ALIGN_TOP;
-        pextra_hfill = false;
-        pextra_start_minipage = false;
-
-        labelstring.clear();
-       labelwidthstring.clear();
+       params().clear();
+       
        layout = 0;
        bibkey = 0;
-       
-       start_of_appendix = false;
 }
 
 
-/* the destructor removes the new paragraph from the list */ 
-LyXParagraph::~LyXParagraph()
+void Paragraph::erase(pos_type pos)
 {
-       if (previous)
-               previous->next = next;
-       if (next)
-               next->previous = previous;
-
-#ifndef NEW_TEXT
-       if (text)
-               delete[] text;
-#endif
+       pimpl_->erase(pos);
+}
 
-#ifndef NEW_TABLE
-       InsetTable * tmpinset;
-       while (insettable) {
-               tmpinset = insettable;
-               insettable = insettable->next;
-               if (tmpinset->inset)
-                       delete tmpinset->inset;
-               delete tmpinset;
-               if (insettable && insettable->next == insettable) {
-                       // somehow this recursion appears occasionally
-                       // but I can't find where.  This bandaid
-                       // helps but isn't the best fix. (ARRae)
-                       if (insettable->inset) {
-                               delete insettable->inset;
-                       }
-                       delete insettable;
-                       break;
-               }
-       }
 
-       FontTable * tmpfont;
-       while (fonttable) {
-               tmpfont = fonttable;
-               fonttable = fonttable->next;
-               delete tmpfont;
-       }
-#endif
+bool Paragraph::checkInsertChar(LyXFont & font)
+{
+       if (pimpl_->inset_owner)
+               return pimpl_->inset_owner->checkInsertChar(font);
+       return true;
+}
 
-       /* table stuff -- begin*/ 
-       if (table)
-               delete table;
-       /* table stuff -- end*/ 
 
-        // ale970302
-       if (bibkey)
-               delete bibkey;
+void Paragraph::insertChar(pos_type pos, Paragraph::value_type c)
+{
+       LyXFont const f(LyXFont::ALL_INHERIT);
+       insertChar(pos, c, f);
 }
 
 
-#ifdef NEW_TEXT
-void LyXParagraph::Erase(LyXParagraph::size_type pos)
-#else
-void LyXParagraph::Erase(int pos)
-#endif
+void Paragraph::insertChar(pos_type pos, Paragraph::value_type c,
+                           LyXFont const & font)
 {
-       /* > because last is the next unused position, and you can 
-        * use it if you want  */
-#ifdef NEW_TEXT
-       if (pos > size()) {
-               if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) 
-                       NextAfterFootnote()->Erase(pos - text.size() - 1);
-               else 
-                       lyxerr.debug() << "ERROR (LyXParagraph::Erase): "
-                               "position does not exist." << endl;
-               return;
-       }
-#else
-       if (pos > last) {
-               if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) 
-                       NextAfterFootnote()->Erase(pos - last - 1);
-               else 
-                       lyxerr.debug() << "ERROR (LyXParagraph::Erase): "
-                               "position does not exist." << endl;
-               return;
-       }
-#endif
-#ifdef NEW_TEXT
-       if (pos < size()) { // last is free for insertation, but should be empty
-#else
-       if (pos < last) { // last is free for insertation, but should be empty
-#endif
-#ifdef NEW_TABLE
-               /* if it is an inset, delete the inset entry */ 
-               if (text[pos] == LYX_META_INSET) {
-                       /* find the entry */
-                       for(InsetList::iterator it = insetlist.begin();
-                           it != insetlist.end(); ++it) {
-                               if ((*it).pos == pos) {
-                                       delete (*it).inset;
-                                       insetlist.erase(it);
-                                       break;
-                               }
-                       }
-               }
-#else
-               /* if it is an inset, delete the inset entry */ 
-               if (text[pos] == LYX_META_INSET) {
-                       /* find the entry */ 
-                       InsetTable *tmpi = insettable;
-                       InsetTable *tmpi2 = tmpi;
-                       while (tmpi && tmpi->pos != pos) {
-                               tmpi2=tmpi;
-                               tmpi=tmpi->next;
-                       }
-                       if (tmpi) {     // this should always be true
-                               if (tmpi->inset) // delete the inset if it exists
-                                       delete tmpi->inset;
-                               if (tmpi == insettable)
-                                       insettable = tmpi->next;
-                               else 
-                                       tmpi2->next = tmpi->next;
-                               delete tmpi;
-                       }
-               }
-#endif
-#ifdef NEW_TEXT
-               text.erase(text.begin() + pos);
-               //text.erase(pos, 1);
-#else
-               // Shift rest of text      
-               for (int i = pos; i < last - 1; i++) {
-                       text[i]=text[i+1];
-               }
-               last--;
-#endif
-#ifdef NEW_TABLE
-               /* erase entries in the tables */
-               for(FontList::iterator it = fontlist.begin();
-                   it != fontlist.end(); ++it) {
-                       if (pos >= (*it).pos && pos <= (*it).pos_end) {
-                               if ((*it).pos == (*it).pos_end) {
-                                       fontlist.erase(it);
-                                       break;
-                               }
-                       }
-               }
-
-               /* update all other entries */
-               for(FontList::iterator it = fontlist.begin();
-                   it != fontlist.end(); ++it) {
-                       if ((*it).pos > pos)
-                               (*it).pos--;
-                       if ((*it).pos_end >= pos)
-                               (*it).pos_end--;
-               }
-      
-               /* update the inset table */
-               for(InsetList::iterator it = insetlist.begin();
-                   it != insetlist.end(); ++it) {
-                       if ((*it).pos > pos)
-                               (*it).pos--;
-               }
-#else
-               /* erase entries in the tables */ 
-               int found = 0;
-               FontTable * tmp = fonttable;
-               FontTable * prev = 0;
-               while (tmp && !found) {
-                       if (pos >= tmp->pos && pos <= tmp->pos_end)
-                               found = 1;
-                       else {
-                               prev = tmp;
-                               tmp = tmp->next;
-                       }
-               }
-      
-               if (found && tmp->pos == tmp->pos_end) {  
-                       /* if it is a multi-character font entry, we just make 
-                        * it smaller (see update below), otherwise we should 
-                        * delete it */
-                       if (prev)
-                               prev->next = tmp->next;
-                       else
-                               fonttable = tmp->next;
-        
-                       delete tmp;
-               }
+       pimpl_->insertChar(pos, c, font);
+}
 
-               /* update all other entries */
 
-               tmp = fonttable;
-               while (tmp) {
-                       if (tmp->pos > pos)
-                               tmp->pos--;
-                       if (tmp->pos_end >= pos)
-                               tmp->pos_end--;
-                       tmp = tmp->next;
-               }
-      
-               /* update the inset table */ 
-               InsetTable * tmpi = insettable;
-               while (tmpi) {
-                       if (tmpi->pos > pos)
-                               tmpi->pos--;
-                       tmpi=tmpi->next;
-               }
-#endif      
-       } else {
-               lyxerr << "ERROR (LyXParagraph::Erase): "
-                       "can't erase non-existant char." << endl;
-       }
+void Paragraph::insertInset(pos_type pos, Inset * inset)
+{
+       LyXFont const f(LyXFont::ALL_INHERIT);
+       insertInset(pos, inset, f);
 }
 
 
-#ifndef NEW_TEXT
-/* pos is needed to specify the paragraph correctly. Remember the
-* closed footnotes */ 
-void LyXParagraph::Enlarge(int pos, int number)
+void Paragraph::insertInset(pos_type pos, Inset * inset, LyXFont const & font)
 {
-       /* > because last is the next unused position, and you can 
-        * use it if you want  */
-       if (pos > last) {
-               if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) 
-                       NextAfterFootnote()->Enlarge(pos - last - 1, number);
-               else 
-                       lyxerr << "ERROR (LyXParagraph::Enlarge): "
-                               "position does not exist." << endl;
-               return;
-       }
+       pimpl_->insertInset(pos, inset, font);
+}
 
-       if (size - last < number) {
-               size += number - size + last + STEP_SIZE_PAR;
-               char * tmp = new char[size];
-               for (int i = 0; i < last; ++i)
-                       tmp[i] = text[i];
-               delete[] text;
-               text = tmp;
-       }
+
+bool Paragraph::insetAllowed(Inset::Code code)
+{
+       //lyxerr << "Paragraph::InsertInsetAllowed" << endl;
+       
+       if (pimpl_->inset_owner)
+               return pimpl_->inset_owner->insetAllowed(code);
+       return true;
 }
-#endif
 
 
-#ifndef NEW_TEXT
-/* make the allocated memory fit to the needed size */
-/* used to make a paragraph smaller */
-void LyXParagraph::FitSize()
+Inset * Paragraph::getInset(pos_type pos)
 {
-       if (size - last > STEP_SIZE_PAR) {
-               size = last + STEP_SIZE_PAR;
-               char * tmp = new char[size];
-               for (int i = 0; i < last; ++i)
-                       tmp[i] = text[i];
-               delete[] text;
-               text = tmp;
-       }
+       lyx::Assert(pos < size());
+
+       // Find the inset.
+       InsetTable search_inset(pos, 0);
+       InsetList::iterator it = lower_bound(insetlist.begin(),
+                                            insetlist.end(),
+                                            search_inset, Pimpl::matchIT());
+       if (it != insetlist.end() && it->pos == pos)
+               return it->inset;
+
+       lyxerr << "ERROR (Paragraph::getInset): "
+               "Inset does not exist: " << pos << endl;
+       //::raise(SIGSTOP);
+       
+       // text[pos] = ' '; // WHY!!! does this set the pos to ' '????
+       // Did this commenting out introduce a bug? So far I have not
+       // see any, please enlighten me. (Lgb)
+       // My guess is that since the inset does not exist, we might
+       // as well replace it with a space to prevent craches. (Asger)
+       return 0;
 }
-#endif
 
-#ifdef NEW_TEXT
-void LyXParagraph::InsertChar(LyXParagraph::size_type pos, char c)
-#else
-void LyXParagraph::InsertChar(int pos, char c)
-#endif
+
+Inset const * Paragraph::getInset(pos_type pos) const
 {
-#ifdef NEW_TEXT
-       /* > because last is the next unused position, and you can 
-        * use it if you want  */
-       if (pos > size()) {
-               if (next
-                   && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) 
-                       NextAfterFootnote()->InsertChar(pos - text.size() - 1,
-                                                       c);
-               else 
-                       lyxerr.debug() << "ERROR (LyXParagraph::InsertChar): "
-                               "position does not exist." << endl;
-               return;
-       }
-       text.insert(text.begin() + pos, c);
-       //text.insert(pos, c);
-#else
-       /* > because last is the next unused position, and you can 
-        * use it if you want  */
-       if (pos > last) {
-               if (next
-                   && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) 
-                       NextAfterFootnote()->InsertChar(pos - last - 1, c);
-               else 
-                       lyxerr.debug() << "ERROR (LyXParagraph::InsertChar): "
-                               "position does not exist." << endl;
-               return;
-       }
-       // Are we full? If so, enlarge.
-       if (last == size) {
-               size += STEP_SIZE_PAR;
-               char * tmp = new char[size];
-               for (int i = 0; i < last; i++)
-                       tmp[i] = text[i];
-               delete[] text;
-               text = tmp;
-       }
+       lyx::Assert(pos < size());
 
-       // Shift rest of character
-       for (int i = last; i>pos; i--) {
-               text[i] = text[i - 1];
-       }
+       // Find the inset.
+       InsetTable search_inset(pos, 0);
+       InsetList::const_iterator cit = lower_bound(insetlist.begin(),
+                                                   insetlist.end(),
+                                                   search_inset, Pimpl::matchIT());
+       if (cit != insetlist.end() && cit->pos == pos)
+               return cit->inset;
 
-       text[pos] = c;
-       last++;
-#endif
-#ifdef NEW_TABLE
-       // update the font table
-       for(FontList::iterator it = fontlist.begin();
-           it != fontlist.end(); ++it) {
-               if ((*it).pos >= pos)
-                       (*it).pos++;
-               if ((*it).pos_end >= pos)
-                       (*it).pos_end++;
-       }
-       // update the inset table
-       for(InsetList::iterator it = insetlist.begin();
-           it != insetlist.end(); ++it) {
-               if ((*it).pos >= pos)
-                       (*it).pos++;
-       }
-#else
-       /* update the font table */ 
-       FontTable * tmp = fonttable;
-       while (tmp) {
-               if (tmp->pos >= pos)
-                       tmp->pos++;
-               if (tmp->pos_end >= pos)
-                       tmp->pos_end++;
-               tmp = tmp->next;
-       }
-   
-       /* update the inset table */ 
-       InsetTable * tmpi = insettable;
-       while (tmpi) {
-               if (tmpi->pos >= pos)
-                       tmpi->pos++;
-               tmpi=tmpi->next;
-       }
-#endif
+       lyxerr << "ERROR (Paragraph::GetInset): "
+               "Inset does not exist: " << pos << endl;
+       //::raise(SIGSTOP);
+       //text[pos] = ' '; // WHY!!! does this set the pos to ' '????
+       // Did this commenting out introduce a bug? So far I have not
+       // see any, please enlighten me. (Lgb)
+       // My guess is that since the inset does not exist, we might
+       // as well replace it with a space to prevent craches. (Asger)
+       return 0;
 }
 
-#ifdef NEW_TEXT
-void LyXParagraph::InsertInset(LyXParagraph::size_type pos,
-                              Inset * inset)
-#else
-void LyXParagraph::InsertInset(int pos, Inset * inset)
-#endif
+
+// Gets uninstantiated font setting at position.
+LyXFont const Paragraph::getFontSettings(BufferParams const & bparams,
+                                         pos_type pos) const
 {
-       /* > because last is the next unused position, and you can 
-        * use it if you want  */
-#ifdef NEW_TEXT
-       if (pos > size()) {
-               if (next
-                   && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) 
-                       NextAfterFootnote()
-                               ->InsertInset(pos - text.size() - 1, inset);
-               else 
-                       lyxerr << "ERROR (LyXParagraph::InsertInset): " 
-                               "position does not exist: " << pos << endl;
-               return;
-       }
-#else
-       if (pos > last) {
-               if (next
-                   && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) 
-                       NextAfterFootnote()
-                               ->InsertInset(pos - last - 1, inset);
-               else 
-                       lyxerr << "ERROR (LyXParagraph::InsertInset): " 
-                               "position does not exist: " << pos << endl;
-               return;
-       }
+       lyx::Assert(pos <= size());
+       
+       Pimpl::FontTable search_font(pos, LyXFont());
+       Pimpl::FontList::const_iterator cit = lower_bound(pimpl_->fontlist.begin(),
+                                                  pimpl_->fontlist.end(),
+                                                  search_font, Pimpl::matchFT());
+       LyXFont retfont;
+       if (cit != pimpl_->fontlist.end()) {
+               retfont = cit->font();
+       } else if (pos == size() && size()) {
+               retfont = getFontSettings(bparams, pos - 1);
+       } else
+               retfont = LyXFont(LyXFont::ALL_INHERIT, getParLanguage(bparams));
+#ifdef INHERIT_LANGUAGE
+       if (retfont.language() == inherit_language)
+               retfont.setLanguage(bparams.language);
 #endif
-       if (text[pos] != LYX_META_INSET) {
-               lyxerr << "ERROR (LyXParagraph::InsertInset): "
-                       "there is no LYX_META_INSET" << endl;
-               return;
-       }
 
-#ifdef NEW_TABLE
-       if (inset) {
-               InsetTable tmp;
-               tmp.pos = pos;
-               tmp.inset = inset;
-               insetlist.push_back(tmp);
-       }
-               
-#else
-       if (inset) {
-               /* add a new entry in the inset table */ 
-               InsetTable * tmpi = new InsetTable;
-               tmpi->pos = pos;
-               tmpi->inset = inset;
-               tmpi->next = insettable;
-               insettable = tmpi;
-       }
-#endif
+       return retfont;
 }
 
-#ifdef NEW_TEXT
-Inset * LyXParagraph::GetInset(LyXParagraph::size_type pos)
-#else
-Inset * LyXParagraph::GetInset(int pos)
-#endif
-{
-#ifdef NEW_TEXT
-       if (pos >= size()) {
-               if (next
-                   && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) 
-                       return NextAfterFootnote()
-                               ->GetInset(pos - text.size() - 1);
-               else { 
-                       lyxerr << "ERROR (LyXParagraph::GetInset): "
-                               "position does not exist: "
-                              << pos << endl;
-               }
-               return 0;
-       }
-#else
-       if (pos >= last) {
-               if (next
-                   && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) 
-                       return NextAfterFootnote()->GetInset(pos - last - 1);
-               else { 
-                       lyxerr << "ERROR (LyXParagraph::GetInset): "
-                               "position does not exist: "
-                              << pos << endl;
-               }
-               return 0;
-       }
-#endif
-#ifdef NEW_TABLE
-       /* find the inset */
-       for(InsetList::iterator it = insetlist.begin();
-           it != insetlist.end(); ++it) {
-               if ((*it).pos == pos) {
-                       return (*it).inset;
-               }
-       }
-       lyxerr << "ERROR (LyXParagraph::GetInset): "
-               "Inset does not exist: " << pos << endl;
-       text[pos] = ' '; /// WHY!!! does this set the pos to ' '????
-       // Did this commenting out introduce a bug? So far I have not
-       // seen any, please enlighten me. (Lgb)
-       // My guess is that since the inset does not exist, we might
-       // as well replace it with a space to prevent crashes. (Asger)
-       return 0;
-#else
-       /* find the inset */ 
-       InsetTable * tmpi = insettable;
-
-       while (tmpi && tmpi->pos != pos)
-               tmpi = tmpi->next;
-
-       if (tmpi)
-               return tmpi->inset;
-       else {
-               lyxerr << "ERROR (LyXParagraph::GetInset): "
-                       "Inset does not exist: " << pos << endl;
-               text[pos] = ' '; /// WHY!!! does this set the pos to ' '????
-               // Did this commenting out introduce a bug? So far I have not
-               // seen any, please enlighten me. (Lgb)
-               // My guess is that since the inset does not exist, we might
-               // as well replace it with a space to prevent crashes. (Asger)
-               return 0;
-       }
-#endif
-}
 
-
-// Gets uninstantiated font setting at position.
-// Optimized after profiling. (Asger)
-#ifdef NEW_TEXT
-LyXFont LyXParagraph::GetFontSettings(LyXParagraph::size_type pos)
-#else
-LyXFont LyXParagraph::GetFontSettings(int pos)
-#endif
+// Gets uninstantiated font setting at position 0
+LyXFont const Paragraph::getFirstFontSettings() const
 {
-#ifdef NEW_TEXT
-       if (pos < size()) {
-#ifdef NEW_TABLE
-               for(FontList::iterator it = fontlist.begin();
-                   it != fontlist.end(); ++it) {
-                       if (pos >= (*it).pos && pos <= (*it).pos_end)
-                               return (*it).font;
-               }
-#else
-               FontTable * tmp = fonttable;
-               while (tmp) {
-                       if (pos >= tmp->pos && pos <= tmp->pos_end) 
-                               return tmp->font;
-                       tmp = tmp->next;
-               }
-#endif
-       }
-       /* > because last is the next unused position, and you can 
-        * use it if you want  */
-       else if (pos > size()) {
-               if (next
-                   && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) 
-                       return NextAfterFootnote()
-                               ->GetFontSettings(pos - text.size() - 1);
-               else {
-                       // Why is it an error to ask for the font of a
-                       // position that does not exist? Would it be
-                       // enough for this to be anable on debug?
-                       // We want strict error checking, but it's ok to only
-                       // have it when debugging. (Asger)
-                       lyxerr << "ERROR (LyXParagraph::GetFontSettings): "
-                               "position does not exist. "
-                              << pos << " (" << static_cast<int>(pos)
-                              << ")\n";
-               }
-       } else if (pos) {
-               return GetFontSettings(pos - 1);
-       }
-#else
-       if (pos < last) {
-#ifdef NEW_TABLE
-               for(FontList::iterator it = fontlist.begin();
-                   it != fontlist.end(); ++it) {
-                       if (pos >= (*it).pos && pos <= (*it).pos_end)
-                               return (*it).font;
-               }
-#else
-               FontTable * tmp = fonttable;
-               while (tmp) {
-                       if (pos >= tmp->pos && pos <= tmp->pos_end) 
-                               return tmp->font;
-                       tmp = tmp->next;
-               }
-#endif
-       }
-       /* > because last is the next unused position, and you can 
-        * use it if you want  */
-       else if (pos > last) {
-               if (next
-                   && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) 
-                       return NextAfterFootnote()
-                               ->GetFontSettings(pos - last - 1);
-               else {
-                       // Why is it an error to ask for the font of a
-                       // position that does not exist? Would it be
-                       // enough for this to be anable on debug?
-                       // We want strict error checking, but it's ok to only
-                       // have it when debugging. (Asger)
-                       lyxerr << "ERROR (LyXParagraph::GetFontSettings): "
-                               "position does not exist. " << pos << endl;
-               }
-       } else if (pos) {
-               return GetFontSettings(pos - 1);
-       }
-#endif
+       if (size() > 0 && !pimpl_->fontlist.empty())
+               return pimpl_->fontlist[0].font();
+       
        return LyXFont(LyXFont::ALL_INHERIT);
 }
 
@@ -1138,2081 +630,1083 @@ LyXFont LyXParagraph::GetFontSettings(int pos)
 // the true picture of the buffer. (Asger)
 // If position is -1, we get the layout font of the paragraph.
 // If position is -2, we get the font of the manual label of the paragraph.
-#ifdef NEW_TEXT
-LyXFont LyXParagraph::getFont(LyXParagraph::size_type pos)
-#else
-LyXFont LyXParagraph::getFont(int pos)
-#endif
+LyXFont const Paragraph::getFont(BufferParams const & bparams,
+                                pos_type pos) const
 {
-       LyXFont tmpfont;
-       LyXLayout const & layout = textclasslist.Style(GetCurrentTextClass(), 
-                                          GetLayout());
-#ifdef NEW_TEXT
-       LyXParagraph::size_type main_body = 0;
+       lyx::Assert(pos >= 0);
+       
+       LyXLayout const & layout =
+               textclasslist.Style(bparams.textclass, 
+                                   getLayout());
+       pos_type main_body = 0;
+       if (layout.labeltype == LABEL_MANUAL)
+               main_body = beginningOfMainBody();
+
+       LyXFont layoutfont;
+       if (pos < main_body)
+               layoutfont = layout.labelfont;
+       else
+               layoutfont = layout.font;
+       
+       LyXFont tmpfont = getFontSettings(bparams, pos);
+#ifndef INHERIT_LANGUAGE
+       tmpfont.realize(layoutfont);
 #else
-       int main_body = 0;
+       tmpfont.realize(layoutfont, bparams.language);
 #endif
-       if (layout.labeltype == LABEL_MANUAL)
-               main_body = BeginningOfMainBody();
 
-       if (pos >= 0){
-               LyXFont layoutfont;
-               if (pos < main_body)
-                       layoutfont = layout.labelfont;
-               else
-                       layoutfont = layout.font;
-               tmpfont = GetFontSettings(pos);
-               tmpfont.realize(layoutfont);
-       } else {
-               // process layoutfont for pos == -1 and labelfont for pos < -1
-               if (pos == -1)
-                       tmpfont = layout.font;
-               else
-                       tmpfont = layout.labelfont;
-       }
+       return pimpl_->realizeFont(tmpfont, bparams);
+}
+
+
+LyXFont const Paragraph::getLabelFont(BufferParams const & bparams) const
+{
+       LyXLayout const & layout =
+               textclasslist.Style(bparams.textclass, getLayout());
+       
+       LyXFont tmpfont = layout.labelfont;
+       tmpfont.setLanguage(getParLanguage(bparams));
+
+       return pimpl_->realizeFont(tmpfont, bparams);
+}
 
-       // check for environment font information
-       char par_depth = GetDepth();
-       LyXParagraph * par = this;
-       while (par && par_depth && !tmpfont.resolved()) {
-               par = par->DepthHook(par_depth - 1);
-               if (par) {
-                       tmpfont.realize(textclasslist.
-                                       Style(GetCurrentTextClass(),
-                                             par->GetLayout()).font);
-                       par_depth = par->GetDepth();
-               }
-       }
 
-       tmpfont.realize(textclasslist.TextClass(GetCurrentTextClass()).defaultfont());
-       return tmpfont;
+LyXFont const Paragraph::getLayoutFont(BufferParams const & bparams) const
+{
+       LyXLayout const & layout =
+               textclasslist.Style(bparams.textclass, 
+                                   getLayout());
+
+       LyXFont tmpfont = layout.font;
+       tmpfont.setLanguage(getParLanguage(bparams));
+
+       return pimpl_->realizeFont(tmpfont, bparams);
 }
 
 
 /// Returns the height of the highest font in range
-#ifdef NEW_TEXT
-LyXFont::FONT_SIZE LyXParagraph::HighestFontInRange(LyXParagraph::size_type startpos, LyXParagraph::size_type endpos) const
-#else
-LyXFont::FONT_SIZE LyXParagraph::HighestFontInRange(int startpos, int endpos) const
-#endif
+LyXFont::FONT_SIZE
+Paragraph::highestFontInRange(pos_type startpos, pos_type endpos,
+                             LyXFont::FONT_SIZE const def_size) const
 {
+       if (pimpl_->fontlist.empty())
+               return def_size;
+
        LyXFont::FONT_SIZE maxsize = LyXFont::SIZE_TINY;
-#ifdef NEW_TABLE
-       for(FontList::const_iterator cit = fontlist.begin();
-           cit != fontlist.end(); ++cit) {
-               if (startpos <= (*cit).pos_end && endpos >= (*cit).pos) {
-                       LyXFont::FONT_SIZE size = (*cit).font.size();
-                       if (size > maxsize && size <= LyXFont::SIZE_HUGER)
-                               maxsize = size;
-               }
-       }
-#else
-       FontTable * tmp = fonttable;
-       while (tmp) {
-               if (startpos <= tmp->pos_end && endpos >= tmp->pos) {
-                       LyXFont::FONT_SIZE size = tmp->font.size();
-                       if (size > maxsize && size<=LyXFont::SIZE_HUGER)
-                               maxsize = size;
-               }
-               tmp = tmp->next;
+       Pimpl::FontTable end_search(endpos, LyXFont());
+       Pimpl::FontList::const_iterator end_it =
+               lower_bound(pimpl_->fontlist.begin(),
+                           pimpl_->fontlist.end(),
+                           end_search, Pimpl::matchFT());
+       if (end_it != pimpl_->fontlist.end())
+               ++end_it;
+
+       Pimpl::FontTable start_search(startpos, LyXFont());
+       Pimpl::FontList::const_iterator cit =
+               lower_bound(pimpl_->fontlist.begin(),
+                           pimpl_->fontlist.end(),
+                           start_search, Pimpl::matchFT());
+       
+       for (; cit != end_it; ++cit) {
+               LyXFont::FONT_SIZE size = cit->font().size();
+               if (size == LyXFont::INHERIT_SIZE)
+                       size = def_size;
+               if (size > maxsize && size <= LyXFont::SIZE_HUGER)
+                       maxsize = size;
        }
-#endif
        return maxsize;
 }
 
 
-#ifdef NEW_TEXT
-char LyXParagraph::GetChar(LyXParagraph::size_type pos)
-#else
-char LyXParagraph::GetChar(int pos)
-#endif
+Paragraph::value_type
+Paragraph::getUChar(BufferParams const & bparams, pos_type pos) const
 {
-#ifdef DEVEL_VERSION
-       /* a workaround to 'fix' some bugs in text-class */
-       if (pos < 0) {
-               // This function is important. It should not work around bugs.
-               // Let's find the bugs instead and fix them. (Asger)
-               lyxerr << "FATAL ERROR (LyXParagraph::GetChar):"
-                       " bad position "  << pos << endl;
-               abort();
-       }
-#endif
+       value_type c = getChar(pos);
+       if (!lyxrc.rtl_support)
+               return c;
 
-#ifdef NEW_TEXT
-       if (pos < size()) {
-               return text[pos];
-       }
-       /* > because last is the next unused position, and you can 
-        * use it if you want  */
-       else if (pos > size()) {
-               if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE) 
-                       return NextAfterFootnote()
-                               ->GetChar(pos - text.size() - 1);
-               else {
-                       lyxerr << "ERROR (LyXParagraph::GetChar): "
-                               "position does not exist."
-                              << pos << " (" << static_cast<int>(pos)
-                              << ")\n";
-               }
-               return '\0';
-#else
-       if (pos < last) {
-               return text[pos];
-       }
-       /* > because last is the next unused position, and you can 
-        * use it if you want  */
-       else if (pos > last) {
-               if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE) 
-                       return NextAfterFootnote()->GetChar(pos - last - 1);
-               else 
-                       lyxerr << "ERROR (LyXParagraph::GetChar): "
-                               "position does not exist." << pos << endl;
-               return '\0';
-#endif
-       } else {
-               /* we should have a footnote environment */ 
-               if (!next || next->footnoteflag == LyXParagraph::NO_FOOTNOTE) {
-                       // Notice that LyX does request the
-                       // last char from time to time. (Asger)
-                       //lyxerr << "ERROR (LyXParagraph::GetChar): "
-                       //      "expected footnote." << endl;
-                       return '\0';
-               }
-               switch (next->footnotekind) {
-               case LyXParagraph::FOOTNOTE:
-                       return LYX_META_FOOTNOTE;
-               case LyXParagraph::MARGIN:
-                       return LYX_META_MARGIN;
-               case LyXParagraph::FIG:
-               case LyXParagraph::WIDE_FIG:
-                       return LYX_META_FIG;
-               case LyXParagraph::TAB:
-               case LyXParagraph::WIDE_TAB:
-                       return LYX_META_TAB;
-               case LyXParagraph::ALGORITHM:
-                       return LYX_META_ALGORITHM;
-               }
-               return '\0'; // to shut up gcc
+       value_type uc = c;
+       switch (c) {
+       case '(':
+               uc = ')';
+               break;
+       case ')':
+               uc = '(';
+               break;
+       case '[':
+               uc = ']';
+               break;
+       case ']':
+               uc = '[';
+               break;
+       case '{':
+               uc = '}';
+               break;
+       case '}':
+               uc = '{';
+               break;
+       case '<':
+               uc = '>';
+               break;
+       case '>':
+               uc = '<';
+               break;
        }
+       if (uc != c && getFontSettings(bparams, pos).isRightToLeft())
+               return uc;
+       else
+               return c;
 }
 
 
-#ifdef NEW_TEXT
-string LyXParagraph::GetWord(LyXParagraph::size_type & lastpos)
-#else
-string LyXParagraph::GetWord(int & lastpos)
-#endif
+void Paragraph::setFont(pos_type pos, LyXFont const & font)
+{
+       lyx::Assert(pos <= size());
 
-  //Added 98/9/21 by REH
-  // return an string of the current word, and the end of the word
-  // in lastpos.
+       // First, reduce font against layout/label font
+       // Update: The SetCharFont() routine in text2.C already
+       // reduces font, so we don't need to do that here. (Asger)
+       // No need to simplify this because it will disappear
+       // in a new kernel. (Asger)
+       // Next search font table
 
-  // the current word is defined as starting at the first character from
-  // the immediate left of lastpospos which meets the definition of IsLetter(),
-  // continuing to the last character to the right of this meeting
-  // IsLetter.
+       Pimpl::FontTable search_font(pos, LyXFont());
+       Pimpl::FontList::iterator it = lower_bound(pimpl_->fontlist.begin(),
+                                           pimpl_->fontlist.end(),
+                                           search_font, Pimpl::matchFT());
+       unsigned int i = it - pimpl_->fontlist.begin();
+       bool notfound = it == pimpl_->fontlist.end();
 
+       if (!notfound && pimpl_->fontlist[i].font() == font)
+               return;
 
-  // i just left this in from GetChar()
-{
-#ifdef DEVEL_VERSION
-       /* a workaround to 'fix' some bugs in text-class */
-       if (lastpos < 0) {
-               // This function is important. It should not work around bugs.
-               // Let's find the bugs instead and fix them. (Asger)
-               lyxerr << "FATAL ERROR (LyXParagraph::GetWord):"
-                       " bad position " << lastpos << endl;
-               abort();
+       bool begin = pos == 0 || notfound ||
+               (i > 0 && pimpl_->fontlist[i-1].pos() == pos - 1);
+       // Is position pos is a beginning of a font block?
+       bool end = !notfound && pimpl_->fontlist[i].pos() == pos;
+       // Is position pos is the end of a font block?
+       if (begin && end) { // A single char block
+               if (i + 1 < pimpl_->fontlist.size() &&
+                   pimpl_->fontlist[i + 1].font() == font) {
+                       // Merge the singleton block with the next block
+                       pimpl_->fontlist.erase(pimpl_->fontlist.begin() + i);
+                       if (i > 0 && pimpl_->fontlist[i - 1].font() == font)
+                               pimpl_->fontlist.erase(pimpl_->fontlist.begin() + i-1);
+               } else if (i > 0 && pimpl_->fontlist[i - 1].font() == font) {
+                       // Merge the singleton block with the previous block
+                       pimpl_->fontlist[i - 1].pos(pos);
+                       pimpl_->fontlist.erase(pimpl_->fontlist.begin() + i);
+               } else
+                       pimpl_->fontlist[i].font(font);
+       } else if (begin) {
+               if (i > 0 && pimpl_->fontlist[i - 1].font() == font)
+                       pimpl_->fontlist[i - 1].pos(pos);
+               else
+                       pimpl_->fontlist.insert(pimpl_->fontlist.begin() + i,
+                                       Pimpl::FontTable(pos, font));
+       } else if (end) {
+               pimpl_->fontlist[i].pos(pos - 1);
+               if (!(i + 1 < pimpl_->fontlist.size() &&
+                     pimpl_->fontlist[i + 1].font() == font))
+                       pimpl_->fontlist.insert(pimpl_->fontlist.begin() + i + 1,
+                                       Pimpl::FontTable(pos, font));
+       } else { // The general case. The block is splitted into 3 blocks
+               pimpl_->fontlist.insert(pimpl_->fontlist.begin() + i, 
+                               Pimpl::FontTable(pos - 1, pimpl_->fontlist[i].font()));
+               pimpl_->fontlist.insert(pimpl_->fontlist.begin() + i + 1,
+                               Pimpl::FontTable(pos, font));
        }
-#endif
-
-       string theword;
-
-       // grab a word
-       
-       
-       //i think the devcode aborts before this, but why not be
-       // versatile?
-       if (lastpos < 0) lastpos=0; 
-
-       
-       // move back until we have a letter
+}
 
-       //there's no real reason to have firstpos & lastpos as
-       //separate variables as this is written, but maybe someon
-       // will want to return firstpos in the future.
 
-       //since someone might have typed a punctuation first
-       int firstpos = lastpos;
-       
-       while ((firstpos >=0) && !IsLetter(firstpos))
-               firstpos--;
 
-       // now find the beginning by looking for a nonletter
-       
-       while ((firstpos>=0) && IsLetter(firstpos))
-               firstpos--;
+void Paragraph::next(Paragraph * p)
+{
+       next_ = p;
+}
 
-       // the above is now pointing to the preceeding non-letter
-       firstpos++;
-       lastpos=firstpos;
 
-       // so copy characters into theword  until we get a nonletter
-       // note that this can easily exceed lastpos, wich means
-       // that if used in the middle of a word, the whole word
-       // is included
+// This function is able to hide closed footnotes.
+Paragraph * Paragraph::next()
+{
+       return next_;
+}
 
-       while (IsLetter(lastpos)) theword += GetChar(lastpos++);
-       
-       return  theword;
 
+Paragraph const * Paragraph::next() const
+{
+       return next_;
 }
 
-#ifdef NEW_TEXT
-LyXParagraph::size_type LyXParagraph::Last()
-#else 
-int LyXParagraph::Last()
-#endif
+
+void Paragraph::previous(Paragraph * p)
 {
-#ifdef NEW_TEXT
-       if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
-               return text.size() + NextAfterFootnote()->Last() + 1;
-                                                  /* the 1 is the symbol
-                                                     for the footnote */
-       else
-               return text.size();
-#else
-       if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
-               return last + NextAfterFootnote()->Last() + 1;
-                                                 /* the 1 is the symbol
-                                                    for the footnote */
-       else
-               return last;
-#endif
+       previous_ = p;
 }
 
 
-#ifdef NEW_TEXT
-LyXParagraph * LyXParagraph::ParFromPos(LyXParagraph::size_type pos)
-#else
-LyXParagraph * LyXParagraph::ParFromPos(int pos)
-#endif
+// This function is able to hide closed footnotes.
+Paragraph * Paragraph::previous()
 {
-#ifdef NEW_TEXT
-       /* > because last is the next unused position, and you can 
-        * use it if you want  */
-       if (pos > size()) {
-               if (next
-                   && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) 
-                       return NextAfterFootnote()
-                               ->ParFromPos(pos - text.size() - 1);
-               else 
-                       lyxerr << "ERROR (LyXParagraph::ParFromPos): "
-                               "position does not exist." << endl;
-               return this;
-       }
-#else
-       /* > because last is the next unused position, and you can 
-        * use it if you want  */
-       if (pos > last) {
-               if (next
-                   && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) 
-                       return NextAfterFootnote()->ParFromPos(pos - last - 1);
-               else 
-                       lyxerr << "ERROR (LyXParagraph::ParFromPos): "
-                               "position does not exist." << endl;
-               return this;
-       }
-#endif
-       else
-               return this;
+       return previous_;
 }
 
 
-#ifdef NEW_TEXT
-int LyXParagraph::PositionInParFromPos(LyXParagraph::size_type pos)
-#else
-int LyXParagraph::PositionInParFromPos(int pos)
-#endif
+// This function is able to hide closed footnotes.
+Paragraph const * Paragraph::previous() const
 {
-       /* > because last is the next unused position, and you can 
-        * use it if you want  */
-#ifdef NEW_TEXT
-       if (pos > size()) {
-               if (next
-                   && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) 
-                       return NextAfterFootnote()
-                               ->PositionInParFromPos(pos - text.size() - 1);
-               else 
-                       lyxerr <<
-                               "ERROR (LyXParagraph::PositionInParFromPos): "
-                               "position does not exist." << endl;
-               return pos;
-       }
-#else
-       if (pos > last) {
-               if (next
-                   && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) 
-                       return NextAfterFootnote()
-                               ->PositionInParFromPos(pos - last - 1);
-               else 
-                       lyxerr <<
-                               "ERROR (LyXParagraph::PositionInParFromPos): "
-                               "position does not exist." << endl;
-               return pos;
-       }
-#endif
-       else
-               return pos;
+       return previous_;
 }
 
 
-#ifdef NEW_TEXT
-void LyXParagraph::SetFont(LyXParagraph::size_type pos,
-                          LyXFont const & font)
-#else
-void LyXParagraph::SetFont(int pos, LyXFont const & font)
-#endif
+void Paragraph::breakParagraph(BufferParams const & bparams,
+                                 pos_type pos,
+                                 int flag)
 {
-       /* > because last is the next unused position, and you can 
-        * use it if you want  */
-#ifdef NEW_TEXT
-       if (pos > size()) {
-               if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
-                       NextAfterFootnote()->SetFont(pos - text.size() - 1,
-                                                    font);
-               } else {
-                       lyxerr << "ERROR (LyXParagraph::SetFont): "
-                               "position does not exist." << endl;
-               }
-               return;
+       // create a new paragraph
+       Paragraph * tmp = new Paragraph(this);
+       // remember to set the inset_owner
+       tmp->setInsetOwner(inInset());
+       
+       // this is an idea for a more userfriendly layout handling, I will
+       // see what the users say
+       
+       // layout stays the same with latex-environments
+       if (flag) {
+               tmp->setOnlyLayout(layout);
+               tmp->setLabelWidthString(params().labelWidthString());
        }
-#else
-       if (pos > last) {
-               if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
-                       NextAfterFootnote()->SetFont(pos - last - 1, font);
-               } else {
-                       lyxerr << "ERROR (LyXParagraph::SetFont): "
-                               "position does not exist." << endl;
+       
+       if (size() > pos || !size() || flag == 2) {
+               tmp->setOnlyLayout(layout);
+               tmp->params().align(params().align());
+               tmp->setLabelWidthString(params().labelWidthString());
+               
+               tmp->params().lineBottom(params().lineBottom());
+               params().lineBottom(false);
+               tmp->params().pagebreakBottom(params().pagebreakBottom());
+               params().pagebreakBottom(false);
+               tmp->params().spaceBottom(params().spaceBottom());
+               params().spaceBottom(VSpace(VSpace::NONE));
+               
+               tmp->params().depth(params().depth());
+               tmp->params().noindent(params().noindent());
+               
+               // copy everything behind the break-position
+               // to the new paragraph
+               pos_type pos_end = pimpl_->size() - 1;
+               pos_type i = pos;
+               pos_type j = pos;
+               for (; i <= pos_end; ++i) {
+                       cutIntoMinibuffer(bparams, i);
+                       if (tmp->insertFromMinibuffer(j - pos))
+                               ++j;
                }
-               return;
-       }
-#endif
-       LyXFont patternfont(LyXFont::ALL_INHERIT);
-
-// First, reduce font against layout/label font
-// Update: The SetCharFont() routine in text2.C already reduces font, so
-// we don't need to do that here. (Asger)
-// No need to simplify this because it will disappear in a new kernel. (Asger)
-#ifdef NEW_TABLE
-       // Next search font table
-       for(FontList::iterator it = fontlist.begin();
-           it != fontlist.end(); ++it) {
-               if (pos >= (*it).pos && pos <= (*it).pos_end) {
-                       // found it
-                       // we found a font entry. maybe we have to
-                       // split it and create a new one 
-                       
-                       if ((*it).pos != (*it).pos_end) {
-                               // more than one character
-                               if (pos == (*it).pos) {
-                                       // maybe we could enlarge
-                                       // the left fonttable
-                                       for(FontList::iterator fit = fontlist.begin();
-                                           fit != fontlist.end(); ++fit) {
-                                               if (pos - 1 >= (*fit).pos
-                                                   && pos - 1 <= (*fit).pos_end
-                                                   && (*fit).font == font) {
-                                                       // put the position
-                                                       // under the font
-                                                       (*fit).pos_end++;
-                                                       (*it).pos++;
-                                                       return;
-                                               }
-                                       }
-                                       // Add a new entry in the 
-                                       // fonttable for the position
-                                       FontTable tmp;
-                                       tmp.pos = pos + 1;
-                                       tmp.pos_end = (*it).pos_end;
-                                       tmp.font = (*it).font;
-                                       (*it).pos_end = pos;
-                                       fontlist.push_back(tmp);
-                               } else if (pos == (*it).pos_end) {
-                                       // Add a new entry in the 
-                                       // fonttable for the position
-                                       FontTable tmp;
-                                       tmp.pos = (*it).pos;
-                                       tmp.pos_end = (*it).pos_end - 1;
-                                       tmp.font = (*it).font;
-                                       (*it).pos = (*it).pos_end;
-                                       fontlist.push_back(tmp);
-                               } else {
-                                       // Add a new entry in the 
-                                       // fonttable for the position
-                                       FontTable tmp;
-                                       tmp.pos = (*it).pos;
-                                       tmp.pos_end = pos - 1;
-                                       tmp.font = (*it).font;
-                                       fontlist.push_back(tmp);
-
-                                       tmp.pos = pos + 1;
-                                       tmp.pos_end = (*it).pos_end;
-                                       tmp.font = (*it).font;
-                                       fontlist.push_back(tmp);
-                                       
-                                       (*it).pos = pos;
-                                       (*it).pos_end = pos;
-                               }
-                       }
-                       (*it).font = font;
-                       return;
+               for (i = pos_end; i >= pos; --i) {
+                       erase(i);
                }
        }
        
-       // if we did not find a font entry, but if the font at hand
-       // is the same as default, we just forget it
-       if (font == patternfont) return;
-
-       // ok, we did not find a font entry. But maybe there is exactly
-       // the needed font entry one position left
-       for(FontList::iterator it = fontlist.begin();
-           it != fontlist.end(); ++it) {
-               if (pos - 1 >= (*it).pos && pos - 1 <= (*it).pos_end
-                   && (*it).font == font) {
-                       (*it).pos_end++;
-                       return;
+       // just an idea of me
+       if (!pos) {
+               tmp->params().lineTop(params().lineTop());
+               tmp->params().pagebreakTop(params().pagebreakTop());
+               tmp->params().spaceTop(params().spaceTop());
+               tmp->bibkey = bibkey;
+               clear();
+               // layout stays the same with latex-environments
+               if (flag) {
+                       setOnlyLayout(tmp->layout);
+                       setLabelWidthString(tmp->params().labelWidthString());
+                       params().depth(tmp->params().depth());
                }
        }
-       // Add a new entry in the 
-       // fonttable for the position
-       FontTable tmp;
-       tmp.pos = pos;
-       tmp.pos_end = pos;
-       tmp.font = patternfont;
-       fontlist.push_back(tmp);
-#else
-       // Next search font table
-       FontTable * tmp2;
+}
+       
 
-       bool found = false;
-       FontTable * tmp = fonttable;
-       while (tmp && !found) {
-               if (pos >= tmp->pos && pos <= tmp->pos_end)
-                       found = true;
-               else
-                       tmp = tmp->next;
+void Paragraph::makeSameLayout(Paragraph const * par)
+{
+       layout = par->layout;
+       // move to pimpl?
+       params() = par->params();
+}
+
+
+int Paragraph::stripLeadingSpaces(lyx::textclass_type tclass) 
+{
+       if (textclasslist.Style(tclass, getLayout()).free_spacing ||
+               isFreeSpacing())
+       {
+               return 0;
+       }
+       
+       int i = 0;
+       while (size() && (isNewline(0) || isLineSeparator(0))) {
+               erase(0);
+               ++i;
        }
 
-       if (!found) {
-               /* if we did not find a font entry, but if the font at hand
-                * is the same as default, we just forget it */
-               if (font == patternfont)
-                       return;
-
-               /* ok, we did not find a font entry. But maybe there is exactly
-                * the needed font entry one position left */ 
-               found = false;
-               tmp2 = fonttable;
-               while (tmp2 && !found) {
-                       if (pos - 1 >= tmp2->pos && pos - 1 <= tmp2->pos_end)
-                               found = true;
-                       else
-                               tmp2 = tmp2->next;
-               }
-               if (found) {
-                       /* ok there is one. maybe it is exactly the needed font */
-                       if (tmp2->font == font) {
-                               /* put the position under the font */ 
-                               tmp2->pos_end++;
-                               return;
-                       }
-               }
-               /* Add a new entry in the 
-                * fonttable for the position */
-               tmp = new FontTable;
-               tmp->pos = pos;
-               tmp->pos_end = pos;
-               tmp->font = patternfont;
-               tmp->next = fonttable;
-               fonttable = tmp;
-       } else {
-               /* we found a font entry. maybe we have to split it and create
-                * a new one */ 
+       return i;
+}
 
-               if (tmp->pos != tmp->pos_end) {  /* more than one character  */
 
-                       if (pos == tmp->pos) {
-                               /* maybe we could enlarge the left fonttable */ 
+bool Paragraph::hasSameLayout(Paragraph const * par) const
+{
+       return 
+               par->layout == layout &&
+               params().sameLayout(par->params());
+}
 
-                               found = false;
-                               tmp2 = fonttable;
-                               while (tmp2 && !found) {
-                                       if (pos - 1 >= tmp2->pos && pos - 1 <= tmp2->pos_end)
-                                               found = true;
-                                       else
-                                               tmp2 = tmp2->next;
-                               }
 
-                               /* Is there is one, and is it exactly the needed font? */
-                               if (found && tmp2->font == font) {
-                                       /* put the position under the font */ 
-                                       tmp2->pos_end++;
-                                       tmp->pos++;
-                                       return;
-                               }
+void Paragraph::breakParagraphConservative(BufferParams const & bparams,
+                                          pos_type pos)
+{
+       // create a new paragraph
+       Paragraph * tmp = new Paragraph(this);
+       tmp->makeSameLayout(this);
 
-                               /* Add a new entry in the 
-                                * fonttable for the position */
-                               tmp2 = new FontTable;
-                               tmp2->pos = pos + 1;
-                               tmp2->pos_end = tmp->pos_end;
-                               tmp2->font = tmp->font;
-                               tmp->pos_end = pos;
-                               tmp2->next = fonttable;
-                               fonttable = tmp2;
-                       }
-                       else if (pos == tmp->pos_end) {
-                               /* Add a new entry in the 
-                                * fonttable for the position */
-                               tmp2 = new FontTable;
-                               tmp2->pos = tmp->pos;
-                               tmp2->pos_end = tmp->pos_end - 1;
-                               tmp2->font = tmp->font;
-                               tmp->pos = tmp->pos_end;
-                               tmp2->next = fonttable;
-                               fonttable = tmp2;
-                       }
-                       else {
-                               /* Add a new entry in the 
-                                * fonttable for the position */
-                               tmp2 = new FontTable;
-                               tmp2->pos = tmp->pos;
-                               tmp2->pos_end = pos - 1;
-                               tmp2->font = tmp->font;
-                               tmp2->next = fonttable;
-                               fonttable = tmp2;
-           
-                               tmp2 = new FontTable;
-                               tmp2->pos = pos + 1;
-                               tmp2->pos_end = tmp->pos_end;
-                               tmp2->font = tmp->font;
-                               tmp2->next = fonttable;
-                               fonttable = tmp2;
-           
-                               tmp->pos = pos;
-                               tmp->pos_end = pos;
-                       }
+       // When can pos > Last()?
+       // I guess pos == Last() is possible.
+       if (size() > pos) {
+               // copy everything behind the break-position to the new
+               // paragraph
+               pos_type pos_end = pimpl_->size() - 1;
+
+               //pos_type i = pos;
+               //pos_type j = pos;
+               for (pos_type i = pos, j = pos; i <= pos_end; ++i) {
+                       cutIntoMinibuffer(bparams, i);
+                       if (tmp->insertFromMinibuffer(j - pos))
+                               ++j;
+               }
+               
+               for (pos_type k = pos_end; k >= pos; --k) {
+                       erase(k);
                }
        }
-       tmp->font = font;
-#endif
 }
 
-   
-/* this function is able to hide closed footnotes */
-LyXParagraph * LyXParagraph::Next()
+
+// Be carefull, this does not make any check at all.
+// This method has wrong name, it combined this par with the next par.
+// In that sense it is the reverse of break paragraph. (Lgb)
+void Paragraph::pasteParagraph(BufferParams const & bparams)
 {
-       if (next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
-               LyXParagraph * tmp = next;
-               while (tmp
-                      && tmp->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
-                       tmp = tmp->next;
-               if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE) 
-                       return tmp->Next(); /* there can be more than one
-                                              footnote in a logical
-                                              paragraph */
-               else
-                       return next;    /* this should never happen! */
+       // copy the next paragraph to this one
+       Paragraph * the_next = next();
+
+       // first the DTP-stuff
+       params().lineBottom(the_next->params().lineBottom());
+       params().spaceBottom(the_next->params().spaceBottom());
+       params().pagebreakBottom(the_next->params().pagebreakBottom());
+
+       pos_type pos_end = the_next->pimpl_->size() - 1;
+       pos_type pos_insert = size();
+
+       // ok, now copy the paragraph
+       for (pos_type i = 0, j = 0; i <= pos_end; ++i) {
+               the_next->cutIntoMinibuffer(bparams, i);
+               if (insertFromMinibuffer(pos_insert + j))
+                       ++j;
        }
-       else
-               return next;
+
+       // delete the next paragraph
+       Paragraph * ppar = the_next->previous_;
+       Paragraph * npar = the_next->next_;
+       delete the_next;
+       ppar->next(npar);
 }
 
 
-LyXParagraph * LyXParagraph::NextAfterFootnote()
+int Paragraph::getEndLabel(BufferParams const & bparams) const
 {
-       if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE) {
-               LyXParagraph * tmp = next;
-               while (tmp && tmp->footnoteflag != LyXParagraph::NO_FOOTNOTE)
-                       tmp = tmp->next;
-               if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE) 
-                       return tmp;   /* there can be more than one footnote
-                                        in a logical paragraph */
-               else
-                       return next;     /* this should never happen! */
+       Paragraph const * par = this;
+       depth_type par_depth = getDepth();
+       while (par) {
+               layout_type layout = par->getLayout();
+               int const endlabeltype =
+                       textclasslist.Style(bparams.textclass,
+                                           layout).endlabeltype;
+               if (endlabeltype != END_LABEL_NO_LABEL) {
+                       if (!next_)
+                               return endlabeltype;
+
+                       depth_type const next_depth = next_->getDepth();
+                       if (par_depth > next_depth ||
+                           (par_depth == next_depth
+                            && layout != next_->getLayout()))
+                               return endlabeltype;
+                       break;
+               }
+               if (par_depth == 0)
+                       break;
+               par = par->outerHook();
+               if (par)
+                       par_depth = par->getDepth();
        }
-       else
-               return next;
+       return END_LABEL_NO_LABEL;
 }
 
 
-LyXParagraph * LyXParagraph::PreviousBeforeFootnote()
+Paragraph::depth_type Paragraph::getDepth() const
 {
-       LyXParagraph * tmp;
-       if (previous && previous->footnoteflag != LyXParagraph::NO_FOOTNOTE) {
-               tmp = next;
-               while (tmp && tmp->footnoteflag != LyXParagraph::NO_FOOTNOTE)
-                       tmp = tmp->previous;
-               if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE) 
-                       return tmp;    /* there can be more than one footnote
-                                         in a logical paragraph */
-               else
-                       return previous;   /* this should never happen! */
-       }
-       else
-               return previous;
+       return params().depth();
 }
 
 
-LyXParagraph * LyXParagraph::LastPhysicalPar()
+char Paragraph::getAlign() const
 {
-       if (footnoteflag != LyXParagraph::NO_FOOTNOTE)
-               return this;
-   
-       LyXParagraph * tmp = this;
-       while (tmp->next && tmp->next->footnoteflag != LyXParagraph::NO_FOOTNOTE)
-               tmp = tmp->NextAfterFootnote();
-   
-       return tmp;
-   
+       return params().align();
 }
 
 
-LyXParagraph * LyXParagraph::FirstPhysicalPar()
+string const & Paragraph::getLabelstring() const
 {
-       if (!IsDummy())
-               return this;
-       LyXParagraph * tmppar = this;
-
-       while (tmppar && (tmppar->IsDummy()
-                         || tmppar->footnoteflag != LyXParagraph::NO_FOOTNOTE))
-               tmppar = tmppar->previous;
-   
-       if (!tmppar)
-               return this;           /* this should never happen!  */
-       else
-               return tmppar;
+       return params().labelString();
 }
 
 
-/* this function is able to hide closed footnotes */
-LyXParagraph * LyXParagraph::Previous()
+int Paragraph::getFirstCounter(int i) const
 {
-       LyXParagraph * tmp = previous;
-       if (!tmp)
-               return tmp;
-   
-       if (tmp->previous
-           && tmp->previous->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
-               tmp = tmp->previous;
-               while (tmp
-                      && tmp->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE)
-                       tmp = tmp->previous;
-               if (tmp && tmp->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE) 
-                       return tmp->next->Previous();   
-
-               else
-                       return previous; 
-       }
-       else
-               return previous;
+       return pimpl_->counter_[i];
 }
 
-#ifdef NEW_TEXT
-void LyXParagraph::BreakParagraph(LyXParagraph::size_type pos,
-                                 int flag)
-#else
-void LyXParagraph::BreakParagraph(int pos, int flag)
-#endif
-{
-#ifdef NEW_TEXT
-       size_type i, pos_end, pos_first;
-#else
-       int i, pos_end, pos_first;
-#endif
-       /* create a new paragraph */
-       LyXParagraph * par = ParFromPos(pos);
-       LyXParagraph * firstpar = FirstPhysicalPar();
-   
-       LyXParagraph * tmp = new LyXParagraph(par);
-   
-       tmp->footnoteflag = footnoteflag;
-       tmp->footnotekind = footnotekind;
-   
-       /* this is an idea for a more userfriendly layout handling, I will
-        * see what the users say */
-   
-       /* layout stays the same with latex-environments */ 
-       if (flag) {
-               tmp->SetOnlyLayout(firstpar->layout);
-               tmp->SetLabelWidthString(firstpar->labelwidthstring);
-       }
 
-       if (Last() > pos || !Last() || flag == 2) {
-               tmp->SetOnlyLayout(firstpar->layout);
-               tmp->align = firstpar->align;
-               tmp->SetLabelWidthString(firstpar->labelwidthstring);
-      
-               tmp->line_bottom = firstpar->line_bottom;
-               firstpar->line_bottom = false;
-               tmp->pagebreak_bottom = firstpar->pagebreak_bottom;
-               firstpar->pagebreak_bottom = false;
-               tmp->added_space_bottom = firstpar->added_space_bottom;
-               firstpar->added_space_bottom = VSpace(VSpace::NONE);
-      
-               tmp->depth = firstpar->depth;
-               tmp->noindent = firstpar->noindent;
-   
-               /* copy everything behind the break-position
-                  to the new paragraph
-               */
-               pos_first = 0;
-               while (ParFromPos(pos_first) != par)
-                       pos_first++;
-
-#ifdef NEW_TEXT
-               pos_end = pos_first + par->text.size() - 1;
-               tmp->text.reserve(pos_end - pos);
-#else
-               pos_end = pos_first + par->last - 1;
-               /* make sure there is enough memory for the now larger
-                  paragraph. This is not neccessary, because
-                  InsertFromMinibuffer will enlarge the memory (it uses
-                  InsertChar of course). But doing it by hand
-                  is MUCH faster! (only one time, not thousend times!!) */
-               tmp->Enlarge(0, pos_end - pos);
-#endif
-               for (i = pos; i <= pos_end; i++) {
-                       par->CutIntoMinibuffer(i - pos_first);
-                       tmp->InsertFromMinibuffer(i - pos);
-               }
+// the next two functions are for the manual labels
+string const Paragraph::getLabelWidthString() const
+{
+       if (!params().labelWidthString().empty())
+               return params().labelWidthString();
+       else
+               return _("Senseless with this layout!");
+}
 
-               for (i = pos_end; i >= pos; i--)
-                       par->Erase(i - pos_first);
-#ifdef NEW_TEXT
-               par->text.resize(par->text.size());
-#else
-               /* free memory of the now shorter paragraph*/
-               par->FitSize();
-#endif
-       }
 
-       /* just an idea of me */ 
-       if (!pos) {
-               tmp->line_top = firstpar->line_top;
-               tmp->pagebreak_top = firstpar->pagebreak_top;
-               tmp->added_space_top = firstpar->added_space_top;
-               tmp->bibkey = firstpar->bibkey;
-               firstpar->Clear();
-               /* layout stays the same with latex-environments */ 
-               if (flag) {
-                       firstpar->SetOnlyLayout(tmp->layout);
-                       firstpar->SetLabelWidthString(tmp->labelwidthstring);
-                       firstpar->depth = tmp->depth;
-               }
-       }
+void Paragraph::setLabelWidthString(string const & s)
+{
+       params().labelWidthString(s);
 }
 
 
-void LyXParagraph::MakeSameLayout(LyXParagraph * par)
+void Paragraph::setOnlyLayout(layout_type new_layout)
 {
-       par = par->FirstPhysicalPar();
-       footnoteflag = par->footnoteflag;
-       footnotekind = par->footnotekind;
-
-       layout = par->layout;
-       align = par-> align;
-       SetLabelWidthString(par->labelwidthstring);
-
-       line_bottom = par->line_bottom;
-       pagebreak_bottom = par->pagebreak_bottom;
-       added_space_bottom = par->added_space_bottom;
-
-       line_top = par->line_top;
-       pagebreak_top = par->pagebreak_top;
-       added_space_top = par->added_space_top;
-
-        pextra_type = par->pextra_type;
-        pextra_width = par->pextra_width;
-        pextra_widthp = par->pextra_widthp;
-        pextra_alignment = par->pextra_alignment;
-        pextra_hfill = par->pextra_hfill;
-        pextra_start_minipage = par->pextra_start_minipage;
-
-       noindent = par->noindent;
-       depth = par->depth;
+       layout = new_layout;
 }
 
 
-LyXParagraph * LyXParagraph::FirstSelfrowPar()
+void Paragraph::setLayout(layout_type new_layout)
 {
-       LyXParagraph * tmppar = this;
-       while (tmppar && (
-               (tmppar->IsDummy()
-                && tmppar->previous->footnoteflag ==
-                LyXParagraph::CLOSED_FOOTNOTE)
-               || tmppar->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE))
-               tmppar = tmppar->previous;
-   
-       if (!tmppar)
-               return this;           /* this should never happen!  */
-       else
-               return tmppar;
+       layout = new_layout;
+       params().labelWidthString(string());
+       params().align(LYX_ALIGN_LAYOUT);
+       params().spaceTop(VSpace(VSpace::NONE));
+       params().spaceBottom(VSpace(VSpace::NONE));
+       params().spacing(Spacing(Spacing::Default));
 }
 
 
-LyXParagraph * LyXParagraph::Clone()
+// if the layout of a paragraph contains a manual label, the beginning of the 
+// main body is the beginning of the second word. This is what the par-
+// function returns. If the layout does not contain a label, the main
+// body always starts with position 0. This differentiation is necessary,
+// because there cannot be a newline or a blank <= the beginning of the 
+// main body in TeX.
+
+int Paragraph::beginningOfMainBody() const
 {
-       /* create a new paragraph */
-       LyXParagraph * result = new LyXParagraph;
-   
-       result->MakeSameLayout(this);
-
-       /* this is because of the dummy layout of the paragraphs that
-          follow footnotes */
-       result->layout = layout;
-   
-       /* table stuff -- begin*/ 
-       if (table)
-               result->table = table->Clone();
-       else
-               result->table = 0;
-       /* table stuff -- end*/ 
-   
-        // ale970302
-        result->bibkey = (bibkey) ? new InsetBibKey(bibkey): 0;
-               
-    
-       /* copy everything behind the break-position to the new paragraph */
-   
-#ifdef NEW_TEXT
-       result->text.reserve(size());
-       for (size_type i = 0; i < size(); i++) {
-               CopyIntoMinibuffer(i);
-               result->InsertFromMinibuffer(i);
-       }
-#else
-       /* make shure there is enough memory for the now larger paragraph.
-        * This is not neccessary, because InsertFromMinibuffer will enlarge
-        * the memory (it uses InsertChar of course). But doing it by hand
-        * is MUCH faster! (only one time, not thousend times!!) */
-       result->Enlarge(0, last+2);
-       for (int i = 0; i < last; i++) {
-               CopyIntoMinibuffer(i);
-               result->InsertFromMinibuffer(i);
-       }
-#endif
-       return result;
-}
-
-
-bool LyXParagraph::HasSameLayout(LyXParagraph * par)
-{
-       par = par->FirstPhysicalPar();
-
-       return (
-               par->footnoteflag == footnoteflag &&
-               par->footnotekind == footnotekind &&
-
-               par->layout == layout &&
-
-               par->align == align &&
-
-               par->line_bottom == line_bottom &&
-               par->pagebreak_bottom == pagebreak_bottom &&
-               par->added_space_bottom == added_space_bottom &&
-
-               par->line_top == line_top &&
-               par->pagebreak_top == pagebreak_top &&
-               par->added_space_top == added_space_top &&
-
-                par->pextra_type == pextra_type &&
-                par->pextra_width == pextra_width && 
-                par->pextra_widthp == pextra_widthp && 
-                par->pextra_alignment == pextra_alignment && 
-                par->pextra_hfill == pextra_hfill && 
-                par->pextra_start_minipage == pextra_start_minipage && 
-
-               par->table == table && // what means: NO TABLE AT ALL 
-
-               par->noindent == noindent &&
-               par->depth == depth);
-}
-
-#ifdef NEW_TEXT
-void LyXParagraph::BreakParagraphConservative(LyXParagraph::size_type pos)
-#else
-void LyXParagraph::BreakParagraphConservative(int pos)
-#endif
-{
-#ifdef NEW_TEXT
-       size_type i, pos_end, pos_first;
-#else
-       int i, pos_end, pos_first;
-#endif
-       
-       /* create a new paragraph */
-       LyXParagraph * par = ParFromPos(pos);
-
-       LyXParagraph * tmp = new LyXParagraph(par);
-   
-       tmp->MakeSameLayout(par);
-   
-       if (Last() > pos) {   
-               /* copy everything behind the break-position to the new
-                  paragraph */
-               pos_first = 0;
-               while (ParFromPos(pos_first) != par)
-                       pos_first++;
-#ifdef NEW_TEXT
-               pos_end = pos_first + par->text.size() - 1;
-#else
-               pos_end = pos_first + par->last - 1;
-#endif
-               /* make shure there is enough memory for the now larger
-                  paragraph. This is not neccessary, because
-                  InsertFromMinibuffer will enlarge the memory (it uses
-                  InsertChar of course). But doing it by hand
-                  is MUCH faster! (only one time, not thousend times!!) */
-#ifdef NEW_TEXT
-               tmp->text.reserve(pos_end - pos);
-#else
-               tmp->Enlarge(0, pos_end - pos);
-#endif
-               for (i = pos; i <= pos_end; i++) {
-      
-                       par->CutIntoMinibuffer(i - pos_first);
-                       tmp->InsertFromMinibuffer(i - pos);
-               }
-               for (i = pos_end; i >= pos; i--)
-                       par->Erase(i - pos_first);
-#ifdef NEW_TEXT
-               par->text.resize(par->text.size());
-#else
-               /* free memory of the now shorter paragraph*/
-               par->FitSize();
-#endif
-       }
-}
-   
-
-/* be carefull, this does not make any check at all */ 
-void LyXParagraph::PasteParagraph()
-{
-       /* copy the next paragraph to this one */
-       LyXParagraph * the_next = Next();
-   
-       LyXParagraph * firstpar = FirstPhysicalPar();
-   
-       /* first the DTP-stuff */ 
-       firstpar->line_bottom = the_next->line_bottom;
-       firstpar->added_space_bottom = the_next->added_space_bottom;
-       firstpar->pagebreak_bottom = the_next->pagebreak_bottom;
-
-#ifdef NEW_TEXT
-       size_type pos_end = the_next->text.size() - 1;
-       size_type pos_insert = Last();
-       size_type i;
-#else
-       int pos_end = the_next->last - 1;
-       int pos_insert = Last();
-       /* enlarge the paragraph. This is faster than enlarge it
-        * every 10th insertion. */ 
-       if (pos_end >= 0)
-               Enlarge(pos_insert, pos_end);
-       int i;
-#endif
-
-       /* ok, now copy the paragraph */ 
-       for (i = 0; i <= pos_end; i++) {
-               the_next->CutIntoMinibuffer(i);
-               InsertFromMinibuffer(pos_insert + i);
-       }
-   
-       /* delete the next paragraph */
-       delete the_next;
-}
-
-#ifdef NEW_TEXT
-void LyXParagraph::OpenFootnote(LyXParagraph::size_type pos)
-#else
-void LyXParagraph::OpenFootnote(int pos)
-#endif
-{
-       LyXParagraph * par = ParFromPos(pos);
-       par = par->next;
-       while (par && par->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
-               par->footnoteflag = LyXParagraph::OPEN_FOOTNOTE;
-               par = par->next;
-       }
-}
-
-#ifdef NEW_TEXT
-void LyXParagraph::CloseFootnote(LyXParagraph::size_type pos)
-#else
-void LyXParagraph::CloseFootnote(int pos)
-#endif
-{
-       LyXParagraph * par = ParFromPos(pos);
-       par = par->next;
-       while (par && par->footnoteflag == LyXParagraph::OPEN_FOOTNOTE) {
-               par->footnoteflag = LyXParagraph::CLOSED_FOOTNOTE;
-               par = par->next;
-       }
-}
-
-
-LyXTextClass::LayoutList::size_type LyXParagraph::GetLayout()
-{
-       return FirstPhysicalPar()->layout;
-}
-
-
-char LyXParagraph::GetDepth()
-{
-       return FirstPhysicalPar()->depth;
-}
-
-
-char LyXParagraph::GetAlign()
-{
-       return FirstPhysicalPar()->align;
-}
-
-
-string LyXParagraph::GetLabestring()
-{
-       return FirstPhysicalPar()->labelstring;
-}
-
-
-int LyXParagraph::GetFirstCounter(int i)
-{
-       return FirstPhysicalPar()->counter[i];
-}
-
-
-/* the next two functions are for the manual labels */ 
-string LyXParagraph::GetLabelWidthString()
-{
-       if (!FirstPhysicalPar()->labelwidthstring.empty())
-               return FirstPhysicalPar()->labelwidthstring;
-       else
-               return _("Senseless with this layout!");
-}
-
-
-void LyXParagraph::SetLabelWidthString(string const & s)
-{
-       LyXParagraph * par = FirstPhysicalPar();
-
-       par->labelwidthstring = s;
-}
-
-
-void LyXParagraph::SetOnlyLayout(LyXTextClass::LayoutList::size_type new_layout)
-{
-       LyXParagraph * par = FirstPhysicalPar();
-       LyXParagraph * ppar = 0;
-       LyXParagraph * npar = 0;
-
-       par->layout = new_layout;
-       /* table stuff -- begin*/ 
-       if (table) 
-               par->layout = 0;
-       /* table stuff -- end*/ 
-        if (par->pextra_type == PEXTRA_NONE) {
-                if (par->Previous()) {
-                        ppar = par->Previous()->FirstPhysicalPar();
-                        while(ppar
-                             && ppar->Previous()
-                             && (ppar->depth > par->depth))
-                                ppar = ppar->Previous()->FirstPhysicalPar();
-                }
-                if (par->Next()) {
-                        npar = par->Next()->NextAfterFootnote();
-                        while(npar
-                             && npar->Next()
-                             && (npar->depth > par->depth))
-                                npar = npar->Next()->NextAfterFootnote();
-                }
-                if (ppar && (ppar->pextra_type != PEXTRA_NONE)) {
-                        string
-                                p1 = ppar->pextra_width,
-                                p2 = ppar->pextra_widthp;
-                        ppar->SetPExtraType(ppar->pextra_type,
-                                            p1.c_str(),p2.c_str());
-                }
-                if ((par->pextra_type == PEXTRA_NONE) &&
-                    npar && (npar->pextra_type != PEXTRA_NONE)) {
-                        string
-                                p1 = npar->pextra_width,
-                                p2 = npar->pextra_widthp;
-                        npar->SetPExtraType(npar->pextra_type,
-                                            p1.c_str(),p2.c_str());
-                }
-        }
-}
-
-
-void LyXParagraph::SetLayout(LyXTextClass::LayoutList::size_type new_layout)
-{
-       LyXParagraph
-               * par = FirstPhysicalPar(),
-               * ppar = 0,
-               * npar = 0;
-
-        par->layout = new_layout;
-       par->labelwidthstring.clear();
-       par->align = LYX_ALIGN_LAYOUT;
-       par->added_space_top = VSpace(VSpace::NONE);
-       par->added_space_bottom = VSpace(VSpace::NONE);
-       /* table stuff -- begin*/ 
-       if (table) 
-               par->layout = 0;
-       /* table stuff -- end*/
-        if (par->pextra_type == PEXTRA_NONE) {
-                if (par->Previous()) {
-                        ppar = par->Previous()->FirstPhysicalPar();
-                        while(ppar
-                             && ppar->Previous()
-                             && (ppar->depth > par->depth))
-                                ppar = ppar->Previous()->FirstPhysicalPar();
-                }
-                if (par->Next()) {
-                        npar = par->Next()->NextAfterFootnote();
-                        while(npar
-                             && npar->Next()
-                             && (npar->depth > par->depth))
-                                npar = npar->Next()->NextAfterFootnote();
-                }
-                if (ppar && (ppar->pextra_type != PEXTRA_NONE)) {
-                        string
-                                p1 = ppar->pextra_width,
-                                p2 = ppar->pextra_widthp;
-                        ppar->SetPExtraType(ppar->pextra_type,
-                                            p1.c_str(),p2.c_str());
-                }
-                if ((par->pextra_type == PEXTRA_NONE) &&
-                    npar && (npar->pextra_type != PEXTRA_NONE)) {
-                        string
-                                p1 = npar->pextra_width,
-                                p2 = npar->pextra_widthp;
-                        npar->SetPExtraType(npar->pextra_type,
-                                            p1.c_str(),p2.c_str());
-                }
-        }
-}
-
-
-/* if the layout of a paragraph contains a manual label, the beginning of the 
-* main body is the beginning of the second word. This is what the par-
-* function returns. If the layout does not contain a label, the main
-* body always starts with position 0. This differentiation is necessary,
-* because there cannot be a newline or a blank <= the beginning of the 
-* main body in TeX. */ 
-
-int LyXParagraph::BeginningOfMainBody()
-{
-       if (FirstPhysicalPar() != this)
-               return -1;
-   
-   
-// Unroll the first two cycles of the loop
-// and remember the previous character to remove unnecessary GetChar() calls
-#ifdef NEW_TEXT
-       size_type i = 0;
+       // Unroll the first two cycles of the loop
+       // and remember the previous character to
+       // remove unnecessary GetChar() calls
+       pos_type i = 0;
        if (i < size()
-           && GetChar(i) != LYX_META_NEWLINE) {
+           && getChar(i) != Paragraph::META_NEWLINE) {
                ++i;
-               char previous_char, temp;
+               char previous_char = 0;
+               char temp = 0; 
                if (i < size()
-                   && (previous_char = GetChar(i)) != LYX_META_NEWLINE) {
-                       // Yes, this  ^ is supposed to be "=" not "=="
+                   && (previous_char = getChar(i)) != Paragraph::META_NEWLINE) {
+                       // Yes, this  ^ is supposed to be "= " not "=="
                        ++i;
                        while (i < size()
                               && previous_char != ' '
-                              && (temp = GetChar(i)) != LYX_META_NEWLINE) {
+                              && (temp = getChar(i)) != Paragraph::META_NEWLINE) {
                                ++i;
                                previous_char = temp;
                        }
                }
        }
 
-       if (i == 0 && i == size() &&
-           !(footnoteflag==LyXParagraph::NO_FOOTNOTE
-             && next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE))
-               i++;                           /* the cursor should not jump  
-                                               * to the main body if there
-                                               * is nothing in! */
-#else
-       int i = 0;
-       if (i < last
-           && GetChar(i) != LYX_META_NEWLINE) {
-               ++i;
-               char previous_char, temp;
-               if (i < last
-                   && (previous_char = GetChar(i)) != LYX_META_NEWLINE) {
-                       // Yes, this  ^ is supposed to be "=" not "=="
-                       ++i;
-                       while (i < last
-                              && previous_char != ' '
-                              && (temp = GetChar(i)) != LYX_META_NEWLINE) {
-                               ++i;
-                               previous_char = temp;
-                       }
-               }
-       }
-
-       if (i==0 && i == last &&
-           !(footnoteflag==LyXParagraph::NO_FOOTNOTE
-             && next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE)
-               )
-               i++;                           /* the cursor should not jump  
-                                               * to the main body if there
-                                               * is nothing in! */
-#endif
        return i;
 }
 
 
-LyXParagraph * LyXParagraph::DepthHook(int deth)
+Paragraph * Paragraph::depthHook(depth_type depth)
 {
-       LyXParagraph * newpar = this;
-       if (deth < 0)
-               return 0;
-   
+       Paragraph * newpar = this;
+
        do {
-               newpar = newpar->FirstPhysicalPar()->Previous();
-       } while (newpar && newpar->GetDepth() > deth
-                && newpar->footnoteflag == footnoteflag);
-   
+               newpar = newpar->previous();
+       } while (newpar && newpar->getDepth() > depth);
+
        if (!newpar) {
-               if (Previous() || GetDepth())
-                       lyxerr << "ERROR (LyXParagraph::DepthHook): "
+               if (previous() || getDepth())
+                       lyxerr << "ERROR (Paragraph::DepthHook): "
                                "no hook." << endl;
                newpar = this;
        }
-       return newpar->FirstPhysicalPar();
+
+       return newpar;
 }
 
 
-int LyXParagraph::AutoDeleteInsets()
+Paragraph const * Paragraph::depthHook(depth_type depth) const
 {
-#ifdef NEW_TABLE
-       int i = 0;
-       for (InsetList::iterator it = insetlist.begin();
-            it != insetlist.end(); ++it) {
-               if ((*it).inset->AutoDelete()) {
-                       ++i;
-                       Erase((*it).pos);
-               }
-       }
-       return i;
-#else
-       InsetTable * tmpi = insettable;
-       InsetTable * tmpi2 = tmpi;
-       int i = 0;
-       while (tmpi) {
-               tmpi2 = tmpi;
-               tmpi = tmpi->next;
-               if (tmpi2->inset)
-                       if (tmpi2->inset->AutoDelete()) {
-                               i++;
-                               Erase(tmpi2->pos);
-                       } else {}
-               else
-                       lyxerr << "ERROR (LyXParagraph::AutoDeleteInsets): "
-                               "cannot auto-delete insets" << endl;
+       Paragraph const * newpar = this;
+
+       do {
+               newpar = newpar->previous();
+       } while (newpar && newpar->getDepth() > depth);
+
+       if (!newpar) {
+               if (previous() || getDepth())
+                       lyxerr << "ERROR (Paragraph::DepthHook): "
+                               "no hook." << endl;
+               newpar = this;
        }
-       return i;
-#endif
-}
 
+       return newpar;
+}
 
-#ifdef NEW_TEXT
-Inset * LyXParagraph::ReturnNextInsetPointer(LyXParagraph::size_type & pos)
-#else
-Inset * LyXParagraph::ReturnNextInsetPointer(int & pos)
-#endif
+Paragraph * Paragraph::outerHook()
 {
-#ifdef NEW_TABLE
-       InsetTable * tmp = 0;
-       for (InsetList::iterator it = insetlist.begin();
-            it != insetlist.end(); ++it) {
-               if ((*it).pos >= pos && (!tmp || (*it).pos < tmp->pos)) {
-                       tmp = &(*it);
-               }
-       }
-       if (tmp) {
-               pos = tmp->pos;
-               return tmp->inset;
-       }
-       return 0;
-               
-#else
-       InsetTable * tmpi = insettable;
-       InsetTable * tmpi2 = 0;
-       while (tmpi){
-               if (tmpi->pos >= pos) {
-                       if (!tmpi2 || tmpi->pos < tmpi2->pos)
-                               tmpi2 = tmpi;
-               }
-               tmpi=tmpi->next;
-       }
-       if (tmpi2){
-               pos = tmpi2->pos;
-               return tmpi2->inset;
-       }
-       else
+       if(!getDepth())
                return 0;
-#endif
+       return depthHook(depth_type(getDepth() - 1));
 }
 
-
-/* returns -1 if inset not found */
-int LyXParagraph::GetPositionOfInset(Inset * inset)
+Paragraph const * Paragraph::outerHook() const
 {
-#ifdef NEW_TABLE
-       for (InsetList::iterator it = insetlist.begin();
-            it != insetlist.end(); ++it) {
-               if ((*it).inset == inset) {
-                       return (*it).pos;
-               }
-       }
-       // Think about footnotes
-       if (footnoteflag == LyXParagraph::NO_FOOTNOTE
-           && next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
-               int further = NextAfterFootnote()->GetPositionOfInset(inset);
-#ifdef NEW_TEXT
-               if (further != -1)
-                       return size() + 1 + further;
-#else
-               if (further != -1)
-                       return last + 1 + further;
-#endif
-       }
-       return -1;
-#else
-       /* find the entry */ 
-       InsetTable * tmpi = insettable;
-       while (tmpi && tmpi->inset != inset) {
-               tmpi = tmpi->next;
-       }
-       if (tmpi && tmpi->inset)
-               return tmpi->pos;
-       else{
-               /* think about footnotes */
-               if (footnoteflag == LyXParagraph::NO_FOOTNOTE 
-                   && next && next->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
-                       int further =
-                               NextAfterFootnote()->GetPositionOfInset(inset);
-#ifdef NEW_TEXT
-                       if (further != -1)
-                               return text.size() + 1 + further;
-#else
-                       if (further != -1)
-                               return last + 1 + further;
-#endif
-               }
-               return -1;
-       }
-#endif
+       if(!getDepth())
+               return 0;
+       return depthHook(depth_type(getDepth() - 1));
 }
 
 
-void LyXParagraph::readSimpleWholeFile(FILE * myfile)
+Paragraph::inset_iterator
+Paragraph::InsetIterator(pos_type pos)
 {
+       InsetTable search_inset(pos, 0);
+       InsetList::iterator it = lower_bound(insetlist.begin(),
+                                            insetlist.end(),
+                                            search_inset, Pimpl::matchIT());
+       return inset_iterator(it);
+}
 
-#ifndef NEW_TEXT
-       FileInfo fileInfo(fileno(myfile));
-       long file_size = fileInfo.getSize();
-       /* it is horrible, I know, but faster.
-        * I should not use InsertString for that :-( */
 
-       /* I will write a better insertion in the future */ 
-       Enlarge(0, file_size + 10);
-#endif
-       rewind(myfile);
-   
-       if (!feof(myfile)) {
-               char c = 0;
-               do {
-                       c = fgetc(myfile);
-#ifdef NEW_TEXT
-                       InsertChar(text.size(), c);
-#else
-                       InsertChar(last,c);
-#endif
-               } while (!feof(myfile));
-      
+// returns -1 if inset not found
+int Paragraph::getPositionOfInset(Inset const * inset) const
+{
+       // Find the entry.
+       for (InsetList::const_iterator cit = insetlist.begin();
+            cit != insetlist.end(); ++cit) {
+               if (cit->inset == inset) {
+                       return cit->pos;
+               }
        }
+       if (inset == bibkey)
+               return 0;
+
+       return -1;
 }
 
 
-LyXParagraph * LyXParagraph::TeXOnePar(string & file, TexRow & texrow,
-                                     string & foot, TexRow & foot_texrow,
-                                     int & foot_count)
+Paragraph * Paragraph::TeXOnePar(Buffer const * buf,
+                                 BufferParams const & bparams,
+                                 ostream & os, TexRow & texrow,
+                                 bool moving_arg)
 {
        lyxerr[Debug::LATEX] << "TeXOnePar...     " << this << endl;
-       LyXParagraph * par = next;
-       LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(), layout);
-
+       Inset const * in = inInset();
        bool further_blank_line = false;
-       if (IsDummy())
-               lyxerr << "ERROR (LyXParagraph::TeXOnePar) is dummy." << endl;
+       LyXLayout style;
+       
+       // well we have to check if we are in an inset with unlimited
+       // lenght (all in one row) if that is true then we don't allow
+       // any special options in the paragraph and also we don't allow
+       // any environment other then "Standard" to be valid!
+       if ((in == 0) || !in->forceDefaultParagraphs(in)) {
+               style = textclasslist.Style(bparams.textclass, layout);
+
+               if (params().startOfAppendix()) {
+                       os << "\\appendix\n";
+                       texrow.newline();
+               }
 
-       if (start_of_appendix) {
-               file += "\\appendix\n";
-               texrow.newline();
-       }
+               if (!params().spacing().isDefault()
+                       && (!previous() || !previous()->hasSameLayout(this))) {
+                       os << params().spacing().writeEnvirBegin() << "\n";
+                       texrow.newline();
+               }
+       
+               if (tex_code_break_column && style.isCommand()){
+                       os << '\n';
+                       texrow.newline();
+               }
 
-       if (tex_code_break_column && style.isCommand()){
-               file += '\n';
-               texrow.newline();
-       }
+               if (params().pagebreakTop()) {
+                       os << "\\newpage";
+                       further_blank_line = true;
+               }
+               if (params().spaceTop().kind() != VSpace::NONE) {
+                       os << params().spaceTop().asLatexCommand(bparams);
+                       further_blank_line = true;
+               }
 
-       if (pagebreak_top) {
-               file += "\\newpage";
-               further_blank_line = true;
-       }
-       if (added_space_top.kind() != VSpace::NONE) {
-               file += added_space_top.asLatexCommand();
-               further_blank_line = true;
-       }
-      
-       if (line_top) {
-               file += "\\lyxline{\\" + getFont(0).latexSize() + '}';
-               file += "\\vspace{-1\\parskip}";
-               further_blank_line = true;
+               if (params().lineTop()) {
+                       os << "\\lyxline{\\" << getFont(bparams, 0).latexSize() << '}'
+                          << "\\vspace{-1\\parskip}";
+                       further_blank_line = true;
+               }
+
+               if (further_blank_line){
+                       os << '\n';
+                       texrow.newline();
+               }
+       } else {
+               style = textclasslist.Style(bparams.textclass, 0);
+       }
+
+       Language const * language = getParLanguage(bparams);
+       Language const * doc_language = bparams.language;
+       Language const * previous_language = previous()
+               ? previous()->getParLanguage(bparams) : doc_language;
+
+       if (language->babel() != previous_language->babel()
+           // check if we already put language command in TeXEnvironment()
+           && !(style.isEnvironment()
+                && (!previous() || previous()->layout != layout ||
+                        previous()->params().depth() != params().depth())))
+       {
+               if (!lyxrc.language_command_end.empty() &&
+                   previous_language->babel() != doc_language->babel())
+               {
+                       os << subst(lyxrc.language_command_end, "$$lang",
+                                   previous_language->babel())
+                          << endl;
+                       texrow.newline();
+               }
+
+               if (lyxrc.language_command_end.empty() ||
+                   language->babel() != doc_language->babel())
+               {
+                       os << subst(lyxrc.language_command_begin, "$$lang",
+                                   language->babel())
+                          << endl;
+                       texrow.newline();
+               }
        }
 
-       if (further_blank_line){
-               file += '\n';
+       if (bparams.inputenc == "auto" &&
+           language->encoding() != previous_language->encoding()) {
+               os << "\\inputencoding{"
+                  << language->encoding()->LatexName()
+                  << "}" << endl;
                texrow.newline();
        }
 
        switch (style.latextype) {
        case LATEX_COMMAND:
-               file += '\\';
-               file += style.latexname();
-               file += style.latexparam();
+               os << '\\'
+                  << style.latexname()
+                  << style.latexparam();
                break;
        case LATEX_ITEM_ENVIRONMENT:
-               if (bibkey) 
-                       bibkey->Latex(file, false);
-               else
-                       file += "\\item ";
+               if (bibkey) {
+                       bibkey->latex(buf, os, false, false);
+               else
+                       os << "\\item ";
                break;
        case LATEX_LIST_ENVIRONMENT:
-               file += "\\item ";
+               os << "\\item ";
                break;
        default:
                break;
        }
 
-       bool need_par = SimpleTeXOnePar(file, texrow);
+       bool need_par = simpleTeXOnePar(buf, bparams, os, texrow, moving_arg);
  
-       // Spit out footnotes
-       while (par && par->footnoteflag != LyXParagraph::NO_FOOTNOTE
-              && par->footnoteflag != footnoteflag) {
-               par = par->TeXFootnote(file, texrow,
-                                      foot, foot_texrow, foot_count);
-               par->SimpleTeXOnePar(file, texrow);
-               par = par->next;
-       }
-
        // Make sure that \\par is done with the font of the last
        // character if this has another size as the default.
        // This is necessary because LaTeX (and LyX on the screen)
        // calculates the space between the baselines according
        // to this font. (Matthias)
-       LyXFont font = getFont(Last()-1);
-       if (need_par) {
-               if (style.resfont.size() != font.size()) {
-                       file += '\\';
-                       file += font.latexSize();
-                       file += ' ';
-               }
-               file += "\\par}";
-       } else if (textclasslist.Style(GetCurrentTextClass(),
-                                 GetLayout()).isCommand()){
-               if (style.resfont.size() != font.size()) {
-                       file += '\\';
-                       file += font.latexSize();
-                       file += ' ';
-               }
-               file += '}';
-       } else if (style.resfont.size() != font.size()){
-               file += "{\\" + font.latexSize() + " \\par}";
-       }
+       //
+       // Is this really needed ? (Dekel)
+       // We do not need to use to change the font for the last paragraph
+       // or for a command.
+       LyXFont const font =
+               (size() == 0
+                ? getLayoutFont(bparams) : getFont(bparams, size() - 1));
+
+       bool is_command = style.isCommand();
        
+       if (style.resfont.size() != font.size() && next_ && !is_command) {
+               if (!need_par)
+                       os << "{";
+               os << "\\" << font.latexSize() << " \\par}";
+       } else if (need_par) {
+               os << "\\par}";
+       } else if (is_command)
+               os << "}";
+
        switch (style.latextype) {
        case LATEX_ITEM_ENVIRONMENT:
        case LATEX_LIST_ENVIRONMENT:
-                if (par && (depth < par->depth)) {
-                        file += '\n';
-                        texrow.newline();
-                }
+               if (next_ && (params().depth() < next_->params().depth())) {
+                       os << '\n';
+                       texrow.newline();
+               }
                break;
        case LATEX_ENVIRONMENT:
                // if its the last paragraph of the current environment
                // skip it otherwise fall through
-               if (par
-                   && (par->layout != layout
-                       || par->depth != depth
-                       || par->pextra_type != pextra_type))
+               if (next_
+                   && (next_->layout != layout
+                       || next_->params().depth() != params().depth()))
                        break;
+               // fall through possible
        default:
-               if (!(footnoteflag != LyXParagraph::NO_FOOTNOTE
-                     && footnotekind != LyXParagraph::FOOTNOTE
-                     && footnotekind != LyXParagraph::MARGIN
-                     && (table
-                         || (par
-                             && par->table)))) {
-                       // don't insert this if we would be adding it
-                       // before or after a table in a float.  This 
-                       // little trick is needed in order to allow
-                       // use of tables in \subfigures or \subtables.
-                       file += '\n';
+               // we don't need it for the last paragraph!!!
+               if (next_) {
+                       os << '\n';
                        texrow.newline();
                }
        }
        
-       further_blank_line = false;
-       if (line_bottom) {
-               file += "\\lyxline{\\" + getFont(Last()-1).latexSize() + '}';
-               further_blank_line = true;
-       }
+       if ((in == 0) || !in->forceDefaultParagraphs(in)) {
+               further_blank_line = false;
+               if (params().lineBottom()) {
+                       os << "\\lyxline{\\" << font.latexSize() << '}';
+                       further_blank_line = true;
+               }
 
-       if (added_space_bottom.kind() != VSpace::NONE) {
-               file += added_space_bottom.asLatexCommand();
-               further_blank_line = true;
-       }
-      
-       if (pagebreak_bottom) {
-               file += "\\newpage";
-               further_blank_line = true;
-       }
+               if (params().spaceBottom().kind() != VSpace::NONE) {
+                       os << params().spaceBottom().asLatexCommand(bparams);
+                       further_blank_line = true;
+               }
 
-       if (further_blank_line){
-               file += '\n';
-               texrow.newline();
-       }
+               if (params().pagebreakBottom()) {
+                       os << "\\newpage";
+                       further_blank_line = true;
+               }
+
+               if (further_blank_line){
+                       os << '\n';
+                       texrow.newline();
+               }
 
-       if (!(footnoteflag != LyXParagraph::NO_FOOTNOTE && par &&
-              par->footnoteflag == LyXParagraph::NO_FOOTNOTE)) {
-               file += '\n';
+               if (!params().spacing().isDefault()
+                       && (!next_ || !next_->hasSameLayout(this))) {
+                       os << params().spacing().writeEnvirEnd() << "\n";
+                       texrow.newline();
+               }
+       }
+       
+       // we don't need it for the last paragraph!!!
+       if (next_) {
+               os << '\n';
                texrow.newline();
+       } else {
+               // Since \selectlanguage write the language to the aux file,
+               // we need to reset the language at the end of footnote or
+               // float.
+
+               if (language->babel() != doc_language->babel()) {
+                       if (lyxrc.language_command_end.empty())
+                               os << subst(lyxrc.language_command_begin,
+                                           "$$lang",
+                                           doc_language->babel())
+                                  << endl;
+                       else
+                               os << subst(lyxrc.language_command_end,
+                                           "$$lang",
+                                           language->babel())
+                                  << endl;
+                       texrow.newline();
+               }
        }
 
-       lyxerr[Debug::LATEX] << "TeXOnePar...done " << par << endl;
-       return par;
+       lyxerr[Debug::LATEX] << "TeXOnePar...done " << next_ << endl;
+       return next_;
 }
 
 
 // This one spits out the text of the paragraph
-bool LyXParagraph::SimpleTeXOnePar(string & file, TexRow & texrow)
+bool Paragraph::simpleTeXOnePar(Buffer const * buf,
+                                BufferParams const & bparams,
+                                ostream & os, TexRow & texrow,
+                                bool moving_arg)
 {
        lyxerr[Debug::LATEX] << "SimpleTeXOnePar...     " << this << endl;
 
-       if (table)
-               return SimpleTeXOneTablePar(file, texrow);
-
-       char c;
-#ifdef NEW_TEXT
-       size_type main_body;
-#else
-       int main_body;
-#endif
-       
        bool return_value = false;
 
-       LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(), GetLayout());
+       LyXLayout style;
+       
+       // well we have to check if we are in an inset with unlimited
+       // lenght (all in one row) if that is true then we don't allow
+       // any special options in the paragraph and also we don't allow
+       // any environment other then "Standard" to be valid!
+       bool asdefault =
+               (inInset() && inInset()->forceDefaultParagraphs(inInset()));
+
+       if (asdefault) {
+               style = textclasslist.Style(bparams.textclass, 0);
+       } else {
+               style = textclasslist.Style(bparams.textclass, layout);
+       }
+       
        LyXFont basefont;
 
-       /* maybe we have to create a optional argument */ 
+       // Maybe we have to create a optional argument.
+       pos_type main_body;
        if (style.labeltype != LABEL_MANUAL)
                main_body = 0;
        else
-               main_body = BeginningOfMainBody();
+               main_body = beginningOfMainBody();
+
+       int column = 0;
 
        if (main_body > 0) {
-               file += '[';
-               basefont = getFont(-2); // Get label font
+               os << '[';
+               ++column;
+               basefont = getLabelFont(bparams);
        } else {
-               basefont = getFont(-1); // Get layout font
+               basefont = getLayoutFont(bparams);
        }
 
-       int column = 0;
-
-       if (main_body >= 0
-#ifdef NEW_TEXT
-           && !text.size()
-#else
-           && !last
-#endif
-           && !IsDummy()) {
+       if (main_body >= 0 && !pimpl_->size()) {
                if (style.isCommand()) {
-                       file += '{';
-                       column++;
-               } else if (align != LYX_ALIGN_LAYOUT) {
-                       file += '{';
-                       column++;
-                       return_value = true;
+                       os << '{';
+                       ++column;
                }
        }
+
+       moving_arg |= style.needprotect;
  
        // Which font is currently active?
-       LyXFont running_font = basefont;
+       LyXFont running_font(basefont);
        // Do we have an open font change?
        bool open_font = false;
 
        texrow.start(this, 0);
 
-#ifdef NEW_TEXT
-       for (size_type i = 0; i < size(); ++i) {
-#else
-       for (int i = 0; i < last; ++i) {
-#endif
-               column++;
+       for (pos_type i = 0; i < size(); ++i) {
+               ++column;
                // First char in paragraph or after label?
-               if (i == main_body && !IsDummy()) {
+               if (i == main_body) {
                        if (main_body > 0) {
                                if (open_font) {
-                                       column += running_font.latexWriteEndChanges(file, basefont);
+                                       column += running_font.latexWriteEndChanges(os, basefont, basefont);
                                        open_font = false;
                                }
-                               basefont = getFont(-1); // Now use the layout font
+                               basefont = getLayoutFont(bparams);
                                running_font = basefont;
-                               file += ']';
-                               column++;
+                               os << ']';
+                               ++column;
                        }
                        if (style.isCommand()) {
-                               file += '{';
-                               column++;
-                       } else if (align != LYX_ALIGN_LAYOUT) {
-                               file += "{\\par";
-                               column += 4;
-                               return_value = true;
+                               os << '{';
+                               ++column;
                        }
 
-                       if (noindent) {
-                               file += "\\noindent ";
-                               column += 10;
-                       }
-                       switch (align) {
-                       case LYX_ALIGN_NONE:
-                       case LYX_ALIGN_BLOCK:
-                       case LYX_ALIGN_LAYOUT:
-                       case LYX_ALIGN_SPECIAL: break;
-                       case LYX_ALIGN_LEFT:
-                               file += "\\raggedright ";
-                               column+=13;
-                               break;
-                       case LYX_ALIGN_RIGHT:
-                               file += "\\raggedleft ";
-                               column+=12;
-                               break;
-                       case LYX_ALIGN_CENTER:
-                               file += "\\centering ";
-                               column+=11;
-                               break;
-                       }        
-               }
-
-               c = GetChar(i);
-
-               // Fully instantiated font
-               LyXFont font = getFont(i);
-
-               // Spaces at end of font change are simulated to be
-               // outside font change, i.e. we write "\textXX{text} "
-               // rather than "\textXX{text }". (Asger)
-#ifdef NEW_TEXT
-               if (open_font && c == ' ' && i <= size() - 2 
-                   && !getFont(i+1).equalExceptLatex(running_font) 
-                   && !getFont(i+1).equalExceptLatex(font)) {
-                       font = getFont(i+1);
+                       if (!asdefault) {
+                               if (params().noindent()) {
+                                       os << "\\noindent ";
+                                       column += 10;
+                               }
+                       
+                               switch (params().align()) {
+                               case LYX_ALIGN_NONE:
+                               case LYX_ALIGN_BLOCK:
+                               case LYX_ALIGN_LAYOUT:
+                               case LYX_ALIGN_SPECIAL:
+                                       break;
+                               case LYX_ALIGN_LEFT:
+                                       if (getParLanguage(bparams)->babel() != "hebrew") {
+                                               os << "\\begin{flushleft}";
+                                               column += 17;
+                                       } else {
+                                               os << "\\begin{flushright}";
+                                               column += 18;
+                                       }
+                                       break;
+                               case LYX_ALIGN_RIGHT:
+                                       if (getParLanguage(bparams)->babel() != "hebrew") {
+                                               os << "\\begin{flushright}";
+                                               column += 18;
+                                       } else {
+                                               os << "\\begin{flushleft}";
+                                               column += 17;
+                                       }
+                                       break;
+                               case LYX_ALIGN_CENTER:
+                                       os << "\\begin{center}";
+                                       column += 14;
+                                       break;
+                               }
+                       }
                }
-#else
-               if (open_font && c == ' ' && i <= last-2 
-                   && !getFont(i+1).equalExceptLatex(running_font) 
-                   && !getFont(i+1).equalExceptLatex(font)) {
-                       font = getFont(i+1);
+
+               value_type c = getChar(i);
+
+               // Fully instantiated font
+               LyXFont font = getFont(bparams, i);
+
+               LyXFont const last_font = running_font;
+
+               // Spaces at end of font change are simulated to be
+               // outside font change, i.e. we write "\textXX{text} "
+               // rather than "\textXX{text }". (Asger)
+               if (open_font && c == ' ' && i <= size() - 2) {
+                       LyXFont const next_font = getFont(bparams, i + 1);
+                       if (next_font != running_font
+                           && next_font != font) {
+                               font = next_font;
+                       }
                }
-#endif
+               
                // We end font definition before blanks
-               if (!font.equalExceptLatex(running_font) && open_font) {
-                       column += running_font.latexWriteEndChanges(file, basefont);
+               if (font != running_font && open_font) {
+                       column += running_font.latexWriteEndChanges(os,
+                                                                   basefont,
+                                                                   (i == main_body-1) ? basefont : font);
                        running_font = basefont;
                        open_font = false;
                }
 
                // Blanks are printed before start of fontswitch
-               if (c == ' '){
+               if (c == ' ') {
                        // Do not print the separation of the optional argument
                        if (i != main_body - 1) {
-                               SimpleTeXBlanks(file, texrow, i, column, font, style);
+                               pimpl_->simpleTeXBlanks(os, texrow, i,
+                                                      column, font, style);
                        }
                }
 
                // Do we need to change font?
-               if (!font.equalExceptLatex(running_font)
-                   && i != main_body-1) {
-                       column += font.latexWriteStartChanges(file, basefont);
+               if (font != running_font && i != main_body - 1) {
+                       column += font.latexWriteStartChanges(os, basefont,
+                                                             last_font);
                        running_font = font;
                        open_font = true;
                }
 
-               if (c == LYX_META_NEWLINE) {
+               if (c == Paragraph::META_NEWLINE) {
                        // newlines are handled differently here than
                        // the default in SimpleTeXSpecialChars().
-                       if (!style.newline_allowed
-                           || font.latex() == LyXFont::ON) {
-                               file += '\n';
+                       if (!style.newline_allowed) {
+                               os << '\n';
                        } else {
                                if (open_font) {
-                                       column += running_font.latexWriteEndChanges(file, basefont);
+                                       column += running_font.latexWriteEndChanges(os, basefont, basefont);
                                        open_font = false;
                                }
-                               basefont = getFont(-1);
+                               basefont = getLayoutFont(bparams);
                                running_font = basefont;
                                if (font.family() == 
                                    LyXFont::TYPEWRITER_FAMILY) {
-                                       file += "~";
+                                       os << "~";
                                }
-                               file += "\\\\\n";
+                               if (moving_arg)
+                                       os << "\\protect ";
+                               os << "\\\\\n";
                        }
                        texrow.newline();
-                       texrow.start(this, i+1);
+                       texrow.start(this, i + 1);
                        column = 0;
                } else {
-                       SimpleTeXSpecialChars(file, texrow,
-                                             font, running_font, basefont,
-                                             open_font, style, i, column, c);
+                       pimpl_->simpleTeXSpecialChars(buf, bparams,
+                                                     os, texrow, moving_arg,
+                                                     font, running_font, 
+                                                     basefont, open_font, 
+                                                     style, i, column, c);
                }
        }
 
        // If we have an open font definition, we have to close it
        if (open_font) {
-               running_font.latexWriteEndChanges(file, basefont);
+#ifdef FIXED_LANGUAGE_END_DETECTION
+               if (next_) {
+                       running_font
+                               .latexWriteEndChanges(os, basefont,
+                                                     next_->getFont(bparams,
+                                                     0));
+               } else {
+                       running_font.latexWriteEndChanges(os, basefont,
+                                                         basefont);
+               }
+#else
+#ifdef WITH_WARNINGS
+//#warning For now we ALWAYS have to close the foreign font settings if they are
+//#warning there as we start another \selectlanguage with the next paragraph if
+//#warning we are in need of this. This should be fixed sometime (Jug)
+#endif
+               running_font.latexWriteEndChanges(os, basefont,  basefont);
+#endif
        }
 
-#ifdef NEW_TEXT
-       /* needed if there is an optional argument but no contents */ 
+       // Needed if there is an optional argument but no contents.
        if (main_body > 0 && main_body == size()) {
-               file += "]~";
-               return_value = false;
-       }
-#else
-       /* needed if there is an optional argument but no contents */ 
-       if (main_body > 0 && main_body == last) {
-               file += "]~";
+               os << "]~";
                return_value = false;
        }
-#endif
-       lyxerr[Debug::LATEX] << "SimpleTeXOnePar...done " << this << endl;
-       return return_value;
-}
-
-
-// This one spits out the text of a table paragraph
-bool LyXParagraph::SimpleTeXOneTablePar(string & file, TexRow & texrow)
-{
-       lyxerr[Debug::LATEX] << "SimpleTeXOneTablePar...     " << this << endl;
-       char c;
-       int tmp;
-   
-       bool return_value = false;
-       int current_cell_number = -1;
 
-       LyXLayout const & style =
-               textclasslist.Style(GetCurrentTextClass(), GetLayout());
-       LyXFont basefont = getFont(-1); // Get layout font
-       // Which font is currently active?
-       LyXFont running_font = basefont;
-       // Do we have an open font change?
-       bool open_font = false;
-       int column = 0;
-       if (!IsDummy()) { // it is dummy if it is in a float!!!
-               if (style.isCommand()) {
-                       file += '{';
-                       column++;
-               } else if (align != LYX_ALIGN_LAYOUT) {
-                       file += '{';
-                       column++;
-                       return_value = true;
-               }
-               if (noindent) {
-                       file += "\\noindent ";
-                       column += 10;
-               }
-               switch (align) {
+       if (!asdefault) {
+               switch (params().align()) {
                case LYX_ALIGN_NONE:
                case LYX_ALIGN_BLOCK:
                case LYX_ALIGN_LAYOUT:
-               case LYX_ALIGN_SPECIAL: break;
+               case LYX_ALIGN_SPECIAL:
+                       break;
                case LYX_ALIGN_LEFT:
-                       file += "\\raggedright ";
-                       column+=13;
+                       if (getParLanguage(bparams)->babel() != "hebrew") {
+                               os << "\\end{flushleft}";
+                               column+= 15;
+                       } else {
+                               os << "\\end{flushright}";
+                               column+= 16;
+                       }
                        break;
                case LYX_ALIGN_RIGHT:
-                       file += "\\raggedleft ";
-                       column+=12;
+                       if (getParLanguage(bparams)->babel() != "hebrew") {
+                               os << "\\end{flushright}";
+                               column+= 16;
+                       } else {
+                               os << "\\end{flushleft}";
+                               column+= 15;
+                       }
                        break;
                case LYX_ALIGN_CENTER:
-                       file += "\\centering ";
-                       column+=11;
+                       os << "\\end{center}";
+                       column+= 12;
                        break;
                }
        }
-       current_cell_number = -1;
-       tmp = table->TexEndOfCell(file,current_cell_number);
-       for (; tmp >0 ; --tmp)
-               texrow.newline();
-       
-       texrow.start(this, 0);
-
-#ifdef NEW_TEXT
-       for (size_type i = 0; i < size(); ++i) {
-#else
-       for (int i = 0; i < last; ++i) {
-#endif
-               c = GetChar(i);
-               if (table->IsContRow(current_cell_number+1)) {
-                       if (c == LYX_META_NEWLINE)
-                               current_cell_number++;
-                       continue;
-               }
-               column++;
-               
-               // Fully instantiated font
-               LyXFont font = getFont(i);
-
-               // Spaces at end of font change are simulated to be outside font change.
-               // i.e. we write "\textXX{text} " rather than "\textXX{text }". (Asger)
-#ifdef NEW_TEXT
-               if (open_font && c == ' ' && i <= size() - 2
-#else
-               if (open_font && c == ' ' && i <= last-2
-#endif
-                   && getFont(i+1) != running_font && getFont(i+1) != font) {
-                       font = getFont(i+1);
-               }
-
-               // We end font definition before blanks
-               if (font != running_font && open_font) {
-                       column += running_font.latexWriteEndChanges(file, basefont);
-                       running_font = basefont;
-                       open_font = false;
-               }
-               // Blanks are printed before start of fontswitch
-               if (c == ' '){
-                       SimpleTeXBlanks(file, texrow, i, column, font, style);
-               }
-               // Do we need to change font?
-               if (font != running_font) {
-                       column += font.latexWriteStartChanges(file, basefont);
-                       running_font = font;
-                       open_font = true;
-               }
-               // Do we need to turn on LaTeX mode?
-               if (font.latex() != running_font.latex()) {
-                       if (font.latex() == LyXFont::ON
-                           && style.needprotect) {
-                               file += "\\protect ";
-                               column += 9;
-                       }
-               }
-               if (c == LYX_META_NEWLINE) {
-                       // special case for inside a table
-                       // different from default case in SimpleTeXSpecialChars()
-                       if (open_font) {
-                               column += running_font.latexWriteEndChanges(file, basefont);
-                               open_font = false;
-                       }
-                       basefont = getFont(-1);
-                       running_font = basefont;
-                       current_cell_number++;
-                       if (table->CellHasContRow(current_cell_number) >= 0) {
-                               TeXContTableRows(file, i+1, current_cell_number, column, texrow);
-                       }
-                       // if this cell follow only ContRows till end don't
-                       // put the EndOfCell because it is put after the
-                       // for(...)
-                       if (table->ShouldBeVeryLastCell(current_cell_number)) {
-                            current_cell_number--;
-                            break;
-                       }
-                       int tmp = table->TexEndOfCell(file, current_cell_number);
-                       if (tmp>0) {
-                               column = 0;
-                       } else if (tmp < 0) {
-                               tmp = -tmp;
-                       }
-                       for (;tmp--;) {
-                               texrow.newline();
-                       }
-                       texrow.start(this, i+1);
-               } else {
-                       SimpleTeXSpecialChars(file, texrow,
-                                             font, running_font, basefont,
-                                             open_font, style, i, column, c);
-               }
-       }
-
-       // If we have an open font definition, we have to close it
-       if (open_font) {
-               running_font.latexWriteEndChanges(file, basefont);
-       }
-       current_cell_number++;
-       tmp = table->TexEndOfCell(file, current_cell_number);
-       for (; tmp > 0; --tmp)
-               texrow.newline();
-       lyxerr[Debug::LATEX] << "SimpleTeXOneTablePar...done " << this << endl;
-       return return_value;
-}
-
-
-// This one spits out the text off ContRows in tables
-#ifdef NEW_TEXT
-bool LyXParagraph::TeXContTableRows(string & file,
-                                   LyXParagraph::size_type i,
-                                   int current_cell_number,
-                                   int & column, TexRow & texrow)
-#else
-bool LyXParagraph::TeXContTableRows(string & file, int i,
-                                   int current_cell_number,
-                                   int & column, TexRow & texrow)
-#endif
-{
-       lyxerr[Debug::LATEX] << "TeXContTableRows...     " << this << endl;
-       if (!table)
-               return false;
-    
-       char c;
-   
-       bool return_value = false;
-       LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(), GetLayout());
-       LyXFont basefont;
-
-       basefont = getFont(-1); // Get layout font
-       // Which font is currently active?
-       LyXFont running_font = basefont;
-       // Do we have an open font change?
-       bool open_font = false;
-
-#ifdef NEW_TEXT
-       size_type lastpos = i;
-#else
-       int lastpos = i;
-#endif
-       int cell = table->CellHasContRow(current_cell_number);
-       current_cell_number++;
-       while(cell >= 0) {
-               // first find the right position
-               i = lastpos;
-#ifdef NEW_TEXT
-               for (; (i < size()) && (current_cell_number<cell); ++i) {
-#else
-               for (; (i < last) && (current_cell_number<cell); ++i) {
-#endif
-                       c = GetChar(i);
-                       if (c == LYX_META_NEWLINE)
-                               current_cell_number++;
-               }
-               lastpos = i;
-               c = GetChar(i);
-               if (table->Linebreaks(table->FirstVirtualCell(cell))) {
-                       file += " \\\\\n";
-                       texrow.newline();
-                       column = 0;
-               } else if ((c != ' ') && (c != LYX_META_NEWLINE)) {
-                       file += ' ';
-               }
-#ifdef NEW_TEXT
-               for (; i < size() && (c = GetChar(i)) != LYX_META_NEWLINE;
-                    ++i) {
-#else
-               for (; (i < last) && ((c=GetChar(i)) != LYX_META_NEWLINE);
-                    ++i) {
-#endif
-                       ++column;
-
-                       // Fully instantiated font
-                       LyXFont font = getFont(i);
-
-                       // Spaces at end of font change are simulated to be outside font change.
-                       // i.e. we write "\textXX{text} " rather than "\textXX{text }". (Asger)
-#ifdef NEW_TEXT
-                       if (open_font && c == ' ' && i <= size() - 2 
-                           && getFont(i + 1) != running_font
-                           && getFont(i + 1) != font) {
-#else
-                       if (open_font && c == ' ' && i <= last - 2 
-                           && getFont(i + 1) != running_font
-                           && getFont(i + 1) != font) {
-#endif
-                               font = getFont(i + 1);
-                       }
 
-                       // We end font definition before blanks
-                       if (font != running_font && open_font) {
-                               column += running_font.latexWriteEndChanges(file, basefont);
-                               running_font = basefont;
-                               open_font = false;
-                       }
-                       // Blanks are printed before start of fontswitch
-                       if (c == ' '){
-                               SimpleTeXBlanks(file, texrow, i, column, font, style);
-                       }
-                       // Do we need to change font?
-                       if (font != running_font) {
-                               column += font.latexWriteStartChanges(file, basefont);
-                               running_font = font;
-                               open_font = true;
-                       }
-                       // Do we need to turn on LaTeX mode?
-                       if (font.latex() != running_font.latex()) {
-                               if (font.latex() == LyXFont::ON
-                                   && style.needprotect)
-                                       {
-                                               file += "\\protect ";
-                                               column += 9;
-                                       }
-                       }
-                       SimpleTeXSpecialChars(file, texrow, font, running_font, basefont,
-                                             open_font, style, i, column, c);
-               }
-               // If we have an open font definition, we have to close it
-               if (open_font) {
-                       running_font.latexWriteEndChanges(file, basefont);
-                       open_font = false;
-               }
-               basefont = getFont(-1);
-               running_font = basefont;
-               cell = table->CellHasContRow(current_cell_number);
-       }
-       lyxerr[Debug::LATEX] << "TeXContTableRows...done " << this << endl;
+       lyxerr[Debug::LATEX] << "SimpleTeXOnePar...done " << this << endl;
        return return_value;
 }
 
 
-bool LyXParagraph::linuxDocConvertChar(char c, string & sgml_string)
+bool Paragraph::sgmlConvertChar(char c, string & sgml_string)
 {
        bool retval = false;
        switch (c) {
-       case LYX_META_HFILL:
-               sgml_string.clear();
+       case Paragraph::META_HFILL:
+               sgml_string.erase();
                break;
-       case LYX_META_PROTECTED_SEPARATOR: 
-               sgml_string = ' ';
-               break;
-       case LYX_META_NEWLINE:
+       case Paragraph::META_NEWLINE:
                sgml_string = '\n';
                break;
        case '&': 
@@ -3258,8 +1752,8 @@ bool LyXParagraph::linuxDocConvertChar(char c, string & sgml_string)
                retval = true;
                sgml_string = ' ';
                break;
-       case '\0': /* Ignore :-) */
-               sgml_string.clear();
+       case '\0': // Ignore :-)
+               sgml_string.erase();
                break;
        default:
                sgml_string = c;
@@ -3268,1366 +1762,426 @@ bool LyXParagraph::linuxDocConvertChar(char c, string & sgml_string)
        return retval;
 }
 
-void LyXParagraph::SimpleDocBookOneTablePar(string & file, string & extra,
-                                           int & desc_on, int depth) 
+
+Paragraph * Paragraph::TeXEnvironment(Buffer const * buf,
+                                           BufferParams const & bparams,
+                                           ostream & os, TexRow & texrow)
 {
-       if (!table)
-               return;
-       lyxerr[Debug::LATEX] << "SimpleDocbookOneTablePar... " << this << endl;
-       int column, tmp;
-       int current_cell_number = -1;
-       LyXFont font1,font2;
-       char c;
-       Inset *inset;
-#ifdef NEW_TEXT
-       size_type main_body;
-#else
-       int  main_body;
-#endif
-       string emph = "emphasis";
-       bool emph_flag=false;
-       int char_line_count=0;
-       
-       LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(), GetLayout());
-       
-       if (style.labeltype != LABEL_MANUAL)
-               main_body = 0;
-       else
-               main_body = BeginningOfMainBody();
-       
-       /* gets paragraph main font */
-       if (main_body > 0)
-               font1 = style.labelfont;
-       else
-               font1 = style.font;
-       
-       char_line_count = depth;
-       addNewlineAndDepth(file, depth);
-       if (footnoteflag == LyXParagraph::NO_FOOTNOTE) {
-               file += "<INFORMALTABLE>";
-               addNewlineAndDepth(file, ++depth);
-       }
-       current_cell_number = -1;
-       tmp = table->DocBookEndOfCell(file,current_cell_number, depth);
-       
-       /* parsing main loop */
-#ifdef NEW_TEXT
-       for (size_type i = 0; i < size(); ++i) {
-#else
-       for (int i = 0; i < last; ++i) {
-#endif
-               c = GetChar(i);
-               if (table->IsContRow(current_cell_number+1)) {
-                       if (c == LYX_META_NEWLINE)
-                               current_cell_number++;
-                       continue;
-               }
-               column++;
-               
-               // Fully instantiated font
-               font2 = getFont(i);
-               
-               /* handle <emphasis> tag */
-               if (font1.emph() != font2.emph() && i) {
-                       if (font2.emph() == LyXFont::ON) {
-                               file += "<emphasis>";
-                               emph_flag=true;
-                       } else if (emph_flag) {
-                               file += "</emphasis>";
-                               emph_flag=false;
-                       }
+       lyxerr[Debug::LATEX] << "TeXEnvironment...     " << this << endl;
+
+       LyXLayout const & style =
+               textclasslist.Style(bparams.textclass,
+                                   layout);
+
+       Language const * language = getParLanguage(bparams);
+       Language const * doc_language = bparams.language;
+       Language const * previous_language = previous_
+               ? previous_->getParLanguage(bparams) : doc_language;
+       if (language->babel() != previous_language->babel()) {
+
+               if (!lyxrc.language_command_end.empty() &&
+                   previous_language->babel() != doc_language->babel()) {
+                       os << subst(lyxrc.language_command_end, "$$lang",
+                                   previous_language->babel())
+                          << endl;
+                       texrow.newline();
                }
-               if (c == LYX_META_NEWLINE) {
-                       // we have only to control for emphasis open here!
-                       if (emph_flag) {
-                               file += "</emphasis>";
-                               emph_flag=false;
-                       }
-                       font1 = font2 = getFont(-1);
-                       current_cell_number++;
-                       if (table->CellHasContRow(current_cell_number) >= 0) {
-                               DocBookContTableRows(file, extra, desc_on, i+1,
-                                                    current_cell_number,
-                                                    column);
-                       }
-                       // if this cell follow only ContRows till end don't
-                       // put the EndOfCell because it is put after the
-                       // for(...)
-                       if (table->ShouldBeVeryLastCell(current_cell_number)) {
-                               current_cell_number--;
-                               break;
-                       }
-                       tmp=table->DocBookEndOfCell(file, current_cell_number,
-                                                   depth);
-                       
-                       if (tmp > 0)
-                               column = 0;
-               } else if (c == LYX_META_INSET) {
-                       inset = GetInset(i);
-                       string tmp_out;
-                       inset->DocBook(tmp_out);
-                       //
-                       // This code needs some explanation:
-                       // Two insets are treated specially
-                       //   label if it is the first element in a command paragraph
-                       //         desc_on==3
-                       //   graphics inside tables or figure floats can't go on
-                               //   title (the equivalente in latex for this case is caption
-                       //   and title should come first
-                       //         desc_on==4
-                       //
-                       if(desc_on != 3 || i != 0) {
-                               if(tmp_out[0] == '@') {
-                                       if(desc_on == 4)
-                                               extra += frontStrip(tmp_out, '@');
-                                       else
-                                               file += frontStrip(tmp_out, '@');
-                               } else
-                                       file += tmp_out;
-                       }
-               } else if (font2.latex() == LyXFont::ON) {
-                       // "TeX"-Mode on ==> SGML-Mode on.
-                       if (c != '\0')
-                               file += c;
-                       char_line_count++;
-               } else {
-                       string sgml_string;
-                       if (linuxDocConvertChar(c, sgml_string) 
-                           && !style.free_spacing) {
-                               // in freespacing mode, spaces are
-                               // non-breaking characters
-                               // char is ' '
-                               if (desc_on == 1) {
-                                       char_line_count++;
-                                       file += '\n';
-                                       file += "</term><listitem><para>";
-                                       desc_on = 2;
-                               } else  {
-                                       file += c;
-                               }
-                       } else {
-                               file += sgml_string;
-                       }
+
+               if (lyxrc.language_command_end.empty() ||
+                   language->babel() != doc_language->babel()) {
+                       os << subst(lyxrc.language_command_begin, "$$lang",
+                                   language->babel())
+                          << endl;
+                       texrow.newline();
                }
-               font1 = font2;
-       }
-       
-       /* needed if there is an optional argument but no contents */
-#ifdef NEW_TEXT
-       if (main_body > 0 && main_body == size()) {
-               font1 = style.font;
-       }
-#else
-       if (main_body > 0 && main_body == last) {
-               font1 = style.font;
        }
-#endif
-       if (emph_flag) {
-               file += "</emphasis>";
+
+       if (style.isEnvironment()) {
+               if (style.latextype == LATEX_LIST_ENVIRONMENT) {
+                       os << "\\begin{" << style.latexname() << "}{"
+                          << params().labelWidthString() << "}\n";
+               } else if (style.labeltype == LABEL_BIBLIO) {
+                       // ale970405
+                       os << "\\begin{" << style.latexname() << "}{"
+                          <<  bibitemWidest(buf)
+                          << "}\n";
+               } else if (style.latextype == LATEX_ITEM_ENVIRONMENT) {
+                       os << "\\begin{" << style.latexname() << '}'
+                          << style.latexparam() << '\n';
+               } else 
+                       os << "\\begin{" << style.latexname() << '}'
+                          << style.latexparam() << '\n';
+               texrow.newline();
        }
-       
-       current_cell_number++;
-       tmp = table->DocBookEndOfCell(file, current_cell_number, depth);
-       /* resets description flag correctly */
-       switch(desc_on){
-       case 1:
-               /* <term> not closed... */
-               file += "</term>";
-               break;
+       Paragraph * par = this;
+       do {
+               par = par->TeXOnePar(buf, bparams, os, texrow, false);
+
+               if (par && par->params().depth() > params().depth()) {
+                       if (textclasslist.Style(bparams.textclass,
+                                               par->layout).isParagraph()
+                           // Thinko!
+                           // How to handle this? (Lgb)
+                           //&& !suffixIs(os, "\n\n")
+                               ) {
+                               // There should be at least one '\n' already
+                               // but we need there to be two for Standard 
+                               // paragraphs that are depth-increment'ed to be
+                               // output correctly.  However, tables can
+                               // also be paragraphs so don't adjust them.
+                               // ARRae
+                               // Thinkee:
+                               // Will it ever harm to have one '\n' too
+                               // many? i.e. that we sometimes will have
+                               // three in a row. (Lgb)
+                               os << '\n';
+                               texrow.newline();
+                       }
+                       par = par->pimpl_->TeXDeeper(buf, bparams, os, texrow);
+               }
+       } while (par
+                && par->layout == layout
+                && par->params().depth() == params().depth());
+       if (style.isEnvironment()) {
+               os << "\\end{" << style.latexname() << "}\n";
+               texrow.newline();
        }
-       if (footnoteflag == LyXParagraph::NO_FOOTNOTE)
-               file += "</INFORMALTABLE>";
-       file += '\n';
-       lyxerr[Debug::LATEX] << "SimpleDocbookOneTablePar...done "
-                            << this << endl;
-}
 
-#ifdef NEW_TEXT
-void LyXParagraph::DocBookContTableRows(string & file, string & extra,
-                                        int & desc_on, LyXParagraph::size_type i,
-                                        int current_cell_number, int &column) 
+       lyxerr[Debug::LATEX] << "TeXEnvironment...done " << par << endl;
+       return par;  // ale970302
+}
 
-#else
-void LyXParagraph::DocBookContTableRows(string & file, string & extra,
-                                        int & desc_on, int i,
-                                        int current_cell_number, int &column) 
 
-#endif
+bool Paragraph::isHfill(pos_type pos) const
 {
-       if (!table)
-               return;
-       
-       lyxerr[Debug::LATEX] << "DocBookContTableRows... " << this << endl;
-
-       int cell;
-       LyXFont font1,font2;
-       char c;
-       Inset * inset;
-#ifdef NEW_TEXT
-       size_type main_body;
-       size_type lastpos;
-#else
-       int main_body;
-       int lastpos;
-#endif
-       string emph="emphasis";
-       bool emph_flag=false;
-       int char_line_count=0;
-       
-       LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(), GetLayout());
-       
-       if (style.labeltype != LABEL_MANUAL)
-               main_body = 0;
-       else
-               main_body = BeginningOfMainBody();
-       
-       /* gets paragraph main font */
-       if (main_body > 0)
-               font1 = style.labelfont;
-       else
-               font1 = style.font;
-       
-       lastpos = i;
-       cell = table->CellHasContRow(current_cell_number);
-       current_cell_number++;
-       while(cell >= 0) {
-               // first find the right position
-               i = lastpos;
-#ifdef NEW_TEXT
-               for (; i < size() && current_cell_number < cell; ++i) {
-#else
-               for (; i < last && (current_cell_number < cell); ++i) {
-#endif
-                       c = GetChar(i);
-                       if (c == LYX_META_NEWLINE)
-                               current_cell_number++;
-               }
-               lastpos = i;
-               c = GetChar(i);
-               // I don't know how to handle this so I comment it
-                // for the moment (Jug)
-//             if (table->Linebreaks(table->FirstVirtualCell(cell))) {
-//                     file += " \\\\\n";
-//                     column = 0;
-//             } else
-               if ((c != ' ') && (c != LYX_META_NEWLINE)) {
-                       file += ' ';
-               }
-#ifdef NEW_TEXT
-               for (; i < size() && (c = GetChar(i)) != LYX_META_NEWLINE;
-                    ++i) {
-#else
-               for (; i < last && ((c = GetChar(i)) != LYX_META_NEWLINE);
-                    ++i) {
-#endif
-                       ++column;
-                       
-                       // Fully instantiated font
-                       font2 = getFont(i);
-                       
-                       /* handle <emphasis> tag */
-                       if (font1.emph() != font2.emph() && i) {
-                               if (font2.emph() == LyXFont::ON) {
-                                       file += "<emphasis>";
-                                       emph_flag=true;
-                               } else if (emph_flag) {
-                                       file += "</emphasis>";
-                                       emph_flag=false;
-                               }
-                       }
-                       if (c == LYX_META_INSET) {
-                               inset = GetInset(i);
-                               string tmp_out;
-                               inset->DocBook(tmp_out);
-                               //
-                               // This code needs some explanation:
-                               // Two insets are treated specially
-                               //   label if it is the first element in a command paragraph
-                               //       desc_on==3
-                               //   graphics inside tables or figure floats can't go on
-                               //   title (the equivalente in latex for this case is caption
-                               //   and title should come first
-                               //       desc_on==4
-                               //
-                               if(desc_on != 3 || i != 0) {
-                                       if(tmp_out[0]=='@') {
-                                               if(desc_on == 4)
-                                                       extra += frontStrip(tmp_out, '@');
-                                               else
-                                                       file += frontStrip(tmp_out, '@');
-                                       } else
-                                               file += tmp_out;
-                               }
-                       } else if (font2.latex() == LyXFont::ON) {
-                               // "TeX"-Mode on ==> SGML-Mode on.
-                               if (c!='\0')
-                                       file += c;
-                               char_line_count++;
-                       } else {
-                               string sgml_string;
-                               if (linuxDocConvertChar(c, sgml_string) 
-                                   && !style.free_spacing) {
-                               // in freespacing mode, spaces are
-                               // non-breaking characters
-                               // char is ' '
-                                       if (desc_on == 1) {
-                                               char_line_count++;
-                                               file += '\n';
-                                               file += "</term><listitem><para>";
-                                               desc_on = 2;
-                                       } else  {
-                                               file += c;
-                                       }
-                               } else {
-                                       file += sgml_string;
-                               }
-                       }
-               }
-               // we have only to control for emphasis open here!
-               if (emph_flag) {
-                       file += "</emphasis>";
-                       emph_flag=false;
-               }
-               font1 = font2 = getFont(-1);
-               cell = table->CellHasContRow(current_cell_number);
-       }
-       lyxerr[Debug::LATEX] << "DocBookContTableRows...done " << this << endl;
+       return IsHfillChar(getChar(pos));
 }
 
-#ifdef NEW_TEXT
-void LyXParagraph::SimpleTeXBlanks(string & file, TexRow & texrow,
-                                  LyXParagraph::size_type const i, int & column, LyXFont const & font,
-                                  LyXLayout const & style)
-#else
-void LyXParagraph::SimpleTeXBlanks(string & file, TexRow & texrow,
-                                  int const i, int & column, LyXFont const & font,
-                                  LyXLayout const & style)
-#endif
+
+bool Paragraph::isInset(pos_type pos) const
 {
-       if (column > tex_code_break_column
-           && i 
-           && GetChar(i - 1) != ' '
-#ifdef NEW_TEXT
-           && (i < size() - 1)
-#else
-           && (i < last-1)
-#endif
-           // In LaTeX mode, we don't want to
-           // break lines since some commands
-           // do not like this
-           && ! (font.latex() == LyXFont::ON)
-           // same in FreeSpacing mode
-           && !style.free_spacing
-           // In typewriter mode, we want to avoid 
-           // ! . ? : at the end of a line
-           && !(font.family() == LyXFont::TYPEWRITER_FAMILY
-                && (GetChar(i-1) == '.'
-                    || GetChar(i-1) == '?' 
-                    || GetChar(i-1) == ':'
-                    || GetChar(i-1) == '!'))) {
-               if (tex_code_break_column == 0) {
-                       // in batchmode we need LaTeX to still
-                       // see it as a space not as an extra '\n'
-                       file += " %\n";
-               } else {
-                       file += '\n';
-               }
-               texrow.newline();
-               texrow.start(this, i+1);
-               column = 0;
-       } else if (font.latex() == LyXFont::OFF) {
-               if (style.free_spacing) {
-                       file += '~';
-               } else {
-                       file += ' ';
-               }
-       }
+       return IsInsetChar(getChar(pos));
 }
 
 
-#ifdef NEW_TEXT
-void LyXParagraph::SimpleTeXSpecialChars(string & file, TexRow & texrow,
-                                        LyXFont & font, LyXFont & running_font,
-                                        LyXFont & basefont,
-                                        bool & open_font,
-                                        LyXLayout const & style,
-                                        LyXParagraph::size_type & i, int &column, char const c)
-#else 
-void LyXParagraph::SimpleTeXSpecialChars(string & file, TexRow & texrow,
-                                        LyXFont & font, LyXFont & running_font,
-                                        LyXFont & basefont,
-                                        bool & open_font,
-                                        LyXLayout const & style,
-                                        int & i, int &column, char const c)
-#endif
+bool Paragraph::isNewline(pos_type pos) const
 {
-       // Two major modes:  LaTeX or plain
-       // Handle here those cases common to both modes
-       // and then split to handle the two modes separately.
-       switch (c) {
-       case LYX_META_INSET: {
-               Inset * inset = GetInset(i);
-               if (inset) {
-                       int len = file.length();
-                       int tmp = inset->Latex(file, style.isCommand());
-                       
-                       if (tmp) {
-                               column = 0;
-                       } else {
-                               column += file.length() - len;
-                       }
-                       for (;tmp--;) {
-                               texrow.newline();
-                       }
-               }
-       }
-       break;
+       return pos >= 0 && IsNewlineChar(getChar(pos));
+}
 
-       case LYX_META_NEWLINE:
-               if (open_font) {
-                       column += running_font.latexWriteEndChanges(file, basefont);
-                       open_font = false;
-               }
-               basefont = getFont(-1);
-               running_font = basefont;
-               break;
 
-       case LYX_META_HFILL: 
-               file += "\\hfill{}";
-               column += 7;
-               break;
+bool Paragraph::isSeparator(pos_type pos) const
+{
+       return IsSeparatorChar(getChar(pos));
+}
 
-       default:
-               // And now for the special cases within each mode
-               // Are we in LaTeX mode?
-               if (font.latex() == LyXFont::ON) {
-                       // at present we only have one option
-                       // but I'll leave it as a switch statement
-                       // so its simpler to extend. (ARRae)
-                       switch (c) {
-                       case LYX_META_PROTECTED_SEPARATOR: 
-                               file += ' ';
-                               break;
-
-                       default:
-                               // make sure that we will not print
-                               // error generating chars to the tex
-                               // file. This test would not be needed
-                               // if it were done in the buffer
-                               // itself.
-                               if (c != '\0') {
-                                       file += c;
-                               }
-                               break;
-                       }
-               } else {
-                       // Plain mode (i.e. not LaTeX)
-                       switch (c) {
-                       case LYX_META_PROTECTED_SEPARATOR: 
-                               file += '~';
-                               break;
-
-                       case '\\': 
-                               file += "\\textbackslash{}";
-                               column += 15;
-                               break;
-               
-                       case '°': case '±': case '²': case '³':  
-                       case '×': case '÷': case '¹': case 'ª':
-                       case 'º': case '¬': case 'µ':
-                               if (current_view->currentBuffer()->params.inputenc == "latin1") {
-                                       file += "\\ensuremath{";
-                                       file += c;
-                                       file += '}';
-                                       column += 13;
-                               } else {
-                                       file += c;
-                               }
-                               break;
-
-                       case '|': case '<': case '>':
-                               // In T1 encoding, these characters exist
-                               if (lyxrc->fontenc == "T1") {
-                                       file += c;
-                                       //... but we should avoid ligatures
-                                       if ((c == '>' || c == '<')
-#ifdef NEW_TEXT
-                                           && i <= size() - 2
-#else
-                                           && i <= last - 2
-#endif
-                                           && GetChar(i+1) == c){
-                                               file += "\\textcompwordmark{}";
-                                               column += 19;
-                                       }
-                                       break;
-                               }
-                               // Typewriter font also has them
-                               if (font.family() == LyXFont::TYPEWRITER_FAMILY) {
-                                       file += c;
-                                       break;
-                               } 
-                               // Otherwise, we use what LaTeX
-                               // provides us.
-                               switch(c) {
-                               case '<':
-                                       file += "\\textless{}";
-                                       column += 10;
-                                       break;
-                               case '>':
-                                       file += "\\textgreater{}";
-                                       column += 13;
-                                       break;
-                               case '|':
-                                       file += "\\textbar{}";
-                                       column += 9;
-                                       break;
-                               }
-                               break;
 
-                       case '-': // "--" in Typewriter mode -> "-{}-"
-#ifdef NEW_TEXT
-                               if (i <= size() - 2
-#else
-                               if (i <= last - 2
-#endif
-                                   && GetChar(i + 1) == '-'
-                                   && font.family() == LyXFont::TYPEWRITER_FAMILY) {
-                                       file += "-{}";
-                                       column += 2;
-                               } else {
-                                       file += '-';
-                               }
-                               break;
+bool Paragraph::isLineSeparator(pos_type pos) const
+{
+       return IsLineSeparatorChar(getChar(pos));
+}
 
-                       case '\"': 
-                               file += "\\char`\\\"{}";
-                               column += 9;
-                               break;
 
-                       case '£':
-                               if (current_view->currentBuffer()->params.inputenc == "default") {
-                                       file += "\\pounds{}";
-                                       column += 8;
-                               } else {
-                                       file += c;
-                               }
-                               break;
-
-                       case '$': case '&':
-                       case '%': case '#': case '{':
-                       case '}': case '_':
-                               file += '\\';
-                               file += c;
-                               column += 1;
-                               break;
-
-                       case '^': case '~':
-                               file += '\\';
-                               file += c;
-                               file += "{}";
-                               column += 3;
-                               break;
-
-                       case '*': case '[': case ']':
-                               // avoid being mistaken for optional arguments
-                               file += '{';
-                               file += c;
-                               file += '}';
-                               column += 2;
-                               break;
-
-                       case ' ':
-                               /* blanks are printed before font switching */
-                               // Sure? I am not! (try nice-latex)
-                               // I am sure it's correct. LyX might be smarter
-                               // in the future, but for now, nothing wrong is
-                               // written. (Asger)
-                               break;
-
-                       default:
-                               /* idea for labels --- begin*/
-                               /* check for LyX */
-                               if (c ==  'L'
-#ifdef NEW_TEXT
-                                   && i <= size() - 3
-#else
-                                   && i <= last - 3
-#endif
-                                   && font.family() != LyXFont::TYPEWRITER_FAMILY
-                                   && GetChar(i + 1) == 'y'
-                                   && GetChar(i + 2) == 'X') {
-                                       file += "\\LyX{}";
-                                       i += 2;
-                                       column += 5;
-                               }
-                               /* check for TeX */ 
-                               else if (c == 'T'
-#ifdef NEW_TEXT
-                                        && i <= size() - 3
-#else
-                                        && i <= last-3
-#endif
-                                        && font.family() != LyXFont::TYPEWRITER_FAMILY
-                                        && GetChar(i + 1) == 'e'
-                                        && GetChar(i + 2) == 'X') {
-                                       file += "\\TeX{}";
-                                       i += 2;
-                                       column += 5;
-                               }
-                               /* check for LaTeX2e */ 
-                               else if (c == 'L'
-#ifdef NEW_TEXT
-                                        && i <= size() - 7
-#else
-                                        && i <= last-7
-#endif
-                                        && font.family() != LyXFont::TYPEWRITER_FAMILY
-                                        && GetChar(i + 1) == 'a'
-                                        && GetChar(i + 2) == 'T'
-                                        && GetChar(i + 3) == 'e'
-                                        && GetChar(i + 4) == 'X'
-                                        && GetChar(i + 5) == '2'
-                                        && GetChar(i + 6) == 'e') {
-                                       file += "\\LaTeXe{}";
-                                       i += 6;
-                                       column += 8;
-                               }
-                               /* check for LaTeX */ 
-                               else if (c == 'L'
-#ifdef NEW_TEXT
-                                        && i <= size() - 5
+bool Paragraph::isKomma(pos_type pos) const
+{
+       return IsKommaChar(getChar(pos));
+}
+
+
+/// Used by the spellchecker
+bool Paragraph::isLetter(pos_type pos) const
+{
+       value_type const c = getChar(pos);
+       if (IsLetterChar(c))
+               return true;
+       if (isInset(pos)) 
+               return getInset(pos)->isLetter();
+       // We want to pass the ' and escape chars to ispell
+       string const extra = lyxrc.isp_esc_chars + '\'';
+       return contains(extra, c);
+}
+bool Paragraph::isWord(pos_type pos ) const
+{
+       return IsWordChar(getChar(pos)) ;
+}
+
+
+Language const *
+Paragraph::getParLanguage(BufferParams const & bparams) const 
+{
+       if (size() > 0) {
+#ifndef INHERIT_LANGUAGE
+               return getFirstFontSettings().language();
 #else
-                                        && i <= last - 5
+               Language const * lang = getFirstFontSettings().language();
+#warning We should make this somewhat better, any ideas? (Jug)
+               if (lang == inherit_language || lang == ignore_language)
+                       lang = bparams.language;
+               return lang;
 #endif
-                                        && font.family() != LyXFont::TYPEWRITER_FAMILY
-                                        && GetChar(i + 1) == 'a'
-                                        && GetChar(i + 2) == 'T'
-                                        && GetChar(i + 3) == 'e'
-                                        && GetChar(i + 4) == 'X') {
-                                       file += "\\LaTeX{}";
-                                       i += 4;
-                                       column += 7;
-                                       /* idea for labels --- end*/ 
-                               } else if (c != '\0') {
-                                       file += c;
-                               }
-                               break;
-                       }
+       } else if (previous_)
+               return previous_->getParLanguage(bparams);
+       else
+               return bparams.language;
+}
+
+
+bool Paragraph::isRightToLeftPar(BufferParams const & bparams) const
+{
+       return lyxrc.rtl_support
+               && getParLanguage(bparams)->RightToLeft();
+}
+
+
+void Paragraph::changeLanguage(BufferParams const & bparams,
+                                 Language const * from, Language const * to)
+{
+       for (pos_type i = 0; i < size(); ++i) {
+               LyXFont font = getFontSettings(bparams, i);
+               if (font.language() == from) {
+                       font.setLanguage(to);
+                       setFont(i, font);
                }
        }
 }
 
-#ifdef NEW_TEXT
-bool LyXParagraph::RoffContTableRows(FILE * fp,
-                                    LyXParagraph::size_type i,
-                                    int actcell)
-#else
-bool LyXParagraph::RoffContTableRows(FILE * fp, int i, int actcell)
-#endif
+
+bool Paragraph::isMultiLingual(BufferParams const & bparams)
 {
-       if (!table)
-               return false;
-
-       LyXFont font1 = LyXFont(LyXFont::ALL_INHERIT);
-       LyXFont font2;
-       Inset * inset;
-       char c;
-       FILE * fp2;
-
-       string fname2 = TmpFileName(string(), "RAT2");
-       int lastpos = i;
-       int cell = table->CellHasContRow(actcell);
-       actcell++;
-       while(cell >= 0) {
-               // first find the right position
-               i = lastpos;
-#ifdef NEW_TEXT
-               for (; i < size() && actcell < cell; ++i) {
-#else
-               for (; i < last && actcell < cell; ++i) {
+       Language const * doc_language = bparams.language;
+       for (Pimpl::FontList::const_iterator cit = pimpl_->fontlist.begin();
+            cit != pimpl_->fontlist.end(); ++cit)
+               if (cit->font().language() != ignore_language &&
+                   cit->font().language() != latex_language &&
+#ifdef INHERIT_LANGUAGE
+                       cit->font().language() != inherit_language &&
 #endif
-                       c = GetChar(i);
-                       if (c == LYX_META_NEWLINE)
-                               actcell++;
-               }
-               lastpos = i;
-               c = GetChar(i);
-               if ((c != ' ') && (c != LYX_META_NEWLINE))
-                       fprintf(fp," ");
-#ifdef NEW_TEXT
-               for (; i < size() && (c = GetChar(i)) != LYX_META_NEWLINE;
-                    ++i) {
-#else
-               for (; (i < last) && ((c=GetChar(i)) != LYX_META_NEWLINE);
-                    ++i) {
-#endif
-                       font2 = GetFontSettings(i);
-                       if (font1.latex() != font2.latex()) {
-                               if (font2.latex() != LyXFont::OFF)
-                                       continue;
-                       }
-                       c = GetChar(i);
-                       switch (c) {
-                       case LYX_META_INSET:
-                               if ((inset = GetInset(i))) {
-                                       if (!(fp2=fopen(fname2.c_str(),"w+"))) {
-                                               WriteAlert(_("LYX_ERROR:"), _("Cannot open temporary file:"), fname2);
-                                               return false;
-                                       }
-                                       inset->Latex(fp2,-1);
-                                       rewind(fp2);
-                                       c = fgetc(fp2);
-                                       while(!feof(fp2)) {
-                                               if (c == '\\')
-                                                       fprintf(fp,"\\\\");
-                                               else
-                                                       fputc(c,fp);
-                                               c = fgetc(fp2);
-                                       }
-                                       fclose(fp2);
-                               }
-                               break;
-                       case LYX_META_NEWLINE:
-                               break;
-                       case LYX_META_HFILL: 
-                               break;
-                       case LYX_META_PROTECTED_SEPARATOR:
-                               break;
-                       case '\\': 
-                               fprintf(fp, "\\\\");
-                               break;
-                       default:
-                               if (c != '\0')
-                                       fprintf(fp, "%c", c);
-                               else
-                                       lyxerr.debug() << "RoffAsciiTable: NULL char in structure." << endl;
-                               break;
-                       }
-               }
-               cell = table->CellHasContRow(actcell);
-       }
-       return true;
+                       cit->font().language() != doc_language)
+                       return true;
+       return false;
 }
 
-LyXParagraph * LyXParagraph::TeXDeeper(string & file, TexRow & texrow,
-                                      string & foot, TexRow & foot_texrow,
-                                      int & foot_count)
+
+// Convert the paragraph to a string.
+// Used for building the table of contents
+string const Paragraph::asString(Buffer const * buffer, bool label)
 {
-       lyxerr[Debug::LATEX] << "TeXDeeper...     " << this << endl;
-       LyXParagraph * par = this;
-
-       while (par && par->depth == depth) {
-               if (par->IsDummy())
-                       lyxerr << "ERROR (LyXParagraph::TeXDeeper)" << endl;
-               if (textclasslist.Style(GetCurrentTextClass(), 
-                                  par->layout).isEnvironment()
-                   || par->pextra_type != PEXTRA_NONE) 
-                       {
-                               par = par->TeXEnvironment(file, texrow,
-                                                         foot, foot_texrow,
-                                                         foot_count);
-                       } else {
-                               par = par->TeXOnePar(file, texrow,
-                                                    foot, foot_texrow,
-                                                    foot_count);
-                       }
+       BufferParams const & bparams = buffer->params;
+       string s;
+       if (label && !params().labelString().empty())
+               s += params().labelString() + ' ';
+       string::size_type const len = s.size();
+
+       for (pos_type i = 0; i < size(); ++i) {
+               value_type c = getChar(i);
+               if (IsPrintable(c))
+                       s += c;
+               else if (c == META_INSET &&
+                        getInset(i)->lyxCode() == Inset::MATH_CODE) {
+                       ostringstream ost;
+                       getInset(i)->ascii(buffer, ost);
+                       s += subst(ost.str().c_str(),'\n',' ');
+               }
        }
-       lyxerr[Debug::LATEX] << "TeXDeeper...done " << par << endl;
 
-       return par;
+       if (isRightToLeftPar(bparams))
+               reverse(s.begin() + len,s.end());
+
+       return s;
 }
 
 
-LyXParagraph * LyXParagraph::TeXEnvironment(string & file, TexRow & texrow,
-                                          string & foot, TexRow & foot_texrow,
-                                          int & foot_count)
+string const Paragraph::asString(Buffer const * buffer, 
+                                pos_type beg, pos_type end, bool label)
 {
-       bool eindent_open = false;
-       bool foot_this_level = false;
-               // flags when footnotetext should be appended to file.
-        static bool minipage_open = false;
-        static int minipage_open_depth = 0;
-       char par_sep = current_view->currentBuffer()->params.paragraph_separation;
-    
-       lyxerr[Debug::LATEX] << "TeXEnvironment...     " << this << endl;
-       if (IsDummy())
-               lyxerr << "ERROR (LyXParagraph::TeXEnvironment)" << endl;
-
-       LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(), layout);
-       
-       if (pextra_type == PEXTRA_INDENT) {
-               if (!pextra_width.empty()) {
-                       file += "\\begin{LyXParagraphIndent}{"
-                               + pextra_width + "}\n";
-               } else {
-                       //float ib = atof(pextra_widthp.c_str())/100;
-                       // string can't handle floats at present (971109)
-                       // so I'll do a conversion by hand knowing that
-                       // the limits are 0.0 to 1.0. ARRae.
-                       file += "\\begin{LyXParagraphIndent}{";
-                       switch (pextra_widthp.length()) {
-                       case 3:
-                               file += "1.00";
-                               break;
-                       case 2:
-                               file += "0.";
-                               file += pextra_widthp;
-                               break;
-                       case 1:
-                               file += "0.0";
-                               file += pextra_widthp;
-                       }
-                       file += "\\columnwidth}\n";
-               }
-               texrow.newline();
-               eindent_open = true;
-       }
-       if ((pextra_type == PEXTRA_MINIPAGE) && !minipage_open) {
-               if (pextra_hfill && Previous() &&
-                   (Previous()->pextra_type == PEXTRA_MINIPAGE)) {
-                       file += "\\hfill{}\n";
-                       texrow.newline();
-               }
-               if (par_sep == LYX_PARSEP_INDENT) {
-                       file += "{\\setlength\\parindent{0pt}\n";
-                       texrow.newline();
-               }
-               file += "\\begin{minipage}";
-               switch(pextra_alignment) {
-               case MINIPAGE_ALIGN_TOP:
-                       file += "[t]";
-                       break;
-               case MINIPAGE_ALIGN_MIDDLE:
-                       file += "[m]";
-                       break;
-               case MINIPAGE_ALIGN_BOTTOM:
-                       file += "[b]";
-                       break;
-               }
-               if (!pextra_width.empty()) {
-                       file += '{';
-                       file += pextra_width + "}\n";
-               } else {
-                       //float ib = atof(par->pextra_width.c_str())/100;
-                       // string can't handle floats at present
-                       // so I'll do a conversion by hand knowing that
-                       // the limits are 0.0 to 1.0. ARRae.
-                       file += '{';
-                       switch (pextra_widthp.length()) {
-                       case 3:
-                               file += "1.00";
-                               break;
-                       case 2:
-                               file += "0.";
-                               file += pextra_widthp;
-                               break;
-                       case 1:
-                               file += "0.0";
-                               file += pextra_widthp;
-                       }
-                       file += "\\columnwidth}\n";
-               }
-               texrow.newline();
-               if (par_sep == LYX_PARSEP_INDENT) {
-                       file += "\\setlength\\parindent{\\LyXMinipageIndent}\n";
-                       texrow.newline();
-               }
-               minipage_open = true;
-                minipage_open_depth = depth;
-       }
+       ostringstream ost;
 
-#ifdef WITH_WARNINGS
-#warning Define FANCY_FOOTNOTE_CODE to re-enable Allan footnote code
-       //I disabled it because it breaks when lists span on several
-       //pages (JMarc)
-#endif
-       if (style.isEnvironment()){
-               if (style.latextype == LATEX_LIST_ENVIRONMENT) {
-#ifdef FANCY_FOOTNOTE_CODE
-                       if (foot_count < 0) {
-                               // flag that footnote[mark][text] should be
-                               // used for any footnotes from now on
-                               foot_count = 0;
-                               foot_this_level = true;
-                       }
-#endif
-                       file += "\\begin{" + style.latexname() + "}{"
-                               + labelwidthstring + "}\n";
-               } else if (style.labeltype == LABEL_BIBLIO) {
-                       // ale970405
-                       file += "\\begin{" + style.latexname() + "}{"
-                               + bibitemWidthest() + "}\n";
-               } else if (style.latextype == LATEX_ITEM_ENVIRONMENT) {
-#ifdef FANCY_FOOTNOTE_CODE
-                       if (foot_count < 0) {
-                               // flag that footnote[mark][text] should be
-                               // used for any footnotes from now on
-                               foot_count = 0;
-                               foot_this_level = true;
-                       }
-#endif
-                       file += "\\begin{" + style.latexname() + '}'
-                               + style.latexparam() + '\n';
-               } else 
-                       file += "\\begin{" + style.latexname() + '}'
-                               + style.latexparam() + '\n';
-               texrow.newline();
-       }
-       LyXParagraph * par = this;
-       do {
-               par = par->TeXOnePar(file, texrow,
-                                    foot, foot_texrow, foot_count);
-
-                if (minipage_open && par && !style.isEnvironment() &&
-                    (par->pextra_type == PEXTRA_MINIPAGE) &&
-                    par->pextra_start_minipage) {
-                    file += "\\end{minipage}\n";
-                    texrow.newline();
-                    if (par_sep == LYX_PARSEP_INDENT) {
-                        file += "}\n";
-                       texrow.newline();
-                    }
-                    minipage_open = false;
-                }
-               if (par && par->depth > depth) {
-                       if (textclasslist.Style(GetCurrentTextClass(),
-                                          par->layout).isParagraph()
-                           && !par->table
-                           && !suffixIs(file, "\n\n")) {
-                           // There should be at least one '\n' already
-                           // but we need there to be two for Standard 
-                           // paragraphs that are depth-increment'ed to be
-                           // output correctly.  However, tables can also be
-                           // paragraphs so don't adjust them.  ARRae
-                               file += '\n';
-                               texrow.newline();
-                       }
-                       par = par->TeXDeeper(file, texrow,
-                                            foot, foot_texrow, foot_count);
-               }
-               if (par && par->layout == layout && par->depth == depth &&
-                   (par->pextra_type == PEXTRA_MINIPAGE) && !minipage_open) {
-                       if (par->pextra_hfill && par->Previous() &&
-                           (par->Previous()->pextra_type == PEXTRA_MINIPAGE)){
-                               file += "\\hfill{}\n";
-                                texrow.newline();
-                        }
-                       if (par_sep == LYX_PARSEP_INDENT) {
-                               file += "{\\setlength\\parindent{0pt}\n";
-                               texrow.newline();
-                       }
-                       file += "\\begin{minipage}";
-                       switch(par->pextra_alignment) {
-                       case MINIPAGE_ALIGN_TOP:
-                               file += "[t]";
-                               break;
-                       case MINIPAGE_ALIGN_MIDDLE:
-                               file += "[m]";
-                               break;
-                       case MINIPAGE_ALIGN_BOTTOM:
-                               file += "[b]";
-                               break;
-                       }
-                       if (!par->pextra_width.empty()) {
-                               file += '{';
-                               file += par->pextra_width;
-                               file += "}\n";
-                       } else {
-                               //float ib = atof(par->pextra_widthp.c_str())/100;
-                               // string can't handle floats at present
-                               // so I'll do a conversion by hand knowing that
-                               // the limits are 0.0 to 1.0. ARRae.
-                               file += '{';
-                               switch (par->pextra_widthp.length()) {
-                               case 3:
-                                       file += "1.00";
-                                       break;
-                               case 2:
-                                       file += "0.";
-                                       file += par->pextra_widthp;
-                                       break;
-                               case 1:
-                                       file += "0.0";
-                                       file += par->pextra_widthp;
-                               }
-                               file += "\\columnwidth}\n";
-                       }
-                       texrow.newline();
-                       if (par_sep == LYX_PARSEP_INDENT) {
-                               file += "\\setlength\\parindent{\\LyXMinipageIndent}\n";
-                               texrow.newline();
-                       }
-                       minipage_open = true;
-                        minipage_open_depth = par->depth;
-               }
-       } while (par
-                && par->layout == layout
-                && par->depth == depth
-                && par->pextra_type == pextra_type);
-       if (style.isEnvironment()) {
-               file += "\\end{" + style.latexname() + '}';
-               // maybe this should go after the minipage closes?
-               if (foot_this_level) {
-                       if (foot_count >= 1) {
-                               if (foot_count > 1) {
-                                       file += "\\addtocounter{footnote}{-";
-                                       file += tostr(foot_count - 1);
-                                       file += '}';
-                               }
-                               file += foot;
-                               texrow += foot_texrow;
-                               foot.clear();
-                               foot_texrow.reset();
-                               foot_count = 0;
-                       }
+       if (beg == 0 && label && !params().labelString().empty())
+               ost << params().labelString() << ' ';
+
+       for (pos_type i = beg; i < end; ++i) {
+               value_type const c = getUChar(buffer->params, i);
+               if (IsPrintable(c))
+                       ost << c;
+               else if (c == META_NEWLINE)
+                       ost << '\n';
+               else if (c == META_HFILL)
+                       ost << '\t'; 
+               else if (c == META_INSET) {
+                       getInset(i)->ascii(buffer, ost);
                }
        }
-        if (minipage_open && (minipage_open_depth == depth) &&
-            (!par || par->pextra_start_minipage ||
-             par->pextra_type != PEXTRA_MINIPAGE)) {
-                file += "\\end{minipage}\n";
-               texrow.newline();
-                if (par_sep == LYX_PARSEP_INDENT) {
-                        file += "}\n";
-                       texrow.newline();
-                }
-                if (par && par->pextra_type != PEXTRA_MINIPAGE) {
-                        file += "\\medskip\n\n";
-                       texrow.newline();
-                       texrow.newline();
-                }
-                minipage_open = false;
-        }
-       if (eindent_open) {
-               file += "\\end{LyXParagraphIndent}\n";
-               texrow.newline();
-       }
-        if (!(par && (par->pextra_type==PEXTRA_MINIPAGE) 
-             && par->pextra_hfill)) {
-                file += '\n';
-               texrow.newline();
-       }
-       lyxerr[Debug::LATEX] << "TeXEnvironment...done " << par << endl;
-       return par;  // ale970302
+
+       return ost.str().c_str();
 }
 
 
-LyXParagraph * LyXParagraph::TeXFootnote(string & file, TexRow & texrow,
-                                        string & foot, TexRow & foot_texrow,
-                                        int & foot_count)
+void Paragraph::setInsetOwner(Inset * i)
 {
-       lyxerr[Debug::LATEX] << "TeXFootnote...  " << this << endl;
-       if (footnoteflag == LyXParagraph::NO_FOOTNOTE)
-               lyxerr << "ERROR (LyXParagraph::TeXFootnote): "
-                       "No footnote!" << endl;
-
-       LyXParagraph * par = this;
-       LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(), 
-                                          previous->GetLayout());
-       
-       if (style.needprotect && footnotekind != LyXParagraph::FOOTNOTE){
-               lyxerr << "ERROR (LyXParagraph::TeXFootnote): "
-                       "Float other than footnote in command"
-                       " with moving argument is illegal" << endl;
+       pimpl_->inset_owner = i;
+       for (InsetList::const_iterator cit = insetlist.begin();
+            cit != insetlist.end(); ++cit) {
+               if (cit->inset)
+                       cit->inset->setOwner(i);
        }
+}
 
-       if (footnotekind != LyXParagraph::FOOTNOTE
-           && footnotekind != LyXParagraph::MARGIN
-           && file.length()
-           && !suffixIs(file, '\n')) {
-               // we need to ensure that real floats like tables and figures
-               // have their \begin{} on a new line otherwise we can get
-               // incorrect results when using the endfloat.sty package
-               // especially if two floats follow one another.  ARRae 981022
-               // NOTE: if the file is length 0 it must have just been
-               //       written out so we assume it ended with a '\n'
-               file += '\n';
-               texrow.newline();
-       }
-       
-       BufferParams * params = &current_view->currentBuffer()->params;
-       bool footer_in_body = true;
-       switch (footnotekind) {
-       case LyXParagraph::FOOTNOTE:
-               if (style.intitle) {
-                       file += "\\thanks{\n";
-                       footer_in_body = false;
-               } else {
-                       if (foot_count == -1) {
-                               // we're at depth 0 so we can use:
-                               file += "\\footnote{%\n";
-                               footer_in_body = false;
-                       } else {
-                               file += "\\footnotemark{}%\n";
-                               if (foot_count) {
-                                       // we only need this when there are
-                                       // multiple footnotes
-                                       foot += "\\stepcounter{footnote}";
-                               }
-                               foot += "\\footnotetext{%\n";
-                               foot_texrow.start(this,0);
-                               foot_texrow.newline();
-                               ++foot_count;
-                       }
-               }
-               break;
-       case LyXParagraph::MARGIN:
-               file += "\\marginpar{\n";
-               break;
-       case LyXParagraph::FIG:
-               if (pextra_type == PEXTRA_FLOATFLT
-                   && (!pextra_width.empty()
-                       || !pextra_widthp.empty())) {
-                       char bufr[80];
-                       if (!pextra_width.empty())
-                               sprintf(bufr, "\\begin{floatingfigure}{%s}\n",
-                                       pextra_width.c_str());
-                       else
-                               sprintf(bufr, "\\begin{floatingfigure}{%f\\textwidth}\n",
-                                       atoi(pextra_widthp.c_str())/100.0);
-                       file += bufr;
-               } else {
-                       file += "\\begin{figure}";
-                       if (!params->float_placement.empty()) { 
-                               file += '[';
-                               file += params->float_placement;
-                               file += "]\n";
-                       } else {
-                               file += '\n';
+
+void Paragraph::deleteInsetsLyXText(BufferView * bv)
+{
+       // then the insets
+       for (InsetList::const_iterator cit = insetlist.begin();
+            cit != insetlist.end(); ++cit) {
+               if (cit->inset) {
+                       if (cit->inset->isTextInset()) {
+                               static_cast<UpdatableInset *>
+                                       (cit->inset)->deleteLyXText(bv, true);
                        }
                }
-               break;
-       case LyXParagraph::TAB:
-               file += "\\begin{table}";
-               if (!params->float_placement.empty()) { 
-                       file += '[';
-                       file += params->float_placement;
-                       file += "]\n";
-               } else {
-                       file += '\n';
-               }
-               break;
-       case LyXParagraph::WIDE_FIG:
-               file += "\\begin{figure*}";
-               if (!params->float_placement.empty()) { 
-                       file += '[';
-                       file += params->float_placement;
-                       file += "]\n";
-               } else {
-                       file += '\n';
-               }
-               break;
-       case LyXParagraph::WIDE_TAB:
-               file += "\\begin{table*}";
-               if (!params->float_placement.empty()) { 
-                       file += '[';
-                       file += params->float_placement;
-                       file += "]\n";
-               } else {
-                       file += '\n';
-               }
-               break;
-       case LyXParagraph::ALGORITHM:
-               file += "\\begin{algorithm}\n";
-               break;
        }
-       texrow.newline();
-   
-       if (footnotekind != LyXParagraph::FOOTNOTE
-           || !footer_in_body) {
-               // Process text for all floats except footnotes in body
-               do {
-                       LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
-                                                         par->layout);
-                       if (par->IsDummy())
-                               lyxerr << "ERROR (LyXParagraph::TeXFootnote)"
-                                      << endl;
-                       if (style.isEnvironment()
-                           || par->pextra_type == PEXTRA_MINIPAGE) { /* && !minipage_open ?? */
-                               // Allows the use of minipages within float environments.
-                               // Shouldn't be circular because we don't support
-                               // footnotes inside floats (yet). ARRae
-                               par = par->TeXEnvironment(file, texrow,
-                                                         foot, foot_texrow,
-                                                         foot_count);
-                       } else {
-                               par = par->TeXOnePar(file, texrow,
-                                                    foot, foot_texrow,
-                                                    foot_count);
-                       }
-                       
-                       if (par && !par->IsDummy() && par->depth > depth) {
-                               par = par->TeXDeeper(file, texrow,
-                                                    foot, foot_texrow,
-                                                    foot_count);
-                       }
-               } while (par && par->footnoteflag != LyXParagraph::NO_FOOTNOTE);
-       } else {
-               // process footnotes > depth 0 or in environments separately
-               // NOTE: Currently don't support footnotes within footnotes
-               //       even though that is possible using the \footnotemark
-               string dummy;
-               TexRow dummy_texrow;
-               int dummy_count = 0;
-               do {
-                       LyXLayout const & style = textclasslist.Style(GetCurrentTextClass(),
-                                                         par->layout);
-                       if (par->IsDummy())
-                               lyxerr << "ERROR (LyXParagraph::TeXFootnote)"
-                                      << endl;
-                       if (style.isEnvironment()
-                           || par->pextra_type == PEXTRA_MINIPAGE) { /* && !minipage_open ?? */
-                               // Allows the use of minipages within float environments.
-                               // Shouldn't be circular because we don't support
-                               // footnotes inside floats (yet). ARRae
-                               par = par->TeXEnvironment(foot, foot_texrow,
-                                                         dummy, dummy_texrow,
-                                                         dummy_count);
-                       } else {
-                               par = par->TeXOnePar(foot, foot_texrow,
-                                                    dummy, dummy_texrow,
-                                                    dummy_count);
-                       }
+}
+
 
-                       if (par && !par->IsDummy() && par->depth > depth) {
-                               par = par->TeXDeeper(foot, foot_texrow,
-                                                    dummy, dummy_texrow,
-                                                    dummy_count);
+void Paragraph::resizeInsetsLyXText(BufferView * bv)
+{
+       // then the insets
+       for (InsetList::const_iterator cit = insetlist.begin();
+            cit != insetlist.end(); ++cit)
+       {
+               if (cit->inset) {
+                       if (cit->inset->isTextInset()) {
+                               static_cast<UpdatableInset *>
+                                       (cit->inset)->resizeLyXText(bv, true);
                        }
-               } while (par && par->footnoteflag != LyXParagraph::NO_FOOTNOTE);
-               if (dummy_count) {
-                       lyxerr << "ERROR (LyXParagraph::TeXFootnote): "
-                               "Footnote in a Footnote -- not supported"
-                              << endl;
                }
        }
+}
 
-       switch (footnotekind) {
-       case LyXParagraph::FOOTNOTE:
-               if (footer_in_body) {
-                       // This helps tell which of the multiple
-                       // footnotetexts an error was in.
-                       foot += "}%\n";
-                       foot_texrow.newline();
-               } else {
-                       file += '}';
-               }
-               break;
-       case LyXParagraph::MARGIN:
-               file += '}';
-               break;
-       case LyXParagraph::FIG:
-               if (pextra_type == PEXTRA_FLOATFLT
-                   && (!pextra_width.empty()
-                       || !pextra_widthp.empty()))
-                       file += "\\end{floatingfigure}";
-               else
-                       file += "\\end{figure}";
-               break;
-       case LyXParagraph::TAB:
-               file += "\\end{table}";
-               break;
-       case LyXParagraph::WIDE_FIG:
-               file += "\\end{figure*}";
-               break;
-       case LyXParagraph::WIDE_TAB:
-               file += "\\end{table*}";
-               break;
-       case LyXParagraph::ALGORITHM:
-               file += "\\end{algorithm}";
-               break;
-       }
 
-       if (footnotekind != LyXParagraph::FOOTNOTE
-           && footnotekind != LyXParagraph::MARGIN) {
-               // we need to ensure that real floats like tables and figures
-               // have their \end{} on a line of their own otherwise we can
-               // get incorrect results when using the endfloat.sty package.
-               file += "\n";
-               texrow.newline();
-       }
+void Paragraph::setContentsFromPar(Paragraph * par)
+{
+       pimpl_->setContentsFromPar(par);
+}
 
-       lyxerr[Debug::LATEX] << "TeXFootnote...done " << par->next << endl;
-       return par;
+
+lyx::pos_type Paragraph::size() const
+{
+       return pimpl_->size();
 }
 
 
-void LyXParagraph::SetPExtraType(int type, char const * width,
-                                char const * widthp)
+Paragraph::value_type Paragraph::getChar(pos_type pos) const
 {
-    pextra_type = type;
-    pextra_width = width;
-    pextra_widthp = widthp;
-
-    if (textclasslist.Style(GetCurrentTextClass(), 
-                       layout).isEnvironment()) {
-        LyXParagraph
-            * par = this,
-            * ppar = par;
-
-        while (par && (par->layout == layout) && (par->depth == depth)) {
-            ppar = par;
-            par = par->Previous();
-            if (par)
-                par = par->FirstPhysicalPar();
-            while (par && par->depth > depth) {
-                par = par->Previous();
-                if (par)
-                    par = par->FirstPhysicalPar();
-            }
-        }
-        par = ppar;
-        while (par && (par->layout == layout) && (par->depth == depth)) {
-            par->pextra_type = type;
-            par->pextra_width = width;
-            par->pextra_widthp = widthp;
-            par = par->NextAfterFootnote();
-            if (par && (par->depth > depth))
-                par->SetPExtraType(type,width,widthp);
-            while (par && ((par->depth > depth) || par->IsDummy()))
-                par = par->NextAfterFootnote();
-        }
-    }
+       return pimpl_->getChar(pos);
 }
 
-void LyXParagraph::UnsetPExtraType()
+
+int Paragraph::id() const
+{
+       return pimpl_->id_;
+}
+
+
+void  Paragraph::id(int id_arg)
+{
+       pimpl_->id_ = id_arg;
+}
+
+
+layout_type Paragraph::getLayout() const
+{
+       return layout;
+}
+
+
+bool Paragraph::isFirstInSequence() const
+{
+       Paragraph const * dhook = depthHook(getDepth());
+       return (dhook == this
+               || dhook->getLayout() != getLayout()
+               || dhook->getDepth() != getDepth());
+}
+
+
+Inset * Paragraph::inInset() const
+{
+       return pimpl_->inset_owner;
+}
+
+
+void Paragraph::clearContents()
+{
+       pimpl_->clear();
+}
+
+
+void Paragraph::setCounter(int i, int v)
+{
+       pimpl_->counter_[i] = v;
+}
+
+
+int Paragraph::getCounter(int i) const
+{
+       return pimpl_->counter_[i];
+}
+
+
+void Paragraph::incCounter(int i)
+{
+       pimpl_->counter_[i]++;
+}
+
+
+void Paragraph::setChar(pos_type pos, value_type c)
+{
+       pimpl_->setChar(pos, c);
+}
+
+
+Paragraph::inset_iterator::inset_iterator(Paragraph::InsetList::iterator const & iter)
+ : it(iter) 
+{}
+
+
+Paragraph::inset_iterator Paragraph::inset_iterator_begin()
+{
+       return inset_iterator(insetlist.begin());
+}
+
+
+Paragraph::inset_iterator Paragraph::inset_iterator_end()
+{
+       return inset_iterator(insetlist.end());
+}
+
+
+ParagraphParameters & Paragraph::params()
+{
+       return pimpl_->params;
+}
+
+
+ParagraphParameters const & Paragraph::params() const
+{
+       return pimpl_->params;
+}
+
+
+Paragraph * Paragraph::getParFromID(int id) const
+{
+       return pimpl_->getParFromID(id);
+}
+
+
+bool Paragraph::isFreeSpacing() const
 {
-    if (pextra_type == PEXTRA_NONE)
-        return;
-    
-    pextra_type = PEXTRA_NONE;
-    pextra_width.clear();
-    pextra_widthp.clear();
-
-    if (textclasslist.Style(GetCurrentTextClass(), 
-                       layout).isEnvironment()) {
-        LyXParagraph
-            * par = this,
-            * ppar = par;
-
-        while (par && (par->layout == layout) && (par->depth == depth)) {
-            ppar = par;
-            par = par->Previous();
-            if (par)
-                par = par->FirstPhysicalPar();
-            while (par && par->depth > depth) {
-                par = par->Previous();
-                if (par)
-                    par = par->FirstPhysicalPar();
-            }
-        }
-        par = ppar;
-        while (par && (par->layout == layout) && (par->depth == depth)) {
-            par->pextra_type = PEXTRA_NONE;
-            par->pextra_width.clear();
-            par->pextra_widthp.clear();
-            par = par->NextAfterFootnote();
-            if (par && (par->depth > depth))
-                par->UnsetPExtraType();
-            while (par && ((par->depth > depth) || par->IsDummy()))
-                par = par->NextAfterFootnote();
-        }
-    }
+       // for now we just need this, later should we need this in some
+       // other way we can always add a function to Inset::() too.
+       if (pimpl_->inset_owner && pimpl_->inset_owner->owner())
+               return (pimpl_->inset_owner->owner()->lyxCode() == Inset::ERT_CODE);
+       return false;
 }