+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:
#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"
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);
} 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
continue;
}
- unknown_tokens += readToken(lex, paragraphs, pit, token, pos, depth, font);
+ unknown_tokens += readParagraph(lex, token, paragraphs, pit, depth);
}
if (unknown_layouts > 0) {
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;
}
}
-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());
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 &,
///
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.
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)
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;
#include "debug.h"
#include "BufferView.h"
#include "lyxtext.h"
+#include "lyxlex.h"
#include "insets/insetbibitem.h"
#include "insets/insetbibtex.h"
#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>
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;
+}
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
+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
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);
}
// 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();
#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 *);
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;
+}
class BufferParams;
class Paragraph;
class TexRow;
+class LyXLex;
///
void breakParagraph(BufferParams const & bparams,
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
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();
break;
}
- owner_->bufferOwner()->readToken(lex, parlist, pit,
- token, pos, depth, font);
-
+ owner_->bufferOwner()->readParagraph(lex, token, parlist, pit, depth);
}
Paragraph * par = &(*parlist.begin());