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 "ParagraphList.h"
24 #include "ParagraphParameters.h"
27 #include "TextClass.h"
29 #include "support/lassert.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
,
101 ParagraphList::const_iterator
const & pbegin
,
102 ParagraphList::const_iterator
const & pend
)
104 ParagraphList
const & paragraphs
= text
.paragraphs();
105 for (ParagraphList::const_iterator par
= pbegin
; par
!= pend
; ++par
) {
108 if (buf
.params().documentClass().isDefaultLayout(par
->layout())
109 && par
->emptyTag()) {
110 par
->simpleDocBookOnePar(buf
, os
, runparams
,
111 text
.outerFont(distance(paragraphs
.begin(), par
)));
113 sgml::openTag(buf
, os
, runparams
, *par
);
114 par
->simpleDocBookOnePar(buf
, os
, runparams
,
115 text
.outerFont(distance(paragraphs
.begin(), par
)));
116 sgml::closeTag(os
, *par
);
123 ParagraphList::const_iterator
makeEnvironment(Buffer
const & buf
,
125 OutputParams
const & runparams
,
127 ParagraphList::const_iterator
const & pbegin
,
128 ParagraphList::const_iterator
const & pend
)
130 ParagraphList
const & paragraphs
= text
.paragraphs();
131 ParagraphList::const_iterator par
= pbegin
;
133 Layout
const & defaultstyle
= buf
.params().documentClass().defaultLayout();
134 Layout
const & bstyle
= par
->layout();
137 // Opening outter tag
138 sgml::openTag(buf
, os
, runparams
, *pbegin
);
140 if (bstyle
.latextype
== LATEX_ENVIRONMENT
&& bstyle
.pass_thru
)
143 while (par
!= pend
) {
144 Layout
const & style
= par
->layout();
145 ParagraphList::const_iterator send
;
146 string id
= par
->getID(buf
, runparams
);
151 switch (bstyle
.latextype
) {
152 case LATEX_ENVIRONMENT
:
153 if (!bstyle
.innertag().empty()) {
154 sgml::openTag(os
, bstyle
.innertag(), id
);
158 case LATEX_ITEM_ENVIRONMENT
:
159 if (!bstyle
.labeltag().empty()) {
160 sgml::openTag(os
, bstyle
.innertag(), id
);
161 sgml::openTag(os
, bstyle
.labeltag());
162 sep
= par
->firstWordDocBook(os
, runparams
) + 1;
163 sgml::closeTag(os
, bstyle
.labeltag());
165 wrapper
= defaultstyle
.latexname();
166 // If a sub list (embedded list) appears next with a
167 // different depth, then there is no need to open
168 // another tag at the current depth.
169 if(par
->params().depth() == pbegin
->params().depth()) {
170 sgml::openTag(os
, bstyle
.itemtag());
177 switch (style
.latextype
) {
178 case LATEX_ENVIRONMENT
:
179 case LATEX_ITEM_ENVIRONMENT
: {
180 if (par
->params().depth() == pbegin
->params().depth()) {
181 sgml::openTag(os
, wrapper
);
182 par
->simpleDocBookOnePar(buf
, os
, runparams
,
183 text
.outerFont(distance(paragraphs
.begin(), par
)), sep
);
184 sgml::closeTag(os
, wrapper
);
188 send
= searchEnvironment(par
, pend
);
189 par
= makeEnvironment(buf
, os
, runparams
, text
, par
,send
);
193 case LATEX_PARAGRAPH
:
194 send
= searchParagraph(par
, pend
);
195 par
= makeParagraph(buf
, os
, runparams
, text
, par
,send
);
197 case LATEX_LIST_ENVIRONMENT
:
198 case LATEX_BIB_ENVIRONMENT
:
200 // FIXME This means that we are just skipping any paragraph that
201 // isn't implemented above, and this includes lists.
207 switch (bstyle
.latextype
) {
208 case LATEX_ENVIRONMENT
:
209 if (!bstyle
.innertag().empty()) {
210 sgml::closeTag(os
, bstyle
.innertag());
214 case LATEX_ITEM_ENVIRONMENT
:
215 // If a sub list (embedded list) appears next, then
216 // there is no need to close the current tag.
217 // par should have already been incremented to the next
218 // element. So we can compare the depth of the next
219 // element with pbegin.
220 // We need to be careful, that we don't dereference par
221 // when par == pend but at the same time that the
222 // current tag is closed.
223 if((par
!= pend
&& par
->params().depth() == pbegin
->params().depth()) || par
== pend
) {
224 sgml::closeTag(os
, bstyle
.itemtag());
226 if (!bstyle
.labeltag().empty())
227 sgml::closeTag(os
, bstyle
.innertag());
234 if (bstyle
.latextype
== LATEX_ENVIRONMENT
&& bstyle
.pass_thru
)
237 // Closing outter tag
238 sgml::closeTag(os
, *pbegin
);
244 ParagraphList::const_iterator
makeCommand(Buffer
const & buf
,
246 OutputParams
const & runparams
,
248 ParagraphList::const_iterator
const & pbegin
,
249 ParagraphList::const_iterator
const & pend
)
251 ParagraphList
const & paragraphs
= text
.paragraphs();
252 ParagraphList::const_iterator par
= pbegin
;
253 Layout
const & bstyle
= par
->layout();
256 sgml::openTag(buf
, os
, runparams
, *pbegin
);
259 // Label around sectioning number:
260 if (!bstyle
.labeltag().empty()) {
261 sgml::openTag(os
, bstyle
.labeltag());
262 // We don't care about appendix in DOCBOOK.
263 os
<< par
->expandLabel(bstyle
, buf
.params(), false);
264 sgml::closeTag(os
, bstyle
.labeltag());
267 // Opend inner tag and close inner tags
268 sgml::openTag(os
, bstyle
.innertag());
269 par
->simpleDocBookOnePar(buf
, os
, runparams
,
270 text
.outerFont(distance(paragraphs
.begin(), par
)));
271 sgml::closeTag(os
, bstyle
.innertag());
275 while (par
!= pend
) {
276 Layout
const & style
= par
->layout();
277 ParagraphList::const_iterator send
;
279 switch (style
.latextype
) {
280 case LATEX_COMMAND
: {
281 send
= searchCommand(par
, pend
);
282 par
= makeCommand(buf
, os
, runparams
, text
, par
,send
);
285 case LATEX_ENVIRONMENT
:
286 case LATEX_ITEM_ENVIRONMENT
: {
287 send
= searchEnvironment(par
, pend
);
288 par
= makeEnvironment(buf
, os
, runparams
, text
, par
,send
);
291 case LATEX_PARAGRAPH
:
292 send
= searchParagraph(par
, pend
);
293 par
= makeParagraph(buf
, os
, runparams
, text
, par
,send
);
300 sgml::closeTag(os
, *pbegin
);
305 } // end anonym namespace
308 void docbookParagraphs(Text
const & text
,
311 OutputParams
const & runparams
)
313 ParagraphList
const & paragraphs
= text
.paragraphs();
314 ParagraphList::const_iterator par
= paragraphs
.begin();
315 ParagraphList::const_iterator pend
= paragraphs
.end();
317 LASSERT(runparams
.par_begin
<= runparams
.par_end
, /**/);
318 // if only part of the paragraphs will be outputed
319 if (runparams
.par_begin
!= runparams
.par_end
) {
320 par
= boost::next(paragraphs
.begin(), runparams
.par_begin
);
321 pend
= boost::next(paragraphs
.begin(), runparams
.par_end
);
322 // runparams will be passed to nested paragraphs, so
323 // we have to reset the range parameters.
324 const_cast<OutputParams
&>(runparams
).par_begin
= 0;
325 const_cast<OutputParams
&>(runparams
).par_end
= 0;
328 while (par
!= pend
) {
329 Layout
const & style
= par
->layout();
330 ParagraphList::const_iterator lastpar
= par
;
331 ParagraphList::const_iterator send
;
333 switch (style
.latextype
) {
334 case LATEX_COMMAND
: {
335 send
= searchCommand(par
, pend
);
336 par
= makeCommand(buf
, os
, runparams
, text
, par
,send
);
339 case LATEX_ENVIRONMENT
:
340 case LATEX_ITEM_ENVIRONMENT
: {
341 send
= searchEnvironment(par
, pend
);
342 par
= makeEnvironment(buf
, os
, runparams
, text
, par
,send
);
345 case LATEX_PARAGRAPH
:
346 send
= searchParagraph(par
, pend
);
347 par
= makeParagraph(buf
, os
, runparams
, text
, par
,send
);
352 // makeEnvironment may process more than one paragraphs and bypass pend
353 if (distance(lastpar
, par
) >= distance(lastpar
, pend
))