metanorma-standoc 1.9.1 → 1.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +0 -2
  3. data/lib/asciidoctor/standoc/blocks.rb +18 -3
  4. data/lib/asciidoctor/standoc/blocks_notes.rb +29 -18
  5. data/lib/asciidoctor/standoc/cleanup.rb +1 -0
  6. data/lib/asciidoctor/standoc/cleanup_block.rb +30 -12
  7. data/lib/asciidoctor/standoc/cleanup_boilerplate.rb +23 -12
  8. data/lib/asciidoctor/standoc/cleanup_ref.rb +3 -2
  9. data/lib/asciidoctor/standoc/converter.rb +7 -2
  10. data/lib/asciidoctor/standoc/datamodel/plantuml_renderer.rb +67 -66
  11. data/lib/asciidoctor/standoc/isodoc.rng +174 -0
  12. data/lib/asciidoctor/standoc/macros.rb +11 -11
  13. data/lib/asciidoctor/standoc/macros_form.rb +63 -0
  14. data/lib/asciidoctor/standoc/ref_sect.rb +20 -17
  15. data/lib/asciidoctor/standoc/section.rb +3 -1
  16. data/lib/asciidoctor/standoc/terms.rb +24 -17
  17. data/lib/asciidoctor/standoc/utils.rb +3 -3
  18. data/lib/asciidoctor/standoc/validate.rb +18 -16
  19. data/lib/metanorma-standoc.rb +0 -1
  20. data/lib/metanorma/standoc/version.rb +1 -1
  21. data/metanorma-standoc.gemspec +1 -1
  22. data/spec/asciidoctor/blocks_spec.rb +829 -734
  23. data/spec/asciidoctor/cleanup_sections_spec.rb +38 -1
  24. data/spec/asciidoctor/isobib_cache_spec.rb +406 -358
  25. data/spec/asciidoctor/macros_spec.rb +537 -441
  26. data/spec/asciidoctor/macros_yaml2text_spec.rb +1 -1
  27. data/spec/asciidoctor/section_spec.rb +367 -297
  28. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +50 -50
  29. data/spec/vcr_cassettes/isobib_get_123.yml +12 -12
  30. data/spec/vcr_cassettes/isobib_get_123_1.yml +24 -24
  31. data/spec/vcr_cassettes/isobib_get_123_1_fr.yml +33 -33
  32. data/spec/vcr_cassettes/isobib_get_123_2001.yml +12 -12
  33. data/spec/vcr_cassettes/isobib_get_124.yml +12 -12
  34. data/spec/vcr_cassettes/rfcbib_get_rfc8341.yml +14 -14
  35. data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +46 -46
  36. metadata +5 -4
@@ -876,6 +876,18 @@
876
876
  </zeroOrMore>
877
877
  </element>
878
878
  </define>
879
+ <define name="pagebreak">
880
+ <element name="pagebreak">
881
+ <optional>
882
+ <attribute name="orientation">
883
+ <choice>
884
+ <value>landscape</value>
885
+ <value>portrait</value>
886
+ </choice>
887
+ </attribute>
888
+ </optional>
889
+ </element>
890
+ </define>
879
891
  </include>
880
892
  <!-- end overrides -->
881
893
  <define name="colgroup">
@@ -943,8 +955,170 @@
943
955
  <ref name="permission"/>
944
956
  <ref name="imagemap"/>
945
957
  <ref name="svgmap"/>
958
+ <ref name="inputform"/>
959
+ </choice>
960
+ </define>
961
+ <define name="inputform">
962
+ <element name="form">
963
+ <attribute name="id">
964
+ <data type="ID"/>
965
+ </attribute>
966
+ <attribute name="name"/>
967
+ <attribute name="action"/>
968
+ <zeroOrMore>
969
+ <choice>
970
+ <ref name="TextElement"/>
971
+ <ref name="FormInput"/>
972
+ </choice>
973
+ </zeroOrMore>
974
+ </element>
975
+ </define>
976
+ <define name="FormInput">
977
+ <choice>
978
+ <ref name="input"/>
979
+ <ref name="formlabel"/>
980
+ <ref name="select"/>
981
+ <ref name="textarea"/>
982
+ </choice>
983
+ </define>
984
+ <define name="InputType">
985
+ <choice>
986
+ <value>button</value>
987
+ <value>checkbox</value>
988
+ <value>date</value>
989
+ <value>file</value>
990
+ <value>password</value>
991
+ <value>radio</value>
992
+ <value>submit</value>
993
+ <value>text</value>
946
994
  </choice>
947
995
  </define>
996
+ <define name="input">
997
+ <element name="input">
998
+ <attribute name="type">
999
+ <ref name="InputType"/>
1000
+ </attribute>
1001
+ <optional>
1002
+ <attribute name="checked">
1003
+ <data type="boolean"/>
1004
+ </attribute>
1005
+ </optional>
1006
+ <optional>
1007
+ <attribute name="disabled">
1008
+ <data type="boolean"/>
1009
+ </attribute>
1010
+ </optional>
1011
+ <optional>
1012
+ <attribute name="readonly">
1013
+ <data type="boolean"/>
1014
+ </attribute>
1015
+ </optional>
1016
+ <optional>
1017
+ <attribute name="maxlength">
1018
+ <data type="int"/>
1019
+ </attribute>
1020
+ </optional>
1021
+ <optional>
1022
+ <attribute name="minlength">
1023
+ <data type="int"/>
1024
+ </attribute>
1025
+ </optional>
1026
+ <optional>
1027
+ <attribute name="name"/>
1028
+ </optional>
1029
+ <optional>
1030
+ <attribute name="value"/>
1031
+ </optional>
1032
+ <optional>
1033
+ <attribute name="id">
1034
+ <data type="ID"/>
1035
+ </attribute>
1036
+ </optional>
1037
+ </element>
1038
+ </define>
1039
+ <define name="formlabel">
1040
+ <element name="label">
1041
+ <attribute name="for">
1042
+ <data type="IDREF"/>
1043
+ </attribute>
1044
+ <zeroOrMore>
1045
+ <ref name="PureTextElement"/>
1046
+ </zeroOrMore>
1047
+ </element>
1048
+ </define>
1049
+ <define name="select">
1050
+ <element name="select">
1051
+ <optional>
1052
+ <attribute name="name"/>
1053
+ </optional>
1054
+ <optional>
1055
+ <attribute name="value"/>
1056
+ </optional>
1057
+ <optional>
1058
+ <attribute name="id">
1059
+ <data type="ID"/>
1060
+ </attribute>
1061
+ </optional>
1062
+ <optional>
1063
+ <attribute name="disabled">
1064
+ <data type="boolean"/>
1065
+ </attribute>
1066
+ </optional>
1067
+ <optional>
1068
+ <attribute name="multiple">
1069
+ <data type="boolean"/>
1070
+ </attribute>
1071
+ </optional>
1072
+ <optional>
1073
+ <attribute name="size">
1074
+ <data type="int"/>
1075
+ </attribute>
1076
+ </optional>
1077
+ <oneOrMore>
1078
+ <ref name="option"/>
1079
+ </oneOrMore>
1080
+ </element>
1081
+ </define>
1082
+ <define name="option">
1083
+ <element name="option">
1084
+ <optional>
1085
+ <attribute name="disabled">
1086
+ <data type="boolean"/>
1087
+ </attribute>
1088
+ </optional>
1089
+ <optional>
1090
+ <attribute name="value"/>
1091
+ </optional>
1092
+ <zeroOrMore>
1093
+ <ref name="PureTextElement"/>
1094
+ </zeroOrMore>
1095
+ </element>
1096
+ </define>
1097
+ <define name="textarea">
1098
+ <element name="textarea">
1099
+ <optional>
1100
+ <attribute name="name"/>
1101
+ </optional>
1102
+ <optional>
1103
+ <attribute name="value"/>
1104
+ </optional>
1105
+ <optional>
1106
+ <attribute name="id">
1107
+ <data type="ID"/>
1108
+ </attribute>
1109
+ </optional>
1110
+ <optional>
1111
+ <attribute name="rows">
1112
+ <data type="int"/>
1113
+ </attribute>
1114
+ </optional>
1115
+ <optional>
1116
+ <attribute name="cols">
1117
+ <data type="int"/>
1118
+ </attribute>
1119
+ </optional>
1120
+ </element>
1121
+ </define>
948
1122
  <define name="bibliography">
949
1123
  <element name="bibliography">
950
1124
  <oneOrMore>
@@ -4,6 +4,7 @@ require "uuidtools"
4
4
  require "yaml"
5
5
  require_relative "./macros_plantuml"
6
6
  require_relative "./macros_terms"
7
+ require_relative "./macros_form"
7
8
  require_relative "./datamodel/attributes_table_preprocessor"
8
9
  require_relative "./datamodel/diagram_preprocessor"
9
10
  require "metanorma-plugin-datastruct"
@@ -74,12 +75,11 @@ module Asciidoctor
74
75
  def supply_br(lines)
75
76
  ignore = false
76
77
  lines.each_with_index do |l, i|
77
- /^(--+|====+|\|===|\.\.\.\.+|\*\*\*\*+|\+\+\+\++|\`\`\`\`+|____\+)$/.match(l) &&
78
- (ignore = !ignore)
79
- next if l.empty? || l.match(/ \+$/)
80
- next if /^\[.*\]$/.match?(l)
81
- next if ignore
82
- next if i == lines.size - 1 || i < lines.size - 1 && lines[i + 1].empty?
78
+ /^(--+|====+|\|===|\.\.\.\.+|\*\*\*\*+|\+\+\+\++|\`\`\`\`+|____\+)$/
79
+ .match(l) && (ignore = !ignore)
80
+ next if l.empty? || l.match(/ \+$/) || /^\[.*\]$/.match?(l) || ignore
81
+ next if i == lines.size - 1 ||
82
+ i < lines.size - 1 && lines[i + 1].empty?
83
83
 
84
84
  lines[i] += " +"
85
85
  end
@@ -128,22 +128,22 @@ module Asciidoctor
128
128
  def process(parent, reader, attrs)
129
129
  attrs["name"] = "todo"
130
130
  attrs["caption"] = "TODO"
131
- create_block parent, :admonition, reader.lines, attrs,
132
- content_model: :compound
131
+ create_block(parent, :admonition, reader.lines, attrs,
132
+ content_model: :compound)
133
133
  end
134
134
  end
135
135
 
136
136
  class ToDoInlineAdmonitionBlock < Extensions::Treeprocessor
137
137
  def process(document)
138
138
  (document.find_by context: :paragraph).each do |para|
139
- next unless /^TODO: /.match para.lines[0]
139
+ next unless /^TODO: /.match? para.lines[0]
140
140
 
141
141
  parent = para.parent
142
142
  para.set_attr("name", "todo")
143
143
  para.set_attr("caption", "TODO")
144
144
  para.lines[0].sub!(/^TODO: /, "")
145
- todo = Block.new parent, :admonition, attributes: para.attributes,
146
- source: para.lines, content_model: :compound
145
+ todo = Block.new(parent, :admonition, attributes: para.attributes,
146
+ source: para.lines, content_model: :compound)
147
147
  parent.blocks[parent.blocks.index(para)] = todo
148
148
  end
149
149
  end
@@ -0,0 +1,63 @@
1
+ module Asciidoctor
2
+ module Standoc
3
+ class FormInputMacro < Asciidoctor::Extensions::InlineMacroProcessor
4
+ use_dsl
5
+ named :input
6
+
7
+ def process(_parent, target, attr)
8
+ m = %w(id name value disabled readonly checked maxlength minlength)
9
+ .map { |a| attr[a] ? " #{a}='#{attr[a]}'" : nil }.compact
10
+ %{<input type='#{target}' #{m.join}/>}
11
+ end
12
+ end
13
+
14
+ class FormLabelMacro < Asciidoctor::Extensions::InlineMacroProcessor
15
+ use_dsl
16
+ named :label
17
+ parse_content_as :text
18
+
19
+ def process(parent, target, attr)
20
+ out = Asciidoctor::Inline.new(parent, :quoted, attr["text"]).convert
21
+ %{<label for="#{target}">#{out}</label>}
22
+ end
23
+ end
24
+
25
+ class FormTextareaMacro < Asciidoctor::Extensions::InlineMacroProcessor
26
+ use_dsl
27
+ named :textarea
28
+ using_format :short
29
+
30
+ def process(_parent, _target, attr)
31
+ m = %w(id name rows cols value)
32
+ .map { |a| attr[a] ? " #{a}='#{attr[a]}'" : nil }.compact
33
+ %{<textarea #{m.join}/>}
34
+ end
35
+ end
36
+
37
+ class FormSelectMacro < Asciidoctor::Extensions::InlineMacroProcessor
38
+ use_dsl
39
+ named :select
40
+ using_format :short
41
+
42
+ def process(parent, _target, attr)
43
+ m = %w(id name size disabled multiple value)
44
+ .map { |a| attr[a] ? " #{a}='#{attr[a]}'" : nil }.compact
45
+ out = Asciidoctor::Inline.new(parent, :quoted, attr["text"]).convert
46
+ %{<select #{m.join}>#{out}</select>}
47
+ end
48
+ end
49
+
50
+ class FormOptionMacro < Asciidoctor::Extensions::InlineMacroProcessor
51
+ use_dsl
52
+ named :option
53
+ using_format :short
54
+
55
+ def process(parent, _target, attr)
56
+ m = %w(disabled value)
57
+ .map { |a| attr[a] ? " #{a}='#{attr[a]}'" : nil }.compact
58
+ out = Asciidoctor::Inline.new(parent, :quoted, attr["text"]).convert
59
+ %{<option #{m.join}">#{out}</option>}
60
+ end
61
+ end
62
+ end
63
+ end
@@ -10,10 +10,10 @@ module Asciidoctor
10
10
  end
11
11
 
12
12
  def reference(node)
13
- noko do |xml|
14
- node.items.each { |item| reference1(node, item.text, xml) }
15
- end.join
16
- end
13
+ noko do |xml|
14
+ node.items.each { |item| reference1(node, item.text, xml) }
15
+ end.join
16
+ end
17
17
 
18
18
  def bibliography_parse(attrs, xml, node)
19
19
  node.option? "bibitem" and return bibitem_parse(attrs, xml, node)
@@ -43,12 +43,12 @@ module Asciidoctor
43
43
  node.attr("style") == "bibliography" or
44
44
  @log.add("AsciiDoc Input", node, "Section not marked up as [bibliography]!")
45
45
  @norm_ref = true
46
- xml.references **attr_code(attrs.merge(
47
- normative: node.attr("normative") || true)) do |xml_section|
48
- xml_section.title { |t| t << node.title }
49
- xml_section << node.content
50
- end
51
- @norm_ref = false
46
+ attrs = attrs.merge(normative: node.attr("normative") || true)
47
+ xml.references **attr_code(attrs) do |xml_section|
48
+ xml_section.title { |t| t << node.title }
49
+ xml_section << node.content
50
+ end
51
+ @norm_ref = false
52
52
  end
53
53
 
54
54
  def global_ievcache_name
@@ -57,6 +57,7 @@ module Asciidoctor
57
57
 
58
58
  def local_ievcache_name(cachename)
59
59
  return nil if cachename.nil?
60
+
60
61
  cachename += "_iev" unless cachename.empty?
61
62
  cachename = "iev" if cachename.empty?
62
63
  "#{cachename}/cache"
@@ -64,10 +65,11 @@ module Asciidoctor
64
65
 
65
66
  def fetch_ref(xml, code, year, **opts)
66
67
  return nil if opts[:no_year]
68
+
67
69
  code = code.sub(/^\([^)]+\)/, "")
68
- #require "byebug"; byebug if opts[:lang] == "fr"
69
70
  hit = @bibdb&.fetch(code, year, opts)
70
71
  return nil if hit.nil?
72
+
71
73
  xml.parent.add_child(smart_render_xml(hit, code, opts))
72
74
  xml
73
75
  rescue RelatonBib::RequestError
@@ -91,10 +93,9 @@ module Asciidoctor
91
93
  "<docidentifier type='metanorma'>#{mn_code(usrlbl)}</docidentifier>"
92
94
  end
93
95
 
94
- def smart_render_xml(x, code, opts)
95
- x.respond_to? :to_xml or return nil
96
- xstr = x.to_xml(lang: opts[:lang])
97
- xml = Nokogiri::XML(xstr)
96
+ def smart_render_xml(xml, code, opts)
97
+ xml.respond_to? :to_xml or return nil
98
+ xml = Nokogiri::XML(xml.to_xml(lang: opts[:lang]))
98
99
  emend_biblio(xml, code, opts[:title], opts[:usrlbl])
99
100
  xml.xpath("//date").each { |d| Metanorma::Utils::endash_date(d) }
100
101
  xml.traverse do |n|
@@ -105,17 +106,19 @@ module Asciidoctor
105
106
 
106
107
  def init_bib_caches(node)
107
108
  return if @no_isobib
109
+
108
110
  global = !@no_isobib_cache && !node.attr("local-cache-only")
109
111
  local = node.attr("local-cache") || node.attr("local-cache-only")
110
112
  local = nil if @no_isobib_cache
111
113
  @bibdb = Relaton::DbCache.init_bib_caches(
112
114
  local_cache: local,
113
115
  flush_caches: node.attr("flush-caches"),
114
- global_cache: global)
116
+ global_cache: global
117
+ )
115
118
  end
116
119
 
117
120
  def init_iev_caches(node)
118
- unless (@no_isobib_cache || @no_isobib)
121
+ unless @no_isobib_cache || @no_isobib
119
122
  node.attr("local-cache-only") or
120
123
  @iev_globalname = global_ievcache_name
121
124
  @iev_localname = local_ievcache_name(node.attr("local-cache") ||
@@ -10,7 +10,9 @@ module Asciidoctor
10
10
  @norm_ref = false
11
11
 
12
12
  def sectiontype1(node)
13
- node&.attr("heading")&.downcase || node.title.gsub(/<[^>]+>/, "").downcase
13
+ node&.attr("heading")&.downcase ||
14
+ node.title.gsub(%r{<index>.*?</index>}m, "").gsub(/<[^>]+>/, "")
15
+ .strip.downcase
14
16
  end
15
17
 
16
18
  def sectiontype(node, level = true)
@@ -12,12 +12,13 @@ module Asciidoctor
12
12
  @definitions = defs
13
13
  end
14
14
 
15
- def symbols_attrs(node, a)
15
+ def symbols_attrs(node, attr)
16
16
  case sectiontype1(node)
17
- when "symbols" then a.merge(type: "symbols")
18
- when "abbreviated terms", "abbreviations" then a.merge(type: "abbreviated_terms")
17
+ when "symbols" then attr.merge(type: "symbols")
18
+ when "abbreviated terms", "abbreviations"
19
+ attr.merge(type: "abbreviated_terms")
19
20
  else
20
- a
21
+ attr
21
22
  end
22
23
  end
23
24
 
@@ -51,13 +52,17 @@ module Asciidoctor
51
52
 
52
53
  # subclause contains subclauses
53
54
  def term_def_subclause_parse(attrs, xml, node)
54
- node.role == "nonterm" and return nonterm_term_def_subclause_parse(attrs, xml, node)
55
- node.role == "boilerplate" and return terms_boilerplate_parse(attrs, xml, node)
55
+ node.role == "nonterm" and
56
+ return nonterm_term_def_subclause_parse(attrs, xml, node)
57
+ node.role == "boilerplate" and
58
+ return terms_boilerplate_parse(attrs, xml, node)
56
59
  st = sectiontype(node, false)
57
60
  return symbols_parse(attrs, xml, node) if @definitions
61
+
58
62
  sub = node.find_by(context: :section) { |s| s.level == node.level + 1 }
59
63
  sub.empty? || (return term_def_parse(attrs, xml, node, false))
60
- st == "symbols and abbreviated terms" and (return symbols_parse(attrs, xml, node))
64
+ st == "symbols and abbreviated terms" and
65
+ return symbols_parse(attrs, xml, node)
61
66
  st == "terms and definitions" and return clause_parse(attrs, xml, node)
62
67
  term_def_subclause_parse1(attrs, xml, node)
63
68
  end
@@ -69,7 +74,7 @@ module Asciidoctor
69
74
  end
70
75
  end
71
76
 
72
- def term_def_parse(attrs, xml, node, toplevel)
77
+ def term_def_parse(attrs, xml, node, _toplevel)
73
78
  xml.terms **attr_code(attrs) do |section|
74
79
  section.title { |t| t << node.title }
75
80
  (s = node.attr("source")) && s.split(/,/).each do |s1|
@@ -79,14 +84,14 @@ module Asciidoctor
79
84
  end
80
85
  end
81
86
 
82
- def term_source_attrs(node, seen_xref)
83
- { case: seen_xref.children[0]["case"],
84
- droploc: seen_xref.children[0]["droploc"],
85
- bibitemid: seen_xref.children[0]["target"],
86
- format: seen_xref.children[0]["format"], type: "inline" }
87
+ def term_source_attrs(_node, seen_xref)
88
+ { case: seen_xref.children[0]["case"],
89
+ droploc: seen_xref.children[0]["droploc"],
90
+ bibitemid: seen_xref.children[0]["target"],
91
+ format: seen_xref.children[0]["format"], type: "inline" }
87
92
  end
88
93
 
89
- def add_term_source(node, xml_t, seen_xref, m)
94
+ def add_term_source(node, xml_t, seen_xref, match)
90
95
  if seen_xref.children[0].name == "concept"
91
96
  xml_t.origin { |o| o << seen_xref.children[0].to_xml }
92
97
  else
@@ -94,8 +99,8 @@ module Asciidoctor
94
99
  attrs.delete(:text)
95
100
  xml_t.origin seen_xref.children[0].content, **attr_code(attrs)
96
101
  end
97
- m[:text] && xml_t.modification do |mod|
98
- mod.p { |p| p << m[:text].sub(/^\s+/, "") }
102
+ match[:text] && xml_t.modification do |mod|
103
+ mod.p { |p| p << match[:text].sub(/^\s+/, "") }
99
104
  end
100
105
  end
101
106
 
@@ -110,7 +115,9 @@ module Asciidoctor
110
115
 
111
116
  def extract_termsource_refs(text, node)
112
117
  matched = TERM_REFERENCE_RE.match text
113
- matched.nil? and @log.add("AsciiDoc Input", node, "term reference not in expected format: #{text}")
118
+ matched.nil? and @log.add("AsciiDoc Input", node,
119
+ "term reference not in expected format:"\
120
+ "#{text}")
114
121
  matched
115
122
  end
116
123