isodoc 1.7.4 → 1.7.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,16 +1,22 @@
1
+ require "metanorma-utils"
2
+ require_relative "./concept"
3
+
1
4
  module IsoDoc
2
5
  class PresentationXMLConvert < ::IsoDoc::Convert
3
6
  def prefix_container(container, linkend, _target)
4
7
  l10n("#{@xrefs.anchor(container, :xref)}, #{linkend}")
5
8
  end
6
9
 
10
+ def anchor_value(id)
11
+ @xrefs.anchor(id, :value) || @xrefs.anchor(id, :label) ||
12
+ @xrefs.anchor(id, :xref)
13
+ end
14
+
7
15
  def anchor_linkend(node, linkend)
8
16
  if node["citeas"].nil? && node["bibitemid"]
9
17
  return @xrefs.anchor(node["bibitemid"], :xref) || "???"
10
18
  elsif node["target"] && node["droploc"]
11
- return @xrefs.anchor(node["target"], :value) ||
12
- @xrefs.anchor(node["target"], :label) ||
13
- @xrefs.anchor(node["target"], :xref) || "???"
19
+ return anchor_value(node["target"]) || "???"
14
20
  elsif node["target"] && !/.#./.match(node["target"])
15
21
  linkend = anchor_linkend1(node)
16
22
  end
@@ -24,14 +30,15 @@ module IsoDoc
24
30
  (container && get_note_container_id(node) != container &&
25
31
  @xrefs.get[node["target"]]) and
26
32
  linkend = prefix_container(container, linkend, node["target"])
27
- capitalise_xref(node, linkend)
33
+ capitalise_xref(node, linkend, anchor_value(node["target"]))
28
34
  end
29
35
 
30
- def capitalise_xref(node, linkend)
31
- return linkend unless %w(Latn Cyrl Grek).include? @script
32
- return linkend&.capitalize if node["case"] == "capital"
33
- return linkend&.downcase if node["case"] == "lowercase"
34
- return linkend if linkend[0, 1].match?(/\p{Upper}/)
36
+ def capitalise_xref(node, linkend, label)
37
+ linktext = linkend.gsub(/<[^>]+>/, "")
38
+ (label && !label.empty? && /^#{Regexp.escape(label)}/.match?(linktext) ||
39
+ linktext[0, 1].match?(/\p{Upper}/)) and return linkend
40
+ node["case"] and
41
+ return Common::case_with_markup(linkend, node["case"], @script)
35
42
 
36
43
  capitalise_xref1(node, linkend)
37
44
  end
@@ -40,7 +47,7 @@ module IsoDoc
40
47
  prec = nearest_block_parent(node).xpath("./descendant-or-self::text()") &
41
48
  node.xpath("./preceding::text()")
42
49
  if prec.empty? || /(?!<[^.].)\.\s+$/.match(prec.map(&:text).join)
43
- linkend&.capitalize
50
+ Common::case_with_markup(linkend, "capital", @script)
44
51
  else linkend
45
52
  end
46
53
  end
@@ -67,7 +74,7 @@ module IsoDoc
67
74
  link += eref_localities(node.xpath(ns("./locality | ./localityStack")),
68
75
  link, node)
69
76
  non_locality_elems(node).each(&:remove)
70
- node.add_child(link)
77
+ node.add_child(cleanup_entities(link))
71
78
  end
72
79
  # so not <origin bibitemid="ISO7301" citeas="ISO 7301">
73
80
  # <locality type="section"><reference>3.1</reference></locality></origin>
@@ -88,8 +95,7 @@ module IsoDoc
88
95
  ret += eref_localities0(rr, j, target, delim, node)
89
96
  delim = ","
90
97
  end
91
- else
92
- ret += eref_localities0(ref, idx, target, delim, node)
98
+ else ret += eref_localities0(ref, idx, target, delim, node)
93
99
  end
94
100
  ret
95
101
  end
@@ -130,7 +136,7 @@ module IsoDoc
130
136
  loc = @i18n.locality[type] || type.sub(/^locality:/, "")
131
137
  loc = case node["case"]
132
138
  when "lowercase" then loc.downcase
133
- else loc.capitalize
139
+ else Metanorma::Utils.strict_capitalize_first(loc)
134
140
  end
135
141
  " #{loc}"
136
142
  end
@@ -155,41 +161,6 @@ module IsoDoc
155
161
  get_linkend(node)
156
162
  end
157
163
 
158
- def concept(docxml)
159
- docxml.xpath(ns("//concept")).each { |f| concept1(f) }
160
- end
161
-
162
- def concept1(node)
163
- xref = node&.at(ns("./xref/@target"))&.text or
164
- return concept_render(node, node["ital"] || "true",
165
- node["ref"] || "true")
166
- if node.at(ns("//definitions//dt[@id = '#{xref}']"))
167
- concept_render(node, node["ital"] || "false", node["ref"] || "false")
168
- else concept_render(node, node["ital"] || "true", node["ref"] || "true")
169
- end
170
- end
171
-
172
- def concept_render(node, ital, ref)
173
- node&.at(ns("./refterm"))&.remove
174
- r = node.at(ns("./renderterm"))
175
- r&.next = " " if node.at(ns("./xref | ./eref | ./termref")) && ref != "false"
176
- if ital == "true" then r&.name = "em"
177
- else r&.replace(r&.children)
178
- end
179
- concept1_ref(node, ref)
180
- node.replace(node.children)
181
- end
182
-
183
- def concept1_ref(node, ref)
184
- r = node.at(ns("./xref | ./eref | ./termref")) or return
185
- return r.remove if ref == "false"
186
-
187
- if non_locality_elems(r).select { |c| !c.text? || /\S/.match(c) }.empty?
188
- r.replace(@i18n.term_defined_in.sub(/%/, r.to_xml))
189
- else r.replace("[#{r.to_xml}]")
190
- end
191
- end
192
-
193
164
  def variant(docxml)
194
165
  docxml.xpath(ns("//variant")).each { |f| variant1(f) }
195
166
  docxml.xpath(ns("//variant[@remove = 'true']")).each(&:remove)
@@ -49,6 +49,7 @@ module IsoDoc
49
49
  termexample docxml
50
50
  note docxml
51
51
  termnote docxml
52
+ termdefinition docxml
52
53
  permission docxml
53
54
  requirement docxml
54
55
  recommendation docxml
@@ -1,3 +1,3 @@
1
1
  module IsoDoc
2
- VERSION = "1.7.4".freeze
2
+ VERSION = "1.7.7".freeze
3
3
  end
@@ -1,231 +1,233 @@
1
1
  require_relative "./table"
2
2
  require_relative "./inline"
3
3
 
4
- module IsoDoc::WordFunction
5
- module Body
6
- def define_head(head, filename, _dir)
7
- head.style do |style|
8
- loc = File.join(File.dirname(__FILE__), "..", "base_style",
9
- "metanorma_word.scss")
10
- stylesheet = File.read(loc, encoding: "utf-8")
11
- style.comment "\n#{stylesheet}\n"
12
- end
13
- super
14
- end
15
-
16
- def body_attr
17
- { lang: "EN-US", link: "blue", vlink: "#954F72" }
18
- end
4
+ module IsoDoc
5
+ module WordFunction
6
+ module Body
7
+ def define_head(head, filename, _dir)
8
+ head.style do |style|
9
+ loc = File.join(File.dirname(__FILE__), "..", "base_style",
10
+ "metanorma_word.scss")
11
+ stylesheet = File.read(loc, encoding: "utf-8")
12
+ style.comment "\n#{stylesheet}\n"
13
+ end
14
+ super
15
+ end
19
16
 
20
- def make_body1(body, _docxml)
21
- body.div **{ class: "WordSection1" } do |div1|
22
- div1.p { |p| p << "&nbsp;" } # placeholder
17
+ def body_attr
18
+ { lang: "EN-US", link: "blue", vlink: "#954F72" }
23
19
  end
24
- section_break(body)
25
- end
26
20
 
27
- def make_body2(body, docxml)
28
- body.div **{ class: "WordSection2" } do |div2|
29
- boilerplate docxml, div2
30
- preface_block docxml, div2
31
- abstract docxml, div2
32
- foreword docxml, div2
33
- introduction docxml, div2
34
- preface docxml, div2
35
- acknowledgements docxml, div2
36
- div2.p { |p| p << "&nbsp;" } # placeholder
37
- end
38
- section_break(body)
39
- end
21
+ def make_body1(body, _docxml)
22
+ body.div **{ class: "WordSection1" } do |div1|
23
+ div1.p { |p| p << "&nbsp;" } # placeholder
24
+ end
25
+ section_break(body)
26
+ end
27
+
28
+ def make_body2(body, docxml)
29
+ body.div **{ class: "WordSection2" } do |div2|
30
+ boilerplate docxml, div2
31
+ preface_block docxml, div2
32
+ abstract docxml, div2
33
+ foreword docxml, div2
34
+ introduction docxml, div2
35
+ preface docxml, div2
36
+ acknowledgements docxml, div2
37
+ div2.p { |p| p << "&nbsp;" } # placeholder
38
+ end
39
+ section_break(body)
40
+ end
40
41
 
41
- def make_body3(body, docxml)
42
- body.div **{ class: "WordSection3" } do |div3|
43
- middle docxml, div3
44
- footnotes div3
45
- comments div3
42
+ def make_body3(body, docxml)
43
+ body.div **{ class: "WordSection3" } do |div3|
44
+ middle docxml, div3
45
+ footnotes div3
46
+ comments div3
47
+ end
46
48
  end
47
- end
48
49
 
49
- def insert_tab(out, count)
50
- out.span **attr_code(style: "mso-tab-count:#{count}") do |span|
51
- [1..count].each { span << "&#xA0; " }
50
+ def insert_tab(out, count)
51
+ out.span **attr_code(style: "mso-tab-count:#{count}") do |span|
52
+ [1..count].each { span << "&#xA0; " }
53
+ end
52
54
  end
53
- end
54
55
 
55
- def para_class(_node)
56
- classtype = nil
57
- classtype = "Note" if @note
58
- classtype = "MsoCommentText" if in_comment
59
- classtype = "Sourcecode" if @annotation
60
- classtype
61
- end
56
+ def para_class(_node)
57
+ classtype = nil
58
+ classtype = "Note" if @note
59
+ classtype = "MsoCommentText" if in_comment
60
+ classtype = "Sourcecode" if @annotation
61
+ classtype
62
+ end
62
63
 
63
- def para_parse(node, out)
64
- out.p **attr_code(para_attrs(node)) do |p|
65
- unless @termdomain.empty?
66
- p << "&lt;#{@termdomain}&gt; "
67
- @termdomain = ""
64
+ def para_parse(node, out)
65
+ out.p **attr_code(para_attrs(node)) do |p|
66
+ unless @termdomain.empty?
67
+ p << "&lt;#{@termdomain}&gt; "
68
+ @termdomain = ""
69
+ end
70
+ node.children.each { |n| parse(n, p) unless n.name == "note" }
68
71
  end
69
- node.children.each { |n| parse(n, p) unless n.name == "note" }
72
+ node.xpath(ns("./note")).each { |n| parse(n, out) }
70
73
  end
71
- node.xpath(ns("./note")).each { |n| parse(n, out) }
72
- end
73
74
 
74
- WORD_DT_ATTRS = { class: @note ? "Note" : nil, align: "left",
75
- style: "margin-left:0pt;text-align:left;" }.freeze
75
+ WORD_DT_ATTRS = { class: @note ? "Note" : nil, align: "left",
76
+ style: "margin-left:0pt;text-align:left;" }.freeze
76
77
 
77
- def dt_parse(dt, term)
78
- term.p **attr_code(WORD_DT_ATTRS) do |p|
79
- if dt.elements.empty?
80
- p << dt.text
81
- else
82
- dt.children.each { |n| parse(n, p) }
78
+ def dt_parse(dterm, term)
79
+ term.p **attr_code(WORD_DT_ATTRS) do |p|
80
+ if dterm.elements.empty?
81
+ p << dterm.text
82
+ else
83
+ dterm.children.each { |n| parse(n, p) }
84
+ end
83
85
  end
84
86
  end
85
- end
86
87
 
87
- def dl_parse(node, out)
88
- out.table **{ class: "dl" } do |v|
89
- node.elements.select { |n| dt_dd? n }.each_slice(2) do |dt, dd|
90
- v.tr do |tr|
91
- tr.td **{ valign: "top", align: "left" } do |term|
92
- dt_parse(dt, term)
93
- end
94
- tr.td **{ valign: "top" } do |listitem|
95
- dd.children.each { |n| parse(n, listitem) }
88
+ def dl_parse(node, out)
89
+ out.table **{ class: "dl" } do |v|
90
+ node.elements.select { |n| dt_dd? n }.each_slice(2) do |dt, dd|
91
+ v.tr do |tr|
92
+ tr.td **{ valign: "top", align: "left" } do |term|
93
+ dt_parse(dt, term)
94
+ end
95
+ tr.td **{ valign: "top" } do |listitem|
96
+ dd.children.each { |n| parse(n, listitem) }
97
+ end
96
98
  end
97
99
  end
100
+ dl_parse_notes(node, v)
98
101
  end
99
- dl_parse_notes(node, v)
100
102
  end
101
- end
102
103
 
103
- def dl_parse_notes(node, v)
104
- return if node.elements.reject { |n| dt_dd? n }.empty?
104
+ def dl_parse_notes(node, out)
105
+ return if node.elements.reject { |n| dt_dd? n }.empty?
105
106
 
106
- v.tr do |tr|
107
- tr.td **{ colspan: 2 } do |td|
108
- node.elements.reject { |n| dt_dd? n }.each { |n| parse(n, td) }
107
+ out.tr do |tr|
108
+ tr.td **{ colspan: 2 } do |td|
109
+ node.elements.reject { |n| dt_dd? n }.each { |n| parse(n, td) }
110
+ end
109
111
  end
110
112
  end
111
- end
112
113
 
113
- def figure_get_or_make_dl(node)
114
- dl = node.at(".//table[@class = 'dl']")
115
- if dl.nil?
116
- node.add_child("<p><b>#{@i18n.key}</b></p><table class='dl'></table>")
114
+ def figure_get_or_make_dl(node)
117
115
  dl = node.at(".//table[@class = 'dl']")
116
+ if dl.nil?
117
+ node.add_child("<p><b>#{@i18n.key}</b></p><table class='dl'></table>")
118
+ dl = node.at(".//table[@class = 'dl']")
119
+ end
120
+ dl
121
+ end
122
+
123
+ def figure_aside_process(fig, aside, key)
124
+ # get rid of footnote link, it is in diagram
125
+ fig&.at("./a[@class='TableFootnoteRef']")&.remove
126
+ fnref = fig.at(".//span[@class='TableFootnoteRef']/..")
127
+ tr = key.add_child("<tr></tr>").first
128
+ dt = tr.add_child("<td valign='top' align='left'></td>").first
129
+ dd = tr.add_child("<td valign='top'></td>").first
130
+ fnref.parent = dt
131
+ aside.xpath(".//p").each do |a|
132
+ a.delete("class")
133
+ a.parent = dd
134
+ end
118
135
  end
119
- dl
120
- end
121
-
122
- def figure_aside_process(fig, aside, key)
123
- # get rid of footnote link, it is in diagram
124
- fig&.at("./a[@class='TableFootnoteRef']")&.remove
125
- fnref = fig.at(".//span[@class='TableFootnoteRef']/..")
126
- tr = key.add_child("<tr></tr>").first
127
- dt = tr.add_child("<td valign='top' align='left'></td>").first
128
- dd = tr.add_child("<td valign='top'></td>").first
129
- fnref.parent = dt
130
- aside.xpath(".//p").each do |a|
131
- a.delete("class")
132
- a.parent = dd
133
- end
134
- end
135
136
 
136
- def note_p_parse(node, div)
137
- name = node&.at(ns("./name"))&.remove
138
- div.p **{ class: "Note" } do |p|
139
- p.span **{ class: "note_label" } do |s|
140
- name&.children&.each { |n| parse(n, s) }
137
+ def note_p_parse(node, div)
138
+ name = node&.at(ns("./name"))&.remove
139
+ div.p **{ class: "Note" } do |p|
140
+ p.span **{ class: "note_label" } do |s|
141
+ name&.children&.each { |n| parse(n, s) }
142
+ end
143
+ insert_tab(p, 1)
144
+ node.first_element_child.children.each { |n| parse(n, p) }
141
145
  end
142
- insert_tab(p, 1)
143
- node.first_element_child.children.each { |n| parse(n, p) }
146
+ node.element_children[1..-1].each { |n| parse(n, div) }
144
147
  end
145
- node.element_children[1..-1].each { |n| parse(n, div) }
146
- end
147
148
 
148
- def note_parse1(node, div)
149
- name = node&.at(ns("./name"))&.remove
150
- div.p **{ class: "Note" } do |p|
151
- p.span **{ class: "note_label" } do |s|
152
- name&.children&.each { |n| parse(n, s) }
149
+ def note_parse1(node, div)
150
+ name = node&.at(ns("./name"))&.remove
151
+ div.p **{ class: "Note" } do |p|
152
+ p.span **{ class: "note_label" } do |s|
153
+ name&.children&.each { |n| parse(n, s) }
154
+ end
155
+ insert_tab(p, 1)
153
156
  end
154
- insert_tab(p, 1)
157
+ node.children.each { |n| parse(n, div) }
155
158
  end
156
- node.children.each { |n| parse(n, div) }
157
- end
158
159
 
159
- def termnote_parse(node, out)
160
- name = node&.at(ns("./name"))&.remove
161
- out.div **note_attrs(node) do |div|
162
- div.p **{ class: "Note" } do |p|
163
- if name
164
- name.children.each { |n| parse(n, p) }
165
- p << l10n(": ")
160
+ def termnote_parse(node, out)
161
+ name = node&.at(ns("./name"))&.remove
162
+ out.div **note_attrs(node) do |div|
163
+ div.p **{ class: "Note" } do |p|
164
+ if name
165
+ name.children.each { |n| parse(n, p) }
166
+ p << l10n(": ")
167
+ end
168
+ para_then_remainder(node.first_element_child, node, p, div)
166
169
  end
167
- para_then_remainder(node.first_element_child, node, p, div)
168
170
  end
169
171
  end
170
- end
171
172
 
172
- def para_attrs(node)
173
- attrs = { class: para_class(node), id: node["id"], style: "" }
174
- unless node["align"].nil?
175
- attrs[:align] = node["align"] unless node["align"] == "justify"
176
- attrs[:style] += "text-align:#{node['align']};"
173
+ def para_attrs(node)
174
+ attrs = { class: para_class(node), id: node["id"], style: "" }
175
+ unless node["align"].nil?
176
+ attrs[:align] = node["align"] unless node["align"] == "justify"
177
+ attrs[:style] += "text-align:#{node['align']};"
178
+ end
179
+ attrs[:style] += keep_style(node).to_s
180
+ attrs[:style] = nil if attrs[:style].empty?
181
+ attrs
177
182
  end
178
- attrs[:style] += keep_style(node).to_s
179
- attrs[:style] = nil if attrs[:style].empty?
180
- attrs
181
- end
182
183
 
183
- def example_table_attr(node)
184
- super.merge({
185
- style: "mso-table-lspace:15.0cm;margin-left:423.0pt;"\
186
- "mso-table-rspace:15.0cm;margin-right:423.0pt;"\
187
- "mso-table-anchor-horizontal:column;"\
188
- "mso-table-overlap:never;border-collapse:collapse;"\
189
- "#{keep_style(node)}",
190
- })
191
- end
184
+ def example_table_attr(node)
185
+ super.merge(
186
+ style: "mso-table-lspace:15.0cm;margin-left:423.0pt;"\
187
+ "mso-table-rspace:15.0cm;margin-right:423.0pt;"\
188
+ "mso-table-anchor-horizontal:column;"\
189
+ "mso-table-overlap:never;border-collapse:collapse;"\
190
+ "#{keep_style(node)}",
191
+ )
192
+ end
192
193
 
193
- def formula_where(deflist, out)
194
- return unless deflist
194
+ def formula_where(deflist, out)
195
+ return unless deflist
195
196
 
196
- out.p { |p| p << @i18n.where }
197
- parse(deflist, out)
198
- out.parent.at("./table")["class"] = "formula_dl"
199
- end
197
+ out.p { |p| p << @i18n.where }
198
+ parse(deflist, out)
199
+ out.parent.at("./table")["class"] = "formula_dl"
200
+ end
200
201
 
201
- def formula_parse1(node, out)
202
- out.div **attr_code(class: "formula") do |div|
203
- div.p do |_p|
204
- parse(node.at(ns("./stem")), div)
205
- insert_tab(div, 1)
206
- if lbl = node&.at(ns("./name"))&.text
207
- div << "(#{lbl})"
202
+ def formula_parse1(node, out)
203
+ out.div **attr_code(class: "formula") do |div|
204
+ div.p do |_p|
205
+ parse(node.at(ns("./stem")), div)
206
+ insert_tab(div, 1)
207
+ if lbl = node&.at(ns("./name"))&.text
208
+ div << "(#{lbl})"
209
+ end
208
210
  end
209
211
  end
210
212
  end
211
- end
212
213
 
213
- def li_parse(node, out)
214
- out.li **attr_code(id: node["id"]) do |li|
215
- if node["uncheckedcheckbox"] == "true"
216
- li << '<span class="zzMoveToFollowing">&#x2610; </span>'
217
- elsif node["checkedcheckbox"] == "true"
218
- li << '<span class="zzMoveToFollowing">&#x2611; </span>'
214
+ def li_parse(node, out)
215
+ out.li **attr_code(id: node["id"]) do |li|
216
+ if node["uncheckedcheckbox"] == "true"
217
+ li << '<span class="zzMoveToFollowing">&#x2610; </span>'
218
+ elsif node["checkedcheckbox"] == "true"
219
+ li << '<span class="zzMoveToFollowing">&#x2611; </span>'
220
+ end
221
+ node.children.each { |n| parse(n, li) }
219
222
  end
220
- node.children.each { |n| parse(n, li) }
221
223
  end
222
- end
223
224
 
224
- def suffix_url(url)
225
- return url if %r{^https?://}.match?(url)
226
- return url unless File.extname(url).empty?
225
+ def suffix_url(url)
226
+ return url if %r{^https?://}.match?(url)
227
+ return url unless File.extname(url).empty?
227
228
 
228
- url.sub(/#{File.extname(url)}$/, ".doc")
229
+ url.sub(/#{File.extname(url)}$/, ".doc")
230
+ end
229
231
  end
230
232
  end
231
233
  end