metanorma-standoc 2.2.5 → 2.2.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (153) hide show
  1. checksums.yaml +4 -4
  2. data/lib/isodoc/html/htmlstyle.css +1 -1
  3. data/lib/metanorma/standoc/base.rb +4 -5
  4. data/lib/metanorma/standoc/basicdoc.rng +0 -27
  5. data/lib/metanorma/standoc/biblio-standoc.rng +164 -0
  6. data/lib/metanorma/standoc/biblio.rng +50 -18
  7. data/lib/metanorma/standoc/cleanup.rb +18 -17
  8. data/lib/metanorma/standoc/cleanup_amend.rb +2 -2
  9. data/lib/metanorma/standoc/cleanup_asciibib.rb +110 -0
  10. data/lib/metanorma/standoc/cleanup_biblio.rb +7 -112
  11. data/lib/metanorma/standoc/cleanup_block.rb +7 -6
  12. data/lib/metanorma/standoc/cleanup_boilerplate.rb +6 -6
  13. data/lib/metanorma/standoc/cleanup_inline.rb +2 -2
  14. data/lib/metanorma/standoc/cleanup_maths.rb +12 -4
  15. data/lib/metanorma/standoc/cleanup_section.rb +19 -9
  16. data/lib/metanorma/standoc/cleanup_symbols.rb +14 -7
  17. data/lib/metanorma/standoc/cleanup_text.rb +19 -6
  18. data/lib/metanorma/standoc/cleanup_toc.rb +1 -2
  19. data/lib/metanorma/standoc/cleanup_xref.rb +55 -14
  20. data/lib/metanorma/standoc/inline.rb +29 -12
  21. data/lib/metanorma/standoc/isodoc-compile.rng +7 -0
  22. data/lib/metanorma/standoc/isodoc.rng +69 -207
  23. data/lib/metanorma/standoc/ref_utility.rb +1 -0
  24. data/lib/metanorma/standoc/render.rb +10 -1
  25. data/lib/metanorma/standoc/section.rb +10 -3
  26. data/lib/metanorma/standoc/utils.rb +6 -1
  27. data/lib/metanorma/standoc/validate.rb +9 -9
  28. data/lib/metanorma/standoc/version.rb +1 -1
  29. data/metanorma-standoc.gemspec +5 -3
  30. metadata +7 -141
  31. data/.github/workflows/rake.yml +0 -15
  32. data/.github/workflows/release.yml +0 -24
  33. data/Rakefile +0 -8
  34. data/bin/rspec +0 -18
  35. data/spec/assets/a1.adoc +0 -8
  36. data/spec/assets/a2.adoc +0 -10
  37. data/spec/assets/a3.adoc +0 -9
  38. data/spec/assets/a3a.adoc +0 -7
  39. data/spec/assets/a4.adoc +0 -4
  40. data/spec/assets/boilerplate.xml +0 -4
  41. data/spec/assets/codes.yml +0 -695
  42. data/spec/assets/correct.png +0 -0
  43. data/spec/assets/corrupt.png +0 -0
  44. data/spec/assets/header.html +0 -7
  45. data/spec/assets/html-override.css +0 -1
  46. data/spec/assets/html.scss +0 -13
  47. data/spec/assets/htmlcover.html +0 -4
  48. data/spec/assets/htmlintro.html +0 -5
  49. data/spec/assets/i18n.yaml +0 -17
  50. data/spec/assets/iso.adoc +0 -10
  51. data/spec/assets/iso.headless.html +0 -33
  52. data/spec/assets/iso.xml +0 -8
  53. data/spec/assets/iso123.rxl +0 -107
  54. data/spec/assets/rice_image1.png +0 -0
  55. data/spec/assets/scripts.html +0 -3
  56. data/spec/assets/std.css +0 -2
  57. data/spec/assets/word-override.css +0 -1
  58. data/spec/assets/word.scss +0 -13
  59. data/spec/assets/wordcover.html +0 -3
  60. data/spec/assets/wordintro.html +0 -4
  61. data/spec/assets/xref_error.adoc +0 -8
  62. data/spec/examples/103_01_02.html +0 -247
  63. data/spec/examples/codes_table.html +0 -3174
  64. data/spec/examples/datamodel/address_class_profile.adoc +0 -5
  65. data/spec/examples/datamodel/address_class_profile.presentation.xml +0 -14
  66. data/spec/examples/datamodel/address_component_profile.adoc +0 -5
  67. data/spec/examples/datamodel/blank_definition_profile.adoc +0 -5
  68. data/spec/examples/datamodel/common_models_diagram.adoc +0 -5
  69. data/spec/examples/datamodel/models/models/AddressClassProfile.yml +0 -90
  70. data/spec/examples/datamodel/models/models/AddressComponentProfile.yml +0 -63
  71. data/spec/examples/datamodel/models/models/AddressComponentSpecification.yml +0 -15
  72. data/spec/examples/datamodel/models/models/AddressProfile.yml +0 -36
  73. data/spec/examples/datamodel/models/models/AttributeProfile.yml +0 -32
  74. data/spec/examples/datamodel/models/models/InterchangeAddressClassProfile.yml +0 -79
  75. data/spec/examples/datamodel/models/models/Localization copy.yml +0 -23
  76. data/spec/examples/datamodel/models/models/Localization.yml +0 -23
  77. data/spec/examples/datamodel/models/models/ProfileCompliantAddress.yml +0 -36
  78. data/spec/examples/datamodel/models/models/ProfileCompliantAddressComponent.yml +0 -15
  79. data/spec/examples/datamodel/models/models/Signature.yml +0 -20
  80. data/spec/examples/datamodel/models/models/SignatureBlankDefinition.yml +0 -20
  81. data/spec/examples/datamodel/models/models/TextDirectionCode copy.yml +0 -16
  82. data/spec/examples/datamodel/models/models/TextDirectionCode.yml +0 -16
  83. data/spec/examples/datamodel/models/models/Validity.yml +0 -14
  84. data/spec/examples/datamodel/models/models/iso19160-1/Address.yml +0 -22
  85. data/spec/examples/datamodel/models/models/iso19160-1/AddressComponent.yml +0 -2
  86. data/spec/examples/datamodel/models/style.uml.inc +0 -37
  87. data/spec/examples/datamodel/models/views/CommonModels.yml +0 -9
  88. data/spec/examples/datamodel/models/views/TopDown.yml +0 -62
  89. data/spec/examples/datamodel/top_down_diagram.adoc +0 -5
  90. data/spec/examples/english.yaml +0 -69
  91. data/spec/examples/iso_123_.xml +0 -46
  92. data/spec/examples/iso_123_all_parts.xml +0 -46
  93. data/spec/examples/iso_123_no_year_note.xml +0 -47
  94. data/spec/examples/iso_124_.xml +0 -42
  95. data/spec/examples/iso_216_.xml +0 -48
  96. data/spec/examples/iso_iec_12382_.xml +0 -49
  97. data/spec/examples/rice.adoc +0 -715
  98. data/spec/examples/rice.preview.html +0 -1877
  99. data/spec/examples/rice.sh +0 -4
  100. data/spec/examples/rice_images/rice_image1.png +0 -0
  101. data/spec/examples/rice_images/rice_image2.png +0 -0
  102. data/spec/examples/rice_images/rice_image3_1.png +0 -0
  103. data/spec/examples/rice_images/rice_image3_2.png +0 -0
  104. data/spec/examples/rice_images/rice_image3_3.png +0 -0
  105. data/spec/fixtures/action_schemaexpg1.svg +0 -122
  106. data/spec/fixtures/datamodel_description_sections_tree.xml +0 -327
  107. data/spec/fixtures/diagram_definitions.lutaml +0 -22
  108. data/spec/fixtures/macros_datamodel/address_class_profile.xml +0 -149
  109. data/spec/fixtures/macros_datamodel/address_component_profile.xml +0 -71
  110. data/spec/fixtures/macros_datamodel/blank_definition_profile.xml +0 -51
  111. data/spec/fixtures/macros_datamodel/common_models_diagram.xml +0 -7
  112. data/spec/fixtures/macros_datamodel/top_down_diagram.xml +0 -7
  113. data/spec/fixtures/test.exp +0 -121
  114. data/spec/fixtures/test.xmi +0 -9250
  115. data/spec/metanorma/base_spec.rb +0 -1125
  116. data/spec/metanorma/biblio_spec.rb +0 -1004
  117. data/spec/metanorma/blank_spec.rb +0 -37
  118. data/spec/metanorma/blocks_spec.rb +0 -1784
  119. data/spec/metanorma/cleanup_blocks_spec.rb +0 -1099
  120. data/spec/metanorma/cleanup_sections_spec.rb +0 -1850
  121. data/spec/metanorma/cleanup_spec.rb +0 -1920
  122. data/spec/metanorma/cleanup_terms_spec.rb +0 -1543
  123. data/spec/metanorma/datamodel/attributes_table_preprocessor_spec.rb +0 -111
  124. data/spec/metanorma/datamodel/diagram_preprocessor_spec.rb +0 -72
  125. data/spec/metanorma/inline_spec.rb +0 -724
  126. data/spec/metanorma/isobib_cache_spec.rb +0 -742
  127. data/spec/metanorma/lists_spec.rb +0 -232
  128. data/spec/metanorma/macros_concept_spec.rb +0 -1052
  129. data/spec/metanorma/macros_json2text_spec.rb +0 -10
  130. data/spec/metanorma/macros_plantuml_spec.rb +0 -402
  131. data/spec/metanorma/macros_spec.rb +0 -1183
  132. data/spec/metanorma/macros_yaml2text_spec.rb +0 -10
  133. data/spec/metanorma/processor_spec.rb +0 -96
  134. data/spec/metanorma/refs_spec.rb +0 -2807
  135. data/spec/metanorma/reqt_spec.rb +0 -130
  136. data/spec/metanorma/section_spec.rb +0 -1325
  137. data/spec/metanorma/table_spec.rb +0 -474
  138. data/spec/metanorma/validate_spec.rb +0 -886
  139. data/spec/spec_helper.rb +0 -290
  140. data/spec/support/shared_examples/structured_data_2_text_preprocessor.rb +0 -781
  141. data/spec/vcr_cassettes/bsi16341.yml +0 -488
  142. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +0 -611
  143. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec1.yml +0 -149
  144. data/spec/vcr_cassettes/hide_refs.yml +0 -587
  145. data/spec/vcr_cassettes/isobib_get_123.yml +0 -149
  146. data/spec/vcr_cassettes/isobib_get_123_1.yml +0 -295
  147. data/spec/vcr_cassettes/isobib_get_123_1_fr.yml +0 -385
  148. data/spec/vcr_cassettes/isobib_get_123_2.yml +0 -295
  149. data/spec/vcr_cassettes/isobib_get_123_2001.yml +0 -149
  150. data/spec/vcr_cassettes/isobib_get_124.yml +0 -149
  151. data/spec/vcr_cassettes/rfcbib_get_rfc8341.yml +0 -351
  152. data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +0 -560
  153. data/spec/vcr_cassettes/std-link.yml +0 -149
@@ -1,113 +1,6 @@
1
- require "set"
2
- require "relaton_bib"
3
-
4
1
  module Metanorma
5
2
  module Standoc
6
3
  module Cleanup
7
- def ref_dl_cleanup(xmldoc)
8
- xmldoc.xpath("//clause[@bibitem = 'true']").each do |c|
9
- bib = dl_bib_extract(c) or next
10
- validate_ref_dl(bib, c)
11
- bibitemxml = RelatonBib::BibliographicItem.from_hash(bib).to_xml or next
12
- bibitem = Nokogiri::XML(bibitemxml)
13
- bibitem.root["id"] = c["id"] if c["id"] && !/^_/.match(c["id"])
14
- c.replace(bibitem.root)
15
- end
16
- end
17
-
18
- # do not accept implicit id
19
- def validate_ref_dl(bib, clause)
20
- id = bib["id"]
21
- id ||= clause["id"] unless /^_/.match?(clause["id"])
22
- unless id
23
- @log.add("Anchors", clause,
24
- "The following reference is missing an anchor:\n"\
25
- "#{clause.to_xml}")
26
- return
27
- end
28
- @refids << id
29
- validate_ref_dl1(bib, id, clause)
30
- end
31
-
32
- def validate_ref_dl1(bib, id, clause)
33
- bib["title"] or
34
- @log.add("Bibliography", clause, "Reference #{id} is missing a title")
35
- bib["docid"] or
36
- @log.add("Bibliography", clause,
37
- "Reference #{id} is missing a document identifier (docid)")
38
- end
39
-
40
- def extract_from_p(tag, bib, key)
41
- return unless bib[tag]
42
-
43
- "<#{key}>#{bib[tag].at('p').children}</#{key}>"
44
- end
45
-
46
- # if the content is a single paragraph, replace it with its children
47
- # single links replaced with uri
48
- def p_unwrap(para)
49
- elems = para.elements
50
- if elems.size == 1 && elems[0].name == "p"
51
- link_unwrap(elems[0]).children.to_xml.strip
52
- else
53
- para.to_xml.strip
54
- end
55
- end
56
-
57
- def link_unwrap(para)
58
- elems = para.elements
59
- if elems.size == 1 && elems[0].name == "link"
60
- para.at("./link").replace(elems[0]["target"].strip)
61
- end
62
- para
63
- end
64
-
65
- def dd_bib_extract(dtd)
66
- return nil if dtd.children.empty?
67
-
68
- dtd.at("./dl") and return dl_bib_extract(dtd)
69
- elems = dtd.remove.elements
70
- return p_unwrap(dtd) unless elems.size == 1 &&
71
- %w(ol ul).include?(elems[0].name)
72
-
73
- elems[0].xpath("./li").each_with_object([]) do |li, ret|
74
- ret << p_unwrap(li)
75
- end
76
- end
77
-
78
- def add_to_hash(bib, key, val)
79
- Metanorma::Utils::set_nested_value(bib, key.split("."), val)
80
- end
81
-
82
- # definition list, with at most one level of unordered lists
83
- def dl_bib_extract(clause, nested = false)
84
- dl = clause.at("./dl") or return
85
- key = ""
86
- bib = dl.xpath("./dt | ./dd").each_with_object({}) do |dtd, m|
87
- (dtd.name == "dt" and key = dtd.text.sub(/:+$/, "")) and next
88
- add_to_hash(m, key, dd_bib_extract(dtd))
89
- end
90
- clause.xpath("./clause").each do |c1|
91
- key = c1&.at("./title")&.text&.downcase&.strip
92
- next unless %w(contributor relation series).include? key
93
-
94
- add_to_hash(bib, key, dl_bib_extract(c1, true))
95
- end
96
- dl_bib_extract_title(bib, clause, nested)
97
- end
98
-
99
- def dl_bib_extract_title(bib, clause, nested)
100
- (!nested && clause.at("./title")) or return bib
101
- title = clause.at("./title").remove.children.to_xml
102
- bib["title"] = [bib["title"]] if bib["title"].is_a?(Hash) ||
103
- bib["title"].is_a?(String)
104
- bib["title"] ||= []
105
- bib["title"] << title if !title.empty?
106
- bib
107
- end
108
-
109
- # ---
110
-
111
4
  def formattedref_spans(xmldoc)
112
5
  xmldoc.xpath("//bibitem[formattedref//span]").each do |b|
113
6
  spans = spans_preprocess(extract_content(b))
@@ -156,7 +49,8 @@ module Metanorma
156
49
  def span_preprocess1(span, ret)
157
50
  case span[:key]
158
51
  when "uri", "docid"
159
- ret[span[:key].to_sym] << { type: span[:type], val: span[:val] }
52
+ val = link_unwrap(Nokogiri::XML.fragment(span[:val])).to_xml
53
+ ret[span[:key].to_sym] << { type: span[:type], val: val }
160
54
  when "date"
161
55
  ret[span[:key].to_sym] << { type: span[:type] || "published",
162
56
  val: span[:val] }
@@ -263,10 +157,11 @@ module Metanorma
263
157
 
264
158
  def span_to_extent(span, key)
265
159
  values = span.split(/[-–]/)
266
- ret = "<extent type='#{key}'><referenceFrom>#{values[0]}</referenceFrom>"
160
+ ret = "<extent type='#{key}'><locality>" \
161
+ "<referenceFrom>#{values[0]}</referenceFrom>"
267
162
  values[1] and
268
163
  ret += "<referenceTo>#{values[1]}</referenceTo>"
269
- "#{ret}</extent>"
164
+ "#{ret}</locality></extent>"
270
165
  end
271
166
 
272
167
  def span_to_docid(span, key)
@@ -287,10 +182,10 @@ module Metanorma
287
182
 
288
183
  def span_to_person(span)
289
184
  pre = (span[:"formatted-initials"] and
290
- "<formatted-initials>"\
185
+ "<formatted-initials>" \
291
186
  "#{span[:"formatted-initials"]}</formatted-initials>") ||
292
187
  "<forename>#{span[:givenname]}</forename>"
293
- "<person><name>#{pre}<surname>#{span[:surname]}</surname></name>"\
188
+ "<person><name>#{pre}<surname>#{span[:surname]}</surname></name>" \
294
189
  "</person>"
295
190
  end
296
191
  end
@@ -7,7 +7,8 @@ module Metanorma
7
7
  def para_cleanup(xmldoc)
8
8
  ["//p[not(ancestor::bibdata)]", "//ol[not(ancestor::bibdata)]",
9
9
  "//ul[not(ancestor::bibdata)]", "//quote[not(ancestor::bibdata)]",
10
- "//note[not(ancestor::bibitem or "\
10
+ "//dl[not(ancestor::bibdata)]",
11
+ "//note[not(ancestor::bibitem or " \
11
12
  "ancestor::table or ancestor::bibdata)]"].each do |w|
12
13
  inject_id(xmldoc, w)
13
14
  end
@@ -106,7 +107,7 @@ module Metanorma
106
107
  prev = n.previous_element || next
107
108
  n.parent = prev if ELEMS_ALLOW_NOTES.include? prev.name
108
109
  end
109
- xmldoc.xpath("//note[@keep-separate] | "\
110
+ xmldoc.xpath("//note[@keep-separate] | " \
110
111
  "//termnote[@keep-separate]").each do |n|
111
112
  n.delete("keep-separate")
112
113
  end
@@ -182,10 +183,10 @@ module Metanorma
182
183
  end
183
184
 
184
185
  def block_index_cleanup(xmldoc)
185
- xmldoc.xpath("//quote | //td | //th | //formula | //li | //dt | "\
186
- "//dd | //example | //note | //figure | //sourcecode | "\
187
- "//admonition | //termnote | //termexample | //form | "\
188
- "//requirement | //recommendation | //permission | "\
186
+ xmldoc.xpath("//quote | //td | //th | //formula | //li | //dt | " \
187
+ "//dd | //example | //note | //figure | //sourcecode | " \
188
+ "//admonition | //termnote | //termexample | //form | " \
189
+ "//requirement | //recommendation | //permission | " \
189
190
  "//imagemap | //svgmap").each do |b|
190
191
  b.xpath("./p[indexterm]").each do |p|
191
192
  indexterm_para?(p) or next
@@ -53,11 +53,11 @@ module Metanorma
53
53
  end
54
54
  end
55
55
 
56
- TERM_CLAUSE = "//sections/terms | "\
56
+ TERM_CLAUSE = "//sections/terms | " \
57
57
  "//sections/clause[descendant::terms]".freeze
58
58
 
59
59
  NORM_REF =
60
- "//bibliography/references[@normative = 'true'][not(@hidden)] | "\
60
+ "//bibliography/references[@normative = 'true'][not(@hidden)] | " \
61
61
  "//bibliography/clause[.//references[@normative = 'true']]".freeze
62
62
 
63
63
  def boilerplate_isodoc(xmldoc)
@@ -79,7 +79,7 @@ module Metanorma
79
79
 
80
80
  def unwrap_boilerplate_clauses(xmldoc, xpath)
81
81
  xmldoc.xpath(xpath).each do |f|
82
- f.xpath(".//clause[@type = 'boilerplate'] | "\
82
+ f.xpath(".//clause[@type = 'boilerplate'] | " \
83
83
  ".//note[@type = 'boilerplate']").each do |c|
84
84
  c&.at("./title")&.remove
85
85
  c.replace(c.children)
@@ -175,9 +175,9 @@ module Metanorma
175
175
  end
176
176
 
177
177
  def indirect_eref_to_xref(eref, ident)
178
- loc = eref&.at("./localityStack[locality[@type = 'anchor']]")
178
+ loc = eref.at("./localityStack[locality[@type = 'anchor']]")
179
179
  &.remove&.text ||
180
- eref&.at("./locality[@type = 'anchor']")&.remove&.text || ident
180
+ eref.at("./locality[@type = 'anchor']")&.remove&.text || ident
181
181
  eref.name = "xref"
182
182
  eref.delete("bibitemid")
183
183
  eref.delete("citeas")
@@ -213,7 +213,7 @@ module Metanorma
213
213
  def bibdata_embed_hdr_cleanup(xmldoc)
214
214
  return if @embed_hdr.nil? || @embed_hdr.empty?
215
215
 
216
- xmldoc.at("//bibdata") << "<relation type='derivedFrom'>"\
216
+ xmldoc.at("//bibdata") << "<relation type='derivedFrom'>" \
217
217
  "#{hdr2bibitem(@embed_hdr.first)}</relation>"
218
218
  end
219
219
 
@@ -35,7 +35,7 @@ module Metanorma
35
35
 
36
36
  def li_bookmark_cleanup(xmldoc)
37
37
  xmldoc.xpath("//li[descendant::bookmark]").each do |x|
38
- if x.at("./*[1][local-name() = 'p']/"\
38
+ if x.at("./*[1][local-name() = 'p']/" \
39
39
  "*[1][local-name() = 'bookmark']") &&
40
40
  empty_text_before_first_element(x.elements[0])
41
41
  bookmark_to_id(x, x.elements[0].elements[0])
@@ -45,7 +45,7 @@ module Metanorma
45
45
 
46
46
  def dt_bookmark_cleanup(xmldoc)
47
47
  xmldoc.xpath("//dt[descendant::bookmark]").each do |x|
48
- if x.at("./*[1][local-name() = 'p']/"\
48
+ if x.at("./*[1][local-name() = 'p']/" \
49
49
  "*[1][local-name() = 'bookmark']") &&
50
50
  empty_text_before_first_element(x.elements[0])
51
51
  bookmark_to_id(x, x.elements[0].elements[0])
@@ -8,16 +8,24 @@ module Metanorma
8
8
  "<amathstem>#{@c.decode($1)}</amathstem>"
9
9
  end
10
10
  text = Html2Doc.new({})
11
- .asciimath_to_mathml(text, ["<amathstem>", "</amathstem>"])
12
- x = Nokogiri::XML(text)
11
+ .asciimath_to_mathml(text, ["<amathstem>", "</amathstem>"],
12
+ retain_asciimath: true)
13
+ asciimath2mathml_wrap(text)
14
+ end
15
+
16
+ def asciimath2mathml_wrap(text)
17
+ x = Nokogiri::XML(text)
13
18
  x.xpath("//*[local-name() = 'math'][not(parent::stem)]").each do |y|
14
19
  y.wrap("<stem type='MathML'></stem>")
15
20
  end
16
- x.to_xml
21
+ x.xpath("//stem").each do |y|
22
+ y.next_element&.name == "asciimath" and y << y.next_element
23
+ end
24
+ to_xml(x)
17
25
  end
18
26
 
19
27
  def xml_unescape_mathml(xml)
20
- return if xml.children.any? { |y| y.element? }
28
+ return if xml.children.any?(&:element?)
21
29
 
22
30
  math = xml.text.gsub(/&lt;/, "<").gsub(/&gt;/, ">")
23
31
  .gsub(/&quot;/, '"').gsub(/&apos;/, "'").gsub(/&amp;/, "&")
@@ -8,7 +8,7 @@ module Metanorma
8
8
  module Standoc
9
9
  module Cleanup
10
10
  def make_preface(xml, sect)
11
- if xml.at("//foreword | //introduction | //acknowledgements | "\
11
+ if xml.at("//foreword | //introduction | //acknowledgements | " \
12
12
  "//*[@preface]")
13
13
  preface = sect.add_previous_sibling("<preface/>").first
14
14
  f = xml.at("//foreword") and preface.add_child f.remove
@@ -33,21 +33,24 @@ module Metanorma
33
33
  abstract = xml.at("//abstract[not(ancestor::bibitem)]").remove
34
34
  preface.prepend_child abstract.remove
35
35
  bibabstract = bibabstract_location(xml)
36
- dupabstract = abstract.dup
37
- dupabstract.traverse { |n| n.remove_attribute("id") }
38
- dupabstract.remove_attribute("language")
39
- dupabstract.remove_attribute("script")
40
- dupabstract&.at("./title")&.remove
41
- bibabstract.next = dupabstract
36
+ bibabstract.next = clean_abstract(abstract.dup)
42
37
  end
43
38
  end
44
39
 
40
+ def clean_abstract(dupabstract)
41
+ dupabstract.traverse { |n| n.remove_attribute("id") }
42
+ dupabstract.remove_attribute("language")
43
+ dupabstract.remove_attribute("script")
44
+ dupabstract.at("./title")&.remove
45
+ dupabstract
46
+ end
47
+
45
48
  def bibabstract_location(xml)
46
49
  xml.at("//bibdata/script") || xml.at("//bibdata/language") ||
47
50
  xml.at("//bibdata/contributor[not(following-sibling::contributor)]") ||
48
51
  xml.at("//bibdata/date[not(following-sibling::date)]") ||
49
52
  xml.at("//docnumber") ||
50
- xml.at("//bibdata/docidentifier"\
53
+ xml.at("//bibdata/docidentifier" \
51
54
  "[not(following-sibling::docidentifier)]") ||
52
55
  xml.at("//bibdata/uri[not(following-sibling::uri)]") ||
53
56
  xml.at("//bibdata/title[not(following-sibling::title)]")
@@ -111,6 +114,7 @@ module Metanorma
111
114
  end
112
115
 
113
116
  def sections_cleanup(xml)
117
+ misccontainer_cleanup(xml)
114
118
  sections_order_cleanup(xml)
115
119
  sections_level_cleanup(xml)
116
120
  sections_names_cleanup(xml)
@@ -118,6 +122,12 @@ module Metanorma
118
122
  change_clauses(xml)
119
123
  end
120
124
 
125
+ def misccontainer_cleanup(xml)
126
+ m = xml.at("//misc-container-clause") or return
127
+ ins = add_misc_container(xml)
128
+ ins << m.remove.children
129
+ end
130
+
121
131
  def single_clause_annex(xml)
122
132
  xml.xpath("//annex").each do |a|
123
133
  single_clause_annex1(a)
@@ -131,7 +141,7 @@ module Metanorma
131
141
  end
132
142
 
133
143
  def obligations_cleanup_info(xml)
134
- xml.xpath("//foreword | //introduction | //acknowledgements | "\
144
+ xml.xpath("//foreword | //introduction | //acknowledgements | " \
135
145
  "//references | //preface//clause").each do |r|
136
146
  r["obligation"] = "informative"
137
147
  end
@@ -5,18 +5,25 @@ module Metanorma
5
5
  # letter (x, x_m, x_1, xa); we use colon to force that sort order.
6
6
  # Numbers sort *after* letters; we use thorn to force that sort order.
7
7
  def symbol_key(sym)
8
- key = sym.dup
9
- key.traverse do |n|
10
- n.name == "math" and
11
- n.replace(grkletters(MathML2AsciiMath.m2a(n.to_xml)))
12
- end
13
- ret = Nokogiri::XML(key.to_xml)
14
- @c.decode(ret.text.downcase)
8
+ @c.decode(asciimath_key(sym).text.downcase)
15
9
  .gsub(/[\[\]{}<>()]/, "").gsub(/\s/m, "")
16
10
  .gsub(/[[:punct:]]|[_^]/, ":\\0").gsub(/`/, "")
17
11
  .gsub(/[0-9]+/, "þ\\0")
18
12
  end
19
13
 
14
+ def asciimath_key(sym)
15
+ key = sym.dup
16
+ key.traverse do |n|
17
+ if n.name == "math"
18
+ n.children = @c.encode(
19
+ @c.decode(grkletters(MathML2AsciiMath.m2a(n.to_xml))), :basic
20
+ )
21
+ end
22
+ end
23
+ key.xpath(".//asciimath").each(&:remove)
24
+ Nokogiri::XML(key.to_xml)
25
+ end
26
+
20
27
  def grkletters(text)
21
28
  text.gsub(/\b(alpha|beta|gamma|delta|epsilon|zeta|eta|theta|iota|kappa|
22
29
  lambda|mu|nu|xi|omicron|pi|rho|sigma|tau|upsilon|phi|chi|
@@ -35,7 +35,8 @@ module Metanorma
35
35
  end
36
36
 
37
37
  IGNORE_QUOTES_ELEMENTS =
38
- %w(pre tt sourcecode stem figure bibdata passthrough identifier).freeze
38
+ %w(pre tt sourcecode stem asciimath figure bibdata passthrough
39
+ identifier).freeze
39
40
 
40
41
  def uninterrupt_quotes_around_xml_skip(elem)
41
42
  !(/\A['"]/.match?(elem.text) &&
@@ -43,7 +44,7 @@ module Metanorma
43
44
  .intersection(IGNORE_QUOTES_ELEMENTS).empty? &&
44
45
  ((elem.previous.text.strip.empty? &&
45
46
  !empty_tag_with_text_content?(elem.previous)) ||
46
- elem.previous.name == "index"))
47
+ ignoretext?(elem.previous)))
47
48
  end
48
49
 
49
50
  def uninterrupt_quotes_around_xml1(elem)
@@ -56,13 +57,20 @@ module Metanorma
56
57
  prev.content = "#{prev.text}#{m[1]}"
57
58
  end
58
59
 
60
+ IGNORE_TEXT_ELEMENTS =
61
+ %w(index fn).freeze
62
+
63
+ def ignoretext?(elem)
64
+ IGNORE_TEXT_ELEMENTS.include? elem.name
65
+ end
66
+
59
67
  def block?(elem)
60
68
  %w(title name variant-title clause figure annex example introduction
61
69
  foreword acknowledgements note li th td dt dd p quote label
62
70
  abstract preferred admitted related deprecates field-of-application
63
71
  usage-info expression pronunciation grammar-value domain
64
72
  definition termnote termexample modification description
65
- newcontent floating-title).include? elem.name
73
+ newcontent floating-title tab).include? elem.name
66
74
  end
67
75
 
68
76
  def empty_tag_with_text_content?(elem)
@@ -79,7 +87,7 @@ module Metanorma
79
87
  ancestors = x.path.split(%r{/})[1..-2]
80
88
  ancestors.intersection(IGNORE_QUOTES_ELEMENTS).empty? and
81
89
  dumb2smart_quotes1(x, prev)
82
- prev = x.text unless ancestors.include?("index")
90
+ prev = x.text if ancestors.intersection(IGNORE_TEXT_ELEMENTS).empty?
83
91
  end
84
92
  end
85
93
 
@@ -93,9 +101,14 @@ module Metanorma
93
101
 
94
102
  def dumbquote_cleanup(xmldoc)
95
103
  xmldoc.traverse do |n|
96
- next unless n.text?
104
+ next unless n.text? && /\u2019/.match?(n.text)
97
105
 
98
- n.replace(n.text.gsub(/(?<=\p{Alnum})\u2019(?=\p{Alpha})/, "'")) # .
106
+ # n.replace(n.text.gsub(/(?<=\p{Alnum})\u2019(?=\p{Alpha})/, "'")) # .
107
+ n.replace(@c.encode(
108
+ @c.decode(n.text)
109
+ .gsub(/(?<=\p{Alnum})\u2019(?=\p{Alpha})/, "'"),
110
+ :basic, :hexadecimal
111
+ ))
99
112
  end
100
113
  end
101
114
  end
@@ -80,8 +80,7 @@ module Metanorma
80
80
  def toc_metadata(xmldoc)
81
81
  return unless @htmltoclevels || @doctoclevels || @toclevels
82
82
 
83
- ins = xmldoc.at("//misc-container") ||
84
- xmldoc.at("//bibdata").after("<misc-container/>").next_element
83
+ ins = add_misc_container(xmldoc)
85
84
  toc_metadata1(ins)
86
85
  end
87
86
 
@@ -20,10 +20,10 @@ module Metanorma
20
20
  end
21
21
 
22
22
  def extract_localities(elem)
23
- f = elem&.children&.first or return
23
+ f = elem.children&.first or return
24
24
  f.text? or return
25
25
  head = f.remove.text
26
- tail = elem&.children&.remove
26
+ tail = elem.children&.remove
27
27
  extract_localities1(elem, head)
28
28
  tail and elem << tail
29
29
  end
@@ -45,7 +45,7 @@ module Metanorma
45
45
  ref =
46
46
  match[:ref] ? "<referenceFrom>#{tq match[:ref]}</referenceFrom>" : ""
47
47
  refto = match[:to] ? "<referenceTo>#{tq match[:to]}</referenceTo>" : ""
48
- stack.add_child("<locality type='#{locality_label(match)}'>#{ref}"\
48
+ stack.add_child("<locality type='#{locality_label(match)}'>#{ref}" \
49
49
  "#{refto}</locality>")
50
50
  end
51
51
 
@@ -67,7 +67,8 @@ module Metanorma
67
67
  /^locality:/.match?(loc) ? loc : loc&.downcase
68
68
  end
69
69
 
70
- def xref_to_eref(elem)
70
+ def xref_to_eref(elem, name)
71
+ elem.name = name
71
72
  elem["bibitemid"] = elem["target"]
72
73
  if ref = @anchors&.dig(elem["target"], :xref)
73
74
  elem["citeas"] = @c.decode(ref)
@@ -82,14 +83,49 @@ module Metanorma
82
83
  def xref_to_eref1(elem)
83
84
  @internal_eref_namespaces.include?(elem["type"]) or
84
85
  @log.add("Crossreferences", elem,
85
- "#{elem['target']} does not have a corresponding "\
86
+ "#{elem['target']} does not have a corresponding " \
86
87
  "anchor ID in the bibliography!")
87
88
  end
88
89
 
89
90
  def xref_cleanup(xmldoc)
91
+ anchor_alias(xmldoc)
90
92
  xref_compound_cleanup(xmldoc)
91
93
  xref_cleanup1(xmldoc)
92
94
  xref_compound_wrapup(xmldoc)
95
+ eref_stack(xmldoc)
96
+ end
97
+
98
+ def eref_stack(xmldoc)
99
+ xmldoc.xpath("//eref[eref]").each do |e|
100
+ e.name = "erefstack"
101
+ e.delete("bibitemid")
102
+ e.delete("citeas")
103
+ e.xpath("./eref").each do |e1|
104
+ e1["type"] = e["type"]
105
+ end
106
+ e.delete("type")
107
+ end
108
+ end
109
+
110
+ def anchor_alias(xmldoc)
111
+ t = xmldoc.at("//misc-container/table[@id = " \
112
+ "'_misccontainer_anchor_aliases']") or return
113
+ key = ""
114
+ t.xpath("./tbody/tr").each do |tr|
115
+ tr.xpath("./td | ./th").each_with_index do |td, i|
116
+ if i.zero? then key = td.text
117
+ else anchor_alias1(key, td)
118
+ end
119
+ end
120
+ end
121
+ end
122
+
123
+ def anchor_alias1(key, elem)
124
+ id = elem.text.strip
125
+ id.empty? and elem.at("./link") and
126
+ id = elem.at("./link/@target")&.text
127
+ (key && !id.empty?) or return
128
+ @anchor_alias[id] = key
93
129
  end
94
130
 
95
131
  def xref_compound_cleanup(xmldoc)
@@ -128,12 +164,12 @@ module Metanorma
128
164
 
129
165
  def xref_cleanup1(xmldoc)
130
166
  xmldoc.xpath("//xref").each do |x|
131
- /:/.match?(x["target"]) and xref_to_internal_eref(x)
167
+ %r{:(?!//)}.match?(x["target"]) and xref_to_internal_eref(x)
132
168
  next unless x.name == "xref"
133
169
 
134
170
  if refid? x["target"]
135
- x.name = "eref"
136
- xref_to_eref(x)
171
+ xref_to_eref(x, "eref")
172
+ elsif @anchor_alias[x["target"]] then xref_alias(x)
137
173
  else x.delete("type")
138
174
  end
139
175
  end
@@ -144,17 +180,22 @@ module Metanorma
144
180
  unless a.size < 2 || a[0].empty? || a[1].empty?
145
181
  elem["target"] = "#{a[0]}_#{a[1]}"
146
182
  a.size > 2 and
147
- elem.children = %{anchor="#{a[2..-1].join}",#{elem&.children&.text}}
183
+ elem.children = %{anchor="#{a[2..-1].join}",#{elem.children&.text}}
148
184
  elem["type"] = a[0]
149
185
  @internal_eref_namespaces << a[0]
150
- elem.name = "eref"
151
- xref_to_eref(elem)
186
+ xref_to_eref(elem, "eref")
152
187
  end
153
188
  end
154
189
 
190
+ def xref_alias(elem)
191
+ elem["style"] == "id" && elem.text.strip.empty? and
192
+ elem << elem["target"]
193
+ elem["target"] = @anchor_alias[elem["target"]]
194
+ end
195
+
155
196
  def quotesource_cleanup(xmldoc)
156
197
  xmldoc.xpath("//quote/source | //terms/source").each do |x|
157
- xref_to_eref(x)
198
+ xref_to_eref(x, "source")
158
199
  end
159
200
  end
160
201
 
@@ -165,9 +206,9 @@ module Metanorma
165
206
  xmldoc.xpath("//origin").each do |x|
166
207
  x["citeas"] = @anchors&.dig(x["bibitemid"], :xref) or
167
208
  @log.add("Crossreferences", x,
168
- "#{x['bibitemid']} does not have a corresponding anchor "\
209
+ "#{x['bibitemid']} does not have a corresponding anchor " \
169
210
  "ID in the bibliography!")
170
- extract_localities(x) unless x.children.empty?
211
+ x.children.empty? or extract_localities(x)
171
212
  end
172
213
  end
173
214
  end
@@ -40,28 +40,44 @@ module Metanorma
40
40
  end
41
41
 
42
42
  def inline_anchor_xref_attrs(node)
43
- m = inline_anchor_xref_match(node)
43
+ text = concatenate_attributes_to_xref_text(node)
44
+ m = inline_anchor_xref_match(text)
44
45
  t = node.target.gsub(/^#/, "").gsub(%r{(\.xml|\.adoc)(#.*$)}, "\\2")
45
- m.nil? and return { target: t, type: "inline", text: node.text }
46
- { target: t, type: m[:fn].nil? ? "inline" : "footnote",
47
- case: m[:case]&.sub(/%$/, ""),
48
- droploc: m[:drop].nil? && m[:drop2].nil? ? nil : true,
49
- text: inline_anchor_xref_text(m, node),
50
- hidden: m[:hidden] }
46
+ m.nil? and return { target: t, type: "inline", text: text }
47
+ inline_anchor_xref_attrs1(m, t, text)
51
48
  end
52
49
 
53
- def inline_anchor_xref_match(node)
50
+ def concatenate_attributes_to_xref_text(node)
51
+ node.attributes.each_with_object([]) do |(k, v), m|
52
+ next if %w(path fragment refid).include?(k)
53
+
54
+ m << "#{k}=#{v}%"
55
+ end.map { |x| x.sub(/%+/, "%") }.join + (node.text || "")
56
+ end
57
+
58
+ def inline_anchor_xref_attrs1(match, target, text)
59
+ { target: target,
60
+ type: match[:fn].nil? ? "inline" : "footnote",
61
+ case: match[:case]&.sub(/%$/, ""),
62
+ style: match[:style]&.sub(/^style=/, "")&.sub(/%$/, "") || @xrefstyle,
63
+ droploc: match[:drop].nil? && match[:drop2].nil? ? nil : true,
64
+ text: inline_anchor_xref_text(match, text),
65
+ hidden: match[:hidden] }
66
+ end
67
+
68
+ def inline_anchor_xref_match(text)
54
69
  /^(?:hidden%(?<hidden>[^,]+),?)?
70
+ (?<style>style=[^%]+%)?
55
71
  (?<drop>droploc%)?(?<case>capital%|lowercase%)?(?<drop2>droploc%)?
56
- (?<fn>fn:?\s*)?(?<text>.*)$/x.match node.text
72
+ (?<fn>fn:?\s*)?(?<text>.*)$/x.match text
57
73
  end
58
74
 
59
- def inline_anchor_xref_text(match, node)
60
- if %i[case fn drop drop2 hidden].any? do |x|
75
+ def inline_anchor_xref_text(match, text)
76
+ if %i[case fn drop drop2 hidden style].any? do |x|
61
77
  !match[x].nil?
62
78
  end
63
79
  match[:text]
64
- else node.text
80
+ else text
65
81
  end
66
82
  end
67
83
 
@@ -158,6 +174,7 @@ module Metanorma
158
174
  .elements[0]
159
175
  math.delete("alttext")
160
176
  s.parent.children = math
177
+ s << "<latexmath>#{text}</latexmath>"
161
178
  end
162
179
  end
163
180
 
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <grammar ns="https://www.metanorma.org/ns/standoc" xmlns="http://relaxng.org/ns/structure/1.0">
3
+ <!-- default namespace isostandard = "https://www.metanorma.com/ns/iso" -->
4
+ <include href="biblio-standoc.rng"/>
5
+ <include href="isodoc.rng"/>
6
+ </grammar>
7
+ <!-- end overrides -->