#!/usr/bin/ruby # Author: Daniel "Trizen" Șuteu # License: GPLv3 # Date: 15th October 2013 # Translated to Sidef in 17 June 2015 # http://trizenx.blogspot.com # Email: <echo dHJpemVueEBnbWFpbC5jb20K | base64 -d> # Smart word wrap algorithm # See: http://en.wikipedia.org/wiki/Word_wrap#Minimum_raggedness # Review: http://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!";