-
Notifications
You must be signed in to change notification settings - Fork 16
/
wrap-text
executable file
·95 lines (74 loc) · 2.86 KB
/
wrap-text
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#!/usr/bin/env ruby
#
# Performs word wrapping for the input given on STDIN,
# with smarter handling of crown margins than `fmt -c`.
#
# The first word (a sequence of printable, non-whitespace characters:
# /\S+/) of a paragraph (a sequence delimited by two newline
# characters with optional whitespace between them: /\r?\n\s*\r?\n/)
# is considered to be a crown if (1) it contains a punctuation mark:
# /[[:punct:]]/ or (2) it is entirely composed of whitespace: /\s+/.
#
# Written in 2007 by Suraj N. Kurapati <https://github.com/sunaku>
require File.join(File.dirname(__FILE__), 'wrap')
def wrap_line line, width, two_space, wrapper = :wrap
line = line.sub(/^(\r?\n)+/, '')
# determine crown and margin
line =~ /^(\s*)(\S*\s*)/
margin = $1.to_s
crown = $2.to_s
rest = $'.to_s
if crown =~ /[[:punct:]]/ && crown !~ /,\s*/
line = rest
else
crown = ''
end
crown = margin + crown
margin = crown.gsub(/\S/, ' ')
# wrap the input in isolation
line.gsub! /\r?\n/, ' '
line.squeeze! ' '
line.gsub! %r/([.?!])(?![[:graph:]])/, '\1 ' if two_space
lines = Array(line.send(wrapper, width - margin.length))
# add crown and margin to result
unless lines.empty?
lines.first.insert(0, crown)
end
lines.join("\n" + margin)
end
def wrap_text text, width, selector, rejector, refill, balanced, two_space
delim = refill ? /\r?\n\s*\r?\n/ : /\r?\n/
newline = refill ? "\n\n" : "\n"
wrapper = balanced ? :balanced_wrap : :wrap
text.split(delim).map do |line|
if line =~ selector and line !~ rejector
wrap_line(line, width, two_space, wrapper)
else
line
end
end.flatten.compact.join(newline).chomp
end
if $0 == __FILE__
require 'optparse'
parser = OptionParser.new
parser.on '-h', '--help', 'show this help message' do
puts File.read(__FILE__).split(/^$/).first, nil, parser
exit
end
parser.on '-w', '--width WIDTH', 'maximum line width',
"(default: #{width = 80})", Integer do |arg| width = arg end
parser.on '-s', '--split-only', 'split long lines, but do not refill',
"(default: #{split = false})" do |arg| split = arg end
parser.on '-2', '--two-space', 'two spaces after sentences',
"(default: #{two_space = false})" do |arg| two_space = arg end
parser.on '-b', '--balance', 'prefer equal line widths',
"(default: #{balanced = false})" do |arg| balanced = arg end
parser.on '-m', '--select REGEXP', 'only wrap lines that match REGEXP',
"(default: #{(selector = //).inspect})",
Regexp do |arg| selector = arg end
parser.on '-M', '--reject REGEXP', 'do not wrap lines that match REGEXP',
"(default: #{(rejector = nil).inspect})",
Regexp do |arg| rejector = arg end
parser.parse ARGV
puts wrap_text(STDIN.read, width, selector, rejector, !split, balanced, two_space)
end