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