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.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/markdown-tables.rb +146 -79
  3. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d81c56a6b5704f57fe1b02ecf891051306873b50
4
- data.tar.gz: 78e3d1343aaadb46e5ea768b498960c73f1ea699
3
+ metadata.gz: ce5cc9285eabf5477a6520866af564cd1d8f90b6
4
+ data.tar.gz: 73042b5f303ff8d1c703a67d62244937206845f1
5
5
  SHA512:
6
- metadata.gz: f31cc74738da99e034bfef0791247d24c7bba6425295c183f95cd2f4ff0928f78bfec11747ebb078c2de6d6cec314a4f8fdec350200458f0721120658dfcb0c5
7
- data.tar.gz: 6295dd0283ae39e794cec164469114faa379331271c46ee364d8b7d4c9b88909a7bc8e28e0e5ec68ce78bac94264b2429fe20b49055872c52ba55ce24657b1e3
6
+ metadata.gz: 0d8a6a6fa9cd1029568c54c2e6da2d0145c5b06f6a9a0f68c9e09240bc0d3c6d4c26533d4c676a1f91385294893da1f6eab01e9affc0e6730e6c90079af52f54
7
+ data.tar.gz: 56ac0af7a9e34b01ae7f2dfb0a2dd7c285cb06f9d3a86434268d4299aad09346004074411c04eafd7edc16ddd7ef1572c5797b69588851f3eeec33906685280a
@@ -1,89 +1,156 @@
1
- # Sanity checks for make_table.
2
- def validate(labels, data, align, is_rows)
3
- if labels.class != Array
4
- raise('labels must be an Array')
5
- elsif data.class != Array || data.any? {|datum| datum.class != Array}
6
- raise('data must be a two-dimensional array')
7
- elsif labels.empty?
8
- raise('No column labels given')
9
- elsif data.empty?
10
- raise('No columns given')
11
- elsif data.all? {|datum| datum.empty?}
12
- raise('No cells given')
13
- elsif labels.any? {|label| !label.respond_to?(:to_s)}
14
- raise('One or more column labels cannot be made into a string')
15
- elsif data.any? {|datum| datum.any? {|cell| !cell.respond_to?(:to_s)}}
16
- raise('One or more cells cannot be made into a string')
17
- elsif ![String, Array].include?(align.class)
18
- raise('align must be a String or Array')
19
- elsif align.class == Array && align.any? {|val| val.class != String}
20
- raise('One or more align values is not a String')
21
- elsif !is_rows && data.length > labels.length
22
- raise('Too many data columns given')
23
- elsif is_rows && data.any? {|row| row.length > labels.length}
24
- raise('One or more rows has too many cells')
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 all input to strings and replace any '|' characters with
29
- # non-breaking equivalents,
30
- def sanitize!(labels, data)
31
- bar = '|' # Non-breaking HTML vertical bar.
32
- labels.map! {|label| label.to_s.gsub('|', bar)}
33
- data.length.times {|i| data[i].map! {|cell| cell.to_s.gsub('|', bar)}}
34
- end
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
- # Generate the alignment line from a string or array.
37
- # align must be a string or array or strings.
38
- # n: number of labels in the table to be created.
39
- def alignment(align, n)
40
- if align.class == String
41
- alignment = align == 'l' ? ':-' : align == 'r' ? '-:' : ':-:'
42
- alignment_line = ([alignment] * n).join('|')
43
- else
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
- alignment_line = alignments.join('|')
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
- # Generate a Markdown table.
56
- # labels and data are one and two-dimensional arrays, respectively.
57
- # All input must have a to_s method.
58
- # Pass align: 'l' for left alignment or 'r' for right alignment. Anything
59
- # else will result in cells being centered. Pass an array of align values
60
- # to specify alignment per column.
61
- # If is_rows is true, then each sub-array represents a row.
62
- # Conversely, if is_rows is false, each sub-array of data represents a column.
63
- # Empty cells can be given with nil or an empty string.
64
- def make_table(labels, data, align: '', is_rows: false)
65
- labels = Marshal.load(Marshal.dump(labels))
66
- data = Marshal.load(Marshal.dump(data))
67
- validate(labels, data, align, is_rows)
68
- sanitize!(labels, data)
69
-
70
- header_line = labels.join('|')
71
- alignment_line = alignment(align, labels.length)
72
-
73
- if is_rows
74
- rows = data.map {|row| row.join('|')}
75
- else
76
- max_len = data.map(&:size).max
77
- rows = []
78
- max_len.times do |i|
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
- return [header_line, alignment_line, rows.join("\n")].join("\n")
86
- end
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 = '&#124;' # 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
- # Print out a Markdown table in human-readable form.
89
- def print_table(table) end
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.1
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: '0'
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: []