expandtabs 
Author Message
 expandtabs

Saluton!

* Steven Shaw, 2003-05-30, 21:05 UTC:

Quote:
> The methods for expanding tabs in the Ruby FAQ don't seem to work.
> def method1(a)
>   1 while a.sub!(/(^[^\t]*)\t(\t*)/){$1+' '*(8-$1.size%8+8*$2.size)}
>   a
> end

> def method2(a)
>   1 while a.sub!(/\t(\t*)/){' '*(8-$~.begin(0)%8+8*$1.size)}
>   a
> end

> def method3(a)
>   a.gsub!(/([^\t]{8})|([^\t]*)\t/n){[$+].pack("A8")}
>   a
> end

> def println(s)
>   print s, "\n"
> end

> string = ""
> (0..10).each {|n|
>   string << "blah\t" + (" " * n) + "blah\n"
> }

> println(method1(string.clone))
> println(method2(string.clone))
> println(method3(string.clone))

I did already answer that in a PM. The above works correct but does
not have the intended result. The problem is that the sample string
does contain "\n" characters.

The easiest solution would be using

string.split("\n").each{|x| println(method1(x))}
string.split("\n").each{|x| println(method2(x))}
string.split("\n").each{|x| println(method3(x))}

in place of the  given calls of println. Nevertheless it would be
better to reset the length counting for each "\n". The following is a
quick'n'dirty hack that does this in a way that is far from optimal.

def method4(a)
  b = ''
  l = 1
  0.upto(a.length) { |i|
    case a[i]
      when 9
        b += ' '
        l += 1
        while l % 8 != 0
          b += ' '
          l += 1
        end
      when 10
        b += a[i..i]
        l = 1
      else
        b += a[i..i]
        l += 1
    end
  }
  return b
end

A shorter solution is:

def method1(a)
  a.split("\n").each {|b|
    1 while b.sub!(/(^[^\t]*)\t(\t*)/){$1+' '*(8-$1.size%8+8*$2.size)}
    b
  }.join("\n")
end

The equivalents for method2 and method3 are obvious. Does anybody
have a better solution that does not require splitting and re-joining
(which is time-consuming)?

Gis,

Josef 'Jupp' Schugt
--
e-mails that do not contain plain text, are larger than 50 KiB, are
unsolicited, or contain binarys are ignored unless payment from your
side or technical reasons give rise to a non-standard treatment.
Schroedinger's cat is <blink>not</blink> alive.



Thu, 17 Nov 2005 03:04:51 GMT  
 expandtabs

Quote:

> The equivalents for method2 and method3 are obvious. Does anybody
> have a better solution that does not require splitting and re-joining
> (which is time-consuming)?

How about this:

def expand_tabs(data, indent=8)
    x = 0
    i = 0
    while i < data.length
        case data[i]
        when 9
            add = indent - (x % indent)
            data[i..i] = '.'*add
            x += add
            i += add
        when 10
            x = 0
            i += 1
        else
            x += 1
            i += 1
        end
    end
    data
end
text = <<TXT
a
1       b
12      4       c
123                     d
                e
        f
g
TXT
expand_tabs(text)
puts text

--
Simon Strandgaard



Thu, 17 Nov 2005 03:46:33 GMT  
 expandtabs
When expanding a tab I guess you are actually interested in the number of
characters since the previous tab or newline, so how about something like:

def expand_tabs(data, indent=8)
  data.gsub(/([^\t\n]*)\t/) {
    $1 + " " * (indent - ($1.size % indent))
  }
end

Anybody have a test suite?

Regards,

Brian.



Thu, 17 Nov 2005 04:35:31 GMT  
 expandtabs

Quote:
> Anybody have a test suite?

No but here's the test script I've been using. It has all the different
methods from the FAQ and the ones posted here. Your method works on my test
data.

def method1(s)
  def sub_line(a)
    1 while a.sub!(/(^[^\t]*)\t(\t*)/){$1+' '*(8-$1.size%8+8*$2.size)}
    a
  end

  result = ""
  s.each { |line| result << sub_line(line) }
  result
end

def method2(s)
  def sub_line(a)
    1 while a.sub!(/\t(\t*)/){' '*(8-$~.begin(0)%8+8*$1.size)}
    a
  end

  result = ""
  s.each { | line | result << sub_line(line) }
  result
end

def method3(s)
  def sub_line(a)
    a.gsub!(/([^\t]{8})|([^\t]*)\t/n){[$+].pack("A8")}
    a
  end

  result = ""
  s.each { | line | result << sub_line(line) }
  result
end

def method4(a)
  b = ''
  l = 1
  0.upto(a.length) { |i|
    case a[i]
    when 9
      b += ' '
      l += 1
      while l % 8 != 0
        b += ' '
        l += 1
      end
    when 10
      b += a[i..i]
      l = 1
    else
      b += a[i..i]
      l += 1
    end
  }
  return b
end

def method5(data, indent=8)
    x = 0
    i = 0
    while i < data.length
        case data[i]
        when 9
            add = indent - (x % indent)
            data[i..i] = ' '*add
            x += add
            i += add
        when 10
            x = 0
            i += 1
        else
            x += 1
            i += 1
        end
    end
    data
end

def method6(data, indent=8)
  data.gsub(/([^\t\n]*)\t/) {
    $1 + " " * (indent - ($1.size % indent))
  }
end

def println(*s)
  print s, "\n"
end

string = ""
(0..10).each {|n|
  string << "blah\t" + (" " * n) + "blah\n"

Quote:
}

(0..10).each {|n|
  string << "blah" + (" " * n) + "\tblah\n"

Quote:
}

println "-- original string"
println(string)

# construct correct answer from method1
$correct = method1(string.clone)

def test_it(result)
  print result
  if result == $correct
    println "result is correct"
  else
    println "result in incorrect"
  end
  println
end

println "-- method2"
test_it(method2(string.clone))

println "-- method3"
test_it(method3(string.clone))

println "-- method4"
test_it(method4(string.clone))

println "-- method5"
test_it(method5(string.clone))

println "-- method6"
test_it(method6(string.clone))

Sorry about my code. I'm just learning Ruby. What's the opposite of split?



Fri, 18 Nov 2005 18:07:08 GMT  
 expandtabs
Saluton!

* Steven Shaw; 2003-06-02, 11:02 UTC:

Quote:
> What's the opposite of split?

join:

ruby -e 'p ["a", "b"].join'
"ab"

ruby -e 'p ["a", "b"].join("\n")'
"a\nb"

ruby -e '$, = "\n";p ["a", "b"].join'
"a\nb"

HTH

Gis,

Josef 'Jupp' Schugt
--
e-mails that do not contain plain text, are larger than 50 KiB, are
unsolicited, or contain binarys are ignored unless payment from your
side or technical reasons give rise to a non-standard treatment.
Schroedinger's cat is <blink>not</blink> alive.



Sat, 19 Nov 2005 00:32:24 GMT  
 
 [ 5 post ] 

 Relevant Pages 
 

 
Powered by phpBB® Forum Software