signore 0.0.0 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +2 -0
- data/lib/signore/database.rb +15 -20
- data/lib/signore/executable.rb +28 -14
- data/lib/signore/signature.rb +12 -4
- data/lib/signore.rb +3 -4
- data/signore.gemspec +2 -1
- data/spec/fixtures/signatures.yml +1 -0
- data/spec/signore/database_spec.rb +25 -58
- data/spec/signore/executable_spec.rb +62 -51
- data/spec/signore/signature_spec.rb +52 -16
- data/spec/spec_helper.rb +7 -0
- metadata +19 -12
- data/lib/signore/wrapper.rb +0 -65
- data/spec/fixtures/min_yaml.yml +0 -39
- data/spec/signore/wrapper_spec.rb +0 -15
data/Gemfile.lock
CHANGED
data/lib/signore/database.rb
CHANGED
@@ -2,31 +2,26 @@
|
|
2
2
|
|
3
3
|
module Signore class Database
|
4
4
|
|
5
|
-
def
|
6
|
-
@
|
5
|
+
def initialize path
|
6
|
+
@store = YAML::Store.new path
|
7
7
|
end
|
8
8
|
|
9
|
-
def
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
.shuffle.first
|
9
|
+
def << sig
|
10
|
+
@store.transaction do
|
11
|
+
@store['signatures'] ||= []
|
12
|
+
@store['signatures'] << sig
|
13
|
+
end
|
15
14
|
end
|
16
15
|
|
17
|
-
def
|
18
|
-
|
19
|
-
@db = File.exists?(@path) ? YAML.load_file(@path) : []
|
20
|
-
end
|
21
|
-
|
22
|
-
def self.min_yaml
|
23
|
-
@db.to_yaml.gsub /^ (author|source|subject|tags): !!null \n/, ''
|
24
|
-
end
|
16
|
+
def find opts = {}
|
17
|
+
opts = { tags: [], no_tags: [] }.merge opts
|
25
18
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
19
|
+
@store.transaction true do
|
20
|
+
@store['signatures']
|
21
|
+
.select { |sig| opts[:tags].all? { |tag| sig.tagged_with? tag } }
|
22
|
+
.reject { |sig| opts[:no_tags].any? { |tag| sig.tagged_with? tag } }
|
23
|
+
.shuffle.first
|
24
|
+
end
|
30
25
|
end
|
31
26
|
|
32
27
|
end end
|
data/lib/signore/executable.rb
CHANGED
@@ -2,32 +2,46 @@
|
|
2
2
|
|
3
3
|
module Signore class Executable
|
4
4
|
|
5
|
-
def initialize args = ARGV,
|
5
|
+
def initialize args = ARGV, db_class = Database
|
6
6
|
opts = Trollop.options args do
|
7
|
-
opt :database, 'Location of the signature database', default: (
|
7
|
+
opt :database, 'Location of the signature database', default: ENV.fetch('XDG_DATA_HOME') { File.expand_path '~/.local/share' } + '/signore/signatures.yml'
|
8
8
|
end
|
9
9
|
Trollop.die 'usage: signore prego|pronto [label, …]' unless ['prego', 'pronto'].include? args.first
|
10
|
-
|
10
|
+
|
11
|
+
@db = db_class.new opts[:database]
|
12
|
+
|
11
13
|
@action = args.shift
|
12
|
-
|
14
|
+
|
15
|
+
@no_tags, @tags = args.partition { |tag| tag.start_with? '~' }
|
13
16
|
@no_tags.map! { |tag| tag[1..-1] }
|
14
17
|
end
|
15
18
|
|
16
|
-
def run
|
19
|
+
def run input = $stdin
|
17
20
|
case @action
|
18
21
|
when 'prego'
|
19
|
-
|
22
|
+
sig = @db.find tags: @tags, no_tags: @no_tags
|
20
23
|
when 'pronto'
|
21
|
-
params =
|
22
|
-
output.puts "#{elem}?"
|
23
|
-
value = ''
|
24
|
-
value << input.gets until value.lines.to_a.last == "\n"
|
25
|
-
[elem, value.rstrip]
|
26
|
-
end].delete_if { |elem, value| value.empty? }
|
24
|
+
params = get_params input
|
27
25
|
sig = Signature.new params[:text], params[:author], params[:source], params[:subject], @tags
|
28
|
-
|
29
|
-
output.puts sig.display
|
26
|
+
@db << sig
|
30
27
|
end
|
28
|
+
|
29
|
+
puts sig.to_s
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def get_param param, input
|
35
|
+
puts "#{param}?"
|
36
|
+
value = ''
|
37
|
+
value << input.gets until value.lines.to_a.last == "\n"
|
38
|
+
value.strip
|
39
|
+
end
|
40
|
+
|
41
|
+
def get_params input
|
42
|
+
Hash[[:text, :author, :subject, :source].map do |param|
|
43
|
+
[param, get_param(param, input)]
|
44
|
+
end].reject { |_, value| value.empty? }
|
31
45
|
end
|
32
46
|
|
33
47
|
end end
|
data/lib/signore/signature.rb
CHANGED
@@ -1,13 +1,21 @@
|
|
1
1
|
module Signore class Signature < Struct.new :text, :author, :source, :subject, :tags
|
2
2
|
|
3
|
-
def display
|
4
|
-
Wrapper.new(text, meta).display
|
5
|
-
end
|
6
|
-
|
7
3
|
def tagged_with? tag
|
8
4
|
tags and tags.include? tag
|
9
5
|
end
|
10
6
|
|
7
|
+
def to_s
|
8
|
+
lines = text.split("\n").map { |line| LovelyRufus::Wrapper.new(line).wrapped 80 }
|
9
|
+
|
10
|
+
if meta
|
11
|
+
lines << "[#{meta}]"
|
12
|
+
max = lines.map { |line| line.split "\n" }.flatten.map(&:size).max
|
13
|
+
lines.last.insert 0, ' ' * (max - meta.size - 2)
|
14
|
+
end
|
15
|
+
|
16
|
+
lines.join "\n"
|
17
|
+
end
|
18
|
+
|
11
19
|
private
|
12
20
|
|
13
21
|
def meta
|
data/lib/signore.rb
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
require 'fileutils'
|
2
|
+
require 'lovely-rufus'
|
2
3
|
require 'trollop'
|
3
|
-
require '
|
4
|
-
|
5
|
-
YAML::ENGINE.yamler = 'psych' if defined? Psych
|
4
|
+
require 'psych'
|
5
|
+
require 'yaml/store'
|
6
6
|
|
7
7
|
require_relative 'signore/database'
|
8
8
|
require_relative 'signore/executable'
|
9
9
|
require_relative 'signore/signature'
|
10
|
-
require_relative 'signore/wrapper'
|
data/signore.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |gem|
|
2
2
|
gem.name = 'signore'
|
3
|
-
gem.version = '0.
|
3
|
+
gem.version = '0.1.0'
|
4
4
|
gem.summary = 'signore: an email signature manager/randomiser'
|
5
5
|
gem.homepage = 'http://github.com/chastell/signore'
|
6
6
|
gem.author = 'Piotr Szotkowski'
|
@@ -10,6 +10,7 @@ Gem::Specification.new do |gem|
|
|
10
10
|
gem.executables = Dir['bin/*'].map { |d| d.split '/' }.map &:last
|
11
11
|
gem.test_files = Dir['spec/**/*.rb']
|
12
12
|
|
13
|
+
gem.add_dependency 'lovely-rufus'
|
13
14
|
gem.add_dependency 'trollop'
|
14
15
|
gem.add_development_dependency 'minitest', '>= 2.3'
|
15
16
|
gem.add_development_dependency 'rake'
|
@@ -4,88 +4,55 @@ require_relative '../spec_helper'
|
|
4
4
|
|
5
5
|
module Signore describe Database do
|
6
6
|
|
7
|
-
|
8
|
-
@path = "#{Dir.tmpdir}/#{rand}/signatures.yml"
|
9
|
-
end
|
10
|
-
|
11
|
-
after do
|
12
|
-
FileUtils.rmtree File.dirname @path
|
13
|
-
end
|
14
|
-
|
15
|
-
describe '.db' do
|
16
|
-
|
17
|
-
it 'returns the signature database loaded by .load' do
|
18
|
-
Database.load @path
|
19
|
-
Database.db.must_equal []
|
20
|
-
end
|
21
|
-
|
22
|
-
end
|
23
|
-
|
24
|
-
describe '.find' do
|
7
|
+
describe '#find' do
|
25
8
|
|
26
9
|
before do
|
27
10
|
srand
|
28
|
-
Database.
|
11
|
+
@db = Database.new 'spec/fixtures/signatures.yml'
|
29
12
|
end
|
30
13
|
|
31
14
|
it 'returns a random signature by default' do
|
32
15
|
srand 1981
|
33
|
-
|
16
|
+
@db.find.text.must_equal 'Amateur fighter pilot ignores orders, listens to the voices in his head and slaughters thousands.'
|
34
17
|
srand 1979
|
35
|
-
|
18
|
+
@db.find.text.must_equal 'stay-at-home executives vs. wallstreet dads'
|
36
19
|
end
|
37
20
|
|
38
21
|
it 'returns a random signature if the tags are empty' do
|
39
22
|
srand 2009
|
40
|
-
|
23
|
+
@db.find(tags: []).text.must_equal '// sometimes I believe compiler ignores all my comments'
|
41
24
|
end
|
42
25
|
|
43
26
|
it 'returns a random signature based on provided tags' do
|
44
|
-
|
45
|
-
|
27
|
+
@db.find(tags: ['programming']).text.must_equal '// sometimes I believe compiler ignores all my comments'
|
28
|
+
@db.find(tags: ['work']).text.must_equal 'You do have to be mad to work here, but it doesn’t help.'
|
46
29
|
end
|
47
30
|
|
48
31
|
it 'returns a random signature based on required and forbidden tags' do
|
49
|
-
|
32
|
+
@db.find(tags: ['tech'], no_tags: ['programming', 'security']).text.must_equal 'You do have to be mad to work here, but it doesn’t help.'
|
50
33
|
end
|
51
34
|
|
52
35
|
end
|
53
36
|
|
54
|
-
describe '
|
55
|
-
|
56
|
-
it 'creates an empty signature database if it does not exist, but does not save it' do
|
57
|
-
refute Pathname(@path).exist?
|
58
|
-
Database.load @path
|
59
|
-
Database.db.must_equal []
|
60
|
-
refute Pathname(@path).exist?
|
61
|
-
end
|
62
|
-
|
63
|
-
end
|
64
|
-
|
65
|
-
describe '.save' do
|
37
|
+
describe '#save' do
|
66
38
|
|
67
39
|
it 'saves the provided signature to disk' do
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
tng = " ← space\nthe final\nfrontier"
|
85
|
-
Database.load @path
|
86
|
-
Database.save Signature.new tng
|
87
|
-
Database.load @path
|
88
|
-
Database.find.display.must_equal tng
|
40
|
+
file = Tempfile.new ''
|
41
|
+
db = Database.new file.path
|
42
|
+
sig = Signature.new 'Normaliser Unix c’est comme pasteuriser le camembert.'
|
43
|
+
|
44
|
+
db << sig
|
45
|
+
|
46
|
+
file.read.must_equal <<-END.dedent
|
47
|
+
---
|
48
|
+
signatures:
|
49
|
+
- !ruby/struct:Signore::Signature
|
50
|
+
text: Normaliser Unix c’est comme pasteuriser le camembert.
|
51
|
+
author: !!null
|
52
|
+
source: !!null
|
53
|
+
subject: !!null
|
54
|
+
tags: !!null
|
55
|
+
END
|
89
56
|
end
|
90
57
|
|
91
58
|
end
|
@@ -6,52 +6,39 @@ module Signore describe Executable do
|
|
6
6
|
|
7
7
|
describe '#initialize' do
|
8
8
|
|
9
|
-
before do
|
10
|
-
$stderr = StringIO.new
|
11
|
-
end
|
12
|
-
|
13
|
-
after do
|
14
|
-
$stderr = STDERR
|
15
|
-
end
|
16
|
-
|
17
|
-
def stderr
|
18
|
-
$stderr.rewind
|
19
|
-
$stderr.read
|
20
|
-
end
|
21
|
-
|
22
9
|
it 'prints usage if no command is given' do
|
23
|
-
|
24
|
-
stderr.
|
10
|
+
stderr = capture_io { -> { Executable.new [] }.must_raise SystemExit }.last
|
11
|
+
stderr.must_include 'usage: signore prego|pronto [label, …]'
|
25
12
|
end
|
26
13
|
|
27
14
|
it 'prints usage if a bogus command is given' do
|
28
|
-
|
29
|
-
stderr.
|
15
|
+
stderr = capture_io { -> { Executable.new ['bogus'] }.must_raise SystemExit }.last
|
16
|
+
stderr.must_include 'usage: signore prego|pronto [label, …]'
|
30
17
|
end
|
31
18
|
|
32
19
|
it 'loads the signature database from the specified location' do
|
33
|
-
|
34
|
-
|
35
|
-
Executable.new ['-d', 'signatures.yml', 'prego'],
|
36
|
-
|
20
|
+
db_class = MiniTest::Mock.new
|
21
|
+
db_class.expect :new, nil, ['signatures.yml']
|
22
|
+
Executable.new ['-d', 'signatures.yml', 'prego'], db_class
|
23
|
+
db_class.verify
|
37
24
|
end
|
38
25
|
|
39
26
|
it 'loads the signature database from ~/.local/share/signore/signatures.yml if no location specified' do
|
40
27
|
pending if ENV['XDG_DATA_HOME']
|
41
|
-
|
42
|
-
|
43
|
-
Executable.new ['prego'],
|
44
|
-
|
28
|
+
db_class = MiniTest::Mock.new
|
29
|
+
db_class.expect :new, nil, [File.expand_path('~/.local/share/signore/signatures.yml')]
|
30
|
+
Executable.new ['prego'], db_class
|
31
|
+
db_class.verify
|
45
32
|
end
|
46
33
|
|
47
34
|
it 'loads the signature database from $XDG_DATA_HOME/signore/signatures.yml if $XDG_DATA_HOME is set' do
|
48
35
|
begin
|
49
36
|
orig_data_home = ENV.delete 'XDG_DATA_HOME'
|
50
37
|
ENV['XDG_DATA_HOME'] = Dir.tmpdir
|
51
|
-
|
52
|
-
|
53
|
-
Executable.new ['prego'],
|
54
|
-
|
38
|
+
db_class = MiniTest::Mock.new
|
39
|
+
db_class.expect :new, nil, ["#{ENV['XDG_DATA_HOME']}/signore/signatures.yml"]
|
40
|
+
Executable.new ['prego'], db_class
|
41
|
+
db_class.verify
|
55
42
|
ensure
|
56
43
|
orig_data_home ? ENV['XDG_DATA_HOME'] = orig_data_home : ENV.delete('XDG_DATA_HOME')
|
57
44
|
end
|
@@ -64,15 +51,18 @@ module Signore describe Executable do
|
|
64
51
|
describe 'prego' do
|
65
52
|
|
66
53
|
it 'prints a signature tagged with the provided tags' do
|
67
|
-
Executable.new(['-d', 'spec/fixtures/signatures.yml', 'prego', 'tech', 'programming']).run
|
68
|
-
|
69
|
-
|
54
|
+
stdout = capture_io { Executable.new(['-d', 'spec/fixtures/signatures.yml', 'prego', 'tech', 'programming']).run }.first
|
55
|
+
stdout.must_equal <<-END.dedent
|
56
|
+
// sometimes I believe compiler ignores all my comments
|
57
|
+
END
|
70
58
|
end
|
71
59
|
|
72
60
|
it 'prints a signature based on allowed and forbidden tags' do
|
73
|
-
Executable.new(['-d', 'spec/fixtures/signatures.yml', 'prego', '~programming', 'tech', '~security']).run
|
74
|
-
|
75
|
-
|
61
|
+
stdout = capture_io { Executable.new(['-d', 'spec/fixtures/signatures.yml', 'prego', '~programming', 'tech', '~security']).run }.first
|
62
|
+
stdout.must_equal <<-END.dedent
|
63
|
+
You do have to be mad to work here, but it doesn’t help.
|
64
|
+
[Gary Barnes, asr]
|
65
|
+
END
|
76
66
|
end
|
77
67
|
|
78
68
|
end
|
@@ -80,28 +70,49 @@ module Signore describe Executable do
|
|
80
70
|
describe 'pronto' do
|
81
71
|
|
82
72
|
before do
|
83
|
-
@
|
84
|
-
end
|
85
|
-
|
86
|
-
after do
|
87
|
-
FileUtils.rmtree File.dirname @path
|
73
|
+
@file = Tempfile.new ''
|
88
74
|
end
|
89
75
|
|
90
76
|
it 'asks about signature parts and saves given signature with provided labels' do
|
91
|
-
input = StringIO.new
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
77
|
+
input = StringIO.new <<-END.dedent
|
78
|
+
The Wikipedia page on ADHD is like 20 pages long. That’s just cruel.\n
|
79
|
+
Mark Pilgrim\n\n\n
|
80
|
+
END
|
81
|
+
|
82
|
+
stdout = capture_io { Executable.new(['-d', @file.path, 'pronto', 'Wikipedia', 'ADHD']).run input }.first
|
83
|
+
stdout.must_equal <<-END.dedent
|
84
|
+
text?
|
85
|
+
author?
|
86
|
+
subject?
|
87
|
+
source?
|
88
|
+
The Wikipedia page on ADHD is like 20 pages long. That’s just cruel.
|
89
|
+
[Mark Pilgrim]
|
90
|
+
END
|
91
|
+
|
92
|
+
stdout = capture_io { Executable.new(['-d', @file.path, 'prego', 'Wikipedia', 'ADHD']).run }.first
|
93
|
+
stdout.must_equal <<-END.dedent
|
94
|
+
The Wikipedia page on ADHD is like 20 pages long. That’s just cruel.
|
95
|
+
[Mark Pilgrim]
|
96
|
+
END
|
98
97
|
end
|
99
98
|
|
100
99
|
it 'handles multi-line signatures' do
|
101
|
-
input = StringIO.new
|
102
|
-
|
103
|
-
|
104
|
-
|
100
|
+
input = StringIO.new <<-END.dedent
|
101
|
+
‘I’ve gone through over-stressed to physical exhaustion – what’s next?’
|
102
|
+
‘Tuesday.’\n
|
103
|
+
Simon Burr, Kyle Hearn\n\n\n
|
104
|
+
END
|
105
|
+
|
106
|
+
stdout = capture_io { Executable.new(['-d', @file.path, 'pronto']).run input }.first
|
107
|
+
stdout.must_equal <<-END.dedent
|
108
|
+
text?
|
109
|
+
author?
|
110
|
+
subject?
|
111
|
+
source?
|
112
|
+
‘I’ve gone through over-stressed to physical exhaustion – what’s next?’
|
113
|
+
‘Tuesday.’
|
114
|
+
[Simon Burr, Kyle Hearn]
|
115
|
+
END
|
105
116
|
end
|
106
117
|
|
107
118
|
end
|
@@ -5,32 +5,68 @@ require_relative '../spec_helper'
|
|
5
5
|
module Signore describe Signature do
|
6
6
|
|
7
7
|
before do
|
8
|
-
|
8
|
+
@confusion, @mad, @compiler, @bruce, @dads, @starwars = YAML.load_file('spec/fixtures/signatures.yml')['signatures']
|
9
9
|
end
|
10
10
|
|
11
|
-
describe '#
|
11
|
+
describe '#tagged_with?' do
|
12
12
|
|
13
|
-
it '
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
13
|
+
it 'says whether a tagged signature is tagged with a given tag' do
|
14
|
+
refute @compiler.tagged_with? 'fnord'
|
15
|
+
assert @compiler.tagged_with? 'programming'
|
16
|
+
assert @compiler.tagged_with? 'tech'
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'says that an untagged signature is not tagged with any tag' do
|
20
|
+
refute @dads.tagged_with? 'fnord'
|
20
21
|
end
|
21
22
|
|
22
23
|
end
|
23
24
|
|
24
|
-
describe '#
|
25
|
+
describe '#to_s' do
|
26
|
+
|
27
|
+
it 'returns a signature formatted with meta information (if available)' do
|
28
|
+
@compiler.to_s.must_equal <<-END.dedent.strip
|
29
|
+
// sometimes I believe compiler ignores all my comments
|
30
|
+
END
|
31
|
+
|
32
|
+
@dads.to_s.must_equal <<-END.dedent.strip
|
33
|
+
stay-at-home executives vs. wallstreet dads
|
34
|
+
[kodz]
|
35
|
+
END
|
36
|
+
|
37
|
+
@mad.to_s.must_equal <<-END.dedent.strip
|
38
|
+
You do have to be mad to work here, but it doesn’t help.
|
39
|
+
[Gary Barnes, asr]
|
40
|
+
END
|
41
|
+
|
42
|
+
@bruce.to_s.must_equal <<-END.dedent.strip
|
43
|
+
Bruce Schneier knows Alice and Bob’s shared secret.
|
44
|
+
[Bruce Schneier Facts]
|
45
|
+
END
|
25
46
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
47
|
+
@confusion.to_s.must_equal <<-END.dedent.strip
|
48
|
+
She was good at playing abstract confusion in
|
49
|
+
the same way a midget is good at being short.
|
50
|
+
[Clive James on Marilyn Monroe]
|
51
|
+
END
|
52
|
+
|
53
|
+
@starwars.to_s.must_equal <<-END.dedent.strip
|
54
|
+
Amateur fighter pilot ignores orders, listens to
|
55
|
+
the voices in his head and slaughters thousands.
|
56
|
+
[Star Wars ending explained]
|
57
|
+
END
|
30
58
|
end
|
31
59
|
|
32
|
-
it '
|
33
|
-
|
60
|
+
it 'handles edge cases properly' do
|
61
|
+
class SignatureWithMeta < Signature
|
62
|
+
attr_accessor :meta
|
63
|
+
end
|
64
|
+
|
65
|
+
YAML.load_file('spec/fixtures/wrapper.yml').each do |sample|
|
66
|
+
sig = SignatureWithMeta.new sample[:text]
|
67
|
+
sig.meta = sample[:meta]
|
68
|
+
sig.to_s.must_equal sample[:wrapped]
|
69
|
+
end
|
34
70
|
end
|
35
71
|
|
36
72
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: signore
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,22 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-10-
|
12
|
+
date: 2011-10-15 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: lovely-rufus
|
16
|
+
requirement: &15779140 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *15779140
|
14
25
|
- !ruby/object:Gem::Dependency
|
15
26
|
name: trollop
|
16
|
-
requirement: &
|
27
|
+
requirement: &15778700 !ruby/object:Gem::Requirement
|
17
28
|
none: false
|
18
29
|
requirements:
|
19
30
|
- - ! '>='
|
@@ -21,10 +32,10 @@ dependencies:
|
|
21
32
|
version: '0'
|
22
33
|
type: :runtime
|
23
34
|
prerelease: false
|
24
|
-
version_requirements: *
|
35
|
+
version_requirements: *15778700
|
25
36
|
- !ruby/object:Gem::Dependency
|
26
37
|
name: minitest
|
27
|
-
requirement: &
|
38
|
+
requirement: &15778200 !ruby/object:Gem::Requirement
|
28
39
|
none: false
|
29
40
|
requirements:
|
30
41
|
- - ! '>='
|
@@ -32,10 +43,10 @@ dependencies:
|
|
32
43
|
version: '2.3'
|
33
44
|
type: :development
|
34
45
|
prerelease: false
|
35
|
-
version_requirements: *
|
46
|
+
version_requirements: *15778200
|
36
47
|
- !ruby/object:Gem::Dependency
|
37
48
|
name: rake
|
38
|
-
requirement: &
|
49
|
+
requirement: &15777780 !ruby/object:Gem::Requirement
|
39
50
|
none: false
|
40
51
|
requirements:
|
41
52
|
- - ! '>='
|
@@ -43,7 +54,7 @@ dependencies:
|
|
43
54
|
version: '0'
|
44
55
|
type: :development
|
45
56
|
prerelease: false
|
46
|
-
version_requirements: *
|
57
|
+
version_requirements: *15777780
|
47
58
|
description:
|
48
59
|
email: chastell@chastell.net
|
49
60
|
executables:
|
@@ -62,15 +73,12 @@ files:
|
|
62
73
|
- lib/signore/database.rb
|
63
74
|
- lib/signore/executable.rb
|
64
75
|
- lib/signore/signature.rb
|
65
|
-
- lib/signore/wrapper.rb
|
66
76
|
- signore.gemspec
|
67
|
-
- spec/fixtures/min_yaml.yml
|
68
77
|
- spec/fixtures/signatures.yml
|
69
78
|
- spec/fixtures/wrapper.yml
|
70
79
|
- spec/signore/database_spec.rb
|
71
80
|
- spec/signore/executable_spec.rb
|
72
81
|
- spec/signore/signature_spec.rb
|
73
|
-
- spec/signore/wrapper_spec.rb
|
74
82
|
- spec/spec_helper.rb
|
75
83
|
homepage: http://github.com/chastell/signore
|
76
84
|
licenses: []
|
@@ -100,5 +108,4 @@ test_files:
|
|
100
108
|
- spec/spec_helper.rb
|
101
109
|
- spec/signore/database_spec.rb
|
102
110
|
- spec/signore/signature_spec.rb
|
103
|
-
- spec/signore/wrapper_spec.rb
|
104
111
|
- spec/signore/executable_spec.rb
|
data/lib/signore/wrapper.rb
DELETED
@@ -1,65 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
module Signore class Wrapper
|
4
|
-
|
5
|
-
NBSP = ' '
|
6
|
-
|
7
|
-
def initialize text, meta
|
8
|
-
@lines = text.split "\n"
|
9
|
-
@meta = meta
|
10
|
-
end
|
11
|
-
|
12
|
-
def display
|
13
|
-
wrap
|
14
|
-
add_meta if @meta
|
15
|
-
@lines.join "\n"
|
16
|
-
end
|
17
|
-
|
18
|
-
private
|
19
|
-
|
20
|
-
def add_meta
|
21
|
-
@lines << "[#{@meta}]"
|
22
|
-
@lines.last.insert 0, ' ' * (width - @meta.size - 2)
|
23
|
-
end
|
24
|
-
|
25
|
-
def find_hangout wrapped
|
26
|
-
lines = wrapped.split "\n"
|
27
|
-
lines.each_with_index do |line, nr|
|
28
|
-
space = line.rindex /[ #{NBSP}]/
|
29
|
-
next unless space and nr < lines.size - 1
|
30
|
-
return nr if nr > 0 and space >= lines[nr - 1].size
|
31
|
-
return nr if nr < lines.size - 2 and space >= lines[nr + 1].size
|
32
|
-
return nr if nr < lines.size - 1 and space >= lines[nr + 1].size and lines.size == 2
|
33
|
-
end
|
34
|
-
nil
|
35
|
-
end
|
36
|
-
|
37
|
-
def width
|
38
|
-
@lines.map { |line| line.split "\n" }.flatten.map(&:size).max
|
39
|
-
end
|
40
|
-
|
41
|
-
def wrap
|
42
|
-
@lines.map! do |line|
|
43
|
-
best_wrap = wrap_line_to line, 80
|
44
|
-
79.downto 1 do |size|
|
45
|
-
new_wrap = wrap_line_to line, size
|
46
|
-
break if new_wrap.count("\n") > best_wrap.count("\n")
|
47
|
-
best_wrap = new_wrap
|
48
|
-
end
|
49
|
-
best_wrap.chomp
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def wrap_line_to line, size
|
54
|
-
line = line.gsub(/ ([^ ]) /, " \\1#{NBSP}")
|
55
|
-
line = line.gsub(/(.{1,#{size}})( |$\n?)/, "\\1\n")
|
56
|
-
if hangout = find_hangout(line)
|
57
|
-
lines = line.split "\n"
|
58
|
-
lines[hangout] << NBSP
|
59
|
-
line = lines.join(' ').gsub("#{NBSP} ", NBSP)
|
60
|
-
line = wrap_line_to line, size
|
61
|
-
end
|
62
|
-
line.tr NBSP, ' '
|
63
|
-
end
|
64
|
-
|
65
|
-
end end
|
data/spec/fixtures/min_yaml.yml
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
---
|
2
|
-
- !ruby/struct:Signore::Signature
|
3
|
-
text: Patches are like Free Software love letters.
|
4
|
-
- !ruby/struct:Signore::Signature
|
5
|
-
text: It’s 8:21 AM, do you know where your process is? Call 0-800-GREP to find out
|
6
|
-
more how YOU can prevent zombification.
|
7
|
-
author: opi
|
8
|
-
tags:
|
9
|
-
- programming
|
10
|
-
- Unix
|
11
|
-
- !ruby/struct:Signore::Signature
|
12
|
-
text: ! '‘Humor. It is a difficult concept: It is not logical.’
|
13
|
-
|
14
|
-
‘We learn by doing.’'
|
15
|
-
source: ! 'Star Trek: The Wrath of Khan'
|
16
|
-
- !ruby/struct:Signore::Signature
|
17
|
-
text: In 1940 he summarized his work in an influential book, ‘Punched Card Methods
|
18
|
-
in Scientific Computation’.
|
19
|
-
author: Paul E. Ceruzzi
|
20
|
-
source: A History of Modern Computing
|
21
|
-
subject: on Wallace Eckert
|
22
|
-
- !ruby/struct:Signore::Signature
|
23
|
-
text: ! 'Idea: A James Cameron-directed prequel entitled ''T\0: The Null Terminator''.'
|
24
|
-
author: Matthew Baldwin
|
25
|
-
- !ruby/struct:Signore::Signature
|
26
|
-
text: ! 'The #1 lesson I learned on my one and only trip to the Caribbean is that
|
27
|
-
society will not actually collapse if you walk down a public street with a beer
|
28
|
-
in your hand. Who woulda thunk?'
|
29
|
-
author: J.D. Baldwin
|
30
|
-
- !ruby/struct:Signore::Signature
|
31
|
-
text: '3:10'
|
32
|
-
author: Elmore Leonard
|
33
|
-
- !ruby/struct:Signore::Signature
|
34
|
-
text: ! ' ← space, the final frontier'
|
35
|
-
- !ruby/struct:Signore::Signature
|
36
|
-
text: Just got another wonderful request from the client… you’re going to lie this
|
37
|
-
one.
|
38
|
-
author: Chris Ivens
|
39
|
-
source: ! '#civicrm'
|
@@ -1,15 +0,0 @@
|
|
1
|
-
require_relative '../spec_helper'
|
2
|
-
|
3
|
-
module Signore describe Wrapper do
|
4
|
-
|
5
|
-
describe '#display' do
|
6
|
-
|
7
|
-
it 'returns properly wrapped signature (with possible meta information)' do
|
8
|
-
YAML.load_file('spec/fixtures/wrapper.yml').each do |sample|
|
9
|
-
Wrapper.new(sample[:text], sample[:meta]).display.must_equal sample[:wrapped]
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
end
|
14
|
-
|
15
|
-
end end
|