relaton-render 3.0.0.pre.alpha.21 → 3.0.0.pre.alpha.22

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: bfc55ca6da22673e6173486336211c48510588218d75e08672e8b3cfc09308cd
4
- data.tar.gz: 0a338c96b9ec80bbd6b345c86d6fa15a9b14810db27729104f1386391f46de69
3
+ metadata.gz: d485246fb8d04c771c257c63295000ade2b54462caaa884aa0a1aecdb22a6498
4
+ data.tar.gz: 8cbb2bed01af3e82d57ebc064853ead1dc0fd7215aab812b782ce5faaf59d4c3
5
5
  SHA512:
6
- metadata.gz: 4d172ba4dd2697389d3372a37eaf460d7673ab7a2ba693e8365f8777f241c8dc19df5b2dc9082563aaeeb08866634318dccfbed54d61a378b341ee0c7b88e954
7
- data.tar.gz: c0258407ac4ca2672164299ffe50b4ea671498dced9f653b06eb818e448e824e405b77e321a4e756f17710aba74a7f2892d69dfea3d7e6e216f84e23c6e6b190
6
+ metadata.gz: 467f05b5d476d4eb759d2248b863eca01e5319b18ab98c95c7283921a27ba5cdaf5ac9fcf93f8b10e24c2dee08028bdeeea25a975473d6311820f46229670826
7
+ data.tar.gz: cd5caf02198e2d34538eab81c0cd0732b1b276bc62195352e9aee68cd61221b180a585b4a3ff9d218664b3ec6deb7dc1d7c937fe85cd02bf887b8a84162071b9
@@ -148,6 +148,8 @@ module Relaton
148
148
  short
149
149
  end
150
150
 
151
+ title = renderer.title_citation(item)
152
+
151
153
  {
152
154
  full: ref,
153
155
  default: item.docidentifier.first&.content.to_s,
@@ -155,8 +157,14 @@ module Relaton
155
157
  author_date: renderer.author_date_citation(
156
158
  item, disambiguator: disambiguator,
157
159
  ),
160
+ author_date_br: renderer.bracketed_date_citation(
161
+ item, disambiguator: disambiguator,
162
+ ),
158
163
  author: renderer.in_text_author(item),
159
- title: renderer.title_citation(item),
164
+ date: renderer.disambiguated_date(item, disambiguator: disambiguator),
165
+ reference_tag: "",
166
+ title: title,
167
+ title_reference_tag: title,
160
168
  }
161
169
  end
162
170
 
@@ -256,7 +264,8 @@ module Relaton
256
264
  # and every flavor still pass string keys.
257
265
  def deep_symbolize(value)
258
266
  case value
259
- when Hash then value.to_h { |k, v| [k.to_sym, deep_symbolize(v)] }
267
+ # isodoc i18n hashes carry nil keys (an unlabeled punct slot)
268
+ when Hash then value.to_h { |k, v| [k&.to_sym, deep_symbolize(v)] }
260
269
  when Array then value.map { |v| deep_symbolize(v) }
261
270
  else value
262
271
  end
@@ -118,9 +118,12 @@ module Relaton
118
118
  end
119
119
 
120
120
  def join_names(names)
121
- # A style with no join word renders a plain serial list
121
+ # A style with no join word renders a plain serial list,
122
+ # separated per the locale (the comma, or the CJK 、)
122
123
  if @i18n.label("and").empty? && names.size > 1
123
- return names.join(", ")
124
+ sep = @i18n.label("list_separator")
125
+ sep = ", " if sep == "list_separator"
126
+ return names.join(sep)
124
127
  end
125
128
 
126
129
  oxford = @i18n.label("oxford_comma")
@@ -34,12 +34,12 @@ module Relaton
34
34
  # from the next element, which follows directly in the
35
35
  # template; a lone editor is unmarked unless declared
36
36
  if editors? && marked?
37
- "#{period(joined)} (#{role_word}) "
37
+ "#{period(joined)}#{role_space}#{role_parenthesis} "
38
38
  else
39
39
  "#{period(joined)} "
40
40
  end
41
41
  else
42
- marker = editors? && marked? ? " (#{role_word})" : ''
42
+ marker = editors? && marked? ? "#{role_space}#{role_parenthesis}" : ''
43
43
  "#{joined}#{marker}"
44
44
  end
45
45
  end
@@ -48,10 +48,30 @@ module Relaton
48
48
  # plain join, without the wrap and sentence period (1.x
49
49
  # short-cite templates carried no wrap)
50
50
  def plain_render
51
- marker = editors? && creators.size > 1 ? " (#{role_word})" : ''
51
+ marker = editors? && creators.size > 1 ?
52
+ "#{role_space}#{role_parenthesis}" : ''
52
53
  "#{join(names)}#{marker}"
53
54
  end
54
55
 
56
+ # The editor role marker's parentheses follow the locale
57
+ # (ASCII for Latin scripts, fullwidth for CJK)
58
+ def role_parenthesis
59
+ open = @i18n.punct_fetch("open-paren", "(")
60
+ close = @i18n.punct_fetch("close-paren", ")")
61
+ "#{open}#{role_word}#{close}"
62
+ end
63
+
64
+ # CJK cites the role marker tight against the name list
65
+ def role_space
66
+ @i18n.punct_fetch("marker-space", " ")
67
+ end
68
+
69
+ # The template-level role slot ("{{role}}"): the marker with
70
+ # its locale spacing, when the creators are all editors
71
+ def role_marker
72
+ editors? ? "#{role_space}#{role_parenthesis}" : ""
73
+ end
74
+
55
75
  def role_placement
56
76
  @style.scheme.name_form.role_placement || "glue"
57
77
  end
@@ -14,10 +14,39 @@ module Relaton
14
14
  def render
15
15
  return "#{@i18n.label('version')} #{raw}" unless word_edition?
16
16
 
17
+ # The worded forms first ("First edition", "第N版" via the
18
+ # ordinal template), the cardinal last
19
+ ordinal = locale_template("edition_ordinal", number)
20
+ return ordinal if ordinal
21
+
17
22
  word = @i18n.label("edition_#{number}")
18
23
  return word unless word == "edition_#{number}"
19
24
 
20
- "#{ordinalize(number)} #{@i18n.label('edition')}"
25
+ cardinal_form || "#{ordinalize(number)} #{@i18n.label('edition')}"
26
+ end
27
+
28
+ # The plain cardinal form ("edition 7")
29
+ def cardinal_form
30
+ locale_template("edition_cardinal", number) ||
31
+ locale_template("version_cardinal", number)
32
+ end
33
+
34
+ private
35
+
36
+ # A locale template carrying {{ var1 }} (optionally through
37
+ # the ordinal_word filter) populated with the edition number;
38
+ # a bare label (no placeholder) is not one
39
+ def locale_template(key, value)
40
+ raw = @i18n.label(key)
41
+ return nil if raw == key || raw !~ /\{{/
42
+
43
+ if raw.include?("ordinal_word")
44
+ word = @i18n.label("ordinal_word_#{value}")
45
+ word = ordinalize(value) if word == "ordinal_word_#{value}"
46
+ raw.gsub(/\{\{\s*var1[^}]*\}\}/, word)
47
+ else
48
+ raw.gsub("{{ var1 }}", value.to_s)
49
+ end
21
50
  end
22
51
 
23
52
  private
@@ -17,17 +17,24 @@ module Relaton
17
17
  return no_place_production_publisher_first if places.empty? &&
18
18
  no_place_declared?
19
19
 
20
- return [publishers.join("; "), places.join("; ")]
20
+ return [publishers.join("; "), places.map { |p| cjk_place(p) }]
21
21
  .reject(&:empty?).join(production_sep)
22
22
  end
23
23
 
24
24
  return no_place_production if places.empty? && no_place_declared?
25
25
 
26
- [places.join("; "), publishers.join("; ")]
26
+ [places.map { |p| cjk_place(p) }, publishers.join("; ")]
27
27
  .reject(&:empty?).join(production_sep)
28
28
  end
29
29
 
30
- def publisher_first?
30
+ # A CJK locale's place names carry the CJK-Latin separator
31
+ # ("Cambridge、UK" over "Cambridge, UK")
32
+ def cjk_place(place)
33
+ sep = @i18n.punct_fetch("cjk-latin-separator", "")
34
+ sep.empty? ? place : place.gsub(", ", sep)
35
+ end
36
+
37
+ def publisher_first?
31
38
  @i18n.punct_fetch("production_order", "") == "publisher_first"
32
39
  end
33
40
 
@@ -28,7 +28,11 @@ module Relaton
28
28
 
29
29
  type = value.is_a?(Hash) ? value[:type] : value.type
30
30
  unit = type && @i18n.label("size_#{type}")
31
- unit.nil? || unit == "size_#{type}" ? content : "#{content} #{unit}"
31
+ return content if unit.nil? || unit == "size_#{type}"
32
+
33
+ # The value/unit glue is locale-declared (CJK cites tight,
34
+ # "巻1" over "vol. 1")
35
+ "#{unit}#{@i18n.punct_fetch('size-join', ' ')}#{content}"
32
36
  end
33
37
  end
34
38
  end
@@ -30,6 +30,7 @@ module Relaton
30
30
  key = slot.to_s.delete("_").downcase
31
31
  table[key] = element_field(slot)
32
32
  end
33
+ table["role"] = role_field
33
34
  table["dategroup"] = dategroup_field
34
35
  table["disambiguateddate"] = disambiguated_date_field(table["date"])
35
36
  unless table["dategroup"].present?
@@ -38,6 +39,20 @@ module Relaton
38
39
  table.merge(name_fields)
39
40
  end
40
41
 
42
+ # The creators' editor-role marker ("(eds.)", "(編)"), as a
43
+ # template slot: a creator list that is not all editors cites no
44
+ # role
45
+ def role_field
46
+ creator = Elements.build(:creator, @model, style: @style,
47
+ i18n: @i18n, elements: @elements)
48
+ return Template::Field[false, ""] unless
49
+ creator&.present? && creator.respond_to?(:role_marker)
50
+
51
+ marker = creator.role_marker
52
+ marker.empty? ? Template::Field[false, ""] :
53
+ Template::Field[true, marker]
54
+ end
55
+
41
56
  # The date carrying the batch disambiguation suffix ("2022a"):
42
57
  # identity when the caller passes none
43
58
  def disambiguated_date_field(date)
@@ -1,6 +1,16 @@
1
1
  lang: en
2
2
  labels:
3
3
  edition: "ed"
4
+ ordinal_word_1: "First"
5
+ ordinal_word_2: "Second"
6
+ ordinal_word_3: "Third"
7
+ ordinal_word_4: "Fourth"
8
+ ordinal_word_5: "Fifth"
9
+ ordinal_word_6: "Sixth"
10
+ ordinal_word_7: "Seventh"
11
+ ordinal_word_8: "Eighth"
12
+ ordinal_word_9: "Ninth"
13
+ ordinal_word_10: "Tenth"
4
14
  size_volume: "vol."
5
15
  size_page: "pp."
6
16
  page: "p."
@@ -0,0 +1,38 @@
1
+ lang: ja
2
+ labels:
3
+ edition: "版"
4
+ size_volume: "巻"
5
+ size_page: "頁"
6
+ page: "頁"
7
+ pages: "頁"
8
+ volume: "巻"
9
+ issue: "号"
10
+ version: "版"
11
+ viewed: "閲覧"
12
+ series_no: "番号"
13
+ report_no: "報告番号"
14
+ available_from: "入手先:"
15
+ at_url: "URL:"
16
+ in: "収録:"
17
+ ed: "編"
18
+ eds: "編"
19
+ updated: "更新"
20
+ no_place: "出版地不明"
21
+ edition_cardinal: "第{{ var1 }}版"
22
+ edition_ordinal: "第{{ var1 }}版"
23
+ version_cardinal: "第{{ var1 }}版"
24
+ in_series: "シリーズ"
25
+ list_separator: "、 "
26
+ and: ""
27
+ oxford_comma: ""
28
+ date_range: "–"
29
+ punct:
30
+ size-join: ""
31
+ marker-space: ""
32
+ production_sep: ": "
33
+ cjk-latin-separator: "、 "
34
+ period: "。"
35
+ comma: "、"
36
+ colon: ":"
37
+ open-paren: "("
38
+ close-paren: ")"
@@ -43,6 +43,7 @@ module Relaton
43
43
  known = %w[
44
44
  edition series_no report_no available_from in and oxford_comma
45
45
  ed eds date_range others no_date no_author at
46
+ edition_ordinal edition_cardinal version_cardinal
46
47
  ]
47
48
  hash.each do |key, value|
48
49
  labels[key.to_s] = value if known.include?(key.to_s) && !value.nil?
@@ -92,6 +92,28 @@ module Relaton
92
92
  .reject(&:empty?).join(" ")
93
93
  end
94
94
 
95
+ # The bracketed author-date in-text capsule ("Aluffi (2022)"):
96
+ # the author and the date in the locale's parentheses
97
+ def bracketed_date_citation(model, disambiguator: nil)
98
+ f = Fields.new(model, style: @style, i18n: @i18n,
99
+ disambiguator: disambiguator,
100
+ elements: @elements).to_h
101
+ date = f["disambiguateddate"].text
102
+ return "" if date.empty?
103
+
104
+ open = @i18n.punct_fetch("open-paren", "(")
105
+ close = @i18n.punct_fetch("close-paren", ")")
106
+ [in_text_author(model), "#{open}#{date}#{close}"]
107
+ .reject(&:empty?).join(" ")
108
+ end
109
+
110
+ # The disambiguated date alone (the citation renderings' date)
111
+ def disambiguated_date(model, disambiguator: nil)
112
+ Fields.new(model, style: @style, i18n: @i18n,
113
+ disambiguator: disambiguator,
114
+ elements: @elements).to_h["disambiguateddate"].text
115
+ end
116
+
95
117
  # The title citation ("{{ title }}" in the 1.x citetemplate):
96
118
  # the title element's plain form, no style markers
97
119
  def title_citation(model)
@@ -124,9 +124,14 @@ module Relaton
124
124
  end
125
125
 
126
126
  # A template's paired literal ("({{production}})") closes even
127
- # when nothing follows the present element it wraps
127
+ # when nothing follows the present element it wraps. Fullwidth
128
+ # parens (CJK) pair the same way
128
129
  def close_pending_paren?(out, value)
129
- value.start_with?(")") && out.count("(") > out.count(")")
130
+ return false unless value.start_with?(")", "\uFF09")
131
+
132
+ opens = out.count("(") + out.count("\uFF08")
133
+ closes = out.count(")") + out.count("\uFF09")
134
+ opens > closes
130
135
  end
131
136
 
132
137
  def terminate(body)
@@ -1,5 +1,5 @@
1
1
  module Relaton
2
2
  module Render
3
- VERSION = "3.0.0.pre.alpha.21".freeze
3
+ VERSION = "3.0.0.pre.alpha.22".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: 3.0.0.pre.alpha.21
4
+ version: 3.0.0.pre.alpha.22
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-10-06 00:00:00.000000000 Z
11
+ date: 2026-10-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: htmlentities
@@ -143,6 +143,7 @@ files:
143
143
  - lib/relaton/render/iso690/i18n.rb
144
144
  - lib/relaton/render/iso690/i18n/en.yml
145
145
  - lib/relaton/render/iso690/i18n/fr.yml
146
+ - lib/relaton/render/iso690/i18n/ja.yml
146
147
  - lib/relaton/render/iso690/identifier_kinds.rb
147
148
  - lib/relaton/render/iso690/index_renderer.rb
148
149
  - lib/relaton/render/iso690/kinds.rb