metanorma-standoc 1.11.4 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (141) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake.yml +3 -31
  3. data/.gitignore +23 -0
  4. data/lib/asciidoctor/standoc/base.rb +2 -145
  5. data/lib/asciidoctor/standoc/blocks.rb +2 -238
  6. data/lib/asciidoctor/standoc/blocks_notes.rb +2 -100
  7. data/lib/asciidoctor/standoc/cleanup.rb +2 -208
  8. data/lib/asciidoctor/standoc/cleanup_amend.rb +2 -53
  9. data/lib/asciidoctor/standoc/cleanup_block.rb +2 -172
  10. data/lib/asciidoctor/standoc/cleanup_boilerplate.rb +2 -212
  11. data/lib/asciidoctor/standoc/cleanup_footnotes.rb +2 -108
  12. data/lib/asciidoctor/standoc/cleanup_image.rb +2 -69
  13. data/lib/asciidoctor/standoc/cleanup_inline.rb +2 -189
  14. data/lib/asciidoctor/standoc/cleanup_maths.rb +2 -221
  15. data/lib/asciidoctor/standoc/cleanup_ref.rb +2 -169
  16. data/lib/asciidoctor/standoc/cleanup_ref_dl.rb +2 -103
  17. data/lib/asciidoctor/standoc/cleanup_reqt.rb +2 -110
  18. data/lib/asciidoctor/standoc/cleanup_section.rb +2 -184
  19. data/lib/asciidoctor/standoc/cleanup_section_names.rb +2 -91
  20. data/lib/asciidoctor/standoc/cleanup_symbols.rb +2 -47
  21. data/lib/asciidoctor/standoc/cleanup_table.rb +2 -67
  22. data/lib/asciidoctor/standoc/cleanup_terms.rb +2 -139
  23. data/lib/asciidoctor/standoc/cleanup_terms_designations.rb +2 -198
  24. data/lib/asciidoctor/standoc/cleanup_text.rb +2 -95
  25. data/lib/asciidoctor/standoc/cleanup_toc.rb +3 -0
  26. data/lib/asciidoctor/standoc/cleanup_xref.rb +2 -106
  27. data/lib/asciidoctor/standoc/converter.rb +2 -123
  28. data/lib/asciidoctor/standoc/datamodel/attributes_table_preprocessor.rb +2 -56
  29. data/lib/asciidoctor/standoc/datamodel/diagram_preprocessor.rb +2 -102
  30. data/lib/asciidoctor/standoc/datamodel/plantuml_renderer.rb +3 -404
  31. data/lib/asciidoctor/standoc/deprecated.rb +5 -0
  32. data/lib/asciidoctor/standoc/front.rb +2 -223
  33. data/lib/asciidoctor/standoc/front_contributor.rb +2 -191
  34. data/lib/asciidoctor/standoc/inline.rb +2 -231
  35. data/lib/asciidoctor/standoc/lists.rb +2 -119
  36. data/lib/asciidoctor/standoc/macros.rb +2 -203
  37. data/lib/asciidoctor/standoc/macros_form.rb +2 -62
  38. data/lib/asciidoctor/standoc/macros_note.rb +2 -44
  39. data/lib/asciidoctor/standoc/macros_plantuml.rb +2 -112
  40. data/lib/asciidoctor/standoc/macros_terms.rb +2 -180
  41. data/lib/asciidoctor/standoc/ref.rb +2 -251
  42. data/lib/asciidoctor/standoc/ref_sect.rb +2 -153
  43. data/lib/asciidoctor/standoc/ref_utility.rb +2 -0
  44. data/lib/asciidoctor/standoc/render.rb +2 -114
  45. data/lib/asciidoctor/standoc/reqt.rb +2 -89
  46. data/lib/asciidoctor/standoc/section.rb +2 -207
  47. data/lib/asciidoctor/standoc/table.rb +2 -84
  48. data/lib/asciidoctor/standoc/term_lookup_cleanup.rb +2 -178
  49. data/lib/asciidoctor/standoc/terms.rb +2 -159
  50. data/lib/asciidoctor/standoc/utils.rb +2 -100
  51. data/lib/asciidoctor/standoc/validate.rb +2 -157
  52. data/lib/asciidoctor/standoc/validate_section.rb +2 -54
  53. data/lib/metanorma/standoc/base.rb +149 -0
  54. data/lib/{asciidoctor → metanorma}/standoc/basicdoc.rng +0 -0
  55. data/lib/{asciidoctor → metanorma}/standoc/biblio.rng +0 -0
  56. data/lib/metanorma/standoc/blocks.rb +239 -0
  57. data/lib/metanorma/standoc/blocks_notes.rb +101 -0
  58. data/lib/metanorma/standoc/cleanup.rb +146 -0
  59. data/lib/metanorma/standoc/cleanup_amend.rb +54 -0
  60. data/lib/metanorma/standoc/cleanup_block.rb +173 -0
  61. data/lib/metanorma/standoc/cleanup_boilerplate.rb +213 -0
  62. data/lib/metanorma/standoc/cleanup_footnotes.rb +109 -0
  63. data/lib/metanorma/standoc/cleanup_image.rb +70 -0
  64. data/lib/metanorma/standoc/cleanup_inline.rb +190 -0
  65. data/lib/metanorma/standoc/cleanup_maths.rb +222 -0
  66. data/lib/metanorma/standoc/cleanup_ref.rb +170 -0
  67. data/lib/metanorma/standoc/cleanup_ref_dl.rb +104 -0
  68. data/lib/metanorma/standoc/cleanup_reqt.rb +111 -0
  69. data/lib/metanorma/standoc/cleanup_section.rb +212 -0
  70. data/lib/metanorma/standoc/cleanup_section_names.rb +92 -0
  71. data/lib/metanorma/standoc/cleanup_symbols.rb +48 -0
  72. data/lib/metanorma/standoc/cleanup_table.rb +68 -0
  73. data/lib/metanorma/standoc/cleanup_terms.rb +140 -0
  74. data/lib/metanorma/standoc/cleanup_terms_designations.rb +199 -0
  75. data/lib/metanorma/standoc/cleanup_text.rb +96 -0
  76. data/lib/metanorma/standoc/cleanup_toc.rb +98 -0
  77. data/lib/metanorma/standoc/cleanup_xref.rb +107 -0
  78. data/lib/metanorma/standoc/converter.rb +124 -0
  79. data/lib/metanorma/standoc/datamodel/attributes_table_preprocessor.rb +57 -0
  80. data/lib/metanorma/standoc/datamodel/diagram_preprocessor.rb +103 -0
  81. data/lib/metanorma/standoc/datamodel/plantuml_renderer.rb +409 -0
  82. data/lib/metanorma/standoc/front.rb +224 -0
  83. data/lib/metanorma/standoc/front_contributor.rb +192 -0
  84. data/lib/metanorma/standoc/inline.rb +232 -0
  85. data/lib/{asciidoctor → metanorma}/standoc/isodoc.rng +29 -0
  86. data/lib/metanorma/standoc/lists.rb +120 -0
  87. data/lib/metanorma/standoc/macros.rb +204 -0
  88. data/lib/metanorma/standoc/macros_form.rb +63 -0
  89. data/lib/metanorma/standoc/macros_note.rb +45 -0
  90. data/lib/metanorma/standoc/macros_plantuml.rb +113 -0
  91. data/lib/metanorma/standoc/macros_terms.rb +181 -0
  92. data/lib/metanorma/standoc/ref.rb +243 -0
  93. data/lib/metanorma/standoc/ref_sect.rb +153 -0
  94. data/lib/{asciidoctor/standoc/ref_date_id.rb → metanorma/standoc/ref_utility.rb} +43 -5
  95. data/lib/metanorma/standoc/render.rb +115 -0
  96. data/lib/metanorma/standoc/reqt.rb +90 -0
  97. data/lib/{asciidoctor → metanorma}/standoc/reqt.rng +0 -0
  98. data/lib/metanorma/standoc/section.rb +209 -0
  99. data/lib/metanorma/standoc/table.rb +85 -0
  100. data/lib/metanorma/standoc/term_lookup_cleanup.rb +179 -0
  101. data/lib/metanorma/standoc/terms.rb +160 -0
  102. data/lib/metanorma/standoc/utils.rb +101 -0
  103. data/lib/metanorma/standoc/validate.rb +158 -0
  104. data/lib/metanorma/standoc/validate_section.rb +55 -0
  105. data/lib/metanorma/standoc/version.rb +1 -1
  106. data/lib/{asciidoctor → metanorma}/standoc/views/datamodel/model_representation.adoc.erb +0 -0
  107. data/lib/{asciidoctor → metanorma}/standoc/views/datamodel/plantuml_representation.adoc.erb +0 -0
  108. data/lib/metanorma-standoc.rb +1 -1
  109. data/metanorma-standoc.gemspec +1 -1
  110. data/spec/{asciidoctor → metanorma}/base_spec.rb +27 -10
  111. data/spec/{asciidoctor → metanorma}/blank_spec.rb +1 -1
  112. data/spec/{asciidoctor → metanorma}/blocks_spec.rb +1 -1
  113. data/spec/{asciidoctor → metanorma}/cleanup_blocks_spec.rb +1 -1
  114. data/spec/{asciidoctor → metanorma}/cleanup_sections_spec.rb +1 -1
  115. data/spec/{asciidoctor → metanorma}/cleanup_spec.rb +5 -5
  116. data/spec/{asciidoctor → metanorma}/cleanup_terms_spec.rb +2 -2
  117. data/spec/{asciidoctor → metanorma}/datamodel/attributes_table_preprocessor_spec.rb +1 -1
  118. data/spec/{asciidoctor → metanorma}/datamodel/diagram_preprocessor_spec.rb +1 -1
  119. data/spec/{asciidoctor → metanorma}/inline_spec.rb +1 -1
  120. data/spec/{asciidoctor → metanorma}/isobib_cache_spec.rb +1 -1
  121. data/spec/{asciidoctor → metanorma}/lists_spec.rb +1 -1
  122. data/spec/{asciidoctor → metanorma}/macros_json2text_spec.rb +0 -0
  123. data/spec/{asciidoctor → metanorma}/macros_plantuml_spec.rb +3 -3
  124. data/spec/{asciidoctor → metanorma}/macros_spec.rb +6 -6
  125. data/spec/{asciidoctor → metanorma}/macros_yaml2text_spec.rb +0 -0
  126. data/spec/metanorma/refs_dl_spec.rb +863 -0
  127. data/spec/{asciidoctor → metanorma}/refs_spec.rb +399 -25
  128. data/spec/{asciidoctor → metanorma}/section_spec.rb +42 -17
  129. data/spec/{asciidoctor → metanorma}/table_spec.rb +1 -1
  130. data/spec/{asciidoctor → metanorma}/validate_spec.rb +2 -2
  131. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +42 -42
  132. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec1.yml +11 -11
  133. data/spec/vcr_cassettes/isobib_get_123.yml +12 -12
  134. data/spec/vcr_cassettes/isobib_get_123_1.yml +21 -21
  135. data/spec/vcr_cassettes/isobib_get_123_1_fr.yml +81 -81
  136. data/spec/vcr_cassettes/isobib_get_123_2001.yml +10 -10
  137. data/spec/vcr_cassettes/isobib_get_124.yml +11 -11
  138. data/spec/vcr_cassettes/rfcbib_get_rfc8341.yml +13 -13
  139. data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +46 -46
  140. metadata +82 -32
  141. data/spec/asciidoctor/refs_dl_spec.rb +0 -864
@@ -0,0 +1,199 @@
1
+ module Metanorma
2
+ module Standoc
3
+ module Cleanup
4
+ def termdef_stem_cleanup(xmldoc)
5
+ termdef_stem2admitted(xmldoc)
6
+ xmldoc.xpath("//term//expression/name[stem]").each do |n|
7
+ test = n.dup
8
+ test.at("./stem").remove
9
+ next unless test.text.strip.empty?
10
+
11
+ n.parent.name = "letter-symbol"
12
+ end
13
+ end
14
+
15
+ def termdef_stem2admitted(xmldoc)
16
+ xmldoc.xpath("//term/p/stem").each do |a|
17
+ if initial_formula(a.parent)
18
+ parent = a.parent
19
+ parent.replace("<admitted>#{term_expr(a.to_xml)}</admitted>")
20
+ end
21
+ end
22
+ xmldoc.xpath("//term/formula").each do |a|
23
+ initial_formula(a) and
24
+ a.replace("<admitted>#{term_expr(a.children.to_xml)}</admitted>")
25
+ end
26
+ end
27
+
28
+ def initial_formula(elem)
29
+ elem.elements.size == 1 && # para contains just stem expression
30
+ !elem.at("./preceding-sibling::p | ./preceding-sibling::dl | "\
31
+ "./preceding-sibling::ol | ./preceding-sibling::ul")
32
+ end
33
+
34
+ # release termdef tags from surrounding paras
35
+ def termdef_unnest_cleanup(xmldoc)
36
+ desgn = "//p/admitted | //p/deprecates | //p/preferred | //p//related"
37
+ nodes = xmldoc.xpath(desgn)
38
+ while !nodes.empty?
39
+ nodes[0].parent.replace(nodes[0].parent.children)
40
+ nodes = xmldoc.xpath(desgn)
41
+ end
42
+ end
43
+
44
+ def term_dl_to_metadata(xmldoc)
45
+ xmldoc.xpath("//term[dl[@metadata = 'true']]").each do |t|
46
+ t.xpath("./dl[@metadata = 'true']").each do |dl|
47
+ prev = related2pref(dl_to_designation(dl)) or next
48
+ term_dl_to_designation_metadata(prev, dl)
49
+ term_dl_to_term_metadata(prev, dl)
50
+ term_dl_to_expression_metadata(prev, dl)
51
+ dl.remove
52
+ end
53
+ end
54
+ end
55
+
56
+ def term_dl_to_term_metadata(prev, dlist)
57
+ return unless prev.name == "preferred" &&
58
+ prev.at("./preceding-sibling::preferred").nil?
59
+
60
+ ins = term_element_insert_point(prev)
61
+ %w(domain subject).each do |a|
62
+ ins = dl_to_elems(ins, prev.parent, dlist, a)
63
+ end
64
+ end
65
+
66
+ def term_dl_to_designation_metadata(prev, dlist)
67
+ %w(absent geographic-area).each do |a|
68
+ dl_to_attrs(prev, dlist, a)
69
+ end
70
+ %w(field-of-application usage-info).reverse.each do |a|
71
+ dl_to_elems(prev.at("./expression"), prev, dlist, a)
72
+ end
73
+ end
74
+
75
+ def term_element_insert_point(prev)
76
+ ins = prev
77
+ while %w(preferred admitted deprecates related domain dl)
78
+ .include? ins&.next_element&.name
79
+ ins = ins.next_element
80
+ end
81
+ ins
82
+ end
83
+
84
+ def term_dl_to_expression_metadata(prev, dlist)
85
+ term_dl_to_expression_root_metadata(prev, dlist)
86
+ term_dl_to_expression_name_metadata(prev, dlist)
87
+ term_to_letter_symbol(prev, dlist)
88
+ end
89
+
90
+ def term_dl_to_expression_root_metadata(prev, dlist)
91
+ %w(isInternational).each do |a|
92
+ p = prev.at("./expression | ./letter-symbol | ./graphical-symbol")
93
+ dl_to_attrs(p, dlist, a)
94
+ end
95
+ %w(language script type).each do |a|
96
+ p = prev.at("./expression") or next
97
+ dl_to_attrs(p, dlist, a)
98
+ end
99
+ end
100
+
101
+ def term_dl_to_expression_name_metadata(prev, dlist)
102
+ %w(abbreviation-type pronunciation).reverse.each do |a|
103
+ dl_to_elems(prev.at("./expression/name"), prev, dlist, a)
104
+ end
105
+ g = dlist.at("./dt[text()='grammar']/following::dd//dl") and
106
+ term_dl_to_expression_grammar(prev, g)
107
+ end
108
+
109
+ def term_dl_to_expression_grammar(prev, dlist)
110
+ prev.at(".//expression") or return
111
+ prev.at(".//expression") << "<grammar><sentinel/></grammar>"
112
+ %w(gender number isPreposition isParticiple isAdjective isAdverb isNoun
113
+ grammar-value).reverse.each do |a|
114
+ dl_to_elems(prev.at(".//expression/grammar/*"), prev.elements.last,
115
+ dlist, a)
116
+ end
117
+ term_dl_to_designation_category(prev, "gender")
118
+ term_dl_to_designation_category(prev, "number")
119
+ prev.at(".//expression/grammar/sentinel").remove
120
+ end
121
+
122
+ def term_dl_to_designation_category(prev, category)
123
+ cat = prev.at(".//expression/grammar/#{category}")
124
+ /,/.match?(cat&.text) and
125
+ cat.replace(cat.text.split(/,\s*/)
126
+ .map { |x| "<#{category}>#{x}</#{category}>" }.join)
127
+ end
128
+
129
+ def term_to_letter_symbol(prev, dlist)
130
+ ls = dlist.at("./dt[text()='letter-symbol']/following::dd/p")
131
+ return unless ls&.text == "true"
132
+
133
+ prev.at(".//expression").name = "letter-symbol"
134
+ end
135
+
136
+ def dl_to_designation(dlist)
137
+ prev = dlist.previous_element
138
+ unless %w(preferred admitted deprecates related).include? prev&.name
139
+ @log.add("AsciiDoc Input", dlist, "Metadata definition list does "\
140
+ "not follow a term designation")
141
+ return nil
142
+ end
143
+ prev
144
+ end
145
+
146
+ def term_nonverbal_designations(xmldoc)
147
+ xmldoc.xpath("//term/preferred | //term/admitted | //term/deprecates")
148
+ .each do |d|
149
+ d.text.strip.empty? or next
150
+ n = d.next_element
151
+ if %w(formula figure).include?(n&.name)
152
+ term_nonverbal_designations1(d, n)
153
+ else d.at("./expression/name") or
154
+ d.children = term_expr("")
155
+ end
156
+ end
157
+ end
158
+
159
+ def term_nonverbal_designations1(desgn, elem)
160
+ desgn = related2pref(desgn)
161
+ if elem.name == "figure"
162
+ elem.at("./name").remove
163
+ desgn.children =
164
+ "<graphical-symbol>#{elem.remove.to_xml}</graphical-symbol>"
165
+ else
166
+ desgn.children = term_expr(elem.at("./stem").to_xml)
167
+ elem.remove
168
+ end
169
+ end
170
+
171
+ def term_termsource_to_designation(xmldoc)
172
+ xmldoc.xpath("//term/termsource").each do |t|
173
+ p = t.previous_element
174
+ while %w(domain subject).include? p&.name
175
+ p = p.previous_element
176
+ end
177
+ %w(preferred admitted deprecates related).include?(p&.name) or
178
+ next
179
+ related2pref(p) << t.remove
180
+ end
181
+ end
182
+
183
+ def term_designation_reorder(xmldoc)
184
+ xmldoc.xpath("//term").each do |t|
185
+ %w(preferred admitted deprecates related)
186
+ .each_with_object([]) do |tag, m|
187
+ t.xpath("./#{tag}").each { |x| m << x.remove }
188
+ end.reverse.each do |x|
189
+ t.children.first.previous = x
190
+ end
191
+ end
192
+ end
193
+
194
+ def related2pref(elem)
195
+ elem&.name == "related" ? elem = elem.at("./preferred") : elem
196
+ end
197
+ end
198
+ end
199
+ end
@@ -0,0 +1,96 @@
1
+ module Metanorma
2
+ module Standoc
3
+ module Cleanup
4
+ def textcleanup(result)
5
+ text = result.flatten.map { |l| l.sub(/\s*$/, "") } * "\n"
6
+ !@keepasciimath and text = asciimath2mathml(text)
7
+ text = text.gsub(/\s+<fn /, "<fn ")
8
+ text.gsub(%r{<passthrough\s+formats="metanorma">([^<]*)
9
+ </passthrough>}mx) { HTMLEntities.new.decode($1) }
10
+ end
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
+ def smartquotes_cleanup(xmldoc)
19
+ xmldoc.xpath("//date").each { |d| Metanorma::Utils::endash_date(d) }
20
+ if @smartquotes then smartquotes_cleanup1(xmldoc)
21
+ else dumbquote_cleanup(xmldoc)
22
+ end
23
+ end
24
+
25
+ def smartquotes_cleanup1(xmldoc)
26
+ uninterrupt_quotes_around_xml(xmldoc)
27
+ dumb2smart_quotes(xmldoc)
28
+ end
29
+
30
+ # "abc<tag/>", def => "abc",<tag/> def
31
+ =begin
32
+ def uninterrupt_quotes_around_xml(xmldoc)
33
+ xmldoc.xpath("//*[following::text()[1]"\
34
+ "[starts-with(., '\"') or starts-with(., \"'\")]]")
35
+ .each do |x|
36
+ next if !x.ancestors("pre, tt, sourcecode, stem, figure").empty?
37
+
38
+ uninterrupt_quotes_around_xml1(x)
39
+ end
40
+ end
41
+ =end
42
+ =begin
43
+ def uninterrupt_quotes_around_xml(xmldoc)
44
+ xmldoc.traverse do |n|
45
+ next unless n.element? && n&.next&.text? &&
46
+ n.ancestors("pre, tt, sourcecode, stem, figure").empty?
47
+ next unless /^['"]/.match?(n.next.text)
48
+
49
+ uninterrupt_quotes_around_xml1(n)
50
+ end
51
+ end
52
+ =end
53
+ def uninterrupt_quotes_around_xml(xmldoc)
54
+ xmldoc.traverse do |n|
55
+ next unless n.text? && n&.previous&.element?
56
+ next unless /^['"]/.match?(n.text)
57
+ next unless n.previous.ancestors("pre, tt, sourcecode, stem, figure")
58
+ .empty?
59
+
60
+ uninterrupt_quotes_around_xml1(n.previous)
61
+ end
62
+ end
63
+
64
+ def uninterrupt_quotes_around_xml1(elem)
65
+ prev = elem.at(".//preceding::text()[1]") or return
66
+ /\S$/.match?(prev.text) or return
67
+ foll = elem.at(".//following::text()[1]")
68
+ m = /^(["'][[:punct:]]*)(\s|$)/
69
+ .match(HTMLEntities.new.decode(foll&.text)) or return
70
+ foll.content = foll.text.sub(/^(["'][[:punct:]]*)/, "")
71
+ prev.content = "#{prev.text}#{m[1]}"
72
+ end
73
+
74
+ def dumb2smart_quotes(xmldoc)
75
+ (xmldoc.xpath("//*[child::text()]") - xmldoc.xpath(IGNORE_DUMBQUOTES))
76
+ .each do |x|
77
+ x.children.each do |n|
78
+ next unless n.text?
79
+
80
+ /[-'"(<>]|\.\.|\dx/.match(n) or next
81
+
82
+ n.replace(Metanorma::Utils::smartformat(n.text))
83
+ end
84
+ end
85
+ end
86
+
87
+ def dumbquote_cleanup(xmldoc)
88
+ xmldoc.traverse do |n|
89
+ next unless n.text?
90
+
91
+ n.replace(n.text.gsub(/(?<=\p{Alnum})\u2019(?=\p{Alpha})/, "'")) # .
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,98 @@
1
+ module Metanorma
2
+ module Standoc
3
+ module Cleanup
4
+ def toc_cleanup(xmldoc)
5
+ toc_cleanup_para(xmldoc)
6
+ xmldoc.xpath("//toc").each { |t| toc_cleanup1(t, xmldoc) }
7
+ toc_cleanup_clause(xmldoc)
8
+ toc_metadata(xmldoc)
9
+ end
10
+
11
+ def toc_cleanup_para(xmldoc)
12
+ xmldoc.xpath("//p[toc]").each do |x|
13
+ x.xpath("./toc").reverse.each do |t|
14
+ x.next = t
15
+ end
16
+ x.remove if x.text.strip.empty?
17
+ end
18
+ end
19
+
20
+ def toc_index(toc, xmldoc)
21
+ depths = toc_index_depths(toc)
22
+ depths.keys.each_with_object([]) do |key, arr|
23
+ xmldoc.xpath(key).each do |x|
24
+ arr << toc_index1(key, x, depths)
25
+ end
26
+ end.sort_by { |a| a[:line] }
27
+ end
28
+
29
+ def toc_index1(key, entry, depths)
30
+ t = entry.at("./following-sibling::variant-title[@type = 'toc']") and
31
+ entry = t
32
+ { text: entry.children.to_xml, depth: depths[key].to_i,
33
+ target: entry.xpath("(./ancestor-or-self::*/@id)[last()]")[0].text,
34
+ line: entry.line }
35
+ end
36
+
37
+ def toc_index_depths(toc)
38
+ toc.xpath("./toc-xpath").each_with_object({}) do |x, m|
39
+ m[x.text] = x["depth"]
40
+ end
41
+ end
42
+
43
+ def toc_cleanup1(toc, xmldoc)
44
+ depth = 1
45
+ ret = ""
46
+ toc_index(toc, xmldoc).each do |x|
47
+ ret = toc_cleanup1_entry(x, depth, ret)
48
+ depth = x[:depth]
49
+ end
50
+ toc.children = "<ul>#{ret}</ul>"
51
+ end
52
+
53
+ def toc_cleanup1_entry(entry, depth, ret)
54
+ if depth > entry[:depth]
55
+ ret += "</ul></li>" * (depth - entry[:depth])
56
+ elsif depth < entry[:depth]
57
+ ret += "<li><ul>" * (entry[:depth] - depth)
58
+ end
59
+ ret + "<li><xref target='#{entry[:target]}'>#{entry[:text]}</xref></li>"
60
+ end
61
+
62
+ def toc_cleanup_clause(xmldoc)
63
+ xmldoc
64
+ .xpath("//clause[@type = 'toc'] | //annex[@type = 'toc']").each do |c|
65
+ c.xpath(".//ul[not(ancestor::ul)]").each do |ul|
66
+ toc_cleanup_clause_entry(xmldoc, ul)
67
+ ul.replace("<toc>#{ul.to_xml}</toc>")
68
+ end
69
+ end
70
+ end
71
+
72
+ def toc_cleanup_clause_entry(xmldoc, list)
73
+ list.xpath(".//xref[not(text())]").each do |x|
74
+ c1 = xmldoc.at("//*[@id = '#{x['target']}']")
75
+ t = c1.at("./variant-title[@type = 'toc']") || c1.at("./title")
76
+ x << t.dup.children
77
+ end
78
+ end
79
+
80
+ def toc_metadata(xmldoc)
81
+ return unless @htmltoclevels || @doctoclevels || @toclevels
82
+
83
+ ins = xmldoc.at("//misc-container") ||
84
+ xmldoc.at("//bibdata").after("<misc-container/>").next_element
85
+ toc_metadata1(ins)
86
+ end
87
+
88
+ def toc_metadata1(ins)
89
+ [[@toclevels, "TOC Heading Levels"],
90
+ [@toclevels, "TOC Heading Levels"],
91
+ [@toclevels, "TOC Heading Levels"]].each do |n|
92
+ n[0] and ins << "<presentation-metadata><name>#{n[1]}</name>"\
93
+ "<value>#{n[0]}</value></presentation-metadata>"
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,107 @@
1
+ module Metanorma
2
+ module Standoc
3
+ module Cleanup
4
+ # extending localities to cover ISO referencing
5
+ LOCALITY_REGEX_STR = <<~REGEXP.freeze
6
+ ^((?<locality>section|clause|part|paragraph|chapter|page|
7
+ table|annex|figure|example|note|formula|list|time|anchor|
8
+ locality:[^ \\t\\n\\r:,;=]+)(\\s+|=)
9
+ (?<ref>[^"][^ \\t\\n,:-]*|"[^"]+")
10
+ (-(?<to>[^"][^ \\t\\n,:-]*|"[^"]"))?|
11
+ (?<locality2>whole|locality:[^ \\t\\n\\r:,;=]+))(?<punct>[,:;]?)\\s*
12
+ (?<text>.*)$
13
+ REGEXP
14
+ LOCALITY_RE = Regexp.new(LOCALITY_REGEX_STR.gsub(/\s/, ""),
15
+ Regexp::IGNORECASE | Regexp::MULTILINE)
16
+
17
+ def tq(text)
18
+ text.sub(/^"/, "").sub(/"$/, "")
19
+ end
20
+
21
+ def extract_localities(elem)
22
+ f = elem&.children&.first or return
23
+ f.text? or return
24
+ head = f.remove.text
25
+ tail = elem&.children&.remove
26
+ extract_localities1(elem, head)
27
+ tail and elem << tail
28
+ end
29
+
30
+ def extract_localities1(elem, text)
31
+ b = elem.add_child("<localityStack/>").first if LOCALITY_RE.match text
32
+ while (m = LOCALITY_RE.match text)
33
+ ref = m[:ref] ? "<referenceFrom>#{tq m[:ref]}</referenceFrom>" : ""
34
+ refto = m[:to] ? "<referenceTo>#{tq m[:to]}</referenceTo>" : ""
35
+ b.add_child("<locality type='#{locality_label(m)}'>#{ref}#{refto}"\
36
+ "</locality>")
37
+ text = m[:text]
38
+ b = elem.add_child("<localityStack/>").first if m[:punct] == ";"
39
+ end
40
+ elem.add_child(text) if text
41
+ end
42
+
43
+ def locality_label(match)
44
+ loc = match[:locality] || match[:locality2]
45
+ /^locality:/.match?(loc) ? loc : loc&.downcase
46
+ end
47
+
48
+ def xref_to_eref(elem)
49
+ elem["bibitemid"] = elem["target"]
50
+ unless elem["citeas"] = @anchors&.dig(elem["target"], :xref)
51
+ @internal_eref_namespaces.include?(elem["type"]) or
52
+ @log.add("Crossreferences", elem,
53
+ "#{elem['target']} does not have a corresponding "\
54
+ "anchor ID in the bibliography!")
55
+ end
56
+ elem.delete("target")
57
+ extract_localities(elem) unless elem.children.empty?
58
+ end
59
+
60
+ def xref_cleanup(xmldoc)
61
+ xmldoc.xpath("//xref").each do |x|
62
+ /:/.match(x["target"]) and xref_to_internal_eref(x)
63
+ next unless x.name == "xref"
64
+
65
+ if refid? x["target"]
66
+ x.name = "eref"
67
+ xref_to_eref(x)
68
+ else x.delete("type")
69
+ end
70
+ end
71
+ end
72
+
73
+ def xref_to_internal_eref(elem)
74
+ a = elem["target"].split(":", 3)
75
+ unless a.size < 2 || a[0].empty? || a[1].empty?
76
+ elem["target"] = "#{a[0]}_#{a[1]}"
77
+ a.size > 2 and
78
+ elem.children = %{anchor="#{a[2..-1].join}",#{elem&.children&.text}}
79
+ elem["type"] = a[0]
80
+ @internal_eref_namespaces << a[0]
81
+ elem.name = "eref"
82
+ xref_to_eref(elem)
83
+ end
84
+ end
85
+
86
+ def quotesource_cleanup(xmldoc)
87
+ xmldoc.xpath("//quote/source | //terms/source").each do |x|
88
+ xref_to_eref(x)
89
+ end
90
+ end
91
+
92
+ def origin_cleanup(xmldoc)
93
+ xmldoc.xpath("//origin/concept[termref]").each do |x|
94
+ t = x.at("./termref")
95
+ x.replace(t)
96
+ end
97
+ xmldoc.xpath("//origin").each do |x|
98
+ x["citeas"] = @anchors&.dig(x["bibitemid"], :xref) or
99
+ @log.add("Crossreferences", x,
100
+ "#{x['bibitemid']} does not have a corresponding anchor "\
101
+ "ID in the bibliography!")
102
+ extract_localities(x) unless x.children.empty?
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,124 @@
1
+ require "asciidoctor"
2
+ require "metanorma/util"
3
+ require "metanorma/standoc/version"
4
+ require "metanorma/standoc/base"
5
+ require "metanorma/standoc/front"
6
+ require "metanorma/standoc/lists"
7
+ require "metanorma/standoc/ref"
8
+ require "metanorma/standoc/inline"
9
+ require "metanorma/standoc/blocks"
10
+ require "metanorma/standoc/section"
11
+ require "metanorma/standoc/table"
12
+ require "metanorma/standoc/validate"
13
+ require "metanorma/standoc/utils"
14
+ require "metanorma/standoc/cleanup"
15
+ require "metanorma/standoc/reqt"
16
+ require_relative "./macros"
17
+
18
+ module Metanorma
19
+ module Standoc
20
+ # A {Converter} implementation that generates Standoc output, and a document
21
+ # schema encapsulation of the document for validation
22
+ class Converter
23
+ Asciidoctor::Extensions.register do
24
+ preprocessor Metanorma::Standoc::Datamodel::AttributesTablePreprocessor
25
+ preprocessor Metanorma::Standoc::Datamodel::DiagramPreprocessor
26
+ preprocessor Metanorma::Plugin::Datastruct::Json2TextPreprocessor
27
+ preprocessor Metanorma::Plugin::Datastruct::Yaml2TextPreprocessor
28
+ preprocessor Metanorma::Plugin::Lutaml::LutamlPreprocessor
29
+ preprocessor Metanorma::Plugin::Lutaml::LutamlUmlAttributesTablePreprocessor
30
+ preprocessor Metanorma::Plugin::Lutaml::LutamlUmlDatamodelDescriptionPreprocessor
31
+ inline_macro Metanorma::Standoc::PreferredTermInlineMacro
32
+ inline_macro Metanorma::Standoc::AltTermInlineMacro
33
+ inline_macro Metanorma::Standoc::DeprecatedTermInlineMacro
34
+ inline_macro Metanorma::Standoc::RelatedTermInlineMacro
35
+ inline_macro Metanorma::Standoc::DomainTermInlineMacro
36
+ inline_macro Metanorma::Standoc::InheritInlineMacro
37
+ inline_macro Metanorma::Standoc::HTML5RubyMacro
38
+ inline_macro Metanorma::Standoc::ConceptInlineMacro
39
+ inline_macro Metanorma::Standoc::AutonumberInlineMacro
40
+ inline_macro Metanorma::Standoc::VariantInlineMacro
41
+ inline_macro Metanorma::Standoc::FootnoteBlockInlineMacro
42
+ inline_macro Metanorma::Standoc::TermRefInlineMacro
43
+ inline_macro Metanorma::Standoc::SymbolRefInlineMacro
44
+ inline_macro Metanorma::Standoc::IndexXrefInlineMacro
45
+ inline_macro Metanorma::Standoc::IndexRangeInlineMacro
46
+ inline_macro Metanorma::Standoc::AddMacro
47
+ inline_macro Metanorma::Standoc::DelMacro
48
+ inline_macro Metanorma::Standoc::FormInputMacro
49
+ inline_macro Metanorma::Standoc::FormLabelMacro
50
+ inline_macro Metanorma::Standoc::FormTextareaMacro
51
+ inline_macro Metanorma::Standoc::FormSelectMacro
52
+ inline_macro Metanorma::Standoc::FormOptionMacro
53
+ inline_macro Metanorma::Standoc::ToCInlineMacro
54
+ inline_macro Metanorma::Standoc::PassInlineMacro
55
+ inline_macro Metanorma::Plugin::Lutaml::LutamlFigureInlineMacro
56
+ inline_macro Metanorma::Plugin::Lutaml::LutamlTableInlineMacro
57
+ block_macro Metanorma::Plugin::Lutaml::LutamlDiagramBlockMacro
58
+ block Metanorma::Standoc::ToDoAdmonitionBlock
59
+ treeprocessor Metanorma::Standoc::ToDoInlineAdmonitionBlock
60
+ block Metanorma::Standoc::PlantUMLBlockMacro
61
+ block Metanorma::Plugin::Lutaml::LutamlDiagramBlock
62
+ block Metanorma::Standoc::PseudocodeBlockMacro
63
+ end
64
+
65
+ include ::Asciidoctor::Converter
66
+ include ::Asciidoctor::Writer
67
+
68
+ include ::Metanorma::Standoc::Base
69
+ include ::Metanorma::Standoc::Front
70
+ include ::Metanorma::Standoc::Lists
71
+ include ::Metanorma::Standoc::Refs
72
+ include ::Metanorma::Standoc::Inline
73
+ include ::Metanorma::Standoc::Blocks
74
+ include ::Metanorma::Standoc::Section
75
+ include ::Metanorma::Standoc::Table
76
+ include ::Metanorma::Standoc::Utils
77
+ include ::Metanorma::Standoc::Cleanup
78
+ include ::Metanorma::Standoc::Validate
79
+
80
+ register_for "standoc"
81
+
82
+ $xreftext = {}
83
+
84
+ def initialize(backend, opts)
85
+ super
86
+ basebackend "html"
87
+ outfilesuffix ".xml"
88
+ @libdir = File.dirname(self.class::_file || __FILE__)
89
+ end
90
+
91
+ class << self
92
+ attr_accessor :_file
93
+ end
94
+
95
+ def self.inherited(konv) # rubocop:disable Lint/MissingSuper
96
+ konv._file = caller_locations(1..1).first.absolute_path
97
+ end
98
+
99
+ # path to isodoc assets in child gems
100
+ def html_doc_path(file)
101
+ File.join(@libdir, "../../isodoc/html", file)
102
+ end
103
+
104
+ def content(node)
105
+ node.content
106
+ end
107
+
108
+ def skip(node, name = nil)
109
+ name = name || node.node_name
110
+ w = "converter missing for #{name} node in Metanorma backend"
111
+ @log.add("AsciiDoc Input", node, w)
112
+ nil
113
+ end
114
+
115
+ alias_method :embedded, :content
116
+ alias_method :verse, :quote
117
+ alias_method :audio, :skip
118
+ alias_method :video, :skip
119
+ alias_method :inline_button, :skip
120
+ alias_method :inline_kbd, :skip
121
+ alias_method :inline_menu, :skip
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "erb"
4
+
5
+ module Metanorma
6
+ module Standoc
7
+ module Datamodel
8
+ class AttributesTablePreprocessor < Asciidoctor::Extensions::Preprocessor
9
+ BLOCK_START_REGEXP = /\{(.+?)\.\*,(.+),(.+)\}/
10
+ BLOCK_END_REGEXP = /\A\{[A-Z]+\}\z/
11
+ MARCO_REGEXP = /\[datamodel_attributes_table,([^,]+),?(.+)?\]/
12
+ TEMPLATES_PATH = File.expand_path("../views/datamodel", __dir__).freeze
13
+ # search document for block `datamodel_attributes_table`
14
+ # read include derectives that goes after that in block and transform
15
+ # into yaml2text blocks
16
+ def process(document, reader)
17
+ input_lines = reader.readlines.to_enum
18
+ Asciidoctor::Reader.new(processed_lines(document, input_lines))
19
+ end
20
+
21
+ private
22
+
23
+ def processed_lines(document, input_lines)
24
+ input_lines.each_with_object([]) do |line, result|
25
+ if match = line.match(MARCO_REGEXP)
26
+ yaml_path = match[1]
27
+ result.push(*parse_marco(yaml_path, document))
28
+ else
29
+ result.push(line)
30
+ end
31
+ end
32
+ end
33
+
34
+ def parse_marco(yaml_path, document)
35
+ model_representation(yaml_relative_path(yaml_path, document))
36
+ .split("\n")
37
+ end
38
+
39
+ def model_representation(model_path)
40
+ template = File.read(File.join(
41
+ TEMPLATES_PATH,
42
+ "model_representation.adoc.erb",
43
+ ))
44
+ file_name = File.basename(model_path).gsub(/\.ya?ml/, "")
45
+ ERB
46
+ .new(template)
47
+ .result(binding)
48
+ end
49
+
50
+ def yaml_relative_path(file_path, document)
51
+ directory = File.dirname(document.attributes["docfile"] || ".")
52
+ document.path_resolver.system_path(file_path, directory)
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end