Module: IsoDoc::WordFunction::Comments

Included in:
IsoDoc::WordConvert
Defined in:
lib/isodoc/word_function/comments.rb

Constant Summary collapse

COMMENT_IN_COMMENT_LIST1 =
'//div[@style="mso-element:comment-list"]//' \
'span[@style="MsoCommentReference"]'.freeze
COMMENT_TARGET_XREFS1 =
"//span[@style='mso-special-character:comment']/@target".freeze

Instance Method Summary collapse

Instance Method Details

#comment_attributes(docxml, span) ⇒ Object



124
125
126
127
128
129
130
131
# File 'lib/isodoc/word_function/comments.rb', line 124

def comment_attributes(docxml, span)
  fromlink = docxml.at("//*[@id='#{span['from']}']")
  return(nil) if fromlink.nil?

  tolink = docxml.at("//*[@id='#{span['to']}']") || fromlink
  target = docxml.at("//*[@id='#{span['target']}']")
  { from: fromlink, to: tolink, target: target }
end

#comment_cleanup(docxml) ⇒ Object



73
74
75
76
77
78
# File 'lib/isodoc/word_function/comments.rb', line 73

def comment_cleanup(docxml)
  number_comments(docxml)
  move_comment_link_to_from(docxml)
  reorder_comments_by_comment_link(docxml)
  embed_comment_in_comment_list(docxml)
end

#comment_id_to_number(docxml) ⇒ Object



96
97
98
99
100
101
102
103
# File 'lib/isodoc/word_function/comments.rb', line 96

def comment_id_to_number(docxml)
  ids = docxml.xpath("//span[@style='MsoCommentReference']").map do |x|
    x["target"]
  end
  ids.uniq.each_with_index.with_object({}) do |(id, i), m|
    m[id] = i + 1
  end
end


23
24
25
26
27
# File 'lib/isodoc/word_function/comments.rb', line 23

def comment_link_attrs(fnote, node)
  { style: "MsoCommentReference", target: fnote,
    class: "commentLink", from: node["source"],
    to: node["end"] }
end

#comments(docxml, out) ⇒ Object



4
5
6
7
8
9
10
11
12
# File 'lib/isodoc/word_function/comments.rb', line 4

def comments(docxml, out)
  c = docxml.xpath(ns("//fmt-review-body"))
  c.empty? and return
  out.div style: "mso-element:comment-list" do |div|
    @in_comment = true
    c.each { |fn| parse(fn, div) }
    @in_comment = false
  end
end

#embed_comment_in_comment_list(docxml) ⇒ Object



109
110
111
112
113
114
115
# File 'lib/isodoc/word_function/comments.rb', line 109

def embed_comment_in_comment_list(docxml)
  docxml.xpath(COMMENT_IN_COMMENT_LIST1).each do |x|
    n = x.next_element
    n&.children&.first&.add_previous_sibling(x.remove)
  end
  docxml
end

#fmt_review_body_parse(node, out) ⇒ Object



65
66
67
68
69
70
71
# File 'lib/isodoc/word_function/comments.rb', line 65

def fmt_review_body_parse(node, out)
  out.div style: "mso-element:comment", id: node["id"] do |div|
    div.span style: %{mso-comment-author:"#{node['reviewer']}"}
    make_comment_target(div)
    node.children.each { |n| parse(n, div) }
  end
end

#fmt_review_start_parse(node, out) ⇒ Object



29
30
31
# File 'lib/isodoc/word_function/comments.rb', line 29

def fmt_review_start_parse(node, out)
  make_comment_link(out, node["target"], node)
end

#get_comments_from_text(docxml, link_order) ⇒ Object



168
169
170
171
172
173
174
175
# File 'lib/isodoc/word_function/comments.rb', line 168

def get_comments_from_text(docxml, link_order)
  comments = docxml.xpath("//div[@style='mso-element:comment']")
    .each_with_object([]) do |c, m|
    c["id"] && !link_order[c["id"]].nil? or next
    m << { text: c.remove.to_s, id: c["id"] }
  end
  comments.sort { |a, b| link_order[a[:id]] <=> link_order[b[:id]] }
end

#insert_comment_cont(from, upto, target) ⇒ Object



148
149
150
151
152
153
154
155
156
157
158
# File 'lib/isodoc/word_function/comments.rb', line 148

def insert_comment_cont(from, upto, target)
  # includes_to = from.at(".//*[@id='#{upto}']")
  while !from.nil? && from["id"] != upto
    following = from.xpath("./following::*")
    (from = following.shift) && incl_to = from.at(".//*[@id='#{upto}']")
    while !incl_to.nil? && !from.nil? && skip_comment_wrap(from)
      (from = following.shift) && incl_to = from.at(".//*[@id='#{upto}']")
    end
    wrap_comment_cont(from, target) if !from.nil?
  end
end

TODO: CONSOLIDATE add in from and to links to move the comment into place



35
36
37
38
39
40
41
42
43
44
# File 'lib/isodoc/word_function/comments.rb', line 35

def make_comment_link(out, fnote, node)
  out.span(**comment_link_attrs(fnote, node)) do |s1|
    s1.span lang: "EN-GB", style: "font-size:9.0pt" do |s2|
      s2.a style: "mso-comment-reference:SMC_#{fnote};" \
                      "mso-comment-date:#{node['date'].gsub(/[:-]+/,
                                                            '')}"
      s2.span style: "mso-special-character:comment", target: fnote # do |s|
    end
  end
end

#make_comment_target(out) ⇒ Object



46
47
48
49
50
51
52
# File 'lib/isodoc/word_function/comments.rb', line 46

def make_comment_target(out)
  out.span style: "MsoCommentReference" do |s1|
    s1.span lang: "EN-GB", style: "font-size:9.0pt" do |s2|
      s2.span style: "mso-special-character:comment"
    end
  end
end

#make_comment_text(node, fnote) ⇒ Object

KILL



55
56
57
58
59
60
61
62
63
# File 'lib/isodoc/word_function/comments.rb', line 55

def make_comment_text(node, fnote)
  noko do |xml|
    xml.div style: "mso-element:comment", id: fnote do |div|
      div.span style: %{mso-comment-author:"#{node['reviewer']}"}
      make_comment_target(div)
      node.children.each { |n| parse(n, div) }
    end
  end.join("\n")
end


160
161
162
163
164
165
166
# File 'lib/isodoc/word_function/comments.rb', line 160

def move_comment_link_to_from(docxml)
  docxml.xpath('//span[@style="MsoCommentReference"][@from]').each do |x|
    attrs = comment_attributes(docxml, x) || next
    move_comment_link_to_from1(x, attrs[:from])
    insert_comment_cont(attrs[:from], x["to"], x["target"])
  end
end


117
118
119
120
121
122
# File 'lib/isodoc/word_function/comments.rb', line 117

def move_comment_link_to_from1(tolink, fromlink)
  tolink.remove
  link = tolink.at(".//a")
  fromlink.replace(tolink)
  link.children = fromlink
end

#number_comments(docxml) ⇒ Object



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/isodoc/word_function/comments.rb', line 80

def number_comments(docxml)
  map = comment_id_to_number(docxml)
  docxml.xpath("//span[@style='MsoCommentReference' or " \
  "'mso-special-character:comment']").each do |x|
    x["target"] &&= map[x["target"]]
  end
  docxml.xpath("//div[@style='mso-element:comment']").each do |x|
    x["id"] = map[x["id"]]
  end
  docxml.xpath("//a[@style]").each do |x|
    m = /mso-comment-reference:SMC_([^;]+);/.match(x["style"]) or next
    x["style"] = x["style"].sub(/mso-comment-reference:SMC_#{m[1]}/,
                                "mso-comment-reference:SMC_#{map[m[1]]}")
  end
end


180
181
182
183
184
185
186
187
188
# File 'lib/isodoc/word_function/comments.rb', line 180

def reorder_comments_by_comment_link(docxml)
  link_order = {}
  docxml.xpath(COMMENT_TARGET_XREFS1).each_with_index do |target, i|
    link_order[target.value] = i
  end
  comments = get_comments_from_text(docxml, link_order)
  list = docxml.at("//*[@style='mso-element:comment-list']") || return
  list.children = comments.map { |c| c[:text] }.join("\n")
end

#review_note_parsex(node, out) ⇒ Object

KILL



15
16
17
18
19
20
21
# File 'lib/isodoc/word_function/comments.rb', line 15

def review_note_parsex(node, out)
  fn = @comments.length + 1
  make_comment_link(out, fn, node)
  @in_comment = true
  @comments << make_comment_text(node, fn)
  @in_comment = false
end

#skip_comment_wrap(from) ⇒ Object



144
145
146
# File 'lib/isodoc/word_function/comments.rb', line 144

def skip_comment_wrap(from)
  from["style"] != "mso-special-character:comment"
end

#wrap_comment_cont(from, target) ⇒ Object



133
134
135
136
137
138
139
140
141
142
# File 'lib/isodoc/word_function/comments.rb', line 133

def wrap_comment_cont(from, target)
  if %w(ol ul li div p).include?(from.name)
    from.children.each do |c|
      wrap_comment_cont(c, target)
    end
  else
    s = from.replace("<span style='mso-comment-continuation:#{target}'>")
    s.first.children = from
  end
end