The beginnings of pure HTML output of math, for our internal XHTML

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
This commit is contained in:
Richard Heck 2010-03-29 22:52:13 +00:00
parent c6721161b0
commit 30b18aec37
9 changed files with 248 additions and 13 deletions

View 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 HullType InsetMath::getType() const
{ {
return hullNone; return hullNone;

View File

@ -73,6 +73,7 @@ class InsetMathUnknown;
class InsetMathRef; class InsetMathRef;
class HtmlStream;
class NormalStream; class NormalStream;
class OctaveStream; class OctaveStream;
class MapleStream; class MapleStream;
@ -186,8 +187,13 @@ public:
virtual void maxima(MaximaStream &) const; virtual void maxima(MaximaStream &) const;
/// write content as something readable by Mathematica /// write content as something readable by Mathematica
virtual void mathematica(MathematicaStream &) const; virtual void mathematica(MathematicaStream &) const;
/// write content as something resembling MathML /// write content as MathML
virtual void mathmlize(MathStream &) const; 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 /// write content as something readable by Octave
virtual void octave(OctaveStream &) const; virtual void octave(OctaveStream &) const;

View 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 void InsetMathGrid::write(WriteStream & os) const
{ {
write(os, 0, 0, nrows(), ncols()); write(os, 0, 0, nrows(), ncols());

View File

@ -223,6 +223,8 @@ public:
/// ///
void mathmlize(MathStream &) const; void mathmlize(MathStream &) const;
/// ///
void htmlize(HtmlStream &) const;
///
//void octave(OctaveStream &) const; //void octave(OctaveStream &) const;
protected: protected:

View File

@ -1810,14 +1810,38 @@ int InsetMathHull::docbook(odocstream & os, OutputParams const & runparams) cons
docstring InsetMathHull::xhtml(XHTMLStream & xs, OutputParams const &) const docstring InsetMathHull::xhtml(XHTMLStream & xs, OutputParams const &) const
{ {
if (getType() == hullSimple) BufferParams::MathOutput mathtype = buffer().params().html_math_output;
xs << html::StartTag("math", "xmlns=\"http://www.w3.org/1998/Math/MathML\"", true); // FIXME Eventually we would like to do this inset by inset.
else switch (mathtype) {
xs << html::StartTag("math", case BufferParams::MathML: {
"display=\"block\" xmlns=\"http://www.w3.org/1998/Math/MathML\"", true); if (getType() == hullSimple)
MathStream ms(xs.os()); xs << html::StartTag("math",
InsetMathGrid::mathmlize(ms); "xmlns=\"http://www.w3.org/1998/Math/MathML\"", true);
xs << html::EndTag("math"); 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(); return docstring();
} }

View File

@ -54,6 +54,7 @@ namespace lyx {
namespace { namespace {
enum ExternalMath { enum ExternalMath {
HTML,
MAPLE, MAPLE,
MAXIMA, MAXIMA,
MATHEMATICA, MATHEMATICA,
@ -120,7 +121,7 @@ MathData::iterator extractArgument(MathData & ar,
// leave out delimiters if this is a function argument // leave out delimiters if this is a function argument
// unless we are doing MathML, in which case we do want // unless we are doing MathML, in which case we do want
// the delimiters // the delimiters
if (function && kind != MATHML) { if (function && kind != MATHML && kind != HTML) {
MathData const & arg = (*pos)->asDelimInset()->cell(0); MathData const & arg = (*pos)->asDelimInset()->cell(0);
MathData::const_iterator cur = arg.begin(); MathData::const_iterator cur = arg.begin();
MathData::const_iterator end = arg.end(); MathData::const_iterator end = arg.end();
@ -948,16 +949,16 @@ void extractLims(MathData & ar)
void extractStructure(MathData & ar, ExternalMath kind) void extractStructure(MathData & ar, ExternalMath kind)
{ {
//lyxerr << "\nStructure from: " << ar << endl; //lyxerr << "\nStructure from: " << ar << endl;
if (kind != MATHML) if (kind != MATHML && kind != HTML)
splitScripts(ar); splitScripts(ar);
extractDelims(ar); extractDelims(ar);
extractIntegrals(ar, kind); extractIntegrals(ar, kind);
if (kind != MATHML) if (kind != MATHML && kind != HTML)
extractSums(ar); extractSums(ar);
extractNumbers(ar); extractNumbers(ar);
extractMatrices(ar); extractMatrices(ar);
extractFunctions(ar, kind); extractFunctions(ar, kind);
if (kind != MATHML) { if (kind != MATHML && kind != HTML) {
extractDets(ar); extractDets(ar);
extractDiff(ar); extractDiff(ar);
extractExps(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 // convert this inset somehow to a number
bool extractNumber(MathData const & ar, int & i) bool extractNumber(MathData const & ar, int & i)
{ {

View File

@ -16,6 +16,7 @@
namespace lyx { namespace lyx {
class HtmlStream;
class NormalStream; class NormalStream;
class MapleStream; class MapleStream;
class MaximaStream; class MaximaStream;
@ -26,6 +27,7 @@ class WriteStream;
class MathData; class MathData;
void write(MathData const &, WriteStream &); void write(MathData const &, WriteStream &);
void htmlize(MathData const &, HtmlStream &);
void normalize(MathData const &, NormalStream &); void normalize(MathData const &, NormalStream &);
void maple(MathData const &, MapleStream &); void maple(MathData const &, MapleStream &);
void maxima(MathData const &, MaximaStream &); void maxima(MathData const &, MaximaStream &);

View 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) SetMode::SetMode(MathStream & os, bool text)
: os_(os), opened_(false) : os_(os), opened_(false)
{ {

View 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 // Debugging
// //