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.
- checksums.yaml +4 -4
- data/.github/workflows/rake.yml +3 -31
- data/.gitignore +23 -0
- data/lib/asciidoctor/standoc/base.rb +2 -145
- data/lib/asciidoctor/standoc/blocks.rb +2 -238
- data/lib/asciidoctor/standoc/blocks_notes.rb +2 -100
- data/lib/asciidoctor/standoc/cleanup.rb +2 -208
- data/lib/asciidoctor/standoc/cleanup_amend.rb +2 -53
- data/lib/asciidoctor/standoc/cleanup_block.rb +2 -172
- data/lib/asciidoctor/standoc/cleanup_boilerplate.rb +2 -212
- data/lib/asciidoctor/standoc/cleanup_footnotes.rb +2 -108
- data/lib/asciidoctor/standoc/cleanup_image.rb +2 -69
- data/lib/asciidoctor/standoc/cleanup_inline.rb +2 -189
- data/lib/asciidoctor/standoc/cleanup_maths.rb +2 -221
- data/lib/asciidoctor/standoc/cleanup_ref.rb +2 -169
- data/lib/asciidoctor/standoc/cleanup_ref_dl.rb +2 -103
- data/lib/asciidoctor/standoc/cleanup_reqt.rb +2 -110
- data/lib/asciidoctor/standoc/cleanup_section.rb +2 -184
- data/lib/asciidoctor/standoc/cleanup_section_names.rb +2 -91
- data/lib/asciidoctor/standoc/cleanup_symbols.rb +2 -47
- data/lib/asciidoctor/standoc/cleanup_table.rb +2 -67
- data/lib/asciidoctor/standoc/cleanup_terms.rb +2 -139
- data/lib/asciidoctor/standoc/cleanup_terms_designations.rb +2 -198
- data/lib/asciidoctor/standoc/cleanup_text.rb +2 -95
- data/lib/asciidoctor/standoc/cleanup_toc.rb +3 -0
- data/lib/asciidoctor/standoc/cleanup_xref.rb +2 -106
- data/lib/asciidoctor/standoc/converter.rb +2 -123
- data/lib/asciidoctor/standoc/datamodel/attributes_table_preprocessor.rb +2 -56
- data/lib/asciidoctor/standoc/datamodel/diagram_preprocessor.rb +2 -102
- data/lib/asciidoctor/standoc/datamodel/plantuml_renderer.rb +3 -404
- data/lib/asciidoctor/standoc/deprecated.rb +5 -0
- data/lib/asciidoctor/standoc/front.rb +2 -223
- data/lib/asciidoctor/standoc/front_contributor.rb +2 -191
- data/lib/asciidoctor/standoc/inline.rb +2 -231
- data/lib/asciidoctor/standoc/lists.rb +2 -119
- data/lib/asciidoctor/standoc/macros.rb +2 -203
- data/lib/asciidoctor/standoc/macros_form.rb +2 -62
- data/lib/asciidoctor/standoc/macros_note.rb +2 -44
- data/lib/asciidoctor/standoc/macros_plantuml.rb +2 -112
- data/lib/asciidoctor/standoc/macros_terms.rb +2 -180
- data/lib/asciidoctor/standoc/ref.rb +2 -251
- data/lib/asciidoctor/standoc/ref_sect.rb +2 -153
- data/lib/asciidoctor/standoc/ref_utility.rb +2 -0
- data/lib/asciidoctor/standoc/render.rb +2 -114
- data/lib/asciidoctor/standoc/reqt.rb +2 -89
- data/lib/asciidoctor/standoc/section.rb +2 -207
- data/lib/asciidoctor/standoc/table.rb +2 -84
- data/lib/asciidoctor/standoc/term_lookup_cleanup.rb +2 -178
- data/lib/asciidoctor/standoc/terms.rb +2 -159
- data/lib/asciidoctor/standoc/utils.rb +2 -100
- data/lib/asciidoctor/standoc/validate.rb +2 -157
- data/lib/asciidoctor/standoc/validate_section.rb +2 -54
- data/lib/metanorma/standoc/base.rb +149 -0
- data/lib/{asciidoctor → metanorma}/standoc/basicdoc.rng +0 -0
- data/lib/{asciidoctor → metanorma}/standoc/biblio.rng +0 -0
- data/lib/metanorma/standoc/blocks.rb +239 -0
- data/lib/metanorma/standoc/blocks_notes.rb +101 -0
- data/lib/metanorma/standoc/cleanup.rb +146 -0
- data/lib/metanorma/standoc/cleanup_amend.rb +54 -0
- data/lib/metanorma/standoc/cleanup_block.rb +173 -0
- data/lib/metanorma/standoc/cleanup_boilerplate.rb +213 -0
- data/lib/metanorma/standoc/cleanup_footnotes.rb +109 -0
- data/lib/metanorma/standoc/cleanup_image.rb +70 -0
- data/lib/metanorma/standoc/cleanup_inline.rb +190 -0
- data/lib/metanorma/standoc/cleanup_maths.rb +222 -0
- data/lib/metanorma/standoc/cleanup_ref.rb +170 -0
- data/lib/metanorma/standoc/cleanup_ref_dl.rb +104 -0
- data/lib/metanorma/standoc/cleanup_reqt.rb +111 -0
- data/lib/metanorma/standoc/cleanup_section.rb +212 -0
- data/lib/metanorma/standoc/cleanup_section_names.rb +92 -0
- data/lib/metanorma/standoc/cleanup_symbols.rb +48 -0
- data/lib/metanorma/standoc/cleanup_table.rb +68 -0
- data/lib/metanorma/standoc/cleanup_terms.rb +140 -0
- data/lib/metanorma/standoc/cleanup_terms_designations.rb +199 -0
- data/lib/metanorma/standoc/cleanup_text.rb +96 -0
- data/lib/metanorma/standoc/cleanup_toc.rb +98 -0
- data/lib/metanorma/standoc/cleanup_xref.rb +107 -0
- data/lib/metanorma/standoc/converter.rb +124 -0
- data/lib/metanorma/standoc/datamodel/attributes_table_preprocessor.rb +57 -0
- data/lib/metanorma/standoc/datamodel/diagram_preprocessor.rb +103 -0
- data/lib/metanorma/standoc/datamodel/plantuml_renderer.rb +409 -0
- data/lib/metanorma/standoc/front.rb +224 -0
- data/lib/metanorma/standoc/front_contributor.rb +192 -0
- data/lib/metanorma/standoc/inline.rb +232 -0
- data/lib/{asciidoctor → metanorma}/standoc/isodoc.rng +29 -0
- data/lib/metanorma/standoc/lists.rb +120 -0
- data/lib/metanorma/standoc/macros.rb +204 -0
- data/lib/metanorma/standoc/macros_form.rb +63 -0
- data/lib/metanorma/standoc/macros_note.rb +45 -0
- data/lib/metanorma/standoc/macros_plantuml.rb +113 -0
- data/lib/metanorma/standoc/macros_terms.rb +181 -0
- data/lib/metanorma/standoc/ref.rb +243 -0
- data/lib/metanorma/standoc/ref_sect.rb +153 -0
- data/lib/{asciidoctor/standoc/ref_date_id.rb → metanorma/standoc/ref_utility.rb} +43 -5
- data/lib/metanorma/standoc/render.rb +115 -0
- data/lib/metanorma/standoc/reqt.rb +90 -0
- data/lib/{asciidoctor → metanorma}/standoc/reqt.rng +0 -0
- data/lib/metanorma/standoc/section.rb +209 -0
- data/lib/metanorma/standoc/table.rb +85 -0
- data/lib/metanorma/standoc/term_lookup_cleanup.rb +179 -0
- data/lib/metanorma/standoc/terms.rb +160 -0
- data/lib/metanorma/standoc/utils.rb +101 -0
- data/lib/metanorma/standoc/validate.rb +158 -0
- data/lib/metanorma/standoc/validate_section.rb +55 -0
- data/lib/metanorma/standoc/version.rb +1 -1
- data/lib/{asciidoctor → metanorma}/standoc/views/datamodel/model_representation.adoc.erb +0 -0
- data/lib/{asciidoctor → metanorma}/standoc/views/datamodel/plantuml_representation.adoc.erb +0 -0
- data/lib/metanorma-standoc.rb +1 -1
- data/metanorma-standoc.gemspec +1 -1
- data/spec/{asciidoctor → metanorma}/base_spec.rb +27 -10
- data/spec/{asciidoctor → metanorma}/blank_spec.rb +1 -1
- data/spec/{asciidoctor → metanorma}/blocks_spec.rb +1 -1
- data/spec/{asciidoctor → metanorma}/cleanup_blocks_spec.rb +1 -1
- data/spec/{asciidoctor → metanorma}/cleanup_sections_spec.rb +1 -1
- data/spec/{asciidoctor → metanorma}/cleanup_spec.rb +5 -5
- data/spec/{asciidoctor → metanorma}/cleanup_terms_spec.rb +2 -2
- data/spec/{asciidoctor → metanorma}/datamodel/attributes_table_preprocessor_spec.rb +1 -1
- data/spec/{asciidoctor → metanorma}/datamodel/diagram_preprocessor_spec.rb +1 -1
- data/spec/{asciidoctor → metanorma}/inline_spec.rb +1 -1
- data/spec/{asciidoctor → metanorma}/isobib_cache_spec.rb +1 -1
- data/spec/{asciidoctor → metanorma}/lists_spec.rb +1 -1
- data/spec/{asciidoctor → metanorma}/macros_json2text_spec.rb +0 -0
- data/spec/{asciidoctor → metanorma}/macros_plantuml_spec.rb +3 -3
- data/spec/{asciidoctor → metanorma}/macros_spec.rb +6 -6
- data/spec/{asciidoctor → metanorma}/macros_yaml2text_spec.rb +0 -0
- data/spec/metanorma/refs_dl_spec.rb +863 -0
- data/spec/{asciidoctor → metanorma}/refs_spec.rb +399 -25
- data/spec/{asciidoctor → metanorma}/section_spec.rb +42 -17
- data/spec/{asciidoctor → metanorma}/table_spec.rb +1 -1
- data/spec/{asciidoctor → metanorma}/validate_spec.rb +2 -2
- data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +42 -42
- data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec1.yml +11 -11
- data/spec/vcr_cassettes/isobib_get_123.yml +12 -12
- data/spec/vcr_cassettes/isobib_get_123_1.yml +21 -21
- data/spec/vcr_cassettes/isobib_get_123_1_fr.yml +81 -81
- data/spec/vcr_cassettes/isobib_get_123_2001.yml +10 -10
- data/spec/vcr_cassettes/isobib_get_124.yml +11 -11
- data/spec/vcr_cassettes/rfcbib_get_rfc8341.yml +13 -13
- data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +46 -46
- metadata +82 -32
- data/spec/asciidoctor/refs_dl_spec.rb +0 -864
@@ -0,0 +1,115 @@
|
|
1
|
+
module Metanorma
|
2
|
+
module Standoc
|
3
|
+
module Base
|
4
|
+
def html_extract_attributes(node)
|
5
|
+
{
|
6
|
+
script: node.attr("script"),
|
7
|
+
bodyfont: node.attr("body-font"),
|
8
|
+
headerfont: node.attr("header-font"),
|
9
|
+
monospacefont: node.attr("monospace-font"),
|
10
|
+
i18nyaml: node.attr("i18nyaml"),
|
11
|
+
scope: node.attr("scope"),
|
12
|
+
htmlstylesheet: node.attr("htmlstylesheet"),
|
13
|
+
htmlstylesheet_override: node.attr("htmlstylesheet-override"),
|
14
|
+
htmlcoverpage: node.attr("htmlcoverpage"),
|
15
|
+
htmlintropage: node.attr("htmlintropage"),
|
16
|
+
scripts: node.attr("scripts"),
|
17
|
+
scripts_override: node.attr("scripts-override"),
|
18
|
+
scripts_pdf: node.attr("scripts-pdf"),
|
19
|
+
datauriimage: node.attr("data-uri-image") != "false",
|
20
|
+
htmltoclevels: node.attr("htmltoclevels") || node.attr("toclevels"),
|
21
|
+
doctoclevels: node.attr("doctoclevels") || node.attr("toclevels"),
|
22
|
+
break_up_urls_in_tables: node.attr("break-up-urls-in-tables"),
|
23
|
+
suppressasciimathdup: node.attr("suppress-asciimath-dup"),
|
24
|
+
bare: node.attr("bare"),
|
25
|
+
sectionsplit: node.attr("sectionsplit"),
|
26
|
+
baseassetpath: node.attr("base-asset-path"),
|
27
|
+
aligncrosselements: node.attr("align-cross-elements"),
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
def html_converter(node)
|
32
|
+
IsoDoc::HtmlConvert.new(html_extract_attributes(node))
|
33
|
+
end
|
34
|
+
|
35
|
+
def pdf_converter(node)
|
36
|
+
return nil if node.attr("no-pdf")
|
37
|
+
|
38
|
+
IsoDoc::Standoc::PdfConvert.new(pdf_extract_attributes(node))
|
39
|
+
end
|
40
|
+
|
41
|
+
def doc_extract_attributes(node)
|
42
|
+
attrs = {
|
43
|
+
script: node.attr("script"),
|
44
|
+
bodyfont: node.attr("body-font"),
|
45
|
+
headerfont: node.attr("header-font"),
|
46
|
+
monospacefont: node.attr("monospace-font"),
|
47
|
+
i18nyaml: node.attr("i18nyaml"),
|
48
|
+
scope: node.attr("scope"),
|
49
|
+
wordstylesheet: node.attr("wordstylesheet"),
|
50
|
+
wordstylesheet_override: node.attr("wordstylesheet-override"),
|
51
|
+
standardstylesheet: node.attr("standardstylesheet"),
|
52
|
+
header: node.attr("header"),
|
53
|
+
wordcoverpage: node.attr("wordcoverpage"),
|
54
|
+
wordintropage: node.attr("wordintropage"),
|
55
|
+
ulstyle: node.attr("ulstyle"),
|
56
|
+
olstyle: node.attr("olstyle"),
|
57
|
+
htmltoclevels: node.attr("htmltoclevels") || node.attr("toclevels"),
|
58
|
+
doctoclevels: node.attr("doctoclevels") || node.attr("toclevels"),
|
59
|
+
break_up_urls_in_tables: node.attr("break-up-urls-in-tables"),
|
60
|
+
suppressasciimathdup: node.attr("suppress-asciimath-dup"),
|
61
|
+
bare: node.attr("bare"),
|
62
|
+
baseassetpath: node.attr("base-asset-path"),
|
63
|
+
aligncrosselements: node.attr("align-cross-elements"),
|
64
|
+
}
|
65
|
+
|
66
|
+
if fonts_manifest = node.attr(FONTS_MANIFEST)
|
67
|
+
attrs[IsoDoc::XslfoPdfConvert::MN2PDF_OPTIONS] = {
|
68
|
+
IsoDoc::XslfoPdfConvert::MN2PDF_FONT_MANIFEST => fonts_manifest,
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
attrs
|
73
|
+
end
|
74
|
+
|
75
|
+
def pdf_extract_attributes(node)
|
76
|
+
%w(pdf-encrypt pdf-encryption-length pdf-user-password
|
77
|
+
pdf-owner-password pdf-allow-copy-content pdf-allow-edit-content
|
78
|
+
pdf-allow-assemble-document pdf-allow-edit-annotations
|
79
|
+
pdf-allow-print pdf-allow-print-hq pdf-allow-fill-in-forms
|
80
|
+
pdf-allow-access-content pdf-encrypt-metadata)
|
81
|
+
.each_with_object({}) do |x, m|
|
82
|
+
m[x.gsub(/-/, "").to_i] = node.attr(x)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def doc_converter(node)
|
87
|
+
IsoDoc::WordConvert.new(doc_extract_attributes(node))
|
88
|
+
end
|
89
|
+
|
90
|
+
def presentation_xml_converter(node)
|
91
|
+
IsoDoc::PresentationXMLConvert.new(html_extract_attributes(node))
|
92
|
+
end
|
93
|
+
|
94
|
+
def default_fonts(node)
|
95
|
+
b = node.attr("body-font") ||
|
96
|
+
(node.attr("script") == "Hans" ? '"Source Han Sans",serif' : '"Cambria",serif')
|
97
|
+
h = node.attr("header-font") ||
|
98
|
+
(node.attr("script") == "Hans" ? '"Source Han Sans",sans-serif' : '"Cambria",serif')
|
99
|
+
m = node.attr("monospace-font") || '"Courier New",monospace'
|
100
|
+
"$bodyfont: #{b};\n$headerfont: #{h};\n$monospacefont: #{m};\n"
|
101
|
+
end
|
102
|
+
|
103
|
+
def outputs(node, ret)
|
104
|
+
File.open("#{@filename}.xml", "w:UTF-8") { |f| f.write(ret) }
|
105
|
+
presentation_xml_converter(node).convert("#{@filename}.xml")
|
106
|
+
html_converter(node).convert("#{@filename}.presentation.xml",
|
107
|
+
nil, false, "#{@filename}.html")
|
108
|
+
doc_converter(node).convert("#{@filename}.presentation.xml",
|
109
|
+
nil, false, "#{@filename}.doc")
|
110
|
+
pdf_converter(node)&.convert("#{@filename}.presentation.xml",
|
111
|
+
nil, false, "#{@filename}.pdf")
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require "htmlentities"
|
2
|
+
require "uri" if /^2\./.match?(RUBY_VERSION)
|
3
|
+
require "mime/types"
|
4
|
+
require "base64"
|
5
|
+
|
6
|
+
module Metanorma
|
7
|
+
module Standoc
|
8
|
+
module Blocks
|
9
|
+
def reqt_subpart(name)
|
10
|
+
%w(specification measurement-target verification import label title
|
11
|
+
description component subject inherit classification).include? name
|
12
|
+
end
|
13
|
+
|
14
|
+
def reqt_subpart_attrs(node, name)
|
15
|
+
klass = node.attr("class") || "component"
|
16
|
+
attr_code(keep_attrs(node)
|
17
|
+
.merge(exclude: node.option?("exclude"),
|
18
|
+
type: node.attr("type"),
|
19
|
+
class: name == "component" ? klass : nil))
|
20
|
+
end
|
21
|
+
|
22
|
+
def requirement_subpart(node)
|
23
|
+
name = node.role || node.attr("style")
|
24
|
+
noko do |xml|
|
25
|
+
xml.send name, **reqt_subpart_attrs(node, name) do |o|
|
26
|
+
o << node.content
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def req_classif_parse(classif)
|
32
|
+
ret = []
|
33
|
+
HTMLEntities.new.decode(classif).split(/;\s*/).each do |c|
|
34
|
+
c1 = c.split(/:\s*/)
|
35
|
+
next unless c1.size == 2
|
36
|
+
|
37
|
+
c1[1].split(/,\s*/).each { |v| ret << [c1[0], v] }
|
38
|
+
end
|
39
|
+
ret
|
40
|
+
end
|
41
|
+
|
42
|
+
def requirement_classification(classif, out)
|
43
|
+
req_classif_parse(classif).each do |r|
|
44
|
+
out.classification do |c|
|
45
|
+
c.tag { |t| t << r[0] }
|
46
|
+
c.value { |v| v << r[1] }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def reqt_attrs(node)
|
52
|
+
attr_code(keep_attrs(node).merge(id_unnum_attrs(node)).merge(
|
53
|
+
id: Metanorma::Utils::anchor_or_uuid(node),
|
54
|
+
unnumbered: node.option?("unnumbered") ? "true" : nil,
|
55
|
+
number: node.attr("number"),
|
56
|
+
subsequence: node.attr("subsequence"),
|
57
|
+
obligation: node.attr("obligation"),
|
58
|
+
filename: node.attr("filename"),
|
59
|
+
type: node.attr("type"),
|
60
|
+
model: node.attr("model"),
|
61
|
+
))
|
62
|
+
end
|
63
|
+
|
64
|
+
def requirement_elems(node, out)
|
65
|
+
node.title and out.title { |t| t << node.title }
|
66
|
+
a = node.attr("label") and out.label do |l|
|
67
|
+
l << a
|
68
|
+
end
|
69
|
+
a = node.attr("subject") and csv_split(a)&.each do |subj|
|
70
|
+
out.subject { |s| s << subj }
|
71
|
+
end
|
72
|
+
a = HTMLEntities.new.decode(node.attr("inherit")) and
|
73
|
+
csv_split(a)&.each do |i|
|
74
|
+
out.inherit { |inh| inh << i }
|
75
|
+
end
|
76
|
+
classif = node.attr("classification") and
|
77
|
+
requirement_classification(classif, out)
|
78
|
+
end
|
79
|
+
|
80
|
+
def requirement(node, obligation)
|
81
|
+
noko do |xml|
|
82
|
+
xml.send obligation, **reqt_attrs(node) do |ex|
|
83
|
+
requirement_elems(node, ex)
|
84
|
+
wrap_in_para(node, ex)
|
85
|
+
end
|
86
|
+
end.join("\n")
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
File without changes
|
@@ -0,0 +1,209 @@
|
|
1
|
+
require "uri" if /^2\./.match?(RUBY_VERSION)
|
2
|
+
require_relative "ref_sect"
|
3
|
+
require_relative "terms"
|
4
|
+
|
5
|
+
module Metanorma
|
6
|
+
module Standoc
|
7
|
+
module Section
|
8
|
+
@biblio = false
|
9
|
+
@term_def = false
|
10
|
+
@norm_ref = false
|
11
|
+
|
12
|
+
def sectiontype1(node)
|
13
|
+
node&.attr("heading")&.downcase ||
|
14
|
+
node.title.gsub(%r{<index>.*?</index>}m, "").gsub(/<[^>]+>/, "")
|
15
|
+
.strip.downcase
|
16
|
+
end
|
17
|
+
|
18
|
+
def sectiontype(node, level = true)
|
19
|
+
ret = sectiontype1(node)
|
20
|
+
ret1 = sectiontype_streamline(ret)
|
21
|
+
return ret1 if ret1 == "symbols and abbreviated terms"
|
22
|
+
return nil unless !level || node.level == 1
|
23
|
+
return nil if @seen_headers.include? ret
|
24
|
+
|
25
|
+
@seen_headers << ret
|
26
|
+
ret1
|
27
|
+
end
|
28
|
+
|
29
|
+
def sectiontype_streamline(ret)
|
30
|
+
case ret
|
31
|
+
when "terms and definitions",
|
32
|
+
"terms, definitions, symbols and abbreviated terms",
|
33
|
+
"terms, definitions, symbols and abbreviations",
|
34
|
+
"terms, definitions and symbols",
|
35
|
+
"terms, definitions and abbreviations",
|
36
|
+
"terms, definitions and abbreviated terms"
|
37
|
+
"terms and definitions"
|
38
|
+
when "symbols and abbreviated terms",
|
39
|
+
"symbols", "abbreviated terms", "abbreviations"
|
40
|
+
"symbols and abbreviated terms"
|
41
|
+
else
|
42
|
+
ret
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def section_attributes(node)
|
47
|
+
ret = { id: Metanorma::Utils::anchor_or_uuid(node),
|
48
|
+
language: node.attributes["language"],
|
49
|
+
script: node.attributes["script"],
|
50
|
+
number: node.attributes["number"],
|
51
|
+
type: node.attributes["type"],
|
52
|
+
annex: (if (node.attr("style") == "appendix" ||
|
53
|
+
node.role == "appendix") &&
|
54
|
+
node.level == 1
|
55
|
+
true
|
56
|
+
end),
|
57
|
+
tag: node&.attr("tag"),
|
58
|
+
"multilingual-rendering": node&.attr("multilingual-rendering"),
|
59
|
+
preface: (if node.role == "preface" ||
|
60
|
+
node.attr("style") == "preface"
|
61
|
+
true
|
62
|
+
end) }
|
63
|
+
return ret unless node.attributes["change"]
|
64
|
+
|
65
|
+
ret.merge(change: node.attributes["change"],
|
66
|
+
path: node.attributes["path"],
|
67
|
+
path_end: node.attributes["path_end"],
|
68
|
+
title: node.attributes["title"])
|
69
|
+
end
|
70
|
+
|
71
|
+
def section(node)
|
72
|
+
a = section_attributes(node)
|
73
|
+
noko do |xml|
|
74
|
+
case sectiontype(node)
|
75
|
+
when "introduction" then introduction_parse(a, xml, node)
|
76
|
+
when "foreword" then foreword_parse(a, xml, node)
|
77
|
+
when "scope" then scope_parse(a, xml, node)
|
78
|
+
when "normative references" then norm_ref_parse(a, xml, node)
|
79
|
+
when "terms and definitions"
|
80
|
+
@term_def = true
|
81
|
+
term_def_parse(a, xml, node, true)
|
82
|
+
@term_def = false
|
83
|
+
when "symbols and abbreviated terms"
|
84
|
+
symbols_parse(symbols_attrs(node, a), xml, node)
|
85
|
+
when "acknowledgements"
|
86
|
+
acknowledgements_parse(a, xml, node)
|
87
|
+
when "bibliography"
|
88
|
+
bibliography_parse(a, xml, node)
|
89
|
+
else
|
90
|
+
if @term_def then term_def_subclause_parse(a, xml, node)
|
91
|
+
elsif @definitions then symbols_parse(a, xml, node)
|
92
|
+
elsif @norm_ref ||
|
93
|
+
(node.attr("style") == "bibliography" &&
|
94
|
+
sectiontype(node, false) == "normative references")
|
95
|
+
norm_ref_parse(a, xml, node)
|
96
|
+
elsif @biblio || node.attr("style") == "bibliography"
|
97
|
+
bibliography_parse(a, xml, node)
|
98
|
+
elsif node.attr("style") == "abstract"
|
99
|
+
abstract_parse(a, xml, node)
|
100
|
+
elsif node.attr("style") == "index"
|
101
|
+
indexsect_parse(a, xml, node)
|
102
|
+
elsif node.attr("style") == "appendix" && node.level == 1
|
103
|
+
annex_parse(a, xml, node)
|
104
|
+
else
|
105
|
+
clause_parse(a, xml, node)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end.join("\n")
|
109
|
+
end
|
110
|
+
|
111
|
+
def set_obligation(attrs, node)
|
112
|
+
attrs[:obligation] = if node.attributes.has_key?("obligation")
|
113
|
+
node.attr("obligation")
|
114
|
+
elsif node.parent.attributes.has_key?("obligation")
|
115
|
+
node.parent.attr("obligation")
|
116
|
+
else
|
117
|
+
"normative"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def preamble(node)
|
122
|
+
noko do |xml|
|
123
|
+
xml.foreword **attr_code(section_attributes(node)) do |xml_abstract|
|
124
|
+
xml_abstract.title do |t|
|
125
|
+
t << (node.blocks[0].title || @i18n.foreword)
|
126
|
+
end
|
127
|
+
content = node.content
|
128
|
+
xml_abstract << content
|
129
|
+
end
|
130
|
+
end.join("\n")
|
131
|
+
end
|
132
|
+
|
133
|
+
def indexsect_parse(attrs, xml, node)
|
134
|
+
xml.indexsect **attr_code(attrs) do |xml_section|
|
135
|
+
xml_section.title { |name| name << node.title }
|
136
|
+
xml_section << node.content
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def abstract_parse(attrs, xml, node)
|
141
|
+
xml.abstract **attr_code(attrs) do |xml_section|
|
142
|
+
xml_section << node.content
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def scope_parse(attrs, xml, node)
|
147
|
+
clause_parse(attrs.merge(type: "scope"), xml, node)
|
148
|
+
end
|
149
|
+
|
150
|
+
def clause_parse(attrs, xml, node)
|
151
|
+
attrs[:"inline-header"] = node.option? "inline-header"
|
152
|
+
attrs[:bibitem] = true if node.option? "bibitem"
|
153
|
+
attrs[:level] = node.attr("level")
|
154
|
+
set_obligation(attrs, node)
|
155
|
+
xml.send "clause", **attr_code(attrs) do |xml_section|
|
156
|
+
xml_section.title { |n| n << node.title } unless node.title.nil?
|
157
|
+
xml_section << node.content
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def annex_parse(attrs, xml, node)
|
162
|
+
attrs[:"inline-header"] = node.option? "inline-header"
|
163
|
+
set_obligation(attrs, node)
|
164
|
+
xml.annex **attr_code(attrs) do |xml_section|
|
165
|
+
xml_section.title { |name| name << node.title }
|
166
|
+
xml_section << node.content
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def introduction_parse(attrs, xml, node)
|
171
|
+
xml.introduction **attr_code(attrs) do |xml_section|
|
172
|
+
xml_section.title { |t| t << @i18n.introduction }
|
173
|
+
content = node.content
|
174
|
+
xml_section << content
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def foreword_parse(attrs, xml, node)
|
179
|
+
xml.foreword **attr_code(attrs) do |xml_section|
|
180
|
+
xml_section.title { |t| t << node.title }
|
181
|
+
content = node.content
|
182
|
+
xml_section << content
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
def acknowledgements_parse(attrs, xml, node)
|
187
|
+
xml.acknowledgements **attr_code(attrs) do |xml_section|
|
188
|
+
xml_section.title { |t| (t << node.title) || @i18n.acknowledgements }
|
189
|
+
content = node.content
|
190
|
+
xml_section << content
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def floating_title_attrs(node)
|
195
|
+
attr_code(id_attr(node).merge(align: node.attr("align"),
|
196
|
+
depth: node.level,
|
197
|
+
type: "floating-title"))
|
198
|
+
end
|
199
|
+
|
200
|
+
def floating_title(node)
|
201
|
+
noko do |xml|
|
202
|
+
xml.floating_title **floating_title_attrs(node) do |xml_t|
|
203
|
+
xml_t << node.title
|
204
|
+
end
|
205
|
+
end.join("\n")
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module Metanorma
|
2
|
+
module Standoc
|
3
|
+
module Table
|
4
|
+
def table_attrs(node)
|
5
|
+
keep_attrs(node)
|
6
|
+
.merge(id: Metanorma::Utils::anchor_or_uuid(node),
|
7
|
+
headerrows: node.attr("headerrows"),
|
8
|
+
unnumbered: node.option?("unnumbered") ? "true" : nil,
|
9
|
+
number: node.attr("number"),
|
10
|
+
subsequence: node.attr("subsequence"),
|
11
|
+
alt: node.attr("alt"),
|
12
|
+
summary: node.attr("summary"),
|
13
|
+
width: node.attr("width"))
|
14
|
+
end
|
15
|
+
|
16
|
+
def table(node)
|
17
|
+
@table_fn_number = "a"
|
18
|
+
noko do |xml|
|
19
|
+
xml.table **attr_code(table_attrs(node)) do |xml_table|
|
20
|
+
colgroup(node, xml_table)
|
21
|
+
table_name(node, xml_table)
|
22
|
+
%i(head body foot).reject do |tblsec|
|
23
|
+
node.rows[tblsec].empty?
|
24
|
+
end
|
25
|
+
table_head_body_and_foot node, xml_table
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def colgroup(node, xml_table)
|
33
|
+
return if node.option? "autowidth"
|
34
|
+
|
35
|
+
cols = node&.attr("cols")&.split(/,/) or return
|
36
|
+
return unless (cols.size > 1) && cols.all? { |c| /\d/.match(c) }
|
37
|
+
|
38
|
+
xml_table.colgroup do |cg|
|
39
|
+
node.columns.each do |col|
|
40
|
+
cg.col **{ width: "#{col.attr 'colpcwidth'}%" }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def table_name(node, xml_table)
|
46
|
+
if node.title?
|
47
|
+
xml_table.name do |n|
|
48
|
+
n << node.title
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def table_cell1(cell, thd)
|
54
|
+
thd << if cell.style == :asciidoc
|
55
|
+
cell.content
|
56
|
+
else
|
57
|
+
cell.text
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def table_cell(node, xml_tr, tblsec)
|
62
|
+
cell_attributes =
|
63
|
+
{ id: node.id, colspan: node.colspan, valign: node.attr("valign"),
|
64
|
+
rowspan: node.rowspan, align: node.attr("halign") }
|
65
|
+
cell_tag = "td"
|
66
|
+
cell_tag = "th" if tblsec == :head || node.style == :header
|
67
|
+
xml_tr.send cell_tag, **attr_code(cell_attributes) do |thd|
|
68
|
+
table_cell1(node, thd)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def table_head_body_and_foot(node, xml)
|
73
|
+
%i(head body foot).reject { |s| node.rows[s].empty? }.each do |s|
|
74
|
+
xml.send "t#{s}" do |xml_tblsec|
|
75
|
+
node.rows[s].each do |row|
|
76
|
+
xml_tblsec.tr do |xml_tr|
|
77
|
+
row.each { |cell| table_cell(cell, xml_tr, s) }
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,179 @@
|
|
1
|
+
# frozen_string_literal: true.
|
2
|
+
require "metanorma/standoc/utils"
|
3
|
+
|
4
|
+
|
5
|
+
module Metanorma
|
6
|
+
module Standoc
|
7
|
+
# Intelligent term lookup xml modifier
|
8
|
+
class TermLookupCleanup
|
9
|
+
AUTOMATIC_GENERATED_ID_REGEXP = /\A_/.freeze
|
10
|
+
EXISTING_TERM_REGEXP = /\Aterm-/.freeze
|
11
|
+
EXISTING_SYMBOL_REGEXP = /\Asymbol-/.freeze
|
12
|
+
|
13
|
+
attr_reader :xmldoc, :termlookup, :log
|
14
|
+
|
15
|
+
def initialize(xmldoc, log)
|
16
|
+
@xmldoc = xmldoc
|
17
|
+
@log = log
|
18
|
+
@termlookup = { term: {}, symbol: {}, secondary2primary: {} }
|
19
|
+
@idhash = {}
|
20
|
+
end
|
21
|
+
|
22
|
+
def call
|
23
|
+
@idhash = populate_idhash
|
24
|
+
@termlookup = replace_automatic_generated_ids_terms
|
25
|
+
set_termxref_tags_target
|
26
|
+
concept_cleanup
|
27
|
+
related_cleanup
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def concept_cleanup
|
33
|
+
xmldoc.xpath("//concept").each do |n|
|
34
|
+
n.delete("type")
|
35
|
+
refterm = n.at("./refterm") or next
|
36
|
+
p = @termlookup[:secondary2primary][refterm.text] and
|
37
|
+
refterm.children = p
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def related_cleanup
|
42
|
+
xmldoc.xpath("//related").each do |n|
|
43
|
+
refterm = n.at("./refterm") or next
|
44
|
+
p = @termlookup[:secondary2primary][refterm.text] and
|
45
|
+
refterm.children = p
|
46
|
+
refterm.replace("<preferred><expression><name>#{refterm.children.to_xml}"\
|
47
|
+
"</name></expression></preferred>")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def populate_idhash
|
52
|
+
xmldoc.xpath("//*[@id]").each_with_object({}) do |n, mem|
|
53
|
+
next unless /^(term|symbol)-/.match?(n["id"])
|
54
|
+
|
55
|
+
mem[n["id"]] = true
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def set_termxref_tags_target
|
60
|
+
xmldoc.xpath("//termxref").each do |node|
|
61
|
+
target = normalize_ref_id(node.text)
|
62
|
+
if termlookup[:term][target].nil? && termlookup[:symbol][target].nil?
|
63
|
+
remove_missing_ref(node, target)
|
64
|
+
next
|
65
|
+
end
|
66
|
+
x = node.at("../xrefrender") and modify_ref_node(x, target)
|
67
|
+
node.name = "refterm"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def remove_missing_ref(node, target)
|
72
|
+
if node.at("../concept[@type = 'symbol']")
|
73
|
+
remove_missing_ref_symbol(node, target)
|
74
|
+
else
|
75
|
+
remove_missing_ref_term(node, target)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def remove_missing_ref_term(node, target)
|
80
|
+
log.add("AsciiDoc Input", node,
|
81
|
+
%(Error: Term reference in `term[#{target}]` missing: \
|
82
|
+
"#{target}" is not defined in document))
|
83
|
+
node.name = "strong"
|
84
|
+
node&.at("../xrefrender")&.remove
|
85
|
+
display = node&.at("../renderterm")&.remove&.children
|
86
|
+
display = [] if display.nil? || display&.to_xml == node.text
|
87
|
+
d = display.empty? ? "" : ", display <tt>#{display.to_xml}</tt>"
|
88
|
+
node.children = "term <tt>#{node.text}</tt>#{d} "\
|
89
|
+
"not resolved via ID <tt>#{target}</tt>"
|
90
|
+
end
|
91
|
+
|
92
|
+
def remove_missing_ref_symbol(node, target)
|
93
|
+
log.add("AsciiDoc Input", node,
|
94
|
+
%(Error: Symbol reference in `symbol[#{target}]` missing: \
|
95
|
+
"#{target}" is not defined in document))
|
96
|
+
node.name = "strong"
|
97
|
+
node&.at("../xrefrender")&.remove
|
98
|
+
display = node&.at("../renderterm")&.remove&.children
|
99
|
+
display = [] if display.nil? || display&.to_xml == node.text
|
100
|
+
d = display.empty? ? "" : ", display <tt>#{display.to_xml}</tt>"
|
101
|
+
node.children = "symbol <tt>#{node.text}</tt>#{d} "\
|
102
|
+
"not resolved via ID <tt>#{target}</tt>"
|
103
|
+
end
|
104
|
+
|
105
|
+
def modify_ref_node(node, target)
|
106
|
+
node.name = "xref"
|
107
|
+
s = termlookup[:symbol][target]
|
108
|
+
t = termlookup[:term][target]
|
109
|
+
type = node.parent["type"]
|
110
|
+
if type == "term" || ((!type || node.parent.name == "related") && t)
|
111
|
+
node["target"] = t
|
112
|
+
elsif type == "symbol" ||
|
113
|
+
((!type || node.parent.name == "related") && s)
|
114
|
+
node["target"] = s
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def replace_automatic_generated_ids_terms
|
119
|
+
r = xmldoc.xpath("//term").each.with_object({}) do |n, res|
|
120
|
+
normalize_id_and_memorize(n, res, "./preferred//name",
|
121
|
+
"term")
|
122
|
+
end
|
123
|
+
s = xmldoc.xpath("//definitions//dt").each.with_object({}) do |n, res|
|
124
|
+
normalize_id_and_memorize(n, res, ".", "symbol")
|
125
|
+
end
|
126
|
+
{ term: r, symbol: s, secondary2primary: pref_secondary2primary }
|
127
|
+
end
|
128
|
+
|
129
|
+
def pref_secondary2primary
|
130
|
+
xmldoc.xpath("//term").each.with_object({}) do |n, res|
|
131
|
+
n.xpath("./preferred//name").each_with_index do |p, i|
|
132
|
+
i.zero? and term = p.text
|
133
|
+
i.positive? and res[p.text] = term
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def normalize_id_and_memorize(node, res_table, text_selector, prefix)
|
139
|
+
normalize_id_and_memorize_init(node, res_table, text_selector, prefix)
|
140
|
+
memorize_other_pref_terms(node, res_table, text_selector)
|
141
|
+
end
|
142
|
+
|
143
|
+
def normalize_id_and_memorize_init(node, res_table, text_selector, prefix)
|
144
|
+
term_text = normalize_ref_id(node.at(text_selector).text)
|
145
|
+
unless AUTOMATIC_GENERATED_ID_REGEXP.match(node["id"]).nil? &&
|
146
|
+
!node["id"].nil?
|
147
|
+
id = unique_text_id(term_text, prefix)
|
148
|
+
node["id"] = id
|
149
|
+
@idhash[id] = true
|
150
|
+
end
|
151
|
+
res_table[term_text] = node["id"]
|
152
|
+
end
|
153
|
+
|
154
|
+
def memorize_other_pref_terms(node, res_table, text_selector)
|
155
|
+
node.xpath(text_selector).each_with_index do |p, i|
|
156
|
+
next unless i.positive?
|
157
|
+
|
158
|
+
res_table[normalize_ref_id(p.text)] = node["id"]
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def normalize_ref_id(text)
|
163
|
+
Metanorma::Utils::to_ncname(text.downcase.gsub(/[[:space:]]/, "-"))
|
164
|
+
end
|
165
|
+
|
166
|
+
def unique_text_id(text, prefix)
|
167
|
+
unless @idhash["#{prefix}-#{text}"]
|
168
|
+
return "#{prefix}-#{text}"
|
169
|
+
end
|
170
|
+
|
171
|
+
(1..Float::INFINITY).lazy.each do |index|
|
172
|
+
unless @idhash["#{prefix}-#{text}-#{index}"]
|
173
|
+
break("#{prefix}-#{text}-#{index}")
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|