codeless_code 0.1.7 → 0.1.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitmodules +1 -1
- data/.reek.yml +14 -0
- data/.rubocop.yml +18 -0
- data/.ruby-version +1 -0
- data/{test/test_codeless_code.rb → .travis.yml} +12 -10
- data/Gemfile +5 -0
- data/Gemfile.lock +21 -0
- data/Guardfile +13 -1
- data/README.md +6 -0
- data/Rakefile +26 -11
- data/VERSION +1 -1
- data/bin/codeless_code +3 -1
- data/codeless_code.gemspec +33 -12
- data/lib/codeless_code/catalog.rb +3 -1
- data/lib/codeless_code/cli.rb +56 -24
- data/lib/codeless_code/commands/filter_fables.rb +15 -10
- data/lib/codeless_code/commands/list_translations.rb +3 -0
- data/lib/codeless_code/fable.rb +42 -53
- data/lib/codeless_code/fable_set.rb +8 -6
- data/lib/codeless_code/filters/builders.rb +4 -2
- data/lib/codeless_code/filters/composite.rb +3 -1
- data/lib/codeless_code/filters/date.rb +40 -30
- data/lib/codeless_code/filters/from_options.rb +45 -28
- data/lib/codeless_code/filters/headers/base.rb +61 -0
- data/lib/codeless_code/filters/{header_integer.rb → headers/integer.rb} +16 -19
- data/lib/codeless_code/filters/{header_string.rb → headers/string.rb} +12 -22
- data/lib/codeless_code/filters/lang.rb +3 -0
- data/lib/codeless_code/filters/translator.rb +7 -2
- data/lib/codeless_code/filters.rb +16 -8
- data/lib/codeless_code/formats/base.rb +20 -7
- data/lib/codeless_code/formats/parsers/base.rb +106 -0
- data/lib/codeless_code/formats/parsers/plain.rb +49 -0
- data/lib/codeless_code/formats/parsers/term.rb +79 -0
- data/lib/codeless_code/formats/plain.rb +21 -12
- data/lib/codeless_code/formats/raw.rb +2 -0
- data/lib/codeless_code/formats/term.rb +21 -15
- data/lib/codeless_code/language_set.rb +7 -4
- data/lib/codeless_code/options.rb +5 -3
- data/lib/codeless_code/renderers/fable.rb +13 -8
- data/lib/codeless_code/renderers/term_page.rb +46 -31
- data/lib/codeless_code.rb +119 -106
- data/test/codeless_code/commands/test_filter_fables.rb +89 -0
- data/test/codeless_code/filters/headers/test_integer.rb +86 -0
- data/test/codeless_code/filters/headers/test_string.rb +86 -0
- data/test/codeless_code/filters/test_builders.rb +4 -2
- data/test/codeless_code/filters/test_composite.rb +70 -0
- data/test/codeless_code/filters/test_date.rb +99 -0
- data/test/codeless_code/filters/test_langs.rb +50 -0
- data/test/codeless_code/filters/test_translator.rb +51 -0
- data/test/codeless_code/renderers/test_fable.rb +98 -0
- data/test/codeless_code/renderers/test_term_page.rb +87 -0
- data/test/codeless_code/test_catalog.rb +12 -5
- data/test/codeless_code/test_cli.rb +85 -0
- data/test/codeless_code/test_fable.rb +19 -10
- data/test/codeless_code/test_fable_set.rb +17 -5
- data/test/codeless_code/test_language_set.rb +16 -3
- data/test/codeless_code/test_options.rb +3 -11
- data/test/helper.rb +36 -10
- data/test/support/fs.rb +103 -0
- metadata +65 -11
- data/.document +0 -5
- data/data/README.md +0 -34
- data/lib/codeless_code/formats/plain_generator.rb +0 -157
- data/lib/codeless_code/formats/term_generator.rb +0 -167
- data/test/codeless_code/filters/test_header_integer.rb +0 -82
- data/test/codeless_code/filters/test_header_string.rb +0 -82
data/lib/codeless_code/fable.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# codeless_code filters and prints fables from http://thecodelesscode.com
|
2
4
|
# Copyright (C) 2018 Jon Sangster
|
3
5
|
#
|
@@ -23,27 +25,43 @@ module CodelessCode
|
|
23
25
|
|
24
26
|
HEADER_PATTERN = /([^:\s]+)\s*:\s*(.+)\s*$/.freeze
|
25
27
|
|
26
|
-
|
28
|
+
RAW_ATTRS = %w[Title Tagline Credits].freeze
|
29
|
+
INTEGER_ATTRS = %w[Number Geekiness].freeze
|
30
|
+
LIST_ATTRS = %w[Names Topics].freeze
|
31
|
+
|
32
|
+
attr_reader :file, :has_read_headers
|
27
33
|
|
28
|
-
|
34
|
+
alias read_headers? has_read_headers
|
29
35
|
def_delegators :headers, :[], :fetch, :key?
|
30
36
|
|
31
37
|
def initialize(file)
|
32
38
|
@file = file
|
33
|
-
@
|
34
|
-
@body_pos =
|
39
|
+
@has_read_headers = false
|
40
|
+
@body_pos = 0
|
35
41
|
end
|
36
42
|
|
37
43
|
# @return [String] the actual story, including MediaWiki markup
|
38
44
|
def body
|
39
45
|
@body ||= read_body.freeze
|
40
46
|
end
|
41
|
-
|
47
|
+
alias to_s body
|
48
|
+
|
49
|
+
# Read, or re-read, the body of the fable from the disk
|
50
|
+
# @see #body
|
51
|
+
def read_body
|
52
|
+
headers unless read_headers?
|
53
|
+
|
54
|
+
io = file.open
|
55
|
+
io.seek @body_pos
|
56
|
+
io.read.strip
|
57
|
+
ensure
|
58
|
+
io&.close
|
59
|
+
end
|
42
60
|
|
43
61
|
# @return [Hash<String, String>] the story's metadata
|
44
62
|
def headers
|
45
63
|
@headers ||= begin
|
46
|
-
@
|
64
|
+
@has_read_headers = true
|
47
65
|
read_headers.freeze
|
48
66
|
end
|
49
67
|
end
|
@@ -52,11 +70,6 @@ module CodelessCode
|
|
52
70
|
headers.key?(key)
|
53
71
|
end
|
54
72
|
|
55
|
-
# @return [::Date, nil]
|
56
|
-
def date
|
57
|
-
::Date.parse(self['Date']) if header?('Date')
|
58
|
-
end
|
59
|
-
|
60
73
|
# @return [Symbol]
|
61
74
|
def lang
|
62
75
|
@lang ||= dir_parts.first.to_sym
|
@@ -66,70 +79,46 @@ module CodelessCode
|
|
66
79
|
@translator ||= dir_parts.last
|
67
80
|
end
|
68
81
|
|
69
|
-
|
70
|
-
self[
|
71
|
-
end
|
72
|
-
|
73
|
-
def tagline
|
74
|
-
self['Tagline']
|
82
|
+
RAW_ATTRS.each do |attr|
|
83
|
+
define_method(attr.downcase.to_sym) { self[attr] }
|
75
84
|
end
|
76
85
|
|
77
|
-
|
78
|
-
self[
|
86
|
+
INTEGER_ATTRS.each do |attr|
|
87
|
+
define_method(attr.downcase.to_sym) { self[attr].to_i }
|
79
88
|
end
|
80
89
|
|
81
|
-
|
82
|
-
|
83
|
-
end
|
84
|
-
|
85
|
-
def geekiness
|
86
|
-
self['Geekiness'].to_i
|
87
|
-
end
|
88
|
-
|
89
|
-
def names
|
90
|
-
list('Names')
|
91
|
-
end
|
92
|
-
|
93
|
-
def topics
|
94
|
-
list('Topics')
|
90
|
+
LIST_ATTRS.each do |attr|
|
91
|
+
define_method(attr.downcase.to_sym) { list(attr) }
|
95
92
|
end
|
96
93
|
|
97
94
|
private
|
98
95
|
|
99
|
-
def
|
100
|
-
headers unless read_headers?
|
101
|
-
|
96
|
+
def read_headers
|
102
97
|
io = file.open
|
103
|
-
io
|
104
|
-
io.read.strip
|
98
|
+
parse_headers(io)
|
105
99
|
ensure
|
106
100
|
io&.close
|
107
101
|
end
|
108
102
|
|
109
|
-
|
110
|
-
|
103
|
+
# :reek:FeatureEnvy
|
104
|
+
def parse_headers(io, head = {})
|
105
|
+
until io.eof?
|
106
|
+
@body_pos = io.pos
|
107
|
+
match = HEADER_PATTERN.match(io.gets)
|
108
|
+
break if match.nil?
|
111
109
|
|
112
|
-
|
113
|
-
until io.eof?
|
114
|
-
@body_pos = io.pos
|
115
|
-
if (m = HEADER_PATTERN.match(io.gets))
|
116
|
-
head[m[1].strip] = m[2]&.strip
|
117
|
-
else
|
118
|
-
break
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
massage_headers(head)
|
110
|
+
head[match[1].strip] = match[2]&.strip
|
123
111
|
end
|
124
|
-
|
125
|
-
io&.close
|
112
|
+
massage_headers(head)
|
126
113
|
end
|
127
114
|
|
115
|
+
# :reek:UtilityFunction
|
128
116
|
def massage_headers(head)
|
129
117
|
if head.key?('Series')
|
130
118
|
head['Series'] = head['Title']
|
131
119
|
head['Title'] = head.delete('Subtitle')
|
132
120
|
end
|
121
|
+
head
|
133
122
|
end
|
134
123
|
|
135
124
|
def list(key)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# codeless_code filters and prints fables from http://thecodelesscode.com
|
2
4
|
# Copyright (C) 2018 Jon Sangster
|
3
5
|
#
|
@@ -22,14 +24,14 @@ module CodelessCode
|
|
22
24
|
extend Forwardable
|
23
25
|
include Enumerable
|
24
26
|
|
25
|
-
FILE_PATTERN = '*.txt'
|
26
|
-
LANG_SEP = '-'
|
27
|
+
FILE_PATTERN = '*.txt'
|
28
|
+
LANG_SEP = '-'
|
27
29
|
|
28
|
-
|
30
|
+
attr_reader :dir
|
29
31
|
def_delegator :fables, :each
|
30
32
|
|
31
33
|
def initialize(dir)
|
32
|
-
|
34
|
+
@dir = dir
|
33
35
|
end
|
34
36
|
|
35
37
|
def lang
|
@@ -41,11 +43,11 @@ module CodelessCode
|
|
41
43
|
end
|
42
44
|
|
43
45
|
def fables
|
44
|
-
@fables ||= files.map { |
|
46
|
+
@fables ||= files.map { |file| Fable.new(file) }.sort_by(&:number)
|
45
47
|
end
|
46
48
|
|
47
49
|
def filter(filt)
|
48
|
-
select { |
|
50
|
+
select { |fable| filt.call(fable) }
|
49
51
|
end
|
50
52
|
|
51
53
|
private
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# codeless_code filters and prints fables from http://thecodelesscode.com
|
2
4
|
# Copyright (C) 2018 Jon Sangster
|
3
5
|
#
|
@@ -20,11 +22,11 @@ module CodelessCode
|
|
20
22
|
module_function
|
21
23
|
|
22
24
|
def header_integer_filter(name)
|
23
|
-
subclass_filter(
|
25
|
+
subclass_filter(Headers::Integer, name)
|
24
26
|
end
|
25
27
|
|
26
28
|
def header_string_filter(name)
|
27
|
-
subclass_filter(
|
29
|
+
subclass_filter(Headers::String, name)
|
28
30
|
end
|
29
31
|
|
30
32
|
def subclass_filter(klass, name)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# codeless_code filters and prints fables from http://thecodelesscode.com
|
2
4
|
# Copyright (C) 2018 Jon Sangster
|
3
5
|
#
|
@@ -35,7 +37,7 @@ module CodelessCode
|
|
35
37
|
end
|
36
38
|
|
37
39
|
def call(fable)
|
38
|
-
select(&:enabled?).all? { |filter| filter.call(fable) }
|
40
|
+
any? && select(&:enabled?).all? { |filter| filter.call(fable) }
|
39
41
|
end
|
40
42
|
end
|
41
43
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# codeless_code filters and prints fables from http://thecodelesscode.com
|
2
4
|
# Copyright (C) 2018 Jon Sangster
|
3
5
|
#
|
@@ -17,43 +19,40 @@ require 'date'
|
|
17
19
|
|
18
20
|
module CodelessCode
|
19
21
|
module Filters
|
20
|
-
|
22
|
+
# Matches {Fable fables} that were published on, before, or after a given
|
23
|
+
# date.
|
24
|
+
class Date < Headers::Base
|
25
|
+
# :reek:BooleanParameter
|
21
26
|
def initialize(exact: nil, min: nil, max: nil, exclude: false)
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
@exclude = exclude
|
27
|
+
super('Date', exclude, [Matcher.parse(exact), :==],
|
28
|
+
[Matcher.parse(min), :<=],
|
29
|
+
[Matcher.parse(max), :>=])
|
26
30
|
end
|
27
31
|
|
28
|
-
|
29
|
-
|
32
|
+
# :reek:UtilityFunction
|
33
|
+
def parse(val)
|
34
|
+
::Date.parse(val)
|
30
35
|
end
|
31
36
|
|
32
|
-
def
|
33
|
-
|
34
|
-
return false unless @exact.nil? || @exact == val
|
35
|
-
return false unless @min.nil? || @min <= val
|
36
|
-
return false unless @max.nil? || @max >= val
|
37
|
-
true
|
38
|
-
else
|
39
|
-
@exclude
|
40
|
-
end
|
37
|
+
def test_single(val, operator, test)
|
38
|
+
test.send(operator, val)
|
41
39
|
end
|
42
40
|
|
41
|
+
# Wraps a {::Date} and matches it against "date substrings". ie:
|
42
|
+
# +2010-12+ will matches any dates in December, 2010 and +2010+ will
|
43
|
+
# match any dates in that year.
|
43
44
|
class Matcher
|
44
45
|
# param str [String] A date like +2010+, +2010-12+, or +2010-12-23+
|
45
46
|
def self.parse(str)
|
46
|
-
|
47
|
+
return nil unless str
|
47
48
|
|
48
49
|
if str.size == 4
|
49
|
-
|
50
|
-
match = :year
|
50
|
+
new(::Date.parse("#{str}-01-01"), match: :year)
|
51
51
|
elsif str.size == 7
|
52
|
-
|
53
|
-
|
52
|
+
new(::Date.parse("#{str}-01"), match: :month)
|
53
|
+
else
|
54
|
+
new(::Date.parse(str), match: :day)
|
54
55
|
end
|
55
|
-
|
56
|
-
new(::Date.parse(str), match: match)
|
57
56
|
end
|
58
57
|
|
59
58
|
def initialize(date, match:)
|
@@ -62,27 +61,38 @@ module CodelessCode
|
|
62
61
|
end
|
63
62
|
|
64
63
|
def ==(other)
|
65
|
-
|
64
|
+
compare(@date, other, :==, @match)
|
66
65
|
end
|
67
66
|
|
68
67
|
def >=(other)
|
69
|
-
|
68
|
+
compare(@date, other, :>=, @match)
|
70
69
|
end
|
71
70
|
|
72
71
|
def <=(other)
|
73
|
-
|
72
|
+
compare(@date, other, :<=, @match)
|
74
73
|
end
|
75
74
|
|
76
75
|
private
|
77
76
|
|
78
|
-
|
77
|
+
# :reek:ControlParameter
|
78
|
+
# :reek:FeatureEnvy
|
79
|
+
def compare(first, second, operator, match)
|
79
80
|
case match
|
80
81
|
when :year
|
81
|
-
|
82
|
+
first.year.send(operator, second.year)
|
82
83
|
when :month
|
83
|
-
|
84
|
+
compare_month(first, second, operator)
|
85
|
+
else
|
86
|
+
first.send(operator, second)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# :reek:FeatureEnvy
|
91
|
+
def compare_month(first, second, operator)
|
92
|
+
if first.year == second.year
|
93
|
+
first.month.send(operator, second.month)
|
84
94
|
else
|
85
|
-
|
95
|
+
compare(first, second, operator, :year)
|
86
96
|
end
|
87
97
|
end
|
88
98
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# codeless_code filters and prints fables from http://thecodelesscode.com
|
2
4
|
# Copyright (C) 2018 Jon Sangster
|
3
5
|
#
|
@@ -37,28 +39,46 @@ module CodelessCode
|
|
37
39
|
end
|
38
40
|
|
39
41
|
def filters
|
40
|
-
@filters ||=
|
41
|
-
|
42
|
+
@filters ||=
|
43
|
+
string_filters +
|
44
|
+
integer_filters +
|
45
|
+
[
|
46
|
+
filter(:Date, :date),
|
47
|
+
new_filter(:Lang, exact: lang),
|
48
|
+
number_filter,
|
49
|
+
translator_filter
|
50
|
+
]
|
51
|
+
end
|
42
52
|
|
43
|
-
|
44
|
-
casecmp: @opts[:translator]),
|
53
|
+
private
|
45
54
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
Filters::Tagline.new(**str_args(:tagline)),
|
50
|
-
Filters::Title.new(**str_args(:title)),
|
55
|
+
def string_filters
|
56
|
+
%i[Credits Name Tagline Title Series].map { |name| filter(name, :str) }
|
57
|
+
end
|
51
58
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
end),
|
59
|
+
def integer_filters
|
60
|
+
%i[Geekiness].map { |name| filter(name, :int) }
|
61
|
+
end
|
56
62
|
|
57
|
-
|
58
|
-
]
|
63
|
+
def number_filter
|
64
|
+
filter(:Number, :int) { |args| args[:exact] ||= @opts.args.last&.to_i }
|
59
65
|
end
|
60
66
|
|
61
|
-
|
67
|
+
def translator_filter
|
68
|
+
new_filter(:Translator, exact: @opts[:translator_exact],
|
69
|
+
casecmp: @opts[:translator])
|
70
|
+
end
|
71
|
+
|
72
|
+
def filter(name, type, &blk)
|
73
|
+
new_filter(name,
|
74
|
+
**send(:"#{type.downcase}_args", name.to_s.downcase.to_s),
|
75
|
+
&blk)
|
76
|
+
end
|
77
|
+
|
78
|
+
def new_filter(name, **args)
|
79
|
+
yield args if block_given?
|
80
|
+
Filters.const_get(name).new(**args)
|
81
|
+
end
|
62
82
|
|
63
83
|
def fallback_lang
|
64
84
|
lang = ENV['LANG']&.split(/_|\./)&.first&.downcase&.to_sym
|
@@ -66,13 +86,14 @@ module CodelessCode
|
|
66
86
|
end
|
67
87
|
|
68
88
|
def non_defaults_enabled?
|
69
|
-
filters.reject { |
|
89
|
+
filters.reject { |filter| filter.is_a?(Filters::Lang) }.any?(&:enabled?)
|
70
90
|
end
|
71
91
|
|
72
92
|
def str_args(name)
|
73
93
|
Hash[
|
74
94
|
%i[exact start_with end_with exclude].zip(
|
75
|
-
@opts.slice(
|
95
|
+
@opts.slice(:"#{name}", :"#{name}_start", :"#{name}_end",
|
96
|
+
:"no_#{name}").values
|
76
97
|
)
|
77
98
|
].tap do |args|
|
78
99
|
args[:start_with] ||= '' if @opts[:"has_#{name}"]
|
@@ -82,7 +103,7 @@ module CodelessCode
|
|
82
103
|
def int_args(name)
|
83
104
|
Hash[
|
84
105
|
%i[exact min max exclude].zip(
|
85
|
-
@opts.slice(
|
106
|
+
@opts.slice(:"#{name}", :"#{name}_gte", :"#{name}_lte")
|
86
107
|
.values
|
87
108
|
.map { |num| num&.to_i }
|
88
109
|
.push(@opts[:"no_#{name}"])
|
@@ -90,18 +111,14 @@ module CodelessCode
|
|
90
111
|
]
|
91
112
|
end
|
92
113
|
|
93
|
-
def date_args
|
114
|
+
def date_args(name)
|
94
115
|
{
|
95
|
-
exact:
|
96
|
-
min:
|
97
|
-
max:
|
98
|
-
exclude: @opts[:
|
116
|
+
exact: @opts[:"#{name}"],
|
117
|
+
min: @opts[:"#{name}_after"],
|
118
|
+
max: @opts[:"#{name}_before"],
|
119
|
+
exclude: @opts[:"no_#{name}"]
|
99
120
|
}
|
100
121
|
end
|
101
|
-
|
102
|
-
def date(arg)
|
103
|
-
arg && Filters::Date::Matcher.parse(arg)
|
104
|
-
end
|
105
122
|
end
|
106
123
|
end
|
107
124
|
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# codeless_code filters and prints fables from http://thecodelesscode.com
|
4
|
+
# Copyright (C) 2018 Jon Sangster
|
5
|
+
#
|
6
|
+
# This program is free software: you can redistribute it and/or modify it under
|
7
|
+
# the terms of the GNU General Public License as published by the Free Software
|
8
|
+
# Foundation, either version 3 of the License, or (at your option) any later
|
9
|
+
# version.
|
10
|
+
#
|
11
|
+
# This program is distributed in the hope that it will be useful, but WITHOUT
|
12
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
13
|
+
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
14
|
+
# details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU General Public License along with
|
17
|
+
# this program. If not, see <https://www.gnu.org/licenses/>.
|
18
|
+
module CodelessCode
|
19
|
+
module Filters
|
20
|
+
module Headers
|
21
|
+
# Abstract base class for all generic filters that test a {Fable fable's}
|
22
|
+
# headers.
|
23
|
+
class Base
|
24
|
+
def initialize(key, exclude, *tests)
|
25
|
+
@key = key
|
26
|
+
@exclude = exclude
|
27
|
+
@tests ||= tests.select(&:first).freeze
|
28
|
+
end
|
29
|
+
|
30
|
+
def enabled?
|
31
|
+
@tests.any? || @exclude
|
32
|
+
end
|
33
|
+
|
34
|
+
def call(fable)
|
35
|
+
if fable.header?(@key)
|
36
|
+
@tests.any? ? test(parse(fable[@key])) : !@exclude
|
37
|
+
else
|
38
|
+
@exclude
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
protected
|
43
|
+
|
44
|
+
# :reek:UtilityFunction
|
45
|
+
def parse(val)
|
46
|
+
val
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_single(val, operator, test)
|
50
|
+
val.send(operator, test)
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def test(val)
|
56
|
+
@tests.any? { |(test, op)| test_single(val, op, test) }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# codeless_code filters and prints fables from http://thecodelesscode.com
|
2
4
|
# Copyright (C) 2018 Jon Sangster
|
3
5
|
#
|
@@ -15,27 +17,22 @@
|
|
15
17
|
# this program. If not, see <https://www.gnu.org/licenses/>.
|
16
18
|
module CodelessCode
|
17
19
|
module Filters
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
20
|
+
module Headers
|
21
|
+
# Matches {Fable fables} that have an integer header equal to, less than,
|
22
|
+
# or greater than the given parameters.
|
23
|
+
class Integer < Base
|
24
|
+
# :reek:BooleanParameter
|
25
|
+
def initialize(key, exact: nil, min: nil, max: nil, exclude: false)
|
26
|
+
super(key, exclude, [exact, :==],
|
27
|
+
[min, :>=],
|
28
|
+
[max, :<=])
|
29
|
+
end
|
26
30
|
|
27
|
-
|
28
|
-
@exact || @min || @max || @exclude
|
29
|
-
end
|
31
|
+
protected
|
30
32
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
return false unless @min.nil? || val >= @min.to_i
|
35
|
-
return false unless @max.nil? || val <= @max.to_i
|
36
|
-
!@exclude
|
37
|
-
else
|
38
|
-
@exclude
|
33
|
+
# :reek:UtilityFunction
|
34
|
+
def parse(val)
|
35
|
+
val.to_i
|
39
36
|
end
|
40
37
|
end
|
41
38
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# codeless_code filters and prints fables from http://thecodelesscode.com
|
2
4
|
# Copyright (C) 2018 Jon Sangster
|
3
5
|
#
|
@@ -15,28 +17,16 @@
|
|
15
17
|
# this program. If not, see <https://www.gnu.org/licenses/>.
|
16
18
|
module CodelessCode
|
17
19
|
module Filters
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
def enabled?
|
29
|
-
@exact || @start_with || @end_with || @exclude
|
30
|
-
end
|
31
|
-
|
32
|
-
def call(fable)
|
33
|
-
if fable.header?(@key) && (val = fable[@key])
|
34
|
-
return false unless @exact.nil? || val == @exact
|
35
|
-
return false unless @start_with.nil? || val.start_with?(@start_with)
|
36
|
-
return false unless @end_with.nil? || val.end_with?(@end_with)
|
37
|
-
!@exclude
|
38
|
-
else
|
39
|
-
@exclude
|
20
|
+
module Headers
|
21
|
+
# Matches {Fable fables} that have an string header equal to, that starts
|
22
|
+
# with, or ends with the given parameters.
|
23
|
+
class String < Base
|
24
|
+
# :reek:BooleanParameter
|
25
|
+
def initialize(key, exact: nil, start_with: nil, end_with: nil,
|
26
|
+
exclude: false)
|
27
|
+
super(key, exclude, [exact, :==],
|
28
|
+
[start_with, :start_with?],
|
29
|
+
[end_with, :end_with?])
|
40
30
|
end
|
41
31
|
end
|
42
32
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# codeless_code filters and prints fables from http://thecodelesscode.com
|
2
4
|
# Copyright (C) 2018 Jon Sangster
|
3
5
|
#
|
@@ -15,6 +17,7 @@
|
|
15
17
|
# this program. If not, see <https://www.gnu.org/licenses/>.
|
16
18
|
module CodelessCode
|
17
19
|
module Filters
|
20
|
+
# Matches {Fable fables} in the given language (code).
|
18
21
|
class Lang
|
19
22
|
def initialize(exact: nil)
|
20
23
|
@exact = exact
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# codeless_code filters and prints fables from http://thecodelesscode.com
|
2
4
|
# Copyright (C) 2018 Jon Sangster
|
3
5
|
#
|
@@ -15,6 +17,7 @@
|
|
15
17
|
# this program. If not, see <https://www.gnu.org/licenses/>.
|
16
18
|
module CodelessCode
|
17
19
|
module Filters
|
20
|
+
# Matches {Fable fables} translated by the person with the given name.
|
18
21
|
class Translator
|
19
22
|
def initialize(exact: nil, casecmp: nil)
|
20
23
|
@exact = exact
|
@@ -26,8 +29,10 @@ module CodelessCode
|
|
26
29
|
end
|
27
30
|
|
28
31
|
def call(fable)
|
29
|
-
|
30
|
-
@
|
32
|
+
trans = fable.translator
|
33
|
+
return false unless @exact.nil? || @exact == trans
|
34
|
+
|
35
|
+
@casecmp.nil? || @casecmp.casecmp?(trans)
|
31
36
|
end
|
32
37
|
end
|
33
38
|
end
|