From b8d43b05bc8411ae6dd347f40669b0c4a9a0d1ee Mon Sep 17 00:00:00 2001 From: Richard Heck Date: Wed, 21 Jul 2010 13:19:52 +0000 Subject: [PATCH] Support for exporting math as images with XHTML. The next step is to allow this as a fallback. E.g., if we're unable to export as MathML, then we try to export as an image. There are several ways, I am sure, in which this implementation is not ideal. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@34993 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/Buffer.cpp | 24 ++++++++++++++++++------ src/Buffer.h | 2 +- src/graphics/PreviewImage.cpp | 6 ++++++ src/graphics/PreviewImage.h | 2 ++ src/graphics/PreviewLoader.cpp | 26 +++++++++++++++++++++----- src/graphics/PreviewLoader.h | 2 +- src/insets/RenderPreview.cpp | 4 ++-- src/insets/RenderPreview.h | 2 +- src/mathed/InsetMathHull.cpp | 32 +++++++++++++++++++++++++++----- src/mathed/InsetMathHull.h | 7 ++++++- 10 files changed, 85 insertions(+), 22 deletions(-) diff --git a/src/Buffer.cpp b/src/Buffer.cpp index 78ca6dd038..1cd24493fc 100644 --- a/src/Buffer.cpp +++ b/src/Buffer.cpp @@ -72,6 +72,7 @@ #include "insets/InsetInclude.h" #include "insets/InsetText.h" +#include "mathed/InsetMathHull.h" #include "mathed/MacroTable.h" #include "mathed/MathMacroTemplate.h" #include "mathed/MathSupport.h" @@ -163,7 +164,8 @@ public: /// Update macro table starting with position of it \param it in some /// text inset. - void updateMacros(DocIterator & it, DocIterator & scope); + void updateMacros(DocIterator & it, DocIterator & scope, + bool record_docits = false); /// void setLabel(ParIterator & it, UpdateType utype) const; /// @@ -403,7 +405,8 @@ Buffer::~Buffer() } // Remove any previewed LaTeX snippets associated with this buffer. - thePreviews().removeLoader(*this); + if (!isClone()) + thePreviews().removeLoader(*this); delete d; } @@ -1571,7 +1574,7 @@ void Buffer::writeLyXHTMLSource(odocstream & os, updateBuffer(UpdateMaster, OutputUpdate); checkBibInfoCache(); d->bibinfo_.makeCitationLabels(*this); - updateMacros(); + updateMacros(true); updateMacroInstances(); if (!only_body) { @@ -2663,7 +2666,8 @@ MacroData const * Buffer::getMacro(docstring const & name, } -void Buffer::Impl::updateMacros(DocIterator & it, DocIterator & scope) +void Buffer::Impl::updateMacros(DocIterator & it, DocIterator & scope, + bool record_docits) { pit_type const lastpit = it.lastpit(); @@ -2717,6 +2721,14 @@ void Buffer::Impl::updateMacros(DocIterator & it, DocIterator & scope) continue; } + if (record_docits && iit->inset->asInsetMath()) { + InsetMath * im = static_cast(iit->inset); + if (im->asHullInset()) { + InsetMathHull * hull = static_cast(im); + hull->recordLocation(it); + } + } + if (iit->inset->lyxCode() != MATHMACRO_CODE) continue; @@ -2748,7 +2760,7 @@ void Buffer::Impl::updateMacros(DocIterator & it, DocIterator & scope) } -void Buffer::updateMacros() const +void Buffer::updateMacros(bool record_docit) const { if (d->macro_lock) return; @@ -2767,7 +2779,7 @@ void Buffer::updateMacros() const DocIterator it = par_iterator_begin(); DocIterator outerScope = it; outerScope.pit() = outerScope.lastpit() + 2; - d->updateMacros(it, outerScope); + d->updateMacros(it, outerScope, record_docit); } diff --git a/src/Buffer.h b/src/Buffer.h index 01537b9b63..811727e5a8 100644 --- a/src/Buffer.h +++ b/src/Buffer.h @@ -427,7 +427,7 @@ public: // Macro handling // /// Collect macro definitions in paragraphs - void updateMacros() const; + void updateMacros(bool record_docit = false) const; /// Iterate through the whole buffer and try to resolve macros void updateMacroInstances() const; diff --git a/src/graphics/PreviewImage.cpp b/src/graphics/PreviewImage.cpp index d84e425c1f..7fe9f2a769 100644 --- a/src/graphics/PreviewImage.cpp +++ b/src/graphics/PreviewImage.cpp @@ -70,6 +70,12 @@ string const & PreviewImage::snippet() const } +support::FileName const & PreviewImage::filename() const +{ + return pimpl_->iloader_.filename(); +} + + Dimension PreviewImage::dim() const { Dimension dim; diff --git a/src/graphics/PreviewImage.h b/src/graphics/PreviewImage.h index 2a112b76a1..04f1338e10 100644 --- a/src/graphics/PreviewImage.h +++ b/src/graphics/PreviewImage.h @@ -46,6 +46,8 @@ public: * triggers that. */ Image const * image() const; + /// + support::FileName const & filename() const; private: /// Use the Pimpl idiom to hide the internals. diff --git a/src/graphics/PreviewLoader.cpp b/src/graphics/PreviewLoader.cpp index 661587ea82..54913b3aec 100644 --- a/src/graphics/PreviewLoader.cpp +++ b/src/graphics/PreviewLoader.cpp @@ -204,7 +204,7 @@ public: /// void remove(string const & latex_snippet); /// - void startLoading(); + void startLoading(bool wait = false); /// Emit this signal when an image is ready for display. boost::signal imageReady; @@ -291,9 +291,9 @@ void PreviewLoader::remove(string const & latex_snippet) const } -void PreviewLoader::startLoading() const +void PreviewLoader::startLoading(bool wait) const { - pimpl_->startLoading(); + pimpl_->startLoading(wait); } @@ -520,7 +520,7 @@ void PreviewLoader::Impl::remove(string const & latex_snippet) } -void PreviewLoader::Impl::startLoading() +void PreviewLoader::Impl::startLoading(bool wait) { if (pending_.empty() || !pconverter_) return; @@ -585,18 +585,34 @@ void PreviewLoader::Impl::startLoading() double font_scaling_factor = 0.01 * lyxrc.dpi * lyxrc.zoom * lyxrc.preview_scale_factor; + // For XHTML image export, we need to control the background + // color here. + ColorCode bg = buffer_.isClone() + ? Color_white : PreviewLoader::backgroundColor(); // The conversion command. ostringstream cs; cs << pconverter_->command << ' ' << pconverter_->to << ' ' << quoteName(latexfile.toFilesystemEncoding()) << ' ' << int(font_scaling_factor) << ' ' << theApp()->hexName(PreviewLoader::foregroundColor()) << ' ' - << theApp()->hexName(PreviewLoader::backgroundColor()); + << theApp()->hexName(bg); if (buffer_.params().useXetex) cs << " xelatex"; string const command = libScriptSearch(cs.str()); + if (wait) { + ForkedCall call; + int ret = call.startScript(ForkedProcess::Wait, command); + static int fake = (2^20) + 1; + int pid = fake++; + inprogress.pid = pid; + inprogress.command = command; + in_progress_[pid] = inprogress; + finishedGenerating(pid, ret); + return; + } + // Initiate the conversion from LaTeX to bitmap images files. ForkedCall::SignalTypePtr convert_ptr(new ForkedCall::SignalType); diff --git a/src/graphics/PreviewLoader.h b/src/graphics/PreviewLoader.h index 980c757444..6910984c9e 100644 --- a/src/graphics/PreviewLoader.h +++ b/src/graphics/PreviewLoader.h @@ -68,7 +68,7 @@ public: /** We have accumulated several latex snippets with status "InQueue". * Initiate their transformation into bitmap images. */ - void startLoading() const; + void startLoading(bool wait = false) const; /** Connect and you'll be informed when the bitmap image file * has been created and is ready for loading through diff --git a/src/insets/RenderPreview.cpp b/src/insets/RenderPreview.cpp index ee2bbce4d1..1b97bef14e 100644 --- a/src/insets/RenderPreview.cpp +++ b/src/insets/RenderPreview.cpp @@ -175,13 +175,13 @@ void RenderPreview::draw(PainterInfo & pi, int x, int y) const } -void RenderPreview::startLoading(Buffer const & buffer) const +void RenderPreview::startLoading(Buffer const & buffer, bool wait) const { if (status() == LyXRC::PREVIEW_OFF || snippet_.empty()) return; graphics::PreviewLoader const & loader = getPreviewLoader(buffer); - loader.startLoading(); + loader.startLoading(wait); } diff --git a/src/insets/RenderPreview.h b/src/insets/RenderPreview.h index bad2bff452..01df8c6000 100644 --- a/src/insets/RenderPreview.h +++ b/src/insets/RenderPreview.h @@ -69,7 +69,7 @@ public: graphics::PreviewLoader & ploader); /// Begin the loading process. - void startLoading(Buffer const & buffer) const; + void startLoading(Buffer const & buffer, bool wait = false) const; /** Remove a snippet from the cache of previews. * Useful if previewing the contents of a file that has changed. diff --git a/src/mathed/InsetMathHull.cpp b/src/mathed/InsetMathHull.cpp index b69e5af089..dd0fbf5b32 100644 --- a/src/mathed/InsetMathHull.cpp +++ b/src/mathed/InsetMathHull.cpp @@ -25,6 +25,7 @@ #include "ColorSet.h" #include "CutAndPaste.h" #include "Encoding.h" +#include "Exporter.h" #include "FuncRequest.h" #include "FuncStatus.h" #include "LaTeXFeatures.h" @@ -539,10 +540,10 @@ void InsetMathHull::preparePreview(DocIterator const & pos) const } -void InsetMathHull::reloadPreview(DocIterator const & pos) const +void InsetMathHull::reloadPreview(DocIterator const & pos, bool wait) const { preparePreview(pos); - preview_->startLoading(*pos.buffer()); + preview_->startLoading(*pos.buffer(), wait); } @@ -1837,7 +1838,7 @@ int InsetMathHull::docbook(odocstream & os, OutputParams const & runparams) cons } -docstring InsetMathHull::xhtml(XHTMLStream & xs, OutputParams const &) const +docstring InsetMathHull::xhtml(XHTMLStream & xs, OutputParams const & op) const { BufferParams::MathOutput mathtype = buffer().params().html_math_output; // FIXME Eventually we would like to do this inset by inset. @@ -1855,7 +1856,7 @@ docstring InsetMathHull::xhtml(XHTMLStream & xs, OutputParams const &) const break; } case BufferParams::HTML: { - string tag = (getType() == hullSimple) ? "span" : "div"; + string const tag = (getType() == hullSimple) ? "span" : "div"; xs << html::StartTag(tag, "class='formula'", true); HtmlStream ms(xs.os()); InsetMathGrid::htmlize(ms); @@ -1863,7 +1864,23 @@ docstring InsetMathHull::xhtml(XHTMLStream & xs, OutputParams const &) const break; } case BufferParams::Images: { - LYXERR0("Image output for math presently unsupported."); + reloadPreview(docit_, true); + graphics::PreviewImage const * pimage = preview_->getPreviewImage(buffer()); + string const tag = (getType() == hullSimple) ? "span" : "div"; + if (!pimage) { + LYXERR0("Unable to generate image. LaTeX follows."); + LYXERR0(latexString(*this)); + xs << html::StartTag(tag) << "MATH" << html::EndTag(tag); + xs.cr(); + break; + } + // need to do a conversion to png, possibly. + FileName const & mathimg = pimage->filename(); + xs << html::StartTag(tag); + xs << html::CompTag("img", "src=\"" + mathimg.onlyFileName() + "\""); + xs << html::EndTag(tag); + xs.cr(); + op.exportdata->addExternalFile("xhtml", mathimg); break; } case BufferParams::LaTeX: { @@ -1887,4 +1904,9 @@ docstring InsetMathHull::contextMenu(BufferView const &, int, int) const } +void InsetMathHull::recordLocation(DocIterator const & di) +{ + docit_ = di; +} + } // namespace lyx diff --git a/src/mathed/InsetMathHull.h b/src/mathed/InsetMathHull.h index 08e3a03cba..d2ca3f6d2b 100644 --- a/src/mathed/InsetMathHull.h +++ b/src/mathed/InsetMathHull.h @@ -14,6 +14,7 @@ #include "InsetMathGrid.h" +#include "DocIterator.h" #include "OutputEnums.h" #include @@ -141,7 +142,7 @@ public: /// Prepare the preview if preview is enabled. void preparePreview(DocIterator const & pos) const; /// Recreates the preview if preview is enabled. - void reloadPreview(DocIterator const & pos) const; + void reloadPreview(DocIterator const & pos, bool wait = false) const; /// void initUnicodeMath() const; @@ -150,6 +151,8 @@ public: /// Force inset into LTR environment if surroundings are RTL virtual bool forceLTR() const { return true; } + /// + void recordLocation(DocIterator const & di); /// virtual docstring contextMenu(BufferView const &, int, int) const; @@ -216,6 +219,8 @@ private: boost::scoped_ptr preview_; /// mutable bool use_preview_; + /// + DocIterator docit_; // // Incorporate me // -- 2.39.5