aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMiquel Sabaté Solà <msabate@suse.com>2024-03-13 18:03:43 +0100
committerMiquel Sabaté Solà <msabate@suse.com>2024-03-13 18:03:43 +0100
commita7791635aa98f012d35f97c3c5288494bbb28e38 (patch)
treebad987e6b4d10ad2f7cd02e40658d464907595ee /lib
downloadoperum-a7791635aa98f012d35f97c3c5288494bbb28e38.tar.gz
operum-a7791635aa98f012d35f97c3c5288494bbb28e38.zip
Initial commit
Signed-off-by: Miquel Sabaté Solà <msabate@suse.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/assets/.keep0
-rw-r--r--lib/base_exporter.rb29
-rw-r--r--lib/csv_exporter.rb21
-rw-r--r--lib/tasks/.keep0
-rw-r--r--lib/uoc_exporter.rb81
5 files changed, 131 insertions, 0 deletions
diff --git a/lib/assets/.keep b/lib/assets/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/lib/assets/.keep
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
--- /dev/null
+++ b/lib/tasks/.keep
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