]> git.lyx.org Git - lyx.git/blobdiff - src/Buffer.cpp
start XeTeX support.
[lyx.git] / src / Buffer.cpp
index e0998f8330b8f7884268e6ee5a41e5c9e2ffb594..a4d78be6b56f2a71f89945d98294c8dde0ab1dff 100644 (file)
@@ -50,6 +50,7 @@
 #include "ParagraphParameters.h"
 #include "ParIterator.h"
 #include "PDFOptions.h"
+#include "SpellChecker.h"
 #include "sgml.h"
 #include "TexRow.h"
 #include "TexStream.h"
@@ -59,6 +60,7 @@
 #include "Undo.h"
 #include "VCBackend.h"
 #include "version.h"
+#include "WordLangTuple.h"
 #include "WordList.h"
 
 #include "insets/InsetBibitem.h"
@@ -79,6 +81,7 @@
 #include "support/lassert.h"
 #include "support/convert.h"
 #include "support/debug.h"
+#include "support/docstring_list.h"
 #include "support/ExceptionMessage.h"
 #include "support/FileName.h"
 #include "support/FileNameList.h"
@@ -118,7 +121,7 @@ namespace {
 
 // Do not remove the comment below, so we get merge conflict in
 // independent branches. Instead add your own.
-int const LYX_FORMAT = 348;  // uwestoehr: add support for \*phantom
+int const LYX_FORMAT = 349;  // jspitzm: initial XeTeX support
 
 typedef map<string, bool> DepClean;
 typedef map<docstring, pair<InsetLabel const *, Buffer::References> > RefCache;
@@ -228,6 +231,9 @@ public:
        /// This is here to force the test to be done whenever parent_buffer
        /// is accessed.
        Buffer const * parent() const { 
+               // if parent_buffer is not loaded, then it has been unloaded,
+               // which means that parent_buffer is an invalid pointer. So we
+               // set it to null in that case.
                if (!theBufferList().isLoaded(parent_buffer))
                        parent_buffer = 0;
                return parent_buffer; 
@@ -927,7 +933,7 @@ bool Buffer::writeFile(FileName const & fname) const
                return false;
        }
 
-       removeAutosaveFile(d->filename.absFilename());
+       removeAutosaveFile();
 
        saveCheckSum(d->filename);
        message(str + _(" done."));
@@ -999,9 +1005,13 @@ bool Buffer::write(ostream & ofs) const
 
 bool Buffer::makeLaTeXFile(FileName const & fname,
                           string const & original_path,
-                          OutputParams const & runparams,
+                          OutputParams const & runparams_in,
                           bool output_preamble, bool output_body) const
 {
+       OutputParams runparams = runparams_in;
+       if (params().useXetex)
+               runparams.flavor = OutputParams::XETEX;
+
        string const encoding = runparams.encoding->iconvName();
        LYXERR(Debug::LATEX, "makeLaTeXFile encoding: " << encoding << "...");
 
@@ -2226,7 +2236,8 @@ void Buffer::getSourceCode(odocstream & os, pit_type par_begin,
 {
        OutputParams runparams(&params().encoding());
        runparams.nice = true;
-       runparams.flavor = OutputParams::LATEX;
+       runparams.flavor = params().useXetex ? 
+               OutputParams::XETEX : OutputParams::LATEX;
        runparams.linelen = lyxrc.plaintext_linelen;
        // No side effect of file copying and image conversion
        runparams.dryrun = true;
@@ -2420,6 +2431,22 @@ int AutoSaveBuffer::generateChild()
 } // namespace anon
 
 
+FileName Buffer::getAutosaveFilename() const
+{
+       string const fpath = isUnnamed() ? lyxrc.document_path : filePath();
+       string const fname = "#" + d->filename.onlyFileName() + "#";
+       return makeAbsPath(fname, fpath);
+}
+
+
+void Buffer::removeAutosaveFile() const
+{
+       FileName const f = getAutosaveFilename();
+       if (f.exists())
+               f.removeFile();
+}
+
+
 // Perfect target for a thread...
 void Buffer::autoSave() const
 {
@@ -2431,14 +2458,7 @@ void Buffer::autoSave() const
 
        // emit message signal.
        message(_("Autosaving current document..."));
-
-       // create autosave filename
-       string fname = filePath();
-       fname += '#';
-       fname += d->filename.onlyFileName();
-       fname += '#';
-
-       AutoSaveBuffer autosave(*this, FileName(fname));
+       AutoSaveBuffer autosave(*this, getAutosaveFilename());
        autosave.start();
 
        markBakClean();
@@ -2452,6 +2472,8 @@ string Buffer::bufferFormat() const
                return "docbook";
        if (isLiterate())
                return "literate";
+       if (params().useXetex)
+               return "xetex";
        if (params().encoding().package() == Encoding::japanese)
                return "platex";
        return "latex";
@@ -3076,8 +3098,12 @@ bool Buffer::nextWord(DocIterator & from, DocIterator & to,
        bool inword = false;
        bool ignoreword = false;
        string lang_code;
+       // Go backward a bit if needed in order to return the word currently
+       // pointed by 'from'.
+       while (from && from.pos() && isLetter(from))
+               from.backwardPos();
+       // OK, we start from here.
        to = from;
-
        while (to.depth()) {
                if (isLetter(to)) {
                        if (!inword) {
@@ -3103,8 +3129,41 @@ bool Buffer::nextWord(DocIterator & from, DocIterator & to,
                }
                to.forwardPos();
        }
-
+       from = to;
+       word.clear();
        return false;
 }
 
+
+int Buffer::spellCheck(DocIterator & from, DocIterator & to,
+       WordLangTuple & word_lang, docstring_list & suggestions) const
+{
+       int progress = 0;
+       SpellChecker::Result res = SpellChecker::OK;
+       SpellChecker * speller = theSpellChecker();
+       suggestions.clear();
+       docstring word;
+       while (nextWord(from, to, word)) {
+               ++progress;
+               string lang_code = lyxrc.spellchecker_use_alt_lang
+                     ? lyxrc.spellchecker_alt_lang
+                     : from.paragraph().getFontSettings(params(), from.pos()).language()->code();
+               WordLangTuple wl(word, lang_code);
+               res = speller->check(wl);
+               // ... just bail out if the spellchecker reports an error.
+               if (!speller->error().empty()) {
+                       throw ExceptionMessage(WarningException,
+                               _("The spellchecker has failed."), speller->error());
+               }
+               if (res != SpellChecker::OK && res != SpellChecker::IGNORED_WORD) {
+                       word_lang = wl;
+                       break;
+               }
+               from = to;
+       }
+       while (!(word = speller->nextMiss()).empty())
+               suggestions.push_back(word);
+       return progress;
+}
+
 } // namespace lyx