[LyX/master] DocBook: fix case with emphasis at end of footnote

2023-09-25 Thread Scott Kostyshak
commit ff9dfa96f26b8544d1264d6eaac390b3f5891bde
Author: Scott Kostyshak 
Date:   Mon Sep 25 10:41:21 2023 -0400

DocBook: fix case with emphasis at end of footnote

For ML discussion, see here:

  
https://www.mail-archive.com/search?l=mid=CAK0LPyiusCMu-X7KpgO0d1-rh4e3%3DRwR5ooXE_fdb7UVuB0VUA%40mail.gmail.com

Patch from Thibaut Cuvelier.
---
 src/Paragraph.cpp |   24 +++-
 src/xml.cpp   |   10 ++
 src/xml.h |   13 +
 3 files changed, 42 insertions(+), 5 deletions(-)

diff --git a/src/Paragraph.cpp b/src/Paragraph.cpp
index a9b186b..3718bd4 100644
--- a/src/Paragraph.cpp
+++ b/src/Paragraph.cpp
@@ -3673,6 +3673,7 @@ std::tuple, 
std::vector, std::vectorstartDivision(false);
 std::vector delayedChars; // When a font tag ends with a space, 
output it after the closing font tag.
 // This requires to store delayed characters at some point.
 
@@ -3696,8 +3697,8 @@ std::tuple, 
std::vector, std::vectorlyxCode() == NEWLINE_CODE) {
if (!ignore_fonts_i)
xs->closeFontTags();
@@ -3705,11 +3706,14 @@ std::tuple, 
std::vector, std::vectorendDivision();
+
// Create a new XMLStream for the new paragraph, 
completely independent of the previous one. This implies
// that the string stream must be reset.
os.str(from_ascii(""));
delete xs;
xs = new XMLStream(os);
+   xs->startDivision(false);
 
// Restore the fonts for the new paragraph, so that the 
right tags are opened for the new entry.
if (!ignore_fonts_i) {
@@ -3744,11 +3748,12 @@ std::tuple, 
std::vector, std::vector::const_iterator sen = 
tagsToOpen.end();
for (; sit != sen; ++sit)
*xs << *sit;
-
-   tagsToClose.clear();
-   tagsToOpen.clear();
}
 
+   // The font tags are no longer useful; free their memory right 
now.
+   tagsToClose.clear();
+   tagsToOpen.clear();
+
 // Finally, write the next character or inset.
if (Inset const * inset = getInset(i)) {
bool inset_is_argument_elsewhere = 
getInset(i)->asInsetArgument() &&
@@ -3781,12 +3786,21 @@ std::tuple, 
std::vector, std::vectorcloseFontTags();
 
+   // Close the potentially remaining tags, like pending font tags.
+   // There is no need to check for ignore_fonts, as these tags won't be
+   // inserted in the stack in the first place if ignore_fonts is false.
+   xs->endDivision();
+
// Deal with the delayed characters *after* closing font tags.
if (!delayedChars.empty()) {
for (const docstring : delayedChars)
diff --git a/src/xml.cpp b/src/xml.cpp
index 53ccb8a..5b81024 100644
--- a/src/xml.cpp
+++ b/src/xml.cpp
@@ -287,6 +287,16 @@ XMLStream ::operator<<(docstring const )
 }
 
 
+XMLStream ::operator<<(xml::NullTag const &)
+{
+   is_last_tag_cr_ = false;
+   clearTagDeque();
+   // Don't output anything to os_, by definition of a NullTag (as opposed 
to text output).
+   escape_ = ESCAPE_ALL;
+   return *this;
+}
+
+
 XMLStream ::operator<<(const char *s)
 {
is_last_tag_cr_ = false;
diff --git a/src/xml.h b/src/xml.h
index 03710c1..346e42d 100644
--- a/src/xml.h
+++ b/src/xml.h
@@ -31,6 +31,7 @@ namespace xml {
 struct StartTag;
 struct EndTag;
 struct CompTag;
+struct NullTag;
 struct ParTag;
 struct FontTag;
 struct CR;
@@ -67,6 +68,8 @@ public:
///
XMLStream & operator<<(char);
///
+   XMLStream & operator<<(xml::NullTag const &);
+   ///
XMLStream & operator<<(xml::StartTag const &);
///
XMLStream & operator<<(xml::EndTag const &);
@@ -274,6 +277,16 @@ struct ParTag : public StartTag
 };
 
 
+/// A special tag that doesn't produce any XML output, but makes the XMLStream 
behave as it it output some text.
+struct NullTag : public StartTag
+{
+   ///
+   NullTag(): StartTag("NULLTAG", from_utf8(""), true) {}
+   ///
+   ~NullTag() override = default;
+};
+
+
 ///
 enum FontTypes {
// ranges
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/master] ctests: update inverted list after DocBook fix

2023-09-25 Thread Scott Kostyshak
commit beec7b669f5b93deee44e528bad21b61c29e2bd7
Author: Scott Kostyshak 
Date:   Mon Sep 25 10:58:50 2023 -0400

ctests: update inverted list after DocBook fix

Thanks to the fix at ff9dfa96, we can uninvert a test.

Also invert a couple of other tests and organize into the correct
location.
---
 development/autotests/invertedTests |5 +
 1 files changed, 1 insertions(+), 4 deletions(-)

diff --git a/development/autotests/invertedTests 
b/development/autotests/invertedTests
index 8805bd9..b8a2d45 100644
--- a/development/autotests/invertedTests
+++ b/development/autotests/invertedTests
@@ -428,7 +428,7 @@ export/export/docbook/Hollywood_docbook5
 #   - Lettre, formatting in elements DocBook does not allow to be formatted 
(like email).
 export/templates/Letters/French_Letter_%28lettre%29_docbook5
 #   - Letter, elements at the end of the document that should be in .
-export/templates/Letters/Letter_%28Standard_Class%29_docbook5
+export/templates(|/es|/ca)/Letters/Letter_%28Standard_Class%29_docbook5
 #   - G-Brief: too far from the other classes, not implemented.
 export/templates/Letters/G-Brief_%28V._2%29_docbook5
 export/templates/Obsolete/G-Brief_%28V._1,_Obsolete%29/.*_docbook5
@@ -517,9 +517,6 @@ 
export/export/latex/lyxbugs-resolved/cprotect/7779-float-in-par-env_docbook5
 #   See also ML discussion:
 # 
https://www.mail-archive.com/search?l=mid=20211102011304.dmrcr7gjpxxwpd4o%40poole
 export/examples/(|ja/)Modules/LilyPond_Book_docbook5
-# - Undiagnosed issues.
-export/doc/ca/Intro_docbook5
-export/templates/ca/Letters/Letter_%28Standard_Class%29_docbook5
 
 Sublabel: docbook poster
 # Posters cannot be properly exported, the LyX documents are too far from
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/master] Improve comments

2023-09-25 Thread Jean-Marc Lasgouttes
commit 549969a56356b57cb912f7caea58e437399f1ca5
Author: Jean-Marc Lasgouttes 
Date:   Mon Sep 25 12:46:16 2023 +0200

Improve comments
---
 src/Row.cpp |   15 ---
 1 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/src/Row.cpp b/src/Row.cpp
index e911fef..687d9ec 100644
--- a/src/Row.cpp
+++ b/src/Row.cpp
@@ -574,9 +574,9 @@ Row::Elements Row::shortenIfNeeded(int const max_width, int 
const next_width)
--cit_brk;
// make a copy of the element to work on it.
Element brk = *cit_brk;
-   /* If the current element is an inset that allows breaking row
-* after itself, and if the row is already short enough after
-* this element, then cut right after it.
+   /* If the current element allows breaking row after itself,
+* and if the row is already short enough after this element,
+* then cut right after it.
 */
if (wid_brk <= max_width && brk.row_flags & CanBreakAfter) {
end_ = brk.endpos;
@@ -586,9 +586,9 @@ Row::Elements Row::shortenIfNeeded(int const max_width, int 
const next_width)
}
// assume now that the current element is not there
wid_brk -= brk.dim.wid;
-   /* If the current element is an inset that allows breaking row
-* before itself, and if the row is already short enough before
-* this element, then cut right before it.
+   /* If the current element allows breaking row before itself,
+* and if the row is already short enough before this element,
+* then cut right before it.
 */
if (wid_brk <= max_width && brk.row_flags & CanBreakBefore && 
cit_brk != beg) {
end_ = (cit_brk -1)->endpos;
@@ -615,13 +615,14 @@ Row::Elements Row::shortenIfNeeded(int const max_width, 
int const next_width)
/* if this element originally did not cause a row 
overflow
 * in itself, and the remainder of the row would still 
be
 * too large after breaking, then we will have issues in
-* next row. Thus breaking does not help.
+* next row. Thus breaking here does not help.
 */
if (wid_brk + cit_brk->dim.wid < max_width
&& min_row_wid - (wid_brk + brk.dim.wid) >= 
next_width) {
tail.clear();
break;
}
+   // We have found a proper place where to break this 
string element.
end_ = brk.endpos;
*cit_brk = brk;
dim_.wid = wid_brk + brk.dim.wid;
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs


[LyX/master] Avoid row breaking at inconvenient places.

2023-09-25 Thread Jean-Marc Lasgouttes
commit 71d9f6e90d52d8f85c9e8b530027a9fd59c697e8
Author: Jean-Marc Lasgouttes 
Date:   Mon Sep 25 12:35:40 2023 +0200

Avoid row breaking at inconvenient places.

When it turns out that breaking a STRING row element was not
sufficient in Row::shortenIfNeeded, we still remember the shortest
width that one can obtain. Later, when we try to split a previous
element of the row, we have a better idea of how much of the row
remains after it.

To this end, change the signature of Element::splitAt to use an enum:
FIT (was: force=false), FORCE (was: force= true) and BEST_EFFORT
(split at max_width, but do not return an error if the string is too
large).

Fixes bug #12660.
---
 src/Row.cpp |   25 ++---
 src/Row.h   |   14 ++
 src/TextMetrics.cpp |2 +-
 3 files changed, 29 insertions(+), 12 deletions(-)

diff --git a/src/Row.cpp b/src/Row.cpp
index a7f00d5..e911fef 100644
--- a/src/Row.cpp
+++ b/src/Row.cpp
@@ -123,7 +123,7 @@ pos_type Row::Element::x2pos(int ) const
 }
 
 
-bool Row::Element::splitAt(int const width, int next_width, bool force,
+bool Row::Element::splitAt(int const width, int next_width, SplitType 
split_type,
Row::Elements & tail)
 {
// Not a string or already OK.
@@ -142,13 +142,13 @@ bool Row::Element::splitAt(int const width, int 
next_width, bool force,
 
bool const wrap_any = !font.language()->wordWrap();
FontMetrics::Breaks breaks = fm.breakString(str, width, next_width,
-isRTL(), wrap_any | force);
+isRTL(), wrap_any || 
split_type == FORCE);
 
/** if breaking did not really work, give up
-* case 1: we do not force break and the first element is longer than 
the limit;
+* case 1: split type is FIT and the first element is longer than the 
limit;
 * case 2: the first break occurs at the front of the string
 */
-   if ((!force && breaks.front().nspc_wid > width)
+   if ((split_type == FIT && breaks.front().nspc_wid > width)
|| (breaks.size() > 1 && breaks.front().len == 0)) {
if (dim.wid == 0)
dim.wid = fm.width(str);
@@ -548,6 +548,8 @@ Row::Elements Row::shortenIfNeeded(int const max_width, int 
const next_width)
Elements::iterator const beg = elements_.begin();
Elements::iterator const end = elements_.end();
int wid = left_margin;
+   // the smallest row width we know we can achieve by breaking a string.
+   int min_row_wid = dim_.wid;
 
// Search for the first element that goes beyond right margin
Elements::iterator cit = beg;
@@ -600,14 +602,23 @@ Row::Elements Row::shortenIfNeeded(int const max_width, 
int const next_width)
 * - shorter than the natural width of the element, in order to 
enforce
 *   break-up.
 */
-   if (brk.splitAt(min(max_width - wid_brk, brk.dim.wid - 2), 
next_width, false, tail)) {
+   int const split_width =  min(max_width - wid_brk, brk.dim.wid - 
2);
+   if (brk.splitAt(split_width, next_width, BEST_EFFORT, tail)) {
+   // if we did not manage to fit a part of the element 
into
+   // the split_width limit, at least remember that we can
+   // shorten the row if needed.
+   if (brk.dim.wid > split_width) {
+   min_row_wid = wid_brk + brk.dim.wid;
+   tail.clear();
+   continue;
+   }
/* if this element originally did not cause a row 
overflow
 * in itself, and the remainder of the row would still 
be
 * too large after breaking, then we will have issues in
 * next row. Thus breaking does not help.
 */
if (wid_brk + cit_brk->dim.wid < max_width
-   && dim_.wid - (wid_brk + brk.dim.wid) >= 
next_width) {
+   && min_row_wid - (wid_brk + brk.dim.wid) >= 
next_width) {
tail.clear();
break;
}
@@ -641,7 +652,7 @@ Row::Elements Row::shortenIfNeeded(int const max_width, int 
const next_width)
 * shorten the row. Let's try to break it again, but force
 * splitting this time.
 */
-   if (cit->splitAt(max_width - wid, next_width, true, tail)) {
+   if (cit->splitAt(max_width - wid, next_width, FORCE, tail)) {
end_ = cit->endpos;
dim_.wid = wid + cit->dim.wid;
// If there are other elements, they should be removed.
diff --git a/src/Row.h b/src/Row.h
index 

[LyX/master] Revert "Avoid row breaking at inconvenient places."

2023-09-25 Thread Jean-Marc Lasgouttes
commit 1ca43e1938e172e6f5a48eb353b0cb678b31f43d
Author: Jean-Marc Lasgouttes 
Date:   Mon Sep 25 12:28:01 2023 +0200

Revert "Avoid row breaking at inconvenient places."

The solution did create new issues.

Fixes bug #12899.
Unfixes bug #12660.

This reverts commit f7de345f85b4a34346fc52b60a9e754b466d24f0.
---
 src/Row.cpp |   27 ---
 1 files changed, 4 insertions(+), 23 deletions(-)

diff --git a/src/Row.cpp b/src/Row.cpp
index a7f09e5..a7f00d5 100644
--- a/src/Row.cpp
+++ b/src/Row.cpp
@@ -602,31 +602,12 @@ Row::Elements Row::shortenIfNeeded(int const max_width, 
int const next_width)
 */
if (brk.splitAt(min(max_width - wid_brk, brk.dim.wid - 2), 
next_width, false, tail)) {
/* if this element originally did not cause a row 
overflow
-* in itself, and the next item is not breakable and 
would
-* still be too large after breaking, then we will have
-* issues in next row. Thus breaking does not help.
-*
-* FIXME: this is not perfect, since it is difficult to
-* know whether next element in tail is too large:
-*
-* - next element could be a very long word, which is
-*   theoretically breakable, but not in practice
-*   (difficult to solve).
-*
-* - next element could be short enough, but linked to
-*   another one with a NoBreak bond.
-*
-* Basically, it is difficult to solve that in a purely
-* left-to-right algorithm; implementing the TeX badness
-* algorithm is more difficult and more costly, so we do
-* our best in our restricted setting.
+* in itself, and the remainder of the row would still 
be
+* too large after breaking, then we will have issues in
+* next row. Thus breaking does not help.
 */
-   auto const cit_next = cit_brk + 1;
-   int const tail_wid = !tail.empty() ? 
tail.front().dim.wid : 0;
if (wid_brk + cit_brk->dim.wid < max_width
-   && cit_next != elements_.end()
-   && tail_wid + cit_next->dim.wid > next_width
-   && !(cit_next->row_flags & CanBreakInside)) {
+   && dim_.wid - (wid_brk + brk.dim.wid) >= 
next_width) {
tail.clear();
break;
}
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs