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