[LyX/master] DocBook: partially remove use of bpit/epit in docbookParagraphs and docbookSimpleAllParagraphs.
Thibaut Cuvelier
tcuvelier at lyx.org
Sat Sep 19 18:18:55 UTC 2020
commit fc0999a4220afb1646a5ae75ea8192b6d304ec56
Author: Thibaut Cuvelier <tcuvelier at lyx.org>
Date: Sat Aug 29 02:55:47 2020 +0200
DocBook: partially remove use of bpit/epit in docbookParagraphs and docbookSimpleAllParagraphs.
This will help with the next refactoring to be much cleaner (only work with iterators, don't maintain twice the same information).
---
src/output_docbook.cpp | 193 ++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 172 insertions(+), 21 deletions(-)
diff --git a/src/output_docbook.cpp b/src/output_docbook.cpp
index 0dc5257..ff47aa6 100644
--- a/src/output_docbook.cpp
+++ b/src/output_docbook.cpp
@@ -308,8 +308,32 @@ void closeParTag(XMLStream & xs, Paragraph const * par, Paragraph const * nextpa
if (nextpar != nullptr) {
Layout const & nextlay = nextpar->layout();
if (nextlay.docbookwrappertag() != "NONE") {
- closeWrapper = nextlay.docbookwrappertag() == lay.docbookwrappertag()
- && !nextlay.docbookwrappermergewithprevious();
+ if (nextpar->getDepth() == par->getDepth()) {
+ // Same depth: the basic condition applies.
+ closeWrapper = nextlay.docbookwrappertag() == lay.docbookwrappertag()
+ && !nextlay.docbookwrappermergewithprevious();
+ } else if (nextpar->getDepth() > par->getDepth()) {
+ // The next paragraph is deeper: no need to close the wrapper, only to open it (cf. openParTag).
+ closeWrapper = 0;
+ } else {
+ // This paragraph is deeper than the next one: close the wrapper,
+ // disregarding docbookwrappermergewithprevious.
+ // Hypothesis: nextlay.docbookwrappertag() == lay.docbookwrappertag(). TODO: THIS IS WRONG! Loop back until a layout with the right depth is found?
+ closeWrapper = 1L + (long long) par->getDepth() - (long long) nextpar->getDepth(); // > 0, as nextpar->getDepth() < par->getDepth()
+ }
+ } else {
+ if (nextpar->getDepth() == par->getDepth()) {
+ // This is not wrapped: this must be the rest of the item, still within the wrapper.
+ closeWrapper = 1;
+ } else if (nextpar->getDepth() > par->getDepth()) {
+ // The next paragraph is deeper: no need to close the wrapper, only to open it (cf. openParTag).
+ closeWrapper = 0;
+ } else {
+ // This paragraph is deeper than the next one: close the wrapper,
+ // disregarding docbookwrappermergewithprevious.
+ // Hypothesis: nextlay.docbookwrappertag() == lay.docbookwrappertag(). TODO: THIS IS WRONG! Loop back until a layout with the right depth is found?
+ closeWrapper = 1L + (long long) par->getDepth() - (long long) nextpar->getDepth(); // > 0, as nextpar->getDepth() < par->getDepth()
+ }
}
}
@@ -507,12 +531,140 @@ void makeParagraph(
}
-void makeEnvironment(
- Buffer const &buf,
- XMLStream &xs,
- OutputParams const &runparams,
- Text const &text,
- ParagraphList::const_iterator const & par)
+void makeEnvironment(Buffer const &buf,
+ XMLStream &xs,
+ OutputParams const &runparams,
+ Text const &text,
+ ParagraphList::const_iterator const & par)
+{
+ // TODO: simplify me!
+ auto const end = text.paragraphs().end();
+
+ // Output the opening tag for this environment, but only if it has not been previously opened (condition
+ // implemented in openParTag).
+ auto prevpar = text.paragraphs().getParagraphBefore(par);
+ openParTag(xs, &*par, prevpar); // TODO: switch in layout for par/block?
+
+ // Generate the contents of this environment. There is a special case if this is like some environment.
+ Layout const & style = par->layout();
+ if (style.latextype == LATEX_COMMAND) {
+ // Nothing to do (otherwise, infinite loops).
+ } else if (style.latextype == LATEX_ENVIRONMENT) {
+ // Open a wrapper tag if needed.
+ if (style.docbookitemwrappertag() != "NONE")
+ openTag(xs, style.docbookitemwrappertag(), style.docbookitemwrapperattr(), style.docbookitemwrappertagtype());
+
+ // Generate the label, if need be. If it is taken from the text, sep != 0 and corresponds to the first
+ // character after the label.
+ pos_type sep = 0;
+ if (style.labeltype != LABEL_NO_LABEL && style.docbookitemlabeltag() != "NONE") {
+ // At least one condition must be met:
+ // - this environment is not a list
+ // - if this is a list, the label must not be manual (i.e. it must be taken from the layout)
+ if (style.latextype != LATEX_LIST_ENVIRONMENT || style.labeltype != LABEL_MANUAL) {
+ // Usual cases: maybe there is something specified at the layout level. Highly unlikely, though.
+ docstring const lbl = par->params().labelString();
+
+ if (lbl.empty()) {
+ xs << xml::CR();
+ } else {
+ openLabelTag(xs, style);
+ xs << lbl;
+ closeLabelTag(xs, style);
+ }
+ } else {
+ // Only variablelist gets here (or similar items defined as an extension in the layout).
+ openLabelTag(xs, style);
+ sep = par->firstWordDocBook(xs, runparams);
+ closeLabelTag(xs, style);
+ }
+ }
+
+ // Maybe the item is completely empty, i.e. if the first word ends at the end of the current paragraph
+ // AND if the next paragraph doesn't have the same depth (if there is such a paragraph).
+ // Common case: there is only the first word on the line, but there is a nested list instead
+ // of more text.
+ bool emptyItem = false;
+ if (sep == par->size()) { // If the separator is already at the end of this paragraph...
+ auto next_par = par;
+ ++next_par;
+ if (next_par == text.paragraphs().end()) // There is no next paragraph.
+ emptyItem = true;
+ else // There is a next paragraph: check depth.
+ emptyItem = par->params().depth() >= next_par->params().depth();
+ }
+
+ if (emptyItem) {
+ // Avoid having an empty item, this is not valid DocBook. A single character is enough to force
+ // generation of a full <para>.
+ // TODO: this always worked only by magic...
+ xs << ' ';
+ } else {
+ // Generate the rest of the paragraph, if need be. Open as many inner tags as necessary.
+ auto pars = par->simpleDocBookOnePar(buf, runparams, text.outerFont(std::distance(text.paragraphs().begin(), par)), sep);
+ auto p = pars.begin();
+ while (true) {
+ xs << XMLStream::ESCAPE_NONE << *p;
+ ++p;
+ if (p != pars.end()) {
+ closeTag(xs, par->layout().docbookiteminnertag(), par->layout().docbookiteminnertagtype());
+ openTag(xs, par->layout().docbookiteminnertag(), par->layout().docbookiteminnerattr(), par->layout().docbookiteminnertagtype());
+ } else
+ break;
+ }
+ }
+ } else {
+ makeAny(text, buf, xs, runparams, par);
+ }
+
+ // Close the environment.
+ auto nextpar = par;
+ ++nextpar;
+ closeParTag(xs, &*par, (nextpar != end) ? &*nextpar : nullptr); // TODO: switch in layout for par/block?
+}
+
+
+ParagraphList::const_iterator findEndOfEnvironment(
+ ParagraphList::const_iterator const & pstart,
+ ParagraphList::const_iterator const & pend)
+{
+ // Copy-paste from XHTML. Should be factored out at some point...
+
+ 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 makeListEnvironment(Buffer const &buf,
+ XMLStream &xs,
+ OutputParams const &runparams,
+ Text const &text,
+ ParagraphList::const_iterator const & par)
+>>>>>>> be6480e59c... DocBook: same refactoring for docbookSimpleAllParagraphs.
{
auto const end = text.paragraphs().end();
@@ -921,12 +1073,13 @@ void docbookSimpleAllParagraphs(
outputDocBookInfo(text, buf, xs, runparams, paragraphs, info);
// Then, the content. It starts where the <info> ends.
- bpit = info.epit;
- while (bpit < epit) {
- auto par = paragraphs.iterator_at(bpit);
+ auto par = text.paragraphs().iterator_at(info.epit);
+ auto end = text.paragraphs().iterator_at(epit);
+ while (par != end) {
if (!hasOnlyNotes(*par))
- makeAny(text, buf, xs, runparams, par);
- bpit += 1;
+ par = makeAny(text, buf, xs, runparams, par);
+ else
+ ++par;
}
}
@@ -967,21 +1120,20 @@ void docbookParagraphs(Text const &text,
bool currentlyInAppendix = false;
- while (bpit < epit) {
+ auto par = text.paragraphs().iterator_at(bpit);
+ auto end = text.paragraphs().iterator_at(epit);
+ while (par != end) {
OutputParams ourparams = runparams;
- auto par = paragraphs.iterator_at(bpit);
if (par->params().startOfAppendix())
currentlyInAppendix = true;
- Layout const &style = par->layout();
- ParagraphList::const_iterator const lastStartedPar = par;
- ParagraphList::const_iterator send;
-
if (hasOnlyNotes(*par)) {
- bpit += 1;
+ ++par;
continue;
}
+ Layout const &style = par->layout();
+
// Think about adding <section> and/or </section>s.
const bool isLayoutSectioning = style.category() == from_utf8("Sectioning");
if (isLayoutSectioning) {
@@ -1058,7 +1210,6 @@ void docbookParagraphs(Text const &text,
// Generate this paragraph.
makeAny(text, buf, xs, ourparams, par);
- bpit += 1;
}
// 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