isodoc 3.1.3 → 3.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0cc231c707c79c5af17d4a07818b64395a13328377f6ab4521e2cdfe1ad8c884
4
- data.tar.gz: 1b6a810aae9f30c35eeea2f59daddc10d62d63cfd3efd3a0c0813c1c6a7b8bf0
3
+ metadata.gz: 6f7b717e7e536647796abc2df27f9a3b00730a7b14790b1724defd797f19ed13
4
+ data.tar.gz: f12c2f1b8e16e8cbb5543940b828308c4aa7a7b5719a0f37e7fa3677f1c4e8cd
5
5
  SHA512:
6
- metadata.gz: 4403a6d48af622fc31f0829683d4c11d2c76226a15f877deb449eaf8fcdf37e9b7fe55b25225ac1889fc2d3a15eda554d568efb9a988def3fe7bdc3e4d1632fc
7
- data.tar.gz: 3365c6b7317a602ea24bf62d3ccc73cadd8ac3b872735945388172f029c0b02460e8f2337f95a192b786057ea69045acc4917a7454c4145bb670777da770ce9e
6
+ metadata.gz: 860033b6e8cd5abf55cd4d4ab172706ac001696758216aff66bc47a53ce3e22a867664ed3325a3c41f7471b9d6afbf65b44df3376b6b8cafbadd845ecda711ea
7
+ data.tar.gz: e8430c322a91a674085aa9acfeb71a41bf8dc0f32e7d481c81208b36f6afa207f3943cad61580a391df54ecfc345d288f73bbd07993474e15debbc7e2af9cca7
data/isodoc.gemspec CHANGED
@@ -30,21 +30,19 @@ Gem::Specification.new do |spec|
30
30
 
31
31
  spec.add_dependency "base64"
32
32
  spec.add_dependency "bigdecimal"
33
- spec.add_dependency "html2doc", "~> 1.8.1"
33
+ spec.add_dependency "html2doc", "~> 1.9.0"
34
34
  # spec.add_dependency "isodoc-i18n", "~> 1.1.0" # already in relaton-render and mn-requirements
35
35
  # spec.add_dependency "relaton-cli"
36
36
  # spec.add_dependency "metanorma-utils", "~> 1.5.0" # already in isodoc-i18n
37
37
  spec.add_dependency "mn2pdf", ">= 2.13"
38
38
  spec.add_dependency "mn-requirements", "~> 0.5.0"
39
39
 
40
- spec.add_dependency "nokogiri", "<= 1.16.8"
41
40
  spec.add_dependency "relaton-render", "~> 0.9.0"
42
41
  spec.add_dependency "roman-numerals"
43
42
  spec.add_dependency "rouge", "~> 4.0"
44
43
  spec.add_dependency "thread_safe"
45
44
  spec.add_dependency "twitter_cldr", ">= 6.6.0"
46
45
  spec.add_dependency "uuidtools"
47
- spec.add_dependency "lutaml-model", "~> 0.6.0"
48
46
 
49
47
  spec.add_development_dependency "bigdecimal"
50
48
  spec.add_development_dependency "debug"
@@ -311,6 +311,13 @@ h6:hover > a.anchor,
311
311
  padding: 0;
312
312
  }
313
313
 
314
+ svg {
315
+ width: 100%;
316
+ padding-bottom: 92%;
317
+ height: 1px;
318
+ overflow: visible;
319
+ }
320
+
314
321
  #standard-band {
315
322
  background-color: #0AC442;
316
323
  }
@@ -310,3 +310,10 @@ h6:hover > a.anchor,
310
310
  overflow: hidden;
311
311
  padding: 0;
312
312
  }
313
+
314
+ svg {
315
+ width: 100%;
316
+ padding-bottom: 92%;
317
+ height: 1px;
318
+ overflow: visible;
319
+ }
@@ -276,3 +276,7 @@ visibility:visible;
276
276
  overflow: hidden;
277
277
  padding: 0;
278
278
  }
279
+
280
+ svg {
281
+ width: 100%; padding-bottom: 92%; height: 1px; overflow: visible;
282
+ }
@@ -198,9 +198,9 @@ module IsoDoc
198
198
  def fmt_fn_body_parse(node, out)
199
199
  node.ancestors("table, figure").empty? and
200
200
  node.at(ns(".//fmt-fn-label"))&.remove
201
- aside = node.parent.name == "fmt-footnote-container"
202
- tag = aside ? "aside" : "div"
203
- out.send tag, id: "fn:#{node['reference']}", class: "footnote" do |div|
201
+ tag = node.parent.name == "fmt-footnote-container" ? "aside" : "div"
202
+ id = node["is_table"] ? node["reference"] : node["id"]
203
+ out.send tag, id: "fn:#{id}", class: "footnote" do |div|
204
204
  node.children.each { |n| parse(n, div) }
205
205
  end
206
206
  end
@@ -32,6 +32,7 @@ module IsoDoc
32
32
  def update_table_fn_body_ref(fnote, table, reference)
33
33
  fnbody = table.at(ns(".//fmt-fn-body[@id = '#{fnote['target']}']")) or return
34
34
  fnbody["reference"] = reference
35
+ fnbody["is_table"] = true
35
36
  sup = fnbody.at(ns(".//fmt-fn-label/sup")) and sup.replace(sup.children)
36
37
  fnbody.xpath(ns(".//fmt-fn-label")).each do |s|
37
38
  s["class"] = "TableFootnoteRef"
@@ -41,17 +42,22 @@ module IsoDoc
41
42
  end
42
43
  end
43
44
 
44
- def footnote_parse(node, out)
45
- return table_footnote_parse(node, out) if (@in_table || @in_figure) &&
45
+ def table_footnote?(node)
46
+ (@in_table || @in_figure) &&
46
47
  !node.ancestors.map(&:name).include?("fmt-name")
48
+ end
47
49
 
48
- fn = node["reference"] || UUIDTools::UUID.random_create.to_s
50
+ def footnote_parse(node, out)
51
+ table_footnote?(node) and return table_footnote_parse(node, out)
52
+ fn = node["target"] # || UUIDTools::UUID.random_create.to_s
49
53
  attrs = { class: "FootnoteRef", href: "#fn:#{fn}" }
50
54
  f = node.at(ns("./fmt-fn-label"))
51
55
  out.a **attrs do |a|
52
56
  children_parse(f, a)
53
57
  end
54
58
  end
59
+
60
+ def fmt_review_body_parse(node, out); end
55
61
  end
56
62
  end
57
63
  end
@@ -213,6 +213,7 @@ module IsoDoc
213
213
  def svgmap_parse(node, out); end
214
214
  def amend_parse(node, out); end
215
215
  def semx_sourcecode_parse(node, out); end
216
+ def review_note_parse(node, out); end
216
217
 
217
218
  def fmt_name_parse(node, out)
218
219
  children_parse(node, out)
@@ -237,6 +238,14 @@ module IsoDoc
237
238
  def fmt_footnote_container_parse(node, out)
238
239
  children_parse(node, out)
239
240
  end
241
+
242
+ def fmt_review_start_parse(node, out)
243
+ children_parse(node, out)
244
+ end
245
+
246
+ def fmt_review_end_parse(node, out)
247
+ children_parse(node, out)
248
+ end
240
249
  end
241
250
  end
242
251
  end
@@ -106,6 +106,7 @@ module IsoDoc
106
106
 
107
107
  def make_tr_attr(cell, row, totalrows, header, bordered)
108
108
  style = cell.name == "th" ? "font-weight:bold;" : ""
109
+ cell["style"] and style += "#{cell['style']};"
109
110
  cell["align"] and style += "text-align:#{cell['align']};"
110
111
  cell["valign"] and style += "vertical-align:#{cell['valign']};"
111
112
  rowmax = cell["rowspan"] ? row + cell["rowspan"].to_i - 1 : row
@@ -125,10 +126,14 @@ module IsoDoc
125
126
  STYLE
126
127
  end
127
128
 
128
- def tr_parse(node, out, ord, totalrows, header)
129
+ def table_bordered?(node)
129
130
  c = node.parent.parent["class"]
130
- bordered = %w(modspec).include?(c) || !c
131
- out.tr do |r|
131
+ %w(modspec).include?(c) || !c
132
+ end
133
+
134
+ def tr_parse(node, out, ord, totalrows, header)
135
+ bordered = table_bordered?(node)
136
+ out.tr **attr_code(style: node["style"]) do |r|
132
137
  node.elements.each do |td|
133
138
  attrs = make_tr_attr(td, ord, totalrows - 1, header, bordered)
134
139
  r.send td.name, **attr_code(attrs) do |entry|
@@ -54,7 +54,7 @@ module IsoDoc
54
54
  boilerplate docxml, div3
55
55
  content(div3, docxml, ns(self.class::TOP_ELEMENTS))
56
56
  footnotes docxml, div3
57
- comments div3
57
+ comments docxml, div3
58
58
  end
59
59
  end
60
60
 
@@ -234,6 +234,9 @@ module IsoDoc
234
234
  when "fmt-fn-body" then fmt_fn_body_parse(node, out)
235
235
  when "fmt-fn-label" then fmt_fn_label_parse(node, out)
236
236
  when "fmt-footnote-container" then fmt_footnote_container_parse(node, out)
237
+ when "fmt-review-start" then fmt_review_start_parse(node, out)
238
+ when "fmt-review-end" then fmt_review_end_parse(node, out)
239
+ when "fmt-review-body" then fmt_review_body_parse(node, out)
237
240
  else error_parse(node, out)
238
241
  end
239
242
  end
@@ -1,10 +1,8 @@
1
- require_relative "html_function/comments"
2
1
  require_relative "html_function/html"
3
2
  require "fileutils"
4
3
 
5
4
  module IsoDoc
6
5
  class HeadlessHtmlConvert < ::IsoDoc::Convert
7
- include HtmlFunction::Comments
8
6
  include HtmlFunction::Html
9
7
 
10
8
  def tmpimagedir_suffix
@@ -1,4 +1,3 @@
1
- require_relative "html_function/comments"
2
1
  require_relative "html_function/html"
3
2
  require_relative "html_function/postprocess"
4
3
  require_relative "html_function/form"
@@ -6,7 +5,6 @@ require_relative "html_function/form"
6
5
  module IsoDoc
7
6
  class HtmlConvert < ::IsoDoc::Convert
8
7
 
9
- include HtmlFunction::Comments
10
8
  include HtmlFunction::Form
11
9
  include HtmlFunction::Html
12
10
 
@@ -110,6 +110,13 @@ module IsoDoc
110
110
  else super
111
111
  end
112
112
  end
113
+
114
+ def in_comment
115
+ @in_comment
116
+ end
117
+
118
+ def comments(docxml, div); end
119
+ def comment_cleanup(docxml); end
113
120
  end
114
121
  end
115
122
  end
@@ -1,9 +1,7 @@
1
- require_relative "html_function/comments"
2
1
  require_relative "html_function/html"
3
2
 
4
3
  module IsoDoc
5
4
  class PdfConvert < ::IsoDoc::Convert
6
- include HtmlFunction::Comments
7
5
  include HtmlFunction::Html
8
6
 
9
7
  def initialize(options)
@@ -125,10 +125,10 @@ module IsoDoc
125
125
  end
126
126
  end
127
127
 
128
- def figure_fn_to_dt_dd(f)
129
- label = f.at(ns(".//fmt-fn-label")).remove
128
+ def figure_fn_to_dt_dd(fnote)
129
+ label = fnote.at(ns(".//fmt-fn-label")).remove
130
130
  label.at(ns(".//span[@class = 'fmt-caption-delim']"))&.remove
131
- [label, f]
131
+ [label, fnote]
132
132
  end
133
133
 
134
134
  def figure_key_insert_pt(elem)
@@ -136,5 +136,74 @@ module IsoDoc
136
136
  elem.at(ns(".//dl"))&.children&.first ||
137
137
  elem.add_child("<dl> </dl>").first.children.first
138
138
  end
139
+
140
+ def comments(docxml)
141
+ docxml.xpath(ns("//review")).each do |c|
142
+ c1 = comment_body(c)
143
+ comment_bookmarks(c1)
144
+ end
145
+ end
146
+
147
+ def comment_body(elem)
148
+ elem["id"] ||= "_#{UUIDTools::UUID.random_create}"
149
+ c1 = elem.after("<fmt-review-body/>").next
150
+ elem.attributes.each_key { |k| c1[k] = elem[k] }
151
+ c1["id"] = "_#{UUIDTools::UUID.random_create}"
152
+ c1 << semx_fmt_dup(elem)
153
+ end
154
+
155
+ def comment_bookmarks(elem)
156
+ from, to = comment_bookmarks_locate(elem)
157
+ new_from = comment_bookmark_start(from, elem)
158
+ new_to = comment_bookmark_end(to, elem)
159
+ elem["from"] = new_from["id"]
160
+ elem["to"] = new_to["id"]
161
+ end
162
+
163
+ # Do not insert a comment bookmark inside another comment bookmark
164
+ AVOID_COMMENT_BOOKMARKS = <<~XPATH.freeze
165
+ [not(ancestor::xmlns:fmt-review-start)][not(ancestor::xmlns:fmt-review-end)]
166
+ XPATH
167
+
168
+ def comment_bookmarks_locate(elem)
169
+ from = elem.document.at("//*[@id = '#{elem['from']}']")
170
+ f = from.at(".//text()#{AVOID_COMMENT_BOOKMARKS}") and from = f
171
+ to = elem.document.at("//*[@id = '#{elem['to']}']") || from
172
+ f = to.at(".//text()[last()]#{AVOID_COMMENT_BOOKMARKS}") and to = f
173
+ [from, to]
174
+ end
175
+
176
+ def comment_to_bookmark_attrs(elem, bookmark, start: true)
177
+ bookmark["target"] = elem["id"]
178
+ if start then bookmark["end"] = elem["to"]
179
+ else bookmark["start"] = elem["from"] end
180
+ %w(author date).each { |k| bookmark[k] = elem[k] }
181
+ end
182
+
183
+ def comment_bookmark_start(from, elem)
184
+ ret = from.before("<fmt-review-start/>").previous
185
+ ret["id"] = "_#{UUIDTools::UUID.random_create}"
186
+ ret["source"] = elem["from"]
187
+ comment_to_bookmark_attrs(elem, ret, start: true)
188
+ ret << comment_bookmark_start_label(elem)
189
+ ret
190
+ end
191
+
192
+ def comment_bookmark_end(to, elem)
193
+ ret = to.after("<fmt-review-end/>").next
194
+ ret["id"] = "_#{UUIDTools::UUID.random_create}"
195
+ ret["source"] = elem["to"]
196
+ comment_to_bookmark_attrs(elem, ret, start: false)
197
+ ret << comment_bookmark_end_label(elem)
198
+ ret
199
+ end
200
+
201
+ def comment_bookmark_start_label(_elem)
202
+ ""
203
+ end
204
+
205
+ def comment_bookmark_end_label(_elem)
206
+ ""
207
+ end
139
208
  end
140
209
  end
@@ -10,15 +10,19 @@ module IsoDoc
10
10
  docxml.xpath(ns("//figure")).each { |f| figure1(f) }
11
11
  docxml.xpath(ns("//svgmap")).each { |s| svgmap_extract(s) }
12
12
  imageconvert(docxml)
13
+ docxml.xpath("//m:svg", SVG).each { |f| svg_scale(f) }
13
14
  end
14
15
 
15
16
  def svg_wrap(elem)
16
- return if elem.parent.name == "image"
17
-
17
+ elem.parent.name == "image" and return
18
18
  elem.wrap("<image src='' mimetype='image/svg+xml' height='auto' " \
19
19
  "width='auto'></image>")
20
20
  end
21
21
 
22
+ def svg_scale(elem)
23
+ elem["preserveaspectratio"] = "xMidYMin slice"
24
+ end
25
+
22
26
  def svgmap_extract(elem)
23
27
  if elem.at(ns("./figure"))# then elem.replace(f)
24
28
  n = semx_fmt_dup(elem)
@@ -34,21 +34,21 @@ module IsoDoc
34
34
  end
35
35
 
36
36
  def repeat_id_validate1(elem)
37
- if @doc_ids[elem["id"]]
38
- @log.add("Anchors", elem,
39
- "Anchor #{elem['id']} has already been " \
40
- "used at line #{@doc_ids[elem['id']]}", severity: 0)
41
- end
42
- @doc_ids[elem["id"]] = elem.line
37
+ if @doc_ids[elem["id"]]
38
+ @log.add("Anchors", elem,
39
+ "Anchor #{elem['id']} has already been " \
40
+ "used at line #{@doc_ids[elem['id']]}", severity: 0)
43
41
  end
42
+ @doc_ids[elem["id"]] = elem.line
43
+ end
44
44
 
45
- def repeat_id_validate(doc)
46
- @log or return
47
- @doc_ids = {}
48
- doc.xpath("//*[@id]").each do |x|
49
- repeat_id_validate1(x)
50
- end
45
+ def repeat_id_validate(doc)
46
+ @log or return
47
+ @doc_ids = {}
48
+ doc.xpath("//*[@id]").each do |x|
49
+ repeat_id_validate1(x)
51
50
  end
51
+ end
52
52
 
53
53
  def bibitem_lookup(docxml)
54
54
  @bibitem_lookup ||= docxml.xpath(ns("//references/bibitem"))
@@ -58,7 +58,7 @@ module IsoDoc
58
58
  end
59
59
 
60
60
  def conversions(docxml)
61
- #semantic_xml_insert(docxml)
61
+ # semantic_xml_insert(docxml)
62
62
  metadata docxml
63
63
  bibdata docxml
64
64
  @xrefs.parse docxml
@@ -88,6 +88,7 @@ module IsoDoc
88
88
  toc docxml
89
89
  display_order docxml # feeds document_footnotes
90
90
  document_footnotes docxml
91
+ comments docxml
91
92
  end
92
93
 
93
94
  def block(docxml)
@@ -117,7 +118,6 @@ module IsoDoc
117
118
  xref docxml
118
119
  eref docxml # feeds eref2link
119
120
  origin docxml # feeds eref2link
120
- #quotesource docxml # feeds eref2link
121
121
  concept docxml
122
122
  eref2link docxml
123
123
  mathml docxml
@@ -136,21 +136,10 @@ module IsoDoc
136
136
  termdefinition docxml
137
137
  designation docxml
138
138
  termsource docxml
139
- #concept docxml
140
139
  related docxml
141
140
  termcleanup docxml
142
141
  end
143
142
 
144
- # KILL
145
- def semantic_xml_insert(xml)
146
- @semantic_xml_insert or return
147
- embed = embedable_semantic_xml(xml)
148
- ins = metanorma_extension_insert_pt(xml)
149
- ins = ins.at(ns("./metanorma")) || ins.add_child("<metanorma/>").first
150
- ins = ins.add_child("<source/>").first
151
- ins << embed
152
- end
153
-
154
143
  def metanorma_extension_insert_pt(xml)
155
144
  xml.at(ns("//metanorma-extension")) ||
156
145
  xml.at(ns("//bibdata"))&.after("<metanorma-extension/>")
@@ -1,3 +1,3 @@
1
1
  module IsoDoc
2
- VERSION = "3.1.3".freeze
2
+ VERSION = "3.1.4".freeze
3
3
  end
@@ -52,7 +52,7 @@ module IsoDoc
52
52
  body.div class: "WordSection3" do |div3|
53
53
  content(div3, docxml, ns(self.class::MAIN_ELEMENTS))
54
54
  footnotes docxml, div3
55
- comments div3
55
+ comments docxml, div3
56
56
  end
57
57
  end
58
58
 
@@ -79,31 +79,6 @@ module IsoDoc
79
79
  node.xpath(ns("./note")).each { |n| parse(n, out) }
80
80
  end
81
81
 
82
- # KILL
83
- def figure_get_or_make_dlx(node)
84
- dl = node.at(".//table[@class = 'dl']")
85
- if dl.nil?
86
- node.add_child("<p><b>#{@i18n.key}</b></p><table class='dl'></table>")
87
- dl = node.at(".//table[@class = 'dl']")
88
- end
89
- dl
90
- end
91
-
92
- # get rid of footnote link, it is in diagram
93
- # KILL
94
- def figure_aside_processx(fig, aside, key)
95
- fig.at("./a[@class='TableFootnoteRef']")&.remove
96
- fnref = fig.at(".//span[@class='TableFootnoteRef']/..")
97
- tr = key.add_child("<tr></tr>").first
98
- dt = tr.add_child("<td valign='top' align='left'></td>").first
99
- dd = tr.add_child("<td valign='top'></td>").first
100
- fnref.parent = dt
101
- aside.xpath(".//p").each do |a|
102
- a.delete("class")
103
- a.parent = dd
104
- end
105
- end
106
-
107
82
  def note_p_class
108
83
  "Note"
109
84
  end
@@ -1,15 +1,18 @@
1
1
  module IsoDoc
2
2
  module WordFunction
3
3
  module Comments
4
- def comments(div)
5
- return if @comments.empty?
6
-
7
- div.div style: "mso-element:comment-list" do |div1|
8
- @comments.each { |fn| div1.parent << fn }
4
+ def comments(docxml, out)
5
+ c = docxml.xpath(ns("//fmt-review-body"))
6
+ c.empty? and return
7
+ out.div style: "mso-element:comment-list" do |div|
8
+ @in_comment = true
9
+ c.each { |fn| parse(fn, div) }
10
+ @in_comment = false
9
11
  end
10
12
  end
11
13
 
12
- def review_note_parse(node, out)
14
+ # KILL
15
+ def review_note_parsex(node, out)
13
16
  fn = @comments.length + 1
14
17
  make_comment_link(out, fn, node)
15
18
  @in_comment = true
@@ -19,10 +22,15 @@ module IsoDoc
19
22
 
20
23
  def comment_link_attrs(fnote, node)
21
24
  { style: "MsoCommentReference", target: fnote,
22
- class: "commentLink", from: node["from"],
23
- to: node["to"] }
25
+ class: "commentLink", from: node["source"],
26
+ to: node["end"] }
27
+ end
28
+
29
+ def fmt_review_start_parse(node, out)
30
+ make_comment_link(out, node["target"], node)
24
31
  end
25
32
 
33
+ # TODO: CONSOLIDATE
26
34
  # add in from and to links to move the comment into place
27
35
  def make_comment_link(out, fnote, node)
28
36
  out.span(**comment_link_attrs(fnote, node)) do |s1|
@@ -43,6 +51,7 @@ module IsoDoc
43
51
  end
44
52
  end
45
53
 
54
+ # KILL
46
55
  def make_comment_text(node, fnote)
47
56
  noko do |xml|
48
57
  xml.div style: "mso-element:comment", id: fnote do |div|
@@ -53,12 +62,46 @@ module IsoDoc
53
62
  end.join("\n")
54
63
  end
55
64
 
65
+ def fmt_review_body_parse(node, out)
66
+ out.div style: "mso-element:comment", id: node["id"] do |div|
67
+ div.span style: %{mso-comment-author:"#{node['reviewer']}"}
68
+ make_comment_target(div)
69
+ node.children.each { |n| parse(n, div) }
70
+ end
71
+ end
72
+
56
73
  def comment_cleanup(docxml)
74
+ number_comments(docxml)
57
75
  move_comment_link_to_from(docxml)
58
76
  reorder_comments_by_comment_link(docxml)
59
77
  embed_comment_in_comment_list(docxml)
60
78
  end
61
79
 
80
+ def number_comments(docxml)
81
+ map = comment_id_to_number(docxml)
82
+ docxml.xpath("//span[@style='MsoCommentReference' or " \
83
+ "'mso-special-character:comment']").each do |x|
84
+ x["target"] &&= map[x["target"]]
85
+ end
86
+ docxml.xpath("//div[@style='mso-element:comment']").each do |x|
87
+ x["id"] = map[x["id"]]
88
+ end
89
+ docxml.xpath("//a[@style]").each do |x|
90
+ m = /mso-comment-reference:SMC_([^;]+);/.match(x["style"]) or next
91
+ x["style"] = x["style"].sub(/mso-comment-reference:SMC_#{m[1]}/,
92
+ "mso-comment-reference:SMC_#{map[m[1]]}")
93
+ end
94
+ end
95
+
96
+ def comment_id_to_number(docxml)
97
+ ids = docxml.xpath("//span[@style='MsoCommentReference']").map do |x|
98
+ x["target"]
99
+ end
100
+ ids.uniq.each_with_index.with_object({}) do |(id, i), m|
101
+ m[id] = i + 1
102
+ end
103
+ end
104
+
62
105
  COMMENT_IN_COMMENT_LIST1 =
63
106
  '//div[@style="mso-element:comment-list"]//' \
64
107
  'span[@style="MsoCommentReference"]'.freeze
@@ -123,14 +166,12 @@ module IsoDoc
123
166
  end
124
167
 
125
168
  def get_comments_from_text(docxml, link_order)
126
- comments = []
127
- docxml.xpath("//div[@style='mso-element:comment']").each do |c|
128
- next unless c["id"] && !link_order[c["id"]].nil?
129
-
130
- comments << { text: c.remove.to_s, id: c["id"] }
169
+ comments = docxml.xpath("//div[@style='mso-element:comment']")
170
+ .each_with_object([]) do |c, m|
171
+ c["id"] && !link_order[c["id"]].nil? or next
172
+ m << { text: c.remove.to_s, id: c["id"] }
131
173
  end
132
- comments.sort! { |a, b| link_order[a[:id]] <=> link_order[b[:id]] }
133
- # comments
174
+ comments.sort { |a, b| link_order[a[:id]] <=> link_order[b[:id]] }
134
175
  end
135
176
 
136
177
  COMMENT_TARGET_XREFS1 =
@@ -22,16 +22,18 @@ module IsoDoc
22
22
  node.at(ns(".//fmt-fn-label"))&.remove
23
23
  aside = node.parent.name == "fmt-footnote-container"
24
24
  tag = aside ? "aside" : "div"
25
- out.send tag, id: "ftn#{node['reference']}" do |div|
25
+ id = node["is_table"] ? node["reference"] : node["id"]
26
+ out.send tag, id: "ftn#{id}" do |div|
26
27
  node.children.each { |n| parse(n, div) }
27
28
  end
28
29
  end
29
30
 
30
31
  # dupe to HTML
31
- def get_table_ancestor_id(node)
32
- table = node.ancestors("table")
32
+ def get_table_ancestor_id(node)
33
+ table = node.ancestors("table")
33
34
  table.empty? and table = node.ancestors("figure")
34
- table.empty? and return [nil, UUIDTools::UUID.random_create.to_s]
35
+ table.empty? and return [nil,
36
+ UUIDTools::UUID.random_create.to_s]
35
37
  [table.last, table.last["id"]]
36
38
  end
37
39
 
@@ -42,30 +44,17 @@ module IsoDoc
42
44
  make_table_footnote_link(out, tid + fn, node.at(ns("./fmt-fn-label")))
43
45
  # do not output footnote text if we have already seen it for this table
44
46
  return if @seen_footnote.include?(tid + fn)
47
+
45
48
  update_table_fn_body_ref(node, table, tid + fn)
46
49
  @seen_footnote << (tid + fn)
47
50
  end
48
51
 
49
- # TODO merge with HTML
50
- def update_table_fn_body_ref(fnote, table, reference)
51
- fnbody = table.at(ns(".//fmt-fn-body[@id = '#{fnote['target']}']")) or return
52
- fnbody["reference"] = reference
53
- sup = fnbody.at(ns(".//fmt-fn-label/sup")) and sup.replace(sup.children)
54
- fnbody.xpath(ns(".//fmt-fn-label")).each do |s|
55
- s["class"] = "TableFootnoteRef"
56
- s.name = "span"
57
- d = s.at(ns("./span[@class = 'fmt-caption-delim']")) and
58
- s.next = d
59
- end
60
- end
61
-
62
52
  def seen_footnote_parse(node, out, footnote)
63
53
  f = node.at(ns("./fmt-fn-label"))
64
54
  sup = f.at(ns(".//sup")) and sup.replace(sup.children)
65
55
  s = f.at(ns(".//semx[@source = '#{node['id']}']"))
66
-
67
56
  semx = <<~SPAN.strip
68
- <span style="mso-element:field-begin"/> NOTEREF _Ref#{@fn_bookmarks[footnote]} \\f \\h<span style="mso-element:field-separator"/>#{footnote}<span style="mso-element:field-end"/>
57
+ <span style="mso-element:field-begin"/> NOTEREF _Ref#{@fn_bookmarks[footnote]} \\f \\h<span style="mso-element:field-separator"/>#{footnote}<span style="mso-element:field-end"/>
69
58
  SPAN
70
59
  s.replace(semx)
71
60
  out.span class: "MsoFootnoteReference" do |fn|
@@ -74,29 +63,36 @@ module IsoDoc
74
63
  end
75
64
 
76
65
  def footnote_parse(node, out)
77
- return table_footnote_parse(node, out) if (@in_table || @in_figure) &&
78
- !node.ancestors.map(&:name).include?("fmt-name")
79
-
80
- fn = node["reference"] || UUIDTools::UUID.random_create.to_s
81
- return seen_footnote_parse(node, out, fn) if @seen_footnote.include?(fn)
82
-
66
+ table_footnote?(node) and return table_footnote_parse(node, out)
67
+ fn = node["reference"] # || UUIDTools::UUID.random_create.to_s
68
+ @seen_footnote.include?(fn) and return seen_footnote_parse(node, out, fn)
83
69
  @fn_bookmarks[fn] = bookmarkid
70
+ f = footnote_label_process(node)
71
+ out.span style: "mso-bookmark:_Ref#{@fn_bookmarks[fn]}",
72
+ class: "MsoFootnoteReference" do |s|
73
+ children_parse(f, s)
74
+ end
75
+ footnote_hyperlink(node, out)
76
+ @seen_footnote << fn
77
+ end
78
+
79
+ def footnote_label_process(node)
84
80
  f = node.at(ns("./fmt-fn-label"))
85
81
  sup = f.at(ns(".//sup")) and sup.replace(sup.children)
86
82
  if semx = f.at(ns(".//semx[@element = 'autonum']"))
87
83
  semx.name = "span"
88
84
  semx["class"] = "FMT-PLACEHOLDER"
89
85
  end
90
- out.span style: "mso-bookmark:_Ref#{@fn_bookmarks[fn]}", class: "MsoFootnoteReference" do |s|
91
- children_parse(f, out)
92
- end
86
+ f
87
+ end
88
+
89
+ def footnote_hyperlink(node, out)
93
90
  if semx = out.parent.at(".//span[@class = 'FMT-PLACEHOLDER']")
94
91
  semx.name = "a"
95
92
  semx["class"] = "FootnoteRef"
96
93
  semx["epub:type"] = "footnote"
97
- semx["href"] = "#ftn#{fn}"
94
+ semx["href"] = "#ftn#{node['target']}"
98
95
  end
99
- @seen_footnote << fn
100
96
  end
101
97
  end
102
98
  end
@@ -23,6 +23,7 @@ module IsoDoc
23
23
 
24
24
  def make_tr_attr(cell, row, totalrows, header, bordered)
25
25
  style = cell.name == "th" ? "font-weight:bold;" : ""
26
+ cell["style"] and style += "#{cell['style']};"
26
27
  rowmax = cell["rowspan"] ? row + cell["rowspan"].to_i - 1 : row
27
28
  style += make_tr_attr_style(cell, row, rowmax, totalrows,
28
29
  { header: header, bordered: bordered })
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: isodoc
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.3
4
+ version: 3.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-03-17 00:00:00.000000000 Z
11
+ date: 2025-03-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: base64
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 1.8.1
47
+ version: 1.9.0
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 1.8.1
54
+ version: 1.9.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: mn2pdf
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -80,20 +80,6 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: 0.5.0
83
- - !ruby/object:Gem::Dependency
84
- name: nokogiri
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - "<="
88
- - !ruby/object:Gem::Version
89
- version: 1.16.8
90
- type: :runtime
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - "<="
95
- - !ruby/object:Gem::Version
96
- version: 1.16.8
97
83
  - !ruby/object:Gem::Dependency
98
84
  name: relaton-render
99
85
  requirement: !ruby/object:Gem::Requirement
@@ -178,20 +164,6 @@ dependencies:
178
164
  - - ">="
179
165
  - !ruby/object:Gem::Version
180
166
  version: '0'
181
- - !ruby/object:Gem::Dependency
182
- name: lutaml-model
183
- requirement: !ruby/object:Gem::Requirement
184
- requirements:
185
- - - "~>"
186
- - !ruby/object:Gem::Version
187
- version: 0.6.0
188
- type: :runtime
189
- prerelease: false
190
- version_requirements: !ruby/object:Gem::Requirement
191
- requirements:
192
- - - "~>"
193
- - !ruby/object:Gem::Version
194
- version: 0.6.0
195
167
  - !ruby/object:Gem::Dependency
196
168
  name: bigdecimal
197
169
  requirement: !ruby/object:Gem::Requirement
@@ -449,7 +421,6 @@ files:
449
421
  - lib/isodoc/headlesshtml_convert.rb
450
422
  - lib/isodoc/html_convert.rb
451
423
  - lib/isodoc/html_function.rb
452
- - lib/isodoc/html_function/comments.rb
453
424
  - lib/isodoc/html_function/form.rb
454
425
  - lib/isodoc/html_function/html.rb
455
426
  - lib/isodoc/html_function/mathvariant_to_plain.rb
@@ -1,142 +0,0 @@
1
- module IsoDoc
2
- module HtmlFunction
3
- module Comments
4
- def in_comment
5
- @in_comment
6
- end
7
-
8
- def comments(div)
9
- # return if @comments.empty?
10
- # div.div **{ style: "mso-element:comment-list" } do |div1|
11
- # @comments.each { |fn| div1.parent << fn }
12
- # end
13
- end
14
-
15
- def review_note_parse(node, out)
16
- # fn = @comments.length + 1
17
- # make_comment_link(out, fn, node)
18
- # @in_comment = true
19
- # @comments << make_comment_text(node, fn)
20
- # @in_comment = false
21
- end
22
-
23
- def comment_link_attrs(fnote, node)
24
- { style: "MsoCommentReference", target: fnote,
25
- class: "commentLink", from: node["from"],
26
- to: node["to"] }
27
- end
28
-
29
- # add in from and to links to move the comment into place
30
- def make_comment_link(out, fnote, node)
31
- out.span(**comment_link_attrs(fnote, node)) do |s1|
32
- s1.a **{ style: "mso-comment-reference:SMC_#{fnote};"\
33
- "mso-comment-date:#{node['date'].gsub(/[-:Z]/,
34
- '')}" }
35
- end
36
- end
37
-
38
- def make_comment_target(out)
39
- out.span **{ style: "MsoCommentReference" } do |s1|
40
- s1.span **{ style: "mso-special-character:comment" }
41
- end
42
- end
43
-
44
- def make_comment_text(node, fnote)
45
- noko do |xml|
46
- xml.div **{ style: "mso-element:comment", id: fnote } do |div|
47
- div.span **{ style: %{mso-comment-author:"#{node['reviewer']}"} }
48
- make_comment_target(div)
49
- node.children.each { |n| parse(n, div) }
50
- end
51
- end.join("\n")
52
- end
53
-
54
- def comment_cleanup(docxml)
55
- # move_comment_link_to_from(docxml)
56
- # reorder_comments_by_comment_link(docxml)
57
- # embed_comment_in_comment_list(docxml)
58
- end
59
-
60
- COMMENT_IN_COMMENT_LIST =
61
- '//div[@style="mso-element:comment-list"]//'\
62
- 'span[@style="MsoCommentReference"]'.freeze
63
-
64
- def embed_comment_in_comment_list(docxml)
65
- docxml.xpath(COMMENT_IN_COMMENT_LIST).each do |x|
66
- n = x.next_element
67
- n&.children&.first&.add_previous_sibling(x.remove)
68
- end
69
- docxml
70
- end
71
-
72
- def move_comment_link_to_from1(x, fromlink)
73
- x.remove
74
- link = x.at(".//a")
75
- fromlink.replace(x)
76
- link.children = fromlink
77
- end
78
-
79
- def comment_attributes(docxml, x)
80
- fromlink = docxml.at("//*[@id='#{x['from']}']")
81
- return(nil) if fromlink.nil?
82
-
83
- tolink = docxml.at("//*[@id='#{x['to']}']") || fromlink
84
- target = docxml.at("//*[@id='#{x['target']}']")
85
- { from: fromlink, to: tolink, target: target }
86
- end
87
-
88
- def wrap_comment_cont(from, target)
89
- s = from.replace("<span style='mso-comment-continuation:#{target}'>")
90
- s.first.children = from
91
- end
92
-
93
- def skip_comment_wrap(from)
94
- from["style"] != "mso-special-character:comment"
95
- end
96
-
97
- def insert_comment_cont(from, upto, target)
98
- # includes_to = from.at(".//*[@id='#{upto}']")
99
- while !from.nil? && from["id"] != upto
100
- following = from.xpath("./following::*")
101
- (from = following.shift) && incl_to = from.at(".//*[@id='#{upto}']")
102
- while !incl_to.nil? && !from.nil? && skip_comment_wrap(from)
103
- (from = following.shift) && incl_to = from.at(".//*[@id='#{upto}']")
104
- end
105
- wrap_comment_cont(from, target) if !from.nil?
106
- end
107
- end
108
-
109
- def move_comment_link_to_from(docxml)
110
- docxml.xpath('//span[@style="MsoCommentReference"][@from]').each do |x|
111
- attrs = comment_attributes(docxml, x) || next
112
- move_comment_link_to_from1(x, attrs[:from])
113
- insert_comment_cont(attrs[:from], x["to"], x["target"])
114
- end
115
- end
116
-
117
- def get_comments_from_text(docxml, link_order)
118
- comments = []
119
- docxml.xpath("//div[@style='mso-element:comment']").each do |c|
120
- next unless c["id"] && !link_order[c["id"]].nil?
121
-
122
- comments << { text: c.remove.to_s, id: c["id"] }
123
- end
124
- comments.sort! { |a, b| link_order[a[:id]] <=> link_order[b[:id]] }
125
- # comments
126
- end
127
-
128
- COMMENT_TARGET_XREFS =
129
- "//span[@style='mso-special-character:comment']/@target".freeze
130
-
131
- def reorder_comments_by_comment_link(docxml)
132
- link_order = {}
133
- docxml.xpath(COMMENT_TARGET_XREFS).each_with_index do |target, i|
134
- link_order[target.value] = i
135
- end
136
- comments = get_comments_from_text(docxml, link_order)
137
- list = docxml.at("//*[@style='mso-element:comment-list']") || return
138
- list.children = comments.map { |c| c[:text] }.join("\n")
139
- end
140
- end
141
- end
142
- end