]> git.lyx.org Git - lyx.git/blob - src/insets/insetspecialchar.C
Rename LatexRunParams::fragile as moving_arg.
[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 "dimension.h"
19 #include "LaTeXFeatures.h"
20 #include "BufferView.h"
21 #include "frontends/Painter.h"
22 #include "frontends/font_metrics.h"
23 #include "lyxlex.h"
24 #include "lyxfont.h"
25
26 using std::ostream;
27 using std::max;
28
29
30 InsetSpecialChar::InsetSpecialChar(Kind k)
31         : kind_(k)
32 {}
33
34
35 InsetSpecialChar::Kind InsetSpecialChar::kind() const
36 {
37         return kind_;
38 }
39
40
41 void InsetSpecialChar::dimension(BufferView *, LyXFont const & font,
42         Dimension & dim) const
43 {
44         dim.a = font_metrics::maxAscent(font);
45         dim.d = font_metrics::maxDescent(font);
46
47         string s;
48         switch (kind_) {
49                 case LIGATURE_BREAK:      s = "|";     break;
50                 case END_OF_SENTENCE:     s = ".";     break;
51                 case LDOTS:               s = ". . ."; break;
52                 case MENU_SEPARATOR:      s = " x ";   break;
53                 case HYPHENATION:      s = "-";   break;
54         }
55         dim.w = font_metrics::width(s, font);
56         if (kind_ == HYPHENATION && dim.w > 5)
57                 dim.w -= 2; // to make it look shorter
58 }
59
60
61 void InsetSpecialChar::draw(BufferView * bv, LyXFont const & f,
62                             int baseline, float & x) const
63 {
64         Painter & pain = bv->painter();
65         LyXFont font(f);
66
67         switch (kind_) {
68         case HYPHENATION:
69         {
70                 font.setColor(LColor::special);
71                 pain.text(int(x), baseline, '-', font);
72                 x += width(bv, font);
73                 break;
74         }
75         case LIGATURE_BREAK:
76         {
77                 font.setColor(LColor::special);
78                 pain.text(int(x), baseline, '|', font);
79                 x += width(bv, font);
80                 break;
81         }
82         case END_OF_SENTENCE:
83         {
84                 font.setColor(LColor::special);
85                 pain.text(int(x), baseline, '.', font);
86                 x += width(bv, font);
87                 break;
88         }
89         case LDOTS:
90         {
91                 font.setColor(LColor::special);
92                 pain.text(int(x), baseline, ". . .", font);
93                 x += width(bv, font);
94                 break;
95         }
96         case MENU_SEPARATOR:
97         {
98                 // A triangle the width and height of an 'x'
99                 int w = font_metrics::width('x', font);
100                 int ox = font_metrics::width(' ', font) + int(x);
101                 int h = font_metrics::ascent('x', font);
102                 int xp[4], yp[4];
103
104                 xp[0] = ox;     yp[0] = baseline;
105                 xp[1] = ox;     yp[1] = baseline - h;
106                 xp[2] = ox + w; yp[2] = baseline - h/2;
107                 xp[3] = ox;     yp[3] = baseline;
108
109                 pain.lines(xp, yp, 4, LColor::special);
110                 x += width(bv, font);
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.nextToken();
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                             LatexRunParams 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::ascii(Buffer const *, ostream & os, int) const
188 {
189         switch (kind_) {
190         case HYPHENATION:
191         case LIGATURE_BREAK:
192                 break;
193         case END_OF_SENTENCE:
194                 os << '.';
195                 break;
196         case LDOTS:
197                 os << "...";
198                 break;
199         case MENU_SEPARATOR:
200                 os << "->";
201                 break;
202         }
203         return 0;
204 }
205
206
207 int InsetSpecialChar::linuxdoc(Buffer const *, ostream & os) const
208 {
209         switch (kind_) {
210         case HYPHENATION:
211         case LIGATURE_BREAK:
212                 break;
213         case END_OF_SENTENCE:
214                 os << '.';
215                 break;
216         case LDOTS:
217                 os << "...";
218                 break;
219         case MENU_SEPARATOR:
220                 os << "&lyxarrow;";
221                 break;
222         }
223         return 0;
224 }
225
226
227 int InsetSpecialChar::docbook(Buffer const *, ostream & os, bool) const
228 {
229         switch (kind_) {
230         case HYPHENATION:
231         case LIGATURE_BREAK:
232                 break;
233         case END_OF_SENTENCE:
234                 os << '.';
235                 break;
236         case LDOTS:
237                 os << "...";
238                 break;
239         case MENU_SEPARATOR:
240                 os << "&lyxarrow;";
241                 break;
242         }
243         return 0;
244 }
245
246
247 Inset * InsetSpecialChar::clone(Buffer const &, bool) const
248 {
249         return new InsetSpecialChar(kind_);
250 }
251
252
253 void InsetSpecialChar::validate(LaTeXFeatures & features) const
254 {
255         if (kind_ == MENU_SEPARATOR) {
256                 features.require("lyxarrow");
257         }
258 }
259
260
261 bool InsetSpecialChar::isChar() const
262 {
263         return true;
264 }
265
266
267 bool InsetSpecialChar::isLetter() const
268 {
269         return kind_ == HYPHENATION || kind_ == LIGATURE_BREAK;
270 }
271
272
273 bool InsetSpecialChar::isSpace() const
274 {
275         return false;
276 }
277
278
279 bool InsetSpecialChar::isLineSeparator() const
280 {
281 #if 0
282         // this would be nice, but it does not work, since
283         // Paragraph::stripLeadingSpaces nukes the characters which
284         // have this property. I leave the code here, since it should
285         // eventually be made to work. (JMarc 20020327)
286         return kind_ == HYPHENATION || kind_ == MENU_SEPARATOR;
287 #else
288         return false;
289 #endif
290 }