isodoc 2.0.8 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/isodoc.gemspec +4 -2
  3. data/lib/isodoc/convert.rb +13 -5
  4. data/lib/isodoc/css.rb +11 -10
  5. data/lib/isodoc/function/blocks.rb +0 -39
  6. data/lib/isodoc/function/blocks_example_note.rb +36 -1
  7. data/lib/isodoc/function/inline.rb +4 -0
  8. data/lib/isodoc/function/references.rb +4 -17
  9. data/lib/isodoc/function/section.rb +5 -0
  10. data/lib/isodoc/function/to_word_html.rb +7 -11
  11. data/lib/isodoc/html_function/postprocess.rb +16 -2
  12. data/lib/isodoc/metadata.rb +2 -1
  13. data/lib/isodoc/presentation_function/bibdata.rb +50 -4
  14. data/lib/isodoc/presentation_function/block.rb +13 -1
  15. data/lib/isodoc/presentation_function/section.rb +38 -2
  16. data/lib/isodoc/presentation_xml_convert.rb +7 -2
  17. data/lib/isodoc/version.rb +1 -1
  18. data/lib/isodoc/word_function/postprocess.rb +4 -4
  19. data/lib/isodoc/word_function/postprocess_cover.rb +14 -0
  20. data/lib/isodoc/word_function/table.rb +12 -10
  21. data/lib/isodoc/xref/xref_anchor.rb +1 -1
  22. data/lib/isodoc/xref/xref_counter.rb +4 -1
  23. data/lib/isodoc/xref/xref_gen_seq.rb +3 -3
  24. data/lib/isodoc/xref/xref_sect_gen.rb +34 -36
  25. data/lib/isodoc/xref.rb +19 -8
  26. data/lib/isodoc-yaml/i18n-ar.yaml +9 -0
  27. data/lib/isodoc-yaml/i18n-de.yaml +13 -0
  28. data/lib/isodoc-yaml/i18n-en.yaml +5 -0
  29. data/lib/isodoc-yaml/i18n-es.yaml +11 -0
  30. data/lib/isodoc-yaml/i18n-fr.yaml +12 -1
  31. data/lib/isodoc-yaml/i18n-ru.yaml +13 -0
  32. data/lib/isodoc-yaml/i18n-zh-Hans.yaml +5 -0
  33. data/lib/relaton/render/config.yml +4 -0
  34. data/lib/relaton/render/general.rb +35 -0
  35. data/spec/assets/i18n.yaml +6 -0
  36. data/spec/isodoc/blocks_spec.rb +249 -62
  37. data/spec/isodoc/i18n_spec.rb +266 -197
  38. data/spec/isodoc/inline_spec.rb +81 -107
  39. data/spec/isodoc/metadata_spec.rb +5 -3
  40. data/spec/isodoc/postproc_spec.rb +539 -397
  41. data/spec/isodoc/presentation_xml_spec.rb +107 -0
  42. data/spec/isodoc/ref_spec.rb +142 -92
  43. data/spec/isodoc/section_spec.rb +4 -4
  44. data/spec/isodoc/xref_numbering_spec.rb +31 -0
  45. data/spec/isodoc/xref_spec.rb +106 -106
  46. metadata +24 -8
@@ -2,8 +2,8 @@ module IsoDoc::WordFunction
2
2
  module Body
3
3
  def remove_bottom_border(td)
4
4
  td["style"] =
5
- td["style"].gsub(/border-bottom:[^;]+;/, "border-bottom:0pt;").
6
- gsub(/mso-border-bottom-alt:[^;]+;/, "mso-border-bottom-alt:0pt;")
5
+ td["style"].gsub(/border-bottom:[^;]+;/, "border-bottom:0pt;")
6
+ .gsub(/mso-border-bottom-alt:[^;]+;/, "mso-border-bottom-alt:0pt;")
7
7
  end
8
8
 
9
9
  SW1 = "solid windowtext".freeze
@@ -15,7 +15,7 @@ module IsoDoc::WordFunction
15
15
  cols += (td["colspan"] ? td["colspan"].to_i : 1)
16
16
  end
17
17
  style = "border-top:0pt;mso-border-top-alt:0pt;"\
18
- "border-bottom:#{SW1} 1.5pt;mso-border-bottom-alt:#{SW1} 1.5pt;"
18
+ "border-bottom:#{SW1} 1.5pt;mso-border-bottom-alt:#{SW1} 1.5pt;"
19
19
  tfoot.add_child("<tr><td colspan='#{cols}' style='#{style}'/></tr>")
20
20
  tfoot.xpath(".//td").last
21
21
  end
@@ -34,13 +34,15 @@ module IsoDoc::WordFunction
34
34
  end
35
35
 
36
36
  def table_attrs(node)
37
- super.merge(attr_code({
38
- summary: node["summary"],
39
- width: node["width"],
40
- style: "mso-table-anchor-horizontal:column;"\
41
- "mso-table-overlap:never;border-spacing:0;border-width:1px;#{keep_style(node)}",
42
- class: (node.text.length > 4000 ? "MsoISOTableBig" : "MsoISOTable")
43
- }))
37
+ super.merge(attr_code(
38
+ {
39
+ summary: node["summary"],
40
+ width: node["width"],
41
+ style: "mso-table-anchor-horizontal:column;"\
42
+ "mso-table-overlap:never;border-spacing:0;border-width:1px;#{keep_style(node)}",
43
+ class: (node.text.length > 4000 ? "MsoISOTableBig" : "MsoISOTable"),
44
+ },
45
+ ))
44
46
  end
45
47
 
46
48
  def colgroup(node, t)
@@ -3,7 +3,7 @@ require "singleton"
3
3
  module IsoDoc
4
4
  module XrefGen
5
5
  module Anchor
6
- class Seen_Anchor
6
+ class SeenAnchor
7
7
  include Singleton
8
8
 
9
9
  def initialize
@@ -4,6 +4,7 @@ module IsoDoc
4
4
  module XrefGen
5
5
  class Counter
6
6
  def initialize(num = 0, opts = { numerals: :arabic })
7
+ @unnumbered = false
7
8
  @num = num
8
9
  @letter = ""
9
10
  @subseq = ""
@@ -112,7 +113,7 @@ module IsoDoc
112
113
  end
113
114
 
114
115
  def increment(node)
115
- return self if node["unnumbered"]
116
+ @unnumbered = (node["unnumbered"] || node["hidden"]) and return self
116
117
 
117
118
  @letter_override = nil
118
119
  @number_override = nil
@@ -126,6 +127,8 @@ module IsoDoc
126
127
  end
127
128
 
128
129
  def print
130
+ return nil if @unnumbered
131
+
129
132
  num = @number_override || @num
130
133
  out = @style == :roman && !num.nil? ? RomanNumerals.to_roman(num) : num
131
134
  "#{@base}#{out}#{@letter_override || @letter}"
@@ -25,11 +25,11 @@ module IsoDoc
25
25
  j = 0
26
26
  clause.xpath(ns(".//figure | .//sourcecode[not(ancestor::example)]"))
27
27
  .each do |t|
28
- # next if labelled_ancestor(t) && t.ancestors("figure").empty?
28
+ next if blank?(t["id"])
29
29
 
30
30
  j = subfigure_increment(j, c, t)
31
- label = c.print + (j.zero? ? "" : "-#{j}")
32
- next if t["id"].nil? || t["id"].empty?
31
+ label = c.print
32
+ label &&= label + (j.zero? ? "" : "-#{j}")
33
33
 
34
34
  @anchors[t["id"]] = anchor_struct(
35
35
  label, nil, @labels["figure"], "figure", t["unnumbered"]
@@ -2,14 +2,16 @@ module IsoDoc
2
2
  module XrefGen
3
3
  module Sections
4
4
  def back_anchor_names(docxml)
5
- i = Counter.new("@")
6
- docxml.xpath(ns("//annex")).each do |c|
7
- annex_names(c, i.increment(c).print)
8
- end
9
- docxml.xpath(ns(@klass.bibliography_xpath)).each do |b|
10
- preface_names(b)
5
+ if @parse_settings.empty? || @parse_settings[:clauses]
6
+ i = Counter.new("@")
7
+ docxml.xpath(ns("//annex")).each do |c|
8
+ annex_names(c, i.increment(c).print)
9
+ end
10
+ docxml.xpath(ns(@klass.bibliography_xpath)).each do |b|
11
+ preface_names(b)
12
+ end
11
13
  end
12
- references(docxml)
14
+ references(docxml) if @parse_settings.empty? || @parse_settings[:refs]
13
15
  end
14
16
 
15
17
  def references(docxml)
@@ -19,21 +21,25 @@ module IsoDoc
19
21
  end
20
22
 
21
23
  def initial_anchor_names(doc)
22
- doc.xpath(ns("//preface/*")).each do |c|
23
- c.element? and preface_names(c)
24
+ if @parse_settings.empty? || @parse_settings[:clauses]
25
+ doc.xpath(ns("//preface/*")).each do |c|
26
+ c.element? and preface_names(c)
27
+ end
28
+ # potentially overridden in middle_section_asset_names()
29
+ sequential_asset_names(doc.xpath(ns("//preface/*")))
30
+ n = Counter.new
31
+ n = section_names(doc.at(ns("//clause[@type = 'scope']")), n, 1)
32
+ n = section_names(doc.at(ns(@klass.norm_ref_xpath)), n, 1)
33
+ n = section_names(doc.at(ns("//sections/terms | "\
34
+ "//sections/clause[descendant::terms]")), n, 1)
35
+ n = section_names(doc.at(ns("//sections/definitions")), n, 1)
36
+ clause_names(doc, n)
37
+ end
38
+ if @parse_settings.empty?
39
+ middle_section_asset_names(doc)
40
+ termnote_anchor_names(doc)
41
+ termexample_anchor_names(doc)
24
42
  end
25
- # potentially overridden in middle_section_asset_names()
26
- sequential_asset_names(doc.xpath(ns("//preface/*")))
27
- n = Counter.new
28
- n = section_names(doc.at(ns("//clause[@type = 'scope']")), n, 1)
29
- n = section_names(doc.at(ns(@klass.norm_ref_xpath)), n, 1)
30
- n = section_names(doc.at(ns("//sections/terms | "\
31
- "//sections/clause[descendant::terms]")), n, 1)
32
- n = section_names(doc.at(ns("//sections/definitions")), n, 1)
33
- clause_names(doc, n)
34
- middle_section_asset_names(doc)
35
- termnote_anchor_names(doc)
36
- termexample_anchor_names(doc)
37
43
  end
38
44
 
39
45
  def preface_clause_name(clause)
@@ -112,26 +118,18 @@ module IsoDoc
112
118
  l10n("<strong>#{title} #{num}</strong><br/>#{obl}")
113
119
  end
114
120
 
115
- def single_annex_special_section(clause)
116
- a = clause.xpath(ns("./references | ./terms | ./definitions"))
117
- a.size == 1 or return nil
118
- clause.xpath(ns("./clause | ./p | ./table | ./ol | ./ul | ./dl | "\
119
- "./note | ./admonition | ./figure")).empty? or
120
- return nil
121
- a[0]
122
- end
123
-
124
121
  def annex_name_anchors(clause, num)
125
122
  { label: annex_name_lbl(clause, num),
126
- elem: @labels["annex"],
127
- type: "clause", value: num.to_s, level: 1,
123
+ elem: @labels["annex"], type: "clause",
124
+ subtype: "annex", value: num.to_s, level: 1,
128
125
  xref: "#{@labels['annex']} #{num}" }
129
126
  end
130
127
 
131
128
  def annex_names(clause, num)
132
129
  @anchors[clause["id"]] = annex_name_anchors(clause, num)
133
- if a = single_annex_special_section(clause)
134
- annex_names1(a, num.to_s, 1)
130
+ if @klass.single_term_clause?(clause)
131
+ annex_names1(clause.at(ns("./references | ./terms | ./definitions")),
132
+ num.to_s, 1)
135
133
  else
136
134
  i = Counter.new
137
135
  clause.xpath(ns(SUBCLAUSES)).each do |c|
@@ -143,8 +141,8 @@ module IsoDoc
143
141
 
144
142
  def annex_names1(clause, num, level)
145
143
  @anchors[clause["id"]] = { xref: "#{@labels['annex']} #{num}",
146
- elem: @labels["annex"],
147
- label: num, level: level, type: "clause" }
144
+ elem: @labels["annex"], type: "clause",
145
+ label: num, level: level, subtype: "annex" }
148
146
  i = Counter.new
149
147
  clause.xpath(ns(SUBCLAUSES)).each do |c|
150
148
  annex_names1(c, "#{num}.#{i.increment(c).print}", level + 1)
data/lib/isodoc/xref.rb CHANGED
@@ -24,17 +24,25 @@ module IsoDoc
24
24
  @i18n = i18n
25
25
  @labels = @i18n.get
26
26
  @klass.i18n = @i18n
27
+ @parse_settings = {}
27
28
  end
28
29
 
29
30
  def get
30
31
  @anchors
31
32
  end
32
33
 
34
+ # parse only the elements set, if any are set
35
+ # defined are: clause: true, refs: true
36
+ def parse_inclusions(options)
37
+ @parse_settings.merge!(options)
38
+ self
39
+ end
40
+
33
41
  def anchor(ident, lbl, warning = true)
34
42
  return nil if ident.nil? || ident.empty?
35
43
 
36
44
  if warning && !@anchors[ident]
37
- @seen ||= Seen_Anchor.instance
45
+ @seen ||= SeenAnchor.instance
38
46
  @seen.seen(ident) or warn "No label has been processed for ID #{ident}"
39
47
  @seen.add(ident)
40
48
  return "[#{ident}]"
@@ -44,16 +52,19 @@ module IsoDoc
44
52
 
45
53
  # extract names for all anchors, xref and label
46
54
  def parse(docxml)
47
- amend_preprocess(docxml)
55
+ amend_preprocess(docxml) if @parse_settings.empty?
48
56
  initial_anchor_names(docxml)
49
57
  back_anchor_names(docxml)
50
58
  # preempt clause notes with all other types of note (ISO default)
51
- note_anchor_names(docxml.xpath(ns("//table | //figure")))
52
- note_anchor_names(docxml.xpath(ns(SECTIONS_XPATH)))
53
- example_anchor_names(docxml.xpath(ns(SECTIONS_XPATH)))
54
- list_anchor_names(docxml.xpath(ns(SECTIONS_XPATH)))
55
- deflist_anchor_names(docxml.xpath(ns(SECTIONS_XPATH)))
56
- bookmark_anchor_names(docxml)
59
+ if @parse_settings.empty?
60
+ note_anchor_names(docxml.xpath(ns("//table | //figure")))
61
+ note_anchor_names(docxml.xpath(ns(SECTIONS_XPATH)))
62
+ example_anchor_names(docxml.xpath(ns(SECTIONS_XPATH)))
63
+ list_anchor_names(docxml.xpath(ns(SECTIONS_XPATH)))
64
+ deflist_anchor_names(docxml.xpath(ns(SECTIONS_XPATH)))
65
+ bookmark_anchor_names(docxml)
66
+ end
67
+ @parse_settings = {}
57
68
  end
58
69
 
59
70
  def ns(xpath)
@@ -38,6 +38,10 @@ chain_and: "%1 و %2"
38
38
  chain_or: "%1 او %2"
39
39
  chain_from: "%1 %من 2"
40
40
  chain_to: "من %1 إلى %2"
41
+ ordinal_keys: [gender]
42
+ SpelloutRules:
43
+ f: spellout-ordinal-feminine
44
+ m: spellout-ordinal-masculine
41
45
  note: ملاحظة
42
46
  note_xref: ملاحظة
43
47
  termnote: ملاحظة % للقيد
@@ -63,6 +67,9 @@ deprecated: مهمل
63
67
  source: مصدر
64
68
  and: و
65
69
  all_parts: كل الأجزاء
70
+ edition_ordinal: "الطبعة؜ %Spellout؜"
71
+ edition: الطبعة؜ ؜
72
+ version: الإصدار
66
73
  toc_figures: جدول الأرقام
67
74
  toc_tables: جدول الجداول
68
75
  toc_recommendations: جدول التوصيات
@@ -180,3 +187,5 @@ inflection:
180
187
  صفحة:
181
188
  sg: صفحة
182
189
  pl: صفحات
190
+ الطبعة؜:
191
+ gender: f
@@ -40,6 +40,14 @@ chain_and: "%1 und %2"
40
40
  chain_or: "%1 oder %2"
41
41
  chain_from: "%1 von %2"
42
42
  chain_to: "%1 bis %2"
43
+ ordinal_keys: [gender,number]
44
+ SpelloutRules:
45
+ m.sg: spellout-ordinal-r
46
+ f.sg: spellout-ordinal
47
+ n.sg: spellout-ordinal-s
48
+ m.pl: spellout-ordinal
49
+ f.pl: spellout-ordinal
50
+ n.pl: spellout-ordinal
43
51
  note: HINWEIS
44
52
  note_xref: Hinweis
45
53
  termnote: Hinweis % zum Eintrag
@@ -65,6 +73,9 @@ deprecated: DEPRECATED
65
73
  source: QUELLE
66
74
  and: und
67
75
  all_parts: Alle Teile
76
+ edition_ordinal: "%Spellout Auflage"
77
+ edition: Auflage
78
+ version: Version
68
79
  toc_figures: Abbildungsverzeichnis
69
80
  toc_tables: Tabellenverzeichnis
70
81
  toc_recommendations: Empfehlungenverzeichnis
@@ -182,3 +193,5 @@ inflection:
182
193
  Seite:
183
194
  sg: Seite
184
195
  pl: Seiten
196
+ Auflage:
197
+ gender: f
@@ -46,6 +46,8 @@ chain_and: "%1 and %2"
46
46
  chain_or: "%1 or %2"
47
47
  chain_from: "%1 from %2"
48
48
  chain_to: "%1 to %2"
49
+ ordinal_keys: []
50
+ SpelloutRules: spellout-ordinal
49
51
  note: NOTE
50
52
  note_xref: Note
51
53
  termnote: Note % to entry
@@ -71,6 +73,9 @@ deprecated: DEPRECATED
71
73
  source: SOURCE
72
74
  and: and
73
75
  all_parts: All Parts
76
+ edition_ordinal: "%Spellout edition"
77
+ edition: edition
78
+ version: version
74
79
  toc_figures: List of figures
75
80
  toc_tables: List of tables
76
81
  toc_recommendations: List of recommendations
@@ -42,6 +42,12 @@ chain_and: "%1 y %2"
42
42
  chain_or: "%1 o %2"
43
43
  chain_from: "%1 del %2"
44
44
  chain_to: "%1 al %2"
45
+ ordinal_keys: [gender,number]
46
+ SpelloutRules:
47
+ m.sg: spellout-ordinal-masculine
48
+ f.sg: spellout-ordinal-feminine
49
+ m.pl: spellout-ordinal-masculine-plural
50
+ f.pl: spellout-ordinal-feminine-plural
45
51
  note: NOTA
46
52
  note_xref: Nota
47
53
  termnote: Nota % a la entrada
@@ -67,6 +73,9 @@ deprecated: OBSOLETO
67
73
  source: FUENTE
68
74
  and: y
69
75
  all_parts: Todas las partes
76
+ edition_ordinal: "%Spellout edición"
77
+ edition: edición
78
+ version: versión
70
79
  toc_figures: Table de figuras
71
80
  toc_tables: Tabla de tablas
72
81
  toc_recommendations: Tabla de recomendaciones
@@ -184,3 +193,5 @@ inflection:
184
193
  Página:
185
194
  sg: Página
186
195
  pl: Páginas
196
+ edición:
197
+ gender: f
@@ -39,6 +39,12 @@ chain_and: "%1 et %2"
39
39
  chain_or: "%1 ou %2"
40
40
  chain_from: "%1 de %2"
41
41
  chain_to: "%1 à %2"
42
+ ordinal_keys: [gender,number]
43
+ SpelloutRules:
44
+ m.sg: spellout-ordinal-masculine
45
+ f.sg: spellout-ordinal-feminine
46
+ m.pl: spellout-ordinal-masculine-plural
47
+ f.pl: spellout-ordinal-feminine-plural
42
48
  note: NOTE
43
49
  note_xref: Note
44
50
  termnote: Note % à l’article
@@ -62,8 +68,12 @@ norm_annex: normative
62
68
  modified: modifié
63
69
  deprecated: DÉCONSEILLÉ
64
70
  source: SOURCE
71
+ edition: édition
72
+ version: version
65
73
  and: et
66
74
  all_parts: toutes les parties
75
+ edition_ordinal: "%Spellout édition"
76
+ edition: édition
67
77
  toc_figures: Table des figures
68
78
  toc_tables: Table des tableaux
69
79
  toc_recommendations: Table de recommandations
@@ -181,4 +191,5 @@ inflection:
181
191
  Page:
182
192
  sg: Page
183
193
  pl: Pages
184
-
194
+ édition:
195
+ gender: f
@@ -45,6 +45,14 @@ chain_and: "%1 и %2"
45
45
  chain_or: "%1 или %2"
46
46
  chain_from: "%1 от %2"
47
47
  chain_to: "%1 до %2"
48
+ ordinal_keys: [gender,number]
49
+ SpelloutRules:
50
+ m.sg: spellout-ordinal-masculine
51
+ f.sg: spellout-ordinal-feminine
52
+ n.sg: spellout-ordinal-neuter
53
+ m.pl: spellout-ordinal-plural
54
+ f.pl: spellout-ordinal-plural
55
+ n.pl: spellout-ordinal-plural
48
56
  note: ПРИМЕЧАНИЕ
49
57
  note_xref: Примечание
50
58
  termnote: Примечание % к определению
@@ -70,6 +78,9 @@ deprecated: НЕ РЕКОМЕНДУЕТСЯ
70
78
  source: ИСТОЧНИК
71
79
  and: и
72
80
  all_parts: Все части
81
+ edition_ordinal: "%Spellout издание"
82
+ edition: издание
83
+ version: версия
73
84
  toc_figures: Таблица фигур
74
85
  toc_tables: Таблица таблиц
75
86
  toc_recommendations: Таблица рекомендаций
@@ -187,3 +198,5 @@ inflection:
187
198
  "Стр.":
188
199
  sg: Стр.
189
200
  pl: Стр.
201
+ издание:
202
+ gender: n
@@ -41,6 +41,8 @@ chain_and: "%1和%2"
41
41
  chain_or: "%1或%2"
42
42
  chain_from: "%1从%2"
43
43
  chain_to: "%1到%2"
44
+ ordinal_keys: []
45
+ SpelloutRules: spellout-ordinal
44
46
  note: 注
45
47
  note_xref: 注
46
48
  termnote: 注%
@@ -66,6 +68,9 @@ deprecated: 被取代
66
68
  source: 定义
67
69
  and: 和
68
70
  all_parts: 所有部分
71
+ edition_ordinal: "第%Spellout版"
72
+ edition: 版
73
+ version: 版本
69
74
  toc_figures: 数字列表
70
75
  toc_tables: 表列表
71
76
  toc_recommendations: 建议清单
@@ -0,0 +1,4 @@
1
+ template:
2
+ # skip standardidentifier, it is inserted in front of formattedref within metanorma
3
+ standard: "{{ creatornames }} ({{ role}}) . <em>{{ title }}</em> . {{ labels['in'] | capitalize }}:_{{ series_title }}. {{ medium | capitalize }}. {{ edition | capitalize_first }}. {{date}}. {{place}} : {%if creatornames == publisher %}{% else %}{{publisher}}{% endif %} . {{size}}. {{ extent }}. {{ uri }}. {{ labels['at'] | capitalize}}:_{{ access_location }}. [{{ labels['viewed'] }}:_{{date_accessed}}]."
4
+
@@ -0,0 +1,35 @@
1
+ require "relaton-render"
2
+
3
+ module Relaton
4
+ module Render
5
+ module IsoDoc
6
+ class General < ::Relaton::Render::General
7
+ def config_loc
8
+ YAML.load_file(File.join(File.dirname(__FILE__), "config.yml"))
9
+ end
10
+
11
+ def read_config
12
+ super.deep_merge(config_loc)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ class ::Hash
20
+ def deep_merge(second)
21
+ merger = proc { |_, v1, v2|
22
+ if Hash === v1 && Hash === v2
23
+ v1.merge(v2, &merger)
24
+ elsif Array === v1 && Array === v2
25
+ v1 | v2
26
+ elsif [:undefined, nil,
27
+ :nil].include?(v2)
28
+ v1
29
+ else
30
+ v2
31
+ end
32
+ }
33
+ merge(second.to_h, &merger)
34
+ end
35
+ end
@@ -33,3 +33,9 @@ array:
33
33
  - elem2
34
34
  - {elem3: elem4, elem5: elem6}
35
35
  void:
36
+ ordinal_keys: [number]
37
+ SpelloutRules:
38
+ sg: spellout-ordinal
39
+ pl: spellout-ordinal
40
+ edition_ordinal: "eldono %Spellout"
41
+ edition: eldono