#include "ParagraphParameters.h"
#include "ParIterator.h"
#include "PDFOptions.h"
-#include "Session.h"
#include "sgml.h"
#include "TexRow.h"
#include "TexStream.h"
#include "graphics/Previews.h"
+#include "support/assert.h"
#include "support/convert.h"
#include "support/debug.h"
#include "support/ExceptionMessage.h"
namespace {
-int const LYX_FORMAT = 318;
+int const LYX_FORMAT = 328;
typedef map<string, bool> DepClean;
typedef map<docstring, pair<InsetLabel const *, Buffer::References> > RefCache;
InsetText inset;
};
+
/// Creates the per buffer temporary directory
static FileName createBufferTmpDir()
{
frontend::WorkAreaManager & Buffer::workAreaManager() const
{
- BOOST_ASSERT(d->wa_);
+ LASSERT(d->wa_, /**/);
return *d->wa_;
}
ErrorList & errorList = d->errorLists["Parse"];
while (lex.isOK()) {
- lex.next();
- string const token = lex.getString();
+ string token;
+ lex >> token;
if (token.empty())
continue;
LYXERR(Debug::PARSER, "Handling document header token: `"
<< token << '\'');
- string unknown = params().readToken(lex, token, d->filename.onlyPath());
+ string unknown = params().readToken(lex, token, d->filename.onlyPath(),
+ d->temppath);
if (!unknown.empty()) {
if (unknown[0] != '\\' && token == "\\textclass") {
Alert::warning(_("Unknown document class"),
ErrorList & errorList = d->errorLists["Parse"];
errorList.clear();
- lex.next();
- string const token = lex.getString();
- if (token != "\\begin_document") {
+ if (!lex.checkFor("\\begin_document")) {
docstring const s = _("\\begin_document is missing");
errorList.push_back(ErrorItem(_("Document header error"),
s, -1, 0, 0));
}
// we are reading in a brand new document
- BOOST_ASSERT(paragraphs().empty());
+ LASSERT(paragraphs().empty(), /**/);
readHeader(lex);
// Enable embeded files, which will set temp path and move
// inconsistent inzip files if needed.
- embeddedFiles().enable(params().embedded, *this, false);
+ try {
+ embeddedFiles().validate(*this);
+ embeddedFiles().enable(params().embedded, *this, false);
+ } catch (ExceptionMessage const & message) {
+ Alert::error(message.title_, message.details_);
+ Alert::warning(_("Failed to read embedded files"),
+ _("Due to most likely a bug, LyX failed to locate all embedded "
+ "file. If you unzip the LyX file, you should be able to see and "
+ "open content.lyx which is your main text. You may also be able "
+ "to recover some embedded files. Please report this bug to the "
+ "lyx-devel mailing list."));
+ return false;
+ }
updateMacros();
updateMacroInstances();
// remove dummy empty par
paragraphs().clear();
- Lexer lex(0, 0);
+ Lexer lex;
istringstream is(s);
lex.setStream(is);
FileName const name = FileName::tempName();
// remove dummy empty par
paragraphs().clear();
- Lexer lex(0, 0);
+ Lexer lex;
lex.setFile(fname);
if (readFile(lex, fname) != success)
return false;
Buffer::ReadStatus Buffer::readFile(Lexer & lex, FileName const & filename,
bool fromstring)
{
- BOOST_ASSERT(!filename.empty());
-
- if (!lex.isOK()) {
- Alert::error(_("Document could not be read"),
- bformat(_("%1$s could not be read."), from_utf8(filename.absFilename())));
- return failure;
- }
-
- lex.next();
- string const token = lex.getString();
-
- if (!lex) {
- Alert::error(_("Document could not be read"),
- bformat(_("%1$s could not be read."), from_utf8(filename.absFilename())));
- return failure;
- }
-
- // the first token _must_ be...
- if (token != "\\lyxformat") {
- lyxerr << "Token: " << token << endl;
+ LASSERT(!filename.empty(), /**/);
+ // the first (non-comment) token _must_ be...
+ if (!lex.checkFor("\\lyxformat")) {
Alert::error(_("Document format failure"),
- bformat(_("%1$s is not a LyX document."),
+ bformat(_("%1$s is not a readable LyX document."),
from_utf8(filename.absFilename())));
return failure;
}
- lex.next();
- string tmp_format = lex.getString();
+ string tmp_format;
+ lex >> tmp_format;
//lyxerr << "LyX Format: `" << tmp_format << '\'' << endl;
// if present remove ".," from string.
- string::size_type dot = tmp_format.find_first_of(".,");
+ size_t dot = tmp_format.find_first_of(".,");
//lyxerr << " dot found at " << dot << endl;
if (dot != string::npos)
tmp_format.erase(dot, 1);
}
if (!retval) {
- message(str + _(" could not write file!."));
+ message(str + _(" could not write file!"));
return false;
}
removeAutosaveFile(d->filename.absFilename());
if (params().embedded) {
- message(str + _(" writing embedded files!."));
+ message(str + _(" writing embedded files."));
// if embedding is enabled, write file.lyx and all the embedded files
// to the zip file fname.
if (!d->embedded_files.writeFile(fname, *this)) {
- message(str + _(" could not write embedded files!."));
+ message(str + _(" could not write embedded files!"));
return false;
}
}
d->texrow.newline();
}
LYXERR(Debug::INFO, "lyx document header finished");
+
+ // Don't move this behind the parent_buffer=0 code below,
+ // because then the macros will not get the right "redefinition"
+ // flag as they don't see the parent macros which are output before.
+ updateMacros();
+
+ // fold macros if possible, still with parent buffer as the
+ // macros will be put in the prefix anyway.
+ updateMacroInstances();
+
// There are a few differences between nice LaTeX and usual files:
// usual is \batchmode and has a
// special input@path to allow the including of figures
d->texrow.newline();
}
+ // get parent macros (if this buffer has a parent) which will be
+ // written at the document begin further down.
+ MacroSet parentMacros;
+ listParentMacros(parentMacros, features);
+
// Write the preamble
runparams.use_babel = params().writeLaTeX(os, features, d->texrow);
// make the body.
os << "\\begin{document}\n";
d->texrow.newline();
+
+ // output the parent macros
+ MacroSet::iterator it = parentMacros.begin();
+ MacroSet::iterator end = parentMacros.end();
+ for (; it != end; ++it)
+ (*it)->write(os, true);
} // output_preamble
d->texrow.start(paragraphs().begin()->id(), 0);
LYXERR(Debug::INFO, "preamble finished, now the body.");
- // Don't move this behind the parent_buffer=0 code below,
- // because then the macros will not get the right "redefinition"
- // flag as they don't see the parent macros which are output before.
- updateMacros();
-
- // fold macros if possible, still with parent buffer as the
- // macros will be put in the prefix anyway.
- updateMacroInstances();
-
// if we are doing a real file with body, even if this is the
// child of some other buffer, let's cut the link here.
// This happens for example if only a child document is printed.
Buffer const * save_parent = 0;
if (output_preamble) {
- // output the macros visible for this buffer
- writeParentMacros(os);
-
save_parent = d->parent_buffer;
d->parent_buffer = 0;
}
latexParagraphs(*this, text(), os, d->texrow, runparams);
// Restore the parenthood if needed
- if (output_preamble) {
+ if (output_preamble)
d->parent_buffer = save_parent;
- // restore macros with correct parent buffer (especially
- // important for the redefinition flag which depends on the
- // parent)
- updateMacros();
- }
-
// add this just in case after all the paragraphs
os << endl;
d->texrow.newline();
if (it->lyxCode() == BIBTEX_CODE) {
InsetBibtex const & inset =
static_cast<InsetBibtex const &>(*it);
- EmbeddedFileList const bibfiles = inset.embeddedFiles();
+ EmbeddedFileList const bibfiles = inset.getBibFiles();
d->bibfilesCache_.insert(d->bibfilesCache_.end(),
bibfiles.begin(),
bibfiles.end());
void Buffer::changeLanguage(Language const * from, Language const * to)
{
- BOOST_ASSERT(from);
- BOOST_ASSERT(to);
+ LASSERT(from, /**/);
+ LASSERT(to, /**/);
for_each(par_iterator_begin(),
par_iterator_end(),
bool Buffer::isExternallyModified(CheckMethod method) const
{
- BOOST_ASSERT(d->filename.exists());
+ LASSERT(d->filename.exists(), /**/);
// if method == timestamp, check timestamp before checksum
return (method == checksum_method
|| d->timestamp_ != d->filename.lastModified())
}
-void Buffer::writeParentMacros(odocstream & os) const
+void Buffer::listParentMacros(MacroSet & macros, LaTeXFeatures & features) const
{
if (!d->parent_buffer)
return;
-
- // collect macro names
+
MacroNameSet names;
d->parent_buffer->listMacroNames(names);
-
- // resolve and output them
+
+ // resolve macros
MacroNameSet::iterator it = names.begin();
MacroNameSet::iterator end = names.end();
for (; it != end; ++it) {
// defined?
MacroData const * data =
d->parent_buffer->getMacro(*it, *this, false);
- if (data)
- data->write(os, true);
+ if (data) {
+ macros.insert(data);
+
+ // we cannot access the original MathMacroTemplate anymore
+ // here to calls validate method. So we do its work here manually.
+ // FIXME: somehow make the template accessible here.
+ if (data->optionals() > 0)
+ features.require("xargs");
+ }
}
}
InsetCode code)
{
//FIXME: This does not work for child documents yet.
- BOOST_ASSERT(code == CITE_CODE);
+ LASSERT(code == CITE_CODE, /**/);
// Check if the label 'from' appears more than once
vector<docstring> labels;
string paramName;