]> git.lyx.org Git - lyx.git/commitdiff
The final parsing patch. Tested on a variety of weird and wonderful things
authorJohn Levon <levon@movementarian.org>
Wed, 12 Mar 2003 11:52:23 +0000 (11:52 +0000)
committerJohn Levon <levon@movementarian.org>
Wed, 12 Mar 2003 11:52:23 +0000 (11:52 +0000)
without finding a regression (yet !) :)

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@6465 a592a061-630c-0410-9148-cb99ea01b6c8

12 files changed:
src/ChangeLog
src/buffer.C
src/buffer.h
src/bufferparams.C
src/bufferparams.h
src/factory.C
src/factory.h
src/insets/ChangeLog
src/insets/insettext.C
src/paragraph_funcs.C
src/paragraph_funcs.h
src/tabular.C

index 0f0e006a0b309053ef0da60af57298d6f03d6c07..1b619a367d3c8fd9558923593bb1f1bd1e88e2c4 100644 (file)
@@ -1,3 +1,21 @@
+2003-03-12  John Levon  <levon@movementarian.org>
+
+       * buffer.h:
+       * buffer.C: move paragraph read into a separate function,
+       a little renaming to reflect that.
+
+       * bufferparams.h:
+       * bufferparams.C: remove the author_ids map, not necessary now
+
+       * factory.h:
+       * factory.C: moved Buffer::readInset to here
+
+       * paragraph_funcs.h:
+       * paragraph_funcs.C: readParagraph free function moved from
+       buffer.C
+
+       * tabular.C: name change
+
 2003-03-12  John Levon  <levon@movementarian.org>
 
        * buffer.C:
index 65819731e677eb0035789b7786fec884c017b685..a7399d9fad8705cdd358f784f3cbb765f27c05d4 100644 (file)
 #include "mathed/formulamacro.h"
 #include "mathed/formula.h"
 
-#include "insets/inset.h"
 #include "insets/inseterror.h"
-#include "insets/insethfill.h"
-#include "insets/insetlabel.h"
-#include "insets/insetref.h"
-#include "insets/inseturl.h"
-#include "insets/insetnote.h"
-#include "insets/insetquotes.h"
-#include "insets/insetlatexaccent.h"
 #include "insets/insetbibitem.h"
 #include "insets/insetbibtex.h"
-#include "insets/insetcite.h"
-#include "insets/insetexternal.h"
-#include "insets/insetindex.h"
 #include "insets/insetinclude.h"
-#include "insets/insettoc.h"
-#include "insets/insetparent.h"
-#include "insets/insetspecialchar.h"
 #include "insets/insettext.h"
-#include "insets/insetert.h"
-#include "insets/insetgraphics.h"
-#include "insets/insetfoot.h"
-#include "insets/insetmarginal.h"
-#include "insets/insetoptarg.h"
-#include "insets/insetminipage.h"
-#include "insets/insetfloat.h"
-#include "insets/insetwrap.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 "frontends/Dialogs.h"
 #include "frontends/Alert.h"
@@ -344,12 +315,9 @@ bool Buffer::readBody(LyXLex & lex, ParagraphList::iterator pit)
        unknown_layouts = 0;
        int unknown_tokens = 0;
 
-       int pos = 0;
        Paragraph::depth_type depth = 0;
        bool the_end_read = false;
 
-       LyXFont font(LyXFont::ALL_INHERIT, params.language);
-
        if (paragraphs.empty()) {
                unknown_tokens += readHeader(lex);
 
@@ -370,7 +338,6 @@ bool Buffer::readBody(LyXLex & lex, ParagraphList::iterator pit)
        } else {
                // We are inserting into an existing document
                users->text->breakParagraph(users, paragraphs);
-               pos = 0;
                markDirty();
 
                // We don't want to adopt the parameters from the
@@ -396,7 +363,7 @@ bool Buffer::readBody(LyXLex & lex, ParagraphList::iterator pit)
                        continue;
                }
 
-               unknown_tokens += readToken(lex, paragraphs, pit, token, pos, depth, font);
+               unknown_tokens += readParagraph(lex, token, paragraphs, pit, depth);
        }
 
        if (unknown_layouts > 0) {
@@ -438,282 +405,42 @@ bool Buffer::readBody(LyXLex & lex, ParagraphList::iterator pit)
 
 
 int
-Buffer::readToken(LyXLex & lex, ParagraphList & pars,
-                  ParagraphList::iterator & pit,
-                  string const & token, int & pos,
-                  Paragraph::depth_type & depth,
-                  LyXFont & font)
+Buffer::readParagraph(LyXLex & lex, string const & token,
+                      ParagraphList & pars, ParagraphList::iterator & pit,
+                      Paragraph::depth_type & depth)
 {
        static Change current_change;
        int unknown = 0;
 
-       // The order of the tags tested may seem unnatural, but this
-       // has been done in order to reduce the number of string
-       // comparisons needed to recognize a given token. This leads
-       // on large documents like UserGuide to a reduction of a
-       // factor 5! (JMarc)
-       if (token[0] != '\\') {
-               for (string::const_iterator cit = token.begin();
-                    cit != token.end(); ++cit) {
-                       pit->insertChar(pos, (*cit), font, current_change);
-                       ++pos;
-               }
-       } else if (token == "\\layout") {
-               // reset the font as we start a new layout and if the font is
-               // not ALL_INHERIT,document_language then it will be set to the
-               // right values after this tag (Jug 20020420)
-               font = LyXFont(LyXFont::ALL_INHERIT, params.language);
-
-               lex.eatLine();
-               string layoutname = lex.getString();
+       if (token == "\\layout") {
+               lex.pushToken(token);
 
-               LyXTextClass const & tclass = params.getLyXTextClass();
-
-               if (layoutname.empty()) {
-                       layoutname = tclass.defaultLayoutName();
-               }
-               bool hasLayout = tclass.hasLayout(layoutname);
-               if (!hasLayout) {
-                       lyxerr << "Layout '" << layoutname << "' does not"
-                              << " exist in textclass '" << tclass.name()
-                              << "'." << endl;
-                       lyxerr << "Trying to use default layout instead."
-                              << endl;
-                       layoutname = tclass.defaultLayoutName();
-               }
+               Paragraph * par = new Paragraph();
+               par->params().depth(depth);
+               if (params.tracking_changes)
+                       par->trackChanges();
+               LyXFont f(LyXFont::ALL_INHERIT, params.language);
+               par->setFont(0, f);
 
-#ifdef USE_CAPTION
-               // The is the compability reading of layout caption.
-               // It can be removed in LyX version 1.3.0. (Lgb)
-               if (compare_ascii_no_case(layoutname, "caption") == 0) {
-                       // We expect that the par we are now working on is
-                       // really inside a InsetText inside a InsetFloat.
-                       // We also know that captions can only be
-                       // one paragraph. (Lgb)
-
-                       // We should now read until the next "\layout"
-                       // is reached.
-                       // This is probably not good enough, what if the
-                       // caption is the last par in the document (Lgb)
-                       istream & ist = lex.getStream();
-                       stringstream ss;
-                       string line;
-                       int begin = 0;
-                       while (true) {
-                               getline(ist, line);
-                               if (prefixIs(line, "\\layout")) {
-                                       lex.pushToken(line);
-                                       break;
-                               }
-                               if (prefixIs(line, "\\begin_inset"))
-                                       ++begin;
-                               if (prefixIs(line, "\\end_inset")) {
-                                       if (begin)
-                                               --begin;
-                                       else {
-                                               lex.pushToken(line);
-                                               break;
-                                       }
-                               }
+               // FIXME: goddamn InsetTabular makes us pass a Buffer
+               // not BufferParams
+               unknown += ::readParagraph(*this, *par, lex);
 
-                               ss << line << '\n';
-                       }
-                       // Now we should have the whole layout in ss
-                       // we should now be able to give this to the
-                       // caption inset.
-                       ss << "\\end_inset\n";
-
-                       // This seems like a bug in stringstream.
-                       // We really should be able to use ss
-                       // directly. (Lgb)
-                       istringstream is(ss.str());
-                       LyXLex tmplex(0, 0);
-                       tmplex.setStream(is);
-                       Inset * inset = new InsetCaption;
-                       inset->Read(this, tmplex);
-                       pit->InsertInset(pos, inset, font);
-                       ++pos;
-               } else {
-#endif
-                       Paragraph * par = new Paragraph();
-                       if (params.tracking_changes)
-                               par->trackChanges();
-                       pos = 0;
-                       par->layout(params.getLyXTextClass()[layoutname]);
-                       // Test whether the layout is obsolete.
-                       LyXLayout_ptr const & layout = par->layout();
-                       if (!layout->obsoleted_by().empty())
-                               par->layout(params.getLyXTextClass()[layout->obsoleted_by()]);
-                       par->params().depth(depth);
-
-                       par->params().read(lex);
-
-                       // insert after
-                       if (pit != pars.end())
-                               ++pit;
-                       pit = pars.insert(pit, par);
-#if USE_CAPTION
-               }
-#endif
-
-       } else if (token == "\\end_inset") {
-               lyxerr << "Solitary \\end_inset in line " << lex.getLineNo() << "\n"
-                      << "Missing \\begin_inset?.\n";
-               // Simply ignore this. The insets do not have
-               // to read this.
-               // But insets should read it, it is a part of
-               // the inset isn't it? Lgb.
-       } else if (token == "\\begin_inset") {
-               readInset(lex, pit, pos, font, current_change);
-       } else if (token == "\\family") {
-               lex.next();
-               font.setLyXFamily(lex.getString());
-       } else if (token == "\\series") {
-               lex.next();
-               font.setLyXSeries(lex.getString());
-       } else if (token == "\\shape") {
-               lex.next();
-               font.setLyXShape(lex.getString());
-       } else if (token == "\\size") {
-               lex.next();
-               font.setLyXSize(lex.getString());
-       } else if (token == "\\lang") {
-               lex.next();
-               string const tok = lex.getString();
-               Language const * lang = languages.getLanguage(tok);
-               if (lang) {
-                       font.setLanguage(lang);
-               } else {
-                       font.setLanguage(params.language);
-                       lex.printError("Unknown language `$$Token'");
-               }
-       } else if (token == "\\numeric") {
-               lex.next();
-               font.setNumber(font.setLyXMisc(lex.getString()));
-       } else if (token == "\\emph") {
-               lex.next();
-               font.setEmph(font.setLyXMisc(lex.getString()));
-       } else if (token == "\\bar") {
-               lex.next();
-               string const tok = lex.getString();
-               // This is dirty, but gone with LyX3. (Asger)
-               if (tok == "under")
-                       font.setUnderbar(LyXFont::ON);
-               else if (tok == "no")
-                       font.setUnderbar(LyXFont::OFF);
-               else if (tok == "default")
-                       font.setUnderbar(LyXFont::INHERIT);
-               else
-                       lex.printError("Unknown bar font flag "
-                                      "`$$Token'");
-       } else if (token == "\\noun") {
-               lex.next();
-               font.setNoun(font.setLyXMisc(lex.getString()));
-       } else if (token == "\\color") {
-               lex.next();
-               font.setLyXColor(lex.getString());
-       } else if (token == "\\SpecialChar") {
-               LyXLayout_ptr const & layout = pit->layout();
-
-               // Insets don't make sense in a free-spacing context! ---Kayvan
-               if (layout->free_spacing || pit->isFreeSpacing()) {
-                       if (lex.isOK()) {
-                               lex.next();
-                               string const next_token = lex.getString();
-                               if (next_token == "\\-") {
-                                       pit->insertChar(pos, '-', font, current_change);
-                               } else if (next_token == "~") {
-                                       pit->insertChar(pos, ' ', font, current_change);
-                               } else {
-                                       lex.printError("Token `$$Token' "
-                                                      "is in free space "
-                                                      "paragraph layout!");
-                                       --pos;
-                               }
-                       }
-               } else {
-                       Inset * inset = new InsetSpecialChar;
-                       inset->read(this, lex);
-                       pit->insertInset(pos, inset, font, current_change);
-               }
-               ++pos;
-       } else if (token == "\\i") {
-               Inset * inset = new InsetLatexAccent;
-               inset->read(this, lex);
-               pit->insertInset(pos, inset, font, current_change);
-               ++pos;
-       } else if (token == "\\backslash") {
-               pit->insertChar(pos, '\\', font, current_change);
-               ++pos;
+               // insert after
+               if (pit != pars.end())
+                       ++pit;
+               pit = pars.insert(pit, par);
        } else if (token == "\\begin_deeper") {
                ++depth;
        } else if (token == "\\end_deeper") {
                if (!depth) {
-                       lex.printError("\\end_deeper: "
-                                      "depth is already null");
-               }
-               else
+                       lex.printError("\\end_deeper: " "depth is already null");
+               } else {
                        --depth;
-               // do not delete this token, it is still needed!
-       } else if (token == "\\newline") {
-               pit->insertChar(pos, Paragraph::META_NEWLINE, font, current_change);
-               ++pos;
-       } else if (token == "\\LyXTable") {
-               Inset * inset = new InsetTabular(*this);
-               inset->read(this, lex);
-               pit->insertInset(pos, inset, font, current_change);
-               ++pos;
-       } else if (token == "\\bibitem") {  // ale970302
-               InsetCommandParams p("bibitem", "dummy");
-               InsetBibitem * inset = new InsetBibitem(p);
-               inset->read(this, lex);
-               pit->insertInset(pos, inset, font, current_change);
-               ++pos;
-       } else if (token == "\\hfill") {
-               pit->insertInset(pos, new InsetHFill(),
-                       LyXFont(LyXFont::ALL_INHERIT, params.language));
-               ++pos;
-       } else if (token == "\\change_unchanged") {
-               // Hack ! Needed for empty paragraphs :/
-               if (!pos)
-                       pit->cleanChanges();
-               current_change = Change(Change::UNCHANGED);
-       } else if (token == "\\change_inserted") {
-               lex.nextToken();
-               istringstream istr(lex.getString());
-               int aid;
-               lyx::time_type ct;
-               istr >> aid;
-               istr >> ct;
-               current_change = Change(Change::INSERTED, params.author_ids[aid], ct);
-       } else if (token == "\\change_deleted") {
-               lex.nextToken();
-               istringstream istr(lex.getString());
-               int aid;
-               lyx::time_type ct;
-               istr >> aid;
-               istr >> ct;
-               current_change = Change(Change::DELETED, params.author_ids[aid], ct);
+               }
        } else {
-               // This should be insurance for the future: (Asger)
                ++unknown;
-               lex.eatLine();
-#if USE_BOOST_FORMAT
-               boost::format fmt(_("Unknown token: %1$s %2$s\n"));
-               fmt % token % lex.text();
-               string const s = fmt.str();
-#else
-               string const s = _("Unknown token: ") + token
-                       + ' ' + lex.text() + '\n';
-#endif
-               // we can do this here this way because we're actually reading
-               // the buffer and don't care about LyXText right now.
-               InsetError * new_inset = new InsetError(s);
-               pit->insertInset(pos, new_inset, LyXFont(LyXFont::ALL_INHERIT,
-                                params.language));
-
        }
-
        return unknown;
 }
 
@@ -777,128 +504,6 @@ void Buffer::insertStringAsLines(Paragraph *& par, pos_type & pos,
 }
 
 
-void Buffer::readInset(LyXLex & lex, ParagraphList::iterator pit,
-                      int & pos, LyXFont & font, Change current_change)
-{
-       // consistency check
-       if (lex.getString() != "\\begin_inset") {
-               lyxerr << "Buffer::readInset: Consistency check failed."
-                      << endl;
-       }
-
-       Inset * inset = 0;
-
-       lex.next();
-       string const tmptok = lex.getString();
-
-       // test the different insets
-       if (tmptok == "LatexCommand") {
-               InsetCommandParams inscmd;
-               inscmd.read(lex);
-
-               string const cmdName = inscmd.getCmdName();
-
-               // This strange command allows LyX to recognize "natbib" style
-               // citations: citet, citep, Citet etc.
-               if (compare_ascii_no_case(cmdName.substr(0,4), "cite") == 0) {
-                       inset = new InsetCitation(inscmd);
-               } else if (cmdName == "bibitem") {
-                       lex.printError("Wrong place for bibitem");
-                       inset = new InsetBibitem(inscmd);
-               } else if (cmdName == "BibTeX") {
-                       inset = new InsetBibtex(inscmd);
-               } else if (cmdName == "index") {
-                       inset = new InsetIndex(inscmd);
-               } else if (cmdName == "include") {
-                       inset = new InsetInclude(inscmd, *this);
-               } else if (cmdName == "label") {
-                       inset = new InsetLabel(inscmd);
-               } else if (cmdName == "url"
-                          || cmdName == "htmlurl") {
-                       inset = new InsetUrl(inscmd);
-               } else if (cmdName == "ref"
-                          || cmdName == "pageref"
-                          || cmdName == "vref"
-                          || cmdName == "vpageref"
-                          || cmdName == "prettyref") {
-                       if (!inscmd.getOptions().empty()
-                           || !inscmd.getContents().empty()) {
-                               inset = new InsetRef(inscmd, *this);
-                       }
-               } else if (cmdName == "tableofcontents") {
-                       inset = new InsetTOC(inscmd);
-               } else if (cmdName == "listofalgorithms") {
-                       inset = new InsetFloatList("algorithm");
-               } else if (cmdName == "listoffigures") {
-                       inset = new InsetFloatList("figure");
-               } else if (cmdName == "listoftables") {
-                       inset = new InsetFloatList("table");
-               } else if (cmdName == "printindex") {
-                       inset = new InsetPrintIndex(inscmd);
-               } else if (cmdName == "lyxparent") {
-                       inset = new InsetParent(inscmd, *this);
-               }
-       } else {
-               if (tmptok == "Quotes") {
-                       inset = new InsetQuotes;
-               } else if (tmptok == "External") {
-                       inset = new InsetExternal;
-               } else if (tmptok == "FormulaMacro") {
-                       inset = new InsetFormulaMacro;
-               } else if (tmptok == "Formula") {
-                       inset = new InsetFormula;
-               } else if (tmptok == "Graphics") {
-                       inset = new InsetGraphics;
-               } else if (tmptok == "Note") {
-                       inset = new InsetNote(params);
-               } else if (tmptok == "Include") {
-                       InsetCommandParams p("Include");
-                       inset = new InsetInclude(p, *this);
-               } else if (tmptok == "ERT") {
-                       inset = new InsetERT(params);
-               } else if (tmptok == "Tabular") {
-                       inset = new InsetTabular(*this);
-               } else if (tmptok == "Text") {
-                       inset = new InsetText(params);
-               } else if (tmptok == "Foot") {
-                       inset = new InsetFoot(params);
-               } else if (tmptok == "Marginal") {
-                       inset = new InsetMarginal(params);
-               } else if (tmptok == "OptArg") {
-                       inset = new InsetOptArg(params);
-               } else if (tmptok == "Minipage") {
-                       inset = new InsetMinipage(params);
-               } else if (tmptok == "Float") {
-                       lex.next();
-                       string tmptok = lex.getString();
-                       inset = new InsetFloat(params, tmptok);
-               } else if (tmptok == "Wrap") {
-                       lex.next();
-                       string tmptok = lex.getString();
-                       inset = new InsetWrap(params, 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(params);
-               } else if (tmptok == "FloatList") {
-                       inset = new InsetFloatList;
-               }
-
-               if (inset)
-                       inset->read(this, lex);
-       }
-
-       if (inset) {
-               pit->insertInset(pos, inset, font, current_change);
-               ++pos;
-       }
-}
-
-
 bool Buffer::readFile(LyXLex & lex, string const & filename)
 {
        return readFile(lex, filename, paragraphs.begin());
index 46cd4b0afb8e1f604e2c461961f9d9514cfbd914..9f749f4969b0bd5c8cd9e1156c89095ea54e41e7 100644 (file)
@@ -112,11 +112,9 @@ public:
        bool readBody(LyXLex &, ParagraphList::iterator pit);
 
        /// This parses a single token
-       int readToken(LyXLex &, ParagraphList & pars,
-                     ParagraphList::iterator & pit,
-                     string const & token, int & pos,
-                     Paragraph::depth_type & depth,
-                     LyXFont &);
+       int readParagraph(LyXLex &, string const & token,
+                     ParagraphList & pars, ParagraphList::iterator & pit,
+                     Paragraph::depth_type & depth);
 
        ///
        void insertStringAsLines(Paragraph *&, lyx::pos_type &,
@@ -124,10 +122,6 @@ public:
        ///
        Paragraph * getParFromID(int id) const;
 
-private:
-       /// Parse a single inset.
-       void readInset(LyXLex &, ParagraphList::iterator pit, int & pos, LyXFont &, Change current_change);
-
 public:
        /** Save file.
            Takes care of auto-save files and backup file if requested.
index 8354e7d23fbe65d299aaaf9819d8200d8fbc2701..3fc1794eb135b0dcc081e40dd57b721eeb102ff1 100644 (file)
@@ -189,8 +189,7 @@ string const BufferParams::readToken(LyXLex & lex, string const & token)
                istringstream ss(lex.getString());
                Author a;
                ss >> a;
-               int aid(authorlist.record(a));
-               author_ids.push_back(aid);
+               authorlist.record(a);
        } else if (token == "\\paperorientation") {
                int tmpret = lex.findToken(string_orientation);
                if (tmpret == -1)
index 370b160179acd5136eb346dd5c767ba661ad5fd1..8be76a23d0961713c3ac5e4b4b7e8951c3329b2b 100644 (file)
@@ -231,10 +231,8 @@ public:
        bool tracking_changes;
        /// Time ago we agreed that this was a buffer property [ale990407]
        string parentname;
-private:
-       /// mapping of author IDs
-       std::vector<int> author_ids;
 
+private:
        /// the author list
        AuthorList authorlist;
 
index f8fb8bf52223d2ec3cad4993e212241b9d10d581..24cd050bfd7e938982e965e466888543cb7ce3d0 100644 (file)
@@ -17,6 +17,7 @@
 #include "debug.h"
 #include "BufferView.h"
 #include "lyxtext.h"
+#include "lyxlex.h"
 
 #include "insets/insetbibitem.h"
 #include "insets/insetbibtex.h"
@@ -25,6 +26,7 @@
 #include "insets/insetert.h"
 #include "insets/insetexternal.h"
 #include "insets/insetfloat.h"
+#include "insets/insetfloatlist.h"
 #include "insets/insetfoot.h"
 #include "insets/insetgraphics.h"
 #include "insets/insethfill.h"
 #include "insets/insettoc.h"
 #include "insets/inseturl.h"
 #include "insets/insetwrap.h"
+#include "mathed/formulamacro.h"
+#include "mathed/formula.h"
 
 #include "frontends/Dialogs.h"
 #include "frontends/LyXView.h"
+#include "support/lstrings.h"
 
 #include <cstdio>
 
@@ -244,3 +249,121 @@ Inset * createInset(FuncRequest const & cmd)
 
        return 0;
 }
+
+
+Inset * readInset(LyXLex & lex, Buffer const & buf)
+{
+       // consistency check
+       if (lex.getString() != "\\begin_inset") {
+               lyxerr << "Buffer::readInset: Consistency check failed."
+                      << endl;
+       }
+
+       Inset * inset = 0;
+
+       lex.next();
+       string const tmptok = lex.getString();
+
+       // test the different insets
+       if (tmptok == "LatexCommand") {
+               InsetCommandParams inscmd;
+               inscmd.read(lex);
+
+               string const cmdName = inscmd.getCmdName();
+
+               // This strange command allows LyX to recognize "natbib" style
+               // citations: citet, citep, Citet etc.
+               if (compare_ascii_no_case(cmdName.substr(0,4), "cite") == 0) {
+                       inset = new InsetCitation(inscmd);
+               } else if (cmdName == "bibitem") {
+                       lex.printError("Wrong place for bibitem");
+                       inset = new InsetBibitem(inscmd);
+               } else if (cmdName == "BibTeX") {
+                       inset = new InsetBibtex(inscmd);
+               } else if (cmdName == "index") {
+                       inset = new InsetIndex(inscmd);
+               } else if (cmdName == "include") {
+                       inset = new InsetInclude(inscmd, buf);
+               } else if (cmdName == "label") {
+                       inset = new InsetLabel(inscmd);
+               } else if (cmdName == "url"
+                          || cmdName == "htmlurl") {
+                       inset = new InsetUrl(inscmd);
+               } else if (cmdName == "ref"
+                          || cmdName == "pageref"
+                          || cmdName == "vref"
+                          || cmdName == "vpageref"
+                          || cmdName == "prettyref") {
+                       if (!inscmd.getOptions().empty()
+                           || !inscmd.getContents().empty()) {
+                               inset = new InsetRef(inscmd, buf);
+                       }
+               } else if (cmdName == "tableofcontents") {
+                       inset = new InsetTOC(inscmd);
+               } else if (cmdName == "listofalgorithms") {
+                       inset = new InsetFloatList("algorithm");
+               } else if (cmdName == "listoffigures") {
+                       inset = new InsetFloatList("figure");
+               } else if (cmdName == "listoftables") {
+                       inset = new InsetFloatList("table");
+               } else if (cmdName == "printindex") {
+                       inset = new InsetPrintIndex(inscmd);
+               } else if (cmdName == "lyxparent") {
+                       inset = new InsetParent(inscmd, buf);
+               }
+       } else {
+               if (tmptok == "Quotes") {
+                       inset = new InsetQuotes;
+               } else if (tmptok == "External") {
+                       inset = new InsetExternal;
+               } else if (tmptok == "FormulaMacro") {
+                       inset = new InsetFormulaMacro;
+               } else if (tmptok == "Formula") {
+                       inset = new InsetFormula;
+               } else if (tmptok == "Graphics") {
+                       inset = new InsetGraphics;
+               } else if (tmptok == "Note") {
+                       inset = new InsetNote(buf.params);
+               } else if (tmptok == "Include") {
+                       InsetCommandParams p("Include");
+                       inset = new InsetInclude(p, buf);
+               } else if (tmptok == "ERT") {
+                       inset = new InsetERT(buf.params);
+               } else if (tmptok == "Tabular") {
+                       inset = new InsetTabular(buf);
+               } else if (tmptok == "Text") {
+                       inset = new InsetText(buf.params);
+               } else if (tmptok == "Foot") {
+                       inset = new InsetFoot(buf.params);
+               } else if (tmptok == "Marginal") {
+                       inset = new InsetMarginal(buf.params);
+               } else if (tmptok == "OptArg") {
+                       inset = new InsetOptArg(buf.params);
+               } else if (tmptok == "Minipage") {
+                       inset = new InsetMinipage(buf.params);
+               } else if (tmptok == "Float") {
+                       lex.next();
+                       string tmptok = lex.getString();
+                       inset = new InsetFloat(buf.params, tmptok);
+               } else if (tmptok == "Wrap") {
+                       lex.next();
+                       string tmptok = lex.getString();
+                       inset = new InsetWrap(buf.params, 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(buf.params);
+               } else if (tmptok == "FloatList") {
+                       inset = new InsetFloatList;
+               }
+
+               if (inset)
+                       inset->read(&buf, lex);
+       }
+
+       return inset;
+}
index 1c25480fdcd99f1eb7efee15161e7ebe72887a4c..772f28b0222024a7fb6d617f0581aabed792d7e5 100644 (file)
 
 class Inset;
 class FuncRequest;
+class LyXLex;
+class Buffer;
 
 /// creates inset according to 'cmd'
 Inset * createInset(FuncRequest const & cmd);
 
-#endif
+/// read inset from a file
+Inset * readInset(LyXLex & lex, Buffer const & buf);
+
+#endif // FACTORY_H
index e4e72e100ca5b1b913707862d0ad7aac893ff811..c6db5cab60dae0da367d49e0b4d69b85435c4b46 100644 (file)
@@ -1,3 +1,7 @@
+2003-03-12  John Levon  <levon@movementarian.org>
+
+       * insettext.C: readToken became readParagraph
+
 2003-03-12  John Levon  <levon@movementarian.org>
 
        * insettext.C: use parlist iterator for reading contents
index 43d6badf464b8e4809db50be4bfce7a8646c5ca4..1f1a1e24400e4098a56b20ae08e4cbcd2e7b3123 100644 (file)
@@ -261,9 +261,7 @@ void InsetText::writeParagraphData(Buffer const * buf, ostream & os) const
 void InsetText::read(Buffer const * buf, LyXLex & lex)
 {
        string token;
-       int pos = 0;
        Paragraph::depth_type depth = 0;
-       LyXFont font(LyXFont::ALL_INHERIT);
 
        clear(false);
 
@@ -289,9 +287,7 @@ void InsetText::read(Buffer const * buf, LyXLex & lex)
                }
 
                // FIXME: ugly.
-
-               const_cast<Buffer*>(buf)->readToken(lex, paragraphs, pit,
-                                                   token, pos, depth, font);
+               const_cast<Buffer*>(buf)->readParagraph(lex, token, paragraphs, pit, depth);
        }
 
        pit = paragraphs.begin();
index a7b5c4546b7fab1326517057326eded97333d029..04081b6195e6424501e9d97ccfadce3ad2efa118 100644 (file)
 #include "ParagraphParameters.h"
 #include "lyxtextclasslist.h"
 #include "debug.h"
+#include "gettext.h"
 #include "language.h"
 #include "encoding.h"
 #include "lyxrc.h"
+#include "lyxlex.h"
+#include "BoostFormat.h"
+#include "factory.h"
 #include "support/lstrings.h"
 #include "insets/insetoptarg.h"
+#include "insets/insetcommandparams.h"
+#include "insets/insetbibitem.h"
+#include "insets/insetspecialchar.h"
+#include "insets/insetlatexaccent.h"
+#include "insets/insettabular.h"
+#include "insets/insethfill.h"
+#include "insets/inseterror.h"
 
 extern string bibitemWidest(Buffer const *);
 
@@ -714,3 +725,285 @@ void latexParagraphs(Buffer const * buf,
                texrow.newline();
        }
 }
+
+
+namespace {
+
+int readParToken(Buffer & buf, Paragraph & par, LyXLex & lex, string const & token)
+{
+       static LyXFont font;
+       static Change change;
+
+       BufferParams const & bp = buf.params;
+
+       if (token[0] != '\\') {
+               string::const_iterator cit = token.begin();
+               for (; cit != token.end(); ++cit) {
+                       par.insertChar(par.size(), (*cit), font, change);
+               }
+       } else if (token == "\\layout") {
+               lex.eatLine();
+               string layoutname = lex.getString();
+
+               font = LyXFont(LyXFont::ALL_INHERIT, bp.language);
+               change = Change();
+
+               LyXTextClass const & tclass = bp.getLyXTextClass();
+
+               if (layoutname.empty()) {
+                       layoutname = tclass.defaultLayoutName();
+               }
+
+               bool hasLayout = tclass.hasLayout(layoutname);
+
+               if (!hasLayout) {
+                       lyxerr << "Layout '" << layoutname << "' does not"
+                              << " exist in textclass '" << tclass.name()
+                              << "'." << endl;
+                       lyxerr << "Trying to use default layout instead."
+                              << endl;
+                       layoutname = tclass.defaultLayoutName();
+               }
+
+#ifdef USE_CAPTION
+               // The is the compability reading of layout caption.
+               if (compare_ascii_no_case(layoutname, "caption") == 0) {
+                       // We expect that the par we are now working on is
+                       // really inside a InsetText inside a InsetFloat.
+                       // We also know that captions can only be
+                       // one paragraph. (Lgb)
+
+                       // We should now read until the next "\layout"
+                       // is reached.
+                       // This is probably not good enough, what if the
+                       // caption is the last par in the document (Lgb)
+                       istream & ist = lex.getStream();
+                       stringstream ss;
+                       string line;
+                       int begin = 0;
+                       while (true) {
+                               getline(ist, line);
+                               if (prefixIs(line, "\\layout")) {
+                                       lex.pushToken(line);
+                                       break;
+                               }
+                               if (prefixIs(line, "\\begin_inset"))
+                                       ++begin;
+                               if (prefixIs(line, "\\end_inset")) {
+                                       if (begin)
+                                               --begin;
+                                       else {
+                                               lex.pushToken(line);
+                                               break;
+                                       }
+                               }
+
+                               ss << line << '\n';
+                       }
+
+                       // Now we should have the whole layout in ss
+                       // we should now be able to give this to the
+                       // caption inset.
+                       ss << "\\end_inset\n";
+
+                       // This seems like a bug in stringstream.
+                       // We really should be able to use ss
+                       // directly. (Lgb)
+                       istringstream is(ss.str());
+                       LyXLex tmplex(0, 0);
+                       tmplex.setStream(is);
+                       Inset * inset = new InsetCaption;
+                       inset->Read(this, tmplex);
+                       par.insertInset(pos, inset, font);
+                       ++pos;
+               } else {
+#endif
+                       par.layout(bp.getLyXTextClass()[layoutname]);
+
+                       // Test whether the layout is obsolete.
+                       LyXLayout_ptr const & layout = par.layout();
+                       if (!layout->obsoleted_by().empty())
+                               par.layout(bp.getLyXTextClass()[layout->obsoleted_by()]);
+
+                       par.params().read(lex);
+#if USE_CAPTION
+               }
+#endif
+
+       } else if (token == "\\end_inset") {
+               lyxerr << "Solitary \\end_inset in line " << lex.getLineNo() << "\n"
+                      << "Missing \\begin_inset?.\n";
+               // Simply ignore this. The insets do not have
+               // to read this.
+               // But insets should read it, it is a part of
+               // the inset isn't it? Lgb.
+       } else if (token == "\\begin_inset") {
+               Inset * i = readInset(lex, buf);
+               par.insertInset(par.size(), i, font, change);
+       } else if (token == "\\family") {
+               lex.next();
+               font.setLyXFamily(lex.getString());
+       } else if (token == "\\series") {
+               lex.next();
+               font.setLyXSeries(lex.getString());
+       } else if (token == "\\shape") {
+               lex.next();
+               font.setLyXShape(lex.getString());
+       } else if (token == "\\size") {
+               lex.next();
+               font.setLyXSize(lex.getString());
+       } else if (token == "\\lang") {
+               lex.next();
+               string const tok = lex.getString();
+               Language const * lang = languages.getLanguage(tok);
+               if (lang) {
+                       font.setLanguage(lang);
+               } else {
+                       font.setLanguage(bp.language);
+                       lex.printError("Unknown language `$$Token'");
+               }
+       } else if (token == "\\numeric") {
+               lex.next();
+               font.setNumber(font.setLyXMisc(lex.getString()));
+       } else if (token == "\\emph") {
+               lex.next();
+               font.setEmph(font.setLyXMisc(lex.getString()));
+       } else if (token == "\\bar") {
+               lex.next();
+               string const tok = lex.getString();
+
+               if (tok == "under")
+                       font.setUnderbar(LyXFont::ON);
+               else if (tok == "no")
+                       font.setUnderbar(LyXFont::OFF);
+               else if (tok == "default")
+                       font.setUnderbar(LyXFont::INHERIT);
+               else
+                       lex.printError("Unknown bar font flag "
+                                      "`$$Token'");
+       } else if (token == "\\noun") {
+               lex.next();
+               font.setNoun(font.setLyXMisc(lex.getString()));
+       } else if (token == "\\color") {
+               lex.next();
+               font.setLyXColor(lex.getString());
+       } else if (token == "\\SpecialChar") {
+               LyXLayout_ptr const & layout = par.layout();
+
+               // Insets don't make sense in a free-spacing context! ---Kayvan
+               if (layout->free_spacing || par.isFreeSpacing()) {
+                       if (lex.isOK()) {
+                               lex.next();
+                               string const next_token = lex.getString();
+                               if (next_token == "\\-") {
+                                       par.insertChar(par.size(), '-', font, change);
+                               } else if (next_token == "~") {
+                                       par.insertChar(par.size(), ' ', font, change);
+                               } else {
+                                       lex.printError("Token `$$Token' "
+                                                      "is in free space "
+                                                      "paragraph layout!");
+                               }
+                       }
+               } else {
+                       Inset * inset = new InsetSpecialChar;
+                       inset->read(&buf, lex);
+                       par.insertInset(par.size(), inset, font, change);
+               }
+       } else if (token == "\\i") {
+               Inset * inset = new InsetLatexAccent;
+               inset->read(&buf, lex);
+               par.insertInset(par.size(), inset, font, change);
+       } else if (token == "\\backslash") {
+               par.insertChar(par.size(), '\\', font, change);
+       // do not delete this token, it is still needed!
+       } else if (token == "\\newline") {
+               par.insertChar(par.size(), Paragraph::META_NEWLINE, font, change);
+       } else if (token == "\\LyXTable") {
+               Inset * inset = new InsetTabular(buf);
+               inset->read(&buf, lex);
+               par.insertInset(par.size(), inset, font, change);
+       } else if (token == "\\bibitem") {
+               InsetCommandParams p("bibitem", "dummy");
+               InsetBibitem * inset = new InsetBibitem(p);
+               inset->read(&buf, lex);
+               par.insertInset(par.size(), inset, font, change);
+       } else if (token == "\\hfill") {
+               par.insertInset(par.size(), new InsetHFill(), font, change);
+       } else if (token == "\\change_unchanged") {
+               // Hack ! Needed for empty paragraphs :/
+               // FIXME: is it still ??
+               if (!par.size())
+                       par.cleanChanges();
+               change = Change(Change::UNCHANGED);
+       } else if (token == "\\change_inserted") {
+               lex.nextToken();
+               istringstream istr(lex.getString());
+               int aid;
+               lyx::time_type ct;
+               istr >> aid;
+               istr >> ct;
+               change = Change(Change::INSERTED, aid, ct);
+       } else if (token == "\\change_deleted") {
+               lex.nextToken();
+               istringstream istr(lex.getString());
+               int aid;
+               lyx::time_type ct;
+               istr >> aid;
+               istr >> ct;
+               change = Change(Change::DELETED, aid, ct);
+       } else {
+               lex.eatLine();
+#if USE_BOOST_FORMAT
+               boost::format fmt(_("Unknown token: %1$s %2$s\n"));
+               fmt % token % lex.text();
+               string const s = fmt.str();
+#else
+               string const s = _("Unknown token: ") + token
+                       + ' ' + lex.text() + '\n';
+#endif
+               // we can do this here this way because we're actually reading
+               // the buffer and don't care about LyXText right now.
+               InsetError * inset = new InsetError(s);
+               par.insertInset(par.size(), inset, font);
+               return 1;
+       }
+       return 0;
+}
+
+}
+
+
+int readParagraph(Buffer & buf, Paragraph & par, LyXLex & lex)
+{
+       int unknown = 0;
+
+       lex.nextToken();
+       string token = lex.getString();
+
+       while (lex.isOK()) {
+
+               unknown += readParToken(buf, par, lex, token);
+
+               lex.nextToken();
+               token = lex.getString();
+
+               if (token.empty())
+                       continue;
+
+               lyxerr[Debug::PARSER] << "Handling paragraph token: `"
+                                     << token << '\'' << endl;
+
+               // reached the next paragraph. FIXME: really we should
+               // change the file format to indicate the end of a par
+               // clearly, but for now, this hack will do
+               if (token == "\\layout" || token == "\\the_end"
+                   || token == "\\end_inset" || token == "\\begin_deeper"
+                   || token == "\\end_deeper") {
+                       lex.pushToken(token);
+                       break;
+               }
+       }
+
+       return unknown;
+}
index 23c8cdd78f3c8d9fc40114771cd96bda7aa1a6fa..6430e3de113ffe3770144a05283da57662ff97be 100644 (file)
@@ -19,6 +19,7 @@ class Buffer;
 class BufferParams;
 class Paragraph;
 class TexRow;
+class LyXLex;
 
 ///
 void breakParagraph(BufferParams const & bparams,
@@ -86,4 +87,7 @@ void latexParagraphs(Buffer const * buf,
                     TexRow & texrow,
                     bool moving_arg = false);
 
+/// read a paragraph from a .lyx file. Returns number of unrecognised tokens
+int readParagraph(Buffer & buf, Paragraph & par, LyXLex & lex);
+
 #endif // PARAGRAPH_FUNCS_H
index 78234ba3d8981b2f53393d16ec6435aea26d788e..0562d9c06f93f4d77aca298ff1c83aa8ceff383b 100644 (file)
@@ -1447,10 +1447,7 @@ void LyXTabular::OldFormatRead(BufferParams const & bp,
        set_row_column_number_info(true);
 
        string tmptok;
-       int pos = 0;
        Paragraph::depth_type depth = 0;
-       LyXFont font(LyXFont::ALL_INHERIT);
-       font.setLanguage(owner_->bufferOwner()->getLanguage());
 
        ParagraphList parlist;
        ParagraphList::iterator pit = parlist.begin();
@@ -1474,9 +1471,7 @@ void LyXTabular::OldFormatRead(BufferParams const & bp,
                        break;
                }
 
-               owner_->bufferOwner()->readToken(lex, parlist, pit,
-                                                token, pos, depth, font);
-
+               owner_->bufferOwner()->readParagraph(lex, token, parlist, pit, depth);
        }
 
        Paragraph * par = &(*parlist.begin());