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