X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fbuffer.C;h=43f7f7efb59cd86ba82ecf3667e9f06f0faf58ca;hb=35204f8f33d7400a5fefeffea533fb4cb4097211;hp=1467f5bd5486b81b83840063227f3cc355f30dfa;hpb=e89625ef28143545a511cdabc67dee8b7be1b216;p=lyx.git diff --git a/src/buffer.C b/src/buffer.C index 1467f5bd54..43f7f7efb5 100644 --- a/src/buffer.C +++ b/src/buffer.C @@ -47,6 +47,7 @@ #include "pariterator.h" #include "sgml.h" #include "texrow.h" +#include "TocBackend.h" #include "undo.h" #include "version.h" @@ -55,7 +56,7 @@ #include "insets/insetinclude.h" #include "insets/insettext.h" -#include "mathed/MatheMacroTemplate.h" +#include "mathed/MathMacroTemplate.h" #include "mathed/MathMacroTable.h" #include "mathed/MathSupport.h" @@ -67,24 +68,23 @@ #include "support/lyxalgo.h" #include "support/filetools.h" #include "support/fs_extras.h" -# include -# include -# include -namespace io = boost::iostreams; #include "support/lyxlib.h" #include "support/os.h" #include "support/path.h" #include "support/textutils.h" #include "support/convert.h" +#include +#include +#include #include #include #include #if defined (HAVE_UTIME_H) -# include +#include #elif defined (HAVE_SYS_UTIME_H) -# include +#include #endif #include @@ -93,37 +93,37 @@ namespace io = boost::iostreams; #include -using lyx::docstring; -using lyx::pos_type; -using lyx::pit_type; - -using lyx::support::addName; -using lyx::support::bformat; -using lyx::support::changeExtension; -using lyx::support::cmd_ret; -using lyx::support::createBufferTmpDir; -using lyx::support::destroyDir; -using lyx::support::getFormatFromContents; -using lyx::support::isDirWriteable; -using lyx::support::libFileSearch; -using lyx::support::latex_path; -using lyx::support::ltrim; -using lyx::support::makeAbsPath; -using lyx::support::makeDisplayPath; -using lyx::support::makeLatexName; -using lyx::support::onlyFilename; -using lyx::support::onlyPath; -using lyx::support::quoteName; -using lyx::support::removeAutosaveFile; -using lyx::support::rename; -using lyx::support::runCommand; -using lyx::support::split; -using lyx::support::subst; -using lyx::support::tempName; -using lyx::support::trim; - -namespace os = lyx::support::os; +namespace lyx { + +using support::addName; +using support::bformat; +using support::changeExtension; +using support::cmd_ret; +using support::createBufferTmpDir; +using support::destroyDir; +using support::getFormatFromContents; +using support::isDirWriteable; +using support::libFileSearch; +using support::latex_path; +using support::ltrim; +using support::makeAbsPath; +using support::makeDisplayPath; +using support::makeLatexName; +using support::onlyFilename; +using support::onlyPath; +using support::quoteName; +using support::removeAutosaveFile; +using support::rename; +using support::runCommand; +using support::split; +using support::subst; +using support::tempName; +using support::trim; + +namespace Alert = frontend::Alert; +namespace os = support::os; namespace fs = boost::filesystem; +namespace io = boost::iostreams; using std::endl; using std::for_each; @@ -141,12 +141,9 @@ using std::vector; using std::string; -// all these externs should eventually be removed. -extern BufferList bufferlist; - namespace { -int const LYX_FORMAT = 249; +int const LYX_FORMAT = 254; } // namespace anon @@ -196,13 +193,16 @@ public: /// MacroTable macros; + + /// + TocBackend toc_backend; }; Buffer::Impl::Impl(Buffer & parent, string const & file, bool readonly_) : lyx_clean(true), bak_clean(true), unnamed(false), read_only(readonly_), - filename(file), file_fully_loaded(false), - inset(params) + filename(file), file_fully_loaded(false), inset(params), + toc_backend(&parent) { inset.setAutoBreakRows(true); lyxvc.buffer(&parent); @@ -232,11 +232,11 @@ Buffer::~Buffer() if (!temppath().empty() && !destroyDir(temppath())) { Alert::warning(_("Could not remove temporary directory"), bformat(_("Could not remove the temporary directory %1$s"), - lyx::from_utf8(temppath()))); + from_utf8(temppath()))); } // Remove any previewed LaTeX snippets associated with this buffer. - lyx::graphics::Previews::get().removeLoader(*this); + graphics::Previews::get().removeLoader(*this); } @@ -330,6 +330,18 @@ TexRow const & Buffer::texrow() const } +TocBackend & Buffer::tocBackend() +{ + return pimpl_->toc_backend; +} + + +TocBackend const & Buffer::tocBackend() const +{ + return pimpl_->toc_backend; +} + + string const Buffer::getLatexName(bool const no_path) const { string const name = changeExtension(makeLatexName(fileName()), ".tex"); @@ -391,7 +403,7 @@ void unknownClass(string const & unknown) { Alert::warning(_("Unknown document class"), bformat(_("Using the default document class, because the " - "class %1$s is unknown."), lyx::from_utf8(unknown))); + "class %1$s is unknown."), from_utf8(unknown))); } } // anon @@ -447,8 +459,8 @@ int Buffer::readHeader(LyXLex & lex) ++unknown_tokens; docstring const s = bformat(_("Unknown token: " "%1$s %2$s\n"), - lyx::from_utf8(token), - lyx::from_utf8(lex.getString())); + from_utf8(token), + from_utf8(lex.getString())); errorList.push_back(ErrorItem(_("Document header error"), s, -1, 0, 0)); } @@ -488,7 +500,7 @@ bool Buffer::readDocument(LyXLex & lex) string theclass = params().getLyXTextClass().name(); Alert::error(_("Can't load document class"), bformat( _("Using the default document class, because the " - " class %1$s could not be loaded."), lyx::from_utf8(theclass))); + " class %1$s could not be loaded."), from_utf8(theclass))); params().textclass = 0; } @@ -531,25 +543,23 @@ void Buffer::insertStringAsLines(ParagraphList & pars, } else if (*cit == '\t') { if (!par.isFreeSpacing()) { // tabs are like spaces here - par.insertChar(pos, ' ', font); + par.insertChar(pos, ' ', font, params().trackChanges); ++pos; space_inserted = true; } else { const pos_type n = 8 - pos % 8; for (pos_type i = 0; i < n; ++i) { - par.insertChar(pos, ' ', font); + par.insertChar(pos, ' ', font, params().trackChanges); ++pos; } space_inserted = true; } -/* FIXME: not needed anymore? } else if (!isPrintable(*cit)) { // Ignore unprintables continue; -*/ } else { // just insert the character - par.insertChar(pos, *cit, font); + par.insertChar(pos, *cit, font, params().trackChanges); ++pos; space_inserted = (*cit == ' '); } @@ -600,7 +610,7 @@ bool Buffer::readFile(LyXLex & lex, string const & filename) if (!lex.isOK()) { Alert::error(_("Document could not be read"), - bformat(_("%1$s could not be read."), lyx::from_utf8(filename))); + bformat(_("%1$s could not be read."), from_utf8(filename))); return false; } @@ -609,7 +619,7 @@ bool Buffer::readFile(LyXLex & lex, string const & filename) if (!lex.isOK()) { Alert::error(_("Document could not be read"), - bformat(_("%1$s could not be read."), lyx::from_utf8(filename))); + bformat(_("%1$s could not be read."), from_utf8(filename))); return false; } @@ -619,7 +629,7 @@ bool Buffer::readFile(LyXLex & lex, string const & filename) Alert::error(_("Document format failure"), bformat(_("%1$s is not a LyX document."), - lyx::from_utf8(filename))); + from_utf8(filename))); return false; } @@ -642,7 +652,7 @@ bool Buffer::readFile(LyXLex & lex, string const & filename) " version of LyX, but a temporary" " file for converting it could" " not be created."), - lyx::from_utf8(filename))); + from_utf8(filename))); return false; } string const lyx2lyx = libFileSearch("lyx2lyx", "lyx2lyx"); @@ -652,7 +662,7 @@ bool Buffer::readFile(LyXLex & lex, string const & filename) " version of LyX, but the" " conversion script lyx2lyx" " could not be found."), - lyx::from_utf8(filename))); + from_utf8(filename))); return false; } ostringstream command; @@ -672,7 +682,7 @@ bool Buffer::readFile(LyXLex & lex, string const & filename) bformat(_("%1$s is from an earlier version" " of LyX, but the lyx2lyx script" " failed to convert it."), - lyx::from_utf8(filename))); + from_utf8(filename))); return false; } else { bool const ret = readFile(tmpfile); @@ -686,7 +696,7 @@ bool Buffer::readFile(LyXLex & lex, string const & filename) Alert::error(_("Document format failure"), bformat(_("%1$s ended unexpectedly, which means" " that it is probably corrupted."), - lyx::from_utf8(filename))); + from_utf8(filename))); } //lyxerr << "removing " << MacroTable::localMacros().size() @@ -723,7 +733,7 @@ bool Buffer::save() const Alert::error(_("Backup failure"), bformat(_("LyX was not able to make a backup copy in %1$s.\n" "Please check if the directory exists and is writeable."), - lyx::from_utf8(fs::path(s).branch_path().native_directory_string()))); + from_utf8(fs::path(s).branch_path().native_directory_string()))); lyxerr[Debug::DEBUG] << "Fs error: " << fe.what() << endl; } @@ -816,27 +826,59 @@ bool Buffer::do_writeFile(ostream & ofs) const } -void Buffer::makeLaTeXFile(string const & fname, +bool Buffer::makeLaTeXFile(string const & fname, string const & original_path, OutputParams const & runparams, bool output_preamble, bool output_body) { - lyxerr[Debug::LATEX] << "makeLaTeXFile..." << endl; + string encoding; + if (params().inputenc == "auto") + encoding = params().language->encoding()->iconvName(); + else { + Encoding const * enc = encodings.getFromLaTeXName(params().inputenc); + if (enc) + encoding = enc->iconvName(); + else { + lyxerr << "Unknown inputenc value `" + << params().inputenc + << "'. Using `auto' instead." << endl; + encoding = params().language->encoding()->iconvName(); + } + } + lyxerr[Debug::LATEX] << "makeLaTeXFile encoding: " + << encoding << "..." << endl; - ofstream ofs; + odocfstream ofs(encoding); if (!openFileWrite(ofs, fname)) - return; + return false; - writeLaTeXSource(ofs, original_path, + try { + writeLaTeXSource(ofs, original_path, runparams, output_preamble, output_body); + } + catch (iconv_codecvt_facet_exception &) { + Alert::error(_("Encoding error"), + _("Some characters of your document are not " + "representable in the chosen encoding.\n" + "Changing the document encoding to utf8 could help.")); + return false; + } ofs.close(); - if (ofs.fail()) + if (ofs.fail()) { lyxerr << "File '" << fname << "' was not closed properly." << endl; + Alert::error(_("Error closing file"), + _("The output file could not be closed properly.\n" + " Probably some characters of your document are not " + "representable in the chosen encoding.\n" + "Changing the document encoding to utf8 could help.")); + return false; + } + return true; } -void Buffer::writeLaTeXSource(ostream & os, +void Buffer::writeLaTeXSource(odocstream & os, string const & original_path, OutputParams const & runparams_in, bool const output_preamble, bool const output_body) @@ -882,11 +924,13 @@ void Buffer::writeLaTeXSource(ostream & os, texrow().newline(); } if (!original_path.empty()) { - string const inputpath = latex_path(original_path); + // FIXME UNICODE + // We don't know the encoding of inputpath + docstring const inputpath = from_utf8(latex_path(original_path)); os << "\\makeatletter\n" - << "\\def\\input@path{{" - << inputpath << "/}}\n" - << "\\makeatother\n"; + << "\\def\\input@path{{" + << inputpath << "/}}\n" + << "\\makeatother\n"; texrow().newline(); texrow().newline(); texrow().newline(); @@ -905,9 +949,11 @@ void Buffer::writeLaTeXSource(ostream & os, lyxerr[Debug::INFO] << "preamble finished, now the body." << endl; if (!lyxrc.language_auto_begin) { - os << subst(lyxrc.language_command_begin, "$$lang", - params().language->babel()) - << endl; + // FIXME UNICODE + os << from_utf8(subst(lyxrc.language_command_begin, + "$$lang", + params().language->babel())) + << '\n'; texrow().newline(); } @@ -932,9 +978,10 @@ void Buffer::writeLaTeXSource(ostream & os, texrow().newline(); if (!lyxrc.language_auto_end) { - os << subst(lyxrc.language_command_end, "$$lang", - params().language->babel()) - << endl; + os << from_utf8(subst(lyxrc.language_command_end, + "$$lang", + params().language->babel())) + << '\n'; texrow().newline(); } @@ -981,7 +1028,8 @@ void Buffer::makeDocBookFile(string const & fname, { lyxerr[Debug::LATEX] << "makeDocBookFile..." << endl; - ofstream ofs; + //ofstream ofs; + odocfstream ofs; if (!openFileWrite(ofs, fname)) return; @@ -993,7 +1041,7 @@ void Buffer::makeDocBookFile(string const & fname, } -void Buffer::writeDocBookSource(ostream & os, string const & fname, +void Buffer::writeDocBookSource(odocstream & os, string const & fname, OutputParams const & runparams, bool const only_body) { @@ -1003,23 +1051,25 @@ void Buffer::writeDocBookSource(ostream & os, string const & fname, texrow().reset(); LyXTextClass const & tclass = params().getLyXTextClass(); - string const & top_element = tclass.latexname(); + string const top_element = tclass.latexname(); if (!only_body) { if (runparams.flavor == OutputParams::XML) - os << "encoding()->name() << "\"?>\n"; + os << "\n"; - os << "\n"; preamble += "\n"; @@ -1033,7 +1083,7 @@ void Buffer::writeDocBookSource(ostream & os, string const & fname, preamble += features.getLyXSGMLEntities(); if (!preamble.empty()) { - os << "\n [ " << preamble << " ]"; + os << "\n [ " << preamble << " ]"; } os << ">\n\n"; } @@ -1075,7 +1125,7 @@ int Buffer::runChktex() string const path = temppath(); string const org_path = filePath(); - lyx::support::Path p(path); // path to LaTeX file + support::Path p(path); // path to LaTeX file message(_("Running chktex...")); // Generate the LaTeX file if neccessary @@ -1108,14 +1158,15 @@ void Buffer::validate(LaTeXFeatures & features) const { LyXTextClass const & tclass = params().getLyXTextClass(); - if (features.isAvailable("dvipost") && params().tracking_changes - && params().output_changes) + if (features.isAvailable("dvipost") && params().outputChanges) features.require("dvipost"); // AMS Style is at document level - if (params().use_amsmath == BufferParams::AMS_ON + if (params().use_amsmath == BufferParams::package_on || tclass.provides(LyXTextClass::amsmath)) features.require("amsmath"); + if (params().use_esint == BufferParams::package_on) + features.require("esint"); for_each(paragraphs().begin(), paragraphs().end(), boost::bind(&Paragraph::validate, _1, boost::ref(features))); @@ -1150,7 +1201,7 @@ void Buffer::validate(LaTeXFeatures & features) const } -void Buffer::getLabelList(vector & list) const +void Buffer::getLabelList(vector & list) const { /// if this is a child document and the parent is already loaded /// Use the parent's list instead [ale990407] @@ -1278,7 +1329,7 @@ bool Buffer::dispatch(FuncRequest const & func, bool * result) switch (func.action) { case LFUN_BUFFER_EXPORT: { - bool const tmp = Exporter::Export(this, lyx::to_utf8(func.argument()), false); + bool const tmp = Exporter::Export(this, to_utf8(func.argument()), false); if (result) *result = tmp; break; @@ -1357,25 +1408,25 @@ bool Buffer::hasParWithID(int const id) const ParIterator Buffer::par_iterator_begin() { - return ::par_iterator_begin(inset()); + return lyx::par_iterator_begin(inset()); } ParIterator Buffer::par_iterator_end() { - return ::par_iterator_end(inset()); + return lyx::par_iterator_end(inset()); } ParConstIterator Buffer::par_iterator_begin() const { - return ::par_const_iterator_begin(inset()); + return lyx::par_const_iterator_begin(inset()); } ParConstIterator Buffer::par_iterator_end() const { - return ::par_const_iterator_end(inset()); + return lyx::par_const_iterator_end(inset()); } @@ -1387,14 +1438,25 @@ Language const * Buffer::getLanguage() const docstring const Buffer::B_(string const & l10n) const { - if (pimpl_->messages.get()) { + if (pimpl_->messages.get()) return pimpl_->messages->get(l10n); - } return _(l10n); } +docstring const Buffer::translateLabel(docstring const & label) const +{ + if (support::isAscii(label)) + // Probably standard layout, try to translate + return B_(to_ascii(label)); + else + // This must be a user defined layout. We can not translate + // this, since gettext accepts only ascii keys. + return label; +} + + bool Buffer::isClean() const { return pimpl_->lyx_clean; @@ -1451,9 +1513,8 @@ void Buffer::markDirty() DepClean::iterator it = pimpl_->dep_clean.begin(); DepClean::const_iterator const end = pimpl_->dep_clean.end(); - for (; it != end; ++it) { + for (; it != end; ++it) it->second = false; - } } @@ -1484,8 +1545,8 @@ void Buffer::setParentName(string const & name) Buffer const * Buffer::getMasterBuffer() const { if (!params().parentname.empty() - && bufferlist.exists(params().parentname)) { - Buffer const * buf = bufferlist.getBuffer(params().parentname); + && theBufferList().exists(params().parentname)) { + Buffer const * buf = theBufferList().getBuffer(params().parentname); if (buf) return buf->getMasterBuffer(); } @@ -1497,8 +1558,8 @@ Buffer const * Buffer::getMasterBuffer() const Buffer * Buffer::getMasterBuffer() { if (!params().parentname.empty() - && bufferlist.exists(params().parentname)) { - Buffer * buf = bufferlist.getBuffer(params().parentname); + && theBufferList().exists(params().parentname)) { + Buffer * buf = theBufferList().getBuffer(params().parentname); if (buf) return buf->getMasterBuffer(); } @@ -1507,19 +1568,19 @@ Buffer * Buffer::getMasterBuffer() } -MacroData const & Buffer::getMacro(std::string const & name) const +MacroData const & Buffer::getMacro(docstring const & name) const { return pimpl_->macros.get(name); } -bool Buffer::hasMacro(string const & name) const +bool Buffer::hasMacro(docstring const & name) const { return pimpl_->macros.has(name); } -void Buffer::insertMacro(string const & name, MacroData const & data) +void Buffer::insertMacro(docstring const & name, MacroData const & data) { MacroTable::globalMacros().insert(name, data); pimpl_->macros.insert(name, data); @@ -1558,37 +1619,40 @@ void Buffer::saveCursor(StableDocIterator cur, StableDocIterator anc) } -void Buffer::changeRefsIfUnique(string const & from, string const & to) +void Buffer::changeRefsIfUnique(docstring const & from, docstring const & to, + InsetBase::Code code) { + //FIXME: This does not work for child documents yet. + BOOST_ASSERT(code == InsetBase::CITE_CODE || code == InsetBase::REF_CODE); // Check if the label 'from' appears more than once - vector labels; - getLabelList(labels); + vector labels; + + if (code == InsetBase::CITE_CODE) { + vector > keys; + fillWithBibKeys(keys); + vector >::const_iterator bit = keys.begin(); + vector >::const_iterator bend = keys.end(); + + for (; bit != bend; ++bit) + // FIXME UNICODE + labels.push_back(from_utf8(bit->first)); + } else + getLabelList(labels); if (lyx::count(labels.begin(), labels.end(), from) > 1) return; - InsetBase::Code code = InsetBase::REF_CODE; - - ParIterator it = par_iterator_begin(); - ParIterator end = par_iterator_end(); - for ( ; it != end; ++it) { - bool changed_inset = false; - for (InsetList::iterator it2 = it->insetlist.begin(); - it2 != it->insetlist.end(); ++it2) { - if (it2->inset->lyxCode() == code) { - InsetCommand * inset = static_cast(it2->inset); - if (inset->getContents() == from) { - inset->setContents(to); - //inset->setButtonLabel(); - changed_inset = true; - } - } + for (InsetIterator it = inset_iterator_begin(inset()); it; ++it) { + if (it->lyxCode() == code) { + InsetCommand & inset = dynamic_cast(*it); + inset.replaceContents(to_utf8(from), to_utf8(to)); } } } -void Buffer::getSourceCode(ostream & os, lyx::pit_type par_begin, lyx::pit_type par_end, bool full_source) +void Buffer::getSourceCode(odocstream & os, pit_type par_begin, + pit_type par_end, bool full_source) { OutputParams runparams; runparams.nice = true; @@ -1597,25 +1661,30 @@ void Buffer::getSourceCode(ostream & os, lyx::pit_type par_begin, lyx::pit_type // No side effect of file copying and image conversion runparams.dryrun = true; + /* Support for docbook temprarily commented out. */ if (full_source) { os << "% Preview source code\n\n"; if (isLatex()) writeLaTeXSource(os, filePath(), runparams, true, true); - else + else { writeDocBookSource(os, fileName(), runparams, false); + } } else { runparams.par_begin = par_begin; runparams.par_end = par_end; if (par_begin + 1 == par_end) os << "% Preview source code for paragraph " << par_begin << "\n\n"; else - os << "% Preview source code from paragraph " << par_begin << " to " << par_end - 1 << "\n\n"; + os << "% Preview source code from paragraph " << par_begin + << " to " << par_end - 1 << "\n\n"; // output paragraphs if (isLatex()) { texrow().reset(); latexParagraphs(*this, paragraphs(), os, texrow(), runparams); - } else // DocBook + } else { + // DocBook docbookParagraphs(paragraphs(), *this, os, runparams); + } } } @@ -1635,3 +1704,6 @@ ErrorList & Buffer::errorList(string const & type) { return errorLists_[type]; } + + +} // namespace lyx