]> git.lyx.org Git - lyx.git/blobdiff - src/mathed/InsetMathHull.cpp
Small improvement for bug #7509 as suggested by JMarc
[lyx.git] / src / mathed / InsetMathHull.cpp
index 5ef21f31b48b9939907f691d821ae50e248e6df1..686e4274077c61251d66d4ec7e6ffb242cfa0789 100644 (file)
@@ -53,6 +53,7 @@
 #include "support/convert.h"
 #include "support/lassert.h"
 #include "support/debug.h"
+#include "support/filetools.h"
 #include "support/gettext.h"
 #include "support/lstrings.h"
 
@@ -224,6 +225,12 @@ void InsetMathHull::setBuffer(Buffer & buffer)
 }
 
 
+namespace {
+       const char * counters_to_save[] = {"section", "chapter"};
+       unsigned int const numcnts = sizeof(counters_to_save)/sizeof(char *);
+}
+
+
 void InsetMathHull::updateBuffer(ParIterator const & it, UpdateType utype)
 {
        if (!buffer_) {
@@ -233,18 +240,40 @@ void InsetMathHull::updateBuffer(ParIterator const & it, UpdateType utype)
                return;
        }
 
-       BufferParams const & bp = buffer_->params();
-       string const & lang = it->getParLanguage(bp)->code();
-       Counters & cnts = bp.documentClass().counters();
-       // so we don't have to write it ten times...
-       docstring const eqstr = from_ascii("equation");
+       // if any of the equations are numbered, then we want to save the values
+       // of some of the counters.
+       if (haveNumbers()) {
+               BufferParams const & bp = buffer_->params();
+               string const & lang = it->getParLanguage(bp)->code();
+               Counters & cnts =
+                       buffer_->masterBuffer()->params().documentClass().counters();
+
+               // right now, we only need to do this at export time
+               if (utype == OutputUpdate) {
+                       for (size_t i = 0; i < numcnts; ++i) {
+                               docstring const cnt = from_ascii(counters_to_save[i]);
+                               if (cnts.hasCounter(cnt))
+                                       counter_map[cnt] = cnts.value(cnt);
+                       }
+               }
+
+               // this has to be done separately
+               docstring const eqstr = from_ascii("equation");
+               if (cnts.hasCounter(eqstr)) {
+                       if (utype == OutputUpdate)
+                               counter_map[eqstr] = cnts.value(eqstr);
+                       for (size_t i = 0; i != label_.size(); ++i) {
+                               if (numbered(i)) {
+                                       cnts.step(eqstr, utype);
+                                       numbers_[i] = cnts.theCounter(eqstr, lang);
+                               } else
+                                       numbers_[i] = empty_docstring();
+                       }
+               }
+       }
 
+       // now the labels
        for (size_t i = 0; i != label_.size(); ++i) {
-               if (numbered(i) && cnts.hasCounter(eqstr)) {
-                       cnts.step(eqstr, utype);
-                       numbers_[i] = cnts.theCounter(eqstr, lang);
-               } else
-                       numbers_[i] = empty_docstring();
                if (label_[i])
                        label_[i]->updateBuffer(it, utype);
        }
@@ -253,7 +282,7 @@ void InsetMathHull::updateBuffer(ParIterator const & it, UpdateType utype)
 }
 
 
-void InsetMathHull::addToToc(DocIterator const & pit)
+void InsetMathHull::addToToc(DocIterator const & pit) const
 {
        if (!buffer_) {
                //FIXME: buffer_ should be set at creation for this inset! Problem is
@@ -561,7 +590,29 @@ void InsetMathHull::preparePreview(DocIterator const & pos,
                }
        }
 
-       docstring const snippet = macro_preamble.str() + latexString(*this);
+       docstring setcnt;
+       if (forexport && haveNumbers()) {
+               docstring eqstr = from_ascii("equation");
+               CounterMap::const_iterator it = counter_map.find(eqstr);
+               if (it != counter_map.end()) {
+                       int num = it->second;
+                       if (num >= 0)
+                               setcnt += from_ascii("\\setcounter{") + eqstr + '}' +
+                                         '{' + convert<docstring>(num) + '}' + '\n';
+               }
+               for (size_t i = 0; i != numcnts; ++i) {
+                       docstring cnt = from_ascii(counters_to_save[i]);
+                       it = counter_map.find(cnt);
+                       if (it == counter_map.end())
+                                       continue;
+                       int num = it->second;
+                       if (num > 0)
+                               setcnt += from_ascii("\\setcounter{") + cnt + '}' +
+                                         '{' + convert<docstring>(num) + '}';
+               }
+       }
+       docstring const snippet = macro_preamble.str() +
+           setcnt + latexString(*this);
        LYXERR(Debug::MACROS, "Preview snippet: " << snippet);
        preview_->addPreview(snippet, *buffer, forexport);
 }
@@ -729,9 +780,9 @@ void InsetMathHull::header_write(WriteStream & os) const
 
        case hullEquation:
                if (n)
-                       os << "\\begin{equation" << star(n) << "}\n";
+                       os << "\n\\begin{equation" << star(n) << "}\n";
                else
-                       os << "\\[\n";
+                       os << "\n\\[\n";
                break;
 
        case hullEqnArray:
@@ -739,17 +790,17 @@ void InsetMathHull::header_write(WriteStream & os) const
        case hullFlAlign:
        case hullGather:
        case hullMultline:
-               os << "\\begin{" << hullName(type_) << star(n) << "}\n";
+               os << "\n\\begin{" << hullName(type_) << star(n) << "}\n";
                break;
 
        case hullAlignAt:
        case hullXAlignAt:
-               os << "\\begin{" << hullName(type_) << star(n) << '}'
+               os << "\n\\begin{" << hullName(type_) << star(n) << '}'
                  << '{' << static_cast<unsigned int>((ncols() + 1)/2) << "}\n";
                break;
 
        case hullXXAlignAt:
-               os << "\\begin{" << hullName(type_) << '}'
+               os << "\n\\begin{" << hullName(type_) << '}'
                  << '{' << static_cast<unsigned int>((ncols() + 1)/2) << "}\n";
                break;
 
@@ -758,7 +809,7 @@ void InsetMathHull::header_write(WriteStream & os) const
                break;
 
        default:
-               os << "\\begin{unknown" << star(n) << "}\n";
+               os << "\n\\begin{unknown" << star(n) << "}\n";
                break;
        }
 }
@@ -1546,7 +1597,7 @@ bool InsetMathHull::getStatus(Cursor & cur, FuncRequest const & cmd,
                // LABEL_INSERT?
                bool const enable = (type_ == hullMultline)
                        ? (nrows() - 1 == cur.row())
-                       : display() != Inline && nrows() > 1;
+                       : display() != Inline;
                row_type const r = (type_ == hullMultline) ? nrows() - 1 : cur.row();
                status.setEnabled(enable);
                status.setOnOff(enable && numbered(r));
@@ -1885,8 +1936,12 @@ int InsetMathHull::docbook(odocstream & os, OutputParams const & runparams) cons
                InsetMathGrid::mathmlize(ms);
                ms << ETag("math");
        } else {
+               TexRow texrow;
+               texrow.reset();
+               otexstream ols(ls, texrow);
                ms << MTag("alt role='tex'");
-               res = latex(ls, runparams);
+               latex(ols, runparams);
+               res = texrow.rows();
                ms << from_utf8(subst(subst(to_utf8(ls.str()), "&", "&amp;"), "<", "&lt;"));
                ms << ETag("alt");
        }
@@ -1908,21 +1963,31 @@ int InsetMathHull::docbook(odocstream & os, OutputParams const & runparams) cons
 }
 
 
-// FIXME XHTML
-// We need to do something about alignment here.
-//
-// This duplicates code from InsetMathGrid, but
-// we need access here to number information,
-// and we simply do not have that in InsetMathGrid.
-void InsetMathHull::htmlize(HtmlStream & os) const
+bool InsetMathHull::haveNumbers() const
 {
        bool havenumbers = false;
+       // inline formulas are never numbered (bug 7351 part 3)
+       if (getType() == hullSimple)
+               return havenumbers;
        for (size_t i = 0; i != numbered_.size(); ++i) {
                if (numbered_[i]) {
                        havenumbers = true;
                        break;
                }
        }
+       return havenumbers;
+}
+
+
+// FIXME XHTML
+// We need to do something about alignment here.
+//
+// This duplicates code from InsetMathGrid, but
+// we need access here to number information,
+// and we simply do not have that in InsetMathGrid.
+void InsetMathHull::htmlize(HtmlStream & os) const
+{
+       bool const havenumbers = haveNumbers();
        bool const havetable = havenumbers || nrows() > 1 || ncols() > 1;
 
        if (!havetable) {
@@ -1956,13 +2021,7 @@ void InsetMathHull::htmlize(HtmlStream & os) const
 // and we simply do not have that in InsetMathGrid.
 void InsetMathHull::mathmlize(MathStream & os) const
 {
-       bool havenumbers = false;
-       for (size_t i = 0; i != numbered_.size(); ++i) {
-               if (numbered_[i]) {
-                       havenumbers = true;
-                       break;
-               }
-       }
+       bool const havenumbers = haveNumbers();
        bool const havetable = havenumbers || nrows() > 1 || ncols() > 1;
 
        if (havetable)
@@ -1999,13 +2058,7 @@ void InsetMathHull::mathmlize(MathStream & os) const
 void InsetMathHull::mathAsLatex(WriteStream & os) const
 {
        MathEnsurer ensurer(os, false);
-       bool havenumbers = false;
-       for (size_t i = 0; i != numbered_.size(); ++i) {
-               if (numbered_[i]) {
-                       havenumbers = true;
-                       break;
-               }
-       }
+       bool havenumbers = haveNumbers();
        bool const havetable = havenumbers || nrows() > 1 || ncols() > 1;
 
        if (!havetable) {
@@ -2038,8 +2091,18 @@ docstring InsetMathHull::xhtml(XHTMLStream & xs, OutputParams const & op) const
 {
        BufferParams::MathOutput const mathtype = 
                buffer().params().html_math_output;
-       
+
        bool success = false;
+
+       // we output all the labels just at the beginning of the equation.
+       // this should be fine.
+       for (size_t i = 0; i != label_.size(); ++i) {
+               InsetLabel const * const il = label_[i];
+               if (!il)
+                       continue;
+               il->xhtml(xs, op);
+       }
+
        // FIXME Eventually we would like to do this inset by inset.
        if (mathtype == BufferParams::MathML) {
                odocstringstream os;
@@ -2085,18 +2148,35 @@ docstring InsetMathHull::xhtml(XHTMLStream & xs, OutputParams const & op) const
        // tried and failed with MathML or HTML or (b) didn't try yet at all but
        // aren't doing LaTeX, in which case we are doing Images.
        if (!success && mathtype != BufferParams::LaTeX) {
-               loadPreview(docit_);
-               graphics::PreviewImage const * pimage = preview_->getPreviewImage(buffer());
-               if (pimage) {
+               graphics::PreviewImage const * pimage = 0;
+               if (!op.dryrun) {
+                       loadPreview(docit_);
+                       pimage = preview_->getPreviewImage(buffer());
                        // FIXME Do we always have png?
+               }
+
+               if (pimage || op.dryrun) {
+                       string const filename = pimage ? pimage->filename().onlyFileName()
+                                                      : "previewimage.png";
+                       if (pimage) {
+                               // if we are not in the master buffer, then we need to see that the
+                               // generated image is copied there; otherwise, preview fails.
+                               Buffer const * mbuf = buffer().masterBuffer();
+                               if (mbuf != &buffer()) {
+                                       string mbtmp = mbuf->temppath();
+                                       FileName const mbufimg(support::addName(mbtmp, filename));
+                                       pimage->filename().copyTo(mbufimg);
+                               }
+                               // add the file to the list of files to be exported
+                               op.exportdata->addExternalFile("xhtml", pimage->filename());
+                       }
+
                        string const tag = (getType() == hullSimple) ? "span" : "div";
-                       FileName const & mathimg = pimage->filename();
-                       xs << html::StartTag(tag)
-                          << html::CompTag("img", "src=\"" + mathimg.onlyFileName() + "\"")
-                          << html::EndTag(tag);
-                       xs.cr();
-                       // add the file to the list of files to be exported
-                       op.exportdata->addExternalFile("xhtml", mathimg);
+                       xs << html::CR()
+                          << html::StartTag(tag)
+                                << html::CompTag("img", "src=\"" + filename + "\"")
+                                << html::EndTag(tag)
+                                << html::CR();
                        success = true;
                }
        }
@@ -2105,7 +2185,6 @@ docstring InsetMathHull::xhtml(XHTMLStream & xs, OutputParams const & op) const
        // if mathtype was LaTeX, since we won't have entered any of the
        // earlier branches
        if (!success /* || mathtype != BufferParams::LaTeX */) {
-               string const tag = (getType() == hullSimple) ? "span" : "div";
                // Unfortunately, we cannot use latexString() because we do not want
                // $...$ or whatever.
                odocstringstream ls;
@@ -2118,11 +2197,11 @@ docstring InsetMathHull::xhtml(XHTMLStream & xs, OutputParams const & op) const
                // http://www.math.union.edu/~dpvc/jsMath/
                // FIXME XHTML
                // probably should allow for some kind of customization here
+               string const tag = (getType() == hullSimple) ? "span" : "div";
                xs << html::StartTag(tag, "class='math'")
-                  << XHTMLStream::ESCAPE_AND
                   << latex 
-                  << html::EndTag(tag);
-               xs.cr();
+                  << html::EndTag(tag)
+                  << html::CR();
        }
        return docstring();
 }