mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-22 21:21:32 +00:00
The final parsing patch. Tested on a variety of weird and wonderful things
without finding a regression (yet !) :) git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@6465 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
d5abf45c1d
commit
b4f4f487d1
@ -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:
|
||||
|
439
src/buffer.C
439
src/buffer.C
@ -47,40 +47,11 @@
|
||||
#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);
|
||||
if (token == "\\layout") {
|
||||
lex.pushToken(token);
|
||||
|
||||
lex.eatLine();
|
||||
string layoutname = lex.getString();
|
||||
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);
|
||||
|
||||
LyXTextClass const & tclass = params.getLyXTextClass();
|
||||
// FIXME: goddamn InsetTabular makes us pass a Buffer
|
||||
// not BufferParams
|
||||
unknown += ::readParagraph(*this, *par, lex);
|
||||
|
||||
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.
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
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());
|
||||
|
12
src/buffer.h
12
src/buffer.h
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
||||
|
123
src/factory.C
123
src/factory.C
@ -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"
|
||||
@ -42,9 +44,12 @@
|
||||
#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;
|
||||
}
|
||||
|
@ -14,8 +14,13 @@
|
||||
|
||||
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
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -16,11 +16,22 @@
|
||||
#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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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());
|
||||
|
Loading…
Reference in New Issue
Block a user