X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FBuffer.cpp;h=d2eff530f835197ca76ef1481d0c3e2f9177c98c;hb=c20e885331c9bba720e386985d0e7bcdb5bf8b9c;hp=1509b5ba28cd272795bba61d0eba1cc200e6f181;hpb=2653011613afaa86a1c964661f1dd815ebfefa7b;p=lyx.git diff --git a/src/Buffer.cpp b/src/Buffer.cpp index 1509b5ba28..d2eff530f8 100644 --- a/src/Buffer.cpp +++ b/src/Buffer.cpp @@ -127,7 +127,7 @@ namespace { // Do not remove the comment below, so we get merge conflict in // independent branches. Instead add your own. -int const LYX_FORMAT = 410; // rgh: dummy format for list->labeling +int const LYX_FORMAT = 413; // rgh: html_css_as_file typedef map DepClean; typedef map > RefCache; @@ -820,6 +820,14 @@ bool Buffer::readDocument(Lexer & lex) // read main text bool const res = text().read(lex, errorList, d->inset); + // inform parent buffer about local macros + if (parent()) { + Buffer const * pbuf = parent(); + UserMacroSet::const_iterator cit = usermacros.begin(); + UserMacroSet::const_iterator end = usermacros.end(); + for (; cit != end; ++cit) + pbuf->usermacros.insert(*cit); + } usermacros.clear(); updateMacros(); updateMacroInstances(); @@ -1047,13 +1055,18 @@ bool Buffer::save() const backupName = FileName(addName(lyxrc.backupdir_path, mangledName)); } - // do not copy because of #6587 - if (fileName().moveTo(backupName)) { - madeBackup = true; - } else { + + // Except file is symlink do not copy because of #6587. + // Hard links have bad luck. + if (fileName().isSymLink()) + madeBackup = fileName().copyTo(backupName); + else + madeBackup = fileName().moveTo(backupName); + + if (!madeBackup) { Alert::error(_("Backup failure"), bformat(_("Cannot create backup file %1$s.\n" - "Please check whether the directory exists and is writeable."), + "Please check whether the directory exists and is writable."), from_utf8(backupName.absFileName()))); //LYXERR(Debug::DEBUG, "Fs error: " << fe.what()); } @@ -1174,7 +1187,7 @@ bool Buffer::write(ostream & ofs) const // The top of the file should not be written by params(). // write out a comment in the top of the file - ofs << "#LyX " << lyx_version + ofs << "#LyX " << lyx_version_major << "." << lyx_version_minor << " created this file. For more info see http://www.lyx.org/\n" << "\\lyxformat " << LYX_FORMAT << "\n" << "\\begin_document\n"; @@ -1256,9 +1269,10 @@ bool Buffer::makeLaTeXFile(FileName const & fname, ErrorList & errorList = d->errorLists["Export"]; errorList.clear(); bool failed_export = false; + otexstream os(ofs, d->texrow); try { - d->texrow.reset(); - writeLaTeXSource(ofs, original_path, + os.texrow().reset(); + writeLaTeXSource(os, original_path, runparams, output_preamble, output_body); } catch (EncodingException & e) { @@ -1301,7 +1315,7 @@ bool Buffer::makeLaTeXFile(FileName const & fname, } -void Buffer::writeLaTeXSource(odocstream & os, +void Buffer::writeLaTeXSource(otexstream & os, string const & original_path, OutputParams const & runparams_in, bool const output_preamble, bool const output_body) const @@ -1326,8 +1340,6 @@ void Buffer::writeLaTeXSource(odocstream & os, "For more info, see http://www.lyx.org/.\n" "%% Do not edit unless you really know what " "you are doing.\n"; - d->texrow.newline(); - d->texrow.newline(); } LYXERR(Debug::INFO, "lyx document header finished"); @@ -1353,9 +1365,7 @@ void Buffer::writeLaTeXSource(odocstream & os, if (output_preamble) { if (!runparams.nice) { // code for usual, NOT nice-latex-file - os << "\\batchmode\n"; // changed - // from \nonstopmode - d->texrow.newline(); + os << "\\batchmode\n"; // changed from \nonstopmode } if (!original_path.empty()) { // FIXME UNICODE @@ -1391,9 +1401,6 @@ void Buffer::writeLaTeXSource(odocstream & os, << "\\def\\input@path{{" << inputpath << "/}}\n" << "\\makeatother\n"; - d->texrow.newline(); - d->texrow.newline(); - d->texrow.newline(); } } @@ -1405,7 +1412,6 @@ void Buffer::writeLaTeXSource(odocstream & os, runparams.use_polyglossia = features.usePolyglossia(); // Write the preamble runparams.use_babel = params().writeLaTeX(os, features, - d->texrow, d->filename.onlyPath()); runparams.use_japanese = features.isRequired("japanese"); @@ -1415,19 +1421,18 @@ void Buffer::writeLaTeXSource(odocstream & os, // 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) { - int num_lines = (*it)->write(os, true); - d->texrow.newlines(num_lines); + int num_lines = (*it)->write(os.os(), true); + os.texrow().newlines(num_lines); } } // output_preamble - d->texrow.start(paragraphs().begin()->id(), 0); + os.texrow().start(paragraphs().begin()->id(), 0); LYXERR(Debug::INFO, "preamble finished, now the body."); @@ -1441,7 +1446,7 @@ void Buffer::writeLaTeXSource(odocstream & os, } // the real stuff - latexParagraphs(*this, text(), os, d->texrow, runparams); + latexParagraphs(*this, text(), os, runparams); // Restore the parenthood if needed if (output_preamble) @@ -1449,11 +1454,9 @@ void Buffer::writeLaTeXSource(odocstream & os, // add this just in case after all the paragraphs os << endl; - d->texrow.newline(); if (output_preamble) { os << "\\end{document}\n"; - d->texrow.newline(); LYXERR(Debug::LATEX, "makeLaTeXFile...done"); } else { LYXERR(Debug::LATEX, "LaTeXFile for inclusion made."); @@ -1461,7 +1464,7 @@ void Buffer::writeLaTeXSource(odocstream & os, runparams_in.encoding = runparams.encoding; // Just to be sure. (Asger) - d->texrow.newline(); + os.texrow().newline(); //for (int i = 0; itexrow.rows(); i++) { // int id,pos; @@ -1470,7 +1473,7 @@ void Buffer::writeLaTeXSource(odocstream & os, //} LYXERR(Debug::INFO, "Finished making LaTeX file."); - LYXERR(Debug::INFO, "Row count was " << d->texrow.rows() - 1 << '.'); + LYXERR(Debug::INFO, "Row count was " << os.texrow().rows() - 1 << '.'); } @@ -2434,6 +2437,8 @@ bool Buffer::isExternallyModified(CheckMethod method) const void Buffer::saveCheckSum() const { FileName const & file = d->filename; + + file.refresh(); if (file.exists()) { d->timestamp_ = file.lastModified(); d->checksum_ = file.checksum(); @@ -2538,7 +2543,7 @@ Buffer const * Buffer::parent() const ListOfBuffers Buffer::allRelatives() const { ListOfBuffers lb = masterBuffer()->getDescendents(); - lb.push_front(const_cast(this)); + lb.push_front(const_cast(masterBuffer())); return lb; } @@ -2679,7 +2684,9 @@ MacroData const * Buffer::Impl::getBufferMacro(docstring const & name, break; // scope ends behind pos? - if (pos < it->second.first) { + if (pos < it->second.first + && (cloned_buffer_ || + theBufferList().isLoaded(it->second.second))) { // look for macro in external file macro_lock = true; MacroData const * data @@ -3071,12 +3078,13 @@ void Buffer::changeRefsIfUnique(docstring const & from, docstring const & to, } -void Buffer::getSourceCode(odocstream & os, pit_type par_begin, - pit_type par_end, bool full_source) +void Buffer::getSourceCode(odocstream & os, string const format, + pit_type par_begin, pit_type par_end, + bool full_source) const { OutputParams runparams(¶ms().encoding()); runparams.nice = true; - runparams.flavor = getDefaultOutputFlavor(); + runparams.flavor = getOutputFlavor(format); runparams.linelen = lyxrc.plaintext_linelen; // No side effect of file copying and image conversion runparams.dryrun = true; @@ -3090,9 +3098,11 @@ void Buffer::getSourceCode(odocstream & os, pit_type par_begin, writeDocBookSource(os, absFileName(), runparams, false); else if (runparams.flavor == OutputParams::HTML) writeLyXHTMLSource(os, runparams, false); - else + else { // latex or literate - writeLaTeXSource(os, string(), runparams, true, true); + otexstream ots(os, d->texrow); + writeLaTeXSource(ots, string(), runparams, true, true); + } } else { runparams.par_begin = par_begin; runparams.par_end = par_end; @@ -3117,9 +3127,11 @@ void Buffer::getSourceCode(odocstream & os, pit_type par_begin, else if (runparams.flavor == OutputParams::HTML) { XHTMLStream xs(os); xhtmlParagraphs(text(), *this, xs, runparams); - } else + } else { // latex or literate - latexParagraphs(*this, text(), os, texrow, runparams); + otexstream ots(os, texrow); + latexParagraphs(*this, text(), ots, runparams); + } } } @@ -3373,12 +3385,10 @@ string Buffer::getDefaultOutputFormat() const if (!params().default_output_format.empty() && params().default_output_format != "default") return params().default_output_format; - typedef vector Formats; - Formats formats = exportableFormats(true); if (isDocBook() - || isLiterate() || params().useNonTeXFonts || params().encoding().package() == Encoding::japanese) { + vector const formats = exportableFormats(true); if (formats.empty()) return string(); // return the first we find @@ -3388,9 +3398,10 @@ string Buffer::getDefaultOutputFormat() const } -OutputParams::FLAVOR Buffer::getDefaultOutputFlavor() +OutputParams::FLAVOR Buffer::getOutputFlavor(string const format) const { - string const dformat = getDefaultOutputFormat(); + string const dformat = (format.empty() || format == "default") ? + getDefaultOutputFormat() : format; DefaultFlavorCache::const_iterator it = default_flavors_.find(dformat); @@ -3465,12 +3476,14 @@ bool Buffer::doExport(string const & format, bool put_in_tempdir, runparams.linelen = lyxrc.plaintext_linelen; runparams.includeall = includeall; vector backs = backends(); + Converters converters = theConverters(); if (find(backs.begin(), backs.end(), format) == backs.end()) { // Get shortest path to format + converters.buildGraph(); Graph::EdgePath path; for (vector::const_iterator it = backs.begin(); it != backs.end(); ++it) { - Graph::EdgePath p = theConverters().getPath(*it, format); + Graph::EdgePath p = converters.getPath(*it, format); if (!p.empty() && (path.empty() || p.size() < path.size())) { backend_format = *it; path = p; @@ -3486,7 +3499,7 @@ bool Buffer::doExport(string const & format, bool put_in_tempdir, } return false; } - runparams.flavor = theConverters().getFlavor(path); + runparams.flavor = converters.getFlavor(path); } else { backend_format = format; @@ -3540,8 +3553,13 @@ bool Buffer::doExport(string const & format, bool put_in_tempdir, // LaTeX backend else if (backend_format == format) { runparams.nice = true; - if (!makeLaTeXFile(FileName(filename), string(), runparams)) + if (!makeLaTeXFile(FileName(filename), string(), runparams)) { + if (d->cloned_buffer_) { + d->cloned_buffer_->d->errorLists["Export"] = + d->errorLists["Export"]; + } return false; + } } else if (!lyxrc.tex_allows_spaces && contains(filePath(), ' ')) { Alert::error(_("File name error"), @@ -3549,8 +3567,13 @@ bool Buffer::doExport(string const & format, bool put_in_tempdir, return false; } else { runparams.nice = false; - if (!makeLaTeXFile(FileName(filename), filePath(), runparams)) + if (!makeLaTeXFile(FileName(filename), filePath(), runparams)) { + if (d->cloned_buffer_) { + d->cloned_buffer_->d->errorLists["Export"] = + d->errorLists["Export"]; + } return false; + } } string const error_type = (format == "program") @@ -3558,12 +3581,12 @@ bool Buffer::doExport(string const & format, bool put_in_tempdir, ErrorList & error_list = d->errorLists[error_type]; string const ext = formats.extension(format); FileName const tmp_result_file(changeExtension(filename, ext)); - bool const success = theConverters().convert(this, FileName(filename), + bool const success = converters.convert(this, FileName(filename), tmp_result_file, FileName(absFileName()), backend_format, format, error_list); // Emit the signal to show the error list or copy it back to the - // cloned Buffer so that it cab be emitted afterwards. + // cloned Buffer so that it can be emitted afterwards. if (format != backend_format) { if (d->cloned_buffer_) { d->cloned_buffer_->d->errorLists[error_type] = @@ -3576,6 +3599,10 @@ bool Buffer::doExport(string const & format, bool put_in_tempdir, ListOfBuffers::const_iterator const cen = clist.end(); for (; cit != cen; ++cit) { if (d->cloned_buffer_) { + // Enable reverse search by copying back the + // texrow object to the cloned buffer. + // FIXME: this is not thread safe. + (*cit)->d->cloned_buffer_->d->texrow = (*cit)->d->texrow; (*cit)->d->cloned_buffer_->d->errorLists[error_type] = (*cit)->d->errorLists[error_type]; } else @@ -3749,7 +3776,7 @@ Buffer::ReadStatus Buffer::loadEmergency() if (success) { if (isReadonly()) { Alert::warning(_("File is read-only"), - bformat(_("An emergency file is succesfully loaded, " + bformat(_("An emergency file is successfully loaded, " "but the original file %1$s is marked read-only. " "Please make sure to save the document as a different " "file."), from_utf8(d->filename.absFileName()))); @@ -3811,7 +3838,7 @@ Buffer::ReadStatus Buffer::loadAutosave() if (ret_llf == ReadSuccess) { if (isReadonly()) { Alert::warning(_("File is read-only"), - bformat(_("A backup file is succesfully loaded, " + bformat(_("A backup file is successfully loaded, " "but the original file %1$s is marked read-only. " "Please make sure to save the document as a " "different file."), @@ -3861,24 +3888,50 @@ Buffer::ReadStatus Buffer::loadThisLyXFile(FileName const & fn) void Buffer::bufferErrors(TeXErrors const & terr, ErrorList & errorList) const { - TeXErrors::Errors::const_iterator cit = terr.begin(); + TeXErrors::Errors::const_iterator it = terr.begin(); TeXErrors::Errors::const_iterator end = terr.end(); + ListOfBuffers clist = getDescendents(); + ListOfBuffers::const_iterator cen = clist.end(); - for (; cit != end; ++cit) { + for (; it != end; ++it) { int id_start = -1; int pos_start = -1; - int errorRow = cit->error_in_line; - bool found = d->texrow.getIdFromRow(errorRow, id_start, - pos_start); + int errorRow = it->error_in_line; + Buffer const * buf = 0; + Impl const * p = d; + if (it->child_name.empty()) + p->texrow.getIdFromRow(errorRow, id_start, pos_start); + else { + // The error occurred in a child + ListOfBuffers::const_iterator cit = clist.begin(); + for (; cit != cen; ++cit) { + string const child_name = + DocFileName(changeExtension( + (*cit)->absFileName(), "tex")). + mangledFileName(); + if (it->child_name != child_name) + continue; + (*cit)->d->texrow.getIdFromRow(errorRow, + id_start, pos_start); + if (id_start != -1) { + buf = d->cloned_buffer_ + ? (*cit)->d->cloned_buffer_->d->owner_ + : (*cit)->d->owner_; + p = (*cit)->d; + break; + } + } + } int id_end = -1; int pos_end = -1; + bool found; do { ++errorRow; - found = d->texrow.getIdFromRow(errorRow, id_end, pos_end); + found = p->texrow.getIdFromRow(errorRow, id_end, pos_end); } while (found && id_start == id_end && pos_start == pos_end); - errorList.push_back(ErrorItem(cit->error_desc, - cit->error_text, id_start, pos_start, pos_end)); + errorList.push_back(ErrorItem(it->error_desc, + it->error_text, id_start, pos_start, pos_end, buf)); } } @@ -4238,6 +4291,7 @@ Buffer::ReadStatus Buffer::reload() updateTitles(); markClean(); message(bformat(_("Document %1$s reloaded."), disp_fn)); + d->undo_.clear(); } else { message(bformat(_("Could not reload document %1$s."), disp_fn)); }