metanorma-standoc 1.10.5 → 1.11.0

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 (66) hide show
  1. checksums.yaml +4 -4
  2. data/README.adoc +19 -23
  3. data/Rakefile +1 -1
  4. data/lib/asciidoctor/standoc/base.rb +14 -17
  5. data/lib/asciidoctor/standoc/basicdoc.rng +21 -4
  6. data/lib/asciidoctor/standoc/blocks.rb +26 -23
  7. data/lib/asciidoctor/standoc/blocks_notes.rb +17 -22
  8. data/lib/asciidoctor/standoc/cleanup.rb +46 -12
  9. data/lib/asciidoctor/standoc/cleanup_block.rb +5 -70
  10. data/lib/asciidoctor/standoc/cleanup_image.rb +6 -7
  11. data/lib/asciidoctor/standoc/cleanup_inline.rb +44 -102
  12. data/lib/asciidoctor/standoc/cleanup_maths.rb +5 -6
  13. data/lib/asciidoctor/standoc/cleanup_ref.rb +5 -0
  14. data/lib/asciidoctor/standoc/cleanup_reqt.rb +51 -33
  15. data/lib/asciidoctor/standoc/cleanup_section_names.rb +5 -5
  16. data/lib/asciidoctor/standoc/cleanup_symbols.rb +48 -0
  17. data/lib/asciidoctor/standoc/cleanup_table.rb +68 -0
  18. data/lib/asciidoctor/standoc/cleanup_terms.rb +38 -78
  19. data/lib/asciidoctor/standoc/cleanup_terms_designations.rb +162 -0
  20. data/lib/asciidoctor/standoc/cleanup_text.rb +5 -2
  21. data/lib/asciidoctor/standoc/cleanup_xref.rb +107 -0
  22. data/lib/asciidoctor/standoc/converter.rb +15 -0
  23. data/lib/asciidoctor/standoc/inline.rb +7 -5
  24. data/lib/asciidoctor/standoc/isodoc.rng +435 -78
  25. data/lib/asciidoctor/standoc/lists.rb +15 -15
  26. data/lib/asciidoctor/standoc/macros.rb +14 -43
  27. data/lib/asciidoctor/standoc/macros_note.rb +45 -0
  28. data/lib/asciidoctor/standoc/macros_plantuml.rb +29 -14
  29. data/lib/asciidoctor/standoc/macros_terms.rb +82 -20
  30. data/lib/asciidoctor/standoc/ref_sect.rb +24 -17
  31. data/lib/asciidoctor/standoc/reqt.rb +2 -2
  32. data/lib/asciidoctor/standoc/reqt.rng +23 -2
  33. data/lib/asciidoctor/standoc/term_lookup_cleanup.rb +50 -11
  34. data/lib/asciidoctor/standoc/terms.rb +21 -3
  35. data/lib/asciidoctor/standoc/utils.rb +36 -23
  36. data/lib/asciidoctor/standoc/validate.rb +45 -27
  37. data/lib/asciidoctor/standoc/validate_section.rb +5 -2
  38. data/lib/metanorma/standoc/version.rb +1 -1
  39. data/metanorma-standoc.gemspec +1 -1
  40. data/spec/asciidoctor/base_spec.rb +4 -36
  41. data/spec/asciidoctor/blank_spec.rb +37 -0
  42. data/spec/asciidoctor/blocks_spec.rb +296 -47
  43. data/spec/asciidoctor/cleanup_blocks_spec.rb +1018 -0
  44. data/spec/asciidoctor/cleanup_sections_spec.rb +153 -12
  45. data/spec/asciidoctor/cleanup_spec.rb +179 -1265
  46. data/spec/asciidoctor/cleanup_terms_spec.rb +990 -0
  47. data/spec/asciidoctor/inline_spec.rb +38 -2
  48. data/spec/asciidoctor/lists_spec.rb +6 -6
  49. data/spec/asciidoctor/macros_plantuml_spec.rb +37 -2
  50. data/spec/asciidoctor/macros_spec.rb +226 -138
  51. data/spec/asciidoctor/refs_spec.rb +4 -26
  52. data/spec/asciidoctor/section_spec.rb +18 -18
  53. data/spec/asciidoctor/validate_spec.rb +109 -1
  54. data/spec/assets/xref_error.adoc +1 -0
  55. data/spec/fixtures/datamodel_description_sections_tree.xml +327 -326
  56. data/spec/spec_helper.rb +6 -7
  57. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +51 -51
  58. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec1.yml +13 -13
  59. data/spec/vcr_cassettes/isobib_get_123.yml +13 -13
  60. data/spec/vcr_cassettes/isobib_get_123_1.yml +26 -26
  61. data/spec/vcr_cassettes/isobib_get_123_1_fr.yml +34 -34
  62. data/spec/vcr_cassettes/isobib_get_123_2001.yml +12 -12
  63. data/spec/vcr_cassettes/isobib_get_124.yml +13 -13
  64. data/spec/vcr_cassettes/rfcbib_get_rfc8341.yml +16 -16
  65. data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +51 -49
  66. metadata +13 -5
@@ -4,10 +4,10 @@ module Asciidoctor
4
4
  def li(xml_ul, item)
5
5
  xml_ul.li do |xml_li|
6
6
  if item.blocks?
7
- xml_li.p(**id_attr(item)) { |t| t << item.text }
7
+ xml_li.p(**attr_code(id_attr(item))) { |t| t << item.text }
8
8
  xml_li << item.content
9
9
  else
10
- xml_li.p(**id_attr(item)) { |p| p << item.text }
10
+ xml_li.p(**attr_code(id_attr(item))) { |p| p << item.text }
11
11
  end
12
12
  end
13
13
  end
@@ -15,10 +15,10 @@ module Asciidoctor
15
15
  def ul_li(xml_ul, item)
16
16
  xml_ul.li **ul_li_attrs(item) do |xml_li|
17
17
  if item.blocks?
18
- xml_li.p(**id_attr(item)) { |t| t << item.text }
18
+ xml_li.p(**attr_code(id_attr(item))) { |t| t << item.text }
19
19
  xml_li << item.content
20
20
  else
21
- xml_li.p(**id_attr(item)) { |p| p << item.text }
21
+ xml_li.p(**attr_code(id_attr(item))) { |p| p << item.text }
22
22
  end
23
23
  end
24
24
  end
@@ -57,9 +57,8 @@ module Asciidoctor
57
57
  end
58
58
 
59
59
  def ol_attrs(node)
60
- attr_code(keep_attrs(node)
61
- .merge(id: Metanorma::Utils::anchor_or_uuid(node),
62
- type: olist_style(node.style)))
60
+ attr_code(id_attr(node).merge(keep_attrs(node)
61
+ .merge(type: olist_style(node.style))))
63
62
  end
64
63
 
65
64
  def olist(node)
@@ -79,22 +78,23 @@ module Asciidoctor
79
78
  end
80
79
  end
81
80
 
82
- def dd(dd, xml_dl)
83
- if dd.nil?
81
+ def dd(ddefn, xml_dl)
82
+ if ddefn.nil?
84
83
  xml_dl.dd
85
84
  return
86
85
  end
87
86
  xml_dl.dd do |xml_dd|
88
- xml_dd.p { |t| t << dd.text } if dd.text?
89
- xml_dd << dd.content if dd.blocks?
87
+ xml_dd.p { |t| t << ddefn.text } if ddefn.text?
88
+ xml_dd << ddefn.content if ddefn.blocks?
90
89
  end
91
90
  end
92
91
 
93
92
  def dl_attrs(node)
94
- attr_code(keep_attrs(node)
95
- .merge(id: Metanorma::Utils::anchor_or_uuid(node),
96
- metadata: node.option?("metadata") ? "true" : nil,
97
- key: node.option?("key") ? "true" : nil))
93
+ attr_code(id_attr(node).merge(keep_attrs(node)
94
+ .merge(
95
+ metadata: node.option?("metadata") ? "true" : nil,
96
+ key: node.option?("key") ? "true" : nil,
97
+ )))
98
98
  end
99
99
 
100
100
  def dlist(node)
@@ -6,6 +6,7 @@ require "csv"
6
6
  require_relative "./macros_plantuml"
7
7
  require_relative "./macros_terms"
8
8
  require_relative "./macros_form"
9
+ require_relative "./macros_note"
9
10
  require_relative "./datamodel/attributes_table_preprocessor"
10
11
  require_relative "./datamodel/diagram_preprocessor"
11
12
  require "metanorma-plugin-datastruct"
@@ -41,7 +42,7 @@ module Asciidoctor
41
42
  def process(_parent, target, attr)
42
43
  args = preprocess_attrs(attr) or return
43
44
  ret = "<index-xref also='#{target == 'also'}'>"\
44
- "<primary>#{args[:primary]}</primary>"
45
+ "<primary>#{args[:primary]}</primary>"
45
46
  ret += "<secondary>#{args[:secondary]}</secondary>" if args[:secondary]
46
47
  ret += "<tertiary>#{args[:tertiary]}</tertiary>" if args[:tertiary]
47
48
  ret + "<target>#{args[:target]}</target></index-xref>"
@@ -50,7 +51,7 @@ module Asciidoctor
50
51
 
51
52
  class IndexRangeInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
52
53
  use_dsl
53
- named "index-range".to_sym
54
+ named :"index-range"
54
55
  parse_content_as :text
55
56
 
56
57
  def process(parent, target, attr)
@@ -121,35 +122,6 @@ module Asciidoctor
121
122
  end
122
123
  end
123
124
 
124
- class ToDoAdmonitionBlock < Extensions::BlockProcessor
125
- use_dsl
126
- named :TODO
127
- on_contexts :example, :paragraph
128
-
129
- def process(parent, reader, attrs)
130
- attrs["name"] = "todo"
131
- attrs["caption"] = "TODO"
132
- create_block(parent, :admonition, reader.lines, attrs,
133
- content_model: :compound)
134
- end
135
- end
136
-
137
- class ToDoInlineAdmonitionBlock < Extensions::Treeprocessor
138
- def process(document)
139
- (document.find_by context: :paragraph).each do |para|
140
- next unless /^TODO: /.match? para.lines[0]
141
-
142
- parent = para.parent
143
- para.set_attr("name", "todo")
144
- para.set_attr("caption", "TODO")
145
- para.lines[0].sub!(/^TODO: /, "")
146
- todo = Block.new(parent, :admonition, attributes: para.attributes,
147
- source: para.lines, content_model: :compound)
148
- parent.blocks[parent.blocks.index(para)] = todo
149
- end
150
- end
151
- end
152
-
153
125
  class AutonumberInlineMacro < Extensions::InlineMacroProcessor
154
126
  use_dsl
155
127
  named :autonumber
@@ -177,18 +149,6 @@ module Asciidoctor
177
149
  end
178
150
  end
179
151
 
180
- class FootnoteBlockInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
181
- use_dsl
182
- named :footnoteblock
183
- parse_content_as :text
184
- using_format :short
185
-
186
- def process(parent, _target, attrs)
187
- out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
188
- %{<footnoteblock>#{out}</footnoteblock>}
189
- end
190
- end
191
-
192
152
  class AddMacro < Asciidoctor::Extensions::InlineMacroProcessor
193
153
  use_dsl
194
154
  named :add
@@ -229,5 +189,16 @@ module Asciidoctor
229
189
  "<toc>#{content}</toc>"
230
190
  end
231
191
  end
192
+
193
+ class PassInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
194
+ use_dsl
195
+ named :"pass-format"
196
+
197
+ def process(parent, target, attrs)
198
+ format = target || "metanorma"
199
+ out = Asciidoctor::Inline.new(parent, :quoted, attrs[1]).convert
200
+ %{<passthrough formats="#{format}">#{out}</passthrough>}
201
+ end
202
+ end
232
203
  end
233
204
  end
@@ -0,0 +1,45 @@
1
+ module Asciidoctor
2
+ module Standoc
3
+ class ToDoAdmonitionBlock < Extensions::BlockProcessor
4
+ use_dsl
5
+ named :TODO
6
+ on_contexts :example, :paragraph
7
+
8
+ def process(parent, reader, attrs)
9
+ attrs["name"] = "todo"
10
+ attrs["caption"] = "TODO"
11
+ create_block(parent, :admonition, reader.lines, attrs,
12
+ content_model: :compound)
13
+ end
14
+ end
15
+
16
+ class ToDoInlineAdmonitionBlock < Extensions::Treeprocessor
17
+ def process(document)
18
+ (document.find_by context: :paragraph).each do |para|
19
+ next unless /^TODO: /.match? para.lines[0]
20
+
21
+ parent = para.parent
22
+ para.set_attr("name", "todo")
23
+ para.set_attr("caption", "TODO")
24
+ para.lines[0].sub!(/^TODO: /, "")
25
+ todo = Block.new(parent, :admonition, attributes: para.attributes,
26
+ source: para.lines,
27
+ content_model: :compound)
28
+ parent.blocks[parent.blocks.index(para)] = todo
29
+ end
30
+ end
31
+ end
32
+
33
+ class FootnoteBlockInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
34
+ use_dsl
35
+ named :footnoteblock
36
+ parse_content_as :text
37
+ using_format :short
38
+
39
+ def process(parent, _target, attrs)
40
+ out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
41
+ %{<footnoteblock>#{out}</footnoteblock>}
42
+ end
43
+ end
44
+ end
45
+ end
@@ -28,32 +28,38 @@ module Asciidoctor
28
28
  # sleep need for windows because dot works in separate process and
29
29
  # plantuml process may finish earlier then dot, as result png file
30
30
  # maybe not created yet after plantuml finish
31
+ #
32
+ # # Warning: metanorma/metanorma-standoc#187
33
+ # Windows Ruby 2.4 will crash if a Tempfile is "mv"ed.
34
+ # This is why we need to copy and then unlink.
31
35
  def self.generate_file(parent, reader)
32
36
  localdir = Metanorma::Utils::localdir(parent.document)
33
37
  imagesdir = parent.document.attr("imagesdir")
34
38
  umlfile, outfile = save_plantuml parent, reader, localdir
35
- run(umlfile, outfile) or raise "No image output from PlantUML (#{umlfile}, #{outfile})!"
39
+ run(umlfile, outfile) or
40
+ raise "No image output from PlantUML (#{umlfile}, #{outfile})!"
36
41
  umlfile.unlink
37
42
 
38
- path = Pathname.new(localdir) + (imagesdir || "plantuml")
39
- File.writable?(localdir) or raise "Destination path #{path} not writable for PlantUML!"
40
- path.mkpath
41
- File.writable?(path) or raise "Destination path #{path} not writable for PlantUML!"
42
- # File.exist?(path) or raise "Destination path #{path} already exists for PlantUML!"
43
-
44
- # Warning: metanorma/metanorma-standoc#187
45
- # Windows Ruby 2.4 will crash if a Tempfile is "mv"ed.
46
- # This is why we need to copy and then unlink.
43
+ path = path_prep(localdir, imagesdir)
47
44
  filename = File.basename(outfile.to_s)
48
- FileUtils.cp(outfile, path) && outfile.unlink
45
+ FileUtils.cp(outfile, path) and outfile.unlink
49
46
 
50
47
  imagesdir ? filename : File.join(path, filename)
51
48
  end
52
49
 
50
+ def self.path_prep(localdir, imagesdir)
51
+ path = Pathname.new(localdir) + (imagesdir || "plantuml")
52
+ File.writable?(localdir) or
53
+ raise "Destination path #{path} not writable for PlantUML!"
54
+ path.mkpath
55
+ File.writable?(path) or
56
+ raise "Destination path #{path} not writable for PlantUML!"
57
+ # File.exist?(path) or raise "Destination path #{path} already exists for PlantUML!"
58
+ path
59
+ end
60
+
53
61
  def self.save_plantuml(_parent, reader, _localdir)
54
- src = reader.source
55
- reader.lines.first.sub(/\s+$/, "").match /^@startuml($| )/ or
56
- src = "@startuml\n#{src}\n@enduml\n"
62
+ src = prep_source(reader)
57
63
  /^@startuml (?<fn>[^\n]+)\n/ =~ src
58
64
  Tempfile.open(["plantuml", ".pml"], encoding: "utf-8") do |f|
59
65
  f.write(src)
@@ -62,6 +68,15 @@ module Asciidoctor
62
68
  end
63
69
  end
64
70
 
71
+ def self.prep_source(reader)
72
+ src = reader.source
73
+ reader.lines.first.sub(/\s+$/, "").match /^@startuml($| )/ or
74
+ src = "@startuml\n#{src}\n@enduml\n"
75
+ %r{@enduml\s*$}m.match?(src) or
76
+ raise "@startuml without matching @enduml in PlantUML!"
77
+ src
78
+ end
79
+
65
80
  def self.generate_attrs(attrs)
66
81
  %w(id align float title role width height alt)
67
82
  .inject({}) do |memo, key|
@@ -2,6 +2,18 @@ require "csv"
2
2
 
3
3
  module Asciidoctor
4
4
  module Standoc
5
+ class PreferredTermInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
6
+ use_dsl
7
+ named :preferred
8
+ parse_content_as :text
9
+ using_format :short
10
+
11
+ def process(parent, _target, attrs)
12
+ out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
13
+ %{<preferred><expression><name>#{out}</name></expression></preferred>}
14
+ end
15
+ end
16
+
5
17
  class AltTermInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
6
18
  use_dsl
7
19
  named :alt
@@ -9,8 +21,9 @@ module Asciidoctor
9
21
  using_format :short
10
22
 
11
23
  def process(parent, _target, attrs)
12
- out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
13
- %{<admitted>#{out}</admitted>}
24
+ out = Asciidoctor::Inline.new(parent, :quoted,
25
+ attrs["text"]).convert
26
+ %{<admitted><expression><name>#{out}</name></expression></admitted>}
14
27
  end
15
28
  end
16
29
 
@@ -21,8 +34,9 @@ module Asciidoctor
21
34
  using_format :short
22
35
 
23
36
  def process(parent, _target, attrs)
24
- out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
25
- %{<deprecates>#{out}</deprecates>}
37
+ out = Asciidoctor::Inline.new(parent, :quoted,
38
+ attrs["text"]).convert
39
+ %{<deprecates><expression><name>#{out}</name></expression></deprecates>}
26
40
  end
27
41
  end
28
42
 
@@ -33,7 +47,8 @@ module Asciidoctor
33
47
  using_format :short
34
48
 
35
49
  def process(parent, _target, attrs)
36
- out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
50
+ out = Asciidoctor::Inline.new(parent, :quoted,
51
+ attrs["text"]).convert
37
52
  %{<domain>#{out}</domain>}
38
53
  end
39
54
  end
@@ -81,15 +96,24 @@ module Asciidoctor
81
96
  def preprocess_attrs(target)
82
97
  m = /^(?<id>&lt;&lt;.+?&gt;&gt;)?(?<rest>.*)$/.match(target)
83
98
  ret = { id: m[:id]&.sub(/^&lt;&lt;/, "")&.sub(/&gt;&gt;$/, "") }
84
- if m2 = /^(?<rest>.*?)(?<opt>,option=.+)$/.match(m[:rest].sub(/^,/, ""))
85
- ret[:opt] = CSV.parse_line(m2[:opt].sub(/^,option=/, "")
99
+ if m2 = /^(?<rest>.*?)(?<opt>,opt(ion)?s=.+)$/
100
+ .match(m[:rest].sub(/^,/, ""))
101
+ ret[:opt] = CSV.parse_line(m2[:opt].sub(/^,opt(ion)?s=/, "")
86
102
  .sub(/^"(.+)"$/, "\\1").sub(/^'(.+)'$/, "\\1"))
87
- attrs = CSV.parse_line(m2[:rest]) || []
103
+ begin
104
+ attrs = CSV.parse_line(m2[:rest]) || []
105
+ rescue StandardError
106
+ raise "error processing #{m2[:rest]} as CSV"
107
+ end
88
108
  else
89
- attrs = CSV.parse_line(m[:rest].sub(/^,/, "")) || []
109
+ begin
110
+ attrs = CSV.parse_line(m[:rest].sub(/^,/, "")) || []
111
+ rescue StandardError
112
+ raise "error processing #{m[:rest]} as CSV"
113
+ end
90
114
  end
91
115
  ret.merge(term: attrs[0], word: attrs[1] || attrs[0],
92
- xrefrender: attrs[2])
116
+ render: attrs[2])
93
117
  end
94
118
 
95
119
  def generate_attrs(opts)
@@ -98,21 +122,59 @@ module Asciidoctor
98
122
  opts.include?("noref") and ret += " ref='false'"
99
123
  opts.include?("ital") and ret += " ital='true'"
100
124
  opts.include?("ref") and ret += " ref='true'"
125
+ opts.include?("nolinkmention") and ret += " linkmention='false'"
126
+ opts.include?("linkmention") and ret += " linkmention='true'"
127
+ opts.include?("nolinkref") and ret += " linkref='false'"
128
+ opts.include?("linkref") and ret += " linkref='true'"
101
129
  ret
102
130
  end
103
131
 
104
132
  def process(parent, target, _attrs)
105
133
  attrs = preprocess_attrs(target)
106
- termout = Asciidoctor::Inline.new(parent, :quoted, attrs[:term]).convert
107
- wordout = Asciidoctor::Inline.new(parent, :quoted, attrs[:word]).convert
108
- xrefout = Asciidoctor::Inline.new(parent, :quoted,
109
- attrs[:xrefrender]).convert
110
- optout = generate_attrs(attrs[:opt] || [])
111
- attrs[:id] and return "<concept#{optout} key='#{attrs[:id]}'><refterm>"\
112
- "#{termout}</refterm><renderterm>#{wordout}</renderterm>"\
113
- "<xrefrender>#{xrefout}</xrefrender></concept>"
114
- "<concept#{optout}><termxref>#{termout}</termxref><renderterm>"\
115
- "#{wordout}</renderterm><xrefrender>#{xrefout}</xrefrender></concept>"
134
+ term = Asciidoctor::Inline.new(parent, :quoted,
135
+ attrs[:term]).convert
136
+ word = Asciidoctor::Inline.new(parent, :quoted,
137
+ attrs[:word]).convert
138
+ xref = Asciidoctor::Inline.new(parent, :quoted,
139
+ attrs[:render]).convert
140
+ opt = generate_attrs(attrs[:opt] || [])
141
+ if attrs[:id] then "<concept#{opt} key='#{attrs[:id]}'><refterm>"\
142
+ "#{term}</refterm><renderterm>#{word}</renderterm>"\
143
+ "<xrefrender>#{xref}</xrefrender></concept>"
144
+ else "<concept#{opt}><termxref>#{term}</termxref><renderterm>"\
145
+ "#{word}</renderterm><xrefrender>#{xref}</xrefrender></concept>"
146
+ end
147
+ rescue StandardError => e
148
+ raise("processing {{#{target}}}: #{e.message}")
149
+ end
150
+ end
151
+
152
+ # Possibilities:
153
+ # related:relation[<<id>>, term]
154
+ # related:relation[<<termbase:id>>, term]
155
+ # related:relation[term] equivalent to a crossreference to term:[term]
156
+ class RelatedTermInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
157
+ use_dsl
158
+ named :related
159
+ parse_content_as :text
160
+
161
+ def preprocess_attrs(target)
162
+ m = /^(?<id>&lt;&lt;.+?&gt;&gt;, ?)?(?<rest>.*)$/.match(target)
163
+ { id: m[:id]&.sub(/^&lt;&lt;/, "")&.sub(/&gt;&gt;, ?$/, ""),
164
+ term: m[:rest] }
165
+ end
166
+
167
+ def process(parent, target, attrs)
168
+ out = preprocess_attrs(attrs["text"])
169
+ term = Asciidoctor::Inline.new(parent, :quoted,
170
+ out[:term]).convert
171
+ if out[:id] then "<related type='#{target}' key='#{out[:id]}'>"\
172
+ "<refterm>#{term}</refterm></related>"
173
+ else "<related type='#{target}'><termxref>#{term}</termxref>"\
174
+ "<xrefrender>#{term}</xrefrender></related>"
175
+ end
176
+ rescue StandardError => e
177
+ raise("processing related:#{target}[#{attrs['text']}]: #{e.message}")
116
178
  end
117
179
  end
118
180
  end
@@ -16,16 +16,14 @@ module Asciidoctor
16
16
  end
17
17
 
18
18
  def bibliography_parse(attrs, xml, node)
19
- node.option? "bibitem" and return bibitem_parse(attrs, xml, node)
20
- node.attr("style") == "bibliography" or
21
- @log.add("AsciiDoc Input", node, "Section not marked up as [bibliography]!")
19
+ x = biblio_prep(attrs, xml, node) and return x
22
20
  @biblio = true
23
- xml.references **attr_code(attrs.merge(
24
- normative: node.attr("normative") || false)) do |xml_section|
25
- xml_section.title { |t| t << node.title }
26
- xml_section << node.content
27
- end
28
- @biblio = false
21
+ attrs = attrs.merge(normative: node.attr("normative") || false)
22
+ xml.references **attr_code(attrs) do |xml_section|
23
+ xml_section.title { |t| t << node.title }
24
+ xml_section << node.content
25
+ end
26
+ @biblio = false
29
27
  end
30
28
 
31
29
  def bibitem_parse(attrs, xml, node)
@@ -39,9 +37,7 @@ module Asciidoctor
39
37
  end
40
38
 
41
39
  def norm_ref_parse(attrs, xml, node)
42
- node.option? "bibitem" and return bibitem_parse(attrs, xml, node)
43
- node.attr("style") == "bibliography" or
44
- @log.add("AsciiDoc Input", node, "Section not marked up as [bibliography]!")
40
+ x = biblio_prep(attrs, xml, node) and return x
45
41
  @norm_ref = true
46
42
  attrs = attrs.merge(normative: node.attr("normative") || true)
47
43
  xml.references **attr_code(attrs) do |xml_section|
@@ -51,6 +47,17 @@ module Asciidoctor
51
47
  @norm_ref = false
52
48
  end
53
49
 
50
+ def biblio_prep(attrs, xml, node)
51
+ if node.option? "bibitem"
52
+ bibitem_parse(attrs, xml, node)
53
+ else
54
+ node.attr("style") == "bibliography" or
55
+ @log.add("AsciiDoc Input", node,
56
+ "Section not marked up as [bibliography]!")
57
+ nil
58
+ end
59
+ end
60
+
54
61
  def global_ievcache_name
55
62
  "#{Dir.home}/.iev/cache"
56
63
  end
@@ -74,7 +81,7 @@ module Asciidoctor
74
81
  xml
75
82
  rescue RelatonBib::RequestError
76
83
  @log.add("Bibliography", nil, "Could not retrieve #{code}: "\
77
- "no access to online site")
84
+ "no access to online site")
78
85
  nil
79
86
  end
80
87
 
@@ -87,10 +94,10 @@ module Asciidoctor
87
94
  unless xml.at("/bibitem/title[text()]")
88
95
  @log.add("Bibliography", nil,
89
96
  "ERROR: No title retrieved for #{code}")
90
- xml.root << "<title>#{title || "(MISSING TITLE)"}</title>"
97
+ xml.root << "<title>#{title || '(MISSING TITLE)'}</title>"
91
98
  end
92
99
  usrlbl and xml.at("/bibitem/docidentifier").next =
93
- "<docidentifier type='metanorma'>#{mn_code(usrlbl)}</docidentifier>"
100
+ "<docidentifier type='metanorma'>#{mn_code(usrlbl)}</docidentifier>"
94
101
  end
95
102
 
96
103
  def smart_render_xml(xml, code, opts)
@@ -113,7 +120,7 @@ module Asciidoctor
113
120
  @bibdb = Relaton::DbCache.init_bib_caches(
114
121
  local_cache: local,
115
122
  flush_caches: node.attr("flush-caches"),
116
- global_cache: global
123
+ global_cache: global,
117
124
  )
118
125
  end
119
126
 
@@ -128,7 +135,7 @@ module Asciidoctor
128
135
  FileUtils.rm_f @iev_localname unless @iev_localname.nil?
129
136
  end
130
137
  end
131
- #@iev = Iev::Db.new(globalname, localname) unless @no_isobib
138
+ # @iev = Iev::Db.new(globalname, localname) unless @no_isobib
132
139
  end
133
140
  end
134
141
  end
@@ -7,8 +7,8 @@ module Asciidoctor
7
7
  module Standoc
8
8
  module Blocks
9
9
  def reqt_subpart(name)
10
- %w(specification measurement-target verification import label
11
- component subject inherit classification title).include? name
10
+ %w(specification measurement-target verification import label title
11
+ description component subject inherit classification).include? name
12
12
  end
13
13
 
14
14
  def reqt_subpart_attrs(node, name)
@@ -58,6 +58,14 @@
58
58
  <optional>
59
59
  <attribute name="type"/>
60
60
  </optional>
61
+ <optional>
62
+ <attribute name="tag"/>
63
+ </optional>
64
+ <optional>
65
+ <attribute name="multilingual-rendering">
66
+ <ref name="MultilingualRenderingType"/>
67
+ </attribute>
68
+ </optional>
61
69
  <optional>
62
70
  <ref name="reqtitle"/>
63
71
  </optional>
@@ -101,7 +109,9 @@
101
109
  </define>
102
110
  <define name="label">
103
111
  <element name="label">
104
- <text/>
112
+ <oneOrMore>
113
+ <ref name="TextElement"/>
114
+ </oneOrMore>
105
115
  </element>
106
116
  </define>
107
117
  <define name="subject">
@@ -175,8 +185,19 @@
175
185
  <data type="boolean"/>
176
186
  </attribute>
177
187
  </optional>
188
+ <optional>
189
+ <attribute name="tag"/>
190
+ </optional>
191
+ <optional>
192
+ <attribute name="multilingual-rendering">
193
+ <ref name="MultilingualRenderingType"/>
194
+ </attribute>
195
+ </optional>
178
196
  <oneOrMore>
179
- <ref name="BasicBlock"/>
197
+ <choice>
198
+ <ref name="BasicBlock"/>
199
+ <ref name="component"/>
200
+ </choice>
180
201
  </oneOrMore>
181
202
  </define>
182
203
  <define name="ObligationType">