relaton-render 1.3.0 → 1.4.0.pre.alpha.2

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 (53) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +15 -2
  3. data/lib/relaton/render/general.rb +51 -0
  4. data/lib/relaton/render/iso690/element.rb +43 -0
  5. data/lib/relaton/render/iso690/elements/component_part.rb +50 -0
  6. data/lib/relaton/render/iso690/elements/creator.rb +129 -0
  7. data/lib/relaton/render/iso690/elements/edition.rb +47 -0
  8. data/lib/relaton/render/iso690/elements/identifier.rb +32 -0
  9. data/lib/relaton/render/iso690/elements/location.rb +27 -0
  10. data/lib/relaton/render/iso690/elements/medium.rb +27 -0
  11. data/lib/relaton/render/iso690/elements/numeration.rb +26 -0
  12. data/lib/relaton/render/iso690/elements/production.rb +36 -0
  13. data/lib/relaton/render/iso690/elements/pub_date.rb +51 -0
  14. data/lib/relaton/render/iso690/elements/series.rb +40 -0
  15. data/lib/relaton/render/iso690/elements/title.rb +30 -0
  16. data/lib/relaton/render/iso690/elements.rb +40 -0
  17. data/lib/relaton/render/iso690/fields.rb +53 -0
  18. data/lib/relaton/render/iso690/i18n/en.yml +13 -0
  19. data/lib/relaton/render/iso690/i18n/fr.yml +14 -0
  20. data/lib/relaton/render/iso690/i18n.rb +66 -0
  21. data/lib/relaton/render/iso690/identifier_kinds.rb +34 -0
  22. data/lib/relaton/render/iso690/index_renderer.rb +57 -0
  23. data/lib/relaton/render/iso690/kinds.rb +43 -0
  24. data/lib/relaton/render/iso690/renderer.rb +54 -0
  25. data/lib/relaton/render/iso690/style/locale.rb +44 -0
  26. data/lib/relaton/render/iso690/style/name_form.rb +21 -0
  27. data/lib/relaton/render/iso690/style/scheme.rb +23 -0
  28. data/lib/relaton/render/iso690/style/sort_rule.rb +25 -0
  29. data/lib/relaton/render/iso690/style/template_map.rb +28 -0
  30. data/lib/relaton/render/iso690/style/type_template.rb +21 -0
  31. data/lib/relaton/render/iso690/style.rb +78 -0
  32. data/lib/relaton/render/iso690/styles/author-date.yml +28 -0
  33. data/lib/relaton/render/iso690/template.rb +72 -0
  34. data/lib/relaton/render/iso690.rb +26 -0
  35. data/lib/relaton/render/version.rb +1 -1
  36. data/lib/relaton-render.rb +3 -7
  37. data/relaton-render.gemspec +2 -19
  38. metadata +36 -249
  39. data/lib/relaton/render/fields/date.rb +0 -48
  40. data/lib/relaton/render/fields/fields.rb +0 -266
  41. data/lib/relaton/render/general/citations.rb +0 -178
  42. data/lib/relaton/render/general/config.yml +0 -129
  43. data/lib/relaton/render/general/render.rb +0 -316
  44. data/lib/relaton/render/general/render_classes.rb +0 -132
  45. data/lib/relaton/render/general/uri.rb +0 -57
  46. data/lib/relaton/render/i18n/i18n.rb +0 -40
  47. data/lib/relaton/render/parse/parse.rb +0 -152
  48. data/lib/relaton/render/parse/parse_contributors.rb +0 -184
  49. data/lib/relaton/render/parse/parse_extract.rb +0 -200
  50. data/lib/relaton/render/parse/parse_id.rb +0 -128
  51. data/lib/relaton/render/template/liquid.rb +0 -48
  52. data/lib/relaton/render/template/subclasses.rb +0 -123
  53. data/lib/relaton/render/template/template.rb +0 -228
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Relaton
4
+ module Render
5
+ module Iso690
6
+ # Field resolver: builds the template evaluator's field table from a
7
+ # relaton model instance. Slots resolve to ISO 690 clause 7 data
8
+ # elements, to name-form fields of the principal creator, or to the
9
+ # disambiguator supplied by the citation caller.
10
+ class Fields
11
+ ELEMENT_SLOTS = %i[
12
+ creator title edition medium series production
13
+ date numeration component_part identifier location
14
+ ].freeze
15
+
16
+ def initialize(model, style:, i18n:, disambiguator: nil)
17
+ @model = model
18
+ @style = style
19
+ @i18n = i18n
20
+ @disambiguator = disambiguator.to_s
21
+ end
22
+
23
+ def to_h
24
+ table = {}
25
+ ELEMENT_SLOTS.each do |slot|
26
+ key = slot.to_s.delete("_").downcase
27
+ table[key] = element_field(slot)
28
+ end
29
+ table.merge(name_fields)
30
+ end
31
+
32
+ private
33
+
34
+ def element_field(slot)
35
+ element = Elements.build(slot, @model, style: @style, i18n: @i18n)
36
+ text = element.render.to_s
37
+ Template::Field[element.present? && !text.empty?, text]
38
+ end
39
+
40
+ def name_fields
41
+ creator = Elements.build(:creator, @model, style: @style, i18n: @i18n)
42
+ {
43
+ "surname" => Template::Field[creator.present?, creator.in_text],
44
+ "givennames" => Template::Field[!creator.principal_given.empty?,
45
+ creator.principal_given],
46
+ "disambiguator" => Template::Field[!@disambiguator.empty?,
47
+ @disambiguator],
48
+ }
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,13 @@
1
+ lang: en
2
+ labels:
3
+ edition: "ed"
4
+ series_no: "no."
5
+ report_no: "Report no."
6
+ available_from: "Available from:"
7
+ in: "In:"
8
+ and: "and"
9
+ oxford_comma: ","
10
+ ed: "ed."
11
+ eds: "eds."
12
+ date_range: "–"
13
+ punct: {}
@@ -0,0 +1,14 @@
1
+ lang: fr
2
+ labels:
3
+ edition: "éd"
4
+ series_no: "n°"
5
+ report_no: "Rapport no."
6
+ available_from: "Disponible sur :"
7
+ in: "Dans :"
8
+ and: "et"
9
+ oxford_comma: ""
10
+ ed: "éd."
11
+ eds: "éd."
12
+ date_range: "–"
13
+ punct:
14
+ production_sep: " : "
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "lutaml/model"
4
+
5
+ module Relaton
6
+ module Render
7
+ module Iso690
8
+ # Language-specific labels and typographic punctuation, declared per
9
+ # language in i18n/<lang>.yml. Adding a language adds a YAML
10
+ # declaration — no code. A style instance's localized strings overlay
11
+ # the language pack; language-varying intra-element punctuation
12
+ # (e.g. French " : " production separator) is declared under
13
+ # `punct:`.
14
+ class I18n < Lutaml::Model::Serializable
15
+ attribute :lang, :string, default: "en"
16
+ attribute :labels, :hash, default: {}
17
+ attribute :punct, :hash, default: {}
18
+
19
+ key_value do
20
+ map "lang", to: :lang
21
+ map "labels", to: :labels
22
+ map "punct", to: :punct
23
+ end
24
+
25
+ def label(key)
26
+ labels.fetch(key.to_s, key.to_s)
27
+ end
28
+
29
+ def punct_fetch(key, default)
30
+ punct.fetch(key, default)
31
+ end
32
+
33
+ # Style-instance localized strings win over the language pack.
34
+ def overlay!(locale)
35
+ labels.merge!(locale.label_map)
36
+ self
37
+ end
38
+
39
+ # Runtime label overrides (a caller's i18n hash): the pack's label
40
+ # names win as the key mapping; unknown keys are ignored.
41
+ def overlay_hash!(hash)
42
+ known = %w[
43
+ edition series_no report_no available_from in and oxford_comma
44
+ ed eds date_range others no_date no_author at
45
+ ]
46
+ hash.each do |key, value|
47
+ labels[key.to_s] = value if known.include?(key.to_s) && !value.nil?
48
+ end
49
+ self
50
+ end
51
+
52
+ class << self
53
+ def load(lang = "en")
54
+ code = lang.to_s.empty? ? "en" : lang
55
+ path = File.join(__dir__, "i18n", "#{code}.yml")
56
+ unless File.file?(path)
57
+ raise ArgumentError, "no i18n declarations for language #{code}"
58
+ end
59
+
60
+ from_yaml(File.read(path))
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Relaton
4
+ module Render
5
+ module Iso690
6
+ # Standard and persistent identifiers (ISO 690 clause 7.11): each
7
+ # identifier kind carries its own rendering method. Kinds are keyed by
8
+ # the docidentifier's type attribute — never guessed from content.
9
+ # Flavors register additional kinds (e.g. Pubid::Iala's MRN).
10
+ module IdentifierKinds
11
+ KINDS = {
12
+ "DOI" => ->(content) { "https://doi.org/#{content}" },
13
+ "ISBN" => ->(content) { "ISBN #{content}" },
14
+ "ISSN" => ->(content) { "ISSN #{content}" },
15
+ "URN" => ->(content) { content },
16
+ "MRN" => ->(content) { content },
17
+ }.freeze
18
+
19
+ class << self
20
+ def register(type, kind)
21
+ KINDS[type] = kind
22
+ kind
23
+ end
24
+
25
+ def render(docidentifier)
26
+ content = docidentifier.content.to_s
27
+ kind = KINDS[docidentifier.type]
28
+ kind ? kind.call(content) : content
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Relaton
4
+ module Render
5
+ module Iso690
6
+ # A bibliographic index: the ordered reference list, laid out per the
7
+ # BibliographicStyle instance. Sorting follows the style's declared
8
+ # sortKey rules (creator, then date); numbering is layout data.
9
+ class IndexRenderer
10
+ def initialize(style: "author-date", lang: "en", script: "Latn")
11
+ @style = Style.load(style)
12
+ @i18n = I18n.load(lang).overlay!(@style.scheme.locale)
13
+ @renderer = Renderer.new(style: style, lang: lang, script: script)
14
+ end
15
+
16
+ # The reference strings, sorted per the style's sortKey rules.
17
+ def references(models)
18
+ sort_rules = @style.sort_keys
19
+ fields = models.to_h { |m| [m, field_table(m)] }
20
+ models.sort do |a, b|
21
+ fa = fields[a]
22
+ fb = fields[b]
23
+ sort_rules.each do |rule|
24
+ cmp = key_of(fa, rule) <=> key_of(fb, rule)
25
+ next if cmp.zero?
26
+
27
+ break(rule.descending? ? -cmp : cmp)
28
+ end || 0
29
+ end.map { |model| @renderer.render(model) }
30
+ end
31
+
32
+ # The laid-out index: numbered entries per the layout rules
33
+ # (arabic by default; "none" renders bare references).
34
+ def render(models, numbering: "arabic")
35
+ refs = references(models)
36
+ return refs if numbering == "none"
37
+
38
+ refs.each_with_index.map { |ref, i| "#{i + 1}. #{ref}" }
39
+ end
40
+
41
+ private
42
+
43
+ def field_table(model)
44
+ Fields.new(model, style: @style, i18n: @i18n).to_h
45
+ end
46
+
47
+ def key_of(fields, rule)
48
+ field = fields[rule.attribute.to_s.delete("_").downcase]
49
+ return "" if field.nil?
50
+
51
+ text = field.respond_to?(:text) ? field.text : field.to_s
52
+ text.downcase
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Relaton
4
+ module Render
5
+ module Iso690
6
+ # The vocabulary mapping from a bibliographic item's wire type value
7
+ # to its ISO 690 clause 8 resource kind (TemplateType). This table is
8
+ # the engine's charter — style instances select perType templates on
9
+ # kinds and never enumerate type synonyms. Unmapped values fall to
10
+ # the report kind (clause 8.11), the runner's fallback.
11
+ module Kinds
12
+ TO_KIND = {
13
+ "book" => "monograph",
14
+ "booklet" => "monograph",
15
+ "manual" => "monograph",
16
+ "proceedings" => "monograph",
17
+ "thesis" => "monograph",
18
+ "standard" => "report",
19
+ "techreport" => "report",
20
+ "report" => "report",
21
+ "patent" => "patent",
22
+ "journal" => "continuing",
23
+ "serial" => "continuing",
24
+ "article-journal" => "continuing",
25
+ "article-magazine" => "continuing",
26
+ "inbook" => "component_part",
27
+ "incollection" => "component_part",
28
+ "inproceedings" => "component_part",
29
+ "website" => "online",
30
+ "webresource" => "online",
31
+ "webpage" => "online",
32
+ "online" => "online",
33
+ }.freeze
34
+
35
+ DEFAULT_KIND = "report"
36
+
37
+ def self.kind_for(type)
38
+ TO_KIND.fetch(type.to_s, DEFAULT_KIND)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Relaton
4
+ module Render
5
+ module Iso690
6
+ # Public API: relaton model in, citation string out. The style
7
+ # instance supplies every rendering decision; this class only wires
8
+ # the template evaluator to the field resolver. No XML, no
9
+ # intermediate hashes.
10
+ class Renderer
11
+ class Unrenderable < StandardError; end
12
+
13
+ DEFAULT_STYLE = "author-date"
14
+
15
+ class << self
16
+ def render(model, style: DEFAULT_STYLE, lang: "en", script: "Latn")
17
+ new(style: style, lang: lang, script: script).render(model)
18
+ end
19
+
20
+ def citation(model, disambiguator: nil, style: DEFAULT_STYLE,
21
+ lang: "en", script: "Latn")
22
+ new(style: style, lang: lang, script: script)
23
+ .citation(model, disambiguator: disambiguator)
24
+ end
25
+ end
26
+
27
+ def initialize(style: DEFAULT_STYLE, lang: "en", script: "Latn",
28
+ labels: {})
29
+ @style = Style.load(style)
30
+ @i18n = I18n.load(lang).overlay!(@style.scheme.locale)
31
+ @i18n.overlay_hash!(labels) unless labels.empty?
32
+ @script = script
33
+ end
34
+
35
+ def render(model)
36
+ out = Template.new(@style.template_for(Kinds.kind_for(model.type))).evaluate(
37
+ Fields.new(model, style: @style, i18n: @i18n).to_h,
38
+ )
39
+ raise Unrenderable, "no renderable elements" if out.strip.empty?
40
+
41
+ out
42
+ end
43
+
44
+ # In-text form: SURNAME, year + disambiguator (name-and-date)
45
+ def citation(model, disambiguator: nil)
46
+ Template.new(@style.templates.citation).evaluate(
47
+ Fields.new(model, style: @style, i18n: @i18n,
48
+ disambiguator: disambiguator).to_h,
49
+ )
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Relaton
4
+ module Render
5
+ module Iso690
6
+ class Style
7
+ # LocalizedStrings: per-style overrides of the language pack's
8
+ # connective strings, keyed as in the CitationStyle model.
9
+ class Locale < Lutaml::Model::Serializable
10
+ attribute :conj, :string
11
+ attribute :others, :string
12
+ attribute :no_date, :string
13
+ attribute :no_author, :string
14
+ attribute :in_str, :string
15
+ attribute :at, :string
16
+ attribute :available_at, :string
17
+
18
+ key_value do
19
+ map "and", to: :conj
20
+ map "others", to: :others
21
+ map "noDate", to: :no_date
22
+ map "noAuthor", to: :no_author
23
+ map "in", to: :in_str
24
+ map "at", to: :at
25
+ map "availableAt", to: :available_at
26
+ end
27
+
28
+ LABEL_FOR = {
29
+ "conj" => "and", "others" => "others", "no_date" => "no_date",
30
+ "no_author" => "no_author", "in_str" => "in", "at" => "at",
31
+ "available_at" => "available_from",
32
+ }.freeze
33
+
34
+ def label_map
35
+ LABEL_FOR.filter_map do |attr, label|
36
+ value = public_send(attr)
37
+ [label, value] unless value.nil?
38
+ end.to_h
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Relaton
4
+ module Render
5
+ module Iso690
6
+ class Style
7
+ # How personal names are formed, as declared by the style's
8
+ # citation scheme (relaton-models NameFormRules).
9
+ class NameForm < Lutaml::Model::Serializable
10
+ attribute :initials, :boolean, default: -> { false }
11
+ attribute :given_name_first, :boolean, default: -> { false }
12
+
13
+ key_value do
14
+ map "initials", to: :initials
15
+ map "givenNameFirst", to: :given_name_first
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Relaton
4
+ module Render
5
+ module Iso690
6
+ class Style
7
+ # CitationScheme: the citation system, its name form and its
8
+ # localized strings (relaton-models CitationScheme).
9
+ class Scheme < Lutaml::Model::Serializable
10
+ attribute :system, :string, default: "name-date"
11
+ attribute :name_form, NameForm, default: -> { NameForm.new }
12
+ attribute :locale, Locale, default: -> { Locale.new }
13
+
14
+ key_value do
15
+ map "system", to: :system
16
+ map "nameForm", to: :name_form
17
+ map "locale", to: :locale
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Relaton
4
+ module Render
5
+ module Iso690
6
+ class Style
7
+ # SortRule: one ordering key of a bibliographic index sort
8
+ # (relaton-models SortRule).
9
+ class SortRule < Lutaml::Model::Serializable
10
+ attribute :attribute, :string
11
+ attribute :order, :string
12
+
13
+ key_value do
14
+ map "attribute", to: :attribute
15
+ map "order", to: :order
16
+ end
17
+
18
+ def descending?
19
+ order == "descending"
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Relaton
4
+ module Render
5
+ module Iso690
6
+ class Style
7
+ # TemplateMap: citation and reference templates as data, plus the
8
+ # title emphasis markers and the first-creator name form. Slots
9
+ # name ISO 690 clause 7 data elements or name-form fields.
10
+ class TemplateMap < Lutaml::Model::Serializable
11
+ attribute :title_open, :string, default: "_"
12
+ attribute :title_close, :string, default: "_"
13
+ attribute :citation, :string, default: "{{surname}}, {{date}}"
14
+ attribute :reference, :string
15
+ attribute :name, :string, default: "{{surname}}, {{givenNames}}"
16
+
17
+ key_value do
18
+ map "titleOpen", to: :title_open
19
+ map "titleClose", to: :title_close
20
+ map "citation", to: :citation
21
+ map "reference", to: :reference
22
+ map "name", to: :name
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Relaton
4
+ module Render
5
+ module Iso690
6
+ class Style
7
+ # TypeTemplate: the template variant for one bibliographic item
8
+ # type, selected by data lookup (relaton-models TypeTemplate).
9
+ class TypeTemplate < Lutaml::Model::Serializable
10
+ attribute :type, :string
11
+ attribute :template, :string
12
+
13
+ key_value do
14
+ map "type", to: :type
15
+ map "template", to: :template
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "lutaml/model"
4
+
5
+ module Relaton
6
+ module Render
7
+ module Iso690
8
+ # A citation style as an instance of the relaton-models CitationStyle
9
+ # model: the citation scheme (name form, localized strings), the
10
+ # citation and reference templates, and per-type template variants.
11
+ # All rendering knowledge is data; the engine holds no styles, no
12
+ # vocabularies, no localized strings.
13
+ class Style < Lutaml::Model::Serializable
14
+ autoload :NameForm, "relaton/render/iso690/style/name_form"
15
+ autoload :Locale, "relaton/render/iso690/style/locale"
16
+ autoload :Scheme, "relaton/render/iso690/style/scheme"
17
+ autoload :TemplateMap, "relaton/render/iso690/style/template_map"
18
+ autoload :SortRule, "relaton/render/iso690/style/sort_rule"
19
+ autoload :TypeTemplate, "relaton/render/iso690/style/type_template"
20
+
21
+ attribute :name, :string
22
+ attribute :scheme, Scheme, default: -> { Scheme.new }
23
+ attribute :templates, TemplateMap, default: -> { TemplateMap.new }
24
+ attribute :per_type, TypeTemplate, collection: true, default: []
25
+ attribute :sort_key, SortRule, collection: true, default: []
26
+
27
+ key_value do
28
+ map "name", to: :name
29
+ map "scheme", to: :scheme
30
+ map "templates", to: :templates
31
+ map "perType", to: :per_type
32
+ map "sortKey", to: :sort_key
33
+ end
34
+
35
+ # The index sort rules; creator then date when the style declares
36
+ # none (the name-and-date default).
37
+ def sort_keys
38
+ return sort_key unless sort_key.empty?
39
+
40
+ [SortRule.new(attribute: "creator"), SortRule.new(attribute: "date")]
41
+ end
42
+
43
+ # Per-type template selection is a data lookup; unmatched types
44
+ # fall back to the general reference template.
45
+ def template_for(type)
46
+ per_type.find { |t| t.type == type.to_s }&.template ||
47
+ templates.reference
48
+ end
49
+
50
+ # First-creator name form: the style's declared name template with
51
+ # the surname upcased, per the name-and-date convention.
52
+ def render_name(surname:, given:)
53
+ Template.new(templates.name).evaluate(
54
+ "surname" => Template::Field[!surname.empty?, surname.upcase],
55
+ "givennames" => Template::Field[!given.empty?, given],
56
+ )
57
+ end
58
+
59
+ class << self
60
+ def load(name_or_path)
61
+ path = style_path(name_or_path) or
62
+ raise ArgumentError, "unknown style #{name_or_path}"
63
+ from_yaml(File.read(path))
64
+ end
65
+
66
+ private
67
+
68
+ def style_path(name)
69
+ file = File.join(__dir__, "styles", "#{name}.yml")
70
+ return file if File.file?(file)
71
+
72
+ name if name.is_a?(String) && File.file?(name)
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,28 @@
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
+ templates:
13
+ titleOpen: "_"
14
+ titleClose: "_"
15
+ citation: "{{surname}}, {{date}}{{disambiguator}}"
16
+ reference: "{{creator}}. {{title}}. {{medium}}. {{edition}}. {{series}}. {{production}}, {{date}}. {{identifier}}. {{location}}."
17
+ name: "{{surname}}, {{givenNames}}"
18
+ perType:
19
+ - type: monograph
20
+ template: "{{creator}}. {{title}}. {{edition}}. {{series}}. {{production}}, {{date}}. {{identifier}}. {{location}}."
21
+ - type: report
22
+ template: "{{creator}}. {{title}}. {{numeration}}. {{edition}}. {{series}}. {{production}}, {{date}}. {{identifier}}. {{location}}."
23
+ - type: patent
24
+ template: "{{creator}}. {{title}}. {{identifier}}. {{date}}."
25
+ - type: continuing
26
+ template: "{{creator}}. {{title}}. {{componentPart}}. {{medium}}. {{edition}}. {{production}}, {{date}}. {{numeration}}. {{identifier}}. {{location}}."
27
+ - type: online
28
+ template: "{{creator}}. {{title}}. {{date}}. {{identifier}}. {{location}}."