metanorma-standoc 1.9.1 → 1.9.2

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