markdown-tables 0.0.1 → 0.0.3
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 +4 -4
- data/lib/markdown-tables.rb +146 -79
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ce5cc9285eabf5477a6520866af564cd1d8f90b6
|
4
|
+
data.tar.gz: 73042b5f303ff8d1c703a67d62244937206845f1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0d8a6a6fa9cd1029568c54c2e6da2d0145c5b06f6a9a0f68c9e09240bc0d3c6d4c26533d4c676a1f91385294893da1f6eab01e9affc0e6730e6c90079af52f54
|
7
|
+
data.tar.gz: 56ac0af7a9e34b01ae7f2dfb0a2dd7c285cb06f9d3a86434268d4299aad09346004074411c04eafd7edc16ddd7ef1572c5797b69588851f3eeec33906685280a
|
data/lib/markdown-tables.rb
CHANGED
@@ -1,89 +1,156 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
1
|
+
class MarkdownTables
|
2
|
+
|
3
|
+
# Generate a Markdown table.
|
4
|
+
# labels and data are one and two-dimensional arrays, respectively.
|
5
|
+
# All input must have a to_s method.
|
6
|
+
# Pass align: 'l' for left alignment or 'r' for right alignment. Anything
|
7
|
+
# else will result in cells being centered. Pass an array of align values
|
8
|
+
# to specify alignment per column.
|
9
|
+
# If is_rows is true, then each sub-array represents a row.
|
10
|
+
# Conversely, if is_rows is false, each sub-array of data represents a column.
|
11
|
+
# Empty cells can be given with nil or an empty string.
|
12
|
+
def self.make_table(labels, data, align: '', is_rows: false)
|
13
|
+
labels = Marshal.load(Marshal.dump(labels))
|
14
|
+
data = Marshal.load(Marshal.dump(data))
|
15
|
+
validate(labels, data, align, is_rows)
|
16
|
+
sanitize!(labels, data)
|
17
|
+
|
18
|
+
header_line = labels.join('|')
|
19
|
+
alignment_line = alignment(align, labels.length)
|
20
|
+
|
21
|
+
if is_rows
|
22
|
+
rows = data.map {|row| row.join('|')}
|
23
|
+
else
|
24
|
+
max_len = data.map(&:size).max
|
25
|
+
rows = []
|
26
|
+
max_len.times do |i|
|
27
|
+
row = []
|
28
|
+
data.each {|col| row.push(col[i])}
|
29
|
+
rows.push(row.join('|'))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
return [header_line, alignment_line, rows.join("\n")].join("\n")
|
25
34
|
end
|
26
|
-
end
|
27
35
|
|
28
|
-
# Convert
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
36
|
+
# Convert a Markdown table into human-readable form.
|
37
|
+
def self.plain_text(md_table)
|
38
|
+
lines = md_table.split("\n")
|
39
|
+
labels = lines[0].split('|')
|
40
|
+
alignments = lines[1].split('|')
|
41
|
+
rows = lines[2..-1].map {|line| line.split('|')}
|
42
|
+
|
43
|
+
# Replace non-breaking HTML characters with their plaintext counterparts.
|
44
|
+
rows.each do |row|
|
45
|
+
row.each do |cell|
|
46
|
+
cell.gsub!(/( )|(|)/, ' ' => ' ', '|' => '|')
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Get the width for each column.
|
51
|
+
widths = labels.map(&:length) # Lengths of each column's longest element.
|
52
|
+
rows.length.times do |i|
|
53
|
+
rows[i].length.times do |j|
|
54
|
+
rows[i][j].length > widths[j] && widths[j] = rows[i][j].length
|
55
|
+
end
|
56
|
+
end
|
57
|
+
widths.map! {|w| w + 2} # Add padding on each side.
|
58
|
+
|
59
|
+
# Align the column labels.
|
60
|
+
labels.length.times do |i|
|
61
|
+
label_length = labels[i].length
|
62
|
+
start = align_cell(label_length, widths[i], alignments[i])
|
63
|
+
|
64
|
+
labels[i].prepend(' ' * start)
|
65
|
+
labels[i] += ' ' * (widths[i] - start - label_length)
|
66
|
+
end
|
35
67
|
|
36
|
-
#
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
alignments = align.map {
|
45
|
-
|a| a.downcase == 'l' ? ':-' : a.downcase == 'r' ? '-:' : ':-l'
|
46
|
-
}
|
47
|
-
if alignments.length < n
|
48
|
-
alignments += [':-:'] * (n - alignments.length)
|
68
|
+
# Align the cells.
|
69
|
+
rows.each do |row|
|
70
|
+
row.length.times do |i|
|
71
|
+
cell_length = row[i].length
|
72
|
+
start = align_cell(cell_length, widths[i], alignments[i])
|
73
|
+
row[i].prepend(' ' * start)
|
74
|
+
row[i] += ' ' * (widths[i] - start - cell_length)
|
75
|
+
end
|
49
76
|
end
|
50
|
-
|
77
|
+
|
78
|
+
border = "\n|" + widths.map {|w| '=' * w}.join('|') + "|\n"
|
79
|
+
separator = border.gsub('=', '-')
|
80
|
+
|
81
|
+
table = border[1..-1] # Don't include the first newline.
|
82
|
+
table += '|' + labels.join('|') + '|'
|
83
|
+
table += border
|
84
|
+
table += rows.map {|row| '|' + row.join('|') + '|'}.join(separator)
|
85
|
+
table += border
|
86
|
+
|
87
|
+
return table.chomp
|
51
88
|
end
|
52
|
-
return alignment_line
|
53
|
-
end
|
54
89
|
|
55
|
-
#
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
row = []
|
80
|
-
data.each {|col| row.push(col[i])}
|
81
|
-
rows.push(row.join('|'))
|
90
|
+
# Sanity checks for make_table.
|
91
|
+
private_class_method def self.validate(labels, data, align, is_rows)
|
92
|
+
if labels.class != Array
|
93
|
+
raise('labels must be an Array')
|
94
|
+
elsif data.class != Array || data.any? {|datum| datum.class != Array}
|
95
|
+
raise('data must be a two-dimensional array')
|
96
|
+
elsif labels.empty?
|
97
|
+
raise('No column labels given')
|
98
|
+
elsif data.empty?
|
99
|
+
raise('No columns given')
|
100
|
+
elsif data.all? {|datum| datum.empty?}
|
101
|
+
raise('No cells given')
|
102
|
+
elsif labels.any? {|label| !label.respond_to?(:to_s)}
|
103
|
+
raise('One or more column labels cannot be made into a string')
|
104
|
+
elsif data.any? {|datum| datum.any? {|cell| !cell.respond_to?(:to_s)}}
|
105
|
+
raise('One or more cells cannot be made into a string')
|
106
|
+
elsif ![String, Array].include?(align.class)
|
107
|
+
raise('align must be a String or Array')
|
108
|
+
elsif align.class == Array && align.any? {|val| val.class != String}
|
109
|
+
raise('One or more align values is not a String')
|
110
|
+
elsif !is_rows && data.length > labels.length
|
111
|
+
raise('Too many data columns given')
|
112
|
+
elsif is_rows && data.any? {|row| row.length > labels.length}
|
113
|
+
raise('One or more rows has too many cells')
|
82
114
|
end
|
83
115
|
end
|
84
116
|
|
85
|
-
|
86
|
-
|
117
|
+
# Convert all input to strings and replace any '|' characters with
|
118
|
+
# non-breaking equivalents,
|
119
|
+
private_class_method def self.sanitize!(labels, data)
|
120
|
+
bar = '|' # Non-breaking HTML vertical bar.
|
121
|
+
labels.map! {|label| label.to_s.gsub('|', bar)}
|
122
|
+
data.length.times {|i| data[i].map! {|cell| cell.to_s.gsub('|', bar)}}
|
123
|
+
end
|
87
124
|
|
88
|
-
#
|
89
|
-
|
125
|
+
# Generate the alignment line from a string or array.
|
126
|
+
# align must be a string or array or strings.
|
127
|
+
# n: number of labels in the table to be created.
|
128
|
+
private_class_method def self.alignment(align, n)
|
129
|
+
if align.class == String
|
130
|
+
alignment = align == 'l' ? ':-' : align == 'r' ? '-:' : ':-:'
|
131
|
+
alignment_line = ([alignment] * n).join('|')
|
132
|
+
else
|
133
|
+
alignments = align.map {
|
134
|
+
|a| a.downcase == 'l' ? ':-' : a.downcase == 'r' ? '-:' : ':-:'
|
135
|
+
}
|
136
|
+
if alignments.length < n
|
137
|
+
alignments += [':-:'] * (n - alignments.length)
|
138
|
+
end
|
139
|
+
alignment_line = alignments.join('|')
|
140
|
+
end
|
141
|
+
return alignment_line
|
142
|
+
end
|
143
|
+
|
144
|
+
# Get the starting index of a cell's text from the text's length, the cell's
|
145
|
+
# width, and the alignment.
|
146
|
+
private_class_method def self.align_cell(length, width, align)
|
147
|
+
if align =~ /:-+:/
|
148
|
+
return (width / 2) - (length / 2)
|
149
|
+
elsif align =~ /-+:/
|
150
|
+
return width - length - 1
|
151
|
+
else
|
152
|
+
return 1
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: markdown-tables
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris de Graaf
|
@@ -29,7 +29,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
29
29
|
requirements:
|
30
30
|
- - ">="
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version:
|
32
|
+
version: 2.1.0
|
33
33
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
34
34
|
requirements:
|
35
35
|
- - ">="
|
@@ -40,5 +40,5 @@ rubyforge_project:
|
|
40
40
|
rubygems_version: 2.6.8
|
41
41
|
signing_key:
|
42
42
|
specification_version: 4
|
43
|
-
summary: Utilities for creating and displaying Markdown tables in Ruby
|
43
|
+
summary: Utilities for creating and displaying Markdown tables in Ruby.
|
44
44
|
test_files: []
|