Bug 71194

Summary: Problems in KNode's handling of tabs in quoted text
Product: knode Reporter: nramkumar
Component: generalAssignee: kdepim bugs <kdepim-bugs>
Status: RESOLVED UNMAINTAINED    
Severity: normal    
Priority: NOR    
Version: 0.7.2   
Target Milestone: ---   
Platform: Mandrake RPMs   
OS: Linux   
Latest Commit: Version Fixed In:

Description nramkumar 2003-12-25 00:34:15 UTC
Version:           0.7.2 (using KDE KDE 3.1.3)
Installed from:    Mandrake RPMs
Compiler:          gcc version 3.3.1 (Mandrake Linux 9.2 3.3.1-2mdk) 
OS:          Linux

I think there's a problem with the way KNode handles tabs ('\t') characters
in an original post that is being replied to.  The problem happens when
the "Rewrap quoted text automatically" option is turned on.  What happens
is that:

a) Tabs in the quoted text are not expanded with spaces till the article
is actually posted.  However, the re-flowing of quoted text takes place
before this.

b) More importantly, leading tabs (that is tabs at the start of the line
in the quoted text) are simply dropped.  This is a big issue in newsgroups
where code tends to get posted with tabs being used for intendation.

I think the correct behavior is to expand tabs with spaces before
attempting to re-flow the quoted text.  I think in no instance, we should
allow tab characters to go out as that is bad usenet etiquette.

Therefore, I created and tested the following patch, where I've modified
utilities.cpp, specifially, KNHelper::rewrapStringList, to expand tabs to
spaces before actually re-wrapping the text.  I am pasting this patch
with this bug report.

*** kdenetwork-3.1.4-orig/knode/utilities.cpp   2002-06-04 14:59:17.000000000 -0500
--- kdenetwork-3.1.4/knode/utilities.cpp        2003-12-23 21:12:56.000000000 -0500
***************
*** 402,408 ****
  QString KNHelper::rewrapStringList(QStringList text, int wrapAt, QChar quoteChar, bool stopAtSig, bool alwaysSpace)
  {
    QString quoted, lastPrefix, thisPrefix, leftover, thisLine;
!   int breakPos;

    for(QStringList::Iterator line=text.begin(); line!=text.end(); ++line) {

--- 402,408 ----
  QString KNHelper::rewrapStringList(QStringList text, int wrapAt, QChar quoteChar, bool stopAtSig, bool alwaysSpace)
  {
    QString quoted, lastPrefix, thisPrefix, leftover, thisLine;
!   int breakPos, hadtabs = 0;

    for(QStringList::Iterator line=text.begin(); line!=text.end(); ++line) {

***************
*** 415,427 ****
      else
        thisLine.prepend(quoteChar+' ');

      thisPrefix=QString::null;
      QChar c;
      for(int idx=0; idx<(int)(thisLine.length()); idx++) {
        c=thisLine.at(idx);
!       if( (c==' ') ||
!           (c==quoteChar) || (c=='>') ||(c=='|') || (c==':') || (c=='#') || (c=='[') || (c=='{'))
!         thisPrefix.append(c);
        else
          break;
      }
--- 415,444 ----
      else
        thisLine.prepend(quoteChar+' ');

+     // Replace all tabs with spaces
+     // If line had tabs, we mark that so that
+     // we don't break it later on.
+     int linelen = int(thisLine.length());
+     for ( int idx = 0; idx < linelen; ++idx ) {
+       if ( thisLine[idx] == '\t' ) {
+         QString replacement;
+         int nspaces = (8 - (idx & 7));
+
+         replacement.fill(' ', nspaces);
+         thisLine.replace(idx, 1, replacement);
+         idx     += nspaces - 1;
+         linelen += nspaces;
+         hadtabs  = 1;
+       }
+     }
+
      thisPrefix=QString::null;
      QChar c;
      for(int idx=0; idx<(int)(thisLine.length()); idx++) {
        c=thisLine.at(idx);
!       if( (c==' ') ||
!           (c==quoteChar) || (c=='>') ||(c=='|') || (c==':') || (c=='#') || (c=='[') || (c=='{'))
!         thisPrefix.append(c);
        else
          break;
      }
***************
*** 430,436 ****
      thisLine = thisLine.stripWhiteSpace();

      if(!leftover.isEmpty()) {   // don't break paragraphs, tables and quote levels
!       if(thisLine.isEmpty() || (thisPrefix!=lastPrefix) || thisLine.contains("  ") || thisLine.contains('\t'))
          appendTextWPrefix(quoted, leftover, wrapAt, lastPrefix);
        else
          thisLine.prepend(leftover+" ");
--- 447,453 ----
      thisLine = thisLine.stripWhiteSpace();

      if(!leftover.isEmpty()) {   // don't break paragraphs, tables and quote levels
!       if(hadtabs || thisLine.isEmpty() || (thisPrefix!=lastPrefix) || thisLine.contains("  "))
          appendTextWPrefix(quoted, leftover, wrapAt, lastPrefix);
        else
          thisLine.prepend(leftover+" ");
Comment 1 Faber 2004-01-16 01:35:26 UTC
The problem (without above patch) is still present in my KNode 0.7.6 compiled by source.
Comment 2 Andrew Crouthamel 2018-09-04 18:38:13 UTC
Hello! Sorry to be the bearer of bad news, but this project has been unmaintained for many years so I am closing this bug.