]> git.lyx.org Git - features.git/blobdiff - src/buffer.C
small stuff
[features.git] / src / buffer.C
index 74049240ff5fe3f42aef0bddf443a5c50edd2f6f..3701b7768301e033e35fd04db72f5353d9aee5df 100644 (file)
@@ -55,7 +55,7 @@
 #include "insets/insetlabel.h"
 #include "insets/insetref.h"
 #include "insets/inseturl.h"
-#include "insets/insetinfo.h"
+#include "insets/insetnote.h"
 #include "insets/insetquotes.h"
 #include "insets/insetlatexaccent.h"
 #include "insets/insetbib.h" 
 #include "insets/insetmarginal.h"
 #include "insets/insetminipage.h"
 #include "insets/insetfloat.h"
-#include "insets/insetlist.h"
 #include "insets/insettabular.h"
+#if 0
 #include "insets/insettheorem.h"
+#include "insets/insetlist.h"
+#endif
 #include "insets/insetcaption.h"
 #include "insets/insetfloatlist.h"
+#include "support/textutils.h"
 #include "support/filetools.h"
 #include "support/path.h"
 #include "support/os.h"
 #include "BufferView.h"
 #include "ParagraphParameters.h"
 
-using std::stringstream;
 using std::ostream;
 using std::ofstream;
 using std::ifstream;
@@ -282,13 +284,24 @@ void Buffer::setFileName(string const & newfile)
 namespace {
 
 string last_inset_read;
-string inset_ert_contents;
-bool ert_active = false;
-bool in_tabular = false;
+
+struct ErtComp 
+{
+       ErtComp() : active(false), in_tabular(false) {
+       }
+       string contents;
+       bool active;
+       bool in_tabular;
+};
+
+std::stack<ErtComp> ert_stack;
+ErtComp ert_comp;
+
 
 } // anon
 
 
+int unknown_layouts;
 
 // candidate for move to BufferView
 // (at least some parts in the beginning of the func)
@@ -300,10 +313,11 @@ bool in_tabular = false;
 // Returns false if "\the_end" is not read for formats >= 2.13. (Asger)
 bool Buffer::readLyXformat2(LyXLex & lex, Paragraph * par)
 {
+       unknown_layouts = 0;
 #ifdef NO_LATEX
-       inset_ert_contents.erase();
-       ert_active = false;
-       in_tabular = false;
+       ert_comp.contents.erase();
+       ert_comp.active = false;
+       ert_comp.in_tabular = false;
 #endif
        
        int pos = 0;
@@ -354,7 +368,19 @@ bool Buffer::readLyXformat2(LyXLex & lex, Paragraph * par)
                first_par = par;
 
        paragraph = first_par;
-       
+
+       if (unknown_layouts > 0) {
+               string s = _("Couldn't set the layout for ");
+               if (unknown_layouts == 1) {
+                       s += _("one paragraph");
+               } else {
+                       s += tostr(unknown_layouts);
+                       s += _(" paragraphs");
+               }
+               WriteAlert(_("Textclass Loading Error!"), s,
+                          _("When reading " + fileName()));
+       }       
+
        return the_end_read;
 }
 
@@ -362,15 +388,15 @@ bool Buffer::readLyXformat2(LyXLex & lex, Paragraph * par)
 void Buffer::insertErtContents(Paragraph * par, int & pos,
                               LyXFont const & font, bool set_inactive) 
 {
-       if (!inset_ert_contents.empty()) {
+       if (!ert_comp.contents.empty()) {
                lyxerr[Debug::INSETS] << "ERT contents:\n"
-                      << inset_ert_contents << endl;
-               Inset * inset = new InsetERT(inset_ert_contents);
+                      << ert_comp.contents << endl;
+               Inset * inset = new InsetERT(ert_comp.contents, true);
                par->insertInset(pos++, inset, font);
-               inset_ert_contents.erase();
+               ert_comp.contents.erase();
        }
        if (set_inactive) {
-               ert_active = false;
+               ert_comp.active = false;
        }
 }
 
@@ -396,8 +422,8 @@ Buffer::parseSingleLyXformat2Token(LyXLex & lex, Paragraph *& par,
        
        if (token[0] != '\\') {
 #ifdef NO_LATEX
-               if (ert_active) {
-                       inset_ert_contents += token;
+               if (ert_comp.active) {
+                       ert_comp.contents += token;
                } else {
 #endif
                for (string::const_iterator cit = token.begin();
@@ -405,7 +431,6 @@ Buffer::parseSingleLyXformat2Token(LyXLex & lex, Paragraph *& par,
                        par->insertChar(pos, (*cit), font);
                        ++pos;
                }
-               checkminipage = true;
 #ifdef NO_LATEX
                }
 #endif
@@ -416,7 +441,7 @@ Buffer::parseSingleLyXformat2Token(LyXLex & lex, Paragraph *& par,
                ++pos;
        } else if (token == "\\layout") {
 #ifdef NO_LATEX
-               in_tabular = false;
+               ert_comp.in_tabular = false;
                // Do the insetert.
                insertErtContents(par, pos, font);
 #endif
@@ -428,7 +453,7 @@ Buffer::parseSingleLyXformat2Token(LyXLex & lex, Paragraph *& par,
 
 #ifdef NO_LATEX
                if (compare_no_case(layoutname, "latex") == 0) {
-                       ert_active = true;
+                       ert_comp.active = true;
                }
 #endif
 #ifdef USE_CAPTION
@@ -496,6 +521,12 @@ Buffer::parseSingleLyXformat2Token(LyXLex & lex, Paragraph *& par,
                                // layout not found
                                // use default layout "Standard" (0)
                                par->layout = 0;
+                               ++unknown_layouts;
+                               string const s = _("Layout had to be changed from\n")
+                                       + layoutname + _(" to ")
+                                       + textclasslist.NameOfLayout(params.textclass, par->layout);
+                               InsetError * new_inset = new InsetError(s);
+                               par->insertInset(0, new_inset);
                        }
                        // Test whether the layout is obsolete.
                        LyXLayout const & layout =
@@ -558,7 +589,9 @@ Buffer::parseSingleLyXformat2Token(LyXLex & lex, Paragraph *& par,
                }
 
                if (!inset) {
+#ifndef NO_PEXTRA_REALLY
                        --call_depth;
+#endif
                        return false; // no end read yet
                }
                
@@ -733,6 +766,12 @@ Buffer::parseSingleLyXformat2Token(LyXLex & lex, Paragraph *& par,
        } else if (token == "\\use_amsmath") {
                lex.nextToken();
                params.use_amsmath = lex.GetInteger();
+       } else if (token == "\\use_natbib") {
+               lex.nextToken();
+               params.use_natbib = lex.GetInteger();
+       } else if (token == "\\use_numerical_citations") {
+               lex.nextToken();
+               params.use_numerical_citations = lex.GetInteger();
        } else if (token == "\\paperorientation") {
                int tmpret = lex.FindToken(string_orientation);
                if (tmpret == -1) ++tmpret;
@@ -912,7 +951,7 @@ Buffer::parseSingleLyXformat2Token(LyXLex & lex, Paragraph *& par,
                        // Do the insetert.
                        insertErtContents(par, pos, font);
                } else if (tok == "latex") {
-                       ert_active = true;
+                       ert_comp.active = true;
                } else if (tok == "default") {
                        // Do the insetert.
                        insertErtContents(par, pos, font);
@@ -1004,9 +1043,15 @@ Buffer::parseSingleLyXformat2Token(LyXLex & lex, Paragraph *& par,
                // the inset isn't it? Lgb.
        } else if (token == "\\begin_inset") {
 #ifdef NO_LATEX
-               insertErtContents(par, pos, font);
+               insertErtContents(par, pos, font, false);
+               ert_stack.push(ert_comp);
+               ert_comp = ErtComp();
 #endif
                readInset(lex, par, pos, font);
+#ifdef NO_LATEX
+               ert_comp = ert_stack.top();
+               ert_stack.pop();
+#endif
        } else if (token == "\\SpecialChar") {
                LyXLayout const & layout =
                        textclasslist.Style(params.textclass, 
@@ -1038,8 +1083,8 @@ Buffer::parseSingleLyXformat2Token(LyXLex & lex, Paragraph *& par,
        } else if (token == "\\newline") {
 #ifdef NO_LATEX
 
-               if (!in_tabular && ert_active) {
-                       inset_ert_contents += char(Paragraph::META_NEWLINE);
+               if (!ert_comp.in_tabular && ert_comp.active) {
+                       ert_comp.contents += char(Paragraph::META_NEWLINE);
                } else {
                        // Since we cannot know it this is only a regular
                        // newline or a tabular cell delimter we have to
@@ -1055,15 +1100,12 @@ Buffer::parseSingleLyXformat2Token(LyXLex & lex, Paragraph *& par,
 #endif
        } else if (token == "\\LyXTable") {
 #ifdef NO_LATEX
-               in_tabular = true;
+               ert_comp.in_tabular = true;
 #endif
                Inset * inset = new InsetTabular(*this);
                inset->read(this, lex);
                par->insertInset(pos, inset, font);
                ++pos;
-               // because of OLD_TABULAR_READ where tabulars have been
-               // one paragraph.
-               checkminipage = true;
        } else if (token == "\\hfill") {
                par->insertChar(pos, Paragraph::META_HFILL, font);
                ++pos;
@@ -1090,8 +1132,8 @@ Buffer::parseSingleLyXformat2Token(LyXLex & lex, Paragraph *& par,
                par->bibkey->read(this, lex);                   
        } else if (token == "\\backslash") {
 #ifdef NO_LATEX
-               if (ert_active) {
-                       inset_ert_contents += "\\";
+               if (ert_comp.active) {
+                       ert_comp.contents += "\\";
                } else {
 #endif
                par->insertChar(pos, '\\', font);
@@ -1106,11 +1148,13 @@ Buffer::parseSingleLyXformat2Token(LyXLex & lex, Paragraph *& par,
                insertErtContents(par, pos, font);
 #endif
                the_end_read = true;
+#ifndef NO_PEXTRA_REALLY
                minipar = parBeforeMinipage = 0;
+#endif
        } else {
 #ifdef NO_LATEX
-               if (ert_active) {
-                       inset_ert_contents += token;
+               if (ert_comp.active) {
+                       ert_comp.contents += token;
                } else {
 #endif
                // This should be insurance for the future: (Asger)
@@ -1126,7 +1170,17 @@ Buffer::parseSingleLyXformat2Token(LyXLex & lex, Paragraph *& par,
                }
 #endif
        }
+
 #ifndef NO_PEXTRA_REALLY
+       // I wonder if we could use this blanket fix for all the
+       // checkminipage cases...
+       if (par && par->size()) {
+               // It is possible that this will check to often,
+               // but that should not be an correctness issue.
+               // Only a speed issue.
+               checkminipage = true;
+       }
+       
        // now check if we have a minipage paragraph as at this
        // point we already read all the necessary data!
        // this cannot be done in layout because there we did
@@ -1268,11 +1322,64 @@ Buffer::parseSingleLyXformat2Token(LyXLex & lex, Paragraph *& par,
        }
        }
        // End of pextra_minipage compability
-#endif
        --call_depth;
+#endif
        return the_end_read;
 }
 
+// needed to insert the selection
+void Buffer::insertStringAsLines(Paragraph *& par, Paragraph::size_type & pos,
+                                LyXFont const & font, 
+                                string const & str) const
+{
+       LyXLayout const & layout = textclasslist.Style(params.textclass, 
+                                                    par->getLayout());
+       // insert the string, don't insert doublespace
+       bool space_inserted = true;
+       for(string::const_iterator cit = str.begin(); 
+           cit != str.end(); ++cit) {
+               if (*cit == '\n') {
+                       if (par->size() || layout.keepempty) { 
+                               par->breakParagraph(params, pos, 
+                                                   layout.isEnvironment());
+                               par = par->next();
+                               pos = 0;
+                               space_inserted = true;
+                       } else {
+                               continue;
+                       }
+                       // do not insert consecutive spaces if !free_spacing
+               } else if ((*cit == ' ' || *cit == '\t')
+                          && space_inserted && !layout.free_spacing) {
+                       continue;
+               } else if (*cit == '\t') {
+                       if (!layout.free_spacing) {
+                               // tabs are like spaces here
+                               par->insertChar(pos, ' ', font);
+                               ++pos;
+                               space_inserted = true;
+                       } else {
+                               const Paragraph::value_type nb = 8 - pos % 8;
+                               for (Paragraph::size_type a = 0; 
+                                    a < nb ; ++a) {
+                                       par->insertChar(pos, ' ', font);
+                                       ++pos;
+                               }
+                               space_inserted = true;
+                       }
+               } else if (!IsPrintable(*cit)) {
+                       // Ignore unprintables
+                       continue;
+               } else {
+                       // just insert the character
+                       par->insertChar(pos, *cit, font);
+                       ++pos;
+                       space_inserted = (*cit == ' ');
+               }
+
+       }       
+}
+
 
 void Buffer::readInset(LyXLex & lex, Paragraph *& par,
                       int & pos, LyXFont & font)
@@ -1296,7 +1403,9 @@ void Buffer::readInset(LyXLex & lex, Paragraph *& par,
 
                string const cmdName = inscmd.getCmdName();
                
-               if (cmdName == "cite") {
+               // This strange command allows LyX to recognize "natbib" style
+               // citations: citet, citep, Citet etc.
+               if (compare_no_case(cmdName, "cite", 4) == 0) {
                        inset = new InsetCitation(inscmd);
                } else if (cmdName == "bibitem") {
                        lex.printError("Wrong place for bibitem");
@@ -1335,6 +1444,7 @@ void Buffer::readInset(LyXLex & lex, Paragraph *& par,
                        inset = new InsetParent(inscmd, *this);
                }
        } else {
+               bool alreadyread = false;
                if (tmptok == "Quotes") {
                        inset = new InsetQuotes;
                } else if (tmptok == "External") {
@@ -1345,8 +1455,13 @@ void Buffer::readInset(LyXLex & lex, Paragraph *& par,
                        inset = new InsetFormula;
                } else if (tmptok == "Figure") {
                        inset = new InsetFig(100, 100, *this);
-               } else if (tmptok == "Info") {
-                       inset = new InsetInfo;
+               } else if (tmptok == "Info") {// backwards compatibility
+                       inset = new InsetNote(this,
+                                             lex.getLongString("\\end_inset"),
+                                             true);
+                       alreadyread = true;
+               } else if (tmptok == "Note") {
+                       inset = new InsetNote;
                } else if (tmptok == "Include") {
                        InsetCommandParams p( "Include" );
                        inset = new InsetInclude(p, *this);
@@ -1366,10 +1481,12 @@ void Buffer::readInset(LyXLex & lex, Paragraph *& par,
                        lex.next();
                        string tmptok = lex.GetString();
                        inset = new InsetFloat(tmptok);
+#if 0
                } else if (tmptok == "List") {
                        inset = new InsetList;
                } else if (tmptok == "Theorem") {
                        inset = new InsetList;
+#endif
                } else if (tmptok == "Caption") {
                        inset = new InsetCaption;
                } else if (tmptok == "GRAPHICS") {
@@ -1378,7 +1495,7 @@ void Buffer::readInset(LyXLex & lex, Paragraph *& par,
                        inset = new InsetFloatList;
                }
                
-               if (inset) inset->read(this, lex);
+               if (inset && !alreadyread) inset->read(this, lex);
        }
        
        if (inset) {
@@ -3228,7 +3345,7 @@ void Buffer::simpleDocBookOnePar(ostream & os, string & extra,
 
                if (c == Paragraph::META_INSET) {
                        Inset * inset = par->getInset(i);
-                       std::ostringstream ost;
+                       ostringstream ost;
                        inset->docBook(this, ost);
                        string tmp_out = ost.str().c_str();
 
@@ -3351,7 +3468,6 @@ void Buffer::validate(LaTeXFeatures & features) const
                textclasslist.TextClass(params.textclass);
     
         // AMS Style is at document level
-    
         features.amsstyle = (params.use_amsmath ||
                             tclass.provides(LyXTextClass::amsmath));