isodoc 1.7.5 → 1.7.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -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