/* This file is part of * ====================================================== * * LyX, The Document Processor * * Copyright (C) 1995 Matthias Ettrich * Copyright (C) 1995-1998 The LyX Team. * * This file is Copyright (C) 1996-1998 * Lars Gullik Bjønnes * *======================================================
*/ #include <config.h>
// Uncomment this line to enable a workaround for the weird behaviour // of the cursor between a displayed inset and last character // at the upper line. (Alejandro 20.9.96) // #define BREAK_BEFORE_INSET
/* Lars, when changing this file sometime in the future to a list, * please check out the figinsets-sideeffects described at the * beginning of figinset.C Matthias (04.07.1996)
*/
// all these externs should eventually be removed. extern BufferList bufferlist; externvoid SmallUpdate(signedchar); externunsignedchar GetCurrentTextClass(); externvoid BeforeChange();
// Use the current buffer's parameters as default
defaults.params.Copy(params); // add an empty paragraph. Is this enough?
defaults.paragraph = new LyXParagraph();
/// Update window titles of all users // Should work on a list void Buffer::updateTitles()
{ if (users) users->getOwner()->updateWindowTitle();
}
/// Reset autosave timer of all users // Should work on a list void Buffer::resetAutosaveTimers()
{ if (users) users->getOwner()->resetAutosaveTimer();
}
void Buffer::InsetUnlock()
{ if (the_locking_inset) { if (!inset_slept) the_locking_inset->InsetUnlock();
the_locking_inset = NULL;
text->FinishUndo();
inset_slept = false;
}
}
// Inserts a file into current document bool Buffer::insertLyXFile(LString const & filen) // // (c) CHT Software Service GmbH // Uwe C. Schroeder // // Insert a Lyxformat - file into current buffer // // Moved from lyx_cb.C (Lgb)
{ if (filen.empty()) returnfalse;
LString filename = MakeAbsPath(filen);
// check if file exist
FileInfo fi(filename);
if (!fi.exist() || !fi.readable()) {
WriteAlert(_("Error!"),
_("Cannot open specified file:"),
MakeDisplayPath(filename,50)); returnfalse;
}
BeforeChange();
FilePtr myfile(filename, FilePtr::read); if (!myfile()) {
WriteAlert(_("Error!"),
_("Cannot open specified file:"),
MakeDisplayPath(filename,50)); returnfalse;
}
LyXLex lex(NULL, 0);
lex.setFile(myfile); int c = fgetc(myfile());
ungetc(c, myfile);
bool res = true;
if (c=='#') {
lyxerr.debug("Will insert file with header");
res = readFile(lex, text->cursor.par);
} else {
lyxerr.debug("Will insert file without header");
res = readLyXformat2(lex, text->cursor.par);
}
resize(); return res;
}
// // Uwe C. Schroeder // changed to be public and have one parameter // if par = NULL normal behavior // else insert behavior // Returns false if "\the_end" is not read for formats >= 2.13. (Asger) bool Buffer::readLyXformat2(LyXLex &lex, LyXParagraph *par)
{
LString tmptok;
Inset *inset = 0; int pos = 0; int tmpret, tmpret2; char depth = 0; // signed or unsigned?
LyXParagraph::footnote_flag footnoteflag = LyXParagraph::NO_FOOTNOTE;
LyXParagraph::footnote_kind footnotekind = LyXParagraph::FOOTNOTE; bool the_end_read = false;
LyXParagraph *return_par = NULL;
LyXFont font = LyXFont(LyXFont::ALL_INHERIT);
// If we are inserting, we cheat and get a token in advance bool has_token = false;
LString pretoken;
if(!par) {
par = new LyXParagraph();
} else {
text->BreakParagraph();
return_par = text->FirstParagraph();
pos=0;
markDirty(); // We don't want to adopt the parameters from the // document we insert, so we skip until the text begins: while (lex.IsOK()) {
lex.nextToken();
pretoken = lex.GetString(); if (pretoken == "\\layout") {
has_token = true; break;
}
}
}
while (lex.IsOK()) { if (has_token) {
has_token = false;
} else {
lex.nextToken();
pretoken = lex.GetString();
}
// Profiling show this should give a lot: (Asger)
LString const token = pretoken;
if (token.empty()) continue; elseif (token[0] != '\\') { int n = token.length(); for (int i=0; i < n; i++) {
par->InsertChar(pos, token[i]);
par->SetFont(pos, font);
pos++;
}
} elseif (token == "\\i") {
inset = new InsetLatexAccent;
inset->Read(lex);
par->InsertChar(pos, LYX_META_INSET);
par->InsertInset(pos, inset);
par->SetFont(pos, font);
pos++;
} elseif (token == "\\layout") { if (!return_par)
return_par = par; else
par = new LyXParagraph(par);
pos = 0;
lex.EatLine();
par->layout =
lyxstyle.NumberOfLayout(params.textclass,
lex.GetString()); if (par->layout == -1) // layout not found // use default layout "Standard" (0)
par->layout = 0; // Test whether the layout is obsolete.
LyXLayout* layout = lyxstyle.Style(params.textclass,
par->layout); if (!layout->obsoleted_by.empty())
par->layout =
lyxstyle.NumberOfLayout(params.textclass,
layout->obsoleted_by);
par->footnoteflag = footnoteflag;
par->footnotekind = footnotekind;
par->depth = depth;
font = LyXFont(LyXFont::ALL_INHERIT);
} elseif (token == "\\end_float") { if (!return_par)
return_par = par; else
par = new LyXParagraph(par);
footnotekind = LyXParagraph::FOOTNOTE;
footnoteflag = LyXParagraph::NO_FOOTNOTE;
pos = 0;
lex.EatLine();
par->layout = LYX_DUMMY_LAYOUT;
font = LyXFont(LyXFont::ALL_INHERIT);
} elseif (token == "\\begin_float") {
tmpret = lex.FindToken(string_footnotekinds); if (tmpret == -1) tmpret++; if (tmpret != LYX_LAYOUT_DEFAULT)
footnotekind = (LyXParagraph::footnote_kind)tmpret; // bad if (footnotekind == LyXParagraph::FOOTNOTE
|| footnotekind == LyXParagraph::MARGIN)
footnoteflag = LyXParagraph::CLOSED_FOOTNOTE; else
footnoteflag = LyXParagraph::OPEN_FOOTNOTE;
} elseif (token == "\\begin_deeper") {
depth++;
} elseif (token == "\\end_deeper") { if (!depth) {
lex.printError("\\end_deeper: " "depth is already null");
} else
depth--;
} elseif (token == "\\begin_preamble") {
params.readPreamble(lex);
} elseif (token == "\\textclass") {
lex.EatLine();
params.textclass = lyxstyle.NumberOfClass(lex.GetString()); if (params.textclass == -1) {
lex.printError("Unknown textclass `$$Token'");
params.textclass = 0;
} if (!lyxstyle.Load(params.textclass)) { // if the textclass wasn't loaded properly // we need to either substitute another // or stop loading the file. // I can substitute but I don't see how I can // stop loading... ideas?? ARRae980418
WriteAlert(_("Textclass Loading Error!"),
LString(_("Can't load textclass ")) +
lyxstyle.NameOfClass(params.textclass),
_("-- substituting default"));
params.textclass = 0;
}
} elseif (token == "\\options") {
lex.EatLine();
params.options = lex.GetString();
} elseif (token == "\\language") {
params.readLanguage(lex);
} elseif (token == "\\fontencoding") {
lex.EatLine();
} elseif (token == "\\inputencoding") {
lex.EatLine();
params.inputenc = lex.GetString();
} elseif (token == "\\graphics") {
params.readGraphicsDriver(lex);
} elseif (token == "\\fontscheme") {
lex.EatLine();
params.fonts = lex.GetString();
} elseif (token == "\\noindent") {
par->noindent = true;
} elseif (token == "\\fill_top") {
par->added_space_top = VSpace::VFILL;
} elseif (token == "\\fill_bottom") {
par->added_space_bottom = VSpace::VFILL;
} elseif (token == "\\line_top") {
par->line_top = true;
} elseif (token == "\\line_bottom") {
par->line_bottom = true;
} elseif (token == "\\pagebreak_top") {
par->pagebreak_top = true;
} elseif (token == "\\pagebreak_bottom") {
par->pagebreak_bottom = true;
} elseif (token == "\\start_of_appendix") {
par->start_of_appendix = true;
} elseif (token == "\\paragraph_separation") {
tmpret = lex.FindToken(string_paragraph_separation); if (tmpret == -1) tmpret++; if (tmpret != LYX_LAYOUT_DEFAULT)
params.paragraph_separation = tmpret;
} elseif (token == "\\defskip") {
lex.nextToken();
params.defskip = VSpace(lex.GetString());
} elseif (token == "\\no_isolatin1") {
lex.nextToken();
} elseif (token == "\\no_babel") {
lex.nextToken();
} elseif (token == "\\no_epsfig") {
lex.nextToken();
} elseif (token == "\\epsfig") { // obsolete // Indeed it is obsolete, but we HAVE to be backwards // compatible until 0.14, because otherwise all figures // in existing documents are irretrivably lost. (Asger)
params.readGraphicsDriver(lex);
} elseif (token == "\\quotes_language") {
tmpret = lex.FindToken(string_quotes_language); if (tmpret == -1) tmpret++; if (tmpret != LYX_LAYOUT_DEFAULT) {
InsetQuotes::quote_language tmpl =
InsetQuotes::EnglishQ; switch(tmpret) { case 0:
tmpl = InsetQuotes::EnglishQ; break; case 1:
tmpl = InsetQuotes::SwedishQ; break; case 2:
tmpl = InsetQuotes::GermanQ; break; case 3:
tmpl = InsetQuotes::PolishQ; break; case 4:
tmpl = InsetQuotes::FrenchQ; break; case 5:
tmpl = InsetQuotes::DanishQ; break;
}
params.quotes_language = tmpl;
}
} elseif (token == "\\quotes_times") {
lex.nextToken(); switch(lex.GetInteger()) { case 1:
params.quotes_times = InsetQuotes::SingleQ; break; case 2:
params.quotes_times = InsetQuotes::DoubleQ; break;
}
} elseif (token == "\\papersize") { if (format > 2.13)
tmpret = lex.FindToken(string_papersize); else
tmpret = lex.FindToken(string_oldpapersize); if (tmpret == -1)
tmpret++; else
params.papersize2 = tmpret;
} elseif (token == "\\paperpackage") {
tmpret = lex.FindToken(string_paperpackages); if (tmpret == -1) {
tmpret++;
params.paperpackage = PACKAGE_NONE;
} else
params.paperpackage = tmpret;
} elseif (token == "\\use_geometry") {
lex.nextToken();
params.use_geometry = lex.GetInteger();
} elseif (token == "\\use_amsmath") {
lex.nextToken();
params.use_amsmath = lex.GetInteger();
} elseif (token == "\\paperorientation") {
tmpret = lex.FindToken(string_orientation); if (tmpret == -1) tmpret++; if (tmpret != LYX_LAYOUT_DEFAULT)
params.orientation = tmpret;
} elseif (token == "\\paperwidth") {
lex.next();
params.paperwidth = lex.GetString();
} elseif (token == "\\paperheight") {
lex.next();
params.paperheight = lex.GetString();
} elseif (token == "\\leftmargin") {
lex.next();
params.leftmargin = lex.GetString();
} elseif (token == "\\topmargin") {
lex.next();
params.topmargin = lex.GetString();
} elseif (token == "\\rightmargin") {
lex.next();
params.rightmargin = lex.GetString();
} elseif (token == "\\bottommargin") {
lex.next();
params.bottommargin = lex.GetString();
} elseif (token == "\\headheight") {
lex.next();
params.headheight = lex.GetString();
} elseif (token == "\\headsep") {
lex.next();
params.headsep = lex.GetString();
} elseif (token == "\\footskip") {
lex.next();
params.footskip = lex.GetString();
} elseif (token == "\\paperfontsize") {
lex.nextToken();
params.fontsize = lex.GetString();
params.fontsize.strip();
} elseif (token == "\\papercolumns") {
lex.nextToken();
params.columns = lex.GetInteger();
} elseif (token == "\\papersides") {
lex.nextToken();
params.sides = lex.GetInteger();
} elseif (token == "\\paperpagestyle") {
lex.nextToken();
params.pagestyle = lex.GetString();
params.pagestyle.strip();
} elseif (token == "\\bullet") {
lex.nextToken(); int index = lex.GetInteger();
lex.nextToken(); int temp_int = lex.GetInteger();
params.user_defined_bullets[index].setFont(temp_int);
params.temp_bullets[index].setFont(temp_int);
lex.nextToken();
temp_int = lex.GetInteger();
params.user_defined_bullets[index].setCharacter(temp_int);
params.temp_bullets[index].setCharacter(temp_int);
lex.nextToken();
temp_int = lex.GetInteger();
params.user_defined_bullets[index].setSize(temp_int);
params.temp_bullets[index].setSize(temp_int);
lex.nextToken();
LString temp_str = lex.GetString(); if (temp_str != "\\end_bullet") { // this element isn't really necessary for // parsing but is easier for humans // to understand bullets. Put it back and // set a debug message?
lex.printError("\\end_bullet expected, got" + temp_str); //how can I put it back?
}
} elseif (token == "\\bulletLaTeX") {
lex.nextToken(); int index = lex.GetInteger();
lex.next();
LString temp_str = lex.GetString(), sum_str; while (temp_str != "\\end_bullet") { // this loop structure is needed when user // enters an empty string since the first // thing returned will be the \\end_bullet // OR // if the LaTeX entry has spaces. Each element // therefore needs to be read in turn
sum_str += temp_str;
lex.next();
temp_str = lex.GetString();
}
params.user_defined_bullets[index].setText(sum_str);
params.temp_bullets[index].setText(sum_str);
} elseif (token == "\\secnumdepth") {
lex.nextToken();
params.secnumdepth = lex.GetInteger();
} elseif (token == "\\tocdepth") {
lex.nextToken();
params.tocdepth = lex.GetInteger();
} elseif (token == "\\baselinestretch") { // now obsolete
lex.nextToken(); // should not be used directly // anymore. // Will probably keep a kind of support just for // compability.
params.spacing.set(Spacing::Other, lex.GetFloat());
} elseif (token == "\\spacing") {
lex.next();
LString tmp = lex.GetString().strip(); if (tmp == "single") {
params.spacing.set(Spacing::Single);
} elseif (tmp == "onehalf") {
params.spacing.set(Spacing::Onehalf);
} elseif (tmp == "double") {
params.spacing.set(Spacing::Double);
} elseif (tmp == "other") {
lex.next();
params.spacing.set(Spacing::Other,
lex.GetFloat());
} else {
lex.printError("Unknown spacing token: '$$Token'");
}
} elseif (token == "\\float_placement") {
lex.nextToken();
params.float_placement = lex.GetString();
} elseif (token == "\\cursor") { // this is obsolete, so we just skip it.
lex.nextToken();
} elseif (token == "\\family") {
lex.next();
font.setLyXFamily(lex.GetString());
} elseif (token == "\\series") {
lex.next();
font.setLyXSeries(lex.GetString());
} elseif (token == "\\shape") {
lex.next();
font.setLyXShape(lex.GetString());
} elseif (token == "\\size") {
lex.next();
font.setLyXSize(lex.GetString());
} elseif (token == "\\latex") {
lex.next();
LString tok = lex.GetString(); // This is dirty, but gone with LyX3. (Asger) if (tok == "no_latex")
font.setLatex(LyXFont::OFF); elseif (tok == "latex")
font.setLatex(LyXFont::ON); elseif (tok == "default")
font.setLatex(LyXFont::INHERIT); else
lex.printError("Unknown LaTeX font flag " "`$$Token'");
} elseif (token == "\\emph") {
lex.next();
font.setEmph(font.setLyXMisc(lex.GetString()));
} elseif (token == "\\bar") {
lex.next();
LString tok = lex.GetString(); // This is dirty, but gone with LyX3. (Asger) if (tok == "under")
font.setUnderbar(LyXFont::ON); elseif (tok == "no")
font.setUnderbar(LyXFont::OFF); elseif (tok == "default")
font.setUnderbar(LyXFont::INHERIT); else
lex.printError("Unknown bar font flag " "`$$Token'");
} elseif (token == "\\noun") {
lex.next();
font.setNoun(font.setLyXMisc(lex.GetString()));
} elseif (token == "\\color") {
lex.next();
font.setLyXColor(lex.GetString());
} elseif (token == "\\align") {
tmpret = lex.FindToken(string_align); if (tmpret == -1) tmpret++; if (tmpret != LYX_LAYOUT_DEFAULT) {
tmpret2 = 1; for (; tmpret>0; tmpret--)
tmpret2 = tmpret2 * 2;
par->align = tmpret2;
}
} elseif (token == "\\added_space_top"){
lex.nextToken();
par->added_space_top = lex.GetString();
} elseif (token == "\\added_space_bottom") {
lex.nextToken();
par->added_space_bottom = lex.GetString();
} elseif (token == "\\pextra_type") {
lex.nextToken();
par->pextra_type = lex.GetInteger();
} elseif (token == "\\pextra_width") {
lex.nextToken();
par->pextra_width = lex.GetString();
} elseif (token == "\\pextra_widthp") {
lex.nextToken();
par->pextra_widthp = lex.GetString();
} elseif (token == "\\pextra_alignment") {
lex.nextToken();
par->pextra_alignment = lex.GetInteger();
} elseif (token == "\\pextra_hfill") {
lex.nextToken();
par->pextra_hfill = lex.GetInteger();
} elseif (token == "\\pextra_start_minipage") {
lex.nextToken();
par->pextra_start_minipage = lex.GetInteger();
} elseif (token == "\\labelwidthstring") {
lex.EatLine();
par->labelwidthstring = lex.GetString(); /* do not delete this token, it is still needed! */
} elseif (token == "\\end_inset") { /* simple 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.
} elseif (token == "\\begin_inset") {
lex.next();
tmptok = lex.GetString(); /* test the different insets */ if (tmptok == "Quotes") {
inset = new InsetQuotes;
inset->Read(lex);
par->InsertChar(pos, LYX_META_INSET);
par->InsertInset(pos, inset);
par->SetFont(pos, font);
pos++;
} elseif (tmptok == "Latex") { // This one is on its way out
lex.EatLine();
tmptok = lex.GetString().strip(); //lyxerr.print(LString(tmptok[0])); if (tmptok[0] == '\\') { // then this latex is a // latex command
InsetCommand *tmpinset = new InsetCommand();
tmpinset->scanCommand(tmptok);
inset = tmpinset;
} else { // This should not use InsetLaTexDel // it should rather insert text into // the paragraph and mark it as tex.
inset = new InsetLatex(tmptok);
}
par->InsertChar(pos, LYX_META_INSET);
par->InsertInset(pos, inset);
par->SetFont(pos, font);
pos++;
} elseif (tmptok == "LatexDel") { // This one is on its way out...
lex.EatLine();
tmptok = lex.GetString().strip(); //lyxerr.print(LString(tmptok[0])); if (tmptok == "\\tableofcontents") {
inset = new InsetTOC(this);
} elseif (tmptok == "\\listoffigures") {
inset = new InsetLOF(this);
} elseif (tmptok == "\\listoftables") {
inset = new InsetLOT(this);
} elseif (tmptok == "\\listofalgorithms") {
inset = new InsetLOA(this);
} elseif (tmptok.contains("\\ref{")
|| tmptok.contains("\\pageref{")) {
LString cont,opt,tmptmptok,cmdname;
lex.next(); while(lex.IsOK() && lex.GetString() != "\\end_inset" ) {
lex.next();
}
lex.next(); while(lex.IsOK()) {
tmptmptok=lex.GetString(); if(tmptmptok[0] == '\\') { if( tmptmptok == "\\backslash")
opt += '\\'; else break;
} else
opt += tmptmptok;
opt += ' ';
lex.next();
} while(lex.IsOK() && lex.GetString() != "\\end_inset" ) {
lex.next();
}
lex.next(); while(lex.IsOK()) {
tmptmptok=lex.GetString(); if(tmptmptok[0] == '\\') { if( tmptmptok == "\\backslash")
cont += '\\'; else break;
} else
cont += tmptmptok;
cont += ' ';
lex.next();
} while(lex.IsOK() && lex.GetString() != "\\end_inset" ) {
lex.next();
}
cmdname = "\\"; if(tmptok.contains("\\ref{"))
cmdname += LString("ref"); else
cmdname += LString("pageref");
cont.strip();
opt.strip();
cmdname += "[" + cont + "]";
cmdname += "{" + opt + "}";
inset = new InsetRef(cmdname,this);
} elseif (tmptok.contains("\\url{")
|| tmptok.contains("\\htmlurl{")) {
LString cont,opt,tmptmptok,cmdname;
lex.next(); while(lex.IsOK() && lex.GetString() != "\\end_inset" ) {
lex.next();
}
lex.next(); while(lex.IsOK()) {
tmptmptok=lex.GetString(); if(tmptmptok[0] == '\\') { if( tmptmptok == "\\backslash")
opt += '\\'; else break;
} else
opt += tmptmptok;
opt += ' ';
lex.next();
} while(lex.IsOK() && lex.GetString() != "\\end_inset" ) {
lex.next();
}
lex.next(); while(lex.IsOK()) {
tmptmptok=lex.GetString(); if(tmptmptok[0] == '\\') { if( tmptmptok == "\\backslash")
cont += '\\'; else break;
} else
cont += tmptmptok;
cont += ' ';
lex.next();
} while(lex.IsOK() && lex.GetString() != "\\end_inset" ) {
lex.next();
} if(tmptok.contains("\\url{"))
cmdname = LString("url"); else
cmdname = LString("htmlurl");
cont.strip();
opt.strip();
inset = new InsetUrl(cmdname,cont,opt);
} elseif (tmptok[0] == '\\') { // then this latex del is a // latex command
InsetCommand *tmpinset = new InsetCommand();
tmpinset->scanCommand(tmptok);
inset = tmpinset;
}
par->InsertChar(pos, LYX_META_INSET);
par->InsertInset(pos, inset);
par->SetFont(pos, font);
pos++;
} elseif (tmptok == "\\i") {
inset = new InsetLatexAccent;
inset->Read(lex);
par->InsertChar(pos, LYX_META_INSET);
par->InsertInset(pos, inset);
par->SetFont(pos, font);
pos++;
} elseif (tmptok == "FormulaMacro") {
inset = new InsetFormulaMacro;
inset->Read(lex);
par->InsertChar(pos, LYX_META_INSET);
par->InsertInset(pos, inset);
par->SetFont(pos, font);
pos++;
} elseif (tmptok == "Formula") {
inset = new InsetFormula;
inset->Read(lex);
par->InsertChar(pos, LYX_META_INSET);
par->InsertInset(pos, inset);
par->SetFont(pos, font);
pos++;
} elseif (tmptok == "Figure") {
inset = new InsetFig(100,100, this);
inset->Read(lex);
par->InsertChar(pos, LYX_META_INSET);
par->InsertInset(pos, inset);
par->SetFont(pos, font);
pos++;
} elseif (tmptok == "Label") { // Kept for compability. Remove in 0.13. if (lex.EatLine()) {
LString tmp;
tmp += "\\label{";
tmp += lex.GetString();
tmp += '}';
inset = new InsetLabel(tmp);
par->InsertChar(pos, LYX_META_INSET);
par->InsertInset(pos, inset);
par->SetFont(pos, font);
pos++;
}
} elseif (tmptok == "Info") {
inset = new InsetInfo;
inset->Read(lex);
par->InsertChar(pos, LYX_META_INSET);
par->InsertInset(pos, inset);
par->SetFont(pos, font);
pos++;
} elseif (tmptok == "Include") {
inset = new InsetInclude(LString(), this);
inset->Read(lex);
par->InsertChar(pos, LYX_META_INSET);
par->InsertInset(pos, inset);
par->SetFont(pos, font);
pos++;
} elseif (tmptok == "LatexCommand") {
InsetCommand inscmd;
inscmd.Read(lex); if (inscmd.getCmdName()=="cite") {
inset = new InsetCitation(inscmd.getContents(), inscmd.getOptions());
} elseif (inscmd.getCmdName()=="bibitem") {
lex.printError("Wrong place for bibitem");
inset = inscmd.Clone();
} elseif (inscmd.getCmdName()=="BibTeX") {
inset = new InsetBibtex(inscmd.getContents(), inscmd.getOptions(), this);
} elseif (inscmd.getCmdName()=="index") {
inset = new InsetIndex(inscmd.getContents());
} elseif (inscmd.getCmdName()=="include") {
inset = new InsetInclude(inscmd.getContents(), this);
} elseif (inscmd.getCmdName()=="label") {
inset = new InsetLabel(inscmd.getCommand());
} elseif (inscmd.getCmdName()=="url"
|| inscmd.getCmdName()=="htmlurl") {
inset = new InsetUrl(inscmd.getCommand());
} elseif (inscmd.getCmdName() == "ref"
|| inscmd.getCmdName() == "pageref") { if (!inscmd.getOptions().empty() || !inscmd.getContents().empty()) {
inset = new InsetRef(inscmd, this);
} /* This condition comes from a temporary solution to the latexdel ref inset that was transformed to an empty ref
inset plus the body surronded by latexdel insets */ else {
LString cont,opt,tmptmptok,cmdname;
lex.next(); while(lex.IsOK() && lex.GetString() != "\\end_inset" ) {
lex.next();
}
lex.next(); while(lex.IsOK()) {
tmptmptok=lex.GetString(); if(tmptmptok[0] == '\\') { if( tmptmptok == "\\backslash")
opt += '\\'; else break;
} else
opt += tmptmptok;
opt += ' ';
lex.next();
} while(lex.IsOK() && lex.GetString() != "\\end_inset" ) {
lex.next();
}
lex.next(); while(lex.IsOK()) {
tmptmptok=lex.GetString(); if(tmptmptok[0] == '\\') { if( tmptmptok == "\\backslash")
cont += '\\'; else break;
} else
cont += tmptmptok;
cont += ' ';
lex.next();
} while(lex.IsOK() && lex.GetString() != "\\end_inset" ) {
lex.next();
}
cont.strip();
opt.strip();
cmdname = "\\" + inscmd.getCmdName();
cmdname += "[" + cont + "]";
cmdname += "{" + opt + "}";
inset = new InsetRef(cmdname,this);
}
} elseif (inscmd.getCmdName()=="tableofcontents") {
inset = new InsetTOC(this);
} elseif (inscmd.getCmdName()=="listoffigures") {
inset = new InsetLOF(this);
} elseif (inscmd.getCmdName()=="listofalgorithms") {
inset = new InsetLOA(this);
} elseif (inscmd.getCmdName()=="listoftables") {
inset = new InsetLOT(this);
} elseif (inscmd.getCmdName()=="printindex") {
inset = new InsetPrintIndex(this);
} elseif (inscmd.getCmdName()=="lyxparent") {
inset = new InsetParent(inscmd.getContents(),this);
} else // The following three are only for compatibility if (inscmd.getCmdName()=="-") {
inset = new InsetSpecialChar(InsetSpecialChar::HYPHENATION);
} elseif (inscmd.getCmdName()=="@.") {
inset = new InsetSpecialChar(InsetSpecialChar::END_OF_SENTENCE);
} elseif (inscmd.getCmdName()=="ldots") {
inset = new InsetSpecialChar(InsetSpecialChar::LDOTS);
} else
inset = inscmd.Clone();
if (lex.IsOK()) {
lex.next();
token = lex.GetString(); if (token == "\\lyxformat") { // the first token _must_ be...
lex.next();
format = lex.GetFloat(); if (format > 1) { if (LYX_FORMAT - format > 0.05) {
printf(_("Warning: need lyxformat %.2f but found %.2f\n"),
LYX_FORMAT, format);
} if (format - LYX_FORMAT > 0.05) {
printf(_("ERROR: need lyxformat %.2f but found %.2f\n"),
LYX_FORMAT, format);
} bool the_end = readLyXformat2(lex, par); // Formats >= 2.13 support "\the_end" marker if (format < 2.13)
the_end = true; // Formats >= 2.14 changed papersize stuff if (format < 2.14) {
setOldPaperStuff();
} else {
setPaperStuff();
} if (!the_end)
WriteAlert(_("Warning!"),
_("Reading of document is not complete"),
_("Maybe the document is truncated")); // We simulate a safe reading anyways to allow // users to take the chance... (Asger) returntrue;
} // format < 1 else {
WriteAlert(_("ERROR!"),
_("Old LyX file format found. " "Use LyX 0.10.x to read this!")); returnfalse;
}
} else { // "\\lyxformat" not found
WriteAlert(_("ERROR!"), _("Not a LyX file!"));
}
} else
WriteAlert(_("ERROR!"), _("Unable to read file!")); returnfalse;
}
// Returns false if unsuccesful bool Buffer::writeFile(LString const & filename, bool flag)
{ // if flag is false writeFile will not create any GUI // warnings, only stderr. // Needed for autosave in background or panic save (Matthias 120496)
if (read_only && (filename == this->filename)) { // Here we should come with a question if we should // perform the write anyway. if (flag)
lyxerr.print(_("Error! Document is read-only: ") + filename); else
WriteAlert(_("Error! Document is read-only: "), filename); returnfalse;
}
FileInfo finfo(filename); if (finfo.exist() && !finfo.writable()) { // Here we should come with a question if we should // try to do the save anyway. (i.e. do a chmod first) if (flag)
lyxerr.print(_("Error! Cannot write file: ") + filename); else
WriteFSAlert(_("Error! Cannot write file: "), filename); returnfalse;
}
FilePtr file(filename, FilePtr::truncate); if (!file()) { if (flag)
lyxerr.print(_("Error! Cannot write file: ") + filename); else
WriteFSAlert(_("Error! Cannot write file: "), filename); returnfalse;
} // The top of the file should not be written by params. // collect some very important information
LString userName(getUserName()) ;
// write out a comment in the top of the file
fprintf(file, "#This file was created by <%s> %s",
userName.c_str(),(char*)date());
fprintf(file, "#LyX 1.0 (C) 1995-1999 Matthias Ettrich" " and the LyX Team\n");
// at the very beginning the used lyx format
fprintf(file, "\\lyxformat %.2f\n", LYX_FORMAT);
// now write out the buffer parameters.
params.writeFile(file);
char footnoteflag = 0; char depth = 0;
// this will write out all the paragraphs // using recursive descent.
paragraph->writeFile(file, params, footnoteflag, depth);
// Write marker that shows file is complete
fprintf(file, "\n\\the_end\n"); if (file.close()) { if (flag)
lyxerr.print(_("Error! Could not close file properly: ")
+ filename); else
WriteFSAlert(_("Error! Could not close file properly: "),
filename); returnfalse;
} returntrue;
}
/* what about the alignment */
} else { /* dummy layout, that means a footnote ended */
footnoteflag = LyXParagraph::NO_FOOTNOTE;
fprintf(file, ") ");
noparbreak = 1;
}
/* It might be a table */ if (par->table){ if (!lyxrc->ascii_roff_command.empty() &&
lyxrc->ascii_roff_command != "none") {
RoffAsciiTable(file,par);
par = par->next; continue;
}
cell = 1;
actcell = 0;
cells = par->table->columns;
clen = newint [cells];
memset(clen,0,sizeof(int)*cells); for (i = 0, j = 0, h=1; i < par->last; i++, h++) {
c = par->GetChar(i); if (c == LYX_META_INSET) { if ((inset = par->GetInset(i))) {
FilePtr fp(fname1,
FilePtr::write); if (!fp()) {
WriteFSAlert(_("Error: Cannot open temporary file:"), fname1); return;
}
inset->Latex(fp,-1);
h += ftell(fp) - 1;
remove(fname1.c_str());
}
} elseif (c == LYX_META_NEWLINE) { if (clen[j] < h)
clen[j] = h;
h = 0;
j = (++j) % par->table->NumberOfCellsInRow(actcell);
actcell++;
}
} if (clen[j] < h)
clen[j] = h;
}
texrow.reset(); // The starting paragraph of the coming rows is the // first paragraph of the document. (Asger)
texrow.start(paragraph, 0);
LString userName(getUserName());
LString LFile;
if (!only_body) {
LFile += "%% This LaTeX-file was created by <";
LFile += userName + "> " + (char*)date();
LFile += "%% LyX 1.0 (C) 1995-1999 by Matthias Ettrich and the LyX Team\n";
LFile += "\n%% Do not edit this file unless you know what you are doing.\n";
texrow.newline();
texrow.newline();
texrow.newline();
texrow.newline();
}
lyxerr.debug("lyx header finished"); // There are a few differences between nice LaTeX and usual files: // usual is \batchmode, uses \listfiles and has a // special input@path to allow the including of figures // with either \input or \includegraphics (what figinsets do). // batchmode is not set if there is a tex_code_break_column. // In this case somebody is interested in the generated LaTeX, // so this is OK. input@path is set when the actual parameter // original_path is set. This is done for usual tex-file, but not // for nice-latex-file. (Matthias 250696) if (!only_body) { if (!nice){ // code for usual, NOT nice-latex-file
LFile += "\\batchmode\n"; // changed // from \nonstopmode
texrow.newline();
LFile += "\\listfiles\n";
texrow.newline();
} if (!original_path.empty()) {
LFile += "\\makeatletter\n";
texrow.newline();
LFile += "\\def\\input@path{{" + original_path
+ "/}}\n";
texrow.newline();
LFile += "\\makeatother\n";
texrow.newline();
}
LFile += "\\documentclass";
LString options; // the document class options.
if (tclass->opt_fontsize.tokenPos('|',params.fontsize) >= 0) { // only write if existing in list (and not default)
options += params.fontsize;
options += "pt,";
}
if (!params.use_geometry &&
(params.paperpackage == PACKAGE_NONE)) { switch (params.papersize) { case PAPER_A4PAPER:
options += "a4paper,"; break; case PAPER_USLETTER:
options += "letterpaper,"; break; case PAPER_A5PAPER:
options += "a5paper,"; break; case PAPER_B5PAPER:
options += "b5paper,"; break; case PAPER_EXECUTIVEPAPER:
options += "executivepaper,"; break; case PAPER_LEGALPAPER:
options += "legalpaper,"; break;
}
}
// if needed if (params.sides != tclass->sides) { if (params.sides == 2)
options += "twoside,"; else
options += "oneside,";
}
// if needed if (params.columns != tclass->columns) { if (params.columns == 2)
options += "twocolumn,"; else
options += "onecolumn,";
}
if (!params.use_geometry && params.orientation == ORIENTATION_LANDSCAPE)
options += "landscape,";
// language should be a parameter to \documentclass if (params.language != "default") {
options += params.language + ',';
}
// the user-defined options if (!params.options.empty()) {
options += params.options + ',';
}
// We try to load babel late, in case it interferes // with other packages. if (params.language != "default") {
LFile += "\\usepackage{babel}\n";
texrow.newline();
}
// Write out what we've generated so far...and reset LFile
fwrite(LFile.c_str(), sizeof(char), LFile.length(), file);
LFile.clean();
// Now insert the LyX specific LaTeX commands...
LString preamble, tmppreamble;
// The optional packages;
preamble = features.getPackages(params);
// this might be useful...
preamble += "\n\\makeatletter\n\n";
// Some macros LyX will need
tmppreamble = features.getMacros(params);
if (!tmppreamble.empty()) {
preamble += "\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% " "LyX specific LaTeX commands.\n"
+ tmppreamble + '\n';
}
// the text class specific preamble
tmppreamble = features.getTClassPreamble(params); if (!tmppreamble.empty()) {
preamble += "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% " "Textclass specific LaTeX commands.\n"
+ tmppreamble + '\n';
}
// Itemize bullet settings need to be last in case the user // defines their own bullets that use a package included // in the user-defined preamble -- ARRae for (int i = 0; i < 4; ++i) { if (params.user_defined_bullets[i] != ITEMIZE_DEFAULTS[i]) {
preamble += "\\renewcommand\\labelitemi"; switch (i) { // `i' is one less than the item to modify case 0: break; case 1:
preamble += 'i'; break; case 2:
preamble += "ii"; break; case 3:
preamble += 'v'; break;
}
preamble += "[0]{" + params.user_defined_bullets[i].getText() + "}\n";
}
}
for (int j = preamble.countChar('\n'); j-- ;) {
texrow.newline();
}
// A bit faster than printing a char at a time I think.
fwrite(preamble.c_str(), sizeof(char),
preamble.length(), file);
// make the body.
LFile += "\\begin{document}\n\n";
texrow.newline();
texrow.newline();
} // only_body
lyxerr.debug("preamble finished, now the body.");
bool was_title = false; bool already_title = false;
LString ftnote;
TexRow ft_texrow; int ftcount = 0; int loop_count = 0;
LyXParagraph *par = paragraph;
// if only_body while (par) {
++loop_count; if (par->IsDummy())
lyxerr.debug("Error in MakeLateXFile.", Error::LATEX);
LyXLayout * layout = lyxstyle.Style(params.textclass,
par->layout);
if (layout->intitle) { if (already_title) {
lyxerr.print("Error in MakeLatexFile: You" " should not mix title layouts" " with normal ones.");
} else
was_title = true;
} elseif (was_title && !already_title) {
LFile += "\\maketitle\n";
texrow.newline();
already_title = true;
was_title = false;
} // We are at depth 0 so we can just use // ordinary \footnote{} generation // flag this with ftcount
ftcount = -1; if (layout->isEnvironment()
|| par->pextra_type != PEXTRA_NONE) {
par = par->TeXEnvironment(LFile, texrow,
ftnote, ft_texrow, ftcount);
} else {
par = par->TeXOnePar(LFile, texrow,
ftnote, ft_texrow, ftcount);
}
// Write out what we've generated...and reset LFile if (ftcount >= 1) { if (ftcount > 1) {
LFile += "\\addtocounter{footnote}{-";
LFile += ftcount - 1;
LFile += '}';
}
LFile += ftnote;
texrow += ft_texrow;
ftnote.clean();
ft_texrow.reset();
ftcount = 0;
} if (loop_count == 2) { // fwrite()ing every second time through the loop // gains a few extra % of speed; going higher than // 2 will slow things down again. I'll look at // LFile.length() in a future revision. ARRae
fwrite(LFile.c_str(), sizeof(char),
LFile.length(), file);
LFile.clean();
loop_count = 0;
}
}
if (!only_body) {
LFile += "\\end{document}\n";
texrow.newline();
// Write out what we've generated...and reset LFile
fwrite(LFile.c_str(), sizeof(char), LFile.length(), file);
LFile.clean();
// tex_code_break_column's value is used to decide // if we are in batchmode or not (within mathed_write() // in math_write.C) so we must set it to a non-zero // value when we leave otherwise we save incorrect .lyx files.
tex_code_break_column = lyxrc->ascii_linelen;
if (file.close()) {
WriteFSAlert(_("Error! Could not close file properly:"), filename);
}
lyxerr.debug("Finished making latex file.");
}
/* treat <toc> as a special case for compatibility with old code */ if (par->GetChar(0) == LYX_META_INSET) {
Inset *inset = par->GetInset(0); char lyx_code = inset->LyxCode(); if (lyx_code ==Inset::TOC_CODE){
LString temp= "toc";
sgmlOpenTag(file, depth, temp);
par = par->next;
linuxDocHandleFootnote(file, par); continue;
}
}
// checks, if newcol chars should be put into this line // writes newline, if necessary. static void linux_doc_line_break(FILE *file, unsignedint &colcount, constunsignedint newcol)
{
colcount += newcol; if (colcount > lyxrc->ascii_linelen) {
fprintf(file, "\n");
colcount = newcol; // assume write after this call
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.