metanorma-standoc 1.10.4.1 → 1.10.8

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 (61) hide show
  1. checksums.yaml +4 -4
  2. data/README.adoc +19 -23
  3. data/lib/asciidoctor/standoc/base.rb +11 -13
  4. data/lib/asciidoctor/standoc/basicdoc.rng +21 -4
  5. data/lib/asciidoctor/standoc/blocks.rb +27 -22
  6. data/lib/asciidoctor/standoc/blocks_notes.rb +17 -22
  7. data/lib/asciidoctor/standoc/cleanup.rb +38 -71
  8. data/lib/asciidoctor/standoc/cleanup_block.rb +5 -70
  9. data/lib/asciidoctor/standoc/cleanup_image.rb +6 -7
  10. data/lib/asciidoctor/standoc/cleanup_inline.rb +27 -98
  11. data/lib/asciidoctor/standoc/cleanup_maths.rb +113 -21
  12. data/lib/asciidoctor/standoc/cleanup_ref.rb +5 -0
  13. data/lib/asciidoctor/standoc/cleanup_reqt.rb +56 -18
  14. data/lib/asciidoctor/standoc/cleanup_section.rb +1 -0
  15. data/lib/asciidoctor/standoc/cleanup_section_names.rb +31 -14
  16. data/lib/asciidoctor/standoc/cleanup_table.rb +68 -0
  17. data/lib/asciidoctor/standoc/cleanup_terms.rb +1 -1
  18. data/lib/asciidoctor/standoc/cleanup_text.rb +73 -0
  19. data/lib/asciidoctor/standoc/cleanup_xref.rb +107 -0
  20. data/lib/asciidoctor/standoc/converter.rb +13 -0
  21. data/lib/asciidoctor/standoc/isodoc.rng +241 -61
  22. data/lib/asciidoctor/standoc/lists.rb +15 -15
  23. data/lib/asciidoctor/standoc/macros.rb +14 -43
  24. data/lib/asciidoctor/standoc/macros_note.rb +45 -0
  25. data/lib/asciidoctor/standoc/macros_terms.rb +33 -15
  26. data/lib/asciidoctor/standoc/reqt.rb +2 -2
  27. data/lib/asciidoctor/standoc/reqt.rng +23 -2
  28. data/lib/asciidoctor/standoc/table.rb +22 -20
  29. data/lib/asciidoctor/standoc/terms.rb +9 -1
  30. data/lib/asciidoctor/standoc/validate.rb +23 -14
  31. data/lib/asciidoctor/standoc/validate_section.rb +5 -2
  32. data/lib/metanorma/standoc/version.rb +1 -1
  33. data/metanorma-standoc.gemspec +1 -1
  34. data/spec/asciidoctor/base_spec.rb +0 -33
  35. data/spec/asciidoctor/blank_spec.rb +37 -0
  36. data/spec/asciidoctor/blocks_spec.rb +151 -30
  37. data/spec/asciidoctor/cleanup_blocks_spec.rb +1018 -0
  38. data/spec/asciidoctor/cleanup_sections_spec.rb +207 -0
  39. data/spec/asciidoctor/cleanup_spec.rb +193 -1078
  40. data/spec/asciidoctor/inline_spec.rb +36 -0
  41. data/spec/asciidoctor/isobib_cache_spec.rb +8 -8
  42. data/spec/asciidoctor/lists_spec.rb +6 -6
  43. data/spec/asciidoctor/macros_plantuml_spec.rb +1 -1
  44. data/spec/asciidoctor/macros_spec.rb +41 -26
  45. data/spec/asciidoctor/refs_dl_spec.rb +1 -1
  46. data/spec/asciidoctor/refs_spec.rb +220 -444
  47. data/spec/asciidoctor/section_spec.rb +1 -1
  48. data/spec/asciidoctor/validate_spec.rb +51 -0
  49. data/spec/assets/xref_error.adoc +1 -0
  50. data/spec/fixtures/datamodel_description_sections_tree.xml +24 -24
  51. data/spec/spec_helper.rb +5 -7
  52. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +231 -143
  53. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec1.yml +152 -0
  54. data/spec/vcr_cassettes/isobib_get_123.yml +52 -36
  55. data/spec/vcr_cassettes/isobib_get_123_1.yml +103 -71
  56. data/spec/vcr_cassettes/isobib_get_123_1_fr.yml +112 -80
  57. data/spec/vcr_cassettes/isobib_get_123_2001.yml +50 -34
  58. data/spec/vcr_cassettes/isobib_get_124.yml +51 -35
  59. data/spec/vcr_cassettes/rfcbib_get_rfc8341.yml +16 -16
  60. data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +70 -46
  61. metadata +11 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4de5b7f8779dae7c359b93ce364ffa7cc406156bf1437c7cdccb6595b7bd958a
4
- data.tar.gz: c35902148b405e451af8487faff391b6eddbbd7b07cd2b6c8d565cd515e4515c
3
+ metadata.gz: 2cc836755aed6cfff989fdcbc9cf8123ccfda29418247d93fdd75ba71660cee7
4
+ data.tar.gz: d1c051429283a6e4153a6a3453b839786561c0975c2acda0586cb0ca787ae26a
5
5
  SHA512:
6
- metadata.gz: 6e33b33321d6826a65257a3440c63218021d5d40b69fa58b268d0a2c5e8436aed951e05c7f44ab97c74b5ce916c25ad7040cc962cf38be15ee2ebaf0c6858529
7
- data.tar.gz: f8f719f8062c3c71ebd2883617b984d7432134cb94da1be308e9ede34bf74def5be6267570c76ff9f248e628e443d6b71a60b9f71e1ba436b7c64eb2c2b25c13
6
+ metadata.gz: 1e17a3351bf46679b587a82498d5f58d97e43743bd2e6906c929aa8dcbb8ca29fdd6e38acb82252375b40e5fff520f7d6a001b023c9c79681ad61fea949c0799
7
+ data.tar.gz: 01dd1e74b7990b44c526616611155067c0725b0b0bcaeebe9d728c341d26acdab64c2c5be7519b22b94fd641015aec504c333c3b3da8cf6067c19999c20ab0ff
data/README.adoc CHANGED
@@ -10,26 +10,24 @@ Gem for serialising the https://github.com/metanorma/metanorma-model-standoc[Met
10
10
 
11
11
  == Functionality
12
12
 
13
- This gem processes Metanorma documents following a template for generating standards documents, according
14
- to a range of standards classes. This gem provides underlying generic functionality; behaviour specific
15
- to each standards class is refined in the gem specific to that standards class (e.g. https://github.com/metanorma/metanorma-iso).
16
- The following outputs are generated.
17
-
18
- * Metanorma XML representation of the document, intended as a document model for
19
- Standards. The Metanorma XML representation is processed in turn, to generate one or more of
20
- the following outputs as end deliverables, depending on each standards class gem:
21
- * Microsoft Word output (`.doc`)
22
- * HTML output (`.html`)
23
- * PDF (`.pdf`)
13
+ This gem processes Metanorma AsciiDoc input into the Metanorma document model.
14
+ This gem provides underlying generic functionality; behaviour specific
15
+ to each standards class is refined in the gem specific to that standards class
16
+ (e.g. https://github.com/metanorma/metanorma-iso[Metanorma ISO]).
17
+
18
+ The following outputs are generated:
19
+
20
+ * Metanorma semantic XML
21
+ * Metanorma presentation XML
22
+
23
+ These Metanorma XML representations are processed downstream by the `isodoc` gem
24
+ to generate other end deliverables, depending on each standards class.
24
25
 
25
26
  The following input formats are supported:
26
27
 
27
- * http://asciidoctor.org/[Asciidoctor]
28
+ * Metanorma AsciiDoc
28
29
 
29
- This README provides an overview of the functionality of the gem; see also
30
- https://github.com/metanorma/metanorma-iso/blob/master/docs/guidance.adoc[Guidance for authoring].
31
- https://github.com/metanorma/metanorma-iso/blob/master/docs/quickstart.adoc[Quickstart guide]
32
- gives a summary overview.
30
+ See the https://www.metanorma.org[Metanorma website] for more information.
33
31
 
34
32
  NOTE: http://asciimath.org[AsciiMathML] is used for mathematical formatting.
35
33
  The gem uses the https://github.com/asciidoctor/asciimath[Ruby AsciiMath parser],
@@ -39,21 +37,19 @@ expressions.
39
37
 
40
38
  === Installation
41
39
 
42
- If you are using a Mac, the https://github.com/metanorma/metanorma-macos-setup
43
- repository has instructions on setting up your machine to run Metanorma
44
- scripts such as this one. You need only run the following in a Terminal console:
40
+ See the https://www.metanorma.org[Metanorma website] for instructions.
41
+
42
+ In the terminal:
45
43
 
46
44
  [source,console]
47
45
  ----
48
- $ bash <(curl -s https://raw.githubusercontent.com/metanorma/metanorma-macos-setup/master/metanorma-setup)
49
46
  $ gem install metanorma-standoc
50
47
  $ gem install metanorma-cli
51
48
  ----
52
49
 
53
- The metanorma-cli gem is the command-line interface for the Metanorma tool suite
50
+ `metanorma-cli` is the command-line interface for the Metanorma suite
54
51
  (incorporating the `metanorma` executable seen above).
55
52
 
56
53
  == Documentation
57
54
 
58
- See http://metanorma.com[]
59
-
55
+ See the https://www.metanorma.org[Metanorma website] for details.
@@ -23,17 +23,6 @@ module Asciidoctor
23
23
  self.class::XML_NAMESPACE
24
24
  end
25
25
 
26
- def content(node)
27
- node.content
28
- end
29
-
30
- def skip(node, name = nil)
31
- name = name || node.node_name
32
- w = "converter missing for #{name} node in Metanorma backend"
33
- @log.add("AsciiDoc Input", node, w)
34
- nil
35
- end
36
-
37
26
  def html_extract_attributes(node)
38
27
  {
39
28
  script: node.attr("script"),
@@ -53,8 +42,11 @@ module Asciidoctor
53
42
  htmltoclevels: node.attr("htmltoclevels") || node.attr("toclevels"),
54
43
  doctoclevels: node.attr("doctoclevels") || node.attr("toclevels"),
55
44
  break_up_urls_in_tables: node.attr("break-up-urls-in-tables"),
45
+ suppressasciimathdup: node.attr("suppress-asciimath-dup"),
56
46
  bare: node.attr("bare"),
57
47
  sectionsplit: node.attr("sectionsplit"),
48
+ baseassetpath: node.attr("base-asset-path"),
49
+ aligncrosselements: node.attr("align-cross-elements"),
58
50
  }
59
51
  end
60
52
 
@@ -87,7 +79,10 @@ module Asciidoctor
87
79
  htmltoclevels: node.attr("htmltoclevels") || node.attr("toclevels"),
88
80
  doctoclevels: node.attr("doctoclevels") || node.attr("toclevels"),
89
81
  break_up_urls_in_tables: node.attr("break-up-urls-in-tables"),
82
+ suppressasciimathdup: node.attr("suppress-asciimath-dup"),
90
83
  bare: node.attr("bare"),
84
+ baseassetpath: node.attr("base-asset-path"),
85
+ aligncrosselements: node.attr("align-cross-elements"),
91
86
  }
92
87
 
93
88
  if font_manifest_file = node.attr("mn2pdf-font-manifest-file")
@@ -122,8 +117,7 @@ module Asciidoctor
122
117
  @files_to_delete = []
123
118
  @filename = if node.attr("docfile")
124
119
  File.basename(node.attr("docfile"))&.gsub(/\.adoc$/, "")
125
- else
126
- ""
120
+ else ""
127
121
  end
128
122
  @localdir = Metanorma::Utils::localdir(node)
129
123
  @output_dir = outputdir node
@@ -172,6 +166,10 @@ module Asciidoctor
172
166
  outputs(node, ret) unless node.attr("nodoc") || !node.attr("docfile")
173
167
  clean_exit
174
168
  ret
169
+ rescue StandardError => e
170
+ @log.add("Fatal Error", nil, e.message)
171
+ clean_exit
172
+ raise e
175
173
  end
176
174
 
177
175
  def version
@@ -624,6 +624,9 @@
624
624
  <choice>
625
625
  <ref name="PureTextElement"/>
626
626
  <ref name="stem"/>
627
+ <ref name="eref"/>
628
+ <ref name="xref"/>
629
+ <ref name="hyperlink"/>
627
630
  </choice>
628
631
  </zeroOrMore>
629
632
  </element>
@@ -634,6 +637,9 @@
634
637
  <choice>
635
638
  <ref name="PureTextElement"/>
636
639
  <ref name="stem"/>
640
+ <ref name="eref"/>
641
+ <ref name="xref"/>
642
+ <ref name="hyperlink"/>
637
643
  </choice>
638
644
  </zeroOrMore>
639
645
  </element>
@@ -641,7 +647,12 @@
641
647
  <define name="tt">
642
648
  <element name="tt">
643
649
  <zeroOrMore>
644
- <ref name="PureTextElement"/>
650
+ <choice>
651
+ <ref name="PureTextElement"/>
652
+ <ref name="eref"/>
653
+ <ref name="xref"/>
654
+ <ref name="hyperlink"/>
655
+ </choice>
645
656
  </zeroOrMore>
646
657
  </element>
647
658
  </define>
@@ -822,7 +833,9 @@
822
833
  <attribute name="alt"/>
823
834
  </optional>
824
835
  <ref name="CitationType"/>
825
- <text/>
836
+ <oneOrMore>
837
+ <ref name="PureTextElement"/>
838
+ </oneOrMore>
826
839
  </define>
827
840
  <define name="hyperlink">
828
841
  <element name="link">
@@ -835,7 +848,9 @@
835
848
  <optional>
836
849
  <attribute name="alt"/>
837
850
  </optional>
838
- <text/>
851
+ <oneOrMore>
852
+ <ref name="PureTextElement"/>
853
+ </oneOrMore>
839
854
  </element>
840
855
  </define>
841
856
  <define name="xref">
@@ -849,7 +864,9 @@
849
864
  <optional>
850
865
  <attribute name="alt"/>
851
866
  </optional>
852
- <text/>
867
+ <oneOrMore>
868
+ <ref name="PureTextElement"/>
869
+ </oneOrMore>
853
870
  </element>
854
871
  </define>
855
872
  <define name="fn">
@@ -6,14 +6,17 @@ module Asciidoctor
6
6
  module Standoc
7
7
  module Blocks
8
8
  def id_attr(node = nil)
9
- { id: Metanorma::Utils::anchor_or_uuid(node) }
9
+ { id: Metanorma::Utils::anchor_or_uuid(node),
10
+ tag: node&.attr("tag"),
11
+ "multilingual-rendering": node&.attr("multilingual-rendering") }
10
12
  end
11
13
 
12
14
  def id_unnum_attrs(node)
13
- attr_code(id: Metanorma::Utils::anchor_or_uuid(node),
14
- unnumbered: node.option?("unnumbered") ? "true" : nil,
15
- number: node.attr("number"),
16
- subsequence: node.attr("subsequence"))
15
+ attr_code(id_attr(node).merge(
16
+ unnumbered: node.option?("unnumbered") ? "true" : nil,
17
+ number: node.attr("number"),
18
+ subsequence: node.attr("subsequence"),
19
+ ))
17
20
  end
18
21
 
19
22
  def formula_attrs(node)
@@ -33,6 +36,7 @@ module Asciidoctor
33
36
  role = node.role || node.attr("style")
34
37
  reqt_subpart(role) and return requirement_subpart(node)
35
38
  role == "form" and return form(node)
39
+ role == "definition" and return termdefinition(node)
36
40
  result = []
37
41
  node.blocks.each do |b|
38
42
  result << send(b.context, b)
@@ -42,10 +46,9 @@ module Asciidoctor
42
46
 
43
47
  def form(node)
44
48
  noko do |xml|
45
- xml.form **attr_code(
46
- id: Metanorma::Utils::anchor_or_uuid, class: node.attr("class"),
47
- name: node.attr("name"), action: node.attr("action")
48
- ) do |f|
49
+ xml.form **attr_code(id_attr(node)
50
+ .merge(class: node.attr("class"),
51
+ name: node.attr("name"), action: node.attr("action"))) do |f|
49
52
  f << node.content
50
53
  end
51
54
  end
@@ -77,7 +80,7 @@ module Asciidoctor
77
80
 
78
81
  def term_example(node)
79
82
  noko do |xml|
80
- xml.termexample **id_attr(node) do |ex|
83
+ xml.termexample **attr_code(id_attr(node)) do |ex|
81
84
  wrap_in_para(node, ex)
82
85
  end
83
86
  end.join("\n")
@@ -92,15 +95,18 @@ module Asciidoctor
92
95
  return pseudocode_example(node) if role == "pseudocode"
93
96
  return svgmap_example(node) if role == "svgmap"
94
97
  return form(node) if role == "form"
98
+ return termdefinition(node) if role == "definition"
95
99
 
100
+ reqt_subpart(role) and return requirement_subpart(node)
96
101
  example_proper(node)
97
102
  end
98
103
 
99
104
  def svgmap_attrs(node)
100
- attr_code({ id: node.id,
101
- unnumbered: node.option?("unnumbered") ? "true" : nil,
102
- number: node.attr("number"),
103
- subsequence: node.attr("subsequence") }
105
+ attr_code(id_attr(node)
106
+ .merge(id: node.id,
107
+ unnumbered: node.option?("unnumbered") ? "true" : nil,
108
+ number: node.attr("number"),
109
+ subsequence: node.attr("subsequence"))
104
110
  .merge(keep_attrs(node)))
105
111
  end
106
112
 
@@ -159,9 +165,10 @@ module Asciidoctor
159
165
  end
160
166
 
161
167
  def para_attrs(node)
162
- attr_code(keep_attrs(node)
168
+ attr_code(id_attr(node).merge(keep_attrs(node)
163
169
  .merge(align: node.attr("align"),
164
- id: Metanorma::Utils::anchor_or_uuid(node)))
170
+ variant_title: node.role == "variant-title" ? true : nil,
171
+ type: node.attr("type"))))
165
172
  end
166
173
 
167
174
  def paragraph(node)
@@ -175,9 +182,8 @@ module Asciidoctor
175
182
  end
176
183
 
177
184
  def quote_attrs(node)
178
- attr_code(keep_attrs(node)
179
- .merge(align: node.attr("align"),
180
- id: Metanorma::Utils::anchor_or_uuid(node)))
185
+ attr_code(id_attr(node).merge(keep_attrs(node))
186
+ .merge(align: node.attr("align")))
181
187
  end
182
188
 
183
189
  def quote_attribution(node, out)
@@ -201,12 +207,11 @@ module Asciidoctor
201
207
  end
202
208
 
203
209
  def listing_attrs(node)
204
- attr_code(keep_attrs(node)
210
+ attr_code(id_attr(node).merge(keep_attrs(node)
205
211
  .merge(lang: node.attr("language"),
206
- id: Metanorma::Utils::anchor_or_uuid(node),
207
212
  unnumbered: node.option?("unnumbered") ? "true" : nil,
208
213
  number: node.attr("number"),
209
- filename: node.attr("filename")))
214
+ filename: node.attr("filename"))))
210
215
  end
211
216
 
212
217
  # NOTE: html escaping is performed by Nokogiri
@@ -2,24 +2,21 @@ module Asciidoctor
2
2
  module Standoc
3
3
  module Blocks
4
4
  def termnote_attrs(node)
5
- attr_code(
6
- id_attr(node).merge(
5
+ attr_code(id_attr(node).merge(keep_attrs(node)
6
+ .merge(
7
7
  unnumbered: node.attr("unnumbered"),
8
8
  number: node.attr("number"),
9
9
  subsequence: node.attr("subsequence"),
10
- "keep-with-next": node.attr("keep-with-next"),
11
- "keep-lines-together": node.attr("keep-with-next"),
12
- "keep-separate": node.attr("keep-separate")
13
- )
14
- )
10
+ "keep-separate": node.attr("keep-separate"),
11
+ )))
15
12
  end
16
13
 
17
14
  def note_attrs(node)
18
15
  attr_code(
19
16
  termnote_attrs(node).merge(
20
17
  type: node.attr("type"),
21
- beforeclauses: node.attr("beforeclauses") == "true" ? "true" : nil
22
- )
18
+ beforeclauses: node.attr("beforeclauses") == "true" ? "true" : nil,
19
+ ),
23
20
  )
24
21
  end
25
22
 
@@ -27,8 +24,8 @@ module Asciidoctor
27
24
  todo_attrs(node).merge(
28
25
  attr_code(
29
26
  from: node.attr("from"),
30
- to: node.attr("to") || node.attr("from")
31
- )
27
+ to: node.attr("to") || node.attr("from"),
28
+ ),
32
29
  )
33
30
  end
34
31
 
@@ -45,11 +42,10 @@ module Asciidoctor
45
42
  def todo_attrs(node)
46
43
  date = node.attr("date") || Date.today.iso8601.gsub(/\+.*$/, "")
47
44
  date += "T00:00:00Z" unless /T/.match? date
48
- attr_code(
49
- id: ::Metanorma::Utils::anchor_or_uuid(node),
50
- reviewer: node.attr("reviewer") || node.attr("source") || "(Unknown)",
51
- date: date
52
- )
45
+ attr_code(id_attr(node)
46
+ .merge(reviewer: node.attr("reviewer") || node.attr("source") ||
47
+ "(Unknown)",
48
+ date: date))
53
49
  end
54
50
 
55
51
  def todo(node)
@@ -81,12 +77,11 @@ module Asciidoctor
81
77
  a = node.attr("type") and ["danger", "safety precautions"].each do |t|
82
78
  name = t if a.casecmp(t).zero?
83
79
  end
84
- attr_code(
85
- keep_attrs(node).merge(
86
- id: Metanorma::Utils::anchor_or_uuid(node), type: name,
87
- beforeclauses: node.attr("beforeclauses") == "true" ? "true" : nil
88
- )
89
- )
80
+ attr_code(keep_attrs(node).merge(id_attr(node)
81
+ .merge(
82
+ type: name,
83
+ beforeclauses: node.attr("beforeclauses") == "true" ? "true" : nil,
84
+ )))
90
85
  end
91
86
 
92
87
  def admonition(node)
@@ -2,30 +2,25 @@ require "nokogiri"
2
2
  require "pathname"
3
3
  require "html2doc"
4
4
  require_relative "./cleanup_block"
5
+ require_relative "./cleanup_table"
5
6
  require_relative "./cleanup_footnotes"
6
7
  require_relative "./cleanup_ref"
7
8
  require_relative "./cleanup_ref_dl"
8
9
  require_relative "./cleanup_boilerplate"
9
10
  require_relative "./cleanup_section"
10
11
  require_relative "./cleanup_terms"
12
+ require_relative "./cleanup_xref"
11
13
  require_relative "./cleanup_inline"
12
14
  require_relative "./cleanup_amend"
13
15
  require_relative "./cleanup_maths"
14
16
  require_relative "./cleanup_image"
15
17
  require_relative "./cleanup_reqt"
18
+ require_relative "./cleanup_text"
16
19
  require "relaton_iev"
17
20
 
18
21
  module Asciidoctor
19
22
  module Standoc
20
23
  module Cleanup
21
- def textcleanup(result)
22
- text = result.flatten.map { |l| l.sub(/\s*$/, "") } * "\n"
23
- !@keepasciimath and text = asciimath2mathml(text)
24
- text = text.gsub(/\s+<fn /, "<fn ")
25
- text.gsub(%r{<passthrough\s+formats="metanorma">([^<]*)
26
- </passthrough>}mx) { HTMLEntities.new.decode($1) }
27
- end
28
-
29
24
  def cleanup(xmldoc)
30
25
  element_name_cleanup(xmldoc)
31
26
  sections_cleanup(xmldoc)
@@ -72,63 +67,6 @@ module Asciidoctor
72
67
  xmldoc
73
68
  end
74
69
 
75
- IGNORE_DUMBQUOTES = "//pre | //pre//* | //tt | //tt//* | "\
76
- "//sourcecode | //sourcecode//* | //bibdata//* | //stem | "\
77
- "//stem//* | //figure[@class = 'pseudocode'] | "\
78
- "//figure[@class = 'pseudocode']//*".freeze
79
-
80
- def smartquotes_cleanup(xmldoc)
81
- xmldoc.xpath("//date").each { |d| Metanorma::Utils::endash_date(d) }
82
- if @smartquotes then smartquotes_cleanup1(xmldoc)
83
- else dumbquote_cleanup(xmldoc)
84
- end
85
- end
86
-
87
- def smartquotes_cleanup1(xmldoc)
88
- uninterrupt_quotes_around_xml(xmldoc)
89
- dumb2smart_quotes(xmldoc)
90
- end
91
-
92
- # "abc<tag/>", def => "abc",<tag/> def
93
- def uninterrupt_quotes_around_xml(xmldoc)
94
- xmldoc.xpath("//*[following::text()[1]"\
95
- "[starts-with(., '\"') or starts-with(., \"'\")]]")
96
- .each do |x|
97
- next if !x.ancestors("pre, tt, sourcecode, stem, figure").empty?
98
- uninterrupt_quotes_around_xml1(x)
99
- end
100
- end
101
-
102
- def uninterrupt_quotes_around_xml1(elem)
103
- prev = elem.at(".//preceding::text()[1]") or return
104
- /\S$/.match?(prev.text) or return
105
- foll = elem.at(".//following::text()[1]")
106
- m = /^(["'][[:punct:]]*)(\s|$)/.match(HTMLEntities.new.decode(foll&.text)) or return
107
- foll.content = foll.text.sub(/^(["'][[:punct:]]*)/, "")
108
- prev.content = "#{prev.text}#{m[1]}"
109
- end
110
-
111
- def dumb2smart_quotes(xmldoc)
112
- (xmldoc.xpath("//*[child::text()]") - xmldoc.xpath(IGNORE_DUMBQUOTES))
113
- .each do |x|
114
- x.children.each do |n|
115
- next unless n.text?
116
-
117
- /[-'"(<>]|\.\.|\dx/.match(n) or next
118
-
119
- n.replace(Metanorma::Utils::smartformat(n.text))
120
- end
121
- end
122
- end
123
-
124
- def dumbquote_cleanup(xmldoc)
125
- xmldoc.traverse do |n|
126
- next unless n.text?
127
-
128
- n.replace(n.text.gsub(/(?<=\p{Alnum})\u2019(?=\p{Alpha})/, "'")) # .
129
- end
130
- end
131
-
132
70
  def docidentifier_cleanup(xmldoc); end
133
71
 
134
72
  TEXT_ELEMS =
@@ -172,8 +110,8 @@ module Asciidoctor
172
110
 
173
111
  c.xpath("./variant").each do |n|
174
112
  if n.at_xpath("preceding-sibling::node()"\
175
- "[not(self::text()[not(normalize-space())])][1]"\
176
- "[self::variantwrap]")
113
+ "[not(self::text()[not(normalize-space())])][1]"\
114
+ "[self::variantwrap]")
177
115
  n.previous_element << n
178
116
  else
179
117
  n.replace("<variantwrap/>").first << n
@@ -193,21 +131,26 @@ module Asciidoctor
193
131
  end
194
132
 
195
133
  def toc_cleanup(xmldoc)
134
+ toc_cleanup_para(xmldoc)
135
+ xmldoc.xpath("//toc").each { |t| toc_cleanup1(t, xmldoc) }
136
+ toc_cleanup_clause(xmldoc)
137
+ end
138
+
139
+ def toc_cleanup_para(xmldoc)
196
140
  xmldoc.xpath("//p[toc]").each do |x|
197
141
  x.xpath("./toc").reverse.each do |t|
198
142
  x.next = t
199
143
  end
200
144
  x.remove if x.text.strip.empty?
201
145
  end
202
- xmldoc.xpath("//toc").each { |t| toc_cleanup1(t, xmldoc) }
203
146
  end
204
147
 
205
148
  def toc_index(toc, xmldoc)
206
- depths = toc.xpath("./toc-xpath").each_with_object({}) do |x, m|
207
- m[x.text] = x["depth"]
208
- end
149
+ depths = toc_index_depths(toc)
209
150
  depths.keys.each_with_object([]) do |key, arr|
210
151
  xmldoc.xpath(key).each do |x|
152
+ t = x.at("./following-sibling::variant-title[@type = 'toc']") and
153
+ x = t
211
154
  arr << { text: x.children.to_xml, depth: depths[key].to_i,
212
155
  target: x.xpath("(./ancestor-or-self::*/@id)[last()]")[0].text,
213
156
  line: x.line }
@@ -215,6 +158,12 @@ module Asciidoctor
215
158
  end.sort_by { |a| a[:line] }
216
159
  end
217
160
 
161
+ def toc_index_depths(toc)
162
+ toc.xpath("./toc-xpath").each_with_object({}) do |x, m|
163
+ m[x.text] = x["depth"]
164
+ end
165
+ end
166
+
218
167
  def toc_cleanup1(toc, xmldoc)
219
168
  depth = 1
220
169
  ret = ""
@@ -227,6 +176,24 @@ module Asciidoctor
227
176
  end
228
177
  toc.children = "<ul>#{ret}</ul>"
229
178
  end
179
+
180
+ def toc_cleanup_clause(xmldoc)
181
+ xmldoc
182
+ .xpath("//clause[@type = 'toc'] | //annex[@type = 'toc']").each do |c|
183
+ c.xpath(".//ul[not(ancestor::ul)]").each do |ul|
184
+ toc_cleanup_clause_entry(xmldoc, ul)
185
+ ul.replace("<toc>#{ul.to_xml}</toc>")
186
+ end
187
+ end
188
+ end
189
+
190
+ def toc_cleanup_clause_entry(xmldoc, list)
191
+ list.xpath(".//xref[not(text())]").each do |x|
192
+ c1 = xmldoc.at("//*[@id = '#{x['target']}']")
193
+ t = c1.at("./variant-title[@type = 'toc']") || c1.at("./title")
194
+ x << t.dup.children
195
+ end
196
+ end
230
197
  end
231
198
  end
232
199
  end
@@ -7,10 +7,9 @@ module Asciidoctor
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 ancestor::table or ancestor::bibdata)]"].each do |w|
11
- inject_id(
12
- xmldoc, w
13
- )
10
+ "//note[not(ancestor::bibitem or "\
11
+ "ancestor::table or ancestor::bibdata)]"].each do |w|
12
+ inject_id(xmldoc, w)
14
13
  end
15
14
  end
16
15
 
@@ -20,68 +19,6 @@ module Asciidoctor
20
19
  end
21
20
  end
22
21
 
23
- def dl1_table_cleanup(xmldoc)
24
- q = "//table/following-sibling::*[1][self::dl]"
25
- xmldoc.xpath(q).each do |s|
26
- s["key"] == "true" and s.previous_element << s.remove
27
- end
28
- end
29
-
30
- # move Key dl after table footer
31
- def dl2_table_cleanup(xmldoc)
32
- q = "//table/following-sibling::*[1][self::p]"
33
- xmldoc.xpath(q).each do |s|
34
- if s.text =~ /^\s*key[^a-z]*$/i && s&.next_element&.name == "dl"
35
- s.next_element["key"] = "true"
36
- s.previous_element << s.next_element.remove
37
- s.remove
38
- end
39
- end
40
- end
41
-
42
- def insert_thead(table)
43
- thead = table.at("./thead")
44
- return thead unless thead.nil?
45
-
46
- if tname = table.at("./name")
47
- thead = tname.add_next_sibling("<thead/>").first
48
- return thead
49
- end
50
- table.children.first.add_previous_sibling("<thead/>").first
51
- end
52
-
53
- def header_rows_cleanup(xmldoc)
54
- xmldoc.xpath("//table[@headerrows]").each do |s|
55
- thead = insert_thead(s)
56
- (thead.xpath("./tr").size...s["headerrows"].to_i).each do
57
- row = s.at("./tbody/tr")
58
- row.parent = thead
59
- end
60
- thead.xpath(".//td").each { |n| n.name = "th" }
61
- s.delete("headerrows")
62
- end
63
- end
64
-
65
- def table_cleanup(xmldoc)
66
- dl1_table_cleanup(xmldoc)
67
- dl2_table_cleanup(xmldoc)
68
- notes_table_cleanup(xmldoc)
69
- header_rows_cleanup(xmldoc)
70
- end
71
-
72
- # move notes into table
73
- def notes_table_cleanup(xmldoc)
74
- nomatches = false
75
- until nomatches
76
- q = "//table/following-sibling::*[1][self::note]"
77
- nomatches = true
78
- xmldoc.xpath(q).each do |n|
79
- n.previous_element << n.remove
80
- nomatches = false
81
- end
82
- end
83
- end
84
-
85
22
  # include where definition list inside stem block
86
23
  def formula_cleanup(formula)
87
24
  formula_cleanup_where1(formula)
@@ -213,18 +150,16 @@ module Asciidoctor
213
150
  end
214
151
 
215
152
  def sourcecode_markup(node)
216
- acc = []
217
153
  node.text.split(/(#{Regexp.escape(@sourcecode_markup_start)}|
218
154
  #{Regexp.escape(@sourcecode_markup_end)})/x)
219
- .each_slice(4).map do |a|
155
+ .each_slice(4).map.with_object([]) do |a, acc|
220
156
  acc << safe_noko(a[0], node.document)
221
157
  next unless a.size == 4
222
158
 
223
159
  acc << Asciidoctor.convert(
224
160
  a[2], doctype: :inline, backend: (self&.backend&.to_sym || :standoc)
225
161
  )
226
- end
227
- acc.join
162
+ end.join
228
163
  end
229
164
 
230
165
  def form_cleanup(xmldoc)