output_mode 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.rspec +3 -0
- data/.travis.yml +13 -0
- data/Gemfile +30 -0
- data/LICENSE.txt +18 -0
- data/README.md +67 -0
- data/Rakefile +32 -0
- data/bin/console +37 -0
- data/bin/demo +60 -0
- data/bin/setup +34 -0
- data/lib/output_mode.rb +34 -0
- data/lib/output_mode/builder_dsl.rb +50 -0
- data/lib/output_mode/callable.rb +138 -0
- data/lib/output_mode/default_erb.rb +19 -0
- data/lib/output_mode/errors.rb +30 -0
- data/lib/output_mode/output.rb +127 -0
- data/lib/output_mode/outputs.rb +36 -0
- data/lib/output_mode/outputs/delimited.rb +49 -0
- data/lib/output_mode/outputs/tabulated.rb +73 -0
- data/lib/output_mode/outputs/templated.rb +128 -0
- data/lib/output_mode/tldr.rb +34 -0
- data/lib/output_mode/tldr/index.rb +55 -0
- data/lib/output_mode/tldr/show.rb +56 -0
- data/lib/output_mode/version.rb +29 -0
- data/output_mode.gemspec +59 -0
- metadata +166 -0
@@ -0,0 +1,19 @@
|
|
1
|
+
#==============================================================================
|
2
|
+
# Refer to LICENSE.txt for licensing terms
|
3
|
+
#==============================================================================
|
4
|
+
|
5
|
+
require 'erb'
|
6
|
+
|
7
|
+
module OutputMode
|
8
|
+
DEFAULT_ERB = ERB.new(<<~TEMPLATE, nil, '-')
|
9
|
+
<% each do |value, field:, padding:, **_| -%>
|
10
|
+
<% if value.nil? && field.nil? -%>
|
11
|
+
|
12
|
+
<% elsif field.nil? -%>
|
13
|
+
<%= pastel.bold '*' -%> <%= pastel.green value %>
|
14
|
+
<% else -%>
|
15
|
+
<%= padding -%><%= pastel.blue.bold field -%><%= pastel.bold ':' -%> <%= pastel.green value %>
|
16
|
+
<% end -%>
|
17
|
+
<% end -%>
|
18
|
+
TEMPLATE
|
19
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
#==============================================================================
|
2
|
+
# Copyright 2020 William McCumstie
|
3
|
+
#
|
4
|
+
# Redistribution and use in source and binary forms, with or without
|
5
|
+
# modification, are permitted provided that the following conditions are met:
|
6
|
+
#
|
7
|
+
# 1. Redistributions of source code must retain the above copyright notice,
|
8
|
+
# this list of conditions and the following disclaimer.
|
9
|
+
#
|
10
|
+
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer in the documentation
|
12
|
+
# and/or other materials provided with the distribution.
|
13
|
+
#
|
14
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
15
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
16
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
17
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
18
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
19
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
20
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
21
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
22
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
23
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
24
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
25
|
+
#==============================================================================
|
26
|
+
|
27
|
+
module OutputMode
|
28
|
+
class Error < StandardError; end
|
29
|
+
end
|
30
|
+
|
@@ -0,0 +1,127 @@
|
|
1
|
+
#==============================================================================
|
2
|
+
# Copyright 2020 William McCumstie
|
3
|
+
#
|
4
|
+
# Redistribution and use in source and binary forms, with or without
|
5
|
+
# modification, are permitted provided that the following conditions are met:
|
6
|
+
#
|
7
|
+
# 1. Redistributions of source code must retain the above copyright notice,
|
8
|
+
# this list of conditions and the following disclaimer.
|
9
|
+
#
|
10
|
+
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer in the documentation
|
12
|
+
# and/or other materials provided with the distribution.
|
13
|
+
#
|
14
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
15
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
16
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
17
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
18
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
19
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
20
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
21
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
22
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
23
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
24
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
25
|
+
#==============================================================================
|
26
|
+
|
27
|
+
module OutputMode
|
28
|
+
# @abstract Defines the public interface to all subclasses
|
29
|
+
#
|
30
|
+
# Base outputting class that wraps an array of procs or other
|
31
|
+
# callable object. Each implementation must override the {#render} method
|
32
|
+
# so it returns an array.
|
33
|
+
class Output
|
34
|
+
# @!attribute [r] procs
|
35
|
+
# @return [Array<#call>] the callable methods to generate output
|
36
|
+
# @!attribute [r] config
|
37
|
+
# @return [Hash] additional key-values to modify the render
|
38
|
+
# @!attribute [r] default
|
39
|
+
# @return either a static default or a column based array of defaults
|
40
|
+
# @!attribute [r] yes
|
41
|
+
# @return either a static yes value or a column based array of values
|
42
|
+
# @!attribute [r] no
|
43
|
+
# @return either a static no value or a column based array of values
|
44
|
+
attr_reader :procs, :config, :yes, :no, :default
|
45
|
+
|
46
|
+
# Creates a new outputting instance from an array of procs
|
47
|
+
#
|
48
|
+
# @param *procs [Array<#call>] an array of procs (or callable objects)
|
49
|
+
# @param default: [String] replaces _blanks_ with a static string
|
50
|
+
# @param default: [Array] replace _blanks_ on a per column basis. The last value is repeated if the +procs+ are longer.
|
51
|
+
# @param yes: [String] replaces +true+ with a static string
|
52
|
+
# @param yes: [Array] replaces +true+ on a per column basis. The last value is repeated if the +procs+ are longer.
|
53
|
+
# @param no: [String] replaces +false+ with a static string
|
54
|
+
# @param no: [Array] replaces +false+ on a per column basis. The last value is repeated if the +procs+ are longer.
|
55
|
+
# @param **config [Hash] a hash of additional keys to be stored
|
56
|
+
def initialize(*procs, default: nil, yes: 'true', no: 'false', **config)
|
57
|
+
@procs = procs
|
58
|
+
@config = config
|
59
|
+
@yes = yes
|
60
|
+
@no = no
|
61
|
+
@default = default
|
62
|
+
end
|
63
|
+
|
64
|
+
# Returns the results of the +procs+ for a particular +object+. It will apply the
|
65
|
+
# +default+, +yes+, and +no+ values.
|
66
|
+
def generate(object)
|
67
|
+
procs.each_with_index.map do |p, idx|
|
68
|
+
raw = p.call(object)
|
69
|
+
if raw == true
|
70
|
+
index_selector(:yes, idx)
|
71
|
+
elsif raw == false
|
72
|
+
index_selector(:no, idx)
|
73
|
+
elsif !default.nil? && (raw.nil? || raw == '')
|
74
|
+
index_selector(:default, idx)
|
75
|
+
else
|
76
|
+
raw
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# @abstract It should be implemented by the subclass using the +generate+ method
|
82
|
+
# Renders the results of the procs into a string. Each data
|
83
|
+
# objects should be passed individual to each proc to generate the final
|
84
|
+
# output.
|
85
|
+
#
|
86
|
+
# The method must be overridden on all inherited classes
|
87
|
+
#
|
88
|
+
# @param *data [Array] a set of data to be rendered into the output
|
89
|
+
# @return [String] the output string
|
90
|
+
# @see #generate
|
91
|
+
def render(*data)
|
92
|
+
raise NotImplementedError
|
93
|
+
end
|
94
|
+
|
95
|
+
# A helper method for selecting elements from a source array or return
|
96
|
+
# a static value.
|
97
|
+
#
|
98
|
+
# @param [Symbol] method The source method on the +output+
|
99
|
+
# @param [Integer] index The index to lookup
|
100
|
+
#
|
101
|
+
# @overload index_selector(array_method, valid_index)
|
102
|
+
# @param array_method A method that returns an array
|
103
|
+
# @param valid_index An index that is less than the array's length
|
104
|
+
# @return the value at the index
|
105
|
+
#
|
106
|
+
# @overload index_selector(array_method, out_of_bounds)
|
107
|
+
# @param array_method A method that returns an array
|
108
|
+
# @param out_of_bounds An index greater than the maximum array length
|
109
|
+
# @return the last element of the array
|
110
|
+
#
|
111
|
+
# @overload index_selector(non_array_method, _)
|
112
|
+
# @param non_array_method A method that does not return an array
|
113
|
+
# @param _ The index is ignored
|
114
|
+
# @return the result of the non_array_method
|
115
|
+
def index_selector(method, index)
|
116
|
+
source = public_send(method)
|
117
|
+
is_array = source.is_a? Array
|
118
|
+
if is_array && source.length > index
|
119
|
+
source[index]
|
120
|
+
elsif is_array
|
121
|
+
source.last
|
122
|
+
else
|
123
|
+
source
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
#==============================================================================
|
2
|
+
# Copyright 2020 William McCumstie
|
3
|
+
#
|
4
|
+
# Redistribution and use in source and binary forms, with or without
|
5
|
+
# modification, are permitted provided that the following conditions are met:
|
6
|
+
#
|
7
|
+
# 1. Redistributions of source code must retain the above copyright notice,
|
8
|
+
# this list of conditions and the following disclaimer.
|
9
|
+
#
|
10
|
+
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer in the documentation
|
12
|
+
# and/or other materials provided with the distribution.
|
13
|
+
#
|
14
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
15
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
16
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
17
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
18
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
19
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
20
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
21
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
22
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
23
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
24
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
25
|
+
#==============================================================================
|
26
|
+
|
27
|
+
require 'output_mode/output'
|
28
|
+
|
29
|
+
module OutputMode
|
30
|
+
module Outputs
|
31
|
+
Dir.glob(File.expand_path('outputs/*.rb', __dir__)).each do |path|
|
32
|
+
autoload File.basename(path).chomp('.rb').capitalize, path
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
@@ -0,0 +1,49 @@
|
|
1
|
+
#==============================================================================
|
2
|
+
# Copyright 2020 William McCumstie
|
3
|
+
#
|
4
|
+
# Redistribution and use in source and binary forms, with or without
|
5
|
+
# modification, are permitted provided that the following conditions are met:
|
6
|
+
#
|
7
|
+
# 1. Redistributions of source code must retain the above copyright notice,
|
8
|
+
# this list of conditions and the following disclaimer.
|
9
|
+
#
|
10
|
+
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer in the documentation
|
12
|
+
# and/or other materials provided with the distribution.
|
13
|
+
#
|
14
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
15
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
16
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
17
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
18
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
19
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
20
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
21
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
22
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
23
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
24
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
25
|
+
#==============================================================================
|
26
|
+
|
27
|
+
require 'csv'
|
28
|
+
|
29
|
+
module OutputMode
|
30
|
+
module Outputs
|
31
|
+
class Delimited < Output
|
32
|
+
# @return [Hash] additional options to CSV.new
|
33
|
+
# @see https://ruby-doc.org/stdlib-2.6.1/libdoc/csv/rdoc/CSV.html
|
34
|
+
def config; super; end
|
35
|
+
|
36
|
+
# Implements the render method using +CSV+
|
37
|
+
#
|
38
|
+
# @see OutputMode::Output#render
|
39
|
+
# @see CSV
|
40
|
+
def render(*data)
|
41
|
+
io = StringIO.new
|
42
|
+
csv = CSV.new(io, **config)
|
43
|
+
data.each { |d| csv << generate(d) }
|
44
|
+
io.tap(&:rewind).read
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
@@ -0,0 +1,73 @@
|
|
1
|
+
#==============================================================================
|
2
|
+
# Copyright 2020 William McCumstie
|
3
|
+
#
|
4
|
+
# Redistribution and use in source and binary forms, with or without
|
5
|
+
# modification, are permitted provided that the following conditions are met:
|
6
|
+
#
|
7
|
+
# 1. Redistributions of source code must retain the above copyright notice,
|
8
|
+
# this list of conditions and the following disclaimer.
|
9
|
+
#
|
10
|
+
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer in the documentation
|
12
|
+
# and/or other materials provided with the distribution.
|
13
|
+
#
|
14
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
15
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
16
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
17
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
18
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
19
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
20
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
21
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
22
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
23
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
24
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
25
|
+
#==============================================================================
|
26
|
+
|
27
|
+
require 'tty-table'
|
28
|
+
|
29
|
+
module OutputMode
|
30
|
+
module Outputs
|
31
|
+
class Tabulated < Output
|
32
|
+
attr_reader :renderer, :header, :default, :block, :yes, :no
|
33
|
+
|
34
|
+
# @!attribute [r] renderer
|
35
|
+
# @return [Symbol] the renderer type, see: https://github.com/piotrmurach/tty-table#32-renderer
|
36
|
+
# @!attribute [r] header
|
37
|
+
# @return [Array] An optional header row for the table
|
38
|
+
# @!attribute [r] block
|
39
|
+
# @return [#call] an optional block of code that configures the renderer
|
40
|
+
|
41
|
+
# @return [Hash] additional options to +TTY::Table+ renderer
|
42
|
+
# @see https://github.com/piotrmurach/tty-table#33-options
|
43
|
+
def config; super; end
|
44
|
+
|
45
|
+
# @overload initialize(*procs, renderer: nil, header: nil, **config)
|
46
|
+
# @param [Array] *procs see {OutputMode::Outputs::Base#initialize}
|
47
|
+
# @param [Symbol] :renderer override the default renderer
|
48
|
+
# @param [Array<String>] :header the header row of the table
|
49
|
+
# @param [Hash] **config additional options to the renderer
|
50
|
+
# @yieldparam tty_table_renderer [TTY::Table::Renderer::Base] optional access the underlining TTY::Table renderer
|
51
|
+
def initialize(*procs,
|
52
|
+
renderer: :unicode,
|
53
|
+
header: nil,
|
54
|
+
**config,
|
55
|
+
&block)
|
56
|
+
@header = header
|
57
|
+
@renderer = renderer
|
58
|
+
@block = block
|
59
|
+
super(*procs, **config)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Implements the render method using +TTY::Table+
|
63
|
+
# @see OutputMode::Outputs::Base#render
|
64
|
+
# @see https://github.com/piotrmurach/tty-table
|
65
|
+
def render(*data)
|
66
|
+
table = TTY::Table.new header: header
|
67
|
+
data.each { |d| table << generate(d) }
|
68
|
+
table.render(renderer, **config, &block) || ''
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
@@ -0,0 +1,128 @@
|
|
1
|
+
#==============================================================================
|
2
|
+
# Copyright 2020 William McCumstie
|
3
|
+
#
|
4
|
+
# Redistribution and use in source and binary forms, with or without
|
5
|
+
# modification, are permitted provided that the following conditions are met:
|
6
|
+
#
|
7
|
+
# 1. Redistributions of source code must retain the above copyright notice,
|
8
|
+
# this list of conditions and the following disclaimer.
|
9
|
+
#
|
10
|
+
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer in the documentation
|
12
|
+
# and/or other materials provided with the distribution.
|
13
|
+
#
|
14
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
15
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
16
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
17
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
18
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
19
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
20
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
21
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
22
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
23
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
24
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
25
|
+
#==============================================================================
|
26
|
+
|
27
|
+
require 'pastel'
|
28
|
+
|
29
|
+
require 'output_mode/default_erb'
|
30
|
+
|
31
|
+
module OutputMode
|
32
|
+
module Outputs
|
33
|
+
class Templated < Output
|
34
|
+
Entry = Struct.new(:output, :model, :colorize) do
|
35
|
+
include Enumerable
|
36
|
+
|
37
|
+
# @yieldparam value An attribute to be rendered
|
38
|
+
# @yieldparam field: An optional field header for the value
|
39
|
+
# @yieldparam padding: A padding string which will right align the +field+
|
40
|
+
# @yieldparam **config TBA
|
41
|
+
def each
|
42
|
+
max = output.max_field_length
|
43
|
+
output.generate(model).each_with_index do |value, idx|
|
44
|
+
field = output.index_selector(:fields, idx)
|
45
|
+
padding = ' ' * (max - field.to_s.length)
|
46
|
+
yield(value, field: field, padding: padding)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Renders an ERB object within the entry's context. This provides access to the
|
51
|
+
# +output+, +model+, and +enumerable+ methods
|
52
|
+
#
|
53
|
+
# @param [ERB] erb the ERB object which contains the template to be rendered
|
54
|
+
# @return [String] the result text
|
55
|
+
def render(erb)
|
56
|
+
erb.result(binding)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Library for colorizing the output. It is automatically disabled when the
|
60
|
+
# +colorize+ flag is +false+
|
61
|
+
def pastel
|
62
|
+
@pastel ||= Pastel.new(enabled: colorize)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# @!attribute [r] erb
|
67
|
+
# @return [ERB] The +erb+ object containing the template to be rendered.
|
68
|
+
# @!attribute [r] separator
|
69
|
+
# @!attribute [r] fields
|
70
|
+
# @!attribute [r] colorize
|
71
|
+
attr_reader :erb, :fields, :separator, :colorize
|
72
|
+
|
73
|
+
# Create a new +output+ which will render using +ERB+. The provided +template+ should
|
74
|
+
# only render the +output+ for a single +entry+ (aka model, record, data object, etc).
|
75
|
+
#
|
76
|
+
# The +template+ maybe either a +String+ or a +ERB+ object. Strings will automatically
|
77
|
+
# be converted to +ERB+ with the +trim_mode+ set to +-+.
|
78
|
+
#
|
79
|
+
# A default template will be used if one has not be provided.
|
80
|
+
#
|
81
|
+
# @see https://ruby-doc.org/stdlib-2.7.1/libdoc/erb/rdoc/ERB.html
|
82
|
+
# @see render
|
83
|
+
# @see DEFAULT_ERB
|
84
|
+
#
|
85
|
+
# @overload initialize(*procs, template: nil, fields: nil, seperator: "\n", yes: 'true', no: 'false', **config)
|
86
|
+
# @param [Array] *procs see {OutputMode::Output#initialize}
|
87
|
+
# @param [String] template: A string to be converted into +ERB+
|
88
|
+
# @param [ERB] template: The +template+ object used by the renderer
|
89
|
+
# @param [Array] fields: An optional array of field headers that map to the procs, repeating the last value if required
|
90
|
+
# @param fields: A static value to use as all field headers
|
91
|
+
# @param separator: The character(s) used to join the "entries" together
|
92
|
+
# @param colorize: Flags if the caller wants the colorized version, this maybe ignored by +template+
|
93
|
+
# @param [Hash] **config see {OutputMode::Output#initialize}
|
94
|
+
def initialize(*procs,
|
95
|
+
template: nil,
|
96
|
+
fields: nil,
|
97
|
+
separator: "\n",
|
98
|
+
colorize: false,
|
99
|
+
**config)
|
100
|
+
@erb = DEFAULT_ERB
|
101
|
+
@fields = fields
|
102
|
+
@separator = separator
|
103
|
+
@colorize = colorize
|
104
|
+
super(*procs, **config)
|
105
|
+
end
|
106
|
+
|
107
|
+
# Implements the render method using the ERB +template+. The +template+ will
|
108
|
+
# be rendered within the context of an +Entry+. An +Entry+ object will be
|
109
|
+
# created/ rendered for each element of +data+
|
110
|
+
#
|
111
|
+
# @see OutputMode::Output#render
|
112
|
+
def render(*data)
|
113
|
+
data.map { |d| Entry.new(self, d, colorize).render(erb) }
|
114
|
+
.join(separator)
|
115
|
+
end
|
116
|
+
|
117
|
+
# Returns the length of the maximum field
|
118
|
+
def max_field_length
|
119
|
+
if fields.is_a? Array
|
120
|
+
fields.map { |f| f.to_s.length }.max
|
121
|
+
else
|
122
|
+
fields.to_s.length
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|