relaton-render 3.0.0.pre.alpha.43 → 3.0.0.pre.alpha.44
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/iso690/csl_import.rb +129 -0
- data/lib/relaton/render/iso690/elements/creator.rb +12 -3
- data/lib/relaton/render/iso690/elements/edition.rb +5 -2
- data/lib/relaton/render/iso690/i18n/en.yml +1 -0
- data/lib/relaton/render/iso690/styles/apa.yml +2 -2
- data/lib/relaton/render/iso690/styles/chicago.yml +2 -1
- data/lib/relaton/render/iso690/styles/mla.yml +56 -0
- data/lib/relaton/render/iso690.rb +1 -0
- data/lib/relaton/render/version.rb +1 -1
- data/lib/relaton/render.rb +9 -0
- data/relaton-render.gemspec +1 -1
- metadata +9 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: aedee88b2cbb112fe10bea8cb0a653126eaa9b9fb4cca2acecea9ab0c658836c
|
|
4
|
+
data.tar.gz: 97d83f937135ae571bbd36aa4a35f1d17421a79b61aafee1690d69181bbd05ee
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8ed88ac9dbb5d27550fe956c9db969a052609d725e5f6eaa02e158ca65ee1937c083146dbaf5ed8223f830b5b619c36c81afbe04a8da8587755c394690787468
|
|
7
|
+
data.tar.gz: 92aa233a10f6e3479f971a373a7d1786215d5552368f19bd982d1dfde7d63c23d0b5b11aeee183652d48f86e00d13b9a163556c4bcf83453b315e07041b53390
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
|
|
3
|
+
module Relaton
|
|
4
|
+
module Render
|
|
5
|
+
module Iso690
|
|
6
|
+
# Imports a CSL style's common properties into a CitationStyle instance
|
|
7
|
+
# (styles as data, the downgrade direction: CSL's element-list engine
|
|
8
|
+
# is strictly richer, so the import covers what the instance format can
|
|
9
|
+
# express and lists everything it dropped in `requires`).
|
|
10
|
+
#
|
|
11
|
+
# Mapped: the info title, the citation/reference variable runs (text
|
|
12
|
+
# elements over the CSL variables, via the crosswalk below), the
|
|
13
|
+
# name-form scalars (initialize-with, name-as-sort-order, et-al
|
|
14
|
+
# lengths), the year-suffix disambiguation, and the delimiters.
|
|
15
|
+
module CslImport
|
|
16
|
+
# CSL variable -> the ISO 690 slot the engine resolves.
|
|
17
|
+
VARIABLE_SLOTS = {
|
|
18
|
+
"author" => "creator", "editor" => "creator",
|
|
19
|
+
"title" => "title", "container-title" => "series",
|
|
20
|
+
"edition" => "edition", "publisher" => "production",
|
|
21
|
+
"publisher-place" => "location", "issued" => "date",
|
|
22
|
+
"DOI" => "identifier", "URL" => "identifier", "PMID" => "identifier",
|
|
23
|
+
"number" => "numeration", "volume" => "numeration",
|
|
24
|
+
"page" => "numeration", "medium" => "medium",
|
|
25
|
+
"accessed" => "access", "version" => "edition",
|
|
26
|
+
}.freeze
|
|
27
|
+
|
|
28
|
+
# CSL features the import drops, reported in `requires` so a resolver
|
|
29
|
+
# fails loudly instead of silently mis-rendering.
|
|
30
|
+
DROPPED_FEATURES = [
|
|
31
|
+
"csl macros (macro elements are not data-expressible)",
|
|
32
|
+
"csl groups with conditional rendering (match= attributes)",
|
|
33
|
+
"csl per-locator templates",
|
|
34
|
+
].freeze
|
|
35
|
+
|
|
36
|
+
class << self
|
|
37
|
+
# Build a CitationStyle instance from a parsed CSL style JSON.
|
|
38
|
+
#
|
|
39
|
+
# @param csl [Hash] parsed CSL style
|
|
40
|
+
# @return [Style]
|
|
41
|
+
def style(csl)
|
|
42
|
+
Style.new(
|
|
43
|
+
name: style_name(csl),
|
|
44
|
+
family: "iso690",
|
|
45
|
+
requires: dropped_features(csl),
|
|
46
|
+
scheme: scheme(csl),
|
|
47
|
+
templates: templates(csl),
|
|
48
|
+
)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Parse a CSL style JSON string and build the instance.
|
|
52
|
+
#
|
|
53
|
+
# @param [String] json
|
|
54
|
+
# @return [Style]
|
|
55
|
+
def from_json(json)
|
|
56
|
+
style(JSON.parse(json))
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
private
|
|
60
|
+
|
|
61
|
+
def style_name(csl)
|
|
62
|
+
title = csl.dig("info", "title").to_s
|
|
63
|
+
title.empty? ? "Imported CSL style" : "#{title} (CSL import)"
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def dropped_features(csl)
|
|
67
|
+
feats = DROPPED_FEATURES.dup
|
|
68
|
+
feats << "csl bibliography section" if csl["bibliography"]
|
|
69
|
+
feats << "csl locales" if csl["locales"]
|
|
70
|
+
feats
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def scheme(csl)
|
|
74
|
+
Style::Scheme.new(
|
|
75
|
+
system: "name-date",
|
|
76
|
+
name_form: name_form(csl),
|
|
77
|
+
locale: Style::Locale.new(no_date: "n.d."),
|
|
78
|
+
)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def name_form(csl)
|
|
82
|
+
citation = csl["citation"] || {}
|
|
83
|
+
initialize_with = citation["initialize-with"]
|
|
84
|
+
Style::NameForm.new(
|
|
85
|
+
initials: !initialize_with.nil?,
|
|
86
|
+
initials_separator: initialize_with.is_a?(String) ? initialize_with : " ",
|
|
87
|
+
initials_period: initialize_with.to_s.include?("."),
|
|
88
|
+
inverted_all: citation["name-as-sort-order"].to_s == "all",
|
|
89
|
+
)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def templates(csl)
|
|
93
|
+
citation_elements = csl.dig("citation", "elements") || []
|
|
94
|
+
reference_elements = csl.dig("bibliography", "elements") || []
|
|
95
|
+
Style::TemplateMap.new(
|
|
96
|
+
citation: element_template(
|
|
97
|
+
citation_elements, csl.dig("citation", "delimiter") || ", ",
|
|
98
|
+
"{{creator}}, {{date}}{{disambiguator}}",
|
|
99
|
+
),
|
|
100
|
+
reference: element_template(
|
|
101
|
+
reference_elements, csl.dig("bibliography", "delimiter") || ". ",
|
|
102
|
+
"{{creator}}. {{title}}. {{edition}}. {{series}}. {{production}}, {{date}}. {{identifier}}. {{location}}.",
|
|
103
|
+
),
|
|
104
|
+
name: "{{surname}}, {{givenNames}}",
|
|
105
|
+
)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# Flatten CSL text/variable elements into a slot template. Non-text
|
|
109
|
+
# elements (macros, groups, conditions) contribute nothing: the
|
|
110
|
+
# import covers flat variable runs only.
|
|
111
|
+
def element_template(elements, delimiter, fallback)
|
|
112
|
+
slots = elements.filter_map do |el|
|
|
113
|
+
next unless el.is_a?(Hash)
|
|
114
|
+
|
|
115
|
+
# A CSL text element nests its variable: {"text": {"variable": ...}}
|
|
116
|
+
variable = el.dig("text", "variable") || el["variable"]
|
|
117
|
+
slot = variable && VARIABLE_SLOTS[variable]
|
|
118
|
+
"{{#{slot}}}" if slot
|
|
119
|
+
end
|
|
120
|
+
slots = slots.uniq
|
|
121
|
+
return fallback if slots.empty?
|
|
122
|
+
|
|
123
|
+
slots.join(delimiter)
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
@@ -95,7 +95,7 @@ module Relaton
|
|
|
95
95
|
return in_text_etal if in_text_etal?
|
|
96
96
|
|
|
97
97
|
name = creators.first ? in_text_name(creators.first) : ""
|
|
98
|
-
etal? ? "#{name}
|
|
98
|
+
etal? ? "#{name}#{etal_suffix}" : name
|
|
99
99
|
end
|
|
100
100
|
|
|
101
101
|
# The in-text cite truncates at its own threshold: at
|
|
@@ -104,7 +104,16 @@ module Relaton
|
|
|
104
104
|
def in_text_etal
|
|
105
105
|
names = creators.first(name_form.in_text_etal_display)
|
|
106
106
|
.map { |c| in_text_name(c) }
|
|
107
|
-
"#{join(names)}
|
|
107
|
+
"#{join(names)}#{etal_suffix}"
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# The et-al suffix is the locale's label (roman by default; a
|
|
111
|
+
# pack's `others` label may carry its own presentation), joined
|
|
112
|
+
# per the style's list style — the serial comma before it is the
|
|
113
|
+
# MLA form ("Fielding, Roy, et al.")
|
|
114
|
+
def etal_suffix
|
|
115
|
+
sep = name_form.list_style == "serial" ? "," : ""
|
|
116
|
+
"#{sep} #{@i18n.label('others')}"
|
|
108
117
|
end
|
|
109
118
|
|
|
110
119
|
# The in-text cite names by surname alone (the 1.x
|
|
@@ -190,7 +199,7 @@ module Relaton
|
|
|
190
199
|
creators.first(display).each_with_index
|
|
191
200
|
.map do |contributor, index|
|
|
192
201
|
format(contributor, first: index.zero?)
|
|
193
|
-
end.join(", ") +
|
|
202
|
+
end.join(", ") + etal_suffix
|
|
194
203
|
end
|
|
195
204
|
|
|
196
205
|
def format(contributor, first:)
|
|
@@ -54,10 +54,13 @@ module Relaton
|
|
|
54
54
|
private
|
|
55
55
|
|
|
56
56
|
# Worded editions are document editions; online resources
|
|
57
|
-
# carry numbered builds rendered as versions
|
|
57
|
+
# carry numbered builds rendered as versions. A standard is a
|
|
58
|
+
# document edition too (its report kind carries the clause 8.11
|
|
59
|
+
# fallback templates, but its numbered editions read as
|
|
60
|
+
# "Nth edition" — the TS contract renders them so).
|
|
58
61
|
def word_edition?
|
|
59
62
|
number.positive? &&
|
|
60
|
-
%w[monograph component_part serial_part]
|
|
63
|
+
%w[monograph component_part serial_part report]
|
|
61
64
|
.include?(item_kind)
|
|
62
65
|
end
|
|
63
66
|
|
|
@@ -15,13 +15,13 @@ scheme:
|
|
|
15
15
|
givenNameFirst: false
|
|
16
16
|
editorsMarked: false
|
|
17
17
|
surnameUpcase: false
|
|
18
|
+
orgUpcase: false
|
|
18
19
|
subsequentSurnameUpcase: false
|
|
19
20
|
locale:
|
|
20
21
|
"in": "In"
|
|
21
22
|
labels:
|
|
22
23
|
"and": "&"
|
|
23
24
|
oxford_comma: ","
|
|
24
|
-
oxford_comma: ","
|
|
25
25
|
templates:
|
|
26
26
|
titleOpen: ""
|
|
27
27
|
titleClose: ""
|
|
@@ -34,7 +34,7 @@ perType:
|
|
|
34
34
|
home: true
|
|
35
35
|
template: "{{title}}"
|
|
36
36
|
- type: report
|
|
37
|
-
template: "{{identifier}}. {{title}}. {{production}}."
|
|
37
|
+
template: "{{identifier}}. ({{date}}). {{title}}. {{production}}."
|
|
38
38
|
- type: monograph
|
|
39
39
|
title: "<em>{{title}}</em>"
|
|
40
40
|
template: "{{creator}} ({{date}}). {{title}}. {{production}}."
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# MLA Handbook (9th ed.), Works Cited forms: every author after the
|
|
2
|
+
# first renders in natural order ("Dorris, Michael, and Louise
|
|
3
|
+
# Erdrich"), three or more collapse to "et al."; self-contained titles
|
|
4
|
+
# are italic and container/part titles take quotation marks; the date
|
|
5
|
+
# closes the entry before the extent. The in-text citation carries the
|
|
6
|
+
# author alone - MLA has no date in the parenthesis.
|
|
7
|
+
name: "MLA (9th edition) Works Cited"
|
|
8
|
+
family: mla
|
|
9
|
+
requires:
|
|
10
|
+
- extent_units
|
|
11
|
+
scheme:
|
|
12
|
+
system: name-date
|
|
13
|
+
nameForm:
|
|
14
|
+
initials: false
|
|
15
|
+
initialsSeparator: " "
|
|
16
|
+
initialsPeriod: true
|
|
17
|
+
invertedAll: false
|
|
18
|
+
givenNameFirst: false
|
|
19
|
+
editorsMarked: true
|
|
20
|
+
surnameUpcase: false
|
|
21
|
+
subsequentSurnameUpcase: false
|
|
22
|
+
orgUpcase: false
|
|
23
|
+
listStyle: serial
|
|
24
|
+
etalCount: 3
|
|
25
|
+
etalDisplay: 1
|
|
26
|
+
locale:
|
|
27
|
+
"in": "in"
|
|
28
|
+
labels:
|
|
29
|
+
"and": "and"
|
|
30
|
+
oxford_comma: ","
|
|
31
|
+
others: "et al."
|
|
32
|
+
templates:
|
|
33
|
+
titleOpen: "\""
|
|
34
|
+
titleClose: "\""
|
|
35
|
+
citation: "{{surname}}"
|
|
36
|
+
reference: "{{creator}}. {{title}}. {{edition}}. {{series}}. {{production}}, {{date}}. {{extent}}."
|
|
37
|
+
name: "{{surname}}, {{givenNames}}"
|
|
38
|
+
identifierMode: all
|
|
39
|
+
perType:
|
|
40
|
+
- type: report
|
|
41
|
+
title: "<em>{{title}}</em>"
|
|
42
|
+
template: "{{creator}}. {{title}}. {{edition}}. {{production}}, {{date}}."
|
|
43
|
+
- type: monograph
|
|
44
|
+
title: "<em>{{title}}</em>"
|
|
45
|
+
template: "{{creator}}. {{title}}. {{edition}}. {{production}}, {{date}}. {{extent}}."
|
|
46
|
+
- type: component_part
|
|
47
|
+
title: "\"{{title}}\""
|
|
48
|
+
componentpart: "<em>{{componentpart}}</em>"
|
|
49
|
+
template: "{{creator}}. {{title}}. {{componentpart}}, {{production}}, {{date}}. {{extent}}."
|
|
50
|
+
- type: continuing
|
|
51
|
+
title: "\"{{title}}\""
|
|
52
|
+
series: "<em>{{seriestitle}}</em>"
|
|
53
|
+
template: "{{creator}}. {{title}}. {{series}}, {{date}}. {{extent}}."
|
|
54
|
+
sortKey:
|
|
55
|
+
- attribute: creator
|
|
56
|
+
- attribute: date
|
|
@@ -21,6 +21,7 @@ module Relaton
|
|
|
21
21
|
autoload :Renderer, "relaton/render/iso690/renderer"
|
|
22
22
|
autoload :Rules, "relaton/render/iso690/rules"
|
|
23
23
|
autoload :Style, "relaton/render/iso690/style"
|
|
24
|
+
autoload :CslImport, "relaton/render/iso690/csl_import"
|
|
24
25
|
autoload :Template, "relaton/render/iso690/template"
|
|
25
26
|
end
|
|
26
27
|
end
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# The gem's require entry: the public rendering surface — General (the
|
|
4
|
+
# localized multi-renderer front) and the ISO 690 engine with its
|
|
5
|
+
# CitationStyle loader. Styles are data (lib/relaton/render/iso690/styles);
|
|
6
|
+
# the engine holds none.
|
|
7
|
+
require_relative "render/version"
|
|
8
|
+
require_relative "render/general"
|
|
9
|
+
require_relative "render/iso690"
|
data/relaton-render.gemspec
CHANGED
|
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
|
|
|
24
24
|
spec.add_dependency "htmlentities"
|
|
25
25
|
spec.add_development_dependency "relaton-bib"
|
|
26
26
|
spec.add_dependency "liquid", "~> 5"
|
|
27
|
-
spec.add_dependency "lutaml-model"
|
|
27
|
+
spec.add_dependency "lutaml-model", "~> 0.8"
|
|
28
28
|
spec.add_dependency "nokogiri"
|
|
29
29
|
spec.add_dependency "twitter_cldr"
|
|
30
30
|
# spec.metadata["rubygems_mfa_required"] = "true"
|
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.
|
|
4
|
+
version: 3.0.0.pre.alpha.44
|
|
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-
|
|
11
|
+
date: 2026-10-26 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: htmlentities
|
|
@@ -56,16 +56,16 @@ dependencies:
|
|
|
56
56
|
name: lutaml-model
|
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
|
58
58
|
requirements:
|
|
59
|
-
- - "
|
|
59
|
+
- - "~>"
|
|
60
60
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '0'
|
|
61
|
+
version: '0.8'
|
|
62
62
|
type: :runtime
|
|
63
63
|
prerelease: false
|
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
65
|
requirements:
|
|
66
|
-
- - "
|
|
66
|
+
- - "~>"
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: '0'
|
|
68
|
+
version: '0.8'
|
|
69
69
|
- !ruby/object:Gem::Dependency
|
|
70
70
|
name: nokogiri
|
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -115,8 +115,10 @@ files:
|
|
|
115
115
|
- bin/setup
|
|
116
116
|
- docs/citation-style-pack.adoc
|
|
117
117
|
- lib/relaton-render.rb
|
|
118
|
+
- lib/relaton/render.rb
|
|
118
119
|
- lib/relaton/render/general.rb
|
|
119
120
|
- lib/relaton/render/iso690.rb
|
|
121
|
+
- lib/relaton/render/iso690/csl_import.rb
|
|
120
122
|
- lib/relaton/render/iso690/element.rb
|
|
121
123
|
- lib/relaton/render/iso690/elements.rb
|
|
122
124
|
- lib/relaton/render/iso690/elements/access.rb
|
|
@@ -165,6 +167,7 @@ files:
|
|
|
165
167
|
- lib/relaton/render/iso690/styles/jis-en.yml
|
|
166
168
|
- lib/relaton/render/iso690/styles/jis-ja.yml
|
|
167
169
|
- lib/relaton/render/iso690/styles/lncs.yml
|
|
170
|
+
- lib/relaton/render/iso690/styles/mla.yml
|
|
168
171
|
- lib/relaton/render/iso690/template.rb
|
|
169
172
|
- lib/relaton/render/version.rb
|
|
170
173
|
- relaton-render.gemspec
|