relaton-render 3.0.0.pre.alpha.25 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ecdbfb0b1c82700b6c957c9eeb259fd48f48d391a35062b07e4d6d6ede4ccb2e
4
- data.tar.gz: 199330b061ce3e07eb3edff0364ffc313773eb27cf6f7b8d0a216bff4caa3cac
3
+ metadata.gz: e2d52f05f42c17071799e1cc19e71d0b84f84a0550430d287e4d8cf4dee389a6
4
+ data.tar.gz: 4170319d650b7d3de48553d5fcddb15857b24939e9a6e008d7f74c095f849f60
5
5
  SHA512:
6
- metadata.gz: f21d46a60631252c2011e73096ea2ff321fae8f8f361c9e8bc46b53709d304da350bac73ab3eb44cdf7c5a4ec6a35c74f10875aa5548e417fc9c66afc43a8693
7
- data.tar.gz: 2fac8549403467928c30917f75e167fba771a3f175c5128d9c2a1daab37cb813cd29b1feb493746559c985df068b68306d9cdd2cd1cb5fb63b82e0e79445a150
6
+ metadata.gz: 021e4859ac3ba1f2dda762db881d1322677578359dc0f9a7c319435d7692a36fb6dcc1b96b9b068ca3ed65f9a621648da698962e49d2d2b132adbf5ea2ee66ff
7
+ data.tar.gz: ad7e119b111cac93e1c70fd0af76431a33dc9e95a5508ca866ab556c7b7e3484e7ae31c1981778f2a86ad6c35ba5ecfdfee9799b2a8c1e21480184f81915bc98
@@ -320,7 +320,10 @@ instances (never ad-hoc hash merges):
320
320
  * `perType`, `types`: merge **per type key** — a delta's `article`
321
321
  entry overlays the base's; the base's other entries survive.
322
322
  * `labels`, `punct`, `fallbacks`: per-key merge.
323
- * `nameForm` knobs, `templates.*`, rule selections: replace.
323
+ * `nameForm` knobs, `templates.*`, rule selections: replace — with
324
+ the caveat that a knob left at its model default counts as unset and
325
+ inherits (a Lutaml model cannot distinguish an explicit default from
326
+ an absent key).
324
327
  * `sortKey`, `requires`: union.
325
328
 
326
329
  The forcing test: PLATEAU's four near-copy styles (document-language
@@ -24,8 +24,8 @@ module Relaton
24
24
 
25
25
  def initialize(style: DEFAULT_STYLE, lang: "en", script: "Latn",
26
26
  labels: {}, elements: {})
27
- @elements = elements
28
27
  @style = Style.load(style)
28
+ @elements = Rules.resolve(@style.rules, elements)
29
29
  @i18n = I18n.load(lang)
30
30
  @i18n.overlay_hash!(labels) unless labels.empty?
31
31
  # The style instance is the citation-style authority: its
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Relaton
4
+ module Render
5
+ module Iso690
6
+ # The named-rule registry: presentation-of-models implementations
7
+ # the engine ships once, addressable from pack data as
8
+ # rules: { slot: rule_name }. Flavors migrate their ELEMENTS maps
9
+ # onto registered rules; nothing references a flavor class.
10
+ module Rules
11
+ REGISTRY = {}
12
+
13
+ class << self
14
+ def register(name, klass)
15
+ REGISTRY[name.to_s] = klass
16
+ end
17
+
18
+ # A pack's rule selections become the renderer's element map;
19
+ # caller-supplied elements win over the pack's selections
20
+ def resolve(rules, elements = {})
21
+ Array(rules).to_h { |slot, name| [slot.to_sym, fetch(name)] }
22
+ .merge(elements || {})
23
+ end
24
+
25
+ private
26
+
27
+ def fetch(name)
28
+ REGISTRY.fetch(name.to_s) do
29
+ raise ArgumentError, "unknown citation style rule #{name}"
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -19,6 +19,21 @@ module Relaton
19
19
  autoload :TypeTemplate, "relaton/render/iso690/style/type_template"
20
20
 
21
21
  attribute :name, :string
22
+ # The citation-style family the pack belongs to (iso690 | lncs |
23
+ # chicago | ieee-sa | apa): selects the presentation-of-models
24
+ # conventions the templates address
25
+ attribute :family, :string, default: "iso690"
26
+ # A named pack this one deltas over; resolved at load with the
27
+ # documented merge semantics (#merge_delta)
28
+ attribute :extends, :string
29
+ # Engine capabilities the pack addresses; a resolver that lacks
30
+ # one fails loudly instead of mis-rendering
31
+ attribute :requires, :string, collection: true, default: []
32
+ # Pack-declared taxonomy: wire type -> kind (aliasing or
33
+ # fallthrough), consulted before the engine's Kinds table
34
+ attribute :types, :hash, default: -> { {} }
35
+ # Presentation-of-models selections: slot -> named engine rule
36
+ attribute :rules, :hash, default: -> { {} }
22
37
  attribute :scheme, Scheme, default: -> { Scheme.new }
23
38
  attribute :templates, TemplateMap, default: -> { TemplateMap.new }
24
39
  attribute :per_type, TypeTemplate, collection: true, default: []
@@ -26,6 +41,11 @@ module Relaton
26
41
 
27
42
  key_value do
28
43
  map "name", to: :name
44
+ map "family", to: :family
45
+ map "extends", to: :extends
46
+ map "requires", to: :requires
47
+ map "types", to: :types
48
+ map "rules", to: :rules
29
49
  map "scheme", to: :scheme
30
50
  map "templates", to: :templates
31
51
  map "perType", to: :per_type
@@ -44,6 +64,12 @@ module Relaton
44
64
  # the style's declared kind for types the vocabulary does not
45
65
  # map (a flavor whose untyped items are not reports)
46
66
  def kind_for(type)
67
+ declared_type = types[type.to_s]
68
+ unless declared_type.to_s.empty?
69
+ return Kinds.mapped?(declared_type) ? Kinds.kind_for(declared_type) :
70
+ declared_type
71
+ end
72
+
47
73
  return Kinds.kind_for(type) if Kinds.mapped?(type)
48
74
 
49
75
  declared = scheme.default_kind.to_s
@@ -97,11 +123,88 @@ module Relaton
97
123
  )
98
124
  end
99
125
 
126
+ # The documented delta merge: perType entries merge per type
127
+ # key (a delta re-declaring `article` never drops the base's
128
+ # `monograph`); hash sections merge per key; scalars, templates
129
+ # and rule selections replace; sortKey and requires union.
130
+ # Deterministic and engine-portable.
131
+ def merge_delta(base)
132
+ merged_per_type = base.per_type.dup
133
+ per_type.each do |delta|
134
+ index = merged_per_type.find_index do |b|
135
+ b.type == delta.type && (b.home || false) == (delta.home || false)
136
+ end
137
+ index ? merged_per_type[index] = delta : merged_per_type << delta
138
+ end
139
+ self.per_type = merged_per_type
140
+ self.types = base.types.merge(types)
141
+ self.rules = base.rules.merge(rules)
142
+ merge_scheme(base)
143
+ merge_templates(base)
144
+ self.sort_key = (base.sort_key + sort_key).uniq
145
+ self.requires = (base.requires + requires).uniq
146
+ self
147
+ end
148
+
149
+ private
150
+
151
+ def merge_scheme(base)
152
+ fresh = NameForm.new
153
+ NameForm.attributes.each_key do |attr|
154
+ val = scheme.name_form.send(attr)
155
+ next unless val == fresh.send(attr)
156
+
157
+ base_val = base.scheme.name_form.send(attr)
158
+ scheme.name_form.send("#{attr}=", base_val) if
159
+ base_val != fresh.send(attr)
160
+ end
161
+
162
+ scheme.system = base.scheme.system if scheme.system.to_s.empty?
163
+ scheme.short_from_reference = base.scheme.short_from_reference unless
164
+ scheme.short_from_reference
165
+ scheme.home_docid_type = base.scheme.home_docid_type if
166
+ Array(scheme.home_docid_type).empty?
167
+ scheme.default_kind = base.scheme.default_kind if
168
+ scheme.default_kind.to_s.empty?
169
+
170
+ locale = scheme.locale
171
+ base_locale = base.scheme.locale
172
+ locale.conj ||= base_locale.conj
173
+ locale.others ||= base_locale.others
174
+ locale.no_date ||= base_locale.no_date
175
+ locale.no_author ||= base_locale.no_author
176
+ locale.in_str ||= base_locale.in_str
177
+ locale.at ||= base_locale.at
178
+ locale.available_at ||= base_locale.available_at
179
+ locale.labels.merge!(base_locale.label_map) { |_k, _b, d| d }
180
+ locale.punct = (base_locale.punct || {}).merge(locale.punct || {})
181
+ end
182
+
183
+ def merge_templates(base)
184
+ fresh = TemplateMap.new
185
+ TemplateMap.attributes.each_key do |attr|
186
+ val = templates.send(attr)
187
+ base_val = base.templates.send(attr)
188
+ next unless val == fresh.send(attr) && base_val != fresh.send(attr)
189
+
190
+ templates.send("#{attr}=", base_val)
191
+ end
192
+ end
193
+
100
194
  class << self
101
- def load(name_or_path)
195
+ def load(name_or_path, seen = [])
102
196
  path = style_path(name_or_path) or
103
197
  raise ArgumentError, "unknown style #{name_or_path}"
104
- from_yaml(File.read(path))
198
+ style = from_yaml(File.read(path))
199
+ return style if style.extends.to_s.empty?
200
+
201
+ style.extends.split(/\s+/).each do |base_name|
202
+ raise ArgumentError,
203
+ "circular extends #{base_name}" if seen.include?(base_name)
204
+
205
+ style.merge_delta(load(base_name, seen + [base_name]))
206
+ end
207
+ style
105
208
  end
106
209
 
107
210
  private
@@ -0,0 +1,45 @@
1
+ # American Psychological Association (7th ed.) reference forms: all
2
+ # author names invert with initials ("Author, A. B."), the date
3
+ # follows the authors in parentheses, article titles take no marks
4
+ # (sentence case is the author's), and only book titles and journal
5
+ # names carry italics. The reference list joins with a comma and ampersand.
6
+ name: "APA (7th edition) references"
7
+ family: apa
8
+ scheme:
9
+ system: name-date
10
+ nameForm:
11
+ initials: true
12
+ initialsSeparator: " "
13
+ initialsPeriod: true
14
+ invertedAll: true
15
+ givenNameFirst: false
16
+ editorsMarked: false
17
+ surnameUpcase: false
18
+ subsequentSurnameUpcase: false
19
+ locale:
20
+ "in": "In"
21
+ labels:
22
+ "and": "&"
23
+ oxford_comma: ","
24
+ oxford_comma: ","
25
+ templates:
26
+ titleOpen: ""
27
+ titleClose: ""
28
+ citation: "{{surname}}, {{date}}"
29
+ reference: "{{creator}} ({{date}}). {{title}}. {{series}}. {{production}}. {{extent}}"
30
+ name: "{{surname}}, {{givenNames}}"
31
+ identifierMode: all
32
+ perType:
33
+ - type: report
34
+ home: true
35
+ template: "{{title}}"
36
+ - type: report
37
+ template: "{{identifier}}. {{title}}. {{production}}."
38
+ - type: monograph
39
+ title: "<em>{{title}}</em>"
40
+ template: "{{creator}} ({{date}}). {{title}}. {{production}}."
41
+ - type: component_part
42
+ template: "{{creator}} ({{date}}). {{title}}. {{componentpart}} ({{extent}}). {{production}}."
43
+ - type: continuing
44
+ series: "<em>{{seriestitle}}, {{serienumber}}</em>"
45
+ template: "{{creator}} ({{date}}). {{title}}. {{series}} {{extent}}. {{location}}"
@@ -0,0 +1,48 @@
1
+ # Chicago Manual of Style (17th ed.), bibliography forms: the notes
2
+ # system's reference list. Only the first author name inverts ("Peck,
3
+ # R. B., W. E. Hanson, and T. H. Thornburn"), article titles carry
4
+ # quotation marks, book titles are set in italics, and production runs
5
+ # "Place: Publisher".
6
+ name: "Chicago Manual of Style (bibliography)"
7
+ family: chicago
8
+ requires:
9
+ - extent_units
10
+ scheme:
11
+ system: name-date
12
+ nameForm:
13
+ initials: false
14
+ initialsSeparator: " "
15
+ initialsPeriod: true
16
+ invertedAll: false
17
+ givenNameFirst: false
18
+ editorsMarked: true
19
+ loneEditorMarked: true
20
+ surnameUpcase: false
21
+ subsequentSurnameUpcase: false
22
+ locale:
23
+ "in": "in"
24
+ labels:
25
+ "and": "and"
26
+ oxford_comma: ","
27
+ series_no: "no."
28
+ templates:
29
+ titleOpen: "\""
30
+ titleClose: "\""
31
+ citation: "{{surname}}, {{date}}"
32
+ reference: "{{creator}}. {{title}}. {{edition}}. {{series}}. {{production}}, {{date}}. {{extent}}."
33
+ name: "{{surname}}, {{givenNames}}"
34
+ identifierMode: all
35
+ perType:
36
+ - type: report
37
+ home: true
38
+ template: "{{title}}"
39
+ - type: report
40
+ template: "{{creator}}. {{title}}. {{edition}}. {{production}}, {{date}}."
41
+ - type: monograph
42
+ title: "<em>{{title}}</em>"
43
+ template: "{{creator}}. {{title}}. {{edition}}. {{production}}, {{date}}. {{extent}}."
44
+ - type: component_part
45
+ template: "{{creator}}. \"{{title}}.\" {{componentpart}}. {{production}}, {{date}}. {{extent}}."
46
+ - type: continuing
47
+ series: "<em>{{seriestitle}}</em>"
48
+ template: "{{creator}}. \"{{title}}.\" {{series}} {{extent}} ({{date}}). {{location}}"
@@ -0,0 +1,45 @@
1
+ # IEEE-SA Standards Style Manual bibliography forms (clause 17): a
2
+ # standard's entry is its designation and title, nothing else - no
3
+ # authors, no publisher, no place; articles and books follow the
4
+ # Chicago-derived forms, with only the first author name inverting and
5
+ # the in-text citation carrying the designation and the [B#] number.
6
+ name: "IEEE-SA standards bibliography"
7
+ family: ieee-sa
8
+ scheme:
9
+ system: designation
10
+ nameForm:
11
+ initials: true
12
+ initialsSeparator: " "
13
+ initialsPeriod: true
14
+ invertedAll: false
15
+ givenNameFirst: false
16
+ editorsMarked: false
17
+ surnameUpcase: false
18
+ subsequentSurnameUpcase: false
19
+ locale:
20
+ labels:
21
+ "and": "and"
22
+ oxford_comma: ","
23
+ templates:
24
+ titleOpen: ""
25
+ titleClose: ""
26
+ citation: "{{identifier}}"
27
+ reference: "{{creator}}, {{title}}. {{series}}. {{extent}}. {{date}}."
28
+ name: "{{surname}}, {{givenNames}}"
29
+ identifierMode: first
30
+ perType:
31
+ - type: report
32
+ home: true
33
+ template: "{{title}}"
34
+ - type: report
35
+ template: "{{identifier}}, {{title}}"
36
+ - type: monograph
37
+ title: "<em>{{title}}</em>"
38
+ template: "{{creator}}, {{title}}, {{edition}}. {{production}}, {{date}}, {{extent}}."
39
+ - type: component_part
40
+ title: "\"{{title}},\""
41
+ template: "{{creator}}, {{title}} {{componentpart}}, {{extent}}, {{date}}."
42
+ - type: continuing
43
+ title: "\"{{title}},\""
44
+ series: "<em>{{seriestitle}}</em>"
45
+ template: "{{creator}}, {{title}} {{series}}, {{extent}}, {{date}}."
@@ -0,0 +1,54 @@
1
+ # Springer LNCS citation style, an instance of the relaton-models
2
+ # CitationStyle model. The LNCS shape: "Author, A.B.: Title. In:
3
+ # Editor, E. (ed.), Proceedings. LNCS 1234, pp. 10-20. Springer,
4
+ # Heidelberg (2010)" - the creator list closes on a colon, the year
5
+ # closes the entry in parentheses, publishers precede places, and a
6
+ # standard with no personal authors leads with the publisher's
7
+ # abbreviation.
8
+ name: "Springer LNCS"
9
+ family: lncs
10
+ requires:
11
+ - production_order
12
+ - extent_units
13
+ scheme:
14
+ system: name-date
15
+ nameForm:
16
+ initials: true
17
+ initialsSeparator: ""
18
+ initialsPeriod: true
19
+ invertedAll: true
20
+ givenNameFirst: false
21
+ editorsMarked: true
22
+ loneEditorMarked: true
23
+ creatorFallback: publisher_abbrev
24
+ surnameUpcase: false
25
+ subsequentSurnameUpcase: false
26
+ locale:
27
+ "in": "In"
28
+ availableAt: ""
29
+ labels:
30
+ "and": ""
31
+ oxford_comma: ""
32
+ series_no: ""
33
+ punct:
34
+ production_order: publisher_first
35
+ production_sep: ", "
36
+ templates:
37
+ titleOpen: ""
38
+ titleClose: ""
39
+ citation: "{{surname}}, {{date}}"
40
+ reference: "{{creator}}: {{title}}. {{series}}. {{production}} {{dategroup}}. {{location}}"
41
+ name: "{{surname}}, {{givenNames}}"
42
+ identifierMode: first
43
+ perType:
44
+ - type: report
45
+ home: true
46
+ template: "{{title}}"
47
+ - type: report
48
+ template: "{{creator}}: {{identifier}}, {{title}}. {{production}} {{dategroup}}."
49
+ - type: monograph
50
+ template: "{{creator}}: {{title}}. {{series}} {{production}} {{dategroup}}"
51
+ - type: component_part
52
+ template: "{{creator}}: {{title}}. {{componentpart}} {{extent}} {{production}} {{dategroup}}"
53
+ - type: continuing
54
+ template: "{{creator}}: {{title}}. {{series}} {{extent}} {{dategroup}}"
@@ -19,6 +19,7 @@ module Relaton
19
19
  autoload :IdentifierKinds, "relaton/render/iso690/identifier_kinds"
20
20
  autoload :Kinds, "relaton/render/iso690/kinds"
21
21
  autoload :Renderer, "relaton/render/iso690/renderer"
22
+ autoload :Rules, "relaton/render/iso690/rules"
22
23
  autoload :Style, "relaton/render/iso690/style"
23
24
  autoload :Template, "relaton/render/iso690/template"
24
25
  end
@@ -1,5 +1,5 @@
1
1
  module Relaton
2
2
  module Render
3
- VERSION = "3.0.0.pre.alpha.25".freeze
3
+ VERSION = "3.0.0.pre.alpha.26".freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
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.25
4
+ version: 3.0.0.pre.alpha.26
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
@@ -147,6 +147,7 @@ files:
147
147
  - lib/relaton/render/iso690/index_renderer.rb
148
148
  - lib/relaton/render/iso690/kinds.rb
149
149
  - lib/relaton/render/iso690/renderer.rb
150
+ - lib/relaton/render/iso690/rules.rb
150
151
  - lib/relaton/render/iso690/style.rb
151
152
  - lib/relaton/render/iso690/style/locale.rb
152
153
  - lib/relaton/render/iso690/style/name_form.rb
@@ -154,7 +155,11 @@ files:
154
155
  - lib/relaton/render/iso690/style/sort_rule.rb
155
156
  - lib/relaton/render/iso690/style/template_map.rb
156
157
  - lib/relaton/render/iso690/style/type_template.rb
158
+ - lib/relaton/render/iso690/styles/apa.yml
157
159
  - lib/relaton/render/iso690/styles/author-date.yml
160
+ - lib/relaton/render/iso690/styles/chicago.yml
161
+ - lib/relaton/render/iso690/styles/ieee-sa.yml
162
+ - lib/relaton/render/iso690/styles/lncs.yml
158
163
  - lib/relaton/render/iso690/template.rb
159
164
  - lib/relaton/render/version.rb
160
165
  - relaton-render.gemspec