#!/usr/bin/env ruby
require 'date'
# TODO: this.
# Take a file as first argument, which is to be the file biblio.csv, containing
# all books read. Then formats this as a table. It sorts the books in
# the order [Ongoing, Completed, Yet to Read], and replaces several values with
# ones more appropriate for viewing pleasure.
# For the final column (index: 11, zero-indexed) we replace the contents with a
# link. So rd/the-progress-of-a-crime becomes
# For column 3 (Part), this is rounded as special logic.
# \n"
exit
end
# def do_header(h: str): str
# Returns the rows of the table corresponding to the header.
def do_header(h)
s = "\t\n"
return s
end
# Make the string look sexy, ooh la la.
def sexify(val)
# Round integers if they end .00.
if val.end_with? ".00" then
integral = val.to_i
unless integral == 0
return integral.to_s
end
end
# Transform strings.
if $status_transform.has_key? (val)
return $status_transform[val]
end
if $form_transform.has_key? (val)
return $form_transform[val]
end
if $ownership_transform.has_key? (val)
return $ownership_transform[val]
end
if $general_transform.has_key? (val)
return $general_transform[val]
end
return val
end
ret=""
header=""
# Contains the buckets into which to put the entries.
unknown = [] # typeof(unknown) == array[str]
known = {} # typeof(known) == Hash[str => array[str]]
def written_month_of(ym)
# Takes, e.g. "2023-09" and returns "September 2023". Invariant: entry must
# be of form "YYYY-MM".
month = ym[-2..-1]
ret = ""
month_name = Date::MONTHNAMES[month.to_i]
ret << month_name << " " << ym[0..3]
return ret
end
def wrap_entries_in_table(entries, header)
# Call after string made of all entries. This fn wraps them into the table.
ret = ""
ret << "
\n" \
<< header \
<< entries \
<< "
\n"
return ret
end
def make_html_entry(entry)
# Makes a singular entry.
ret = ""
ret << "\t\n"
entry.split($delim).each_with_index do |e, i|
next if i == 0 or i == 6 or i == 7 or i == 8 or i == 9
e = e.delete "\n"
if i == 11 and e != "N/A" then
ret << "\t\tLink | \n"
else
ret << "\t\t" \
<< sexify(e) \
<< " | \n"
end
end
ret << "\t
\n"
return ret
end
File.foreach(ARGV[0]).with_index do |line, line_num|
# 0. If entry not completed, skip, otherwise ...; [done]
# 1. Figure out what month the line corresponds to;
# 2. Chuck line into a bucket corresponding to entries in that month;
# 3. Sorting that bucket into the right month, and make the table out of the
# entries.
if line_num == 0 then # Must go first, otherwise skipped by checks below.
header << do_header(line)
end
next if line == "\n" or line == "\t" or line == "" or line == " " or line == $delim
next if not line.include? "completed;"
finished_date = line.split($delim)[5]
if finished_date == "" or finished_date == "\t" or finished_date == "N/A" then
unknown = unknown.append line
else
# Invariant: everything completed is either unknown date, or has at least
# a year and a month (but not necessarily a day). We use this, e.g.
# "2023-01", as the index for the month.
index = finished_date[0..6]
# It is possible for the index not to be added here, so if this is the case
# just add the index as [] and then we directly append to what we've just
# added.
if not known.has_key? (index)
known[index] = []
end
# And now we can append.
known[index] = (known[index] << line)
end
end
# Sort hash, so we can simply iterate over it.
known = known.sort.reverse.to_h
# Make HTML for "Unknown"s
unknown = unknown.map! { |entry| make_html_entry(entry) }.join ("\n")
unknown_table = wrap_entries_in_table(unknown, header) # typeof == str
unkn_ret = ""
unkn_ret << "Unknown
\n" \
<< unknown_table
kn_rets = []
# Make HTML for each month.
known.each do |key, values|
# Here, values is an array of all entries. We want to merge then together,
# and thereby get the table.
values = values.map! { |value| make_html_entry(value) }.join ("\n")
known_table = wrap_entries_in_table(values, header) # typeof == str
kn_ret = ""
kn_ret << "" \
<< written_month_of(key) \
<< "
\n" \
<< known_table
kn_rets = kn_rets.append(kn_ret)
end
# File.foreach(ARGV[0]).with_index do |line, line_num|
# next if line == "\n" or line == "\t" or line == "" or line == " " or line == $delim
#
# # Handle the first line - the header.
# if line_num == 0 then
# header << do_header(line)
# else
# # We need to figure out whether it is ongoing, completed, or yet to read.
# # To do this, we will check if the corresponding string is in the line.
# if line.include? "completed;" then
# target = table_cmp
# elsif line.include? "ongoing;" then
# target = table_ongoing
# elsif line.include? "dropped;" then
# target = table_drp
# else
# target = table_rest
# end
#
# end
# end
# Echo the file.
puts kn_rets
puts unkn_ret