}
+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;
class InsetMathRef;
+class HtmlStream;
class NormalStream;
class OctaveStream;
class MapleStream;
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;
}
+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());
//void maple(MapleStream &) const;
///
void mathmlize(MathStream &) const;
+ ///
+ void htmlize(HtmlStream &) const;
///
//void octave(OctaveStream &) const;
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();
}
namespace {
enum ExternalMath {
+ HTML,
MAPLE,
MAXIMA,
MATHEMATICA,
// 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();
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);
}
+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)
{
namespace lyx {
+class HtmlStream;
class NormalStream;
class MapleStream;
class MaximaStream;
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 &);
}
+//////////////////////////////////////////////////////////////////////
+
+
+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)
{
};
+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
//