relaton-render 0.4.2 → 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.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake.yml +6 -1
  3. data/.github/workflows/release.yml +24 -0
  4. data/.gitignore +14 -0
  5. data/.rubocop.yml +2 -2
  6. data/Gemfile +17 -1
  7. data/README.adoc +13 -258
  8. data/docs/citation-style-pack.adoc +370 -0
  9. data/lib/relaton/render/general.rb +305 -0
  10. data/lib/relaton/render/iso690/element.rb +153 -0
  11. data/lib/relaton/render/iso690/elements/access.rb +44 -0
  12. data/lib/relaton/render/iso690/elements/authorizer.rb +30 -0
  13. data/lib/relaton/render/iso690/elements/citeid.rb +39 -0
  14. data/lib/relaton/render/iso690/elements/component_part.rb +99 -0
  15. data/lib/relaton/render/iso690/elements/creator.rb +258 -0
  16. data/lib/relaton/render/iso690/elements/edition.rb +92 -0
  17. data/lib/relaton/render/iso690/elements/extent.rb +71 -0
  18. data/lib/relaton/render/iso690/elements/identifier.rb +46 -0
  19. data/lib/relaton/render/iso690/elements/location.rb +73 -0
  20. data/lib/relaton/render/iso690/elements/medium.rb +32 -0
  21. data/lib/relaton/render/iso690/elements/numeration.rb +26 -0
  22. data/lib/relaton/render/iso690/elements/production.rb +92 -0
  23. data/lib/relaton/render/iso690/elements/pub_date.rb +56 -0
  24. data/lib/relaton/render/iso690/elements/series.rb +66 -0
  25. data/lib/relaton/render/iso690/elements/size.rb +41 -0
  26. data/lib/relaton/render/iso690/elements/status.rb +30 -0
  27. data/lib/relaton/render/iso690/elements/stddoc.rb +40 -0
  28. data/lib/relaton/render/iso690/elements/title.rb +56 -0
  29. data/lib/relaton/render/iso690/elements/updated.rb +38 -0
  30. data/lib/relaton/render/iso690/elements.rb +67 -0
  31. data/lib/relaton/render/iso690/fields.rb +142 -0
  32. data/lib/relaton/render/iso690/i18n/en.yml +47 -0
  33. data/lib/relaton/render/iso690/i18n/fr.yml +14 -0
  34. data/lib/relaton/render/iso690/i18n/ja.yml +38 -0
  35. data/lib/relaton/render/iso690/i18n.rb +83 -0
  36. data/lib/relaton/render/iso690/identifier_kinds.rb +29 -0
  37. data/lib/relaton/render/iso690/index_renderer.rb +57 -0
  38. data/lib/relaton/render/iso690/kinds.rb +53 -0
  39. data/lib/relaton/render/iso690/renderer.rb +148 -0
  40. data/lib/relaton/render/iso690/rules.rb +36 -0
  41. data/lib/relaton/render/iso690/style/locale.rb +53 -0
  42. data/lib/relaton/render/iso690/style/name_form.rb +87 -0
  43. data/lib/relaton/render/iso690/style/scheme.rb +33 -0
  44. data/lib/relaton/render/iso690/style/sort_rule.rb +25 -0
  45. data/lib/relaton/render/iso690/style/template_map.rb +40 -0
  46. data/lib/relaton/render/iso690/style/type_template.rb +37 -0
  47. data/lib/relaton/render/iso690/style.rb +222 -0
  48. data/lib/relaton/render/iso690/styles/apa.yml +45 -0
  49. data/lib/relaton/render/iso690/styles/author-date.yml +31 -0
  50. data/lib/relaton/render/iso690/styles/chicago.yml +48 -0
  51. data/lib/relaton/render/iso690/styles/ieee-sa.yml +45 -0
  52. data/lib/relaton/render/iso690/styles/lncs.yml +54 -0
  53. data/lib/relaton/render/iso690/template.rb +248 -0
  54. data/lib/relaton/render/iso690.rb +27 -0
  55. data/lib/relaton/render/version.rb +1 -1
  56. data/lib/relaton-render.rb +11 -5
  57. data/relaton-render.gemspec +6 -13
  58. metadata +61 -116
  59. data/lib/isodoc/i18n.rb +0 -33
  60. data/lib/isodoc-yaml/i18n-ar.yaml +0 -44
  61. data/lib/isodoc-yaml/i18n-de.yaml +0 -43
  62. data/lib/isodoc-yaml/i18n-en.yaml +0 -40
  63. data/lib/isodoc-yaml/i18n-es.yaml +0 -47
  64. data/lib/isodoc-yaml/i18n-fr.yaml +0 -48
  65. data/lib/isodoc-yaml/i18n-ru.yaml +0 -51
  66. data/lib/isodoc-yaml/i18n-zh-Hans.yaml +0 -40
  67. data/lib/relaton/render/fields/date.rb +0 -45
  68. data/lib/relaton/render/fields/fields.rb +0 -245
  69. data/lib/relaton/render/general/citations.rb +0 -96
  70. data/lib/relaton/render/general/config.yml +0 -79
  71. data/lib/relaton/render/general/render.rb +0 -185
  72. data/lib/relaton/render/general/render_classes.rb +0 -129
  73. data/lib/relaton/render/parse/parse.rb +0 -64
  74. data/lib/relaton/render/parse/parse_contributors.rb +0 -132
  75. data/lib/relaton/render/parse/parse_extract.rb +0 -180
  76. data/lib/relaton/render/template/liquid.rb +0 -15
  77. data/lib/relaton/render/template/template.rb +0 -188
  78. data/lib/relaton/render/utils/utils.rb +0 -27
@@ -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,31 @@
1
+ # ISO 690 name-and-date citation style, an instance of the relaton-models
2
+ # CitationStyle model. Templates place the ISO 690 clause 7 data elements
3
+ # ({{creator}}, {{title}}, ...) in each resource kind's clause 8 order; an
4
+ # absent element takes its trailing punctuation with it. A new style is a
5
+ # YAML instance — the engine holds no styles.
6
+ name: "ISO 690 (name and date)"
7
+ scheme:
8
+ system: name-date
9
+ nameForm:
10
+ initials: false
11
+ givenNameFirst: false
12
+ # ISO 690 marks an editor list's role ("(éd.)") also when the list
13
+ # holds a single editor; flavors opt out per their own style
14
+ loneEditorMarked: true
15
+ templates:
16
+ titleOpen: "_"
17
+ titleClose: "_"
18
+ citation: "{{surname}}, {{date}}{{disambiguator}}"
19
+ reference: "{{creator}}. {{title}}. {{medium}}. {{edition}}. {{series}}. {{production}}, {{date}}. {{identifier}}. {{location}}."
20
+ name: "{{surname}}, {{givenNames}}"
21
+ perType:
22
+ - type: monograph
23
+ template: "{{creator}}. {{title}}. {{edition}}. {{series}}. {{production}}, {{date}}. {{identifier}}. {{location}}."
24
+ - type: report
25
+ template: "{{creator}}. {{title}}. {{numeration}}. {{edition}}. {{series}}. {{production}}, {{date}}. {{identifier}}. {{location}}."
26
+ - type: patent
27
+ template: "{{creator}}. {{title}}. {{identifier}}. {{date}}."
28
+ - type: continuing
29
+ template: "{{creator}}. {{title}}. {{componentPart}}. {{medium}}. {{edition}}. {{production}}, {{date}}. {{numeration}}. {{identifier}}. {{location}}."
30
+ - type: online
31
+ template: "{{creator}}. {{title}}. {{date}}. {{identifier}}. {{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}}"
@@ -0,0 +1,248 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Relaton
4
+ module Render
5
+ module Iso690
6
+ # A citation template as declared in a style instance: literal text
7
+ # interleaved with {{slot}} placeholders resolved against the ISO 690
8
+ # data element inventory. A leading literal attaches to the first
9
+ # slot, and a literal between two slots to the preceding one, so an
10
+ # absent field never orphans punctuation around it. The last rendered
11
+ # slot gives up its trailing literal in favour of the template
12
+ # terminator, appended once when any field rendered and the output
13
+ # does not already end with it.
14
+ class Template
15
+ SLOT = /\{\{\s*([\w-]+)\s*\}\}/.freeze
16
+
17
+ Field = Struct.new(:present?, :text)
18
+
19
+ def initialize(source)
20
+ @chunks = []
21
+ @terminator = ""
22
+ scan(source.to_s)
23
+ end
24
+
25
+ # The short cite renders the reference with the first-biblio
26
+ # marker appended to its first component: isodoc's styled
27
+ # references (eref2linkshort) split there (the 1.x
28
+ # fmt-first-biblio-delim)
29
+ def evaluate_short(fields, delim)
30
+ present = present_indices(fields)
31
+ return "" if present.empty?
32
+
33
+ # The split marker follows the leading run of present slots
34
+ # (the 1.x first SEGMENT: "{{creator}}{{role}}" splits after
35
+ # the role), before the first literal that follows it
36
+ lead_slots = []
37
+ @chunks.each_with_index do |(kind, _value), i|
38
+ break if kind != :slot || !present.include?(i)
39
+
40
+ lead_slots << i
41
+ end
42
+ split_at = lead_slots.last ? lead_slots.last + 1 : nil
43
+
44
+ out = +""
45
+ @chunks.each_with_index do |(kind, value), i|
46
+ text =
47
+ case kind
48
+ when :slot
49
+ field = fields[normalise(value)]
50
+ next unless field&.present?
51
+
52
+ field.text
53
+ else
54
+ next unless bridged?(i, present)
55
+
56
+ value
57
+ end
58
+ if split_at == i
59
+ out << fieldless(lead_slots, fields) if false
60
+ out << delim.to_s
61
+ split_at = nil
62
+ end
63
+ out << text unless text.nil?
64
+ end
65
+ out << delim.to_s if split_at == @chunks.length
66
+ terminate(out).rstrip
67
+ end
68
+
69
+ # 1.x segment-join semantics: present elements joined with the
70
+ # template's separators — a literal renders only when it
71
+ # separates (a run of absent elements between) two present
72
+ # elements; leading and trailing literals drop with the
73
+ # elements they would have attached to
74
+ def evaluate(fields)
75
+ present = present_indices(fields)
76
+ return "" if present.empty?
77
+
78
+ out = +"".dup
79
+ # Parenthetical groups balance on the template's literal
80
+ # parens alone: data text (a series run "(N.S.)", a host
81
+ # creator's closing paren) carries parens of its own that
82
+ # are no part of the template's group structure
83
+ paren_balance = 0
84
+ @chunks.each_with_index do |(kind, value), i|
85
+ if kind == :slot
86
+ field = fields[normalise(value)]
87
+ out << field.text if field&.present?
88
+ elsif value.to_s.match?(/\A[))]/)
89
+ # Symmetric close: with no pending open the close-paren
90
+ # drops, and any trailing punctuation bridges normally
91
+ closes = value.to_s[/\A[))]+/]
92
+ emitted = [paren_balance, closes.size].min
93
+ if emitted.positive?
94
+ out << closes[0, emitted] +
95
+ value.to_s[closes.size..].to_s
96
+ paren_balance -= emitted
97
+ else
98
+ rest = value.to_s.sub(/\A[))]+/, "")
99
+ # the trailing separator of a dropped group bridges as
100
+ # though the group were never there
101
+ if !rest.empty? && present.any? { |j| j > i } &&
102
+ group_gap?(i, present)
103
+ out << rest
104
+ end
105
+ end
106
+ elsif value.to_s.match?(/[((]\z/)
107
+ # A literal opening a parenthetical group ("({{series}})",
108
+ # "。({{series}})") attaches its paren to the slot it
109
+ # opens — the pair drops with an absent element, while
110
+ # any leading punctuation bridges normally
111
+ lead, paren = value.to_s.match(/\A(.*)([((])\z/).captures
112
+ out << lead if bridged_text?(i, lead, present)
113
+ if present.include?(i + 1)
114
+ out << paren
115
+ paren_balance += 1
116
+ end
117
+ elsif bridged?(i, present) ||
118
+ (value.include?("<") && present.any? { |j| j < i })
119
+ # markup attaches to the element it closes
120
+ out << value
121
+ elsif close_pending_paren?(out, value)
122
+ out << value
123
+ end
124
+ end
125
+ terminate(out).rstrip
126
+ end
127
+
128
+ private
129
+
130
+ def scan(source)
131
+ rest = source
132
+ while (slot = SLOT.match(rest))
133
+ @chunks << [:text, rest[0...slot.begin(0)]] if
134
+ slot.begin(0).positive?
135
+ @chunks << [:slot, slot[1]]
136
+ rest = rest[slot.end(0)..]
137
+ end
138
+ @terminator = rest
139
+ end
140
+
141
+ def present_indices(fields)
142
+ @chunks.each_index.select do |i|
143
+ kind, value = @chunks[i]
144
+ next false unless kind == :slot
145
+
146
+ field = fields[normalise(value)]
147
+ !field.nil? && field.present?
148
+ end
149
+ end
150
+
151
+ # The texts between this close and the last present slot are
152
+ # all parenthetical-group parts (each dropped or partial)
153
+ def group_gap?(index, present)
154
+ left = present.select { |i| i < index }.max
155
+ @chunks[(left + 1)...index].all? do |(_, text)|
156
+ text.to_s.match?(/\A[))]|[((]\z/)
157
+ end
158
+ end
159
+
160
+ # The leading punctuation of a paren-opening literal bridges
161
+ # per the segment-join rule (a bare paren has no lead)
162
+ def bridged_text?(index, lead, present)
163
+ return true if lead.empty?
164
+
165
+ first_slot = @chunks.index { |(kind, _)| kind == :slot }
166
+ return present.include?(first_slot) if index < first_slot
167
+
168
+ left = present.select { |i| i < index }.max
169
+ left && present.any? { |i| i > index } &&
170
+ !@chunks[(left + 1)...index].any? do |(kind, _)|
171
+ kind == :text
172
+ end
173
+ end
174
+
175
+ # A literal is the trailing separator of the element that
176
+ # precedes it: it renders when that element renders and a
177
+ # later element renders, and it is the FIRST literal of its
178
+ # gap (the 1.x segment join — absent elements between two
179
+ # present ones leave the single separator that follows the
180
+ # earlier present element; an absent slot directly before a
181
+ # present one, as "{{date}}{{disambiguator}}, {{access}}",
182
+ # does not swallow it). A leading literal (no slot precedes
183
+ # it) attaches to the first slot, emitting only when that
184
+ # slot is present.
185
+ def bridged?(index, present)
186
+ first_slot = @chunks.index { |(kind, _)| kind == :slot }
187
+ return present.include?(first_slot) if index < first_slot
188
+
189
+ left = present.select { |i| i < index }.max
190
+ left && present.any? { |i| i > index } &&
191
+ !@chunks[(left + 1)...index].any? do |(kind, _)|
192
+ kind == :text
193
+ end
194
+ end
195
+
196
+ # A template's paired literal ("({{production}})") closes even
197
+ # when nothing follows the present element it wraps. Fullwidth
198
+ # parens (CJK) pair the same way
199
+ def close_pending_paren?(out, value)
200
+ return false unless value.start_with?(")", "\uFF09")
201
+
202
+ opens = out.count("(") + out.count("\uFF08")
203
+ closes = out.count(")") + out.count("\uFF09")
204
+ opens > closes
205
+ end
206
+
207
+ def terminate(body)
208
+ # 1.x punctuation cleanup: a sentence period before a spaced
209
+ # comma yields to the comma (", 2013" over ". , 2013"; an
210
+ # initials period before a comma ("P.,") stands, being
211
+ # unspaced), and stacked separators around absent elements
212
+ # collapse into one (". : ." into ". "); an empty pair left
213
+ # by an absent element drops
214
+ body = body.gsub(/:\s*\.\s*/, ": ")
215
+ body = body.gsub(/\.\s+,/, ",")
216
+ body = body.gsub(/(?:[.,:;]\s+)+[.,:;]/, ". ")
217
+ body = body.gsub(/\.\s*\./, ". ")
218
+ body = body.gsub(/:\s*\.\s*/, ": ")
219
+ body = body.gsub(/\(\s*\)/, "")
220
+ body = body.gsub(/ +/, " ").gsub(" ,", ",")
221
+ terminator = unbalanced_close(body, @terminator)
222
+ return body if terminator.strip.empty?
223
+ if terminator !~ /[<\w]/ && body.rstrip.end_with?(terminator.strip)
224
+ return body
225
+ end
226
+
227
+ "#{body}#{terminator}"
228
+ end
229
+
230
+ # The terminator's closing parens stand only when the body
231
+ # opened them (their "(" died with an absent element)
232
+ def unbalanced_close(body, terminator)
233
+ return terminator unless terminator.start_with?(")")
234
+
235
+ open = body.count("(") - body.count(")")
236
+ return terminator.sub(/\A\)+/) { |closes| closes[0, open] } if
237
+ open.positive?
238
+
239
+ terminator.sub(/\A\)+/, "")
240
+ end
241
+
242
+ def normalise(slot)
243
+ slot.to_s.delete("_").downcase
244
+ end
245
+ end
246
+ end
247
+ end
248
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Relaton
4
+ module Render
5
+ # Citation rendering per the ISO 690 architecture: a style instance
6
+ # places the inventory's data elements (clause 7) in each resource
7
+ # kind's order (clause 8); the engine is a template evaluator over a
8
+ # field resolver and holds no styles, no vocabularies, no i18n.
9
+ # The v1 compatibility facade (relaton-render#90): isodoc's
10
+ # render-isodoc subclasses Relaton::Render::General.
11
+ autoload :General, "relaton/render/general"
12
+
13
+ module Iso690
14
+ autoload :Element, "relaton/render/iso690/element"
15
+ autoload :Elements, "relaton/render/iso690/elements"
16
+ autoload :Fields, "relaton/render/iso690/fields"
17
+ autoload :I18n, "relaton/render/iso690/i18n"
18
+ autoload :IndexRenderer, "relaton/render/iso690/index_renderer"
19
+ autoload :IdentifierKinds, "relaton/render/iso690/identifier_kinds"
20
+ autoload :Kinds, "relaton/render/iso690/kinds"
21
+ autoload :Renderer, "relaton/render/iso690/renderer"
22
+ autoload :Rules, "relaton/render/iso690/rules"
23
+ autoload :Style, "relaton/render/iso690/style"
24
+ autoload :Template, "relaton/render/iso690/template"
25
+ end
26
+ end
27
+ end
@@ -1,5 +1,5 @@
1
1
  module Relaton
2
2
  module Render
3
- VERSION = "0.4.2".freeze
3
+ VERSION = "3.0.0.pre.alpha.26".freeze
4
4
  end
5
5
  end
@@ -1,7 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "relaton/render/version"
2
- require "relaton/render/general/render"
3
- require "relaton/render/fields/fields"
4
- require "relaton/render/parse/parse"
5
- require "relaton/render/utils/utils"
6
- require "isodoc/i18n"
4
+ require "relaton/render/iso690"
5
+
6
+ module Relaton
7
+ module Render
8
+ # A bibliographic item whose style template resolves to nothing: the
9
+ # single-item API raises, the batch API skips
10
+ class Unrenderable < StandardError; end
7
11
 
12
+ end
13
+ end
@@ -19,20 +19,13 @@ Gem::Specification.new do |spec|
19
19
  spec.bindir = "exe"
20
20
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
21
  spec.require_paths = ["lib"]
22
- spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
22
+ spec.required_ruby_version = Gem::Requirement.new(">= 3.3.0")
23
23
 
24
- spec.add_development_dependency "bundler"
25
- spec.add_development_dependency "debug"
26
- spec.add_development_dependency "equivalent-xml", "~> 0.6"
27
- spec.add_development_dependency "rake", ">= 12.3.3"
28
- spec.add_development_dependency "rspec", "~> 3.0"
29
- spec.add_development_dependency "simplecov"
30
-
31
- spec.add_dependency "isodoc-i18n"
32
- spec.add_dependency "liquid", "~> 4"
24
+ spec.add_dependency "htmlentities"
25
+ spec.add_development_dependency "relaton-bib"
26
+ spec.add_dependency "liquid", "~> 5"
27
+ spec.add_dependency "lutaml-model"
33
28
  spec.add_dependency "nokogiri"
34
- spec.add_dependency "relaton-bib", ">= 1.12.0"
35
29
  spec.add_dependency "twitter_cldr"
36
- spec.add_dependency "tzinfo-data" # we need this for windows only
37
- #spec.metadata["rubygems_mfa_required"] = "true"
30
+ # spec.metadata["rubygems_mfa_required"] = "true"
38
31
  end