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