relaton-render 3.0.0.pre.alpha.34 → 3.0.0.pre.alpha.36
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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8cc3d3010efcd83bdec9412ff02d171123404ca088993b6eed94b7480fe5e7a9
|
|
4
|
+
data.tar.gz: 4b88cbd036bdb0a4b4f35d3b5c290656225bb9360236219b0842269ad64cc327
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5c397f214df631e40b4352209c4a45deabe77363eb7d1f8ede9f88e4e4245da3a21ae179f139b21a897fab353a5df369b91075314ba0a78955478467e573435e
|
|
7
|
+
data.tar.gz: 57d5c764a1307b5e620aa28ec875723d88d38b4f1d8e7acb01b9da7e2e4f6463f843ebcba4a30858f9f7bf68f291d02e9cba711eb664283d5ea61c0102a49bdc
|
|
@@ -290,10 +290,10 @@ is a rule to promote:
|
|
|
290
290
|
|Flavor override |Becomes rule
|
|
291
291
|
|
|
292
292
|
|`ItuIdentifier` |**[impl]** promoted: `identifier: itu_identifier`
|
|
293
|
-
|`NistIdentifier`, `NistCreator`, `NistDate`, `SerialDate`, `NistSeries`, `NistComponentPart`, `NistPublisher`, `Draft`
|
|
293
|
+
|`NistIdentifier`, `NistCreator`, `NistDate`, `SerialDate`, `NistSeries`, `NistComponentPart`, `NistPublisher`, `Draft` |**[impl]** promoted: `nist_identifier`, `nist_creator`, `nist_date`, `nist_serial_date`, `nist_series`, `nist_component_part`, `nist_publisher`, `nist_draft`
|
|
294
294
|
|`IeeeIdentifier`, `IeeeComponentPart`, `IeeeAccess`, `IeeeMedium` |**[impl]** promoted: `ieee_identifier`, `ieee_component_part`, `ieee_access`, `ieee_medium`
|
|
295
|
-
|`BipmCreator`, `BipmComponentPart`, `BipmProduction`, `BipmExtent`, `BipmMedium`, `BipmEdition`, `BipmVolume`
|
|
296
|
-
|`IhoEdition`, `IhoCreator`
|
|
295
|
+
|`BipmCreator`, `BipmComponentPart`, `BipmProduction`, `BipmExtent`, `BipmMedium`, `BipmEdition`, `BipmVolume` |**[impl]** promoted: `bipm_creator`, `bipm_component_part`, `bipm_production`, `bipm_extent`, `bipm_medium`, `bipm_edition`, `bipm_volume` (slot `volsize`)
|
|
296
|
+
|`IhoEdition`, `IhoCreator` |**[impl]** promoted: `iho_edition`, `iho_creator` (the %w publisher list could never match the multiword organization name — now a string array)
|
|
297
297
|
|`JisComponentPart`, `JisSeries`, `JisExtent` |the JIS host-citation rules
|
|
298
298
|
|`BsiStatus` |status presentation
|
|
299
299
|
|===
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Relaton
|
|
4
|
+
module Render
|
|
5
|
+
module Iso690
|
|
6
|
+
module Rules
|
|
7
|
+
# The BIPM rule set, moved verbatim from the metanorma-bipm
|
|
8
|
+
# flavor's BipmElements: the affiliation-free organization
|
|
9
|
+
# creator, the bold-volume journal numeration, the
|
|
10
|
+
# no-place-with-publisher production, the separator-carrying
|
|
11
|
+
# edition and medium, and the component-part host order.
|
|
12
|
+
# Select from pack data:
|
|
13
|
+
# rules: { creator: bipm_creator, ... }
|
|
14
|
+
module Bipm
|
|
15
|
+
# The BIPM component-part order: the host editors before the
|
|
16
|
+
# host title, the host medium after it, and the production
|
|
17
|
+
# parenthesized with its own trailing period
|
|
18
|
+
class BipmComponentPart < Elements::ComponentPart
|
|
19
|
+
def render
|
|
20
|
+
h = host or return ""
|
|
21
|
+
out = +"#{lead}#{host_names(h)} (#{eds_label(h)})"
|
|
22
|
+
out += " #{host_title}" unless host_title_text.empty?
|
|
23
|
+
out += medium_text(h)
|
|
24
|
+
out += production_text(h)
|
|
25
|
+
out
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def host_editors(h)
|
|
31
|
+
Array(h.contributor).select { |c| has_role?(c, "editor") }
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def eds_label(h)
|
|
35
|
+
@i18n.label(host_editors(h).one? ? "ed" : "eds")
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def host_names(h)
|
|
39
|
+
names = host_editors(h).map { |c|
|
|
40
|
+
person = c.person or next ""
|
|
41
|
+
|
|
42
|
+
[person_surname(person), person_given(person)].reject(&:empty?)
|
|
43
|
+
.join(" ")
|
|
44
|
+
}.reject(&:empty?)
|
|
45
|
+
join_names(names)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def medium_text(h)
|
|
49
|
+
BipmMedium.new(h, style: @style, i18n: @i18n).render.to_s
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def production_text(h)
|
|
53
|
+
production = Elements::Production
|
|
54
|
+
.new(h, style: @style, i18n: @i18n).render.to_s
|
|
55
|
+
production.empty? ? "" : " (#{production})."
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# The BIPM journal numeration: the volume bold and the issue
|
|
60
|
+
# in parens, pages unlabelled. Separate extent elements join
|
|
61
|
+
# with semicolons, localities within one element with spaces
|
|
62
|
+
class BipmExtent < Elements::Extent
|
|
63
|
+
def render
|
|
64
|
+
groups = extent_locality_groups.map { |g| group_text(g) }
|
|
65
|
+
.reject(&:empty?)
|
|
66
|
+
groups.join("; ")
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
private
|
|
70
|
+
|
|
71
|
+
def extent_locality_groups
|
|
72
|
+
Array(@model.extent).map do |e|
|
|
73
|
+
Array(e.locality) +
|
|
74
|
+
Array(e.locality_stack).flat_map { |s| Array(s.locality) }
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def group_text(localities)
|
|
79
|
+
volume = plain_locality(localities, "volume")
|
|
80
|
+
volume = volume.empty? ? "" : "<strong>#{volume}</strong>"
|
|
81
|
+
issue = plain_locality(localities, "issue")
|
|
82
|
+
issue = issue.empty? ? "" : "(#{issue})"
|
|
83
|
+
[volume, issue, page_text(localities)].reject(&:empty?).join(" ")
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def plain_locality(localities, type)
|
|
87
|
+
loc = localities.find { |l| l.type == type } or return ""
|
|
88
|
+
loc.reference_from.to_s
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def page_text(localities)
|
|
92
|
+
loc = localities.find { |l| l.type == "page" } or return ""
|
|
93
|
+
from = loc.reference_from.to_s
|
|
94
|
+
to = loc.reference_to.to_s
|
|
95
|
+
text = to.empty? || to == from ? from :
|
|
96
|
+
"#{from}#{@i18n.label('date_range')}#{to}"
|
|
97
|
+
return text if item_kind == "serial_part"
|
|
98
|
+
|
|
99
|
+
"#{@i18n.label(to.empty? || to == from ? 'page' : 'pages')} #{text}"
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# The BIPM production: the no-place placeholder stands only
|
|
104
|
+
# with a publisher ("(n.p.: Publisher)"); a nameless
|
|
105
|
+
# publisher drops the production entirely
|
|
106
|
+
class BipmProduction < Elements::Production
|
|
107
|
+
private
|
|
108
|
+
|
|
109
|
+
def no_place_production
|
|
110
|
+
return "" if publishers.empty?
|
|
111
|
+
|
|
112
|
+
super
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# The serial volume, bold, from the size's volume value
|
|
117
|
+
class BipmVolume < Element
|
|
118
|
+
def present?
|
|
119
|
+
!render.empty?
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def render
|
|
123
|
+
volume = Array(@model.size&.value).find do |v|
|
|
124
|
+
!v.is_a?(String) && !v.is_a?(Hash) && v.type == "volume"
|
|
125
|
+
end or return ""
|
|
126
|
+
|
|
127
|
+
"<strong>#{volume.content}</strong>"
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# The BIPM medium, verbatim and bracketed with its leading
|
|
132
|
+
# separator (" [Online]", " [dataset]") — an absent medium
|
|
133
|
+
# attaches to nothing
|
|
134
|
+
class BipmMedium < Elements::Medium
|
|
135
|
+
private
|
|
136
|
+
|
|
137
|
+
def medium
|
|
138
|
+
m = @model.medium or return ""
|
|
139
|
+
text = m.carrier.to_s
|
|
140
|
+
text = m.genre.to_s if text.empty?
|
|
141
|
+
text = [m.form.to_s, m.size.to_s].reject(&:empty?)
|
|
142
|
+
.join(", ") if text.empty?
|
|
143
|
+
text.empty? ? "" : " [#{text}]"
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# The BIPM edition carries its own leading separator (",
|
|
148
|
+
# First edition" for monographs, ". Version 2" online), so
|
|
149
|
+
# its absence drops the separator with it
|
|
150
|
+
class BipmEdition < Elements::Edition
|
|
151
|
+
def render
|
|
152
|
+
text = super.to_s
|
|
153
|
+
sep = item_kind == "monograph" ? ", " : ". "
|
|
154
|
+
text.empty? ? "" : "#{sep}#{text}"
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# The BIPM organization creator: the name alone, no
|
|
159
|
+
# abbreviation suffix. Standards without personal creators
|
|
160
|
+
# cite their publisher's name; monographs cite nothing
|
|
161
|
+
class BipmCreator < Elements::Creator
|
|
162
|
+
private
|
|
163
|
+
|
|
164
|
+
def org_name(contributor)
|
|
165
|
+
Array(contributor.organization&.name).map { |n| localized(n) }
|
|
166
|
+
.join(", ")
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def fallback_name
|
|
170
|
+
return "" if %w[monograph continuing component_part]
|
|
171
|
+
.include?(@style.kind_for(@model.type))
|
|
172
|
+
|
|
173
|
+
publishers = contributors("publisher").filter_map do |c|
|
|
174
|
+
localized(Array(c.organization&.name).first)
|
|
175
|
+
end
|
|
176
|
+
publishers.reject(&:empty?).first.to_s
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
end
|
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Relaton
|
|
4
|
+
module Render
|
|
5
|
+
module Iso690
|
|
6
|
+
module Rules
|
|
7
|
+
# The NIST rule set, moved verbatim from the metanorma-nist
|
|
8
|
+
# flavor's NistElements: the corporate creator forms, the
|
|
9
|
+
# series derivation from nist-long identifiers, the draft
|
|
10
|
+
# stage forms, the identifier order, and the component-part
|
|
11
|
+
# host citation. Select from pack data:
|
|
12
|
+
# rules: { creator: nist_series_publisher, ... }
|
|
13
|
+
module Nist
|
|
14
|
+
NIST_AND_ABBREV =
|
|
15
|
+
["NIST", "National Institute of Standards and Technology"].freeze
|
|
16
|
+
|
|
17
|
+
STAGE_PRINT = {
|
|
18
|
+
"draft-internal" => "Internal Draft",
|
|
19
|
+
"draft-wip" => "Work-in-Progress Draft",
|
|
20
|
+
"draft-prelim" => "Preliminary Draft",
|
|
21
|
+
"draft-public" => "Public Draft",
|
|
22
|
+
"draft-approval" => "Approval Draft",
|
|
23
|
+
"final" => "Final",
|
|
24
|
+
"final-review" => "Under Review",
|
|
25
|
+
}.freeze
|
|
26
|
+
|
|
27
|
+
FIPS_PUBLISHER = "U.S. Department of Commerce, Washington, D.C."
|
|
28
|
+
NIST_PUBLISHER = "National Institute of Standards and Technology, " \
|
|
29
|
+
"Gaithersburg, MD"
|
|
30
|
+
|
|
31
|
+
HOST_RELATION_TYPES = %w[partOf includedIn].freeze
|
|
32
|
+
|
|
33
|
+
# The partOf/includedIn host and its publication year: shared
|
|
34
|
+
# by the component part and the host-date fallback of the
|
|
35
|
+
# date element
|
|
36
|
+
module HostDate
|
|
37
|
+
def relation_host
|
|
38
|
+
Array(@model.relation).find do |r|
|
|
39
|
+
HOST_RELATION_TYPES.include?(r.type)
|
|
40
|
+
end&.bibitem
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def host_date_year
|
|
44
|
+
h = relation_host or return ""
|
|
45
|
+
d = Array(h.date).find(&:published) ||
|
|
46
|
+
Array(h.date).find { |x| x.type.nil? } ||
|
|
47
|
+
Array(h.date).find { |x| x.type == "issued" } ||
|
|
48
|
+
Array(h.date).first or return ""
|
|
49
|
+
v = d.at || d.from || d.to or return ""
|
|
50
|
+
begin
|
|
51
|
+
v.to_date.year.to_s
|
|
52
|
+
rescue ArgumentError, TypeError
|
|
53
|
+
v.to_s[/\d{4}/].to_s
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# NIST-aware element base: NIST Standard Reference documents
|
|
59
|
+
# are detected by identifier type or publisher
|
|
60
|
+
class Base < Element
|
|
61
|
+
def present?
|
|
62
|
+
!render.to_s.empty?
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
private
|
|
66
|
+
|
|
67
|
+
def nist?
|
|
68
|
+
return true if Array(@model.docidentifier).any? do |d|
|
|
69
|
+
d.type.to_s.start_with?("NIST")
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
Array(@model.contributor).select { |c| has_role?(c, "publisher") }
|
|
73
|
+
.any? do |c|
|
|
74
|
+
org = c.organization or next false
|
|
75
|
+
|
|
76
|
+
Array(org.name).any? { |n| NIST_AND_ABBREV.include?(n.content) } ||
|
|
77
|
+
org.abbreviation&.content == "NIST"
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def series_title
|
|
82
|
+
Array(@model.series).first&.title&.first&.content.to_s
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# The series publisher block, parenthesized, after the title
|
|
87
|
+
class NistPublisher < Base
|
|
88
|
+
def render
|
|
89
|
+
if series_title == "NIST Federal Information Processing Standards"
|
|
90
|
+
return " (#{FIPS_PUBLISHER})"
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
nist? ? " (#{NIST_PUBLISHER})" : ""
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# The NIST draft form ("Draft (Third Public Draft)")
|
|
98
|
+
class NistDraft < Base
|
|
99
|
+
def render
|
|
100
|
+
stage = @model.status&.stage&.content.to_s
|
|
101
|
+
return "" unless stage.start_with?("draft") && nist?
|
|
102
|
+
|
|
103
|
+
"Draft (#{iteration(stage)} #{STAGE_PRINT.fetch(stage, stage)})"
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
private
|
|
107
|
+
|
|
108
|
+
def iteration(stage)
|
|
109
|
+
iter = @model.status&.iteration.to_s
|
|
110
|
+
return "Initial" if iter.empty? || iter == "1"
|
|
111
|
+
return "Final" if iter.casecmp("final").zero?
|
|
112
|
+
|
|
113
|
+
spellout_ordinal(iter.to_i)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# The language packs carry ordinal word labels; beyond
|
|
117
|
+
# their reach the numeric suffix form carries the value
|
|
118
|
+
def spellout_ordinal(num)
|
|
119
|
+
word = @i18n.label("ordinal_word_#{num}")
|
|
120
|
+
return word.capitalize unless word == "ordinal_word_#{num}"
|
|
121
|
+
|
|
122
|
+
"#{num}#{ordinal_suffix(num)}"
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def ordinal_suffix(num)
|
|
126
|
+
case num % 100
|
|
127
|
+
when 11, 12, 13 then "th"
|
|
128
|
+
else
|
|
129
|
+
case num % 10
|
|
130
|
+
when 1 then "st"
|
|
131
|
+
when 2 then "nd"
|
|
132
|
+
when 3 then "rd"
|
|
133
|
+
else "th"
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# The NIST series form ("NIST Special Publication (SP)
|
|
140
|
+
# 800-116 Rev. 1"). A series carrying a formattedref renders
|
|
141
|
+
# it verbatim; the number joins the partnumber ("800-116.1"),
|
|
142
|
+
# and the edition carries the revision. NIST documents
|
|
143
|
+
# without a series element derive it from the nist-long
|
|
144
|
+
# identifier
|
|
145
|
+
class NistSeries < Base
|
|
146
|
+
def render
|
|
147
|
+
s = Array(@model.series).first
|
|
148
|
+
return derived_series unless s
|
|
149
|
+
|
|
150
|
+
formatted = localized(s.formattedref)
|
|
151
|
+
return formatted unless formatted.empty?
|
|
152
|
+
|
|
153
|
+
title = localized(Array(s.title).first)
|
|
154
|
+
return "" if title.empty?
|
|
155
|
+
|
|
156
|
+
[title, parens(s), number(s)].reject(&:empty?).join(" ")
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
private
|
|
160
|
+
|
|
161
|
+
def derived_series
|
|
162
|
+
long = Array(@model.docidentifier).find do |d|
|
|
163
|
+
d.type == "nist-long"
|
|
164
|
+
end&.content.to_s
|
|
165
|
+
return "" if long.empty?
|
|
166
|
+
|
|
167
|
+
title = long[/\A(NIST [A-Za-z ]+?) \d/, 1] || ""
|
|
168
|
+
return "" if title.empty?
|
|
169
|
+
|
|
170
|
+
[title, parens_derived(long), number_derived(long)]
|
|
171
|
+
.reject(&:empty?).join(" ")
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def parens_derived(long)
|
|
175
|
+
# strip the NIST sigla before the whitespace strip: the
|
|
176
|
+
# 1.x order left a bare "NIST" parenthesized
|
|
177
|
+
abbr = long[/\A[A-Z.]+ /, 0].to_s.sub(/\ANIST /, "").strip
|
|
178
|
+
abbr.empty? ? "" : "(#{abbr})"
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def number_derived(long)
|
|
182
|
+
num = long[/\A[NISTa-z. ]*([0-9][0-9A-Za-z.-]*)/, 1].to_s
|
|
183
|
+
num.empty? ? num : with_revision(num)
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def parens(s)
|
|
187
|
+
abbr = localized(s.abbreviation).sub(/\ANIST /, "")
|
|
188
|
+
abbr.empty? ? "" : "(#{abbr})"
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def number(s)
|
|
192
|
+
num = s.number.to_s
|
|
193
|
+
unless s.partnumber.to_s.empty?
|
|
194
|
+
num = num.empty? ? s.partnumber.to_s : "#{num}.#{s.partnumber}"
|
|
195
|
+
end
|
|
196
|
+
num = @model.docnumber.to_s if num.empty? && nist?
|
|
197
|
+
num.empty? ? num : with_revision(num)
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def with_revision(num)
|
|
201
|
+
rev = @model.edition&.content.to_s.sub(/\ARevision /, "")
|
|
202
|
+
rev.empty? ? num : "#{num} Rev. #{rev}"
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
module Relaton
|
|
212
|
+
module Render
|
|
213
|
+
module Iso690
|
|
214
|
+
module Rules
|
|
215
|
+
module Nist
|
|
216
|
+
# The NIST identifier order: the authoritative identifiers
|
|
217
|
+
# (ISO, IEC, ...) before the kind-rendered ISBN/DOI/ISSN
|
|
218
|
+
# group; NIST documents cite the NIST identifier alone (the
|
|
219
|
+
# biblio tag)
|
|
220
|
+
class NistIdentifier < Elements::Identifier
|
|
221
|
+
OTHER_TYPES = %w[ISBN ISSN DOI].freeze
|
|
222
|
+
|
|
223
|
+
def render
|
|
224
|
+
return "" if nist?
|
|
225
|
+
|
|
226
|
+
auth, other = unscoped_ids.partition do |d|
|
|
227
|
+
!OTHER_TYPES.include?(d.type)
|
|
228
|
+
end
|
|
229
|
+
(auth + other).map { |d| render_id(d) }.reject(&:empty?)
|
|
230
|
+
.join(". ")
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
private
|
|
234
|
+
|
|
235
|
+
def nist?
|
|
236
|
+
Array(@model.docidentifier).any? do |d|
|
|
237
|
+
d.type.to_s.start_with?("NIST")
|
|
238
|
+
end || Array(@model.contributor).any? do |c|
|
|
239
|
+
next false unless has_role?(c, "publisher")
|
|
240
|
+
|
|
241
|
+
org = c.organization or next false
|
|
242
|
+
|
|
243
|
+
Array(org.name).any? { |n| NIST_AND_ABBREV.include?(n.content) } ||
|
|
244
|
+
org.abbreviation&.content == "NIST"
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def unscoped_ids
|
|
249
|
+
Array(@model.docidentifier).reject do |d|
|
|
250
|
+
Elements::Identifier::INTERNAL_TYPES.include?(d.type) ||
|
|
251
|
+
!d.scope.to_s.empty? || d.content.to_s.strip.empty?
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
# The NIST ISBN and ISSN kinds cite the kind label with a
|
|
256
|
+
# colon
|
|
257
|
+
def render_id(docidentifier)
|
|
258
|
+
return "#{docidentifier.type}: #{docidentifier.content}" if
|
|
259
|
+
%w[ISBN ISSN].include?(docidentifier.type)
|
|
260
|
+
|
|
261
|
+
super
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
# The NIST component-part order: the host editors before the
|
|
266
|
+
# host title, the host date after the production
|
|
267
|
+
# ("In: Pellegrini AD, Smith PK (Eds.) <em>The nature of
|
|
268
|
+
# play</em> (New York, NY: Guilford Press), 2005")
|
|
269
|
+
class NistComponentPart < Elements::ComponentPart
|
|
270
|
+
include HostDate
|
|
271
|
+
|
|
272
|
+
def render
|
|
273
|
+
h = relation_host or return ""
|
|
274
|
+
out = +"#{lead}#{host_names(h)}"
|
|
275
|
+
eds = host_editors(h)
|
|
276
|
+
out += " (#{@i18n.label(eds.one? ? "ed" : "eds")})" unless
|
|
277
|
+
eds.empty?
|
|
278
|
+
out += " #{host_title}" unless host_title_text.empty?
|
|
279
|
+
production = host_production_text(h)
|
|
280
|
+
out += " (#{production})" unless production.empty?
|
|
281
|
+
date = host_date_year
|
|
282
|
+
out += ", #{date}" unless date.empty?
|
|
283
|
+
out
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
private
|
|
287
|
+
|
|
288
|
+
def host_editors(h)
|
|
289
|
+
Array(h.contributor).select { |c| has_role?(c, "editor") }
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
def host_names(h)
|
|
293
|
+
names = host_editors(h).map { |c|
|
|
294
|
+
person = c.person or next ""
|
|
295
|
+
|
|
296
|
+
[person_surname(person), person_given(person)].reject(&:empty?)
|
|
297
|
+
.join(" ")
|
|
298
|
+
}.reject(&:empty?)
|
|
299
|
+
join_names(names)
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
def host_production_text(h)
|
|
303
|
+
Elements::Production.new(h, style: @style, i18n: @i18n)
|
|
304
|
+
.render.to_s
|
|
305
|
+
end
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
# A component part with no date of its own cites the host's
|
|
309
|
+
class NistDate < Elements::PubDate
|
|
310
|
+
include HostDate
|
|
311
|
+
|
|
312
|
+
def render
|
|
313
|
+
text = super.to_s
|
|
314
|
+
text.empty? ? host_date_year : text
|
|
315
|
+
end
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
# The series-position date segment of the 1.x templates: the
|
|
319
|
+
# date carries its own leading comma ("<series>, 2018
|
|
320
|
+
# (updated November 2018)"), so an absent date removes the
|
|
321
|
+
# comma with it
|
|
322
|
+
class NistSerialDate < Base
|
|
323
|
+
def render
|
|
324
|
+
text = pub_date or return ""
|
|
325
|
+
|
|
326
|
+
", #{text}#{updated_date}"
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
private
|
|
330
|
+
|
|
331
|
+
def pub_date
|
|
332
|
+
t = Elements::PubDate.new(@model, style: @style, i18n: @i18n)
|
|
333
|
+
.render.to_s
|
|
334
|
+
t.empty? ? nil : t
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
def updated_date
|
|
338
|
+
Elements::Updated.new(@model, style: @style, i18n: @i18n).render
|
|
339
|
+
end
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
# The FIPS creator form: the series names the corporate
|
|
343
|
+
# creator; standards without personal creators cite their
|
|
344
|
+
# publisher's name, monographs cite nothing (their "(n.d.)"
|
|
345
|
+
# comes from the perType fallback)
|
|
346
|
+
class NistCreator < Elements::Creator
|
|
347
|
+
def render
|
|
348
|
+
return fips_creator if fips_series?
|
|
349
|
+
|
|
350
|
+
super
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
def plain_render
|
|
354
|
+
return fips_creator if fips_series?
|
|
355
|
+
|
|
356
|
+
super
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
private
|
|
360
|
+
|
|
361
|
+
def fallback_name
|
|
362
|
+
return "" if %w[monograph continuing component_part]
|
|
363
|
+
.include?(Kinds.kind_for(@model.type))
|
|
364
|
+
|
|
365
|
+
publishers = contributors("publisher").filter_map do |c|
|
|
366
|
+
localized(Array(c.organization&.name).first)
|
|
367
|
+
end
|
|
368
|
+
publishers.reject(&:empty?).first.to_s
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
def fips_series?
|
|
372
|
+
Array(@model.series).first&.title&.first&.content ==
|
|
373
|
+
"NIST Federal Information Processing Standards"
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
def fips_creator
|
|
377
|
+
"National Institute of Standards and Technology"
|
|
378
|
+
end
|
|
379
|
+
end
|
|
380
|
+
end
|
|
381
|
+
end
|
|
382
|
+
end
|
|
383
|
+
end
|
|
384
|
+
end
|
|
@@ -106,6 +106,71 @@ module Relaton
|
|
|
106
106
|
end
|
|
107
107
|
end
|
|
108
108
|
|
|
109
|
+
# The IHO creator cites the affiliation's organization name
|
|
110
|
+
# after the creator list ("D. Balenson, Internet Engineering
|
|
111
|
+
# Task Force")
|
|
112
|
+
class IhoCreator < Elements::Creator
|
|
113
|
+
def render
|
|
114
|
+
out = super.to_s
|
|
115
|
+
aff = affiliation_names
|
|
116
|
+
out.empty? || aff.empty? ? out : "#{out}, #{aff}"
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
private
|
|
120
|
+
|
|
121
|
+
def affiliation_names
|
|
122
|
+
creators.filter_map do |c|
|
|
123
|
+
person = c.person or next ""
|
|
124
|
+
|
|
125
|
+
Array(person.affiliation).filter_map do |a|
|
|
126
|
+
Array(a.organization&.name).map(&:content).first.to_s
|
|
127
|
+
end.reject(&:empty?).first.to_s
|
|
128
|
+
end.reject(&:empty?).uniq.join(", ")
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# The IHO edition cites only for IHO-published documents, as
|
|
133
|
+
# the raw numeric edition carrying its own label ("edition
|
|
134
|
+
# 3.1.0"); worded editions ("Revision 1") cite as nothing
|
|
135
|
+
class IhoEdition < Elements::Edition
|
|
136
|
+
def render
|
|
137
|
+
return "" unless iho_publisher?
|
|
138
|
+
|
|
139
|
+
text = edition_text
|
|
140
|
+
text.match?(/\A\d/) ? " edition #{text}" : ""
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
private
|
|
144
|
+
|
|
145
|
+
def edition_text
|
|
146
|
+
raw = @model.edition
|
|
147
|
+
raw.respond_to?(:content) ? raw.content.to_s : raw.to_s
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def iho_publisher?
|
|
151
|
+
Array(@model.contributor).any? do |c|
|
|
152
|
+
next false unless Array(c.role).any? do |r|
|
|
153
|
+
r.is_a?(String) ? r == "publisher" : r.type == "publisher"
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
org = c.organization or next false
|
|
157
|
+
names = Array(org.name).map(&:content) +
|
|
158
|
+
[org.abbreviation&.content.to_s]
|
|
159
|
+
# a string array: %w[] would split the organization's
|
|
160
|
+
# full name into words and never match it
|
|
161
|
+
names.any? do |n|
|
|
162
|
+
["IHO", "International Hydrographic Organization"]
|
|
163
|
+
.include?(n)
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# The NIST and BIPM rule sets live in their own autoloaded
|
|
170
|
+
# sections
|
|
171
|
+
autoload :Nist, "relaton/render/iso690/rules/nist"
|
|
172
|
+
autoload :Bipm, "relaton/render/iso690/rules/bipm"
|
|
173
|
+
|
|
109
174
|
REGISTRY = {
|
|
110
175
|
"status_bare" => BareStatus,
|
|
111
176
|
"itu_identifier" => ItuIdentifier,
|
|
@@ -113,6 +178,23 @@ module Relaton
|
|
|
113
178
|
"ieee_component_part" => IeeeComponentPart,
|
|
114
179
|
"ieee_access" => IeeeAccess,
|
|
115
180
|
"ieee_medium" => IeeeMedium,
|
|
181
|
+
"nist_creator" => Nist::NistCreator,
|
|
182
|
+
"nist_date" => Nist::NistDate,
|
|
183
|
+
"nist_serial_date" => Nist::NistSerialDate,
|
|
184
|
+
"nist_series" => Nist::NistSeries,
|
|
185
|
+
"nist_component_part" => Nist::NistComponentPart,
|
|
186
|
+
"nist_identifier" => Nist::NistIdentifier,
|
|
187
|
+
"nist_publisher" => Nist::NistPublisher,
|
|
188
|
+
"nist_draft" => Nist::NistDraft,
|
|
189
|
+
"iho_creator" => IhoCreator,
|
|
190
|
+
"iho_edition" => IhoEdition,
|
|
191
|
+
"bipm_creator" => Bipm::BipmCreator,
|
|
192
|
+
"bipm_component_part" => Bipm::BipmComponentPart,
|
|
193
|
+
"bipm_production" => Bipm::BipmProduction,
|
|
194
|
+
"bipm_extent" => Bipm::BipmExtent,
|
|
195
|
+
"bipm_medium" => Bipm::BipmMedium,
|
|
196
|
+
"bipm_edition" => Bipm::BipmEdition,
|
|
197
|
+
"bipm_volume" => Bipm::BipmVolume,
|
|
116
198
|
}.freeze
|
|
117
199
|
|
|
118
200
|
class << self
|
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.36
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
@@ -148,6 +148,8 @@ files:
|
|
|
148
148
|
- lib/relaton/render/iso690/kinds.rb
|
|
149
149
|
- lib/relaton/render/iso690/renderer.rb
|
|
150
150
|
- lib/relaton/render/iso690/rules.rb
|
|
151
|
+
- lib/relaton/render/iso690/rules/bipm.rb
|
|
152
|
+
- lib/relaton/render/iso690/rules/nist.rb
|
|
151
153
|
- lib/relaton/render/iso690/style.rb
|
|
152
154
|
- lib/relaton/render/iso690/style/locale.rb
|
|
153
155
|
- lib/relaton/render/iso690/style/name_form.rb
|