relaton-render 3.0.0.pre.alpha.11 → 3.0.0.pre.alpha.13
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 +4 -4
- data/lib/relaton/render/general.rb +4 -2
- data/lib/relaton/render/iso690/element.rb +1 -1
- data/lib/relaton/render/iso690/elements/authorizer.rb +30 -0
- data/lib/relaton/render/iso690/elements/pub_date.rb +0 -2
- data/lib/relaton/render/iso690/elements.rb +2 -0
- data/lib/relaton/render/iso690/fields.rb +2 -2
- data/lib/relaton/render/iso690/kinds.rb +6 -0
- data/lib/relaton/render/iso690/renderer.rb +2 -2
- data/lib/relaton/render/iso690/style/scheme.rb +2 -0
- data/lib/relaton/render/iso690/style/template_map.rb +0 -2
- data/lib/relaton/render/iso690/style.rb +10 -0
- data/lib/relaton/render/iso690/template.rb +103 -51
- data/lib/relaton/render/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3e80ae8de229852d85ba4eabcd093152e140c9252f07c301fb6091c03694eac8
|
|
4
|
+
data.tar.gz: c378a86333710cabdcd00fd085a43e74a924c47e0b5df3d37eb830b56697ecf8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 51b3ee0d7f8486e221ad0ea3fc0a69b8ae43a8f18056aa7357e77a362ea9c414c71ae724f241c8c12cc76ee29d34a906788a0b1abf82e1bf5a740d1c8dd5cada
|
|
7
|
+
data.tar.gz: 5d99388b322ae77613713554f9d6a0a7effb284a31267dda00427fbedf122a1c8d3abc990eceef6de27350b3394b6c710d433311bb025614c7c9db11adfb7e5d
|
|
@@ -63,7 +63,7 @@ module Relaton
|
|
|
63
63
|
end
|
|
64
64
|
m[item.id] = {
|
|
65
65
|
id: item.id, ord: i,
|
|
66
|
-
formattedref: terminate_reference(ref),
|
|
66
|
+
formattedref: terminate_reference(ref, item),
|
|
67
67
|
citation: citation_renderings(item, ref),
|
|
68
68
|
}
|
|
69
69
|
end
|
|
@@ -82,7 +82,9 @@ module Relaton
|
|
|
82
82
|
# render_all feeds the bibliography list: a reference not ending
|
|
83
83
|
# in the biblio terminator takes one (the 1.x render1 behaviour;
|
|
84
84
|
# single-item render stays verbatim)
|
|
85
|
-
|
|
85
|
+
# The bibliography terminator; flavors override to suppress it
|
|
86
|
+
# (1.x use_terminator?), receiving the item it terminates
|
|
87
|
+
def terminate_reference(ref, _item = nil)
|
|
86
88
|
return ref if ref.empty? || ref.rstrip.end_with?(".")
|
|
87
89
|
|
|
88
90
|
"#{ref}."
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Relaton
|
|
4
|
+
module Render
|
|
5
|
+
module Iso690
|
|
6
|
+
module Elements
|
|
7
|
+
# The authorizing body of a standard (the IETF RFC Series, the
|
|
8
|
+
# W3C Recommendation process): the organization carrying the
|
|
9
|
+
# authorizer role, cited after the status
|
|
10
|
+
class Authorizer < Element
|
|
11
|
+
def present?
|
|
12
|
+
!authorizer_name.empty?
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def render
|
|
16
|
+
authorizer_name
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def authorizer_name
|
|
22
|
+
contributors("authorizer").map do |c|
|
|
23
|
+
Array(c.organization&.name).map { |n| localized(n) }.join(", ")
|
|
24
|
+
end.reject(&:empty?).first.to_s
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -21,6 +21,7 @@ module Relaton
|
|
|
21
21
|
autoload :Access, "relaton/render/iso690/elements/access"
|
|
22
22
|
autoload :Stddoc, "relaton/render/iso690/elements/stddoc"
|
|
23
23
|
autoload :Status, "relaton/render/iso690/elements/status"
|
|
24
|
+
autoload :Authorizer, "relaton/render/iso690/elements/authorizer"
|
|
24
25
|
autoload :Citeid, "relaton/render/iso690/elements/citeid"
|
|
25
26
|
autoload :Updated, "relaton/render/iso690/elements/updated"
|
|
26
27
|
|
|
@@ -41,6 +42,7 @@ module Relaton
|
|
|
41
42
|
access: Access,
|
|
42
43
|
stddoc: Stddoc,
|
|
43
44
|
status: Status,
|
|
45
|
+
authorizer: Authorizer,
|
|
44
46
|
citeid: Citeid,
|
|
45
47
|
updated: Updated,
|
|
46
48
|
}.freeze
|
|
@@ -11,7 +11,7 @@ module Relaton
|
|
|
11
11
|
ELEMENT_SLOTS = %i[
|
|
12
12
|
creator title edition medium series production
|
|
13
13
|
date numeration component_part identifier location size
|
|
14
|
-
extent access stddoc status citeid updated
|
|
14
|
+
extent access stddoc status citeid authorizer updated
|
|
15
15
|
].freeze
|
|
16
16
|
|
|
17
17
|
def initialize(model, style:, i18n:, disambiguator: nil,
|
|
@@ -98,7 +98,7 @@ module Relaton
|
|
|
98
98
|
end
|
|
99
99
|
|
|
100
100
|
def item_kind
|
|
101
|
-
|
|
101
|
+
@style.kind_for(@model.type)
|
|
102
102
|
end
|
|
103
103
|
|
|
104
104
|
def name_fields
|
|
@@ -35,7 +35,7 @@ module Relaton
|
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
def render(model)
|
|
38
|
-
kind =
|
|
38
|
+
kind = @style.kind_for(model.type)
|
|
39
39
|
template = @style.template_for(kind, home: home_docid?(model))
|
|
40
40
|
out = Template.new(template).evaluate(
|
|
41
41
|
Fields.new(model, style: @style, i18n: @i18n,
|
|
@@ -62,7 +62,7 @@ module Relaton
|
|
|
62
62
|
|
|
63
63
|
# The short cite: the reference with the first-biblio marker
|
|
64
64
|
def render_short(model, delim)
|
|
65
|
-
kind =
|
|
65
|
+
kind = @style.kind_for(model.type)
|
|
66
66
|
template = @style.type_template_for(kind)&.short ||
|
|
67
67
|
@style.template_for(kind, home: home_docid?(model))
|
|
68
68
|
Template.new(template).evaluate_short(
|
|
@@ -11,12 +11,14 @@ module Relaton
|
|
|
11
11
|
attribute :name_form, NameForm, default: -> { NameForm.new }
|
|
12
12
|
attribute :locale, Locale, default: -> { Locale.new }
|
|
13
13
|
attribute :home_docid_type, :string, collection: true
|
|
14
|
+
attribute :default_kind, :string, default: ""
|
|
14
15
|
|
|
15
16
|
key_value do
|
|
16
17
|
map "system", to: :system
|
|
17
18
|
map "nameForm", to: :name_form
|
|
18
19
|
map "locale", to: :locale
|
|
19
20
|
map "homeDocidType", to: :home_docid_type
|
|
21
|
+
map "defaultKind", to: :default_kind
|
|
20
22
|
end
|
|
21
23
|
end
|
|
22
24
|
end
|
|
@@ -17,7 +17,6 @@ module Relaton
|
|
|
17
17
|
attribute :uri, :string, default: ""
|
|
18
18
|
attribute :creators, :string, default: ""
|
|
19
19
|
attribute :uri_short, :string, default: ""
|
|
20
|
-
attribute :date_form, :string, default: ""
|
|
21
20
|
# "first": cite only the first identifier (1.x
|
|
22
21
|
# authoritative_identifier|first styles)
|
|
23
22
|
attribute :identifier_mode, :string, default: "all"
|
|
@@ -32,7 +31,6 @@ module Relaton
|
|
|
32
31
|
map "uri", to: :uri
|
|
33
32
|
map "creators", to: :creators
|
|
34
33
|
map "uriShort", to: :uri_short
|
|
35
|
-
map "dateForm", to: :date_form
|
|
36
34
|
map "identifierMode", to: :identifier_mode
|
|
37
35
|
end
|
|
38
36
|
end
|
|
@@ -40,6 +40,16 @@ module Relaton
|
|
|
40
40
|
[SortRule.new(attribute: "creator"), SortRule.new(attribute: "date")]
|
|
41
41
|
end
|
|
42
42
|
|
|
43
|
+
# The ISO 690 kind of an item: the vocabulary's mapping, or
|
|
44
|
+
# the style's declared kind for types the vocabulary does not
|
|
45
|
+
# map (a flavor whose untyped items are not reports)
|
|
46
|
+
def kind_for(type)
|
|
47
|
+
return Kinds.kind_for(type) if Kinds.mapped?(type)
|
|
48
|
+
|
|
49
|
+
declared = scheme.default_kind.to_s
|
|
50
|
+
declared.empty? ? Kinds.kind_for(type) : declared
|
|
51
|
+
end
|
|
52
|
+
|
|
43
53
|
# Per-type template selection is a data lookup; unmatched types
|
|
44
54
|
# fall back to the general reference template. When a kind has
|
|
45
55
|
# home-flagged variants, the split is resolved by whether the item
|
|
@@ -17,7 +17,7 @@ module Relaton
|
|
|
17
17
|
Field = Struct.new(:present?, :text)
|
|
18
18
|
|
|
19
19
|
def initialize(source)
|
|
20
|
-
@
|
|
20
|
+
@chunks = []
|
|
21
21
|
@terminator = ""
|
|
22
22
|
scan(source.to_s)
|
|
23
23
|
end
|
|
@@ -27,41 +27,56 @@ module Relaton
|
|
|
27
27
|
# references (eref2linkshort) split there (the 1.x
|
|
28
28
|
# fmt-first-biblio-delim)
|
|
29
29
|
def evaluate_short(fields, delim)
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
next unless field.present?
|
|
30
|
+
present = present_indices(fields)
|
|
31
|
+
return "" if present.empty?
|
|
33
32
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
33
|
+
out = +""
|
|
34
|
+
first_seen = false
|
|
35
|
+
@chunks.each_with_index do |(kind, value), i|
|
|
36
|
+
text =
|
|
37
|
+
case kind
|
|
38
|
+
when :slot
|
|
39
|
+
field = fields[normalise(value)]
|
|
40
|
+
next unless field&.present?
|
|
41
|
+
|
|
42
|
+
first_seen ? field.text : "#{field.text}#{delim} "
|
|
43
|
+
else
|
|
44
|
+
# the split marker precedes the component's trailing
|
|
45
|
+
# punctuation (1.x ret[0] += delim, then join), with
|
|
46
|
+
# the join's separating space
|
|
47
|
+
next unless bridged?(i, present)
|
|
48
|
+
|
|
49
|
+
value
|
|
50
|
+
end
|
|
51
|
+
first_seen = true if @chunks[i].first == :slot
|
|
52
|
+
out << text unless text.nil?
|
|
49
53
|
end
|
|
50
|
-
terminate(
|
|
54
|
+
terminate(out).rstrip
|
|
51
55
|
end
|
|
52
56
|
|
|
57
|
+
# 1.x segment-join semantics: present elements joined with the
|
|
58
|
+
# template's separators — a literal renders only when it
|
|
59
|
+
# separates (a run of absent elements between) two present
|
|
60
|
+
# elements; leading and trailing literals drop with the
|
|
61
|
+
# elements they would have attached to
|
|
53
62
|
def evaluate(fields)
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
next unless field.present?
|
|
63
|
+
present = present_indices(fields)
|
|
64
|
+
return "" if present.empty?
|
|
57
65
|
|
|
58
|
-
|
|
66
|
+
out = +"".dup
|
|
67
|
+
@chunks.each_with_index do |(kind, value), i|
|
|
68
|
+
if kind == :slot
|
|
69
|
+
field = fields[normalise(value)]
|
|
70
|
+
out << field.text if field&.present?
|
|
71
|
+
elsif bridged?(i, present) ||
|
|
72
|
+
(value.include?("<") && present.any? { |j| j < i })
|
|
73
|
+
# markup attaches to the element it closes
|
|
74
|
+
out << value
|
|
75
|
+
elsif close_pending_paren?(out, value)
|
|
76
|
+
out << value
|
|
77
|
+
end
|
|
59
78
|
end
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
terminate(rendered.each_with_index.map do |(head, text, tail), i|
|
|
63
|
-
i == rendered.size - 1 ? "#{head}#{text}" : "#{head}#{text}#{tail}"
|
|
64
|
-
end.join).rstrip
|
|
79
|
+
terminate(out).rstrip
|
|
65
80
|
end
|
|
66
81
|
|
|
67
82
|
private
|
|
@@ -69,37 +84,74 @@ module Relaton
|
|
|
69
84
|
def scan(source)
|
|
70
85
|
rest = source
|
|
71
86
|
while (slot = SLOT.match(rest))
|
|
72
|
-
|
|
73
|
-
|
|
87
|
+
@chunks << [:text, rest[0...slot.begin(0)]] if
|
|
88
|
+
slot.begin(0).positive?
|
|
89
|
+
@chunks << [:slot, slot[1]]
|
|
74
90
|
rest = rest[slot.end(0)..]
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
91
|
+
end
|
|
92
|
+
@terminator = rest
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def present_indices(fields)
|
|
96
|
+
@chunks.each_index.select do |i|
|
|
97
|
+
kind, value = @chunks[i]
|
|
98
|
+
next false unless kind == :slot
|
|
99
|
+
|
|
100
|
+
field = fields[normalise(value)]
|
|
101
|
+
!field.nil? && field.present?
|
|
84
102
|
end
|
|
85
103
|
end
|
|
86
104
|
|
|
105
|
+
# A literal bridges two present elements when at least one
|
|
106
|
+
# present element stands on each side of it; a leading literal
|
|
107
|
+
# (no slot precedes it) attaches to the first slot, emitting
|
|
108
|
+
# only when that slot is present
|
|
109
|
+
def bridged?(index, present)
|
|
110
|
+
first_slot = @chunks.index { |(kind, _)| kind == :slot }
|
|
111
|
+
return present.include?(first_slot) if index < first_slot
|
|
112
|
+
|
|
113
|
+
present.any? { |i| i < index } && present.any? { |i| i > index }
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# A template's paired literal ("({{production}})") closes even
|
|
117
|
+
# when nothing follows the present element it wraps
|
|
118
|
+
def close_pending_paren?(out, value)
|
|
119
|
+
value.start_with?(")") && out.count("(") > out.count(")")
|
|
120
|
+
end
|
|
121
|
+
|
|
87
122
|
def terminate(body)
|
|
88
|
-
# 1.x punctuation cleanup:
|
|
89
|
-
#
|
|
90
|
-
#
|
|
91
|
-
#
|
|
92
|
-
#
|
|
93
|
-
#
|
|
94
|
-
# comma
|
|
123
|
+
# 1.x punctuation cleanup: a sentence period before a spaced
|
|
124
|
+
# comma yields to the comma (", 2013" over ". , 2013"; an
|
|
125
|
+
# initials period before a comma ("P.,") stands, being
|
|
126
|
+
# unspaced), and stacked separators around absent elements
|
|
127
|
+
# collapse into one (". : ." into ". "); an empty pair left
|
|
128
|
+
# by an absent element drops
|
|
95
129
|
body = body.gsub(/:\s*\.\s*/, ": ")
|
|
96
130
|
body = body.gsub(/\.\s+,/, ",")
|
|
97
|
-
body = body.gsub(
|
|
131
|
+
body = body.gsub(/(?:[.,:;]\s+)+[.,:;]/, ". ")
|
|
132
|
+
body = body.gsub(/\.\s*\./, ". ")
|
|
133
|
+
body = body.gsub(/:\s*\.\s*/, ": ")
|
|
134
|
+
body = body.gsub(/\(\s*\)/, "")
|
|
98
135
|
body = body.gsub(/ +/, " ").gsub(" ,", ",")
|
|
99
|
-
|
|
100
|
-
return body if
|
|
136
|
+
terminator = unbalanced_close(body, @terminator)
|
|
137
|
+
return body if terminator.strip.empty?
|
|
138
|
+
if terminator !~ /[<\w]/ && body.rstrip.end_with?(terminator.strip)
|
|
139
|
+
return body
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
"#{body}#{terminator}"
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# The terminator's closing parens stand only when the body
|
|
146
|
+
# opened them (their "(" died with an absent element)
|
|
147
|
+
def unbalanced_close(body, terminator)
|
|
148
|
+
return terminator unless terminator.start_with?(")")
|
|
149
|
+
|
|
150
|
+
open = body.count("(") - body.count(")")
|
|
151
|
+
return terminator.sub(/\A\)+/) { |closes| closes[0, open] } if
|
|
152
|
+
open.positive?
|
|
101
153
|
|
|
102
|
-
|
|
154
|
+
terminator.sub(/\A\)+/, "")
|
|
103
155
|
end
|
|
104
156
|
|
|
105
157
|
def normalise(slot)
|
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.
|
|
4
|
+
version: 3.0.0.pre.alpha.13
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
@@ -121,6 +121,7 @@ files:
|
|
|
121
121
|
- lib/relaton/render/iso690/element.rb
|
|
122
122
|
- lib/relaton/render/iso690/elements.rb
|
|
123
123
|
- lib/relaton/render/iso690/elements/access.rb
|
|
124
|
+
- lib/relaton/render/iso690/elements/authorizer.rb
|
|
124
125
|
- lib/relaton/render/iso690/elements/citeid.rb
|
|
125
126
|
- lib/relaton/render/iso690/elements/component_part.rb
|
|
126
127
|
- lib/relaton/render/iso690/elements/creator.rb
|