]> git.lyx.org Git - lyx.git/commitdiff
The beginnings of pure HTML output of math, for our internal XHTML
authorRichard Heck <rgheck@comcast.net>
Mon, 29 Mar 2010 22:52:13 +0000 (22:52 +0000)
committerRichard Heck <rgheck@comcast.net>
Mon, 29 Mar 2010 22:52:13 +0000 (22:52 +0000)
output routines. The idea is that in some cases people may not want to
use MathML, so we are going to try to give options.

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@33936 a592a061-630c-0410-9148-cb99ea01b6c8

src/mathed/InsetMath.cpp
src/mathed/InsetMath.h
src/mathed/InsetMathGrid.cpp
src/mathed/InsetMathGrid.h
src/mathed/InsetMathHull.cpp
src/mathed/MathExtern.cpp
src/mathed/MathExtern.h
src/mathed/MathStream.cpp
src/mathed/MathStream.h

index a1cc8d8049e940914e2d1510ab5050f228c97e6d..943ca902635bad29b77f9e5d6d04dd6c97a643c6 100644 (file)
@@ -130,6 +130,16 @@ void InsetMath::mathmlize(MathStream & os) const
 }
 
 
+void InsetMath::htmlize(HtmlStream & os) const
+{
+       os << "<!-- " << from_utf8(insetName(lyxCode())) << " -->";
+       os << MTag("span", "style='color: red;'");
+       NormalStream ns(os.os());
+       normalize(ns);
+       os << ETag("span");
+}
+
+
 HullType InsetMath::getType() const
 {
        return hullNone;
index 555762c8c7bab3e568b8d9247475e612b1c96ef5..e043a733fbc95a4a7e013339ac7129dd3453b4eb 100644 (file)
@@ -73,6 +73,7 @@ class InsetMathUnknown;
 
 class InsetMathRef;
 
+class HtmlStream;
 class NormalStream;
 class OctaveStream;
 class MapleStream;
@@ -186,8 +187,13 @@ public:
        virtual void maxima(MaximaStream &) const;
        /// write content as something readable by Mathematica
        virtual void mathematica(MathematicaStream &) const;
-       /// write content as something resembling MathML
+       /// write content as MathML
        virtual void mathmlize(MathStream &) const;
+       /// write content as HTML, best we can.
+       /// the idea for this, and some of the details, come from
+       /// eLyXer, written by Alex Fernandez. no code is borrowed. rather,
+       /// we try to mimic how eLyXer outputs some math.
+       virtual void htmlize(HtmlStream &) const;
        /// write content as something readable by Octave
        virtual void octave(OctaveStream &) const;
 
index 7ce5858145bb47b72188a1aaef651319dcf604be..14f9ba87dd197a62076a651a955e913576c0bef9 100644 (file)
@@ -998,6 +998,27 @@ void InsetMathGrid::mathmlize(MathStream & os) const
 }
 
 
+void InsetMathGrid::htmlize(HtmlStream & os) const
+{
+       bool const havetable = nrows() > 1 || ncols() > 1;
+       if (!havetable) {
+               os << cell(index(0, 0));
+               return;
+       }
+       os << MTag("table", "class='mathtable'");
+       for (row_type row = 0; row < nrows(); ++row) {
+               os << MTag("tr");;
+               for (col_type col = 0; col < ncols(); ++col) {
+                       os << MTag("td");
+                       os << cell(index(row, col));
+                       os << ETag("td");
+               }
+               os << ETag("tr");;
+       }
+       os << ETag("table");
+}
+
+
 void InsetMathGrid::write(WriteStream & os) const
 {
        write(os, 0, 0, nrows(), ncols());
index 17e9650124e28380a146050abd804bba4e48c6ea..cd86b6b7f655e984d442d0cea9556357421a89b9 100644 (file)
@@ -222,6 +222,8 @@ public:
        //void maple(MapleStream &) const;
        ///
        void mathmlize(MathStream &) const;
+       /// 
+       void htmlize(HtmlStream &) const;
        ///
        //void octave(OctaveStream &) const;
 
index 35e4186e2b74d07e6b0d933d5f8c2b01b77a0017..f977dacb9729627583527838d63db8573ce80a6b 100644 (file)
@@ -1810,14 +1810,38 @@ int InsetMathHull::docbook(odocstream & os, OutputParams const & runparams) cons
 
 docstring InsetMathHull::xhtml(XHTMLStream & xs, OutputParams const &) const
 {
-       if (getType() == hullSimple)
-               xs << html::StartTag("math", "xmlns=\"http://www.w3.org/1998/Math/MathML\"", true);
-       else 
-               xs << html::StartTag("math", 
-                       "display=\"block\" xmlns=\"http://www.w3.org/1998/Math/MathML\"", true);
-       MathStream ms(xs.os());
-       InsetMathGrid::mathmlize(ms);
-       xs << html::EndTag("math");
+       BufferParams::MathOutput mathtype = buffer().params().html_math_output;
+       // FIXME Eventually we would like to do this inset by inset.
+       switch (mathtype) {
+       case BufferParams::MathML: {
+               if (getType() == hullSimple)
+                       xs << html::StartTag("math", 
+                             "xmlns=\"http://www.w3.org/1998/Math/MathML\"", true);
+               else 
+                       xs << html::StartTag("math", 
+                             "display=\"block\" xmlns=\"http://www.w3.org/1998/Math/MathML\"", true);
+               MathStream ms(xs.os());
+               InsetMathGrid::mathmlize(ms);
+               xs << html::EndTag("math");
+               break;
+       } 
+       case BufferParams::HTML: {
+               string tag = (getType() == hullSimple) ? "span" : "div";
+               xs << html::StartTag(tag, "class='formula'", true);
+               HtmlStream ms(xs.os());
+               InsetMathGrid::htmlize(ms);
+               xs << html::EndTag(tag);
+               break;
+       } 
+       case BufferParams::Images: {
+               LYXERR0("Image output for math presently unsupported.");
+               break;
+       } 
+       case BufferParams::LaTeX: {
+               // FIXME Obviously, the only real question is how to wrap this.
+               LYXERR0("LaTeX output for math presently unsupported.");
+       }
+       } // end switch
        return docstring();
 }
 
index fb0ed20517b5c442fe058aa4dda0518f0f05ce8b..f39418396518cf1e6ecc5d45f5e9a0e35124ee74 100644 (file)
@@ -54,6 +54,7 @@ namespace lyx {
 namespace {
 
 enum ExternalMath {
+       HTML,
        MAPLE,
        MAXIMA,
        MATHEMATICA,
@@ -120,7 +121,7 @@ MathData::iterator extractArgument(MathData & ar,
                // leave out delimiters if this is a function argument
                // unless we are doing MathML, in which case we do want
                // the delimiters
-               if (function && kind != MATHML) {
+               if (function && kind != MATHML && kind != HTML) {
                        MathData const & arg = (*pos)->asDelimInset()->cell(0);
                        MathData::const_iterator cur = arg.begin();
                        MathData::const_iterator end = arg.end();
@@ -948,16 +949,16 @@ void extractLims(MathData & ar)
 void extractStructure(MathData & ar, ExternalMath kind)
 {
        //lyxerr << "\nStructure from: " << ar << endl;
-       if (kind != MATHML)
+       if (kind != MATHML && kind != HTML)
                splitScripts(ar);
        extractDelims(ar);
        extractIntegrals(ar, kind);
-       if (kind != MATHML)
+       if (kind != MATHML && kind != HTML)
                extractSums(ar);
        extractNumbers(ar);
        extractMatrices(ar);
        extractFunctions(ar, kind);
-       if (kind != MATHML) {
+       if (kind != MATHML && kind != HTML) {
                extractDets(ar);
                extractDiff(ar);
                extractExps(ar);
@@ -1434,6 +1435,21 @@ void mathmlize(MathData const & dat, MathStream & os)
 }
 
 
+void htmlize(MathData const & dat, HtmlStream & os)
+{
+       MathData ar = dat;
+       extractStructure(ar, HTML);
+       if (ar.size() == 0) 
+               return;
+       if (ar.size() == 1) {
+               os << ar.front();
+               return;
+       }
+       for (MathData::const_iterator it = ar.begin(); it != ar.end(); ++it)
+               (*it)->htmlize(os);
+}
+
+
 // convert this inset somehow to a number
 bool extractNumber(MathData const & ar, int & i)
 {
index 199295ae960511a633e0e2440feae16922b55609..fba3ecbe9e708a52d3850d7aaa84d4383b7be82d 100644 (file)
@@ -16,6 +16,7 @@
 
 namespace lyx {
 
+class HtmlStream;
 class NormalStream;
 class MapleStream;
 class MaximaStream;
@@ -26,6 +27,7 @@ class WriteStream;
 class MathData;
 
 void write(MathData const &, WriteStream &);
+void htmlize(MathData const &, HtmlStream &);
 void normalize(MathData const &, NormalStream &);
 void maple(MathData const &, MapleStream &);
 void maxima(MathData const &, MaximaStream &);
index 2d2be812548389c7b218181018f50967dfce0637..bcd7160bc02cfdccdcce43a974ad23deea365659 100644 (file)
@@ -346,6 +346,99 @@ MathStream & operator<<(MathStream & ms, docstring const & s)
 }
 
 
+//////////////////////////////////////////////////////////////////////
+
+
+HtmlStream::HtmlStream(odocstream & os)
+       : os_(os), tab_(0), line_(0), lastchar_(0), in_text_(false)
+{}
+
+
+void HtmlStream::defer(docstring const & s)
+{
+       deferred_ << s;
+}
+
+
+void HtmlStream::defer(string const & s)
+{
+       deferred_ << from_utf8(s);
+}
+
+
+docstring HtmlStream::deferred() const
+{ 
+       return deferred_.str();
+}
+
+
+HtmlStream & operator<<(HtmlStream & ms, MathAtom const & at)
+{
+       at->htmlize(ms);
+       return ms;
+}
+
+
+HtmlStream & operator<<(HtmlStream & ms, MathData const & ar)
+{
+       htmlize(ar, ms);
+       return ms;
+}
+
+
+HtmlStream & operator<<(HtmlStream & ms, char const * s)
+{
+       ms.os() << s;
+       return ms;
+}
+
+
+HtmlStream & operator<<(HtmlStream & ms, char c)
+{
+       ms.os() << c;
+       return ms;
+}
+
+
+HtmlStream & operator<<(HtmlStream & ms, char_type c)
+{
+       ms.os().put(c);
+       return ms;
+}
+
+
+HtmlStream & operator<<(HtmlStream & ms, MTag const & t)
+{
+       ++ms.tab();
+       ms.os() << "\n";
+       ms.os() << '<' << from_ascii(t.tag_);
+       if (!t.attr_.empty())
+               ms.os() << " " << from_ascii(t.attr_);
+       ms << '>';
+       return ms;
+}
+
+
+HtmlStream & operator<<(HtmlStream & ms, ETag const & t)
+{
+       ms.os() << "\n";
+       if (ms.tab() > 0)
+               --ms.tab();
+       ms.os() << "</" << from_ascii(t.tag_) << '>';
+       return ms;
+}
+
+
+HtmlStream & operator<<(HtmlStream & ms, docstring const & s)
+{
+       ms.os() << s;
+       return ms;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+
+
 SetMode::SetMode(MathStream & os, bool text)
        : os_(os), opened_(false)
 {
index 6fb8f8265fe18b3b45d8458edfa096876fa19871..cf08afe23c5890405a6664fb4ce4617a7bbacf2d 100644 (file)
@@ -352,6 +352,67 @@ private:
 };
 
 
+class HtmlStream {
+public:
+       ///
+       explicit HtmlStream(odocstream & os);
+       ///
+       void cr();
+       ///
+       odocstream & os() { return os_; }
+       ///
+       int line() const { return line_; }
+       ///
+       int & tab() { return tab_; }
+       ///
+       friend HtmlStream & operator<<(HtmlStream &, char const *);
+       ///
+       void defer(docstring const &);
+       ///
+       void defer(std::string const &);
+       ///
+       docstring deferred() const;
+       ///
+       bool inText() const { return in_text_; }
+private:
+       ///
+       void setTextMode() { in_text_ = true; }
+       ///
+       void setMathMode() { in_text_ = false; }
+       ///
+       odocstream & os_;
+       ///
+       int tab_;
+       ///
+       int line_;
+       ///
+       char lastchar_;
+       ///
+       bool in_text_;
+       ///
+       odocstringstream deferred_;
+       ///
+       friend class SetMode;
+};
+
+///
+HtmlStream & operator<<(HtmlStream &, MathAtom const &);
+///
+HtmlStream & operator<<(HtmlStream &, MathData const &);
+///
+HtmlStream & operator<<(HtmlStream &, docstring const &);
+///
+HtmlStream & operator<<(HtmlStream &, char const *);
+///
+HtmlStream & operator<<(HtmlStream &, char);
+///
+HtmlStream & operator<<(HtmlStream &, char_type);
+///
+HtmlStream & operator<<(HtmlStream &, MTag const &);
+///
+HtmlStream & operator<<(HtmlStream &, ETag const &);
+
+
 //
 // Debugging
 //