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