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"
22 #include "OutputParams.h"
23 #include "Paragraph.h"
24 #include "paragraph_funcs.h"
25 #include "ParagraphList.h"
26 #include "ParagraphParameters.h"
29 #include "support/lstrings.h"
30 #include "support/lyxlib.h"
31 #include "support/convert.h"
32 #include "support/types.h"
34 #include <boost/next_prior.hpp>
48 ParagraphList::const_iterator searchParagraph(
49 ParagraphList::const_iterator const & par,
50 ParagraphList::const_iterator const & pend)
52 ParagraphList::const_iterator p = boost::next(par);
54 for (; p != pend && p->layout()->latextype == LATEX_PARAGRAPH; ++p)
61 ParagraphList::const_iterator searchCommand(
62 ParagraphList::const_iterator const & par,
63 ParagraphList::const_iterator const & pend)
65 LayoutPtr const & bstyle = par->layout();
66 ParagraphList::const_iterator p = boost::next(par);
68 for ( ; p != pend; ++p) {
69 LayoutPtr const & style = p->layout();
70 if (style->latextype == LATEX_COMMAND
71 && style->commanddepth <= bstyle->commanddepth)
78 ParagraphList::const_iterator searchEnvironment(
79 ParagraphList::const_iterator const & par,
80 ParagraphList::const_iterator const & pend)
82 LayoutPtr const & bstyle = par->layout();
83 ParagraphList::const_iterator p = boost::next(par);
84 for (; p != pend; ++p) {
85 LayoutPtr const & style = p->layout();
86 if (style->latextype == LATEX_COMMAND)
89 if (style->latextype == LATEX_PARAGRAPH) {
90 if (p->params().depth() > par->params().depth())
95 if (p->params().depth() < par->params().depth())
98 if (style->latexname() != bstyle->latexname()
99 && p->params().depth() == par->params().depth() )
106 ParagraphList::const_iterator makeParagraph(Buffer const & buf,
108 OutputParams const & runparams,
109 ParagraphList const & paragraphs,
110 ParagraphList::const_iterator const & pbegin,
111 ParagraphList::const_iterator const & pend)
113 LayoutPtr const & defaultstyle =
114 buf.params().getTextClass().defaultLayout();
115 for (ParagraphList::const_iterator par = pbegin; par != pend; ++par) {
118 if (par->layout() == defaultstyle && par->emptyTag()) {
119 par->simpleDocBookOnePar(buf, os, runparams, outerFont(std::distance(paragraphs.begin(), par), paragraphs));
121 sgml::openTag(buf, os, runparams, *par);
122 par->simpleDocBookOnePar(buf, os, runparams, outerFont(std::distance(paragraphs.begin(), par), paragraphs));
123 sgml::closeTag(os, *par);
130 ParagraphList::const_iterator makeEnvironment(Buffer const & buf,
132 OutputParams const & runparams,
133 ParagraphList const & paragraphs,
134 ParagraphList::const_iterator const & pbegin,
135 ParagraphList::const_iterator const & pend) {
136 ParagraphList::const_iterator par = pbegin;
138 LayoutPtr const & defaultstyle = buf.params().getTextClass().defaultLayout();
139 LayoutPtr const & bstyle = par->layout();
142 // Opening outter tag
143 sgml::openTag(buf, os, runparams, *pbegin);
145 if (bstyle->latextype == LATEX_ENVIRONMENT && bstyle->pass_thru)
148 while (par != pend) {
149 LayoutPtr const & style = par->layout();
150 ParagraphList::const_iterator send;
151 string id = par->getID(buf, runparams);
156 switch (bstyle->latextype) {
157 case LATEX_ENVIRONMENT:
158 if (!bstyle->innertag().empty()) {
159 sgml::openTag(os, bstyle->innertag(), id);
163 case LATEX_ITEM_ENVIRONMENT:
164 if (!bstyle->labeltag().empty()) {
165 sgml::openTag(os, bstyle->innertag(), id);
166 sgml::openTag(os, bstyle->labeltag());
167 sep = par->getFirstWord(buf, os, runparams) + 1;
168 sgml::closeTag(os, bstyle->labeltag());
170 wrapper = defaultstyle->latexname();
171 // If a sub list (embedded list) appears next with a
172 // different depth, then there is no need to open
173 // another tag at the current depth.
174 if(par->params().depth() == pbegin->params().depth()) {
175 sgml::openTag(os, bstyle->itemtag());
182 switch (style->latextype) {
183 case LATEX_ENVIRONMENT:
184 case LATEX_ITEM_ENVIRONMENT: {
185 if (par->params().depth() == pbegin->params().depth()) {
186 sgml::openTag(os, wrapper);
187 par->simpleDocBookOnePar(buf, os, runparams, outerFont(std::distance(paragraphs.begin(), par), paragraphs), sep);
188 sgml::closeTag(os, wrapper);
192 send = searchEnvironment(par, pend);
193 par = makeEnvironment(buf, os, runparams, paragraphs, par,send);
197 case LATEX_PARAGRAPH:
198 send = searchParagraph(par, pend);
199 par = makeParagraph(buf, os, runparams, paragraphs, par,send);
206 switch (bstyle->latextype) {
207 case LATEX_ENVIRONMENT:
208 if (!bstyle->innertag().empty()) {
209 sgml::closeTag(os, bstyle->innertag());
213 case LATEX_ITEM_ENVIRONMENT:
214 // If a sub list (embedded list) appears next, then
215 // there is no need to close the current tag.
216 // par should have already been incremented to the next
217 // element. So we can compare the depth of the next
218 // element with pbegin.
219 // We need to be careful, that we don't dereference par
220 // when par == pend but at the same time that the
221 // current tag is closed.
222 if((par != pend && par->params().depth() == pbegin->params().depth()) || par == pend) {
223 sgml::closeTag(os, bstyle->itemtag());
225 if (!bstyle->labeltag().empty())
226 sgml::closeTag(os, bstyle->innertag());
233 if (bstyle->latextype == LATEX_ENVIRONMENT && bstyle->pass_thru)
236 // Closing outter tag
237 sgml::closeTag(os, *pbegin);
243 ParagraphList::const_iterator makeCommand(Buffer const & buf,
245 OutputParams const & runparams,
246 ParagraphList const & paragraphs,
247 ParagraphList::const_iterator const & pbegin,
248 ParagraphList::const_iterator const & pend)
250 ParagraphList::const_iterator par = pbegin;
251 LayoutPtr const & bstyle = par->layout();
254 sgml::openTag(buf, os, runparams, *pbegin);
257 // Label around sectioning number:
258 if (!bstyle->labeltag().empty()) {
259 sgml::openTag(os, bstyle->labeltag());
260 // We don't care about appendix in DOCBOOK.
261 os << par->expandLabel(bstyle, buf.params(), false);
262 sgml::closeTag(os, bstyle->labeltag());
265 // Opend inner tag and close inner tags
266 sgml::openTag(os, bstyle->innertag());
267 par->simpleDocBookOnePar(buf, os, runparams, outerFont(std::distance(paragraphs.begin(), par), paragraphs));
268 sgml::closeTag(os, bstyle->innertag());
272 while (par != pend) {
273 LayoutPtr const & style = par->layout();
274 ParagraphList::const_iterator send;
276 switch (style->latextype) {
277 case LATEX_COMMAND: {
278 send = searchCommand(par, pend);
279 par = makeCommand(buf, os, runparams, paragraphs, par,send);
282 case LATEX_ENVIRONMENT:
283 case LATEX_ITEM_ENVIRONMENT: {
284 send = searchEnvironment(par, pend);
285 par = makeEnvironment(buf, os, runparams, paragraphs, par,send);
288 case LATEX_PARAGRAPH:
289 send = searchParagraph(par, pend);
290 par = makeParagraph(buf, os, runparams, paragraphs, par,send);
297 sgml::closeTag(os, *pbegin);
302 } // end anonym namespace
305 void docbookParagraphs(ParagraphList const & paragraphs,
308 OutputParams const & runparams)
310 ParagraphList::const_iterator par = paragraphs.begin();
311 ParagraphList::const_iterator pend = paragraphs.end();
313 BOOST_ASSERT(runparams.par_begin <= runparams.par_end);
314 // if only part of the paragraphs will be outputed
315 if (runparams.par_begin != runparams.par_end) {
316 par = boost::next(paragraphs.begin(), runparams.par_begin);
317 pend = boost::next(paragraphs.begin(), runparams.par_end);
318 // runparams will be passed to nested paragraphs, so
319 // we have to reset the range parameters.
320 const_cast<OutputParams&>(runparams).par_begin = 0;
321 const_cast<OutputParams&>(runparams).par_end = 0;
324 while (par != pend) {
325 LayoutPtr const & style = par->layout();
326 ParagraphList::const_iterator lastpar = par;
327 ParagraphList::const_iterator send;
329 switch (style->latextype) {
330 case LATEX_COMMAND: {
331 send = searchCommand(par, pend);
332 par = makeCommand(buf, os, runparams, paragraphs, par,send);
335 case LATEX_ENVIRONMENT:
336 case LATEX_ITEM_ENVIRONMENT: {
337 send = searchEnvironment(par, pend);
338 par = makeEnvironment(buf, os, runparams, paragraphs, par,send);
341 case LATEX_PARAGRAPH:
342 send = searchParagraph(par, pend);
343 par = makeParagraph(buf, os, runparams, paragraphs, par,send);
348 // makeEnvironment may process more than one paragraphs and bypass pend
349 if (std::distance(lastpar, par) >= std::distance(lastpar, pend))