]> git.lyx.org Git - lyx.git/blob - src/output_docbook.C
Sanitize ids for SGML/XML.
[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 "bufferparams.h"
18 #include "counters.h"
19 #include "debug.h"
20 #include "lyxtext.h"
21 #include "paragraph.h"
22 #include "paragraph_funcs.h"
23 #include "ParagraphParameters.h"
24 #include "sgml.h"
25
26 #include "insets/insetcommand.h"
27
28 #include "support/lstrings.h"
29 #include "support/lyxlib.h"
30 #include "support/tostr.h"
31 #include "support/types.h"
32
33 #ifdef HAVE_LOCALE
34 #endif
35
36 using lyx::pos_type;
37 using lyx::support::subst;
38
39 using std::endl;
40 using std::ostream;
41 using std::vector;
42 using std::string;
43
44 namespace {
45
46 ParagraphList::const_iterator searchParagraph(ParagraphList::const_iterator const & par,
47                                               ParagraphList::const_iterator const & pend)
48 {
49         ParagraphList::const_iterator p = par + 1;
50
51         for( ; p != pend && p->layout()->latextype == LATEX_PARAGRAPH; ++p);
52
53         return p;
54 }
55
56
57 ParagraphList::const_iterator searchCommand(ParagraphList::const_iterator const & par,
58                                             ParagraphList::const_iterator const & pend)
59 {
60         LyXLayout_ptr const & bstyle = par->layout();
61         ParagraphList::const_iterator p = par + 1;
62
63         for( ; p != pend; ++p) {
64                 LyXLayout_ptr const & style = p->layout();
65                 if( style->latextype == LATEX_COMMAND && style->commanddepth <= bstyle->commanddepth)
66                         return p;
67         }
68         return pend;
69 }
70
71
72 ParagraphList::const_iterator searchEnvironment(ParagraphList::const_iterator const & par,
73                                                 ParagraphList::const_iterator const & pend)
74 {
75         LyXLayout_ptr const & bstyle = par->layout();
76         ParagraphList::const_iterator p = par + 1;
77         for( ; p != pend; ++p) {
78                 LyXLayout_ptr const & style = p->layout();
79                 if( style->latextype == LATEX_COMMAND)
80                         return p;
81
82                 if( style->latextype == LATEX_PARAGRAPH) {
83                         if (p->params().depth() > par->params().depth())
84                                 continue;
85                         return p;
86                 }
87
88                 if(p->params().depth() < par->params().depth())
89                         return p;
90
91                 if( style->latexname() != bstyle->latexname() and p->params().depth() == par->params().depth() )
92                         return p;
93         }
94         return pend;
95 }
96
97
98 ParagraphList::const_iterator makeParagraph(Buffer const & buf,
99                                             ostream & os,
100                                             OutputParams const & runparams,
101                                             ParagraphList const & paragraphs,
102                                             ParagraphList::const_iterator const & pbegin,
103                                             ParagraphList::const_iterator const & pend)
104 {
105         for(ParagraphList::const_iterator par = pbegin; par != pend; ++par) {
106                 sgml::openTag(buf, os, *par);
107                 par->simpleDocBookOnePar(buf, os, runparams, outerFont(par - paragraphs.begin(), paragraphs));
108                 sgml::closeTag(os, *par);
109                 os << '\n';
110         }
111         return pend;
112 }
113
114
115 ParagraphList::const_iterator makeEnvironment(Buffer const & buf,
116                                               ostream & os,
117                                               OutputParams const & runparams,
118                                               ParagraphList const & paragraphs,
119                                               ParagraphList::const_iterator const & pbegin,
120                                               ParagraphList::const_iterator const & pend) {
121         ParagraphList::const_iterator par = pbegin;
122
123         LyXLayout_ptr const & defaultstyle = buf.params().getLyXTextClass().defaultLayout();
124         LyXLayout_ptr const & bstyle = par->layout();
125         string item_tag;
126
127         // Opening outter tag
128         sgml::openTag(buf, os, *pbegin);
129         os << '\n';
130         if (bstyle->latextype == LATEX_ENVIRONMENT and bstyle->innertag() == "CDATA")
131                 os << "<![CDATA[";
132
133         while (par != pend) {
134                 LyXLayout_ptr const & style = par->layout();
135                 ParagraphList::const_iterator send;
136                 string id = par->getID();
137                 string wrapper = "";
138                 pos_type sep = 0;
139
140                 // Opening inner tag
141                 switch (bstyle->latextype) {
142                 case LATEX_ENVIRONMENT:
143                         if (!bstyle->innertag().empty() and bstyle->innertag() != "CDATA") {
144                                 sgml::openTag(os, bstyle->innertag(), id);
145                         }
146                         break;
147
148                 case LATEX_ITEM_ENVIRONMENT:
149                         if (!bstyle->labeltag().empty()) {
150                                 sgml::openTag(os, bstyle->innertag(), id);
151                                 sgml::openTag(os, bstyle->labeltag());
152                                 sep = par->getFirstWord(buf, os, runparams) + 1;
153                                 sgml::closeTag(os, bstyle->labeltag());
154                         }
155                         wrapper = defaultstyle->latexname();
156                         sgml::openTag(os, bstyle->itemtag());
157                 default:
158                         break;
159                 }
160
161                 switch (style->latextype) {
162                 case LATEX_ENVIRONMENT:
163                 case LATEX_ITEM_ENVIRONMENT: {
164                         if(par->params().depth() == pbegin->params().depth()) {
165                                 sgml::openTag(os, wrapper);
166                                 par->simpleDocBookOnePar(buf, os, runparams, outerFont(par - paragraphs.begin(), paragraphs), sep);
167                                 sgml::closeTag(os, wrapper);
168                                 ++par;
169                         }
170                         else {
171                                 send = searchEnvironment(par, pend);
172                                 par = makeEnvironment(buf, os, runparams, paragraphs, par,send);
173                         }
174                         break;
175                 }
176                 case LATEX_PARAGRAPH:
177                         send = searchParagraph(par, pend);
178                         par = makeParagraph(buf, os, runparams, paragraphs, par,send);
179                         break;
180                 default:
181                         break;
182                 }
183
184                 // Closing inner tag
185                 switch (bstyle->latextype) {
186                 case LATEX_ENVIRONMENT:
187                         if (!bstyle->innertag().empty() and bstyle->innertag() != "CDATA") {
188                                 sgml::closeTag(os, bstyle->innertag());
189                                 os << '\n';
190                         }
191                         break;
192                 case LATEX_ITEM_ENVIRONMENT:
193                         sgml::closeTag(os, bstyle->itemtag());
194                         if (!bstyle->labeltag().empty())
195                                 sgml::closeTag(os, bstyle->innertag());
196                         break;
197                 default:
198                         break;
199                 }
200         }
201
202         if (bstyle->latextype == LATEX_ENVIRONMENT and bstyle->innertag() == "CDATA")
203                 os << "]]>";
204
205         // Closing outter tag
206         sgml::closeTag(os, *pbegin);
207
208         return pend;
209 }
210
211
212 ParagraphList::const_iterator makeCommand(Buffer const & buf,
213                                           ostream & os,
214                                           OutputParams const & runparams,
215                                           ParagraphList const & paragraphs,
216                                           ParagraphList::const_iterator const & pbegin,
217                                           ParagraphList::const_iterator const & pend)
218 {
219         ParagraphList::const_iterator par = pbegin;
220         LyXLayout_ptr const & bstyle = par->layout();
221
222         //Open outter tag
223         sgml::openTag(buf, os, *pbegin);
224         os << '\n';
225
226         // Label around sectioning number:
227         if (!bstyle->labeltag().empty()) {
228                 sgml::openTag(os, bstyle->labeltag());
229                 os << expandLabel(buf.params().getLyXTextClass(), bstyle, false);
230                 sgml::closeTag(os, bstyle->labeltag());
231         }
232
233         // Opend inner tag and  close inner tags
234         sgml::openTag(os, bstyle->innertag());
235         par->simpleDocBookOnePar(buf, os, runparams,  outerFont(par - paragraphs.begin(), paragraphs));
236         sgml::closeTag(os, bstyle->innertag());
237         os << '\n';
238
239         ++par;
240         while (par != pend) {
241                 LyXLayout_ptr const & style = par->layout();
242                 ParagraphList::const_iterator send;
243
244                 switch (style->latextype) {
245                 case LATEX_COMMAND: {
246                         send = searchCommand(par, pend);
247                         par = makeCommand(buf, os, runparams, paragraphs, par,send);
248                         break;
249                 }
250                 case LATEX_ENVIRONMENT:
251                 case LATEX_ITEM_ENVIRONMENT: {
252                         send = searchEnvironment(par, pend);
253                         par = makeEnvironment(buf, os, runparams, paragraphs, par,send);
254                         break;
255                 }
256                 case LATEX_PARAGRAPH:
257                         send = searchParagraph(par, pend);
258                         par = makeParagraph(buf, os, runparams, paragraphs, par,send);
259                         break;
260                 default:
261                         break;
262                 }
263         }
264         // Close outter tag
265         sgml::closeTag(os, *pbegin);
266
267         return pend;
268 }
269
270 } // end anonym namespace
271
272
273 void docbookParagraphs(ParagraphList const & paragraphs,
274                        Buffer const & buf,
275                        ostream & os,
276                        OutputParams const & runparams)
277 {
278         ParagraphList::const_iterator par = paragraphs.begin();
279         ParagraphList::const_iterator pend = paragraphs.end();
280
281         while (par != pend) {
282                 LyXLayout_ptr const & style = par->layout();
283                 ParagraphList::const_iterator send;
284
285                 switch (style->latextype) {
286                 case LATEX_COMMAND: {
287                         send = searchCommand(par, pend);
288                         par = makeCommand(buf, os, runparams, paragraphs, par,send);
289                         break;
290                 }
291                 case LATEX_ENVIRONMENT:
292                 case LATEX_ITEM_ENVIRONMENT: {
293                         send = searchEnvironment(par, pend);
294                         par = makeEnvironment(buf, os, runparams, paragraphs, par,send);
295                         break;
296                 }
297                 case LATEX_PARAGRAPH:
298                         send = searchParagraph(par, pend);
299                         par = makeParagraph(buf, os, runparams, paragraphs, par,send);
300                         break;
301                 default:
302                         break;
303                 }
304         }
305 }