]> git.lyx.org Git - lyx.git/blob - src/insets/insetspecialchar.C
Introduce wide streams. This fixes the remaining problems of plain text
[lyx.git] / src / insets / insetspecialchar.C
1 /**
2  * \file insetspecialchar.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Asger Alstrup Nielsen
7  * \author Jean-Marc Lasgouttes
8  * \author Lars Gullik Bjønnes
9  *
10  * Full author contact details are available in file CREDITS.
11  */
12
13 #include <config.h>
14
15 #include "insetspecialchar.h"
16
17 #include "debug.h"
18 #include "LaTeXFeatures.h"
19 #include "LColor.h"
20 #include "lyxlex.h"
21 #include "metricsinfo.h"
22
23 #include "frontends/FontMetrics.h"
24 #include "frontends/Painter.h"
25
26 using lyx::docstring;
27
28 using std::string;
29 using std::auto_ptr;
30 using std::ostream;
31
32
33 InsetSpecialChar::InsetSpecialChar(Kind k)
34         : kind_(k)
35 {}
36
37
38 InsetSpecialChar::Kind InsetSpecialChar::kind() const
39 {
40         return kind_;
41 }
42
43
44 void InsetSpecialChar::metrics(MetricsInfo & mi, Dimension & dim) const
45 {
46         lyx::frontend::FontMetrics const & fm =
47                 theFontMetrics(mi.base.font);
48         dim.asc = fm.maxAscent();
49         dim.des = fm.maxDescent();
50
51         string s;
52         switch (kind_) {
53                 case LIGATURE_BREAK:      s = "|";     break;
54                 case END_OF_SENTENCE:     s = ".";     break;
55                 case LDOTS:               s = ". . ."; break;
56                 case MENU_SEPARATOR:      s = " x ";   break;
57                 case HYPHENATION:      s = "-";   break;
58         }
59         docstring ds(s.begin(), s.end());
60         dim.wid = fm.width(ds);
61         if (kind_ == HYPHENATION && dim.wid > 5)
62                 dim.wid -= 2; // to make it look shorter
63         dim_ = dim;
64 }
65
66
67 void InsetSpecialChar::draw(PainterInfo & pi, int x, int y) const
68 {
69         LyXFont font = pi.base.font;
70
71         switch (kind_) {
72         case HYPHENATION:
73         {
74                 font.setColor(LColor::special);
75                 pi.pain.text(x, y, lyx::char_type('-'), font);
76                 break;
77         }
78         case LIGATURE_BREAK:
79         {
80                 font.setColor(LColor::special);
81                 pi.pain.text(x, y, lyx::char_type('|'), font);
82                 break;
83         }
84         case END_OF_SENTENCE:
85         {
86                 font.setColor(LColor::special);
87                 pi.pain.text(x, y, lyx::char_type('.'), font);
88                 break;
89         }
90         case LDOTS:
91         {
92                 font.setColor(LColor::special);
93                 string ell = ". . . ";
94                 docstring dell(ell.begin(), ell.end());
95                 pi.pain.text(x, y, dell, font);
96                 break;
97         }
98         case MENU_SEPARATOR:
99         {
100                 lyx::frontend::FontMetrics const & fm =
101                         theFontMetrics(font);
102
103                 // A triangle the width and height of an 'x'
104                 int w = fm.width(lyx::char_type('x'));
105                 int ox = fm.width(lyx::char_type(' ')) + x;
106                 int h = fm.ascent(lyx::char_type('x'));
107                 int xp[4], yp[4];
108
109                 xp[0] = ox;     yp[0] = y;
110                 xp[1] = ox;     yp[1] = y - h;
111                 xp[2] = ox + w; yp[2] = y - h/2;
112                 xp[3] = ox;     yp[3] = y;
113
114                 pi.pain.lines(xp, yp, 4, LColor::special);
115                 break;
116         }
117         }
118 }
119
120
121 // In lyxf3 this will be just LaTeX
122 void InsetSpecialChar::write(Buffer const &, ostream & os) const
123 {
124         string command;
125         switch (kind_) {
126         case HYPHENATION:
127                 command = "\\-";
128                 break;
129         case LIGATURE_BREAK:
130                 command = "\\textcompwordmark{}";
131                 break;
132         case END_OF_SENTENCE:
133                 command = "\\@.";
134                 break;
135         case LDOTS:
136                 command = "\\ldots{}";
137                 break;
138         case MENU_SEPARATOR:
139                 command = "\\menuseparator";
140                 break;
141         }
142         os << "\\SpecialChar " << command << "\n";
143 }
144
145
146 // This function will not be necessary when lyx3
147 void InsetSpecialChar::read(Buffer const &, LyXLex & lex)
148 {
149         lex.next();
150         string const command = lex.getString();
151
152         if (command == "\\-")
153                 kind_ = HYPHENATION;
154         else if (command == "\\textcompwordmark{}")
155                 kind_ = LIGATURE_BREAK;
156         else if (command == "\\@.")
157                 kind_ = END_OF_SENTENCE;
158         else if (command == "\\ldots{}")
159                 kind_ = LDOTS;
160         else if (command == "\\menuseparator")
161                 kind_ = MENU_SEPARATOR;
162         else
163                 lex.printError("InsetSpecialChar: Unknown kind: `$$Token'");
164 }
165
166
167 int InsetSpecialChar::latex(Buffer const &, ostream & os,
168                             OutputParams const &) const
169 {
170         switch (kind_) {
171         case HYPHENATION:
172                 os << "\\-";
173                 break;
174         case LIGATURE_BREAK:
175                 os << "\\textcompwordmark{}";
176                 break;
177         case END_OF_SENTENCE:
178                 os << "\\@.";
179                 break;
180         case LDOTS:
181                 os << "\\ldots{}";
182                 break;
183         case MENU_SEPARATOR:
184                 os << "\\lyxarrow{}";
185                 break;
186         }
187         return 0;
188 }
189
190
191 int InsetSpecialChar::plaintext(Buffer const &, lyx::odocstream & os,
192                             OutputParams const &) const
193 {
194         switch (kind_) {
195         case HYPHENATION:
196         case LIGATURE_BREAK:
197                 break;
198         case END_OF_SENTENCE:
199                 os << '.';
200                 break;
201         case LDOTS:
202                 os << "...";
203                 break;
204         case MENU_SEPARATOR:
205                 os << "->";
206                 break;
207         }
208         return 0;
209 }
210
211
212 int InsetSpecialChar::docbook(Buffer const &, ostream & os,
213                               OutputParams const &) const
214 {
215         switch (kind_) {
216         case HYPHENATION:
217         case LIGATURE_BREAK:
218                 break;
219         case END_OF_SENTENCE:
220                 os << '.';
221                 break;
222         case LDOTS:
223                 os << "...";
224                 break;
225         case MENU_SEPARATOR:
226                 os << "&lyxarrow;";
227                 break;
228         }
229         return 0;
230 }
231
232
233 int InsetSpecialChar::textString(Buffer const & buf, lyx::odocstream & os,
234                        OutputParams const & op) const
235 {
236         return plaintext(buf, os, op);
237 }
238
239
240 auto_ptr<InsetBase> InsetSpecialChar::doClone() const
241 {
242         return auto_ptr<InsetBase>(new InsetSpecialChar(kind_));
243 }
244
245
246 void InsetSpecialChar::validate(LaTeXFeatures & features) const
247 {
248         if (kind_ == MENU_SEPARATOR) {
249                 features.require("lyxarrow");
250         }
251 }
252
253
254 bool InsetSpecialChar::isChar() const
255 {
256         return true;
257 }
258
259
260 bool InsetSpecialChar::isLetter() const
261 {
262         return kind_ == HYPHENATION || kind_ == LIGATURE_BREAK;
263 }
264
265
266 bool InsetSpecialChar::isLineSeparator() const
267 {
268 #if 0
269         // this would be nice, but it does not work, since
270         // Paragraph::stripLeadingSpaces nukes the characters which
271         // have this property. I leave the code here, since it should
272         // eventually be made to work. (JMarc 20020327)
273         return kind_ == HYPHENATION || kind_ == MENU_SEPARATOR;
274 #else
275         return false;
276 #endif
277 }