relaton-render 0.5.4 → 0.5.6

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c8779d553f6f96bee35c94ba359e34485d32f6d6408741921605f47affd3f6ed
4
- data.tar.gz: 95ac20e5eb03a0a02e95fd25aa9cbef8070c061bcd1b5d64a26dc8973213a81c
3
+ metadata.gz: ca7bf47fcca9f20390105c3bd1168e9bfa9fa6e16289fc8155be3de4b1b9e5fb
4
+ data.tar.gz: 6e2e6e8882405c484067bf2bf760af8a1aa84a2639583e2ea5e3ec4fe92d5683
5
5
  SHA512:
6
- metadata.gz: ca75fef0dd5c3f29ce115d470828e564206764ff2f93e4ce710edba7bcd1e0f38b010275d3d873180df7dbe84781d84ec1caed26c1519297635d02af9f78621b
7
- data.tar.gz: 5ce4b44da59612f956fab4ea2d8d18456989fbd72614e5176e5c7bf1f729f6c567b5f641a4e82f3dfc1caad0c75c1401f5de413d47940d2e32e79d270a0471b7
6
+ metadata.gz: de6bd46639d0419f4c271fe451768e10be23d044f8d0957c2659412461052ff6a8ca34de7b8e23fa73fcc569ef8bb72da90f4fdb8d7aec9d40f9489dad2cf5a9
7
+ data.tar.gz: 27d0c9a160d2d784272a71d15d335f1e882ffac41d25c81af084e8fe624356dfd4a4098041ad6ac43977d7eb5a25398efb65c68ce51fca7dd37bfd5e5a7482cd
data/README.adoc CHANGED
@@ -158,7 +158,7 @@ drawn from the bibliographic item:
158
158
  | authoritative_identifier | ./docidentifier[not(@type = 'metanorma' or @type = 'ordinal' or @type = 'ISBN' or @type = 'ISSN' or @type = 'DOI')] | Y | |
159
159
  | other_identifier | ./docidentifier[@type = 'ISBN' or @type = 'ISSN' or @type = 'DOI'] | Y | | By default, each such identifier is prefixed with its type and colon
160
160
  | status | ./status | | | Rendering varies by flavour
161
- | uri | ./uri[@type = 'citation' or @type = 'doi' or @type = 'uri' or @type = 'src' or true] | | | If multiples, prioritise language match
161
+ | uri | ./uri[@type = 'citation' or @type = 'uri' or @type = 'src' or true] | | | If multiples, prioritise language match. Always exclude DOI: that is not where the resource is available from
162
162
  | access_location | ./accessLocation | | Y |
163
163
  | extent | ./extent | Y | | Render with standard abbreviations for pp, vols, with n-dash, with delimiting of multiple locations
164
164
  | creatornames | ./contributor[role/@type = 'author'] \| ./contributor[role/@type = 'performer'] \| ./contributor[role/@type = 'adapter'] \| ./contributor[role/@type = 'translator'] \| ./contributor[role/@type = 'editor'] \| ./contributor[role/@type = 'distributor'] \| ./contributor | Y | | <<nametemplate,`nametemplate`>> applied to each name; joining template from internationalisation applied to multiple names
@@ -256,12 +256,31 @@ For example:
256
256
 
257
257
  In the case of `more`, the `(name)[1]` entries are repeated for all additional authors above 2 and before the final author.
258
258
 
259
+ The behaviour of _et al._ can be specified as follows:
260
+
261
+ * `etal_count`: the number of authors to trigger _et al._ in bibliographic rendering
262
+ * `etal_display`: how many authors to show if using _et al._ in bibliography (by default, same as `etal_count`)
263
+
264
+ So the Chicago Manual of Style behaviour:
265
+
266
+ ____
267
+ For more than ten authors (not shown here), list the first seven in the reference list, followed by et al.
268
+ ____
269
+
270
+ is realised with etal_count = 10, etal_display = 7
271
+
259
272
  [[authorcitetemplate]]
260
273
  === Author citation templates
261
274
 
262
275
  The `authorcitetemplate` is a subclass of the name template, configured for rendering author names for author-date citations.
263
276
  That means that it typically selects only surnames for rendering.
264
277
 
278
+
279
+ The behaviour of _et al._ in author-date citations can be specified as follows:
280
+
281
+ * `etal_count`: the number of authors to trigger _et al._ in bibliographic rendering
282
+ * `etal_display`: how many authors to show if using _et al._ in bibliography (by default, same as `etal_count`)
283
+
265
284
  [[seriestemplate]]
266
285
  === Series template
267
286
 
@@ -31,35 +31,35 @@ sizetemplate:
31
31
  language: en
32
32
  script: Latn
33
33
  template:
34
- book: "{{ creatornames }} ({{role}}) . {{labels['qq-open']}}|{{ title }}|{{labels['qq-close']}} [{{medium}}] . {{ edition | capitalize_first }}. ({{ series }}.) {% if place %}{{place}}{%else%}{{ labels['no_place']}}{%endif%}: {{publisher}}. {{date}}. {{ labels['updated'] | capitalize }}:_{{date_updated}}. {{ authoritative_identifier | join: '. ' }}. {{ other_identifier | join: '. ' }}. {{ uri }}. {{ labels['at'] | capitalize}}:_{{ access_location }}. [{{ labels['viewed'] }}:_{{date_accessed}}]. {{size}}. {{extent}}."
34
+ book: "{{ creatornames }} ({{role}}) . {{labels['qq-open']}}{{ title }}{{labels['qq-close']}} [{{medium}}] . {{ edition | capitalize_first }}. ({{ series }}.) {% if place %}{{place}}{%else%}{{ labels['no_place']}}{%endif%}: {{publisher}}. {{date}}. {{ labels['updated'] | capitalize }}:_{{date_updated}}. {{ authoritative_identifier | join: '. ' }}. {{ other_identifier | join: '. ' }}. {{ uri }}. {{ labels['at'] | capitalize}}:_{{ access_location }}. [{{ labels['viewed'] }}:_{{date_accessed}}]. {{size}}. {{extent}}."
35
35
  # TODO: omitted: author ids, subsidiary titles, subsidiary creators, rights metadata, distributor, item attributes, relationships
36
36
  booklet: book
37
37
  manual: book
38
38
  proceedings: book
39
- inbook: "{{ creatornames }} ({{role}}) . {{labels['q-open']}}|{{ title }}|{{labels['q-close']}} . {{ labels['in'] | capitalize }}: {{ host_creatornames}} ({{ host_role}}) : {{labels['qq-open']}}|{{host_title}}|{{labels['qq-close']}} [{{medium}}] . {{ edition | capitalize_first }}. ({{ series }}.) {% if place %}{{place}}{%else%}{{ labels['no_place']}}{%endif%}: {{publisher}}. {{date}}. {{size}}. {{extent}}. {{ labels['updated'] | capitalize }}:_{{date_updated}}. {{ authoritative_identifier | join: '. ' }}. {{ other_identifier | join: '. ' }}. {{ uri }}. {{ labels['at'] | capitalize}}:_{{ access_location }}. [{{ labels['viewed'] }}:_{{date_accessed}}]."
39
+ inbook: "{{ creatornames }} ({{role}}) . {{labels['q-open']}}{{ title }}{{labels['q-close']}} . {{ labels['in'] | capitalize }}: {{ host_creatornames}} ({{ host_role}}) : {{labels['qq-open']}}{{host_title}}{{labels['qq-close']}} [{{medium}}] . {{ edition | capitalize_first }}. ({{ series }}.) {% if place %}{{place}}{%else%}{{ labels['no_place']}}{%endif%}: {{publisher}}. {{date}}. {{size}}. {{extent}}. {{ labels['updated'] | capitalize }}:_{{date_updated}}. {{ authoritative_identifier | join: '. ' }}. {{ other_identifier | join: '. ' }}. {{ uri }}. {{ labels['at'] | capitalize}}:_{{ access_location }}. [{{ labels['viewed'] }}:_{{date_accessed}}]."
40
40
  inproceedings: inbook
41
41
  incollection: inbook
42
42
  # TODO: omitted: author ids, additional info for component part, subsidiary titles of host resource, rights metadata, distributor, relationships
43
- journal: "{{labels['qq-open']}}|{{ title}}|{{labels['qq-close']}} [{{medium}}] . {{ edition | capitalize_first }}. {{place}}: {{publisher}}. {{date}}. {{size}}. {{extent}}. {{ authoritative_identifier | join: '. ' }}. {{ other_identifier | join: '. ' }}. {{ uri }}. {{ labels['at'] | capitalize}}:_{{ access_location }}. [{{ labels['viewed'] }}:_{{date_accessed}}]."
43
+ journal: "{{labels['qq-open']}}{{ title}}{{labels['qq-close']}} [{{medium}}] . {{ edition | capitalize_first }}. {{place}}: {{publisher}}. {{date}}. {{size}}. {{extent}}. {{ authoritative_identifier | join: '. ' }}. {{ other_identifier | join: '. ' }}. {{ uri }}. {{ labels['at'] | capitalize}}:_{{ access_location }}. [{{ labels['viewed'] }}:_{{date_accessed}}]."
44
44
  # TODO subsidiary titles, rights metadata, item attributes, relationships
45
- article: "{{ creatornames }} ({{role}}) . {{labels['q-open']}}|{{ title }}|{{labels['q-close']}}. {{ series }} [{{medium}}] . {{ edition | capitalize_first }}. {{size}}. {{ extent }}. {{place}}: {{publisher}}. {{date}}. {{ labels['updated'] | capitalize }}:_{{date_updated}}. {{ authoritative_identifier | join: '. ' }}. {{ other_identifier | join: '. ' }}. {{ uri }}. {{ labels['at'] | capitalize}}:_{{ access_location }}. [{{ labels['viewed'] }}:_{{date_accessed}}]."
45
+ article: "{{ creatornames }} ({{role}}) . {{labels['q-open']}}{{ title }}{{labels['q-close']}}. {{ series }} [{{medium}}] . {{ edition | capitalize_first }}. {{size}}. {{ extent }}. {{place}}: {{publisher}}. {{date}}. {{ labels['updated'] | capitalize }}:_{{date_updated}}. {{ authoritative_identifier | join: '. ' }}. {{ other_identifier | join: '. ' }}. {{ uri }}. {{ labels['at'] | capitalize}}:_{{ access_location }}. [{{ labels['viewed'] }}:_{{date_accessed}}]."
46
46
  # TODO: omitted: author ids, subsidiary titles, rights metadata, distributor, item attributes, relationships; newspapers
47
- software: "{{ creatornames }} ({{ role}}) . {{labels['qq-open']}}|{{ title }}|{{labels['qq-close']}} . {{ labels['version'] | capitalize }}_{{ edition_raw }}. {{medium | capitalize}}. {{place}}: {{publisher}}. {{date}}. {{ labels['updated'] | capitalize }}:_{{date_updated}}. {{ authoritative_identifier | join: '. ' }}. {{ other_identifier | join: '. ' }}. {{ uri }}. {{size}}. {{ extent}}. [{{ labels['viewed'] }}:_{{date_accessed}}]. "
47
+ software: "{{ creatornames }} ({{ role}}) . {{labels['qq-open']}}{{ title }}{{labels['qq-close']}} . {{ labels['version'] | capitalize }}_{{ edition_raw }}. {{medium | capitalize}}. {{place}}: {{publisher}}. {{date}}. {{ labels['updated'] | capitalize }}:_{{date_updated}}. {{ authoritative_identifier | join: '. ' }}. {{ other_identifier | join: '. ' }}. {{ uri }}. {{size}}. {{ extent}}. [{{ labels['viewed'] }}:_{{date_accessed}}]. "
48
48
  # TODO: omitted: author ids, subsidiary titles, subsidiary creators, copyright, license, distributor, system requirements, relationships
49
49
  electronic resource: software
50
- standard: "{{ creatornames }} ({{ role}}) . {{ authoritative_identifier | join '|' }}: {{labels['qq-open']}}|{{ title }}|{{labels['qq-close']}} . {{ labels['in'] | capitalize }}:_{{ series_title }}. {{ medium | capitalize }}. {{ edition | capitalize_first }}. {{ place }}: {{ publisher }}. {{date}}. {{size}}. {{ extent }}. {{ other_identifier | join: '. ' }}. {{ uri }}. {{ labels['at'] | capitalize}}:_{{ access_location }}. [{{ labels['viewed'] }}:_{{date_accessed}}]."
50
+ standard: "{{ creatornames }} ({{ role}}) . {{ authoritative_identifier | join '|' }}: {{labels['qq-open']}}{{ title }}{{labels['qq-close']}} . {{ labels['in'] | capitalize }}:_{{ series_title }}. {{ medium | capitalize }}. {{ edition | capitalize_first }}. {{ place }}: {{ publisher }}. {{date}}. {{size}}. {{ extent }}. {{ other_identifier | join: '. ' }}. {{ uri }}. {{ labels['at'] | capitalize}}:_{{ access_location }}. [{{ labels['viewed'] }}:_{{date_accessed}}]."
51
51
  # TODO: omitted: author ids, subsidiary titles, rights metadata, distributor, persistent identifier, item attributes, relationships
52
52
  techreport: standard
53
- dataset: "{{ creatornames }} ({{ role }}) . {{labels['qq-open']}}|{{ title }}|{{labels['qq-close']}} . {{ labels['version'] | capitalize }}_{{ edition_raw }}. {{medium | capitalize }}. {{ labels['in'] | capitalize }}:_{{series}}. {{date}}. {{ labels['updated'] | capitalize }}:_{{date_updated}}. {{ authoritative_identifier | join: '. ' }}. {{ other_identifier | join: '. ' }}. {{ uri }}. {{ size }}. {{ extent}}. [{{ labels['viewed'] }}:_{{date_accessed}}]. "
53
+ dataset: "{{ creatornames }} ({{ role }}) . {{labels['qq-open']}}{{ title }}{{labels['qq-close']}} . {{ labels['version'] | capitalize }}_{{ edition_raw }}. {{medium | capitalize }}. {{ labels['in'] | capitalize }}:_{{series}}. {{date}}. {{ labels['updated'] | capitalize }}:_{{date_updated}}. {{ authoritative_identifier | join: '. ' }}. {{ other_identifier | join: '. ' }}. {{ uri }}. {{ size }}. {{ extent}}. [{{ labels['viewed'] }}:_{{date_accessed}}]. "
54
54
  # TODO: omitted: author ids, system requirements, host archive, copyright, license, data source, distributor, usage instructions, relationships, provenance
55
- website: "{{ creatornames }} ({{ role }}) . {{labels['qq-open']}}|{{ title }}|{{labels['qq-close']}} . {{ labels['version'] | capitalize }}_{{ edition_raw }}. {{medium | capitalize }}. {{ place }}: {{ publisher }}. {{date}}. {{ labels['updated'] | capitalize }}:_{{date_updated}}. {{ authoritative_identifier | join: '. ' }}. {{ other_identifier | join: '. ' }}. {{ uri }}. [{{ labels['viewed'] }}:_{{date_accessed}}]. "
55
+ website: "{{ creatornames }} ({{ role }}) . {{labels['qq-open']}}{{ title }}{{labels['qq-close']}} . {{ labels['version'] | capitalize }}_{{ edition_raw }}. {{medium | capitalize }}. {{ place }}: {{ publisher }}. {{date}}. {{ labels['updated'] | capitalize }}:_{{date_updated}}. {{ authoritative_identifier | join: '. ' }}. {{ other_identifier | join: '. ' }}. {{ uri }}. [{{ labels['viewed'] }}:_{{date_accessed}}]. "
56
56
  # TODO: omitted: author ids, page title, system requirements, subsidiary creator, rights metadata, distributor, persistent identifier, archive location, archive date and time, relationships
57
57
  webresource: website
58
58
  # TODO: component part
59
- unpublished: "{{ creatornames }} ({{ role }}) . {{labels['qq-open']}}|{{ title }}|{{labels['qq-close']}} . {{ medium | capitalize }}. {{ date }}. {{ labels['at'] | capitalize}}:_{{ access_location }}. {{ authoritative_identifier | join: '. ' }}. {{ other_identifier | join: '. ' }}. {{ uri }}. [{{ labels['viewed'] }}:_{{date_accessed}}]."
59
+ unpublished: "{{ creatornames }} ({{ role }}) . {{labels['qq-open']}}{{ title }}{{labels['qq-close']}} . {{ medium | capitalize }}. {{ date }}. {{ labels['at'] | capitalize}}:_{{ access_location }}. {{ authoritative_identifier | join: '. ' }}. {{ other_identifier | join: '. ' }}. {{ uri }}. [{{ labels['viewed'] }}:_{{date_accessed}}]."
60
60
  # TODO: omitted: author ids, subsidiary titles, subsidiary creators, host archive, item attributes, relationships
61
61
  presentation: unpublished
62
- thesis: "{{ creatornames }} ({{ role }}) . {{labels['qq-open']}}|{{ title }}|{{labels['qq-close']}} . {{ medium | capitalize }}. {{ place }}: {{ publisher }}. {{ date }}. {{ labels['at'] | capitalize}}:_{{ access_location }}. {{ authoritative_identifier | join: '. ' }}. {{ other_identifier | join: '. ' }}. {{ uri }}. [{{ labels['viewed'] }}:_{{date_accessed}}]."
62
+ thesis: "{{ creatornames }} ({{ role }}) . {{labels['qq-open']}}{{ title }}{{labels['qq-close']}} . {{ medium | capitalize }}. {{ place }}: {{ publisher }}. {{ date }}. {{ labels['at'] | capitalize}}:_{{ access_location }}. {{ authoritative_identifier | join: '. ' }}. {{ other_identifier | join: '. ' }}. {{ uri }}. [{{ labels['viewed'] }}:_{{date_accessed}}]."
63
63
  misc: "{{ creatornames }} ({{ role }}) . {{labels['qq-open']}}{{ title }}{{labels['qq-close']}} . {{ date }}."
64
64
  # following are # unsupported types:
65
65
  map: misc
@@ -1,14 +1,19 @@
1
1
  module Relaton
2
2
  module Render
3
3
  class Parse
4
+ def content(node)
5
+ node.nil? and return node
6
+ node.content.strip
7
+ end
8
+
4
9
  def extract_orgname(org)
5
- org.name&.first&.content
10
+ content(org.name&.first)
6
11
  end
7
12
 
8
13
  def extract_personname(person)
9
14
  surname = person.name.surname || person.name.completename
10
15
  given, middle, initials = given_and_middle_name(person)
11
- { surname: surname.content,
16
+ { surname: content(surname),
12
17
  given: given,
13
18
  middle: middle,
14
19
  initials: initials }
@@ -16,9 +21,9 @@ module Relaton
16
21
 
17
22
  def given_and_middle_name(person)
18
23
  forenames = person.name.forename.map do |x|
19
- x.content.empty? ? "#{x.initial}." : x.content
24
+ x.content.empty? ? "#{x.initial}." : content(x)
20
25
  end
21
- initials = person.name.initials&.content&.sub(/(.)\.?$/, "\\1.")
26
+ initials = content(person.name.initials)&.sub(/(.)\.?$/, "\\1.")
22
27
  &.split /(?<=\.) /
23
28
  initials ||= person.name.forename.map(&:initial)
24
29
  .compact.map { |x| x.sub(/(.)\.?$/, "\\1.") }
@@ -29,13 +34,13 @@ module Relaton
29
34
 
30
35
  def forenames_parse(person)
31
36
  person.name.forename.map do |x|
32
- x.content.empty? ? "#{x.initial}." : x.content
37
+ x.content.empty? ? "#{x.initial}." : content(x)
33
38
  end
34
39
  end
35
40
 
36
41
  # de S. => one initial, M.-J. => one initial
37
42
  def initials_parse(person)
38
- i = person.name.initials&.content or
43
+ i = content(person.name.initials) or
39
44
  return person.name.forename.map(&:initial)
40
45
  .compact.map { |x| x.sub(/(.)\.?$/, "\\1.") }
41
46
 
@@ -136,8 +141,8 @@ module Relaton
136
141
  host and x ||= pick_contributor(host, "publisher")
137
142
  x.nil? and return nil
138
143
  x.map do |c|
139
- c.entity.abbreviation&.content ||
140
- c.entity.name.first&.content
144
+ content(c.entity.abbreviation) ||
145
+ content(c.entity.name.first)
141
146
  end
142
147
  end
143
148
 
@@ -13,7 +13,7 @@ module Relaton
13
13
  t.empty? and t = doc.title
14
14
  t1 = t.select { |x| x.type == "main" }
15
15
  t1.empty? and t1 = t
16
- t1.first&.title&.content
16
+ content(t1.first&.title)
17
17
  end
18
18
 
19
19
  def medium(doc, host)
@@ -33,7 +33,7 @@ module Relaton
33
33
  end
34
34
 
35
35
  def edition(doc, host)
36
- doc.edition&.content || host&.edition&.content
36
+ content(doc.edition || host&.edition)
37
37
  end
38
38
 
39
39
  def edition_num(doc, host)
@@ -65,17 +65,19 @@ module Relaton
65
65
  return nil if series.nil?
66
66
 
67
67
  series.title.respond_to?(:titles) && !series.title.titles.empty? and
68
- return series.title.titles.first.title.content
69
- series.title.respond_to?(:title) and return series.title.title&.content
70
- series.title.respond_to?(:formattedref) and series.formattedref.content
68
+ return content(series.title.titles.first.title)
69
+ series.title.respond_to?(:title) and
70
+ return content(series.title.title)
71
+ series.title.respond_to?(:formattedref) and
72
+ content(series.formattedref)
71
73
  end
72
74
 
73
75
  def series_formatted(series, _doc)
74
- series.formattedref&.content
76
+ content(series.formattedref)
75
77
  end
76
78
 
77
79
  def series_abbr(series, _doc)
78
- series.abbreviation&.content
80
+ content(series.abbreviation)
79
81
  end
80
82
 
81
83
  def series_num(series, _doc)
@@ -113,21 +115,23 @@ module Relaton
113
115
 
114
116
  def uri(doc)
115
117
  uri = nil
116
- %w(citation doi uri src).each do |t|
118
+ %w(citation uri src).each do |t|
117
119
  uri = uri_type_select(doc, t) and break
118
120
  end
119
- uri ||= doc.link.detect { |u| u.language == @lang }
120
- uri ||= doc.link.first
121
+ uri ||= doc.link.detect do |u|
122
+ u.language == @lang && !u.type&.casecmp("doi")&.zero?
123
+ end
124
+ uri ||= doc.link.detect { |u| !u.type&.casecmp("doi")&.zero? }
121
125
  return nil unless uri
122
126
 
123
- uri.content.to_s
127
+ uri.content.to_s.strip
124
128
  end
125
129
 
126
130
  def uri_type_select(doc, type)
127
131
  uri = doc.link.detect do |u|
128
- u.type == type && u.language == @lang
132
+ u.type&.downcase == type && u.language == @lang
129
133
  end and return uri
130
- uri = doc.link.detect { |u| u.type == type } and return uri
134
+ uri = doc.link.detect { |u| u.type&.downcase == type } and return uri
131
135
  nil
132
136
  end
133
137
 
@@ -199,7 +203,7 @@ module Relaton
199
203
  def localized_string_or_text(str)
200
204
  case str
201
205
  when RelatonBib::LocalizedString
202
- str.content
206
+ content(str)
203
207
  when String
204
208
  str
205
209
  end
@@ -31,7 +31,7 @@ module Relaton
31
31
 
32
32
  # denote start and end of field,
33
33
  # so that we can detect empty fields in postprocessing
34
- #FIELD_DELIM = "\u0018".freeze
34
+ # FIELD_DELIM = "\u0018".freeze
35
35
  FIELD_DELIM = "%%".freeze
36
36
 
37
37
  # escape < >
@@ -130,7 +130,9 @@ module Relaton
130
130
  class Name < General
131
131
  def initialize(opt = {})
132
132
  @etal_count = opt[:template]["etal_count"]
133
+ @etal_display = opt[:template]["etal_display"] || @etal_count
133
134
  opt[:template].delete("etal_count")
135
+ opt[:template].delete("etal_display")
134
136
  super
135
137
  end
136
138
 
@@ -147,8 +149,9 @@ module Relaton
147
149
 
148
150
  def template_select_etal(names)
149
151
  if @etal_count && names[:surname].size >= @etal_count
150
- @template[:etal]
151
- else expand_nametemplate(@template_raw[:more], names[:surname].size)
152
+ expand_nametemplate(@template_raw[:etal], @etal_display)
153
+ else
154
+ expand_nametemplate(@template_raw[:more], names[:surname].size)
152
155
  end
153
156
  end
154
157
 
@@ -156,29 +159,41 @@ module Relaton
156
159
  # ...[0], ...[1], ...[2]
157
160
  def expand_nametemplate(template, size)
158
161
  t = nametemplate_split(template)
162
+
159
163
  mid = (1..size - 2).each_with_object([]) do |i, m|
160
164
  m << t[1].gsub(/\[1\]/, "[#{i}]")
161
165
  end
162
- template_process(t[0] + mid.join + t[2].gsub(/\[2\]/,
163
- "[#{size - 1}]"))
166
+ t[1] = mid.join
167
+ t[2].gsub!(/\[\d+\]/, "[#{size - 1}]")
168
+ template_process(combine_nametemplate(t, size))
169
+ end
170
+
171
+ def combine_nametemplate(parts, size)
172
+ case size
173
+ when 1 then parts[0] + parts[3]
174
+ when 2 then parts[0] + parts[2] + parts[3]
175
+ else parts.join
176
+ end
164
177
  end
165
178
 
166
179
  def nametemplate_split(template)
167
180
  curr = 0
168
181
  prec = ""
169
182
  t = template.split(/(\{[{%].+?[}%]\})/)
170
- .each_with_object(["", "", ""]) do |n, m|
183
+ .each_with_object([""]) do |n, m|
171
184
  m, curr, prec = nametemplate_split1(n, m, curr, prec)
172
185
 
173
186
  m
174
187
  end
175
- t[-1] += prec
176
- t
188
+ [t[0], t[1], t[-1], prec]
177
189
  end
178
190
 
179
191
  def nametemplate_split1(elem, acc, curr, prec)
180
192
  if match = /\{[{%].+?\[(\d)\]/.match(elem)
181
- curr += 1 if match[1].to_i > curr
193
+ if match[1].to_i > curr
194
+ curr += 1
195
+ acc[curr] ||= ""
196
+ end
182
197
  acc[curr] += prec
183
198
  prec = ""
184
199
  acc[curr] += elem
@@ -1,5 +1,5 @@
1
1
  module Relaton
2
2
  module Render
3
- VERSION = "0.5.4".freeze
3
+ VERSION = "0.5.6".freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: relaton-render
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.4
4
+ version: 0.5.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-11-28 00:00:00.000000000 Z
11
+ date: 2022-12-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler