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