The branch, feature/docbook, has been updated. - Log -----------------------------------------------------------------
commit a0a88840cdf96e3f21386c55c54294d452a7b7c9 Author: Thibaut Cuvelier <[email protected]> Date: Sat Aug 29 03:53:44 2020 +0200 WIP: clean some mess. diff --git a/src/output_docbook.cpp b/src/output_docbook.cpp index 4d156d0..e8edee1 100644 --- a/src/output_docbook.cpp +++ b/src/output_docbook.cpp @@ -708,108 +708,6 @@ ParagraphList::const_iterator makeListEnvironment(Text const &text, closeTag(xs, envstyle.docbookwrappertag(), envstyle.docbookwrappertagtype()); return envend; - -// xs << XMLStream::ESCAPE_NONE << from_ascii("<!-- ENV DEPTH: " + to_string(par->getDepth()) + ". "); -// if (prevpar) -// xs << XMLStream::ESCAPE_NONE << from_ascii("PREV DEPTH: " + to_string(prevpar->getDepth()) + ". "); -// if (par != end) { -// auto nextpar = par; -// ++nextpar; -// xs << XMLStream::ESCAPE_NONE << from_ascii("NEXT DEPTH: " + to_string(nextpar->getDepth())); -// } -// xs << XMLStream::ESCAPE_NONE << from_ascii(" -->"); - -// // Generate the contents of this environment. There is a special case if this is like some environment. -// Layout const & style = par->layout(); -// if (envstyle.latextype == LATEX_COMMAND) { -// // Nothing to do (otherwise, infinite loops). -// } else if (envstyle.latextype == LATEX_ENVIRONMENT || -// envstyle.latextype == LATEX_LIST_ENVIRONMENT || -// envstyle.latextype == LATEX_ITEM_ENVIRONMENT) { -// // Open a wrapper tag if needed. -// if (envstyle.docbookitemwrappertag() != "NONE") -// openTag(xs, envstyle.docbookitemwrappertag(), envstyle.docbookitemwrapperattr(), envstyle.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 (envstyle.labeltype != LABEL_NO_LABEL && envstyle.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 (envstyle.latextype != LATEX_LIST_ENVIRONMENT || envstyle.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, envstyle); -// xs << lbl; -// closeLabelTag(xs, envstyle); -// } -// } else { -// // Only variablelist gets here (or similar items defined as an extension in the layout). -// openLabelTag(xs, envstyle); -// sep = par->firstWordDocBook(xs, runparams); -// closeLabelTag(xs, envstyle); -// } -// } -// -// // 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); -// } -// -//// stack<Layout> previous_; -//// int curdepth = -1; text.paragraphs().front().getDepth(); -//// for (auto const & p : text.paragraphs()) { -//// if (p.layout().latextype == LATEX_ITEM_ENVIRONMENT) { -//// if (curdepth ) { -//// ; -//// } -//// curdepth = p.getDepth(); -//// } else if (curdepth > 0) -//// } -// -// // Close the environment. -// auto nextpar = par; -// ++nextpar; -// closeParTag(xs, &*par, (nextpar != end) ? &*nextpar : nullptr); // TODO: switch in layout for par/block? -// -// return nextpar; } commit cbbba04773004ef1331afc91c5afddde0b10405a Author: Thibaut Cuvelier <[email protected]> Date: Sat Aug 29 03:53:17 2020 +0200 WIP: lists seem to work properly! diff --git a/autotests/export/docbook/lists.lyx b/autotests/export/docbook/lists.lyx index 2e7c0e0..3e8e72a 100644 --- a/autotests/export/docbook/lists.lyx +++ b/autotests/export/docbook/lists.lyx @@ -87,10 +87,6 @@ Test document \end_layout \begin_layout Standard -\begin_inset Note Note -status open - -\begin_layout Plain Layout A simple list: \end_layout @@ -110,7 +106,7 @@ I'm the second line Third item \end_layout -\begin_layout Plain Layout +\begin_layout Standard A simple enumerated list: \end_layout @@ -126,7 +122,7 @@ Second item on two lines I'm the second line \end_layout -\begin_layout Plain Layout +\begin_layout Standard Nested lists: \end_layout @@ -158,11 +154,6 @@ Second second item \end_layout \end_deeper -\end_inset - - -\end_layout - \begin_layout Standard A complex list: \end_layout @@ -204,10 +195,6 @@ Text after second item \end_deeper \begin_layout Standard -\begin_inset Note Note -status open - -\begin_layout Plain Layout A very complex list: \end_layout @@ -224,20 +211,11 @@ First first item First second item \end_layout -\begin_layout Plain Layout +\begin_layout Standard Text after first item \end_layout \end_deeper -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset Note Note -status open - \begin_layout Itemize Second item \end_layout @@ -251,15 +229,10 @@ Second first item Second second item \end_layout -\begin_layout Plain Layout +\begin_layout Standard Text after second item \end_layout \end_deeper -\end_inset - - -\end_layout - \end_body \end_document diff --git a/autotests/export/docbook/lists.xml b/autotests/export/docbook/lists.xml index 4b72f7f..c0dad39 100644 --- a/autotests/export/docbook/lists.xml +++ b/autotests/export/docbook/lists.xml @@ -3,7 +3,30 @@ See http://www.lyx.org/ for more information --> <article 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"> <title>Test document</title> -<para>A complex list:</para> +<para>A simple list: </para> +<itemizedlist> +<listitem> +<para>First item</para> +</listitem> +<listitem> +<para>Second item on two lines</para> +<para>I'm the second line</para> +</listitem> +<listitem> +<para>Third item</para> +</listitem> +</itemizedlist> +<para>A simple enumerated list: </para> +<orderedlist> +<listitem> +<para>First item</para> +</listitem> +<listitem> +<para>Second item on two lines</para> +<para>I'm the second line</para> +</listitem> +</orderedlist> +<para>Nested lists:</para> <itemizedlist> <listitem> <para>First item</para> @@ -16,9 +39,33 @@ </listitem> </itemizedlist> </listitem> -Text after first item +<listitem> +<para>Second item</para> +<itemizedlist> +<listitem> +<para>Second first item</para> +</listitem> +<listitem> +<para>Second second item</para> +</listitem> +</itemizedlist> +</listitem> +</itemizedlist> +<para>A complex list:</para> +<itemizedlist> +<listitem> +<para>First item</para> <itemizedlist> <listitem> +<para>First first item</para> +</listitem> +<listitem> +<para>First second item</para> +</listitem> +</itemizedlist> +<para>Text after first item</para> +</listitem> +<listitem> <para>Second item</para> <itemizedlist> <listitem> @@ -28,8 +75,34 @@ Text after first item <para>Second second item</para> </listitem> </itemizedlist> +<para>Text after second item</para> +</listitem> +</itemizedlist> +<para>A very complex list:</para> +<itemizedlist> +<listitem> +<para>First item</para> +<itemizedlist> +<listitem> +<para>First first item</para> +</listitem> +<listitem> +<para>First second item</para> </listitem> -Text after second item </itemizedlist> +<para>Text after first item</para> +</listitem> +<listitem> +<para>Second item</para> +<orderedlist> +<listitem> +<para>Second first item</para> +</listitem> +<listitem> +<para>Second second item</para> +</listitem> +</orderedlist> +<para>Text after second item</para> +</listitem> </itemizedlist> </article> \ No newline at end of file diff --git a/src/output_docbook.cpp b/src/output_docbook.cpp index ba1fd47..4d156d0 100644 --- a/src/output_docbook.cpp +++ b/src/output_docbook.cpp @@ -693,8 +693,10 @@ ParagraphList::const_iterator makeListEnvironment(Text const &text, // By construction, with findEndOfEnvironment, depth can only stay constant or increase, never decrease. depth_type currentDepth = par->getDepth(); ++par; - if (par != envend && par->getDepth() != currentDepth) - par = makeAny(buf, xs, runparams, text, par); + while (par != envend && par->getDepth() != currentDepth) + par = makeAny(text, buf, xs, runparams, par); + // Usually, this loop only makes one iteration, except in complex scenarios, like an item with a paragraph, + // a list, and another paragraph. // Close the item. closeTag(xs, style.docbookitemwrappertag(), style.docbookitemwrappertagtype()); commit b1a683c696abc4129adb6111e0be42797365c6de Author: Thibaut Cuvelier <[email protected]> Date: Sat Aug 29 03:46:30 2020 +0200 DocBook: make all make* functions have the same argument order. diff --git a/src/output_docbook.cpp b/src/output_docbook.cpp index 617d3b7..ba1fd47 100644 --- a/src/output_docbook.cpp +++ b/src/output_docbook.cpp @@ -351,11 +351,11 @@ ParagraphList::const_iterator makeAny(Text const &, ParagraphList::const_iterator); -void makeParagraphBibliography( +void makeBibliography( + Text const & text, Buffer const & buf, XMLStream & xs, OutputParams const & runparams, - Text const & text, ParagraphList::const_iterator const & par) { // If this is the first paragraph in a bibliography, open the bibliography tag. @@ -406,10 +406,10 @@ void makeParagraphBibliography( void makeParagraph( + Text const & text, Buffer const & buf, XMLStream & xs, OutputParams const & runparams, - Text const & text, ParagraphList::const_iterator const & par) { auto const begin = text.paragraphs().begin(); @@ -504,10 +504,10 @@ void makeParagraph( } -void makeEnvironment(Buffer const &buf, +void makeEnvironment(Text const &text, + Buffer const &buf, XMLStream &xs, OutputParams const &runparams, - Text const &text, ParagraphList::const_iterator const & par) { // TODO: simplify me! @@ -632,10 +632,10 @@ ParagraphList::const_iterator findEndOfEnvironment( } -ParagraphList::const_iterator makeListEnvironment(Buffer const &buf, +ParagraphList::const_iterator makeListEnvironment(Text const &text, + Buffer const &buf, XMLStream &xs, OutputParams const &runparams, - Text const &text, ParagraphList::const_iterator const & begin) { auto par = begin; @@ -812,10 +812,10 @@ ParagraphList::const_iterator makeListEnvironment(Buffer const &buf, void makeCommand( + Text const & text, Buffer const & buf, XMLStream & xs, OutputParams const & runparams, - Text const & text, ParagraphList::const_iterator const & par) { // Unlike XHTML, no need for labels, as they are handled by DocBook tags. @@ -840,25 +840,25 @@ void makeCommand( ParagraphList::const_iterator makeAny(Text const &text, Buffer const &buf, XMLStream &xs, - OutputParams const &ourparams, + OutputParams const &runparams, ParagraphList::const_iterator par) { switch (par->layout().latextype) { case LATEX_COMMAND: - makeCommand(buf, xs, ourparams, text, par); + makeCommand(text, buf, xs, runparams, par); break; case LATEX_ENVIRONMENT: - makeEnvironment(buf, xs, ourparams, text, par); + makeEnvironment(text, buf, xs, runparams, par); break; case LATEX_LIST_ENVIRONMENT: case LATEX_ITEM_ENVIRONMENT: // Only case when makeAny() might consume more than one paragraph. - return makeListEnvironment(buf, xs, ourparams, text, par); + return makeListEnvironment(text, buf, xs, runparams, par); case LATEX_PARAGRAPH: - makeParagraph(buf, xs, ourparams, text, par); + makeParagraph(text, buf, xs, runparams, par); break; case LATEX_BIB_ENVIRONMENT: - makeParagraphBibliography(buf, xs, ourparams, text, par); + makeBibliography(text, buf, xs, runparams, par); break; } ++par; commit 4d038e49c39d8e08448b8f987b878f694922ab15 Author: Thibaut Cuvelier <[email protected]> Date: Sat Aug 29 03:44:17 2020 +0200 WIP... diff --git a/autotests/export/docbook/lists.lyx b/autotests/export/docbook/lists.lyx index 1f51b1d..2e7c0e0 100644 --- a/autotests/export/docbook/lists.lyx +++ b/autotests/export/docbook/lists.lyx @@ -87,6 +87,10 @@ Test document \end_layout \begin_layout Standard +\begin_inset Note Note +status open + +\begin_layout Plain Layout A simple list: \end_layout @@ -106,7 +110,7 @@ I'm the second line Third item \end_layout -\begin_layout Standard +\begin_layout Plain Layout A simple enumerated list: \end_layout @@ -122,7 +126,7 @@ Second item on two lines I'm the second line \end_layout -\begin_layout Standard +\begin_layout Plain Layout Nested lists: \end_layout @@ -154,11 +158,12 @@ Second second item \end_layout \end_deeper -\begin_layout Standard -\begin_inset Note Note -status open +\end_inset -\begin_layout Plain Layout + +\end_layout + +\begin_layout Standard A complex list: \end_layout @@ -175,7 +180,7 @@ First first item First second item \end_layout -\begin_layout Plain Layout +\begin_layout Standard Text after first item \end_layout @@ -193,16 +198,11 @@ Second first item Second second item \end_layout -\begin_layout Plain Layout +\begin_layout Standard Text after second item \end_layout \end_deeper -\end_inset - - -\end_layout - \begin_layout Standard \begin_inset Note Note status open diff --git a/autotests/export/docbook/lists.xml b/autotests/export/docbook/lists.xml index ee6a152..4b72f7f 100644 --- a/autotests/export/docbook/lists.xml +++ b/autotests/export/docbook/lists.xml @@ -3,30 +3,7 @@ See http://www.lyx.org/ for more information --> <article 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"> <title>Test document</title> -<para>A simple list: </para> -<itemizedlist> -<listitem> -<para>First item</para> -</listitem> -<listitem> -<para>Second item on two lines</para> -<para>I'm the second line</para> -</listitem> -<listitem> -<para>Third item</para> -</listitem> -</itemizedlist> -<para>A simple enumerated list: </para> -<orderedlist> -<listitem> -<para>First item</para> -</listitem> -<listitem> -<para>Second item on two lines</para> -<para>I'm the second line</para> -</listitem> -</orderedlist> -<para>Nested lists:</para> +<para>A complex list:</para> <itemizedlist> <listitem> <para>First item</para> @@ -39,6 +16,8 @@ </listitem> </itemizedlist> </listitem> +Text after first item +<itemizedlist> <listitem> <para>Second item</para> <itemizedlist> @@ -50,5 +29,7 @@ </listitem> </itemizedlist> </listitem> +Text after second item +</itemizedlist> </itemizedlist> </article> \ No newline at end of file diff --git a/src/output_docbook.cpp b/src/output_docbook.cpp index e632ceb..617d3b7 100644 --- a/src/output_docbook.cpp +++ b/src/output_docbook.cpp @@ -693,8 +693,8 @@ ParagraphList::const_iterator makeListEnvironment(Buffer const &buf, // By construction, with findEndOfEnvironment, depth can only stay constant or increase, never decrease. depth_type currentDepth = par->getDepth(); ++par; - if (par != envend && par->getDepth() > currentDepth) - par = makeListEnvironment(buf, xs, runparams, text, par); + if (par != envend && par->getDepth() != currentDepth) + par = makeAny(buf, xs, runparams, text, par); // Close the item. closeTag(xs, style.docbookitemwrappertag(), style.docbookitemwrappertagtype()); commit ddd605523443078207e95614bb151dc97cbb33a3 Author: Thibaut Cuvelier <[email protected]> Date: Sat Aug 29 03:42:11 2020 +0200 WIP: works for nested lists! diff --git a/autotests/export/docbook/lists.lyx b/autotests/export/docbook/lists.lyx index 68a91b2..1f51b1d 100644 --- a/autotests/export/docbook/lists.lyx +++ b/autotests/export/docbook/lists.lyx @@ -102,6 +102,10 @@ Second item on two lines I'm the second line \end_layout +\begin_layout Itemize +Third item +\end_layout + \begin_layout Standard A simple enumerated list: \end_layout @@ -119,10 +123,6 @@ I'm the second line \end_layout \begin_layout Standard -\begin_inset Note Note -status open - -\begin_layout Plain Layout Nested lists: \end_layout @@ -154,6 +154,10 @@ Second second item \end_layout \end_deeper +\begin_layout Standard +\begin_inset Note Note +status open + \begin_layout Plain Layout A complex list: \end_layout diff --git a/autotests/export/docbook/lists.xml b/autotests/export/docbook/lists.xml index 266cab6..ee6a152 100644 --- a/autotests/export/docbook/lists.xml +++ b/autotests/export/docbook/lists.xml @@ -2,15 +2,8 @@ <!-- This DocBook file was created by LyX 2.4.0dev See http://www.lyx.org/ for more information --> <article 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"> -<!-- Decision to open the wrapper: --><!-- Result: 0 --> -<title>Test document<!-- closeWrapper: 1 --><!-- closeWrapper: condition met --></title> -<!-- closeWrapper first iteration: 1 --><!-- Output Error: Tried to close `title' when no tags were open! --> - -<!-- closeWrapper has looped --><!-- Decision to open the wrapper: prevpar != nullptr; --><!-- Result: 0 --> -<para>A simple list: <!-- closeWrapper: 1 --><!-- closeWrapper: condition met --></para> -<!-- closeWrapper first iteration: 1 --><!-- Output Error: Tried to close `para' when no tags were open! --> - -<!-- closeWrapper has looped --> +<title>Test document</title> +<para>A simple list: </para> <itemizedlist> <listitem> <para>First item</para> @@ -19,18 +12,11 @@ <para>Second item on two lines</para> <para>I'm the second line</para> </listitem> -</itemizedlist> -<itemizedlist> <listitem> -<para>Second item on two lines</para> -<para>I'm the second line</para> +<para>Third item</para> </listitem> </itemizedlist> -<!-- Decision to open the wrapper: prevpar != nullptr; --><!-- Result: 0 --> -<para>A simple enumerated list: <!-- closeWrapper: 1 --><!-- closeWrapper: condition met --></para> -<!-- closeWrapper first iteration: 1 --><!-- Output Error: Tried to close `para' when no tags were open! --> - -<!-- closeWrapper has looped --> +<para>A simple enumerated list: </para> <orderedlist> <listitem> <para>First item</para> @@ -40,10 +26,29 @@ <para>I'm the second line</para> </listitem> </orderedlist> -<orderedlist> +<para>Nested lists:</para> +<itemizedlist> <listitem> -<para>Second item on two lines</para> -<para>I'm the second line</para> +<para>First item</para> +<itemizedlist> +<listitem> +<para>First first item</para> </listitem> -</orderedlist> +<listitem> +<para>First second item</para> +</listitem> +</itemizedlist> +</listitem> +<listitem> +<para>Second item</para> +<itemizedlist> +<listitem> +<para>Second first item</para> +</listitem> +<listitem> +<para>Second second item</para> +</listitem> +</itemizedlist> +</listitem> +</itemizedlist> </article> \ No newline at end of file diff --git a/src/output_docbook.cpp b/src/output_docbook.cpp index 75095b6..e632ceb 100644 --- a/src/output_docbook.cpp +++ b/src/output_docbook.cpp @@ -689,12 +689,16 @@ ParagraphList::const_iterator makeListEnvironment(Buffer const &buf, closeTag(xs, par->layout().docbookiteminnertag(), par->layout().docbookiteminnertagtype()); } + // If the next item is deeper, it must go entirely within this item (do it recursively). + // By construction, with findEndOfEnvironment, depth can only stay constant or increase, never decrease. + depth_type currentDepth = par->getDepth(); + ++par; + if (par != envend && par->getDepth() > currentDepth) + par = makeListEnvironment(buf, xs, runparams, text, par); + // Close the item. closeTag(xs, style.docbookitemwrappertag(), style.docbookitemwrappertagtype()); closeTag(xs, style.docbookitemtag(), style.docbookitemtagtype()); - - // Go to the next item. - ++par; } // Close this environment in exactly the same way as it was opened. commit eee7387c4912589bec354d967a925adb1143d744 Author: Thibaut Cuvelier <[email protected]> Date: Sat Aug 29 03:31:12 2020 +0200 DocBook: same refactoring for docbookSimpleAllParagraphs. diff --git a/src/output_docbook.cpp b/src/output_docbook.cpp index b7190bc..75095b6 100644 --- a/src/output_docbook.cpp +++ b/src/output_docbook.cpp @@ -601,6 +601,8 @@ 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(); @@ -855,6 +857,7 @@ ParagraphList::const_iterator makeAny(Text const &text, makeParagraphBibliography(buf, xs, ourparams, text, par); break; } + ++par; return par; } @@ -1126,12 +1129,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; } } commit d4801b8d49e386a15c094f08534d1b8f2f1eeb13 Author: Thibaut Cuvelier <[email protected]> Date: Sat Aug 29 03:26:07 2020 +0200 WIP: restore open/closeParTag. diff --git a/src/output_docbook.cpp b/src/output_docbook.cpp index 3ec1d9e..b7190bc 100644 --- a/src/output_docbook.cpp +++ b/src/output_docbook.cpp @@ -269,34 +269,13 @@ void openParTag(XMLStream & xs, const Paragraph * par, const Paragraph * prevpar // next paragraph is the affiliation, then it should be output in the same <author> tag (different // layout, same wrapper tag). bool openWrapper = lay.docbookwrappertag() != "NONE"; - xs << XMLStream::ESCAPE_NONE << from_ascii("<!-- Decision to open the wrapper: "); if (prevpar != nullptr) { - xs << XMLStream::ESCAPE_NONE << from_ascii("prevpar != nullptr; "); Layout const & prevlay = prevpar->layout(); if (prevlay.docbookwrappertag() != "NONE") { - xs << XMLStream::ESCAPE_NONE << from_ascii("prevlay.docbookwrappertag() != NONE; "); - if (prevpar->getDepth() == par->getDepth()) { - // Same depth: the basic condition applies. - openWrapper = prevlay.docbookwrappertag() == lay.docbookwrappertag() - && !lay.docbookwrappermergewithprevious(); - xs << XMLStream::ESCAPE_NONE << from_ascii("SAME DEPTH "); - } else if (prevpar->getDepth() > par->getDepth()) { - // The previous paragraph was deeper: close the wrapper, no need to open it. - xs << XMLStream::ESCAPE_NONE << from_ascii("PREV DEEPER "); - } else { - // This paragraph is deeper than the previous one: open the wrapper, - // disregarding docbookwrappermergewithprevious. - // Don't change openWrapper! - openWrapper = lay.docbookwrappertag() != "NONE"; // prevlay.docbookwrappertag() == lay.docbookwrappertag(); - xs << XMLStream::ESCAPE_NONE << from_ascii("PREV SHALLOWER "); - } - } else { -// openWrapper = false; + openWrapper = prevlay.docbookwrappertag() == lay.docbookwrappertag() + && !lay.docbookwrappermergewithprevious(); } } - xs << XMLStream::ESCAPE_NONE << from_ascii(" -->"); - - xs << XMLStream::ESCAPE_NONE << from_ascii("<!-- Result: " + to_string(openWrapper) + " -->"); // Main logic. if (openWrapper) @@ -306,8 +285,8 @@ void openParTag(XMLStream & xs, const Paragraph * par, const Paragraph * prevpar if (tag != "NONE") { auto xmltag = xml::ParTag(tag, lay.docbookattr()); if (!xs.isTagOpen(xmltag, 1)) // Don't nest a paragraph directly in a paragraph. - // TODO: is this condition required or not? - // TODO: avoid creating a ParTag object (xmltag) just for this query... + // TODO: required or not? + // TODO: avoid creating a ParTag object just for this query... openTag(xs, lay.docbooktag(), lay.docbookattr(), lay.docbooktagtype()); } @@ -322,64 +301,22 @@ void closeParTag(XMLStream & xs, Paragraph const * par, Paragraph const * nextpa nextpar = nullptr; // See comment in openParTag. - // If closeWrapper == 0, the wrapper should not be closed: the next paragraph is another item to add to this list. Layout const & lay = par->layout(); - long long closeWrapper = 0; // (lay.docbookwrappertag() == "NONE") ? 0 : 1; // Avoid unsigned, as -1 might appear as value. - if (nextpar == nullptr) { - closeWrapper = 1L + (long long) par->getDepth(); - } else { - Layout const &nextlay = nextpar->layout(); + bool closeWrapper = lay.docbookwrappertag() != "NONE"; + if (nextpar != nullptr) { + Layout const & nextlay = nextpar->layout(); if (nextlay.docbookwrappertag() != "NONE") { - 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() - } + closeWrapper = nextlay.docbookwrappertag() == lay.docbookwrappertag() + && !nextlay.docbookwrappermergewithprevious(); } } - // Main logic. (Comments mostly correspond to lists.) - xs << XMLStream::ESCAPE_NONE << from_ascii("<!-- closeWrapper: " + to_string(closeWrapper) + " -->"); - // - Close this paragraph. + // Main logic. closeTag(xs, lay.docbookiteminnertag(), lay.docbookiteminnertagtype()); - - // - Close the current item. - if (!nextpar || nextpar->getDepth() == par->getDepth()) { - xs << XMLStream::ESCAPE_NONE << from_ascii("<!-- closeWrapper: condition met -->"); - closeTag(xs, lay.docbookitemtag(), lay.docbookitemtagtype()); - closeTag(xs, lay.docbooktag(), lay.docbooktagtype()); - } - - // - Close wrapper tags as many times as required. - while (closeWrapper > 0) { - xs << XMLStream::ESCAPE_NONE << from_ascii("<!-- closeWrapper first iteration: " + to_string(closeWrapper) + " -->"); - closeTag(xs, lay.docbookitemtag(), lay.docbookitemtagtype()); - closeTag(xs, lay.docbooktag(), lay.docbooktagtype()); + closeTag(xs, lay.docbookitemtag(), lay.docbookitemtagtype()); + closeTag(xs, lay.docbooktag(), lay.docbooktagtype()); + if (closeWrapper) closeTag(xs, lay.docbookwrappertag(), lay.docbookwrappertagtype()); - closeWrapper -= 1; - } - xs << XMLStream::ESCAPE_NONE << "<!-- closeWrapper has looped -->"; } commit d7c6cc78d4f27777062032c9dd8fee54a1d200e2 Author: Thibaut Cuvelier <[email protected]> Date: Sat Aug 29 03:24:43 2020 +0200 WIP: rewrite makeListEnv. diff --git a/autotests/export/docbook/lists.lyx b/autotests/export/docbook/lists.lyx index 76df45e..68a91b2 100644 --- a/autotests/export/docbook/lists.lyx +++ b/autotests/export/docbook/lists.lyx @@ -87,10 +87,6 @@ Test document \end_layout \begin_layout Standard -\begin_inset Note Note -status open - -\begin_layout Plain Layout A simple list: \end_layout @@ -106,7 +102,7 @@ Second item on two lines I'm the second line \end_layout -\begin_layout Plain Layout +\begin_layout Standard A simple enumerated list: \end_layout @@ -122,6 +118,10 @@ Second item on two lines I'm the second line \end_layout +\begin_layout Standard +\begin_inset Note Note +status open + \begin_layout Plain Layout Nested lists: \end_layout @@ -200,6 +200,10 @@ Text after second item \end_layout \begin_layout Standard +\begin_inset Note Note +status open + +\begin_layout Plain Layout A very complex list: \end_layout @@ -216,11 +220,16 @@ First first item First second item \end_layout -\begin_layout Standard +\begin_layout Plain Layout Text after first item \end_layout \end_deeper +\end_inset + + +\end_layout + \begin_layout Standard \begin_inset Note Note status open diff --git a/autotests/export/docbook/lists.xml b/autotests/export/docbook/lists.xml index ede9acb..266cab6 100644 --- a/autotests/export/docbook/lists.xml +++ b/autotests/export/docbook/lists.xml @@ -3,26 +3,47 @@ See http://www.lyx.org/ for more information --> <article 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"> <!-- Decision to open the wrapper: --><!-- Result: 0 --> -<title>Test document<!-- closeWrapper: 0 --><!-- closeWrapper: condition met --></title> +<title>Test document<!-- closeWrapper: 1 --><!-- closeWrapper: condition met --></title> +<!-- closeWrapper first iteration: 1 --><!-- Output Error: Tried to close `title' when no tags were open! --> + <!-- closeWrapper has looped --><!-- Decision to open the wrapper: prevpar != nullptr; --><!-- Result: 0 --> -<para>A very complex list:<!-- closeWrapper: 0 --><!-- closeWrapper: condition met --></para> -<!-- closeWrapper has looped --><!-- 4 --><!-- Decision to open the wrapper: prevpar != nullptr; --><!-- Result: 1 --> +<para>A simple list: <!-- closeWrapper: 1 --><!-- closeWrapper: condition met --></para> +<!-- closeWrapper first iteration: 1 --><!-- Output Error: Tried to close `para' when no tags were open! --> + +<!-- closeWrapper has looped --> <itemizedlist> <listitem> -<para><!-- ENV DEPTH: 0. PREV DEPTH: 0. NEXT DEPTH: 1 -->First item<!-- closeWrapper: 0 --></para> -<!-- closeWrapper has looped --><!-- 4 --><!-- Decision to open the wrapper: prevpar != nullptr; prevlay.docbookwrappertag() != NONE; PREV SHALLOWER --><!-- Result: 1 --> -<itemizedlist> +<para>First item</para> +</listitem> <listitem> -<para><!-- ENV DEPTH: 1. PREV DEPTH: 0. NEXT DEPTH: 1 -->First first item<!-- closeWrapper: 0 --></para> -<!-- closeWrapper: condition met --> +<para>Second item on two lines</para> +<para>I'm the second line</para> </listitem> -<!-- closeWrapper has looped --><!-- 4 --><!-- Decision to open the wrapper: prevpar != nullptr; prevlay.docbookwrappertag() != NONE; SAME DEPTH --><!-- Result: 0 --> +</itemizedlist> +<itemizedlist> <listitem> -<para><!-- ENV DEPTH: 1. PREV DEPTH: 1. NEXT DEPTH: 1 -->First second item<!-- closeWrapper: 0 --></para> -<!-- closeWrapper: condition met --> +<para>Second item on two lines</para> +<para>I'm the second line</para> </listitem> -<!-- closeWrapper has looped --><!-- Decision to open the wrapper: prevpar != nullptr; prevlay.docbookwrappertag() != NONE; SAME DEPTH --><!-- Result: 0 --> -<para>Text after first item<!-- closeWrapper: 2 --><!-- closeWrapper first iteration: 2 --></para> -<!-- closeWrapper first iteration: 1 --><!-- Output Error: Tried to close `para' when tag was not open. Tag discarded. --> +</itemizedlist> +<!-- Decision to open the wrapper: prevpar != nullptr; --><!-- Result: 0 --> +<para>A simple enumerated list: <!-- closeWrapper: 1 --><!-- closeWrapper: condition met --></para> +<!-- closeWrapper first iteration: 1 --><!-- Output Error: Tried to close `para' when no tags were open! --> -<!-- closeWrapper has looped --></article> \ No newline at end of file +<!-- closeWrapper has looped --> +<orderedlist> +<listitem> +<para>First item</para> +</listitem> +<listitem> +<para>Second item on two lines</para> +<para>I'm the second line</para> +</listitem> +</orderedlist> +<orderedlist> +<listitem> +<para>Second item on two lines</para> +<para>I'm the second line</para> +</listitem> +</orderedlist> +</article> \ No newline at end of file diff --git a/lib/layouts/stdlists.inc b/lib/layouts/stdlists.inc index f6dd411..700402f 100644 --- a/lib/layouts/stdlists.inc +++ b/lib/layouts/stdlists.inc @@ -43,9 +43,7 @@ Style Itemize Color latex EndFont EndArgument - DocBookWrapperTag itemizedlist - DocBookWrapperMergeWithPrevious true - DocBookTag NONE + DocBookTag itemizedlist DocBookItemTag listitem DocBookItemInnerTag para End @@ -87,9 +85,7 @@ Style Enumerate Color latex EndFont EndArgument - DocBookWrapperTag orderedlist - DocBookWrapperMergeWithPrevious true - DocBookTag NONE + DocBookTag orderedlist DocBookItemTag listitem DocBookItemInnerTag para End @@ -131,9 +127,7 @@ Style Description Color latex EndFont EndArgument - DocBookWrapperTag variablelist - DocBookWrapperMergeWithPrevious true - DocBookTag NONE + DocBookTag variablelist DocBookItemWrapperTag varlistentry DocBookItemTag listitem DocBookItemInnerTag para diff --git a/src/output_docbook.cpp b/src/output_docbook.cpp index a573159..3ec1d9e 100644 --- a/src/output_docbook.cpp +++ b/src/output_docbook.cpp @@ -660,41 +660,61 @@ void makeEnvironment(Buffer const &buf, } +ParagraphList::const_iterator findEndOfEnvironment( + ParagraphList::const_iterator const & pstart, + ParagraphList::const_iterator const & pend) +{ + 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) + ParagraphList::const_iterator const & begin) { + auto par = begin; auto const end = text.paragraphs().end(); + auto const envend = findEndOfEnvironment(par, end); - xs << XMLStream::ESCAPE_NONE << from_ascii("<!-- " + to_string(par->layout().latextype) + " -->"); + // Output the opening tag for this environment. + Layout const & envstyle = par->layout(); + openTag(xs, envstyle.docbookwrappertag(), envstyle.docbookwrapperattr(), envstyle.docbookwrappertagtype()); + openTag(xs, envstyle.docbooktag(), envstyle.docbookattr(), envstyle.docbooktagtype()); - // 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? + // Handle the content of the list environment, item by item. + while (par != envend) { + Layout const & style = par->layout(); - xs << XMLStream::ESCAPE_NONE << from_ascii("<!-- ENV DEPTH: " + to_string(par->getDepth()) + ". "); - if (prevpar) - xs << XMLStream::ESCAPE_NONE << from_ascii("PREV DEPTH: " + to_string(prevpar->getDepth()) + ". "); - if (par != end) { - auto nextpar = par; - ++nextpar; - xs << XMLStream::ESCAPE_NONE << from_ascii("NEXT DEPTH: " + to_string(nextpar->getDepth())); - } - xs << XMLStream::ESCAPE_NONE << from_ascii(" -->"); - - // 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 || - style.latextype == LATEX_LIST_ENVIRONMENT || - style.latextype == LATEX_ITEM_ENVIRONMENT) { - // Open a wrapper tag if needed. - if (style.docbookitemwrappertag() != "NONE") - openTag(xs, style.docbookitemwrappertag(), style.docbookitemwrapperattr(), style.docbookitemwrappertagtype()); + // Open the item. + openTag(xs, style.docbookitemtag(), style.docbookitemattr(), style.docbookitemtagtype()); + 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. @@ -722,60 +742,129 @@ ParagraphList::const_iterator makeListEnvironment(Buffer const &buf, } } - // 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(); + // Generate the content of the item. + auto pars = par->simpleDocBookOnePar(buf, runparams, text.outerFont(std::distance(text.paragraphs().begin(), par)), sep); + for (auto & p : pars) { + openTag(xs, par->layout().docbookiteminnertag(), par->layout().docbookiteminnerattr(), par->layout().docbookiteminnertagtype()); + xs << XMLStream::ESCAPE_NONE << p; + closeTag(xs, par->layout().docbookiteminnertag(), par->layout().docbookiteminnertagtype()); } - 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 item. + closeTag(xs, style.docbookitemwrappertag(), style.docbookitemwrappertagtype()); + closeTag(xs, style.docbookitemtag(), style.docbookitemtagtype()); + + // Go to the next item. + ++par; } -// stack<Layout> previous_; -// int curdepth = -1; text.paragraphs().front().getDepth(); -// for (auto const & p : text.paragraphs()) { -// if (p.layout().latextype == LATEX_ITEM_ENVIRONMENT) { -// if (curdepth ) { -// ; -// } -// curdepth = p.getDepth(); -// } else if (curdepth > 0) -// } + // Close this environment in exactly the same way as it was opened. + closeTag(xs, envstyle.docbooktag(), envstyle.docbooktagtype()); + closeTag(xs, envstyle.docbookwrappertag(), envstyle.docbookwrappertagtype()); - // Close the environment. - auto nextpar = par; - ++nextpar; - closeParTag(xs, &*par, (nextpar != end) ? &*nextpar : nullptr); // TODO: switch in layout for par/block? + return envend; - return nextpar; +// xs << XMLStream::ESCAPE_NONE << from_ascii("<!-- ENV DEPTH: " + to_string(par->getDepth()) + ". "); +// if (prevpar) +// xs << XMLStream::ESCAPE_NONE << from_ascii("PREV DEPTH: " + to_string(prevpar->getDepth()) + ". "); +// if (par != end) { +// auto nextpar = par; +// ++nextpar; +// xs << XMLStream::ESCAPE_NONE << from_ascii("NEXT DEPTH: " + to_string(nextpar->getDepth())); +// } +// xs << XMLStream::ESCAPE_NONE << from_ascii(" -->"); + +// // Generate the contents of this environment. There is a special case if this is like some environment. +// Layout const & style = par->layout(); +// if (envstyle.latextype == LATEX_COMMAND) { +// // Nothing to do (otherwise, infinite loops). +// } else if (envstyle.latextype == LATEX_ENVIRONMENT || +// envstyle.latextype == LATEX_LIST_ENVIRONMENT || +// envstyle.latextype == LATEX_ITEM_ENVIRONMENT) { +// // Open a wrapper tag if needed. +// if (envstyle.docbookitemwrappertag() != "NONE") +// openTag(xs, envstyle.docbookitemwrappertag(), envstyle.docbookitemwrapperattr(), envstyle.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 (envstyle.labeltype != LABEL_NO_LABEL && envstyle.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 (envstyle.latextype != LATEX_LIST_ENVIRONMENT || envstyle.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, envstyle); +// xs << lbl; +// closeLabelTag(xs, envstyle); +// } +// } else { +// // Only variablelist gets here (or similar items defined as an extension in the layout). +// openLabelTag(xs, envstyle); +// sep = par->firstWordDocBook(xs, runparams); +// closeLabelTag(xs, envstyle); +// } +// } +// +// // 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); +// } +// +//// stack<Layout> previous_; +//// int curdepth = -1; text.paragraphs().front().getDepth(); +//// for (auto const & p : text.paragraphs()) { +//// if (p.layout().latextype == LATEX_ITEM_ENVIRONMENT) { +//// if (curdepth ) { +//// ; +//// } +//// curdepth = p.getDepth(); +//// } else if (curdepth > 0) +//// } +// +// // Close the environment. +// auto nextpar = par; +// ++nextpar; +// closeParTag(xs, &*par, (nextpar != end) ? &*nextpar : nullptr); // TODO: switch in layout for par/block? +// +// return nextpar; } commit 61b0383cffeb0b586e28b987a11c5bb44f02363c Author: Thibaut Cuvelier <[email protected]> Date: Sat Aug 29 03:03:16 2020 +0200 DocBook: start splitting environment handling in two, to have proper things for lists. diff --git a/src/output_docbook.cpp b/src/output_docbook.cpp index f5e92b7..a573159 100644 --- a/src/output_docbook.cpp +++ b/src/output_docbook.cpp @@ -407,12 +407,11 @@ void closeItemTag(XMLStream & xs, Layout const & lay) } -void makeAny( - Text const &, - Buffer const &, - XMLStream &, - OutputParams const &, - ParagraphList::const_iterator); +ParagraphList::const_iterator makeAny(Text const &, + Buffer const &, + XMLStream &, + OutputParams const &, + ParagraphList::const_iterator); void makeParagraphBibliography( @@ -568,12 +567,104 @@ 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 makeListEnvironment(Buffer const &buf, + XMLStream &xs, + OutputParams const &runparams, + Text const &text, + ParagraphList::const_iterator const & par) { auto const end = text.paragraphs().end(); @@ -683,6 +774,8 @@ void makeEnvironment( auto nextpar = par; ++nextpar; closeParTag(xs, &*par, (nextpar != end) ? &*nextpar : nullptr); // TODO: switch in layout for par/block? + + return nextpar; } @@ -712,22 +805,23 @@ void makeCommand( } -void makeAny( - Text const &text, - Buffer const &buf, - XMLStream &xs, - OutputParams const &ourparams, - ParagraphList::const_iterator par) +ParagraphList::const_iterator makeAny(Text const &text, + Buffer const &buf, + XMLStream &xs, + OutputParams const &ourparams, + ParagraphList::const_iterator par) { switch (par->layout().latextype) { case LATEX_COMMAND: makeCommand(buf, xs, ourparams, text, par); break; case LATEX_ENVIRONMENT: - case LATEX_LIST_ENVIRONMENT: - case LATEX_ITEM_ENVIRONMENT: makeEnvironment(buf, xs, ourparams, text, par); break; + case LATEX_LIST_ENVIRONMENT: + case LATEX_ITEM_ENVIRONMENT: + // Only case when makeAny() might consume more than one paragraph. + return makeListEnvironment(buf, xs, ourparams, text, par); case LATEX_PARAGRAPH: makeParagraph(buf, xs, ourparams, text, par); break; @@ -735,6 +829,7 @@ void makeAny( makeParagraphBibliography(buf, xs, ourparams, text, par); break; } + return par; } @@ -1140,7 +1235,7 @@ void docbookParagraphs(Text const &text, } // Generate this paragraph. - makeAny(text, buf, xs, ourparams, par); + par = makeAny(text, buf, xs, ourparams, par); } // If need be, close <section>s, but only at the end of the document (otherwise, dealt with at the beginning commit 8f160bb840428aa7059e18808c0ccf957838bea0 Author: Thibaut Cuvelier <[email protected]> Date: Sat Aug 29 02:55:47 2020 +0200 DocBook: partially remove use of bpit/epit in docbookParagraphs. This will help with the next refactoring to be much cleaner (only work with iterators, don't maintain twice the same information). diff --git a/src/output_docbook.cpp b/src/output_docbook.cpp index 78c4bda..f5e92b7 100644 --- a/src/output_docbook.cpp +++ b/src/output_docbook.cpp @@ -346,7 +346,7 @@ void closeParTag(XMLStream & xs, Paragraph const * par, Paragraph const * nextpa } else { if (nextpar->getDepth() == par->getDepth()) { // This is not wrapped: this must be the rest of the item, still within the wrapper. - closeWrapper = 0; + 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; @@ -1051,21 +1051,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) { @@ -1142,7 +1141,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 commit 4f2edfa7966deba19c823c054695be9c0376b122 Author: Thibaut Cuvelier <[email protected]> Date: Sat Aug 29 02:50:47 2020 +0200 WIP: argh! diff --git a/autotests/export/docbook/lists.lyx b/autotests/export/docbook/lists.lyx index d8b9c1b..76df45e 100644 --- a/autotests/export/docbook/lists.lyx +++ b/autotests/export/docbook/lists.lyx @@ -87,6 +87,10 @@ Test document \end_layout \begin_layout Standard +\begin_inset Note Note +status open + +\begin_layout Plain Layout A simple list: \end_layout @@ -102,7 +106,7 @@ Second item on two lines I'm the second line \end_layout -\begin_layout Standard +\begin_layout Plain Layout A simple enumerated list: \end_layout @@ -118,7 +122,7 @@ Second item on two lines I'm the second line \end_layout -\begin_layout Standard +\begin_layout Plain Layout Nested lists: \end_layout @@ -150,10 +154,6 @@ Second second item \end_layout \end_deeper -\begin_layout Standard -\begin_inset Note Note -status open - \begin_layout Plain Layout A complex list: \end_layout @@ -194,17 +194,12 @@ Text after second item \end_layout \end_deeper -\begin_layout Plain Layout - -\end_layout - \end_inset -\begin_inset Note Note -status open +\end_layout -\begin_layout Plain Layout +\begin_layout Standard A very complex list: \end_layout @@ -221,11 +216,15 @@ First first item First second item \end_layout -\begin_layout Plain Layout +\begin_layout Standard Text after first item \end_layout \end_deeper +\begin_layout Standard +\begin_inset Note Note +status open + \begin_layout Itemize Second item \end_layout diff --git a/autotests/export/docbook/lists.xml b/autotests/export/docbook/lists.xml index 4c3f588..ede9acb 100644 --- a/autotests/export/docbook/lists.xml +++ b/autotests/export/docbook/lists.xml @@ -3,47 +3,9 @@ See http://www.lyx.org/ for more information --> <article 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"> <!-- Decision to open the wrapper: --><!-- Result: 0 --> -<title>Test document<!-- closeWrapper: 1 --><!-- closeWrapper: condition met --></title> -<!-- closeWrapper first iteration: 1 --><!-- Output Error: Tried to close `title' when no tags were open! --> - +<title>Test document<!-- closeWrapper: 0 --><!-- closeWrapper: condition met --></title> <!-- closeWrapper has looped --><!-- Decision to open the wrapper: prevpar != nullptr; --><!-- Result: 0 --> -<para>A simple list: <!-- closeWrapper: 0 --><!-- closeWrapper: condition met --></para> -<!-- closeWrapper has looped --><!-- 4 --><!-- Decision to open the wrapper: prevpar != nullptr; --><!-- Result: 1 --> -<itemizedlist> -<listitem> -<para><!-- ENV DEPTH: 0. PREV DEPTH: 0. NEXT DEPTH: 0 -->First item<!-- closeWrapper: 0 --></para> -<!-- closeWrapper: condition met --> -</listitem> -<!-- closeWrapper has looped --><!-- 4 --><!-- Decision to open the wrapper: prevpar != nullptr; prevlay.docbookwrappertag() != NONE; SAME DEPTH --><!-- Result: 0 --> -<listitem> -<para><!-- ENV DEPTH: 0. PREV DEPTH: 0. NEXT DEPTH: 0 -->Second item on two lines</para> -<para>I'm the second line<!-- closeWrapper: 1 --></para> -<!-- closeWrapper: condition met --> -</listitem> -<!-- closeWrapper first iteration: 1 --> -<!-- Output Error: Tried to close `listitem' when tag was not open. Tag discarded. --> - -</itemizedlist> -<!-- closeWrapper has looped --><!-- Decision to open the wrapper: prevpar != nullptr; prevlay.docbookwrappertag() != NONE; SAME DEPTH --><!-- Result: 0 --> -<para>A simple enumerated list: <!-- closeWrapper: 0 --><!-- closeWrapper: condition met --></para> -<!-- closeWrapper has looped --><!-- 4 --><!-- Decision to open the wrapper: prevpar != nullptr; --><!-- Result: 1 --> -<orderedlist> -<listitem> -<para><!-- ENV DEPTH: 0. PREV DEPTH: 0. NEXT DEPTH: 0 -->First item<!-- closeWrapper: 0 --></para> -<!-- closeWrapper: condition met --> -</listitem> -<!-- closeWrapper has looped --><!-- 4 --><!-- Decision to open the wrapper: prevpar != nullptr; prevlay.docbookwrappertag() != NONE; SAME DEPTH --><!-- Result: 0 --> -<listitem> -<para><!-- ENV DEPTH: 0. PREV DEPTH: 0. NEXT DEPTH: 0 -->Second item on two lines</para> -<para>I'm the second line<!-- closeWrapper: 1 --></para> -<!-- closeWrapper: condition met --> -</listitem> -<!-- closeWrapper first iteration: 1 --> -<!-- Output Error: Tried to close `listitem' when tag was not open. Tag discarded. --> - -</orderedlist> -<!-- closeWrapper has looped --><!-- Decision to open the wrapper: prevpar != nullptr; prevlay.docbookwrappertag() != NONE; SAME DEPTH --><!-- Result: 0 --> -<para>Nested lists:<!-- closeWrapper: 0 --><!-- closeWrapper: condition met --></para> +<para>A very complex list:<!-- closeWrapper: 0 --><!-- closeWrapper: condition met --></para> <!-- closeWrapper has looped --><!-- 4 --><!-- Decision to open the wrapper: prevpar != nullptr; --><!-- Result: 1 --> <itemizedlist> <listitem> @@ -56,30 +18,11 @@ </listitem> <!-- closeWrapper has looped --><!-- 4 --><!-- Decision to open the wrapper: prevpar != nullptr; prevlay.docbookwrappertag() != NONE; SAME DEPTH --><!-- Result: 0 --> <listitem> -<para><!-- ENV DEPTH: 1. PREV DEPTH: 1. NEXT DEPTH: 0 -->First second item<!-- closeWrapper: 2 --></para> -<!-- closeWrapper first iteration: 2 --> -</listitem> -</itemizedlist> -<!-- closeWrapper first iteration: 1 --> -</listitem> -</itemizedlist> -<!-- closeWrapper has looped --><!-- 4 --><!-- Decision to open the wrapper: prevpar != nullptr; prevlay.docbookwrappertag() != NONE; PREV DEEPER --><!-- Result: 1 --> -<itemizedlist> -<listitem> -<para><!-- ENV DEPTH: 0. PREV DEPTH: 1. NEXT DEPTH: 1 -->Second item<!-- closeWrapper: 0 --></para> -<!-- closeWrapper has looped --><!-- 4 --><!-- Decision to open the wrapper: prevpar != nullptr; prevlay.docbookwrappertag() != NONE; PREV SHALLOWER --><!-- Result: 1 --> -<itemizedlist> -<listitem> -<para><!-- ENV DEPTH: 1. PREV DEPTH: 0. NEXT DEPTH: 1 -->Second first item<!-- closeWrapper: 0 --></para> +<para><!-- ENV DEPTH: 1. PREV DEPTH: 1. NEXT DEPTH: 1 -->First second item<!-- closeWrapper: 0 --></para> <!-- closeWrapper: condition met --> </listitem> -<!-- closeWrapper has looped --><!-- 4 --><!-- Decision to open the wrapper: prevpar != nullptr; prevlay.docbookwrappertag() != NONE; SAME DEPTH --><!-- Result: 0 --> -<listitem> -<para><!-- ENV DEPTH: 1. PREV DEPTH: 1. NEXT DEPTH: 0 -->Second second item<!-- closeWrapper: 2 --></para> -<!-- closeWrapper first iteration: 2 --> -</listitem> -</itemizedlist> -<!-- closeWrapper first iteration: 1 --> -</listitem> -</itemizedlist> +<!-- closeWrapper has looped --><!-- Decision to open the wrapper: prevpar != nullptr; prevlay.docbookwrappertag() != NONE; SAME DEPTH --><!-- Result: 0 --> +<para>Text after first item<!-- closeWrapper: 2 --><!-- closeWrapper first iteration: 2 --></para> +<!-- closeWrapper first iteration: 1 --><!-- Output Error: Tried to close `para' when tag was not open. Tag discarded. --> + <!-- closeWrapper has looped --></article> \ No newline at end of file diff --git a/src/output_docbook.cpp b/src/output_docbook.cpp index a9140ab..78c4bda 100644 --- a/src/output_docbook.cpp +++ b/src/output_docbook.cpp @@ -345,7 +345,8 @@ void closeParTag(XMLStream & xs, Paragraph const * par, Paragraph const * nextpa } } else { if (nextpar->getDepth() == par->getDepth()) { - closeWrapper = 1; + // This is not wrapped: this must be the rest of the item, still within the wrapper. + closeWrapper = 0; } 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; commit 9bbf953d8ca5830ccad2a6f6aeda3ab46205c5fb Author: Thibaut Cuvelier <[email protected]> Date: Sat Aug 29 02:43:30 2020 +0200 XML: use the new mechanisms for CR detection with errors. This helps tracking down line problems even in the presence of errors. diff --git a/src/xml.cpp b/src/xml.cpp index 1a25e54..0daa9d8 100644 --- a/src/xml.cpp +++ b/src/xml.cpp @@ -167,17 +167,21 @@ bool FontTag::operator==(StartTag const & tag) const } // namespace xml -void XMLStream::writeError(std::string const &s) const +void XMLStream::writeError(std::string const &s) { LYXERR0(s); - os_ << from_utf8("<!-- Output Error: " + s + " -->\n"); + *this << ESCAPE_NONE << from_utf8("<!-- Output Error: " + s + " -->"); + *this << xml::CR(); } -void XMLStream::writeError(docstring const &s) const +void XMLStream::writeError(docstring const &s) { LYXERR0(s); - os_ << from_utf8("<!-- Output Error: ") << s << from_utf8(" -->\n"); + *this << ESCAPE_NONE << from_utf8("<!-- Output Error: "); + *this << s; + *this << ESCAPE_NONE << from_utf8(" -->"); + *this << xml::CR(); } diff --git a/src/xml.h b/src/xml.h index ccb1293..bbf5b58 100644 --- a/src/xml.h +++ b/src/xml.h @@ -105,9 +105,9 @@ public: /// that simplifies the logic using this code. bool isLastTagCR() const { return is_last_tag_cr_; }; /// - void writeError(std::string const &) const; + void writeError(std::string const &); /// - void writeError(docstring const &) const; + void writeError(docstring const &); /// typedef std::shared_ptr<xml::StartTag> TagPtr; /// Returns the last element on the tag stack. XMLStream keeps ownership of the item. commit fc5f06a7cb7c57d889c6733030cabbbc3e5e2a69 Author: Thibaut Cuvelier <[email protected]> Date: Sat Aug 29 02:38:49 2020 +0200 WIP... WORKS on many cases! But not all... diff --git a/autotests/export/docbook/lists.lyx b/autotests/export/docbook/lists.lyx index ecfb81d..d8b9c1b 100644 --- a/autotests/export/docbook/lists.lyx +++ b/autotests/export/docbook/lists.lyx @@ -87,10 +87,6 @@ Test document \end_layout \begin_layout Standard -\begin_inset Note Note -status open - -\begin_layout Plain Layout A simple list: \end_layout @@ -106,7 +102,7 @@ Second item on two lines I'm the second line \end_layout -\begin_layout Plain Layout +\begin_layout Standard A simple enumerated list: \end_layout @@ -122,11 +118,6 @@ Second item on two lines I'm the second line \end_layout -\end_inset - - -\end_layout - \begin_layout Standard Nested lists: \end_layout @@ -145,10 +136,6 @@ First second item \end_layout \end_deeper -\begin_layout Standard -\begin_inset Note Note -status open - \begin_layout Itemize Second item \end_layout @@ -163,11 +150,6 @@ Second second item \end_layout \end_deeper -\end_inset - - -\end_layout - \begin_layout Standard \begin_inset Note Note status open @@ -213,6 +195,16 @@ Text after second item \end_deeper \begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Note Note +status open + +\begin_layout Plain Layout A very complex list: \end_layout diff --git a/autotests/export/docbook/lists.xml b/autotests/export/docbook/lists.xml index ae6b6bf..4c3f588 100644 --- a/autotests/export/docbook/lists.xml +++ b/autotests/export/docbook/lists.xml @@ -7,6 +7,42 @@ <!-- closeWrapper first iteration: 1 --><!-- Output Error: Tried to close `title' when no tags were open! --> <!-- closeWrapper has looped --><!-- Decision to open the wrapper: prevpar != nullptr; --><!-- Result: 0 --> +<para>A simple list: <!-- closeWrapper: 0 --><!-- closeWrapper: condition met --></para> +<!-- closeWrapper has looped --><!-- 4 --><!-- Decision to open the wrapper: prevpar != nullptr; --><!-- Result: 1 --> +<itemizedlist> +<listitem> +<para><!-- ENV DEPTH: 0. PREV DEPTH: 0. NEXT DEPTH: 0 -->First item<!-- closeWrapper: 0 --></para> +<!-- closeWrapper: condition met --> +</listitem> +<!-- closeWrapper has looped --><!-- 4 --><!-- Decision to open the wrapper: prevpar != nullptr; prevlay.docbookwrappertag() != NONE; SAME DEPTH --><!-- Result: 0 --> +<listitem> +<para><!-- ENV DEPTH: 0. PREV DEPTH: 0. NEXT DEPTH: 0 -->Second item on two lines</para> +<para>I'm the second line<!-- closeWrapper: 1 --></para> +<!-- closeWrapper: condition met --> +</listitem> +<!-- closeWrapper first iteration: 1 --> +<!-- Output Error: Tried to close `listitem' when tag was not open. Tag discarded. --> + +</itemizedlist> +<!-- closeWrapper has looped --><!-- Decision to open the wrapper: prevpar != nullptr; prevlay.docbookwrappertag() != NONE; SAME DEPTH --><!-- Result: 0 --> +<para>A simple enumerated list: <!-- closeWrapper: 0 --><!-- closeWrapper: condition met --></para> +<!-- closeWrapper has looped --><!-- 4 --><!-- Decision to open the wrapper: prevpar != nullptr; --><!-- Result: 1 --> +<orderedlist> +<listitem> +<para><!-- ENV DEPTH: 0. PREV DEPTH: 0. NEXT DEPTH: 0 -->First item<!-- closeWrapper: 0 --></para> +<!-- closeWrapper: condition met --> +</listitem> +<!-- closeWrapper has looped --><!-- 4 --><!-- Decision to open the wrapper: prevpar != nullptr; prevlay.docbookwrappertag() != NONE; SAME DEPTH --><!-- Result: 0 --> +<listitem> +<para><!-- ENV DEPTH: 0. PREV DEPTH: 0. NEXT DEPTH: 0 -->Second item on two lines</para> +<para>I'm the second line<!-- closeWrapper: 1 --></para> +<!-- closeWrapper: condition met --> +</listitem> +<!-- closeWrapper first iteration: 1 --> +<!-- Output Error: Tried to close `listitem' when tag was not open. Tag discarded. --> + +</orderedlist> +<!-- closeWrapper has looped --><!-- Decision to open the wrapper: prevpar != nullptr; prevlay.docbookwrappertag() != NONE; SAME DEPTH --><!-- Result: 0 --> <para>Nested lists:<!-- closeWrapper: 0 --><!-- closeWrapper: condition met --></para> <!-- closeWrapper has looped --><!-- 4 --><!-- Decision to open the wrapper: prevpar != nullptr; --><!-- Result: 1 --> <itemizedlist> @@ -27,4 +63,23 @@ <!-- closeWrapper first iteration: 1 --> </listitem> </itemizedlist> +<!-- closeWrapper has looped --><!-- 4 --><!-- Decision to open the wrapper: prevpar != nullptr; prevlay.docbookwrappertag() != NONE; PREV DEEPER --><!-- Result: 1 --> +<itemizedlist> +<listitem> +<para><!-- ENV DEPTH: 0. PREV DEPTH: 1. NEXT DEPTH: 1 -->Second item<!-- closeWrapper: 0 --></para> +<!-- closeWrapper has looped --><!-- 4 --><!-- Decision to open the wrapper: prevpar != nullptr; prevlay.docbookwrappertag() != NONE; PREV SHALLOWER --><!-- Result: 1 --> +<itemizedlist> +<listitem> +<para><!-- ENV DEPTH: 1. PREV DEPTH: 0. NEXT DEPTH: 1 -->Second first item<!-- closeWrapper: 0 --></para> +<!-- closeWrapper: condition met --> +</listitem> +<!-- closeWrapper has looped --><!-- 4 --><!-- Decision to open the wrapper: prevpar != nullptr; prevlay.docbookwrappertag() != NONE; SAME DEPTH --><!-- Result: 0 --> +<listitem> +<para><!-- ENV DEPTH: 1. PREV DEPTH: 1. NEXT DEPTH: 0 -->Second second item<!-- closeWrapper: 2 --></para> +<!-- closeWrapper first iteration: 2 --> +</listitem> +</itemizedlist> +<!-- closeWrapper first iteration: 1 --> +</listitem> +</itemizedlist> <!-- closeWrapper has looped --></article> \ No newline at end of file commit 9f9f7302771535ad9b789c3b6570143441d2590a Author: Thibaut Cuvelier <[email protected]> Date: Sat Aug 29 02:37:20 2020 +0200 WIP... WORKS on one example! diff --git a/autotests/export/docbook/lists.lyx b/autotests/export/docbook/lists.lyx index 05f23d3..ecfb81d 100644 --- a/autotests/export/docbook/lists.lyx +++ b/autotests/export/docbook/lists.lyx @@ -128,7 +128,7 @@ I'm the second line \end_layout \begin_layout Standard -Nested lists: +Nested lists: \end_layout \begin_layout Itemize diff --git a/autotests/export/docbook/lists.xml b/autotests/export/docbook/lists.xml index 902fa7d..ae6b6bf 100644 --- a/autotests/export/docbook/lists.xml +++ b/autotests/export/docbook/lists.xml @@ -2,33 +2,29 @@ <!-- This DocBook file was created by LyX 2.4.0dev See http://www.lyx.org/ for more information --> <article 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"> +<!-- Decision to open the wrapper: --><!-- Result: 0 --> <title>Test document<!-- closeWrapper: 1 --><!-- closeWrapper: condition met --></title> <!-- closeWrapper first iteration: 1 --><!-- Output Error: Tried to close `title' when no tags were open! --> -<!-- closeWrapper has looped --> -<para>Nested lists: <!-- closeWrapper: 0 --><!-- closeWrapper: condition met --></para> -<!-- closeWrapper has looped --><!-- 4 --> +<!-- closeWrapper has looped --><!-- Decision to open the wrapper: prevpar != nullptr; --><!-- Result: 0 --> +<para>Nested lists:<!-- closeWrapper: 0 --><!-- closeWrapper: condition met --></para> +<!-- closeWrapper has looped --><!-- 4 --><!-- Decision to open the wrapper: prevpar != nullptr; --><!-- Result: 1 --> <itemizedlist> <listitem> -<para><!-- ENV DEPTH: 0. PREV DEPTH: 0. NEXT DEPTH: 1 -->First item<!-- closeWrapper: 1 --></para> -<!-- closeWrapper first iteration: 1 --> -</listitem> -</itemizedlist> -<!-- closeWrapper has looped --><!-- 4 --> +<para><!-- ENV DEPTH: 0. PREV DEPTH: 0. NEXT DEPTH: 1 -->First item<!-- closeWrapper: 0 --></para> +<!-- closeWrapper has looped --><!-- 4 --><!-- Decision to open the wrapper: prevpar != nullptr; prevlay.docbookwrappertag() != NONE; PREV SHALLOWER --><!-- Result: 1 --> <itemizedlist> <listitem> <para><!-- ENV DEPTH: 1. PREV DEPTH: 0. NEXT DEPTH: 1 -->First first item<!-- closeWrapper: 0 --></para> <!-- closeWrapper: condition met --> </listitem> -<!-- closeWrapper has looped --><!-- 4 --> +<!-- closeWrapper has looped --><!-- 4 --><!-- Decision to open the wrapper: prevpar != nullptr; prevlay.docbookwrappertag() != NONE; SAME DEPTH --><!-- Result: 0 --> <listitem> <para><!-- ENV DEPTH: 1. PREV DEPTH: 1. NEXT DEPTH: 0 -->First second item<!-- closeWrapper: 2 --></para> <!-- closeWrapper first iteration: 2 --> </listitem> </itemizedlist> <!-- closeWrapper first iteration: 1 --> -<!-- Output Error: Tried to close `listitem' when no tags were open! --> - -<!-- Output Error: Tried to close `itemizedlist' when no tags were open! --> - +</listitem> +</itemizedlist> <!-- closeWrapper has looped --></article> \ No newline at end of file diff --git a/src/output_docbook.cpp b/src/output_docbook.cpp index 4a6adde..a9140ab 100644 --- a/src/output_docbook.cpp +++ b/src/output_docbook.cpp @@ -269,24 +269,34 @@ void openParTag(XMLStream & xs, const Paragraph * par, const Paragraph * prevpar // next paragraph is the affiliation, then it should be output in the same <author> tag (different // layout, same wrapper tag). bool openWrapper = lay.docbookwrappertag() != "NONE"; + xs << XMLStream::ESCAPE_NONE << from_ascii("<!-- Decision to open the wrapper: "); if (prevpar != nullptr) { + xs << XMLStream::ESCAPE_NONE << from_ascii("prevpar != nullptr; "); Layout const & prevlay = prevpar->layout(); if (prevlay.docbookwrappertag() != "NONE") { + xs << XMLStream::ESCAPE_NONE << from_ascii("prevlay.docbookwrappertag() != NONE; "); if (prevpar->getDepth() == par->getDepth()) { // Same depth: the basic condition applies. openWrapper = prevlay.docbookwrappertag() == lay.docbookwrappertag() && !lay.docbookwrappermergewithprevious(); + xs << XMLStream::ESCAPE_NONE << from_ascii("SAME DEPTH "); } else if (prevpar->getDepth() > par->getDepth()) { // The previous paragraph was deeper: close the wrapper, no need to open it. + xs << XMLStream::ESCAPE_NONE << from_ascii("PREV DEEPER "); } else { // This paragraph is deeper than the previous one: open the wrapper, // disregarding docbookwrappermergewithprevious. - openWrapper = true; // prevlay.docbookwrappertag() == lay.docbookwrappertag(); + // Don't change openWrapper! + openWrapper = lay.docbookwrappertag() != "NONE"; // prevlay.docbookwrappertag() == lay.docbookwrappertag(); + xs << XMLStream::ESCAPE_NONE << from_ascii("PREV SHALLOWER "); } } else { // openWrapper = false; } } + xs << XMLStream::ESCAPE_NONE << from_ascii(" -->"); + + xs << XMLStream::ESCAPE_NONE << from_ascii("<!-- Result: " + to_string(openWrapper) + " -->"); // Main logic. if (openWrapper) @@ -314,7 +324,7 @@ void closeParTag(XMLStream & xs, Paragraph const * par, Paragraph const * nextpa // See comment in openParTag. // If closeWrapper == 0, the wrapper should not be closed: the next paragraph is another item to add to this list. Layout const & lay = par->layout(); - long long closeWrapper = (lay.docbookwrappertag() == "NONE") ? 0 : 1; // Avoid unsigned, as -1 might appear as value. + long long closeWrapper = 0; // (lay.docbookwrappertag() == "NONE") ? 0 : 1; // Avoid unsigned, as -1 might appear as value. if (nextpar == nullptr) { closeWrapper = 1L + (long long) par->getDepth(); } else { @@ -326,6 +336,7 @@ void closeParTag(XMLStream & xs, Paragraph const * par, Paragraph const * nextpa && !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. @@ -337,6 +348,7 @@ void closeParTag(XMLStream & xs, Paragraph const * par, Paragraph const * nextpa 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. commit e5e81a94489ed4a7ad4c898931de980b5cd7f233 Author: Thibaut Cuvelier <[email protected]> Date: Sat Aug 29 02:31:23 2020 +0200 WIP... diff --git a/autotests/export/docbook/lists.lyx b/autotests/export/docbook/lists.lyx index d5abc84..05f23d3 100644 --- a/autotests/export/docbook/lists.lyx +++ b/autotests/export/docbook/lists.lyx @@ -87,6 +87,10 @@ Test document \end_layout \begin_layout Standard +\begin_inset Note Note +status open + +\begin_layout Plain Layout A simple list: \end_layout @@ -102,7 +106,7 @@ Second item on two lines I'm the second line \end_layout -\begin_layout Standard +\begin_layout Plain Layout A simple enumerated list: \end_layout @@ -118,6 +122,11 @@ Second item on two lines I'm the second line \end_layout +\end_inset + + +\end_layout + \begin_layout Standard Nested lists: \end_layout @@ -136,6 +145,10 @@ First second item \end_layout \end_deeper +\begin_layout Standard +\begin_inset Note Note +status open + \begin_layout Itemize Second item \end_layout @@ -150,6 +163,11 @@ Second second item \end_layout \end_deeper +\end_inset + + +\end_layout + \begin_layout Standard \begin_inset Note Note status open diff --git a/autotests/export/docbook/lists.xml b/autotests/export/docbook/lists.xml index 255c802..902fa7d 100644 --- a/autotests/export/docbook/lists.xml +++ b/autotests/export/docbook/lists.xml @@ -2,58 +2,33 @@ <!-- This DocBook file was created by LyX 2.4.0dev See http://www.lyx.org/ for more information --> <article 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"> -<title>Test document<!-- closeWrapper: 0 --></title> -<para>A simple list: <!-- closeWrapper: 0 --></para> -<!-- 4 --> +<title>Test document<!-- closeWrapper: 1 --><!-- closeWrapper: condition met --></title> +<!-- closeWrapper first iteration: 1 --><!-- Output Error: Tried to close `title' when no tags were open! --> + +<!-- closeWrapper has looped --> +<para>Nested lists: <!-- closeWrapper: 0 --><!-- closeWrapper: condition met --></para> +<!-- closeWrapper has looped --><!-- 4 --> <itemizedlist> <listitem> -<para><!-- ENV: 0 --><!-- PREVDEPTH: 0 -->First item<!-- closeWrapper: 0 --></para> -</listitem> -<!-- 4 --> -<listitem> -<para><!-- ENV: 0 --><!-- PREVDEPTH: 0 -->Second item on two lines</para> -<para>I'm the second line<!-- closeWrapper: 1 --></para> -</listitem> -</itemizedlist> -<para>A simple enumerated list: <!-- closeWrapper: 0 --></para> -<!-- 4 --> -<orderedlist> -<listitem> -<para><!-- ENV: 0 --><!-- PREVDEPTH: 0 -->First item<!-- closeWrapper: 0 --></para> -</listitem> -<!-- 4 --> -<listitem> -<para><!-- ENV: 0 --><!-- PREVDEPTH: 0 -->Second item on two lines</para> -<para>I'm the second line<!-- closeWrapper: 1 --></para> -</listitem> -</orderedlist> -<para>Nested lists: <!-- closeWrapper: 0 --></para> -<!-- 4 --> -<itemizedlist> -<listitem> -<para><!-- ENV: 0 --><!-- PREVDEPTH: 0 -->First item<!-- closeWrapper: 0 --></para> -<!-- 4 --> -<itemizedlist> -<listitem> -<para><!-- ENV: 1 --><!-- PREVDEPTH: 0 -->First first item<!-- closeWrapper: 0 --></para> -</listitem> -<!-- 4 --> -<listitem> -<para><!-- ENV: 1 --><!-- PREVDEPTH: 1 -->First second item<!-- closeWrapper: 1 --></para> +<para><!-- ENV DEPTH: 0. PREV DEPTH: 0. NEXT DEPTH: 1 -->First item<!-- closeWrapper: 1 --></para> +<!-- closeWrapper first iteration: 1 --> </listitem> </itemizedlist> -<!-- 4 --> -<itemizedlist> -<listitem> -<para><!-- ENV: 0 --><!-- PREVDEPTH: 1 -->Second item<!-- closeWrapper: 0 --></para> -<!-- 4 --> +<!-- closeWrapper has looped --><!-- 4 --> <itemizedlist> <listitem> -<para><!-- ENV: 1 --><!-- PREVDEPTH: 0 -->Second first item<!-- closeWrapper: 0 --></para> +<para><!-- ENV DEPTH: 1. PREV DEPTH: 0. NEXT DEPTH: 1 -->First first item<!-- closeWrapper: 0 --></para> +<!-- closeWrapper: condition met --> </listitem> -<!-- 4 --> +<!-- closeWrapper has looped --><!-- 4 --> <listitem> -<para><!-- ENV: 1 --><!-- PREVDEPTH: 1 -->Second second item<!-- closeWrapper: 1 --></para> +<para><!-- ENV DEPTH: 1. PREV DEPTH: 1. NEXT DEPTH: 0 -->First second item<!-- closeWrapper: 2 --></para> +<!-- closeWrapper first iteration: 2 --> </listitem> </itemizedlist> -</article> \ No newline at end of file +<!-- closeWrapper first iteration: 1 --> +<!-- Output Error: Tried to close `listitem' when no tags were open! --> + +<!-- Output Error: Tried to close `itemizedlist' when no tags were open! --> + +<!-- closeWrapper has looped --></article> \ No newline at end of file diff --git a/src/output_docbook.cpp b/src/output_docbook.cpp index ac867c1..4a6adde 100644 --- a/src/output_docbook.cpp +++ b/src/output_docbook.cpp @@ -281,8 +281,10 @@ void openParTag(XMLStream & xs, const Paragraph * par, const Paragraph * prevpar } else { // This paragraph is deeper than the previous one: open the wrapper, // disregarding docbookwrappermergewithprevious. - openWrapper = prevlay.docbookwrappertag() == lay.docbookwrappertag(); + openWrapper = true; // prevlay.docbookwrappertag() == lay.docbookwrappertag(); } + } else { +// openWrapper = false; } } @@ -294,8 +296,8 @@ void openParTag(XMLStream & xs, const Paragraph * par, const Paragraph * prevpar if (tag != "NONE") { auto xmltag = xml::ParTag(tag, lay.docbookattr()); if (!xs.isTagOpen(xmltag, 1)) // Don't nest a paragraph directly in a paragraph. - // TODO: required or not? - // TODO: avoid creating a ParTag object just for this query... + // TODO: is this condition required or not? + // TODO: avoid creating a ParTag object (xmltag) just for this query... openTag(xs, lay.docbooktag(), lay.docbookattr(), lay.docbooktagtype()); } @@ -310,47 +312,61 @@ void closeParTag(XMLStream & xs, Paragraph const * par, Paragraph const * nextpa nextpar = nullptr; // See comment in openParTag. + // If closeWrapper == 0, the wrapper should not be closed: the next paragraph is another item to add to this list. Layout const & lay = par->layout(); - unsigned long long closeWrapper = (lay.docbookwrappertag() == "NONE") ? 0 : 1; - if (nextpar != nullptr) { - Layout const & nextlay = nextpar->layout(); + long long closeWrapper = (lay.docbookwrappertag() == "NONE") ? 0 : 1; // Avoid unsigned, as -1 might appear as value. + if (nextpar == nullptr) { + closeWrapper = 1L + (long long) par->getDepth(); + } else { + 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. + // The next paragraph is deeper: no need to close the wrapper, only to open it (cf. openParTag). + } 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()) { + 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). } else { // This paragraph is deeper than the next one: close the wrapper, // disregarding docbookwrappermergewithprevious. - // Hypothesis: nextlay.docbookwrappertag() == lay.docbookwrappertag(). TODO: THIS IS WRONG! Use a stack? - closeWrapper = par->getDepth() - nextpar->getDepth(); + // 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 { - closeWrapper = 1 + par->getDepth(); } - // Main logic. + // Main logic. (Comments mostly correspond to lists.) xs << XMLStream::ESCAPE_NONE << from_ascii("<!-- closeWrapper: " + to_string(closeWrapper) + " -->"); + // - Close this paragraph. closeTag(xs, lay.docbookiteminnertag(), lay.docbookiteminnertagtype()); + + // - Close the current item. if (!nextpar || nextpar->getDepth() == par->getDepth()) { + xs << XMLStream::ESCAPE_NONE << from_ascii("<!-- closeWrapper: condition met -->"); closeTag(xs, lay.docbookitemtag(), lay.docbookitemtagtype()); closeTag(xs, lay.docbooktag(), lay.docbooktagtype()); - if (closeWrapper > 0) { - closeTag(xs, lay.docbookwrappertag(), lay.docbookwrappertagtype()); - closeWrapper -= 1; - } } + + // - Close wrapper tags as many times as required. while (closeWrapper > 0) { + xs << XMLStream::ESCAPE_NONE << from_ascii("<!-- closeWrapper first iteration: " + to_string(closeWrapper) + " -->"); closeTag(xs, lay.docbookitemtag(), lay.docbookitemtagtype()); closeTag(xs, lay.docbooktag(), lay.docbooktagtype()); closeTag(xs, lay.docbookwrappertag(), lay.docbookwrappertagtype()); closeWrapper -= 1; } + xs << XMLStream::ESCAPE_NONE << "<!-- closeWrapper has looped -->"; } @@ -555,9 +571,15 @@ void makeEnvironment( auto prevpar = text.paragraphs().getParagraphBefore(par); openParTag(xs, &*par, prevpar); // TODO: switch in layout for par/block? - xs << XMLStream::ESCAPE_NONE << from_ascii("<!-- ENV: " + to_string(par->getDepth()) + " -->"); + xs << XMLStream::ESCAPE_NONE << from_ascii("<!-- ENV DEPTH: " + to_string(par->getDepth()) + ". "); if (prevpar) - xs << XMLStream::ESCAPE_NONE << from_ascii("<!-- PREVDEPTH: " + to_string(prevpar->getDepth()) + " -->"); + xs << XMLStream::ESCAPE_NONE << from_ascii("PREV DEPTH: " + to_string(prevpar->getDepth()) + ". "); + if (par != end) { + auto nextpar = par; + ++nextpar; + xs << XMLStream::ESCAPE_NONE << from_ascii("NEXT DEPTH: " + to_string(nextpar->getDepth())); + } + xs << XMLStream::ESCAPE_NONE << from_ascii(" -->"); // Generate the contents of this environment. There is a special case if this is like some environment. Layout const & style = par->layout(); diff --git a/src/xml.cpp b/src/xml.cpp index b4004af..1a25e54 100644 --- a/src/xml.cpp +++ b/src/xml.cpp @@ -181,6 +181,12 @@ void XMLStream::writeError(docstring const &s) const } +XMLStream::TagPtr XMLStream::getLastStackTag() +{ + return tag_stack_.back(); +} + + bool XMLStream::closeFontTags() { if (isTagPending(xml::parsep_tag)) diff --git a/src/xml.h b/src/xml.h index 576a4f2..ccb1293 100644 --- a/src/xml.h +++ b/src/xml.h @@ -108,6 +108,10 @@ public: void writeError(std::string const &) const; /// void writeError(docstring const &) const; + /// + typedef std::shared_ptr<xml::StartTag> TagPtr; + /// Returns the last element on the tag stack. XMLStream keeps ownership of the item. + TagPtr getLastStackTag(); private: /// void clearTagDeque(); @@ -123,7 +127,6 @@ private: // own these pointers and how they will be deleted, so we use shared // pointers. /// - typedef std::shared_ptr<xml::StartTag> TagPtr; typedef std::deque<TagPtr> TagDeque; /// template <typename T> commit a83b01665274f087f5a82d5130161e7d4ed47dfb Author: Thibaut Cuvelier <[email protected]> Date: Thu Aug 27 02:07:41 2020 +0200 WIP... diff --git a/autotests/export/docbook/lists.xml b/autotests/export/docbook/lists.xml index 0609b36..255c802 100644 --- a/autotests/export/docbook/lists.xml +++ b/autotests/export/docbook/lists.xml @@ -4,44 +4,54 @@ <article 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"> <title>Test document<!-- closeWrapper: 0 --></title> <para>A simple list: <!-- closeWrapper: 0 --></para> +<!-- 4 --> <itemizedlist> <listitem> <para><!-- ENV: 0 --><!-- PREVDEPTH: 0 -->First item<!-- closeWrapper: 0 --></para> </listitem> +<!-- 4 --> <listitem> <para><!-- ENV: 0 --><!-- PREVDEPTH: 0 -->Second item on two lines</para> <para>I'm the second line<!-- closeWrapper: 1 --></para> </listitem> </itemizedlist> <para>A simple enumerated list: <!-- closeWrapper: 0 --></para> +<!-- 4 --> <orderedlist> <listitem> <para><!-- ENV: 0 --><!-- PREVDEPTH: 0 -->First item<!-- closeWrapper: 0 --></para> </listitem> +<!-- 4 --> <listitem> <para><!-- ENV: 0 --><!-- PREVDEPTH: 0 -->Second item on two lines</para> <para>I'm the second line<!-- closeWrapper: 1 --></para> </listitem> </orderedlist> <para>Nested lists: <!-- closeWrapper: 0 --></para> +<!-- 4 --> <itemizedlist> <listitem> <para><!-- ENV: 0 --><!-- PREVDEPTH: 0 -->First item<!-- closeWrapper: 0 --></para> +<!-- 4 --> <itemizedlist> <listitem> <para><!-- ENV: 1 --><!-- PREVDEPTH: 0 -->First first item<!-- closeWrapper: 0 --></para> </listitem> +<!-- 4 --> <listitem> <para><!-- ENV: 1 --><!-- PREVDEPTH: 1 -->First second item<!-- closeWrapper: 1 --></para> </listitem> </itemizedlist> +<!-- 4 --> <itemizedlist> <listitem> <para><!-- ENV: 0 --><!-- PREVDEPTH: 1 -->Second item<!-- closeWrapper: 0 --></para> +<!-- 4 --> <itemizedlist> <listitem> <para><!-- ENV: 1 --><!-- PREVDEPTH: 0 -->Second first item<!-- closeWrapper: 0 --></para> </listitem> +<!-- 4 --> <listitem> <para><!-- ENV: 1 --><!-- PREVDEPTH: 1 -->Second second item<!-- closeWrapper: 1 --></para> </listitem> diff --git a/src/output_docbook.cpp b/src/output_docbook.cpp index 9de9238..ac867c1 100644 --- a/src/output_docbook.cpp +++ b/src/output_docbook.cpp @@ -324,7 +324,7 @@ void closeParTag(XMLStream & xs, Paragraph const * par, Paragraph const * nextpa } else if (nextpar->getDepth() > par->getDepth()) { // The next paragraph is deeper: no need to close the wrapper. } else { - // This paragraph is deeper than the previous one: open the wrapper, + // This paragraph is deeper than the next one: close the wrapper, // disregarding docbookwrappermergewithprevious. // Hypothesis: nextlay.docbookwrappertag() == lay.docbookwrappertag(). TODO: THIS IS WRONG! Use a stack? closeWrapper = par->getDepth() - nextpar->getDepth(); @@ -548,6 +548,8 @@ void makeEnvironment( { auto const end = text.paragraphs().end(); + xs << XMLStream::ESCAPE_NONE << from_ascii("<!-- " + to_string(par->layout().latextype) + " -->"); + // 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); @@ -631,6 +633,17 @@ void makeEnvironment( makeAny(text, buf, xs, runparams, par); } +// stack<Layout> previous_; +// int curdepth = -1; text.paragraphs().front().getDepth(); +// for (auto const & p : text.paragraphs()) { +// if (p.layout().latextype == LATEX_ITEM_ENVIRONMENT) { +// if (curdepth ) { +// ; +// } +// curdepth = p.getDepth(); +// } else if (curdepth > 0) +// } + // Close the environment. auto nextpar = par; ++nextpar; commit 7fba82b4bcf0473f266078220262acd5a5ac2ab0 Author: Thibaut Cuvelier <[email protected]> Date: Thu Aug 27 00:52:06 2020 +0200 WIP... diff --git a/autotests/export/docbook/lists.lyx b/autotests/export/docbook/lists.lyx index f4a58c2..d5abc84 100644 --- a/autotests/export/docbook/lists.lyx +++ b/autotests/export/docbook/lists.lyx @@ -103,8 +103,56 @@ I'm the second line \end_layout \begin_layout Standard +A simple enumerated list: +\end_layout + +\begin_layout Enumerate +First item +\end_layout + +\begin_layout Enumerate +Second item on two lines +\begin_inset Newline newline +\end_inset + +I'm the second line +\end_layout + +\begin_layout Standard +Nested lists: +\end_layout + +\begin_layout Itemize +First item +\end_layout + +\begin_deeper +\begin_layout Itemize +First first item +\end_layout + +\begin_layout Itemize +First second item +\end_layout + +\end_deeper +\begin_layout Itemize +Second item +\end_layout + +\begin_deeper +\begin_layout Itemize +Second first item +\end_layout + +\begin_layout Itemize +Second second item +\end_layout + +\end_deeper +\begin_layout Standard \begin_inset Note Note -status collapsed +status open \begin_layout Plain Layout A complex list: @@ -133,6 +181,46 @@ Second item \end_layout \begin_deeper +\begin_layout Itemize +Second first item +\end_layout + +\begin_layout Itemize +Second second item +\end_layout + +\begin_layout Plain Layout +Text after second item +\end_layout + +\end_deeper +\begin_layout Plain Layout +A very complex list: +\end_layout + +\begin_layout Itemize +First item +\end_layout + +\begin_deeper +\begin_layout Itemize +First first item +\end_layout + +\begin_layout Itemize +First second item +\end_layout + +\begin_layout Plain Layout +Text after first item +\end_layout + +\end_deeper +\begin_layout Itemize +Second item +\end_layout + +\begin_deeper \begin_layout Enumerate Second first item \end_layout diff --git a/autotests/export/docbook/lists.xml b/autotests/export/docbook/lists.xml index d7b24f6..0609b36 100644 --- a/autotests/export/docbook/lists.xml +++ b/autotests/export/docbook/lists.xml @@ -2,15 +2,48 @@ <!-- This DocBook file was created by LyX 2.4.0dev See http://www.lyx.org/ for more information --> <article 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"> -<title>Test document</title> -<para>A simple list: </para> +<title>Test document<!-- closeWrapper: 0 --></title> +<para>A simple list: <!-- closeWrapper: 0 --></para> <itemizedlist> <listitem> -<para>First item</para> +<para><!-- ENV: 0 --><!-- PREVDEPTH: 0 -->First item<!-- closeWrapper: 0 --></para> </listitem> <listitem> -<para>Second item on two lines</para> -<para>I'm the second line</para> +<para><!-- ENV: 0 --><!-- PREVDEPTH: 0 -->Second item on two lines</para> +<para>I'm the second line<!-- closeWrapper: 1 --></para> +</listitem> +</itemizedlist> +<para>A simple enumerated list: <!-- closeWrapper: 0 --></para> +<orderedlist> +<listitem> +<para><!-- ENV: 0 --><!-- PREVDEPTH: 0 -->First item<!-- closeWrapper: 0 --></para> +</listitem> +<listitem> +<para><!-- ENV: 0 --><!-- PREVDEPTH: 0 -->Second item on two lines</para> +<para>I'm the second line<!-- closeWrapper: 1 --></para> +</listitem> +</orderedlist> +<para>Nested lists: <!-- closeWrapper: 0 --></para> +<itemizedlist> +<listitem> +<para><!-- ENV: 0 --><!-- PREVDEPTH: 0 -->First item<!-- closeWrapper: 0 --></para> +<itemizedlist> +<listitem> +<para><!-- ENV: 1 --><!-- PREVDEPTH: 0 -->First first item<!-- closeWrapper: 0 --></para> +</listitem> +<listitem> +<para><!-- ENV: 1 --><!-- PREVDEPTH: 1 -->First second item<!-- closeWrapper: 1 --></para> +</listitem> +</itemizedlist> +<itemizedlist> +<listitem> +<para><!-- ENV: 0 --><!-- PREVDEPTH: 1 -->Second item<!-- closeWrapper: 0 --></para> +<itemizedlist> +<listitem> +<para><!-- ENV: 1 --><!-- PREVDEPTH: 0 -->Second first item<!-- closeWrapper: 0 --></para> +</listitem> +<listitem> +<para><!-- ENV: 1 --><!-- PREVDEPTH: 1 -->Second second item<!-- closeWrapper: 1 --></para> </listitem> </itemizedlist> </article> \ No newline at end of file diff --git a/lib/layouts/stdlists.inc b/lib/layouts/stdlists.inc index c0b346d..f6dd411 100644 --- a/lib/layouts/stdlists.inc +++ b/lib/layouts/stdlists.inc @@ -87,7 +87,9 @@ Style Enumerate Color latex EndFont EndArgument - DocBookTag orderedlist + DocBookWrapperTag orderedlist + DocBookWrapperMergeWithPrevious true + DocBookTag NONE DocBookItemTag listitem DocBookItemInnerTag para End @@ -129,7 +131,9 @@ Style Description Color latex EndFont EndArgument - DocBookTag variablelist + DocBookWrapperTag variablelist + DocBookWrapperMergeWithPrevious true + DocBookTag NONE DocBookItemWrapperTag varlistentry DocBookItemTag listitem DocBookItemInnerTag para diff --git a/src/output_docbook.cpp b/src/output_docbook.cpp index 6668ee7..9de9238 100644 --- a/src/output_docbook.cpp +++ b/src/output_docbook.cpp @@ -272,8 +272,17 @@ void openParTag(XMLStream & xs, const Paragraph * par, const Paragraph * prevpar if (prevpar != nullptr) { Layout const & prevlay = prevpar->layout(); if (prevlay.docbookwrappertag() != "NONE") { - openWrapper = prevlay.docbookwrappertag() == lay.docbookwrappertag() - && !lay.docbookwrappermergewithprevious(); + if (prevpar->getDepth() == par->getDepth()) { + // Same depth: the basic condition applies. + openWrapper = prevlay.docbookwrappertag() == lay.docbookwrappertag() + && !lay.docbookwrappermergewithprevious(); + } else if (prevpar->getDepth() > par->getDepth()) { + // The previous paragraph was deeper: close the wrapper, no need to open it. + } else { + // This paragraph is deeper than the previous one: open the wrapper, + // disregarding docbookwrappermergewithprevious. + openWrapper = prevlay.docbookwrappertag() == lay.docbookwrappertag(); + } } } @@ -302,21 +311,46 @@ void closeParTag(XMLStream & xs, Paragraph const * par, Paragraph const * nextpa // See comment in openParTag. Layout const & lay = par->layout(); - bool closeWrapper = lay.docbookwrappertag() != "NONE"; + unsigned long long closeWrapper = (lay.docbookwrappertag() == "NONE") ? 0 : 1; 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. + } else { + // This paragraph is deeper than the previous one: open the wrapper, + // disregarding docbookwrappermergewithprevious. + // Hypothesis: nextlay.docbookwrappertag() == lay.docbookwrappertag(). TODO: THIS IS WRONG! Use a stack? + closeWrapper = par->getDepth() - nextpar->getDepth(); + } } + } else { + closeWrapper = 1 + par->getDepth(); } // Main logic. + xs << XMLStream::ESCAPE_NONE << from_ascii("<!-- closeWrapper: " + to_string(closeWrapper) + " -->"); closeTag(xs, lay.docbookiteminnertag(), lay.docbookiteminnertagtype()); - closeTag(xs, lay.docbookitemtag(), lay.docbookitemtagtype()); - closeTag(xs, lay.docbooktag(), lay.docbooktagtype()); - if (closeWrapper) + if (!nextpar || nextpar->getDepth() == par->getDepth()) { + closeTag(xs, lay.docbookitemtag(), lay.docbookitemtagtype()); + closeTag(xs, lay.docbooktag(), lay.docbooktagtype()); + if (closeWrapper > 0) { + closeTag(xs, lay.docbookwrappertag(), lay.docbookwrappertagtype()); + closeWrapper -= 1; + } + } + while (closeWrapper > 0) { + closeTag(xs, lay.docbookitemtag(), lay.docbookitemtagtype()); + closeTag(xs, lay.docbooktag(), lay.docbooktagtype()); closeTag(xs, lay.docbookwrappertag(), lay.docbookwrappertagtype()); + closeWrapper -= 1; + } } @@ -519,6 +553,10 @@ void makeEnvironment( auto prevpar = text.paragraphs().getParagraphBefore(par); openParTag(xs, &*par, prevpar); // TODO: switch in layout for par/block? + xs << XMLStream::ESCAPE_NONE << from_ascii("<!-- ENV: " + to_string(par->getDepth()) + " -->"); + if (prevpar) + xs << XMLStream::ESCAPE_NONE << from_ascii("<!-- PREVDEPTH: " + to_string(prevpar->getDepth()) + " -->"); + // 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) { ----------------------------------------------------------------------- Summary of changes: autotests/export/docbook/lists.lyx | 99 ++++++++++++++++-- autotests/export/docbook/lists.xml | 92 ++++++++++++++++ lib/layouts/stdlists.inc | 4 +- src/output_docbook.cpp | 205 ++++++++++++++++++++++++++++-------- src/xml.cpp | 18 +++- src/xml.h | 9 +- 6 files changed, 363 insertions(+), 64 deletions(-) hooks/post-receive -- Repository for new features -- lyx-cvs mailing list [email protected] http://lists.lyx.org/mailman/listinfo/lyx-cvs
