]> git.lyx.org Git - lyx.git/blob - src/output_docbook.C
Fix bug 2195: Slowness in rendering inside insets, especially on the Mac
[lyx.git] / src / output_docbook.C
1 /**
2  * \file output_docbook.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Lars Gullik Bjønnes
7  * \author José Matos
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "output_docbook.h"
15
16 #include "buffer.h"
17 #include "buffer_funcs.h"
18 #include "bufferparams.h"
19 #include "counters.h"
20 #include "debug.h"
21 #include "paragraph.h"
22 #include "paragraph_funcs.h"
23 #include "ParagraphList_fwd.h"
24 #include "ParagraphParameters.h"
25 #include "sgml.h"
26
27 #include "insets/insetcommand.h"
28
29 #include "support/lstrings.h"
30 #include "support/lyxlib.h"
31 #include "support/convert.h"
32 #include "support/types.h"
33
34 #ifdef HAVE_LOCALE
35 #endif
36
37 using lyx::pos_type;
38 using lyx::support::subst;
39
40 using std::endl;
41 using std::ostream;
42 using std::vector;
43 using std::string;
44
45 namespace {
46
47 ParagraphList::const_iterator searchParagraph(ParagraphList::const_iterator const & par,
48                                               ParagraphList::const_iterator const & pend)
49 {
50         ParagraphList::const_iterator p = par + 1;
51
52         for( ; p != pend && p->layout()->latextype == LATEX_PARAGRAPH; ++p);
53
54         return p;
55 }
56
57
58 ParagraphList::const_iterator searchCommand(ParagraphList::const_iterator const & par,
59                                             ParagraphList::const_iterator const & pend)
60 {
61         LyXLayout_ptr const & bstyle = par->layout();
62         ParagraphList::const_iterator p = par + 1;
63
64         for( ; p != pend; ++p) {
65                 LyXLayout_ptr const & style = p->layout();
66                 if( style->latextype == LATEX_COMMAND && style->commanddepth <= bstyle->commanddepth)
67                         return p;
68         }
69         return pend;
70 }
71
72
73 ParagraphList::const_iterator searchEnvironment(ParagraphList::const_iterator const & par,
74                                                 ParagraphList::const_iterator const & pend)
75 {
76         LyXLayout_ptr const & bstyle = par->layout();
77         ParagraphList::const_iterator p = par + 1;
78         for( ; p != pend; ++p) {
79                 LyXLayout_ptr const & style = p->layout();
80                 if( style->latextype == LATEX_COMMAND)
81                         return p;
82
83                 if( style->latextype == LATEX_PARAGRAPH) {
84                         if (p->params().depth() > par->params().depth())
85                                 continue;
86                         return p;
87                 }
88
89                 if(p->params().depth() < par->params().depth())
90                         return p;
91
92                 if( style->latexname() != bstyle->latexname() && p->params().depth() == par->params().depth() )
93                         return p;
94         }
95         return pend;
96 }
97
98
99 ParagraphList::const_iterator makeParagraph(Buffer const & buf,
100                                             ostream & os,
101                                             OutputParams const & runparams,
102                                             ParagraphList const & paragraphs,
103                                             ParagraphList::const_iterator const & pbegin,
104                                             ParagraphList::const_iterator const & pend)
105 {
106         LyXLayout_ptr const & defaultstyle = buf.params().getLyXTextClass().defaultLayout();
107         for(ParagraphList::const_iterator par = pbegin; par != pend; ++par) {
108                 if (par != pbegin)
109                         os << '\n';
110                 if (par->layout() == defaultstyle && par->emptyTag()) {
111                         par->simpleDocBookOnePar(buf, os, runparams, outerFont(par - paragraphs.begin(), paragraphs));
112                 } else {
113                         sgml::openTag(buf, os, runparams, *par);
114                         par->simpleDocBookOnePar(buf, os, runparams, outerFont(par - paragraphs.begin(), paragraphs));
115                         sgml::closeTag(os, *par);
116                 }
117         }
118         return pend;
119 }
120
121
122 ParagraphList::const_iterator makeEnvironment(Buffer const & buf,
123                                               ostream & os,
124                                               OutputParams const & runparams,
125                                               ParagraphList const & paragraphs,
126                                               ParagraphList::const_iterator const & pbegin,
127                                               ParagraphList::const_iterator const & pend) {
128         ParagraphList::const_iterator par = pbegin;
129
130         LyXLayout_ptr const & defaultstyle = buf.params().getLyXTextClass().defaultLayout();
131         LyXLayout_ptr const & bstyle = par->layout();
132         string item_tag;
133
134         // Opening outter tag
135         sgml::openTag(buf, os, runparams, *pbegin);
136         os << '\n';
137         if (bstyle->latextype == LATEX_ENVIRONMENT && bstyle->pass_thru)
138                 os << "<![CDATA[";
139
140         while (par != pend) {
141                 LyXLayout_ptr const & style = par->layout();
142                 ParagraphList::const_iterator send;
143                 string id = par->getID(buf, runparams);
144                 string wrapper = "";
145                 pos_type sep = 0;
146
147                 // Opening inner tag
148                 switch (bstyle->latextype) {
149                 case LATEX_ENVIRONMENT:
150                         if (!bstyle->innertag().empty()) {
151                                 sgml::openTag(os, bstyle->innertag(), id);
152                         }
153                         break;
154
155                 case LATEX_ITEM_ENVIRONMENT:
156                         if (!bstyle->labeltag().empty()) {
157                                 sgml::openTag(os, bstyle->innertag(), id);
158                                 sgml::openTag(os, bstyle->labeltag());
159                                 sep = par->getFirstWord(buf, os, runparams) + 1;
160                                 sgml::closeTag(os, bstyle->labeltag());
161                         }
162                         wrapper = defaultstyle->latexname();
163                         sgml::openTag(os, bstyle->itemtag());
164                 default:
165                         break;
166                 }
167
168                 switch (style->latextype) {
169                 case LATEX_ENVIRONMENT:
170                 case LATEX_ITEM_ENVIRONMENT: {
171                         if(par->params().depth() == pbegin->params().depth()) {
172                                 sgml::openTag(os, wrapper);
173                                 par->simpleDocBookOnePar(buf, os, runparams, outerFont(par - paragraphs.begin(), paragraphs), sep);
174                                 sgml::closeTag(os, wrapper);
175                                 ++par;
176                         }
177                         else {
178                                 send = searchEnvironment(par, pend);
179                                 par = makeEnvironment(buf, os, runparams, paragraphs, par,send);
180                         }
181                         break;
182                 }
183                 case LATEX_PARAGRAPH:
184                         send = searchParagraph(par, pend);
185                         par = makeParagraph(buf, os, runparams, paragraphs, par,send);
186                         break;
187                 default:
188                         break;
189                 }
190
191                 // Closing inner tag
192                 switch (bstyle->latextype) {
193                 case LATEX_ENVIRONMENT:
194                         if (!bstyle->innertag().empty()) {
195                                 sgml::closeTag(os, bstyle->innertag());
196                                 os << '\n';
197                         }
198                         break;
199                 case LATEX_ITEM_ENVIRONMENT:
200                         sgml::closeTag(os, bstyle->itemtag());
201                         if (!bstyle->labeltag().empty())
202                                 sgml::closeTag(os, bstyle->innertag());
203                         break;
204                 default:
205                         break;
206                 }
207         }
208
209         if (bstyle->latextype == LATEX_ENVIRONMENT && bstyle->pass_thru)
210                 os << "]]>";
211
212         // Closing outter tag
213         sgml::closeTag(os, *pbegin);
214
215         return pend;
216 }
217
218
219 ParagraphList::const_iterator makeCommand(Buffer const & buf,
220                                           ostream & os,
221                                           OutputParams const & runparams,
222                                           ParagraphList const & paragraphs,
223                                           ParagraphList::const_iterator const & pbegin,
224                                           ParagraphList::const_iterator const & pend)
225 {
226         ParagraphList::const_iterator par = pbegin;
227         LyXLayout_ptr const & bstyle = par->layout();
228
229         //Open outter tag
230         sgml::openTag(buf, os, runparams, *pbegin);
231         os << '\n';
232
233         // Label around sectioning number:
234         if (!bstyle->labeltag().empty()) {
235                 sgml::openTag(os, bstyle->labeltag());
236                 os << expandLabel(buf, bstyle, false);
237                 sgml::closeTag(os, bstyle->labeltag());
238         }
239
240         // Opend inner tag and  close inner tags
241         sgml::openTag(os, bstyle->innertag());
242         par->simpleDocBookOnePar(buf, os, runparams,  outerFont(par - paragraphs.begin(), paragraphs));
243         sgml::closeTag(os, bstyle->innertag());
244         os << '\n';
245
246         ++par;
247         while (par != pend) {
248                 LyXLayout_ptr const & style = par->layout();
249                 ParagraphList::const_iterator send;
250
251                 switch (style->latextype) {
252                 case LATEX_COMMAND: {
253                         send = searchCommand(par, pend);
254                         par = makeCommand(buf, os, runparams, paragraphs, par,send);
255                         break;
256                 }
257                 case LATEX_ENVIRONMENT:
258                 case LATEX_ITEM_ENVIRONMENT: {
259                         send = searchEnvironment(par, pend);
260                         par = makeEnvironment(buf, os, runparams, paragraphs, par,send);
261                         break;
262                 }
263                 case LATEX_PARAGRAPH:
264                         send = searchParagraph(par, pend);
265                         par = makeParagraph(buf, os, runparams, paragraphs, par,send);
266                         break;
267                 default:
268                         break;
269                 }
270         }
271         // Close outter tag
272         sgml::closeTag(os, *pbegin);
273
274         return pend;
275 }
276
277 } // end anonym namespace
278
279
280 void docbookParagraphs(ParagraphList const & paragraphs,
281                        Buffer const & buf,
282                        ostream & os,
283                        OutputParams const & runparams)
284 {
285         ParagraphList::const_iterator par = paragraphs.begin();
286         ParagraphList::const_iterator pend = paragraphs.end();
287
288         while (par != pend) {
289                 LyXLayout_ptr const & style = par->layout();
290                 ParagraphList::const_iterator send;
291
292                 switch (style->latextype) {
293                 case LATEX_COMMAND: {
294                         send = searchCommand(par, pend);
295                         par = makeCommand(buf, os, runparams, paragraphs, par,send);
296                         break;
297                 }
298                 case LATEX_ENVIRONMENT:
299                 case LATEX_ITEM_ENVIRONMENT: {
300                         send = searchEnvironment(par, pend);
301                         par = makeEnvironment(buf, os, runparams, paragraphs, par,send);
302                         break;
303                 }
304                 case LATEX_PARAGRAPH:
305                         send = searchParagraph(par, pend);
306                         par = makeParagraph(buf, os, runparams, paragraphs, par,send);
307                         break;
308                 default:
309                         break;
310                 }
311         }
312 }