The branch, feature/docbook, has been updated. - Log -----------------------------------------------------------------
commit ecf93ca5aaf9c087e98a168752855177d808f868 Author: Thibaut Cuvelier <[email protected]> Date: Sun Aug 30 01:14:44 2020 +0200 DocBook: generate <partintro> when required. diff --git a/autotests/export/docbook/basic.xml b/autotests/export/docbook/basic.xml index ea91d3d..49ec1f4 100644 --- a/autotests/export/docbook/basic.xml +++ b/autotests/export/docbook/basic.xml @@ -12,7 +12,9 @@ <para>I am an abstract</para> <para>I am also an abstract</para> </abstract> + </info> +<para>I am a standard paragraph. </para> <section xml:id="sec.Sec-1"> <title>I am the first section </title> <para>I am the first paragraph of the first section. </para> diff --git a/autotests/export/docbook/basic_book.xml b/autotests/export/docbook/basic_book.xml index 18496b9..c6e9078 100644 --- a/autotests/export/docbook/basic_book.xml +++ b/autotests/export/docbook/basic_book.xml @@ -17,7 +17,9 @@ </chapter> <part> <title>First part</title> +<partintro> <para>Part intro. </para> +</partintro> <chapter> <title>First chapter of first part</title> <para>Paragraph. </para> @@ -29,7 +31,9 @@ </part> <part> <title>Second part</title> +<partintro> <para>Part 2 intro. </para> +</partintro> <chapter> <title>First chapter of second part</title> <para>Paragraph. </para> diff --git a/src/output_docbook.cpp b/src/output_docbook.cpp index 609f45c..f584b8b 100644 --- a/src/output_docbook.cpp +++ b/src/output_docbook.cpp @@ -819,7 +819,7 @@ bool hasOnlyNotes(Paragraph const & par) for (int i = 0; i < par.size(); ++i) // If you find something that is not an inset (like actual text) or an inset that is not a note, // return false. - if (!par.isInset(i) || !dynamic_cast<InsetNote *>(par.insetList().get(i))) + if (!par.isInset(i) || par.getInset(i)->lyxCode() != NOTE_CODE) return false; return true; } @@ -849,7 +849,7 @@ DocBookInfoTag getParagraphsWithInfo(ParagraphList const ¶graphs, for (; cpit < epit; ++cpit) { // Skip paragraphs that don't generate anything in DocBook. Paragraph const & par = paragraphs[cpit]; - if (par.empty() || par.emptyTag() || hasOnlyNotes(par)) + if (hasOnlyNotes(par)) continue; // There should never be any section here. (Just a sanity check: if this fails, this function could end up @@ -867,14 +867,14 @@ DocBookInfoTag getParagraphsWithInfo(ParagraphList const ¶graphs, } // Based on layout information, store this paragraph in one set: should be in <info>, must be, - // or abstract (). + // or abstract (either because of layout or of position). Layout const &style = par.layout(); if (style.docbookininfo() == "always") mustBeInInfo.emplace(cpit); else if (style.docbookininfo() == "maybe") shouldBeInInfo.emplace(cpit); - else if (!hasAbstractLayout) + else if (documentHasSections && !hasAbstractLayout) abstractNoLayout.emplace(cpit); else // This should definitely not be in <info>. break; @@ -991,17 +991,17 @@ void docbookSimpleAllParagraphs( { // Handle the given text, supposing it has no sections (i.e. a "simple" text). The input may vary in length // between a single paragraph to a whole document. + pit_type const bpit = runparams.par_begin; + pit_type const epit = runparams.par_end; + ParagraphList const ¶graphs = text.paragraphs(); // First, the <info> tag. - ParagraphList const ¶graphs = text.paragraphs(); - pit_type bpit = runparams.par_begin; - pit_type const epit = runparams.par_end; DocBookInfoTag info = getParagraphsWithInfo(paragraphs, bpit, epit, false); outputDocBookInfo(text, buf, xs, runparams, paragraphs, info); // Then, the content. It starts where the <info> ends. - auto par = text.paragraphs().iterator_at(info.epit); - auto end = text.paragraphs().iterator_at(epit); + auto par = paragraphs.iterator_at(info.epit); + auto end = paragraphs.iterator_at(epit); while (par != end) { if (!hasOnlyNotes(*par)) par = makeAny(text, buf, xs, runparams, par); @@ -1038,7 +1038,7 @@ void docbookParagraphs(Text const &text, tie(documentHasSections, eppit) = hasDocumentSectioning(paragraphs, bpit, epit); // Deal with "simple" documents, i.e. those without sections. - if (!documentHasSections){ + if (!documentHasSections) { docbookSimpleAllParagraphs(text, buf, xs, runparams); return; } @@ -1046,7 +1046,7 @@ void docbookParagraphs(Text const &text, // Output the first <info> tag (or just the title). DocBookInfoTag info = getParagraphsWithInfo(paragraphs, bpit, eppit, true); outputDocBookInfo(text, buf, xs, runparams, paragraphs, info); - bpit = eppit; + bpit = info.epit; // Then, iterate through the paragraphs of this document. bool currentlyInAppendix = false; @@ -1139,6 +1139,29 @@ void docbookParagraphs(Text const &text, // Generate this paragraph. par = makeAny(text, buf, xs, ourparams, par); + + // Some special sections may require abstracts (mostly parts, in books). + // TODO: docbookforceabstracttag is a bit contrived here, but it does the job. Having another field just for this would be cleaner, but that's just for <part> and <partintro>, so it's probably not worth the effort. + if (isLayoutSectioning(style) && style.docbookforceabstracttag() != "NONE") { + // This abstract may be found between the next paragraph and the next title. + pit_type cpit = std::distance(text.paragraphs().begin(), par); + pit_type ppit = std::get<1>(hasDocumentSectioning(paragraphs, cpit, epit)); + + // Generate this abstract (this code corresponds to parts of outputDocBookInfo). + DocBookInfoTag secInfo = getParagraphsWithInfo(paragraphs, cpit, ppit, true); + + if (!secInfo.abstract.empty()) { + xs << xml::StartTag(style.docbookforceabstracttag()); + xs << xml::CR(); + for (auto const &p : secInfo.abstract) + makeAny(text, buf, xs, runparams, paragraphs.iterator_at(p)); + xs << xml::EndTag(style.docbookforceabstracttag()); + xs << xml::CR(); + } + + // Skip all the text that just has been generated. + par = paragraphs.iterator_at(ppit); + } } // If need be, close <section>s, but only at the end of the document (otherwise, dealt with at the beginning commit 67c1425cba16e55c20e710515691c980b0ac85de Author: Thibaut Cuvelier <[email protected]> Date: Sun Aug 30 00:58:50 2020 +0200 DocBook: streamline code to handle sections. diff --git a/src/output_docbook.cpp b/src/output_docbook.cpp index 375babb..609f45c 100644 --- a/src/output_docbook.cpp +++ b/src/output_docbook.cpp @@ -1069,18 +1069,18 @@ void docbookParagraphs(Text const &text, if (isLayoutSectioning(style)) { int level = style.toclevel; - // Need to close a previous section if it has the same level or a higher one (close <section> if opening a <h2> - // after a <h2>, <h3>, <h4>, <h5> or <h6>). More examples: + // Need to close a previous section if it has the same level or a higher one (close <section> if opening a + // <h2> after a <h2>, <h3>, <h4>, <h5> or <h6>). More examples: // - current: h2; back: h1; do not close any <section> // - current: h1; back: h2; close two <section> (first the <h2>, then the <h1>, so a new <h1> can come) while (!headerLevels.empty() && level <= headerLevels.top().first) { + // Output the tag only if it corresponds to a legit section. int stackLevel = headerLevels.top().first; - docstring stackTag = from_utf8("</" + headerLevels.top().second + ">"); + if (stackLevel != Layout::NOT_IN_TOC) { + xs << xml::EndTag(headerLevels.top().second); + xs << xml::CR(); + } headerLevels.pop(); - - // Output the tag only if it corresponds to a legit section. - if (stackLevel != Layout::NOT_IN_TOC) - xs << XMLStream::ESCAPE_NONE << stackTag << xml::CR(); } // Open the new section: first push it onto the stack, then output it in DocBook. @@ -1109,11 +1109,10 @@ void docbookParagraphs(Text const &text, } // Write the open tag for this section. - docstring tag = from_utf8("<" + sectionTag); + docstring attrs; if (!id.empty()) - tag += from_utf8(" ") + id; - tag += from_utf8(">"); - xs << XMLStream::ESCAPE_NONE << tag; + attrs = id; + xs << xml::StartTag(sectionTag, attrs); xs << xml::CR(); } } commit a36ebdd3940a69f8dad26fa65b8cc6977624cb4b Author: Thibaut Cuvelier <[email protected]> Date: Sun Aug 30 00:35:47 2020 +0200 DocBook: streamline code to handle abstracts. diff --git a/autotests/export/docbook/basic_book.xml b/autotests/export/docbook/basic_book.xml index c94d2fa..18496b9 100644 --- a/autotests/export/docbook/basic_book.xml +++ b/autotests/export/docbook/basic_book.xml @@ -1,12 +1,14 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- This DocBook file was created by LyX 2.4.0dev See http://www.lyx.org/ for more information --> -<book xml:lang="en_US" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:xi="http://www.w3.org/2001/XInclude" version="5.1"> - -<info><title>Book title</title> -<author><personname>Book author</personname></author> - -<abstract><para>Book abstract in info. </para> +<book xml:lang="en_US" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:xi="http://www.w3.org/2001/XInclude" version="5.2"> +<info> +<title>Book title</title> +<author> +<personname>Book author</personname> +</author> +<abstract> +<para>Book abstract in info. </para> </abstract> </info> <chapter> @@ -15,9 +17,7 @@ </chapter> <part> <title>First part</title> - -<partintro><para>Part intro. </para> -</partintro> +<para>Part intro. </para> <chapter> <title>First chapter of first part</title> <para>Paragraph. </para> @@ -29,9 +29,7 @@ </part> <part> <title>Second part</title> - -<partintro><para>Part 2 intro. </para> -</partintro> +<para>Part 2 intro. </para> <chapter> <title>First chapter of second part</title> <para>Paragraph. </para> @@ -41,5 +39,4 @@ <para>Paragraph. </para> </chapter> </part> - </book> \ No newline at end of file diff --git a/src/output_docbook.cpp b/src/output_docbook.cpp index 419de20..375babb 100644 --- a/src/output_docbook.cpp +++ b/src/output_docbook.cpp @@ -771,21 +771,28 @@ ParagraphList::const_iterator makeAny(Text const &text, } +bool isLayoutSectioning(Layout const & lay) +{ + return lay.category() == from_utf8("Sectioning"); +} + + using DocBookDocumentSectioning = tuple<bool, pit_type>; struct DocBookInfoTag { const set<pit_type> shouldBeInInfo; - const set<pit_type> mustBeInInfo; + const set<pit_type> mustBeInInfo; // With the notable exception of the abstract! const set<pit_type> abstract; + const bool abstractLayout; pit_type bpit; pit_type epit; DocBookInfoTag(const set<pit_type> & shouldBeInInfo, const set<pit_type> & mustBeInInfo, - const set<pit_type> & abstract, pit_type bpit, pit_type epit) : + const set<pit_type> & abstract, bool abstractLayout, pit_type bpit, pit_type epit) : shouldBeInInfo(shouldBeInInfo), mustBeInInfo(mustBeInInfo), abstract(abstract), - bpit(bpit), epit(epit) {} + abstractLayout(abstractLayout), bpit(bpit), epit(epit) {} }; @@ -794,7 +801,7 @@ DocBookDocumentSectioning hasDocumentSectioning(ParagraphList const ¶graphs, while (bpit < epit) { Layout const &style = paragraphs[bpit].layout(); - documentHasSections |= style.category() == from_utf8("Sectioning"); + documentHasSections |= isLayoutSectioning(style); if (documentHasSections) break; @@ -818,10 +825,14 @@ bool hasOnlyNotes(Paragraph const & par) } -DocBookInfoTag getParagraphsWithInfo(ParagraphList const ¶graphs, pit_type bpit, pit_type const epit) { +DocBookInfoTag getParagraphsWithInfo(ParagraphList const ¶graphs, + pit_type bpit, pit_type const epit, + // Typically, bpit is the beginning of the document and epit the end *or* the first section. + bool documentHasSections) { set<pit_type> shouldBeInInfo; set<pit_type> mustBeInInfo; - set<pit_type> abstract; + set<pit_type> abstractWithLayout; + set<pit_type> abstractNoLayout; // Find the first non empty paragraph by mutating bpit. while (bpit < epit) { @@ -832,78 +843,48 @@ DocBookInfoTag getParagraphsWithInfo(ParagraphList const ¶graphs, pit_type b break; } - // Find the last info-like paragraph. - pit_type cpit = bpit; + // Traverse everything that might belong to <info>. bool hasAbstractLayout = false; - while (cpit < epit) { - // Skip paragraphs only containing one note. + pit_type cpit = bpit; + for (; cpit < epit; ++cpit) { + // Skip paragraphs that don't generate anything in DocBook. Paragraph const & par = paragraphs[cpit]; - if (hasOnlyNotes(par)) { - cpit += 1; + if (par.empty() || par.emptyTag() || hasOnlyNotes(par)) continue; + + // There should never be any section here. (Just a sanity check: if this fails, this function could end up + // processing the whole document.) + if (isLayoutSectioning(par.layout())) { + LYXERR0("Assertion failed: section found in potential <info> paragraphs."); + break; } - if (par.layout().docbookabstract()) + // If this is marked as an abstract by the layout, put it in the right set. + if (par.layout().docbookabstract()) { hasAbstractLayout = true; + abstractWithLayout.emplace(cpit); + continue; + } - // Based on layout information, store this paragraph in one set: should be in <info>, must be. + // Based on layout information, store this paragraph in one set: should be in <info>, must be, + // or abstract (). Layout const &style = par.layout(); - if (style.docbookininfo() == "always") { + if (style.docbookininfo() == "always") mustBeInInfo.emplace(cpit); - } else if (style.docbookininfo() == "maybe") { + else if (style.docbookininfo() == "maybe") shouldBeInInfo.emplace(cpit); - } else { - // Hypothesis: the <info> parts should be grouped together near the beginning bpit. - // There may be notes in between, but nothing else. + else if (!hasAbstractLayout) + abstractNoLayout.emplace(cpit); + else // This should definitely not be in <info>. break; - } - cpit += 1; } - // Now, cpit points to the last paragraph that has things that could go in <info>. + // Now, cpit points to the first paragraph that no more has things that could go in <info>. // bpit is the beginning of the <info> part. - // Go once again through the list of paragraphs to find the abstract. If there is an abstract - // layout, only consider it. Otherwise, an abstract is just a sequence of paragraphs with text. - if (hasAbstractLayout) { - pit_type pit = bpit; - while (pit < cpit) { // Don't overshoot the <info> part. - if (paragraphs[pit].layout().docbookabstract()) - abstract.emplace(pit); - pit++; - } - } else { - pit_type lastAbstract = epit + 1; // A nonsensical value. - docstring lastAbstractLayout; - - pit_type pit = bpit; - while (pit < cpit) { // Don't overshoot the <info> part. - const Paragraph & par = paragraphs.at(pit); - if (!par.insetList().empty()) { - for (const auto &i : par.insetList()) { - if (i.inset->getText(0) != nullptr) { - if (lastAbstract == epit + 1) { - // First paragraph that matches the heuristic definition of abstract. - lastAbstract = pit; - lastAbstractLayout = par.layout().name(); - } else if (pit > lastAbstract + 1 || par.layout().name() != lastAbstractLayout) { - // This is either too far from the last abstract paragraph or doesn't - // have the right layout name, BUT there has already been an abstract - // in this document: done with detecting the abstract. - goto done; // Easier to get out of two nested loops. - } - - abstract.emplace(pit); - break; - } - } - } - pit++; - } - } - - done: - return DocBookInfoTag(shouldBeInInfo, mustBeInInfo, abstract, bpit, cpit); + return DocBookInfoTag(shouldBeInInfo, mustBeInInfo, + hasAbstractLayout ? abstractWithLayout : abstractNoLayout, + hasAbstractLayout, bpit, cpit); } } // end anonymous namespace @@ -938,17 +919,9 @@ void outputDocBookInfo( if (hasAbstract) { // Generate the abstract XML into a string before further checks. odocstringstream os2; - { - XMLStream xs2(os2); - auto bpit = *std::min_element(info.abstract.begin(), info.abstract.end()); - auto epit = 1 + *std::max_element(info.abstract.begin(), info.abstract.end()); - // info.abstract is inclusive, epit is exclusive, hence +1 for looping. - - while (bpit < epit) { - makeAny(text, buf, xs2, runparams, paragraphs.iterator_at(bpit)); - bpit += 1; - } - } + XMLStream xs2(os2); + for (auto const & p : info.abstract) + makeAny(text, buf, xs2, runparams, paragraphs.iterator_at(p)); // Actually output the abstract if there is something to do. Don't count line feeds or spaces in this, // even though they must be properly output if there is some abstract. @@ -972,27 +945,33 @@ void outputDocBookInfo( } // Output the elements that should go in <info>, before and after the abstract. - for (auto pit : info.shouldBeInInfo) { // Typically, the title: these elements are so important and ubiquitous + for (auto pit : info.shouldBeInInfo) // Typically, the title: these elements are so important and ubiquitous // that mandating a wrapper like <info> would repel users. Thus, generate them first. makeAny(text, buf, xs, runparams, paragraphs.iterator_at(pit)); - } - for (auto pit : info.mustBeInInfo) { + for (auto pit : info.mustBeInInfo) if (info.abstract.find(pit) == info.abstract.end()) // The abstract must be in info, but is dealt with after. makeAny(text, buf, xs, runparams, paragraphs.iterator_at(pit)); - } // Always output the abstract as the last item of the <info>, as it requires special treatment (especially if // it contains several paragraphs that are empty). if (hasAbstract) { -// string tag = paragraphs[*info.abstract.begin()].layout().docbookforceabstracttag(); -// if (tag == "NONE") -// tag = "abstract"; -// -// xs << xml::StartTag(tag); -// xs << xml::CR(); - xs << XMLStream::ESCAPE_NONE << abstract; -// xs << xml::EndTag(tag); -// xs << xml::CR(); + if (info.abstractLayout) { + xs << XMLStream::ESCAPE_NONE << abstract; + xs << xml::CR(); + } else { + string tag = paragraphs[*info.abstract.begin()].layout().docbookforceabstracttag(); + if (tag == "NONE") + tag = "abstract"; + + if (!xs.isLastTagCR()) + xs << xml::CR(); + + xs << xml::StartTag(tag); + xs << xml::CR(); + xs << XMLStream::ESCAPE_NONE << abstract; + xs << xml::EndTag(tag); + xs << xml::CR(); + } } // End the <info> tag if it was started. @@ -1004,23 +983,6 @@ void outputDocBookInfo( } -void docbookFirstParagraphs( - Text const &text, - Buffer const &buf, - XMLStream &xs, - OutputParams const &runparams, - pit_type epit) -{ - // Handle the beginning of the document, supposing it has sections. - // Major role: output the first <info> tag. - - ParagraphList const ¶graphs = text.paragraphs(); - pit_type bpit = runparams.par_begin; - DocBookInfoTag info = getParagraphsWithInfo(paragraphs, bpit, epit); - outputDocBookInfo(text, buf, xs, runparams, paragraphs, info); -} - - void docbookSimpleAllParagraphs( Text const & text, Buffer const & buf, @@ -1034,7 +996,7 @@ void docbookSimpleAllParagraphs( ParagraphList const ¶graphs = text.paragraphs(); pit_type bpit = runparams.par_begin; pit_type const epit = runparams.par_end; - DocBookInfoTag info = getParagraphsWithInfo(paragraphs, bpit, epit); + DocBookInfoTag info = getParagraphsWithInfo(paragraphs, bpit, epit, false); outputDocBookInfo(text, buf, xs, runparams, paragraphs, info); // Then, the content. It starts where the <info> ends. @@ -1069,20 +1031,24 @@ void docbookParagraphs(Text const &text, std::stack<std::pair<int, string>> headerLevels; // Used to determine when to open/close sections: store the depth // of the section and the tag that was used to open it. - // Detect whether the document contains sections. If there are no sections, there can be no automatically - // discovered abstract. + // Detect whether the document contains sections. If there are no sections, treatment is largely simplified. + // In particular, there can't be an abstract, unless it is manually marked. bool documentHasSections; pit_type eppit; tie(documentHasSections, eppit) = hasDocumentSectioning(paragraphs, bpit, epit); - if (documentHasSections) { - docbookFirstParagraphs(text, buf, xs, runparams, eppit); - bpit = eppit; - } else { + // Deal with "simple" documents, i.e. those without sections. + if (!documentHasSections){ docbookSimpleAllParagraphs(text, buf, xs, runparams); return; } + // Output the first <info> tag (or just the title). + DocBookInfoTag info = getParagraphsWithInfo(paragraphs, bpit, eppit, true); + outputDocBookInfo(text, buf, xs, runparams, paragraphs, info); + bpit = eppit; + + // Then, iterate through the paragraphs of this document. bool currentlyInAppendix = false; auto par = text.paragraphs().iterator_at(bpit); @@ -1100,8 +1066,7 @@ void docbookParagraphs(Text const &text, Layout const &style = par->layout(); // Think about adding <section> and/or </section>s. - const bool isLayoutSectioning = style.category() == from_utf8("Sectioning"); - if (isLayoutSectioning) { + if (isLayoutSectioning(style)) { int level = style.toclevel; // Need to close a previous section if it has the same level or a higher one (close <section> if opening a <h2> commit 932bb3fc61419dffa8e25254ebd94e791dca28d5 Author: Thibaut Cuvelier <[email protected]> Date: Sun Aug 30 00:30:44 2020 +0200 Fix warning. diff --git a/src/output_docbook.cpp b/src/output_docbook.cpp index ea9180b..419de20 100644 --- a/src/output_docbook.cpp +++ b/src/output_docbook.cpp @@ -444,7 +444,7 @@ void makeParagraph( special_case = true; } - int nInsets = std::distance(par->insetList().begin(), par->insetList().end()); + size_t nInsets = std::distance(par->insetList().begin(), par->insetList().end()); // Plain layouts must be ignored. special_case |= buf.params().documentClass().isPlainLayout(par->layout()) && !runparams.docbook_force_pars; commit a2ed7d2ce7eeeda4acb6af231242fd4e3f5f019b Author: Thibaut Cuvelier <[email protected]> Date: Sat Aug 29 23:41:28 2020 +0200 DocBook: fix handling of index end-of-range. diff --git a/autotests/export/docbook/basic.xml b/autotests/export/docbook/basic.xml index a4dc276..ea91d3d 100644 --- a/autotests/export/docbook/basic.xml +++ b/autotests/export/docbook/basic.xml @@ -205,9 +205,9 @@ I am a second line of code. <para>Then several terms for the first index: <indexterm type="idx"><primary>Term</primary><secondary>to</secondary><tertiary>index</tertiary></indexterm>. </para> <para>With a see: <indexterm type="idx"><primary>Term</primary><see>index</see></indexterm>. With a see also: <indexterm type="idx"><primary>Term</primary><seealso>index</seealso></indexterm>. </para> <para>Several terms with a see: <indexterm type="idx"><primary>Term</primary><secondary>to</secondary><tertiary>index</tertiary><see>index</see></indexterm>. Several terms with a see also: <indexterm type="idx"><primary>Term</primary><secondary>to</secondary><tertiary>index</tertiary><seealso>index</seealso></indexterm>. </para> -<para>A start of range: <indexterm type="idx" class="startofrange" xml:id="Term-to-index"><primary>Term to index</primary></indexterm>. The corresponding end of range: <indexterm type="idx" class="endofrange" startref="Term-to-index"><primary>Term to index</primary></indexterm>.</para> -<para>Several terms with a start of range: <indexterm type="idx" class="startofrange" xml:id="Term.to.index"><primary>Term</primary><secondary>to</secondary><tertiary>index</tertiary></indexterm>. The corresponding end of range: <indexterm type="idx" class="endofrange" startref="Term.to.index"><primary>Term</primary><secondary>to</secondary><tertiary>index</tertiary></indexterm>.</para> -<para>These terms already appeared before! Start of range: <indexterm type="idx" class="startofrange" xml:id="Term.to.index-0"><primary>Term</primary><secondary>to</secondary><tertiary>index</tertiary></indexterm>. The corresponding end of range: <indexterm type="idx" class="endofrange" startref="Term.to.index-0"><primary>Term</primary><secondary>to</secondary><tertiary>index</tertiary></indexterm>.</para> +<para>A start of range: <indexterm type="idx" class="startofrange" xml:id="Term-to-index"><primary>Term to index</primary></indexterm>. The corresponding end of range: <indexterm class="endofrange" startref="Term-to-index" />.</para> +<para>Several terms with a start of range: <indexterm type="idx" class="startofrange" xml:id="Term.to.index"><primary>Term</primary><secondary>to</secondary><tertiary>index</tertiary></indexterm>. The corresponding end of range: <indexterm class="endofrange" startref="Term.to.index" />.</para> +<para>These terms already appeared before! Start of range: <indexterm type="idx" class="startofrange" xml:id="Term.to.index-0"><primary>Term</primary><secondary>to</secondary><tertiary>index</tertiary></indexterm>. The corresponding end of range: <indexterm class="endofrange" startref="Term.to.index-0" />.</para> </section> <section> <title>I am the eight section and I deal with star sections</title> diff --git a/src/insets/InsetIndex.cpp b/src/insets/InsetIndex.cpp index 987c138..149ef65 100644 --- a/src/insets/InsetIndex.cpp +++ b/src/insets/InsetIndex.cpp @@ -287,14 +287,17 @@ void InsetIndex::docbook(XMLStream & xs, OutputParams const & runparams) const // Hence the thread-local storage, as the numbers must strictly be unique, and thus cannot be shared across // a paragraph (making the solution used for HTML worthless). This solution is very similar to the one used in // xml::cleanID. - docstring attrs = indexType; - if (hasStartRange || hasEndRange) { + // indexType can only be used for singular and startofrange types! + docstring attrs; + if (!hasStartRange && !hasEndRange) { + attrs = indexType; + } else { // Append an ID if uniqueness is not guaranteed across the document. static QThreadStorage<set<docstring>> tKnownTermLists; static QThreadStorage<int> tID; - set<docstring> & knownTermLists = tKnownTermLists.localData(); - int & ID = tID.localData(); + set<docstring> &knownTermLists = tKnownTermLists.localData(); + int &ID = tID.localData(); if (!tID.hasLocalData()) { tID.localData() = 0; @@ -319,47 +322,51 @@ void InsetIndex::docbook(XMLStream & xs, OutputParams const & runparams) const // Generate the attributes. docstring id = xml::cleanID(newIndexTerms); if (hasStartRange) { - attrs += " class=\"startofrange\" xml:id=\"" + id + "\""; + attrs = indexType + " class=\"startofrange\" xml:id=\"" + id + "\""; } else { - attrs += " class=\"endofrange\" startref=\"" + id + "\""; + attrs = " class=\"endofrange\" startref=\"" + id + "\""; } } // Handle the index terms (including the specific index for this entry). - xs << xml::StartTag("indexterm", attrs); - if (terms.size() > 0) { // hasEndRange has no content. - xs << xml::StartTag("primary"); - xs << terms[0]; - xs << xml::EndTag("primary"); - } - if (terms.size() > 1) { - xs << xml::StartTag("secondary"); - xs << terms[1]; - xs << xml::EndTag("secondary"); - } - if (terms.size() > 2) { - xs << xml::StartTag("tertiary"); - xs << terms[2]; - xs << xml::EndTag("tertiary"); - } + if (hasEndRange) { + xs << xml::CompTag("indexterm", attrs); + } else { + xs << xml::StartTag("indexterm", attrs); + if (!terms.empty()) { // hasEndRange has no content. + xs << xml::StartTag("primary"); + xs << terms[0]; + xs << xml::EndTag("primary"); + } + if (terms.size() > 1) { + xs << xml::StartTag("secondary"); + xs << terms[1]; + xs << xml::EndTag("secondary"); + } + if (terms.size() > 2) { + xs << xml::StartTag("tertiary"); + xs << terms[2]; + xs << xml::EndTag("tertiary"); + } - // Handle see and see also. - if (!see.empty()) { - xs << xml::StartTag("see"); - xs << see; - xs << xml::EndTag("see"); - } + // Handle see and see also. + if (!see.empty()) { + xs << xml::StartTag("see"); + xs << see; + xs << xml::EndTag("see"); + } - if (!seeAlsoes.empty()) { - for (auto & entry : seeAlsoes) { - xs << xml::StartTag("seealso"); - xs << entry; - xs << xml::EndTag("seealso"); + if (!seeAlsoes.empty()) { + for (auto &entry : seeAlsoes) { + xs << xml::StartTag("seealso"); + xs << entry; + xs << xml::EndTag("seealso"); + } } - } - // Close the entry. - xs << xml::EndTag("indexterm"); + // Close the entry. + xs << xml::EndTag("indexterm"); + } } } diff --git a/src/xml.cpp b/src/xml.cpp index 0daa9d8..557bb01 100644 --- a/src/xml.cpp +++ b/src/xml.cpp @@ -140,11 +140,11 @@ docstring EndTag::writeEndTag() const docstring CompTag::writeTag() const { - docstring output = '<' + from_utf8(tag_); + docstring output = '<' + tag_; if (!attr_.empty()) { // Erase the beginning of the attributes if it contains space characters: this function deals with that // automatically. - docstring attributes = escapeString(from_utf8(attr_), XMLStream::ESCAPE_NONE); + docstring attributes = escapeString(attr_, XMLStream::ESCAPE_NONE); attributes.erase(attributes.begin(), std::find_if(attributes.begin(), attributes.end(), [](int c) {return !std::isspace(c);})); if (!attributes.empty()) { diff --git a/src/xml.h b/src/xml.h index bbf5b58..ebb8b8e 100644 --- a/src/xml.h +++ b/src/xml.h @@ -242,16 +242,19 @@ struct CompTag { /// explicit CompTag(std::string const & tag) - : tag_(tag) {} + : tag_(from_utf8(tag)) {} /// explicit CompTag(std::string const & tag, std::string const & attr) - : tag_(tag), attr_(attr) {} + : tag_(from_utf8(tag)), attr_(from_utf8(attr)) {} + /// + explicit CompTag(std::string const & tag, docstring const & attr) + : tag_(from_utf8(tag)), attr_(attr) {} /// <tag_ attr_ /> docstring writeTag() const; /// - std::string tag_; + docstring tag_; /// - std::string attr_; + docstring attr_; }; commit 2d02d355c16dfb69e58d81019404e88b7085f1fb Author: Thibaut Cuvelier <[email protected]> Date: Sat Aug 29 22:58:23 2020 +0200 DocBook: fix float tags (was unduly overridden). The output was not valid for floats without title. diff --git a/CMakeLists.txt b/CMakeLists.txt index 62eff71..3dbf98b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,6 +6,11 @@ cmake_minimum_required(VERSION 3.1.0) +set(CMAKE_CXX_STANDARD 20) +set(GNUWIN32_DIR D:/LyX/lyx-unstable/lyx-windows-deps-msvc2017) +set(LYX_USE_QT "QT5") +set(LYX_REQUIRE_SPELLCHECK true) + set(LYX_PROJECT LyX) # Instruct cmake to not use gnu extensions, diff --git a/autotests/export/docbook/basic.xml b/autotests/export/docbook/basic.xml index 430611e..a4dc276 100644 --- a/autotests/export/docbook/basic.xml +++ b/autotests/export/docbook/basic.xml @@ -164,7 +164,7 @@ I am a second line of code. </tr> </tbody> </table> -<table> +<informaltable> <tbody> <tr> <td align='center' valign='top'>Table that has no caption 1</td> @@ -182,7 +182,7 @@ I am a second line of code. <td align='center' valign='top'>Col 3, row 2</td> </tr> </tbody> -</table> +</informaltable> <para>Then, one figure: </para> <figure> diff --git a/lib/layouts/stdfloats.inc b/lib/layouts/stdfloats.inc index cd6614a..044fcb2 100644 --- a/lib/layouts/stdfloats.inc +++ b/lib/layouts/stdfloats.inc @@ -20,7 +20,6 @@ Float UsesFloatPkg false ListCommand listoftables RefPrefix tab - DocBookTag table End @@ -36,7 +35,6 @@ Float UsesFloatPkg false ListCommand listoffigures RefPrefix fig - DocBookTag figure End @@ -51,7 +49,6 @@ Float IsPredefined false UsesFloatPkg true RefPrefix alg - DocBookTag figure # TODO: No DocBook tag really corresponds... End diff --git a/src/Floating.cpp b/src/Floating.cpp index d44afc3..19fbf5f 100644 --- a/src/Floating.cpp +++ b/src/Floating.cpp @@ -40,8 +40,7 @@ Floating::Floating(string const & type, string const & placement, usesfloatpkg_(usesfloat), ispredefined_(ispredefined), allowswide_(allowswide), allowssideways_(allowssideways), html_tag_(htmlTag), html_attrib_(htmlAttrib), html_style_(htmlStyle), - docbook_tag_(docbookTag), docbook_attr_(docbookAttr), - docbook_tag_type_(docbookTagType) + docbook_attr_(docbookAttr), docbook_tag_type_(docbookTagType) {} @@ -89,21 +88,17 @@ string const & Floating::docbookAttr() const } -string const & Floating::docbookTag(bool hasTitle) const +string Floating::docbookTag(bool hasTitle) const { - if (docbook_tag_.empty()) { - docbook_tag_ = ""; - if (floattype_ == "figure") { - docbook_tag_ = hasTitle ? "figure" : "informalfigure"; - } else if (floattype_ == "table") { - docbook_tag_ = hasTitle ? "table" : "informaltable"; - } else if (floattype_ == "algorithm") { - // TODO: no good translation for now! Figures are the closest match, as they can contain text. - // Solvable as soon as https://github.com/docbook/docbook/issues/157 has a definitive answer. - docbook_tag_ = "figure"; - } + if (floattype_ == "figure") { + return hasTitle ? "figure" : "informalfigure"; + } else if (floattype_ == "table") { + return hasTitle ? "table" : "informaltable"; + } else if (floattype_ == "algorithm") { + // TODO: no good translation for now! Figures are the closest match, as they can contain text. + // Solvable as soon as https://github.com/docbook/docbook/issues/157 has a definitive answer. + return "figure"; } - return docbook_tag_; } diff --git a/src/Floating.h b/src/Floating.h index 5cfea08..977958b 100644 --- a/src/Floating.h +++ b/src/Floating.h @@ -81,7 +81,7 @@ public: /// tag type, defaults to "div" std::string const & htmlTag() const; /// - std::string const & docbookTag(bool hasTitle = false) const; + std::string docbookTag(bool hasTitle = false) const; /// std::string const & docbookAttr() const; /// @@ -129,8 +129,8 @@ private: mutable std::string defaultcssclass_; /// docstring html_style_; - /// DocBook tag - mutable std::string docbook_tag_; + // There is no way to override the DocBook tag based on the layouts: half of it is determined by whether the float + // has a title or not, an information that is not available in the layouts. /// attribute (mostly, role) mutable std::string docbook_caption_; /// caption tag (mostly, either caption or title) diff --git a/src/insets/InsetFloat.cpp b/src/insets/InsetFloat.cpp index b0a48f2..8914cfe 100644 --- a/src/insets/InsetFloat.cpp +++ b/src/insets/InsetFloat.cpp @@ -654,7 +654,7 @@ void docbookNoSubfigures(XMLStream & xs, OutputParams const & runparams, const I xs << xml::StartTag(ftype.docbookTag(caption != nullptr), attr); xs << xml::CR(); - if (caption != nullptr) { + if (caption) { xs << xml::StartTag(titleTag); caption->getCaptionAsDocBook(xs, rpNoLabel); xs << xml::EndTag(titleTag); diff --git a/src/mathed/InsetMathHull.cpp b/src/mathed/InsetMathHull.cpp index 35c8a36..e8dc3af 100644 --- a/src/mathed/InsetMathHull.cpp +++ b/src/mathed/InsetMathHull.cpp @@ -2419,7 +2419,7 @@ void InsetMathHull::docbook(XMLStream & xs, OutputParams const & runparams) cons } // DocBook also has <equation>, but it comes with a title. - // TODO: recognise \tag from amsmath? + // TODO: recognise \tag from amsmath? This would allow having <equation> with a proper title. docstring attr; for (row_type i = 0; i < nrows(); ++i) { commit 79950e1824899b711007f32764d21cb803ce4391 Author: Thibaut Cuvelier <[email protected]> Date: Sat Aug 29 19:05:59 2020 +0200 DocBook: improve equation formatting (new lines for block equations). diff --git a/autotests/export/docbook/basic.lyx b/autotests/export/docbook/basic.lyx index 1735dc4..fa98d65 100644 --- a/autotests/export/docbook/basic.lyx +++ b/autotests/export/docbook/basic.lyx @@ -185,7 +185,7 @@ noprefix "false" \begin_layout Standard Also, a formula with an user-defined macro that outputs well in LaTeX but - cannot in MathML (hence replaced by picture): + cannot in MathML: \begin_inset Formula $\testmacro$ \end_inset diff --git a/autotests/export/docbook/basic.xml b/autotests/export/docbook/basic.xml index 7980289..430611e 100644 --- a/autotests/export/docbook/basic.xml +++ b/autotests/export/docbook/basic.xml @@ -30,7 +30,7 @@ </inlineequation>. </para> </blockquote> <para>Now, we're outside quotes.</para> -<para><informalequation> +<informalequation> <alt role='tex'>Formula!</alt> <m:math> @@ -39,7 +39,8 @@ </m:mrow> </m:mrow> </m:math> -</informalequation><informalequation xml:id="eq.EQ."> +</informalequation> +<informalequation xml:id="eq.EQ."> <alt role='tex'>\text{I am a formula with a ref.}\label{eq:EQ.}</alt> <m:math> @@ -50,9 +51,9 @@ </m:mstyle> </m:mrow> </m:math> -</informalequation></para> +</informalequation> <para>See <xref linkend="sec.Sec-2kqgsdiflhqsdlifgjuzer-povtuizmvnuer-t-vmsrmfli--uh--a--rtpfuo----rtpc.m-ca-rgifzapeu-tvgz" />.</para> -<para>Also, a formula with an user-defined macro that outputs well in LaTeX but cannot in MathML (hence replaced by picture): <inlineequation> +<para>Also, a formula with an user-defined macro that outputs well in LaTeX but cannot in MathML: <inlineequation> <alt role='tex'>\testmacro</alt> <mathphrase>MathML export failed. Please report this as a bug.</mathphrase> </inlineequation>. </para> diff --git a/src/Paragraph.cpp b/src/Paragraph.cpp index 5ee6171..91c8bf3 100644 --- a/src/Paragraph.cpp +++ b/src/Paragraph.cpp @@ -3336,7 +3336,8 @@ std::vector<docstring> Paragraph::simpleDocBookOnePar(Buffer const & buf, std::vector<docstring> generatedParagraphs; odocstringstream os; - auto * xs = new XMLStream(os); + auto * xs = new XMLStream(os); // XMLStream has no copy constructor: to create a new object, the only solution + // is to hold a pointer to the XMLStream (xs = XMLStream(os) is not allowed once the first object is built). // Parsing main loop. for (pos_type i = initial; i < size(); ++i) { @@ -3348,7 +3349,6 @@ std::vector<docstring> Paragraph::simpleDocBookOnePar(Buffer const & buf, if (getInset(i) != nullptr && getInset(i)->lyxCode() == NEWLINE_CODE) { generatedParagraphs.push_back(os.str()); os = odocstringstream(); - // XMLStream has no copy constructor. delete xs; xs = new XMLStream(os); } diff --git a/src/mathed/InsetMathHull.cpp b/src/mathed/InsetMathHull.cpp index 2cecba9..35c8a36 100644 --- a/src/mathed/InsetMathHull.cpp +++ b/src/mathed/InsetMathHull.cpp @@ -2410,10 +2410,16 @@ void InsetMathHull::docbook(XMLStream & xs, OutputParams const & runparams) cons docstring name; if (getType() == hullSimple) name = from_ascii("inlineequation"); - else + else { + // This is a block equation, always have <informalequation> on its own line. + if (!xs.isLastTagCR()) + xs << xml::CR(); + name = from_ascii("informalequation"); + } // DocBook also has <equation>, but it comes with a title. + // TODO: recognise \tag from amsmath? docstring attr; for (row_type i = 0; i < nrows(); ++i) { diff --git a/src/output_docbook.cpp b/src/output_docbook.cpp index 6c61dc6..ea9180b 100644 --- a/src/output_docbook.cpp +++ b/src/output_docbook.cpp @@ -444,10 +444,16 @@ void makeParagraph( special_case = true; } + int nInsets = std::distance(par->insetList().begin(), par->insetList().end()); + // Plain layouts must be ignored. - if (!special_case && buf.params().documentClass().isPlainLayout(par->layout()) && !runparams.docbook_force_pars) - special_case = true; - // TODO: Could get rid of this with a DocBook equivalent to htmlisblock? + special_case |= buf.params().documentClass().isPlainLayout(par->layout()) && !runparams.docbook_force_pars; + // Equations do not deserve their own paragraph (DocBook allows them outside paragraphs). + special_case |= nInsets == par->size() && std::all_of(par->insetList().begin(), par->insetList().end(), [](InsetList::Element inset) { + return inset.inset && inset.inset->asInsetMath(); + }); + + // TODO: Could get rid of this with a DocBook equivalent to htmlisblock? Not for all cases, unfortunately... See above for those that have been determined not to be allowable for this potential refactoring. if (!special_case && par->size() == 1 && par->getInset(0)) { Inset const * firstInset = par->getInset(0); @@ -458,10 +464,6 @@ void makeParagraph( 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; commit 7189e5ae41f3c0ddc7ff305b7aee7c882f928e58 Author: Thibaut Cuvelier <[email protected]> Date: Sat Aug 29 18:40:31 2020 +0200 DocBook: fix indentation for section titles (including stars). diff --git a/autotests/export/docbook/basic.lyx b/autotests/export/docbook/basic.lyx index 0bd87ce..1735dc4 100644 --- a/autotests/export/docbook/basic.lyx +++ b/autotests/export/docbook/basic.lyx @@ -1,5 +1,5 @@ -#LyX 2.4 created this file. For more info see http://www.lyx.org/ -\lyxformat 544 +#LyX 2.4 created this file. For more info see https://www.lyx.org/ +\lyxformat 598 \begin_document \begin_header \save_transient_properties true @@ -9,11 +9,11 @@ \newcommand{\testmacro}{\ensuremath{\operatorname{testmacro}}} \end_preamble \use_default_options true -\maintain_unincluded_children false +\maintain_unincluded_children no \language english \language_package default -\inputencoding auto -\fontencoding global +\inputencoding auto-legacy +\fontencoding auto \font_roman "default" "default" \font_sans "default" "default" \font_typewriter "default" "default" @@ -21,7 +21,9 @@ \font_default_family default \use_non_tex_fonts false \font_sc false -\font_osf false +\font_roman_osf false +\font_sans_osf false +\font_typewriter_osf false \font_sf_scale 100 100 \font_tt_scale 100 100 \use_microtype false @@ -56,6 +58,7 @@ \justification true \use_refstyle 1 \use_minted 0 +\use_lineno 0 \index Index \shortcut idx \color #008000 @@ -75,11 +78,15 @@ \papercolumns 1 \papersides 1 \paperpagestyle default +\tablestyle default \tracking_changes false \output_changes false +\change_bars false +\postpone_fragile_content false \html_math_output 0 \html_css_as_file 0 \html_be_strict false +\docbook_table_output 0 \end_header \begin_body @@ -140,6 +147,10 @@ I am a quote \end_layout \begin_layout Standard +Now, we're outside quotes. +\end_layout + +\begin_layout Standard \begin_inset Formula \[ Formula! @@ -386,6 +397,8 @@ Now, three tables: \begin_layout Standard \begin_inset Float table +placement document +alignment document wide false sideways false status open @@ -511,6 +524,8 @@ I am a table caption below the table. \begin_layout Standard \begin_inset Float table +placement document +alignment document wide false sideways false status open @@ -636,6 +651,8 @@ Col 3, row 2 \begin_layout Standard \begin_inset Float table +placement document +alignment document wide false sideways false status open @@ -753,6 +770,8 @@ Then, one figure: \begin_layout Standard \begin_inset Float figure +placement document +alignment document wide false sideways false status open diff --git a/autotests/export/docbook/basic.xml b/autotests/export/docbook/basic.xml index 6f4a828..7980289 100644 --- a/autotests/export/docbook/basic.xml +++ b/autotests/export/docbook/basic.xml @@ -29,6 +29,7 @@ </m:math> </inlineequation>. </para> </blockquote> +<para>Now, we're outside quotes.</para> <para><informalequation> <alt role='tex'>Formula!</alt> <m:math> @@ -72,22 +73,37 @@ </section> <section> <title>I am the third section and I have fun with lists</title> -<orderedlist><listitem>First item. -<br /> -Second line of the first item, after a line break. </listitem></orderedlist> -<orderedlist><listitem>Second item. </listitem></orderedlist> -<itemizedlist><listitem>Item has no order (1). </listitem></itemizedlist> -<itemizedlist><listitem>Item has no order (2). </listitem></itemizedlist> -<variablelist><listitem><varlistentry> - -Word description<!-- Output Error: Closing tag `listitem' when other tags are open, namely: --> -<!-- Output Error: varlistentry --> -</varlistentry></listitem></variablelist> -<variablelist><listitem><varlistentry> - -Sentence meaning<!-- Output Error: Closing tag `listitem' when other tags are open, namely: --> -<!-- Output Error: varlistentry --> -</varlistentry></listitem></variablelist> +<orderedlist> +<listitem> +<para>First item. </para> +<para>Second line of the first item, after a line break. </para> +</listitem> +<listitem> +<para>Second item. </para> +</listitem> +</orderedlist> +<itemizedlist> +<listitem> +<para>Item has no order (1). </para> +</listitem> +<listitem> +<para>Item has no order (2). </para> +</listitem> +</itemizedlist> +<variablelist> +<varlistentry> +<term>Word</term> +<listitem> +<para>description</para> +</listitem> +</varlistentry> +<varlistentry> +<term>Sentence</term> +<listitem> +<para>meaning</para> +</listitem> +</varlistentry> +</variablelist> </section> <section> <title>I am the fourth section and I deal with formatting. </title> @@ -95,9 +111,11 @@ Sentence meaning<!-- Output Error: Closing tag `listitem' when other tags are op <para><programlisting>I am some code. I am a second line of code. </programlisting>I am no more code. </para> -<para>This line has inline code. <code>This has typewriter font</code><footnote><para>I repeat that in a footnote.</para> +<para>This line has inline code. <code>This has typewriter font</code><footnote> +<para>I repeat that in a footnote.</para> </footnote>. </para> -<para>On the other hand, <footnote><para>this footnote</para> +<para>On the other hand, <footnote> +<para>this footnote</para> <para>has multiple </para> <para>paragraphs.</para> </footnote>. </para> @@ -145,7 +163,7 @@ I am a second line of code. </tr> </tbody> </table> -<informaltable> +<table> <tbody> <tr> <td align='center' valign='top'>Table that has no caption 1</td> @@ -163,7 +181,8 @@ I am a second line of code. <td align='center' valign='top'>Col 3, row 2</td> </tr> </tbody> -</informaltable> +</table> + <para>Then, one figure: </para> <figure> <title>Caption.</title> @@ -334,5 +353,4 @@ I am a second line of code. </author> </authorgroup> </biblioentry> -</bibliography> -</article> \ No newline at end of file +</bibliography></article> \ No newline at end of file diff --git a/lib/layouts/stdsections.inc b/lib/layouts/stdsections.inc index fa42eac..30b64ea 100644 --- a/lib/layouts/stdsections.inc +++ b/lib/layouts/stdsections.inc @@ -7,7 +7,7 @@ # commands that are useful for article-like document classes, but not # for letters. -Format 82 +Format 84 Style Part Category Sectioning @@ -40,6 +40,7 @@ Style Part EndFont HTMLTag h1 DocBookTag title + DocBookTagType paragraph DocBookSectionTag part DocBookForceAbstractTag partintro End @@ -75,6 +76,7 @@ Style Chapter EndFont HTMLTag h1 DocBookTag title + DocBookTagType paragraph DocBookSectionTag chapter End @@ -108,6 +110,7 @@ Style Section EndFont HTMLTag h2 DocBookTag title + DocBookTagType paragraph DocBookSectionTag section End ----------------------------------------------------------------------- Summary of changes: CMakeLists.txt | 5 + autotests/export/docbook/basic.lyx | 33 +++- autotests/export/docbook/basic.xml | 75 ++++++--- autotests/export/docbook/basic_book.xml | 23 ++-- lib/layouts/stdfloats.inc | 3 - lib/layouts/stdsections.inc | 5 +- src/Floating.cpp | 25 ++-- src/Floating.h | 6 +- src/Paragraph.cpp | 4 +- src/insets/InsetFloat.cpp | 2 +- src/insets/InsetIndex.cpp | 79 +++++----- src/mathed/InsetMathHull.cpp | 8 +- src/output_docbook.cpp | 263 +++++++++++++++---------------- src/xml.cpp | 4 +- src/xml.h | 11 +- 15 files changed, 296 insertions(+), 250 deletions(-) hooks/post-receive -- Repository for new features -- lyx-cvs mailing list [email protected] http://lists.lyx.org/mailman/listinfo/lyx-cvs
