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