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