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