]> git.lyx.org Git - lyx.git/blob - src/insets/insetspecialchar.C
eecfe288f253bd99cfb27c86719dbd3a70c0ed44
[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/font_metrics.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         LyXFont & font = mi.base.font;
47         dim.asc = font_metrics::maxAscent(font);
48         dim.des = font_metrics::maxDescent(font);
49
50         string s;
51         switch (kind_) {
52                 case LIGATURE_BREAK:      s = "|";     break;
53                 case END_OF_SENTENCE:     s = ".";     break;
54                 case LDOTS:               s = ". . ."; break;
55                 case MENU_SEPARATOR:      s = " x ";   break;
56                 case HYPHENATION:      s = "-";   break;
57         }
58         docstring ds(s.begin(), s.end());
59         dim.wid = font_metrics::width(ds, font);
60         if (kind_ == HYPHENATION && dim.wid > 5)
61                 dim.wid -= 2; // to make it look shorter
62         dim_ = dim;
63 }
64
65
66 void InsetSpecialChar::draw(PainterInfo & pi, int x, int y) const
67 {
68         LyXFont font = pi.base.font;
69
70         switch (kind_) {
71         case HYPHENATION:
72         {
73                 font.setColor(LColor::special);
74                 pi.pain.text(x, y, lyx::char_type('-'), font);
75                 break;
76         }
77         case LIGATURE_BREAK:
78         {
79                 font.setColor(LColor::special);
80                 pi.pain.text(x, y, lyx::char_type('|'), font);
81                 break;
82         }
83         case END_OF_SENTENCE:
84         {
85                 font.setColor(LColor::special);
86                 pi.pain.text(x, y, lyx::char_type('.'), font);
87                 break;
88         }
89         case LDOTS:
90         {
91                 font.setColor(LColor::special);
92                 string ell = ". . . ";
93                 docstring dell(ell.begin(), ell.end());
94                 pi.pain.text(x, y, dell, font);
95                 break;
96         }
97         case MENU_SEPARATOR:
98         {
99                 // A triangle the width and height of an 'x'
100                 int w = font_metrics::width(lyx::char_type('x'), font);
101                 int ox = font_metrics::width(lyx::char_type(' '), font) + x;
102                 int h = font_metrics::ascent(lyx::char_type('x'), font);
103                 int xp[4], yp[4];
104
105                 xp[0] = ox;     yp[0] = y;
106                 xp[1] = ox;     yp[1] = y - h;
107                 xp[2] = ox + w; yp[2] = y - h/2;
108                 xp[3] = ox;     yp[3] = y;
109
110                 pi.pain.lines(xp, yp, 4, LColor::special);
111                 break;
112         }
113         }
114 }
115
116
117 // In lyxf3 this will be just LaTeX
118 void InsetSpecialChar::write(Buffer const &, ostream & os) const
119 {
120         string command;
121         switch (kind_) {
122         case HYPHENATION:
123                 command = "\\-";
124                 break;
125         case LIGATURE_BREAK:
126                 command = "\\textcompwordmark{}";
127                 break;
128         case END_OF_SENTENCE:
129                 command = "\\@.";
130                 break;
131         case LDOTS:
132                 command = "\\ldots{}";
133                 break;
134         case MENU_SEPARATOR:
135                 command = "\\menuseparator";
136                 break;
137         }
138         os << "\\SpecialChar " << command << "\n";
139 }
140
141
142 // This function will not be necessary when lyx3
143 void InsetSpecialChar::read(Buffer const &, LyXLex & lex)
144 {
145         lex.next();
146         string const command = lex.getString();
147
148         if (command == "\\-")
149                 kind_ = HYPHENATION;
150         else if (command == "\\textcompwordmark{}")
151                 kind_ = LIGATURE_BREAK;
152         else if (command == "\\@.")
153                 kind_ = END_OF_SENTENCE;
154         else if (command == "\\ldots{}")
155                 kind_ = LDOTS;
156         else if (command == "\\menuseparator")
157                 kind_ = MENU_SEPARATOR;
158         else
159                 lex.printError("InsetSpecialChar: Unknown kind: `$$Token'");
160 }
161
162
163 int InsetSpecialChar::latex(Buffer const &, ostream & os,
164                             OutputParams const &) const
165 {
166         switch (kind_) {
167         case HYPHENATION:
168                 os << "\\-";
169                 break;
170         case LIGATURE_BREAK:
171                 os << "\\textcompwordmark{}";
172                 break;
173         case END_OF_SENTENCE:
174                 os << "\\@.";
175                 break;
176         case LDOTS:
177                 os << "\\ldots{}";
178                 break;
179         case MENU_SEPARATOR:
180                 os << "\\lyxarrow{}";
181                 break;
182         }
183         return 0;
184 }
185
186
187 int InsetSpecialChar::plaintext(Buffer const &, ostream & os,
188                             OutputParams const &) const
189 {
190         switch (kind_) {
191         case HYPHENATION:
192         case LIGATURE_BREAK:
193                 break;
194         case END_OF_SENTENCE:
195                 os << '.';
196                 break;
197         case LDOTS:
198                 os << "...";
199                 break;
200         case MENU_SEPARATOR:
201                 os << "->";
202                 break;
203         }
204         return 0;
205 }
206
207
208 int InsetSpecialChar::linuxdoc(Buffer const &, ostream & os,
209                                OutputParams const &) const
210 {
211         switch (kind_) {
212         case HYPHENATION:
213         case LIGATURE_BREAK:
214                 break;
215         case END_OF_SENTENCE:
216                 os << '.';
217                 break;
218         case LDOTS:
219                 os << "...";
220                 break;
221         case MENU_SEPARATOR:
222                 os << "&lyxarrow;";
223                 break;
224         }
225         return 0;
226 }
227
228
229 int InsetSpecialChar::docbook(Buffer const &, ostream & os,
230                               OutputParams const &) const
231 {
232         switch (kind_) {
233         case HYPHENATION:
234         case LIGATURE_BREAK:
235                 break;
236         case END_OF_SENTENCE:
237                 os << '.';
238                 break;
239         case LDOTS:
240                 os << "...";
241                 break;
242         case MENU_SEPARATOR:
243                 os << "&lyxarrow;";
244                 break;
245         }
246         return 0;
247 }
248
249
250 int InsetSpecialChar::textString(Buffer const & buf, ostream & os,
251                        OutputParams const & op) const
252 {
253         return plaintext(buf, os, op);
254 }
255
256
257 auto_ptr<InsetBase> InsetSpecialChar::doClone() const
258 {
259         return auto_ptr<InsetBase>(new InsetSpecialChar(kind_));
260 }
261
262
263 void InsetSpecialChar::validate(LaTeXFeatures & features) const
264 {
265         if (kind_ == MENU_SEPARATOR) {
266                 features.require("lyxarrow");
267         }
268 }
269
270
271 bool InsetSpecialChar::isChar() const
272 {
273         return true;
274 }
275
276
277 bool InsetSpecialChar::isLetter() const
278 {
279         return kind_ == HYPHENATION || kind_ == LIGATURE_BREAK;
280 }
281
282
283 bool InsetSpecialChar::isLineSeparator() const
284 {
285 #if 0
286         // this would be nice, but it does not work, since
287         // Paragraph::stripLeadingSpaces nukes the characters which
288         // have this property. I leave the code here, since it should
289         // eventually be made to work. (JMarc 20020327)
290         return kind_ == HYPHENATION || kind_ == MENU_SEPARATOR;
291 #else
292         return false;
293 #endif
294 }