format_output 0.1.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 +8 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +352 -0
- data/exe/README.md +43 -0
- data/exe/format_output_demo +36 -0
- data/format_output.gemspec +32 -0
- data/lib/format_output/builders/bullet_builder.rb +61 -0
- data/lib/format_output/builders/column_builder.rb +116 -0
- data/lib/format_output/bullets.rb +134 -0
- data/lib/format_output/columns.rb +37 -0
- data/lib/format_output/version.rb +7 -0
- data/lib/format_output/word_wrap.rb +51 -0
- data/lib/format_output.rb +70 -0
- data/rakefile.rb +16 -0
- metadata +131 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9c8c65f32fd95cbd19905fc587273dbea1ce18da
|
4
|
+
data.tar.gz: baf65ce1f265d28f1174e5ac4151852c432ced21
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d42cd2b4fa43e1beaeaac9779bb389716543e89b80be942cf0d20eff34575f8e90677ffd5c55c749c9f19f77c2850aecfc4e0408bff5e9f7f1b173bce8d70078
|
7
|
+
data.tar.gz: 53ac409dcef76919bf95553f642e6ac3ac2ca7ede43d6d730b1200f0615b328d7bb4f7992d24de79e145633e2e02ee2ad963c40051283a87bab4bd9bc1c6fe7d
|
data/.gitignore
ADDED
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
2
|
+
|
3
|
+
## Our Pledge
|
4
|
+
|
5
|
+
In the interest of fostering an open and welcoming environment, we as
|
6
|
+
contributors and maintainers pledge to making participation in our project and
|
7
|
+
our community a harassment-free experience for everyone, regardless of age, body
|
8
|
+
size, disability, ethnicity, gender identity and expression, level of experience,
|
9
|
+
nationality, personal appearance, race, religion, or sexual identity and
|
10
|
+
orientation.
|
11
|
+
|
12
|
+
## Our Standards
|
13
|
+
|
14
|
+
Examples of behavior that contributes to creating a positive environment
|
15
|
+
include:
|
16
|
+
|
17
|
+
* Using welcoming and inclusive language
|
18
|
+
* Being respectful of differing viewpoints and experiences
|
19
|
+
* Gracefully accepting constructive criticism
|
20
|
+
* Focusing on what is best for the community
|
21
|
+
* Showing empathy towards other community members
|
22
|
+
|
23
|
+
Examples of unacceptable behavior by participants include:
|
24
|
+
|
25
|
+
* The use of sexualized language or imagery and unwelcome sexual attention or
|
26
|
+
advances
|
27
|
+
* Trolling, insulting/derogatory comments, and personal or political attacks
|
28
|
+
* Public or private harassment
|
29
|
+
* Publishing others' private information, such as a physical or electronic
|
30
|
+
address, without explicit permission
|
31
|
+
* Other conduct which could reasonably be considered inappropriate in a
|
32
|
+
professional setting
|
33
|
+
|
34
|
+
## Our Responsibilities
|
35
|
+
|
36
|
+
Project maintainers are responsible for clarifying the standards of acceptable
|
37
|
+
behavior and are expected to take appropriate and fair corrective action in
|
38
|
+
response to any instances of unacceptable behavior.
|
39
|
+
|
40
|
+
Project maintainers have the right and responsibility to remove, edit, or
|
41
|
+
reject comments, commits, code, wiki edits, issues, and other contributions
|
42
|
+
that are not aligned to this Code of Conduct, or to ban temporarily or
|
43
|
+
permanently any contributor for other behaviors that they deem inappropriate,
|
44
|
+
threatening, offensive, or harmful.
|
45
|
+
|
46
|
+
## Scope
|
47
|
+
|
48
|
+
This Code of Conduct applies both within project spaces and in public spaces
|
49
|
+
when an individual is representing the project or its community. Examples of
|
50
|
+
representing a project or community include using an official project e-mail
|
51
|
+
address, posting via an official social media account, or acting as an appointed
|
52
|
+
representative at an online or offline event. Representation of a project may be
|
53
|
+
further defined and clarified by project maintainers.
|
54
|
+
|
55
|
+
## Enforcement
|
56
|
+
|
57
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
58
|
+
reported by contacting the project team at peter.c.camilleri@gmail.com. All
|
59
|
+
complaints will be reviewed and investigated and will result in a response that
|
60
|
+
is deemed necessary and appropriate to the circumstances. The project team is
|
61
|
+
obligated to maintain confidentiality with regard to the reporter of an incident.
|
62
|
+
Further details of specific enforcement policies may be posted separately.
|
63
|
+
|
64
|
+
Project maintainers who do not follow or enforce the Code of Conduct in good
|
65
|
+
faith may face temporary or permanent repercussions as determined by other
|
66
|
+
members of the project's leadership.
|
67
|
+
|
68
|
+
## Attribution
|
69
|
+
|
70
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
71
|
+
available at [http://contributor-covenant.org/version/1/4][version]
|
72
|
+
|
73
|
+
[homepage]: http://contributor-covenant.org
|
74
|
+
[version]: http://contributor-covenant.org/version/1/4/
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2018 PeterCamilleri
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,352 @@
|
|
1
|
+
# FormatOutput
|
2
|
+
|
3
|
+
The format_output gem is used to facilitate the creation of CLI programs in
|
4
|
+
Ruby by formatting data as bullet points, columns, or word wrap to the console,
|
5
|
+
strings, or arrays of strings.
|
6
|
+
|
7
|
+
This gem started out life buried deep within the mysh gem where it served as
|
8
|
+
the data formatting facility for that program. Such was the usefulness of these
|
9
|
+
methods that the long task of splitting them away from mysh was started.
|
10
|
+
|
11
|
+
Along the way, additional capabilities were added to flesh out range of
|
12
|
+
available formatting transformations. The following are taken from the
|
13
|
+
format_output unit test suite and include:
|
14
|
+
|
15
|
+
### Columns
|
16
|
+
|
17
|
+
Neat, efficient columns of data are nice:
|
18
|
+
|
19
|
+
0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95
|
20
|
+
1 6 11 16 21 26 31 36 41 46 51 56 61 66 71 76 81 86 91 96
|
21
|
+
2 7 12 17 22 27 32 37 42 47 52 57 62 67 72 77 82 87 92 97
|
22
|
+
3 8 13 18 23 28 33 38 43 48 53 58 63 68 73 78 83 88 93 98
|
23
|
+
4 9 14 19 24 29 34 39 44 49 54 59 64 69 74 79 84 89 94 99
|
24
|
+
|
25
|
+
### Bullet Points
|
26
|
+
|
27
|
+
How about making some (bullet) points:
|
28
|
+
|
29
|
+
Name Wiley Coyote
|
30
|
+
Education Super Genius
|
31
|
+
Incident Run over by a large truck
|
32
|
+
Status Flattened and accordion like
|
33
|
+
|
34
|
+
### Word Wrap
|
35
|
+
|
36
|
+
Well long text can be hard to (word) wrap your head around:
|
37
|
+
|
38
|
+
There are many many stars in the
|
39
|
+
heavens. Lots really. Like billions and
|
40
|
+
billions
|
41
|
+
|
42
|
+
There are many many fishies in the sea.
|
43
|
+
Lots really. Like billions and billions
|
44
|
+
|
45
|
+
There are many many birds in the sky.
|
46
|
+
Lots really. Like billions and billions
|
47
|
+
|
48
|
+
|
49
|
+
## Installation
|
50
|
+
|
51
|
+
Add this line to your application's Gemfile:
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
gem 'format_output'
|
55
|
+
```
|
56
|
+
|
57
|
+
And then execute:
|
58
|
+
|
59
|
+
$ bundle
|
60
|
+
|
61
|
+
Or install it yourself as:
|
62
|
+
|
63
|
+
$ gem install format_output
|
64
|
+
|
65
|
+
## Usage
|
66
|
+
|
67
|
+
### Formatting Control Parameters
|
68
|
+
|
69
|
+
The formatting of output is controlled by four parameters. These are:
|
70
|
+
|
71
|
+
Parameter| Description | Default
|
72
|
+
---------|-------------------------------------------------------------------|-----------
|
73
|
+
width |The overall width of the output "stage". | 80
|
74
|
+
left |The size of the left margin. White space to the left of the data. | 0
|
75
|
+
body |The center of the "stage" where the formatted data resides. | 80
|
76
|
+
right |The size of the right margin. White space to the right of the data.| 0
|
77
|
+
|
78
|
+
These relationships are illustrated below:
|
79
|
+
|
80
|
+
|<-------------------------- width --------------------------->|
|
81
|
+
|<left margin>|<------------ body ------------>|<right margin>|
|
82
|
+
1 4 7 10 13 16 19 22 25
|
83
|
+
2 5 8 11 14 17 20 23
|
84
|
+
3 6 9 12 15 18 21 24
|
85
|
+
|
86
|
+
width = 60
|
87
|
+
left = 14
|
88
|
+
right = 14
|
89
|
+
body = 32
|
90
|
+
|
91
|
+
In many cases however, the programmer will not need to modify these parameters.
|
92
|
+
That is the defaults values provided are suitable for most application.
|
93
|
+
|
94
|
+
If the defaults are not suitable, there are two approaches that are available:
|
95
|
+
|
96
|
+
1. The global parameters can be changed. For example:
|
97
|
+
|
98
|
+
FormatOutput.width = 132
|
99
|
+
|
100
|
+
2. The parameters can be set for one call only. For example:
|
101
|
+
|
102
|
+
my_array.format_output_columns(left: 5, right: 5)
|
103
|
+
|
104
|
+
|
105
|
+
Note: The format_output parameters are connected in that they define the same
|
106
|
+
formatting work area. As a result, the following interactions occur:
|
107
|
+
|
108
|
+
FormatOutput.left # Gets the left margin
|
109
|
+
FormatOutput.left = value # Sets the left margin
|
110
|
+
FormatOutput.right # Gets the left margin
|
111
|
+
FormatOutput.right = value # Sets the left margin
|
112
|
+
FormatOutput.width # Gets the full width
|
113
|
+
FormatOutput.width = value # Sets the full width
|
114
|
+
FormatOutput.body # Gets width - (left + right)
|
115
|
+
FormatOutput.width = value # Sets width = value + left + right
|
116
|
+
|
117
|
+
As can be seen, setting the body and setting the other parameters does interact
|
118
|
+
quite a bit. So these rules should be followed:
|
119
|
+
|
120
|
+
* Always set left and right margins before setting the body. Otherwise, the
|
121
|
+
body setting will be modified to a value other than the set value.
|
122
|
+
* Don't set both the body and the width or unexpected results may be observed.
|
123
|
+
|
124
|
+
When parameters are passed in for individual calls, they take effect at the
|
125
|
+
same time so the ordering is not significant. Still, setting body and width
|
126
|
+
will have unpredictable results.
|
127
|
+
|
128
|
+
### API Levels
|
129
|
+
|
130
|
+
Each of the three types of formatting has three levels of support. These are
|
131
|
+
summarized as follows:
|
132
|
+
|
133
|
+
Columns | Word Wrap | Bullet Points | Returns
|
134
|
+
--------------------------|----------------------------|--------------------------|----------------
|
135
|
+
puts_format_output_columns|puts_format_output_word_wrap|puts_format_output_bullets| nil
|
136
|
+
format_output_columns |format_output_word_wrap |format_output_bullets | a string
|
137
|
+
format_output_raw_columns |format_output_raw_word_wrap |format_output_raw_bullets | [strings]
|
138
|
+
|
139
|
+
The puts_etc methods return nil because they directly print the results of the
|
140
|
+
formatting using the puts method. The intermediate methods return a string,
|
141
|
+
replete with any needed new line characters. Finally the "raw" methods return
|
142
|
+
an array of strings in place of said new line sequences.
|
143
|
+
|
144
|
+
Regardless of how output of the results is achieved, the formatting done is the
|
145
|
+
same for all three levels. The next sections focus on that formatting.
|
146
|
+
|
147
|
+
### Columns
|
148
|
+
|
149
|
+
The column format is used to display data in neat columns. Yes sure, you can
|
150
|
+
just do a puts on an array of data and it will blast it to the console, one
|
151
|
+
item per line, but that can be a lot off lines scrolling meaninglessly off the
|
152
|
+
screen.
|
153
|
+
|
154
|
+
Column formatting tries to use as few lines of output as it can. For example:
|
155
|
+
|
156
|
+
```ruby
|
157
|
+
# Some simple number, squared, and cubed columns
|
158
|
+
column_data = Array.new(25) { |i| "#{i}, #{i*i}, #{i*i*i} " }
|
159
|
+
puts "Numbers, squares, and cubes.", ""
|
160
|
+
column_data.puts_format_output_columns(width: 72)
|
161
|
+
```
|
162
|
+
|
163
|
+
The output is:
|
164
|
+
|
165
|
+
Numbers, squares, and cubes.
|
166
|
+
|
167
|
+
0, 0, 0 7, 49, 343 14, 196, 2744 21, 441, 9261
|
168
|
+
1, 1, 1 8, 64, 512 15, 225, 3375 22, 484, 10648
|
169
|
+
2, 4, 8 9, 81, 729 16, 256, 4096 23, 529, 12167
|
170
|
+
3, 9, 27 10, 100, 1000 17, 289, 4913 24, 576, 13824
|
171
|
+
4, 16, 64 11, 121, 1331 18, 324, 5832
|
172
|
+
5, 25, 125 12, 144, 1728 19, 361, 6859
|
173
|
+
6, 36, 216 13, 169, 2197 20, 400, 8000
|
174
|
+
|
175
|
+
Now this is not meant to be optimal, but to instead show how neat columns are
|
176
|
+
created even with items of varying length.
|
177
|
+
|
178
|
+
### Word Wrap
|
179
|
+
|
180
|
+
The word wrap format is used to take very long lines of text and convert it
|
181
|
+
into a number of shorter lines. The trick is to avoid splitting words and
|
182
|
+
making the text hard to read.
|
183
|
+
|
184
|
+
```ruby
|
185
|
+
# Maybe (word) wrap your head around a little Shakespear?
|
186
|
+
long_text = "Wherefore rejoice? What conquest brings he home? What tributaries follow him to Rome, to grace in captive bonds his chariot-wheels? You blocks, you stones, you worse than senseless things!"
|
187
|
+
puts "", "", "Word wrapping the Great Bard!", ""
|
188
|
+
long_text.puts_format_output_word_wrap(width: 72)
|
189
|
+
```
|
190
|
+
|
191
|
+
The output is:
|
192
|
+
|
193
|
+
Word wrapping the Great Bard!
|
194
|
+
|
195
|
+
Wherefore rejoice? What conquest brings he home? What tributaries
|
196
|
+
follow him to Rome, to grace in captive bonds his chariot-wheels? You
|
197
|
+
blocks, you stones, you worse than senseless things!
|
198
|
+
|
199
|
+
Now, if the input is an array of really long strings, the word wrapper will
|
200
|
+
convert each of those lines into a neatly word wrapped paragraph with a blank
|
201
|
+
line between them.
|
202
|
+
|
203
|
+
### Bullet Points
|
204
|
+
|
205
|
+
The bullet point formatter is used to create an output consisting of one or
|
206
|
+
more bullet points. So how is a bullet point defined? There are two essential
|
207
|
+
components, illustrated here:
|
208
|
+
|
209
|
+
tag1 detail1
|
210
|
+
tag2 detail2
|
211
|
+
tag3 etc etc etc
|
212
|
+
|
213
|
+
So what is the input? An array of bullet point data of course! That is an array
|
214
|
+
of arrays. The following array describes the sample bullet point above:
|
215
|
+
|
216
|
+
```ruby
|
217
|
+
datum = [["tag1", "detail1"],["tag2", "detail2"],["tag3", "etc etc etc"]]
|
218
|
+
datum.puts_format_output_bullets
|
219
|
+
```
|
220
|
+
|
221
|
+
Now, this array contained in the outer array describes the actual bullet points
|
222
|
+
that are created. This inner array may contain zero or more elelemts.
|
223
|
+
|
224
|
+
#### Zero Elements and Empty Bullets
|
225
|
+
|
226
|
+
When an empty array is used, the bullet formatter skips that entry. This can be
|
227
|
+
useful when gathering data for a report and for one item no data is found.
|
228
|
+
There are three ways to create an empty bullet point:
|
229
|
+
|
230
|
+
```ruby
|
231
|
+
[]
|
232
|
+
["zero", []]
|
233
|
+
["zero", nil]
|
234
|
+
```
|
235
|
+
|
236
|
+
Note that the following, is not fully empty
|
237
|
+
|
238
|
+
```ruby
|
239
|
+
["zero", ""]
|
240
|
+
```
|
241
|
+
|
242
|
+
Yields a bullet point with a bullet of "zero" and no detail text.
|
243
|
+
|
244
|
+
#### One Element
|
245
|
+
|
246
|
+
When an array with one element is used, that element becomes the detail and the
|
247
|
+
default bullet ("*") is used:
|
248
|
+
|
249
|
+
```ruby
|
250
|
+
["one with a (default) bullet."]
|
251
|
+
```
|
252
|
+
|
253
|
+
produces:
|
254
|
+
|
255
|
+
* one with a (default) bullet.
|
256
|
+
|
257
|
+
#### Two Elements
|
258
|
+
|
259
|
+
When an array with two elements is used, the first is the bullet and the second
|
260
|
+
is the detail. This is by far the most common:
|
261
|
+
|
262
|
+
```ruby
|
263
|
+
["two", 2],
|
264
|
+
```
|
265
|
+
|
266
|
+
produces:
|
267
|
+
|
268
|
+
two 2
|
269
|
+
|
270
|
+
|
271
|
+
#### Three or more Elements
|
272
|
+
|
273
|
+
When an array with three or more elements is used, the first is the bullet and
|
274
|
+
the second is the detail. The rest of the elements are additional details for
|
275
|
+
this bullet point. Like this:
|
276
|
+
|
277
|
+
```ruby
|
278
|
+
["three", 3, "more than two", "more than one", "more than zero"],
|
279
|
+
```
|
280
|
+
|
281
|
+
produces:
|
282
|
+
|
283
|
+
three 3
|
284
|
+
more than two
|
285
|
+
more than one
|
286
|
+
more than zero
|
287
|
+
|
288
|
+
#### The Details
|
289
|
+
|
290
|
+
Now we can turn our attention to the actual details and to a lesser extent, the
|
291
|
+
tags. These can be:
|
292
|
+
|
293
|
+
1. A String
|
294
|
+
2. An object that responds favorably to the to_s method.
|
295
|
+
|
296
|
+
In addition, the details may be an Array.
|
297
|
+
|
298
|
+
So when the details are a string that string is used as the details. And yes,
|
299
|
+
if the string is too long to fit, it gets word wrapped! Like this:
|
300
|
+
|
301
|
+
```ruby
|
302
|
+
['five', "I can see for miles and miles and more miles and yet more miles and a lot of miles and damn more miles"]
|
303
|
+
```
|
304
|
+
|
305
|
+
produces:
|
306
|
+
|
307
|
+
five I can see for miles and miles and more miles and yet more miles
|
308
|
+
and a lot of miles and damn more miles
|
309
|
+
|
310
|
+
Note, this courtesy does not extend to the bullet tags. They must exhibit a
|
311
|
+
sensible level of brevity!
|
312
|
+
|
313
|
+
Further, when the details are contained in there own little array, they are
|
314
|
+
displayed in columns if they don't fit in one line. Look here:
|
315
|
+
|
316
|
+
```ruby
|
317
|
+
["four", (1..100).to_a]
|
318
|
+
```
|
319
|
+
|
320
|
+
produces:
|
321
|
+
|
322
|
+
four 1 6 11 16 21 26 31 36 41 46 51 56 61 66 71 76 81 86 91 96
|
323
|
+
2 7 12 17 22 27 32 37 42 47 52 57 62 67 72 77 82 87 92 97
|
324
|
+
3 8 13 18 23 28 33 38 43 48 53 58 63 68 73 78 83 88 93 98
|
325
|
+
4 9 14 19 24 29 34 39 44 49 54 59 64 69 74 79 84 89 94 99
|
326
|
+
5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100
|
327
|
+
|
328
|
+
|
329
|
+
## Contributing
|
330
|
+
|
331
|
+
1. Fork it
|
332
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
333
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
334
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
335
|
+
5. Create new Pull Request
|
336
|
+
|
337
|
+
OR...
|
338
|
+
|
339
|
+
* Make a suggestion by raising an
|
340
|
+
[issue](https://github.com/PeterCamilleri/format_output/issues)
|
341
|
+
. All ideas and comments are welcome.
|
342
|
+
|
343
|
+
## License
|
344
|
+
|
345
|
+
The gem is available as open source under the terms of the
|
346
|
+
[MIT License](./LICENSE.txt).
|
347
|
+
|
348
|
+
## Code of Conduct
|
349
|
+
|
350
|
+
Everyone interacting in the format_output project’s codebases, issue trackers,
|
351
|
+
chat rooms and mailing lists is expected to follow the
|
352
|
+
[code of conduct](./CODE_OF_CONDUCT.md).
|
data/exe/README.md
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
# format_output_demo
|
2
|
+
|
3
|
+
The format_output gem comes with the format_output_demo program. The source
|
4
|
+
code for that program is in this folder. This file shows the output of that
|
5
|
+
program:
|
6
|
+
|
7
|
+
A simple demo of the format_output gem in action.
|
8
|
+
|
9
|
+
|
10
|
+
Numbers, squares, and cubes.
|
11
|
+
|
12
|
+
0, 0, 0 7, 49, 343 14, 196, 2744 21, 441, 9261
|
13
|
+
1, 1, 1 8, 64, 512 15, 225, 3375 22, 484, 10648
|
14
|
+
2, 4, 8 9, 81, 729 16, 256, 4096 23, 529, 12167
|
15
|
+
3, 9, 27 10, 100, 1000 17, 289, 4913 24, 576, 13824
|
16
|
+
4, 16, 64 11, 121, 1331 18, 324, 5832
|
17
|
+
5, 25, 125 12, 144, 1728 19, 361, 6859
|
18
|
+
6, 36, 216 13, 169, 2197 20, 400, 8000
|
19
|
+
|
20
|
+
|
21
|
+
Word wrapping the Great Bard!
|
22
|
+
|
23
|
+
Wherefore rejoice? What conquest brings he home? What tributaries
|
24
|
+
follow him to Rome, to grace in captive bonds his chariot-wheels? You
|
25
|
+
blocks, you stones, you worse than senseless things!
|
26
|
+
|
27
|
+
|
28
|
+
And now some Bullet Points!
|
29
|
+
|
30
|
+
zero
|
31
|
+
* one with a (default) bullet.
|
32
|
+
two 2
|
33
|
+
three 3
|
34
|
+
more than two
|
35
|
+
more than one
|
36
|
+
more than zero
|
37
|
+
four 1 6 11 16 21 26 31 36 41 46 51 56 61 66 71 76 81 86 91 96
|
38
|
+
2 7 12 17 22 27 32 37 42 47 52 57 62 67 72 77 82 87 92 97
|
39
|
+
3 8 13 18 23 28 33 38 43 48 53 58 63 68 73 78 83 88 93 98
|
40
|
+
4 9 14 19 24 29 34 39 44 49 54 59 64 69 74 79 84 89 94 99
|
41
|
+
5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100
|
42
|
+
five I can see for miles and miles and more miles and yet more miles
|
43
|
+
and a lot of miles and damn more miles
|
@@ -0,0 +1,36 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# A demo of the format_output gem.
|
4
|
+
#
|
5
|
+
|
6
|
+
require_relative '..\lib\format_output'
|
7
|
+
|
8
|
+
puts "A simple demo of the format_output gem in action."
|
9
|
+
|
10
|
+
# Some simple number, squared, and cubed columns
|
11
|
+
column_data = Array.new(25) { |i| "#{i}, #{i*i}, #{i*i*i} " }
|
12
|
+
puts "", "", "Numbers, squares, and cubes.", ""
|
13
|
+
column_data.puts_format_output_columns(width: 72)
|
14
|
+
|
15
|
+
# Maybe (word) wrap your head around a little Shakespear?
|
16
|
+
long_text = "Wherefore rejoice? What conquest brings he home? What tributaries follow him to Rome, to grace in captive bonds his chariot-wheels? You blocks, you stones, you worse than senseless things!"
|
17
|
+
puts "", "", "Word wrapping the Great Bard!", ""
|
18
|
+
long_text.puts_format_output_word_wrap(width: 72)
|
19
|
+
|
20
|
+
# And now to dodge a bullet (point) or twelve!
|
21
|
+
|
22
|
+
demo = [
|
23
|
+
[],
|
24
|
+
["zero", []],
|
25
|
+
["zero", nil],
|
26
|
+
["zero", ""],
|
27
|
+
["one with a (default) bullet."],
|
28
|
+
["two", 2],
|
29
|
+
["three", 3, "more than two", "more than one", "more than zero"],
|
30
|
+
["four", (1..100).to_a],
|
31
|
+
['five', "I can see for miles and miles and more miles and yet more miles and a lot of miles and damn more miles"],
|
32
|
+
]
|
33
|
+
|
34
|
+
puts "", "", "And now some Bullet Points!", ""
|
35
|
+
|
36
|
+
demo.puts_format_output_bullets(width: 72)
|
@@ -0,0 +1,32 @@
|
|
1
|
+
lib = File.expand_path("../lib", __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require "format_output/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "format_output"
|
7
|
+
spec.version = FormatOutput::VERSION
|
8
|
+
spec.authors = ["PeterCamilleri"]
|
9
|
+
spec.email = ["peter.c.camilleri@gmail.com"]
|
10
|
+
|
11
|
+
spec.summary = %q{Formatted output to the console or strings.}
|
12
|
+
spec.description = %q{Formatted bullet points, columns, or word wrap to the console or strings.}
|
13
|
+
spec.homepage = "https://github.com/PeterCamilleri/format_output"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
17
|
+
f.match(%r{^(test|docs)/})
|
18
|
+
end
|
19
|
+
spec.bindir = "exe"
|
20
|
+
spec.executables = spec
|
21
|
+
.files
|
22
|
+
.reject { |f| f.downcase == 'exe/readme.md'}
|
23
|
+
.grep(%r{^exe/}) { |f| File.basename(f) }
|
24
|
+
spec.require_paths = ["lib"]
|
25
|
+
|
26
|
+
spec.add_development_dependency "bundler", "~> 1.17"
|
27
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
28
|
+
spec.add_development_dependency "minitest", "~> 5.0"
|
29
|
+
spec.add_development_dependency 'minitest_visible', "~> 0.1"
|
30
|
+
spec.add_development_dependency 'reek', "~> 5.0.2"
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
# Print out bullet points.
|
4
|
+
module FormatOutput
|
5
|
+
|
6
|
+
# A class to build bullet points for display.
|
7
|
+
class BulletPointBuilder
|
8
|
+
|
9
|
+
# Prepare a blank slate.
|
10
|
+
def initialize(options)
|
11
|
+
@body = ::FormatOutput.width(options)
|
12
|
+
@pad = ::FormatOutput.pad(options)
|
13
|
+
@bullet_data = []
|
14
|
+
@key_length = nil
|
15
|
+
end
|
16
|
+
|
17
|
+
# Add items to these bullet points.
|
18
|
+
def add(bullet, *items)
|
19
|
+
items.each do |item|
|
20
|
+
@bullet_data << [bullet.to_s, item]
|
21
|
+
bullet = ""
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Render the bullet points as an array of strings.
|
26
|
+
def render
|
27
|
+
@key_length, results = get_key_length, []
|
28
|
+
|
29
|
+
@bullet_data.each do |key, item|
|
30
|
+
results.concat(render_bullet(key, item))
|
31
|
+
end
|
32
|
+
|
33
|
+
@bullet_data = []
|
34
|
+
results
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
# Allowing for a trailing space, how large is the largest bullet?
|
40
|
+
def get_key_length
|
41
|
+
(@bullet_data.max_by {|line| line[0].length})[0].length + 1
|
42
|
+
end
|
43
|
+
|
44
|
+
# Render one bullet point.
|
45
|
+
# Returns: An array of strings, formatted as: bullet details
|
46
|
+
# more details
|
47
|
+
# more etc
|
48
|
+
def render_bullet(key, item)
|
49
|
+
result = []
|
50
|
+
|
51
|
+
item.format_output_bullet_detail(width: @body - @key_length - 1, left: 0).each do |desc_line|
|
52
|
+
result << @pad + key.ljust(@key_length) + desc_line
|
53
|
+
key = ""
|
54
|
+
end
|
55
|
+
|
56
|
+
result
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
# Print out data in neat columns.
|
4
|
+
module FormatOutput
|
5
|
+
|
6
|
+
# A class to build columns for display.
|
7
|
+
class ColumnBuilder
|
8
|
+
|
9
|
+
# Prepare a blank page.
|
10
|
+
def initialize(options)
|
11
|
+
@body = ::FormatOutput.body(options)
|
12
|
+
@pad = ::FormatOutput.pad(options)
|
13
|
+
@page_data = []
|
14
|
+
end
|
15
|
+
|
16
|
+
# Add an item to this page.
|
17
|
+
# Returns: The number of items that did not fit in the page.
|
18
|
+
def add(raw_item)
|
19
|
+
item = raw_item.to_s
|
20
|
+
fail "Item too large to fit." unless item.length < @body
|
21
|
+
|
22
|
+
if (column = find_next_column)
|
23
|
+
@page_data[column] << item
|
24
|
+
else
|
25
|
+
@page_data << [item]
|
26
|
+
end
|
27
|
+
|
28
|
+
adjust_configuration
|
29
|
+
end
|
30
|
+
|
31
|
+
# Render the page as an array of strings.
|
32
|
+
def render
|
33
|
+
results, column_widths = [], get_column_widths
|
34
|
+
|
35
|
+
rows.times { |row_index| results << render_row(row_index, column_widths)}
|
36
|
+
|
37
|
+
@page_data.clear
|
38
|
+
results
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
# Get the widths of all columns
|
44
|
+
def get_column_widths
|
45
|
+
@page_data.map {|column| column.format_output_greatest_width}
|
46
|
+
end
|
47
|
+
|
48
|
+
# Render a single row of data.
|
49
|
+
# Returns: A string.
|
50
|
+
def render_row(row_index, widths)
|
51
|
+
@pad + @page_data.each_with_index.map do |column, index|
|
52
|
+
column[row_index].to_s.ljust(widths[index])
|
53
|
+
end.join(" ")
|
54
|
+
end
|
55
|
+
|
56
|
+
# Make sure the page fits within its boundaries.
|
57
|
+
def adjust_configuration
|
58
|
+
while total_width >= @body
|
59
|
+
add_a_row
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Add a row to the page, moving items as needed.
|
64
|
+
def add_a_row
|
65
|
+
new_rows = rows + 1
|
66
|
+
pool, @page_data = @page_data.flatten, []
|
67
|
+
|
68
|
+
until pool.empty?
|
69
|
+
@page_data << pool.shift(new_rows)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Compute the total width of all of the columns.
|
74
|
+
# Returns: The sum of the widths of the widest items of each column plus
|
75
|
+
# a space between each of those columns.
|
76
|
+
def total_width
|
77
|
+
if empty?
|
78
|
+
0
|
79
|
+
else
|
80
|
+
#The starting point, @page_data.length-1, represents the spaces needed
|
81
|
+
#between the columns. So N columns means N-1 spaces.
|
82
|
+
@page_data.inject(@page_data.length-1) do |sum, column|
|
83
|
+
sum + column.format_output_greatest_width
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Does the data fit on the page?
|
89
|
+
def fits?
|
90
|
+
total_width < @body
|
91
|
+
end
|
92
|
+
|
93
|
+
# How many rows are currently in this page?
|
94
|
+
def rows
|
95
|
+
empty? ? 0 : @page_data[0].length
|
96
|
+
end
|
97
|
+
|
98
|
+
# Is this page empty?
|
99
|
+
def empty?
|
100
|
+
@page_data.empty?
|
101
|
+
end
|
102
|
+
|
103
|
+
# Which column will receive the next item?
|
104
|
+
# Returns: The index of the first non-filled column or nil if none found.
|
105
|
+
def find_next_column
|
106
|
+
(1...(@page_data.length)).each do |index|
|
107
|
+
if @page_data[index].length < @page_data[index-1].length
|
108
|
+
return index
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
nil
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
# Support for displaying an array formatted neatly.
|
4
|
+
# Output as bullet points starts with an array as input.
|
5
|
+
class Array
|
6
|
+
|
7
|
+
# Print out the array as bullet points.
|
8
|
+
def puts_format_output_bullets(options = {})
|
9
|
+
puts format_output_bullets(options)
|
10
|
+
end
|
11
|
+
|
12
|
+
# Convert the array to a string with bullet points.
|
13
|
+
# Returns: A string.
|
14
|
+
def format_output_bullets(options = {})
|
15
|
+
format_output_raw_bullets(options).join("\n")
|
16
|
+
end
|
17
|
+
|
18
|
+
# Convert the array to strings with bullet points.
|
19
|
+
# Returns: An array of strings.
|
20
|
+
def format_output_raw_bullets(options = {})
|
21
|
+
return [""] if empty?
|
22
|
+
|
23
|
+
builder = FormatOutput::BulletPointBuilder.new(options)
|
24
|
+
|
25
|
+
each {|pair| builder.add(*pair.format_output_prepare_bullet_detail)}
|
26
|
+
|
27
|
+
builder.render
|
28
|
+
end
|
29
|
+
|
30
|
+
# Helper methods for the BulletPointBuilder
|
31
|
+
|
32
|
+
# This method is a duplicate of a column method with a new name.
|
33
|
+
alias :format_output_bullet_detail :format_output_raw_columns
|
34
|
+
|
35
|
+
# Get data ready for being in a bullet point.
|
36
|
+
def format_output_prepare_bullet_detail
|
37
|
+
if length < 2
|
38
|
+
["*", self[0]]
|
39
|
+
else
|
40
|
+
self
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
# Support for displaying data formatted neatly.
|
47
|
+
class Object
|
48
|
+
|
49
|
+
# Create a bullet point description from this object.
|
50
|
+
# Returns: An array of strings.
|
51
|
+
def format_output_bullet_detail(options = {})
|
52
|
+
self.to_s.format_output_bullet_detail(options)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Get data ready for being in a bullet point.
|
56
|
+
def format_output_prepare_bullet_detail
|
57
|
+
["*", self]
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
# Support for displaying nothing formatted neatly.
|
63
|
+
class NilClass
|
64
|
+
|
65
|
+
# Create a bullet point description from nothing.
|
66
|
+
# Returns: An array of nothing.
|
67
|
+
def format_output_bullet_detail(_options = nil)
|
68
|
+
[]
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
# Support for displaying string data formatted in bullet points.
|
74
|
+
class String
|
75
|
+
|
76
|
+
# Create a bullet point description from this string.
|
77
|
+
# Returns: An array of strings.
|
78
|
+
def format_output_bullet_detail(options = {})
|
79
|
+
body = ::FormatOutput.width(options)
|
80
|
+
pad = ::FormatOutput.pad(options)
|
81
|
+
|
82
|
+
do_format_output_bullet_detail(split(' ').each, body, pad)
|
83
|
+
end
|
84
|
+
|
85
|
+
# Do the formatting legwork.
|
86
|
+
# Returns: An array of strings.
|
87
|
+
def do_format_output_bullet_detail(input, body, pad)
|
88
|
+
buffer, build, empty = [], "", false
|
89
|
+
|
90
|
+
# Grab "words" of input, splitting off lines as needed.
|
91
|
+
# Note: This loop exits when input.next runs out of data.
|
92
|
+
loop do
|
93
|
+
build = build.format_output_split_if_over(buffer, body, pad, input.next)
|
94
|
+
.format_output_split_if_huge(buffer, body, pad)
|
95
|
+
|
96
|
+
empty = build.empty?
|
97
|
+
end
|
98
|
+
|
99
|
+
unless empty
|
100
|
+
buffer << pad + build
|
101
|
+
end
|
102
|
+
|
103
|
+
buffer
|
104
|
+
end
|
105
|
+
|
106
|
+
# Split if adding a word goes over a little.
|
107
|
+
# Note: self is the build string from do_format_output_bullet_detail.
|
108
|
+
# Returns: A string.
|
109
|
+
def format_output_split_if_over(buffer, body, pad, word)
|
110
|
+
word.prepend(" ") unless empty? #Add a space except for the first word.
|
111
|
+
|
112
|
+
word_len = word.length
|
113
|
+
|
114
|
+
if (length + word_len) >= body && word_len < body
|
115
|
+
buffer << pad + self # Line done, add to buffer.
|
116
|
+
word.lstrip # Start of a new line, remove the leading space.
|
117
|
+
else
|
118
|
+
self + word
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
# Split up a overlong blob of text.
|
123
|
+
# Note: self is the result string from format_output_split_if_over.
|
124
|
+
# Returns: A string.
|
125
|
+
def format_output_split_if_huge(buffer, body, pad)
|
126
|
+
|
127
|
+
# Slice away any excess text into lines in the buffer.
|
128
|
+
while length >= body
|
129
|
+
buffer << pad + slice!(0, body)
|
130
|
+
end
|
131
|
+
|
132
|
+
self
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
# Support for displaying an array formatted neatly.
|
4
|
+
# Output as columns starts with an array as input.
|
5
|
+
class Array
|
6
|
+
|
7
|
+
# Print out the array with efficient columns.
|
8
|
+
def puts_format_output_columns(options = {})
|
9
|
+
puts format_output_columns(options)
|
10
|
+
end
|
11
|
+
|
12
|
+
# Convert the array to a string with efficient columns.
|
13
|
+
# Returns: A string.
|
14
|
+
# Endemic Code Smells reek:FeatureEnvy -- false positive.
|
15
|
+
def format_output_columns(options = {})
|
16
|
+
format_output_raw_columns(options).join("\n")
|
17
|
+
end
|
18
|
+
|
19
|
+
# Convert the array to strings with efficient columns.
|
20
|
+
# Returns: An array of strings.
|
21
|
+
def format_output_raw_columns(options = {})
|
22
|
+
builder = FormatOutput::ColumnBuilder.new(options)
|
23
|
+
|
24
|
+
each {|item| builder.add(item)}
|
25
|
+
|
26
|
+
builder.render
|
27
|
+
end
|
28
|
+
|
29
|
+
# Helper methods for the ColumnBuilder
|
30
|
+
|
31
|
+
# Get the widest element of an array.
|
32
|
+
# Returns: The width of the widest string in the array.
|
33
|
+
def format_output_greatest_width
|
34
|
+
max_by {|item| item.length}.length
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
# Support for displaying an array of strings formatted with word wrap.
|
4
|
+
class Array
|
5
|
+
|
6
|
+
# Print out the array with word wrap.
|
7
|
+
def puts_format_output_word_wrap(options = {})
|
8
|
+
puts format_output_word_wrap(options).join("\n")
|
9
|
+
end
|
10
|
+
|
11
|
+
# Convert the array to a string with bullet points.
|
12
|
+
# Returns: A string.
|
13
|
+
def format_output_word_wrap(options = {})
|
14
|
+
format_output_raw_word_wrap(options).join("\n")
|
15
|
+
end
|
16
|
+
|
17
|
+
# Returns: An array of strings.
|
18
|
+
# This method is a duplicate of a bullet point method with a new name.
|
19
|
+
def format_output_raw_word_wrap(options = {})
|
20
|
+
result = []
|
21
|
+
|
22
|
+
each do |item|
|
23
|
+
result.concat(item.to_s.format_output_raw_word_wrap(options))
|
24
|
+
result << ""
|
25
|
+
end
|
26
|
+
|
27
|
+
result
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
# Support for displaying string data formatted with word wrap.
|
33
|
+
class String
|
34
|
+
|
35
|
+
# Print out the string with word wrap.
|
36
|
+
def puts_format_output_word_wrap(options = {})
|
37
|
+
puts format_output_word_wrap(options)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Convert the string to a string with bullet points.
|
41
|
+
# Returns: A string.
|
42
|
+
def format_output_word_wrap(options = {})
|
43
|
+
format_output_raw_word_wrap(options).join("\n")
|
44
|
+
end
|
45
|
+
|
46
|
+
# Convert the string to an array of strings with word wrap.
|
47
|
+
# Returns: An array of strings.
|
48
|
+
# This method is a duplicate of a bullet point method with a new name.
|
49
|
+
alias :format_output_raw_word_wrap :format_output_bullet_detail
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require_relative "format_output/columns"
|
4
|
+
require_relative "format_output/bullets"
|
5
|
+
require_relative "format_output/word_wrap"
|
6
|
+
|
7
|
+
require_relative "format_output/builders/bullet_builder"
|
8
|
+
require_relative "format_output/builders/column_builder"
|
9
|
+
|
10
|
+
require_relative "format_output/version"
|
11
|
+
|
12
|
+
# The format output facility. Neat columns and bullet points for all!
|
13
|
+
module FormatOutput
|
14
|
+
|
15
|
+
# Some property variables.
|
16
|
+
@width = 80
|
17
|
+
@left = 0
|
18
|
+
@right = 0
|
19
|
+
|
20
|
+
class << self
|
21
|
+
|
22
|
+
# Get the full page width.
|
23
|
+
def width(options = {})
|
24
|
+
(options[:width] || @width).to_i
|
25
|
+
end
|
26
|
+
|
27
|
+
# Set the full page width.
|
28
|
+
def width=(value)
|
29
|
+
@width = value.to_i
|
30
|
+
end
|
31
|
+
|
32
|
+
# Get the working page width.
|
33
|
+
def body(options = {})
|
34
|
+
width(options) - (left(options) + right(options))
|
35
|
+
end
|
36
|
+
|
37
|
+
# Set the working page width.
|
38
|
+
# Note always set after left and right are set.
|
39
|
+
def body=(value)
|
40
|
+
@width = value.to_i + @left + @right
|
41
|
+
end
|
42
|
+
|
43
|
+
# Get the left margin
|
44
|
+
def left(options = {})
|
45
|
+
(options[:left] || @left).to_i
|
46
|
+
end
|
47
|
+
|
48
|
+
# Set the left margin
|
49
|
+
def left=(value)
|
50
|
+
@left = value.to_i
|
51
|
+
end
|
52
|
+
|
53
|
+
# Get the left margin
|
54
|
+
def right(options = {})
|
55
|
+
(options[:right] || @right).to_i
|
56
|
+
end
|
57
|
+
|
58
|
+
# Set the right margin
|
59
|
+
def right=(value)
|
60
|
+
@right = value.to_i
|
61
|
+
end
|
62
|
+
|
63
|
+
# The left margin pad string.
|
64
|
+
def pad(options = {})
|
65
|
+
" " * left(options)
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
data/rakefile.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rake/testtask"
|
3
|
+
|
4
|
+
Rake::TestTask.new(:test) do |t|
|
5
|
+
t.libs << "test"
|
6
|
+
t.libs << "lib"
|
7
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
8
|
+
end
|
9
|
+
|
10
|
+
task :default => :test
|
11
|
+
|
12
|
+
desc "What version of format_output is this?"
|
13
|
+
task :vers do |t|
|
14
|
+
puts
|
15
|
+
puts "format_output version = #{::FormatOutput::VERSION}"
|
16
|
+
end
|
metadata
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: format_output
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- PeterCamilleri
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-12-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.17'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.17'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '5.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '5.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: minitest_visible
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.1'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.1'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: reek
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 5.0.2
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 5.0.2
|
83
|
+
description: Formatted bullet points, columns, or word wrap to the console or strings.
|
84
|
+
email:
|
85
|
+
- peter.c.camilleri@gmail.com
|
86
|
+
executables:
|
87
|
+
- format_output_demo
|
88
|
+
extensions: []
|
89
|
+
extra_rdoc_files: []
|
90
|
+
files:
|
91
|
+
- ".gitignore"
|
92
|
+
- CODE_OF_CONDUCT.md
|
93
|
+
- Gemfile
|
94
|
+
- LICENSE.txt
|
95
|
+
- README.md
|
96
|
+
- exe/README.md
|
97
|
+
- exe/format_output_demo
|
98
|
+
- format_output.gemspec
|
99
|
+
- lib/format_output.rb
|
100
|
+
- lib/format_output/builders/bullet_builder.rb
|
101
|
+
- lib/format_output/builders/column_builder.rb
|
102
|
+
- lib/format_output/bullets.rb
|
103
|
+
- lib/format_output/columns.rb
|
104
|
+
- lib/format_output/version.rb
|
105
|
+
- lib/format_output/word_wrap.rb
|
106
|
+
- rakefile.rb
|
107
|
+
homepage: https://github.com/PeterCamilleri/format_output
|
108
|
+
licenses:
|
109
|
+
- MIT
|
110
|
+
metadata: {}
|
111
|
+
post_install_message:
|
112
|
+
rdoc_options: []
|
113
|
+
require_paths:
|
114
|
+
- lib
|
115
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
116
|
+
requirements:
|
117
|
+
- - ">="
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: '0'
|
120
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
requirements: []
|
126
|
+
rubyforge_project:
|
127
|
+
rubygems_version: 2.5.2
|
128
|
+
signing_key:
|
129
|
+
specification_version: 4
|
130
|
+
summary: Formatted output to the console or strings.
|
131
|
+
test_files: []
|