]> git.lyx.org Git - lyx.git/blob - src/texstream.cpp
prepare Qt 5.6 builds
[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
33 void otexrowstream::append(docstring const & str, TexRow const & texrow)
34 {
35         os_ << str;
36         texrow_.append(texrow);
37 }
38
39
40 void otexrowstream::put(char_type const & c)
41 {
42         os_.put(c);
43         if (c == '\n')
44                 texrow_.newline();
45 }
46
47
48 void otexstream::put(char_type const & c)
49 {
50         if (protectspace_) {
51                 if (!canbreakline_ && c == ' ')
52                         os() << "{}";
53                 protectspace_ = false;
54         }
55         otexrowstream::put(c);
56         lastChar(c);
57 }
58
59
60 BreakLine breakln;
61 SafeBreakLine safebreakln;
62
63
64 otexstream & operator<<(otexstream & ots, BreakLine)
65 {
66         if (ots.canBreakLine()) {
67                 ots.otexrowstream::put('\n');
68                 ots.lastChar('\n');
69         }
70         ots.protectSpace(false);
71         return ots;
72 }
73
74
75 otexstream & operator<<(otexstream & ots, SafeBreakLine)
76 {
77         otexrowstream & otrs = ots;
78         if (ots.canBreakLine()) {
79                 otrs << "%\n";
80                 ots.lastChar('\n');
81         }
82         ots.protectSpace(false);
83         return ots;
84 }
85
86
87 otexrowstream & operator<<(otexrowstream & ots, odocstream_manip pf)
88 {
89         ots.os() << pf;
90         if (pf == static_cast<odocstream_manip>(endl)) {
91                 ots.texrow().newline();
92         }
93         return ots;
94 }
95
96 otexstream & operator<<(otexstream & ots, odocstream_manip pf)
97 {
98         otexrowstream & otrs = ots;
99         otrs << pf;
100         if (pf == static_cast<odocstream_manip>(endl)) {
101                 ots.lastChar('\n');
102         }
103         return ots;
104 }
105
106
107 otexrowstream & operator<<(otexrowstream & ots, docstring const & s)
108 {
109         ots.os() << s;
110         ots.texrow().newlines(count(s.begin(), s.end(), '\n'));
111         return ots;
112 }
113
114
115 otexstream & operator<<(otexstream & ots, docstring const & s)
116 {
117         size_t const len = s.length();
118
119         // Check whether there's something to output
120         if (len == 0)
121                 return ots;
122         otexrowstream & otrs = ots;
123         if (ots.protectSpace()) {
124                 if (!ots.canBreakLine() && s[0] == ' ')
125                         otrs << "{}";
126                 ots.protectSpace(false);
127         }
128
129         if (contains(s, 0xF0000)) {
130                 // Some encoding changes for the underlying stream are embedded
131                 // in the docstring. The encoding names to be used are enclosed
132                 // between the code points 0xF0000 and 0xF0001, the first two
133                 // characters of plane 15, which is a Private Use Area whose
134                 // codepoints don't have any associated glyph.
135                 docstring s1;
136                 docstring s2 = split(s, s1, 0xF0000);
137                 while (true) {
138                         if (!s1.empty())
139                                 otrs << s1;
140                         if (s2.empty())
141                                 break;
142                         docstring enc;
143                         docstring const s3 = split(s2, enc, 0xF0001);
144                         if (!contains(s2, 0xF0001))
145                                 s2 = split(enc, s1, 0xF0000);
146                         else {
147                                 otrs << setEncoding(to_ascii(enc));
148                                 s2 = split(s3, s1, 0xF0000);
149                         }
150                 }
151         } else
152                 otrs << s;
153
154         if (len > 1)
155                 ots.canBreakLine(s[len - 2] != '\n');
156         ots.lastChar(s[len - 1]);
157         return ots;
158 }
159
160
161 otexrowstream & operator<<(otexrowstream & ots, string const & s)
162 {
163         ots << from_utf8(s);
164         return ots;
165 }
166
167
168 otexstream & operator<<(otexstream & ots, string const & s)
169 {
170         ots << from_utf8(s);
171         return ots;
172 }
173
174
175 otexrowstream & operator<<(otexrowstream & ots, char const * s)
176 {
177         ots << from_utf8(s);
178         return ots;
179 }
180
181
182 otexstream & operator<<(otexstream & ots, char const * s)
183 {
184         ots << from_utf8(s);
185         return ots;
186 }
187
188
189 otexrowstream & operator<<(otexrowstream & ots, char c)
190 {
191         ots.put(c);
192         return ots;
193 }
194
195
196 otexstream & operator<<(otexstream & ots, char c)
197 {
198         ots.put(c);
199         return ots;
200 }
201
202
203 template <typename Type>
204 otexrowstream & operator<<(otexrowstream & ots, Type value)
205 {
206         ots.os() << value;
207         return ots;
208 }
209
210 template otexrowstream & operator<< <SetEnc>(otexrowstream & os, SetEnc);
211 template otexrowstream & operator<< <double>(otexrowstream &, double);
212 template otexrowstream & operator<< <int>(otexrowstream &, int);
213 template otexrowstream & operator<< <unsigned int>(otexrowstream &,
214                                                                                                    unsigned int);
215 template otexrowstream & operator<< <unsigned long>(otexrowstream &,
216                                                                                                         unsigned long);
217
218
219 template <typename Type>
220 otexstream & operator<<(otexstream & ots, Type value)
221 {
222         ots.os() << value;
223         ots.lastChar(0);
224         ots.protectSpace(false);
225         return ots;
226 }
227
228 template otexstream & operator<< <SetEnc>(otexstream & os, SetEnc);
229 template otexstream & operator<< <double>(otexstream &, double);
230 template otexstream & operator<< <int>(otexstream &, int);
231 template otexstream & operator<< <unsigned int>(otexstream &, unsigned int);
232 template otexstream & operator<< <unsigned long>(otexstream &, unsigned long);
233
234 }