Change the escaping mechanism for XHTML output and so allow a fix for

bug #7061.


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@36455 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Richard Heck 2010-11-24 15:27:36 +00:00
parent f3ff65f4df
commit a81bf77314
14 changed files with 92 additions and 96 deletions

View File

@ -2759,7 +2759,7 @@ docstring Paragraph::simpleLyXHTMLOnePar(Buffer const & buf,
// We don't want to escape the entities. Note that
// it is safe to do this, since str can otherwise
// only be "-". E.g., it can't be "<".
xs << XHTMLStream::NextRaw() << str;
xs << XHTMLStream::ESCAPE_NONE << str;
} else
xs << c;
}

View File

@ -976,7 +976,7 @@ docstring InsetBibtex::xhtml(XHTMLStream & xs, OutputParams const &) const
// which will give us all the cross-referenced info. But for every
// entry, so there's a lot of repitition. This should be fixed.
xs << html::StartTag("span", "class='bibtexinfo'")
<< XHTMLStream::NextRaw()
<< XHTMLStream::ESCAPE_AND
<< bibinfo.getInfo(entry.key(), buffer(), true)
<< html::EndTag("span")
<< html::EndTag("div");

View File

@ -207,7 +207,8 @@ inline docstring wrapCitation(docstring const & key,
return content;
// we have to do the escaping here, because we will ultimately
// write this as a raw string, so as not to escape the tags.
return "<a href='#" + key + "'>" + html::htmlize(content) + "</a>";
return "<a href='#" + key + "'>" +
html::htmlize(content, XHTMLStream::ESCAPE_ALL) + "</a>";
}
} // anonymous namespace
@ -533,7 +534,7 @@ docstring InsetCitation::xhtml(XHTMLStream & xs, OutputParams const &) const
return docstring();
// have to output this raw, because generateLabel() will include tags
xs << XHTMLStream::NextRaw() << generateLabel(true);
xs << XHTMLStream::ESCAPE_NONE << generateLabel(true);
return docstring();
}

View File

@ -319,7 +319,7 @@ docstring InsetFloat::xhtml(XHTMLStream & xs, OutputParams const & rp) const
// we can write to the stream.
// Note that things will already have been escaped, so we do not
// want to escape them again.
xs << XHTMLStream::NextRaw() << ods.str();
xs << XHTMLStream::ESCAPE_NONE << ods.str();
return deferred;
}

View File

@ -235,7 +235,7 @@ docstring InsetFloatList::xhtml(XHTMLStream &, OutputParams const &) const {
<< html::StartTag("a", parattr)
// FIXME XHTML
// There ought to be a simple way to customize this.
<< XHTMLStream::NextRaw() << "&gt;"
<< XHTMLStream::ESCAPE_NONE << "&gt;"
<< html::EndTag("a");
xs << html::EndTag("div");
}

View File

@ -792,7 +792,7 @@ docstring InsetPrintIndex::xhtml(XHTMLStream &, OutputParams const & op) const
if (level == 3) {
// another subsubentry
xs << html::StartTag("li", "class='subsubentry'")
<< XHTMLStream::NextRaw() << subsub;
<< XHTMLStream::ESCAPE_NONE << subsub;
} else if (level == 2) {
// there are two ways we can be here:
// (i) we can actually be inside a sub-entry already and be about
@ -806,13 +806,13 @@ docstring InsetPrintIndex::xhtml(XHTMLStream &, OutputParams const & op) const
// have a sub-sub-entry.
if (eit->sub != last.sub)
xs << html::StartTag("li", "class='subentry'")
<< XHTMLStream::NextRaw() << sub;
<< XHTMLStream::ESCAPE_NONE << sub;
if (!subsub.empty()) {
// it's actually a subsubentry, so we need to start that list
xs.cr();
xs << html::StartTag("ul", "class='subsubentry'")
<< html::StartTag("li", "class='subsubentry'")
<< XHTMLStream::NextRaw() << subsub;
<< XHTMLStream::ESCAPE_NONE << subsub;
level = 3;
}
} else {
@ -833,14 +833,14 @@ docstring InsetPrintIndex::xhtml(XHTMLStream &, OutputParams const & op) const
xs.cr();
xs << html::StartTag("ul", "class='subentry'")
<< html::StartTag("li", "class='subentry'")
<< XHTMLStream::NextRaw() << sub;
<< XHTMLStream::ESCAPE_NONE << sub;
level = 2;
if (!subsub.empty()) {
// and a sub-sub-entry
xs.cr();
xs << html::StartTag("ul", "class='subsubentry'")
<< html::StartTag("li", "class='subsubentry'")
<< XHTMLStream::NextRaw() << subsub;
<< XHTMLStream::ESCAPE_NONE << subsub;
level = 3;
}
}

View File

@ -298,7 +298,7 @@ docstring InsetListings::xhtml(XHTMLStream & os, OutputParams const & rp) const
if (isInline) {
out << html::CompTag("br");
// escaping will already have been done
os << XHTMLStream::NextRaw() << ods.str();
os << XHTMLStream::ESCAPE_NONE << ods.str();
} else {
out << html::EndTag("div");
// In this case, this needs to be deferred, but we'll put it

View File

@ -720,7 +720,7 @@ docstring InsetSpace::xhtml(XHTMLStream & xs, OutputParams const &) const
break;
}
// don't escape the entities!
xs << XHTMLStream::NextRaw() << from_ascii(output);
xs << XHTMLStream::ESCAPE_NONE << from_ascii(output);
return docstring();
}

View File

@ -302,13 +302,13 @@ docstring InsetSpecialChar::xhtml(XHTMLStream & xs, OutputParams const &) const
xs << '.';
break;
case LDOTS:
xs << XHTMLStream::NextRaw() << "&hellip;";
xs << XHTMLStream::ESCAPE_NONE << "&hellip;";
break;
case MENU_SEPARATOR:
xs << XHTMLStream::NextRaw() << "&rArr;";
xs << XHTMLStream::ESCAPE_NONE << "&rArr;";
break;
case SLASH:
xs << XHTMLStream::NextRaw() << "&frasl;";
xs << XHTMLStream::ESCAPE_NONE << "&frasl;";
break;
case NOBREAKDASH:
xs << '-';

View File

@ -161,7 +161,7 @@ docstring InsetTOC::xhtml(XHTMLStream &, OutputParams const & op) const
// FIXME XHTML
// There ought to be a simple way to customize this.
// Maybe if we had an InsetLayout for TOC...
xs << XHTMLStream::NextRaw() << "&gt;";
xs << XHTMLStream::ESCAPE_NONE << "&gt;";
xs << html::EndTag("a");
}
for (int i = lastdepth; i > 0; --i)

View File

@ -886,7 +886,7 @@ docstring InsetText::getCaptionHTML(OutputParams const & runparams) const
docstring def = ins->getCaptionAsHTML(xs, runparams);
if (!def.empty())
// should already have been escaped
xs << XHTMLStream::NextRaw() << def << '\n';
xs << XHTMLStream::ESCAPE_NONE << def << '\n';
return ods.str();
}

View File

@ -1889,8 +1889,8 @@ docstring InsetMathHull::xhtml(XHTMLStream & xs, OutputParams const & op) const
"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);
xs << XHTMLStream::NextRaw()
"display=\"block\" xmlns=\"http://www.w3.org/1998/Math/MathML\"", true);
xs << XHTMLStream::ESCAPE_NONE
<< os.str()
<< html::EndTag("math");
}
@ -1904,9 +1904,9 @@ docstring InsetMathHull::xhtml(XHTMLStream & xs, OutputParams const & op) const
if (success) {
string const tag = (getType() == hullSimple) ? "span" : "div";
xs << html::StartTag(tag, "class='formula'", true)
<< XHTMLStream::NextRaw()
<< os.str()
<< html::EndTag(tag);
<< XHTMLStream::ESCAPE_NONE
<< os.str()
<< html::EndTag(tag);
}
}

View File

@ -43,72 +43,78 @@ namespace lyx {
namespace html {
docstring escapeChar(char_type c)
docstring escapeChar(char_type c, XHTMLStream::EscapeSettings e)
{
docstring str;
switch (c) {
case ' ':
str += " ";
break;
case '&':
str += "&amp;";
break;
case '<':
str += "&lt;";
break;
case '>':
str += "&gt;";
break;
default:
switch (e) {
case XHTMLStream::ESCAPE_NONE:
str += c;
break;
case XHTMLStream::ESCAPE_ALL:
if (c == '<') {
str += "&lt;";
break;
} else if (c == '>') {
str += "&gt;";
break;
}
// fall through
case XHTMLStream::ESCAPE_AND:
if (c == '&')
str += "&amp;";
else
str +=c ;
break;
}
return str;
}
// escape what needs escaping
docstring htmlize(docstring const & str) {
docstring htmlize(docstring const & str, XHTMLStream::EscapeSettings e) {
odocstringstream d;
docstring::const_iterator it = str.begin();
docstring::const_iterator en = str.end();
for (; it != en; ++it)
d << escapeChar(*it);
d << escapeChar(*it, e);
return d.str();
}
string escapeChar(char c)
string escapeChar(char c, XHTMLStream::EscapeSettings e)
{
string str;
switch (c) {
case ' ':
str += " ";
break;
case '&':
str += "&amp;";
break;
case '<':
str += "&lt;";
break;
case '>':
str += "&gt;";
break;
default:
switch (e) {
case XHTMLStream::ESCAPE_NONE:
str += c;
break;
case XHTMLStream::ESCAPE_ALL:
if (c == '<') {
str += "&lt;";
break;
} else if (c == '>') {
str += "&gt;";
break;
}
// fall through
case XHTMLStream::ESCAPE_AND:
if (c == '&')
str += "&amp;";
else
str +=c ;
break;
}
return str;
}
// escape what needs escaping
string htmlize(string const & str) {
string htmlize(string const & str, XHTMLStream::EscapeSettings e) {
ostringstream d;
string::const_iterator it = str.begin();
string::const_iterator en = str.end();
for (; it != en; ++it)
d << escapeChar(*it);
d << escapeChar(*it, e);
return d.str();
}
@ -147,7 +153,7 @@ docstring StartTag::asTag() const
{
string output = "<" + tag_;
if (!attr_.empty())
output += " " + html::htmlize(attr_);
output += " " + html::htmlize(attr_, XHTMLStream::ESCAPE_NONE);
output += ">";
return from_utf8(output);
}
@ -171,7 +177,7 @@ docstring CompTag::asTag() const
{
string output = "<" + tag_;
if (!attr_.empty())
output += " " + html::htmlize(attr_);
output += " " + html::htmlize(attr_, XHTMLStream::ESCAPE_NONE);
output += " />";
return from_utf8(output);
}
@ -187,7 +193,7 @@ docstring CompTag::asTag() const
////////////////////////////////////////////////////////////////
XHTMLStream::XHTMLStream(odocstream & os)
: os_(os), nextraw_(false)
: os_(os), escape_(ESCAPE_ALL)
{}
@ -252,11 +258,8 @@ void XHTMLStream::clearTagDeque()
XHTMLStream & XHTMLStream::operator<<(docstring const & d)
{
clearTagDeque();
if (nextraw_) {
os_ << d;
nextraw_ = false;
} else
os_ << html::htmlize(d);
os_ << html::htmlize(d, escape_);
escape_ = ESCAPE_ALL;
return *this;
}
@ -265,11 +268,8 @@ XHTMLStream & XHTMLStream::operator<<(const char * s)
{
clearTagDeque();
docstring const d = from_ascii(s);
if (nextraw_) {
os_ << d;
nextraw_ = false;
} else
os_ << html::htmlize(d);
os_ << html::htmlize(d, escape_);
escape_ = ESCAPE_ALL;
return *this;
}
@ -277,11 +277,8 @@ XHTMLStream & XHTMLStream::operator<<(const char * s)
XHTMLStream & XHTMLStream::operator<<(char_type c)
{
clearTagDeque();
if (nextraw_) {
os_ << c;
nextraw_ = false;
} else
os_ << html::escapeChar(c);
os_ << html::escapeChar(c, escape_);
escape_ = ESCAPE_ALL;
return *this;
}
@ -289,13 +286,8 @@ XHTMLStream & XHTMLStream::operator<<(char_type c)
XHTMLStream & XHTMLStream::operator<<(char c)
{
clearTagDeque();
if (nextraw_) {
os_ << c;
nextraw_ = false;
} else {
string const d = html::escapeChar(c);
os_ << from_ascii(d);
}
string const d = html::escapeChar(c, escape_);
escape_ = ESCAPE_ALL;
return *this;
}
@ -304,14 +296,14 @@ XHTMLStream & XHTMLStream::operator<<(int i)
{
clearTagDeque();
os_ << i;
nextraw_ = false;
escape_ = ESCAPE_ALL;
return *this;
}
XHTMLStream & XHTMLStream::operator<<(NextRaw const &)
XHTMLStream & XHTMLStream::operator<<(EscapeSettings e)
{
nextraw_ = true;
escape_ = e;
return *this;
}
@ -648,7 +640,7 @@ ParagraphList::const_iterator makeParagraphs(Buffer const & buf,
xs.cr();
}
if (!deferred.empty()) {
xs << XHTMLStream::NextRaw() << deferred;
xs << XHTMLStream::ESCAPE_NONE << deferred;
xs.cr();
}
}

View File

@ -117,12 +117,15 @@ public:
XHTMLStream & operator<<(html::EndTag const &);
///
XHTMLStream & operator<<(html::CompTag const &);
/// A trivial struct that functions as a stream modifier.
/// << NextRaw() causes the next string-like thing sent to the
/// stream not to be escaped.
struct NextRaw {};
///
XHTMLStream & operator<<(NextRaw const &);
enum EscapeSettings {
ESCAPE_NONE,
ESCAPE_AND, // meaning &
ESCAPE_ALL // meaning <, >, &, at present
};
/// Sets what we are going to escape on the NEXT write.
/// Everything is reset for the next time.
XHTMLStream & operator<<(EscapeSettings);
private:
///
void clearTagDeque();
@ -143,7 +146,7 @@ private:
/// remembers the history, so we can make sure we nest properly.
TagStack tag_stack_;
///
bool nextraw_;
EscapeSettings escape_;
};
///
@ -158,16 +161,16 @@ std::string alignmentToCSS(LyXAlignment align);
namespace html {
///
docstring escapeChar(char_type c);
docstring escapeChar(char_type c, XHTMLStream::EscapeSettings e);
/// converts a string to a form safe for links, etc
docstring htmlize(docstring const & str);
docstring htmlize(docstring const & str, XHTMLStream::EscapeSettings e);
/// cleans \param str for use as an atttribute by replacing
/// all non-alnum by "_"
docstring cleanAttr(docstring const & str);
///
std::string escapeChar(char c);
std::string escapeChar(char c, XHTMLStream::EscapeSettings e);
///
std::string htmlize(std::string const & str);
std::string htmlize(std::string const & str, XHTMLStream::EscapeSettings e);
///
std::string cleanAttr(std::string const & str);