]> git.lyx.org Git - lyx.git/blob - src/insets/InsetSpecialChar.cpp
* src/paragraph_funcs.cpp (breakParagraph): change parameter 'flag' to
[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         setDimCache(mi, dim);
65 }
66
67
68 void InsetSpecialChar::draw(PainterInfo & pi, int x, int y) const
69 {
70         Font font = pi.base.font;
71
72         switch (kind_) {
73         case HYPHENATION:
74         {
75                 font.setColor(Color::special);
76                 pi.pain.text(x, y, char_type('-'), font);
77                 break;
78         }
79         case LIGATURE_BREAK:
80         {
81                 font.setColor(Color::special);
82                 pi.pain.text(x, y, char_type('|'), font);
83                 break;
84         }
85         case END_OF_SENTENCE:
86         {
87                 font.setColor(Color::special);
88                 pi.pain.text(x, y, char_type('.'), font);
89                 break;
90         }
91         case LDOTS:
92         {
93                 font.setColor(Color::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                 frontend::FontMetrics const & fm =
102                         theFontMetrics(font);
103
104                 // A triangle the width and height of an 'x'
105                 int w = fm.width(char_type('x'));
106                 int ox = fm.width(char_type(' ')) + x;
107                 int h = fm.ascent(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, Color::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 &, Lexer & 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                 return 0;
199         case END_OF_SENTENCE:
200                 os << '.';
201                 return 1;
202         case LDOTS:
203                 os << "...";
204                 return 3;
205         case MENU_SEPARATOR:
206                 os << "->";
207                 return 2;
208         }
209         return 0;
210 }
211
212
213 int InsetSpecialChar::docbook(Buffer const &, odocstream & 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 Inset * InsetSpecialChar::clone() const
242 {
243         return 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 bool InsetSpecialChar::isChar() const
255 {
256         return true;
257 }
258
259
260 bool InsetSpecialChar::isLetter() const
261 {
262         return kind_ == HYPHENATION || kind_ == LIGATURE_BREAK;
263 }
264
265
266 bool InsetSpecialChar::isLineSeparator() const
267 {
268 #if 0
269         // this would be nice, but it does not work, since
270         // Paragraph::stripLeadingSpaces nukes the characters which
271         // have this property. I leave the code here, since it should
272         // eventually be made to work. (JMarc 20020327)
273         return kind_ == HYPHENATION || kind_ == MENU_SEPARATOR;
274 #else
275         return false;
276 #endif
277 }
278
279
280 } // namespace lyx