[LyX/master] DocBook: generate <partintro> when required.

Thibaut Cuvelier tcuvelier at lyx.org
Sat Sep 19 18:18:55 UTC 2020


commit 642b18aad0b2add87ef746f78f77f3eb8467f693
Author: Thibaut Cuvelier <tcuvelier at lyx.org>
Date:   Sun Aug 30 01:14:44 2020 +0200

    DocBook: generate <partintro> when required.
---
 autotests/export/docbook/basic.xml      |    2 +
 autotests/export/docbook/basic_book.xml |    4 +++
 src/output_docbook.cpp                  |   45 +++++++++++++++++++++++-------
 3 files changed, 40 insertions(+), 11 deletions(-)

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 3e37f90..a0ac96a 100644
--- a/src/output_docbook.cpp
+++ b/src/output_docbook.cpp
@@ -821,7 +821,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;
 }
@@ -851,7 +851,7 @@ DocBookInfoTag getParagraphsWithInfo(ParagraphList const &paragraphs,
 	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
@@ -869,14 +869,14 @@ DocBookInfoTag getParagraphsWithInfo(ParagraphList const &paragraphs,
 		}
 
 		// 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;
@@ -993,17 +993,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 &paragraphs = text.paragraphs();
 
 	// First, the <info> tag.
-	ParagraphList const &paragraphs = 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);
@@ -1040,7 +1040,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;
 	}
@@ -1048,7 +1048,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;
@@ -1141,6 +1141,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


More information about the lyx-cvs mailing list