+ xs << xml::EndTag(lay.docbookitemlabeltag());
+ xs << xml::CR();
+}
+
+
+void openItemTag(XMLStream &xs, Layout const &lay) {
+ xs << xml::StartTag(lay.docbookitemtag(), lay.docbookitemattr());
+}
+
+
+// Return true when new elements are output in a paragraph, false otherwise.
+bool openInnerItemTag(XMLStream &xs, Layout const &lay) {
+ if (lay.docbookiteminnertag() != "NONE") {
+ xs << xml::CR();
+ xs << xml::ParTag(lay.docbookiteminnertag(), lay.docbookiteminnerattr());
+
+ if (lay.docbookiteminnertag() == "para") {
+ return true;
+ }
+ }
+ return false;
+}
+
+
+void closeInnerItemTag(XMLStream &xs, Layout const &lay) {
+ if (lay.docbookiteminnertag()!= "NONE") {
+ xs << xml::EndTag(lay.docbookiteminnertag());
+ xs << xml::CR();
+ }
+}
+
+
+inline void closeItemTag(XMLStream &xs, Layout const &lay) {
+ xs << xml::EndTag(lay.docbookitemtag()) << xml::CR();
+}
+
+// end of convenience functions
+
+ParagraphList::const_iterator findLastParagraph(
+ ParagraphList::const_iterator p,
+ ParagraphList::const_iterator const &pend) {
+ for (++p; p != pend && p->layout().latextype == LATEX_PARAGRAPH; ++p);
+
+ return p;
+}
+
+
+ParagraphList::const_iterator findEndOfEnvironment(
+ ParagraphList::const_iterator const &pstart,
+ ParagraphList::const_iterator const &pend) {
+ ParagraphList::const_iterator p = pstart;
+ Layout const &bstyle = p->layout();
+ size_t const depth = p->params().depth();
+ for (++p; p != pend; ++p) {
+ Layout const &style = p->layout();
+ // It shouldn't happen that e.g. a section command occurs inside
+ // a quotation environment, at a higher depth, but as of 6/2009,
+ // it can happen. We pretend that it's just at lowest depth.
+ if (style.latextype == LATEX_COMMAND)
+ return p;
+
+ // If depth is down, we're done
+ if (p->params().depth() < depth)
+ return p;
+
+ // If depth is up, we're not done
+ if (p->params().depth() > depth)
+ continue;
+
+ // FIXME I am not sure about the first check.
+ // Surely we *could* have different layouts that count as
+ // LATEX_PARAGRAPH, right?
+ if (style.latextype == LATEX_PARAGRAPH || style != bstyle)
+ return p;
+ }
+ return pend;
+}
+
+
+ParagraphList::const_iterator makeParagraphs(Buffer const &buf,
+ XMLStream &xs,
+ OutputParams const &runparams,
+ Text const &text,
+ ParagraphList::const_iterator const &pbegin,
+ ParagraphList::const_iterator const &pend) {
+ ParagraphList::const_iterator const begin = text.paragraphs().begin();
+ ParagraphList::const_iterator par = pbegin;
+ for (; par != pend; ++par) {
+ Layout const &lay = par->layout();
+ if (!lay.counter.empty())
+ buf.masterBuffer()->params().
+ documentClass().counters().step(lay.counter, OutputUpdate);
+
+ // We want to open the paragraph tag if:
+ // (i) the current layout permits multiple paragraphs
+ // (ii) we are either not already inside a paragraph (HTMLIsBlock) OR
+ // we are, but this is not the first paragraph
+ //
+ // But there is also a special case, and we first see whether we are in it.
+ // We do not want to open the paragraph tag if this paragraph contains
+ // only one item, and that item is "inline", i.e., not HTMLIsBlock (such
+ // as a branch). On the other hand, if that single item has a font change
+ // applied to it, then we still do need to open the paragraph.
+ //
+ // Obviously, this is very fragile. The main reason we need to do this is
+ // because of branches, e.g., a branch that contains an entire new section.
+ // We do not really want to wrap that whole thing in a <div>...</div>.
+ bool special_case = false;
+ Inset const *specinset = par->size() == 1 ? par->getInset(0) : 0;
+ if (specinset && !specinset->getLayout().htmlisblock()) { // TODO: Convert htmlisblock to a DocBook parameter?
+ Layout const &style = par->layout();
+ FontInfo const first_font = style.labeltype == LABEL_MANUAL ?
+ style.labelfont : style.font;
+ FontInfo const our_font =
+ par->getFont(buf.masterBuffer()->params(), 0,
+ text.outerFont(distance(begin, par))).fontInfo();
+
+ if (first_font == our_font)
+ special_case = true;
+ }
+
+ // Plain layouts must be ignored.
+ if (!special_case && buf.params().documentClass().isPlainLayout(lay) && !runparams.docbook_force_pars)
+ special_case = true;
+ // TODO: Could get rid of this with a DocBook equivalent to htmlisblock?
+ if (!special_case && par->size() == 1 && par->getInset(0)) {
+ Inset const * firstInset = par->getInset(0);
+
+ // Floats cannot be in paragraphs.
+ special_case = to_ascii(firstInset->layoutName()).substr(0, 6) == "Float:";
+
+ // Bibliographies cannot be in paragraphs.
+ if (!special_case && firstInset->asInsetCommand())
+ special_case = firstInset->asInsetCommand()->params().getCmdName() == "bibtex";
+
+ // Equations do not deserve their own paragraph (DocBook allows them outside paragraphs).
+ if (!special_case && firstInset->asInsetMath())
+ special_case = true;
+
+ // ERTs are in comments, not paragraphs.
+ if (!special_case && firstInset->lyxCode() == lyx::ERT_CODE)
+ special_case = true;
+
+ // Listings should not get into their own paragraph.
+ if (!special_case && firstInset->lyxCode() == lyx::LISTINGS_CODE)
+ special_case = true;
+ }
+
+ bool const open_par = runparams.docbook_make_pars
+ && (!runparams.docbook_in_par || par != pbegin)
+ && !special_case;
+
+ // We want to issue the closing tag if either:
+ // (i) We opened it, and either docbook_in_par is false,
+ // or we're not in the last paragraph, anyway.
+ // (ii) We didn't open it and docbook_in_par is true,
+ // but we are in the first par, and there is a next par.
+ ParagraphList::const_iterator nextpar = par;
+ ++nextpar;
+ bool const close_par =
+ ((open_par && (!runparams.docbook_in_par || nextpar != pend))
+ || (!open_par && runparams.docbook_in_par && par == pbegin && nextpar != pend));
+
+ if (open_par) {
+ openParTag(xs, lay);
+ }
+
+ par->simpleDocBookOnePar(buf, xs, runparams, text.outerFont(distance(begin, par)), open_par, close_par, 0);
+
+ if (close_par) {
+ closeTag(xs, lay);
+ xs << xml::CR();
+ }
+ }
+ return pend;
+}
+
+
+bool isNormalEnv(Layout const &lay) {
+ return lay.latextype == LATEX_ENVIRONMENT
+ || lay.latextype == LATEX_BIB_ENVIRONMENT;
+}
+
+
+ParagraphList::const_iterator makeEnvironment(Buffer const &buf,
+ XMLStream &xs,
+ OutputParams const &runparams,
+ Text const &text,
+ ParagraphList::const_iterator const &pbegin,
+ ParagraphList::const_iterator const &pend) {
+ ParagraphList::const_iterator const begin = text.paragraphs().begin();