X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Foutput_docbook.cpp;h=ce6b702f647fedf73adfdd59dd68ff4049a019e1;hb=33f9cfb7961501b38c573eede468b011687f46de;hp=ec11481cd966adc37edbc01e98d7b9c276bc25e5;hpb=633a617841f6a5fe1ca79ee28e555ec75985998e;p=lyx.git diff --git a/src/output_docbook.cpp b/src/output_docbook.cpp index ec11481cd9..ce6b702f64 100644 --- a/src/output_docbook.cpp +++ b/src/output_docbook.cpp @@ -350,15 +350,6 @@ void makeParagraph( size_t nInsets = std::distance(par->insetList().begin(), par->insetList().end()); auto parSize = (size_t) par->size(); - // If this LyX code does not produce any output, it can be safely ignored in the following checks: if this thing - // is present in the paragraph, it has no impact on the definition of the special case (i.e. whether or not - // a tag should be output). - auto isLyxCodeToIgnore = [](InsetCode x) { return x == TOC_CODE || x == NOTE_CODE; }; - - // TODO: if a paragraph *only* contains floats, listings, bibliographies, etc., should this be considered as a - // special case? If so, the code could be largely simplifies (all the calls to all_of, basically) and optimised - // at the compilation stage. - // Plain layouts must be ignored. special_case |= buf.params().documentClass().isPlainLayout(par->layout()) && !runparams.docbook_force_pars; // Equations do not deserve their own paragraph (DocBook allows them outside paragraphs). @@ -366,40 +357,63 @@ void makeParagraph( special_case |= nInsets == parSize && std::all_of(par->insetList().begin(), par->insetList().end(), [](InsetList::Element inset) { return inset.inset && inset.inset->asInsetMath() && inset.inset->asInsetMath()->getType() != hullSimple; }); - // Tables do not deserve their own paragraphs (DocBook allows them outside paragraphs). - special_case |= nInsets == parSize && std::all_of(par->insetList().begin(), par->insetList().end(), [isLyxCodeToIgnore](InsetList::Element inset) { - return inset.inset->lyxCode() == TABULAR_CODE || isLyxCodeToIgnore(inset.inset->lyxCode()); - }); - // Floats cannot be in paragraphs. - special_case |= nInsets == parSize && std::all_of(par->insetList().begin(), par->insetList().end(), [isLyxCodeToIgnore](InsetList::Element inset) { - return inset.inset->lyxCode() == FLOAT_CODE || isLyxCodeToIgnore(inset.inset->lyxCode()); - }); - // Bibliographies cannot be in paragraphs. Bibitems should still be handled as paragraphs, though - // (see makeParagraphBibliography). - special_case |= nInsets == parSize && std::all_of(par->insetList().begin(), par->insetList().end(), [isLyxCodeToIgnore](InsetList::Element inset) { - return inset.inset->lyxCode() == BIBTEX_CODE || isLyxCodeToIgnore(inset.inset->lyxCode()); - }); - // ERTs are in comments, not paragraphs. - special_case |= nInsets == parSize && std::all_of(par->insetList().begin(), par->insetList().end(), [isLyxCodeToIgnore](InsetList::Element inset) { - return inset.inset->lyxCode() == ERT_CODE || isLyxCodeToIgnore(inset.inset->lyxCode()); - }); - // Listings should not get into their own paragraph. - special_case |= nInsets == parSize && std::all_of(par->insetList().begin(), par->insetList().end(), [isLyxCodeToIgnore](InsetList::Element inset) { - return inset.inset->lyxCode() == LISTINGS_CODE || isLyxCodeToIgnore(inset.inset->lyxCode()); - }); - // Boxes cannot get into their own paragraph. - special_case |= nInsets == parSize && std::all_of(par->insetList().begin(), par->insetList().end(), [isLyxCodeToIgnore](InsetList::Element inset) { - return inset.inset->lyxCode() == BOX_CODE || isLyxCodeToIgnore(inset.inset->lyxCode()); - }); - // Includes should not have a paragraph. - special_case |= nInsets == parSize && std::all_of(par->insetList().begin(), par->insetList().end(), [isLyxCodeToIgnore](InsetList::Element inset) { - return inset.inset->lyxCode() == INCLUDE_CODE || isLyxCodeToIgnore(inset.inset->lyxCode()); - }); - // Glossaries should not have a paragraph. - special_case |= nInsets == parSize && std::all_of(par->insetList().begin(), par->insetList().end(), [isLyxCodeToIgnore](InsetList::Element inset) { - return inset.inset->lyxCode() == NOMENCL_PRINT_CODE || isLyxCodeToIgnore(inset.inset->lyxCode()); - }); + // Things that should not get into their own paragraph. (Only valid for DocBook.) + static std::set lyxCodeSpecialCases = { + TABULAR_CODE, + FLOAT_CODE, + BIBTEX_CODE, // Bibliographies cannot be in paragraphs. Bibitems should still be handled as paragraphs, + // though (see makeParagraphBibliography). + ERT_CODE, // ERTs are in comments, not paragraphs. + LISTINGS_CODE, + BOX_CODE, + INCLUDE_CODE, + NOMENCL_PRINT_CODE, + TOC_CODE, // To be ignored in DocBook, the processor afterwards should deal with ToCs. + NOTE_CODE // Notes do not produce any output. + }; + auto isLyxCodeSpecialCase = [](InsetList::Element inset) { + return lyxCodeSpecialCases.find(inset.inset->lyxCode()) != lyxCodeSpecialCases.end(); + }; + special_case |= nInsets == parSize && std::all_of(par->insetList().begin(), par->insetList().end(), isLyxCodeSpecialCase); + + // Flex elements (InsetLayout) have their own parameter to control the special case. + auto isFlexSpecialCase = [](InsetList::Element inset) { + if (inset.inset->lyxCode() != FLEX_CODE) + return false; + + // Standard condition: check the parameter. + if (inset.inset->getLayout().docbooknotinpara()) + return true; + + // If the parameter is not set, maybe the flex inset only contains things that should match the standard + // condition. In this case, isLyxCodeSpecialCase must also check for bibitems... + auto isLyxCodeSpecialCase = [](InsetList::Element inset) { + return lyxCodeSpecialCases.find(inset.inset->lyxCode()) != lyxCodeSpecialCases.end() || + inset.inset->lyxCode() == BIBITEM_CODE; + }; + if (InsetText * text = inset.inset->asInsetText()) { + for (auto const & par : text->paragraphs()) { + size_t nInsets = std::distance(par.insetList().begin(), par.insetList().end()); + auto parSize = (size_t) par.size(); + + if (nInsets == 1 && par.insetList().begin()->inset->lyxCode() == BIBITEM_CODE) + return true; + if (nInsets != parSize) + return false; + if (!std::all_of(par.insetList().begin(), par.insetList().end(), isLyxCodeSpecialCase)) + return false; + } + return true; + } + + // No case matched: give up. + return false; + }; + special_case |= nInsets == parSize && std::all_of(par->insetList().begin(), par->insetList().end(), isFlexSpecialCase); + + // Open a paragraph if it is allowed, we are not already within a paragraph, and the insets in the paragraph do + // not forbid paragraphs (aka special cases). bool const open_par = runparams.docbook_make_pars && !runparams.docbook_in_par && !special_case;