"trans. (T. Onoma)" <transami@runbox.com> schrieb im Newsbeitrag
news:200412131012.46675.transami@runbox.com...
P.S. Does anyone have a really good String#word_wrap method? I wrote one
but
it isn't so good b/c it strip newlines.
What about
class String
def word_wrap!(n = 80)
raise ArgumentError, "Wrap margin too low: #{n}" if n <= 2
gsub!( Regexp.new( "(.{1,#{n-1}}\\w)\\b\\s*" ), "\\1\n")
end
def word_wrap(n = 80)
c = dup
c.word_wrap! n
c
end
end
class Array
def each_combination(k)
n = self.size
return unless (1..n) === k
idx = (0...k).to_a
loop do
yield self.values_at(*idx)
i = k - 1
i -= 1 while idx[i] == n - k + i
break if i < 0
idx[i] += 1
(i + 1 ... k).each {|j| idx[j] = idx[i] + j - i}
end
end
end
a = %w|a b c d e|
n = 3
a.each_combination(3) do |c|
p c
end
regards,
andrew
···
On Tue, 14 Dec 2004 00:12:50 +0900, trans. (T. Onoma) <transami@runbox.com> wrote:
Thanks, robert. That's a nice basic approach, and for the lack of something
better I think I will used. But it would be nice to have something a little
more robust. Something that can determine when to divide and hyphenate a word
if it is just too long.
Like I said, mine is far from perfect but I'll show it anyway:
def word_wrap(max_width=nil, margin=6)
max_width ||= 80
max_width -= 1
min_width = max_width - margin
blocks = ; scan(/(.*)(\n\s+\n|\Z)/m){ blocks << $~ }
complete = ''
blocks.each{ |block|
str = ''; line = ''
body = block[1].gsub(/\s+/, ' ')
padding = block[2].to_s
words = body.split(/\s+/)
i = 0
words.each { |word|
line << word
while line.length > max_width
clean_break = line.index(/\s\S*?$/)
clean_break = 0 unless clean_break
if clean_break < min_width
remaining = line[max_width..-1]
str << line.slice(0,max_width)
str << '-' if /^[a-zA-Z0-9]/ =~ remaining
str << "\n"
line = line[max_width..-1]
else
str << line.slice(0,clean_break)
str << " \n"
line = line[(clean_break + 1)..-1]
end
end
line << ' '
}
str << line.chomp(' ')
complete << str << padding
}
complete << "\n"
end
I never realized how complex something seemingly so simple could be.
Thanks,
T.
···
On Monday 13 December 2004 10:37 am, Robert Klemme wrote:
What about
class String
def word_wrap!(n = 80)
raise ArgumentError, "Wrap margin too low: #{n}" if n <= 2
gsub!( Regexp.new( "(.{1,#{n-1}}\\w)\\b\\s*" ), "\\1\n")
end
def word_wrap(n = 80)
c = dup
c.word_wrap! n
c
end
end
Perfect. Thanks. Think #each_combination is best name?
T.
···
On Monday 13 December 2004 04:12 pm, Andrew Johnson wrote:
One way:
class Array
def each_combination(k)
n = self.size
return unless (1..n) === k
idx = (0...k).to_a
loop do
yield self.values_at(*idx)
i = k - 1
i -= 1 while idx[i] == n - k + i
break if i < 0
idx[i] += 1
(i + 1 ... k).each {|j| idx[j] = idx[i] + j - i}
end
end
end
a = %w|a b c d e|
n = 3
a.each_combination(3) do |c|
p c
end
On Monday 13 December 2004 10:37 am, Robert Klemme wrote:
> What about
>
> class String
> def word_wrap!(n = 80)
> raise ArgumentError, "Wrap margin too low: #{n}" if n <= 2
> gsub!( Regexp.new( "(.{1,#{n-1}}\\w)\\b\\s*" ), "\\1\n")
> end
>
> def word_wrap(n = 80)
> c = dup
> c.word_wrap! n
> c
> end
> end
Thanks, robert. That's a nice basic approach, and for the lack of something
better I think I will used. But it would be nice to have something a little
more robust. Something that can determine when to divide and hyphenate a word
if it is just too long.
Austin Ziegler is working on an interface to TeX's hyphenation
facilities. I'm not sure where it stands, but we were talking about
it last week and it sounded cool.
"trans. (T. Onoma)" <transami@runbox.com> schrieb im Newsbeitrag news:200412131056.58363.transami@runbox.com...
> What about
>
> class String
> def word_wrap!(n = 80)
> raise ArgumentError, "Wrap margin too low: #{n}" if n <= 2
> gsub!( Regexp.new( "(.{1,#{n-1}}\\w)\\b\\s*" ), "\\1\n")
> end
>
> def word_wrap(n = 80)
> c = dup
> c.word_wrap! n
> c
> end
> end
Thanks, robert.
You're welcome.
That's a nice basic approach, and for the lack of something
better I think I will used. But it would be nice to have something a little
more robust. Something that can determine when to divide and hyphenate a word
if it is just too long.
Err, that plays in a whole different league...
Like I said, mine is far from perfect but I'll show it anyway:
def word_wrap(max_width=nil, margin=6)
max_width ||= 80
max_width -= 1
min_width = max_width - margin
blocks = ; scan(/(.*)(\n\s+\n|\Z)/m){ blocks << $~ }
complete = ''
blocks.each{ |block|
str = ''; line = ''
body = block[1].gsub(/\s+/, ' ')
padding = block[2].to_s
words = body.split(/\s+/)
i = 0
words.each { |word|
line << word
while line.length > max_width
clean_break = line.index(/\s\S*?$/)
clean_break = 0 unless clean_break
if clean_break < min_width
remaining = line[max_width..-1]
str << line.slice(0,max_width)
str << '-' if /^[a-zA-Z0-9]/ =~ remaining
str << "\n"
line = line[max_width..-1]
else
str << line.slice(0,clean_break)
str << " \n"
line = line[(clean_break + 1)..-1]
end
end
line << ' '
}
str << line.chomp(' ')
complete << str << padding
}
complete << "\n"
end
Ah, you use a margin to determine min line length. That makes things a bit more complicated of course.
I never realized how complex something seemingly so simple could be.
I guess, that's because of the complexity of our language (no, not Ruby).
Kind regards
robert
···
On Monday 13 December 2004 10:37 am, Robert Klemme wrote:
Minor correction. TeX::Hyphen already does this, but it only works
with English hyphenation and standard "czech" substitution. I would
not trust it with any other language, which is why I'm working on
Text::Hyphen. Martin DeMello ported TeX::Hyphen from the Perl
version and it works incredibly well.
Text::Format can use TeX::Hyphen as a plugin, so formatting can
happen with hyphenation.
I am in the process of reworking the architecture of TeX::Hyphen
(the algorithm is not going to change; this simply WORKS!) and it
will better support a wide variety of languages. I have converted 16
of 42 TeX hyphenation files to the new Text::Hyphen format that will
be used for languages. After I finish Text::Hyphen (this weekend?) I
will be revisiting Text::Format. Because I am changing the
initialization API with no backwards compatibility, I will be
renaming Text::Format to Text::Formatter and bumping the version to
1.0. After this, I will be working on Ruwiki and Diff::LCS again,
but I will be open to new features for Text::Formatter.
The algorithm behind Text::Formatter is extgensive; I highly
recommend using this instead of trying to write your own.
-austin
···
On Tue, 14 Dec 2004 01:05:45 +0900, David A. Black <dblack@wobblini.net> wrote:
On Tue, 14 Dec 2004, trans. (T. Onoma) wrote:
On Monday 13 December 2004 10:37 am, Robert Klemme wrote:
What about
class String
def word_wrap!(n = 80)
raise ArgumentError, "Wrap margin too low: #{n}" if n <= 2
gsub!( Regexp.new( "(.{1,#{n-1}}\\w)\\b\\s*" ), "\\1\n")
end
def word_wrap(n = 80)
c = dup
c.word_wrap! n
c
end
end
Thanks, robert. That's a nice basic approach, and for the lack of
something better I think I will used. But it would be nice to
have something a little more robust. Something that can determine
when to divide and hyphenate a word if it is just too long.
Austin Ziegler is working on an interface to TeX's hyphenation
facilities. I'm not sure where it stands, but we were talking
about it last week and it sounded cool.