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 +4 -4
- data/isodoc.gemspec +1 -3
- data/lib/isodoc/base_style/all.css +7 -0
- data/lib/isodoc/base_style/reset.css +7 -0
- data/lib/isodoc/base_style/reset.scss +4 -0
- data/lib/isodoc/function/blocks.rb +3 -3
- data/lib/isodoc/function/footnotes.rb +9 -3
- data/lib/isodoc/function/inline.rb +9 -0
- data/lib/isodoc/function/table.rb +8 -3
- data/lib/isodoc/function/to_word_html.rb +4 -1
- data/lib/isodoc/headlesshtml_convert.rb +0 -2
- data/lib/isodoc/html_convert.rb +0 -2
- data/lib/isodoc/html_function/html.rb +7 -0
- data/lib/isodoc/pdf_convert.rb +0 -2
- data/lib/isodoc/presentation_function/footnotes.rb +72 -3
- data/lib/isodoc/presentation_function/image.rb +6 -2
- data/lib/isodoc/presentation_xml_convert.rb +14 -25
- data/lib/isodoc/version.rb +1 -1
- data/lib/isodoc/word_function/body.rb +1 -26
- data/lib/isodoc/word_function/comments.rb +56 -15
- data/lib/isodoc/word_function/footnotes.rb +26 -30
- data/lib/isodoc/word_function/table.rb +1 -0
- metadata +4 -33
- data/lib/isodoc/html_function/comments.rb +0 -142
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6f7b717e7e536647796abc2df27f9a3b00730a7b14790b1724defd797f19ed13
|
4
|
+
data.tar.gz: f12c2f1b8e16e8cbb5543940b828308c4aa7a7b5719a0f37e7fa3677f1c4e8cd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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"
|
@@ -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
|
-
|
202
|
-
|
203
|
-
out.send tag, id: "fn:#{
|
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
|
45
|
-
|
45
|
+
def table_footnote?(node)
|
46
|
+
(@in_table || @in_figure) &&
|
46
47
|
!node.ancestors.map(&:name).include?("fmt-name")
|
48
|
+
end
|
47
49
|
|
48
|
-
|
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
|
129
|
+
def table_bordered?(node)
|
129
130
|
c = node.parent.parent["class"]
|
130
|
-
|
131
|
-
|
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
|
data/lib/isodoc/html_convert.rb
CHANGED
@@ -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
|
|
data/lib/isodoc/pdf_convert.rb
CHANGED
@@ -125,10 +125,10 @@ module IsoDoc
|
|
125
125
|
end
|
126
126
|
end
|
127
127
|
|
128
|
-
def figure_fn_to_dt_dd(
|
129
|
-
label =
|
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,
|
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
|
-
|
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
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
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
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
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/>")
|
data/lib/isodoc/version.rb
CHANGED
@@ -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(
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
@
|
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
|
-
|
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["
|
23
|
-
to: node["
|
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
|
-
|
128
|
-
|
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
|
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
|
-
|
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
|
-
|
32
|
-
|
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,
|
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)
|
78
|
-
|
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
|
-
|
91
|
-
|
92
|
-
|
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#{
|
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.
|
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-
|
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.
|
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.
|
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
|