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
{
return hullNone;

View 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;

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
{
write(os, 0, 0, nrows(), ncols());

View File

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

View 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();
}

View 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)
{

View 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 &);

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)
: 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
//