commit fc0999a4220afb1646a5ae75ea8192b6d304ec56
Author: Thibaut Cuvelier <[email protected]>
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
-- 
lyx-cvs mailing list
[email protected]
http://lists.lyx.org/mailman/listinfo/lyx-cvs

Reply via email to