]> git.lyx.org Git - lyx.git/blob - src/output_docbook.cpp
Don't show citation engines in the list of modules. They are found under the bibliogr...
[lyx.git] / src / output_docbook.cpp
1 /**
2  * \file output_docbook.cpp
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 "Font.h"
21 #include "Layout.h"
22 #include "OutputParams.h"
23 #include "Paragraph.h"
24 #include "ParagraphList.h"
25 #include "ParagraphParameters.h"
26 #include "sgml.h"
27 #include "Text.h"
28 #include "TextClass.h"
29
30 #include "support/lassert.h"
31 #include "support/debug.h"
32 #include "support/lstrings.h"
33
34 #include <boost/next_prior.hpp>
35
36 using namespace std;
37 using namespace lyx::support;
38
39 namespace lyx {
40
41 namespace {
42
43 ParagraphList::const_iterator searchParagraph(
44         ParagraphList::const_iterator p,
45   ParagraphList::const_iterator const & pend)
46 {
47         for (++p; p != pend && p->layout().latextype == LATEX_PARAGRAPH; ++p)
48                 ;
49
50         return p;
51 }
52
53
54 ParagraphList::const_iterator searchCommand(
55                 ParagraphList::const_iterator p,
56                 ParagraphList::const_iterator const & pend)
57 {
58         Layout const & bstyle = p->layout();
59
60         for (++p; p != pend; ++p) {
61                 Layout const & style = p->layout();
62                 if (style.latextype == LATEX_COMMAND
63                                 && style.commanddepth <= bstyle.commanddepth)
64                         return p;
65         }
66         return pend;
67 }
68
69
70 ParagraphList::const_iterator searchEnvironment(
71                 ParagraphList::const_iterator p,
72                 ParagraphList::const_iterator const & pend)
73 {
74         Layout const & bstyle = p->layout();
75         size_t const depth = p->params().depth();
76         for (++p; p != pend; ++p) {
77                 Layout const & style = p->layout();
78                 if (style.latextype == LATEX_COMMAND)
79                         return p;
80
81                 if (style.latextype == LATEX_PARAGRAPH) {
82                         if (p->params().depth() > depth)
83                                 continue;
84                         return p;
85                 }
86
87                 if (p->params().depth() < depth)
88                         return p;
89
90                 if (style.latexname() != bstyle.latexname()
91                                 && p->params().depth() == depth)
92                         return p;
93         }
94         return pend;
95 }
96
97
98 ParagraphList::const_iterator makeParagraph(Buffer const & buf,
99                                             odocstream & os,
100                                             OutputParams const & runparams,
101                                             Text const & text,
102                                             ParagraphList::const_iterator const & pbegin,
103                                             ParagraphList::const_iterator const & pend)
104 {
105         ParagraphList const & paragraphs = text.paragraphs();
106         for (ParagraphList::const_iterator par = pbegin; par != pend; ++par) {
107                 if (par != pbegin)
108                         os << '\n';
109                 bool const default_or_plain = 
110                         (buf.params().documentClass().isDefaultLayout(par->layout()) 
111                                 || buf.params().documentClass().isPlainLayout(par->layout()));
112                 if (default_or_plain && par->emptyTag()) {
113                         par->simpleDocBookOnePar(buf, os, runparams, 
114                                         text.outerFont(distance(paragraphs.begin(), par)));
115                 } else {
116                         sgml::openTag(buf, os, runparams, *par);
117                         par->simpleDocBookOnePar(buf, os, runparams, 
118                                         text.outerFont(distance(paragraphs.begin(), par)));
119                         sgml::closeTag(os, *par);
120                 }
121         }
122         return pend;
123 }
124
125
126 ParagraphList::const_iterator makeEnvironment(Buffer const & buf,
127                                               odocstream & os,
128                                               OutputParams const & runparams,
129                                               Text const & text,
130                                               ParagraphList::const_iterator const & pbegin,
131                                               ParagraphList::const_iterator const & pend)
132 {
133         ParagraphList const & paragraphs = text.paragraphs();
134         ParagraphList::const_iterator par = pbegin;
135
136         Layout const & defaultstyle = buf.params().documentClass().defaultLayout();
137         Layout const & bstyle = par->layout();
138         string item_tag;
139
140         // Opening outter tag
141         sgml::openTag(buf, os, runparams, *pbegin);
142         os << '\n';
143         if (bstyle.latextype == LATEX_ENVIRONMENT && bstyle.pass_thru)
144                 os << "<![CDATA[";
145
146         while (par != pend) {
147                 Layout const & style = par->layout();
148                 ParagraphList::const_iterator send;
149                 string id = par->getID(buf, runparams);
150                 string wrapper = "";
151                 pos_type sep = 0;
152
153                 // Opening inner tag
154                 switch (bstyle.latextype) {
155                 case LATEX_ENVIRONMENT:
156                         if (!bstyle.innertag().empty()) {
157                                 sgml::openTag(os, bstyle.innertag(), id);
158                         }
159                         break;
160
161                 case LATEX_ITEM_ENVIRONMENT:
162                         if (!bstyle.labeltag().empty()) {
163                                 sgml::openTag(os, bstyle.innertag(), id);
164                                 sgml::openTag(os, bstyle.labeltag());
165                                 sep = par->firstWordDocBook(os, runparams) + 1;
166                                 sgml::closeTag(os, bstyle.labeltag());
167                         }
168                         wrapper = defaultstyle.latexname();
169                         // If a sub list (embedded list) appears next with a
170                         // different depth, then there is no need to open
171                         // another tag at the current depth.
172                         if(par->params().depth() == pbegin->params().depth()) {
173                                 sgml::openTag(os, bstyle.itemtag());
174                         }
175                         break;
176                 default:
177                         break;
178                 }
179
180                 switch (style.latextype) {
181                 case LATEX_ENVIRONMENT:
182                 case LATEX_ITEM_ENVIRONMENT: {
183                         if (par->params().depth() == pbegin->params().depth()) {
184                                 sgml::openTag(os, wrapper);
185                                 par->simpleDocBookOnePar(buf, os, runparams,
186                                         text.outerFont(distance(paragraphs.begin(), par)), sep);
187                                 sgml::closeTag(os, wrapper);
188                                 ++par;
189                         }
190                         else {
191                                 send = searchEnvironment(par, pend);
192                                 par = makeEnvironment(buf, os, runparams, text, par,send);
193                         }
194                         break;
195                 }
196                 case LATEX_PARAGRAPH:
197                         send = searchParagraph(par, pend);
198                         par = makeParagraph(buf, os, runparams, text, par,send);
199                         break;
200                 case LATEX_LIST_ENVIRONMENT:
201                 case LATEX_BIB_ENVIRONMENT:
202                 case LATEX_COMMAND:
203                         // FIXME This means that we are just skipping any paragraph that
204                         // isn't implemented above, and this includes lists.
205                         ++par;
206                         break;
207                 }
208
209                 // Closing inner tag
210                 switch (bstyle.latextype) {
211                 case LATEX_ENVIRONMENT:
212                         if (!bstyle.innertag().empty()) {
213                                 sgml::closeTag(os, bstyle.innertag());
214                                 os << '\n';
215                         }
216                         break;
217                 case LATEX_ITEM_ENVIRONMENT:
218                         // If a sub list (embedded list) appears next, then
219                         // there is no need to close the current tag.
220                         // par should have already been incremented to the next
221                         // element. So we can compare the depth of the next
222                         // element with pbegin.
223                         // We need to be careful, that we don't dereference par
224                         // when par == pend but at the same time that the
225                         // current tag is closed.
226                         if((par != pend && par->params().depth() == pbegin->params().depth()) || par == pend) {
227                                 sgml::closeTag(os, bstyle.itemtag());
228                         }
229                         if (!bstyle.labeltag().empty())
230                                 sgml::closeTag(os, bstyle.innertag());
231                         break;
232                 default:
233                         break;
234                 }
235         }
236
237         if (bstyle.latextype == LATEX_ENVIRONMENT && bstyle.pass_thru)
238                 os << "]]>";
239
240         // Closing outter tag
241         sgml::closeTag(os, *pbegin);
242
243         return pend;
244 }
245
246
247 ParagraphList::const_iterator makeCommand(Buffer const & buf,
248                                           odocstream & os,
249                                           OutputParams const & runparams,
250                                           Text const & text,
251                                           ParagraphList::const_iterator const & pbegin,
252                                           ParagraphList::const_iterator const & pend)
253 {
254         ParagraphList const & paragraphs = text.paragraphs();
255         ParagraphList::const_iterator par = pbegin;
256         Layout const & bstyle = par->layout();
257
258         //Open outter tag
259         sgml::openTag(buf, os, runparams, *pbegin);
260         os << '\n';
261
262         // Label around sectioning number:
263         if (!bstyle.labeltag().empty()) {
264                 sgml::openTag(os, bstyle.labeltag());
265                 // We don't care about appendix in DOCBOOK.
266                 os << par->expandDocBookLabel(bstyle, buf.params());
267                 sgml::closeTag(os, bstyle.labeltag());
268         }
269
270         // Opend inner tag and  close inner tags
271         sgml::openTag(os, bstyle.innertag());
272         par->simpleDocBookOnePar(buf, os, runparams,
273                 text.outerFont(distance(paragraphs.begin(), par)));
274         sgml::closeTag(os, bstyle.innertag());
275         os << '\n';
276
277         ++par;
278         while (par != pend) {
279                 Layout const & style = par->layout();
280                 ParagraphList::const_iterator send;
281
282                 switch (style.latextype) {
283                 case LATEX_COMMAND: {
284                         send = searchCommand(par, pend);
285                         par = makeCommand(buf, os, runparams, text, par,send);
286                         break;
287                 }
288                 case LATEX_ENVIRONMENT:
289                 case LATEX_ITEM_ENVIRONMENT: {
290                         send = searchEnvironment(par, pend);
291                         par = makeEnvironment(buf, os, runparams, text, par,send);
292                         break;
293                 }
294                 case LATEX_PARAGRAPH:
295                         send = searchParagraph(par, pend);
296                         par = makeParagraph(buf, os, runparams, text, par,send);
297                         break;
298                 default:
299                         break;
300                 }
301         }
302         // Close outter tag
303         sgml::closeTag(os, *pbegin);
304
305         return pend;
306 }
307
308 } // end anonym namespace
309
310
311 void docbookParagraphs(Text const & text,
312                        Buffer const & buf,
313                        odocstream & os,
314                        OutputParams const & runparams)
315 {
316         ParagraphList const & paragraphs = text.paragraphs();
317         ParagraphList::const_iterator par = paragraphs.begin();
318         ParagraphList::const_iterator pend = paragraphs.end();
319
320         LASSERT(runparams.par_begin <= runparams.par_end, /**/);
321         // if only part of the paragraphs will be outputed
322         if (runparams.par_begin !=  runparams.par_end) {
323                 par = boost::next(paragraphs.begin(), runparams.par_begin);
324                 pend = boost::next(paragraphs.begin(), runparams.par_end);
325                 // runparams will be passed to nested paragraphs, so
326                 // we have to reset the range parameters.
327                 const_cast<OutputParams&>(runparams).par_begin = 0;
328                 const_cast<OutputParams&>(runparams).par_end = 0;
329         }
330
331         while (par != pend) {
332                 Layout const & style = par->layout();
333                 ParagraphList::const_iterator lastpar = par;
334                 ParagraphList::const_iterator send;
335
336                 switch (style.latextype) {
337                 case LATEX_COMMAND: {
338                         send = searchCommand(par, pend);
339                         par = makeCommand(buf, os, runparams, text, par,send);
340                         break;
341                 }
342                 case LATEX_ENVIRONMENT:
343                 case LATEX_ITEM_ENVIRONMENT: {
344                         send = searchEnvironment(par, pend);
345                         par = makeEnvironment(buf, os, runparams, text, par,send);
346                         break;
347                 }
348                 case LATEX_PARAGRAPH:
349                         send = searchParagraph(par, pend);
350                         par = makeParagraph(buf, os, runparams, text, par,send);
351                         break;
352                 default:
353                         break;
354                 }
355                 // makeEnvironment may process more than one paragraphs and bypass pend
356                 if (distance(lastpar, par) >= distance(lastpar, pend))
357                         break;
358         }
359 }
360
361
362 } // namespace lyx