]> git.lyx.org Git - lyx.git/blob - src/insets/insetcommand.C
3fada648cf056e3c007dcbfe00e06b8fefdf13b2
[lyx.git] / src / insets / insetcommand.C
1 /* This file is part of
2  * ======================================================
3  * 
4  *           LyX, The Document Processor
5  *       
6  *          Copyright 1995 Matthias Ettrich
7  *          Copyright 1995-2000 The LyX Team.
8  *
9  * ====================================================== */
10
11 #include <config.h>
12
13 #ifdef __GNUG__
14 #pragma implementation
15 #endif
16
17 #include "insetcommand.h"
18 #include "debug.h"
19 #include "Painter.h"
20
21 using std::endl;
22
23
24 InsetCommand::InsetCommand()
25 {
26 }
27
28
29 InsetCommand::InsetCommand(string const & cmd, string const & arg, 
30                            string const & opt)
31         : command(cmd), options(opt), contents(arg)
32 {
33 }
34
35
36 int InsetCommand::ascent(Painter & pain, LyXFont const &) const
37 {
38         LyXFont font(LyXFont::ALL_SANE);
39         font.decSize();
40         
41         int width, ascent, descent;
42         string s = getScreenLabel();
43         
44         if (Editable()) {
45                 pain.buttonText(0, 0, s, font,
46                                 false, width, ascent, descent);
47         } else {
48                 pain.rectText(0, 0, s, font,
49                               LColor::commandbg, LColor::commandframe,
50                               false, width, ascent, descent);
51         }
52         return ascent;
53 }
54
55
56 int InsetCommand::descent(Painter & pain, LyXFont const &) const
57 {
58         LyXFont font(LyXFont::ALL_SANE);
59         font.decSize();
60         
61         int width, ascent, descent;
62         string s = getScreenLabel();
63         
64         if (Editable()) {
65                 pain.buttonText(0, 0, s, font,
66                                 false, width, ascent, descent);
67         } else {
68                 pain.rectText(0, 0, s, font,
69                               LColor::commandbg, LColor::commandframe,
70                               false, width, ascent, descent);
71         }
72         return descent;
73 }
74
75
76 int InsetCommand::width(Painter & pain, LyXFont const &) const
77 {
78         LyXFont font(LyXFont::ALL_SANE);
79         font.decSize();
80         
81         int width, ascent, descent;
82         string s = getScreenLabel();
83         
84         if (Editable()) {
85                 pain.buttonText(0, 0, s, font,
86                                 false, width, ascent, descent);
87         } else {
88                 pain.rectText(0, 0, s, font,
89                               LColor::commandbg, LColor::commandframe,
90                               false, width, ascent, descent);
91         }
92         return width + 4;
93 }
94
95
96 void InsetCommand::draw(Painter & pain, LyXFont const &,
97                         int baseline, float & x) const
98 {
99         // Draw it as a box with the LaTeX text
100         LyXFont font(LyXFont::ALL_SANE);
101         font.setColor(LColor::command).decSize();
102
103         int width;
104         string s = getScreenLabel();
105
106         if (Editable()) {
107                 pain.buttonText(int(x)+2, baseline, s, font, true, width);
108         } else {
109                 pain.rectText(int(x)+2, baseline, s, font,
110                               LColor::commandbg, LColor::commandframe,
111                               true, width);
112         }
113
114         x += width + 4;
115 }
116
117
118 // In lyxf3 this will be just LaTeX
119 void InsetCommand::Write(ostream & os) const
120 {
121         os << "LatexCommand " << getCommand() << "\n";
122 }
123
124
125 void InsetCommand::scanCommand(string const & cmd)
126 {
127         string tcommand, toptions, tcontents;
128
129         if (cmd.empty()) return;
130
131         enum { WS, Command, Option, Content } state = WS;
132         
133         // Used to handle things like \command[foo[bar]]{foo{bar}}
134         int nestdepth = 0;
135
136         for (string::size_type i = 0; i < cmd.length(); ++i) {
137                 char c = cmd[i];
138                 if ((state == Command && c == ' ') ||
139                     (state == Command && c == '[') ||
140                     (state == Command && c == '{')) {
141                         state = WS;
142                 }
143                 if ((state == Option  && c == ']') ||
144                     (state == Content && c == '}')) {
145                         if (nestdepth == 0) {
146                                 state = WS;
147                         } else {
148                                 --nestdepth;
149                         }
150                 }
151                 if ((state == Option  && c == '[') ||
152                     (state == Content && c == '{')) {
153                         ++nestdepth;
154                 }
155                 switch (state) {
156                 case Command:   tcommand += c; break;
157                 case Option:    toptions += c; break;
158                 case Content:   tcontents += c; break;
159                 case WS:
160                         if (c == '\\') {
161                                 state = Command;
162                         } else if (c == '[') {
163                                 state = Option;
164                                 nestdepth = 0; // Just to be sure
165                         } else if (c == '{') {
166                                 state = Content;
167                                 nestdepth = 0; // Just to be sure
168                         }
169                         break;
170                 }
171         }
172
173         // Don't mess with this.
174         if (!tcommand.empty()) command = tcommand;
175         if (!toptions.empty()) options = toptions;
176         if (!tcontents.empty()) setContents(tcontents); 
177                         // setContents is overloaded in InsetInclude
178
179         if (lyxerr.debugging(Debug::PARSER))
180                 lyxerr << "Command <" <<  cmd
181                        << "> == <" << getCommand()
182                        << "> == <" << getCmdName()
183                        << '|' << getContents()
184                        << '|' << getOptions() << '>' << endl;
185 }
186
187
188 // This function will not be necessary when lyx3
189 void InsetCommand::Read(LyXLex & lex)
190 {    
191         if (lex.EatLine()) {
192                 string t = lex.GetString();
193                 scanCommand(t);
194         } else
195                 lex.printError("InsetCommand: Parse error: `$$Token'");
196 }
197
198
199 int InsetCommand::Latex(ostream & os, signed char /*fragile*/, bool/*fs*/) const
200 {
201         os << getCommand();
202         return 0;
203 }
204
205
206 int InsetCommand::Linuxdoc(ostream &) const
207 {
208         return 0;
209 }
210
211
212 int InsetCommand::DocBook(ostream &) const
213 {
214         return 0;
215 }
216
217
218 Inset * InsetCommand::Clone() const
219 {
220         return new InsetCommand(command, contents, options);
221 }
222
223
224 string InsetCommand::getCommand() const
225 {       
226         string s;
227         if (!command.empty()) s += "\\"+command;
228         if (!options.empty()) s += "["+options+']';
229         s += "{"+contents+'}';
230         return s;
231 }