From a7791635aa98f012d35f97c3c5288494bbb28e38 Mon Sep 17 00:00:00 2001 From: Miquel Sabaté Solà Date: Wed, 13 Mar 2024 18:03:43 +0100 Subject: Initial commit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Miquel Sabaté Solà --- lib/assets/.keep | 0 lib/base_exporter.rb | 29 +++++++++++++++++++ lib/csv_exporter.rb | 21 ++++++++++++++ lib/tasks/.keep | 0 lib/uoc_exporter.rb | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 131 insertions(+) create mode 100644 lib/assets/.keep create mode 100644 lib/base_exporter.rb create mode 100644 lib/csv_exporter.rb create mode 100644 lib/tasks/.keep create mode 100644 lib/uoc_exporter.rb (limited to 'lib') diff --git a/lib/assets/.keep b/lib/assets/.keep new file mode 100644 index 0000000..e69de29 diff --git a/lib/base_exporter.rb b/lib/base_exporter.rb new file mode 100644 index 0000000..b040592 --- /dev/null +++ b/lib/base_exporter.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +class BaseExporter + def initialize(things:) + @things = things + end + + # Returns a string which forces a new TeX line. + def tex_new_line + '\\\\~\\\\' + end + + # Returns a two-sized array containing the first name and the last name as + # parsed from the `author` string. This method assumes the following format is + # followed: + # - 'Name' -> ['Name', nil] + # - 'Name Surname' -> ['Name', 'Surname'] + # - 'Compound Name Surname' -> ['Compound Name', 'Surname'] + # - 'Name _Surname1 Surname2_' -> ['Name', 'Surname1 Surname2'] + def parse_author(author:) + matches = /(.+)?\s_(.+)_/.match(author) + return matches[1].strip, matches[2].strip if matches&.size == 3 + + a = author.split + return [author, nil] if a.size == 1 + + [a[0..-2].join(' '), a.last] + end +end diff --git a/lib/csv_exporter.rb b/lib/csv_exporter.rb new file mode 100644 index 0000000..a44815d --- /dev/null +++ b/lib/csv_exporter.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +require 'csv' + +class CsvExporter < BaseExporter + def export + str = '' + @things.each do |thing| + str += thing_to_csv(thing:) + end + + str + end + + def thing_to_csv(thing:) + CSV.generate_line([thing.target, thing.authors, thing.editors, thing.year, thing.title, + thing.note, thing.insideof, thing.url, thing.publisher, thing.kind, + thing.access, thing.bought_at], + quote_empty: false) + end +end diff --git a/lib/tasks/.keep b/lib/tasks/.keep new file mode 100644 index 0000000..e69de29 diff --git a/lib/uoc_exporter.rb b/lib/uoc_exporter.rb new file mode 100644 index 0000000..9a83d7c --- /dev/null +++ b/lib/uoc_exporter.rb @@ -0,0 +1,81 @@ +# frozen_string_literal: true + +class UocExporter < BaseExporter + def export + @things.map.with_index do |thing, idx| + if idx.zero? + "\\hypertarget{#{thing.target}}{#{head(thing:)} #{body(thing:)}}" + else + "#{tex_new_line}\\hypertarget{#{thing.target}}{#{head(thing:)} #{body(thing:)}}" + end + end.join("\n\n") + end + + protected + + # Returns the head of a line, containing authors, year, title and, if + # available, the "inside of" information. + def head(thing:) + str = "#{parse_authors(thing:)} (#{thing.year}). \\emph{#{thing.title}}." + + if thing.insideof.present? + str += " #{inside_of(thing.insideof)}" + str += thing.pages.present? ? ", #{thing.pages}." : '.' + end + + str + end + + # Parse the authors as delivered by `thing.authors` and render them in the + # proper format. + def parse_authors(thing:) + str = thing.authors.split(',').map do |author| + first, last = parse_author(author: author.strip) + last.blank? ? "\\textsc{#{first}}" : "\\textsc{#{last}}, #{first}" + end.join('; ') + + str += ' (eds.)' if thing.editors + str + end + + # Returns the proper 'inside of' translated text. + def inside_of(sub) + str = if sub.downcase.start_with?(*%w[a e i o u]) + I18n.t('general.insideof-vowel') + else + I18n.t('general.insideof') + end + + str + " \\emph{#{sub}}" + end + + # Returns the 'body' of the line, which is the rest of it (i.e. note, + # publisher, year). + def body(thing:) + union, tail = thing_union_tail(thing:) + + if thing.publisher.present? + pub = thing.note.present? ? "#{thing.note}. #{thing.publisher}" : thing.publisher + pub + union + tail + else + tail + end + end + + # Returns a two-sized array containing the last bits of info from a line, + # being either the address, the url + access date, or just a final dot. The + # first item contains the 'union' of the last item of the returned array and + # the expected string that is going to be prefixed to it. + def thing_union_tail(thing:) + if thing.address.present? + [', ', "#{thing.address}: #{thing.year}."] + elsif thing.url.present? + ['. ', + "[\\url{#{thing.url}}]. [#{I18n.t('activerecord.attributes.thing.access')}: #{I18n.l( + thing.access, format: :long + ).downcase}]."] + else + ['', '.'] + end + end +end -- cgit v1.2.3