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