2 * \file output_docbook.cpp
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Lars Gullik Bjønnes
9 * Full author contact details are available in file CREDITS.
14 #include "output_docbook.h"
17 #include "buffer_funcs.h"
18 #include "BufferParams.h"
21 #include "OutputParams.h"
22 #include "Paragraph.h"
23 #include "paragraph_funcs.h"
24 #include "ParagraphList.h"
25 #include "ParagraphParameters.h"
27 #include "TextClass.h"
29 #include "support/convert.h"
30 #include "support/debug.h"
31 #include "support/lstrings.h"
33 #include <boost/next_prior.hpp>
36 using namespace lyx::support
;
42 ParagraphList::const_iterator
searchParagraph(
43 ParagraphList::const_iterator p
,
44 ParagraphList::const_iterator
const & pend
)
46 for (++p
; p
!= pend
&& p
->layout().latextype
== LATEX_PARAGRAPH
; ++p
)
53 ParagraphList::const_iterator
searchCommand(
54 ParagraphList::const_iterator p
,
55 ParagraphList::const_iterator
const & pend
)
57 Layout
const & bstyle
= p
->layout();
59 for (++p
; p
!= pend
; ++p
) {
60 Layout
const & style
= p
->layout();
61 if (style
.latextype
== LATEX_COMMAND
62 && style
.commanddepth
<= bstyle
.commanddepth
)
69 ParagraphList::const_iterator
searchEnvironment(
70 ParagraphList::const_iterator p
,
71 ParagraphList::const_iterator
const & pend
)
73 Layout
const & bstyle
= p
->layout();
74 size_t const depth
= p
->params().depth();
75 for (++p
; p
!= pend
; ++p
) {
76 Layout
const & style
= p
->layout();
77 if (style
.latextype
== LATEX_COMMAND
)
80 if (style
.latextype
== LATEX_PARAGRAPH
) {
81 if (p
->params().depth() > depth
)
86 if (p
->params().depth() < depth
)
89 if (style
.latexname() != bstyle
.latexname()
90 && p
->params().depth() == depth
)
97 ParagraphList::const_iterator
makeParagraph(Buffer
const & buf
,
99 OutputParams
const & runparams
,
100 ParagraphList
const & paragraphs
,
101 ParagraphList::const_iterator
const & pbegin
,
102 ParagraphList::const_iterator
const & pend
)
104 for (ParagraphList::const_iterator par
= pbegin
; par
!= pend
; ++par
) {
107 if (buf
.params().documentClass().isDefaultLayout(par
->layout())
108 && par
->emptyTag()) {
109 par
->simpleDocBookOnePar(buf
, os
, runparams
,
110 outerFont(distance(paragraphs
.begin(), par
), paragraphs
));
112 sgml::openTag(buf
, os
, runparams
, *par
);
113 par
->simpleDocBookOnePar(buf
, os
, runparams
,
114 outerFont(distance(paragraphs
.begin(), par
), paragraphs
));
115 sgml::closeTag(os
, *par
);
122 ParagraphList::const_iterator
makeEnvironment(Buffer
const & buf
,
124 OutputParams
const & runparams
,
125 ParagraphList
const & paragraphs
,
126 ParagraphList::const_iterator
const & pbegin
,
127 ParagraphList::const_iterator
const & pend
) {
128 ParagraphList::const_iterator par
= pbegin
;
130 Layout
const & defaultstyle
= buf
.params().documentClass().defaultLayout();
131 Layout
const & bstyle
= par
->layout();
134 // Opening outter tag
135 sgml::openTag(buf
, os
, runparams
, *pbegin
);
137 if (bstyle
.latextype
== LATEX_ENVIRONMENT
&& bstyle
.pass_thru
)
140 while (par
!= pend
) {
141 Layout
const & style
= par
->layout();
142 ParagraphList::const_iterator send
;
143 string id
= par
->getID(buf
, runparams
);
148 switch (bstyle
.latextype
) {
149 case LATEX_ENVIRONMENT
:
150 if (!bstyle
.innertag().empty()) {
151 sgml::openTag(os
, bstyle
.innertag(), id
);
155 case LATEX_ITEM_ENVIRONMENT
:
156 if (!bstyle
.labeltag().empty()) {
157 sgml::openTag(os
, bstyle
.innertag(), id
);
158 sgml::openTag(os
, bstyle
.labeltag());
159 sep
= par
->firstWord(os
, runparams
) + 1;
160 sgml::closeTag(os
, bstyle
.labeltag());
162 wrapper
= defaultstyle
.latexname();
163 // If a sub list (embedded list) appears next with a
164 // different depth, then there is no need to open
165 // another tag at the current depth.
166 if(par
->params().depth() == pbegin
->params().depth()) {
167 sgml::openTag(os
, bstyle
.itemtag());
174 switch (style
.latextype
) {
175 case LATEX_ENVIRONMENT
:
176 case LATEX_ITEM_ENVIRONMENT
: {
177 if (par
->params().depth() == pbegin
->params().depth()) {
178 sgml::openTag(os
, wrapper
);
179 par
->simpleDocBookOnePar(buf
, os
, runparams
, outerFont(distance(paragraphs
.begin(), par
), paragraphs
), sep
);
180 sgml::closeTag(os
, wrapper
);
184 send
= searchEnvironment(par
, pend
);
185 par
= makeEnvironment(buf
, os
, runparams
, paragraphs
, par
,send
);
189 case LATEX_PARAGRAPH
:
190 send
= searchParagraph(par
, pend
);
191 par
= makeParagraph(buf
, os
, runparams
, paragraphs
, par
,send
);
198 switch (bstyle
.latextype
) {
199 case LATEX_ENVIRONMENT
:
200 if (!bstyle
.innertag().empty()) {
201 sgml::closeTag(os
, bstyle
.innertag());
205 case LATEX_ITEM_ENVIRONMENT
:
206 // If a sub list (embedded list) appears next, then
207 // there is no need to close the current tag.
208 // par should have already been incremented to the next
209 // element. So we can compare the depth of the next
210 // element with pbegin.
211 // We need to be careful, that we don't dereference par
212 // when par == pend but at the same time that the
213 // current tag is closed.
214 if((par
!= pend
&& par
->params().depth() == pbegin
->params().depth()) || par
== pend
) {
215 sgml::closeTag(os
, bstyle
.itemtag());
217 if (!bstyle
.labeltag().empty())
218 sgml::closeTag(os
, bstyle
.innertag());
225 if (bstyle
.latextype
== LATEX_ENVIRONMENT
&& bstyle
.pass_thru
)
228 // Closing outter tag
229 sgml::closeTag(os
, *pbegin
);
235 ParagraphList::const_iterator
makeCommand(Buffer
const & buf
,
237 OutputParams
const & runparams
,
238 ParagraphList
const & paragraphs
,
239 ParagraphList::const_iterator
const & pbegin
,
240 ParagraphList::const_iterator
const & pend
)
242 ParagraphList::const_iterator par
= pbegin
;
243 Layout
const & bstyle
= par
->layout();
246 sgml::openTag(buf
, os
, runparams
, *pbegin
);
249 // Label around sectioning number:
250 if (!bstyle
.labeltag().empty()) {
251 sgml::openTag(os
, bstyle
.labeltag());
252 // We don't care about appendix in DOCBOOK.
253 os
<< par
->expandLabel(bstyle
, buf
.params(), false);
254 sgml::closeTag(os
, bstyle
.labeltag());
257 // Opend inner tag and close inner tags
258 sgml::openTag(os
, bstyle
.innertag());
259 par
->simpleDocBookOnePar(buf
, os
, runparams
, outerFont(distance(paragraphs
.begin(), par
), paragraphs
));
260 sgml::closeTag(os
, bstyle
.innertag());
264 while (par
!= pend
) {
265 Layout
const & style
= par
->layout();
266 ParagraphList::const_iterator send
;
268 switch (style
.latextype
) {
269 case LATEX_COMMAND
: {
270 send
= searchCommand(par
, pend
);
271 par
= makeCommand(buf
, os
, runparams
, paragraphs
, par
,send
);
274 case LATEX_ENVIRONMENT
:
275 case LATEX_ITEM_ENVIRONMENT
: {
276 send
= searchEnvironment(par
, pend
);
277 par
= makeEnvironment(buf
, os
, runparams
, paragraphs
, par
,send
);
280 case LATEX_PARAGRAPH
:
281 send
= searchParagraph(par
, pend
);
282 par
= makeParagraph(buf
, os
, runparams
, paragraphs
, par
,send
);
289 sgml::closeTag(os
, *pbegin
);
294 } // end anonym namespace
297 void docbookParagraphs(ParagraphList
const & paragraphs
,
300 OutputParams
const & runparams
)
302 ParagraphList::const_iterator par
= paragraphs
.begin();
303 ParagraphList::const_iterator pend
= paragraphs
.end();
305 BOOST_ASSERT(runparams
.par_begin
<= runparams
.par_end
);
306 // if only part of the paragraphs will be outputed
307 if (runparams
.par_begin
!= runparams
.par_end
) {
308 par
= boost::next(paragraphs
.begin(), runparams
.par_begin
);
309 pend
= boost::next(paragraphs
.begin(), runparams
.par_end
);
310 // runparams will be passed to nested paragraphs, so
311 // we have to reset the range parameters.
312 const_cast<OutputParams
&>(runparams
).par_begin
= 0;
313 const_cast<OutputParams
&>(runparams
).par_end
= 0;
316 while (par
!= pend
) {
317 Layout
const & style
= par
->layout();
318 ParagraphList::const_iterator lastpar
= par
;
319 ParagraphList::const_iterator send
;
321 switch (style
.latextype
) {
322 case LATEX_COMMAND
: {
323 send
= searchCommand(par
, pend
);
324 par
= makeCommand(buf
, os
, runparams
, paragraphs
, par
,send
);
327 case LATEX_ENVIRONMENT
:
328 case LATEX_ITEM_ENVIRONMENT
: {
329 send
= searchEnvironment(par
, pend
);
330 par
= makeEnvironment(buf
, os
, runparams
, paragraphs
, par
,send
);
333 case LATEX_PARAGRAPH
:
334 send
= searchParagraph(par
, pend
);
335 par
= makeParagraph(buf
, os
, runparams
, paragraphs
, par
,send
);
340 // makeEnvironment may process more than one paragraphs and bypass pend
341 if (distance(lastpar
, par
) >= distance(lastpar
, pend
))