Module: PROIEL::Citations

Defined in:
lib/proiel/citations.rb

Class Method Summary collapse

Class Method Details

.citation_make_range(cit1, cit2, dividers: /([\s\.]+)/) ⇒ String

Returns a citation range that spans `cit1` to `cit2`.

The regular expression `dividers` is used to chunk the strings, and then the longest common prefix of chunks is removed from `cit2`. `dividers` should chosen so that the chunks match logical components of a citation, e.g. book titles, chapter numbers and section identifiers.

Examples:

citation_make_range('Matt 5.16', 'Matt 5.27') # => "Matt 5.16–27"
citation_make_range('Matt 4.13', 'Matt 5.27') # => "Matt 4.13–5.27"

Parameters:

  • cit1 (String)

    first citation in range

  • cit2 (String)

    second citation in range

  • dividers (Regexp) (defaults to: /([\s\.]+)/)

    dividing elements between components of citation

Returns:

  • (String)

Raises:

  • (ArgumentError)

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/proiel/citations.rb', line 25

def self.citation_make_range(cit1, cit2, dividers: /([\s\.]+)/)
  raise ArgumentError unless cit1.is_a?(String) or cit1.nil?
  raise ArgumentError unless cit2.is_a?(String) or cit1.nil?

  # Remove any nil and empty-string citation, and reduce a range that starts
  # and ends with the same citation to a single citation.
  c = [cit1, cit2].reject { |c| c.nil? || c.empty? }.uniq

  case c.length
  when 0
    nil
  when 1
    c.first
  else
    s = citation_strip_prefix(cit1, cit2, dividers: dividers)
    [cit1, s].reject(&:empty?).join("\u{2013}")
  end
end

.citation_strip_prefix(cit1, cit2, dividers: /([\s\.]+)/u) ⇒ String

Returns `cit2` without the longest prefix that `cit1` and `cit2` have in common.

The longest common prefix is not computed from the raw strings `cit1` and `cit2` but from string chunks. The regular expression `dividers` is used to chunk the strings, and then the longest prefix of chunks is removed.

`dividers` should chosen so that the chunks match logical componets of a citation, e.g. book titles, chapter numbers and section identifiers.

Examples:

citation_strip_prefix('Matt 5.16', 'Matt 5.27') # => "27"
citation_strip_prefix('Matt 5.26', 'Matt 5.27') # => "27"
citation_strip_prefix('Matt 4.13', 'Matt 5.27') # => "5.27"

Parameters:

  • cit1 (String)

    first citation in range

  • cit2 (String)

    second citation in range

  • dividers (Regexp) (defaults to: /([\s\.]+)/u)

    dividing elements between components of citation

Returns:

  • (String)

Raises:

  • (ArgumentError)

65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/proiel/citations.rb', line 65

def self.citation_strip_prefix(cit1, cit2, dividers: /([\s\.]+)/u)
  raise ArgumentError unless cit1.is_a?(String)
  raise ArgumentError unless cit2.is_a?(String)

  x, y = cit1.split(dividers), cit2.split(dividers)

  # Interleave x and y but compensate for zip's behaviour when
  # y.length < x.length
  zipped = x.length >= y.length ? x.zip(y) : y.zip(x).map(&:reverse)

  zipped.inject('') do |d, (a, b)|
    if not d.empty? or a != b
      d + (b || '')
    else
      ''
    end
  end
end