]> git.lyx.org Git - lyx.git/blob - src/output_docbook.C
Output docbook as utf8. Probably quite a bit more work needed, but then help form...
[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                 // FIXME UNICODE
239                 os << lyx::from_ascii(expandLabel(buf, bstyle, false));
240                 sgml::closeTag(os, bstyle->labeltag());
241         }
242
243         // Opend inner tag and  close inner tags
244         sgml::openTag(os, bstyle->innertag());
245         par->simpleDocBookOnePar(buf, os, runparams,  outerFont(std::distance(paragraphs.begin(), par), paragraphs));
246         sgml::closeTag(os, bstyle->innertag());
247         os << '\n';
248
249         ++par;
250         while (par != pend) {
251                 LyXLayout_ptr const & style = par->layout();
252                 ParagraphList::const_iterator send;
253
254                 switch (style->latextype) {
255                 case LATEX_COMMAND: {
256                         send = searchCommand(par, pend);
257                         par = makeCommand(buf, os, runparams, paragraphs, par,send);
258                         break;
259                 }
260                 case LATEX_ENVIRONMENT:
261                 case LATEX_ITEM_ENVIRONMENT: {
262                         send = searchEnvironment(par, pend);
263                         par = makeEnvironment(buf, os, runparams, paragraphs, par,send);
264                         break;
265                 }
266                 case LATEX_PARAGRAPH:
267                         send = searchParagraph(par, pend);
268                         par = makeParagraph(buf, os, runparams, paragraphs, par,send);
269                         break;
270                 default:
271                         break;
272                 }
273         }
274         // Close outter tag
275         sgml::closeTag(os, *pbegin);
276
277         return pend;
278 }
279
280 } // end anonym namespace
281
282
283 void docbookParagraphs(ParagraphList const & paragraphs,
284                        Buffer const & buf,
285                        odocstream & os,
286                        OutputParams const & runparams)
287 {
288         ParagraphList::const_iterator par = paragraphs.begin();
289         ParagraphList::const_iterator pend = paragraphs.end();
290
291         BOOST_ASSERT(runparams.par_begin <= runparams.par_end);
292         // if only part of the paragraphs will be outputed
293         if (runparams.par_begin !=  runparams.par_end) {
294                 par = boost::next(paragraphs.begin(), runparams.par_begin);
295                 pend = boost::next(paragraphs.begin(), runparams.par_end);
296                 // runparams will be passed to nested paragraphs, so
297                 // we have to reset the range parameters.
298                 const_cast<OutputParams&>(runparams).par_begin = 0;
299                 const_cast<OutputParams&>(runparams).par_end = 0;
300         }
301         
302         while (par != pend) {
303                 LyXLayout_ptr const & style = par->layout();
304                 ParagraphList::const_iterator lastpar = par;
305                 ParagraphList::const_iterator send;
306
307                 switch (style->latextype) {
308                 case LATEX_COMMAND: {
309                         send = searchCommand(par, pend);
310                         par = makeCommand(buf, os, runparams, paragraphs, par,send);
311                         break;
312                 }
313                 case LATEX_ENVIRONMENT:
314                 case LATEX_ITEM_ENVIRONMENT: {
315                         send = searchEnvironment(par, pend);
316                         par = makeEnvironment(buf, os, runparams, paragraphs, par,send);
317                         break;
318                 }
319                 case LATEX_PARAGRAPH:
320                         send = searchParagraph(par, pend);
321                         par = makeParagraph(buf, os, runparams, paragraphs, par,send);
322                         break;
323                 default:
324                         break;
325                 }
326                 // makeEnvironment may process more than one paragraphs and bypass pend
327                 if (std::distance(lastpar, par) >= std::distance(lastpar, pend))
328                         break;
329         }
330 }