Fix std::string docstream output error

This was made visible by aab1b145a5, since xhtml export for
lib/doc/Additional.lyx caused an exception. However, the cause for this was
already present earlier: All attempts to output a std::string to an
odocstream resulted in trying to change the encoding of the stream instead,
since there is no operator<<(odocstream &, std::string) defined, and an
implicit conversion to SetEnc happened instead.
This is fixed by making the SetEnc constructor explicit and adjusting all
code parts that did not compile anymore after that. The parts of the code
that did use the wrong output operator were the std::string version of
htmlize() from output_xhtml.cpp and all changed parts in the other .cpp files.
I also removed the std::string versions of html::htmlize() and
html::cleanAttr(), since it was difficult to see which encodings were used
with these. Now we are always explcit when using html::cleanAttr() and
html::htmlize().
This commit is contained in:
Georg Baum 2015-10-15 20:52:28 +02:00
parent 8be88f0d5f
commit 79f11f4e7d
9 changed files with 40 additions and 78 deletions

View File

@ -75,7 +75,8 @@ docstring const Length::asDocstring() const
{
odocstringstream os;
if (unit_ != UNIT_NONE)
os << formatFPNumber(val_) << unit_name[unit_]; // setw?
os << from_ascii(formatFPNumber(val_))
<< from_ascii(unit_name[unit_]); // setw?
return os.str();
}

View File

@ -194,7 +194,7 @@ Buffer & Inset::buffer()
string const iname = insetName(lyxCode());
LYXERR0("Inset: " << this << " LyX Code: " << lyxCode()
<< " name: " << iname);
s << "LyX Code: " << lyxCode() << " name: " << iname;
s << "LyX Code: " << lyxCode() << " name: " << from_ascii(iname);
LATTEST(false);
throw ExceptionMessage(BufferException,
from_ascii("Inset::buffer_ member not initialized!"), s.str());

View File

@ -295,8 +295,8 @@ docstring InsetLabel::xhtml(XHTMLStream & xs, OutputParams const &) const
// id here to get the document to validate as XHTML 1.1. This will cause a
// problem with some browsers, though, I'm sure. (Guess which!) So we will
// have to figure out what to do about this later.
string const attr = "id=\"" + html::cleanAttr(to_utf8(getParam("name"))) + "\"";
xs << html::CompTag("a", attr);
docstring const attr = "id=\"" + html::cleanAttr(getParam("name")) + '"';
xs << html::CompTag("a", to_utf8(attr));
return docstring();
}

View File

@ -359,13 +359,13 @@ int InsetPhantom::plaintext(odocstringstream & os,
int InsetPhantom::docbook(odocstream & os, OutputParams const & runparams) const
{
string cmdname;
docstring cmdname;
switch (params_.type) {
case InsetPhantomParams::Phantom:
case InsetPhantomParams::HPhantom:
case InsetPhantomParams::VPhantom:
default:
cmdname = "phantom";
cmdname = from_ascii("phantom");
break;
}
os << "<" + cmdname + ">";

View File

@ -244,8 +244,8 @@ docstring InsetRef::xhtml(XHTMLStream & xs, OutputParams const & op) const
// FIXME What we'd really like to do is to be able to output some
// appropriate sort of text here. But to do that, we need to associate
// some sort of counter with the label, and we don't have that yet.
string const attr = "href=\"#" + html::cleanAttr(to_utf8(ref)) + "\"";
xs << html::StartTag("a", attr);
docstring const attr = "href=\"#" + html::cleanAttr(ref) + '"';
xs << html::StartTag("a", to_utf8(attr));
xs << display_string;
xs << html::EndTag("a");
return docstring();

View File

@ -362,13 +362,13 @@ int InsetScript::plaintext(odocstringstream & os,
int InsetScript::docbook(odocstream & os, OutputParams const & runparams) const
{
string cmdname;
docstring cmdname;
switch (params_.type) {
case InsetScriptParams::Subscript:
cmdname = "subscript";
cmdname = from_ascii("subscript");
break;
case InsetScriptParams::Superscript:
cmdname = "superscript";
cmdname = from_ascii("superscript");
break;
}
os << '<' + cmdname + '>';

View File

@ -85,53 +85,10 @@ docstring htmlize(docstring const & str, XHTMLStream::EscapeSettings e)
}
string escapeChar(char c, XHTMLStream::EscapeSettings e)
docstring escapeChar(char c, XHTMLStream::EscapeSettings e)
{
string str;
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, XHTMLStream::EscapeSettings e)
{
ostringstream d;
string::const_iterator it = str.begin();
string::const_iterator en = str.end();
for (; it != en; ++it)
d << escapeChar(*it, e);
return d.str();
}
string cleanAttr(string const & str)
{
string newname;
string::const_iterator it = str.begin();
string::const_iterator en = str.end();
for (; it != en; ++it)
newname += isAlnumASCII(*it) ? *it : '_';
return newname;
LATTEST(static_cast<unsigned char>(c) < 0x80);
return escapeChar(static_cast<char_type>(c), e);
}
@ -150,11 +107,11 @@ docstring cleanAttr(docstring const & str)
docstring StartTag::writeTag() const
{
string output = "<" + tag_;
docstring output = '<' + from_utf8(tag_);
if (!attr_.empty())
output += " " + html::htmlize(attr_, XHTMLStream::ESCAPE_NONE);
output += ' ' + html::htmlize(from_utf8(attr_), XHTMLStream::ESCAPE_NONE);
output += ">";
return from_utf8(output);
return output;
}
@ -193,11 +150,11 @@ docstring ParTag::writeTag() const
docstring CompTag::writeTag() const
{
string output = "<" + tag_;
docstring output = '<' + from_utf8(tag_);
if (!attr_.empty())
output += " " + html::htmlize(attr_, XHTMLStream::ESCAPE_NONE);
output += ' ' + html::htmlize(from_utf8(attr_), XHTMLStream::ESCAPE_NONE);
output += " />";
return from_utf8(output);
return output;
}

View File

@ -41,8 +41,8 @@ struct StartTag
///
explicit StartTag(std::string const & tag) : tag_(tag), keepempty_(false) {}
///
explicit StartTag(std::string const & tag, std::string const & attr,
bool keepempty = false)
explicit StartTag(std::string const & tag, std::string const & attr,
bool keepempty = false)
: tag_(tag), attr_(attr), keepempty_(keepempty) {}
///
virtual ~StartTag() {}
@ -210,10 +210,10 @@ public:
/// because they are "blocked" by open non-font tags on the stack.
bool closeFontTags();
/// call at start of paragraph. sets a mark so we know what tags
/// to close at the end.
/// to close at the end.
void startParagraph(bool keep_empty);
/// call at end of paragraph to clear that mark. note that this
/// will also close any tags still open.
/// will also close any tags still open.
void endParagraph();
///
XHTMLStream & operator<<(docstring const &);
@ -265,11 +265,11 @@ private:
void writeError(std::string const &) const;
///
odocstream & os_;
///
///
EscapeSettings escape_;
// What we would really like to do here is simply use a
// deque<StartTag>. But we want to store both StartTags and
// sub-classes thereof on this stack, which means we run into the
// sub-classes thereof on this stack, which means we run into the
// so-called polymorphic class problem with the STL. We therefore have
// to use a deque<StartTag *>, which leads to the question who will
// own these pointers and how they will be deleted, so we use shared
@ -278,8 +278,8 @@ private:
typedef shared_ptr<html::StartTag> TagPtr;
typedef std::deque<TagPtr> TagDeque;
///
template <typename T>
shared_ptr<T> makeTagPtr(T const & tag)
template <typename T>
shared_ptr<T> makeTagPtr(T const & tag)
{ return shared_ptr<T>(new T(tag)); }
///
TagDeque pending_tags_;
@ -305,12 +305,8 @@ 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, XHTMLStream::EscapeSettings e);
///
std::string htmlize(std::string const & str, XHTMLStream::EscapeSettings e);
///
std::string cleanAttr(std::string const & str);
/// \p c must be ASCII
docstring escapeChar(char c, XHTMLStream::EscapeSettings e);
} // namespace html
} // namespace lyx

View File

@ -85,7 +85,15 @@ typedef odocstream & (*odocstream_manip)(odocstream &);
/// Helper struct for changing stream encoding
struct SetEnc {
SetEnc(std::string const & e) : encoding(e) {}
/**
* It is important that this constructor is explicit.
* Otherwise the attempt to output a std::string to an odocstream
* would compile, but cause a (probably failing) encoding change
* instead of string output (we do not define
* operator<<(odocstream &, std::string) since we want to avoid
* outputting strings with unspecified encoding)
*/
explicit SetEnc(std::string const & e) : encoding(e) {}
std::string encoding;
};