Hi!
Here is the polished version of the snippet conversion patch. Changes to last version:
* no directories are created by accident
* creates bitmaps for more than one graphic format (currently PNG+EPS)
* create DocBook hooks for PNG, EPS, PDF and BMP graphics like in InsetGraphics
* refactored insetGraphics::toDocbookLength() and writeImageObject() to
output_docbook.[hC]
* create additional anchors for math equation labels (this is not directly related to
math bitmaps but I couldn't resist. Prevents "Undefined IDREF" errors in exported
DocBook documents)
The complete Changelog entries are at the beginning of the patch.
Ciao /Andreas
PS: Lars has been quiet about this patch, no? :-)
The Changelog for src/graphics:
2005-02-17 Andreas Vox <[EMAIL PROTECTED]> * Makefile.am: new files SnippetConverion.[hC] * SnippetConversion.[hC]: new files containing refactored code from PreviewLoader * PreviewLoader.[hC] (setConverter): renamed to defaultConverter and moved (dumpPreamble,dumpData,setAscentFraction): also moved (InProgress): replaced by SnippetConversion The Changelog for src/insets: 2005-02-17 Andreas Vox <[EMAIL PROTECTED]> * insetgraphics.C (toDocbookLength, writeImageObject): moved to output_docbook.[hC] The Changelog for src/mathed: 2005-02-17 Andreas Vox <[EMAIL PROTECTED]> * math_hullinset.C (docbook): removed workaround for db2latex, this has to be fixed in db2latex * math_hullinset.C (docbook): changed the filenames of bitmaps from "eqn/xyz" to buffer.filename() + "_math/xyz" * math_hullinset.C (docbook): add the mathbitmaps to exportData * math_hullinset.C (registerExternalFile,registerExternalDirectory) new helper functions * math_hullinset.C (docbook): generate anchors for additional labels The Changelog for src/: 2005-02-17 Andreas Vox <[EMAIL PROTECTED]> * exporter.[hC] (ExportedFile::isDirectory): new bool member * exporter.[hC] (ExportData::addExternalDirectory): new function * exporter.[hC] (ExportData::bitmaps_): a map which gives a pointer to a SnippetConversion for each graphic format * exporter.C (Exporter::Export): handle exported directories * buffer.C (makeDocBookFile, createBitmaps): create a SnippetConversion object for PNG / EPS each and associate it with exportData * output_docbook.[hC] (toDocbookLength, docbookImageObject) moved to this place from insetgraphics.C PATCH PROPER: Index: src/buffer.C =================================================================== RCS file: /cvs/lyx/lyx-devel/src/buffer.C,v retrieving revision 1.612 diff -u -p -r1.612 buffer.C --- src/buffer.C 2005/02/08 13:17:57 1.612 +++ src/buffer.C 2005/02/26 00:30:17 @@ -62,6 +62,7 @@ #include "frontends/Alert.h" #include "graphics/Previews.h" +#include "graphics/SnippetConversion.h" #include "support/filetools.h" #include "support/fs_extras.h" @@ -113,6 +114,8 @@ using lyx::support::subst; using lyx::support::tempName; using lyx::support::trim; +using lyx::graphics::SnippetConversion; + namespace os = lyx::support::os; namespace fs = boost::filesystem; @@ -1021,6 +1024,56 @@ void Buffer::makeLinuxDocFile(string con lyxerr << "File '" << fname << "' was not closed properly." << endl; } +namespace { +void createBitmaps(Buffer const & buffer, OutputParams const & runparams) +{ + string const from = "lyxpreview"; + string const to_1 = "png"; + string const to_2 = "eps"; + string const fore = "000000"; + string const back = "FFFFFF"; + double const scale = 100; + + Converter const * converter_1 = converters.getConverter(from, to_1); + Converter const * converter_2 = converters.getConverter(from, to_2); + + if (!converter_1 && !converter_2) { + lyxerr << "couldn't find converter from " << from + << " to " << to_1 << " or " << to_2 << endl; + return; + } + + string const & filename_base = buffer.temppath() + "/eqn"; + + SnippetConversion::SnippetList snippets; + + InsetBase & inset = buffer.inset(); + InsetIterator it = inset_iterator_begin(inset); + InsetIterator const end = inset_iterator_end(inset); + + for (; it != end; ++it) + if (it->lyxCode() == InsetBase::MATH_CODE) + { + ostringstream cs; + it->latex(buffer, cs, runparams); + snippets.push_back(cs.str()); + } + + SnippetConversion * snipp; + + if (converter_1) { + snipp = new SnippetConversion(filename_base, converter_1, snippets); + snipp->startAndWait(buffer, fore, back, scale); + runparams.exportdata->addBitmaps(to_1, snipp); + } + + if (converter_2) { + snipp = new SnippetConversion(filename_base, converter_2, snippets); + snipp->startAndWait(buffer, fore, back, scale); + runparams.exportdata->addBitmaps(to_2, snipp); + } +} +} // namespace void Buffer::makeDocBookFile(string const & fname, OutputParams const & runparams, @@ -1034,6 +1087,8 @@ void Buffer::makeDocBookFile(string cons validate(features); texrow().reset(); + + createBitmaps(*this, runparams); LyXTextClass const & tclass = params().getLyXTextClass(); string const & top_element = tclass.latexname(); Index: src/exporter.C =================================================================== RCS file: /cvs/lyx/lyx-devel/src/exporter.C,v retrieving revision 1.58 diff -u -p -r1.58 exporter.C --- src/exporter.C 2005/01/31 10:42:18 1.58 +++ src/exporter.C 2005/02/26 00:30:18 @@ -30,7 +30,10 @@ #include "outputparams.h" #include "frontends/Alert.h" +#include "graphics/SnippetConversion.h" + #include "support/filetools.h" +#include "support/lstrings.h" #include "support/lyxlib.h" #include "support/package.h" @@ -44,8 +47,11 @@ using lyx::support::MakeAbsPath; using lyx::support::MakeDisplayPath; using lyx::support::OnlyFilename; using lyx::support::OnlyPath; +using lyx::support::IsDirWriteable; +using lyx::support::createDirectory; using lyx::support::package; using lyx::support::prefixIs; +using lyx::support::subst; using std::find; using std::string; @@ -70,7 +76,7 @@ int checkOverwrite(string const & filena { if (fs::exists(filename)) { string text = bformat(_("The file %1$s already exists.\n\n" - "Do you want to over-write that file?"), + "Do you want to over-write that file?"), MakeDisplayPath(filename)); return Alert::prompt(_("Over-write file?"), text, 0, 2, @@ -136,7 +142,7 @@ CopyStatus copyFile(string const & forma bool Exporter::Export(Buffer * buffer, string const & format, - bool put_in_tempdir, string & result_file) + bool put_in_tempdir, string & result_file) { string backend_format; OutputParams runparams; @@ -185,9 +191,9 @@ bool Exporter::Export(Buffer * buffer, s else if (backend_format == format) { runparams.nice = true; buffer->makeLaTeXFile(filename, string(), runparams); - } else if (contains(buffer->filePath(), ' ')) { + } else if (false && contains(buffer->filePath(), ' ')) { Alert::error(_("File name error"), - _("The directory path to the document cannot contain spaces.")); + _("The directory path to the document cannot contain spaces.")); return false; } else { runparams.nice = false; @@ -195,7 +201,7 @@ bool Exporter::Export(Buffer * buffer, s } if (!converters.convert(buffer, filename, filename, - backend_format, format, result_file)) + backend_format, format, result_file)) return false; if (!put_in_tempdir) { @@ -208,13 +214,32 @@ bool Exporter::Export(Buffer * buffer, s runparams.exportdata->externalFiles(format); string const dest = OnlyPath(result_file); CopyStatus status = SUCCESS; + // first pass: create directories if needed + for (vector<ExportedFile>::const_iterator it = files.begin(); + it != files.end() && status != CANCEL; ++it) { + if (it->isDirectory) { + string const path = MakeAbsPath(it->exportName, dest); + if (IsDirWriteable(path)) { + // ok, reuse that + } + else if (!createDirectory(path,0777)) { + Alert::error(_("Directory not writeable"), + bformat(_("Copying to directory %1$s failed."), + MakeDisplayPath(path))); + status = CANCEL; + } + } + } + // second pass: copy files 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 (!(it->isDirectory)) { + string const path = MakeAbsPath(it->exportName, dest); + string const fmt = + formats.getFormatFromFile(it->sourceName); + status = copyFile(fmt, it->sourceName, path, + it->exportName, status == FORCE); + } } if (status == CANCEL) { buffer->message(_("Document export cancelled.")); @@ -279,13 +304,14 @@ Exporter::GetExportableFormats(Buffer co ExportedFile::ExportedFile(string const & s, string const & e) : - sourceName(s), exportName(e) {} + sourceName(s), exportName(e), isDirectory(false) {} bool operator==(ExportedFile const & f1, ExportedFile const & f2) { return f1.sourceName == f2.sourceName && - f1.exportName == f2.exportName; + f1.exportName == f2.exportName && + f1.isDirectory == f2.isDirectory; } @@ -304,6 +330,18 @@ void ExportData::addExternalFile(string files.push_back(file); } +void ExportData::addExternalDirectory(string const & format, + string const & exportName) +{ + // Make sure that we have every file only once, otherwise copyFile() + // would ask several times if it should overwrite a file. + vector<ExportedFile> & files = externalfiles[format]; + ExportedFile dir("", exportName); + dir.isDirectory = true; + if (find(files.begin(), files.end(), dir) == files.end()) + files.push_back(dir); +} + void ExportData::addExternalFile(string const & format, string const & sourceName) @@ -319,4 +357,18 @@ ExportData::externalFiles(string const & if (cit != externalfiles.end()) return cit->second; return vector<ExportedFile>(); +} + + +void ExportData::addBitmaps(string const & gr_format, lyx::graphics::SnippetConversion * bitmaps) +{ + bitmaps_[gr_format] = bitmaps; +} + +lyx::graphics::SnippetConversion * ExportData::bitmaps(string const & gr_format) const +{ + SnippetConversionMap::const_iterator cit = bitmaps_.find(gr_format); + if (cit != bitmaps_.end()) + return cit->second; + return 0; } Index: src/exporter.h =================================================================== RCS file: /cvs/lyx/lyx-devel/src/exporter.h,v retrieving revision 1.22 diff -u -p -r1.22 exporter.h --- src/exporter.h 2005/01/19 15:03:29 1.22 +++ src/exporter.h 2005/02/26 00:30:18 @@ -17,10 +17,12 @@ #include <string> #include <vector> +#include "graphics/SnippetConversion.h" class Buffer; class Format; + class Exporter { public: /// @@ -53,6 +55,7 @@ public: /// final name that the exported file should get (absolute name or /// relative to the directory of the master document) std::string exportName; + bool isDirectory; }; @@ -82,15 +85,31 @@ public: */ void addExternalFile(std::string const & format, std::string const & sourceName); + /** add a referenced directory for one format. + * \param format format that references the given directory + * \param exportName resulting directory name. Can be either absolute + * or relative to the exported document. + */ + void addExternalDirectory(std::string const & format, + std::string const & exportName); /// get referenced files for \p format std::vector<ExportedFile> const externalFiles(std::string const & format) const; + /// add a list of bitmap file with format gr_format + void addBitmaps(std::string const & gr_format, lyx::graphics::SnippetConversion * bitmaps); + /// get the bitmaps for this graphics format + lyx::graphics::SnippetConversion * bitmaps(std::string const & gr_format) const; private: typedef std::map<std::string, std::vector<ExportedFile> > FileMap; /** Files that are referenced by the export result in the * different formats. */ FileMap externalfiles; + + typedef std::map<std::string, lyx::graphics::SnippetConversion * > + SnippetConversionMap; + /** Snippets which are used to generate bitmaps for equations etc. */ + SnippetConversionMap bitmaps_; }; #endif Index: src/output_docbook.C =================================================================== RCS file: /cvs/lyx/lyx-devel/src/output_docbook.C,v retrieving revision 1.28 diff -u -p -r1.28 output_docbook.C --- src/output_docbook.C 2005/02/25 11:55:32 1.28 +++ src/output_docbook.C 2005/02/26 00:30:19 @@ -18,6 +18,8 @@ #include "bufferparams.h" #include "counters.h" #include "debug.h" +#include "lyxtext.h" +#include "outputparams.h" #include "paragraph.h" #include "paragraph_funcs.h" #include "ParagraphList_fwd.h" @@ -31,6 +33,8 @@ #include "support/convert.h" #include "support/types.h" +#include <sstream> + #ifdef HAVE_LOCALE #endif @@ -308,4 +313,93 @@ void docbookParagraphs(ParagraphList con break; } } +} + + +int docbookImageObject(char * format, string const filename, string const attributes, + ostream & os, OutputParams const & runparams, bool graphictag = false) +{ + if (runparams.flavor != OutputParams::XML) { + os << "<![ %output.print." << format << "; [" << std::endl; + } + + if (graphictag) + os << "<graphic"; + else + os <<"<imageobject><imagedata"; + + os << " fileref=\"" << filename << "." << format << "\" " << attributes ; + if (runparams.flavor == OutputParams::XML) { + os << " role=\"" << format << "\"/>" ; + } + else { + os << " format=\"" << format << "\">" ; + } + + if (! graphictag) + os << "</imageobject>"; + + if (runparams.flavor != OutputParams::XML) { + os << std::endl << "]]>" ; + } + return runparams.flavor == OutputParams::XML ? 0 : 2; +} + + + +string const toDocbookLength(LyXLength const & len) +{ + std::ostringstream result; + switch (len.unit()) { + case LyXLength::SP: // Scaled point (65536sp = 1pt) TeX's smallest unit. + result << len.value() * 65536.0 * 72 / 72.27 << "pt"; + break; + case LyXLength::PT: // Point = 1/72.27in = 0.351mm + result << len.value() * 72 / 72.27 << "pt"; + break; + case LyXLength::BP: // Big point (72bp = 1in), also PostScript point + result << len.value() << "pt"; + break; + case LyXLength::DD: // Didot point = 1/72 of a French inch, = 0.376mm + result << len.value() * 0.376 << "mm"; + break; + case LyXLength::MM: // Millimeter = 2.845pt + result << len.value() << "mm"; + break; + case LyXLength::PC: // Pica = 12pt = 4.218mm + result << len.value() << "pc"; + break; + case LyXLength::CC: // Cicero = 12dd = 4.531mm + result << len.value() * 4.531 << "mm"; + break; + case LyXLength::CM: // Centimeter = 10mm = 2.371pc + result << len.value() << "cm"; + break; + case LyXLength::IN: // Inch = 25.4mm = 72.27pt = 6.022pc + result << len.value() << "in"; + break; + case LyXLength::EX: // Height of a small "x" for the current font. + // Obviously we have to compromise here. Any better ratio than 1.5 ? + result << len.value() / 1.5 << "em"; + break; + case LyXLength::EM: // Width of capital "M" in current font. + result << len.value() << "em"; + break; + case LyXLength::MU: // Math unit (18mu = 1em) for positioning in math mode + result << len.value() * 18 << "em"; + break; + case LyXLength::PTW: // Percent of TextWidth + case LyXLength::PCW: // Percent of ColumnWidth + case LyXLength::PPW: // Percent of PageWidth + case LyXLength::PLW: // Percent of LineWidth + case LyXLength::PTH: // Percent of TextHeight + case LyXLength::PPH: // Percent of Paper + // Sigh, this will go wrong. + result << len.value() << "%"; + break; + default: + result << len.asString(); + break; + } + return result.str(); } Index: src/output_docbook.h =================================================================== RCS file: /cvs/lyx/lyx-devel/src/output_docbook.h,v retrieving revision 1.4 diff -u -p -r1.4 output_docbook.h --- src/output_docbook.h 2004/10/24 00:02:38 1.4 +++ src/output_docbook.h 2005/02/26 00:30:19 @@ -13,6 +13,8 @@ #ifndef OUTPUT_DOCBOOK_H #define OUTPUT_DOCBOOK_H +#include "lyxlength.h" + #include <iosfwd> class Buffer; @@ -24,4 +26,17 @@ void docbookParagraphs(ParagraphList con Buffer const & buf, std::ostream & os, OutputParams const & runparams); +/** Write an <IMAGEOBJECT> or <GRAPHIC> element to os. Uses parameter entities to + * control the format. + * If graphictag is true, an <GRAPHIC> element is written. + */ +int docbookImageObject(char * format, + std::string const filename, + std::string const attributes, + std::ostream & os, + OutputParams const & runparams, + bool graphictag = false); +/// Create length values for docbook export. +std::string const toDocbookLength(LyXLength const & len); + #endif Index: src/graphics/Makefile.am =================================================================== RCS file: /cvs/lyx/lyx-devel/src/graphics/Makefile.am,v retrieving revision 1.32 diff -u -p -r1.32 Makefile.am --- src/graphics/Makefile.am 2004/12/04 14:50:24 1.32 +++ src/graphics/Makefile.am 2005/02/26 00:30:24 @@ -5,6 +5,8 @@ noinst_LTLIBRARIES = libgraphics.la AM_CPPFLAGS = $(PCH_FLAGS) -I$(srcdir)/.. $(BOOST_INCLUDES) libgraphics_la_SOURCES = \ + SnippetConversion.h \ + SnippetConversion.C \ GraphicsCache.h \ GraphicsCache.C \ GraphicsCacheItem.h \ Index: src/graphics/PreviewLoader.C =================================================================== RCS file: /cvs/lyx/lyx-devel/src/graphics/PreviewLoader.C,v retrieving revision 1.86 diff -u -p -r1.86 PreviewLoader.C --- src/graphics/PreviewLoader.C 2005/01/27 21:05:38 1.86 +++ src/graphics/PreviewLoader.C 2005/02/26 00:30:24 @@ -10,27 +10,22 @@ #include <config.h> +#include "GraphicsCache.h" +#include "SnippetConversion.h" #include "PreviewLoader.h" #include "PreviewImage.h" -#include "GraphicsCache.h" #include "buffer.h" #include "converter.h" #include "debug.h" #include "format.h" -#include "insetiterator.h" #include "LColor.h" #include "lyxrc.h" #include "outputparams.h" -#include "paragraph.h" #include "frontends/lyx_gui.h" // hexname -#include "insets/inset.h" - #include "support/filetools.h" -#include "support/forkedcall.h" -#include "support/forkedcontr.h" #include "support/lstrings.h" #include "support/lyxlib.h" #include "support/convert.h" @@ -61,59 +56,17 @@ using std::pair; using std::vector; using std::string; - namespace { -typedef pair<string, string> StrPair; +typedef lyx::graphics::SnippetConversion::SnippetList SnippetList; -// A list of alll snippets to be converted to previews -typedef list<string> PendingSnippets; -// Each item in the vector is a pair<snippet, image file name>. -typedef vector<StrPair> BitmapFile; - string const unique_filename(string const bufferpath); Converter const * setConverter(); -void setAscentFractions(vector<double> & ascent_fractions, - string const & metrics_file); - -class FindFirst : public std::unary_function<StrPair, bool> { -public: - FindFirst(string const & comp) : comp_(comp) {} - bool operator()(StrPair const & sp) const - { - return sp.first == comp_; - } -private: - string const comp_; -}; - - -/// Store info on a currently executing, forked process. -class InProgress { -public: - /// - InProgress() : pid(0) {} - /// - InProgress(string const & filename_base, - PendingSnippets const & pending, - string const & to_format); - /// Remove any files left lying around and kill the forked process. - void stop() const; - - /// - pid_t pid; - /// - string command; - /// - string metrics_file; - /// - BitmapFile snippets; -}; -typedef map<pid_t, InProgress> InProgressProcesses; +typedef map<pid_t, lyx::graphics::SnippetConversion> InProgressProcesses; typedef InProgressProcesses::value_type InProgressProcess; @@ -127,7 +80,7 @@ class PreviewLoader::Impl : public boost public: /// Impl(PreviewLoader & p, Buffer const & b); - /// Stop any InProgress items still executing. + /// Stop any SnippetConversion items still executing. ~Impl(); /// PreviewImage const * preview(string const & latex_snippet) const; @@ -148,10 +101,6 @@ public: private: /// Called by the Forkedcall process that generated the bitmap files. void finishedGenerating(pid_t, int); - /// - void dumpPreamble(ostream &) const; - /// - void dumpData(ostream &, BitmapFile const &) const; /** cache_ allows easy retrieval of already-generated images * using the LaTeX snippet as the identifier. @@ -165,7 +114,7 @@ private: /** pending_ stores the LaTeX snippets in anticipation of them being * sent to the converter. */ - PendingSnippets pending_; + SnippetList pending_; /** in_progress_ stores all forked processes so that we can proceed * thereafter. @@ -253,66 +202,7 @@ Buffer const & PreviewLoader::buffer() c // The details of the Impl // ======================= -namespace { -class IncrementedFileName { -public: - IncrementedFileName(string const & to_format, - string const & filename_base) - : to_format_(to_format), base_(filename_base), counter_(1) - {} - - StrPair const operator()(string const & snippet) - { - ostringstream os; - os << base_ << counter_++ << '.' << to_format_; - string const file = os.str(); - - return make_pair(snippet, file); - } - -private: - string const & to_format_; - string const & base_; - int counter_; -}; - - -InProgress::InProgress(string const & filename_base, - PendingSnippets const & pending, - string const & to_format) - : pid(0), - metrics_file(filename_base + ".metrics"), - snippets(pending.size()) -{ - PendingSnippets::const_iterator pit = pending.begin(); - PendingSnippets::const_iterator pend = pending.end(); - BitmapFile::iterator sit = snippets.begin(); - - std::transform(pit, pend, sit, - IncrementedFileName(to_format, filename_base)); -} - - -void InProgress::stop() const -{ - if (pid) - support::ForkedcallsController::get().kill(pid, 0); - - if (!metrics_file.empty()) - support::unlink(metrics_file); - - BitmapFile::const_iterator vit = snippets.begin(); - BitmapFile::const_iterator vend = snippets.end(); - for (; vit != vend; ++vit) { - if (!vit->second.empty()) - support::unlink(vit->second); - } -} - -} // namespace anon - - namespace lyx { namespace graphics { @@ -326,7 +216,7 @@ PreviewLoader::Impl::Impl(PreviewLoader << font_scaling_factor_ << endl; if (!pconverter_) - pconverter_ = setConverter(); + pconverter_ = defaultConverter(); } @@ -351,15 +241,15 @@ PreviewLoader::Impl::preview(string cons namespace { +typedef SnippetConversion::SnippetList SnippetList; + + class FindSnippet : public std::unary_function<InProgressProcess, bool> { public: FindSnippet(string const & s) : snippet_(s) {} bool operator()(InProgressProcess const & process) const { - BitmapFile const & snippets = process.second.snippets; - BitmapFile::const_iterator beg = snippets.begin(); - BitmapFile::const_iterator end = snippets.end(); - return find_if(beg, end, FindFirst(snippet_)) != end; + return ! (process.second.findSnippet(snippet_).empty()); } private: @@ -375,8 +265,8 @@ PreviewLoader::Impl::status(string const if (cit != cache_.end()) return Ready; - PendingSnippets::const_iterator pit = pending_.begin(); - PendingSnippets::const_iterator pend = pending_.end(); + SnippetList::const_iterator pit = pending_.begin(); + SnippetList::const_iterator pend = pending_.end(); pit = find(pit, pend, latex_snippet); if (pit != pend) @@ -415,13 +305,7 @@ public: EraseSnippet(string const & s) : snippet_(s) {} void operator()(InProgressProcess & process) { - BitmapFile & snippets = process.second.snippets; - BitmapFile::iterator it = snippets.begin(); - BitmapFile::iterator end = snippets.end(); - - it = find_if(it, end, FindFirst(snippet_)); - if (it != end) - snippets.erase(it, it+1); + process.second.eraseSnippet(snippet_); } private: @@ -437,8 +321,8 @@ void PreviewLoader::Impl::remove(string if (cit != cache_.end()) cache_.erase(cit); - PendingSnippets::iterator pit = pending_.begin(); - PendingSnippets::iterator pend = pending_.end(); + SnippetList::iterator pit = pending_.begin(); + SnippetList::iterator pend = pending_.end(); pending_.erase(std::remove(pit, pend, latex_snippet), pend); @@ -449,7 +333,7 @@ void PreviewLoader::Impl::remove(string while (ipit != ipend) { InProgressProcesses::iterator curr = ipit++; - if (curr->second.snippets.empty()) + if (curr->second.empty()) in_progress_.erase(curr); } } @@ -471,58 +355,23 @@ void PreviewLoader::Impl::startLoading() string const filename_base(unique_filename(directory)); - // Create an InProgress instance to place in the map of all + // Create an SnippetConversion instance to place in the map of all // such processes if it starts correctly. - InProgress inprogress(filename_base, pending_, pconverter_->to); + SnippetConversion inprogress(filename_base, pconverter_, pending_); // clear pending_, so we're ready to start afresh. pending_.clear(); - // Output the LaTeX file. - string const latexfile = filename_base + ".tex"; - - ofstream of(latexfile.c_str()); - if (!of) { - lyxerr[Debug::GRAPHICS] << "PreviewLoader::startLoading()\n" - << "Unable to create LaTeX file\n" - << latexfile << endl; - return; - } - of << "\\batchmode\n"; - dumpPreamble(of); - of << "\n\\begin{document}\n"; - dumpData(of, inprogress.snippets); - of << "\n\\end{document}\n"; - of.close(); - - // The conversion command. - ostringstream cs; - cs << pconverter_->command << ' ' << pconverter_->to << ' ' - << latexfile << ' ' << int(font_scaling_factor_) << ' ' - << lyx_gui::hexname(LColor::preview) << ' ' - << lyx_gui::hexname(LColor::background); - - string const command = support::LibScriptSearch(cs.str()); - // Initiate the conversion from LaTeX to bitmap images files. - support::Forkedcall::SignalTypePtr - convert_ptr(new support::Forkedcall::SignalType); + support::Forkedcall::SignalTypePtr convert_ptr(new support::Forkedcall::SignalType); convert_ptr->connect(bind(&Impl::finishedGenerating, this, _1, _2)); - support::Forkedcall call; - int ret = call.startscript(command, convert_ptr); - - if (ret != 0) { - lyxerr[Debug::GRAPHICS] << "PreviewLoader::startLoading()\n" - << "Unable to start process\n" - << command << endl; - return; - } - // Store the generation process in a list of all such processes - inprogress.pid = call.pid(); - inprogress.command = command; - in_progress_[inprogress.pid] = inprogress; + inprogress.start(buffer_, + lyx_gui::hexname(LColor::preview), + lyx_gui::hexname(LColor::background), + font_scaling_factor_, convert_ptr); + in_progress_[inprogress.pid()] = inprogress; } @@ -536,7 +385,7 @@ void PreviewLoader::Impl::finishedGenera return; } - string const command = git->second.command; + string const command = git->second.command(); string const status = retval > 0 ? "failed" : "succeeded"; lyxerr[Debug::GRAPHICS] << "PreviewLoader::finishedInProgress(" << retval << "): processing " << status @@ -545,21 +394,19 @@ void PreviewLoader::Impl::finishedGenera return; // Read the metrics file, if it exists - vector<double> ascent_fractions(git->second.snippets.size()); - setAscentFractions(ascent_fractions, git->second.metrics_file); + git->second.setAscentFractions(); + + std::list<PreviewImagePtr> newimages; // Add these newly generated bitmap files to the cache and // start loading them into LyX. - BitmapFile::const_iterator it = git->second.snippets.begin(); - BitmapFile::const_iterator end = git->second.snippets.end(); + vector<SnippetConversion::Entry>::const_iterator it = git->second.begin(); + vector<SnippetConversion::Entry>::const_iterator end = git->second.end(); - std::list<PreviewImagePtr> newimages; - - int metrics_counter = 0; - for (; it != end; ++it, ++metrics_counter) { - string const & snip = it->first; - string const & file = it->second; - double af = ascent_fractions[metrics_counter]; + for (; it != end; ++it) { + string const & snip = it->latex; + string const & file = it->filename; + double af = it->ascentfraction; PreviewImagePtr ptr(new PreviewImage(parent_, snip, file, af)); cache_[snip] = ptr; @@ -580,84 +427,8 @@ void PreviewLoader::Impl::finishedGenera } } - -void PreviewLoader::Impl::dumpPreamble(ostream & os) const -{ - // Why on earth is Buffer::makeLaTeXFile a non-const method? - Buffer & tmp = const_cast<Buffer &>(buffer_); - // Dump the preamble only. - OutputParams runparams; - runparams.flavor = OutputParams::LATEX; - runparams.nice = true; - runparams.moving_arg = true; - runparams.free_spacing = true; - tmp.makeLaTeXFile(os, buffer_.filePath(), runparams, true, false); - - // FIXME! This is a HACK! The proper fix is to control the 'true' - // passed to WriteStream below: - // int InsetFormula::latex(Buffer const &, ostream & os, - // OutputParams const & runparams) const - // { - // WriteStream wi(os, runparams.moving_arg, true); - // par_->write(wi); - // return wi.line(); - // } - os << "\n" - << "\\def\\lyxlock{}\n" - << "\n"; - - // Loop over the insets in the buffer and dump all the math-macros. - InsetBase & inset = buffer_.inset(); - InsetIterator it = inset_iterator_begin(inset); - InsetIterator const end = inset_iterator_end(inset); - - for (; it != end; ++it) - if (it->lyxCode() == InsetBase::MATHMACRO_CODE) - it->latex(buffer_, os, runparams); - - // All equation lables appear as "(#)" + preview.sty's rendering of - // the label name - if (lyxrc.preview_hashed_labels) - os << "\\renewcommand{\\theequation}{\\#}\n"; - - // Use the preview style file to ensure that each snippet appears on a - // fresh page. - os << "\n" - << "\\usepackage[active,delayed,dvips,showlabels,lyx]{preview}\n" - << "\n"; -} - - -void PreviewLoader::Impl::dumpData(ostream & os, - BitmapFile const & vec) const -{ - if (vec.empty()) - return; - - BitmapFile::const_iterator it = vec.begin(); - BitmapFile::const_iterator end = vec.end(); - - for (; it != end; ++it) { - os << "\\begin{preview}\n" - << it->first - << "\n\\end{preview}\n\n"; - } -} - -} // namespace graphics -} // namespace lyx - -namespace { - -string const unique_filename(string const bufferpath) -{ - static int theCounter = 0; - string const filename = convert<string>(theCounter++) + "lyxpreview"; - return support::AddName(bufferpath, filename); -} - -Converter const * setConverter() +Converter const * defaultConverter() { string const from = "lyxpreview"; @@ -689,57 +460,20 @@ Converter const * setConverter() return 0; } - -void setAscentFractions(vector<double> & ascent_fractions, - string const & metrics_file) -{ - // If all else fails, then the images will have equal ascents and - // descents. - vector<double>::iterator it = ascent_fractions.begin(); - vector<double>::iterator end = ascent_fractions.end(); - fill(it, end, 0.5); - - ifstream in(metrics_file.c_str()); - if (!in.good()) { - lyxerr[Debug::GRAPHICS] - << "setAscentFractions(" << metrics_file << ")\n" - << "Unable to open file!" << endl; - return; - } - - bool error = false; - - int snippet_counter = 1; - while (!in.eof() && it != end) { - string snippet; - int id; - double ascent_fraction; - in >> snippet >> id >> ascent_fraction; - - if (!in.good()) - // eof after all - break; +} // namespace graphics +} // namespace lyx - error = snippet != "Snippet"; - if (error) - break; +namespace { - error = id != snippet_counter; - if (error) - break; +string const unique_filename(string const bufferpath) +{ + static int theCounter = 0; + string const filename = convert<string>(theCounter++) + "lyxpreview"; + return support::AddName(bufferpath, filename); +} - *it = ascent_fraction; - ++snippet_counter; - ++it; - } - if (error) { - lyxerr[Debug::GRAPHICS] - << "setAscentFractions(" << metrics_file << ")\n" - << "Error reading file!\n" << endl; - } -} } // namespace anon Index: src/graphics/PreviewLoader.h =================================================================== RCS file: /cvs/lyx/lyx-devel/src/graphics/PreviewLoader.h,v retrieving revision 1.16 diff -u -p -r1.16 PreviewLoader.h --- src/graphics/PreviewLoader.h 2004/09/26 14:19:47 1.16 +++ src/graphics/PreviewLoader.h 2005/02/26 00:30:24 @@ -23,11 +23,14 @@ #include <boost/signal.hpp> class Buffer; +class Converter; namespace lyx { namespace graphics { class PreviewImage; + +Converter const * defaultConverter(); class PreviewLoader : boost::noncopyable { public: Index: src/insets/insetgraphics.C =================================================================== RCS file: /cvs/lyx/lyx-devel/src/insets/insetgraphics.C,v retrieving revision 1.274 diff -u -p -r1.274 insetgraphics.C --- src/insets/insetgraphics.C 2005/02/22 16:57:36 1.274 +++ src/insets/insetgraphics.C 2005/02/26 00:30:26 @@ -68,6 +68,7 @@ TODO #include "lyxlex.h" #include "metricsinfo.h" #include "mover.h" +#include "output_docbook.h" #include "outputparams.h" #include "sgml.h" @@ -338,63 +339,6 @@ string const InsetGraphics::createLatexO } -string const InsetGraphics::toDocbookLength(LyXLength const & len) const -{ - ostringstream result; - switch (len.unit()) { - case LyXLength::SP: // Scaled point (65536sp = 1pt) TeX's smallest unit. - result << len.value() * 65536.0 * 72 / 72.27 << "pt"; - break; - case LyXLength::PT: // Point = 1/72.27in = 0.351mm - result << len.value() * 72 / 72.27 << "pt"; - break; - case LyXLength::BP: // Big point (72bp = 1in), also PostScript point - result << len.value() << "pt"; - break; - case LyXLength::DD: // Didot point = 1/72 of a French inch, = 0.376mm - result << len.value() * 0.376 << "mm"; - break; - case LyXLength::MM: // Millimeter = 2.845pt - result << len.value() << "mm"; - break; - case LyXLength::PC: // Pica = 12pt = 4.218mm - result << len.value() << "pc"; - break; - case LyXLength::CC: // Cicero = 12dd = 4.531mm - result << len.value() * 4.531 << "mm"; - break; - case LyXLength::CM: // Centimeter = 10mm = 2.371pc - result << len.value() << "cm"; - break; - case LyXLength::IN: // Inch = 25.4mm = 72.27pt = 6.022pc - result << len.value() << "in"; - break; - case LyXLength::EX: // Height of a small "x" for the current font. - // Obviously we have to compromise here. Any better ratio than 1.5 ? - result << len.value() / 1.5 << "em"; - break; - case LyXLength::EM: // Width of capital "M" in current font. - result << len.value() << "em"; - break; - case LyXLength::MU: // Math unit (18mu = 1em) for positioning in math mode - result << len.value() * 18 << "em"; - break; - case LyXLength::PTW: // Percent of TextWidth - case LyXLength::PCW: // Percent of ColumnWidth - case LyXLength::PPW: // Percent of PageWidth - case LyXLength::PLW: // Percent of LineWidth - case LyXLength::PTH: // Percent of TextHeight - case LyXLength::PPH: // Percent of Paper - // Sigh, this will go wrong. - result << len.value() << "%"; - break; - default: - result << len.asString(); - break; - } - return result.str(); -} - string const InsetGraphics::createDocBookAttributes() const { // Calculate the options part of the command, we must do it to a string @@ -783,32 +727,7 @@ int InsetGraphics::linuxdoc(Buffer const } -namespace { -int writeImageObject(char * format, ostream& os, OutputParams const & runparams, - string const graphic_label, string const attributes) -{ - if (runparams.flavor != OutputParams::XML) { - os << "<![ %output.print." << format << "; [" << std::endl; - } - os <<"<imageobject><imagedata fileref=\"&" - << graphic_label << ";." << format << "\" " << attributes ; - if (runparams.flavor == OutputParams::XML) { - os << " role=\"" << format << "\"/>" ; - } - else { - os << " format=\"" << format << "\">" ; - } - os << "</imageobject>"; - if (runparams.flavor != OutputParams::XML) { - os << std::endl << "]]>" ; - } - return runparams.flavor == OutputParams::XML ? 0 : 2; -} -// end anonymous namespace -} - - // For explanation on inserting graphics into DocBook checkout: // http://en.tldp.org/LDP/LDP-Author-Guide/html/inserting-pictures.html // See also the docbook guide at http://www.docbook.org/ @@ -825,14 +744,16 @@ int InsetGraphics::docbook(Buffer const runparams.exportdata->addExternalFile("docbook", params().filename.absFilename()); } + os << "<inlinemediaobject>"; int r = 0; string attributes = createDocBookAttributes(); - r += writeImageObject("png", os, runparams, graphic_label, attributes); - r += writeImageObject("pdf", os, runparams, graphic_label, attributes); - r += writeImageObject("eps", os, runparams, graphic_label, attributes); - r += writeImageObject("bmp", os, runparams, graphic_label, attributes); + string filename_entitity = "&" + graphic_label + ";" ; + r += docbookImageObject("pdf", filename_entitity, attributes, os, runparams); + r += docbookImageObject("eps", filename_entitity, attributes, os, runparams); + r += docbookImageObject("png", filename_entitity, attributes, os, runparams); + r += docbookImageObject("bmp", filename_entitity, attributes, os, runparams); os << "</inlinemediaobject>"; return r; Index: src/insets/insetgraphics.h =================================================================== RCS file: /cvs/lyx/lyx-devel/src/insets/insetgraphics.h,v retrieving revision 1.103 diff -u -p -r1.103 insetgraphics.h --- src/insets/insetgraphics.h 2004/11/25 19:13:04 1.103 +++ src/insets/insetgraphics.h 2005/02/26 00:30:26 @@ -92,8 +92,6 @@ private: std::string const statusMessage() const; /// Create the options for the latex command. std::string const createLatexOptions() const; - /// Create length values for docbook export. - std::string const toDocbookLength(LyXLength const & len) const; /// Create the atributes for docbook export. std::string const createDocBookAttributes() const; /// Convert the file if needed, and return the location of the file. Index: src/mathed/math_hullinset.C =================================================================== RCS file: /cvs/lyx/lyx-devel/src/mathed/math_hullinset.C,v retrieving revision 1.161 diff -u -p -r1.161 math_hullinset.C --- src/mathed/math_hullinset.C 2005/02/14 14:25:17 1.161 +++ src/mathed/math_hullinset.C 2005/02/26 00:30:29 @@ -18,6 +18,7 @@ #include "math_streamstr.h" #include "math_support.h" +#include "buffer.h" #include "BufferView.h" #include "CutAndPaste.h" #include "FuncStatus.h" @@ -26,10 +27,12 @@ #include "cursor.h" #include "debug.h" #include "dispatchresult.h" +#include "exporter.h" #include "funcrequest.h" #include "gettext.h" #include "lyx_main.h" #include "lyxrc.h" +#include "output_docbook.h" #include "outputparams.h" #include "sgml.h" #include "textpainter.h" @@ -41,8 +44,10 @@ #include "graphics/PreviewImage.h" #include "graphics/PreviewLoader.h" +#include "graphics/SnippetConversion.h" #include "support/lstrings.h" +#include "support/filetools.h" #include <boost/bind.hpp> @@ -51,6 +56,9 @@ using lyx::cap::grabAndEraseSelection; using lyx::support::bformat; using lyx::support::subst; +using lyx::support::GetExtension; +using lyx::support::ChangeExtension; +using lyx::support::OnlyFilename; using std::endl; using std::max; @@ -1351,7 +1373,37 @@ int MathHullInset::linuxdoc(Buffer const return docbook(buf, os, runparams); } +namespace { +void registerExternalFile(string const & gr_format, OutputParams const & runparams, + string const & latex_snippet, string const & external_name) +{ + lyx::graphics::SnippetConversion const * bitmaps = runparams.exportdata->bitmaps(gr_format); + if (!bitmaps) { + return; + } + string const bitmapfile = bitmaps->findSnippet(latex_snippet); + string const ext = "." + GetExtension(bitmapfile); + if (runparams.flavor == OutputParams::XML) { + runparams.exportdata->addExternalFile("docbook-xml", + bitmapfile, external_name + ext); + } else { + runparams.exportdata->addExternalFile("docbook", + bitmapfile, external_name + ext); + } +} +void registerExternalDirectory(OutputParams const & runparams, string const & dirname) +{ + if (runparams.flavor == OutputParams::XML) { + runparams.exportdata->addExternalDirectory("docbook-xml", dirname); + } else { + runparams.exportdata->addExternalDirectory("docbook", dirname); + } +} + +} // namespace + + int MathHullInset::docbook(Buffer const & buf, ostream & os, OutputParams const & runparams) const { @@ -1366,38 +1418,51 @@ int MathHullInset::docbook(Buffer const string bname = name; if (!label(0).empty()) bname += " id=\"" + sgml::cleanID(buf, runparams, label(0)) + "\""; + // Let's do something about the other labels ... + for (row_type i=1; i < nrows(); i++) { + if (!label(i).empty()) { + string aname = "anchor id=\"" + sgml::cleanID(buf, runparams, label(i)) + "\""; + ms << MTag(aname.c_str()); + if (runparams.flavor == OutputParams::XML) { + ms << ETag("anchor"); + } + } + } ms << MTag(bname.c_str()); ostringstream ls; + res = latex(buf, ls, runparams); + + ms << MTag("alt role=\"tex\" "); + ms << subst(subst(ls.str(), "&", "&"), "<", "<"); + ms << ETag("alt"); if (runparams.flavor == OutputParams::XML) { - ms << MTag("alt role=\"tex\" "); - // Workaround for db2latex: db2latex always includes equations with - // \ensuremath{} or \begin{display}\end{display} - // so we strip LyX' math environment - WriteStream wi(ls, false, false); - MathGridInset::write(wi); - ms << subst(subst(ls.str(), "&", "&"), "<", "<"); - ms << ETag("alt"); ms << MTag("math"); MathGridInset::mathmlize(ms); ms << ETag("math"); - } else { - ms << MTag("alt role=\"tex\""); - res = latex(buf, ls, runparams); - ms << subst(subst(ls.str(), "&", "&"), "<", "<"); - ms << ETag("alt"); } - ms << "<graphic fileref=\"eqn/"; + string const dirname = ChangeExtension(OnlyFilename(buf.fileName()), string()) + "_math"; + ostringstream efs; + efs << dirname << "/"; if ( !label(0).empty()) - ms << sgml::cleanID(buf, runparams, label(0)); + efs << sgml::cleanID(buf, runparams, label(0)); else { - ms << sgml::uniqueID("anon"); + efs << sgml::uniqueID("anon"); } - if (runparams.flavor == OutputParams::XML) - ms << "\"/>"; - else - ms << "\">"; + + registerExternalDirectory(runparams, dirname); + registerExternalFile("pdf", runparams, ls.str(), efs.str()); + registerExternalFile("eps", runparams, ls.str(), efs.str()); + registerExternalFile("png", runparams, ls.str(), efs.str()); + registerExternalFile("bmp", runparams, ls.str(), efs.str()); + + string const attributes; + // this would be the place to include the alignment information. AV + docbookImageObject("pdf", efs.str(), attributes, os, runparams, true); + docbookImageObject("eps", efs.str(), attributes, os, runparams, true); + docbookImageObject("png", efs.str(), attributes, os, runparams, true); + docbookImageObject("bmp", efs.str(), attributes, os, runparams, true); ms << ETag(name.c_str()); return ms.line() + res;
// -*- C++ -*- /** * \file SnippetConversion.C * This file is part of LyX, the document processor. * Licence details can be found in the file COPYING. * * \author Andreas Vox * * Full author contact details are available in file CREDITS. * * lyx::graphics::SnippetConversion converts latex snippets to bitmap * files. * snippets are collected one by one. Then, on start converting, these * are dumped to file and processed, converting each snippet to a * separate bitmap image file. */ #include "SnippetConversion.h" #include "buffer.h" #include "debug.h" #include "insetiterator.h" #include "lyxrc.h" #include "paragraph.h" #include "insets/inset.h" #include "support/filetools.h" #include "support/forkedcontr.h" #include "support/lyxlib.h" #include <boost/utility.hpp> #include <boost/scoped_ptr.hpp> #include <boost/signal.hpp> namespace support = lyx::support; using std::vector; using std::string; using std::ostream; using std::ostringstream; using std::ofstream; using std::ifstream; using std::endl; // some helpers: namespace { typedef vector<lyx::graphics::SnippetConversion::Entry> BitmapFileList; typedef lyx::graphics::SnippetConversion::SnippetList SnippetList; typedef lyx::graphics::SnippetConversion::Entry Entry; class IncrementedFileName { public: IncrementedFileName(string const & to_format, string const & filename_base) : to_format_(to_format), base_(filename_base), counter_(1) {} Entry const operator()(string const & snippet) { ostringstream os; os << base_ << counter_++ << '.' << to_format_; Entry result; result.filename = os.str(); result.latex = snippet; return result; } private: string const & to_format_; string const & base_; int counter_; }; class FindFirst : public std::unary_function<Entry, bool> { public: FindFirst(string const & comp) : comp_(comp) {} bool operator()(Entry const & sp) const { return sp.latex == comp_; } private: string const comp_; }; } // namespace anon namespace lyx { namespace graphics { SnippetConversion::SnippetConversion(string const & filename_base, Converter const * converter, SnippetList const & pending) : pid_(0), filename_base(filename_base), metrics_file(filename_base + ".metrics"), snippets(pending.size()), converter_(converter) { SnippetList::const_iterator pit = pending.begin(); SnippetList::const_iterator pend = pending.end(); BitmapFileList::iterator sit = snippets.begin(); std::transform(pit, pend, sit, IncrementedFileName(converter->to, filename_base)); } bool SnippetConversion::empty() const { return snippets.empty(); } int SnippetConversion::size() const { return snippets.size(); } BitmapFileList::const_iterator SnippetConversion::begin() const { return snippets.begin(); } BitmapFileList::const_iterator SnippetConversion::end() const { return snippets.end(); } string const SnippetConversion::findSnippet(string const & snippet_) const { BitmapFileList::const_iterator beg = snippets.begin(); BitmapFileList::const_iterator end = snippets.end(); BitmapFileList::const_iterator res = find_if(beg, end, FindFirst(snippet_)); if (res != end) { return res-> filename; } else { return string(); } } void SnippetConversion::eraseSnippet(string const & snippet_) { BitmapFileList::iterator it = snippets.begin(); BitmapFileList::iterator end = snippets.end(); it = find_if(it, end, FindFirst(snippet_)); if (it != end) snippets.erase(it, it+1); } string SnippetConversion::prepareCommand(Buffer const & buffer, string const & hex_foreground, string const & hex_background, double font_scaling_factor_, bool showLabels) { // Output the LaTeX file. string const latexfile = filename_base + ".tex"; lyxerr << "preview snippets in " << latexfile << endl; ofstream of(latexfile.c_str()); if (!of) { lyxerr[Debug::GRAPHICS] << "SnippetConversion::start()\n" << "Unable to create LaTeX file\n" << latexfile << endl; return ""; } lyxerr << "writing preview snippets now" << endl; of << "\\batchmode\n"; dumpPreamble(of, buffer, showLabels); of << "\n\\begin{document}\n"; dumpData(of, snippets); of << "\n\\end{document}\n"; of.close(); lyxerr << "done writing preview snippets" << endl; // The conversion command. ostringstream cs; cs << converter_->command << ' ' << converter_->to << ' ' << latexfile << ' ' << int(font_scaling_factor_) << ' ' << hex_foreground << ' ' << hex_background; lyxerr << "preview command is " << cs.str() << endl; return support::LibScriptSearch(cs.str()); } void SnippetConversion::start(Buffer const & buffer, string const & hex_foreground, string const & hex_background, double font_scaling_factor, support::Forkedcall::SignalTypePtr convert_ptr) { command_ = prepareCommand(buffer, hex_foreground, hex_background, font_scaling_factor,true); support::Forkedcall call; int ret = call.startscript(command_, convert_ptr); if (ret != 0) { lyxerr[Debug::GRAPHICS] << "SnippetConversion::start()\n" << "Unable to start process\n" << command_ << endl; return; } pid_ = call.pid(); } int SnippetConversion::startAndWait(Buffer const & buffer, string const & hex_foreground, string const & hex_background, double font_scaling_factor) { command_ = prepareCommand(buffer, hex_foreground, hex_background, font_scaling_factor,false); support::Forkedcall call; int ret = call.startscript(support::ForkedProcess::Wait, command_); if (ret != 0) { lyxerr[Debug::GRAPHICS] << "SnippetConversion::startAndWait()\n" << "Unable to start process\n" << command_ << endl; } return ret; } void SnippetConversion::stop() { if (!metrics_file.empty()) support::unlink(metrics_file); BitmapFileList::const_iterator vit = snippets.begin(); BitmapFileList::const_iterator vend = snippets.end(); for (; vit != vend; ++vit) { if (!vit->filename.empty()) support::unlink(vit->filename); } if (pid_) support::ForkedcallsController::get().kill(pid_, 0); } void SnippetConversion::dumpPreamble(ostream & os, Buffer const & buffer, bool showLabels) const { // Why on earth is Buffer::makeLaTeXFile a non-const method? Buffer & tmp = const_cast<Buffer &>(buffer); // Dump the preamble only. OutputParams runparams; runparams.flavor = OutputParams::LATEX; runparams.nice = true; runparams.moving_arg = true; runparams.free_spacing = true; tmp.makeLaTeXFile(os, buffer.filePath(), runparams, true, false); // FIXME! This is a HACK! The proper fix is to control the 'true' // passed to WriteStream below: // int InsetFormula::latex(Buffer const &, ostream & os, // OutputParams const & runparams) const // { // WriteStream wi(os, runparams.moving_arg, true); // par_->write(wi); // return wi.line(); // } os << "\n" << "\\def\\lyxlock{}\n" << "\n"; // Loop over the insets in the buffer and dump all the math-macros. InsetBase & inset = buffer.inset(); InsetIterator it = inset_iterator_begin(inset); InsetIterator const end = inset_iterator_end(inset); for (; it != end; ++it) if (it->lyxCode() == InsetBase::MATHMACRO_CODE) it->latex(buffer, os, runparams); // All equation lables appear as "(#)" + preview.sty's rendering of // the label name if (lyxrc.preview_hashed_labels) os << "\\renewcommand{\\theequation}{\\#}\n"; // Use the preview style file to ensure that each snippet appears on a // fresh page. os << "\n" << "\\usepackage[active,delayed,dvips," << (showLabels? "showlabels," : "") << "lyx]{preview}\n" << "\n"; } void SnippetConversion::dumpData(ostream & os, BitmapFileList const & vec) const { if (vec.empty()) return; BitmapFileList::const_iterator it = vec.begin(); BitmapFileList::const_iterator end = vec.end(); for (; it != end; ++it) { os << "\\begin{preview}\n" << it->latex << "\n\\end{preview}\n\n"; } } void SnippetConversion::setAscentFractions() { BitmapFileList::iterator it = snippets.begin(); BitmapFileList::iterator end = snippets.end(); bool error = false; ifstream in(metrics_file.c_str()); if (!in.good()) { lyxerr[Debug::GRAPHICS] << "setAscentFractions(" << metrics_file << ")\n" << "Unable to open file!" << endl; } else { int snippet_counter = 1; while (!in.eof() && it != end) { string snippet; int id; double ascent_fraction; in >> snippet >> id >> ascent_fraction; if (!in.good()) // eof after all break; error = snippet != "Snippet"; if (error) break; error = id != snippet_counter; if (error) break; it->ascentfraction = ascent_fraction; ++snippet_counter; ++it; } } // If all else fails, then the images will have equal ascents and // descents. while (it != end) { it->ascentfraction = 0.5; ++it; } if (error) { lyxerr[Debug::GRAPHICS] << "setAscentFractions(" << metrics_file << ")\n" << "Error reading file!\n" << endl; } } } // namespace } // lyx::graphics
// -*- C++ -*- /** * \file SnippetConversion.h * This file is part of LyX, the document processor. * Licence details can be found in the file COPYING. * * \author Andreas Vox * * Full author contact details are available in file CREDITS. * * lyx::graphics::SnippetConversion converts latex snippets to bitmap * files. * snippets are collected one by one. Then, on start converting, these * are dumped to file and processed, converting each snippet to a * separate bitmap image file. */ #ifndef SNIPPETCONVERSION_H #define SNIPPETCONVERSION_H #include "converter.h" #include "support/forkedcall.h" #include <boost/utility.hpp> #include <boost/scoped_ptr.hpp> #include <boost/signal.hpp> #include <boost/bind.hpp> #include <sstream> #include <fstream> namespace lyx { namespace graphics { /// Converts a set of LaTeX snippets to graphic files using yxpreview2bitmap class SnippetConversion { public: /// Holds one snippet and its associated graphics file struct Entry { std::string latex; std::string filename; double ascentfraction; }; // A list of all snippets to be converted to previews typedef std::list<std::string> SnippetList; /// Default constructor. No conversions are intitiated. SnippetConversion() : pid_(0) {} /// Initialise member variables. Do not initiate conversions. SnippetConversion(std::string const & filename_base, Converter const * converter, SnippetList const & pending); /// Dynamically forget about a snippet void eraseSnippet(std::string const & snippet_); /// return start of entry list std::vector<Entry>::const_iterator begin() const; /// return end of entry list std::vector<Entry>::const_iterator end() const; /// is the entry list empty? bool empty() const; /// how many entries are in the list? int size() const; /// Find a snippet in the entry list. Return its associated graphics filename std::string const findSnippet(std::string const & snippet_) const; /** Start the conversion and return immediately. * The conversion process is run asynchronously. */ void start(Buffer const & buffer, std::string const & hex_foreground, std::string const & hex_background, double font_scaling_factor_, lyx::support::Forkedcall::SignalTypePtr convert_ptr); /** Start the conversion and block further execution until * the conversion process finiishes. */ int startAndWait(Buffer const & buffer, std::string const & hex_foreground, std::string const & hex_background, double font_scaling_factor_); /// Remove any files left lying around and kill the forked process. void stop(); /// Read the metrics file and set ascentfractions in entries void setAscentFractions(); /// The external command which gets forked std::string const & command() const { return command_; } /// The PID of the forked process pid_t pid() const { return pid_; } private: /// void dumpPreamble(std::ostream &, Buffer const & buffer, bool showLabels) const; /// void dumpData(std::ostream &, std::vector<Entry> const &) const; /// std::string prepareCommand(Buffer const & buffer, std::string const & hex_foreground, std::string const & hex_background, double font_scaling_factor_, bool showLabels); /// std::string command_; /// pid_t pid_; /// std::string filename_base; /// std::string metrics_file; /// std::vector<Entry> snippets; Converter const * converter_; }; } // namespace graphics } // namespace lyx #endif // SNIPPETCONVERSION_H