]> git.lyx.org Git - lyx.git/blob - src/output_docbook.C
Move counters toward unicode.
[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 #ifdef HAVE_LOCALE
36 #endif
37
38 using lyx::pos_type;
39 using lyx::odocstream;
40 using lyx::support::subst;
41
42 using std::endl;
43 using std::ostream;
44 using std::vector;
45 using std::string;
46
47 namespace {
48
49 ParagraphList::const_iterator searchParagraph(ParagraphList::const_iterator const & par,
50                                               ParagraphList::const_iterator const & pend)
51 {
52         ParagraphList::const_iterator p = boost::next(par);
53
54         for( ; p != pend && p->layout()->latextype == LATEX_PARAGRAPH; ++p);
55
56         return p;
57 }
58
59
60 ParagraphList::const_iterator searchCommand(ParagraphList::const_iterator const & par,
61                                             ParagraphList::const_iterator const & pend)
62 {
63         LyXLayout_ptr const & bstyle = par->layout();
64         ParagraphList::const_iterator p = boost::next(par);
65
66         for( ; p != pend; ++p) {
67                 LyXLayout_ptr const & style = p->layout();
68                 if( style->latextype == LATEX_COMMAND && style->commanddepth <= bstyle->commanddepth)
69                         return p;
70         }
71         return pend;
72 }
73
74
75 ParagraphList::const_iterator searchEnvironment(ParagraphList::const_iterator const & par,
76                                                 ParagraphList::const_iterator const & pend)
77 {
78         LyXLayout_ptr const & bstyle = par->layout();
79         ParagraphList::const_iterator p = boost::next(par);
80         for( ; p != pend; ++p) {
81                 LyXLayout_ptr const & style = p->layout();
82                 if( style->latextype == LATEX_COMMAND)
83                         return p;
84
85                 if( style->latextype == LATEX_PARAGRAPH) {
86                         if (p->params().depth() > par->params().depth())
87                                 continue;
88                         return p;
89                 }
90
91                 if(p->params().depth() < par->params().depth())
92                         return p;
93
94                 if( style->latexname() != bstyle->latexname() && p->params().depth() == par->params().depth() )
95                         return p;
96         }
97         return pend;
98 }
99
100
101 ParagraphList::const_iterator makeParagraph(Buffer const & buf,
102                                             odocstream & os,
103                                             OutputParams const & runparams,
104                                             ParagraphList const & paragraphs,
105                                             ParagraphList::const_iterator const & pbegin,
106                                             ParagraphList::const_iterator const & pend)
107 {
108         LyXLayout_ptr const & defaultstyle = buf.params().getLyXTextClass().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         LyXLayout_ptr const & defaultstyle = buf.params().getLyXTextClass().defaultLayout();
133         LyXLayout_ptr 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                 LyXLayout_ptr 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                         sgml::openTag(os, bstyle->itemtag());
166                 default:
167                         break;
168                 }
169
170                 switch (style->latextype) {
171                 case LATEX_ENVIRONMENT:
172                 case LATEX_ITEM_ENVIRONMENT: {
173                         if(par->params().depth() == pbegin->params().depth()) {
174                                 sgml::openTag(os, wrapper);
175                                 par->simpleDocBookOnePar(buf, os, runparams, outerFont(std::distance(paragraphs.begin(), par), paragraphs), sep);
176                                 sgml::closeTag(os, wrapper);
177                                 ++par;
178                         }
179                         else {
180                                 send = searchEnvironment(par, pend);
181                                 par = makeEnvironment(buf, os, runparams, paragraphs, par,send);
182                         }
183                         break;
184                 }
185                 case LATEX_PARAGRAPH:
186                         send = searchParagraph(par, pend);
187                         par = makeParagraph(buf, os, runparams, paragraphs, par,send);
188                         break;
189                 default:
190                         break;
191                 }
192
193                 // Closing inner tag
194                 switch (bstyle->latextype) {
195                 case LATEX_ENVIRONMENT:
196                         if (!bstyle->innertag().empty()) {
197                                 sgml::closeTag(os, bstyle->innertag());
198                                 os << '\n';
199                         }
200                         break;
201                 case LATEX_ITEM_ENVIRONMENT:
202                         sgml::closeTag(os, bstyle->itemtag());
203                         if (!bstyle->labeltag().empty())
204                                 sgml::closeTag(os, bstyle->innertag());
205                         break;
206                 default:
207                         break;
208                 }
209         }
210
211         if (bstyle->latextype == LATEX_ENVIRONMENT && bstyle->pass_thru)
212                 os << "]]>";
213
214         // Closing outter tag
215         sgml::closeTag(os, *pbegin);
216
217         return pend;
218 }
219
220
221 ParagraphList::const_iterator makeCommand(Buffer const & buf,
222                                           odocstream & os,
223                                           OutputParams const & runparams,
224                                           ParagraphList const & paragraphs,
225                                           ParagraphList::const_iterator const & pbegin,
226                                           ParagraphList::const_iterator const & pend)
227 {
228         ParagraphList::const_iterator par = pbegin;
229         LyXLayout_ptr const & bstyle = par->layout();
230
231         //Open outter tag
232         sgml::openTag(buf, os, runparams, *pbegin);
233         os << '\n';
234
235         // Label around sectioning number:
236         if (!bstyle->labeltag().empty()) {
237                 sgml::openTag(os, bstyle->labeltag());
238                 os << expandLabel(buf, bstyle, false);
239                 sgml::closeTag(os, bstyle->labeltag());
240         }
241
242         // Opend inner tag and  close inner tags
243         sgml::openTag(os, bstyle->innertag());
244         par->simpleDocBookOnePar(buf, os, runparams,  outerFont(std::distance(paragraphs.begin(), par), paragraphs));
245         sgml::closeTag(os, bstyle->innertag());
246         os << '\n';
247
248         ++par;
249         while (par != pend) {
250                 LyXLayout_ptr const & style = par->layout();
251                 ParagraphList::const_iterator send;
252
253                 switch (style->latextype) {
254                 case LATEX_COMMAND: {
255                         send = searchCommand(par, pend);
256                         par = makeCommand(buf, os, runparams, paragraphs, par,send);
257                         break;
258                 }
259                 case LATEX_ENVIRONMENT:
260                 case LATEX_ITEM_ENVIRONMENT: {
261                         send = searchEnvironment(par, pend);
262                         par = makeEnvironment(buf, os, runparams, paragraphs, par,send);
263                         break;
264                 }
265                 case LATEX_PARAGRAPH:
266                         send = searchParagraph(par, pend);
267                         par = makeParagraph(buf, os, runparams, paragraphs, par,send);
268                         break;
269                 default:
270                         break;
271                 }
272         }
273         // Close outter tag
274         sgml::closeTag(os, *pbegin);
275
276         return pend;
277 }
278
279 } // end anonym namespace
280
281
282 void docbookParagraphs(ParagraphList const & paragraphs,
283                        Buffer const & buf,
284                        odocstream & os,
285                        OutputParams const & runparams)
286 {
287         ParagraphList::const_iterator par = paragraphs.begin();
288         ParagraphList::const_iterator pend = paragraphs.end();
289
290         BOOST_ASSERT(runparams.par_begin <= runparams.par_end);
291         // if only part of the paragraphs will be outputed
292         if (runparams.par_begin !=  runparams.par_end) {
293                 par = boost::next(paragraphs.begin(), runparams.par_begin);
294                 pend = boost::next(paragraphs.begin(), runparams.par_end);
295                 // runparams will be passed to nested paragraphs, so
296                 // we have to reset the range parameters.
297                 const_cast<OutputParams&>(runparams).par_begin = 0;
298                 const_cast<OutputParams&>(runparams).par_end = 0;
299         }
300         
301         while (par != pend) {
302                 LyXLayout_ptr const & style = par->layout();
303                 ParagraphList::const_iterator lastpar = par;
304                 ParagraphList::const_iterator send;
305
306                 switch (style->latextype) {
307                 case LATEX_COMMAND: {
308                         send = searchCommand(par, pend);
309                         par = makeCommand(buf, os, runparams, paragraphs, par,send);
310                         break;
311                 }
312                 case LATEX_ENVIRONMENT:
313                 case LATEX_ITEM_ENVIRONMENT: {
314                         send = searchEnvironment(par, pend);
315                         par = makeEnvironment(buf, os, runparams, paragraphs, par,send);
316                         break;
317                 }
318                 case LATEX_PARAGRAPH:
319                         send = searchParagraph(par, pend);
320                         par = makeParagraph(buf, os, runparams, paragraphs, par,send);
321                         break;
322                 default:
323                         break;
324                 }
325                 // makeEnvironment may process more than one paragraphs and bypass pend
326                 if (std::distance(lastpar, par) >= std::distance(lastpar, pend))
327                         break;
328         }
329 }