aboutsummaryrefslogtreecommitdiff
path: root/lib/base_exporter.rb
blob: f64301b9b21aaed9ad7fee5330fd1c7e11c50dbb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# frozen_string_literal: true

class BaseExporter
  def initialize(things:)
    @things = things
  end

  protected

  # 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

  # Parse the string in `thing.authors` and put each author followed by
  # semicolon and the right order for first and last name. It will also cover
  # whenever editors are involved.
  def parse_authors(thing:)
    str = thing.authors.split(',').map do |author|
      first, last = parse_author(author: author.strip)
      last.blank? ? upper_case(text: first).to_s : "#{upper_case(text: last)}, #{first}"
    end.join('; ')

    str += ' (eds.)' if thing.editors
    str
  end

  # Returns an "Inside of" string where `sub` is the substring contained in it.
  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(text: sub)}"
  end

  # Returns the head of a formatted "thing", containing authors, year, title
  # and, if available, the "inside of" information. This is shared across some
  # exporters, thus placed in here.
  #
  # NOTE: the subclass *must* implement `parse_title`.
  def head(thing:)
    str = "#{parse_authors(thing:)} (#{thing.year}). #{parse_title(title: thing.title)}."

    if thing.insideof.present?
      str += " #{inside_of(sub: thing.insideof)}"
      str += thing.pages.present? ? ", #{thing.pages}." : '.'
    end

    str
  end
end