metanorma-standoc 1.5.2 → 1.5.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/lib/asciidoctor/standoc/base_structured_text_preprocessor.rb +123 -0
  3. data/lib/asciidoctor/standoc/basicdoc.rng +31 -1
  4. data/lib/asciidoctor/standoc/cleanup.rb +1 -0
  5. data/lib/asciidoctor/standoc/cleanup_amend.rb +54 -0
  6. data/lib/asciidoctor/standoc/cleanup_block.rb +0 -2
  7. data/lib/asciidoctor/standoc/cleanup_footnotes.rb +0 -3
  8. data/lib/asciidoctor/standoc/cleanup_inline.rb +6 -1
  9. data/lib/asciidoctor/standoc/cleanup_section.rb +1 -2
  10. data/lib/asciidoctor/standoc/converter.rb +3 -1
  11. data/lib/asciidoctor/standoc/front_contributor.rb +15 -7
  12. data/lib/asciidoctor/standoc/inline.rb +13 -1
  13. data/lib/asciidoctor/standoc/isodoc.rng +108 -8
  14. data/lib/asciidoctor/standoc/json2_text_preprocessor.rb +43 -0
  15. data/lib/asciidoctor/standoc/macros.rb +45 -33
  16. data/lib/asciidoctor/standoc/section.rb +8 -3
  17. data/lib/asciidoctor/standoc/table.rb +3 -2
  18. data/lib/asciidoctor/standoc/views/datamodel/model_representation.adoc.erb +10 -10
  19. data/lib/asciidoctor/standoc/yaml2_text_preprocessor.rb +43 -0
  20. data/lib/liquid/custom_blocks/key_iterator.rb +21 -0
  21. data/lib/liquid/custom_filters/values.rb +7 -0
  22. data/lib/metanorma/standoc/version.rb +1 -1
  23. data/metanorma-standoc.gemspec +1 -3
  24. data/spec/asciidoctor-standoc/blocks_spec.rb +254 -142
  25. data/spec/asciidoctor-standoc/cleanup_spec.rb +31 -31
  26. data/spec/asciidoctor-standoc/macros_json2text_spec.rb +10 -0
  27. data/spec/asciidoctor-standoc/macros_spec.rb +2 -0
  28. data/spec/asciidoctor-standoc/macros_yaml2text_spec.rb +5 -560
  29. data/spec/asciidoctor-standoc/section_spec.rb +0 -1
  30. data/spec/asciidoctor-standoc/table_spec.rb +112 -112
  31. data/spec/asciidoctor-standoc/validate_spec.rb +5 -1
  32. data/spec/examples/codes_table.html +1365 -1365
  33. data/spec/fixtures/macros_datamodel/address_class_profile.xml +46 -46
  34. data/spec/fixtures/macros_datamodel/address_component_profile.xml +21 -21
  35. data/spec/fixtures/macros_datamodel/blank_definition_profile.xml +21 -21
  36. data/spec/spec_helper.rb +110 -109
  37. data/spec/support/shared_examples/structured_data_2_text_preprocessor.rb +583 -0
  38. metadata +24 -3
  39. data/lib/asciidoctor/standoc/macros_yaml2text.rb +0 -165
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "asciidoctor/standoc/base_structured_text_preprocessor"
4
+
5
+ module Asciidoctor
6
+ module Standoc
7
+ class Json2TextPreprocessor < BaseStructuredTextPreprocessor
8
+ # search document for block `yaml2text`
9
+ # after that take template from block and read file into this template
10
+ # example:
11
+ # [yaml2text,foobar.yaml]
12
+ # ----
13
+ # === {item.name}
14
+ # {item.desc}
15
+ #
16
+ # {item.symbol}:: {item.symbol_def}
17
+ # ----
18
+ #
19
+ # with content of `foobar.yaml` file equal to:
20
+ # - name: spaghetti
21
+ # desc: wheat noodles of 9mm diameter
22
+ # symbol: SPAG
23
+ # symbol_def: the situation is message like spaghetti at a kid's
24
+ #
25
+ # will produce:
26
+ # === spaghetti
27
+ # wheat noodles of 9mm diameter
28
+ #
29
+ # SPAG:: the situation is message like spaghetti at a kid's meal
30
+
31
+ def initialize(config = {})
32
+ super
33
+ @config[:block_name] = "json2text"
34
+ end
35
+
36
+ protected
37
+
38
+ def content_from_file(document, file_path)
39
+ JSON.parse(File.read(relative_file_path(document, file_path)))
40
+ end
41
+ end
42
+ end
43
+ end
@@ -1,11 +1,12 @@
1
1
  require "asciidoctor/extensions"
2
2
  require "fileutils"
3
3
  require "uuidtools"
4
- require 'yaml'
5
- require_relative './macros_plantuml.rb'
6
- require_relative './datamodel/attributes_table_preprocessor.rb'
7
- require_relative './datamodel/diagram_preprocessor.rb'
8
- require_relative './macros_yaml2text.rb'
4
+ require "yaml"
5
+ require_relative "./macros_plantuml.rb"
6
+ require_relative "./datamodel/attributes_table_preprocessor.rb"
7
+ require_relative "./datamodel/diagram_preprocessor.rb"
8
+ require_relative "./yaml2_text_preprocessor.rb"
9
+ require_relative "./json2_text_preprocessor.rb"
9
10
 
10
11
  module Asciidoctor
11
12
  module Standoc
@@ -61,17 +62,17 @@ module Asciidoctor
61
62
  use_dsl
62
63
  named :concept
63
64
  name_positional_attributes "id", "word", "term"
64
- #match %r{concept:(?<target>[^\[]*)\[(?<content>|.*?[^\\])\]$}
65
+ # match %r{concept:(?<target>[^\[]*)\[(?<content>|.*?[^\\])\]$}
65
66
  match /\{\{(?<content>|.*?[^\\])\}\}/
66
67
  using_format :short
67
68
 
68
69
  # deal with locality attrs and their disruption of positional attrs
69
70
  def preprocess_attrs(attrs)
70
- attrs.delete("term") if attrs["term"] and !attrs["word"]
71
+ attrs.delete("term") if attrs["term"] && !attrs["word"]
71
72
  attrs.delete(3) if attrs[3] == attrs["term"]
72
- a = attrs.keys.reject { |k| k.is_a? String or [1, 2].include? k }
73
- attrs["word"] ||= attrs[a[0]] if a.length() > 0
74
- attrs["term"] ||= attrs[a[1]] if a.length() > 1
73
+ a = attrs.keys.reject { |k| k.is_a?(String) || [1, 2].include?(k) }
74
+ attrs["word"] ||= attrs[a[0]] if !a.empty?
75
+ attrs["term"] ||= attrs[a[1]] if a.length > 1
75
76
  attrs
76
77
  end
77
78
 
@@ -94,30 +95,30 @@ module Asciidoctor
94
95
 
95
96
  def init_indent(s)
96
97
  /^(?<prefix>[ \t]*)(?<suffix>.*)$/ =~ s
97
- prefix = prefix.gsub(/\t/, "\u00a0\u00a0\u00a0\u00a0").
98
- gsub(/ /, "\u00a0")
98
+ prefix = prefix.gsub(/\t/, "\u00a0\u00a0\u00a0\u00a0")
99
+ .gsub(/ /, "\u00a0")
99
100
  prefix + suffix
100
101
  end
101
102
 
102
103
  def supply_br(lines)
103
104
  ignore = false
104
105
  lines.each_with_index do |l, i|
105
- /^(--+|====+|\|===|\.\.\.\.+|\*\*\*\*+|\+\+\+\++|\`\`\`\`+|____\+)$/.match(l) and
106
- ignore = !ignore
106
+ /^(--+|====+|\|===|\.\.\.\.+|\*\*\*\*+|\+\+\+\++|\`\`\`\`+|____\+)$/.match(l) &&
107
+ (ignore = !ignore)
107
108
  next if l.empty? || l.match(/ \+$/)
108
109
  next if /^\[.*\]$/.match(l)
109
110
  next if ignore
110
- next if i == lines.size - 1 || i < lines.size - 1 && lines[i+1].empty?
111
+ next if i == lines.size - 1 || i < lines.size - 1 && lines[i + 1].empty?
111
112
  lines[i] += " +"
112
113
  end
113
114
  lines
114
115
  end
115
116
 
116
- def process parent, reader, attrs
117
- attrs['role'] = 'pseudocode'
117
+ def process(parent, reader, attrs)
118
+ attrs["role"] = "pseudocode"
118
119
  lines = reader.lines.map { |m| init_indent(m) }
119
120
  ret = create_block(parent, :example, supply_br(lines),
120
- attrs, content_model: :compound)
121
+ attrs, content_model: :compound)
121
122
  ret
122
123
  end
123
124
  end
@@ -128,19 +129,19 @@ module Asciidoctor
128
129
  parse_content_as :text
129
130
  option :pos_attrs, %w(rpbegin rt rpend)
130
131
 
131
- def process(parent, target, attributes)
132
- rpbegin = '('
133
- rpend = ')'
134
- if attributes.size == 1 and attributes.key?("text")
132
+ def process(_parent, target, attributes)
133
+ rpbegin = "("
134
+ rpend = ")"
135
+ if (attributes.size == 1) && attributes.key?("text")
135
136
  rt = attributes["text"]
136
- elsif attributes.size == 2 and attributes.key?(1) and
137
- attributes.key?("rpbegin")
137
+ elsif (attributes.size == 2) && attributes.key?(1) &&
138
+ attributes.key?("rpbegin")
138
139
  # for example, html5ruby:楽聖少女[がくせいしょうじょ]
139
140
  rt = attributes[1] || ""
140
141
  else
141
- rpbegin = attributes['rpbegin']
142
- rt = attributes['rt']
143
- rpend = attributes['rpend']
142
+ rpbegin = attributes["rpbegin"]
143
+ rt = attributes["rt"]
144
+ rpend = attributes["rpend"]
144
145
  end
145
146
 
146
147
  "<ruby>#{target}<rp>#{rpbegin}</rp><rt>#{rt}</rt>"\
@@ -153,16 +154,16 @@ module Asciidoctor
153
154
  named :TODO
154
155
  on_contexts :example, :paragraph
155
156
 
156
- def process parent, reader, attrs
157
- attrs['name'] = 'todo'
158
- attrs['caption'] = 'TODO'
157
+ def process(parent, reader, attrs)
158
+ attrs["name"] = "todo"
159
+ attrs["caption"] = "TODO"
159
160
  create_block parent, :admonition, reader.lines, attrs,
160
- content_model: :compound
161
+ content_model: :compound
161
162
  end
162
163
  end
163
164
 
164
165
  class ToDoInlineAdmonitionBlock < Extensions::Treeprocessor
165
- def process document
166
+ def process(document)
166
167
  (document.find_by context: :paragraph).each do |para|
167
168
  next unless /^TODO: /.match para.lines[0]
168
169
  parent = para.parent
@@ -170,10 +171,21 @@ module Asciidoctor
170
171
  para.set_attr("caption", "TODO")
171
172
  para.lines[0].sub!(/^TODO: /, "")
172
173
  todo = Block.new parent, :admonition, attributes: para.attributes,
173
- source: para.lines, content_model: :compound
174
+ source: para.lines, content_model: :compound
174
175
  parent.blocks[parent.blocks.index(para)] = todo
175
176
  end
176
177
  end
177
178
  end
179
+
180
+ class AutonumberInlineMacro < Extensions::InlineMacroProcessor
181
+ use_dsl
182
+ named :autonumber
183
+ parse_content_as :text
184
+
185
+ def process(parent, target, attrs)
186
+ out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
187
+ %{<autonumber type=#{target}>#{out}</autonumber>}
188
+ end
189
+ end
178
190
  end
179
191
  end
@@ -46,7 +46,7 @@ module Asciidoctor
46
46
  end
47
47
 
48
48
  def section_attributes(node)
49
- { id: Utils::anchor_or_uuid(node),
49
+ ret = { id: Utils::anchor_or_uuid(node),
50
50
  language: node.attributes["language"],
51
51
  script: node.attributes["script"],
52
52
  annex: (
@@ -55,8 +55,13 @@ module Asciidoctor
55
55
  ),
56
56
  preface: (
57
57
  (node.role == "preface" || node.attr("style") == "preface") ?
58
- true : nil),
59
- }
58
+ true : nil) }
59
+ return ret unless node.attributes["change"]
60
+ ret.merge(change: node.attributes["change"],
61
+ path: node.attributes["path"],
62
+ path_end: node.attributes["path_end"],
63
+ title: node.attributes["title"],
64
+ )
60
65
  end
61
66
 
62
67
  def section(node)
@@ -45,8 +45,9 @@ module Asciidoctor
45
45
  end
46
46
 
47
47
  def table_cell(c, xml_tr, tblsec)
48
- cell_attributes = { id: c.id, colspan: c.colspan,
49
- rowspan: c.rowspan, align: c.attr("halign") }
48
+ cell_attributes =
49
+ { id: c.id, colspan: c.colspan, valign: c.attr("valign"),
50
+ rowspan: c.rowspan, align: c.attr("halign") }
50
51
  cell_tag = "td"
51
52
  cell_tag = "th" if tblsec == :head || c.style == :header
52
53
  xml_tr.send cell_tag, **attr_code(cell_attributes) do |thd|
@@ -2,29 +2,29 @@
2
2
  [yaml2text,<%= model_path %>,definition]
3
3
  ----
4
4
 
5
- === {definition.name || "<%= file_name %>"}
5
+ === {definition.name | default: "<%= file_name %>"}
6
6
  {definition.definition}
7
7
 
8
- {if definition.attributes}
9
- .{definition.name || "<%= file_name %>"} attributes
8
+ {% if definition.attributes %}
9
+ .{definition.name | default: "<%= file_name %>"} attributes
10
10
  |===
11
11
  |Name |Definition |Mandatory/ Optional/ Conditional |Max Occur |Data Type
12
12
 
13
- {definition.attributes&.*,key,EOK}
14
- |{key} |{definition.attributes[key].definition || "TODO: enum " + key.to_s + "'s definition"} |{definition.attributes[key]&.cardinality&.min == 0 ? "O" : "M"} |{definition.attributes[key]&.cardinality&.max == "*" ? "N" : "1"} |{definition.attributes[key].origin ? "<<" + definition.attributes[key].origin.to_s + ">>" : ""}`{definition.attributes[key].type}`
13
+ {definition.attributes.*,key,EOK}
14
+ |{key} |{% if definition.attributes[key].definition %}{{ definition.attributes[key].definition }}{% else %}TODO: enum {{ key }}'s definition{% endif %} |{% if definition.attributes[key].cardinality.min == 0 %}O{% else %}M{% endif %} |{% if definition.attributes[key].cardinality.max == "*" %}N{% else %}1{% endif %} |{% if definition.attributes[key].origin %}<<{{ definition.attributes[key].origin }}>>{% endif %} `{definition.attributes[key].type}`
15
15
  {EOK}
16
16
  |===
17
- {end}
17
+ {% endif %}
18
18
 
19
- {if definition['values']}
20
- .{definition.name || "<%= file_name %>"} values
19
+ {% if definition['values'] %}
20
+ .{definition.name | default: "<%= file_name %>"} values
21
21
  |===
22
22
  |Name |Definition
23
23
 
24
- {definition['values']&.*,key,EOK}
24
+ {definition['values'].*,key,EOK}
25
25
  |{key} |{definition['values'][key].definition}
26
26
  {EOK}
27
27
  |===
28
- {end}
28
+ {% endif %}
29
29
 
30
30
  ----
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "asciidoctor/standoc/base_structured_text_preprocessor"
4
+
5
+ module Asciidoctor
6
+ module Standoc
7
+ class Yaml2TextPreprocessor < BaseStructuredTextPreprocessor
8
+ # search document for block `yaml2text`
9
+ # after that take template from block and read file into this template
10
+ # example:
11
+ # [yaml2text,foobar.yaml]
12
+ # ----
13
+ # === {item.name}
14
+ # {item.desc}
15
+ #
16
+ # {item.symbol}:: {item.symbol_def}
17
+ # ----
18
+ #
19
+ # with content of `foobar.yaml` file equal to:
20
+ # - name: spaghetti
21
+ # desc: wheat noodles of 9mm diameter
22
+ # symbol: SPAG
23
+ # symbol_def: the situation is message like spaghetti at a kid's
24
+ #
25
+ # will produce:
26
+ # === spaghetti
27
+ # wheat noodles of 9mm diameter
28
+ #
29
+ # SPAG:: the situation is message like spaghetti at a kid's meal
30
+
31
+ def initialize(config = {})
32
+ super
33
+ @config[:block_name] = "yaml2text"
34
+ end
35
+
36
+ protected
37
+
38
+ def content_from_file(document, file_path)
39
+ YAML.safe_load(File.read(relative_file_path(document, file_path)))
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,21 @@
1
+ module Liquid
2
+ module CustomBlocks
3
+ class KeyIterator < Block
4
+ def initialize(tag_name, markup, tokens)
5
+ super
6
+ @context_name, @var_name = markup.split(',').map(&:strip)
7
+ end
8
+
9
+ def render(context)
10
+ res = ''
11
+ iterator = context[@context_name].is_a?(Hash) ? context[@context_name].keys : context[@context_name]
12
+ iterator.each.with_index do |key, index|
13
+ context['index'] = index
14
+ context[@var_name] = key
15
+ res += super
16
+ end
17
+ res
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,7 @@
1
+ module Liquid
2
+ module CustomFilters
3
+ def values(list)
4
+ list.values
5
+ end
6
+ end
7
+ end
@@ -1,5 +1,5 @@
1
1
  module Metanorma
2
2
  module Standoc
3
- VERSION = "1.5.2".freeze
3
+ VERSION = "1.5.3".freeze
4
4
  end
5
5
  end
@@ -37,6 +37,7 @@ Gem::Specification.new do |spec|
37
37
  spec.add_dependency "unicode2latex", "~> 0.0.1"
38
38
  spec.add_dependency "mimemagic"
39
39
  spec.add_dependency "mathml2asciimath"
40
+ spec.add_dependency "latexmath"
40
41
 
41
42
  spec.add_development_dependency "byebug"
42
43
  spec.add_development_dependency "sassc", "2.4.0"
@@ -50,7 +51,4 @@ Gem::Specification.new do |spec|
50
51
  spec.add_development_dependency "timecop", "~> 0.9"
51
52
  spec.add_development_dependency "vcr", "~> 5.0.0"
52
53
  spec.add_development_dependency "webmock"
53
- #spec.add_development_dependency "relaton-iec"
54
- #spec.add_development_dependency "relaton-iso"
55
- #spec.add_development_dependency "relaton-ietf"
56
54
  end
@@ -86,172 +86,149 @@ RSpec.describe Asciidoctor::Standoc do
86
86
 
87
87
  INPUT
88
88
  #{BLANK_HDR}
89
- <sections>
90
- <formula id="ABC" inequality="true" number="3" keep-with-next="true" keep-lines-together="true">
91
- <stem type="MathML"><math xmlns="http://www.w3.org/1998/Math/MathML"><mi>r</mi><mo>=</mo><mn>1</mn><mi>%</mi><mi>r</mi><mo>=</mo><mn>1</mn><mi>%</mi></math></stem>
92
- </formula>
93
-
94
- <formula id="_" unnumbered="true">
95
- <stem type="MathML"><math xmlns="http://www.w3.org/1998/Math/MathML"><msub> <mrow> <mrow> <mi mathvariant="bold-italic">F</mi> </mrow> </mrow> <mrow> <mrow> <mi mathvariant="bold-italic">Α</mi> </mrow> </mrow> </msub> </math></stem>
96
- </formula>
97
- <formula id="_" subsequence="A">
98
- <stem type="MathML">
99
- <math xmlns="http://www.w3.org/1998/Math/MathML">
100
- <mrow>
101
- <mi>M</mi>
102
- <mo>=</mo>
103
- <mrow>
104
- <mo>[</mo>
105
- <mtable columnspacing="5pt" displaystyle="true" rowspacing="0pt">
106
- <mtr>
107
- <mtd columnalign="center">
89
+ <sections>
90
+ <formula id='ABC' number='3' keep-with-next='true' keep-lines-together='true' inequality='true'>
91
+ <stem type='MathML'>
92
+ <math xmlns='http://www.w3.org/1998/Math/MathML'>
93
+ <mi>r</mi>
94
+ <mo>=</mo>
95
+ <mn>1</mn>
96
+ <mi>%</mi>
97
+ <mi>r</mi>
98
+ <mo>=</mo>
99
+ <mn>1</mn>
100
+ <mi>%</mi>
101
+ </math>
102
+ </stem>
103
+ </formula>
104
+ <formula id='_' unnumbered='true'>
105
+ <stem type='MathML'>
106
+ <math xmlns='http://www.w3.org/1998/Math/MathML'>
107
+ <msub>
108
108
  <mrow>
109
- <mo>-</mo>
110
109
  <mrow>
111
- <mi>sin</mi>
112
- <mo>⁡</mo>
113
- <msub>
114
- <mi>λ</mi>
115
- <mn>0</mn>
116
- </msub>
110
+ <mi mathvariant='bold-italic'>F</mi>
117
111
  </mrow>
118
112
  </mrow>
119
- </mtd>
120
- <mtd columnalign="center">
121
113
  <mrow>
122
- <mi>cos</mi>
123
- <mo>⁡</mo>
124
- <msub>
125
- <mi>λ</mi>
126
- <mn>0</mn>
127
- </msub>
128
- </mrow>
129
- </mtd>
130
- <mtd columnalign="center">
131
- <mn>0</mn>
132
- </mtd>
133
- </mtr>
134
- <mtr>
135
- <mtd columnalign="center">
136
- <mrow>
137
- <mo>-</mo>
138
114
  <mrow>
139
- <mrow>
140
- <mi>sin</mi>
141
- <mo>⁡</mo>
115
+ <mi mathvariant='bold-italic'>Α</mi>
116
+ </mrow>
117
+ </mrow>
118
+ </msub>
119
+ </math>
120
+ </stem>
121
+ </formula>
122
+ <formula id='_' subsequence='A'>
123
+ <stem type='MathML'>
124
+ <math xmlns='http://www.w3.org/1998/Math/MathML'>
125
+ <mrow>
126
+ <mi>M</mi>
127
+ <mo>=</mo>
128
+ <mo>[</mo>
129
+ <mtable>
130
+ <mtr>
131
+ <mtd>
132
+ <mrow>
133
+ <mo>−</mo>
134
+ <mi>sin</mi>
135
+ </mrow>
136
+ <msub>
137
+ <mi>λ</mi>
138
+ <mn>0</mn>
139
+ </msub>
140
+ </mtd>
141
+ <mtd>
142
+ <mi>cos</mi>
143
+ <msub>
144
+ <mi>λ</mi>
145
+ <mn>0</mn>
146
+ </msub>
147
+ </mtd>
148
+ <mtd>
149
+ <mn>0</mn>
150
+ </mtd>
151
+ </mtr>
152
+ <mtr>
153
+ <mtd>
154
+ <mrow>
155
+ <mo>−</mo>
156
+ <mi>sin</mi>
157
+ </mrow>
142
158
  <msub>
143
159
  <mi>φ</mi>
144
160
  <mn>0</mn>
145
161
  </msub>
146
- </mrow>
147
- <mo>⁢</mo>
148
- <mrow>
149
162
  <mi>cos</mi>
150
- <mo>⁡</mo>
151
163
  <msub>
152
164
  <mi>λ</mi>
153
165
  <mn>0</mn>
154
166
  </msub>
155
- </mrow>
156
- </mrow>
157
- </mrow>
158
- </mtd>
159
- <mtd columnalign="center">
160
- <mrow>
161
- <mo>-</mo>
162
- <mrow>
163
- <mrow>
167
+ </mtd>
168
+ <mtd>
169
+ <mrow>
170
+ <mo>−</mo>
171
+ <mi>sin</mi>
172
+ </mrow>
173
+ <msub>
174
+ <mi>φ</mi>
175
+ <mn>0</mn>
176
+ </msub>
164
177
  <mi>sin</mi>
165
- <mo>⁡</mo>
178
+ <msub>
179
+ <mi>λ</mi>
180
+ <mn>0</mn>
181
+ </msub>
182
+ </mtd>
183
+ <mtd>
184
+ <mi>cos</mi>
185
+ <msub>
186
+ <mi>φ</mi>
187
+ <mn>0</mn>
188
+ </msub>
189
+ </mtd>
190
+ </mtr>
191
+ <mtr>
192
+ <mtd>
193
+ <mi>cos</mi>
194
+ <msub>
195
+ <mi>φ</mi>
196
+ <mn>0</mn>
197
+ </msub>
198
+ <mi>cos</mi>
199
+ <msub>
200
+ <mi>λ</mi>
201
+ <mn>0</mn>
202
+ </msub>
203
+ </mtd>
204
+ <mtd>
205
+ <mi>cos</mi>
166
206
  <msub>
167
207
  <mi>φ</mi>
168
208
  <mn>0</mn>
169
209
  </msub>
170
- </mrow>
171
- <mo>⁢</mo>
172
- <mrow>
173
210
  <mi>sin</mi>
174
- <mo>⁡</mo>
175
211
  <msub>
176
212
  <mi>λ</mi>
177
213
  <mn>0</mn>
178
214
  </msub>
179
- </mrow>
180
- </mrow>
181
- </mrow>
182
- </mtd>
183
- <mtd columnalign="center">
184
- <mrow>
185
- <mi>cos</mi>
186
- <mo>⁡</mo>
187
- <msub>
188
- <mi>φ</mi>
189
- <mn>0</mn>
190
- </msub>
191
- </mrow>
192
- </mtd>
193
- </mtr>
194
- <mtr>
195
- <mtd columnalign="center">
196
- <mrow>
197
- <mrow>
198
- <mi>cos</mi>
199
- <mo>⁡</mo>
200
- <msub>
201
- <mi>φ</mi>
202
- <mn>0</mn>
203
- </msub>
204
- </mrow>
205
- <mo>⁢</mo>
206
- <mrow>
207
- <mi>cos</mi>
208
- <mo>⁡</mo>
209
- <msub>
210
- <mi>λ</mi>
211
- <mn>0</mn>
212
- </msub>
213
- </mrow>
214
- </mrow>
215
- </mtd>
216
- <mtd columnalign="center">
217
- <mrow>
218
- <mrow>
219
- <mi>cos</mi>
220
- <mo>⁡</mo>
221
- <msub>
222
- <mi>φ</mi>
223
- <mn>0</mn>
224
- </msub>
225
- </mrow>
226
- <mo>⁢</mo>
227
- <mrow>
228
- <mi>sin</mi>
229
- <mo>⁡</mo>
230
- <msub>
231
- <mi>λ</mi>
232
- <mn>0</mn>
233
- </msub>
234
- </mrow>
235
- </mrow>
236
- </mtd>
237
- <mtd columnalign="center">
238
- <mrow>
239
- <mi>sin</mi>
240
- <mo>⁡</mo>
241
- <msub>
242
- <mi>φ</mi>
243
- <mn>0</mn>
244
- </msub>
245
- </mrow>
246
- </mtd>
247
- </mtr>
248
- </mtable>
249
- <mo>]</mo>
250
- </mrow>
251
- </mrow>
252
- </math></stem>
253
- </formula>
254
- </sections></standard-document>
215
+ </mtd>
216
+ <mtd>
217
+ <mi>sin</mi>
218
+ <msub>
219
+ <mi>φ</mi>
220
+ <mn>0</mn>
221
+ </msub>
222
+ </mtd>
223
+ </mtr>
224
+ </mtable>
225
+ <mo>]</mo>
226
+ </mrow>
227
+ </math>
228
+ </stem>
229
+ </formula>
230
+ </sections>
231
+ </standard-document>
255
232
  OUTPUT
256
233
  end
257
234
 
@@ -1253,7 +1230,7 @@ RSpec.describe Asciidoctor::Standoc do
1253
1230
  <recommendation id="ABC" obligation="permission,recommendation" filename="reqt1.rq"><label>/ogc/recommendation/wfs/2</label><subject>user</subject>
1254
1231
  <classification><tag>control-class</tag><value>Technical</value></classification><classification><tag>priority</tag><value>P0</value></classification><classification><tag>family</tag><value>System &amp; Communications Protection</value></classification><classification><tag>family</tag><value>System and Communications Protocols</value></classification>
1255
1232
  <description><p id="_">I recommend <em>this</em>.</p>
1256
- </description><specification exclude="false" type="tabular" keep-with-next="true" keep-lines-together="true"><p id="_">This is the object of the recommendation:</p><table id="_"> <tbody> <tr> <td align="left">Object</td> <td align="left">Value</td> </tr> <tr> <td align="left">Mission</td> <td align="left">Accomplished</td> </tr> </tbody></table></specification><description>
1233
+ </description><specification exclude="false" type="tabular" keep-with-next="true" keep-lines-together="true"><p id="_">This is the object of the recommendation:</p><table id="_"> <tbody> <tr> <td valign="top" align="left">Object</td> <td valign="top" align="left">Value</td> </tr> <tr> <td valign="top" align="left">Mission</td> <td valign="top" align="left">Accomplished</td> </tr> </tbody></table></specification><description>
1257
1234
  <p id="_">As for the measurement targets,</p>
1258
1235
  </description><measurement-target exclude="false"><p id="_">The measurement target shall be measured as:</p><formula id="_"> <stem type="MathML"><math xmlns="http://www.w3.org/1998/Math/MathML"><mfrac>
1259
1236
  <mrow>
@@ -1275,4 +1252,139 @@ end</sourcecode></verification>
1275
1252
  expect(xmlpp(strip_guid(Asciidoctor.convert(input, backend: :standoc, header_footer: true)))).to be_equivalent_to xmlpp(output)
1276
1253
  end
1277
1254
 
1255
+ it "processes delete change clauses" do
1256
+ input = <<~"INPUT"
1257
+ #{ASCIIDOC_BLANK_HDR}
1258
+ [change="modify",locality="page=27",path="//table[2]",path_end="//table[2]/following-sibling:example[1]",title="Change"]
1259
+ ==== Change Clause
1260
+ _This table contains information on polygon cells which are not included in ISO 10303-52. Remove table 2 completely and replace with:_
1261
+ INPUT
1262
+ output = <<~"OUTPUT"
1263
+ #{BLANK_HDR}
1264
+ <sections>
1265
+ <clause id='_' inline-header='false' obligation='normative'>
1266
+ <title>Change Clause</title>
1267
+ <amend id='_' change='modify' path='//table[2]' path_end='//table[2]/following-sibling:example[1]' title='Change'>
1268
+ <description>
1269
+ <p id='_'>
1270
+ <em>
1271
+ This table contains information on polygon cells which are not
1272
+ included in ISO 10303-52. Remove table 2 completely and replace
1273
+ with:
1274
+ </em>
1275
+ </p>
1276
+ </description>
1277
+ </amend>
1278
+ </clause>
1279
+ </sections>
1280
+ </standard-document>
1281
+ OUTPUT
1282
+ expect(xmlpp(strip_guid(Asciidoctor.convert(input, backend: :standoc, header_footer: true)))).to be_equivalent_to xmlpp(output)
1283
+
1284
+ end
1285
+
1286
+ it "processes modify change clauses" do
1287
+ input = <<~"INPUT"
1288
+ #{ASCIIDOC_BLANK_HDR}
1289
+ [change="modify",locality="page=27",path="//table[2]",path_end="//table[2]/following-sibling:example[1]",title="Change"]
1290
+ ==== Change Clause
1291
+
1292
+ autonumber:table[2]
1293
+ autonumber:note[7]
1294
+
1295
+ _This table contains information on polygon cells which are not included in ISO 10303-52. Remove table 2 completely and replace with:_
1296
+
1297
+ ____
1298
+ .Edges of triangle and quadrilateral cells
1299
+ |===
1300
+ 2+^.^h| triangle 2+^.^h| quadrilateral
1301
+ ^.^| edge ^.^| vertices ^.^| edge ^.^| vertices
1302
+ ^.^| 1 ^.^| 1, 2 ^.^| 1 ^.^| 1, 2
1303
+ ^.^| 2 ^.^| 2, 3 ^.^| 2 ^.^| 2, 3
1304
+ ^.^| 3 ^.^| 3, 1 ^.^| 3 ^.^| 3, 4
1305
+ | | ^.^| 4 ^.^| 4, 1
1306
+ |===
1307
+
1308
+ ====
1309
+ This is not generalised further.
1310
+ ====
1311
+
1312
+ ____
1313
+
1314
+ Any further exceptions can be ignored.
1315
+ INPUT
1316
+
1317
+ output = <<~"OUTPUT"
1318
+ #{BLANK_HDR}
1319
+ <sections>
1320
+ <clause id='_' inline-header='false' obligation='normative'>
1321
+ <title>Change Clause</title>
1322
+ <amend id='_' change='modify' path='//table[2]' path_end='//table[2]/following-sibling:example[1]' title='Change'>
1323
+ <autonumber type='table'>2</autonumber>
1324
+ <autonumber type='note'>7</autonumber>
1325
+ <description>
1326
+ <p id='_'>
1327
+ <em>
1328
+ This table contains information on polygon cells which are not
1329
+ included in ISO 10303-52. Remove table 2 completely and replace
1330
+ with:
1331
+ </em>
1332
+ </p>
1333
+ </description>
1334
+ <newcontent id='_'>
1335
+ <table id='_'>
1336
+ <name>Edges of triangle and quadrilateral cells</name>
1337
+ <tbody>
1338
+ <tr>
1339
+ <th colspan='2' valign='middle' align='center'>triangle</th>
1340
+ <th colspan='2' valign='middle' align='center'>quadrilateral</th>
1341
+ </tr>
1342
+ <tr>
1343
+ <td valign='middle' align='center'>edge</td>
1344
+ <td valign='middle' align='center'>vertices</td>
1345
+ <td valign='middle' align='center'>edge</td>
1346
+ <td valign='middle' align='center'>vertices</td>
1347
+ </tr>
1348
+ <tr>
1349
+ <td valign='middle' align='center'>1</td>
1350
+ <td valign='middle' align='center'>1, 2</td>
1351
+ <td valign='middle' align='center'>1</td>
1352
+ <td valign='middle' align='center'>1, 2</td>
1353
+ </tr>
1354
+ <tr>
1355
+ <td valign='middle' align='center'>2</td>
1356
+ <td valign='middle' align='center'>2, 3</td>
1357
+ <td valign='middle' align='center'>2</td>
1358
+ <td valign='middle' align='center'>2, 3</td>
1359
+ </tr>
1360
+ <tr>
1361
+ <td valign='middle' align='center'>3</td>
1362
+ <td valign='middle' align='center'>3, 1</td>
1363
+ <td valign='middle' align='center'>3</td>
1364
+ <td valign='middle' align='center'>3, 4</td>
1365
+ </tr>
1366
+ <tr>
1367
+ <td valign='top' align='left'/>
1368
+ <td valign='top' align='left'/>
1369
+ <td valign='middle' align='center'>4</td>
1370
+ <td valign='middle' align='center'>4, 1</td>
1371
+ </tr>
1372
+ </tbody>
1373
+ </table>
1374
+ <example id='_'>
1375
+ <p id='_'>This is not generalised further.</p>
1376
+ </example>
1377
+ </newcontent>
1378
+ <description>
1379
+ <p id='_'>Any further exceptions can be ignored.</p>
1380
+ </description>
1381
+ </amend>
1382
+ </clause>
1383
+ </sections>
1384
+ </standard-document>
1385
+ OUTPUT
1386
+ expect(xmlpp(strip_guid(Asciidoctor.convert(input, backend: :standoc, header_footer: true)))).to be_equivalent_to xmlpp(output)
1387
+ end
1388
+
1389
+
1278
1390
  end