-void otexstream::put(char_type const & c)
-{
- if (protectspace_) {
- if (!canbreakline_ && c == ' ')
- os_ << "{}";
- protectspace_ = false;
- }
- os_.put(c);
- lastchar_ = c;
- if (c == '\n') {
- texrow_.newline();
- canbreakline_ = false;
- } else
- canbreakline_ = true;
-}
-
-
-BreakLine breakln;
-SafeBreakLine safebreakln;
-
-
-otexstream & operator<<(otexstream & ots, BreakLine)
-{
- if (ots.canBreakLine()) {
- ots.os().put('\n');
- ots.lastChar('\n');
- ots.canBreakLine(false);
- ots.texrow().newline();
- }
- ots.protectSpace(false);
- return ots;
-}
-
-
-otexstream & operator<<(otexstream & ots, SafeBreakLine)
-{
- if (ots.canBreakLine()) {
- ots.os() << "%\n";
- ots.lastChar('\n');
- ots.canBreakLine(false);
- ots.texrow().newline();
- }
- ots.protectSpace(false);
- return ots;
-}
-
-
-otexstream & operator<<(otexstream & ots, odocstream_manip pf)
-{
- ots.os() << pf;
- if (pf == static_cast<odocstream_manip>(endl)) {
- ots.lastChar('\n');
- ots.texrow().newline();
- }
- return ots;
-}
-
-
-otexstream & operator<<(otexstream & ots, docstring const & s)
-{
- size_t const len = s.length();
-
- // Check whether there's something to output
- if (len == 0)
- return ots;
-
- if (ots.protectSpace()) {
- if (!ots.canBreakLine() && s[0] == ' ')
- ots.os() << "{}";
- ots.protectSpace(false);
- }
-
- if (contains(s, 0xF0000)) {
- // Some encoding changes for the underlying stream are embedded
- // in the docstring. The encoding names to be used are enclosed
- // between the code points 0xF0000 and 0xF0001, the first two
- // characters of plane 15, which is a Private Use Area whose
- // codepoints don't have any associated glyph.
- docstring s1;
- docstring s2 = split(s, s1, 0xF0000);
- while (true) {
- if (!s1.empty())
- ots.os() << s1;
- if (s2.empty())
- break;
- docstring enc;
- docstring const s3 = split(s2, enc, 0xF0001);
- if (!contains(s2, 0xF0001))
- s2 = split(enc, s1, 0xF0000);
- else {
- ots.os() << setEncoding(to_ascii(enc));
- s2 = split(s3, s1, 0xF0000);
- }
- }
- } else
- ots.os() << s;
-
- ots.lastChar(s[len - 1]);
- ots.texrow().newlines(count(s.begin(), s.end(), '\n'));
- ots.canBreakLine(s[len - 1] != '\n');
- return ots;
-}
-
-
-otexstream & operator<<(otexstream & ots, string const & s)
-{
- ots << s.c_str();
- return ots;
-}
-
-
-namespace {
-
-int findToken(char const * s, char const * search_token)
-{
- char const * token = strstr(s, search_token);
- if (token)
- return token - s;
- return -1;
-}
-
-} // namespace anon
-
-
-otexstream & operator<<(otexstream & ots, char const * s)
-{
- size_t const len = strlen(s);
-
- // Check whether there's something to output
- if (len == 0)
- return ots;
-
- if (ots.protectSpace()) {
- if (!ots.canBreakLine() && s[0] == ' ')
- ots.os() << "{}";
- ots.protectSpace(false);
- }
-
- char const * start_token = "\xf3\xb0\x80\x80";
- char const * end_token = "\xf3\xb0\x80\x81";
-
- int i = findToken(s, start_token);
-
- if (i >= 0) {
- // Some encoding changes for the underlying stream are embedded
- // in the string. The encoding names to be used are enclosed
- // between the code points 0xF0000 and xF0001 (0xf3b08080 and
- // 0xf3b08081 in utf8 encoding). These codepoints belong to the
- // plane 15 Private Use Area and have no associated glyph.
- string s1(s, i);
- char const * s2 = s + i + 4;
- while (true) {
- if (!s1.empty())
- ots.os() << s1;
- if (s2[0] == '\0')
- break;
- i = findToken(s2, end_token);
- if (i >= 0) {
- ots.os() << setEncoding(string(s2, i));
- s2 += i + 4;
- }
- i = findToken(s2, start_token);
- if (i >= 0) {
- s1 = string(s2, i);
- s2 += i + 4;
- } else {
- s1 = s2;
- s2 += strlen(s2);
- }
- }
- } else
- ots.os() << s;
-
- ots.lastChar(s[len - 1]);
- ots.texrow().newlines(count(s, s + len, '\n'));
- ots.canBreakLine(s[len - 1] != '\n');
- return ots;
-}
-
-
-otexstream & operator<<(otexstream & ots, char c)
-{
- if (ots.protectSpace()) {
- if (!ots.canBreakLine() && c == ' ')
- ots.os() << "{}";
- ots.protectSpace(false);
- }
- ots.os() << c;
- ots.lastChar(c);
- if (c == '\n')
- ots.texrow().newline();
- ots.canBreakLine(c != '\n');
- return ots;
-}
-
-
-template <typename Type>
-otexstream & operator<<(otexstream & ots, Type value)
-{
- ots.os() << value;
- ots.lastChar(0);
- ots.canBreakLine(true);
- ots.protectSpace(false);
- return ots;
-}
-
-template otexstream & operator<< <SetEnc>(otexstream & os, SetEnc);
-template otexstream & operator<< <double>(otexstream &, double);
-template otexstream & operator<< <int>(otexstream &, int);
-template otexstream & operator<< <unsigned int>(otexstream &, unsigned int);
-template otexstream & operator<< <unsigned long>(otexstream &, unsigned long);
-
-}