fat_table 0.2.2
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 +22 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.org +2106 -0
- data/README.rdoc +1965 -0
- data/Rakefile +12 -0
- data/TODO.org +31 -0
- data/bin/ft_console +119 -0
- data/bin/setup +8 -0
- data/fat_table.gemspec +80 -0
- data/lib/fat_table.rb +225 -0
- data/lib/fat_table/column.rb +522 -0
- data/lib/fat_table/db_handle.rb +81 -0
- data/lib/fat_table/errors.rb +13 -0
- data/lib/fat_table/evaluator.rb +55 -0
- data/lib/fat_table/formatters.rb +7 -0
- data/lib/fat_table/formatters/aoa_formatter.rb +91 -0
- data/lib/fat_table/formatters/aoh_formatter.rb +91 -0
- data/lib/fat_table/formatters/formatter.rb +1248 -0
- data/lib/fat_table/formatters/latex_formatter.rb +208 -0
- data/lib/fat_table/formatters/org_formatter.rb +72 -0
- data/lib/fat_table/formatters/term_formatter.rb +297 -0
- data/lib/fat_table/formatters/text_formatter.rb +92 -0
- data/lib/fat_table/table.rb +1322 -0
- data/lib/fat_table/version.rb +4 -0
- metadata +331 -0
@@ -0,0 +1,208 @@
|
|
1
|
+
module FatTable
|
2
|
+
# A subclass of Formatter for rendering the table as a LaTeX table. It allows
|
3
|
+
# foreground colors through LaTeX's xcolor package but ignores background
|
4
|
+
# colors. You can see the valid color names with LaTeXFormatter.valid_colors.
|
5
|
+
class LaTeXFormatter < Formatter
|
6
|
+
# Return a new LaTeXFormatter for +table+. You can set the following
|
7
|
+
# +options+ with hash-like parameters:
|
8
|
+
#
|
9
|
+
# document::
|
10
|
+
# if set to true, include a document preamble and wrap the output in a
|
11
|
+
# LaTeX document environment so that the output can be compiled by a LaTeX
|
12
|
+
# processor such as +pdflatex+. By default, only the table environment is
|
13
|
+
# output.
|
14
|
+
#
|
15
|
+
# environment::
|
16
|
+
# set to a string, by default 'longtable' that indicates what kind of
|
17
|
+
# LaTeX tabular-like environment to use for the table. The default is good
|
18
|
+
# for tables that might continue over multiple pages since it repeats the
|
19
|
+
# header at the top of each continuation page.
|
20
|
+
|
21
|
+
def initialize(table = Table.new, **options)
|
22
|
+
super
|
23
|
+
@options[:document] = options.fetch(:document, false)
|
24
|
+
@options[:environment] = options.fetch(:environment, 'longtable')
|
25
|
+
end
|
26
|
+
|
27
|
+
# Taken from the Rainbow gem's list of valid colors.
|
28
|
+
self.valid_colors = %w(
|
29
|
+
none black blue brown cyan darkgray gray green lightgray lime magenta
|
30
|
+
olive orange pink purple red teal violet white yellow AntiqueWhite1
|
31
|
+
AntiqueWhite2 AntiqueWhite3 AntiqueWhite4 Aquamarine1 Aquamarine2
|
32
|
+
Aquamarine3 Aquamarine4 Azure1 Azure2 Azure3 Azure4 Bisque1 Bisque2
|
33
|
+
Bisque3 Bisque4 Blue1 Blue2 Blue3 Blue4 Brown1 Brown2 Brown3 Brown4
|
34
|
+
Burlywood1 Burlywood2 Burlywood3 Burlywood4 CadetBlue1 CadetBlue2
|
35
|
+
CadetBlue3 CadetBlue4 Chartreuse1 Chartreuse2 Chartreuse3 Chartreuse4
|
36
|
+
Chocolate1 Chocolate2 Chocolate3 Chocolate4 Coral1 Coral2 Coral3 Coral4
|
37
|
+
Cornsilk1 Cornsilk2 Cornsilk3 Cornsilk4 Cyan1 Cyan2 Cyan3 Cyan4
|
38
|
+
DarkGoldenrod1 DarkGoldenrod2 DarkGoldenrod3 DarkGoldenrod4
|
39
|
+
DarkOliveGreen1 DarkOliveGreen2 DarkOliveGreen3 DarkOliveGreen4
|
40
|
+
DarkOrange1 DarkOrange2 DarkOrange3 DarkOrange4 DarkOrchid1 DarkOrchid2
|
41
|
+
DarkOrchid3 DarkOrchid4 DarkSeaGreen1 DarkSeaGreen2 DarkSeaGreen3
|
42
|
+
DarkSeaGreen4 DarkSlateGray1 DarkSlateGray2 DarkSlateGray3 DarkSlateGray4
|
43
|
+
DeepPink1 DeepPink2 DeepPink3 DeepPink4 DeepSkyBlue1 DeepSkyBlue2
|
44
|
+
DeepSkyBlue3 DeepSkyBlue4 DodgerBlue1 DodgerBlue2 DodgerBlue3 DodgerBlue4
|
45
|
+
Firebrick1 Firebrick2 Firebrick3 Firebrick4 Gold1 Gold2 Gold3 Gold4
|
46
|
+
Goldenrod1 Goldenrod2 Goldenrod3 Goldenrod4 Gray0 Green0 Green1 Green2
|
47
|
+
Green3 Green4 Grey0 Honeydew1 Honeydew2 Honeydew3 Honeydew4 HotPink1
|
48
|
+
HotPink2 HotPink3 HotPink4 IndianRed1 IndianRed2 IndianRed3 IndianRed4
|
49
|
+
Ivory1 Ivory2 Ivory3 Ivory4 Khaki1 Khaki2 Khaki3 Khaki4 LavenderBlush1
|
50
|
+
LavenderBlush2 LavenderBlush3 LavenderBlush4 LemonChiffon1 LemonChiffon2
|
51
|
+
LemonChiffon3 LemonChiffon4 LightBlue1 LightBlue2 LightBlue3 LightBlue4
|
52
|
+
LightCyan1 LightCyan2 LightCyan3 LightCyan4 LightGoldenrod1
|
53
|
+
LightGoldenrod2 LightGoldenrod3 LightGoldenrod4 LightPink1 LightPink2
|
54
|
+
LightPink3 LightPink4 LightSalmon1 LightSalmon2 LightSalmon3 LightSalmon4
|
55
|
+
LightSkyBlue1 LightSkyBlue2 LightSkyBlue3 LightSkyBlue4 LightSteelBlue1
|
56
|
+
LightSteelBlue2 LightSteelBlue3 LightSteelBlue4 LightYellow1 LightYellow2
|
57
|
+
LightYellow3 LightYellow4 Magenta1 Magenta2 Magenta3 Magenta4 Maroon0
|
58
|
+
Maroon1 Maroon2 Maroon3 Maroon4 MediumOrchid1 MediumOrchid2 MediumOrchid3
|
59
|
+
MediumOrchid4 MediumPurple1 MediumPurple2 MediumPurple3 MediumPurple4
|
60
|
+
MistyRose1 MistyRose2 MistyRose3 MistyRose4 NavajoWhite1 NavajoWhite2
|
61
|
+
NavajoWhite3 NavajoWhite4 OliveDrab1 OliveDrab2 OliveDrab3 OliveDrab4
|
62
|
+
Orange1 Orange2 Orange3 Orange4 OrangeRed1 OrangeRed2 OrangeRed3
|
63
|
+
OrangeRed4 Orchid1 Orchid2 Orchid3 Orchid4 PaleGreen1 PaleGreen2
|
64
|
+
PaleGreen3 PaleGreen4 PaleTurquoise1 PaleTurquoise2 PaleTurquoise3
|
65
|
+
PaleTurquoise4 PaleVioletRed1 PaleVioletRed2 PaleVioletRed3 PaleVioletRed4
|
66
|
+
PeachPuff1 PeachPuff2 PeachPuff3 PeachPuff4 Pink1 Pink2 Pink3 Pink4 Plum1
|
67
|
+
Plum2 Plum3 Plum4 Purple0 Purple1 Purple2 Purple3 Purple4 Red1 Red2 Red3
|
68
|
+
Red4 RosyBrown1 RosyBrown2 RosyBrown3 RosyBrown4 RoyalBlue1 RoyalBlue2
|
69
|
+
RoyalBlue3 RoyalBlue4 Salmon1 Salmon2 Salmon3 Salmon4 SeaGreen1 SeaGreen2
|
70
|
+
SeaGreen3 SeaGreen4 Seashell1 Seashell2 Seashell3 Seashell4 Sienna1
|
71
|
+
Sienna2 Sienna3 Sienna4 SkyBlue1 SkyBlue2 SkyBlue3 SkyBlue4 SlateBlue1
|
72
|
+
SlateBlue2 SlateBlue3 SlateBlue4 SlateGray1 SlateGray2 SlateGray3
|
73
|
+
SlateGray4 Snow1 Snow2 Snow3 Snow4 SpringGreen1 SpringGreen2 SpringGreen3
|
74
|
+
SpringGreen4 SteelBlue1 SteelBlue2 SteelBlue3 SteelBlue4 Tan1 Tan2 Tan3
|
75
|
+
Tan4 Thistle1 Thistle2 Thistle3 Thistle4 Tomato1 Tomato2 Tomato3 Tomato4
|
76
|
+
Turquoise1 Turquoise2 Turquoise3 Turquoise4 VioletRed1 VioletRed2
|
77
|
+
VioletRed3 VioletRed4 Wheat1 Wheat2 Wheat3 Wheat4 Yellow1 Yellow2 Yellow3
|
78
|
+
Yellow4
|
79
|
+
)
|
80
|
+
|
81
|
+
# LaTeX commands to load the needed packages based on the :environement
|
82
|
+
# option. For now, just handles the default 'longtable' :environment. The
|
83
|
+
# preamble always includes a command to load the xcolor package.
|
84
|
+
def preamble
|
85
|
+
result = ''
|
86
|
+
result +=
|
87
|
+
case @options[:environment]
|
88
|
+
when 'longtable'
|
89
|
+
"\\usepackage{longtable}\n"
|
90
|
+
else
|
91
|
+
''
|
92
|
+
end
|
93
|
+
result += "\\usepackage[pdftex,x11names]{xcolor}\n"
|
94
|
+
result
|
95
|
+
end
|
96
|
+
|
97
|
+
private
|
98
|
+
|
99
|
+
def color_valid?(clr)
|
100
|
+
valid_colors.include?(clr)
|
101
|
+
end
|
102
|
+
|
103
|
+
def invalid_color_msg(clr)
|
104
|
+
valid_colors_list = valid_colors.join(' ').wrap
|
105
|
+
"LaTeXFormatter invalid color '#{clr}'. Valid colors are:\n" +
|
106
|
+
valid_colors_list
|
107
|
+
end
|
108
|
+
|
109
|
+
# Add LaTeX control sequences. Ignore background color, underline, and
|
110
|
+
# blink. Alignment needs to be done by LaTeX, so we have to take it into
|
111
|
+
# account unless it's the same as the body alignment, since that is the
|
112
|
+
# default.
|
113
|
+
def decorate_string(str, istruct)
|
114
|
+
str = quote(str)
|
115
|
+
result = ''
|
116
|
+
result += '\\bfseries{}' if istruct.bold
|
117
|
+
result += '\\itshape{}' if istruct.italic
|
118
|
+
result += "\\color{#{istruct.color}}" if istruct.color && istruct.color != 'none'
|
119
|
+
result = "#{result}#{str}"
|
120
|
+
unless istruct.alignment == format_at[:body][istruct._h].alignment
|
121
|
+
ac = alignment_code(istruct.alignment)
|
122
|
+
result = "\\multicolumn{1}{#{ac}}{#{result}}"
|
123
|
+
end
|
124
|
+
result
|
125
|
+
end
|
126
|
+
|
127
|
+
# Return +str+ with quote marks oriented and special TeX characters quoted.
|
128
|
+
def quote(str)
|
129
|
+
# Replace single and double quotes with TeX oriented quotes.
|
130
|
+
result = str.gsub(/'([^']*)'/, "`\\1'")
|
131
|
+
result = result.gsub(/"([^"]*)"/, "``\\1''")
|
132
|
+
# Escape special TeX characters, such as $ and %
|
133
|
+
result.tex_quote
|
134
|
+
end
|
135
|
+
|
136
|
+
def pre_table
|
137
|
+
result = ''
|
138
|
+
if @options[:document]
|
139
|
+
result += "\\documentclass{article}\n"
|
140
|
+
result += preamble
|
141
|
+
result += "\\begin{document}\n"
|
142
|
+
end
|
143
|
+
result += "\\begin{#{@options[:environment]}}{"
|
144
|
+
table.headers.each do |h|
|
145
|
+
result += alignment_code(format_at[:body][h].alignment)
|
146
|
+
end
|
147
|
+
result += "}\n"
|
148
|
+
result
|
149
|
+
end
|
150
|
+
|
151
|
+
def post_table
|
152
|
+
result = "\\end{#{@options[:environment]}}\n"
|
153
|
+
result += "\\end{document}\n" if @options[:document]
|
154
|
+
result
|
155
|
+
end
|
156
|
+
|
157
|
+
def alignment_code(al_sym)
|
158
|
+
case al_sym
|
159
|
+
when :center
|
160
|
+
'c'
|
161
|
+
when :right
|
162
|
+
'r'
|
163
|
+
else
|
164
|
+
'l'
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def post_header(_widths)
|
169
|
+
"\\endhead\n"
|
170
|
+
end
|
171
|
+
|
172
|
+
def pre_row
|
173
|
+
''
|
174
|
+
end
|
175
|
+
|
176
|
+
def pre_cell(_h)
|
177
|
+
''
|
178
|
+
end
|
179
|
+
|
180
|
+
# We do quoting before applying decoration, so do not re-quote here. We
|
181
|
+
# will have LaTeX commands in v.
|
182
|
+
def quote_cell(v)
|
183
|
+
v
|
184
|
+
end
|
185
|
+
|
186
|
+
def post_cell
|
187
|
+
''
|
188
|
+
end
|
189
|
+
|
190
|
+
def inter_cell
|
191
|
+
"&\n"
|
192
|
+
end
|
193
|
+
|
194
|
+
def post_row
|
195
|
+
"\\\\\n"
|
196
|
+
end
|
197
|
+
|
198
|
+
# Hlines look to busy in a printed table
|
199
|
+
def hline(_widths)
|
200
|
+
''
|
201
|
+
end
|
202
|
+
|
203
|
+
# Hlines look too busy in a printed table
|
204
|
+
def post_footers(_widths)
|
205
|
+
''
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module FatTable
|
2
|
+
# Output the table in the same way as org-mode for emacs does. This is almost
|
3
|
+
# identical to TextFormatter except that dates do get formatted as inactive
|
4
|
+
# timestamps and the connector at the beginning of hlines is a '|' rather than
|
5
|
+
# a '+' as for text tables.
|
6
|
+
class OrgFormatter < Formatter
|
7
|
+
|
8
|
+
self.default_format = default_format.dup
|
9
|
+
self.default_format[:date_fmt] = '[%F]'
|
10
|
+
self.default_format[:datetime_fmt] = '[%F %a %H:%M:%S]'
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
# Does this Formatter require a second pass over the cells to align the
|
15
|
+
# columns according to the alignment formatting instruction to the width of
|
16
|
+
# the widest cell in each column?
|
17
|
+
def aligned?
|
18
|
+
true
|
19
|
+
end
|
20
|
+
|
21
|
+
def pre_header(widths)
|
22
|
+
result = '|'
|
23
|
+
widths.values.each do |w|
|
24
|
+
result += '-' * (w + 2) + '+'
|
25
|
+
end
|
26
|
+
result[-1] = '|'
|
27
|
+
result + "\n"
|
28
|
+
end
|
29
|
+
|
30
|
+
def pre_row
|
31
|
+
'|'
|
32
|
+
end
|
33
|
+
|
34
|
+
def pre_cell(_h)
|
35
|
+
''
|
36
|
+
end
|
37
|
+
|
38
|
+
def quote_cell(v)
|
39
|
+
v
|
40
|
+
end
|
41
|
+
|
42
|
+
def post_cell
|
43
|
+
''
|
44
|
+
end
|
45
|
+
|
46
|
+
def inter_cell
|
47
|
+
'|'
|
48
|
+
end
|
49
|
+
|
50
|
+
def post_row
|
51
|
+
"|\n"
|
52
|
+
end
|
53
|
+
|
54
|
+
def hline(widths)
|
55
|
+
result = '|'
|
56
|
+
widths.values.each do |w|
|
57
|
+
result += '-' * (w + 2) + '+'
|
58
|
+
end
|
59
|
+
result[-1] = '|'
|
60
|
+
result + "\n"
|
61
|
+
end
|
62
|
+
|
63
|
+
def post_footers(widths)
|
64
|
+
result = '|'
|
65
|
+
widths.values.each do |w|
|
66
|
+
result += '-' * (w + 2) + '+'
|
67
|
+
end
|
68
|
+
result[-1] = '|'
|
69
|
+
result + "\n"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,297 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'rainbow'
|
4
|
+
|
5
|
+
module FatTable
|
6
|
+
# Output the table as for a unicode-enabled ANSI terminal. This makes table
|
7
|
+
# gridlines drawable with unicode characters, as well as supporting colored
|
8
|
+
# text and backgrounds, and blink, and underline attributes. See
|
9
|
+
# TermFormatter.valid_colors for an Array of valid colors that you can use.
|
10
|
+
# The extent to which all of these are actually supported depends on your
|
11
|
+
# terminal. TermFormatter uses the +rainbow+ gem for forming colored strings.
|
12
|
+
# Use a
|
13
|
+
class TermFormatter < Formatter
|
14
|
+
# Return a new TermFormatter for +table+. You can set a few +options+ with
|
15
|
+
# the following hash-like parameters:
|
16
|
+
#
|
17
|
+
# unicode::
|
18
|
+
# if set true, use unicode characters to form the frame of the table on
|
19
|
+
# output; if set false, use ASCII characters for the frame. By default,
|
20
|
+
# this is true.
|
21
|
+
#
|
22
|
+
# framecolor::
|
23
|
+
# set to a string of the form '<color>' or '<color.color>' to set the
|
24
|
+
# color of the frame or the color and background color. By default, the
|
25
|
+
# framecolor is set to 'none.none', meaning that the normal terminal
|
26
|
+
# foreground and background colors will be used for the frame.
|
27
|
+
def initialize(table = Table.new, **options)
|
28
|
+
super
|
29
|
+
@options[:unicode] = options.fetch(:unicode, true)
|
30
|
+
@options[:framecolor] = options.fetch(:framecolor, 'none.none')
|
31
|
+
return unless @options[:framecolor] =~ /([-_a-zA-Z]*)(\.([-_a-zA-Z]*))/
|
32
|
+
@options[:frame_fg] = $1.downcase unless $1.blank?
|
33
|
+
@options[:frame_bg] = $3.downcase unless $3.blank?
|
34
|
+
end
|
35
|
+
|
36
|
+
# Valid colors for ANSI terminal using the rainbow gem's X11ColorNames.
|
37
|
+
self.valid_colors = ['none'] +
|
38
|
+
::Rainbow::X11ColorNames::NAMES.keys.map(&:to_s).sort
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def color_valid?(clr)
|
43
|
+
valid_colors.include?(clr)
|
44
|
+
end
|
45
|
+
|
46
|
+
def invalid_color_msg(clr)
|
47
|
+
valid_colors_list = valid_colors.join(' ').wrap
|
48
|
+
"TermFormatter invalid color '#{clr}'. Valid colors are:\n" +
|
49
|
+
valid_colors_list
|
50
|
+
end
|
51
|
+
|
52
|
+
# Compute the width of the string as displayed, taking into account the
|
53
|
+
# characteristics of the target device. For example, a colored string
|
54
|
+
# should not include in the width terminal control characters that simply
|
55
|
+
# change the color without occupying any space. Thus, this method must be
|
56
|
+
# overridden in a subclass if a simple character count does not reflect the
|
57
|
+
# width as displayed.
|
58
|
+
def width(str)
|
59
|
+
strip_ansi(str).length
|
60
|
+
end
|
61
|
+
|
62
|
+
def strip_ansi(str)
|
63
|
+
str&.gsub(/\e\[[0-9;]+m/, '')
|
64
|
+
end
|
65
|
+
|
66
|
+
# Add ANSI codes to string to implement the given decorations
|
67
|
+
def decorate_string(str, istruct)
|
68
|
+
result = Rainbow(str)
|
69
|
+
result = colorize(result, istruct.color, istruct.bgcolor)
|
70
|
+
result = result.bold if istruct.bold
|
71
|
+
result = result.italic if istruct.italic
|
72
|
+
result = result.underline if istruct.underline
|
73
|
+
result = result.blink if istruct.blink
|
74
|
+
result
|
75
|
+
end
|
76
|
+
|
77
|
+
def colorize(str, fg, bg)
|
78
|
+
fg = nil if fg == 'none'
|
79
|
+
bg = nil if bg == 'none'
|
80
|
+
return str unless fg || bg
|
81
|
+
result = Rainbow(str)
|
82
|
+
if fg
|
83
|
+
fg = fg.tr(' ', '').downcase.as_sym
|
84
|
+
result = result.color(fg) if fg
|
85
|
+
end
|
86
|
+
if bg
|
87
|
+
bg = bg.tr(' ', '').downcase.as_sym
|
88
|
+
result = result.bg(bg) if bg
|
89
|
+
end
|
90
|
+
result
|
91
|
+
end
|
92
|
+
|
93
|
+
# Colorize frame components
|
94
|
+
def frame_colorize(str)
|
95
|
+
colorize(str, @options[:frame_fg], @options[:frame_bg])
|
96
|
+
end
|
97
|
+
|
98
|
+
# :stopdoc:
|
99
|
+
# Unicode line-drawing characters. We use double lines before and after the
|
100
|
+
# table and single lines for the sides and hlines between groups and
|
101
|
+
# footers.
|
102
|
+
UPPER_LEFT = "\u2552".freeze
|
103
|
+
UPPER_RIGHT = "\u2555".freeze
|
104
|
+
DOUBLE_RULE = "\u2550".freeze
|
105
|
+
UPPER_TEE = "\u2564".freeze
|
106
|
+
VERTICAL_RULE = "\u2502".freeze
|
107
|
+
LEFT_TEE = "\u251C".freeze
|
108
|
+
HORIZONTAL_RULE = "\u2500".freeze
|
109
|
+
SINGLE_CROSS = "\u253C".freeze
|
110
|
+
RIGHT_TEE = "\u2524".freeze
|
111
|
+
LOWER_LEFT = "\u2558".freeze
|
112
|
+
LOWER_RIGHT = "\u255B".freeze
|
113
|
+
LOWER_TEE = "\u2567".freeze
|
114
|
+
# :startdoc:
|
115
|
+
|
116
|
+
def upper_left
|
117
|
+
if options[:unicode]
|
118
|
+
UPPER_LEFT
|
119
|
+
else
|
120
|
+
'+'
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def upper_right
|
125
|
+
if options[:unicode]
|
126
|
+
UPPER_RIGHT
|
127
|
+
else
|
128
|
+
'+'
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def double_rule
|
133
|
+
if options[:unicode]
|
134
|
+
DOUBLE_RULE
|
135
|
+
else
|
136
|
+
'='
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def upper_tee
|
141
|
+
if options[:unicode]
|
142
|
+
UPPER_TEE
|
143
|
+
else
|
144
|
+
'+'
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def vertical_rule
|
149
|
+
if options[:unicode]
|
150
|
+
VERTICAL_RULE
|
151
|
+
else
|
152
|
+
'|'
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def left_tee
|
157
|
+
if options[:unicode]
|
158
|
+
LEFT_TEE
|
159
|
+
else
|
160
|
+
'+'
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def horizontal_rule
|
165
|
+
if options[:unicode]
|
166
|
+
HORIZONTAL_RULE
|
167
|
+
else
|
168
|
+
'-'
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def single_cross
|
173
|
+
if options[:unicode]
|
174
|
+
SINGLE_CROSS
|
175
|
+
else
|
176
|
+
'+'
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def right_tee
|
181
|
+
if options[:unicode]
|
182
|
+
RIGHT_TEE
|
183
|
+
else
|
184
|
+
'+'
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
def lower_left
|
189
|
+
if options[:unicode]
|
190
|
+
LOWER_LEFT
|
191
|
+
else
|
192
|
+
'+'
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
def lower_right
|
197
|
+
if options[:unicode]
|
198
|
+
LOWER_RIGHT
|
199
|
+
else
|
200
|
+
'+'
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
def lower_tee
|
205
|
+
if options[:unicode]
|
206
|
+
LOWER_TEE
|
207
|
+
else
|
208
|
+
'+'
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
# Does this Formatter require a second pass over the cells to align the
|
213
|
+
# columns according to the alignment formatting instruction to the width of
|
214
|
+
# the widest cell in each column?
|
215
|
+
def aligned?
|
216
|
+
true
|
217
|
+
end
|
218
|
+
|
219
|
+
def pre_header(widths)
|
220
|
+
result = upper_left
|
221
|
+
widths.values.each do |w|
|
222
|
+
result += double_rule * (w + 2) + upper_tee
|
223
|
+
end
|
224
|
+
result[-1] = upper_right
|
225
|
+
result = colorize(result, @options[:frame_fg], @options[:frame_bg])
|
226
|
+
result + "\n"
|
227
|
+
end
|
228
|
+
|
229
|
+
def pre_row
|
230
|
+
frame_colorize(vertical_rule)
|
231
|
+
end
|
232
|
+
|
233
|
+
def pre_cell(_h)
|
234
|
+
''
|
235
|
+
end
|
236
|
+
|
237
|
+
def quote_cell(v)
|
238
|
+
v
|
239
|
+
end
|
240
|
+
|
241
|
+
def post_cell
|
242
|
+
''
|
243
|
+
end
|
244
|
+
|
245
|
+
def inter_cell
|
246
|
+
frame_colorize(vertical_rule)
|
247
|
+
end
|
248
|
+
|
249
|
+
def post_row
|
250
|
+
frame_colorize(vertical_rule) + "\n"
|
251
|
+
end
|
252
|
+
|
253
|
+
def hline(widths)
|
254
|
+
result = left_tee
|
255
|
+
widths.values.each do |w|
|
256
|
+
result += horizontal_rule * (w + 2) + single_cross
|
257
|
+
end
|
258
|
+
result[-1] = right_tee
|
259
|
+
result = frame_colorize(result)
|
260
|
+
result + "\n"
|
261
|
+
end
|
262
|
+
|
263
|
+
def pre_group
|
264
|
+
''
|
265
|
+
end
|
266
|
+
|
267
|
+
def post_group
|
268
|
+
''
|
269
|
+
end
|
270
|
+
|
271
|
+
def pre_gfoot
|
272
|
+
''
|
273
|
+
end
|
274
|
+
|
275
|
+
def post_gfoot
|
276
|
+
''
|
277
|
+
end
|
278
|
+
|
279
|
+
def pre_foot
|
280
|
+
''
|
281
|
+
end
|
282
|
+
|
283
|
+
def post_foot
|
284
|
+
''
|
285
|
+
end
|
286
|
+
|
287
|
+
def post_footers(widths)
|
288
|
+
result = lower_left
|
289
|
+
widths.values.each do |w|
|
290
|
+
result += double_rule * (w + 2) + lower_tee
|
291
|
+
end
|
292
|
+
result[-1] = lower_right
|
293
|
+
result = frame_colorize(result)
|
294
|
+
result + "\n"
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|