groff-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[groff] 09/10: [man]: Abbreviate TH arguments more carefully.


From: G. Branden Robinson
Subject: [groff] 09/10: [man]: Abbreviate TH arguments more carefully.
Date: Thu, 7 Apr 2022 19:03:11 -0400 (EDT)

gbranden pushed a commit to branch master
in repository groff.

commit 223814d9c217a8ac137e9e521297377572e31526
Author: G. Branden Robinson <g.branden.robinson@gmail.com>
AuthorDate: Fri Apr 8 07:48:45 2022 +1000

    [man]: Abbreviate TH arguments more carefully.
    
    * tmac/an.tmac: Do it.
    
      (an*scan-string-for-backslash): Add new helper macro.
    
      (an*abbreviate-inner-footer): Rewrite.  Use the foregoing and a
      different technique to compute available space and shorten the string.
      So that we don't break the inner footer in the middle of an escape
      sequence, just trim characters from the end.
    
    Fixes <https://savannah.gnu.org/bugs/?62257>.
---
 ChangeLog                                        |  13 +++
 tmac/an.tmac                                     | 118 +++++++++++++----------
 tmac/tests/an_inner-footer-abbreviation-works.sh |   2 +-
 3 files changed, 81 insertions(+), 52 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 39b19221..1fb95937 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2022-04-08  G. Branden Robinson <g.branden.robinson@gmail.com>
+
+       [man]: Abbreviate long `TH` arguments more carefully.
+
+       * tmac/an.tmac: Do it.
+       (an*scan-string-for-backslash): Add new helper macro.
+       (an*abbreviate-inner-footer): Rewrite.  Use the foregoing and a
+       different technique to compute available space and shorten the
+       string.  So that we don't break the inner footer in the middle
+       of an escape sequence, just trim characters from the end.
+
+       Fixes <https://savannah.gnu.org/bugs/?62257>.
+
 2022-04-08  G. Branden Robinson <g.branden.robinson@gmail.com>
 
        [man]: Add regression test for Savannah #62257.
diff --git a/tmac/an.tmac b/tmac/an.tmac
index 26ff1643..e2a9785c 100644
--- a/tmac/an.tmac
+++ b/tmac/an.tmac
@@ -477,65 +477,81 @@
 .  rm an-ellipsis
 ..
 .
+.\" Iterate through concatenation of arguments as a string.  If a bare
+.\" backslash is found, make `an*string-contains-backslash` true.  Our
+.\" caller should delete this register when done with it.
+.de an*scan-string-for-backslash
+.  nr an*string-contains-backslash 0
+.  ds an*string \\$*
+.  nr an*index 0
+.  length an*max-index \\$*
+.  while (\\n[an*index] < \\n[an*max-index]) \{\
+.    ds an*char \\*[an*string]
+.    substring an*char \\n[an*index] \\n[an*index]
+.    ec @
+.    \" Use a weird delimiter to reduce lexical colorizer confusion.
+.    if _@*[an*char]_\\_ .nr an*string-contains-backslash 1
+.    ec
+.    if \\n[an*string-contains-backslash] .break
+.    nr an*index +1
+.  \}
+.  rm an*char
+.  rr an*max-index
+.  rr an*index
+..
+.
 .\" Abbreviate the `an-extra2` string (set by .TH) if it's too long for
 .\" the footer.  By default, `an-extra2` is placed as the inner footer.
 .\" We call it `an*ifoot` here and leave it defined for .BT use.
+.\" (`an*ofoot` is not treated the same way; it is regenerated by
+.\" `an-footer` on every page because it may have a page number in it,
+.\" which frequently changes.)
 .\"
-.\" The method here differs from an*abbreviate-page-title, because the
-.\" (default) header is symmetrical, with `an-pageref` on both sides,
-.\" whereas the (default) footer is not.  Our approach is to chop
-.\" `an-extra1` (the default center footer) in half and ensure that the
-.\" formatted `an*ifoot` plus that is less than half the title length.
+.\" Shorten the inner footer if necessary by trimming characters off the
+.\" end and replacing them with an ellipsis.  We don't yet know if the
+.\" outer footer will be a page number (short) or the page reference
+.\" (potentially long), so we take a pessimistic approach and assume the
+.\" latter.  The page title, `an-pageref`, must already be prepared.
 .de an*abbreviate-inner-footer
-.  ds an-half-cfoot \\*[an-extra1]\"
-.  length an-half-cfoot-length \\*[an-half-cfoot]
-.  if \\n[an-half-cfoot-length] \{\
-.    nr an-half-cfoot-length (\\n[an-half-cfoot-length] / 2u)
-.    substring an-half-cfoot 0 \\n[an-half-cfoot-length]
-.  \}
-.  rr an-half-cfoot-length
 .  ds an*ifoot \\*[an-extra2]\"
-.  nr an-half-title-width (\\n[.lt] / 2u)
-.  nr an-half-footer-width \\w'\\*[an*ifoot]\\*[an-half-cfoot]'
-.  \" If abbreviation is not necessary, skip the remaining work.
-.  if (\\n[an-half-footer-width] <= \\n[an-half-title-width]) .return
-.  ds an-ellipsis \|.\|.\|.\|\"
-.  \" Now divide the inner footer in half.
-.  length an*ifoot-length \\*[an*ifoot]
-.  nr an-mark1 (\\n[an*ifoot-length] / 2)
-.  nr an-mark2 (\\n[an*ifoot-length] / 2 + 1)
-.  rr an*ifoot-length
-.  ds an*ifoot-half1 \\*[an*ifoot]\"
-.  ds an*ifoot-half2 \\*[an*ifoot]\"
-.  substring an*ifoot-half1 0 \\n[an-mark1]
-.  substring an*ifoot-half2 \\n[an-mark2] -1
-.  rr an-mark1
-.  rr an-mark2
-.  \" Reduce the two halves until, when rejoined with each other, the
-.  \" ellipsis, and half of the center footer, they fit the half-title.
-.  nr an-half-footer-width \\w'\\*[an*ifoot-half1]\\*[an-ellipsis]\
-\\*[an*ifoot-half2]\\*[an-half-cfoot]'
-.  while (\\n[an-half-footer-width] > \\n[an-half-title-width]) \{\
-.    length an-half1-length \\*[an*ifoot-half1]
-.    length an-half2-length \\*[an*ifoot-half2]
-.    \" Give up if we'd have to trim ifoot's first or last characters.
-.    if ((\\n[an-half1-length] = 1) : (\\n[an-half2-length] = 1)) \
+.  nr an*half-title-width (\\n[.lt] / 2u)
+.  nr an*half-cfoot-width (\w'\\*[an-extra1]' / 2u)
+.  nr an*half-footer-width \
+     (\w'\\*[an*ifoot]' + \\n[an*half-cfoot-width])
+.  if (\\n[an*half-footer-width] < \\n[an*half-title-width]) .return
+.  an*scan-string-for-backslash \\*[an*ifoot]
+.  if \\n[an*string-contains-backslash] \{\
+.    an-warn not abbreviating fourth argument to 'TH' '\\*[an*ifoot]': \
+contains unsupported escape sequence
+.    return
+.  \}
+.  ds an*saved-ifoot \\*[an*ifoot]
+.  ds an*ellipsis \|.\|.\|.\|\"
+.  \" Remeasure with ellipsis added to inner footer so that henceforth,
+.  \" the measured width strictly decreases.
+.  nr an*half-footer-width \
+     (\w'\\*[an*ifoot]\\*[an*ellipsis]' + \\n[an*half-cfoot-width])
+.  nr an*end-index (-2)
+.  while (\\n[an*half-footer-width] >= \\n[an*half-title-width]) \{\
+.    ds an*ifoot \\*[an*saved-ifoot]
+.    substring an*ifoot 0 \\n[an*end-index]
+.    \" Measure the string again and give up if we made no progress.
+.    nr an*new-half-footer-width \
+       (\w'\\*[an*ifoot]\\*[an*ellipsis]' + \\n[an*half-cfoot-width])
+.    ie (\\n[an*new-half-footer-width] >= \\n[an*half-footer-width]) \
 .      break
-.    \" Trim a character from half1's end and half2's beginning.
-.    substring an*ifoot-half1 0 (\\n[an-half1-length] - 2)
-.    substring an*ifoot-half2 2 (\\n[an-half2-length] - 1)
-.    nr an-half-footer-width \\w'\\*[an*ifoot-half1]\\*[an-ellipsis]\
-\\*[an*ifoot-half2]\\*[an-half-cfoot]'
+.    nr an*half-footer-width \\n[an*new-half-footer-width]
+.    nr an*end-index -1
 .  \}
-.  ds an*ifoot \\*[an*ifoot-half1]\\*[an-ellipsis]\\*[an*ifoot-half2]\"
-.  rr an-half1-length
-.  rr an-half2-length
-.  rm an*ifoot-half1
-.  rm an*ifoot-half2
-.  rr an-half-footer-width
-.  rr an-half-title-width
-.  rm an-ellipsis
-.  rm an-half-cfoot
+.  ds an*ifoot \\*[an*ifoot]\\*[an*ellipsis]\"
+.  rr an*end-index
+.  rr an*new-half-footer-width
+.  rm an*ellipsis
+.  rm an*saved-ifoot
+.  rr an*string-contains-backslash
+.  rr an*half-footer-width
+.  rr an*half-cfoot-width
+.  rr an*half-title-width
 ..
 .
 .\" Prepare the header for a page of the document.
diff --git a/tmac/tests/an_inner-footer-abbreviation-works.sh 
b/tmac/tests/an_inner-footer-abbreviation-works.sh
index 26b5ba23..2d16b7d2 100755
--- a/tmac/tests/an_inner-footer-abbreviation-works.sh
+++ b/tmac/tests/an_inner-footer-abbreviation-works.sh
@@ -44,7 +44,7 @@ fi
 
 echo 'testing long inner footer with insufficient space to set it' >&2
 OUTPUT=$(echo "$INPUT" | "$groff" -Tascii -P-cbou -man -rLL=60n)
-PATTERN='groff 1\.23\.0\.\.\.449-84949 +2021-10-26 +foo\(1\)'
+PATTERN='groff 1\.23\.0\.rc1\.1449\.\.\. +2021-10-26 +foo\(1\)'
 
 if ! echo "$OUTPUT" | grep -Eq "$PATTERN"
 then



reply via email to

[Prev in Thread] Current Thread [Next in Thread]