metanorma-standoc 2.0.3 → 2.0.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/lib/metanorma/standoc/base.rb +73 -23
  3. data/lib/metanorma/standoc/blocks.rb +1 -1
  4. data/lib/metanorma/standoc/blocks_notes.rb +2 -2
  5. data/lib/metanorma/standoc/cleanup_amend.rb +33 -30
  6. data/lib/metanorma/standoc/cleanup_boilerplate.rb +29 -5
  7. data/lib/metanorma/standoc/cleanup_ref.rb +31 -2
  8. data/lib/metanorma/standoc/cleanup_ref_dl.rb +25 -16
  9. data/lib/metanorma/standoc/cleanup_section.rb +1 -1
  10. data/lib/metanorma/standoc/cleanup_terms_designations.rb +4 -2
  11. data/lib/metanorma/standoc/cleanup_text.rb +39 -17
  12. data/lib/metanorma/standoc/cleanup_xref.rb +70 -8
  13. data/lib/metanorma/standoc/converter.rb +2 -1
  14. data/lib/metanorma/standoc/inline.rb +21 -12
  15. data/lib/metanorma/standoc/isodoc.rng +63 -3
  16. data/lib/metanorma/standoc/macros.rb +14 -2
  17. data/lib/metanorma/standoc/macros_embed.rb +35 -14
  18. data/lib/metanorma/standoc/macros_note.rb +4 -3
  19. data/lib/metanorma/standoc/processor.rb +6 -1
  20. data/lib/metanorma/standoc/ref.rb +14 -15
  21. data/lib/metanorma/standoc/ref_utility.rb +6 -5
  22. data/lib/metanorma/standoc/render.rb +7 -3
  23. data/lib/metanorma/standoc/table.rb +8 -10
  24. data/lib/metanorma/standoc/term_lookup_cleanup.rb +10 -6
  25. data/lib/metanorma/standoc/utils.rb +3 -1
  26. data/lib/metanorma/standoc/validate.rb +79 -10
  27. data/lib/metanorma/standoc/version.rb +1 -1
  28. data/metanorma-standoc.gemspec +2 -2
  29. data/spec/assets/a2.adoc +4 -2
  30. data/spec/assets/a3.adoc +2 -2
  31. data/spec/assets/a3a.adoc +7 -0
  32. data/spec/metanorma/base_spec.rb +1 -1
  33. data/spec/metanorma/cleanup_spec.rb +31 -20
  34. data/spec/metanorma/cleanup_terms_spec.rb +16 -4
  35. data/spec/metanorma/inline_spec.rb +31 -0
  36. data/spec/metanorma/macros_plantuml_spec.rb +41 -42
  37. data/spec/metanorma/macros_spec.rb +206 -4
  38. data/spec/metanorma/processor_spec.rb +17 -13
  39. data/spec/metanorma/refs_spec.rb +129 -2
  40. data/spec/metanorma/validate_spec.rb +108 -0
  41. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +45 -45
  42. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec1.yml +10 -10
  43. data/spec/vcr_cassettes/hide_refs.yml +39 -39
  44. data/spec/vcr_cassettes/isobib_get_123.yml +12 -12
  45. data/spec/vcr_cassettes/isobib_get_123_1.yml +23 -23
  46. data/spec/vcr_cassettes/isobib_get_123_1_fr.yml +28 -28
  47. data/spec/vcr_cassettes/isobib_get_123_2001.yml +11 -11
  48. data/spec/vcr_cassettes/isobib_get_124.yml +12 -12
  49. data/spec/vcr_cassettes/rfcbib_get_rfc8341.yml +18 -18
  50. data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +75 -65
  51. metadata +10 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cc4b55c7be36492191bd86bc19646a520c76e94bd2e2af9f96cf0d80d25fb05e
4
- data.tar.gz: 533fc5380552ab239528a559ee41a47c246203e17cb33df64cb5cdef5df21f34
3
+ metadata.gz: cfc9dd3ae0dd167d4c3b92c4b051619cde74ae602a66c9b34e363af1498682a0
4
+ data.tar.gz: 1cde7c4c003cdf59c2ef85e0ec1fc3247095716b6fc4f99b121c638f0744aaf9
5
5
  SHA512:
6
- metadata.gz: adc2d0b10dd30e5f59060b20574701dc6049b25a9d25eff06557ac51ca66645f62b553517690380009460f01fe135d26e83ab653b81c7746209e8f55221c3703
7
- data.tar.gz: 8bc78cf1ab42e80d93c8a22f0028e44e7ba735914fa43c2dcdd5eb53cb57b3a3ee52ea1677cae5033dbc738f8b444bc0dc2e5021ff08a443d991535c84c373b2
6
+ metadata.gz: af0f552acb3f93c8c2e1f1bff1ca60fadff61a5242e08bf0de29df086906a14025a1f6b2d2fb23a6e97afdd086fb60c9b812a91359056e6195a42a6d1d305630
7
+ data.tar.gz: cfad71e3de0a31950aee00c477a50449b97eb436ea6261584b73c616d7d24d30ab380ff7504b0357bd5e234752639a7705a43dca46f9f15983114ea50eaf2210
@@ -26,17 +26,54 @@ module Metanorma
26
26
  end
27
27
 
28
28
  def init(node)
29
+ init_vars
30
+ init_misc(node)
31
+ init_processing(node)
32
+ init_toc(node)
33
+ init_output(node)
34
+ init_i18n(node)
35
+ init_biblio(node)
36
+ @metadata_attrs = metadata_attrs(node)
37
+ end
38
+
39
+ def init_vars
29
40
  @fn_number ||= 0
30
- @draft = false
31
41
  @refids = Set.new
32
42
  @anchors = {}
33
43
  @internal_eref_namespaces = []
44
+ @seen_headers = []
45
+ @embed_hdr = []
46
+ end
47
+
48
+ def init_misc(node)
34
49
  @draft = node.attributes.has_key?("draft")
50
+ @index_terms = node.attr("index-terms")
51
+ @boilerplateauthority = node.attr("boilerplate-authority")
52
+ @embed_hdr = node.attr("embed_hdr")
53
+ end
54
+
55
+ def init_processing(node)
35
56
  @novalid = node.attr("novalid")
36
57
  @smartquotes = node.attr("smartquotes") != "false"
37
58
  @keepasciimath = node.attr("mn-keep-asciimath") &&
38
59
  node.attr("mn-keep-asciimath") != "false"
60
+ @sourcecode_markup_start = node.attr("sourcecode-markup-start") || "{{{"
61
+ @sourcecode_markup_end = node.attr("sourcecode-markup-end") || "}}}"
62
+ @datauriimage = node.attr("data-uri-image") != "false"
63
+ end
64
+
65
+ def init_toc(node)
66
+ @htmltoclevels = node.attr("htmltoclevels")
67
+ @doctoclevels = node.attr("doctoclevels")
68
+ @toclevels = node.attr("toclevels")
69
+ @tocfigures = node.attr("toc-figures")
70
+ @toctables = node.attr("toc-tables")
71
+ @tocrecommendations = node.attr("toc-recommendations")
72
+ end
73
+
74
+ def init_output(node)
39
75
  @fontheader = default_fonts(node)
76
+ @log = Metanorma::Utils::Log.new
40
77
  @files_to_delete = []
41
78
  @filename = if node.attr("docfile")
42
79
  File.basename(node.attr("docfile"))&.gsub(/\.adoc$/, "")
@@ -44,35 +81,26 @@ module Metanorma
44
81
  end
45
82
  @localdir = Metanorma::Utils::localdir(node)
46
83
  @output_dir = outputdir node
47
- @no_isobib_cache = node.attr("no-isobib-cache")
48
- @no_isobib = node.attr("no-isobib")
49
- @index_terms = node.attr("index-terms")
50
- @sourcecode_markup_start = node.attr("sourcecode-markup-start") || "{{{"
51
- @sourcecode_markup_end = node.attr("sourcecode-markup-end") || "}}}"
52
- @bibdb = nil
53
- @seen_headers = []
54
- @datauriimage = node.attr("data-uri-image") != "false"
55
- @boilerplateauthority = node.attr("boilerplate-authority")
56
- @sourcecode_markup_start = node.attr("sourcecode-markup-start") || "{{{"
57
- @sourcecode_markup_end = node.attr("sourcecode-markup-end") || "}}}"
58
- @log = Metanorma::Utils::Log.new
59
- init_bib_caches(node)
60
- init_iev_caches(node)
84
+ end
85
+
86
+ def init_i18n(node)
61
87
  @lang = (node.attr("language") || "en")
62
88
  @script = (node.attr("script") ||
63
89
  Metanorma::Utils.default_script(node.attr("language")))
64
90
  @isodoc = isodoc(@lang, @script, node.attr("i18nyaml"))
65
91
  @i18n = @isodoc.i18n
66
- @htmltoclevels = node.attr("htmltoclevels")
67
- @doctoclevels = node.attr("doctoclevels")
68
- @toclevels = node.attr("toclevels")
69
- @metadata_attrs = metadata_attrs(node)
92
+ end
93
+
94
+ def init_biblio(node)
95
+ @no_isobib_cache = node.attr("no-isobib-cache")
96
+ @no_isobib = node.attr("no-isobib")
97
+ @bibdb = nil
98
+ init_bib_caches(node)
99
+ init_iev_caches(node)
70
100
  end
71
101
 
72
102
  def document(node)
73
- init(node)
74
- ret = makexml(node).to_xml(encoding: "UTF-8", indent: 2)
75
- outputs(node, ret) unless node.attr("nodoc") || !node.attr("docfile")
103
+ ret = document1(node)
76
104
  clean_exit
77
105
  ret
78
106
  rescue StandardError => e
@@ -81,6 +109,28 @@ module Metanorma
81
109
  raise e
82
110
  end
83
111
 
112
+ def document1(node)
113
+ init(node)
114
+ ret = makexml(node)
115
+ .to_xml(encoding: "UTF-8", indent: 2,
116
+ save_with: Nokogiri::XML::Node::SaveOptions::AS_XML)
117
+ outputs(node, ret) unless node.attr("nodoc") || !node.attr("docfile")
118
+ ret
119
+ end
120
+
121
+ def insert_xml_cr(doc)
122
+ doc
123
+ .gsub(%r{(</(clause|table|figure|p|bibitem|ul|ol|dl|dt|dd|li|example|
124
+ sourcecode|formula|quote|references|annex|appendix|title|
125
+ name|note|thead|tbody|tfoot|th|td|form|requirement|
126
+ recommendation|permission|imagemap|svgmap|preferred|
127
+ admitted|related|deprecates|letter-symbol|domain|
128
+ graphical-symbol|expression|abbreviation-type|subject|
129
+ pronunciation|grammar|term|terms|termnote|termexample|
130
+ termsource|origin|termref|modification)>)}x, "\\1\n")
131
+ .gsub(%r{(<(title|name))}x, "\n\\1")
132
+ end
133
+
84
134
  def version
85
135
  flavour = self.class.name.sub(/::Converter$/, "").sub(/^.+::/, "")
86
136
  Metanorma.versioned(Metanorma, flavour)[-1]::VERSION
@@ -110,7 +160,7 @@ module Metanorma
110
160
 
111
161
  def makexml(node)
112
162
  result = makexml1(node)
113
- ret1 = cleanup(Nokogiri::XML(result))
163
+ ret1 = cleanup(Nokogiri::XML(insert_xml_cr(result)))
114
164
  ret1.root.add_namespace(nil, xml_namespace)
115
165
  validate(ret1) unless @novalid
116
166
  ret1
@@ -188,7 +188,7 @@ module Metanorma
188
188
 
189
189
  def quote_attribution(node, out)
190
190
  if node.attr("citetitle")
191
- m = /^(?<cite>[^,]+)(,(?<text>.*$))?$/m.match node.attr("citetitle")
191
+ m = /^(?<cite>[^,]+)(?:,(?<text>.*$))?$/m.match node.attr("citetitle")
192
192
  out.source **attr_code(target: m[:cite], type: "inline") do |s|
193
193
  s << m[:text]
194
194
  end
@@ -36,7 +36,7 @@ module Metanorma
36
36
  xml.review **sidebar_attrs(node) do |r|
37
37
  wrap_in_para(node, r)
38
38
  end
39
- end
39
+ end.join("\n")
40
40
  end
41
41
 
42
42
  def todo_attrs(node)
@@ -53,7 +53,7 @@ module Metanorma
53
53
  xml.review **todo_attrs(node) do |r|
54
54
  wrap_in_para(node, r)
55
55
  end
56
- end
56
+ end.join("\n")
57
57
  end
58
58
 
59
59
  def termnote(node)
@@ -1,53 +1,56 @@
1
1
  module Metanorma
2
2
  module Standoc
3
3
  module Cleanup
4
- def change_clauses(x)
5
- x.xpath("//clause[@change]").each do |c|
6
- a = create_amend(c)
4
+ def change_clauses(docxml)
5
+ docxml.xpath("//clause[@change]").each do |c|
6
+ create_amend(c)
7
7
  end
8
8
  end
9
9
 
10
- def create_amend(c)
11
- a = c.add_child("<amend id='_#{UUIDTools::UUID.random_create}'/>").first
12
- c.elements.each do |e|
10
+ def create_amend(clause)
11
+ a = clause.add_child("<amend id='_#{UUIDTools::UUID.random_create}'/>")
12
+ .first
13
+ clause.elements.each do |e|
13
14
  e.parent = a unless %w(amend title).include? e.name
14
15
  end
15
- create_amend1(c, a)
16
+ create_amend1(clause, a)
16
17
  end
17
18
 
18
- def create_amend1(c, a)
19
- create_amend2(c, a)
20
- d = a.at("./description")
19
+ def create_amend1(clause, amend)
20
+ create_amend2(clause, amend)
21
+ d = amend.at("./description")
21
22
  d.xpath(".//autonumber").each { |e| d.previous = e }
22
- d.xpath(".//p[normalize-space(.)='']").each { |e| e.remove }
23
- move_attrs_to_amend(c, a)
24
- a
23
+ d.xpath(".//p[normalize-space(.)='']").each(&:remove)
24
+ move_attrs_to_amend(clause, amend)
25
+ amend
25
26
  end
26
27
 
27
- def create_amend2(c, a)
28
- q = a.at("./quote") and q.name = "newcontent"
28
+ def create_amend2(_clause, amend)
29
+ q = amend.at("./quote") and q.name = "newcontent"
29
30
  if q.nil?
30
- a.children = "<description>#{a.children.to_xml}</description>"
31
- else
32
- pre = q&.xpath("./preceding-sibling::*")&.remove
33
- post = q&.xpath("./following-sibling::*")&.remove
34
- pre.empty? or a << "<description>#{pre.to_xml}</description>"
35
- a << q.remove
36
- post.empty? or a << "<description>#{post.to_xml}</description>"
31
+ amend.children = "<description>#{amend.children.to_xml}</description>"
32
+ return
37
33
  end
34
+ pre = q&.xpath("./preceding-sibling::*")&.remove
35
+ post = q&.xpath("./following-sibling::*")&.remove
36
+ pre.empty? or amend << "<description>#{pre.to_xml}</description>"
37
+ amend << q.remove
38
+ post.empty? or amend << "<description>#{post.to_xml}</description>"
38
39
  end
39
40
 
40
- def move_attrs_to_amend(c, a)
41
+ def move_attrs_to_amend(clause, amend)
41
42
  %w(change path path_end title).each do |e|
42
- next unless c[e]
43
- a[e] = c[e]
44
- c.delete(e)
43
+ next unless clause[e]
44
+
45
+ amend[e] = clause[e]
46
+ clause.delete(e)
45
47
  end
46
- return unless a["locality"]
47
- loc = a.children.add_previous_sibling("<location/>")
48
- extract_localities1(loc, a["locality"])
48
+ return unless amend["locality"]
49
+
50
+ loc = amend.children.add_previous_sibling("<location/>")
51
+ extract_localities1(loc, amend["locality"])
49
52
  loc1 = loc.at("./localityStack") and loc.replace(loc1.elements)
50
- a.delete("locality")
53
+ amend.delete("locality")
51
54
  end
52
55
  end
53
56
  end
@@ -56,9 +56,9 @@ module Metanorma
56
56
  TERM_CLAUSE = "//sections/terms | "\
57
57
  "//sections/clause[descendant::terms]".freeze
58
58
 
59
- NORM_REF = "//bibliography/references[@normative = 'true'] | "\
60
- "//bibliography/clause[.//references[@normative = 'true']]"
61
- .freeze
59
+ NORM_REF =
60
+ "//bibliography/references[@normative = 'true'][not(@hidden)] | "\
61
+ "//bibliography/clause[.//references[@normative = 'true']]".freeze
62
62
 
63
63
  def boilerplate_isodoc(xmldoc)
64
64
  x = xmldoc.dup
@@ -133,6 +133,7 @@ module Metanorma
133
133
  def bibdata_cleanup(xmldoc)
134
134
  bibdata_anchor_cleanup(xmldoc)
135
135
  bibdata_docidentifier_cleanup(xmldoc)
136
+ bibdata_embed_hdr_cleanup(xmldoc)
136
137
  biblio_indirect_erefs(xmldoc, @internal_eref_namespaces&.uniq)
137
138
  end
138
139
 
@@ -190,8 +191,8 @@ module Metanorma
190
191
  def resolve_local_indirect_erefs(xmldoc, refs, prefix)
191
192
  refs.each_with_object([]) do |r, m|
192
193
  id = r.sub(/^#{prefix}_/, "")
193
- if n = xmldoc.at("//*[@id = '#{id}']") and
194
- n.at("./ancestor-or-self::*[@type = '#{prefix}']")
194
+ n = xmldoc.at("//*[@id = '#{id}']")
195
+ if n&.at("./ancestor-or-self::*[@type = '#{prefix}']")
195
196
  xmldoc.xpath("//eref[@bibitemid = '#{r}']").each do |e|
196
197
  indirect_eref_to_xref(e, id)
197
198
  end
@@ -208,6 +209,29 @@ module Metanorma
208
209
  insert_indirect_biblio(xmldoc, refs, prefix)
209
210
  end
210
211
  end
212
+
213
+ def bibdata_embed_hdr_cleanup(xmldoc)
214
+ return if @embed_hdr.nil? || @embed_hdr.empty?
215
+
216
+ embed_recurse(xmldoc.at("//bibdata"), @embed_hdr.first)
217
+ end
218
+
219
+ def hdr2bibitem(hdr)
220
+ xml = Asciidoctor
221
+ .convert(hdr[:text], backend: Processor.new.asciidoctor_backend,
222
+ header_footer: true)
223
+ b = Nokogiri::XML(xml).at("//xmlns:bibdata")
224
+ b.name = "bibitem"
225
+ b.delete("type")
226
+ embed_recurse(b, hdr)
227
+ b.to_xml
228
+ end
229
+
230
+ def embed_recurse(bibitem, node)
231
+ node[:child].map { |x| hdr2bibitem(x) }.each do |x|
232
+ bibitem << "<relation type='derivedFrom'>#{x}</relation>"
233
+ end
234
+ end
211
235
  end
212
236
  end
213
237
  end
@@ -16,7 +16,7 @@ module Metanorma
16
16
  insert = refs&.at("./bibitem")&.previous_element
17
17
  refs.xpath("./bibitem").each(&:remove)
18
18
  bib.reverse.each do |b|
19
- insert and insert.next = b.to_xml or
19
+ (insert and insert.next = b.to_xml) or
20
20
  refs.children.first.add_previous_sibling b.to_xml
21
21
  end
22
22
  extract_notes_from_biblio(refs)
@@ -84,9 +84,39 @@ module Metanorma
84
84
  biblio_reorder(xmldoc)
85
85
  biblio_nested(xmldoc)
86
86
  biblio_renumber(xmldoc)
87
+ biblio_linkonly(xmldoc)
88
+ biblio_hidden_inherit(xmldoc)
87
89
  biblio_no_ext(xmldoc)
88
90
  end
89
91
 
92
+ def biblio_hidden_inherit(xmldoc)
93
+ xmldoc.xpath("//references[@hidden = 'true']").each do |r|
94
+ r.xpath("./bibitem").each do |b|
95
+ b["hidden"] = true
96
+ end
97
+ end
98
+ end
99
+
100
+ def biblio_linkonly(xmldoc)
101
+ return unless xmldoc.at("//xref[@hidden]")
102
+
103
+ ins = xmldoc.at("//bibliography")
104
+ .add_child("<references hidden='true' normative='true'/>").first
105
+ refs = xmldoc.xpath("//xref[@hidden]").each_with_object([]) do |x, m|
106
+ @refids << x["target"]
107
+ m << { id: x["target"], ref: x["hidden"] }
108
+ x.delete("hidden")
109
+ end
110
+ ins << insert_hidden_bibitems(refs)
111
+ end
112
+
113
+ def insert_hidden_bibitems(bib)
114
+ refs = bib.each_with_object([]) do |b, m|
115
+ m << reference1code(%(<ref id="#{b[:id]}">[#{b[:ref]}]</ref>), nil)
116
+ end
117
+ reference_populate(refs)
118
+ end
119
+
90
120
  def biblio_no_ext(xmldoc)
91
121
  xmldoc.xpath("//bibitem/ext").each(&:remove)
92
122
  end
@@ -114,7 +144,6 @@ module Metanorma
114
144
 
115
145
  def reference_names(xmldoc)
116
146
  xmldoc.xpath("//bibitem[not(ancestor::bibitem)]").each do |ref|
117
- # isopub = ref.at(ISO_PUBLISHER_XPATH)
118
147
  docid = ref.at("./docidentifier[@type = 'metanorma']") ||
119
148
  ref.at("./docidentifier[not(@type = 'DOI')]") or next
120
149
  reference = format_ref(docid.children.to_xml, docid["type"])
@@ -15,19 +15,25 @@ module Metanorma
15
15
  end
16
16
  end
17
17
 
18
- def validate_ref_dl(bib, c)
18
+ # do not accept implicit id
19
+ def validate_ref_dl(bib, clause)
19
20
  id = bib["id"]
20
- id ||= c["id"] unless /^_/.match?(c["id"]) # do not accept implicit id
21
+ id ||= clause["id"] unless /^_/.match?(clause["id"])
21
22
  unless id
22
- @log.add("Anchors", c,
23
- "The following reference is missing an anchor:\n" + c.to_xml)
23
+ @log.add("Anchors", clause,
24
+ "The following reference is missing an anchor:\n"\
25
+ "#{clause.to_xml}")
24
26
  return
25
27
  end
26
28
  @refids << id
29
+ validate_ref_dl1(bib, id, clause)
30
+ end
31
+
32
+ def validate_ref_dl1(bib, id, clause)
27
33
  bib["title"] or
28
- @log.add("Bibliography", c, "Reference #{id} is missing a title")
34
+ @log.add("Bibliography", clause, "Reference #{id} is missing a title")
29
35
  bib["docid"] or
30
- @log.add("Bibliography", c,
36
+ @log.add("Bibliography", clause,
31
37
  "Reference #{id} is missing a document identifier (docid)")
32
38
  end
33
39
 
@@ -76,27 +82,30 @@ module Metanorma
76
82
  end
77
83
 
78
84
  # definition list, with at most one level of unordered lists
79
- def dl_bib_extract(c, nested = false)
80
- dl = c.at("./dl") or return
85
+ def dl_bib_extract(clause, nested = false)
86
+ dl = clause.at("./dl") or return
81
87
  bib = {}
82
88
  key = ""
83
89
  dl.xpath("./dt | ./dd").each do |dtd|
84
90
  (dtd.name == "dt" and key = dtd.text.sub(/:+$/, "")) or
85
91
  add_to_hash(bib, key, dd_bib_extract(dtd))
86
92
  end
87
- c.xpath("./clause").each do |c1|
93
+ clause.xpath("./clause").each do |c1|
88
94
  key = c1&.at("./title")&.text&.downcase&.strip
89
95
  next unless %w(contributor relation series).include? key
90
96
 
91
97
  add_to_hash(bib, key, dl_bib_extract(c1, true))
92
98
  end
93
- if !nested && c.at("./title")
94
- title = c.at("./title").remove.children.to_xml
95
- bib["title"] = [bib["title"]] if bib["title"].is_a? Hash
96
- bib["title"] = [bib["title"]] if bib["title"].is_a? String
97
- bib["title"] = [] unless bib["title"]
98
- bib["title"] << title if !title.empty?
99
- end
99
+ dl_bib_extract_title(bib, clause, nested)
100
+ end
101
+
102
+ def dl_bib_extract_title(bib, clause, nested)
103
+ (!nested && clause.at("./title")) or return bib
104
+ title = clause.at("./title").remove.children.to_xml
105
+ bib["title"] = [bib["title"]] if bib["title"].is_a?(Hash) ||
106
+ bib["title"].is_a?(String)
107
+ bib["title"] = [] unless bib["title"]
108
+ bib["title"] << title if !title.empty?
100
109
  bib
101
110
  end
102
111
  end
@@ -54,7 +54,7 @@ module Metanorma
54
54
  end
55
55
 
56
56
  def make_bibliography(xml, sect)
57
- if xml.at("//sections/references")
57
+ if xml.at("//sections/references | //xref[@hidden]")
58
58
  biblio = sect.add_next_sibling("<bibliography/>").first
59
59
  xml.xpath("//sections/references").each do |r|
60
60
  biblio.add_child r.remove
@@ -182,10 +182,12 @@ module Metanorma
182
182
 
183
183
  def term_designation_reorder(xmldoc)
184
184
  xmldoc.xpath("//term").each do |t|
185
- %w(preferred admitted deprecates related)
185
+ des = %w(preferred admitted deprecates related)
186
186
  .each_with_object([]) do |tag, m|
187
187
  t.xpath("./#{tag}").each { |x| m << x.remove }
188
- end.reverse.each do |x|
188
+ end.reverse
189
+ t << " "
190
+ des.each do |x|
189
191
  t.children.first.previous = x
190
192
  end
191
193
  end
@@ -9,12 +9,6 @@ module Metanorma
9
9
  </passthrough>}mx) { HTMLEntities.new.decode($1) }
10
10
  end
11
11
 
12
- IGNORE_DUMBQUOTES =
13
- "//pre | //pre//* | //tt | //tt//* | "\
14
- "//sourcecode | //sourcecode//* | //bibdata//* | //stem | "\
15
- "//stem//* | //figure[@class = 'pseudocode'] | "\
16
- "//figure[@class = 'pseudocode']//*".freeze
17
-
18
12
  def smartquotes_cleanup(xmldoc)
19
13
  xmldoc.xpath("//date").each { |d| Metanorma::Utils::endash_date(d) }
20
14
  if @smartquotes then smartquotes_cleanup1(xmldoc)
@@ -31,14 +25,21 @@ module Metanorma
31
25
  def uninterrupt_quotes_around_xml(xmldoc)
32
26
  xmldoc.traverse do |n|
33
27
  next unless n.text? && n&.previous&.element?
34
- next unless /^['"]/.match?(n.text)
35
- next unless n.previous.ancestors("pre, tt, sourcecode, stem, figure")
36
- .empty?
28
+ next if uninterrupt_quotes_around_xml_skip(n)
37
29
 
38
30
  uninterrupt_quotes_around_xml1(n.previous)
39
31
  end
40
32
  end
41
33
 
34
+ def uninterrupt_quotes_around_xml_skip(elem)
35
+ !(/^['"]/.match?(elem.text) &&
36
+ elem.previous.ancestors("pre, tt, sourcecode, stem, figure, bibdata")
37
+ .empty? &&
38
+ ((elem.previous.text.strip.empty? &&
39
+ !empty_tag_with_text_content?(elem.previous)) ||
40
+ elem.previous.name == "index"))
41
+ end
42
+
42
43
  def uninterrupt_quotes_around_xml1(elem)
43
44
  prev = elem.at(".//preceding::text()[1]") or return
44
45
  /\S$/.match?(prev.text) or return
@@ -49,19 +50,40 @@ module Metanorma
49
50
  prev.content = "#{prev.text}#{m[1]}"
50
51
  end
51
52
 
52
- def dumb2smart_quotes(xmldoc)
53
- (xmldoc.xpath("//*[child::text()]") - xmldoc.xpath(IGNORE_DUMBQUOTES))
54
- .each do |x|
55
- x.children.each do |n|
56
- next unless n.text?
53
+ def block?(elem)
54
+ %w(title name variant-title clause figure annex example introduction
55
+ foreword acknowledgements note li th td dt dd p quote label
56
+ abstract preferred admitted related deprecates field-of-application
57
+ usage-info expression pronunciation grammar-value domain
58
+ definition termnote termexample modification description
59
+ newcontent floating-title).include? elem.name
60
+ end
57
61
 
58
- /[-'"(<>]|\.\.|\dx/.match(n) or next
62
+ def empty_tag_with_text_content?(elem)
63
+ %w(eref xref termref link).include? elem.name
64
+ end
59
65
 
60
- n.replace(Metanorma::Utils::smartformat(n.text))
61
- end
66
+ def dumb2smart_quotes(xmldoc)
67
+ prev = ""
68
+ xmldoc.traverse do |x|
69
+ block?(x) and prev = ""
70
+ empty_tag_with_text_content?(x) and prev = "dummy"
71
+ next unless x.text?
72
+
73
+ x.ancestors("pre, tt, sourcecode, stem, figure, bibdata").empty? and
74
+ dumb2smart_quotes1(x, prev)
75
+ prev = x.text if x.ancestors("index").empty?
62
76
  end
63
77
  end
64
78
 
79
+ def dumb2smart_quotes1(curr, prev)
80
+ /[-'"(<>]|\.\.|\dx/.match?(curr.text) or return
81
+
82
+ /^["']/.match?(curr.text) && prev.match?(/\S$/) and
83
+ curr.content = curr.text.sub(/^"/, "”").sub(/"’"/, "‘")
84
+ curr.replace(Metanorma::Utils::smartformat(curr.text))
85
+ end
86
+
65
87
  def dumbquote_cleanup(xmldoc)
66
88
  xmldoc.traverse do |n|
67
89
  next unless n.text?