bug-texinfo
[Top][All Lists]
Advanced

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

protection of space inside @w is wrong


From: Gavin Smith
Subject: protection of space inside @w is wrong
Date: Thu, 20 Oct 2022 19:39:51 +0100

It came up by accident in the other discussion that the treatment
of multiple spaces inside @w is inconsistent between texinfo.tex and
texi2any.

@w has a very simple implementation in texinfo.tex - it
puts the contents into an \hbox, which stops line break.

In texi2any, as well as stopping line breaks, multiple spaces are
protected, so @w{a  b} outputs as 'a  b' not 'a b'.

(However, I checked that in contexts where you would like multiple spaces
to be protected, like @samp{a  b}, this doesn't happen.)

I think texi2any should follow what texinfo.tex does.

I've got code written for this (at bottom of mail).  However, since this
is quite a major change to what @w does, and stems from confusion and/or
disagreement about the purpose of @w, and since it is does not appear to
be causing any problems for anybody at the moment, I propose that this
change (and any others for @samp, @code etc.) be delayed until after the
Texinfo 7.0 release.


diff --git a/tp/Texinfo/Convert/ParagraphNonXS.pm 
b/tp/Texinfo/Convert/ParagraphNonXS.pm
index 1cb442846b..b947fb675e 100644
--- a/tp/Texinfo/Convert/ParagraphNonXS.pm
+++ b/tp/Texinfo/Convert/ParagraphNonXS.pm
@@ -330,17 +330,19 @@ sub add_text($$)
       print STDERR "SPACES($paragraph->{'counter'}) `"
           ._print_escaped_spaces($spaces)."'\n" if $debug_flag;
       if ($protect_spaces_flag) {
-        $paragraph->{'word'} .= $spaces;
-        $paragraph->{'last_char'} = substr($spaces, -1);
-        $paragraph->{'word_counter'} += length($spaces);
-        $paragraph->{'word'} =~ s/\n/ /g;
-
-        # The $paragraph->{'counter'} != 0 is here to avoid having an
-        # additional line output when the text is longer than the max.
-        if ($paragraph->{'counter'} != 0 and 
-            $paragraph->{'counter'} + $paragraph->{'word_counter'} + 
-               length($paragraph->{'space'}) > $paragraph->{'max'}) {
-          $result .= _cut_line($paragraph);
+        if ($paragraph->{'word'} !~ /\s$/) {
+          $paragraph->{'word'} .= substr($spaces, 0,  1);
+          $paragraph->{'last_char'} = substr($spaces, 0, 1);
+          $paragraph->{'word_counter'}++;
+          $paragraph->{'word'} =~ s/\n/ /g;
+
+          # The $paragraph->{'counter'} != 0 is here to avoid having an
+          # additional line output when the text is longer than the max.
+          if ($paragraph->{'counter'} != 0 and 
+              $paragraph->{'counter'} + $paragraph->{'word_counter'} + 
+                 length($paragraph->{'space'}) > $paragraph->{'max'}) {
+            $result .= _cut_line($paragraph);
+          }
         }
       } else {
         my $pending_word = $paragraph->{'word'};
diff --git a/tp/Texinfo/XS/xspara.c b/tp/Texinfo/XS/xspara.c
index bf4ef91650..8dfff95f98 100644
--- a/tp/Texinfo/XS/xspara.c
+++ b/tp/Texinfo/XS/xspara.c
@@ -845,29 +845,23 @@ xspara_add_text (char *text)
           /* If protect_spaces is on, ... */
           if (state.protect_spaces)
             {
-              /* Append the spaces to the pending word. */
-              text_append_n (&state.word, p, char_len);
-              state.word_counter++;
-
-              if (strchr (state.word.text, '\n'))
+              if (state.word.end == 0 || !isspace
+                    ((unsigned char) state.word.text[state.word.end - 1]))
                 {
-                  /* Replace any '\n' with a ' '. Note that state.word_counter 
-                     will still be correct after this. */
-                  char *ptr = state.word.text;
-                  while (*ptr)
+                  state.last_letter = L' ';
+                  /* Append the spaces to the pending word. */
+                  if (*p == '\n')
+                    text_append_n (&state.word, " ", 1);
+                  else
+                    text_append_n (&state.word, p, 1);
+                  state.word_counter++;
+
+                  if (state.counter != 0 && state.counter
+                      + state.word_counter + state.space_counter > state.max)
                     {
-                      if (*ptr == '\n')
-                        *ptr = ' ';
-                      ptr++;
+                      xspara__cut_line (&result);
                     }
                 }
-
-              if (state.counter != 0
-                  && state.counter + state.word_counter + state.space_counter
-                     > state.max)
-                {
-                  xspara__cut_line (&result);
-                }
             }
           else /* protect_spaces off */
             {





reply via email to

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