]> git.lyx.org Git - features.git/commitdiff
Support for exporting math as images with XHTML. The next step is to
authorRichard Heck <rgheck@comcast.net>
Wed, 21 Jul 2010 13:19:52 +0000 (13:19 +0000)
committerRichard Heck <rgheck@comcast.net>
Wed, 21 Jul 2010 13:19:52 +0000 (13:19 +0000)
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
src/Buffer.h
src/graphics/PreviewImage.cpp
src/graphics/PreviewImage.h
src/graphics/PreviewLoader.cpp
src/graphics/PreviewLoader.h
src/insets/RenderPreview.cpp
src/insets/RenderPreview.h
src/mathed/InsetMathHull.cpp
src/mathed/InsetMathHull.h

index 78ca6dd038f19756dcd71727657517eb5bcf7d10..1cd24493fced6dfa250ff89fc2371f39f2b212e7 100644 (file)
@@ -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<InsetMath *>(iit->inset);
+                               if (im->asHullInset()) {
+                                       InsetMathHull * hull = static_cast<InsetMathHull *>(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);
 }
 
 
index 01537b9b6362908609fa9c2faef240dab10a2461..811727e5a856294f2ed97c165f117f25ef3a722e 100644 (file)
@@ -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;
 
index d84e425c1f75f31c30e684c73c49517155331c11..7fe9f2a769303fa408d4df8f2048313973ed5cae 100644 (file)
@@ -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;
index 2a112b76a169e1e6818eb699b0de323e4504f4bf..04f1338e1080befd50f7f34af003e1a434e751c3 100644 (file)
@@ -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.
index 661587ea82bf26f0566ad91adf5cbb6205e24aab..54913b3aeca0b0b8beb09d2de55cd4614ec7ddc8 100644 (file)
@@ -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<void(PreviewImage const &)> 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);
index 980c757444f5b2b7ef0873d531038beb243621cf..6910984c9ed13eb77c851ac49ee3bad94403fd4d 100644 (file)
@@ -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
index ee2bbce4d1479dbc41c24e72bd4802bc2f08837a..1b97bef14e9f1038dd30649f4f38b4da788f567d 100644 (file)
@@ -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);
 }
 
 
index bad2bff452059bffbd39b504d8c824eb245c5507..01df8c60000e88cbde59d34ab2544b5c624c64f1 100644 (file)
@@ -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.
index b69e5af08942cb782619f1fa2a0cd927a1c8e8d1..dd0fbf5b32b72d1f07158bb1b045d37930caf6b1 100644 (file)
@@ -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
index 08e3a03cba0b9820bd9ba4ddf02033abed52db22..d2ca3f6d2bec84a0cca6814bf5dd4cba53ab9f70 100644 (file)
@@ -14,6 +14,7 @@
 
 #include "InsetMathGrid.h"
 
+#include "DocIterator.h"
 #include "OutputEnums.h"
 
 #include <boost/scoped_ptr.hpp>
@@ -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<RenderPreview> preview_;
        ///
        mutable bool use_preview_;
+       ///
+       DocIterator docit_;
 //
 // Incorporate me
 //