output_mode 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
|