isodoc 1.7.4 → 1.7.7

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.
@@ -1,145 +1,150 @@
1
- module IsoDoc::WordFunction
2
- module Comments
1
+ module IsoDoc
2
+ module WordFunction
3
+ module Comments
4
+ def in_comment
5
+ @in_comment
6
+ end
3
7
 
4
- def in_comment
5
- @in_comment
6
- end
8
+ def comments(div)
9
+ return if @comments.empty?
7
10
 
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 }
11
+ div.div **{ style: "mso-element:comment-list" } do |div1|
12
+ @comments.each { |fn| div1.parent << fn }
13
+ end
12
14
  end
13
- end
14
15
 
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
16
+ def review_note_parse(node, out)
17
+ fn = @comments.length + 1
18
+ make_comment_link(out, fn, node)
19
+ @in_comment = true
20
+ @comments << make_comment_text(node, fn)
21
+ @in_comment = false
22
+ end
22
23
 
23
- def comment_link_attrs(fn, node)
24
- { style: "MsoCommentReference", target: fn,
25
- class: "commentLink", from: node["from"],
26
- to: node["to"] }
27
- end
24
+ def comment_link_attrs(fnote, node)
25
+ { style: "MsoCommentReference", target: fnote,
26
+ class: "commentLink", from: node["from"],
27
+ to: node["to"] }
28
+ end
28
29
 
29
- # add in from and to links to move the comment into place
30
- def make_comment_link(out, fn, node)
31
- out.span(**comment_link_attrs(fn, node)) do |s1|
32
- s1.span **{ lang: "EN-GB", style: "font-size:9.0pt" } do |s2|
33
- s2.a **{ style: "mso-comment-reference:SMC_#{fn};"\
34
- "mso-comment-date:#{node['date'].gsub(/[:-]+/, '')}" }
35
- s2.span **{ style: "mso-special-character:comment",
36
- target: fn } # do |s|
30
+ # add in from and to links to move the comment into place
31
+ def make_comment_link(out, fnote, node)
32
+ out.span(**comment_link_attrs(fnote, node)) do |s1|
33
+ s1.span **{ lang: "EN-GB", style: "font-size:9.0pt" } do |s2|
34
+ s2.a **{ style: "mso-comment-reference:SMC_#{fnote};"\
35
+ "mso-comment-date:#{node['date'].gsub(/[:-]+/,
36
+ '')}" }
37
+ s2.span **{ style: "mso-special-character:comment",
38
+ target: fnote } # do |s|
39
+ end
37
40
  end
38
41
  end
39
- end
40
42
 
41
- def make_comment_target(out)
42
- out.span **{ style: "MsoCommentReference" } do |s1|
43
- s1.span **{ lang: "EN-GB", style: "font-size:9.0pt" } do |s2|
44
- s2.span **{ style: "mso-special-character:comment" }
43
+ def make_comment_target(out)
44
+ out.span **{ style: "MsoCommentReference" } do |s1|
45
+ s1.span **{ lang: "EN-GB", style: "font-size:9.0pt" } do |s2|
46
+ s2.span **{ style: "mso-special-character:comment" }
47
+ end
45
48
  end
46
49
  end
47
- end
48
50
 
49
- def make_comment_text(node, fn)
50
- noko do |xml|
51
- xml.div **{ style: "mso-element:comment", id: fn } do |div|
52
- div.span **{ style: %{mso-comment-author:"#{node['reviewer']}"} }
53
- make_comment_target(div)
54
- node.children.each { |n| parse(n, div) }
55
- end
56
- end.join("\n")
57
- end
51
+ def make_comment_text(node, fnote)
52
+ noko do |xml|
53
+ xml.div **{ style: "mso-element:comment", id: fnote } do |div|
54
+ div.span **{ style: %{mso-comment-author:"#{node['reviewer']}"} }
55
+ make_comment_target(div)
56
+ node.children.each { |n| parse(n, div) }
57
+ end
58
+ end.join("\n")
59
+ end
58
60
 
59
- def comment_cleanup(docxml)
60
- move_comment_link_to_from(docxml)
61
- reorder_comments_by_comment_link(docxml)
62
- embed_comment_in_comment_list(docxml)
63
- end
61
+ def comment_cleanup(docxml)
62
+ move_comment_link_to_from(docxml)
63
+ reorder_comments_by_comment_link(docxml)
64
+ embed_comment_in_comment_list(docxml)
65
+ end
64
66
 
65
- COMMENT_IN_COMMENT_LIST1 =
66
- '//div[@style="mso-element:comment-list"]//'\
67
- 'span[@style="MsoCommentReference"]'.freeze
67
+ COMMENT_IN_COMMENT_LIST1 =
68
+ '//div[@style="mso-element:comment-list"]//'\
69
+ 'span[@style="MsoCommentReference"]'.freeze
68
70
 
69
- def embed_comment_in_comment_list(docxml)
70
- #docxml.xpath(COMMENT_IN_COMMENT_LIST).each do |x|
71
- docxml.xpath(COMMENT_IN_COMMENT_LIST1).each do |x|
72
- n = x.next_element
73
- n&.children&.first&.add_previous_sibling(x.remove)
71
+ def embed_comment_in_comment_list(docxml)
72
+ # docxml.xpath(COMMENT_IN_COMMENT_LIST).each do |x|
73
+ docxml.xpath(COMMENT_IN_COMMENT_LIST1).each do |x|
74
+ n = x.next_element
75
+ n&.children&.first&.add_previous_sibling(x.remove)
76
+ end
77
+ docxml
74
78
  end
75
- docxml
76
- end
77
79
 
78
- def move_comment_link_to_from1(x, fromlink)
79
- x.remove
80
- link = x.at(".//a")
81
- fromlink.replace(x)
82
- link.children = fromlink
83
- end
80
+ def move_comment_link_to_from1(tolink, fromlink)
81
+ tolink.remove
82
+ link = tolink.at(".//a")
83
+ fromlink.replace(tolink)
84
+ link.children = fromlink
85
+ end
84
86
 
85
- def comment_attributes(docxml, x)
86
- fromlink = docxml.at("//*[@id='#{x['from']}']")
87
- return(nil) if fromlink.nil?
88
- tolink = docxml.at("//*[@id='#{x['to']}']") || fromlink
89
- target = docxml.at("//*[@id='#{x['target']}']")
90
- { from: fromlink, to: tolink, target: target }
91
- end
87
+ def comment_attributes(docxml, x)
88
+ fromlink = docxml.at("//*[@id='#{x['from']}']")
89
+ return(nil) if fromlink.nil?
92
90
 
93
- def wrap_comment_cont(from, target)
94
- s = from.replace("<span style='mso-comment-continuation:#{target}'>")
95
- s.first.children = from
96
- end
91
+ tolink = docxml.at("//*[@id='#{x['to']}']") || fromlink
92
+ target = docxml.at("//*[@id='#{x['target']}']")
93
+ { from: fromlink, to: tolink, target: target }
94
+ end
97
95
 
98
- def skip_comment_wrap(from)
99
- from["style"] != "mso-special-character:comment"
100
- end
96
+ def wrap_comment_cont(from, target)
97
+ s = from.replace("<span style='mso-comment-continuation:#{target}'>")
98
+ s.first.children = from
99
+ end
100
+
101
+ def skip_comment_wrap(from)
102
+ from["style"] != "mso-special-character:comment"
103
+ end
101
104
 
102
- def insert_comment_cont(from, to, target)
103
- # includes_to = from.at(".//*[@id='#{to}']")
104
- while !from.nil? && from["id"] != to
105
- following = from.xpath("./following::*")
106
- (from = following.shift) && incl_to = from.at(".//*[@id='#{to}']")
107
- while !incl_to.nil? && !from.nil? && skip_comment_wrap(from)
108
- (from = following.shift) && incl_to = from.at(".//*[@id='#{to}']")
105
+ def insert_comment_cont(from, upto, target)
106
+ # includes_to = from.at(".//*[@id='#{upto}']")
107
+ while !from.nil? && from["id"] != upto
108
+ following = from.xpath("./following::*")
109
+ (from = following.shift) && incl_to = from.at(".//*[@id='#{upto}']")
110
+ while !incl_to.nil? && !from.nil? && skip_comment_wrap(from)
111
+ (from = following.shift) && incl_to = from.at(".//*[@id='#{upto}']")
112
+ end
113
+ wrap_comment_cont(from, target) if !from.nil?
109
114
  end
110
- wrap_comment_cont(from, target) if !from.nil?
111
115
  end
112
- end
113
116
 
114
- def move_comment_link_to_from(docxml)
115
- docxml.xpath('//span[@style="MsoCommentReference"][@from]').each do |x|
116
- attrs = comment_attributes(docxml, x) || next
117
- move_comment_link_to_from1(x, attrs[:from])
118
- insert_comment_cont(attrs[:from], x["to"], x["target"])
117
+ def move_comment_link_to_from(docxml)
118
+ docxml.xpath('//span[@style="MsoCommentReference"][@from]').each do |x|
119
+ attrs = comment_attributes(docxml, x) || next
120
+ move_comment_link_to_from1(x, attrs[:from])
121
+ insert_comment_cont(attrs[:from], x["to"], x["target"])
122
+ end
119
123
  end
120
- end
121
124
 
122
- def get_comments_from_text(docxml, link_order)
123
- comments = []
124
- docxml.xpath("//div[@style='mso-element:comment']").each do |c|
125
- next unless c["id"] && !link_order[c["id"]].nil?
126
- comments << { text: c.remove.to_s, id: c["id"] }
125
+ 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"] }
131
+ end
132
+ comments.sort! { |a, b| link_order[a[:id]] <=> link_order[b[:id]] }
133
+ # comments
127
134
  end
128
- comments.sort! { |a, b| link_order[a[:id]] <=> link_order[b[:id]] }
129
- # comments
130
- end
131
135
 
132
- COMMENT_TARGET_XREFS1 =
133
- "//span[@style='mso-special-character:comment']/@target".freeze
136
+ COMMENT_TARGET_XREFS1 =
137
+ "//span[@style='mso-special-character:comment']/@target".freeze
134
138
 
135
- def reorder_comments_by_comment_link(docxml)
136
- link_order = {}
137
- docxml.xpath(COMMENT_TARGET_XREFS1).each_with_index do |target, i|
138
- link_order[target.value] = i
139
+ def reorder_comments_by_comment_link(docxml)
140
+ link_order = {}
141
+ docxml.xpath(COMMENT_TARGET_XREFS1).each_with_index do |target, i|
142
+ link_order[target.value] = i
143
+ end
144
+ comments = get_comments_from_text(docxml, link_order)
145
+ list = docxml.at("//*[@style='mso-element:comment-list']") || return
146
+ list.children = comments.map { |c| c[:text] }.join("\n")
139
147
  end
140
- comments = get_comments_from_text(docxml, link_order)
141
- list = docxml.at("//*[@style='mso-element:comment-list']") || return
142
- list.children = comments.map { |c| c[:text] }.join("\n")
143
148
  end
144
149
  end
145
150
  end
@@ -1,112 +1,114 @@
1
- module IsoDoc::WordFunction
2
- module Footnotes
3
- def bookmarkid
4
- ret = "X"
5
- until !@bookmarks_allocated[ret]
6
- ret = Random.rand(1000000000)
1
+ module IsoDoc
2
+ module WordFunction
3
+ module Footnotes
4
+ def bookmarkid
5
+ ret = "X"
6
+ until !@bookmarks_allocated[ret]
7
+ ret = Random.rand(1000000000)
8
+ end
9
+ @bookmarks_allocated[ret] = true
10
+ sprintf "%09d", ret
7
11
  end
8
- @bookmarks_allocated[ret] = true
9
- sprintf "%09d", ret
10
- end
11
-
12
- def footnotes(div)
13
- return if @footnotes.empty?
14
12
 
15
- @footnotes.each { |fn| div.parent << fn }
16
- end
13
+ def footnotes(div)
14
+ return if @footnotes.empty?
17
15
 
18
- def make_table_footnote_link(out, fnid, fnref)
19
- attrs = { href: "##{fnid}", class: "TableFootnoteRef" }
20
- out.a **attrs do |a|
21
- a << fnref
16
+ @footnotes.each { |fn| div.parent << fn }
22
17
  end
23
- end
24
18
 
25
- def make_table_footnote_target(out, fnid, fnref)
26
- attrs = { id: fnid, class: "TableFootnoteRef" }
27
- out.span do |s|
28
- out.span **attrs do |a|
19
+ def make_table_footnote_link(out, fnid, fnref)
20
+ attrs = { href: "##{fnid}", class: "TableFootnoteRef" }
21
+ out.a **attrs do |a|
29
22
  a << fnref
30
23
  end
31
- insert_tab(s, 1)
32
24
  end
33
- end
34
25
 
35
- def make_table_footnote_text(node, fnid, fnref)
36
- attrs = { id: "ftn#{fnid}" }
37
- noko do |xml|
38
- xml.div **attr_code(attrs) do |div|
39
- make_table_footnote_target(div, fnid, fnref)
40
- node.children.each { |n| parse(n, div) }
26
+ def make_table_footnote_target(out, fnid, fnref)
27
+ attrs = { id: fnid, class: "TableFootnoteRef" }
28
+ out.span do |s|
29
+ out.span **attrs do |a|
30
+ a << fnref
31
+ end
32
+ insert_tab(s, 1)
41
33
  end
42
- end.join("\n")
43
- end
34
+ end
44
35
 
45
- def make_generic_footnote_text(node, fnid)
46
- noko do |xml|
47
- xml.aside **{ id: "ftn#{fnid}" } do |div|
48
- node.children.each { |n| parse(n, div) }
49
- end
50
- end.join("\n")
51
- end
36
+ def make_table_footnote_text(node, fnid, fnref)
37
+ attrs = { id: "ftn#{fnid}" }
38
+ noko do |xml|
39
+ xml.div **attr_code(attrs) do |div|
40
+ make_table_footnote_target(div, fnid, fnref)
41
+ node.children.each { |n| parse(n, div) }
42
+ end
43
+ end.join("\n")
44
+ end
52
45
 
53
- def get_table_ancestor_id(node)
54
- table = node.ancestors("table") || node.ancestors("figure")
55
- return UUIDTools::UUID.random_create.to_s if table.empty?
46
+ def make_generic_footnote_text(node, fnid)
47
+ noko do |xml|
48
+ xml.aside **{ id: "ftn#{fnid}" } do |div|
49
+ node.children.each { |n| parse(n, div) }
50
+ end
51
+ end.join("\n")
52
+ end
56
53
 
57
- table.last["id"]
58
- end
54
+ def get_table_ancestor_id(node)
55
+ table = node.ancestors("table") || node.ancestors("figure")
56
+ return UUIDTools::UUID.random_create.to_s if table.empty?
59
57
 
60
- def table_footnote_parse(node, out)
61
- fn = node["reference"] || UUIDTools::UUID.random_create.to_s
62
- tid = get_table_ancestor_id(node)
63
- make_table_footnote_link(out, tid + fn, fn)
64
- # do not output footnote text if we have already seen it for this table
65
- return if @seen_footnote.include?(tid + fn)
66
-
67
- @in_footnote = true
68
- out.aside { |a| a << make_table_footnote_text(node, tid + fn, fn) }
69
- @in_footnote = false
70
- @seen_footnote << (tid + fn)
71
- end
58
+ table.last["id"]
59
+ end
72
60
 
73
- def seen_footnote_parse(_node, out, footnote)
74
- out.span **{ style: "mso-element:field-begin" }
75
- out << " NOTEREF _Ref#{@fn_bookmarks[footnote]} \\f \\h"
76
- out.span **{ style: "mso-element:field-separator" }
77
- out.span **{ class: "MsoFootnoteReference" } do |s|
78
- s << footnote
61
+ def table_footnote_parse(node, out)
62
+ fn = node["reference"] || UUIDTools::UUID.random_create.to_s
63
+ tid = get_table_ancestor_id(node)
64
+ make_table_footnote_link(out, tid + fn, fn)
65
+ # do not output footnote text if we have already seen it for this table
66
+ return if @seen_footnote.include?(tid + fn)
67
+
68
+ @in_footnote = true
69
+ out.aside { |a| a << make_table_footnote_text(node, tid + fn, fn) }
70
+ @in_footnote = false
71
+ @seen_footnote << (tid + fn)
79
72
  end
80
- out.span **{ style: "mso-element:field-end" }
81
- end
82
73
 
83
- def footnote_parse(node, out)
84
- return table_footnote_parse(node, out) if (@in_table || @in_figure) &&
85
- !node.ancestors.map { |m| m.name }.include?("name")
74
+ def seen_footnote_parse(_node, out, footnote)
75
+ out.span **{ style: "mso-element:field-begin" }
76
+ out << " NOTEREF _Ref#{@fn_bookmarks[footnote]} \\f \\h"
77
+ out.span **{ style: "mso-element:field-separator" }
78
+ out.span **{ class: "MsoFootnoteReference" } do |s|
79
+ s << footnote
80
+ end
81
+ out.span **{ style: "mso-element:field-end" }
82
+ end
83
+
84
+ def footnote_parse(node, out)
85
+ return table_footnote_parse(node, out) if (@in_table || @in_figure) &&
86
+ !node.ancestors.map(&:name).include?("name")
86
87
 
87
- fn = node["reference"] || UUIDTools::UUID.random_create.to_s
88
- return seen_footnote_parse(node, out, fn) if @seen_footnote.include?(fn)
88
+ fn = node["reference"] || UUIDTools::UUID.random_create.to_s
89
+ return seen_footnote_parse(node, out, fn) if @seen_footnote.include?(fn)
89
90
 
90
- @fn_bookmarks[fn] = bookmarkid
91
- out.span **{ style: "mso-bookmark:_Ref#{@fn_bookmarks[fn]}" } do |s|
92
- s.a **{ "class": "FootnoteRef", "epub:type": "footnote",
93
- href: "#ftn#{fn}" } do |a|
94
- a.sup { |sup| sup << fn }
91
+ @fn_bookmarks[fn] = bookmarkid
92
+ out.span **{ style: "mso-bookmark:_Ref#{@fn_bookmarks[fn]}" } do |s|
93
+ s.a **{ class: "FootnoteRef", "epub:type": "footnote",
94
+ href: "#ftn#{fn}" } do |a|
95
+ a.sup { |sup| sup << fn }
96
+ end
95
97
  end
98
+ @in_footnote = true
99
+ @footnotes << make_generic_footnote_text(node, fn)
100
+ @in_footnote = false
101
+ @seen_footnote << fn
96
102
  end
97
- @in_footnote = true
98
- @footnotes << make_generic_footnote_text(node, fn)
99
- @in_footnote = false
100
- @seen_footnote << fn
101
- end
102
103
 
103
- def make_footnote(node, footnote)
104
- return if @seen_footnote.include?(footnote)
104
+ def make_footnote(node, footnote)
105
+ return if @seen_footnote.include?(footnote)
105
106
 
106
- @in_footnote = true
107
- @footnotes << make_generic_footnote_text(node, footnote)
108
- @in_footnote = false
109
- @seen_footnote << footnote
107
+ @in_footnote = true
108
+ @footnotes << make_generic_footnote_text(node, footnote)
109
+ @in_footnote = false
110
+ @seen_footnote << footnote
111
+ end
110
112
  end
111
113
  end
112
114
  end
@@ -1,83 +1,58 @@
1
- module IsoDoc::WordFunction
2
- module Body
3
- def section_break(body)
4
- body.p do |p|
5
- p.br **{ clear: "all", class: "section" }
6
- end
7
- end
8
-
9
- def page_break(out)
10
- out.p do |p|
11
- p.br **{ clear: "all",
12
- style: "mso-special-character:line-break;"\
13
- "page-break-before:always" }
1
+ module IsoDoc
2
+ module WordFunction
3
+ module Body
4
+ def section_break(body)
5
+ body.p do |p|
6
+ p.br **{ clear: "all", class: "section" }
7
+ end
14
8
  end
15
- end
16
9
 
17
- def pagebreak_parse(node, out)
18
- return page_break(out) if node["orientation"].nil?
19
- out.p do |p|
20
- p.br **{clear: "all", class: "section",
21
- orientation: node["orientation"] }
10
+ def page_break(out)
11
+ out.p do |p|
12
+ p.br **{ clear: "all",
13
+ style: "mso-special-character:line-break;"\
14
+ "page-break-before:always" }
15
+ end
22
16
  end
23
- end
24
-
25
- def svg_parse(node, out)
26
- svg = Base64.strict_encode64(node.to_xml)
27
- r = node.replace("<img src='data:image/svg+xml;base64,#{svg}' mimetype='image/svg+xml'/>").first
28
- image_parse(r, out, nil)
29
- end
30
17
 
31
- def imgsrc(node)
32
- ret = svg_to_emf(node) and return ret
33
- return node["src"] unless %r{^data:}.match node["src"]
34
- save_dataimage(node["src"])
35
- end
18
+ def pagebreak_parse(node, out)
19
+ return page_break(out) if node["orientation"].nil?
36
20
 
37
- def image_parse(node, out, caption)
38
- attrs = { src: imgsrc(node),
39
- height: node["height"],
40
- alt: node["alt"],
41
- title: node["title"],
42
- width: node["width"] }
43
- out.img **attr_code(attrs)
44
- image_title_parse(out, caption)
45
- end
21
+ out.p do |p|
22
+ p.br **{ clear: "all", class: "section",
23
+ orientation: node["orientation"] }
24
+ end
25
+ end
46
26
 
47
- def svg_to_emf_filename(uri)
48
- File.join(File.dirname(uri), File.basename(uri, ".*")) + ".emf"
49
- end
27
+ def imgsrc(node)
28
+ return node["src"] unless %r{^data:}.match? node["src"]
50
29
 
51
- def svg_to_emf(node)
52
- return unless node["mimetype"] == "image/svg+xml"
53
- uri = node["src"]
54
- %r{^data:}.match(uri) and uri = save_dataimage(uri)
55
- ret = svg_to_emf_filename(uri)
56
- File.exists?(ret) and return ret
57
- exe = inkscape_installed? or return nil
58
- system %(#{exe} --export-type="emf" #{uri}) and
59
- return ret
60
- nil
61
- end
30
+ save_dataimage(node["src"])
31
+ end
62
32
 
63
- def inkscape_installed?
64
- cmd = "inkscape"
65
- exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
66
- ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
67
- exts.each do |ext|
68
- exe = File.join(path, "#{cmd}#{ext}")
69
- return exe if File.executable?(exe) && !File.directory?(exe)
33
+ def image_parse(node, out, caption)
34
+ if emf = node.at(ns("./emf"))
35
+ node["src"] = emf["src"]
36
+ node["mimetype"] = "image/x-emf"
37
+ node.children.remove
70
38
  end
39
+ attrs = { src: imgsrc(node),
40
+ height: node["height"], alt: node["alt"],
41
+ title: node["title"], width: node["width"] }
42
+ out.img **attr_code(attrs)
43
+ image_title_parse(out, caption)
71
44
  end
72
- nil
73
- end
74
45
 
75
- def xref_parse(node, out)
76
- target = /#/.match(node["target"]) ? node["target"].sub(/#/, ".doc#") :
77
- "##{node["target"]}"
78
- out.a(**{ "href": target }) do |l|
46
+ def xref_parse(node, out)
47
+ target = if /#/.match?(node["target"])
48
+ node["target"].sub(/#/, ".doc#")
49
+ else
50
+ "##{node['target']}"
51
+ end
52
+ out.a(**{ href: target }) do |l|
79
53
  node.children.each { |n| parse(n, l) }
80
54
  end
55
+ end
81
56
  end
82
57
  end
83
58
  end