metanorma-iso 1.7.2 → 1.8.2
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 +11 -41
- data/.gitignore +2 -0
- data/.rubocop.yml +7 -1
- data/lib/asciidoctor/iso/base.rb +14 -11
- data/lib/asciidoctor/iso/biblio.rng +4 -6
- data/lib/asciidoctor/iso/cleanup.rb +40 -24
- data/lib/asciidoctor/iso/front.rb +29 -17
- data/lib/asciidoctor/iso/front_id.rb +81 -60
- data/lib/asciidoctor/iso/isodoc.rng +327 -2
- data/lib/asciidoctor/iso/isostandard.rng +12 -97
- data/lib/asciidoctor/iso/section.rb +2 -1
- data/lib/asciidoctor/iso/validate.rb +22 -109
- data/lib/asciidoctor/iso/validate_image.rb +97 -0
- data/lib/asciidoctor/iso/validate_requirements.rb +26 -20
- data/lib/asciidoctor/iso/validate_section.rb +39 -20
- data/lib/asciidoctor/iso/validate_style.rb +36 -24
- data/lib/asciidoctor/iso/validate_title.rb +23 -17
- data/lib/isodoc/iso/base_convert.rb +19 -2
- data/lib/isodoc/iso/html/style-human.css +7 -0
- data/lib/isodoc/iso/html/style-iso.css +7 -0
- data/lib/isodoc/iso/html_convert.rb +0 -1
- data/lib/isodoc/iso/i18n-en.yaml +4 -0
- data/lib/isodoc/iso/i18n-fr.yaml +4 -0
- data/lib/isodoc/iso/i18n-zh-Hans.yaml +4 -0
- data/lib/isodoc/iso/index.rb +140 -0
- data/lib/isodoc/iso/iso.amendment.xsl +1157 -208
- data/lib/isodoc/iso/iso.international-standard.xsl +1157 -208
- data/lib/isodoc/iso/metadata.rb +1 -0
- data/lib/isodoc/iso/presentation_xml_convert.rb +45 -37
- data/lib/isodoc/iso/sts_convert.rb +10 -13
- data/lib/isodoc/iso/word_convert.rb +0 -1
- data/lib/isodoc/iso/xref.rb +46 -25
- data/lib/metanorma/iso/processor.rb +1 -0
- data/lib/metanorma/iso/version.rb +1 -1
- data/metanorma-iso.gemspec +8 -8
- data/spec/{asciidoctor-iso → asciidoctor}/amd_spec.rb +5 -5
- data/spec/asciidoctor/base_spec.rb +825 -0
- data/spec/{asciidoctor-iso → asciidoctor}/blocks_spec.rb +0 -0
- data/spec/{asciidoctor-iso → asciidoctor}/cleanup_spec.rb +383 -25
- data/spec/{asciidoctor-iso → asciidoctor}/inline_spec.rb +0 -0
- data/spec/{asciidoctor-iso → asciidoctor}/lists_spec.rb +0 -0
- data/spec/{asciidoctor-iso → asciidoctor}/refs_spec.rb +0 -0
- data/spec/{asciidoctor-iso → asciidoctor}/section_spec.rb +0 -14
- data/spec/{asciidoctor-iso → asciidoctor}/table_spec.rb +0 -0
- data/spec/{asciidoctor-iso → asciidoctor}/validate_spec.rb +188 -83
- data/spec/isodoc/postproc_spec.rb +481 -438
- data/spec/isodoc/section_spec.rb +219 -0
- data/spec/spec_helper.rb +2 -0
- metadata +65 -64
- data/lib/isodoc/iso/html/scripts.html +0 -178
- data/spec/asciidoctor-iso/base_spec.rb +0 -704
@@ -7,28 +7,32 @@ module Asciidoctor
|
|
7
7
|
class Converter < Standoc::Converter
|
8
8
|
def extract_text(node)
|
9
9
|
return "" if node.nil?
|
10
|
+
|
10
11
|
node1 = Nokogiri::XML.fragment(node.to_s)
|
11
12
|
node1.xpath("//link | //locality | //localityStack").each(&:remove)
|
12
13
|
ret = ""
|
13
14
|
node1.traverse { |x| ret += x.text if x.text? }
|
14
|
-
ret
|
15
|
+
HTMLEntities.new.decode(ret)
|
15
16
|
end
|
16
17
|
|
17
18
|
# ISO/IEC DIR 2, 12.2
|
18
19
|
def foreword_style(node)
|
19
20
|
return if @novalid
|
21
|
+
|
20
22
|
style_no_guidance(node, extract_text(node), "Foreword")
|
21
23
|
end
|
22
24
|
|
23
25
|
# ISO/IEC DIR 2, 14.2
|
24
26
|
def scope_style(node)
|
25
27
|
return if @novalid
|
28
|
+
|
26
29
|
style_no_guidance(node, extract_text(node), "Scope")
|
27
30
|
end
|
28
31
|
|
29
32
|
# ISO/IEC DIR 2, 13.2
|
30
33
|
def introduction_style(node)
|
31
34
|
return if @novalid
|
35
|
+
|
32
36
|
r = requirement_check(extract_text(node))
|
33
37
|
style_warning(node, "Introduction may contain requirement", r) if r
|
34
38
|
end
|
@@ -36,6 +40,7 @@ module Asciidoctor
|
|
36
40
|
# ISO/IEC DIR 2, 16.5.6
|
37
41
|
def definition_style(node)
|
38
42
|
return if @novalid
|
43
|
+
|
39
44
|
r = requirement_check(extract_text(node))
|
40
45
|
style_warning(node, "Definition may contain requirement", r) if r
|
41
46
|
end
|
@@ -44,6 +49,7 @@ module Asciidoctor
|
|
44
49
|
# ISO/IEC DIR 2, 25.5
|
45
50
|
def example_style(node)
|
46
51
|
return if @novalid
|
52
|
+
|
47
53
|
style_no_guidance(node, extract_text(node), "Example")
|
48
54
|
style(node, extract_text(node))
|
49
55
|
end
|
@@ -51,6 +57,7 @@ module Asciidoctor
|
|
51
57
|
# ISO/IEC DIR 2, 24.5
|
52
58
|
def note_style(node)
|
53
59
|
return if @novalid
|
60
|
+
|
54
61
|
style_no_guidance(node, extract_text(node), "Note")
|
55
62
|
style(node, extract_text(node))
|
56
63
|
end
|
@@ -58,6 +65,7 @@ module Asciidoctor
|
|
58
65
|
# ISO/IEC DIR 2, 26.5
|
59
66
|
def footnote_style(node)
|
60
67
|
return if @novalid
|
68
|
+
|
61
69
|
style_no_guidance(node, extract_text(node), "Footnote")
|
62
70
|
style(node, extract_text(node))
|
63
71
|
end
|
@@ -70,6 +78,7 @@ module Asciidoctor
|
|
70
78
|
# and a negative match on its preceding token
|
71
79
|
def style_two_regex_not_prev(n, text, re, re_prev, warning)
|
72
80
|
return if text.nil?
|
81
|
+
|
73
82
|
arr = Tokenizer::WhitespaceTokenizer.new.tokenize(text)
|
74
83
|
arr.each_index do |i|
|
75
84
|
m = re.match arr[i]
|
@@ -80,43 +89,45 @@ module Asciidoctor
|
|
80
89
|
end
|
81
90
|
end
|
82
91
|
|
83
|
-
def style(
|
92
|
+
def style(node, text)
|
84
93
|
return if @novalid
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
94
|
+
|
95
|
+
style_number(node, text)
|
96
|
+
style_percent(node, text)
|
97
|
+
style_abbrev(node, text)
|
98
|
+
style_units(node, text)
|
89
99
|
end
|
90
100
|
|
91
101
|
# ISO/IEC DIR 2, 9.1
|
92
102
|
# ISO/IEC DIR 2, Table B.1
|
93
|
-
def style_number(
|
103
|
+
def style_number(node, text)
|
94
104
|
style_two_regex_not_prev(
|
95
|
-
|
105
|
+
node, text, /^(?<num>-?[0-9]{4,}[,0-9]*)$/,
|
96
106
|
%r{\b(ISO|IEC|IEEE/|(in|January|February|March|April|May|June|August|September|October|November|December)\b)$},
|
97
|
-
"number not broken up in threes"
|
107
|
+
"number not broken up in threes"
|
108
|
+
)
|
98
109
|
style_regex(/\b(?<num>[0-9]+\.[0-9]+)/i,
|
99
|
-
"possible decimal point",
|
100
|
-
style_regex(/\b(?<num>
|
101
|
-
"ambiguous number",
|
110
|
+
"possible decimal point", node, text)
|
111
|
+
style_regex(/\b(?<num>billions?)\b/i,
|
112
|
+
"ambiguous number", node, text)
|
102
113
|
end
|
103
114
|
|
104
115
|
# ISO/IEC DIR 2, 9.2.1
|
105
|
-
def style_percent(
|
116
|
+
def style_percent(node, text)
|
106
117
|
style_regex(/\b(?<num>[0-9.,]+%)/,
|
107
|
-
"no space before percent sign",
|
118
|
+
"no space before percent sign", node, text)
|
108
119
|
style_regex(/\b(?<num>[0-9.,]+ \u00b1 [0-9,.]+ %)/,
|
109
|
-
"unbracketed tolerance before percent sign",
|
120
|
+
"unbracketed tolerance before percent sign", node, text)
|
110
121
|
end
|
111
122
|
|
112
123
|
# ISO/IEC DIR 2, 8.4
|
113
124
|
# ISO/IEC DIR 2, 9.3
|
114
|
-
def style_abbrev(
|
125
|
+
def style_abbrev(node, text)
|
115
126
|
style_regex(/(^|\s)(?!e\.g\.|i\.e\.)
|
116
127
|
(?<num>[a-z]{1,2}\.([a-z]{1,2}|\.))\b/ix,
|
117
|
-
|
128
|
+
"no dots in abbreviations", node, text)
|
118
129
|
style_regex(/\b(?<num>ppm)\b/i,
|
119
|
-
"language-specific abbreviation",
|
130
|
+
"language-specific abbreviation", node, text)
|
120
131
|
end
|
121
132
|
|
122
133
|
# leaving out as problematic: N J K C S T H h d B o E
|
@@ -125,12 +136,13 @@ module Asciidoctor
|
|
125
136
|
"bit|kB|MB|Hart|nat|Sh|var)".freeze
|
126
137
|
|
127
138
|
# ISO/IEC DIR 2, 9.3
|
128
|
-
def style_units(
|
139
|
+
def style_units(node, text)
|
129
140
|
style_regex(/\b(?<num>[0-9][0-9,]*\s+[\u00b0\u2032\u2033])/,
|
130
|
-
"space between number and degrees/minutes/seconds",
|
141
|
+
"space between number and degrees/minutes/seconds",
|
142
|
+
node, text)
|
131
143
|
style_regex(/\b(?<num>[0-9][0-9,]*#{SI_UNIT})\b/,
|
132
|
-
"no space between number and SI unit",
|
133
|
-
style_non_std_units(
|
144
|
+
"no space between number and SI unit", node, text)
|
145
|
+
style_non_std_units(node, text)
|
134
146
|
end
|
135
147
|
|
136
148
|
NONSTD_UNITS = {
|
@@ -139,10 +151,10 @@ module Asciidoctor
|
|
139
151
|
}.freeze
|
140
152
|
|
141
153
|
# ISO/IEC DIR 2, 9.3
|
142
|
-
def style_non_std_units(
|
154
|
+
def style_non_std_units(node, text)
|
143
155
|
NONSTD_UNITS.each do |k, v|
|
144
156
|
style_regex(/\b(?<num>[0-9][0-9,]*\s+#{k})\b/,
|
145
|
-
"non-standard unit (should be #{v})",
|
157
|
+
"non-standard unit (should be #{v})", node, text)
|
146
158
|
end
|
147
159
|
end
|
148
160
|
end
|
@@ -3,9 +3,13 @@ require "metanorma-standoc"
|
|
3
3
|
module Asciidoctor
|
4
4
|
module ISO
|
5
5
|
class Converter < Standoc::Converter
|
6
|
+
def title_lang_part(doc, part, lang)
|
7
|
+
doc.at("//bibdata/title[@type='title-#{part}' and @language='#{lang}']")
|
8
|
+
end
|
9
|
+
|
6
10
|
def title_intro_validate(root)
|
7
|
-
title_intro_en = root
|
8
|
-
title_intro_fr = root
|
11
|
+
title_intro_en = title_lang_part(root, "intro", "en")
|
12
|
+
title_intro_fr = title_lang_part(root, "intro", "fr")
|
9
13
|
if title_intro_en.nil? && !title_intro_fr.nil?
|
10
14
|
@log.add("Style", title_intro_fr, "No English Title Intro!")
|
11
15
|
end
|
@@ -15,8 +19,8 @@ module Asciidoctor
|
|
15
19
|
end
|
16
20
|
|
17
21
|
def title_main_validate(root)
|
18
|
-
title_main_en = root
|
19
|
-
title_main_fr = root
|
22
|
+
title_main_en = title_lang_part(root, "main", "en")
|
23
|
+
title_main_fr = title_lang_part(root, "main", "fr")
|
20
24
|
if title_main_en.nil? && !title_main_fr.nil?
|
21
25
|
@log.add("Style", title_main_fr, "No English Title!")
|
22
26
|
end
|
@@ -26,8 +30,8 @@ module Asciidoctor
|
|
26
30
|
end
|
27
31
|
|
28
32
|
def title_part_validate(root)
|
29
|
-
title_part_en = root
|
30
|
-
title_part_fr = root
|
33
|
+
title_part_en = title_lang_part(root, "part", "en")
|
34
|
+
title_part_fr = title_lang_part(root, "part", "fr")
|
31
35
|
(title_part_en.nil? && !title_part_fr.nil?) &&
|
32
36
|
@log.add("Style", title_part_fr, "No English Title Part!")
|
33
37
|
(!title_part_en.nil? && title_part_fr.nil?) &&
|
@@ -41,21 +45,21 @@ module Asciidoctor
|
|
41
45
|
iec = root.at("//bibdata/contributor[role/@type = 'publisher']/"\
|
42
46
|
"organization[abbreviation = 'IEC' or "\
|
43
47
|
"name = 'International Electrotechnical Commission']")
|
44
|
-
|
48
|
+
subpart && !iec and
|
49
|
+
@log.add("Style", docid, "Subpart defined on non-IEC document!")
|
45
50
|
end
|
46
51
|
|
47
52
|
# ISO/IEC DIR 2, 11.5.2
|
48
53
|
def title_names_type_validate(root)
|
49
54
|
doctypes = /International\sStandard | Technical\sSpecification |
|
50
55
|
Publicly\sAvailable\sSpecification | Technical\sReport | Guide /xi
|
51
|
-
title_main_en = root
|
52
|
-
|
56
|
+
title_main_en = title_lang_part(root, "main", "en")
|
57
|
+
!title_main_en.nil? && doctypes.match(title_main_en.text) and
|
53
58
|
@log.add("Style", title_main_en, "Main Title may name document type")
|
54
|
-
|
55
|
-
title_intro_en
|
56
|
-
|
57
|
-
|
58
|
-
end
|
59
|
+
title_intro_en = title_lang_part(root, "intro", "en")
|
60
|
+
!title_intro_en.nil? && doctypes.match(title_intro_en.text) and
|
61
|
+
@log.add("Style", title_intro_en,
|
62
|
+
"Title Intro may name document type")
|
59
63
|
end
|
60
64
|
|
61
65
|
# ISO/IEC DIR 2, 22.2
|
@@ -64,8 +68,9 @@ module Asciidoctor
|
|
64
68
|
title = s&.at("./title")&.text || s.name
|
65
69
|
s.xpath("./clause | ./terms | ./references").each do |ss|
|
66
70
|
subtitle = ss.at("./title")
|
67
|
-
!subtitle.nil? && !subtitle&.text&.empty?
|
68
|
-
@log.add("Style", ss,
|
71
|
+
!subtitle.nil? && !subtitle&.text&.empty? or
|
72
|
+
@log.add("Style", ss,
|
73
|
+
"#{title}: each first-level subclause must have a title")
|
69
74
|
end
|
70
75
|
end
|
71
76
|
end
|
@@ -82,7 +87,8 @@ module Asciidoctor
|
|
82
87
|
withtitle = withtitle || (subtitle && !subtitle.text.empty?)
|
83
88
|
end
|
84
89
|
notitle && withtitle &&
|
85
|
-
@log.add("Style", nil,
|
90
|
+
@log.add("Style", nil,
|
91
|
+
"#{label}: all subclauses must have a title, or none")
|
86
92
|
end
|
87
93
|
|
88
94
|
def title_validate(root)
|
@@ -15,6 +15,7 @@ module IsoDoc
|
|
15
15
|
|
16
16
|
def implicit_reference(b)
|
17
17
|
return true if b&.at(ns("./docidentifier"))&.text == "IEV"
|
18
|
+
|
18
19
|
super
|
19
20
|
end
|
20
21
|
|
@@ -27,8 +28,9 @@ module IsoDoc
|
|
27
28
|
end
|
28
29
|
end
|
29
30
|
|
30
|
-
def example_span_label(
|
31
|
+
def example_span_label(_node, div, name)
|
31
32
|
return if name.nil?
|
33
|
+
|
32
34
|
div.span **{ class: "example_label" } do |p|
|
33
35
|
name.children.each { |n| parse(n, div) }
|
34
36
|
end
|
@@ -56,6 +58,7 @@ module IsoDoc
|
|
56
58
|
node.elements.each do |e|
|
57
59
|
next if e.name == "name"
|
58
60
|
return true if e.name == "p"
|
61
|
+
|
59
62
|
return false
|
60
63
|
end
|
61
64
|
false
|
@@ -74,6 +77,7 @@ module IsoDoc
|
|
74
77
|
def insertall_after_here(node, insert, name)
|
75
78
|
node.children.each do |n|
|
76
79
|
next unless n.name == name
|
80
|
+
|
77
81
|
insert.next = n.remove
|
78
82
|
insert = n
|
79
83
|
end
|
@@ -83,6 +87,7 @@ module IsoDoc
|
|
83
87
|
def termexamples_before_termnotes(node)
|
84
88
|
return unless node.at(ns("./termnote")) && node.at(ns("./termexample"))
|
85
89
|
return unless insert = node.at(ns("./definition"))
|
90
|
+
|
86
91
|
insert = insertall_after_here(node, insert, "termexample")
|
87
92
|
insert = insertall_after_here(node, insert, "termnote")
|
88
93
|
end
|
@@ -110,6 +115,7 @@ module IsoDoc
|
|
110
115
|
return super unless (dl&.xpath(ns("./dt"))&.size == 1 &&
|
111
116
|
dl&.at(ns("./dd"))&.elements&.size == 1 &&
|
112
117
|
dl&.at(ns("./dd/p")))
|
118
|
+
|
113
119
|
out.span **{ class: "zzMoveToFollowing" } do |s|
|
114
120
|
s << "#{@i18n.where} "
|
115
121
|
dl.at(ns("./dt")).children.each { |n| parse(n, s) }
|
@@ -149,7 +155,18 @@ module IsoDoc
|
|
149
155
|
|
150
156
|
def figure_name_parse(node, div, name)
|
151
157
|
div.p **{ class: "FigureTitle", style: "text-align:center;" } do |p|
|
152
|
-
name
|
158
|
+
name&.children&.each { |n| parse(n, div) }
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def middle(isoxml, out)
|
163
|
+
super
|
164
|
+
indexsect isoxml, out
|
165
|
+
end
|
166
|
+
|
167
|
+
def indexsect(isoxml, out)
|
168
|
+
isoxml.xpath(ns("//indexsect")).each do |i|
|
169
|
+
clause_parse(i, out)
|
153
170
|
end
|
154
171
|
end
|
155
172
|
end
|
@@ -115,6 +115,13 @@ a.FootnoteRef + a.FootnoteRef:before {
|
|
115
115
|
content: ", ";
|
116
116
|
vertical-align: super; }
|
117
117
|
|
118
|
+
.addition {
|
119
|
+
color: blue; }
|
120
|
+
|
121
|
+
.deletion {
|
122
|
+
color: red;
|
123
|
+
text-decoration: line-through; }
|
124
|
+
|
118
125
|
#standard-band {
|
119
126
|
background-color: #0AC442; }
|
120
127
|
|
@@ -115,6 +115,13 @@ a.FootnoteRef + a.FootnoteRef:before {
|
|
115
115
|
content: ", ";
|
116
116
|
vertical-align: super; }
|
117
117
|
|
118
|
+
.addition {
|
119
|
+
color: blue; }
|
120
|
+
|
121
|
+
.deletion {
|
122
|
+
color: red;
|
123
|
+
text-decoration: line-through; }
|
124
|
+
|
118
125
|
#standard-band {
|
119
126
|
background-color: #0AC442; }
|
120
127
|
|
data/lib/isodoc/iso/i18n-en.yaml
CHANGED
data/lib/isodoc/iso/i18n-fr.yaml
CHANGED
@@ -0,0 +1,140 @@
|
|
1
|
+
module IsoDoc
|
2
|
+
module Iso
|
3
|
+
class PresentationXMLConvert < IsoDoc::PresentationXMLConvert
|
4
|
+
def add_id
|
5
|
+
%(id="_#{UUIDTools::UUID.random_create}")
|
6
|
+
end
|
7
|
+
|
8
|
+
def index(docxml)
|
9
|
+
unless docxml.at(ns("//index"))
|
10
|
+
docxml.xpath(ns("//indexsect")).each { |i| i.remove }
|
11
|
+
return
|
12
|
+
end
|
13
|
+
i = docxml.at(ns("//indexsect")) ||
|
14
|
+
docxml.root.add_child("<indexsect #{add_id}><title>#{@i18n.index}</title></indexsect>").first
|
15
|
+
index = sort_indexterms(docxml.xpath(ns("//index")), docxml.xpath(ns("//index-xref[@also = 'false']")),
|
16
|
+
docxml.xpath(ns("//index-xref[@also = 'true']")))
|
17
|
+
index1(docxml, i, index)
|
18
|
+
end
|
19
|
+
|
20
|
+
def index1(docxml, i, index)
|
21
|
+
c = i.add_child("<ul></ul>").first
|
22
|
+
index.keys.sort.each do |k|
|
23
|
+
#c = i.add_child "<clause #{add_id}><title>#{k}</title><ul></ul></clause>"
|
24
|
+
words = index[k].keys.each_with_object({}) { |w, v| v[sortable(w).downcase] = w }
|
25
|
+
words.keys.localize(@lang.to_sym).sort.to_a.each do |w|
|
26
|
+
#c.first.at(ns("./ul")).add_child index_entries(words, index[k], w)
|
27
|
+
c.add_child index_entries(words, index[k], w)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
docxml.xpath(ns("//indexsect//xref")).each { |x| x.children.remove }
|
31
|
+
@xrefs.bookmark_anchor_names(docxml)
|
32
|
+
end
|
33
|
+
|
34
|
+
def sortable(s)
|
35
|
+
HTMLEntities.new.decode(Nokogiri::XML.fragment(s).text)
|
36
|
+
end
|
37
|
+
|
38
|
+
def index_entries_opt
|
39
|
+
{ xref_lbl: ", ", see_lbl: ", #{see_lbl}", also_lbl: ", #{also_lbl}" }
|
40
|
+
end
|
41
|
+
|
42
|
+
def index_entries(words, index, primary)
|
43
|
+
ret = index_entries_head(words[primary], index.dig(words[primary], nil, nil), index_entries_opt)
|
44
|
+
words2 = index[words[primary]]&.keys&.reject { |k| k.nil?}&.each_with_object({}) { |w, v| v[w.downcase] = w }
|
45
|
+
unless words2.empty?
|
46
|
+
ret += "<ul>"
|
47
|
+
words2.keys.localize(@lang.to_sym).sort.to_a.each do |w|
|
48
|
+
ret += index_entries2(words2, index[words[primary]], w)
|
49
|
+
end
|
50
|
+
ret += "</ul>"
|
51
|
+
end
|
52
|
+
ret + "</li>"
|
53
|
+
end
|
54
|
+
|
55
|
+
def index_entries2(words, index, secondary)
|
56
|
+
ret = index_entries_head(words[secondary], index.dig(words[secondary], nil), index_entries_opt)
|
57
|
+
words3 = index[words[secondary]]&.keys&.reject { |k| k.nil?}&.each_with_object({}) { |w, v| v[w.downcase] = w }
|
58
|
+
unless words3.empty?
|
59
|
+
ret += "<ul>"
|
60
|
+
words3.keys.localize(@lang.to_sym).sort.to_a.each do |w|
|
61
|
+
ret += (index_entries_head(words3[w], index[words[secondary]][words3[w]], index_entries_opt) + "</li>")
|
62
|
+
end
|
63
|
+
ret += "</ul>"
|
64
|
+
end
|
65
|
+
ret + "</li>"
|
66
|
+
end
|
67
|
+
|
68
|
+
def index_entries_head(head, entries, opt)
|
69
|
+
ret = "<li>#{head}"
|
70
|
+
xref = entries&.dig(:xref)&.join(", ")
|
71
|
+
see_sort = entries&.dig(:see)&.each_with_object({}) { |w, v| v[sortable(w).downcase] = w }
|
72
|
+
see = see_sort&.keys&.localize(@lang.to_sym)&.sort&.to_a&.map { |k| see_sort[k] }&.join(", ")
|
73
|
+
also_sort = entries&.dig(:also)&.each_with_object({}) { |w, v| v[sortable(w).downcase] = w }
|
74
|
+
also = also_sort&.keys&.localize(@lang.to_sym)&.sort&.to_a&.map { |k| also_sort[k] }&.join(", ")
|
75
|
+
ret += "#{opt[:xref_lbl]} #{xref}" if xref
|
76
|
+
ret += "#{opt[:see_lbl]} #{see}" if see
|
77
|
+
ret += "#{opt[:also_lbl]} #{also}" if also
|
78
|
+
ret
|
79
|
+
end
|
80
|
+
|
81
|
+
def see_lbl
|
82
|
+
@lang == "en" ? @i18n.see : "<em>#{@i18n.see}</em>"
|
83
|
+
end
|
84
|
+
|
85
|
+
def also_lbl
|
86
|
+
@lang == "en" ? @i18n.see_also : "<em>#{@i18n.see_also}</em>"
|
87
|
+
end
|
88
|
+
|
89
|
+
def sort_indexterms(terms, see, also)
|
90
|
+
index = extract_indexterms(terms)
|
91
|
+
index = extract_indexsee(index, see, :see)
|
92
|
+
index = extract_indexsee(index, also, :also)
|
93
|
+
index.keys.sort.each_with_object({}) do |k, v|
|
94
|
+
v[sortable(k)[0].upcase.transliterate] ||= {}
|
95
|
+
v[sortable(k)[0].upcase.transliterate][k] = index[k]
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def extract_indexsee(v, terms, label)
|
100
|
+
terms.each_with_object(v) do |t, v|
|
101
|
+
term = t&.at(ns("./primary"))&.children&.to_xml
|
102
|
+
term2 = t&.at(ns("./secondary"))&.children&.to_xml
|
103
|
+
term3 = t&.at(ns("./tertiary"))&.children&.to_xml
|
104
|
+
v[term] ||= {}
|
105
|
+
v[term][term2] ||= {}
|
106
|
+
v[term][term2][term3] ||= {}
|
107
|
+
v[term][term2][term3][label] ||= []
|
108
|
+
v[term][term2][term3][label] << t&.at(ns("./target"))&.children&.to_xml
|
109
|
+
t.remove
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def xml_encode_attr(s)
|
114
|
+
HTMLEntities.new.encode(s, :basic, :hexadecimal).gsub(/\&#x([^;]+);/) { |x| "&#x#{$1.upcase};" }
|
115
|
+
end
|
116
|
+
|
117
|
+
# attributes are decoded into UTF-8, elements in extract_indexsee are still in entities
|
118
|
+
def extract_indexterms(terms)
|
119
|
+
terms.each_with_object({}) do |t, v|
|
120
|
+
term = t&.at(ns("./primary"))&.children&.to_xml
|
121
|
+
term2 = t&.at(ns("./secondary"))&.children&.to_xml
|
122
|
+
term3 = t&.at(ns("./tertiary"))&.children&.to_xml
|
123
|
+
index2bookmark(t)
|
124
|
+
v[term] ||= {}
|
125
|
+
v[term][term2] ||= {}
|
126
|
+
v[term][term2][term3] ||= {}
|
127
|
+
v[term][term2][term3][:xref] ||= []
|
128
|
+
to = t["to"] ? "to='#{t['to']}' " : ""
|
129
|
+
v[term][term2][term3][:xref] << "<xref target='#{t['id']}' #{to}pagenumber='true'/>"
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def index2bookmark(t)
|
134
|
+
t.name = "bookmark"
|
135
|
+
t.children.each { |x| x.remove }
|
136
|
+
t["id"] = "_#{UUIDTools::UUID.random_create}"
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|