metanorma-standoc 1.11.2 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (145) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake.yml +3 -31
  3. data/.gitignore +23 -0
  4. data/Gemfile +1 -0
  5. data/lib/asciidoctor/standoc/base.rb +2 -241
  6. data/lib/asciidoctor/standoc/blocks.rb +2 -238
  7. data/lib/asciidoctor/standoc/blocks_notes.rb +2 -100
  8. data/lib/asciidoctor/standoc/cleanup.rb +2 -207
  9. data/lib/asciidoctor/standoc/cleanup_amend.rb +2 -53
  10. data/lib/asciidoctor/standoc/cleanup_block.rb +2 -173
  11. data/lib/asciidoctor/standoc/cleanup_boilerplate.rb +2 -212
  12. data/lib/asciidoctor/standoc/cleanup_footnotes.rb +2 -108
  13. data/lib/asciidoctor/standoc/cleanup_image.rb +2 -69
  14. data/lib/asciidoctor/standoc/cleanup_inline.rb +2 -179
  15. data/lib/asciidoctor/standoc/cleanup_maths.rb +2 -221
  16. data/lib/asciidoctor/standoc/cleanup_ref.rb +2 -169
  17. data/lib/asciidoctor/standoc/cleanup_ref_dl.rb +2 -103
  18. data/lib/asciidoctor/standoc/cleanup_reqt.rb +2 -110
  19. data/lib/asciidoctor/standoc/cleanup_section.rb +2 -184
  20. data/lib/asciidoctor/standoc/cleanup_section_names.rb +2 -91
  21. data/lib/asciidoctor/standoc/cleanup_symbols.rb +2 -47
  22. data/lib/asciidoctor/standoc/cleanup_table.rb +2 -67
  23. data/lib/asciidoctor/standoc/cleanup_terms.rb +2 -117
  24. data/lib/asciidoctor/standoc/cleanup_terms_designations.rb +2 -178
  25. data/lib/asciidoctor/standoc/cleanup_text.rb +2 -95
  26. data/lib/asciidoctor/standoc/cleanup_toc.rb +3 -0
  27. data/lib/asciidoctor/standoc/cleanup_xref.rb +2 -106
  28. data/lib/asciidoctor/standoc/converter.rb +2 -123
  29. data/lib/asciidoctor/standoc/datamodel/attributes_table_preprocessor.rb +2 -56
  30. data/lib/asciidoctor/standoc/datamodel/diagram_preprocessor.rb +2 -102
  31. data/lib/asciidoctor/standoc/datamodel/plantuml_renderer.rb +3 -404
  32. data/lib/asciidoctor/standoc/deprecated.rb +5 -0
  33. data/lib/asciidoctor/standoc/front.rb +2 -219
  34. data/lib/asciidoctor/standoc/front_contributor.rb +2 -191
  35. data/lib/asciidoctor/standoc/inline.rb +2 -231
  36. data/lib/asciidoctor/standoc/lists.rb +2 -119
  37. data/lib/asciidoctor/standoc/macros.rb +2 -203
  38. data/lib/asciidoctor/standoc/macros_form.rb +2 -62
  39. data/lib/asciidoctor/standoc/macros_note.rb +2 -44
  40. data/lib/asciidoctor/standoc/macros_plantuml.rb +2 -112
  41. data/lib/asciidoctor/standoc/macros_terms.rb +2 -180
  42. data/lib/asciidoctor/standoc/ref.rb +2 -251
  43. data/lib/asciidoctor/standoc/ref_sect.rb +2 -153
  44. data/lib/asciidoctor/standoc/ref_utility.rb +2 -0
  45. data/lib/asciidoctor/standoc/render.rb +3 -0
  46. data/lib/asciidoctor/standoc/reqt.rb +2 -89
  47. data/lib/asciidoctor/standoc/section.rb +2 -190
  48. data/lib/asciidoctor/standoc/table.rb +2 -84
  49. data/lib/asciidoctor/standoc/term_lookup_cleanup.rb +2 -178
  50. data/lib/asciidoctor/standoc/terms.rb +2 -153
  51. data/lib/asciidoctor/standoc/utils.rb +2 -116
  52. data/lib/asciidoctor/standoc/validate.rb +2 -157
  53. data/lib/asciidoctor/standoc/validate_section.rb +2 -54
  54. data/lib/isodoc/html/htmlstyle.css +44 -29
  55. data/lib/isodoc/html/htmlstyle.scss +17 -12
  56. data/lib/metanorma/standoc/base.rb +163 -0
  57. data/lib/{asciidoctor → metanorma}/standoc/basicdoc.rng +0 -0
  58. data/lib/{asciidoctor → metanorma}/standoc/biblio.rng +0 -0
  59. data/lib/metanorma/standoc/blocks.rb +239 -0
  60. data/lib/metanorma/standoc/blocks_notes.rb +101 -0
  61. data/lib/metanorma/standoc/cleanup.rb +157 -0
  62. data/lib/metanorma/standoc/cleanup_amend.rb +54 -0
  63. data/lib/metanorma/standoc/cleanup_block.rb +173 -0
  64. data/lib/metanorma/standoc/cleanup_boilerplate.rb +213 -0
  65. data/lib/metanorma/standoc/cleanup_footnotes.rb +109 -0
  66. data/lib/metanorma/standoc/cleanup_image.rb +70 -0
  67. data/lib/metanorma/standoc/cleanup_inline.rb +190 -0
  68. data/lib/metanorma/standoc/cleanup_maths.rb +222 -0
  69. data/lib/metanorma/standoc/cleanup_ref.rb +170 -0
  70. data/lib/metanorma/standoc/cleanup_ref_dl.rb +104 -0
  71. data/lib/metanorma/standoc/cleanup_reqt.rb +111 -0
  72. data/lib/metanorma/standoc/cleanup_section.rb +212 -0
  73. data/lib/metanorma/standoc/cleanup_section_names.rb +92 -0
  74. data/lib/metanorma/standoc/cleanup_symbols.rb +48 -0
  75. data/lib/metanorma/standoc/cleanup_table.rb +68 -0
  76. data/lib/metanorma/standoc/cleanup_terms.rb +140 -0
  77. data/lib/metanorma/standoc/cleanup_terms_designations.rb +199 -0
  78. data/lib/metanorma/standoc/cleanup_text.rb +96 -0
  79. data/lib/metanorma/standoc/cleanup_toc.rb +98 -0
  80. data/lib/metanorma/standoc/cleanup_xref.rb +107 -0
  81. data/lib/metanorma/standoc/converter.rb +125 -0
  82. data/lib/metanorma/standoc/datamodel/attributes_table_preprocessor.rb +57 -0
  83. data/lib/metanorma/standoc/datamodel/diagram_preprocessor.rb +103 -0
  84. data/lib/metanorma/standoc/datamodel/plantuml_renderer.rb +409 -0
  85. data/lib/metanorma/standoc/front.rb +224 -0
  86. data/lib/metanorma/standoc/front_contributor.rb +192 -0
  87. data/lib/metanorma/standoc/inline.rb +232 -0
  88. data/lib/{asciidoctor → metanorma}/standoc/isodoc.rng +49 -2
  89. data/lib/metanorma/standoc/lists.rb +120 -0
  90. data/lib/metanorma/standoc/macros.rb +204 -0
  91. data/lib/metanorma/standoc/macros_form.rb +63 -0
  92. data/lib/metanorma/standoc/macros_note.rb +45 -0
  93. data/lib/metanorma/standoc/macros_plantuml.rb +113 -0
  94. data/lib/metanorma/standoc/macros_terms.rb +194 -0
  95. data/lib/metanorma/standoc/ref.rb +243 -0
  96. data/lib/metanorma/standoc/ref_sect.rb +153 -0
  97. data/lib/{asciidoctor/standoc/ref_date_id.rb → metanorma/standoc/ref_utility.rb} +43 -5
  98. data/lib/metanorma/standoc/render.rb +115 -0
  99. data/lib/metanorma/standoc/reqt.rb +90 -0
  100. data/lib/{asciidoctor → metanorma}/standoc/reqt.rng +0 -0
  101. data/lib/metanorma/standoc/section.rb +209 -0
  102. data/lib/metanorma/standoc/table.rb +85 -0
  103. data/lib/metanorma/standoc/term_lookup_cleanup.rb +179 -0
  104. data/lib/metanorma/standoc/terms.rb +160 -0
  105. data/lib/metanorma/standoc/utils.rb +101 -0
  106. data/lib/metanorma/standoc/validate.rb +158 -0
  107. data/lib/metanorma/standoc/validate_section.rb +55 -0
  108. data/lib/metanorma/standoc/version.rb +1 -1
  109. data/lib/{asciidoctor → metanorma}/standoc/views/datamodel/model_representation.adoc.erb +0 -0
  110. data/lib/{asciidoctor → metanorma}/standoc/views/datamodel/plantuml_representation.adoc.erb +0 -0
  111. data/lib/metanorma-standoc.rb +1 -1
  112. data/metanorma-standoc.gemspec +2 -2
  113. data/spec/{asciidoctor → metanorma}/base_spec.rb +499 -407
  114. data/spec/{asciidoctor → metanorma}/blank_spec.rb +1 -1
  115. data/spec/{asciidoctor → metanorma}/blocks_spec.rb +34 -5
  116. data/spec/{asciidoctor → metanorma}/cleanup_blocks_spec.rb +25 -1
  117. data/spec/{asciidoctor → metanorma}/cleanup_sections_spec.rb +1 -1
  118. data/spec/{asciidoctor → metanorma}/cleanup_spec.rb +5 -5
  119. data/spec/{asciidoctor → metanorma}/cleanup_terms_spec.rb +281 -29
  120. data/spec/{asciidoctor → metanorma}/datamodel/attributes_table_preprocessor_spec.rb +1 -1
  121. data/spec/{asciidoctor → metanorma}/datamodel/diagram_preprocessor_spec.rb +1 -1
  122. data/spec/{asciidoctor → metanorma}/inline_spec.rb +170 -1
  123. data/spec/{asciidoctor → metanorma}/isobib_cache_spec.rb +1 -1
  124. data/spec/{asciidoctor → metanorma}/lists_spec.rb +1 -1
  125. data/spec/{asciidoctor → metanorma}/macros_json2text_spec.rb +0 -0
  126. data/spec/{asciidoctor → metanorma}/macros_plantuml_spec.rb +3 -3
  127. data/spec/{asciidoctor → metanorma}/macros_spec.rb +8 -6
  128. data/spec/{asciidoctor → metanorma}/macros_yaml2text_spec.rb +0 -0
  129. data/spec/metanorma/refs_dl_spec.rb +863 -0
  130. data/spec/{asciidoctor → metanorma}/refs_spec.rb +522 -15
  131. data/spec/{asciidoctor → metanorma}/section_spec.rb +88 -1
  132. data/spec/{asciidoctor → metanorma}/table_spec.rb +1 -1
  133. data/spec/{asciidoctor → metanorma}/validate_spec.rb +2 -2
  134. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +53 -53
  135. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec1.yml +14 -14
  136. data/spec/vcr_cassettes/hide_refs.yml +599 -0
  137. data/spec/vcr_cassettes/isobib_get_123.yml +14 -14
  138. data/spec/vcr_cassettes/isobib_get_123_1.yml +99 -99
  139. data/spec/vcr_cassettes/isobib_get_123_1_fr.yml +109 -109
  140. data/spec/vcr_cassettes/isobib_get_123_2001.yml +13 -13
  141. data/spec/vcr_cassettes/isobib_get_124.yml +12 -12
  142. data/spec/vcr_cassettes/rfcbib_get_rfc8341.yml +14 -14
  143. data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +46 -46
  144. metadata +87 -35
  145. data/spec/asciidoctor/refs_dl_spec.rb +0 -864
@@ -0,0 +1,163 @@
1
+ require "date"
2
+ require "nokogiri"
3
+ require "htmlentities"
4
+ require "json"
5
+ require "pathname"
6
+ require "isodoc"
7
+ require "relaton"
8
+ require "fileutils"
9
+ require "metanorma-utils"
10
+ require "isodoc/xslfo_convert"
11
+ require_relative "render"
12
+
13
+ module Metanorma
14
+ module Standoc
15
+ module Base
16
+ XML_ROOT_TAG = "standard-document".freeze
17
+ XML_NAMESPACE = "https://www.metanorma.org/ns/standoc".freeze
18
+ FONTS_MANIFEST = "fonts-manifest".freeze
19
+
20
+ def xml_root_tag
21
+ self.class::XML_ROOT_TAG
22
+ end
23
+
24
+ def xml_namespace
25
+ self.class::XML_NAMESPACE
26
+ end
27
+
28
+ def init(node)
29
+ @fn_number ||= 0
30
+ @draft = false
31
+ @refids = Set.new
32
+ @anchors = {}
33
+ @internal_eref_namespaces = []
34
+ @draft = node.attributes.has_key?("draft")
35
+ @novalid = node.attr("novalid")
36
+ @smartquotes = node.attr("smartquotes") != "false"
37
+ @keepasciimath = node.attr("mn-keep-asciimath") &&
38
+ node.attr("mn-keep-asciimath") != "false"
39
+ @fontheader = default_fonts(node)
40
+ @files_to_delete = []
41
+ @filename = if node.attr("docfile")
42
+ File.basename(node.attr("docfile"))&.gsub(/\.adoc$/, "")
43
+ else ""
44
+ end
45
+ @localdir = Metanorma::Utils::localdir(node)
46
+ @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)
61
+ @lang = (node.attr("language") || "en")
62
+ @script = (node.attr("script") ||
63
+ Metanorma::Utils.default_script(node.attr("language")))
64
+ @isodoc = isodoc(@lang, @script, node.attr("i18nyaml"))
65
+ @i18n = @isodoc.i18n
66
+ @htmltoclevels = node.attr("htmltoclevels")
67
+ @doctoclevels = node.attr("doctoclevels")
68
+ @toclevels = node.attr("toclevels")
69
+ @metadata_attrs = metadata_attrs(node)
70
+ end
71
+
72
+ def document(node)
73
+ init(node)
74
+ ret = makexml(node).to_xml(encoding: "US-ASCII", indent: 2)
75
+ outputs(node, ret) unless node.attr("nodoc") || !node.attr("docfile")
76
+ clean_exit
77
+ ret
78
+ rescue StandardError => e
79
+ @log.add("Fatal Error", nil, e.message)
80
+ clean_exit
81
+ raise e
82
+ end
83
+
84
+ def version
85
+ flavour = self.class.name.sub(/::Converter$/, "").sub(/^.+::/, "")
86
+ Metanorma.versioned(Metanorma, flavour)[-1]::VERSION
87
+ end
88
+
89
+ def clean_exit
90
+ @log.write("#{@output_dir}#{@filename}.err") unless @novalid
91
+
92
+ @files_to_delete.each { |f| FileUtils.rm f }
93
+ end
94
+
95
+ def clean_abort(msg, file = nil)
96
+ file and
97
+ File.open("#{@filename}.xml.abort", "w:UTF-8") { |f| f.write(file) }
98
+ clean_exit
99
+ abort(msg)
100
+ end
101
+
102
+ def makexml1(node)
103
+ result = ["<?xml version='1.0' encoding='UTF-8'?>",
104
+ "<#{xml_root_tag} type='semantic' version='#{version}'>"]
105
+ result << noko { |ixml| front node, ixml }
106
+ result << noko { |ixml| middle node, ixml }
107
+ result << "</#{xml_root_tag}>"
108
+ textcleanup(result)
109
+ end
110
+
111
+ def makexml(node)
112
+ result = makexml1(node)
113
+ ret1 = cleanup(Nokogiri::XML(result))
114
+ ret1.root.add_namespace(nil, xml_namespace)
115
+ validate(ret1) unless @novalid
116
+ ret1
117
+ end
118
+
119
+ def draft?
120
+ @draft
121
+ end
122
+
123
+ def doctype(node)
124
+ node.attr("doctype")&.gsub(/\s+/, "-")&.downcase
125
+ end
126
+
127
+ def front(node, xml)
128
+ xml.bibdata **attr_code(type: "standard") do |b|
129
+ metadata node, b
130
+ end
131
+ end
132
+
133
+ def middle(node, xml)
134
+ xml.sections do |s|
135
+ s << node.content if node.blocks?
136
+ end
137
+ end
138
+
139
+ def metadata_attrs(node)
140
+ node.attributes.each_with_object([]) do |(k, v), ret|
141
+ %w(presentation semantic).each do |t|
142
+ next unless /^#{t}-metadata-/.match?(k)
143
+
144
+ k = k.sub(/^#{t}-metadata-/, "")
145
+ csv_split(v, ",")&.each do |c|
146
+ ret << "<#{t}-metadata><#{k}>#{c}</#{k}></#{t}-metadata>"
147
+ end
148
+ end
149
+ end.join
150
+ end
151
+
152
+ private
153
+
154
+ def outputdir(node)
155
+ if node.attr("output_dir").nil_or_empty?
156
+ Metanorma::Utils::localdir(node)
157
+ else
158
+ File.join(node.attr("output_dir"), "")
159
+ end
160
+ end
161
+ end
162
+ end
163
+ end
File without changes
File without changes
@@ -0,0 +1,239 @@
1
+ require "htmlentities"
2
+ require "uri" if /^2\./.match?(RUBY_VERSION)
3
+ require_relative "./blocks_notes"
4
+
5
+ module Metanorma
6
+ module Standoc
7
+ module Blocks
8
+ def id_attr(node = nil)
9
+ { id: Metanorma::Utils::anchor_or_uuid(node),
10
+ tag: node&.attr("tag"),
11
+ "multilingual-rendering": node&.attr("multilingual-rendering") }
12
+ end
13
+
14
+ def id_unnum_attrs(node)
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
+ ))
20
+ end
21
+
22
+ def formula_attrs(node)
23
+ attr_code(id_unnum_attrs(node)
24
+ .merge(keep_attrs(node).merge(
25
+ inequality: node.option?("inequality") ? "true" : nil,
26
+ )))
27
+ end
28
+
29
+ def keep_attrs(node)
30
+ { "keep-with-next": node.attr("keep-with-next"),
31
+ "keep-lines-together": node.attr("keep-lines-together") }
32
+ end
33
+
34
+ # We append each contained block to its parent
35
+ def open(node)
36
+ role = node.role || node.attr("style")
37
+ reqt_subpart(role) and return requirement_subpart(node)
38
+ role == "form" and return form(node)
39
+ role == "definition" and return termdefinition(node)
40
+ result = []
41
+ node.blocks.each do |b|
42
+ result << send(b.context, b)
43
+ end
44
+ result
45
+ end
46
+
47
+ def form(node)
48
+ noko do |xml|
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|
52
+ f << node.content
53
+ end
54
+ end
55
+ end
56
+
57
+ def literal_attrs(node)
58
+ attr_code(id_attr(node).merge(keep_attrs(node)))
59
+ end
60
+
61
+ def literal(node)
62
+ noko do |xml|
63
+ xml.figure **literal_attrs(node) do |f|
64
+ figure_title(node, f)
65
+ f.pre node.lines.join("\n"),
66
+ **attr_code(id: Metanorma::Utils::anchor_or_uuid,
67
+ alt: node.attr("alt"))
68
+ end
69
+ end
70
+ end
71
+
72
+ # NOTE: html escaping is performed by Nokogiri
73
+ def stem(node)
74
+ noko do |xml|
75
+ xml.formula **formula_attrs(node) do |s|
76
+ stem_parse(node.lines.join("\n"), s, node.style.to_sym)
77
+ end
78
+ end
79
+ end
80
+
81
+ def term_example(node)
82
+ noko do |xml|
83
+ xml.termexample **attr_code(id_attr(node)) do |ex|
84
+ wrap_in_para(node, ex)
85
+ end
86
+ end.join("\n")
87
+ end
88
+
89
+ def example(node)
90
+ return term_example(node) if in_terms?
91
+
92
+ role = node.role || node.attr("style")
93
+ %w(recommendation requirement permission).include?(role) and
94
+ return requirement(node, role)
95
+ return pseudocode_example(node) if role == "pseudocode"
96
+ return svgmap_example(node) if role == "svgmap"
97
+ return form(node) if role == "form"
98
+ return termdefinition(node) if role == "definition"
99
+
100
+ reqt_subpart(role) and return requirement_subpart(node)
101
+ example_proper(node)
102
+ end
103
+
104
+ def svgmap_attrs(node)
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"))
110
+ .merge(keep_attrs(node)))
111
+ end
112
+
113
+ def svgmap_example(node)
114
+ noko do |xml|
115
+ xml.svgmap **attr_code(svgmap_attrs(node).merge(
116
+ src: node.attr("src"), alt: node.attr("alt"),
117
+ )) do |ex|
118
+ figure_title(node, ex)
119
+ ex << node.content
120
+ end
121
+ end.join("\n")
122
+ end
123
+
124
+ # prevent A's and other subs inappropriate for pseudocode
125
+ def pseudocode_example(node)
126
+ node.blocks.each { |b| b.remove_sub(:replacements) }
127
+ noko do |xml|
128
+ xml.figure **example_attrs(node).merge(class: "pseudocode") do |ex|
129
+ figure_title(node, ex)
130
+ wrap_in_para(node, ex)
131
+ end
132
+ end.join("\n")
133
+ end
134
+
135
+ def example_attrs(node)
136
+ attr_code(id_unnum_attrs(node).merge(keep_attrs(node)))
137
+ end
138
+
139
+ def example_proper(node)
140
+ noko do |xml|
141
+ xml.example **example_attrs(node) do |ex|
142
+ node.title.nil? or ex.name { |name| name << node.title }
143
+ wrap_in_para(node, ex)
144
+ end
145
+ end.join("\n")
146
+ end
147
+
148
+ def figure_title(node, out)
149
+ return if node.title.nil?
150
+
151
+ out.name { |name| name << node.title }
152
+ end
153
+
154
+ def figure_attrs(node)
155
+ attr_code(id_unnum_attrs(node).merge(keep_attrs(node)))
156
+ end
157
+
158
+ def image(node)
159
+ noko do |xml|
160
+ xml.figure **figure_attrs(node) do |f|
161
+ figure_title(node, f)
162
+ f.image **image_attributes(node)
163
+ end
164
+ end
165
+ end
166
+
167
+ def para_attrs(node)
168
+ attr_code(id_attr(node).merge(keep_attrs(node)
169
+ .merge(align: node.attr("align"),
170
+ variant_title: node.role == "variant-title" ? true : nil,
171
+ type: node.attr("type"))))
172
+ end
173
+
174
+ def paragraph(node)
175
+ return termsource(node) if node.role == "source"
176
+
177
+ noko do |xml|
178
+ xml.p **para_attrs(node) do |xml_t|
179
+ xml_t << node.content
180
+ end
181
+ end.join("\n")
182
+ end
183
+
184
+ def quote_attrs(node)
185
+ attr_code(id_attr(node).merge(keep_attrs(node))
186
+ .merge(align: node.attr("align")))
187
+ end
188
+
189
+ def quote_attribution(node, out)
190
+ if node.attr("citetitle")
191
+ m = /^(?<cite>[^,]+)(,(?<text>.*$))?$/m.match node.attr("citetitle")
192
+ out.source **attr_code(target: m[:cite], type: "inline") do |s|
193
+ s << m[:text]
194
+ end
195
+ end
196
+ node.attr("attribution") and
197
+ out.author { |a| a << node.attr("attribution") }
198
+ end
199
+
200
+ def quote(node)
201
+ noko do |xml|
202
+ xml.quote **quote_attrs(node) do |q|
203
+ quote_attribution(node, q)
204
+ wrap_in_para(node, q)
205
+ end
206
+ end.join("\n")
207
+ end
208
+
209
+ def listing_attrs(node)
210
+ attr_code(id_attr(node).merge(keep_attrs(node)
211
+ .merge(lang: node.attr("language"),
212
+ unnumbered: node.option?("unnumbered") ? "true" : nil,
213
+ number: node.attr("number"),
214
+ filename: node.attr("filename"))))
215
+ end
216
+
217
+ # NOTE: html escaping is performed by Nokogiri
218
+ def listing(node)
219
+ fragment = ::Nokogiri::XML::Builder.new do |xml|
220
+ xml.sourcecode **listing_attrs(node) do |s|
221
+ figure_title(node, s)
222
+ s << node.content
223
+ end
224
+ end
225
+ fragment.to_xml(encoding: "US-ASCII", save_with:
226
+ Nokogiri::XML::Node::SaveOptions::NO_DECLARATION)
227
+ end
228
+
229
+ def pass(node)
230
+ noko do |xml|
231
+ xml.passthrough **attr_code(formats:
232
+ node.attr("format") || "metanorma") do |p|
233
+ p << HTMLEntities.new.encode(node.content, :basic, :hexadecimal)
234
+ end
235
+ end
236
+ end
237
+ end
238
+ end
239
+ end
@@ -0,0 +1,101 @@
1
+ module Metanorma
2
+ module Standoc
3
+ module Blocks
4
+ def termnote_attrs(node)
5
+ attr_code(id_attr(node).merge(keep_attrs(node)
6
+ .merge(
7
+ unnumbered: node.attr("unnumbered"),
8
+ number: node.attr("number"),
9
+ subsequence: node.attr("subsequence"),
10
+ "keep-separate": node.attr("keep-separate"),
11
+ )))
12
+ end
13
+
14
+ def note_attrs(node)
15
+ attr_code(
16
+ termnote_attrs(node).merge(
17
+ type: node.attr("type"),
18
+ beforeclauses: node.attr("beforeclauses") == "true" ? "true" : nil,
19
+ ),
20
+ )
21
+ end
22
+
23
+ def sidebar_attrs(node)
24
+ todo_attrs(node).merge(
25
+ attr_code(
26
+ from: node.attr("from"),
27
+ to: node.attr("to") || node.attr("from"),
28
+ ),
29
+ )
30
+ end
31
+
32
+ def sidebar(node)
33
+ return unless draft?
34
+
35
+ noko do |xml|
36
+ xml.review **sidebar_attrs(node) do |r|
37
+ wrap_in_para(node, r)
38
+ end
39
+ end
40
+ end
41
+
42
+ def todo_attrs(node)
43
+ date = node.attr("date") || Date.today.iso8601.gsub(/\+.*$/, "")
44
+ date += "T00:00:00Z" unless /T/.match? date
45
+ attr_code(id_attr(node)
46
+ .merge(reviewer: node.attr("reviewer") || node.attr("source") ||
47
+ "(Unknown)",
48
+ date: date))
49
+ end
50
+
51
+ def todo(node)
52
+ noko do |xml|
53
+ xml.review **todo_attrs(node) do |r|
54
+ wrap_in_para(node, r)
55
+ end
56
+ end
57
+ end
58
+
59
+ def termnote(node)
60
+ noko do |xml|
61
+ xml.termnote **termnote_attrs(node) do |ex|
62
+ wrap_in_para(node, ex)
63
+ end
64
+ end.join("\n")
65
+ end
66
+
67
+ def note(node)
68
+ noko do |xml|
69
+ xml.note **note_attrs(node) do |c|
70
+ wrap_in_para(node, c)
71
+ end
72
+ end.join("\n")
73
+ end
74
+
75
+ def admonition_attrs(node)
76
+ name = node.attr("name")
77
+ a = node.attr("type") and ["danger", "safety precautions"].each do |t|
78
+ name = t if a.casecmp(t).zero?
79
+ end
80
+ attr_code(keep_attrs(node).merge(id_attr(node)
81
+ .merge(
82
+ type: name,
83
+ beforeclauses: node.attr("beforeclauses") == "true" ? "true" : nil,
84
+ )))
85
+ end
86
+
87
+ def admonition(node)
88
+ return termnote(node) if in_terms?
89
+ return note(node) if node.attr("name") == "note"
90
+ return todo(node) if node.attr("name") == "todo"
91
+
92
+ noko do |xml|
93
+ xml.admonition **admonition_attrs(node) do |a|
94
+ node.title.nil? or a.name { |name| name << node.title }
95
+ wrap_in_para(node, a)
96
+ end
97
+ end.join("\n")
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,157 @@
1
+ require "nokogiri"
2
+ require "pathname"
3
+ require "html2doc"
4
+ require_relative "./cleanup_block"
5
+ require_relative "./cleanup_table"
6
+ require_relative "./cleanup_footnotes"
7
+ require_relative "./cleanup_ref"
8
+ require_relative "./cleanup_ref_dl"
9
+ require_relative "./cleanup_boilerplate"
10
+ require_relative "./cleanup_section"
11
+ require_relative "./cleanup_terms"
12
+ require_relative "./cleanup_symbols"
13
+ require_relative "./cleanup_xref"
14
+ require_relative "./cleanup_inline"
15
+ require_relative "./cleanup_amend"
16
+ require_relative "./cleanup_maths"
17
+ require_relative "./cleanup_image"
18
+ require_relative "./cleanup_reqt"
19
+ require_relative "./cleanup_text"
20
+ require_relative "./cleanup_toc"
21
+ require "relaton_iev"
22
+
23
+ module Metanorma
24
+ module Standoc
25
+ module Cleanup
26
+ def cleanup(xmldoc)
27
+ element_name_cleanup(xmldoc)
28
+ sections_cleanup(xmldoc)
29
+ obligations_cleanup(xmldoc)
30
+ table_cleanup(xmldoc)
31
+ formula_cleanup(xmldoc)
32
+ form_cleanup(xmldoc)
33
+ sourcecode_cleanup(xmldoc)
34
+ figure_cleanup(xmldoc)
35
+ element_name_cleanup(xmldoc)
36
+ ref_cleanup(xmldoc)
37
+ note_cleanup(xmldoc)
38
+ clausebefore_cleanup(xmldoc)
39
+ floatingtitle_cleanup(xmldoc)
40
+ bibitem_cleanup(xmldoc)
41
+ normref_cleanup(xmldoc)
42
+ biblio_cleanup(xmldoc)
43
+ reference_names(xmldoc)
44
+ symbols_cleanup(xmldoc)
45
+ xref_cleanup(xmldoc)
46
+ concept_cleanup(xmldoc)
47
+ related_cleanup(xmldoc)
48
+ origin_cleanup(xmldoc)
49
+ bookmark_cleanup(xmldoc)
50
+ termdef_cleanup(xmldoc)
51
+ RelatonIev::iev_cleanup(xmldoc, @bibdb)
52
+ element_name_cleanup(xmldoc)
53
+ index_cleanup(xmldoc)
54
+ bpart_cleanup(xmldoc)
55
+ quotesource_cleanup(xmldoc)
56
+ callout_cleanup(xmldoc)
57
+ footnote_cleanup(xmldoc)
58
+ mathml_cleanup(xmldoc)
59
+ script_cleanup(xmldoc)
60
+ docidentifier_cleanup(xmldoc)
61
+ requirement_cleanup(xmldoc)
62
+ bibdata_cleanup(xmldoc)
63
+ svgmap_cleanup(xmldoc)
64
+ boilerplate_cleanup(xmldoc)
65
+ toc_cleanup(xmldoc)
66
+ metadata_cleanup(xmldoc)
67
+ smartquotes_cleanup(xmldoc)
68
+ variant_cleanup(xmldoc)
69
+ para_cleanup(xmldoc)
70
+ empty_element_cleanup(xmldoc)
71
+ img_cleanup(xmldoc)
72
+ anchor_cleanup(xmldoc)
73
+ xmldoc
74
+ end
75
+
76
+ def docidentifier_cleanup(xmldoc); end
77
+
78
+ TEXT_ELEMS =
79
+ %w{status language script version author name callout phone email
80
+ street city state country postcode identifier referenceFrom surname
81
+ referenceTo docidentifier docnumber prefix initial addition forename
82
+ title draft secretariat title-main title-intro title-part
83
+ verbal-definition non-verbal-representation}.freeze
84
+
85
+ # it seems Nokogiri::XML is treating the content of <script> as cdata,
86
+ # because of its use in HTML. Bad nokogiri. Undoing that, since we use
87
+ # script as a normal tag
88
+ def script_cleanup(xmldoc)
89
+ xmldoc.xpath("//script").each { |x| x.content = x.to_str }
90
+ end
91
+
92
+ def empty_element_cleanup(xmldoc)
93
+ xmldoc.xpath("//#{TEXT_ELEMS.join(' | //')}").each do |x|
94
+ next if x.name == "name" && x.parent.name == "expression"
95
+
96
+ x.remove if x.children.empty?
97
+ end
98
+ end
99
+
100
+ def element_name_cleanup(xmldoc)
101
+ xmldoc.traverse { |n| n.name = n.name.gsub(/_/, "-") }
102
+ end
103
+
104
+ # allows us to deal with doc relation localities,
105
+ # temporarily stashed to "bpart"
106
+ def bpart_cleanup(xmldoc)
107
+ xmldoc.xpath("//relation/bpart").each do |x|
108
+ extract_localities(x)
109
+ x.replace(x.children)
110
+ end
111
+ end
112
+
113
+ def variant_cleanup(xmldoc)
114
+ variant_space_cleanup(xmldoc)
115
+ xmldoc.xpath("//*[variant]").each do |c|
116
+ next unless c.children.any? do |n|
117
+ n.name != "variant" && (!n.text? || !n.text.gsub(/\s/, "").empty?)
118
+ end
119
+
120
+ variant_cleanup1(c)
121
+ end
122
+ xmldoc.xpath("//variantwrap").each { |n| n.name = "variant" }
123
+ end
124
+
125
+ def variant_cleanup1(elem)
126
+ elem.xpath("./variant").each do |n|
127
+ if n.at_xpath("preceding-sibling::node()"\
128
+ "[not(self::text()[not(normalize-space())])][1]"\
129
+ "[self::variantwrap]")
130
+ n.previous_element << n
131
+ else
132
+ n.replace("<variantwrap/>").first << n
133
+ end
134
+ end
135
+ end
136
+
137
+ def variant_space_cleanup(xmldoc)
138
+ xmldoc.xpath("//*[variant]").each do |c|
139
+ next if c.next.nil? || c.next.next.nil?
140
+
141
+ if c.next.text? && c.next.next.name == "variant"
142
+ c.next.text.gsub(/\s/, "").empty? and
143
+ c.next.remove
144
+ end
145
+ end
146
+ end
147
+
148
+ def metadata_cleanup(xmldoc)
149
+ return if @metadata_attrs.nil? || @metadata_attrs.empty?
150
+
151
+ ins = xmldoc.at("//misc-container") ||
152
+ xmldoc.at("//bibdata").after("<misc-container/>").next_element
153
+ ins << @metadata_attrs
154
+ end
155
+ end
156
+ end
157
+ end