CloneList * clone_list_;
/// are we in the process of exporting this buffer?
mutable bool doing_export;
+
+ /// compute statistics
+ /// \p from initial position
+ /// \p to points to the end position
+ void updateStatistics(DocIterator & from, DocIterator & to,
+ bool skipNoOutput = true);
+ /// statistics accessor functions
+ int wordCount() const { return word_count_; }
+ int charCount(bool with_blanks) const {
+ return char_count_
+ + (with_blanks ? blank_count_ : 0);
+ }
private:
/// So we can force access via the accessors.
mutable Buffer const * parent_buffer;
+ int word_count_;
+ int char_count_;
+ int blank_count_;
+
};
}
-Buffer * Buffer::clone() const
+Buffer * Buffer::cloneFromMaster() const
{
BufferMap bufmap;
cloned_buffers.push_back(new CloneList());
CloneList * clones = cloned_buffers.back();
- masterBuffer()->clone(bufmap, clones);
+ masterBuffer()->cloneWithChildren(bufmap, clones);
// make sure we got cloned
BufferMap::const_iterator bit = bufmap.find(this);
}
-void Buffer::clone(BufferMap & bufmap, CloneList * clones) const
+void Buffer::cloneWithChildren(BufferMap & bufmap, CloneList * clones) const
{
// have we already been cloned?
if (bufmap.find(this) != bufmap.end())
dit.setBuffer(buffer_clone);
Buffer * child = const_cast<Buffer *>(it->second.second);
- child->clone(bufmap, clones);
+ child->cloneWithChildren(bufmap, clones);
BufferMap::iterator const bit = bufmap.find(child);
LASSERT(bit != bufmap.end(), continue);
Buffer * child_clone = bit->second;
}
+Buffer * Buffer::cloneBufferOnly() const {
+ cloned_buffers.push_back(new CloneList());
+ CloneList * clones = cloned_buffers.back();
+ Buffer * buffer_clone = new Buffer(fileName().absFileName(), false, this);
+ clones->insert(buffer_clone);
+ buffer_clone->d->clone_list_ = clones;
+ // we won't be cloning the children
+ buffer_clone->d->children_positions.clear();
+ return buffer_clone;
+}
+
+
bool Buffer::isClone() const
{
return d->cloned_buffer_;
html::htmlize(doctitle, XHTMLStream::ESCAPE_ALL))
<< "</title>\n";
- os << "\n<!-- Text Class Preamble -->\n"
- << features.getTClassHTMLPreamble()
- << "\n<!-- Preamble Snippets -->\n"
- << from_utf8(features.getPreambleSnippets());
-
- os << "\n<!-- Layout-provided Styles -->\n";
- docstring const styleinfo = features.getTClassHTMLStyles();
- if (!styleinfo.empty()) {
- os << "<style type='text/css'>\n"
- << styleinfo
- << "</style>\n";
- }
+ docstring styles = features.getTClassHTMLPreamble();
+ if (!styles.empty())
+ os << "\n<!-- Text Class Preamble -->\n" << styles << '\n';
+
+ styles = from_utf8(features.getPreambleSnippets());
+ 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());
+ if (!styles.empty())
+ css << "/* LyX Provided Styles */\n" << styles << '\n';
+
+ styles = features.getTClassHTMLStyles();
+ if (!styles.empty())
+ css << "/* Layout-provided Styles */\n" << styles << '\n';
bool const needfg = params().fontcolor != RGBColor(0, 0, 0);
bool const needbg = params().backgroundcolor != RGBColor(0xFF, 0xFF, 0xFF);
if (needfg || needbg) {
- os << "<style type='text/css'>\nbody {\n";
+ css << "\nbody {\n";
if (needfg)
- os << " color: "
+ css << " color: "
<< from_ascii(X11hexname(params().fontcolor))
<< ";\n";
if (needbg)
- os << " background-color: "
+ css << " background-color: "
<< from_ascii(X11hexname(params().backgroundcolor))
<< ";\n";
- os << "}\n</style>\n";
+ css << "}\n";
+ }
+
+ docstring const dstyles = css.str();
+ if (!dstyles.empty()) {
+ bool written = false;
+ if (params().html_css_as_file) {
+ // open a file for CSS info
+ ofdocstream ocss;
+ string const fcssname = addName(temppath(), "docstyle.css");
+ FileName const fcssfile = FileName(fcssname);
+ if (openFileWrite(ocss, fcssfile)) {
+ ocss << dstyles;
+ ocss.close();
+ written = true;
+ // write link to header
+ os << "<link rel='stylesheet' href='docstyle.css' type='text/css' />\n";
+ // register file
+ runparams.exportdata->addExternalFile("xhtml", fcssfile);
+ }
+ }
+ // we are here if the CSS is supposed to be written to the header
+ // or if we failed to write it to an external file.
+ if (!written) {
+ os << "<style type='text/css'>\n"
+ << dstyles
+ << "\n</style>\n";
+ }
}
os << "</head>\n";
}
}
+void Buffer::removeBiblioTempFiles() const
+{
+ // We remove files that contain LaTeX commands specific to the
+ // particular bibliographic style being used, in order to avoid
+ // LaTeX errors when we switch style.
+ FileName const aux_file(addName(temppath(), changeExtension(latexName(),".aux")));
+ FileName const bbl_file(addName(temppath(), changeExtension(latexName(),".bbl")));
+ LYXERR(Debug::FILES, "Removing the .aux file " << aux_file);
+ aux_file.removeFile();
+ LYXERR(Debug::FILES, "Removing the .bbl file " << bbl_file);
+ bbl_file.removeFile();
+ // Also for the parent buffer
+ Buffer const * const pbuf = parent();
+ if (pbuf)
+ pbuf->removeBiblioTempFiles();
+}
+
+
bool Buffer::isDepClean(string const & name) const
{
DepClean::const_iterator const it = d->dep_clean.find(name);
docbookParagraphs(text(), *this, os, runparams);
else if (runparams.flavor == OutputParams::HTML) {
XHTMLStream xs(os);
+ setMathFlavor(runparams);
xhtmlParagraphs(text(), *this, xs, runparams);
} else {
// latex or literate
}
+void Buffer::setMathFlavor(OutputParams & op) const
+{
+ switch (params().html_math_output) {
+ case BufferParams::MathML:
+ op.math_flavor = OutputParams::MathAsMathML;
+ break;
+ case BufferParams::HTML:
+ op.math_flavor = OutputParams::MathAsHTML;
+ break;
+ case BufferParams::Images:
+ op.math_flavor = OutputParams::MathAsImages;
+ break;
+ case BufferParams::LaTeX:
+ op.math_flavor = OutputParams::MathAsLaTeX;
+ break;
+ }
+}
+
+
Buffer::ExportStatus Buffer::doExport(string const & target, bool put_in_tempdir,
bool includeall, string & result_file) const
{
// HTML backend
else if (backend_format == "xhtml") {
runparams.flavor = OutputParams::HTML;
- switch (params().html_math_output) {
- case BufferParams::MathML:
- runparams.math_flavor = OutputParams::MathAsMathML;
- break;
- case BufferParams::HTML:
- runparams.math_flavor = OutputParams::MathAsHTML;
- break;
- case BufferParams::Images:
- runparams.math_flavor = OutputParams::MathAsImages;
- break;
- case BufferParams::LaTeX:
- runparams.math_flavor = OutputParams::MathAsLaTeX;
- break;
- }
+ setMathFlavor(runparams);
makeLyXHTMLFile(FileName(filename), runparams);
} else if (backend_format == "lyx")
writeFile(FileName(filename));
}
+void Buffer::Impl::updateStatistics(DocIterator & from, DocIterator & to, bool skipNoOutput)
+{
+ bool inword = false;
+ word_count_ = 0;
+ char_count_ = 0;
+ blank_count_ = 0;
+
+ for (DocIterator dit = from ; dit != to && !dit.atEnd(); ) {
+ if (!dit.inTexted()) {
+ dit.forwardPos();
+ continue;
+ }
+
+ Paragraph const & par = dit.paragraph();
+ pos_type const pos = dit.pos();
+
+ // Copied and adapted from isWordSeparator() in Paragraph
+ if (pos == dit.lastpos()) {
+ inword = false;
+ } else {
+ Inset const * ins = par.getInset(pos);
+ if (ins && skipNoOutput && !ins->producesOutput()) {
+ // skip this inset
+ ++dit.top().pos();
+ // stop if end of range was skipped
+ if (!to.atEnd() && dit >= to)
+ break;
+ continue;
+ } else if (!par.isDeleted(pos)) {
+ if (par.isWordSeparator(pos))
+ inword = false;
+ else if (!inword) {
+ ++word_count_;
+ inword = true;
+ }
+ if (ins && ins->isLetter())
+ ++char_count_;
+ else if (ins && ins->isSpace())
+ ++blank_count_;
+ else {
+ char_type const c = par.getChar(pos);
+ if (isPrintableNonspace(c))
+ ++char_count_;
+ else if (isSpace(c))
+ ++blank_count_;
+ }
+ }
+ }
+ dit.forwardPos();
+ }
+}
+
+
+void Buffer::updateStatistics(DocIterator & from, DocIterator & to, bool skipNoOutput) const
+{
+ d->updateStatistics(from, to, skipNoOutput);
+}
+
+
+int Buffer::wordCount() const
+{
+ return d->wordCount();
+}
+
+
+int Buffer::charCount(bool with_blanks) const
+{
+ return d->charCount(with_blanks);
+}
+
+
Buffer::ReadStatus Buffer::reload()
{
setBusy(true);
d->filename.refresh();
docstring const disp_fn = makeDisplayPath(d->filename.absFileName());
+ // clear parent. this will get reset if need be.
+ d->setParent(0);
ReadStatus const status = loadLyXFile();
if (status == ReadSuccess) {
updateBuffer();