metanorma-standoc 1.10.5 → 1.11.0

Sign up to get free protection for your applications and to get access to all the features.
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">