mirror of
https://github.com/ToshioCP/Gtk4-tutorial.git
synced 2025-01-12 20:03:28 +01:00
262 lines
6.4 KiB
Ruby
262 lines
6.4 KiB
Ruby
# mktbl.rb -- make table easy to read
|
|
|
|
def usage
|
|
print "ruby mktbl.rb file\n"
|
|
exit
|
|
end
|
|
|
|
def get_sep line
|
|
unless line.instance_of?(String) && line =~ /^\|(:?-+:?\|)+$/
|
|
raise "Ilegal parameter"
|
|
end
|
|
line = line.chomp.sub(/^\|/,"")
|
|
a = []
|
|
while line.length >= 1
|
|
if line =~ /^(:?-+:?)\|(.*)$/
|
|
pat = $1
|
|
line = $2
|
|
if pat[0] == ":" && pat[-1] == ":"
|
|
a << :c
|
|
elsif pat[0] == ":"
|
|
a << :l
|
|
elsif pat[-1] == ":"
|
|
a << :r
|
|
else #default
|
|
a << :l
|
|
end
|
|
else
|
|
raise "Unexpected error. line is \"#{line}\""
|
|
end
|
|
end
|
|
a
|
|
end
|
|
|
|
def line2cells line
|
|
unless line.instance_of?(String)
|
|
raise "Argument must be String"
|
|
end
|
|
unless line.length < 1000
|
|
raise "String too long"
|
|
end
|
|
a = []
|
|
line = line.chomp.sub(/^\s*\|/,"").sub(/\s*$/, "")
|
|
i = 0
|
|
while i < line.length
|
|
cell = ""
|
|
while i < line.length && (c = line[i]) != "|"
|
|
if c != "\\" && c != "|"
|
|
cell << c
|
|
i += 1
|
|
elsif i+1 < line.length && line[i+1] == "|"
|
|
cell << "\\|"
|
|
i += 2
|
|
else
|
|
cell << "\\"
|
|
i += 1
|
|
end
|
|
end
|
|
unless i < line.length
|
|
raise "String format error in #{line}."
|
|
end
|
|
cell = cell.sub(/^\s*/,"").sub(/\s*$/, "")
|
|
a << cell
|
|
i += 1
|
|
end
|
|
return a
|
|
end
|
|
|
|
def get_tbl buf
|
|
t = []
|
|
buf.each do |line|
|
|
t << line2cells(line)
|
|
end
|
|
n = t[0].size
|
|
t.each do |a|
|
|
raise "Each row must have the same number of columns." unless a.size == n
|
|
end
|
|
t
|
|
end
|
|
|
|
def get_width tbl, sep
|
|
n = sep.size
|
|
tbl.each do |a|
|
|
raise "Each row must have the same number of columns." unless a.size == n
|
|
end
|
|
width = []
|
|
0.upto(n-1) do |i|
|
|
max = 0
|
|
tbl.each do |a|
|
|
max = max < a[i].length ? a[i].length : max
|
|
end
|
|
if sep[i] == :l || sep[i] == :r
|
|
max = max < 2 ? 2 : max
|
|
elsif sep[i] == :c
|
|
max = max < 3 ? 3 : max
|
|
else
|
|
raise "Separater format error."
|
|
end
|
|
width << max
|
|
end
|
|
width
|
|
end
|
|
|
|
def mk_sep_l sep, width
|
|
raise "Size of sep and width is different." unless sep.size == width.size
|
|
n = sep.size
|
|
line = "|"
|
|
0.upto(n-1) do |i|
|
|
if sep[i] == :l
|
|
line << ":"+"-"*(width[i]-1)+ "|"
|
|
elsif sep[i] == :r
|
|
line << "-"*(width[i]-1) + ":|"
|
|
elsif sep[i] == :c
|
|
line << ":" + "-"*(width[i]-2) + ":|"
|
|
else
|
|
raise "Separater format error."
|
|
end
|
|
end
|
|
line
|
|
end
|
|
|
|
def mk_tbl_l tbl, sep, width
|
|
n = width.size
|
|
raise "mk_tbl_l: Each row must have the same number of columns." unless sep.size == n
|
|
tbl.each do |a|
|
|
raise "mk_tbl_l: Each row must have the same number of columns." unless a.size == n
|
|
0.upto(n-1) do |i|
|
|
raise "mk_tbl_l: table data [#{i}] has wider width than expected (#{width[i]})." if a[i].size > width[i]
|
|
end
|
|
end
|
|
tbl_l = []
|
|
tbl.each do |row|
|
|
line = "|"
|
|
0.upto(n-1) do |i|
|
|
space = width[i]-row[i].length
|
|
if sep[i] == :l
|
|
line << row[i] + " "*space + "|"
|
|
elsif sep[i] == :r
|
|
line << " "*space + row[i] + "|"
|
|
elsif sep[i] == :c
|
|
left = space / 2
|
|
right = space - left
|
|
line << " "*left + row[i] + " "*right + "|"
|
|
else
|
|
raise "mk_tbl_l: Separater format error."
|
|
end
|
|
end
|
|
tbl_l << line
|
|
end
|
|
tbl_l
|
|
end
|
|
|
|
def mktbl buf
|
|
raise "The data not a table." unless buf.size >= 3 # table must have header, separator, body
|
|
sep = get_sep buf[1] # Sep is an array contains ALIGNMENT (LEFT, CENTER or RIGHT) information of each column.
|
|
buf.delete_at 1
|
|
tbl = get_tbl buf # Tbl is a two dimensional array of the table. Each element is a cell of the table.
|
|
width = get_width tbl, sep # Width is an array. Each element is the maximum width of the cells in the column corresponds to the element.
|
|
sep_l = mk_sep_l sep, width # Make a text of the separator. Each column in the text has a width given by the second argument.
|
|
tbl_l = mk_tbl_l tbl, sep, width # Make an array of texts. Each column in the text has a width given by the second argument.
|
|
tbl_l.insert(1, sep_l)
|
|
tbl_l
|
|
end
|
|
|
|
# ---- test ----
|
|
def test_sep
|
|
s = "|:-:|:---|---:|-|\n"
|
|
sep = get_sep s
|
|
raise "test_sep: Error." unless sep == [:c, :l, :r, :l]
|
|
end
|
|
|
|
def test_tbl
|
|
t = "| a | bc|def | gh i | \\|kl|\n"
|
|
tbl = line2cells t
|
|
raise "test_tbl: Error." unless tbl == ["a", "bc", "def", "gh i", "\\|kl"]
|
|
end
|
|
|
|
def test_get_tbl
|
|
buf = [ "||book|author|price|\n",
|
|
"| 1 | Calculus | T. Takagi | \\3,600 |\n",
|
|
"|2|Algebra|S. Lang|$50|\n"
|
|
]
|
|
tbl = get_tbl buf
|
|
tbl_expected = [["", "book", "author", "price"],
|
|
["1", "Calculus", "T. Takagi", "\\3,600"],
|
|
["2", "Algebra", "S. Lang", "$50"]
|
|
]
|
|
raise "test_get_tbl: Error" unless tbl == tbl_expected
|
|
end
|
|
|
|
def test_get_width
|
|
tbl = [["", "book", "author", "price"],
|
|
["1", "Calculus", "T. Takagi", "\\3,600"],
|
|
["2", "Algebra", "S. Lang", "$50"]
|
|
]
|
|
sep = [:c, :c, :c, :c]
|
|
width = get_width tbl, sep
|
|
width_expected = [3, 8, 9, 6]
|
|
raise "test_get_width: Error" unless width == width_expected
|
|
end
|
|
|
|
def test_mk_sep_l
|
|
sep = [:l, :c, :r, :c]
|
|
width = [3, 8, 9, 6]
|
|
sep_l = mk_sep_l sep, width
|
|
sep_l_expected = "|:--|:------:|--------:|:----:|"
|
|
raise "test_mk_sep_l: Error" unless sep_l == sep_l_expected
|
|
end
|
|
|
|
def test_mk_tbl_l
|
|
sep = [:l, :c, :r, :c]
|
|
width = [3, 8, 9, 6]
|
|
tbl = [["", "book", "author", "price"],
|
|
["1", "Calculus", "T. Takagi", "\\3,600"],
|
|
["2", "Algebra", "S. Lang", "$50"]
|
|
]
|
|
tbl_l = mk_tbl_l tbl, sep, width
|
|
tbl_l_expected = ["| | book | author|price |",
|
|
"|1 |Calculus|T. Takagi|\\3,600|",
|
|
"|2 |Algebra | S. Lang| $50 |"
|
|
]
|
|
raise "test_mk_tbl_l: Error" unless tbl_l == tbl_l_expected
|
|
end
|
|
|
|
def test_mktbl
|
|
buf = <<'EOS'.split("\n")
|
|
| |token kind | yylval.ID | yylval.NUM |
|
|
|:-:|:-|-:|:-:|
|
|
|1|ID|distance| |
|
|
|2|=|||
|
|
|3|NUM||100|
|
|
|4|FD|||
|
|
|5|ID|distance||
|
|
|6|*|||
|
|
|7|NUM||2|
|
|
EOS
|
|
|
|
tbl_l = mktbl buf
|
|
|
|
tbl_l_expected = <<'EOS'.split("\n")
|
|
| |token kind|yylval.ID|yylval.NUM|
|
|
|:-:|:---------|--------:|:--------:|
|
|
| 1 |ID | distance| |
|
|
| 2 |= | | |
|
|
| 3 |NUM | | 100 |
|
|
| 4 |FD | | |
|
|
| 5 |ID | distance| |
|
|
| 6 |* | | |
|
|
| 7 |NUM | | 2 |
|
|
EOS
|
|
raise "test_mktbl: Error" unless tbl_l == tbl_l_expected
|
|
end
|
|
|
|
def test
|
|
test_sep
|
|
test_tbl
|
|
test_get_tbl
|
|
test_get_width
|
|
test_mk_sep_l
|
|
test_mk_tbl_l
|
|
test_mktbl
|
|
end
|
|
|