]> git.lyx.org Git - lyx.git/blob - src/insets/InsetSpecialChar.cpp
Inset::addToToc(): change signature. Use DocIterator instead of ParConstIterator...
[lyx.git] / src / insets / InsetSpecialChar.cpp
1 /**
2  * \file InsetSpecialChar.cpp
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 "Dimension.h"
18 #include "LaTeXFeatures.h"
19 #include "Lexer.h"
20 #include "MetricsInfo.h"
21
22 #include "frontends/FontMetrics.h"
23 #include "frontends/Painter.h"
24
25 #include "support/debug.h"
26 #include "support/docstream.h"
27
28 using namespace std;
29
30 namespace lyx {
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         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:
54                         s = "|";
55                         break;
56                 case END_OF_SENTENCE:
57                         s = ".";
58                         break;
59                 case LDOTS:
60                         s = ". . .";
61                         break;
62                 case MENU_SEPARATOR:
63                         s = " x ";
64                         break;
65                 case HYPHENATION:
66                         s = "-";
67                         break;
68                 case SLASH:
69                         s = "/";
70                         break;
71                 case NOBREAKDASH:
72                         s = "-";
73                         break;
74         }
75         docstring ds(s.begin(), s.end());
76         dim.wid = fm.width(ds);
77         if (kind_ == HYPHENATION && dim.wid > 5)
78                 dim.wid -= 2; // to make it look shorter
79         
80         setDimCache(mi, dim);
81 }
82
83
84 void InsetSpecialChar::draw(PainterInfo & pi, int x, int y) const
85 {
86         FontInfo font = pi.base.font;
87
88         switch (kind_) {
89         case HYPHENATION:
90         {
91                 font.setColor(Color_special);
92                 pi.pain.text(x, y, char_type('-'), font);
93                 break;
94         }
95         case LIGATURE_BREAK:
96         {
97                 font.setColor(Color_special);
98                 pi.pain.text(x, y, char_type('|'), font);
99                 break;
100         }
101         case END_OF_SENTENCE:
102         {
103                 font.setColor(Color_special);
104                 pi.pain.text(x, y, char_type('.'), font);
105                 break;
106         }
107         case LDOTS:
108         {
109                 font.setColor(Color_special);
110                 string ell = ". . . ";
111                 docstring dell(ell.begin(), ell.end());
112                 pi.pain.text(x, y, dell, font);
113                 break;
114         }
115         case MENU_SEPARATOR:
116         {
117                 frontend::FontMetrics const & fm =
118                         theFontMetrics(font);
119
120                 // A triangle the width and height of an 'x'
121                 int w = fm.width(char_type('x'));
122                 int ox = fm.width(char_type(' ')) + x;
123                 int h = fm.ascent(char_type('x'));
124                 int xp[4], yp[4];
125
126                 xp[0] = ox;     yp[0] = y;
127                 xp[1] = ox;     yp[1] = y - h;
128                 xp[2] = ox + w; yp[2] = y - h/2;
129                 xp[3] = ox;     yp[3] = y;
130
131                 pi.pain.lines(xp, yp, 4, Color_special);
132                 break;
133         }
134         case SLASH:
135         {
136                 font.setColor(Color_special);
137                 pi.pain.text(x, y, char_type('/'), font);
138                 break;
139         }
140         case NOBREAKDASH:
141         {
142                 font.setColor(Color_latex);
143                 pi.pain.text(x, y, char_type('-'), font);
144                 break;
145         }
146         }
147 }
148
149
150 // In lyxf3 this will be just LaTeX
151 void InsetSpecialChar::write(ostream & os) const
152 {
153         string command;
154         switch (kind_) {
155         case HYPHENATION:
156                 command = "\\-";
157                 break;
158         case LIGATURE_BREAK:
159                 command = "\\textcompwordmark{}";
160                 break;
161         case END_OF_SENTENCE:
162                 command = "\\@.";
163                 break;
164         case LDOTS:
165                 command = "\\ldots{}";
166                 break;
167         case MENU_SEPARATOR:
168                 command = "\\menuseparator";
169                 break;
170         case SLASH:
171                 command = "\\slash{}";
172                 break;
173         case NOBREAKDASH:
174                 command = "\\nobreakdash-";
175                 break;
176         }
177         os << "\\SpecialChar " << command << "\n";
178 }
179
180
181 // This function will not be necessary when lyx3
182 void InsetSpecialChar::read(Lexer & lex)
183 {
184         lex.next();
185         string const command = lex.getString();
186
187         if (command == "\\-")
188                 kind_ = HYPHENATION;
189         else if (command == "\\textcompwordmark{}")
190                 kind_ = LIGATURE_BREAK;
191         else if (command == "\\@.")
192                 kind_ = END_OF_SENTENCE;
193         else if (command == "\\ldots{}")
194                 kind_ = LDOTS;
195         else if (command == "\\menuseparator")
196                 kind_ = MENU_SEPARATOR;
197         else if (command == "\\slash{}")
198                 kind_ = SLASH;
199         else if (command == "\\nobreakdash-")
200                 kind_ = NOBREAKDASH;
201         else
202                 lex.printError("InsetSpecialChar: Unknown kind: `$$Token'");
203 }
204
205
206 int InsetSpecialChar::latex(odocstream & os,
207                             OutputParams const &) const
208 {
209         switch (kind_) {
210         case HYPHENATION:
211                 os << "\\-";
212                 break;
213         case LIGATURE_BREAK:
214                 os << "\\textcompwordmark{}";
215                 break;
216         case END_OF_SENTENCE:
217                 os << "\\@.";
218                 break;
219         case LDOTS:
220                 os << "\\ldots{}";
221                 break;
222         case MENU_SEPARATOR:
223                 os << "\\lyxarrow{}";
224                 break;
225         case SLASH:
226                 os << "\\slash{}";
227                 break;
228         case NOBREAKDASH:
229                 os << "\\nobreakdash-";
230                 break;
231         }
232         return 0;
233 }
234
235
236 int InsetSpecialChar::plaintext(odocstream & os, OutputParams const &) const
237 {
238         switch (kind_) {
239         case HYPHENATION:
240         case LIGATURE_BREAK:
241                 return 0;
242         case END_OF_SENTENCE:
243                 os << '.';
244                 return 1;
245         case LDOTS:
246                 os << "...";
247                 return 3;
248         case MENU_SEPARATOR:
249                 os << "->";
250                 return 2;
251         case SLASH:
252                 os << '/';
253                 return 1;
254         case NOBREAKDASH:
255                 os << '-';
256                 return 1;
257         }
258         return 0;
259 }
260
261
262 int InsetSpecialChar::docbook(odocstream & os, OutputParams const &) const
263 {
264         switch (kind_) {
265         case HYPHENATION:
266         case LIGATURE_BREAK:
267                 break;
268         case END_OF_SENTENCE:
269                 os << '.';
270                 break;
271         case LDOTS:
272                 os << "...";
273                 break;
274         case MENU_SEPARATOR:
275                 os << "&lyxarrow;";
276                 break;
277         case SLASH:
278                 os << '/';
279                 break;
280         case NOBREAKDASH:
281                 os << '-';
282                 break;
283         }
284         return 0;
285 }
286
287
288 void InsetSpecialChar::textString(odocstream & os) const
289 {
290         plaintext(os, OutputParams(0));
291 }
292
293
294 void InsetSpecialChar::validate(LaTeXFeatures & features) const
295 {
296         if (kind_ == MENU_SEPARATOR)
297                 features.require("lyxarrow");
298         if (kind_ == NOBREAKDASH)
299                 features.require("amsmath");
300 }
301
302
303 bool InsetSpecialChar::isChar() const
304 {
305         return true;
306 }
307
308
309 bool InsetSpecialChar::isLetter() const
310 {
311         return kind_ == HYPHENATION || kind_ == LIGATURE_BREAK;
312 }
313
314
315 bool InsetSpecialChar::isLineSeparator() const
316 {
317 #if 0
318         // this would be nice, but it does not work, since
319         // Paragraph::stripLeadingSpaces nukes the characters which
320         // have this property. I leave the code here, since it should
321         // eventually be made to work. (JMarc 20020327)
322         return kind_ == HYPHENATION || kind_ == MENU_SEPARATOR;
323 #else
324         return false;
325 #endif
326 }
327
328
329 } // namespace lyx