123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- #!/usr/bin/ruby
- # Author: Daniel "Trizen" Șuteu
- # License: GPLv3
- # Date: 15th October 2013
- # Translated to Sidef in 17 June 2015
- # https://trizenx.blogspot.com
- # Smart word wrap algorithm
- # See: https://en.wikipedia.org/wiki/Word_wrap#Minimum_raggedness
- # Review: https://trizenx.blogspot.ro/2013/11/smart-word-wrap.html
- class SmartWordWrap(WIDTH=80) {
- method prepare_words(array) {
- var root = [];
- var len = 0;
- for (var i = 0 ; i <= array.end ; i++) {
- var word_len = array[i].len;
- len += word_len;
- len > WIDTH && (
- word_len > WIDTH && (
- len -= word_len;
- array.splice(i, 1, array[i].split(WIDTH)...);
- --i; next;
- );
- break;
- );
- root.append(Hash.new(array.ft(0, i).join(" ")
- => self.prepare_words(array.ft(i + 1, array.end))));
- ++len >= WIDTH && break;
- }
- root ? root : null;
- }
- method combine(root, hash) {
- var row = [];
- hash.each { |key, value|
- root.append(key);
- if (value.is_an(Array)) {
- value.each { |item|
- row.append(self.combine(root, item)...);
- }
- }
- else {
- row = [[root...]];
- }
- root.pop;
- }
- row;
- }
- method find_best(arrays) {
- var best = Hash.new(
- score => Inf,
- value => [],
- );
- arrays.each { |array_ref|
- var score = 0;
- array_ref.each { |string|
- score += ::pow(WIDTH - string.len, 2);
- }
- score < best{:score} && (
- best{:score} = score;
- best{:value} = array_ref;
- );
- }
- best{:value};
- }
- method wrap(text, width) {
- # Temporarily modify the width
- local WIDTH = width if defined(width);
- # Split the text into words
- text.is_a(String) && text.words!;
- var lines = [];
- self.prepare_words(text).each { |path|
- lines.append(self.combine([], path)...);
- }
- self.find_best(lines).join("\n");
- }
- }
- var sww = SmartWordWrap();
- var words = %w(aaa bb cc ddddd);
- #var words = %w(Lorem ipsum dolor sit amet, consectetur adipiscing elit.);
- var wrapped = sww.wrap(words, 6);
- say wrapped;
- wrapped == ['aaa', 'bb cc', 'ddddd'].join("\n") || die "error!";
|