2003-03-29 09:48:03 +00:00
|
|
|
|
/**
|
2007-04-26 04:41:58 +00:00
|
|
|
|
* \file Buffer.cpp
|
2003-03-29 09:48:03 +00:00
|
|
|
|
* This file is part of LyX, the document processor.
|
|
|
|
|
* Licence details can be found in the file COPYING.
|
2002-03-21 16:55:34 +00:00
|
|
|
|
*
|
2007-05-25 09:20:35 +00:00
|
|
|
|
* \author Lars Gullik Bj<EFBFBD>nnes
|
2007-11-01 11:13:07 +00:00
|
|
|
|
* \author Stefan Schimanski
|
1999-09-27 18:44:28 +00:00
|
|
|
|
*
|
2003-08-23 00:17:00 +00:00
|
|
|
|
* Full author contact details are available in file CREDITS.
|
1999-09-27 18:44:28 +00:00
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
|
2007-04-26 04:41:58 +00:00
|
|
|
|
#include "Buffer.h"
|
2003-09-06 18:38:02 +00:00
|
|
|
|
|
2007-04-26 04:41:58 +00:00
|
|
|
|
#include "Author.h"
|
2007-08-20 17:04:36 +00:00
|
|
|
|
#include "BiblioInfo.h"
|
2005-03-27 13:31:04 +00:00
|
|
|
|
#include "BranchList.h"
|
2003-06-24 20:42:15 +00:00
|
|
|
|
#include "buffer_funcs.h"
|
2007-04-26 04:41:58 +00:00
|
|
|
|
#include "BufferList.h"
|
|
|
|
|
#include "BufferParams.h"
|
2003-09-09 17:00:19 +00:00
|
|
|
|
#include "Bullet.h"
|
2001-12-10 20:06:59 +00:00
|
|
|
|
#include "Chktex.h"
|
2007-10-20 10:51:13 +00:00
|
|
|
|
#include "Converter.h"
|
|
|
|
|
#include "Counters.h"
|
2007-08-21 07:33:46 +00:00
|
|
|
|
#include "DocIterator.h"
|
2007-10-21 10:50:56 +00:00
|
|
|
|
#include "EmbeddedFiles.h"
|
2007-04-26 04:41:58 +00:00
|
|
|
|
#include "Encoding.h"
|
|
|
|
|
#include "ErrorList.h"
|
|
|
|
|
#include "Exporter.h"
|
|
|
|
|
#include "Format.h"
|
|
|
|
|
#include "FuncRequest.h"
|
|
|
|
|
#include "InsetIterator.h"
|
2007-10-18 15:29:51 +00:00
|
|
|
|
#include "InsetList.h"
|
2007-04-26 04:41:58 +00:00
|
|
|
|
#include "Language.h"
|
2003-09-06 18:38:02 +00:00
|
|
|
|
#include "LaTeXFeatures.h"
|
2007-10-21 10:50:56 +00:00
|
|
|
|
#include "LaTeX.h"
|
2007-09-29 20:02:32 +00:00
|
|
|
|
#include "Layout.h"
|
2007-04-26 11:30:54 +00:00
|
|
|
|
#include "Lexer.h"
|
2007-10-21 10:50:56 +00:00
|
|
|
|
#include "LyXAction.h"
|
2007-05-16 10:39:41 +00:00
|
|
|
|
#include "LyX.h"
|
2007-04-26 04:41:58 +00:00
|
|
|
|
#include "LyXRC.h"
|
|
|
|
|
#include "LyXVC.h"
|
2003-11-05 12:06:20 +00:00
|
|
|
|
#include "output_docbook.h"
|
2007-10-21 10:50:56 +00:00
|
|
|
|
#include "output.h"
|
2003-11-05 12:06:20 +00:00
|
|
|
|
#include "output_latex.h"
|
2007-10-20 10:51:13 +00:00
|
|
|
|
#include "output_plaintext.h"
|
2003-09-06 18:38:02 +00:00
|
|
|
|
#include "paragraph_funcs.h"
|
2007-10-21 10:50:56 +00:00
|
|
|
|
#include "Paragraph.h"
|
2003-09-06 18:38:02 +00:00
|
|
|
|
#include "ParagraphParameters.h"
|
2007-04-26 04:41:58 +00:00
|
|
|
|
#include "ParIterator.h"
|
2007-10-21 10:50:56 +00:00
|
|
|
|
#include "PDFOptions.h"
|
2007-10-03 11:00:18 +00:00
|
|
|
|
#include "Session.h"
|
2003-09-06 18:38:02 +00:00
|
|
|
|
#include "sgml.h"
|
2007-04-26 04:41:58 +00:00
|
|
|
|
#include "TexRow.h"
|
2007-08-12 14:54:54 +00:00
|
|
|
|
#include "TexStream.h"
|
2007-10-21 10:50:56 +00:00
|
|
|
|
#include "TextClassList.h"
|
|
|
|
|
#include "Text.h"
|
2006-11-11 00:35:14 +00:00
|
|
|
|
#include "TocBackend.h"
|
2007-04-26 04:41:58 +00:00
|
|
|
|
#include "Undo.h"
|
2007-10-21 10:50:56 +00:00
|
|
|
|
#include "VCBackend.h"
|
2003-09-06 18:38:02 +00:00
|
|
|
|
#include "version.h"
|
2001-12-10 20:06:59 +00:00
|
|
|
|
|
2007-04-25 01:24:38 +00:00
|
|
|
|
#include "insets/InsetBibitem.h"
|
|
|
|
|
#include "insets/InsetBibtex.h"
|
|
|
|
|
#include "insets/InsetInclude.h"
|
|
|
|
|
#include "insets/InsetText.h"
|
2001-12-10 20:06:59 +00:00
|
|
|
|
|
2007-04-28 20:44:46 +00:00
|
|
|
|
#include "mathed/MacroTable.h"
|
2007-11-01 11:13:07 +00:00
|
|
|
|
#include "mathed/MathMacroTemplate.h"
|
2006-09-17 09:14:18 +00:00
|
|
|
|
#include "mathed/MathSupport.h"
|
2004-04-13 06:27:29 +00:00
|
|
|
|
|
2007-04-28 20:44:46 +00:00
|
|
|
|
#include "frontends/alert.h"
|
2007-10-02 18:27:20 +00:00
|
|
|
|
#include "frontends/Delegates.h"
|
2007-10-02 09:00:08 +00:00
|
|
|
|
#include "frontends/WorkAreaManager.h"
|
2001-12-10 20:06:59 +00:00
|
|
|
|
|
2002-07-05 21:24:15 +00:00
|
|
|
|
#include "graphics/Previews.h"
|
|
|
|
|
|
2007-11-29 07:04:28 +00:00
|
|
|
|
#include "support/convert.h"
|
|
|
|
|
#include "support/debug.h"
|
2007-10-03 11:00:18 +00:00
|
|
|
|
#include "support/FileFilterList.h"
|
1999-10-02 16:21:10 +00:00
|
|
|
|
#include "support/filetools.h"
|
2007-11-29 19:19:39 +00:00
|
|
|
|
#include "support/ForkedCalls.h"
|
2007-11-29 07:04:28 +00:00
|
|
|
|
#include "support/gettext.h"
|
2007-08-01 15:16:44 +00:00
|
|
|
|
#include "support/gzstream.h"
|
2007-11-13 23:50:28 +00:00
|
|
|
|
#include "support/lstrings.h"
|
2007-11-29 07:04:28 +00:00
|
|
|
|
#include "support/lyxalgo.h"
|
2003-09-06 18:38:02 +00:00
|
|
|
|
#include "support/lyxlib.h"
|
2001-05-17 15:11:01 +00:00
|
|
|
|
#include "support/os.h"
|
Rename files in src/support, step one.
src/support/package.h src/support/Package.h Package
src/support/package.C.in src/support/Package.C.in Package
src/support/path.h src/support/Path.h Path
src/support/fs_extras.h src/support/fs_extras.h NOCLASSES
src/support/RandomAccessList.h src/support/RandomAccessList.h RandomAccessList
src/support/lyxmanip.h src/support/lyxmanip.h NOCLASSES
src/support/rename.C src/support/rename.cpp NOCLASSES
src/support/abort.C src/support/abort.cpp NOCLASSES
src/support/lyxlib.h src/support/lyxlib.h NOCLASSES
src/support/ExceptionMessage.h src/support/ExceptionMessage.h ExceptionMessage
src/support/copy.C src/support/copy.cpp NOCLASSES
src/support/limited_stack.h src/support/limited_stack.h limited_stack
src/support/filefilterlist.C src/support/FileFilterList.cpp ['FileFilterList', 'Filter']
src/support/cow_ptr.h src/support/cow_ptr.h cow_ptr
src/support/os_unix.C src/support/os_unix.cpp NOCLASSES
src/support/socktools.h src/support/socktools.h NOCLASSES
src/support/forkedcontr.h src/support/ForkedcallsController.h ForkedcallsController
src/support/os.h src/support/os.h NOCLASSES
src/support/FileMonitor.h src/support/FileMonitor.h FileMonitor
src/support/copied_ptr.h src/support/copied_ptr.h copied_ptr
src/support/translator.h src/support/Translator.h Translator
src/support/filetools.C src/support/filetools.cpp NOCLASSES
src/support/unlink.C src/support/unlink.cpp NOCLASSES
src/support/os_win32.C src/support/os_win32.cpp GetFolderPath
src/support/lstrings.C src/support/lstrings.cpp NOCLASSES
src/support/qstring_helpers.C src/support/qstring_helpers.cpp NOCLASSES
src/support/getcwd.C src/support/getcwd.cpp NOCLASSES
src/support/systemcall.C src/support/Systemcall.cpp Systemcall
src/support/lyxalgo.h src/support/lyxalgo.h NOCLASSES
src/support/filefilterlist.h src/support/FileFilterList.h ['FileFilterList', 'Filter']
src/support/unicode.C src/support/unicode.cpp IconvProcessor
src/support/userinfo.C src/support/userinfo.cpp NOCLASSES
src/support/lyxtime.C src/support/lyxtime.cpp NOCLASSES
src/support/kill.C src/support/kill.cpp NOCLASSES
src/support/docstring.C src/support/docstring.cpp to_local8bit_failure
src/support/os_cygwin.C src/support/os_cygwin.cpp NOCLASSES
src/support/lyxsum.C src/support/lyxsum.cpp NOCLASSES
src/support/environment.C src/support/environment.cpp NOCLASSES
src/support/filetools.h src/support/filetools.h NOCLASSES
src/support/textutils.C src/support/textutils.cpp NOCLASSES
src/support/mkdir.C src/support/mkdir.cpp NOCLASSES
src/support/forkedcall.C src/support/Forkedcall.cpp ['ForkedProcess', 'Forkedcall']
src/support/tempname.C src/support/tempname.cpp NOCLASSES
src/support/os_win32.h src/support/os_win32.h GetFolderPath
src/support/types.h src/support/types.h NOCLASSES
src/support/lstrings.h src/support/lstrings.h NOCLASSES
src/support/forkedcallqueue.C src/support/ForkedCallQueue.cpp ForkedCallQueue
src/support/qstring_helpers.h src/support/qstring_helpers.h NOCLASSES
src/support/convert.C src/support/convert.cpp NOCLASSES
src/support/filename.C src/support/FileName.cpp ['FileName', 'DocFileName']
src/support/tests/convert.C src/support/tests/convert.cpp NOCLASSES
src/support/tests/filetools.C src/support/tests/filetools.cpp NOCLASSES
src/support/tests/lstrings.C src/support/tests/lstrings.cpp NOCLASSES
src/support/tests/boost.C src/support/tests/boost.cpp NOCLASSES
src/support/docstream.C src/support/docstream.cpp ['iconv_codecvt_facet_exception', 'idocfstream', 'odocfstream']
src/support/std_istream.h src/support/std_istream.h NOCLASSES
src/support/systemcall.h src/support/Systemcall.h Systemcall
src/support/chdir.C src/support/chdir.cpp NOCLASSES
src/support/std_ostream.h src/support/std_ostream.h NOCLASSES
src/support/unicode.h src/support/unicode.h IconvProcessor
src/support/path.C src/support/Path.cpp Path
src/support/fs_extras.C src/support/fs_extras.cpp NOCLASSES
src/support/userinfo.h src/support/userinfo.h NOCLASSES
src/support/lyxtime.h src/support/lyxtime.h NOCLASSES
src/support/docstring.h src/support/docstring.h to_local8bit_failure
src/support/debugstream.h src/support/debugstream.h basic_debugstream
src/support/environment.h src/support/environment.h NOCLASSES
src/support/textutils.h src/support/textutils.h NOCLASSES
src/support/forkedcall.h src/support/Forkedcall.h ['ForkedProcess', 'Forkedcall']
src/support/socktools.C src/support/socktools.cpp NOCLASSES
src/support/forkedcallqueue.h src/support/ForkedCallQueue.h ForkedCallQueue
src/support/forkedcontr.C src/support/ForkedcallsController.cpp ForkedcallsController
src/support/os.C src/support/os.cpp NOCLASSES
src/support/convert.h src/support/convert.h NOCLASSES
src/support/filename.h src/support/FileName.h ['FileName', 'DocFileName']
src/support/docstream.h src/support/docstream.h ['iconv_codecvt_facet_exception', 'idocfstream', 'odocfstream']
src/support/FileMonitor.C src/support/FileMonitor.cpp FileMonitor
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@18024 a592a061-630c-0410-9148-cb99ea01b6c8
2007-04-26 05:12:52 +00:00
|
|
|
|
#include "support/Path.h"
|
2003-09-06 18:38:02 +00:00
|
|
|
|
#include "support/textutils.h"
|
2007-11-29 07:04:28 +00:00
|
|
|
|
#include "support/types.h"
|
2007-12-02 10:43:11 +00:00
|
|
|
|
#include "support/FileZipListDir.h"
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
2007-10-03 22:22:40 +00:00
|
|
|
|
#if !defined (HAVE_FORK)
|
|
|
|
|
# define fork() -1
|
|
|
|
|
#endif
|
|
|
|
|
|
2002-08-14 22:15:18 +00:00
|
|
|
|
#include <boost/bind.hpp>
|
2007-10-03 11:00:18 +00:00
|
|
|
|
#include <boost/shared_ptr.hpp>
|
2002-08-14 22:15:18 +00:00
|
|
|
|
|
2007-08-12 08:57:17 +00:00
|
|
|
|
#include <algorithm>
|
2001-12-08 14:20:11 +00:00
|
|
|
|
#include <iomanip>
|
|
|
|
|
#include <stack>
|
2004-07-24 10:55:30 +00:00
|
|
|
|
#include <sstream>
|
2005-01-20 16:17:37 +00:00
|
|
|
|
#include <fstream>
|
2001-12-08 14:20:11 +00:00
|
|
|
|
|
2007-07-17 17:40:44 +00:00
|
|
|
|
using std::endl;
|
|
|
|
|
using std::for_each;
|
|
|
|
|
using std::make_pair;
|
|
|
|
|
|
|
|
|
|
using std::ios;
|
|
|
|
|
using std::map;
|
|
|
|
|
using std::ostream;
|
|
|
|
|
using std::ostringstream;
|
|
|
|
|
using std::ofstream;
|
2007-08-30 20:46:42 +00:00
|
|
|
|
using std::ifstream;
|
2007-07-17 17:40:44 +00:00
|
|
|
|
using std::pair;
|
|
|
|
|
using std::stack;
|
|
|
|
|
using std::vector;
|
|
|
|
|
using std::string;
|
2007-08-09 20:46:22 +00:00
|
|
|
|
using std::time_t;
|
2007-07-17 17:40:44 +00:00
|
|
|
|
|
2006-10-21 00:16:43 +00:00
|
|
|
|
namespace lyx {
|
|
|
|
|
|
|
|
|
|
using support::addName;
|
|
|
|
|
using support::bformat;
|
|
|
|
|
using support::changeExtension;
|
|
|
|
|
using support::cmd_ret;
|
|
|
|
|
using support::createBufferTmpDir;
|
2006-11-26 21:30:39 +00:00
|
|
|
|
using support::FileName;
|
2006-10-21 00:16:43 +00:00
|
|
|
|
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;
|
2007-09-04 15:16:24 +00:00
|
|
|
|
using support::suffixIs;
|
2006-10-21 00:16:43 +00:00
|
|
|
|
|
|
|
|
|
namespace Alert = frontend::Alert;
|
|
|
|
|
namespace os = support::os;
|
2003-09-16 11:03:20 +00:00
|
|
|
|
|
2001-03-20 01:22:46 +00:00
|
|
|
|
namespace {
|
1999-12-10 00:07:59 +00:00
|
|
|
|
|
2007-12-04 09:25:50 +00:00
|
|
|
|
int const LYX_FORMAT = 304; // JSpitzm: framed.sty goes InsetBox
|
2001-03-20 01:22:46 +00:00
|
|
|
|
|
|
|
|
|
} // namespace anon
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
2003-09-09 11:24:33 +00:00
|
|
|
|
|
|
|
|
|
typedef std::map<string, bool> DepClean;
|
|
|
|
|
|
2005-01-19 15:03:31 +00:00
|
|
|
|
class Buffer::Impl
|
2003-09-09 11:24:33 +00:00
|
|
|
|
{
|
2005-01-19 15:03:31 +00:00
|
|
|
|
public:
|
2006-11-30 16:59:50 +00:00
|
|
|
|
Impl(Buffer & parent, FileName const & file, bool readonly);
|
2007-11-30 20:30:09 +00:00
|
|
|
|
|
|
|
|
|
~Impl()
|
|
|
|
|
{
|
|
|
|
|
if (wa_) {
|
|
|
|
|
wa_->closeAll();
|
|
|
|
|
delete wa_;
|
|
|
|
|
}
|
|
|
|
|
}
|
2007-10-18 11:51:17 +00:00
|
|
|
|
|
2003-09-09 11:24:33 +00:00
|
|
|
|
BufferParams params;
|
|
|
|
|
LyXVC lyxvc;
|
|
|
|
|
string temppath;
|
2007-11-30 17:41:27 +00:00
|
|
|
|
mutable TexRow texrow;
|
|
|
|
|
Buffer const * parent_buffer;
|
2003-09-09 11:24:33 +00:00
|
|
|
|
|
2004-03-01 17:12:09 +00:00
|
|
|
|
/// need to regenerate .tex?
|
2003-09-09 11:24:33 +00:00
|
|
|
|
DepClean dep_clean;
|
|
|
|
|
|
2004-03-01 17:12:09 +00:00
|
|
|
|
/// is save needed?
|
2003-09-09 11:24:33 +00:00
|
|
|
|
mutable bool lyx_clean;
|
|
|
|
|
|
2004-03-01 17:12:09 +00:00
|
|
|
|
/// is autosave needed?
|
2003-09-09 11:24:33 +00:00
|
|
|
|
mutable bool bak_clean;
|
|
|
|
|
|
2004-03-01 17:12:09 +00:00
|
|
|
|
/// is this a unnamed file (New...)?
|
2003-09-09 11:24:33 +00:00
|
|
|
|
bool unnamed;
|
|
|
|
|
|
|
|
|
|
/// buffer is r/o
|
|
|
|
|
bool read_only;
|
|
|
|
|
|
|
|
|
|
/// name of the file the buffer is associated with.
|
2006-11-30 16:59:50 +00:00
|
|
|
|
FileName filename;
|
2003-09-09 11:24:33 +00:00
|
|
|
|
|
2004-03-01 17:12:09 +00:00
|
|
|
|
/** Set to true only when the file is fully loaded.
|
2003-10-22 13:15:18 +00:00
|
|
|
|
* Used to prevent the premature generation of previews
|
|
|
|
|
* and by the citation inset.
|
|
|
|
|
*/
|
|
|
|
|
bool file_fully_loaded;
|
2003-11-28 15:08:38 +00:00
|
|
|
|
|
2007-04-29 23:33:02 +00:00
|
|
|
|
/// our Text that should be wrapped in an InsetText
|
2004-03-18 12:53:43 +00:00
|
|
|
|
InsetText inset;
|
2004-04-13 06:27:29 +00:00
|
|
|
|
|
2006-11-11 00:35:14 +00:00
|
|
|
|
///
|
2007-11-30 17:41:27 +00:00
|
|
|
|
mutable TocBackend toc_backend;
|
2007-06-15 13:13:49 +00:00
|
|
|
|
|
2007-11-01 11:13:07 +00:00
|
|
|
|
/// macro table
|
|
|
|
|
typedef std::map<unsigned int, MacroData, std::greater<int> > PositionToMacroMap;
|
|
|
|
|
typedef std::map<docstring, PositionToMacroMap> NameToPositionMacroMap;
|
|
|
|
|
NameToPositionMacroMap macros;
|
|
|
|
|
|
2007-06-15 13:13:49 +00:00
|
|
|
|
/// Container for all sort of Buffer dependant errors.
|
|
|
|
|
map<string, ErrorList> errorLists;
|
2007-08-09 20:46:22 +00:00
|
|
|
|
|
2007-08-30 20:46:42 +00:00
|
|
|
|
/// all embedded files of this buffer
|
|
|
|
|
EmbeddedFiles embedded_files;
|
|
|
|
|
|
2007-08-09 20:46:22 +00:00
|
|
|
|
/// timestamp and checksum used to test if the file has been externally
|
|
|
|
|
/// modified. (Used to properly enable 'File->Revert to saved', bug 4114).
|
|
|
|
|
time_t timestamp_;
|
|
|
|
|
unsigned long checksum_;
|
2007-10-02 09:00:08 +00:00
|
|
|
|
|
|
|
|
|
///
|
|
|
|
|
frontend::WorkAreaManager * wa_;
|
2007-10-18 11:51:17 +00:00
|
|
|
|
|
|
|
|
|
///
|
|
|
|
|
Undo undo_;
|
2003-09-09 11:24:33 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2006-11-30 16:59:50 +00:00
|
|
|
|
Buffer::Impl::Impl(Buffer & parent, FileName const & file, bool readonly_)
|
2007-11-30 17:41:27 +00:00
|
|
|
|
: parent_buffer(0), lyx_clean(true), bak_clean(true), unnamed(false),
|
|
|
|
|
read_only(readonly_), filename(file), file_fully_loaded(false),
|
|
|
|
|
inset(params), toc_backend(&parent), embedded_files(&parent),
|
|
|
|
|
timestamp_(0), checksum_(0), wa_(0), undo_(parent)
|
2003-09-09 11:24:33 +00:00
|
|
|
|
{
|
2005-01-31 17:21:17 +00:00
|
|
|
|
inset.setAutoBreakRows(true);
|
2007-10-20 17:35:27 +00:00
|
|
|
|
lyxvc.setBuffer(&parent);
|
2004-02-25 12:00:53 +00:00
|
|
|
|
temppath = createBufferTmpDir();
|
2007-11-28 15:25:07 +00:00
|
|
|
|
|
2004-02-25 12:00:53 +00:00
|
|
|
|
// FIXME: And now do something if temppath == string(), because we
|
|
|
|
|
// assume from now on that temppath points to a valid temp dir.
|
|
|
|
|
// See http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg67406.html
|
2007-10-02 09:00:08 +00:00
|
|
|
|
|
|
|
|
|
if (use_gui)
|
|
|
|
|
wa_ = new frontend::WorkAreaManager;
|
2003-09-09 11:24:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2005-07-14 22:09:22 +00:00
|
|
|
|
Buffer::Buffer(string const & file, bool readonly)
|
2007-11-30 17:46:49 +00:00
|
|
|
|
: d(new Impl(*this, FileName(file), readonly)), gui_(0)
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
2007-11-15 20:04:51 +00:00
|
|
|
|
LYXERR(Debug::INFO, "Buffer::Buffer()");
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Buffer::~Buffer()
|
|
|
|
|
{
|
2007-11-15 20:04:51 +00:00
|
|
|
|
LYXERR(Debug::INFO, "Buffer::~Buffer()");
|
1999-09-27 18:44:28 +00:00
|
|
|
|
// here the buffer should take care that it is
|
|
|
|
|
// saved properly, before it goes into the void.
|
|
|
|
|
|
2007-12-01 12:17:00 +00:00
|
|
|
|
// GuiView already destroyed
|
|
|
|
|
gui_ = 0;
|
|
|
|
|
|
2007-11-30 17:41:27 +00:00
|
|
|
|
Buffer const * master = masterBuffer();
|
2007-08-21 07:33:46 +00:00
|
|
|
|
if (master != this && use_gui)
|
|
|
|
|
// We are closing buf which was a child document so we
|
|
|
|
|
// must update the labels and section numbering of its master
|
|
|
|
|
// Buffer.
|
|
|
|
|
updateLabels(*master);
|
2003-07-11 12:21:31 +00:00
|
|
|
|
|
2007-11-30 17:41:27 +00:00
|
|
|
|
resetChildDocuments(false);
|
|
|
|
|
|
2007-10-20 17:35:27 +00:00
|
|
|
|
if (!temppath().empty() && !FileName(temppath()).destroyDirectory()) {
|
2006-09-11 08:54:10 +00:00
|
|
|
|
Alert::warning(_("Could not remove temporary directory"),
|
|
|
|
|
bformat(_("Could not remove the temporary directory %1$s"),
|
2006-10-21 00:16:43 +00:00
|
|
|
|
from_utf8(temppath())));
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
2002-03-21 16:55:34 +00:00
|
|
|
|
|
2003-08-22 08:47:32 +00:00
|
|
|
|
// Remove any previewed LaTeX snippets associated with this buffer.
|
2006-10-21 00:16:43 +00:00
|
|
|
|
graphics::Previews::get().removeLoader(*this);
|
2007-12-01 09:51:45 +00:00
|
|
|
|
|
|
|
|
|
delete d;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-10-02 18:27:20 +00:00
|
|
|
|
void Buffer::changed() const
|
2007-10-02 09:00:08 +00:00
|
|
|
|
{
|
2007-11-30 17:46:49 +00:00
|
|
|
|
if (d->wa_)
|
|
|
|
|
d->wa_->redrawAll();
|
2007-10-02 09:00:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-10-02 14:39:48 +00:00
|
|
|
|
frontend::WorkAreaManager & Buffer::workAreaManager() const
|
2007-10-02 09:00:08 +00:00
|
|
|
|
{
|
2007-11-30 17:46:49 +00:00
|
|
|
|
BOOST_ASSERT(d->wa_);
|
|
|
|
|
return *d->wa_;
|
2007-10-02 09:00:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-10-02 14:39:48 +00:00
|
|
|
|
|
2007-04-29 23:33:02 +00:00
|
|
|
|
Text & Buffer::text() const
|
2003-11-28 15:08:38 +00:00
|
|
|
|
{
|
2007-11-30 17:46:49 +00:00
|
|
|
|
return const_cast<Text &>(d->inset.text_);
|
2004-03-18 12:53:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-04-29 13:39:47 +00:00
|
|
|
|
Inset & Buffer::inset() const
|
2004-03-18 12:53:43 +00:00
|
|
|
|
{
|
2007-11-30 17:46:49 +00:00
|
|
|
|
return const_cast<InsetText &>(d->inset);
|
2003-11-28 15:08:38 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2003-09-09 09:47:59 +00:00
|
|
|
|
BufferParams & Buffer::params()
|
|
|
|
|
{
|
2007-11-30 17:46:49 +00:00
|
|
|
|
return d->params;
|
2003-09-09 09:47:59 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BufferParams const & Buffer::params() const
|
|
|
|
|
{
|
2007-11-30 17:46:49 +00:00
|
|
|
|
return d->params;
|
2003-09-09 09:47:59 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ParagraphList & Buffer::paragraphs()
|
|
|
|
|
{
|
2004-03-18 12:53:43 +00:00
|
|
|
|
return text().paragraphs();
|
2003-09-09 09:47:59 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ParagraphList const & Buffer::paragraphs() const
|
|
|
|
|
{
|
2004-03-18 12:53:43 +00:00
|
|
|
|
return text().paragraphs();
|
2003-09-09 09:47:59 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LyXVC & Buffer::lyxvc()
|
|
|
|
|
{
|
2007-11-30 17:46:49 +00:00
|
|
|
|
return d->lyxvc;
|
2003-09-09 09:47:59 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LyXVC const & Buffer::lyxvc() const
|
|
|
|
|
{
|
2007-11-30 17:46:49 +00:00
|
|
|
|
return d->lyxvc;
|
2003-09-09 09:47:59 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
string const & Buffer::temppath() const
|
|
|
|
|
{
|
2007-11-30 17:46:49 +00:00
|
|
|
|
return d->temppath;
|
2003-09-09 09:47:59 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TexRow const & Buffer::texrow() const
|
|
|
|
|
{
|
2007-11-30 17:46:49 +00:00
|
|
|
|
return d->texrow;
|
2003-09-09 09:47:59 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-11-30 17:41:27 +00:00
|
|
|
|
TocBackend & Buffer::tocBackend() const
|
2006-11-11 00:35:14 +00:00
|
|
|
|
{
|
2007-11-30 17:46:49 +00:00
|
|
|
|
return d->toc_backend;
|
2006-11-11 00:35:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-08-30 20:46:42 +00:00
|
|
|
|
EmbeddedFiles & Buffer::embeddedFiles()
|
|
|
|
|
{
|
2007-11-30 17:46:49 +00:00
|
|
|
|
return d->embedded_files;
|
2007-08-30 20:46:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
EmbeddedFiles const & Buffer::embeddedFiles() const
|
|
|
|
|
{
|
2007-11-30 17:46:49 +00:00
|
|
|
|
return d->embedded_files;
|
2007-08-30 20:46:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-10-20 10:03:45 +00:00
|
|
|
|
|
2007-10-18 11:51:17 +00:00
|
|
|
|
Undo & Buffer::undo()
|
|
|
|
|
{
|
2007-11-30 17:46:49 +00:00
|
|
|
|
return d->undo_;
|
2007-10-18 11:51:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-10-20 10:03:45 +00:00
|
|
|
|
string Buffer::latexName(bool const no_path) const
|
2000-04-08 17:02:02 +00:00
|
|
|
|
{
|
2007-11-30 17:46:49 +00:00
|
|
|
|
FileName latex_name = makeLatexName(d->filename);
|
2007-11-28 18:07:09 +00:00
|
|
|
|
return no_path ? latex_name.onlyFileName()
|
|
|
|
|
: latex_name.absFilename();
|
2000-04-08 17:02:02 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-14 14:54:30 +00:00
|
|
|
|
|
2007-11-01 22:17:22 +00:00
|
|
|
|
string Buffer::logName(LogType * type) const
|
2001-02-06 17:41:42 +00:00
|
|
|
|
{
|
2007-10-20 10:03:45 +00:00
|
|
|
|
string const filename = latexName(false);
|
2001-02-06 17:41:42 +00:00
|
|
|
|
|
2007-11-01 22:17:22 +00:00
|
|
|
|
if (filename.empty()) {
|
|
|
|
|
if (type)
|
|
|
|
|
*type = latexlog;
|
|
|
|
|
return string();
|
|
|
|
|
}
|
2001-02-06 17:41:42 +00:00
|
|
|
|
|
2004-02-25 12:00:53 +00:00
|
|
|
|
string const path = temppath();
|
2001-02-06 17:41:42 +00:00
|
|
|
|
|
2006-11-30 16:59:50 +00:00
|
|
|
|
FileName const fname(addName(temppath(),
|
2006-04-08 22:31:11 +00:00
|
|
|
|
onlyFilename(changeExtension(filename,
|
2006-11-30 16:59:50 +00:00
|
|
|
|
".log"))));
|
|
|
|
|
FileName const bname(
|
2006-04-08 22:31:11 +00:00
|
|
|
|
addName(path, onlyFilename(
|
|
|
|
|
changeExtension(filename,
|
2006-11-30 16:59:50 +00:00
|
|
|
|
formats.extension("literate") + ".out"))));
|
2001-02-06 17:41:42 +00:00
|
|
|
|
|
|
|
|
|
// If no Latex log or Build log is newer, show Build log
|
2001-02-09 15:54:30 +00:00
|
|
|
|
|
2007-10-18 19:29:32 +00:00
|
|
|
|
if (bname.exists() &&
|
|
|
|
|
(!fname.exists() || fname.lastModified() < bname.lastModified())) {
|
2007-11-15 20:04:51 +00:00
|
|
|
|
LYXERR(Debug::FILES, "Log name calculated as: " << bname);
|
2007-11-01 22:17:22 +00:00
|
|
|
|
if (type)
|
|
|
|
|
*type = buildlog;
|
|
|
|
|
return bname.absFilename();
|
2001-02-09 15:54:30 +00:00
|
|
|
|
}
|
2007-11-15 20:04:51 +00:00
|
|
|
|
LYXERR(Debug::FILES, "Log name calculated as: " << fname);
|
2007-11-01 22:17:22 +00:00
|
|
|
|
if (type)
|
|
|
|
|
*type = latexlog;
|
|
|
|
|
return fname.absFilename();
|
2001-02-06 17:41:42 +00:00
|
|
|
|
}
|
2000-04-08 17:02:02 +00:00
|
|
|
|
|
2001-03-14 14:54:30 +00:00
|
|
|
|
|
2005-01-05 20:21:27 +00:00
|
|
|
|
void Buffer::setReadonly(bool const flag)
|
2000-04-08 17:02:02 +00:00
|
|
|
|
{
|
2007-11-30 17:46:49 +00:00
|
|
|
|
if (d->read_only != flag) {
|
|
|
|
|
d->read_only = flag;
|
2007-10-23 21:41:17 +00:00
|
|
|
|
setReadOnly(flag);
|
2000-04-08 17:02:02 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2000-10-12 00:11:06 +00:00
|
|
|
|
void Buffer::setFileName(string const & newfile)
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
2007-11-30 17:46:49 +00:00
|
|
|
|
d->filename = makeAbsPath(newfile);
|
|
|
|
|
setReadonly(d->filename.isReadOnly());
|
1999-09-27 18:44:28 +00:00
|
|
|
|
updateTitles();
|
|
|
|
|
}
|
|
|
|
|
|
1999-12-10 00:07:59 +00:00
|
|
|
|
|
2007-04-26 11:30:54 +00:00
|
|
|
|
int Buffer::readHeader(Lexer & lex)
|
2003-03-12 02:39:12 +00:00
|
|
|
|
{
|
|
|
|
|
int unknown_tokens = 0;
|
2004-08-14 18:41:27 +00:00
|
|
|
|
int line = -1;
|
|
|
|
|
int begin_header_line = -1;
|
2003-03-12 02:39:12 +00:00
|
|
|
|
|
2005-03-27 13:31:04 +00:00
|
|
|
|
// Initialize parameters that may be/go lacking in header:
|
|
|
|
|
params().branchlist().clear();
|
2006-02-22 17:34:43 +00:00
|
|
|
|
params().preamble.erase();
|
2005-03-27 13:31:04 +00:00
|
|
|
|
params().options.erase();
|
|
|
|
|
params().float_placement.erase();
|
|
|
|
|
params().paperwidth.erase();
|
|
|
|
|
params().paperheight.erase();
|
|
|
|
|
params().leftmargin.erase();
|
|
|
|
|
params().rightmargin.erase();
|
|
|
|
|
params().topmargin.erase();
|
|
|
|
|
params().bottommargin.erase();
|
|
|
|
|
params().headheight.erase();
|
|
|
|
|
params().headsep.erase();
|
|
|
|
|
params().footskip.erase();
|
2007-05-25 12:32:08 +00:00
|
|
|
|
params().listings_params.clear();
|
This is one of a series of patches that will merge the layout modules development in personal/branches/rgheck back into the tree.
Design goal: Allow the use of layout "modules", which are to LaTeX packages as layout files are to LaTeX document classes. Thus, one could have a module that defined certain character styles, environments, commands, or what have you, and include it in various documents, each of which uses a different document class, without having to modify the layout files themselves. For example, a theorems.module could be used with article.layout to provide support for theorem-type environments, without having to modify article.layout itself, and the same module could be used with book.layout, etc.
This patch adds the backend. The ModuleList class holds a list of the available modules, which are retrieved from lyxmodules.lst, itself generated by configure.py. There are two LFUNs available: modules-clear and module-add, which do the obvious thing; you can test by typing these into the minibuffer, along with the name of one of the available modules: URL (a CharStyle), Endnote (a Custom Inset), and---with the spaces---End To Foot (View>LaTeX and look at the user preamble), which are themselves in lib/layouts. There are some others, too, that allow theorems to be added to classes like article and book.
The GUI will come next.
Issues: (i) The configure.py script could be improved. It'd be nice, for example, if it tested for the presence of the LaTeX packages a particular module needs. But this would mean re-working the LaTeX script, and I don't know how to do that. Note that at present, the packages are ignored. This will change shortly. (ii) I've used std::string in LyXModule, following what seemed to be a precedent in TextClass. If some of these should be docstrings, please let me know, and I'll change them. (iii) There is at present no distinction between LaTeX and DocBook modules. Should there be? That is: Should there be modules that are available when the document class is a LaTeX class and others that are available only when it is DocBook? Or should there just be one set of modules? Each module can of course indicate for what it is suitable in its description.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@19893 a592a061-630c-0410-9148-cb99ea01b6c8
2007-08-29 17:59:49 +00:00
|
|
|
|
params().clearLayoutModules();
|
2007-09-20 22:31:18 +00:00
|
|
|
|
params().pdfoptions().clear();
|
This is one of a series of patches that will merge the layout modules development in personal/branches/rgheck back into the tree.
Design goal: Allow the use of layout "modules", which are to LaTeX packages as layout files are to LaTeX document classes. Thus, one could have a module that defined certain character styles, environments, commands, or what have you, and include it in various documents, each of which uses a different document class, without having to modify the layout files themselves. For example, a theorems.module could be used with article.layout to provide support for theorem-type environments, without having to modify article.layout itself, and the same module could be used with book.layout, etc.
This first patch does some reworking of the infrastructrue. We need to distinguish between the TextClass that a particular document is using and the layout of that document, since modules, in particular, can modify the layout. The solution adopted here is to add a TextClass pointer to BufferParams, which will hold the layout. The layout itself is then constructed from the TextClass the document is using. At present, this is completely trivial, but that will change when modules are added.
The pointer in question is a boost::shared_ptr. This is needed because CutAndPaste saves a copy of the layout with each cut or copied selection. We cannot assume the selection vanishes when the document is closed, so there are two options: (i) keep a list of all the layouts that have ever been used by any document; (ii) used some kind of smart pointer. The latter seems preferable, as the former would waste memory. More importantly, the use of a smart pointer allows modules to be modified on disk and then reloaded while LyX is running, and it will eventually allow the same for layout files.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@19756 a592a061-630c-0410-9148-cb99ea01b6c8
2007-08-23 16:41:13 +00:00
|
|
|
|
|
2007-03-12 15:15:21 +00:00
|
|
|
|
for (int i = 0; i < 4; ++i) {
|
|
|
|
|
params().user_defined_bullet(i) = ITEMIZE_DEFAULTS[i];
|
|
|
|
|
params().temp_bullet(i) = ITEMIZE_DEFAULTS[i];
|
|
|
|
|
}
|
2005-03-27 13:31:04 +00:00
|
|
|
|
|
2007-11-30 17:46:49 +00:00
|
|
|
|
ErrorList & errorList = d->errorLists["Parse"];
|
2006-08-13 16:16:43 +00:00
|
|
|
|
|
2003-03-12 02:39:12 +00:00
|
|
|
|
while (lex.isOK()) {
|
2004-08-14 18:41:27 +00:00
|
|
|
|
lex.next();
|
2003-03-12 02:39:12 +00:00
|
|
|
|
string const token = lex.getString();
|
|
|
|
|
|
|
|
|
|
if (token.empty())
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (token == "\\end_header")
|
|
|
|
|
break;
|
|
|
|
|
|
2004-08-14 18:41:27 +00:00
|
|
|
|
++line;
|
|
|
|
|
if (token == "\\begin_header") {
|
|
|
|
|
begin_header_line = line;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2007-11-15 20:04:51 +00:00
|
|
|
|
LYXERR(Debug::PARSER, "Handling document header token: `"
|
|
|
|
|
<< token << '\'');
|
2003-03-12 02:39:12 +00:00
|
|
|
|
|
2007-11-30 17:46:49 +00:00
|
|
|
|
string unknown = params().readToken(lex, token, d->filename.onlyPath());
|
2003-03-12 02:39:12 +00:00
|
|
|
|
if (!unknown.empty()) {
|
2005-01-19 15:26:41 +00:00
|
|
|
|
if (unknown[0] != '\\' && token == "\\textclass") {
|
2007-10-20 10:03:45 +00:00
|
|
|
|
Alert::warning(_("Unknown document class"),
|
|
|
|
|
bformat(_("Using the default document class, because the "
|
|
|
|
|
"class %1$s is unknown."), from_utf8(unknown)));
|
2003-03-12 02:39:12 +00:00
|
|
|
|
} else {
|
2003-03-29 10:29:38 +00:00
|
|
|
|
++unknown_tokens;
|
2006-09-11 08:54:10 +00:00
|
|
|
|
docstring const s = bformat(_("Unknown token: "
|
|
|
|
|
"%1$s %2$s\n"),
|
2006-10-21 00:16:43 +00:00
|
|
|
|
from_utf8(token),
|
2006-11-22 09:15:38 +00:00
|
|
|
|
lex.getDocString());
|
2006-09-11 08:54:10 +00:00
|
|
|
|
errorList.push_back(ErrorItem(_("Document header error"),
|
2006-07-15 22:43:37 +00:00
|
|
|
|
s, -1, 0, 0));
|
2003-03-12 02:39:12 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2004-08-14 18:41:27 +00:00
|
|
|
|
if (begin_header_line) {
|
2006-09-11 08:54:10 +00:00
|
|
|
|
docstring const s = _("\\begin_header is missing");
|
|
|
|
|
errorList.push_back(ErrorItem(_("Document header error"),
|
2006-07-15 22:43:37 +00:00
|
|
|
|
s, -1, 0, 0));
|
2004-08-14 18:41:27 +00:00
|
|
|
|
}
|
2006-07-15 22:43:37 +00:00
|
|
|
|
|
2003-03-12 02:39:12 +00:00
|
|
|
|
return unknown_tokens;
|
|
|
|
|
}
|
|
|
|
|
|
2001-08-30 07:13:15 +00:00
|
|
|
|
|
1999-09-27 18:44:28 +00:00
|
|
|
|
// Uwe C. Schroeder
|
|
|
|
|
// changed to be public and have one parameter
|
2003-07-28 22:30:50 +00:00
|
|
|
|
// Returns false if "\end_document" is not read (Asger)
|
2007-04-26 11:30:54 +00:00
|
|
|
|
bool Buffer::readDocument(Lexer & lex)
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
2007-11-30 17:46:49 +00:00
|
|
|
|
ErrorList & errorList = d->errorLists["Parse"];
|
2006-08-13 16:16:43 +00:00
|
|
|
|
errorList.clear();
|
2006-07-15 22:43:37 +00:00
|
|
|
|
|
2004-08-14 18:41:27 +00:00
|
|
|
|
lex.next();
|
|
|
|
|
string const token = lex.getString();
|
|
|
|
|
if (token != "\\begin_document") {
|
2006-09-11 08:54:10 +00:00
|
|
|
|
docstring const s = _("\\begin_document is missing");
|
|
|
|
|
errorList.push_back(ErrorItem(_("Document header error"),
|
2006-07-15 22:43:37 +00:00
|
|
|
|
s, -1, 0, 0));
|
2004-08-14 18:41:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
2005-11-29 15:08:35 +00:00
|
|
|
|
// we are reading in a brand new document
|
|
|
|
|
BOOST_ASSERT(paragraphs().empty());
|
|
|
|
|
|
|
|
|
|
readHeader(lex);
|
2007-09-08 17:50:09 +00:00
|
|
|
|
TextClass const & baseClass = textclasslist[params().getBaseClass()];
|
|
|
|
|
if (!baseClass.load(filePath())) {
|
|
|
|
|
string theclass = baseClass.name();
|
2006-09-11 08:54:10 +00:00
|
|
|
|
Alert::error(_("Can't load document class"), bformat(
|
|
|
|
|
_("Using the default document class, because the "
|
2006-12-02 23:39:17 +00:00
|
|
|
|
"class %1$s could not be loaded."), from_utf8(theclass)));
|
This is one of a series of patches that will merge the layout modules development in personal/branches/rgheck back into the tree.
Design goal: Allow the use of layout "modules", which are to LaTeX packages as layout files are to LaTeX document classes. Thus, one could have a module that defined certain character styles, environments, commands, or what have you, and include it in various documents, each of which uses a different document class, without having to modify the layout files themselves. For example, a theorems.module could be used with article.layout to provide support for theorem-type environments, without having to modify article.layout itself, and the same module could be used with book.layout, etc.
This first patch does some reworking of the infrastructrue. We need to distinguish between the TextClass that a particular document is using and the layout of that document, since modules, in particular, can modify the layout. The solution adopted here is to add a TextClass pointer to BufferParams, which will hold the layout. The layout itself is then constructed from the TextClass the document is using. At present, this is completely trivial, but that will change when modules are added.
The pointer in question is a boost::shared_ptr. This is needed because CutAndPaste saves a copy of the layout with each cut or copied selection. We cannot assume the selection vanishes when the document is closed, so there are two options: (i) keep a list of all the layouts that have ever been used by any document; (ii) used some kind of smart pointer. The latter seems preferable, as the former would waste memory. More importantly, the use of a smart pointer allows modules to be modified on disk and then reloaded while LyX is running, and it will eventually allow the same for layout files.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@19756 a592a061-630c-0410-9148-cb99ea01b6c8
2007-08-23 16:41:13 +00:00
|
|
|
|
params().setBaseClass(defaultTextclass());
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-05-08 17:46:03 +00:00
|
|
|
|
if (params().outputChanges) {
|
2007-05-13 15:17:57 +00:00
|
|
|
|
bool dvipost = LaTeXFeatures::isAvailable("dvipost");
|
|
|
|
|
bool xcolorsoul = LaTeXFeatures::isAvailable("soul") &&
|
2007-05-28 22:27:45 +00:00
|
|
|
|
LaTeXFeatures::isAvailable("xcolor");
|
|
|
|
|
|
2007-05-13 15:17:57 +00:00
|
|
|
|
if (!dvipost && !xcolorsoul) {
|
2007-05-08 17:46:03 +00:00
|
|
|
|
Alert::warning(_("Changes not shown in LaTeX output"),
|
2007-05-28 22:27:45 +00:00
|
|
|
|
_("Changes will not be highlighted in LaTeX output, "
|
|
|
|
|
"because neither dvipost nor xcolor/soul are installed.\n"
|
|
|
|
|
"Please install these packages or redefine "
|
|
|
|
|
"\\lyxadded and \\lyxdeleted in the LaTeX preamble."));
|
2007-05-13 15:17:57 +00:00
|
|
|
|
} else if (!xcolorsoul) {
|
2007-05-08 17:46:03 +00:00
|
|
|
|
Alert::warning(_("Changes not shown in LaTeX output"),
|
2007-05-28 22:27:45 +00:00
|
|
|
|
_("Changes will not be highlighted in LaTeX output "
|
|
|
|
|
"when using pdflatex, because xcolor and soul are not installed.\n"
|
|
|
|
|
"Please install both packages or redefine "
|
|
|
|
|
"\\lyxadded and \\lyxdeleted in the LaTeX preamble."));
|
2007-05-08 17:46:03 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-09-11 14:23:12 +00:00
|
|
|
|
// read main text
|
2006-08-13 16:16:43 +00:00
|
|
|
|
bool const res = text().read(*this, lex, errorList);
|
2005-11-29 15:08:35 +00:00
|
|
|
|
for_each(text().paragraphs().begin(),
|
|
|
|
|
text().paragraphs().end(),
|
|
|
|
|
bind(&Paragraph::setInsetOwner, _1, &inset()));
|
2006-07-15 22:43:37 +00:00
|
|
|
|
|
2005-11-29 15:08:35 +00:00
|
|
|
|
return res;
|
2000-03-01 14:13:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2001-07-23 09:11:14 +00:00
|
|
|
|
// needed to insert the selection
|
2004-03-25 09:16:36 +00:00
|
|
|
|
void Buffer::insertStringAsLines(ParagraphList & pars,
|
2005-01-31 17:21:17 +00:00
|
|
|
|
pit_type & pit, pos_type & pos,
|
2007-04-29 18:17:15 +00:00
|
|
|
|
Font const & fn, docstring const & str, bool autobreakrows)
|
2001-07-23 09:11:14 +00:00
|
|
|
|
{
|
2007-04-29 18:17:15 +00:00
|
|
|
|
Font font = fn;
|
2002-03-21 16:55:34 +00:00
|
|
|
|
|
2001-07-23 09:11:14 +00:00
|
|
|
|
// insert the string, don't insert doublespace
|
|
|
|
|
bool space_inserted = true;
|
2006-09-03 07:02:38 +00:00
|
|
|
|
for (docstring::const_iterator cit = str.begin();
|
2005-02-08 13:18:05 +00:00
|
|
|
|
cit != str.end(); ++cit) {
|
2005-01-31 17:21:17 +00:00
|
|
|
|
Paragraph & par = pars[pit];
|
2001-07-23 09:11:14 +00:00
|
|
|
|
if (*cit == '\n') {
|
2005-01-31 17:21:17 +00:00
|
|
|
|
if (autobreakrows && (!par.empty() || par.allowEmpty())) {
|
|
|
|
|
breakParagraph(params(), pars, pit, pos,
|
|
|
|
|
par.layout()->isEnvironment());
|
|
|
|
|
++pit;
|
2001-07-23 09:11:14 +00:00
|
|
|
|
pos = 0;
|
|
|
|
|
space_inserted = true;
|
|
|
|
|
} else {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
// do not insert consecutive spaces if !free_spacing
|
2001-10-22 09:45:31 +00:00
|
|
|
|
} else if ((*cit == ' ' || *cit == '\t') &&
|
2005-01-31 17:21:17 +00:00
|
|
|
|
space_inserted && !par.isFreeSpacing()) {
|
2001-07-23 09:11:14 +00:00
|
|
|
|
continue;
|
|
|
|
|
} else if (*cit == '\t') {
|
2005-01-31 17:21:17 +00:00
|
|
|
|
if (!par.isFreeSpacing()) {
|
2001-07-23 09:11:14 +00:00
|
|
|
|
// tabs are like spaces here
|
2006-10-20 11:44:58 +00:00
|
|
|
|
par.insertChar(pos, ' ', font, params().trackChanges);
|
2001-07-23 09:11:14 +00:00
|
|
|
|
++pos;
|
|
|
|
|
space_inserted = true;
|
|
|
|
|
} else {
|
2004-02-11 14:45:44 +00:00
|
|
|
|
const pos_type n = 8 - pos % 8;
|
|
|
|
|
for (pos_type i = 0; i < n; ++i) {
|
2006-10-20 11:44:58 +00:00
|
|
|
|
par.insertChar(pos, ' ', font, params().trackChanges);
|
2001-07-23 09:11:14 +00:00
|
|
|
|
++pos;
|
|
|
|
|
}
|
|
|
|
|
space_inserted = true;
|
|
|
|
|
}
|
2006-04-08 09:09:57 +00:00
|
|
|
|
} else if (!isPrintable(*cit)) {
|
2001-07-23 09:11:14 +00:00
|
|
|
|
// Ignore unprintables
|
|
|
|
|
continue;
|
|
|
|
|
} else {
|
|
|
|
|
// just insert the character
|
2006-10-20 11:44:58 +00:00
|
|
|
|
par.insertChar(pos, *cit, font, params().trackChanges);
|
2001-07-23 09:11:14 +00:00
|
|
|
|
++pos;
|
|
|
|
|
space_inserted = (*cit == ' ');
|
|
|
|
|
}
|
|
|
|
|
|
2002-03-21 16:55:34 +00:00
|
|
|
|
}
|
2001-07-23 09:11:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
2000-07-24 21:49:58 +00:00
|
|
|
|
|
2007-01-13 18:29:50 +00:00
|
|
|
|
bool Buffer::readString(std::string const & s)
|
|
|
|
|
{
|
|
|
|
|
params().compressed = false;
|
|
|
|
|
|
|
|
|
|
// remove dummy empty par
|
|
|
|
|
paragraphs().clear();
|
2007-04-26 11:30:54 +00:00
|
|
|
|
Lexer lex(0, 0);
|
2007-01-13 18:29:50 +00:00
|
|
|
|
std::istringstream is(s);
|
|
|
|
|
lex.setStream(is);
|
|
|
|
|
FileName const name(tempName());
|
2007-01-29 18:35:56 +00:00
|
|
|
|
switch (readFile(lex, name, true)) {
|
2007-01-13 18:29:50 +00:00
|
|
|
|
case failure:
|
|
|
|
|
return false;
|
|
|
|
|
case wrongversion: {
|
|
|
|
|
// We need to call lyx2lyx, so write the input to a file
|
|
|
|
|
std::ofstream os(name.toFilesystemEncoding().c_str());
|
|
|
|
|
os << s;
|
|
|
|
|
os.close();
|
2007-01-29 18:35:56 +00:00
|
|
|
|
return readFile(name);
|
2007-01-13 18:29:50 +00:00
|
|
|
|
}
|
|
|
|
|
case success:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2006-12-17 12:12:17 +00:00
|
|
|
|
bool Buffer::readFile(FileName const & filename)
|
2003-03-12 05:46:35 +00:00
|
|
|
|
{
|
2007-08-30 20:46:42 +00:00
|
|
|
|
FileName fname(filename);
|
2003-07-28 14:40:29 +00:00
|
|
|
|
// Check if the file is compressed.
|
2007-10-20 17:35:27 +00:00
|
|
|
|
string format = filename.guessFormatFromContents();
|
2007-08-30 20:46:42 +00:00
|
|
|
|
if (format == "zip") {
|
|
|
|
|
// decompress to a temp directory
|
2007-11-15 20:04:51 +00:00
|
|
|
|
LYXERR(Debug::FILES, filename << " is in zip format. Unzip to " << temppath());
|
2007-09-03 21:09:11 +00:00
|
|
|
|
::unzipToDir(filename.toFilesystemEncoding(), temppath());
|
2007-08-30 20:46:42 +00:00
|
|
|
|
//
|
2007-09-11 14:23:12 +00:00
|
|
|
|
FileName lyxfile(addName(temppath(), "content.lyx"));
|
2007-08-30 20:46:42 +00:00
|
|
|
|
// if both manifest.txt and file.lyx exist, this is am embedded file
|
2007-10-18 19:29:32 +00:00
|
|
|
|
if (lyxfile.exists()) {
|
2007-08-30 20:46:42 +00:00
|
|
|
|
params().embedded = true;
|
|
|
|
|
fname = lyxfile;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// The embedded lyx file can also be compressed, for backward compatibility
|
2007-10-20 17:35:27 +00:00
|
|
|
|
format = fname.guessFormatFromContents();
|
|
|
|
|
if (format == "gzip" || format == "zip" || format == "compress")
|
2003-09-09 09:47:59 +00:00
|
|
|
|
params().compressed = true;
|
2003-07-28 14:40:29 +00:00
|
|
|
|
|
2004-03-18 12:53:43 +00:00
|
|
|
|
// remove dummy empty par
|
|
|
|
|
paragraphs().clear();
|
2007-04-26 11:30:54 +00:00
|
|
|
|
Lexer lex(0, 0);
|
2007-08-30 20:46:42 +00:00
|
|
|
|
lex.setFile(fname);
|
|
|
|
|
if (readFile(lex, fname) != success)
|
2006-08-24 08:17:47 +00:00
|
|
|
|
return false;
|
2003-04-24 23:19:41 +00:00
|
|
|
|
|
2006-08-24 08:17:47 +00:00
|
|
|
|
return true;
|
2003-03-12 05:46:35 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-10-20 10:03:45 +00:00
|
|
|
|
bool Buffer::isFullyLoaded() const
|
2003-10-22 13:15:18 +00:00
|
|
|
|
{
|
2007-11-30 17:46:49 +00:00
|
|
|
|
return d->file_fully_loaded;
|
2003-10-22 13:15:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-10-20 10:03:45 +00:00
|
|
|
|
void Buffer::setFullyLoaded(bool value)
|
2003-10-22 14:40:24 +00:00
|
|
|
|
{
|
2007-11-30 17:46:49 +00:00
|
|
|
|
d->file_fully_loaded = value;
|
2003-10-22 14:40:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-04-26 11:30:54 +00:00
|
|
|
|
Buffer::ReadStatus Buffer::readFile(Lexer & lex, FileName const & filename,
|
2007-01-13 18:29:50 +00:00
|
|
|
|
bool fromstring)
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
2003-09-09 17:25:35 +00:00
|
|
|
|
BOOST_ASSERT(!filename.empty());
|
2003-09-02 08:26:20 +00:00
|
|
|
|
|
2003-03-29 11:34:53 +00:00
|
|
|
|
if (!lex.isOK()) {
|
2006-09-11 08:54:10 +00:00
|
|
|
|
Alert::error(_("Document could not be read"),
|
2006-12-17 12:12:17 +00:00
|
|
|
|
bformat(_("%1$s could not be read."), from_utf8(filename.absFilename())));
|
2007-01-13 18:29:50 +00:00
|
|
|
|
return failure;
|
2003-03-29 11:34:53 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lex.next();
|
2007-10-17 22:21:50 +00:00
|
|
|
|
string const token = lex.getString();
|
2003-03-29 11:34:53 +00:00
|
|
|
|
|
2007-03-26 13:43:49 +00:00
|
|
|
|
if (!lex) {
|
2006-09-11 08:54:10 +00:00
|
|
|
|
Alert::error(_("Document could not be read"),
|
2006-12-17 12:12:17 +00:00
|
|
|
|
bformat(_("%1$s could not be read."), from_utf8(filename.absFilename())));
|
2007-01-13 18:29:50 +00:00
|
|
|
|
return failure;
|
2003-03-29 11:34:53 +00:00
|
|
|
|
}
|
2002-05-22 12:33:02 +00:00
|
|
|
|
|
2003-03-29 11:34:53 +00:00
|
|
|
|
// the first token _must_ be...
|
|
|
|
|
if (token != "\\lyxformat") {
|
2003-07-28 23:05:58 +00:00
|
|
|
|
lyxerr << "Token: " << token << endl;
|
|
|
|
|
|
2006-09-11 08:54:10 +00:00
|
|
|
|
Alert::error(_("Document format failure"),
|
|
|
|
|
bformat(_("%1$s is not a LyX document."),
|
2006-12-17 12:12:17 +00:00
|
|
|
|
from_utf8(filename.absFilename())));
|
2007-01-13 18:29:50 +00:00
|
|
|
|
return failure;
|
2003-03-29 11:34:53 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-08-14 18:41:27 +00:00
|
|
|
|
lex.next();
|
2003-03-29 11:34:53 +00:00
|
|
|
|
string tmp_format = lex.getString();
|
|
|
|
|
//lyxerr << "LyX Format: `" << tmp_format << '\'' << endl;
|
|
|
|
|
// if present remove ".," from string.
|
|
|
|
|
string::size_type dot = tmp_format.find_first_of(".,");
|
|
|
|
|
//lyxerr << " dot found at " << dot << endl;
|
|
|
|
|
if (dot != string::npos)
|
|
|
|
|
tmp_format.erase(dot, 1);
|
2005-01-27 21:05:44 +00:00
|
|
|
|
int const file_format = convert<int>(tmp_format);
|
2003-03-29 11:34:53 +00:00
|
|
|
|
//lyxerr << "format: " << file_format << endl;
|
2003-09-02 08:26:20 +00:00
|
|
|
|
|
2007-08-30 14:50:12 +00:00
|
|
|
|
// save timestamp and checksum of the original disk file, making sure
|
|
|
|
|
// to not overwrite them with those of the file created in the tempdir
|
|
|
|
|
// when it has to be converted to the current format.
|
2007-11-30 17:46:49 +00:00
|
|
|
|
if (!d->checksum_) {
|
2007-09-04 15:03:50 +00:00
|
|
|
|
// Save the timestamp and checksum of disk file. If filename is an
|
2007-11-30 09:23:44 +00:00
|
|
|
|
// emergency file, save the timestamp and checksum of the original lyx file
|
2007-09-04 15:03:50 +00:00
|
|
|
|
// because isExternallyModified will check for this file. (BUG4193)
|
2007-11-14 23:30:13 +00:00
|
|
|
|
string diskfile = filename.absFilename();
|
2007-09-04 15:03:50 +00:00
|
|
|
|
if (suffixIs(diskfile, ".emergency"))
|
|
|
|
|
diskfile = diskfile.substr(0, diskfile.size() - 10);
|
2007-10-20 10:03:45 +00:00
|
|
|
|
saveCheckSum(FileName(diskfile));
|
2007-08-30 14:50:12 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-08-14 18:41:27 +00:00
|
|
|
|
if (file_format != LYX_FORMAT) {
|
2007-01-13 18:29:50 +00:00
|
|
|
|
|
|
|
|
|
if (fromstring)
|
|
|
|
|
// lyx2lyx would fail
|
|
|
|
|
return wrongversion;
|
|
|
|
|
|
2006-12-17 12:12:17 +00:00
|
|
|
|
FileName const tmpfile(tempName());
|
2004-02-25 12:00:53 +00:00
|
|
|
|
if (tmpfile.empty()) {
|
2006-09-11 08:54:10 +00:00
|
|
|
|
Alert::error(_("Conversion failed"),
|
2007-01-31 15:27:05 +00:00
|
|
|
|
bformat(_("%1$s is from a different"
|
2004-02-25 12:00:53 +00:00
|
|
|
|
" version of LyX, but a temporary"
|
|
|
|
|
" file for converting it could"
|
2006-09-11 08:54:10 +00:00
|
|
|
|
" not be created."),
|
2006-12-17 12:12:17 +00:00
|
|
|
|
from_utf8(filename.absFilename())));
|
2007-01-13 18:29:50 +00:00
|
|
|
|
return failure;
|
2004-02-25 12:00:53 +00:00
|
|
|
|
}
|
2006-11-26 21:30:39 +00:00
|
|
|
|
FileName const lyx2lyx = libFileSearch("lyx2lyx", "lyx2lyx");
|
2005-05-19 08:43:52 +00:00
|
|
|
|
if (lyx2lyx.empty()) {
|
2006-09-11 08:54:10 +00:00
|
|
|
|
Alert::error(_("Conversion script not found"),
|
2007-01-31 15:27:05 +00:00
|
|
|
|
bformat(_("%1$s is from a different"
|
2003-09-02 08:26:20 +00:00
|
|
|
|
" version of LyX, but the"
|
|
|
|
|
" conversion script lyx2lyx"
|
2006-09-11 08:54:10 +00:00
|
|
|
|
" could not be found."),
|
2006-12-17 12:12:17 +00:00
|
|
|
|
from_utf8(filename.absFilename())));
|
2007-01-13 18:29:50 +00:00
|
|
|
|
return failure;
|
2003-09-02 08:26:20 +00:00
|
|
|
|
}
|
2005-05-19 08:43:52 +00:00
|
|
|
|
ostringstream command;
|
2006-12-17 12:12:17 +00:00
|
|
|
|
command << os::python()
|
2007-05-28 22:27:45 +00:00
|
|
|
|
<< ' ' << quoteName(lyx2lyx.toFilesystemEncoding())
|
|
|
|
|
<< " -t " << convert<string>(LYX_FORMAT)
|
|
|
|
|
<< " -o " << quoteName(tmpfile.toFilesystemEncoding())
|
|
|
|
|
<< ' ' << quoteName(filename.toFilesystemEncoding());
|
2005-05-19 08:43:52 +00:00
|
|
|
|
string const command_str = command.str();
|
|
|
|
|
|
2007-11-15 20:04:51 +00:00
|
|
|
|
LYXERR(Debug::INFO, "Running '" << command_str << '\'');
|
2005-05-19 08:43:52 +00:00
|
|
|
|
|
2006-04-08 22:31:11 +00:00
|
|
|
|
cmd_ret const ret = runCommand(command_str);
|
2003-09-02 08:26:20 +00:00
|
|
|
|
if (ret.first != 0) {
|
2006-09-11 08:54:10 +00:00
|
|
|
|
Alert::error(_("Conversion script failed"),
|
2007-01-31 15:27:05 +00:00
|
|
|
|
bformat(_("%1$s is from a different version"
|
2003-09-02 08:26:20 +00:00
|
|
|
|
" of LyX, but the lyx2lyx script"
|
2006-09-11 08:54:10 +00:00
|
|
|
|
" failed to convert it."),
|
2006-12-17 12:12:17 +00:00
|
|
|
|
from_utf8(filename.absFilename())));
|
2007-01-13 18:29:50 +00:00
|
|
|
|
return failure;
|
2003-09-02 08:26:20 +00:00
|
|
|
|
} else {
|
2005-11-29 15:08:35 +00:00
|
|
|
|
bool const ret = readFile(tmpfile);
|
2003-09-02 08:26:20 +00:00
|
|
|
|
// Do stuff with tmpfile name and buffer name here.
|
2007-01-13 18:29:50 +00:00
|
|
|
|
return ret ? success : failure;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
2003-09-02 08:26:20 +00:00
|
|
|
|
|
2003-03-29 09:48:03 +00:00
|
|
|
|
}
|
2003-09-02 08:26:20 +00:00
|
|
|
|
|
2004-08-14 18:41:27 +00:00
|
|
|
|
if (readDocument(lex)) {
|
2006-09-11 08:54:10 +00:00
|
|
|
|
Alert::error(_("Document format failure"),
|
|
|
|
|
bformat(_("%1$s ended unexpectedly, which means"
|
|
|
|
|
" that it is probably corrupted."),
|
2006-12-17 12:12:17 +00:00
|
|
|
|
from_utf8(filename.absFilename())));
|
2003-03-29 11:34:53 +00:00
|
|
|
|
}
|
2004-08-14 18:41:27 +00:00
|
|
|
|
|
2007-11-30 17:46:49 +00:00
|
|
|
|
d->file_fully_loaded = true;
|
2007-01-13 18:29:50 +00:00
|
|
|
|
return success;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
2002-03-21 16:55:34 +00:00
|
|
|
|
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
2000-02-22 00:36:17 +00:00
|
|
|
|
// Should probably be moved to somewhere else: BufferView? LyXView?
|
2000-03-20 14:49:54 +00:00
|
|
|
|
bool Buffer::save() const
|
2000-02-22 00:36:17 +00:00
|
|
|
|
{
|
|
|
|
|
// We don't need autosaves in the immediate future. (Asger)
|
|
|
|
|
resetAutosaveTimers();
|
|
|
|
|
|
2007-11-30 17:46:49 +00:00
|
|
|
|
string const encodedFilename = d->filename.toFilesystemEncoding();
|
2007-01-14 17:31:15 +00:00
|
|
|
|
|
|
|
|
|
FileName backupName;
|
|
|
|
|
bool madeBackup = false;
|
|
|
|
|
|
2006-11-30 15:21:23 +00:00
|
|
|
|
// make a backup if the file already exists
|
2007-11-03 18:30:05 +00:00
|
|
|
|
if (lyxrc.make_backup && fileName().exists()) {
|
2007-10-20 10:03:45 +00:00
|
|
|
|
backupName = FileName(absFileName() + '~');
|
2007-10-21 17:57:13 +00:00
|
|
|
|
if (!lyxrc.backupdir_path.empty()) {
|
|
|
|
|
string const mangledName =
|
2007-11-28 15:25:07 +00:00
|
|
|
|
subst(subst(backupName.absFilename(), '/', '!'), ':', '!');
|
2007-01-14 17:31:15 +00:00
|
|
|
|
backupName = FileName(addName(lyxrc.backupdir_path,
|
2007-10-21 17:57:13 +00:00
|
|
|
|
mangledName));
|
|
|
|
|
}
|
2007-11-28 09:01:49 +00:00
|
|
|
|
if (fileName().copyTo(backupName, true)) {
|
2007-01-14 17:31:15 +00:00
|
|
|
|
madeBackup = true;
|
2007-11-07 19:52:11 +00:00
|
|
|
|
} else {
|
2006-09-11 08:54:10 +00:00
|
|
|
|
Alert::error(_("Backup failure"),
|
2007-05-28 22:27:45 +00:00
|
|
|
|
bformat(_("Cannot create backup file %1$s.\n"
|
|
|
|
|
"Please check whether the directory exists and is writeable."),
|
|
|
|
|
from_utf8(backupName.absFilename())));
|
2007-11-15 20:04:51 +00:00
|
|
|
|
//LYXERR(Debug::DEBUG, "Fs error: " << fe.what());
|
2000-02-22 00:36:17 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2002-03-21 16:55:34 +00:00
|
|
|
|
|
2007-08-09 20:46:22 +00:00
|
|
|
|
// ask if the disk file has been externally modified (use checksum method)
|
2007-11-03 18:30:05 +00:00
|
|
|
|
if (fileName().exists() && isExternallyModified(checksum_method)) {
|
2007-10-20 10:03:45 +00:00
|
|
|
|
docstring const file = makeDisplayPath(absFileName(), 20);
|
2007-08-09 20:46:22 +00:00
|
|
|
|
docstring text = bformat(_("Document %1$s has been externally modified. Are you sure "
|
|
|
|
|
"you want to overwrite this file?"), file);
|
|
|
|
|
int const ret = Alert::prompt(_("Overwrite modified file?"),
|
|
|
|
|
text, 1, 1, _("&Overwrite"), _("&Cancel"));
|
|
|
|
|
if (ret == 1)
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2007-11-30 17:46:49 +00:00
|
|
|
|
if (writeFile(d->filename)) {
|
2002-08-04 23:11:50 +00:00
|
|
|
|
markClean();
|
2007-01-14 17:31:15 +00:00
|
|
|
|
return true;
|
2000-02-22 00:36:17 +00:00
|
|
|
|
} else {
|
|
|
|
|
// Saving failed, so backup is not backup
|
2007-01-14 17:31:15 +00:00
|
|
|
|
if (madeBackup)
|
2007-11-30 17:46:49 +00:00
|
|
|
|
rename(backupName, d->filename);
|
2000-02-22 00:36:17 +00:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2006-11-30 16:59:50 +00:00
|
|
|
|
bool Buffer::writeFile(FileName const & fname) const
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
2007-11-30 17:46:49 +00:00
|
|
|
|
if (d->read_only && fname == d->filename)
|
1999-09-27 18:44:28 +00:00
|
|
|
|
return false;
|
|
|
|
|
|
2004-07-25 00:04:42 +00:00
|
|
|
|
bool retval = false;
|
2003-07-27 23:40:08 +00:00
|
|
|
|
|
2007-08-30 20:46:42 +00:00
|
|
|
|
FileName content;
|
|
|
|
|
if (params().embedded)
|
|
|
|
|
// first write the .lyx file to the temporary directory
|
2007-09-11 14:23:12 +00:00
|
|
|
|
content = FileName(addName(temppath(), "content.lyx"));
|
2007-08-30 20:46:42 +00:00
|
|
|
|
else
|
|
|
|
|
content = fname;
|
2007-12-04 22:21:25 +00:00
|
|
|
|
|
|
|
|
|
docstring const str = bformat(_("Saving document %1$s..."),
|
|
|
|
|
makeDisplayPath(content.absFilename()));
|
|
|
|
|
message(str);
|
|
|
|
|
|
2003-09-09 09:47:59 +00:00
|
|
|
|
if (params().compressed) {
|
2007-08-30 20:46:42 +00:00
|
|
|
|
gz::ogzstream ofs(content.toFilesystemEncoding().c_str(), ios::out|ios::trunc);
|
2007-12-04 22:21:25 +00:00
|
|
|
|
retval = ofs && write(ofs);
|
2003-07-28 14:40:29 +00:00
|
|
|
|
} else {
|
2007-08-30 20:46:42 +00:00
|
|
|
|
ofstream ofs(content.toFilesystemEncoding().c_str(), ios::out|ios::trunc);
|
2007-12-04 22:21:25 +00:00
|
|
|
|
retval = ofs && write(ofs);
|
|
|
|
|
}
|
2003-07-27 23:40:08 +00:00
|
|
|
|
|
2007-12-04 22:21:25 +00:00
|
|
|
|
if (!retval) {
|
|
|
|
|
message(str + _(" could not write file!."));
|
|
|
|
|
return false;
|
2003-07-28 14:40:29 +00:00
|
|
|
|
}
|
2000-09-14 17:53:12 +00:00
|
|
|
|
|
2007-12-04 22:21:25 +00:00
|
|
|
|
removeAutosaveFile(d->filename.absFilename());
|
|
|
|
|
saveCheckSum(d->filename);
|
|
|
|
|
message(str + _(" done."));
|
|
|
|
|
|
|
|
|
|
if (!params().embedded)
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
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)) {
|
|
|
|
|
message(str + _(" could not write embedded files!."));
|
|
|
|
|
return false;
|
2007-08-30 20:46:42 +00:00
|
|
|
|
}
|
2007-12-04 22:21:25 +00:00
|
|
|
|
message(str + _(" error while writing embedded files."));
|
|
|
|
|
return true;
|
2003-07-27 23:40:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-01-13 18:29:50 +00:00
|
|
|
|
bool Buffer::write(ostream & ofs) const
|
2003-07-27 23:40:08 +00:00
|
|
|
|
{
|
2000-09-14 17:53:12 +00:00
|
|
|
|
#ifdef HAVE_LOCALE
|
|
|
|
|
// Use the standard "C" locale for file output.
|
2000-09-15 10:24:15 +00:00
|
|
|
|
ofs.imbue(std::locale::classic());
|
2000-09-14 17:53:12 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
2003-09-09 09:47:59 +00:00
|
|
|
|
// The top of the file should not be written by params().
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
|
|
|
|
// write out a comment in the top of the file
|
2003-07-28 14:09:05 +00:00
|
|
|
|
ofs << "#LyX " << lyx_version
|
2001-02-14 19:22:41 +00:00
|
|
|
|
<< " created this file. For more info see http://www.lyx.org/\n"
|
2004-08-14 18:41:27 +00:00
|
|
|
|
<< "\\lyxformat " << LYX_FORMAT << "\n"
|
|
|
|
|
<< "\\begin_document\n";
|
2001-02-14 19:22:41 +00:00
|
|
|
|
|
2007-07-09 20:52:34 +00:00
|
|
|
|
|
|
|
|
|
/// For each author, set 'used' to true if there is a change
|
|
|
|
|
/// by this author in the document; otherwise set it to 'false'.
|
|
|
|
|
AuthorList::Authors::const_iterator a_it = params().authors().begin();
|
|
|
|
|
AuthorList::Authors::const_iterator a_end = params().authors().end();
|
|
|
|
|
for (; a_it != a_end; ++a_it)
|
2007-11-01 22:17:22 +00:00
|
|
|
|
a_it->second.setUsed(false);
|
2007-07-09 20:52:34 +00:00
|
|
|
|
|
|
|
|
|
ParIterator const end = par_iterator_end();
|
|
|
|
|
ParIterator it = par_iterator_begin();
|
|
|
|
|
for ( ; it != end; ++it)
|
|
|
|
|
it->checkAuthors(params().authors());
|
|
|
|
|
|
2003-12-02 12:39:14 +00:00
|
|
|
|
// now write out the buffer parameters.
|
2004-08-16 11:27:51 +00:00
|
|
|
|
ofs << "\\begin_header\n";
|
2003-09-09 09:47:59 +00:00
|
|
|
|
params().writeFile(ofs);
|
2003-03-12 02:39:12 +00:00
|
|
|
|
ofs << "\\end_header\n";
|
2004-10-05 10:11:42 +00:00
|
|
|
|
|
2003-12-02 12:39:14 +00:00
|
|
|
|
// write the text
|
2004-08-14 18:41:27 +00:00
|
|
|
|
ofs << "\n\\begin_body\n";
|
2003-12-02 12:39:14 +00:00
|
|
|
|
text().write(*this, ofs);
|
2004-08-14 18:41:27 +00:00
|
|
|
|
ofs << "\n\\end_body\n";
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
|
|
|
|
// Write marker that shows file is complete
|
2004-08-14 18:41:27 +00:00
|
|
|
|
ofs << "\\end_document" << endl;
|
2000-10-13 12:20:38 +00:00
|
|
|
|
|
2003-07-27 23:40:08 +00:00
|
|
|
|
// Shouldn't really be needed....
|
|
|
|
|
//ofs.close();
|
2000-10-13 12:20:38 +00:00
|
|
|
|
|
1999-12-07 00:44:53 +00:00
|
|
|
|
// how to check if close went ok?
|
2000-10-13 12:20:38 +00:00
|
|
|
|
// Following is an attempt... (BE 20001011)
|
2002-03-21 16:55:34 +00:00
|
|
|
|
|
2000-10-13 12:20:38 +00:00
|
|
|
|
// good() returns false if any error occured, including some
|
|
|
|
|
// formatting error.
|
|
|
|
|
// bad() returns true if something bad happened in the buffer,
|
|
|
|
|
// which should include file system full errors.
|
|
|
|
|
|
|
|
|
|
bool status = true;
|
2004-02-11 14:45:44 +00:00
|
|
|
|
if (!ofs) {
|
2000-10-13 12:20:38 +00:00
|
|
|
|
status = false;
|
2004-02-11 14:45:44 +00:00
|
|
|
|
lyxerr << "File was not closed properly." << endl;
|
2000-10-13 12:20:38 +00:00
|
|
|
|
}
|
2002-03-21 16:55:34 +00:00
|
|
|
|
|
2000-10-13 12:20:38 +00:00
|
|
|
|
return status;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2006-12-04 15:46:57 +00:00
|
|
|
|
bool Buffer::makeLaTeXFile(FileName const & fname,
|
2000-03-06 02:42:40 +00:00
|
|
|
|
string const & original_path,
|
2003-11-05 12:06:20 +00:00
|
|
|
|
OutputParams const & runparams,
|
2007-11-30 17:41:27 +00:00
|
|
|
|
bool output_preamble, bool output_body) const
|
2000-03-06 02:42:40 +00:00
|
|
|
|
{
|
2007-03-25 16:31:16 +00:00
|
|
|
|
string const encoding = runparams.encoding->iconvName();
|
2007-11-15 20:04:51 +00:00
|
|
|
|
LYXERR(Debug::LATEX, "makeLaTeXFile encoding: " << encoding << "...");
|
2002-03-21 16:55:34 +00:00
|
|
|
|
|
2006-10-26 15:01:45 +00:00
|
|
|
|
odocfstream ofs(encoding);
|
2003-11-05 12:06:20 +00:00
|
|
|
|
if (!openFileWrite(ofs, fname))
|
2006-10-26 15:01:45 +00:00
|
|
|
|
return false;
|
2002-03-21 16:55:34 +00:00
|
|
|
|
|
2007-08-12 14:54:54 +00:00
|
|
|
|
//TexStream ts(ofs.rdbuf(), &texrow());
|
|
|
|
|
|
2007-05-16 10:39:41 +00:00
|
|
|
|
bool failed_export = false;
|
2006-10-26 15:01:45 +00:00
|
|
|
|
try {
|
2007-11-30 17:46:49 +00:00
|
|
|
|
d->texrow.reset();
|
2006-10-26 15:01:45 +00:00
|
|
|
|
writeLaTeXSource(ofs, original_path,
|
2003-07-26 21:37:10 +00:00
|
|
|
|
runparams, output_preamble, output_body);
|
2006-10-26 15:01:45 +00:00
|
|
|
|
}
|
2007-05-16 10:39:41 +00:00
|
|
|
|
catch (iconv_codecvt_facet_exception & e) {
|
|
|
|
|
lyxerr << "Caught iconv exception: " << e.what() << endl;
|
|
|
|
|
failed_export = true;
|
|
|
|
|
}
|
2007-08-12 18:58:59 +00:00
|
|
|
|
catch (std::exception const & e) {
|
2007-05-16 10:39:41 +00:00
|
|
|
|
lyxerr << "Caught \"normal\" exception: " << e.what() << endl;
|
|
|
|
|
failed_export = true;
|
|
|
|
|
}
|
|
|
|
|
catch (...) {
|
|
|
|
|
lyxerr << "Caught some really weird exception..." << endl;
|
|
|
|
|
LyX::cref().emergencyCleanup();
|
|
|
|
|
abort();
|
2006-10-26 15:01:45 +00:00
|
|
|
|
}
|
2002-07-05 19:21:29 +00:00
|
|
|
|
|
|
|
|
|
ofs.close();
|
2006-10-26 15:01:45 +00:00
|
|
|
|
if (ofs.fail()) {
|
2007-05-16 10:39:41 +00:00
|
|
|
|
failed_export = true;
|
2004-02-11 14:45:44 +00:00
|
|
|
|
lyxerr << "File '" << fname << "' was not closed properly." << endl;
|
2007-05-16 10:39:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (failed_export) {
|
|
|
|
|
Alert::error(_("Encoding error"),
|
|
|
|
|
_("Some characters of your document are probably not "
|
|
|
|
|
"representable in the chosen encoding.\n"
|
|
|
|
|
"Changing the document encoding to utf8 could help."));
|
2006-10-26 15:01:45 +00:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
2002-07-05 19:21:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2006-10-19 16:51:30 +00:00
|
|
|
|
void Buffer::writeLaTeXSource(odocstream & os,
|
2002-07-05 19:21:29 +00:00
|
|
|
|
string const & original_path,
|
2003-11-05 12:06:20 +00:00
|
|
|
|
OutputParams const & runparams_in,
|
2007-11-30 17:41:27 +00:00
|
|
|
|
bool const output_preamble, bool const output_body) const
|
2002-07-05 19:21:29 +00:00
|
|
|
|
{
|
2003-11-05 12:06:20 +00:00
|
|
|
|
OutputParams runparams = runparams_in;
|
2002-03-07 16:03:36 +00:00
|
|
|
|
|
2000-03-06 02:42:40 +00:00
|
|
|
|
// validate the buffer.
|
2007-11-15 20:04:51 +00:00
|
|
|
|
LYXERR(Debug::LATEX, " Validating buffer...");
|
2006-03-28 18:49:46 +00:00
|
|
|
|
LaTeXFeatures features(*this, params(), runparams);
|
2000-03-06 02:42:40 +00:00
|
|
|
|
validate(features);
|
2007-11-15 20:04:51 +00:00
|
|
|
|
LYXERR(Debug::LATEX, " Buffer validation done.");
|
2002-03-21 16:55:34 +00:00
|
|
|
|
|
|
|
|
|
// The starting paragraph of the coming rows is the
|
2000-03-06 02:42:40 +00:00
|
|
|
|
// first paragraph of the document. (Asger)
|
2003-07-26 21:37:10 +00:00
|
|
|
|
if (output_preamble && runparams.nice) {
|
2003-07-28 14:09:05 +00:00
|
|
|
|
os << "%% LyX " << lyx_version << " created this file. "
|
2000-03-06 02:42:40 +00:00
|
|
|
|
"For more info, see http://www.lyx.org/.\n"
|
|
|
|
|
"%% Do not edit unless you really know what "
|
|
|
|
|
"you are doing.\n";
|
2007-11-30 17:46:49 +00:00
|
|
|
|
d->texrow.newline();
|
|
|
|
|
d->texrow.newline();
|
2000-03-06 02:42:40 +00:00
|
|
|
|
}
|
2007-11-15 20:04:51 +00:00
|
|
|
|
LYXERR(Debug::INFO, "lyx document header finished");
|
2000-03-06 02:42:40 +00:00
|
|
|
|
// There are a few differences between nice LaTeX and usual files:
|
2002-03-21 16:55:34 +00:00
|
|
|
|
// usual is \batchmode and has a
|
2000-03-06 02:42:40 +00:00
|
|
|
|
// special input@path to allow the including of figures
|
|
|
|
|
// with either \input or \includegraphics (what figinsets do).
|
2002-08-09 00:42:12 +00:00
|
|
|
|
// input@path is set when the actual parameter
|
2000-03-06 02:42:40 +00:00
|
|
|
|
// original_path is set. This is done for usual tex-file, but not
|
|
|
|
|
// for nice-latex-file. (Matthias 250696)
|
2004-03-25 10:12:44 +00:00
|
|
|
|
// Note that input@path is only needed for something the user does
|
|
|
|
|
// in the preamble, included .tex files or ERT, files included by
|
|
|
|
|
// LyX work without it.
|
2003-07-26 21:37:10 +00:00
|
|
|
|
if (output_preamble) {
|
2003-05-22 21:10:22 +00:00
|
|
|
|
if (!runparams.nice) {
|
2000-03-06 02:42:40 +00:00
|
|
|
|
// code for usual, NOT nice-latex-file
|
2002-07-05 19:21:29 +00:00
|
|
|
|
os << "\\batchmode\n"; // changed
|
2000-03-06 02:42:40 +00:00
|
|
|
|
// from \nonstopmode
|
2007-11-30 17:46:49 +00:00
|
|
|
|
d->texrow.newline();
|
2000-03-06 02:42:40 +00:00
|
|
|
|
}
|
|
|
|
|
if (!original_path.empty()) {
|
2006-10-19 16:51:30 +00:00
|
|
|
|
// FIXME UNICODE
|
|
|
|
|
// We don't know the encoding of inputpath
|
2006-10-21 00:16:43 +00:00
|
|
|
|
docstring const inputpath = from_utf8(latex_path(original_path));
|
2002-07-05 19:21:29 +00:00
|
|
|
|
os << "\\makeatletter\n"
|
2006-10-19 16:51:30 +00:00
|
|
|
|
<< "\\def\\input@path{{"
|
|
|
|
|
<< inputpath << "/}}\n"
|
|
|
|
|
<< "\\makeatother\n";
|
2007-11-30 17:46:49 +00:00
|
|
|
|
d->texrow.newline();
|
|
|
|
|
d->texrow.newline();
|
|
|
|
|
d->texrow.newline();
|
2000-03-06 02:42:40 +00:00
|
|
|
|
}
|
2002-03-21 16:55:34 +00:00
|
|
|
|
|
2003-02-16 00:54:43 +00:00
|
|
|
|
// Write the preamble
|
2007-11-30 17:46:49 +00:00
|
|
|
|
runparams.use_babel = params().writeLaTeX(os, features, d->texrow);
|
2002-07-05 19:21:29 +00:00
|
|
|
|
|
2003-07-26 21:37:10 +00:00
|
|
|
|
if (!output_body)
|
2002-07-05 19:21:29 +00:00
|
|
|
|
return;
|
2002-05-10 12:58:07 +00:00
|
|
|
|
|
2000-03-06 02:42:40 +00:00
|
|
|
|
// make the body.
|
2002-07-05 19:21:29 +00:00
|
|
|
|
os << "\\begin{document}\n";
|
2007-11-30 17:46:49 +00:00
|
|
|
|
d->texrow.newline();
|
2003-07-26 21:37:10 +00:00
|
|
|
|
} // output_preamble
|
2007-08-13 14:24:49 +00:00
|
|
|
|
|
2007-11-30 17:46:49 +00:00
|
|
|
|
d->texrow.start(paragraphs().begin()->id(), 0);
|
2007-08-13 14:24:49 +00:00
|
|
|
|
|
2007-11-15 20:04:51 +00:00
|
|
|
|
LYXERR(Debug::INFO, "preamble finished, now the body.");
|
2001-03-01 15:57:10 +00:00
|
|
|
|
|
2007-05-05 19:18:34 +00:00
|
|
|
|
if (!lyxrc.language_auto_begin &&
|
|
|
|
|
!params().language->babel().empty()) {
|
2006-10-19 16:51:30 +00:00
|
|
|
|
// FIXME UNICODE
|
2006-10-21 00:16:43 +00:00
|
|
|
|
os << from_utf8(subst(lyxrc.language_command_begin,
|
2007-05-28 22:27:45 +00:00
|
|
|
|
"$$lang",
|
|
|
|
|
params().language->babel()))
|
2006-10-19 16:51:30 +00:00
|
|
|
|
<< '\n';
|
2007-11-30 17:46:49 +00:00
|
|
|
|
d->texrow.newline();
|
2000-03-17 10:14:46 +00:00
|
|
|
|
}
|
2002-03-21 16:55:34 +00:00
|
|
|
|
|
2007-05-06 20:26:02 +00:00
|
|
|
|
Encoding const & encoding = params().encoding();
|
|
|
|
|
if (encoding.package() == Encoding::CJK) {
|
|
|
|
|
// Open a CJK environment, since in contrast to the encodings
|
|
|
|
|
// handled by inputenc the document encoding is not set in
|
|
|
|
|
// the preamble if it is handled by CJK.sty.
|
|
|
|
|
os << "\\begin{CJK}{" << from_ascii(encoding.latexName())
|
|
|
|
|
<< "}{}\n";
|
2007-11-30 17:46:49 +00:00
|
|
|
|
d->texrow.newline();
|
2007-05-06 20:26:02 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-03-25 10:12:44 +00:00
|
|
|
|
// 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.
|
2007-11-30 17:41:27 +00:00
|
|
|
|
Buffer const * save_parent = 0;
|
2004-03-25 10:12:44 +00:00
|
|
|
|
if (output_preamble) {
|
2007-11-30 17:46:49 +00:00
|
|
|
|
save_parent = d->parent_buffer;
|
|
|
|
|
d->parent_buffer = 0;
|
2004-03-25 10:12:44 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-10-20 10:03:45 +00:00
|
|
|
|
loadChildDocuments();
|
2007-08-15 08:55:36 +00:00
|
|
|
|
|
2004-03-25 10:12:44 +00:00
|
|
|
|
// the real stuff
|
2007-11-30 17:46:49 +00:00
|
|
|
|
latexParagraphs(*this, paragraphs(), os, d->texrow, runparams);
|
2000-05-04 08:14:34 +00:00
|
|
|
|
|
2004-03-25 10:12:44 +00:00
|
|
|
|
// Restore the parenthood if needed
|
|
|
|
|
if (output_preamble)
|
2007-11-30 17:46:49 +00:00
|
|
|
|
d->parent_buffer = save_parent;
|
2004-03-25 10:12:44 +00:00
|
|
|
|
|
2000-05-04 08:14:34 +00:00
|
|
|
|
// add this just in case after all the paragraphs
|
2002-07-05 19:21:29 +00:00
|
|
|
|
os << endl;
|
2007-11-30 17:46:49 +00:00
|
|
|
|
d->texrow.newline();
|
2000-05-04 08:14:34 +00:00
|
|
|
|
|
2007-05-06 20:26:02 +00:00
|
|
|
|
if (encoding.package() == Encoding::CJK) {
|
|
|
|
|
// Close the open CJK environment.
|
|
|
|
|
// latexParagraphs will have opened one even if the last text
|
|
|
|
|
// was not CJK.
|
|
|
|
|
os << "\\end{CJK}\n";
|
2007-11-30 17:46:49 +00:00
|
|
|
|
d->texrow.newline();
|
2007-05-06 20:26:02 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-05-05 19:18:34 +00:00
|
|
|
|
if (!lyxrc.language_auto_end &&
|
|
|
|
|
!params().language->babel().empty()) {
|
2006-10-21 00:16:43 +00:00
|
|
|
|
os << from_utf8(subst(lyxrc.language_command_end,
|
2007-05-28 22:27:45 +00:00
|
|
|
|
"$$lang",
|
|
|
|
|
params().language->babel()))
|
2006-10-19 16:51:30 +00:00
|
|
|
|
<< '\n';
|
2007-11-30 17:46:49 +00:00
|
|
|
|
d->texrow.newline();
|
2000-05-04 08:14:34 +00:00
|
|
|
|
}
|
|
|
|
|
|
2003-07-26 21:37:10 +00:00
|
|
|
|
if (output_preamble) {
|
2002-07-05 19:21:29 +00:00
|
|
|
|
os << "\\end{document}\n";
|
2007-11-30 17:46:49 +00:00
|
|
|
|
d->texrow.newline();
|
2007-11-15 20:04:51 +00:00
|
|
|
|
LYXERR(Debug::LATEX, "makeLaTeXFile...done");
|
2000-05-04 08:14:34 +00:00
|
|
|
|
} else {
|
2007-11-15 20:04:51 +00:00
|
|
|
|
LYXERR(Debug::LATEX, "LaTeXFile for inclusion made.");
|
2000-05-04 08:14:34 +00:00
|
|
|
|
}
|
2007-03-18 10:59:16 +00:00
|
|
|
|
runparams_in.encoding = runparams.encoding;
|
2000-05-04 08:14:34 +00:00
|
|
|
|
|
|
|
|
|
// Just to be sure. (Asger)
|
2007-11-30 17:46:49 +00:00
|
|
|
|
d->texrow.newline();
|
2000-05-04 08:14:34 +00:00
|
|
|
|
|
2007-11-15 20:04:51 +00:00
|
|
|
|
LYXERR(Debug::INFO, "Finished making LaTeX file.");
|
2007-11-30 17:46:49 +00:00
|
|
|
|
LYXERR(Debug::INFO, "Row count was " << d->texrow.rows() - 1 << '.');
|
2000-05-04 08:14:34 +00:00
|
|
|
|
}
|
|
|
|
|
|
2000-07-04 19:16:35 +00:00
|
|
|
|
|
1999-11-15 12:01:38 +00:00
|
|
|
|
bool Buffer::isLatex() const
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
2007-04-29 19:53:54 +00:00
|
|
|
|
return params().getTextClass().outputType() == LATEX;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
1999-11-15 12:01:38 +00:00
|
|
|
|
bool Buffer::isLiterate() const
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
2007-04-29 19:53:54 +00:00
|
|
|
|
return params().getTextClass().outputType() == LITERATE;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
1999-11-15 12:01:38 +00:00
|
|
|
|
bool Buffer::isDocBook() const
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
2007-04-29 19:53:54 +00:00
|
|
|
|
return params().getTextClass().outputType() == DOCBOOK;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2006-12-04 15:46:57 +00:00
|
|
|
|
void Buffer::makeDocBookFile(FileName const & fname,
|
2006-08-04 13:59:12 +00:00
|
|
|
|
OutputParams const & runparams,
|
2007-11-30 17:41:27 +00:00
|
|
|
|
bool const body_only) const
|
2006-08-04 13:59:12 +00:00
|
|
|
|
{
|
2007-11-15 20:04:51 +00:00
|
|
|
|
LYXERR(Debug::LATEX, "makeDocBookFile...");
|
2006-08-04 13:59:12 +00:00
|
|
|
|
|
2006-10-19 21:00:33 +00:00
|
|
|
|
//ofstream ofs;
|
2007-05-28 22:27:45 +00:00
|
|
|
|
odocfstream ofs;
|
2006-08-04 13:59:12 +00:00
|
|
|
|
if (!openFileWrite(ofs, fname))
|
|
|
|
|
return;
|
|
|
|
|
|
2006-12-04 15:46:57 +00:00
|
|
|
|
writeDocBookSource(ofs, fname.absFilename(), runparams, body_only);
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
1999-12-07 00:44:53 +00:00
|
|
|
|
ofs.close();
|
2004-02-11 14:45:44 +00:00
|
|
|
|
if (ofs.fail())
|
|
|
|
|
lyxerr << "File '" << fname << "' was not closed properly." << endl;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2006-10-19 21:00:33 +00:00
|
|
|
|
void Buffer::writeDocBookSource(odocstream & os, string const & fname,
|
2003-11-05 12:06:20 +00:00
|
|
|
|
OutputParams const & runparams,
|
2007-11-30 17:41:27 +00:00
|
|
|
|
bool const only_body) const
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
2006-03-28 18:49:46 +00:00
|
|
|
|
LaTeXFeatures features(*this, params(), runparams);
|
2000-07-01 12:54:45 +00:00
|
|
|
|
validate(features);
|
2002-03-21 16:55:34 +00:00
|
|
|
|
|
2007-11-30 17:46:49 +00:00
|
|
|
|
d->texrow.reset();
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
2007-04-29 19:53:54 +00:00
|
|
|
|
TextClass const & tclass = params().getTextClass();
|
2006-10-19 21:00:33 +00:00
|
|
|
|
string const top_element = tclass.latexname();
|
2001-03-23 08:37:44 +00:00
|
|
|
|
|
2000-11-04 10:00:12 +00:00
|
|
|
|
if (!only_body) {
|
2004-05-13 11:21:58 +00:00
|
|
|
|
if (runparams.flavor == OutputParams::XML)
|
2006-10-19 21:00:33 +00:00
|
|
|
|
os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
|
2004-05-13 11:21:58 +00:00
|
|
|
|
|
2007-05-28 22:27:45 +00:00
|
|
|
|
// FIXME UNICODE
|
2006-10-21 00:16:43 +00:00
|
|
|
|
os << "<!DOCTYPE " << from_ascii(top_element) << ' ';
|
2004-05-14 15:47:35 +00:00
|
|
|
|
|
2007-05-28 22:27:45 +00:00
|
|
|
|
// FIXME UNICODE
|
2006-10-19 21:00:33 +00:00
|
|
|
|
if (! tclass.class_header().empty())
|
2007-05-28 22:27:45 +00:00
|
|
|
|
os << from_ascii(tclass.class_header());
|
2004-05-14 15:47:35 +00:00
|
|
|
|
else if (runparams.flavor == OutputParams::XML)
|
2006-08-04 13:59:12 +00:00
|
|
|
|
os << "PUBLIC \"-//OASIS//DTD DocBook XML//EN\" "
|
2004-05-14 15:47:35 +00:00
|
|
|
|
<< "\"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd\"";
|
|
|
|
|
else
|
2006-08-04 13:59:12 +00:00
|
|
|
|
os << " PUBLIC \"-//OASIS//DTD DocBook V4.2//EN\"";
|
2004-07-24 10:55:30 +00:00
|
|
|
|
|
2006-10-21 19:40:29 +00:00
|
|
|
|
docstring preamble = from_utf8(params().preamble);
|
2004-10-21 22:55:04 +00:00
|
|
|
|
if (runparams.flavor != OutputParams::XML ) {
|
|
|
|
|
preamble += "<!ENTITY % output.print.png \"IGNORE\">\n";
|
|
|
|
|
preamble += "<!ENTITY % output.print.pdf \"IGNORE\">\n";
|
|
|
|
|
preamble += "<!ENTITY % output.print.eps \"IGNORE\">\n";
|
|
|
|
|
preamble += "<!ENTITY % output.print.bmp \"IGNORE\">\n";
|
|
|
|
|
}
|
2004-10-26 21:16:44 +00:00
|
|
|
|
|
2007-10-20 10:03:45 +00:00
|
|
|
|
string const name = runparams.nice
|
|
|
|
|
? changeExtension(absFileName(), ".sgml") : fname;
|
2002-03-05 13:38:40 +00:00
|
|
|
|
preamble += features.getIncludedFiles(name);
|
2001-10-23 09:42:14 +00:00
|
|
|
|
preamble += features.getLyXSGMLEntities();
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
2001-10-23 09:42:14 +00:00
|
|
|
|
if (!preamble.empty()) {
|
2007-05-28 22:27:45 +00:00
|
|
|
|
os << "\n [ " << preamble << " ]";
|
2001-10-23 09:42:14 +00:00
|
|
|
|
}
|
2006-08-04 13:59:12 +00:00
|
|
|
|
os << ">\n\n";
|
2000-11-13 15:43:36 +00:00
|
|
|
|
}
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
2002-03-21 16:55:34 +00:00
|
|
|
|
string top = top_element;
|
2001-01-28 21:54:15 +00:00
|
|
|
|
top += " lang=\"";
|
2004-05-14 15:47:35 +00:00
|
|
|
|
if (runparams.flavor == OutputParams::XML)
|
|
|
|
|
top += params().language->code();
|
|
|
|
|
else
|
|
|
|
|
top += params().language->code().substr(0,2);
|
2002-11-27 10:30:28 +00:00
|
|
|
|
top += '"';
|
2001-01-28 21:54:15 +00:00
|
|
|
|
|
2003-09-09 09:47:59 +00:00
|
|
|
|
if (!params().options.empty()) {
|
2002-11-27 10:30:28 +00:00
|
|
|
|
top += ' ';
|
2003-09-09 09:47:59 +00:00
|
|
|
|
top += params().options;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-08-04 13:59:12 +00:00
|
|
|
|
os << "<!-- " << ((runparams.flavor == OutputParams::XML)? "XML" : "SGML")
|
2004-05-13 11:21:58 +00:00
|
|
|
|
<< " file was created by LyX " << lyx_version
|
2000-07-01 12:54:45 +00:00
|
|
|
|
<< "\n See http://www.lyx.org/ for more information -->\n";
|
|
|
|
|
|
2007-04-29 19:53:54 +00:00
|
|
|
|
params().getTextClass().counters().reset();
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
2007-10-20 10:03:45 +00:00
|
|
|
|
loadChildDocuments();
|
2007-08-15 08:55:36 +00:00
|
|
|
|
|
2006-08-04 13:59:12 +00:00
|
|
|
|
sgml::openTag(os, top);
|
|
|
|
|
os << '\n';
|
|
|
|
|
docbookParagraphs(paragraphs(), *this, os, runparams);
|
|
|
|
|
sgml::closeTag(os, top_element);
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// chktex should be run with these flags disabled: 3, 22, 25, 30, 38(?)
|
|
|
|
|
// Other flags: -wall -v0 -x
|
|
|
|
|
int Buffer::runChktex()
|
|
|
|
|
{
|
2007-10-21 10:50:56 +00:00
|
|
|
|
setBusy(true);
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
|
|
|
|
// get LaTeX-Filename
|
2007-04-06 18:03:29 +00:00
|
|
|
|
FileName const path(temppath());
|
2007-10-20 10:03:45 +00:00
|
|
|
|
string const name = addName(path.absFilename(), latexName());
|
2004-02-25 12:00:53 +00:00
|
|
|
|
string const org_path = filePath();
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
2007-11-10 13:44:50 +00:00
|
|
|
|
support::PathChanger p(path); // path to LaTeX file
|
2006-09-11 08:54:10 +00:00
|
|
|
|
message(_("Running chktex..."));
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
|
|
|
|
// Generate the LaTeX file if neccessary
|
2007-03-18 10:59:16 +00:00
|
|
|
|
OutputParams runparams(¶ms().encoding());
|
2003-11-05 12:06:20 +00:00
|
|
|
|
runparams.flavor = OutputParams::LATEX;
|
2003-05-22 21:10:22 +00:00
|
|
|
|
runparams.nice = false;
|
2006-12-04 15:46:57 +00:00
|
|
|
|
makeLaTeXFile(FileName(name), org_path, runparams);
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
|
|
|
|
TeXErrors terr;
|
2006-12-04 15:46:57 +00:00
|
|
|
|
Chktex chktex(lyxrc.chktex_command, onlyFilename(name), filePath());
|
2005-01-05 20:21:27 +00:00
|
|
|
|
int const res = chktex.run(terr); // run chktex
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
|
|
|
|
if (res == -1) {
|
2006-09-11 08:54:10 +00:00
|
|
|
|
Alert::error(_("chktex failure"),
|
|
|
|
|
_("Could not run chktex successfully."));
|
1999-09-27 18:44:28 +00:00
|
|
|
|
} else if (res > 0) {
|
2007-11-30 17:46:49 +00:00
|
|
|
|
ErrorList & errlist = d->errorLists["ChkTeX"];
|
2007-10-21 10:50:56 +00:00
|
|
|
|
errlist.clear();
|
|
|
|
|
bufferErrors(terr, errlist);
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-10-21 10:50:56 +00:00
|
|
|
|
setBusy(false);
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
2006-08-13 16:16:43 +00:00
|
|
|
|
errors("ChkTeX");
|
|
|
|
|
|
1999-09-27 18:44:28 +00:00
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2000-02-04 09:38:32 +00:00
|
|
|
|
void Buffer::validate(LaTeXFeatures & features) const
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
2007-04-29 19:53:54 +00:00
|
|
|
|
TextClass const & tclass = params().getTextClass();
|
2002-03-21 16:55:34 +00:00
|
|
|
|
|
2007-05-08 17:46:03 +00:00
|
|
|
|
if (params().outputChanges) {
|
2007-05-13 15:17:57 +00:00
|
|
|
|
bool dvipost = LaTeXFeatures::isAvailable("dvipost");
|
|
|
|
|
bool xcolorsoul = LaTeXFeatures::isAvailable("soul") &&
|
2007-05-28 22:27:45 +00:00
|
|
|
|
LaTeXFeatures::isAvailable("xcolor");
|
|
|
|
|
|
|
|
|
|
if (features.runparams().flavor == OutputParams::LATEX) {
|
2007-05-13 15:17:57 +00:00
|
|
|
|
if (dvipost) {
|
|
|
|
|
features.require("ct-dvipost");
|
2007-05-08 17:46:03 +00:00
|
|
|
|
features.require("dvipost");
|
2007-05-13 15:17:57 +00:00
|
|
|
|
} else if (xcolorsoul) {
|
|
|
|
|
features.require("ct-xcolor-soul");
|
|
|
|
|
features.require("soul");
|
|
|
|
|
features.require("xcolor");
|
2007-05-28 22:27:45 +00:00
|
|
|
|
} else {
|
2007-05-08 17:46:03 +00:00
|
|
|
|
features.require("ct-none");
|
|
|
|
|
}
|
|
|
|
|
} else if (features.runparams().flavor == OutputParams::PDFLATEX ) {
|
2007-05-13 15:17:57 +00:00
|
|
|
|
if (xcolorsoul) {
|
|
|
|
|
features.require("ct-xcolor-soul");
|
|
|
|
|
features.require("soul");
|
|
|
|
|
features.require("xcolor");
|
|
|
|
|
features.require("pdfcolmk"); // improves color handling in PDF output
|
|
|
|
|
} else {
|
|
|
|
|
features.require("ct-none");
|
|
|
|
|
}
|
2007-05-28 22:27:45 +00:00
|
|
|
|
}
|
2007-05-08 17:46:03 +00:00
|
|
|
|
}
|
2003-03-02 12:16:00 +00:00
|
|
|
|
|
2002-03-21 16:55:34 +00:00
|
|
|
|
// AMS Style is at document level
|
2006-11-13 17:35:18 +00:00
|
|
|
|
if (params().use_amsmath == BufferParams::package_on
|
2007-04-06 09:02:23 +00:00
|
|
|
|
|| tclass.provides("amsmath"))
|
2002-01-10 10:05:45 +00:00
|
|
|
|
features.require("amsmath");
|
2006-11-13 17:35:18 +00:00
|
|
|
|
if (params().use_esint == BufferParams::package_on)
|
|
|
|
|
features.require("esint");
|
2002-03-21 16:55:34 +00:00
|
|
|
|
|
2007-10-20 10:03:45 +00:00
|
|
|
|
loadChildDocuments();
|
2007-08-15 08:55:36 +00:00
|
|
|
|
|
2003-09-09 09:47:59 +00:00
|
|
|
|
for_each(paragraphs().begin(), paragraphs().end(),
|
2002-08-14 22:15:18 +00:00
|
|
|
|
boost::bind(&Paragraph::validate, _1, boost::ref(features)));
|
1999-09-27 18:44:28 +00:00
|
|
|
|
|
|
|
|
|
// the bullet shapes are buffer level not paragraph level
|
|
|
|
|
// so they are tested here
|
|
|
|
|
for (int i = 0; i < 4; ++i) {
|
2003-09-09 17:00:19 +00:00
|
|
|
|
if (params().user_defined_bullet(i) != ITEMIZE_DEFAULTS[i]) {
|
|
|
|
|
int const font = params().user_defined_bullet(i).getFont();
|
1999-09-27 18:44:28 +00:00
|
|
|
|
if (font == 0) {
|
2003-09-09 09:47:59 +00:00
|
|
|
|
int const c = params()
|
2003-09-09 17:00:19 +00:00
|
|
|
|
.user_defined_bullet(i)
|
1999-11-04 01:40:20 +00:00
|
|
|
|
.getCharacter();
|
1999-09-27 18:44:28 +00:00
|
|
|
|
if (c == 16
|
|
|
|
|
|| c == 17
|
|
|
|
|
|| c == 25
|
|
|
|
|
|| c == 26
|
|
|
|
|
|| c == 31) {
|
2001-11-19 15:34:11 +00:00
|
|
|
|
features.require("latexsym");
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
2000-09-26 13:54:57 +00:00
|
|
|
|
} else if (font == 1) {
|
2001-11-19 15:34:11 +00:00
|
|
|
|
features.require("amssymb");
|
2000-09-26 13:54:57 +00:00
|
|
|
|
} else if ((font >= 2 && font <= 5)) {
|
2001-11-19 15:34:11 +00:00
|
|
|
|
features.require("pifont");
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-03-21 16:55:34 +00:00
|
|
|
|
|
1999-10-07 18:44:17 +00:00
|
|
|
|
if (lyxerr.debugging(Debug::LATEX)) {
|
2000-04-10 21:40:13 +00:00
|
|
|
|
features.showStruct();
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2006-10-12 10:50:45 +00:00
|
|
|
|
void Buffer::getLabelList(vector<docstring> & list) const
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
|
|
|
|
/// if this is a child document and the parent is already loaded
|
|
|
|
|
/// Use the parent's list instead [ale990407]
|
2007-10-20 10:03:45 +00:00
|
|
|
|
Buffer const * tmp = masterBuffer();
|
2004-03-27 12:46:30 +00:00
|
|
|
|
if (!tmp) {
|
2007-10-20 10:03:45 +00:00
|
|
|
|
lyxerr << "masterBuffer() failed!" << endl;
|
2004-03-27 12:46:30 +00:00
|
|
|
|
BOOST_ASSERT(tmp);
|
|
|
|
|
}
|
2004-03-25 10:12:44 +00:00
|
|
|
|
if (tmp != this) {
|
|
|
|
|
tmp->getLabelList(list);
|
|
|
|
|
return;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-10-20 10:03:45 +00:00
|
|
|
|
loadChildDocuments();
|
2007-08-15 08:55:36 +00:00
|
|
|
|
|
2004-03-30 08:18:09 +00:00
|
|
|
|
for (InsetIterator it = inset_iterator_begin(inset()); it; ++it)
|
2004-03-27 12:46:30 +00:00
|
|
|
|
it.nextInset()->getLabelList(*this, list);
|
2000-05-19 16:46:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-11-30 17:41:27 +00:00
|
|
|
|
void Buffer::updateBibfilesCache() const
|
2006-04-15 11:46:17 +00:00
|
|
|
|
{
|
|
|
|
|
// if this is a child document and the parent is already loaded
|
|
|
|
|
// update the parent's cache instead
|
2007-11-30 17:41:27 +00:00
|
|
|
|
Buffer const * tmp = masterBuffer();
|
2006-04-15 11:46:17 +00:00
|
|
|
|
BOOST_ASSERT(tmp);
|
|
|
|
|
if (tmp != this) {
|
|
|
|
|
tmp->updateBibfilesCache();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bibfilesCache_.clear();
|
|
|
|
|
for (InsetIterator it = inset_iterator_begin(inset()); it; ++it) {
|
2007-10-13 09:04:52 +00:00
|
|
|
|
if (it->lyxCode() == BIBTEX_CODE) {
|
2006-04-15 11:46:17 +00:00
|
|
|
|
InsetBibtex const & inset =
|
2007-03-25 00:56:01 +00:00
|
|
|
|
static_cast<InsetBibtex const &>(*it);
|
2006-12-01 20:09:08 +00:00
|
|
|
|
vector<FileName> const bibfiles = inset.getFiles(*this);
|
2006-04-15 11:46:17 +00:00
|
|
|
|
bibfilesCache_.insert(bibfilesCache_.end(),
|
|
|
|
|
bibfiles.begin(),
|
|
|
|
|
bibfiles.end());
|
2007-10-13 09:04:52 +00:00
|
|
|
|
} else if (it->lyxCode() == INCLUDE_CODE) {
|
2006-04-15 11:46:17 +00:00
|
|
|
|
InsetInclude & inset =
|
2007-03-25 00:56:01 +00:00
|
|
|
|
static_cast<InsetInclude &>(*it);
|
2006-04-15 11:46:17 +00:00
|
|
|
|
inset.updateBibfilesCache(*this);
|
2006-12-01 20:09:08 +00:00
|
|
|
|
vector<FileName> const & bibfiles =
|
2006-04-15 11:46:17 +00:00
|
|
|
|
inset.getBibfilesCache(*this);
|
|
|
|
|
bibfilesCache_.insert(bibfilesCache_.end(),
|
|
|
|
|
bibfiles.begin(),
|
|
|
|
|
bibfiles.end());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2006-12-01 20:09:08 +00:00
|
|
|
|
vector<FileName> const & Buffer::getBibfilesCache() const
|
2006-04-15 11:46:17 +00:00
|
|
|
|
{
|
|
|
|
|
// if this is a child document and the parent is already loaded
|
|
|
|
|
// use the parent's cache instead
|
2007-10-20 10:03:45 +00:00
|
|
|
|
Buffer const * tmp = masterBuffer();
|
2006-04-15 11:46:17 +00:00
|
|
|
|
BOOST_ASSERT(tmp);
|
|
|
|
|
if (tmp != this)
|
|
|
|
|
return tmp->getBibfilesCache();
|
|
|
|
|
|
2007-01-08 13:36:01 +00:00
|
|
|
|
// We update the cache when first used instead of at loading time.
|
|
|
|
|
if (bibfilesCache_.empty())
|
|
|
|
|
const_cast<Buffer *>(this)->updateBibfilesCache();
|
|
|
|
|
|
2006-04-15 11:46:17 +00:00
|
|
|
|
return bibfilesCache_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
1999-10-02 16:21:10 +00:00
|
|
|
|
bool Buffer::isDepClean(string const & name) const
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
2007-11-30 17:46:49 +00:00
|
|
|
|
DepClean::const_iterator const it = d->dep_clean.find(name);
|
|
|
|
|
if (it == d->dep_clean.end())
|
2003-02-09 00:27:52 +00:00
|
|
|
|
return true;
|
|
|
|
|
return it->second;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
1999-10-02 16:21:10 +00:00
|
|
|
|
void Buffer::markDepClean(string const & name)
|
1999-09-27 18:44:28 +00:00
|
|
|
|
{
|
2007-11-30 17:46:49 +00:00
|
|
|
|
d->dep_clean[name] = true;
|
1999-09-27 18:44:28 +00:00
|
|
|
|
}
|
1999-12-10 00:07:59 +00:00
|
|
|
|
|
2000-01-08 21:02:58 +00:00
|
|
|
|
|
2002-05-30 19:49:00 +00:00
|
|
|
|
bool Buffer::dispatch(string const & command, bool * result)
|
1999-12-10 00:07:59 +00:00
|
|
|
|
{
|
2003-09-21 23:00:47 +00:00
|
|
|
|
return dispatch(lyxaction.lookupFunc(command), result);
|
1999-12-10 00:07:59 +00:00
|
|
|
|
}
|
|
|
|
|
|
2000-01-08 21:02:58 +00:00
|
|
|
|
|
2003-09-21 23:00:47 +00:00
|
|
|
|
bool Buffer::dispatch(FuncRequest const & func, bool * result)
|
1999-12-10 00:07:59 +00:00
|
|
|
|
{
|
2000-04-28 11:18:04 +00:00
|
|
|
|
bool dispatched = true;
|
2002-06-24 20:28:12 +00:00
|
|
|
|
|
2003-09-21 23:00:47 +00:00
|
|
|
|
switch (func.action) {
|
2006-05-05 20:23:12 +00:00
|
|
|
|
case LFUN_BUFFER_EXPORT: {
|
2007-10-20 10:51:13 +00:00
|
|
|
|
bool const tmp = doExport(to_utf8(func.argument()), false);
|
2002-05-30 19:49:00 +00:00
|
|
|
|
if (result)
|
|
|
|
|
*result = tmp;
|
1999-12-15 17:42:22 +00:00
|
|
|
|
break;
|
2002-05-30 19:49:00 +00:00
|
|
|
|
}
|
1999-12-10 00:07:59 +00:00
|
|
|
|
|
|
|
|
|
default:
|
2000-04-28 11:18:04 +00:00
|
|
|
|
dispatched = false;
|
|
|
|
|
}
|
|
|
|
|
return dispatched;
|
1999-12-10 00:07:59 +00:00
|
|
|
|
}
|
2000-04-10 21:40:13 +00:00
|
|
|
|
|
2000-04-26 13:57:28 +00:00
|
|
|
|
|
2001-06-28 10:25:20 +00:00
|
|
|
|
void Buffer::changeLanguage(Language const * from, Language const * to)
|
2000-04-10 21:40:13 +00:00
|
|
|
|
{
|
2005-01-05 20:21:27 +00:00
|
|
|
|
BOOST_ASSERT(from);
|
|
|
|
|
BOOST_ASSERT(to);
|
|
|
|
|
|
2004-11-06 15:23:12 +00:00
|
|
|
|
for_each(par_iterator_begin(),
|
|
|
|
|
par_iterator_end(),
|
|
|
|
|
bind(&Paragraph::changeLanguage, _1, params(), from, to));
|
2000-04-10 21:40:13 +00:00
|
|
|
|
}
|
|
|
|
|
|
2003-04-28 21:58:53 +00:00
|
|
|
|
|
2004-02-25 12:00:53 +00:00
|
|
|
|
bool Buffer::isMultiLingual() const
|
2000-04-10 21:40:13 +00:00
|
|
|
|
{
|
2004-02-25 12:00:53 +00:00
|
|
|
|
ParConstIterator end = par_iterator_end();
|
|
|
|
|
for (ParConstIterator it = par_iterator_begin(); it != end; ++it)
|
2003-09-09 09:47:59 +00:00
|
|
|
|
if (it->isMultiLingual(params()))
|
2000-04-10 21:40:13 +00:00
|
|
|
|
return true;
|
2001-09-01 21:26:34 +00:00
|
|
|
|
|
2000-04-10 21:40:13 +00:00
|
|
|
|
return false;
|
|
|
|
|
}
|
2000-05-19 16:46:01 +00:00
|
|
|
|
|
|
|
|
|
|
2005-01-05 20:21:27 +00:00
|
|
|
|
ParIterator Buffer::getParFromID(int const id) const
|
2001-07-09 09:16:00 +00:00
|
|
|
|
{
|
2004-03-30 08:18:09 +00:00
|
|
|
|
ParConstIterator it = par_iterator_begin();
|
2005-01-05 20:21:27 +00:00
|
|
|
|
ParConstIterator const end = par_iterator_end();
|
2003-04-28 18:20:31 +00:00
|
|
|
|
|
|
|
|
|
if (id < 0) {
|
|
|
|
|
// John says this is called with id == -1 from undo
|
|
|
|
|
lyxerr << "getParFromID(), id: " << id << endl;
|
2003-05-22 08:01:41 +00:00
|
|
|
|
return end;
|
2003-04-28 18:20:31 +00:00
|
|
|
|
}
|
2002-08-14 22:15:18 +00:00
|
|
|
|
|
2003-05-22 08:01:41 +00:00
|
|
|
|
for (; it != end; ++it)
|
2003-06-12 11:09:55 +00:00
|
|
|
|
if (it->id() == id)
|
2003-05-22 08:01:41 +00:00
|
|
|
|
return it;
|
2003-02-14 02:21:01 +00:00
|
|
|
|
|
2003-05-22 08:01:41 +00:00
|
|
|
|
return end;
|
2001-07-09 09:16:00 +00:00
|
|
|
|
}
|
2001-09-01 21:26:34 +00:00
|
|
|
|
|
|
|
|
|
|
2005-01-05 20:21:27 +00:00
|
|
|
|
bool Buffer::hasParWithID(int const id) const
|
2003-05-05 17:28:21 +00:00
|
|
|
|
{
|
2005-01-05 20:21:27 +00:00
|
|
|
|
ParConstIterator const it = getParFromID(id);
|
2004-11-06 15:23:12 +00:00
|
|
|
|
return it != par_iterator_end();
|
2003-05-05 17:28:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2001-09-01 21:26:34 +00:00
|
|
|
|
ParIterator Buffer::par_iterator_begin()
|
|
|
|
|
{
|
2006-10-21 00:16:43 +00:00
|
|
|
|
return lyx::par_iterator_begin(inset());
|
2001-09-01 21:26:34 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ParIterator Buffer::par_iterator_end()
|
|
|
|
|
{
|
2006-10-21 00:16:43 +00:00
|
|
|
|
return lyx::par_iterator_end(inset());
|
2001-09-01 21:26:34 +00:00
|
|
|
|
}
|
2002-08-20 17:18:21 +00:00
|
|
|
|
|
2003-08-26 14:50:16 +00:00
|
|
|
|
|
2002-11-08 01:08:27 +00:00
|
|
|
|
ParConstIterator Buffer::par_iterator_begin() const
|
|
|
|
|
{
|
2006-10-21 00:16:43 +00:00
|
|
|
|
return lyx::par_const_iterator_begin(inset());
|
2002-11-08 01:08:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ParConstIterator Buffer::par_iterator_end() const
|
|
|
|
|
{
|
2006-10-21 00:16:43 +00:00
|
|
|
|
return lyx::par_const_iterator_end(inset());
|
2002-11-08 01:08:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-10-20 10:03:45 +00:00
|
|
|
|
Language const * Buffer::language() const
|
2002-08-20 17:18:21 +00:00
|
|
|
|
{
|
2003-09-09 09:47:59 +00:00
|
|
|
|
return params().language;
|
2002-08-20 17:18:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2006-09-09 11:16:28 +00:00
|
|
|
|
docstring const Buffer::B_(string const & l10n) const
|
2003-04-24 23:19:41 +00:00
|
|
|
|
{
|
2007-05-01 08:26:40 +00:00
|
|
|
|
return params().B_(l10n);
|
2003-04-24 23:19:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2002-08-20 17:18:21 +00:00
|
|
|
|
bool Buffer::isClean() const
|
|
|
|
|
{
|
2007-11-30 17:46:49 +00:00
|
|
|
|
return d->lyx_clean;
|
2002-08-20 17:18:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool Buffer::isBakClean() const
|
|
|
|
|
{
|
2007-11-30 17:46:49 +00:00
|
|
|
|
return d->bak_clean;
|
2002-08-20 17:18:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-08-09 20:46:22 +00:00
|
|
|
|
bool Buffer::isExternallyModified(CheckMethod method) const
|
|
|
|
|
{
|
2007-11-30 17:46:49 +00:00
|
|
|
|
BOOST_ASSERT(d->filename.exists());
|
2007-08-09 20:46:22 +00:00
|
|
|
|
// if method == timestamp, check timestamp before checksum
|
|
|
|
|
return (method == checksum_method
|
2007-11-30 17:46:49 +00:00
|
|
|
|
|| d->timestamp_ != d->filename.lastModified())
|
|
|
|
|
&& d->checksum_ != d->filename.checksum();
|
2007-08-09 20:46:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-10-20 10:03:45 +00:00
|
|
|
|
void Buffer::saveCheckSum(FileName const & file) const
|
2007-09-06 15:54:17 +00:00
|
|
|
|
{
|
2007-10-20 10:03:45 +00:00
|
|
|
|
if (file.exists()) {
|
2007-11-30 17:46:49 +00:00
|
|
|
|
d->timestamp_ = file.lastModified();
|
|
|
|
|
d->checksum_ = file.checksum();
|
2007-09-06 15:54:17 +00:00
|
|
|
|
} else {
|
|
|
|
|
// in the case of save to a new file.
|
2007-11-30 17:46:49 +00:00
|
|
|
|
d->timestamp_ = 0;
|
|
|
|
|
d->checksum_ = 0;
|
2007-09-06 15:54:17 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2002-08-20 17:18:21 +00:00
|
|
|
|
void Buffer::markClean() const
|
|
|
|
|
{
|
2007-11-30 17:46:49 +00:00
|
|
|
|
if (!d->lyx_clean) {
|
|
|
|
|
d->lyx_clean = true;
|
2002-08-20 17:18:21 +00:00
|
|
|
|
updateTitles();
|
|
|
|
|
}
|
|
|
|
|
// if the .lyx file has been saved, we don't need an
|
|
|
|
|
// autosave
|
2007-11-30 17:46:49 +00:00
|
|
|
|
d->bak_clean = true;
|
2002-08-20 17:18:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-10-03 11:00:18 +00:00
|
|
|
|
void Buffer::markBakClean() const
|
2002-08-20 17:18:21 +00:00
|
|
|
|
{
|
2007-11-30 17:46:49 +00:00
|
|
|
|
d->bak_clean = true;
|
2002-08-20 17:18:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Buffer::setUnnamed(bool flag)
|
|
|
|
|
{
|
2007-11-30 17:46:49 +00:00
|
|
|
|
d->unnamed = flag;
|
2002-08-20 17:18:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2004-02-25 12:00:53 +00:00
|
|
|
|
bool Buffer::isUnnamed() const
|
2002-08-20 17:18:21 +00:00
|
|
|
|
{
|
2007-11-30 17:46:49 +00:00
|
|
|
|
return d->unnamed;
|
2002-08-20 17:18:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-08-10 11:47:12 +00:00
|
|
|
|
// FIXME: this function should be moved to buffer_pimpl.C
|
2002-08-20 17:18:21 +00:00
|
|
|
|
void Buffer::markDirty()
|
|
|
|
|
{
|
2007-11-30 17:46:49 +00:00
|
|
|
|
if (d->lyx_clean) {
|
|
|
|
|
d->lyx_clean = false;
|
2002-08-20 17:18:21 +00:00
|
|
|
|
updateTitles();
|
|
|
|
|
}
|
2007-11-30 17:46:49 +00:00
|
|
|
|
d->bak_clean = false;
|
2003-02-09 00:27:52 +00:00
|
|
|
|
|
2007-11-30 17:46:49 +00:00
|
|
|
|
DepClean::iterator it = d->dep_clean.begin();
|
|
|
|
|
DepClean::const_iterator const end = d->dep_clean.end();
|
2003-02-09 00:27:52 +00:00
|
|
|
|
|
2006-10-21 00:16:43 +00:00
|
|
|
|
for (; it != end; ++it)
|
2003-02-09 00:27:52 +00:00
|
|
|
|
it->second = false;
|
2002-08-20 17:18:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-11-03 17:37:37 +00:00
|
|
|
|
FileName Buffer::fileName() const
|
|
|
|
|
{
|
2007-11-30 17:46:49 +00:00
|
|
|
|
return d->filename;
|
2007-11-03 17:37:37 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-10-20 10:03:45 +00:00
|
|
|
|
string Buffer::absFileName() const
|
2002-08-20 17:18:21 +00:00
|
|
|
|
{
|
2007-11-30 17:46:49 +00:00
|
|
|
|
return d->filename.absFilename();
|
2002-08-20 17:18:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-11-28 15:25:07 +00:00
|
|
|
|
string Buffer::filePath() const
|
2002-08-20 17:18:21 +00:00
|
|
|
|
{
|
2007-11-30 17:46:49 +00:00
|
|
|
|
return d->filename.onlyPath().absFilename();
|
2002-08-20 17:18:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool Buffer::isReadonly() const
|
|
|
|
|
{
|
2007-11-30 17:46:49 +00:00
|
|
|
|
return d->read_only;
|
2002-08-20 17:18:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-11-30 17:41:27 +00:00
|
|
|
|
void Buffer::setParent(Buffer const * buffer)
|
2002-08-20 17:18:21 +00:00
|
|
|
|
{
|
2007-11-30 17:41:27 +00:00
|
|
|
|
// Avoids recursive include.
|
2007-11-30 17:46:49 +00:00
|
|
|
|
d->parent_buffer = buffer == this ? 0 : buffer;
|
2002-08-20 17:18:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-11-30 17:41:27 +00:00
|
|
|
|
Buffer const * Buffer::parent()
|
2004-03-25 10:12:44 +00:00
|
|
|
|
{
|
2007-11-30 17:46:49 +00:00
|
|
|
|
return d->parent_buffer;
|
2004-03-25 10:12:44 +00:00
|
|
|
|
}
|
2004-04-13 06:27:29 +00:00
|
|
|
|
|
|
|
|
|
|
2007-11-30 17:41:27 +00:00
|
|
|
|
Buffer const * Buffer::masterBuffer() const
|
2006-04-15 11:46:17 +00:00
|
|
|
|
{
|
2007-11-30 17:46:49 +00:00
|
|
|
|
if (!d->parent_buffer)
|
2007-11-30 17:41:27 +00:00
|
|
|
|
return this;
|
|
|
|
|
|
2007-11-30 17:46:49 +00:00
|
|
|
|
return d->parent_buffer->masterBuffer();
|
2006-04-15 11:46:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-11-01 11:13:07 +00:00
|
|
|
|
bool Buffer::hasMacro(docstring const & name, Paragraph const & par) const
|
2004-04-13 06:27:29 +00:00
|
|
|
|
{
|
2007-11-01 11:13:07 +00:00
|
|
|
|
Impl::PositionToMacroMap::iterator it;
|
2007-11-30 17:46:49 +00:00
|
|
|
|
it = d->macros[name].upper_bound(par.macrocontextPosition());
|
|
|
|
|
if (it != d->macros[name].end())
|
2007-11-01 11:13:07 +00:00
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
// If there is a master buffer, query that
|
2007-11-30 17:41:27 +00:00
|
|
|
|
Buffer const * master = masterBuffer();
|
2007-11-05 20:33:20 +00:00
|
|
|
|
if (master && master != this)
|
2007-11-01 11:13:07 +00:00
|
|
|
|
return master->hasMacro(name);
|
|
|
|
|
|
|
|
|
|
return MacroTable::globalMacros().has(name);
|
2004-04-13 06:27:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2006-10-22 10:15:23 +00:00
|
|
|
|
bool Buffer::hasMacro(docstring const & name) const
|
2004-04-13 06:27:29 +00:00
|
|
|
|
{
|
2007-11-30 17:46:49 +00:00
|
|
|
|
if( !d->macros[name].empty() )
|
2007-11-01 11:13:07 +00:00
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
// If there is a master buffer, query that
|
2007-11-30 17:41:27 +00:00
|
|
|
|
Buffer const * master = masterBuffer();
|
2007-11-05 20:33:20 +00:00
|
|
|
|
if (master && master != this)
|
2007-11-01 11:13:07 +00:00
|
|
|
|
return master->hasMacro(name);
|
|
|
|
|
|
|
|
|
|
return MacroTable::globalMacros().has(name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-11-05 20:33:20 +00:00
|
|
|
|
MacroData const & Buffer::getMacro(docstring const & name,
|
|
|
|
|
Paragraph const & par) const
|
2007-11-01 11:13:07 +00:00
|
|
|
|
{
|
|
|
|
|
Impl::PositionToMacroMap::iterator it;
|
2007-11-30 17:46:49 +00:00
|
|
|
|
it = d->macros[name].upper_bound(par.macrocontextPosition());
|
|
|
|
|
if( it != d->macros[name].end() )
|
2007-11-01 11:13:07 +00:00
|
|
|
|
return it->second;
|
|
|
|
|
|
|
|
|
|
// If there is a master buffer, query that
|
2007-11-30 17:41:27 +00:00
|
|
|
|
Buffer const * master = masterBuffer();
|
2007-11-05 20:33:20 +00:00
|
|
|
|
if (master && master != this)
|
2007-11-01 11:13:07 +00:00
|
|
|
|
return master->getMacro(name);
|
|
|
|
|
|
|
|
|
|
return MacroTable::globalMacros().get(name);
|
2004-04-13 06:27:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-11-01 11:13:07 +00:00
|
|
|
|
MacroData const & Buffer::getMacro(docstring const & name) const
|
2004-04-13 06:27:29 +00:00
|
|
|
|
{
|
2007-11-01 11:13:07 +00:00
|
|
|
|
Impl::PositionToMacroMap::iterator it;
|
2007-11-30 17:46:49 +00:00
|
|
|
|
it = d->macros[name].begin();
|
|
|
|
|
if( it != d->macros[name].end() )
|
2007-11-01 11:13:07 +00:00
|
|
|
|
return it->second;
|
|
|
|
|
|
|
|
|
|
// If there is a master buffer, query that
|
2007-11-30 17:41:27 +00:00
|
|
|
|
Buffer const * master = masterBuffer();
|
2007-11-05 20:33:20 +00:00
|
|
|
|
if (master && master != this)
|
2007-11-01 11:13:07 +00:00
|
|
|
|
return master->getMacro(name);
|
|
|
|
|
|
|
|
|
|
return MacroTable::globalMacros().get(name);
|
2004-04-13 06:27:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-11-01 11:13:07 +00:00
|
|
|
|
void Buffer::updateMacros()
|
2004-04-13 06:27:29 +00:00
|
|
|
|
{
|
2007-11-01 11:13:07 +00:00
|
|
|
|
// start with empty table
|
2007-11-30 17:46:49 +00:00
|
|
|
|
d->macros = Impl::NameToPositionMacroMap();
|
2004-04-13 06:27:29 +00:00
|
|
|
|
|
2007-11-01 11:13:07 +00:00
|
|
|
|
// Iterate over buffer
|
|
|
|
|
ParagraphList & pars = text().paragraphs();
|
2004-04-13 06:27:29 +00:00
|
|
|
|
for (size_t i = 0, n = pars.size(); i != n; ++i) {
|
2007-11-01 11:13:07 +00:00
|
|
|
|
// set position again
|
|
|
|
|
pars[i].setMacrocontextPosition(i);
|
|
|
|
|
|
2004-04-13 06:27:29 +00:00
|
|
|
|
//lyxerr << "searching main par " << i
|
|
|
|
|
// << " for macro definitions" << std::endl;
|
2007-10-18 15:29:51 +00:00
|
|
|
|
InsetList const & insets = pars[i].insetList();
|
2005-07-18 14:25:20 +00:00
|
|
|
|
InsetList::const_iterator it = insets.begin();
|
|
|
|
|
InsetList::const_iterator end = insets.end();
|
2004-04-13 06:27:29 +00:00
|
|
|
|
for ( ; it != end; ++it) {
|
2007-11-01 11:13:07 +00:00
|
|
|
|
if (it->inset->lyxCode() != MATHMACRO_CODE)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
// get macro data
|
|
|
|
|
MathMacroTemplate const & macroTemplate
|
|
|
|
|
= static_cast<MathMacroTemplate const &>(*it->inset);
|
|
|
|
|
|
|
|
|
|
// valid?
|
|
|
|
|
if (macroTemplate.validMacro()) {
|
|
|
|
|
MacroData macro = macroTemplate.asMacroData();
|
|
|
|
|
|
|
|
|
|
// redefinition?
|
|
|
|
|
// call hasMacro here instead of directly querying mc to
|
|
|
|
|
// also take the master document into consideration
|
|
|
|
|
macro.setRedefinition(hasMacro(macroTemplate.name()));
|
|
|
|
|
|
|
|
|
|
// register macro (possibly overwrite the previous one of this paragraph)
|
2007-11-30 17:46:49 +00:00
|
|
|
|
d->macros[macroTemplate.name()][i] = macro;
|
2004-04-13 06:27:29 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2005-07-17 14:29:35 +00:00
|
|
|
|
|
2005-07-17 23:03:01 +00:00
|
|
|
|
|
2006-10-22 11:00:04 +00:00
|
|
|
|
void Buffer::changeRefsIfUnique(docstring const & from, docstring const & to,
|
2007-10-13 09:11:10 +00:00
|
|
|
|
InsetCode code)
|
2005-07-17 23:03:01 +00:00
|
|
|
|
{
|
2006-10-09 14:21:11 +00:00
|
|
|
|
//FIXME: This does not work for child documents yet.
|
2007-10-13 09:04:52 +00:00
|
|
|
|
BOOST_ASSERT(code == CITE_CODE || code == REF_CODE);
|
2005-07-17 23:03:01 +00:00
|
|
|
|
// Check if the label 'from' appears more than once
|
2006-10-12 10:50:45 +00:00
|
|
|
|
vector<docstring> labels;
|
2006-10-09 14:21:11 +00:00
|
|
|
|
|
2007-10-23 18:51:04 +00:00
|
|
|
|
string paramName;
|
2007-10-13 09:04:52 +00:00
|
|
|
|
if (code == CITE_CODE) {
|
2007-08-20 16:30:02 +00:00
|
|
|
|
BiblioInfo keys;
|
|
|
|
|
keys.fillWithBibKeys(this);
|
|
|
|
|
BiblioInfo::const_iterator bit = keys.begin();
|
|
|
|
|
BiblioInfo::const_iterator bend = keys.end();
|
2006-10-09 14:21:11 +00:00
|
|
|
|
|
|
|
|
|
for (; bit != bend; ++bit)
|
2006-10-12 10:50:45 +00:00
|
|
|
|
// FIXME UNICODE
|
2007-08-20 16:30:02 +00:00
|
|
|
|
labels.push_back(bit->first);
|
2007-10-23 18:51:04 +00:00
|
|
|
|
paramName = "key";
|
|
|
|
|
} else {
|
2006-10-09 14:21:11 +00:00
|
|
|
|
getLabelList(labels);
|
2007-10-23 18:51:04 +00:00
|
|
|
|
paramName = "reference";
|
|
|
|
|
}
|
2005-07-17 23:03:01 +00:00
|
|
|
|
|
2007-08-12 08:57:17 +00:00
|
|
|
|
if (std::count(labels.begin(), labels.end(), from) > 1)
|
2005-07-17 23:03:01 +00:00
|
|
|
|
return;
|
|
|
|
|
|
2006-10-09 14:21:11 +00:00
|
|
|
|
for (InsetIterator it = inset_iterator_begin(inset()); it; ++it) {
|
|
|
|
|
if (it->lyxCode() == code) {
|
2007-03-25 00:56:01 +00:00
|
|
|
|
InsetCommand & inset = static_cast<InsetCommand &>(*it);
|
2007-10-23 18:51:04 +00:00
|
|
|
|
docstring const oldValue = inset.getParam(paramName);
|
|
|
|
|
if (oldValue == from)
|
|
|
|
|
inset.setParam(paramName, to);
|
2005-07-17 23:03:01 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
view-source feature, from Bo Peng <ben.bob@gmail.com>
* src/buffer.h buffer.C - getSourceCode()
* src/lyxfunc.C - open view-source dialog
* src/text3.C - change LFUN_MOUSE_RELEASE
* src/output_linuxdoc.C, src/output_docbook.C, src/output_latex.C
- intercept output
* src/outputparams.h, outputparams.C - add par_begin, par_end, dryrun
* src/insets/insetgraphics.C - add dryrun mode of file conversion
* lib/ui/stdmenus.ui - add view-source menu item under view
* Add view-source dialog, add
src/frontends/qt2/QViewSourceDialog.h, QViewSource.C, QViewSource.h, QViewSourceDialog.C
src/frontends/qt2/ui/QViewSourceDialogBase.ui
src/frontends/controllers/ControlViewSource.h ControlViewSource.C
modify
src/frontends/qt2/Makefile.dialogs, Makefile.am, Dialogs.C,
src/frontends/controllers/Makefile.am, po.POTFILES.in
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@13610 a592a061-630c-0410-9148-cb99ea01b6c8
2006-04-09 02:48:54 +00:00
|
|
|
|
|
|
|
|
|
|
2006-10-22 11:00:04 +00:00
|
|
|
|
void Buffer::getSourceCode(odocstream & os, pit_type par_begin,
|
|
|
|
|
pit_type par_end, bool full_source)
|
view-source feature, from Bo Peng <ben.bob@gmail.com>
* src/buffer.h buffer.C - getSourceCode()
* src/lyxfunc.C - open view-source dialog
* src/text3.C - change LFUN_MOUSE_RELEASE
* src/output_linuxdoc.C, src/output_docbook.C, src/output_latex.C
- intercept output
* src/outputparams.h, outputparams.C - add par_begin, par_end, dryrun
* src/insets/insetgraphics.C - add dryrun mode of file conversion
* lib/ui/stdmenus.ui - add view-source menu item under view
* Add view-source dialog, add
src/frontends/qt2/QViewSourceDialog.h, QViewSource.C, QViewSource.h, QViewSourceDialog.C
src/frontends/qt2/ui/QViewSourceDialogBase.ui
src/frontends/controllers/ControlViewSource.h ControlViewSource.C
modify
src/frontends/qt2/Makefile.dialogs, Makefile.am, Dialogs.C,
src/frontends/controllers/Makefile.am, po.POTFILES.in
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@13610 a592a061-630c-0410-9148-cb99ea01b6c8
2006-04-09 02:48:54 +00:00
|
|
|
|
{
|
2007-03-18 10:59:16 +00:00
|
|
|
|
OutputParams runparams(¶ms().encoding());
|
view-source feature, from Bo Peng <ben.bob@gmail.com>
* src/buffer.h buffer.C - getSourceCode()
* src/lyxfunc.C - open view-source dialog
* src/text3.C - change LFUN_MOUSE_RELEASE
* src/output_linuxdoc.C, src/output_docbook.C, src/output_latex.C
- intercept output
* src/outputparams.h, outputparams.C - add par_begin, par_end, dryrun
* src/insets/insetgraphics.C - add dryrun mode of file conversion
* lib/ui/stdmenus.ui - add view-source menu item under view
* Add view-source dialog, add
src/frontends/qt2/QViewSourceDialog.h, QViewSource.C, QViewSource.h, QViewSourceDialog.C
src/frontends/qt2/ui/QViewSourceDialogBase.ui
src/frontends/controllers/ControlViewSource.h ControlViewSource.C
modify
src/frontends/qt2/Makefile.dialogs, Makefile.am, Dialogs.C,
src/frontends/controllers/Makefile.am, po.POTFILES.in
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@13610 a592a061-630c-0410-9148-cb99ea01b6c8
2006-04-09 02:48:54 +00:00
|
|
|
|
runparams.nice = true;
|
|
|
|
|
runparams.flavor = OutputParams::LATEX;
|
2007-01-15 22:49:14 +00:00
|
|
|
|
runparams.linelen = lyxrc.plaintext_linelen;
|
view-source feature, from Bo Peng <ben.bob@gmail.com>
* src/buffer.h buffer.C - getSourceCode()
* src/lyxfunc.C - open view-source dialog
* src/text3.C - change LFUN_MOUSE_RELEASE
* src/output_linuxdoc.C, src/output_docbook.C, src/output_latex.C
- intercept output
* src/outputparams.h, outputparams.C - add par_begin, par_end, dryrun
* src/insets/insetgraphics.C - add dryrun mode of file conversion
* lib/ui/stdmenus.ui - add view-source menu item under view
* Add view-source dialog, add
src/frontends/qt2/QViewSourceDialog.h, QViewSource.C, QViewSource.h, QViewSourceDialog.C
src/frontends/qt2/ui/QViewSourceDialogBase.ui
src/frontends/controllers/ControlViewSource.h ControlViewSource.C
modify
src/frontends/qt2/Makefile.dialogs, Makefile.am, Dialogs.C,
src/frontends/controllers/Makefile.am, po.POTFILES.in
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@13610 a592a061-630c-0410-9148-cb99ea01b6c8
2006-04-09 02:48:54 +00:00
|
|
|
|
// No side effect of file copying and image conversion
|
|
|
|
|
runparams.dryrun = true;
|
|
|
|
|
|
2007-11-30 17:46:49 +00:00
|
|
|
|
d->texrow.reset();
|
2006-08-04 13:59:12 +00:00
|
|
|
|
if (full_source) {
|
2007-05-25 09:20:35 +00:00
|
|
|
|
os << "% " << _("Preview source code") << "\n\n";
|
2007-11-30 17:46:49 +00:00
|
|
|
|
d->texrow.newline();
|
|
|
|
|
d->texrow.newline();
|
2006-09-09 11:16:28 +00:00
|
|
|
|
if (isLatex())
|
2006-08-04 13:59:12 +00:00
|
|
|
|
writeLaTeXSource(os, filePath(), runparams, true, true);
|
2006-10-19 16:51:30 +00:00
|
|
|
|
else {
|
2007-10-20 10:03:45 +00:00
|
|
|
|
writeDocBookSource(os, absFileName(), runparams, false);
|
2006-10-19 16:51:30 +00:00
|
|
|
|
}
|
2006-08-04 13:59:12 +00:00
|
|
|
|
} else {
|
|
|
|
|
runparams.par_begin = par_begin;
|
|
|
|
|
runparams.par_end = par_end;
|
|
|
|
|
if (par_begin + 1 == par_end)
|
2007-05-25 09:20:35 +00:00
|
|
|
|
os << "% "
|
2007-08-12 18:58:59 +00:00
|
|
|
|
<< bformat(_("Preview source code for paragraph %1$d"), par_begin)
|
2007-05-25 09:20:35 +00:00
|
|
|
|
<< "\n\n";
|
2006-08-04 13:59:12 +00:00
|
|
|
|
else
|
2007-05-25 09:20:35 +00:00
|
|
|
|
os << "% "
|
|
|
|
|
<< bformat(_("Preview source code from paragraph %1$s to %2$s"),
|
|
|
|
|
convert<docstring>(par_begin),
|
|
|
|
|
convert<docstring>(par_end - 1))
|
|
|
|
|
<< "\n\n";
|
2007-11-30 17:46:49 +00:00
|
|
|
|
d->texrow.newline();
|
|
|
|
|
d->texrow.newline();
|
2006-08-04 13:59:12 +00:00
|
|
|
|
// output paragraphs
|
|
|
|
|
if (isLatex()) {
|
2007-11-30 17:46:49 +00:00
|
|
|
|
latexParagraphs(*this, paragraphs(), os, d->texrow, runparams);
|
2006-10-19 16:51:30 +00:00
|
|
|
|
} else {
|
|
|
|
|
// DocBook
|
2006-10-19 21:00:33 +00:00
|
|
|
|
docbookParagraphs(paragraphs(), *this, os, runparams);
|
2006-10-19 16:51:30 +00:00
|
|
|
|
}
|
2006-08-04 13:59:12 +00:00
|
|
|
|
}
|
view-source feature, from Bo Peng <ben.bob@gmail.com>
* src/buffer.h buffer.C - getSourceCode()
* src/lyxfunc.C - open view-source dialog
* src/text3.C - change LFUN_MOUSE_RELEASE
* src/output_linuxdoc.C, src/output_docbook.C, src/output_latex.C
- intercept output
* src/outputparams.h, outputparams.C - add par_begin, par_end, dryrun
* src/insets/insetgraphics.C - add dryrun mode of file conversion
* lib/ui/stdmenus.ui - add view-source menu item under view
* Add view-source dialog, add
src/frontends/qt2/QViewSourceDialog.h, QViewSource.C, QViewSource.h, QViewSourceDialog.C
src/frontends/qt2/ui/QViewSourceDialogBase.ui
src/frontends/controllers/ControlViewSource.h ControlViewSource.C
modify
src/frontends/qt2/Makefile.dialogs, Makefile.am, Dialogs.C,
src/frontends/controllers/Makefile.am, po.POTFILES.in
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@13610 a592a061-630c-0410-9148-cb99ea01b6c8
2006-04-09 02:48:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-07-15 22:43:37 +00:00
|
|
|
|
|
2007-11-30 17:41:27 +00:00
|
|
|
|
ErrorList & Buffer::errorList(string const & type) const
|
2006-07-15 22:43:37 +00:00
|
|
|
|
{
|
2007-11-30 17:41:27 +00:00
|
|
|
|
static ErrorList emptyErrorList;
|
2007-11-30 17:46:49 +00:00
|
|
|
|
std::map<string, ErrorList>::iterator I = d->errorLists.find(type);
|
|
|
|
|
if (I == d->errorLists.end())
|
2006-08-14 09:33:49 +00:00
|
|
|
|
return emptyErrorList;
|
2006-07-15 22:43:37 +00:00
|
|
|
|
|
2006-08-13 16:16:43 +00:00
|
|
|
|
return I->second;
|
2006-07-15 22:43:37 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-10-02 18:27:20 +00:00
|
|
|
|
void Buffer::structureChanged() const
|
|
|
|
|
{
|
|
|
|
|
if (gui_)
|
|
|
|
|
gui_->structureChanged();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Buffer::errors(std::string const & err) const
|
|
|
|
|
{
|
|
|
|
|
if (gui_)
|
|
|
|
|
gui_->errors(err);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Buffer::message(docstring const & msg) const
|
|
|
|
|
{
|
|
|
|
|
if (gui_)
|
|
|
|
|
gui_->message(msg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-10-21 10:50:56 +00:00
|
|
|
|
void Buffer::setBusy(bool on) const
|
2007-10-02 18:27:20 +00:00
|
|
|
|
{
|
|
|
|
|
if (gui_)
|
2007-10-23 21:41:17 +00:00
|
|
|
|
gui_->setBusy(on);
|
2007-10-02 18:27:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-10-23 21:41:17 +00:00
|
|
|
|
void Buffer::setReadOnly(bool on) const
|
2007-10-02 18:27:20 +00:00
|
|
|
|
{
|
2007-11-30 17:46:49 +00:00
|
|
|
|
if (d->wa_)
|
|
|
|
|
d->wa_->setReadOnly(on);
|
2007-10-02 18:27:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Buffer::updateTitles() const
|
|
|
|
|
{
|
2007-11-30 17:46:49 +00:00
|
|
|
|
if (d->wa_)
|
|
|
|
|
d->wa_->updateTitles();
|
2007-10-02 18:27:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Buffer::resetAutosaveTimers() const
|
|
|
|
|
{
|
|
|
|
|
if (gui_)
|
|
|
|
|
gui_->resetAutosaveTimers();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Buffer::setGuiDelegate(frontend::GuiBufferDelegate * gui)
|
|
|
|
|
{
|
|
|
|
|
gui_ = gui;
|
|
|
|
|
}
|
|
|
|
|
|
2007-10-03 11:00:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
|
|
class AutoSaveBuffer : public support::ForkedProcess {
|
|
|
|
|
public:
|
|
|
|
|
///
|
|
|
|
|
AutoSaveBuffer(Buffer const & buffer, FileName const & fname)
|
|
|
|
|
: buffer_(buffer), fname_(fname) {}
|
|
|
|
|
///
|
|
|
|
|
virtual boost::shared_ptr<ForkedProcess> clone() const
|
|
|
|
|
{
|
|
|
|
|
return boost::shared_ptr<ForkedProcess>(new AutoSaveBuffer(*this));
|
|
|
|
|
}
|
|
|
|
|
///
|
|
|
|
|
int start()
|
|
|
|
|
{
|
|
|
|
|
command_ = to_utf8(bformat(_("Auto-saving %1$s"),
|
|
|
|
|
from_utf8(fname_.absFilename())));
|
|
|
|
|
return run(DontWait);
|
|
|
|
|
}
|
|
|
|
|
private:
|
|
|
|
|
///
|
|
|
|
|
virtual int generateChild();
|
|
|
|
|
///
|
|
|
|
|
Buffer const & buffer_;
|
|
|
|
|
FileName fname_;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2007-10-03 22:27:31 +00:00
|
|
|
|
#if !defined (HAVE_FORK)
|
|
|
|
|
# define fork() -1
|
|
|
|
|
#endif
|
|
|
|
|
|
2007-10-03 11:00:18 +00:00
|
|
|
|
int AutoSaveBuffer::generateChild()
|
|
|
|
|
{
|
|
|
|
|
// tmp_ret will be located (usually) in /tmp
|
|
|
|
|
// will that be a problem?
|
2007-10-03 22:27:31 +00:00
|
|
|
|
pid_t const pid = fork();
|
|
|
|
|
// If you want to debug the autosave
|
|
|
|
|
// you should set pid to -1, and comment out the fork.
|
2007-10-03 11:00:18 +00:00
|
|
|
|
if (pid == 0 || pid == -1) {
|
|
|
|
|
// pid = -1 signifies that lyx was unable
|
|
|
|
|
// to fork. But we will do the save
|
|
|
|
|
// anyway.
|
|
|
|
|
bool failed = false;
|
|
|
|
|
|
|
|
|
|
FileName const tmp_ret(tempName(FileName(), "lyxauto"));
|
|
|
|
|
if (!tmp_ret.empty()) {
|
|
|
|
|
buffer_.writeFile(tmp_ret);
|
|
|
|
|
// assume successful write of tmp_ret
|
|
|
|
|
if (!rename(tmp_ret, fname_)) {
|
|
|
|
|
failed = true;
|
|
|
|
|
// most likely couldn't move between
|
|
|
|
|
// filesystems unless write of tmp_ret
|
|
|
|
|
// failed so remove tmp file (if it
|
|
|
|
|
// exists)
|
2007-11-28 09:01:49 +00:00
|
|
|
|
tmp_ret.removeFile();
|
2007-10-03 11:00:18 +00:00
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
failed = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (failed) {
|
|
|
|
|
// failed to write/rename tmp_ret so try writing direct
|
|
|
|
|
if (!buffer_.writeFile(fname_)) {
|
|
|
|
|
// It is dangerous to do this in the child,
|
|
|
|
|
// but safe in the parent, so...
|
|
|
|
|
if (pid == -1) // emit message signal.
|
|
|
|
|
buffer_.message(_("Autosave failed!"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (pid == 0) { // we are the child so...
|
|
|
|
|
_exit(0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return pid;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace anon
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Perfect target for a thread...
|
|
|
|
|
void Buffer::autoSave() const
|
|
|
|
|
{
|
|
|
|
|
if (isBakClean() || isReadonly()) {
|
|
|
|
|
// We don't save now, but we'll try again later
|
|
|
|
|
resetAutosaveTimers();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// emit message signal.
|
|
|
|
|
message(_("Autosaving current document..."));
|
|
|
|
|
|
|
|
|
|
// create autosave filename
|
|
|
|
|
string fname = filePath();
|
|
|
|
|
fname += '#';
|
2007-12-04 22:21:25 +00:00
|
|
|
|
fname += d->filename.onlyFileName();
|
2007-10-03 11:00:18 +00:00
|
|
|
|
fname += '#';
|
|
|
|
|
|
|
|
|
|
AutoSaveBuffer autosave(*this, FileName(fname));
|
|
|
|
|
autosave.start();
|
|
|
|
|
|
|
|
|
|
markBakClean();
|
|
|
|
|
resetAutosaveTimers();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-11-30 17:41:27 +00:00
|
|
|
|
void Buffer::resetChildDocuments(bool close_them) const
|
|
|
|
|
{
|
|
|
|
|
for (InsetIterator it = inset_iterator_begin(inset()); it; ++it) {
|
|
|
|
|
if (it->lyxCode() != INCLUDE_CODE)
|
|
|
|
|
continue;
|
|
|
|
|
InsetCommand const & inset = static_cast<InsetCommand const &>(*it);
|
|
|
|
|
InsetCommandParams const & ip = inset.params();
|
|
|
|
|
|
|
|
|
|
resetParentBuffer(this, ip, close_them);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (use_gui && masterBuffer() == this)
|
|
|
|
|
updateLabels(*this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-10-20 10:03:45 +00:00
|
|
|
|
void Buffer::loadChildDocuments() const
|
|
|
|
|
{
|
|
|
|
|
bool parse_error = false;
|
|
|
|
|
|
|
|
|
|
for (InsetIterator it = inset_iterator_begin(inset()); it; ++it) {
|
|
|
|
|
if (it->lyxCode() != INCLUDE_CODE)
|
|
|
|
|
continue;
|
2007-10-23 15:02:15 +00:00
|
|
|
|
InsetCommand const & inset = static_cast<InsetCommand const &>(*it);
|
2007-10-20 10:03:45 +00:00
|
|
|
|
InsetCommandParams const & ip = inset.params();
|
|
|
|
|
Buffer * child = loadIfNeeded(*this, ip);
|
|
|
|
|
if (!child)
|
|
|
|
|
continue;
|
|
|
|
|
parse_error |= !child->errorList("Parse").empty();
|
|
|
|
|
child->loadChildDocuments();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (use_gui && masterBuffer() == this)
|
|
|
|
|
updateLabels(*this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
string Buffer::bufferFormat() const
|
|
|
|
|
{
|
|
|
|
|
if (isDocBook())
|
|
|
|
|
return "docbook";
|
|
|
|
|
if (isLiterate())
|
|
|
|
|
return "literate";
|
|
|
|
|
return "latex";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-10-23 21:41:17 +00:00
|
|
|
|
bool Buffer::doExport(string const & format, bool put_in_tempdir,
|
2007-11-30 17:41:27 +00:00
|
|
|
|
string & result_file) const
|
2007-10-20 10:51:13 +00:00
|
|
|
|
{
|
|
|
|
|
string backend_format;
|
|
|
|
|
OutputParams runparams(¶ms().encoding());
|
|
|
|
|
runparams.flavor = OutputParams::LATEX;
|
|
|
|
|
runparams.linelen = lyxrc.plaintext_linelen;
|
|
|
|
|
vector<string> backs = backends();
|
|
|
|
|
if (find(backs.begin(), backs.end(), format) == backs.end()) {
|
|
|
|
|
// Get shortest path to format
|
|
|
|
|
Graph::EdgePath path;
|
|
|
|
|
for (vector<string>::const_iterator it = backs.begin();
|
|
|
|
|
it != backs.end(); ++it) {
|
|
|
|
|
Graph::EdgePath p = theConverters().getPath(*it, format);
|
|
|
|
|
if (!p.empty() && (path.empty() || p.size() < path.size())) {
|
|
|
|
|
backend_format = *it;
|
|
|
|
|
path = p;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!path.empty())
|
|
|
|
|
runparams.flavor = theConverters().getFlavor(path);
|
|
|
|
|
else {
|
|
|
|
|
Alert::error(_("Couldn't export file"),
|
|
|
|
|
bformat(_("No information for exporting the format %1$s."),
|
|
|
|
|
formats.prettyName(format)));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
backend_format = format;
|
|
|
|
|
// FIXME: Don't hardcode format names here, but use a flag
|
|
|
|
|
if (backend_format == "pdflatex")
|
|
|
|
|
runparams.flavor = OutputParams::PDFLATEX;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
string filename = latexName(false);
|
|
|
|
|
filename = addName(temppath(), filename);
|
|
|
|
|
filename = changeExtension(filename,
|
|
|
|
|
formats.extension(backend_format));
|
|
|
|
|
|
|
|
|
|
// Plain text backend
|
|
|
|
|
if (backend_format == "text")
|
|
|
|
|
writePlaintextFile(*this, FileName(filename), runparams);
|
|
|
|
|
// no backend
|
|
|
|
|
else if (backend_format == "lyx")
|
|
|
|
|
writeFile(FileName(filename));
|
|
|
|
|
// Docbook backend
|
|
|
|
|
else if (isDocBook()) {
|
|
|
|
|
runparams.nice = !put_in_tempdir;
|
|
|
|
|
makeDocBookFile(FileName(filename), runparams);
|
|
|
|
|
}
|
|
|
|
|
// LaTeX backend
|
|
|
|
|
else if (backend_format == format) {
|
|
|
|
|
runparams.nice = true;
|
|
|
|
|
if (!makeLaTeXFile(FileName(filename), string(), runparams))
|
|
|
|
|
return false;
|
|
|
|
|
} else if (!lyxrc.tex_allows_spaces
|
|
|
|
|
&& support::contains(filePath(), ' ')) {
|
|
|
|
|
Alert::error(_("File name error"),
|
|
|
|
|
_("The directory path to the document cannot contain spaces."));
|
|
|
|
|
return false;
|
|
|
|
|
} else {
|
|
|
|
|
runparams.nice = false;
|
|
|
|
|
if (!makeLaTeXFile(FileName(filename), filePath(), runparams))
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
string const error_type = (format == "program")
|
|
|
|
|
? "Build" : bufferFormat();
|
|
|
|
|
string const ext = formats.extension(format);
|
|
|
|
|
FileName const tmp_result_file(changeExtension(filename, ext));
|
|
|
|
|
bool const success = theConverters().convert(this, FileName(filename),
|
|
|
|
|
tmp_result_file, FileName(absFileName()), backend_format, format,
|
|
|
|
|
errorList(error_type));
|
|
|
|
|
// Emit the signal to show the error list.
|
|
|
|
|
if (format != backend_format)
|
|
|
|
|
errors(error_type);
|
|
|
|
|
if (!success)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (put_in_tempdir)
|
|
|
|
|
result_file = tmp_result_file.absFilename();
|
|
|
|
|
else {
|
|
|
|
|
result_file = changeExtension(absFileName(), ext);
|
|
|
|
|
// We need to copy referenced files (e. g. included graphics
|
|
|
|
|
// if format == "dvi") to the result dir.
|
|
|
|
|
vector<ExportedFile> const files =
|
|
|
|
|
runparams.exportdata->externalFiles(format);
|
|
|
|
|
string const dest = onlyPath(result_file);
|
|
|
|
|
CopyStatus status = SUCCESS;
|
|
|
|
|
for (vector<ExportedFile>::const_iterator it = files.begin();
|
|
|
|
|
it != files.end() && status != CANCEL; ++it) {
|
|
|
|
|
string const fmt =
|
|
|
|
|
formats.getFormatFromFile(it->sourceName);
|
|
|
|
|
status = copyFile(fmt, it->sourceName,
|
|
|
|
|
makeAbsPath(it->exportName, dest),
|
|
|
|
|
it->exportName, status == FORCE);
|
|
|
|
|
}
|
|
|
|
|
if (status == CANCEL) {
|
|
|
|
|
message(_("Document export cancelled."));
|
|
|
|
|
} else if (tmp_result_file.exists()) {
|
|
|
|
|
// Finally copy the main file
|
|
|
|
|
status = copyFile(format, tmp_result_file,
|
|
|
|
|
FileName(result_file), result_file,
|
|
|
|
|
status == FORCE);
|
|
|
|
|
message(bformat(_("Document exported as %1$s "
|
|
|
|
|
"to file `%2$s'"),
|
|
|
|
|
formats.prettyName(format),
|
|
|
|
|
makeDisplayPath(result_file)));
|
|
|
|
|
} else {
|
|
|
|
|
// This must be a dummy converter like fax (bug 1888)
|
|
|
|
|
message(bformat(_("Document exported as %1$s"),
|
|
|
|
|
formats.prettyName(format)));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-11-30 17:41:27 +00:00
|
|
|
|
bool Buffer::doExport(string const & format, bool put_in_tempdir) const
|
2007-10-20 10:51:13 +00:00
|
|
|
|
{
|
|
|
|
|
string result_file;
|
|
|
|
|
return doExport(format, put_in_tempdir, result_file);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-11-30 17:41:27 +00:00
|
|
|
|
bool Buffer::preview(string const & format) const
|
2007-10-20 10:51:13 +00:00
|
|
|
|
{
|
|
|
|
|
string result_file;
|
|
|
|
|
if (!doExport(format, true, result_file))
|
|
|
|
|
return false;
|
|
|
|
|
return formats.view(*this, FileName(result_file), format);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool Buffer::isExportable(string const & format) const
|
|
|
|
|
{
|
|
|
|
|
vector<string> backs = backends();
|
|
|
|
|
for (vector<string>::const_iterator it = backs.begin();
|
|
|
|
|
it != backs.end(); ++it)
|
|
|
|
|
if (theConverters().isReachable(*it, format))
|
|
|
|
|
return true;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vector<Format const *> Buffer::exportableFormats(bool only_viewable) const
|
|
|
|
|
{
|
|
|
|
|
vector<string> backs = backends();
|
|
|
|
|
vector<Format const *> result =
|
|
|
|
|
theConverters().getReachable(backs[0], only_viewable, true);
|
|
|
|
|
for (vector<string>::const_iterator it = backs.begin() + 1;
|
|
|
|
|
it != backs.end(); ++it) {
|
|
|
|
|
vector<Format const *> r =
|
|
|
|
|
theConverters().getReachable(*it, only_viewable, false);
|
|
|
|
|
result.insert(result.end(), r.begin(), r.end());
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vector<string> Buffer::backends() const
|
|
|
|
|
{
|
|
|
|
|
vector<string> v;
|
|
|
|
|
if (params().getTextClass().isTeXClassAvailable()) {
|
|
|
|
|
v.push_back(bufferFormat());
|
|
|
|
|
// FIXME: Don't hardcode format names here, but use a flag
|
|
|
|
|
if (v.back() == "latex")
|
|
|
|
|
v.push_back("pdflatex");
|
|
|
|
|
}
|
|
|
|
|
v.push_back("text");
|
|
|
|
|
v.push_back("lyx");
|
|
|
|
|
return v;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-10-21 10:50:56 +00:00
|
|
|
|
bool Buffer::readFileHelper(FileName const & s)
|
|
|
|
|
{
|
|
|
|
|
// File information about normal file
|
|
|
|
|
if (!s.exists()) {
|
|
|
|
|
docstring const file = makeDisplayPath(s.absFilename(), 50);
|
|
|
|
|
docstring text = bformat(_("The specified document\n%1$s"
|
|
|
|
|
"\ncould not be read."), file);
|
|
|
|
|
Alert::error(_("Could not read document"), text);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check if emergency save file exists and is newer.
|
|
|
|
|
FileName const e(s.absFilename() + ".emergency");
|
|
|
|
|
|
|
|
|
|
if (e.exists() && s.exists() && e.lastModified() > s.lastModified()) {
|
|
|
|
|
docstring const file = makeDisplayPath(s.absFilename(), 20);
|
|
|
|
|
docstring const text =
|
|
|
|
|
bformat(_("An emergency save of the document "
|
|
|
|
|
"%1$s exists.\n\n"
|
|
|
|
|
"Recover emergency save?"), file);
|
|
|
|
|
switch (Alert::prompt(_("Load emergency save?"), text, 0, 2,
|
|
|
|
|
_("&Recover"), _("&Load Original"),
|
|
|
|
|
_("&Cancel")))
|
|
|
|
|
{
|
|
|
|
|
case 0:
|
|
|
|
|
// the file is not saved if we load the emergency file.
|
|
|
|
|
markDirty();
|
|
|
|
|
return readFile(e);
|
|
|
|
|
case 1:
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Now check if autosave file is newer.
|
|
|
|
|
FileName const a(onlyPath(s.absFilename()) + '#' + onlyFilename(s.absFilename()) + '#');
|
|
|
|
|
|
|
|
|
|
if (a.exists() && s.exists() && a.lastModified() > s.lastModified()) {
|
|
|
|
|
docstring const file = makeDisplayPath(s.absFilename(), 20);
|
|
|
|
|
docstring const text =
|
|
|
|
|
bformat(_("The backup of the document "
|
|
|
|
|
"%1$s is newer.\n\nLoad the "
|
|
|
|
|
"backup instead?"), file);
|
|
|
|
|
switch (Alert::prompt(_("Load backup?"), text, 0, 2,
|
|
|
|
|
_("&Load backup"), _("Load &original"),
|
|
|
|
|
_("&Cancel") ))
|
|
|
|
|
{
|
|
|
|
|
case 0:
|
|
|
|
|
// the file is not saved if we load the autosave file.
|
|
|
|
|
markDirty();
|
|
|
|
|
return readFile(a);
|
|
|
|
|
case 1:
|
|
|
|
|
// Here we delete the autosave
|
2007-11-28 09:01:49 +00:00
|
|
|
|
a.removeFile();
|
2007-10-21 10:50:56 +00:00
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return readFile(s);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool Buffer::loadLyXFile(FileName const & s)
|
|
|
|
|
{
|
2007-11-25 11:18:16 +00:00
|
|
|
|
if (s.isReadableFile()) {
|
2007-10-21 10:50:56 +00:00
|
|
|
|
if (readFileHelper(s)) {
|
|
|
|
|
lyxvc().file_found_hook(s);
|
|
|
|
|
if (!s.isWritable())
|
|
|
|
|
setReadonly(true);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
docstring const file = makeDisplayPath(s.absFilename(), 20);
|
|
|
|
|
// Here we probably should run
|
|
|
|
|
if (LyXVC::file_not_found_hook(s)) {
|
|
|
|
|
docstring const text =
|
|
|
|
|
bformat(_("Do you want to retrieve the document"
|
|
|
|
|
" %1$s from version control?"), file);
|
|
|
|
|
int const ret = Alert::prompt(_("Retrieve from version control?"),
|
|
|
|
|
text, 0, 1, _("&Retrieve"), _("&Cancel"));
|
|
|
|
|
|
|
|
|
|
if (ret == 0) {
|
|
|
|
|
// How can we know _how_ to do the checkout?
|
|
|
|
|
// With the current VC support it has to be,
|
|
|
|
|
// a RCS file since CVS do not have special ,v files.
|
|
|
|
|
RCS::retrieve(s);
|
|
|
|
|
return loadLyXFile(s);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Buffer::bufferErrors(TeXErrors const & terr, ErrorList & errorList) const
|
|
|
|
|
{
|
|
|
|
|
TeXErrors::Errors::const_iterator cit = terr.begin();
|
|
|
|
|
TeXErrors::Errors::const_iterator end = terr.end();
|
|
|
|
|
|
|
|
|
|
for (; cit != end; ++cit) {
|
|
|
|
|
int id_start = -1;
|
|
|
|
|
int pos_start = -1;
|
|
|
|
|
int errorRow = cit->error_in_line;
|
2007-11-30 17:46:49 +00:00
|
|
|
|
bool found = d->texrow.getIdFromRow(errorRow, id_start,
|
2007-10-21 10:50:56 +00:00
|
|
|
|
pos_start);
|
|
|
|
|
int id_end = -1;
|
|
|
|
|
int pos_end = -1;
|
|
|
|
|
do {
|
|
|
|
|
++errorRow;
|
2007-11-30 17:46:49 +00:00
|
|
|
|
found = d->texrow.getIdFromRow(errorRow, id_end, pos_end);
|
2007-10-21 10:50:56 +00:00
|
|
|
|
} 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));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2006-10-21 00:16:43 +00:00
|
|
|
|
} // namespace lyx
|