relaton-render 0.4.2 → 3.0.0.pre.alpha.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake.yml +6 -1
  3. data/.github/workflows/release.yml +24 -0
  4. data/.gitignore +14 -0
  5. data/.rubocop.yml +2 -2
  6. data/Gemfile +17 -1
  7. data/README.adoc +13 -258
  8. data/docs/citation-style-pack.adoc +370 -0
  9. data/lib/relaton/render/general.rb +305 -0
  10. data/lib/relaton/render/iso690/element.rb +153 -0
  11. data/lib/relaton/render/iso690/elements/access.rb +44 -0
  12. data/lib/relaton/render/iso690/elements/authorizer.rb +30 -0
  13. data/lib/relaton/render/iso690/elements/citeid.rb +39 -0
  14. data/lib/relaton/render/iso690/elements/component_part.rb +99 -0
  15. data/lib/relaton/render/iso690/elements/creator.rb +258 -0
  16. data/lib/relaton/render/iso690/elements/edition.rb +92 -0
  17. data/lib/relaton/render/iso690/elements/extent.rb +71 -0
  18. data/lib/relaton/render/iso690/elements/identifier.rb +46 -0
  19. data/lib/relaton/render/iso690/elements/location.rb +73 -0
  20. data/lib/relaton/render/iso690/elements/medium.rb +32 -0
  21. data/lib/relaton/render/iso690/elements/numeration.rb +26 -0
  22. data/lib/relaton/render/iso690/elements/production.rb +92 -0
  23. data/lib/relaton/render/iso690/elements/pub_date.rb +56 -0
  24. data/lib/relaton/render/iso690/elements/series.rb +66 -0
  25. data/lib/relaton/render/iso690/elements/size.rb +41 -0
  26. data/lib/relaton/render/iso690/elements/status.rb +30 -0
  27. data/lib/relaton/render/iso690/elements/stddoc.rb +40 -0
  28. data/lib/relaton/render/iso690/elements/title.rb +56 -0
  29. data/lib/relaton/render/iso690/elements/updated.rb +38 -0
  30. data/lib/relaton/render/iso690/elements.rb +67 -0
  31. data/lib/relaton/render/iso690/fields.rb +142 -0
  32. data/lib/relaton/render/iso690/i18n/en.yml +47 -0
  33. data/lib/relaton/render/iso690/i18n/fr.yml +14 -0
  34. data/lib/relaton/render/iso690/i18n/ja.yml +38 -0
  35. data/lib/relaton/render/iso690/i18n.rb +83 -0
  36. data/lib/relaton/render/iso690/identifier_kinds.rb +29 -0
  37. data/lib/relaton/render/iso690/index_renderer.rb +57 -0
  38. data/lib/relaton/render/iso690/kinds.rb +53 -0
  39. data/lib/relaton/render/iso690/renderer.rb +148 -0
  40. data/lib/relaton/render/iso690/rules.rb +36 -0
  41. data/lib/relaton/render/iso690/style/locale.rb +53 -0
  42. data/lib/relaton/render/iso690/style/name_form.rb +87 -0
  43. data/lib/relaton/render/iso690/style/scheme.rb +33 -0
  44. data/lib/relaton/render/iso690/style/sort_rule.rb +25 -0
  45. data/lib/relaton/render/iso690/style/template_map.rb +40 -0
  46. data/lib/relaton/render/iso690/style/type_template.rb +37 -0
  47. data/lib/relaton/render/iso690/style.rb +222 -0
  48. data/lib/relaton/render/iso690/styles/apa.yml +45 -0
  49. data/lib/relaton/render/iso690/styles/author-date.yml +31 -0
  50. data/lib/relaton/render/iso690/styles/chicago.yml +48 -0
  51. data/lib/relaton/render/iso690/styles/ieee-sa.yml +45 -0
  52. data/lib/relaton/render/iso690/styles/lncs.yml +54 -0
  53. data/lib/relaton/render/iso690/template.rb +248 -0
  54. data/lib/relaton/render/iso690.rb +27 -0
  55. data/lib/relaton/render/version.rb +1 -1
  56. data/lib/relaton-render.rb +11 -5
  57. data/relaton-render.gemspec +6 -13
  58. metadata +61 -116
  59. data/lib/isodoc/i18n.rb +0 -33
  60. data/lib/isodoc-yaml/i18n-ar.yaml +0 -44
  61. data/lib/isodoc-yaml/i18n-de.yaml +0 -43
  62. data/lib/isodoc-yaml/i18n-en.yaml +0 -40
  63. data/lib/isodoc-yaml/i18n-es.yaml +0 -47
  64. data/lib/isodoc-yaml/i18n-fr.yaml +0 -48
  65. data/lib/isodoc-yaml/i18n-ru.yaml +0 -51
  66. data/lib/isodoc-yaml/i18n-zh-Hans.yaml +0 -40
  67. data/lib/relaton/render/fields/date.rb +0 -45
  68. data/lib/relaton/render/fields/fields.rb +0 -245
  69. data/lib/relaton/render/general/citations.rb +0 -96
  70. data/lib/relaton/render/general/config.yml +0 -79
  71. data/lib/relaton/render/general/render.rb +0 -185
  72. data/lib/relaton/render/general/render_classes.rb +0 -129
  73. data/lib/relaton/render/parse/parse.rb +0 -64
  74. data/lib/relaton/render/parse/parse_contributors.rb +0 -132
  75. data/lib/relaton/render/parse/parse_extract.rb +0 -180
  76. data/lib/relaton/render/template/liquid.rb +0 -15
  77. data/lib/relaton/render/template/template.rb +0 -188
  78. data/lib/relaton/render/utils/utils.rb +0 -27
@@ -1,129 +0,0 @@
1
- module Relaton
2
- module Render
3
- BIBTYPE =
4
- %w(article book booklet manual proceedings presentation thesis techreport
5
- standard unpublished map electronic_resource audiovisual film video
6
- broadcast software graphic_work music patent inbook incollection
7
- inproceedings journal website webresource dataset archival social_media
8
- alert message conversation misc internal).freeze
9
-
10
- class General
11
- singleton_class.send(:attr_reader, :descendants)
12
- @descendants = {}
13
-
14
- def self.inherited(subclass) # rubocop:disable Lint/MissingSuper
15
- type = subclass.name.downcase.sub(/relaton::render::/, "")
16
- General.descendants[type] = subclass
17
- end
18
-
19
- def self.subclass(type)
20
- @descendants[type]
21
- end
22
- end
23
-
24
- class Book < General
25
- end
26
-
27
- class Journal < General
28
- end
29
-
30
- class Booklet < General
31
- end
32
-
33
- class Manual < General
34
- end
35
-
36
- class Proceedings < General
37
- end
38
-
39
- class Presentation < General
40
- end
41
-
42
- class Thesis < General
43
- end
44
-
45
- class Techreport < General
46
- end
47
-
48
- class Standard < General
49
- end
50
-
51
- class Unpublished < General
52
- end
53
-
54
- class Map < General
55
- end
56
-
57
- class Electronic_resource < General
58
- end
59
-
60
- class Software < Electronic_resource
61
- end
62
-
63
- class Webresource < Electronic_resource
64
- end
65
-
66
- class Website < Webresource
67
- end
68
-
69
- class Dataset < Electronic_resource
70
- end
71
-
72
- class Social_media < Electronic_resource
73
- end
74
-
75
- class Alert < Social_media
76
- end
77
-
78
- class Message < Social_media
79
- end
80
-
81
- class Audiovisual < General
82
- end
83
-
84
- class Film < Audiovisual
85
- end
86
-
87
- class Video < Audiovisual
88
- end
89
-
90
- class Broadcast < Audiovisual
91
- end
92
-
93
- class Graphic_work < General
94
- end
95
-
96
- class Music < General
97
- end
98
-
99
- class Patent < General
100
- end
101
-
102
- class Hosted < General
103
- end
104
-
105
- class Article < Hosted
106
- end
107
-
108
- class InBook < Hosted
109
- end
110
-
111
- class InCollection < Hosted
112
- end
113
-
114
- class InProceedings < Hosted
115
- end
116
-
117
- class Archival < General
118
- end
119
-
120
- class Conversation < General
121
- end
122
-
123
- class Misc < General
124
- end
125
-
126
- class Internal < General
127
- end
128
- end
129
- end
@@ -1,64 +0,0 @@
1
- require "nokogiri"
2
- require "twitter_cldr"
3
- require_relative "parse_contributors"
4
- require_relative "parse_extract"
5
-
6
- module Relaton
7
- module Render
8
- class Parse
9
- def initialize(options)
10
- @lang = options[:lang] || "en"
11
- @script = options[:script] || "Latn"
12
- end
13
-
14
- def extract(doc)
15
- host = host(doc)
16
- simple_xml2hash(doc).merge(simple_or_host_xml2hash(doc, host))
17
- .merge(host_xml2hash(host))
18
- .merge(series_xml2hash(doc, host))
19
- end
20
-
21
- def simple_xml2hash(doc)
22
- creators, role = creatornames(doc)
23
- { type: type(doc), title: title(doc), extent_raw: extent(doc),
24
- size_raw: size(doc),
25
- standardidentifier: standardidentifier(doc), uri_raw: uri(doc),
26
- status: status(doc), creators: creators, role_raw: role }
27
- end
28
-
29
- def simple_or_host_xml2hash(doc, host)
30
- { edition_raw: edition(doc, host), edition_num: edition_num(doc, host),
31
- medium_raw: medium(doc, host),
32
- place_raw: place(doc, host), publisher_raw: publisher(doc, host),
33
- publisher_abbrev_raw: publisher_abbrev(doc, host),
34
- distributor_raw: distributor(doc, host), draft_raw: draft(doc, host),
35
- access_location: access_location(doc, host),
36
- date: date(doc, host), date_updated: date_updated(doc, host),
37
- date_accessed: date_accessed(doc, host) }
38
- end
39
-
40
- def host_xml2hash(host)
41
- creators, role = creatornames(host)
42
- { host_creators: creators, host_role_raw: role,
43
- host_title: title(host) }
44
- end
45
-
46
- def series_xml2hash(doc, host)
47
- series = series(doc)
48
- host and series ||= series(host)
49
- series_xml2hash1(series, doc)
50
- end
51
-
52
- def series_xml2hash1(series, doc)
53
- return {} unless series
54
-
55
- { series_formatted: series_formatted(series, doc),
56
- series_title: series_title(series, doc),
57
- series_abbr: series_abbr(series, doc),
58
- series_run: series_run(series, doc),
59
- series_num: series_num(series, doc),
60
- series_partnumber: series_partnumber(series, doc) }
61
- end
62
- end
63
- end
64
- end
@@ -1,132 +0,0 @@
1
- module Relaton
2
- module Render
3
- class Parse
4
- def extract_orgname(org)
5
- org.name&.first&.content
6
- end
7
-
8
- def extract_personname(person)
9
- surname = person.name.surname || person.name.completename
10
- given, middle, initials = given_and_middle_name(person)
11
- { surname: surname.content,
12
- given: given,
13
- middle: middle,
14
- initials: initials }
15
- end
16
-
17
- def given_and_middle_name(person)
18
- forenames = person.name.forename.map(&:content)
19
- initials = person.name.initial.map(&:content)
20
- .map { |x| x.sub(/\.$/, "") }
21
- forenames.empty? and initials.empty? and return [nil, nil, nil]
22
- initials.empty? and initials = forenames.map { |x| x[0] }
23
- [forenames.first, forenames[1..-1], initials]
24
- end
25
-
26
- def extractname(contributor)
27
- org = contributor.entity if contributor.entity
28
- .is_a?(RelatonBib::Organization)
29
- person = contributor.entity if contributor.entity
30
- .is_a?(RelatonBib::Person)
31
- return { nonpersonal: extract_orgname(org) } if org
32
- return extract_personname(person) if person
33
-
34
- nil
35
- end
36
-
37
- def contributor_role(contributors)
38
- return nil unless contributors.length.positive?
39
-
40
- desc = contributors[0].role.first.description.join("\n")
41
- type = contributors[0].role.first.type
42
- desc.empty? ? type : desc
43
- end
44
-
45
- def creatornames(doc)
46
- cr = creatornames1(doc)
47
- cr.empty? and return [nil, nil]
48
- [cr.map { |x| extractname(x) }, contributor_role(cr)]
49
- end
50
-
51
- def creatornames_roles_allowed
52
- %w(author performer adapter translator editor publisher distributor)
53
- end
54
-
55
- def creatornames1(doc)
56
- cr = []
57
- return [] if doc.nil?
58
-
59
- creatornames_roles_allowed.each do |r|
60
- add = pick_contributor(doc, r)
61
- next if add.nil?
62
-
63
- cr = add and break
64
- end
65
- cr.nil? and cr = doc.contributor
66
- cr
67
- end
68
-
69
- def datepick(date)
70
- return nil if date.nil?
71
-
72
- on = date.on
73
- from = date.from
74
- to = date.to
75
- return { on: on } if on
76
- return { from: from, to: to } if from
77
-
78
- nil
79
- end
80
-
81
- def date1(date)
82
- %w(published issued circulated).each do |t|
83
- ret = date.detect { |x| x.type == t } and
84
- return ret
85
- end
86
- date.first
87
- end
88
-
89
- def date(doc, host)
90
- ret = date1(doc.date)
91
- host and ret ||= date1(host.date)
92
- datepick(ret)
93
- end
94
-
95
- def date_updated(doc, host)
96
- ret = doc.date.detect { |x| x.type == "updated" }
97
- host and ret ||= host.date.detect { |x| x.type == "updated" }
98
- datepick(ret)
99
- end
100
-
101
- def date_accessed(doc, host)
102
- ret = doc.date.detect { |x| x.type == "accessed" }
103
- host and ret ||= host.date.detect { |x| x.type == "accessed" }
104
- datepick(ret)
105
- end
106
-
107
- def publisher(doc, host)
108
- x = pick_contributor(doc, "publisher")
109
- host and x ||= pick_contributor(host, "publisher")
110
- x.nil? and return nil
111
- x.map { |c| extractname(c) }
112
- end
113
-
114
- def publisher_abbrev(doc, host)
115
- x = pick_contributor(doc, "publisher")
116
- host and x ||= pick_contributor(host, "publisher")
117
- x.nil? and return nil
118
- x.map do |c|
119
- c.entity.abbreviation&.content ||
120
- c.entity.name.first&.content
121
- end
122
- end
123
-
124
- def distributor(doc, host)
125
- x = pick_contributor(doc, "distributor")
126
- host and x ||= pick_contributor(host, "distributor")
127
- x.nil? and return nil
128
- x.map { |c| extractname(c) }
129
- end
130
- end
131
- end
132
- end
@@ -1,180 +0,0 @@
1
- module Relaton
2
- module Render
3
- class Parse
4
- def host(doc)
5
- doc.relation.detect { |r| r.type == "includedIn" }&.bibitem
6
- end
7
-
8
- # TODO : first is naive choice
9
- def title(doc)
10
- return nil if doc.nil? || doc.title.empty?
11
-
12
- t = doc.title.select { |x| x.title.language&.include? @lang }
13
- t.empty? and t = doc.title
14
- t1 = t.select { |x| x.type == "main" }
15
- t1.empty? and t1 = t
16
- t1.first&.title&.content
17
- end
18
-
19
- def medium(doc, host)
20
- x = doc.medium || host&.medium or return nil
21
-
22
- %w(content genre form carrier size scale).each_with_object({}) do |i, m|
23
- m[i] = x.send i
24
- end.compact
25
- end
26
-
27
- def size(doc)
28
- x = doc.size or return nil
29
- x.size.each_with_object({}) do |v, m|
30
- m[v.type] ||= []
31
- m[v.type] << v.value
32
- end
33
- end
34
-
35
- def edition(doc, host)
36
- doc.edition&.content || host&.edition&.content
37
- end
38
-
39
- def edition_num(doc, host)
40
- doc.edition&.number || host&.edition&.number
41
- end
42
-
43
- def place(doc, host)
44
- x = doc.place
45
- x.empty? && host and x = host.place
46
- x.empty? and return x
47
- x.map(&:name)
48
- end
49
-
50
- def series(doc)
51
- doc.series.detect { |s| s.type == "main" } ||
52
- doc.series.detect { |s| s.type.nil? } ||
53
- doc.series.first
54
- end
55
-
56
- def series_title(series, _doc)
57
- return nil if series.nil?
58
-
59
- series.title.respond_to?(:titles) and
60
- return series.title.titles.first.title.content
61
- series.title&.title&.content || series.formattedref&.content
62
- end
63
-
64
- def series_formatted(series, _doc)
65
- series.formattedref&.content
66
- end
67
-
68
- def series_abbr(series, _doc)
69
- series.abbreviation&.content
70
- end
71
-
72
- def series_num(series, _doc)
73
- series.number
74
- end
75
-
76
- def series_partnumber(series, _doc)
77
- series.partnumber
78
- end
79
-
80
- def series_run(series, _doc)
81
- series.run
82
- end
83
-
84
- def standardidentifier(doc)
85
- doc.docidentifier.each_with_object([]) do |id, ret|
86
- ret << id.id unless standardidentifier_exclude.include? id.type
87
- end
88
- end
89
-
90
- def standardidentifier_exclude
91
- %w(metanorma metanorma-ordinal)
92
- end
93
-
94
- def uri(doc)
95
- uri = nil
96
- %w(doi uri src).each do |t|
97
- uri = doc.link.detect { |u| u.type == t } and break
98
- end
99
- uri ||= doc.link.first
100
- return nil unless uri
101
-
102
- uri.content.to_s
103
- end
104
-
105
- def access_location(doc, host)
106
- x = doc.accesslocation || host&.accesslocation or
107
- return nil
108
- x.first
109
- end
110
-
111
- def included(type)
112
- ["article", "inbook", "incollection", "inproceedings"].include? type
113
- end
114
-
115
- def type(doc)
116
- type = doc.type and return type
117
- doc.relation.any? { |r| r.type == "includedIn" } and return "inbook"
118
- "book"
119
- end
120
-
121
- def extent1(localities)
122
- localities.each_with_object({}) do |l, ret|
123
- ret[(l.type || "page").to_sym] = {
124
- from: localized_string_or_text(l.reference_from),
125
- to: localized_string_or_text(l.reference_to),
126
- }
127
- end
128
- end
129
-
130
- def extent(doc)
131
- doc.extent.each_with_object([]) do |e, acc|
132
- case e
133
- when RelatonBib::LocalityStack
134
- acc << extent1(e.locality)
135
- when RelatonBib::Locality
136
- acc << extent1(Array(e))
137
- end
138
- end
139
- end
140
-
141
- def draft(doc, host)
142
- dr = doc.status&.stage&.value || host&.status&.stage&.value
143
-
144
- { iteration: iter_ordinal(doc) || iter_ordinal(host), status: dr }
145
- end
146
-
147
- def iter_ordinal(doc)
148
- return nil unless iter = doc&.status&.iteration
149
-
150
- iter
151
- end
152
-
153
- def status(doc)
154
- doc.status&.stage&.value
155
- end
156
-
157
- private
158
-
159
- def blank?(text)
160
- text.nil? || text.empty?
161
- end
162
-
163
- def pick_contributor(doc, role)
164
- ret = doc.contributor.select do |c|
165
- c.role.any? { |r| r.type == role }
166
- end
167
- ret.empty? ? nil : ret
168
- end
169
-
170
- def localized_string_or_text(str)
171
- case str
172
- when RelatonBib::LocalizedString
173
- str.content
174
- when String
175
- str
176
- end
177
- end
178
- end
179
- end
180
- end
@@ -1,15 +0,0 @@
1
- module Relaton
2
- module Render
3
- module Template
4
- module CapitalizeFirst
5
- def capitalize_first(words)
6
- return nil if words.nil?
7
-
8
- ret = words.split(/[ _]/)
9
- ret.first.capitalize! if ret.size.positive?
10
- ret.join("_")
11
- end
12
- end
13
- end
14
- end
15
- end
@@ -1,188 +0,0 @@
1
- require_relative "../utils/utils"
2
- require_relative "liquid"
3
-
4
- module Relaton
5
- module Render
6
- module Template
7
- class General
8
- def initialize(opt = {})
9
- @htmlentities = HTMLEntities.new
10
- customise_liquid
11
- parse_options(opt)
12
- end
13
-
14
- def parse_options(opt)
15
- opt = Utils::sym_keys(opt)
16
- @i18n = opt[:i18n]
17
- @template_raw = opt[:template].dup
18
- @template =
19
- case opt[:template]
20
- when Hash
21
- opt[:template].transform_values { |x| template_process(x) }
22
- when Array then opt[:template].map { |x| template_process(x) }
23
- else { default: template_process(opt[:template]) }
24
- end
25
- end
26
-
27
- def customise_liquid
28
- ::Liquid::Template
29
- .register_filter(::Relaton::Render::Template::CapitalizeFirst)
30
- end
31
-
32
- # denote start and end of field,
33
- # so that we can detect empty fields in postprocessing
34
- FIELD_DELIM = "\u0018".freeze
35
-
36
- # escape < >
37
- LT_DELIM = "\u0019".freeze
38
- GT_DELIM = "\u001a".freeze
39
-
40
- # use tab internally for non-spacing delimiter
41
- NON_SPACING_DELIM = "\t".freeze
42
-
43
- def template_process(template)
44
- t = template.gsub(/\{\{/, "#{FIELD_DELIM}{{")
45
- .gsub(/\}\}/, "}}#{FIELD_DELIM}")
46
- .gsub(/\t/, " ")
47
- t1 = t.split(/(\{\{.+?\}\})/).map do |n|
48
- n.include?("{{") ? n : n.gsub(/(?<!\\)\|/, "\t")
49
- end.join
50
- ::Liquid::Template.parse(t1)
51
- end
52
-
53
- def render(hash)
54
- t = template_select(hash) or return nil
55
-
56
- template_clean(t.render(liquid_hash(hash.merge("labels" => @i18n.get))))
57
- end
58
-
59
- def template_select(_hash)
60
- @template[:default]
61
- end
62
-
63
- def template_clean(str)
64
- str = str.gsub(/&#x3c;/i, LT_DELIM).gsub(/&#x3e;/i, GT_DELIM)
65
- str = template_clean1(@htmlentities.decode(str))
66
- /[[:alnum:]]/.match?(str) or return nil
67
- str.strip.gsub(/#{LT_DELIM}/o, "&#x3c;")
68
- .gsub(/#{GT_DELIM}/o, "&#x3e;")
69
- .gsub(/&(?!#\S+?;)/, "&#x26;")
70
- end
71
-
72
- # use tab internally for non-spacing delimiter
73
- def template_clean1(str)
74
- str.gsub(/\S*#{FIELD_DELIM}#{FIELD_DELIM}\S*/o, "")
75
- .gsub(/#{FIELD_DELIM}/o, "")
76
- .gsub(/([,:;]\s*)+([,:;](\s|$))/, "\\2")
77
- .gsub(/([,.:;]\s*)+([.](\s|$))/, "\\2")
78
- .gsub(/([,:;]\s*)+(,(\s|$))/, "\\2")
79
- .gsub(/(:\s+)(&\s)/, "\\2")
80
- .gsub(/\s+([,.:;)])/, "\\1")
81
- .sub(/^\s*[,.:;]\s*/, "")
82
- .sub(/[,:;]\s*$/, "")
83
- .gsub(/(?<!\\)_/, " ")
84
- .gsub(/\\_/, "_")
85
- .gsub(/#{NON_SPACING_DELIM}/o, "").gsub(/\s+/, " ")
86
- end
87
-
88
- # need non-breaking spaces in fields: "Updated:_nil" ---
89
- # we want the "Updated:" deleted,
90
- # even if it's multiple words, as in French Mise_à_jour.
91
- def liquid_hash(hash)
92
- case hash
93
- when Hash
94
- hash.map { |k, v| [k.to_s, liquid_hash(v)] }.to_h
95
- when Array
96
- hash.map { |v| liquid_hash(v) }
97
- when String
98
- hash.empty? ? nil : hash.gsub(/ /, "_")
99
- else hash
100
- end
101
- end
102
- end
103
-
104
- class Series < General
105
- end
106
-
107
- class Extent < General
108
- def template_select(hash)
109
- @template[hash[:type].to_sym]
110
- end
111
- end
112
-
113
- class Size < General
114
- def template_select(hash)
115
- @template[hash[:type].to_sym]
116
- end
117
- end
118
-
119
- class Name < General
120
- def initialize(opt = {})
121
- @etal_count = opt[:template]["etal_count"]
122
- opt[:template].delete("etal_count")
123
- super
124
- end
125
-
126
- def template_select(names)
127
- return nil if names.nil? || names.empty?
128
-
129
- case names[:surname].size
130
- when 1 then @template[:one]
131
- when 2 then @template[:two]
132
- when 3 then @template[:more]
133
- else template_select_etal(names)
134
- end
135
- end
136
-
137
- def template_select_etal(names)
138
- if @etal_count && names[:surname].size >= @etal_count
139
- @template[:etal]
140
- else expand_nametemplate(@template_raw[:more], names[:surname].size)
141
- end
142
- end
143
-
144
- # assumes that template contains, consecutively and not interleaved,
145
- # ...[0], ...[1], ...[2]
146
- def expand_nametemplate(template, size)
147
- t = nametemplate_split(template)
148
- mid = (1..size - 2).each_with_object([]) do |i, m|
149
- m << t[1].gsub(/\[1\]/, "[#{i}]")
150
- end
151
- template_process(t[0] + mid.join + t[2].gsub(/\[2\]/,
152
- "[#{size - 1}]"))
153
- end
154
-
155
- def nametemplate_split(template)
156
- curr = 0
157
- prec = ""
158
- t = template.split(/(\{[{%].+?[}%]\})/)
159
- .each_with_object(["", "", ""]) do |n, m|
160
- m, curr, prec = nametemplate_split1(n, m, curr, prec)
161
-
162
- m
163
- end
164
- t[-1] += prec
165
- t
166
- end
167
-
168
- def nametemplate_split1(elem, acc, curr, prec)
169
- if match = /\{[{%].+?\[(\d)\]/.match(elem)
170
- curr += 1 if match[1].to_i > curr
171
- acc[curr] += prec
172
- prec = ""
173
- acc[curr] += elem
174
- elsif /\{%\s*endif/.match?(elem)
175
- acc[curr] += prec
176
- prec = ""
177
- acc[curr] += elem
178
- else prec += elem
179
- end
180
- [acc, curr, prec]
181
- end
182
- end
183
-
184
- class AuthorCite < Name
185
- end
186
- end
187
- end
188
- end