]> git.lyx.org Git - lyx.git/blob - src/tex2lyx/Context.cpp
Hack to display section symbol
[lyx.git] / src / tex2lyx / Context.cpp
1 /**
2  * \file Context.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Jean-Marc Lasgouttes
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 #include "Context.h"
14 #include "Layout.h"
15
16 #include "support/lstrings.h"
17
18 #include <iostream>
19
20 using namespace std;
21 using namespace lyx::support;
22
23 namespace lyx {
24
25 namespace {
26
27 void end_layout(ostream & os)
28 {
29         os << "\n\\end_layout\n";
30 }
31
32
33 void begin_deeper(ostream & os)
34 {
35         os << "\n\\begin_deeper";
36 }
37
38
39 void end_deeper(ostream & os)
40 {
41         os << "\n\\end_deeper";
42 }
43
44 } // namespace
45
46
47 bool operator==(TeXFont const & f1, TeXFont const & f2)
48 {
49         return
50                 f1.size == f2.size &&
51                 f1.family == f2.family &&
52                 f1.series == f2.series &&
53                 f1.shape == f2.shape &&
54                 f1.language == f2.language;
55 }
56
57
58 void output_font_change(ostream & os, TeXFont const & oldfont,
59                         TeXFont const & newfont)
60 {
61         if (oldfont.family != newfont.family)
62                 os << "\n\\family " << newfont.family << '\n';
63         if (oldfont.series != newfont.series)
64                 os << "\n\\series " << newfont.series << '\n';
65         if (oldfont.shape != newfont.shape)
66                 os << "\n\\shape " << newfont.shape << '\n';
67         if (oldfont.size != newfont.size)
68                 os << "\n\\size " << newfont.size << '\n';
69         if (oldfont.language != newfont.language)
70                 os << "\n\\lang " << newfont.language << '\n';
71 }
72
73
74 TeXFont Context::normalfont;
75 bool Context::empty = true;
76
77
78 Context::Context(bool need_layout_,
79                  TeX2LyXDocClass const & textclass_,
80                  Layout const * layout_, Layout const * parent_layout_,
81                  TeXFont const & font_)
82         : need_layout(need_layout_),
83           need_end_layout(false), need_end_deeper(false),
84           has_item(false), in_list_preamble(false), deeper_paragraph(false),
85           new_layout_allowed(true), merging_hyphens_allowed(true),
86           textclass(textclass_),
87           layout(layout_), parent_layout(parent_layout_),
88           font(font_), tablerotation(0), in_table_cell(false), cell_align('c')
89 {
90         if (!layout)
91                 layout = &textclass.defaultLayout();
92         if (!parent_layout)
93                 parent_layout = &textclass.defaultLayout();
94         pass_thru_cmds.clear();
95 }
96
97
98 Context::~Context()
99 {
100         if (!par_extra_stuff.empty())
101                 warning_message("Bug: Ignoring par-level extra stuff '"
102                      + par_extra_stuff + '\'');
103 }
104
105
106 void Context::begin_layout(ostream & os, Layout const * const & l)
107 {
108         os << "\n\\begin_layout " << to_utf8(l->name()) << "\n";
109         if (!extra_stuff.empty()) {
110                 os << extra_stuff;
111         }
112         if (!par_extra_stuff.empty()) {
113                 os << par_extra_stuff;
114                 par_extra_stuff.erase();
115         }
116         // FIXME: This is not enough for things like
117         // \\Huge par1 \\par par2
118         // FIXME: If the document language is not english this outputs a
119         // superfluous language change. Fortunately this is only file format
120         // bloat and does not change the TeX export of LyX.
121         output_font_change(os, normalfont, font);
122 }
123
124
125 void Context::check_layout(ostream & os)
126 {
127         if (need_layout) {
128                 check_end_layout(os);
129
130                 // are we in a list-like environment?
131                 if (layout->isEnvironment()
132                     && layout->latextype != LATEX_ENVIRONMENT) {
133                         // A list-like environment
134                         if (has_item) {
135                                 // a new item. If we had a standard
136                                 // paragraph before, we have to end it.
137                                 if (deeper_paragraph) {
138                                         end_deeper(os);
139                                         deeper_paragraph = false;
140                                 }
141                                 begin_layout(os, layout);
142                                 has_item = false;
143                         } else {
144                                 // A standard paragraph in a list.
145                                 // We have to recognize that this
146                                 // may require a begin_deeper.
147                                 if (!deeper_paragraph)
148                                         begin_deeper(os);
149                                 begin_layout(os, &textclass.defaultLayout());
150                                 deeper_paragraph = true;
151                         }
152                 } else {
153                         // No list-like environment
154                         begin_layout(os, layout);
155                 }
156                 need_layout = false;
157                 need_end_layout = true;
158                 empty = false;
159         }
160 }
161
162
163 void Context::check_end_layout(ostream & os)
164 {
165         if (need_end_layout) {
166                 end_layout(os);
167                 need_end_layout = false;
168         }
169 }
170
171
172 void Context::check_deeper(ostream & os)
173 {
174         if (parent_layout->isEnvironment()) {
175                 // We start a nested environment.
176                 // We need to increase the depth.
177                 if (need_end_deeper) {
178                         // no need to have \end_deeper \begin_deeper
179                         need_end_deeper = false;
180                 } else {
181                         begin_deeper(os);
182                         need_end_deeper = true;
183                 }
184         } else
185                 check_end_deeper(os);
186 }
187
188
189 void Context::check_end_deeper(ostream & os)
190 {
191         if (need_end_deeper) {
192                 end_deeper(os);
193                 need_end_deeper = false;
194         }
195         if (deeper_paragraph) {
196                 end_deeper(os);
197                 deeper_paragraph = false;
198         }
199 }
200
201
202 void Context::set_item()
203 {
204         need_layout = true;
205         has_item = true;
206 }
207
208
209 void Context::new_paragraph(ostream & os)
210 {
211         check_end_layout(os);
212         need_layout = true;
213 }
214
215
216 void Context::add_extra_stuff(string const & stuff)
217 {
218         if (!contains(extra_stuff, stuff))
219                 extra_stuff += stuff;
220 }
221
222
223 void Context::add_par_extra_stuff(string const & stuff)
224 {
225         if (!contains(par_extra_stuff, stuff))
226                 par_extra_stuff += stuff;
227 }
228
229
230 void Context::dump(ostream & os, string const & desc) const
231 {
232         os << "\n" << desc <<" [";
233         if (need_layout)
234                 os << "need_layout ";
235         if (need_end_layout)
236                 os << "need_end_layout ";
237         if (need_end_deeper)
238                 os << "need_end_deeper ";
239         if (has_item)
240                 os << "has_item ";
241         if (deeper_paragraph)
242                 os << "deeper_paragraph ";
243         if (new_layout_allowed)
244                 os << "new_layout_allowed ";
245         if (merging_hyphens_allowed)
246                 os << "merging_hyphens_allowed ";
247         if (!extra_stuff.empty())
248                 os << "extrastuff=[" << extra_stuff << "] ";
249         if (!par_extra_stuff.empty())
250                 os << "parextrastuff=[" << par_extra_stuff << "] ";
251         if (!list_extra_stuff.empty())
252                 os << "listextrastuff=[" << list_extra_stuff << "] ";
253         os << "textclass=" << textclass.name()
254            << " layout=" << to_utf8(layout->name())
255            << " parent_layout=" << to_utf8(parent_layout->name()) << "] font=["
256            << font.size << ' ' << font.family << ' ' << font.series << ' '
257            << font.shape << ']' << endl;
258 }
259
260
261 } // namespace lyx