#include "PDFOptions.h"
#include "SpellChecker.h"
#include "sgml.h"
+#include "texstream.h"
#include "TexRow.h"
#include "Text.h"
#include "TextClass.h"
#include "mathed/MathMacroTemplate.h"
#include "mathed/MathSupport.h"
+#include "graphics/GraphicsCache.h"
#include "graphics/PreviewLoader.h"
#include "frontends/alert.h"
#include "support/types.h"
#include "support/bind.h"
-#include "support/shared_ptr.h"
#include <algorithm>
#include <fstream>
#include <iomanip>
#include <map>
+#include <memory>
#include <set>
#include <sstream>
#include <vector>
/// positions of child buffers in the buffer
typedef map<Buffer const * const, DocIterator> BufferPositionMap;
struct ScopeBuffer {
- ScopeBuffer() {}
- ScopeBuffer(DocIterator const & s,Buffer const * b)
+ ScopeBuffer() : buffer(0) {}
+ ScopeBuffer(DocIterator const & s, Buffer const * b)
: scope(s), buffer(b) {}
DocIterator scope;
Buffer const * buffer;
file_fully_loaded(false), file_format(LYX_FORMAT), need_format_backup(false),
ignore_parent(false), toc_backend(owner), macro_lock(false), timestamp_(0),
checksum_(0), wa_(0), gui_(0), undo_(*owner), bibinfo_cache_valid_(false),
- bibfile_cache_valid_(false), cite_labels_valid_(false), inset(0),
- preview_loader_(0), cloned_buffer_(cloned_buffer), clone_list_(0),
- doing_export(false), parent_buffer(0),
+ bibfile_cache_valid_(false), cite_labels_valid_(false), preview_error_(false),
+ inset(0), preview_loader_(0), cloned_buffer_(cloned_buffer),
+ clone_list_(0), doing_export(false), parent_buffer(0),
word_count_(0), char_count_(0), blank_count_(0)
{
if (!cloned_buffer_) {
params().html_latex_end.clear();
params().html_math_img_scale = 1.0;
params().output_sync_macro.erase();
- params().setLocalLayout(string(), false);
- params().setLocalLayout(string(), true);
+ params().setLocalLayout(docstring(), false);
+ params().setLocalLayout(docstring(), true);
for (int i = 0; i < 4; ++i) {
params().user_defined_bullet(i) = ITEMIZE_DEFAULTS[i];
"%1$s %2$s\n"),
from_utf8(token),
lex.getDocString());
- errorList.push_back(ErrorItem(_("Document header error"),
- s, -1, 0, 0));
+ errorList.push_back(ErrorItem(_("Document header error"), s));
}
}
}
if (begin_header_line) {
docstring const s = _("\\begin_header is missing");
- errorList.push_back(ErrorItem(_("Document header error"),
- s, -1, 0, 0));
+ errorList.push_back(ErrorItem(_("Document header error"), s));
}
params().makeDocumentClass();
if (!lex.checkFor("\\begin_document")) {
docstring const s = _("\\begin_document is missing");
- errorList.push_back(ErrorItem(_("Document header error"),
- s, -1, 0, 0));
+ errorList.push_back(ErrorItem(_("Document header error"), s));
}
readHeader(lex);
FileName Buffer::getBackupName() const {
FileName const & fn = fileName();
string const fname = fn.onlyFileNameWithoutExt();
- string const fext = fn.extension();
+ string const fext = fn.extension() + "~";
string const fpath = lyxrc.backupdir_path.empty() ?
fn.onlyPath().absFileName() :
lyxrc.backupdir_path;
// proper location once that has been done successfully. that
// way we preserve the original file if something goes wrong.
string const justname = fileName().onlyFileNameWithoutExt();
- boost::scoped_ptr<TempFile>
- tempfile(new TempFile(fileName().onlyPath(),
- justname + "-XXXXXX.lyx"));
+ auto tempfile = make_unique<TempFile>(fileName().onlyPath(),
+ justname + "-XXXXXX.lyx");
bool const symlink = fileName().isSymLink();
if (!symlink)
tempfile->setAutoRemove(false);
{
OutputParams runparams = runparams_in;
- // XeTeX with TeX fonts is only safe with ASCII encoding,
- // but the "flavor" is not known in BufferParams::encoding().
- if (!params().useNonTeXFonts && (runparams.flavor == OutputParams::XETEX))
+ // XeTeX with TeX fonts is only safe with ASCII encoding (see also #9740),
+ // Check here, because the "flavor" is not known in BufferParams::encoding()
+ // (power users can override this safety measure selecting "utf8-plain").
+ if (!params().useNonTeXFonts && (runparams.flavor == OutputParams::XETEX)
+ && (runparams.encoding->name() != "utf8-plain"))
runparams.encoding = encodings.fromLyXName("ascii");
string const encoding = runparams.encoding->iconvName();
ErrorList & errorList = d->errorLists["Export"];
errorList.clear();
bool failed_export = false;
- otexstream os(ofs, d->texrow);
+ otexstream os(ofs);
// make sure we are ready to export
// this needs to be done before we validate
updateMacroInstances(OutputUpdate);
try {
- os.texrow().reset();
writeLaTeXSource(os, original_path, runparams, output);
}
catch (EncodingException const & e) {
errorList.push_back(ErrorItem(msg, _("Some characters of your document are probably not "
"representable in the chosen encoding.\n"
"Changing the document encoding to utf8 could help."),
- e.par_id, e.pos, e.pos + 1));
+ {e.par_id, e.pos}, {e.par_id, e.pos + 1}));
failed_export = true;
}
catch (iconv_codecvt_facet_exception const & e) {
errorList.push_back(ErrorItem(_("iconv conversion failed"),
- _(e.what()), -1, 0, 0));
+ _(e.what())));
failed_export = true;
}
catch (exception const & e) {
errorList.push_back(ErrorItem(_("conversion failed"),
- _(e.what()), -1, 0, 0));
+ _(e.what())));
failed_export = true;
}
catch (...) {
lyx_exit(1);
}
+ d->texrow = move(os.texrow());
+
ofs.close();
if (ofs.fail()) {
failed_export = true;
OutputParams runparams = runparams_in;
// XeTeX with TeX fonts is only safe with ASCII encoding,
- // but the "flavor" is not known in BufferParams::encoding().
- if (!params().useNonTeXFonts && (runparams.flavor == OutputParams::XETEX))
+ // Check here, because the "flavor" is not known in BufferParams::encoding()
+ // (power users can override this safety measure selecting "utf8-plain").
+ if (!params().useNonTeXFonts && (runparams.flavor == OutputParams::XETEX)
+ && (runparams.encoding->name() != "utf8-plain"))
runparams.encoding = encodings.fromLyXName("ascii");
// FIXME: when only the current paragraph is shown, this is ignored
// (or not reached) and characters encodable in the current
// Write the preamble
runparams.use_babel = params().writeLaTeX(os, features,
d->filename.onlyPath());
+
+ if (!runparams.dryrun && features.hasPolyglossiaExclusiveLanguages()
+ && !features.hasOnlyPolyglossiaLanguages()) {
+ docstring blangs;
+ docstring plangs;
+ vector<string> bll = features.getBabelExclusiveLanguages();
+ vector<string> pll = features.getPolyglossiaExclusiveLanguages();
+ if (!bll.empty()) {
+ docstring langs;
+ for (vector<string>::const_iterator it = bll.begin(); it != bll.end(); ++it) {
+ if (!langs.empty())
+ langs += ", ";
+ langs += _(*it);
+ }
+ blangs = bll.size() > 1 ?
+ support::bformat(_("The languages %1$s are only supported by Babel."), langs)
+ : support::bformat(_("The language %1$s is only supported by Babel."), langs);
+ }
+ if (!pll.empty()) {
+ docstring langs;
+ for (vector<string>::const_iterator it = pll.begin(); it != pll.end(); ++it) {
+ if (!langs.empty())
+ langs += ", ";
+ langs += _(*it);
+ }
+ plangs = pll.size() > 1 ?
+ support::bformat(_("The languages %1$s are only supported by Polyglossia."), langs)
+ : support::bformat(_("The language %1$s is only supported by Polyglossia."), langs);
+ if (!blangs.empty())
+ plangs += "\n";
+ }
+
+ frontend::Alert::warning(
+ _("Incompatible Languages!"),
+ support::bformat(
+ _("You cannot use the following languages "
+ "together in one LaTeX document because "
+ "they require conflicting language packages:\n"
+ "%1$s%2$s"),
+ plangs, blangs));
+ }
// Japanese might be required only in some children of a document,
// but once required, we must keep use_japanese true.
}
// make the body.
+ // mark the beginning of the body to separate it from InPreamble insets
+ os.texrow().start(TexRow::beginDocument());
os << "\\begin{document}\n";
+ // mark the start of a new paragraph by simulating a newline,
+ // so that os.afterParbreak() returns true at document start
+ os.lastChar('\n');
+
// output the parent macros
MacroSet::iterator it = parentMacros.begin();
MacroSet::iterator end = parentMacros.end();
} // output_preamble
- os.texrow().start(paragraphs().begin()->id(), 0);
-
LYXERR(Debug::INFO, "preamble finished, now the body.");
// the real stuff
}
runparams_in.encoding = runparams.encoding;
- os.texrow().finalize();
-
LYXERR(Debug::INFO, "Finished making LaTeX file.");
LYXERR(Debug::INFO, "Row count was " << os.texrow().rows() - 1 << '.');
}
LaTeXFeatures features(*this, params(), runparams);
validate(features);
- d->texrow.reset(false);
+ d->texrow.reset();
DocumentClass const & tclass = params().documentClass();
string const & top_element = tclass.latexname();
else
os << " PUBLIC \"-//OASIS//DTD DocBook V4.2//EN\"";
- docstring preamble = from_utf8(params().preamble);
+ docstring preamble = params().preamble;
if (runparams.flavor != OutputParams::XML ) {
preamble += "<!ENTITY % output.print.png \"IGNORE\">\n";
preamble += "<!ENTITY % output.print.pdf \"IGNORE\">\n";
if (!styles.empty())
os << "\n<!-- Text Class Preamble -->\n" << styles << '\n';
- styles = from_utf8(features.getPreambleSnippets());
+ styles = features.getPreambleSnippets().str;
if (!styles.empty())
os << "\n<!-- Preamble Snippets -->\n" << styles << '\n';
// we will collect CSS information in a stream, and then output it
// either here, as part of the header, or else in a separate file.
odocstringstream css;
- styles = from_utf8(features.getCSSSnippets());
+ styles = features.getCSSSnippets();
if (!styles.empty())
css << "/* LyX Provided Styles */\n" << styles << '\n';
if (output_body) {
bool const output_body_tag = (output != IncludedFile);
if (output_body_tag)
- os << "<body>\n";
+ os << "<body dir=\"auto\">\n";
XHTMLStream xs(os);
if (output != IncludedFile)
// if we're an included file, the counters are in the master.
if (!features.runparams().is_child)
params().validate(features);
- for_each(paragraphs().begin(), paragraphs().end(),
- bind(&Paragraph::validate, _1, ref(features)));
+ for (Paragraph const & p : paragraphs())
+ p.validate(features);
if (lyxerr.debugging(Debug::LATEX)) {
features.showStruct();
size_t pos = format.find(' ');
if (pos != string::npos)
format = format.substr(0, pos);
- enable = params().isExportable(format);
+ enable = params().isExportable(format, false);
if (!enable)
flag.message(bformat(
_("Don't know how to export to format: %1$s"), arg));
break;
case LFUN_BUILD_PROGRAM:
- enable = params().isExportable("program");
+ enable = params().isExportable("program", false);
break;
case LFUN_BRANCH_ACTIVATE:
DocIterator Buffer::getParFromID(int const id) const
{
Buffer * buf = const_cast<Buffer *>(this);
- if (id < 0) {
- // John says this is called with id == -1 from undo
- lyxerr << "getParFromID(), id: " << id << endl;
+ if (id < 0)
+ // This means non-existent
return doc_iterator_end(buf);
- }
for (DocIterator it = doc_iterator_begin(buf); !it.atEnd(); it.forwardPar())
if (it.paragraph().id() == id)
MacroContext mc = MacroContext(this, it);
for (DocIterator::idx_type i = 0; i < n; ++i) {
MathData & data = minset->cell(i);
- data.updateMacros(0, mc, utype);
+ data.updateMacros(0, mc, utype, 0);
}
}
}
// in order to know if we should output polyglossia
// macros (instead of babel macros)
LaTeXFeatures features(*this, params(), runparams);
- params().validate(features);
+ validate(features);
runparams.use_polyglossia = features.usePolyglossia();
- texrow = make_unique<TexRow>();
- texrow->newline();
- texrow->newline();
// latex or literate
- otexstream ots(os, *texrow);
-
+ otexstream ots(os);
+ // output above
+ ots.texrow().newlines(2);
// the real stuff
latexParagraphs(*this, text(), ots, runparams);
- texrow->finalize();
+ texrow = ots.releaseTexRow();
// Restore the parenthood
if (!master)
writeDocBookSource(os, absFileName(), runparams, output);
} else {
// latex or literate
- texrow = make_unique<TexRow>();
- texrow->newline();
- texrow->newline();
- otexstream ots(os, *texrow);
+ otexstream ots(os);
+ // output above
+ ots.texrow().newlines(2);
if (master)
runparams.is_child = true;
writeLaTeXSource(ots, string(), runparams, output);
- texrow->finalize();
+ texrow = ots.releaseTexRow();
}
}
return texrow;
///
virtual shared_ptr<ForkedProcess> clone() const
{
- return shared_ptr<ForkedProcess>(new AutoSaveBuffer(*this));
+ return make_shared<AutoSaveBuffer>(*this);
}
///
int start()
ExportStatus const status = doExport(format, true, false, result_file);
FileName const previewFile(result_file);
- LATTEST (isClone());
- d->cloned_buffer_->d->preview_file_ = previewFile;
- d->cloned_buffer_->d->preview_format_ = format;
- d->cloned_buffer_->d->preview_error_ = (status != ExportSuccess);
+ Impl * theimpl = isClone() ? d->cloned_buffer_->d : d;
+ theimpl->preview_file_ = previewFile;
+ theimpl->preview_format_ = format;
+ theimpl->preview_error_ = (status != ExportSuccess);
if (status != ExportSuccess)
return status;
- if (previewFile.exists()) {
- if (!formats.view(*this, previewFile, format))
- return PreviewError;
- else
- return PreviewSuccess;
- }
- else {
- // Successful export but no output file?
- // Probably a bug in error detection.
- LATTEST (status != ExportSuccess);
- return status;
- }
+ if (previewFile.exists())
+ return formats.view(*this, previewFile, format) ?
+ PreviewSuccess : PreviewError;
+
+ // Successful export but no output file?
+ // Probably a bug in error detection.
+ LATTEST(status != ExportSuccess);
+ return status;
}
void Buffer::bufferErrors(TeXErrors const & terr, ErrorList & errorList) const
{
- TeXErrors::Errors::const_iterator it = terr.begin();
- TeXErrors::Errors::const_iterator end = terr.end();
- ListOfBuffers clist = getDescendents();
- ListOfBuffers::const_iterator cen = clist.end();
-
- for (; it != end; ++it) {
- int id_start = -1;
- int pos_start = -1;
- int errorRow = it->error_in_line;
+ for (auto const & err : terr) {
+ TexRow::TextEntry start, end = TexRow::text_none;
+ int errorRow = err.error_in_line;
Buffer const * buf = 0;
Impl const * p = d;
- if (it->child_name.empty())
- p->texrow.getIdFromRow(errorRow, id_start, pos_start);
+ if (err.child_name.empty())
+ tie(start, end) = p->texrow.getEntriesFromRow(errorRow);
else {
// The error occurred in a child
- ListOfBuffers::const_iterator cit = clist.begin();
- for (; cit != cen; ++cit) {
+ for (Buffer const * child : getDescendents()) {
string const child_name =
- DocFileName(changeExtension(
- (*cit)->absFileName(), "tex")).
- mangledFileName();
- if (it->child_name != child_name)
+ DocFileName(changeExtension(child->absFileName(), "tex")).
+ mangledFileName();
+ if (err.child_name != child_name)
continue;
- (*cit)->d->texrow.getIdFromRow(errorRow,
- id_start, pos_start);
- if (id_start != -1) {
+ tie(start, end) = child->d->texrow.getEntriesFromRow(errorRow);
+ if (!TexRow::isNone(start)) {
buf = d->cloned_buffer_
- ? (*cit)->d->cloned_buffer_->d->owner_
- : (*cit)->d->owner_;
- p = (*cit)->d;
+ ? child->d->cloned_buffer_->d->owner_
+ : child->d->owner_;
+ p = child->d;
break;
}
}
}
- int id_end = -1;
- int pos_end = -1;
- bool found;
- do {
- ++errorRow;
- found = p->texrow.getIdFromRow(errorRow, id_end, pos_end);
- } while (found && id_start == id_end && pos_start == pos_end);
-
- if (id_start != id_end) {
- // Next registered position is outside the inset where
- // the error occurred, so signal end-of-paragraph
- pos_end = 0;
- }
-
- errorList.push_back(ErrorItem(it->error_desc,
- it->error_text, id_start, pos_start, pos_end, buf));
+ errorList.push_back(ErrorItem(err.error_desc, err.error_text,
+ start, end, buf));
}
}
if (!it[i].inset().inMathed())
depth += it[i].paragraph().getDepth() + 1;
// remove 1 since the outer inset does not count
+ // we should have at least one non-math inset, so
+ // depth should nevery be 0. but maybe it is worth
+ // marking this, just in case.
+ LATTEST(depth > 0);
+ // coverity[INTEGER_OVERFLOW]
return depth - 1;
}
--prev_it.top().pit();
Paragraph const & prev_par = *prev_it;
if (prev_par.getDepth() <= cur_depth)
- return prev_par.layout().labeltype != LABEL_ENUMERATE;
+ return prev_par.layout().name() != par.layout().name();
}
// start of nested inset: reset
return true;
break;
}
+ // Increase the master counter?
+ if (layout.stepmastercounter && needEnumCounterReset(it))
+ counters.stepMaster(enumcounter, utype);
+
// Maybe we have to reset the enumeration counter.
- if (needEnumCounterReset(it))
+ if (!layout.resumecounter && needEnumCounterReset(it))
counters.reset(enumcounter);
counters.step(enumcounter, utype);