]> git.lyx.org Git - lyx.git/blob - src/texstream.cpp
avoid float-conversion warning and simplify size computation
[lyx.git] / src / texstream.cpp
1 /**
2  * \file texstream.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Enrico Forestieri
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 #include "texstream.h"
14 #include "support/lstrings.h"
15 #include "support/unicode.h"
16
17 #include <algorithm>
18 #include <cerrno>
19 #include <cstdio>
20 #include <cstring>
21 #include <iconv.h>
22 #include <locale>
23
24 using namespace std;
25
26 using lyx::support::contains;
27 using lyx::support::split;
28
29
30 namespace lyx {
31
32 void otexstream::put(char_type const & c)
33 {
34         if (protectspace_) {
35                 if (!canbreakline_ && c == ' ')
36                         os_ << "{}";
37                 protectspace_ = false;
38         }
39         os_.put(c);
40         lastChar(c);
41         if (c == '\n')
42                 texrow_.newline();
43 }
44
45
46 BreakLine breakln;
47 SafeBreakLine safebreakln;
48
49
50 otexstream & operator<<(otexstream & ots, BreakLine)
51 {
52         if (ots.canBreakLine()) {
53                 ots.os().put('\n');
54                 ots.lastChar('\n');
55                 ots.texrow().newline();
56         }
57         ots.protectSpace(false);
58         return ots;
59 }
60
61
62 otexstream & operator<<(otexstream & ots, SafeBreakLine)
63 {
64         if (ots.canBreakLine()) {
65                 ots.os() << "%\n";
66                 ots.lastChar('\n');
67                 ots.texrow().newline();
68         }
69         ots.protectSpace(false);
70         return ots;
71 }
72
73
74 otexstream & operator<<(otexstream & ots, odocstream_manip pf)
75 {
76         ots.os() << pf;
77         if (pf == static_cast<odocstream_manip>(endl)) {
78                 ots.lastChar('\n');
79                 ots.texrow().newline();
80         }
81         return ots;
82 }
83
84
85 otexstream & operator<<(otexstream & ots, docstring const & s)
86 {
87         size_t const len = s.length();
88
89         // Check whether there's something to output
90         if (len == 0)
91                 return ots;
92
93         if (ots.protectSpace()) {
94                 if (!ots.canBreakLine() && s[0] == ' ')
95                         ots.os() << "{}";
96                 ots.protectSpace(false);
97         }
98
99         if (contains(s, 0xF0000)) {
100                 // Some encoding changes for the underlying stream are embedded
101                 // in the docstring. The encoding names to be used are enclosed
102                 // between the code points 0xF0000 and 0xF0001, the first two
103                 // characters of plane 15, which is a Private Use Area whose
104                 // codepoints don't have any associated glyph.
105                 docstring s1;
106                 docstring s2 = split(s, s1, 0xF0000);
107                 while (true) {
108                         if (!s1.empty())
109                                 ots.os() << s1;
110                         if (s2.empty())
111                                 break;
112                         docstring enc;
113                         docstring const s3 = split(s2, enc, 0xF0001);
114                         if (!contains(s2, 0xF0001))
115                                 s2 = split(enc, s1, 0xF0000);
116                         else {
117                                 ots.os() << setEncoding(to_ascii(enc));
118                                 s2 = split(s3, s1, 0xF0000);
119                         }
120                 }
121         } else
122                 ots.os() << s;
123
124         if (len > 1)
125                 ots.canBreakLine(s[len - 2] != '\n');
126         ots.lastChar(s[len - 1]);
127         ots.texrow().newlines(count(s.begin(), s.end(), '\n'));
128         return ots;
129 }
130
131
132 otexstream & operator<<(otexstream & ots, string const & s)
133 {
134         ots << from_utf8(s);
135         return ots;
136 }
137
138
139 otexstream & operator<<(otexstream & ots, char const * s)
140 {
141         ots << from_utf8(s);
142         return ots;
143 }
144
145
146 otexstream & operator<<(otexstream & ots, char c)
147 {
148         if (ots.protectSpace()) {
149                 if (!ots.canBreakLine() && c == ' ')
150                         ots.os() << "{}";
151                 ots.protectSpace(false);
152         }
153         ots.os() << c;
154         ots.lastChar(c);
155         if (c == '\n')
156                 ots.texrow().newline();
157         return ots;
158 }
159
160
161 template <typename Type>
162 otexstream & operator<<(otexstream & ots, Type value)
163 {
164         ots.os() << value;
165         ots.lastChar(0);
166         ots.protectSpace(false);
167         return ots;
168 }
169
170 template otexstream & operator<< <SetEnc>(otexstream & os, SetEnc);
171 template otexstream & operator<< <double>(otexstream &, double);
172 template otexstream & operator<< <int>(otexstream &, int);
173 template otexstream & operator<< <unsigned int>(otexstream &, unsigned int);
174 template otexstream & operator<< <unsigned long>(otexstream &, unsigned long);
175
176 }