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