| author | gibus |
| Mon, 06 Aug 2012 13:42:15 +0200 | |
| changeset 454 | b7a092a52eae |
| parent 365 | a478cb9786fd |
| child 496 | c3df46754007 |
| permissions | -rw-r--r-- |
| 0 | 1 |
# -*- coding: utf-8 -*- |
2 |
from difflib import SequenceMatcher |
|
3 |
#from cm.utils.spannifier import Spannifier |
|
4 |
import sys, operator |
|
5 |
from cm.utils.spannifier import spannify |
|
6 |
from cm.converters.pandoc_converters import pandoc_convert |
|
7 |
import logging |
|
8 |
from cm.utils.spannifier import get_the_soup |
|
9 |
||
10 |
import html5lib |
|
11 |
from html5lib import treebuilders |
|
12 |
||
13 |
def compute_new_comment_positions(old_content, old_format, new_content, new_format, commentList): |
|
14 |
||
| 175 | 15 |
# cf. TextVersion.get_content |
16 |
previousVersionContent = pandoc_convert(old_content, old_format, 'html') |
|
17 |
newVersionContent = pandoc_convert(new_content, new_format, 'html') |
|
18 |
||
| 0 | 19 |
_, previous_char_list, span_starts_previous = spannify(previousVersionContent) |
20 |
_, new_char_list, span_starts_new = spannify(newVersionContent) |
|
21 |
||
22 |
sm = SequenceMatcher(None, previous_char_list, new_char_list) |
|
23 |
||
24 |
opcodes = sm.get_opcodes() |
|
25 |
to_remove_comments_ids = set() |
|
26 |
||
| 103 | 27 |
# limit to real comments (not replies) and those that have scope |
28 |
commentList = [c for c in commentList if not c.is_reply() and not c.is_scope_removed()] |
|
| 0 | 29 |
|
30 |
for comment in commentList: |
|
31 |
try: |
|
32 |
comment.initial_start_offset = span_starts_previous[comment.start_wrapper] + comment.start_offset |
|
33 |
comment.initial_end_offset = span_starts_previous[comment.end_wrapper] + comment.end_offset |
|
34 |
except KeyError: |
|
35 |
logging.error('Key error (wrapper out of bounds of span_starts_previous)') |
|
36 |
continue |
|
37 |
||
38 |
comment.computed_start_offset = comment.initial_start_offset |
|
39 |
comment.computed_end_offset = comment.initial_end_offset |
|
40 |
||
41 |
# comment.computed_start_wrapper = None |
|
42 |
# comment.computed_end_wrapper = None |
|
43 |
||
44 |
comment.valid = True |
|
45 |
for tag, i1, i2, j1, j2 in opcodes: |
|
46 |
#print tag, i1, i2, j1, j2 |
|
47 |
||
48 |
for i in xrange(len(commentList)) : |
|
49 |
if tag != 'equal' : |
|
50 |
comment = commentList[i] |
|
51 |
if not comment.valid: |
|
52 |
continue |
|
53 |
||
54 |
if comment.initial_start_offset >= i2 : |
|
55 |
# if offset |
|
56 |
delta = ((j2 - j1) - (i2 - i1)) |
|
57 |
comment.computed_start_offset += delta |
|
58 |
comment.computed_end_offset += delta |
|
59 |
||
60 |
elif comment.initial_end_offset > i1: |
|
61 |
comment.valid = False |
|
62 |
||
63 |
# id, initial_start, initial_end, computed_start, computed_end, valid = self.computationResults[i] |
|
64 |
||
| 172 | 65 |
for cc in commentList: |
66 |
if cc.valid: |
|
| 0 | 67 |
for id in xrange(len(span_starts_new.keys())): |
68 |
start = span_starts_new.get(id) |
|
69 |
end = span_starts_new.get(id+1, sys.maxint) |
|
70 |
||
71 |
# adjust start |
|
| 172 | 72 |
if cc.computed_start_offset >= start and cc.computed_start_offset < end: |
73 |
cc.start_wrapper = id |
|
74 |
cc.start_offset = cc.computed_start_offset - start |
|
| 0 | 75 |
|
76 |
# adjust end |
|
| 172 | 77 |
if cc.computed_end_offset >= start and cc.computed_end_offset < end: |
78 |
cc.end_wrapper = id |
|
79 |
cc.end_offset = cc.computed_end_offset - start |
|
| 0 | 80 |
|
81 |
# returns to_modify, to_remove |
|
82 |
return [c for c in commentList if c.valid], \ |
|
83 |
[c for c in commentList if not c.valid] |
|
84 |
||
85 |
def add_marker(text, color, start_ids, end_ids, with_markers, with_colors): |
|
86 |
# TODO |
|
87 |
# THESE 3 LINES ARE REALLY JUST FOR TESTING THIS IS COPIED FROM C-TEXT.CSS AND SHOULD BE DONE DIFFERENTLY |
|
88 |
BCKCOLORS = ['#FFF', '#FFF39A', '#FFDB9A', '#FFC39A', '#FFAB9A', '#FF879A', '#FF7B9A', '#FF6272'] |
|
89 |
for i in range(30) : |
|
90 |
BCKCOLORS.append('#FF6272') |
|
91 |
||
92 |
ret = text |
|
93 |
||
94 |
if with_markers: |
|
95 |
end_ids.reverse() |
|
|
360
bfaab8740995
Add abiword as an alternative to open office for conversions
gibus
parents:
308
diff
changeset
|
96 |
ret = "%s%s%s"%(''.join(["[%s>"%start_id for start_id in start_ids]), ret, ''.join(["<%s]"%end_id for end_id in end_ids])) |
| 0 | 97 |
|
98 |
if with_colors and color != 0 : |
|
|
365
a478cb9786fd
For some reasons, abiwords can read background style attribute but not background-color
gibus
parents:
360
diff
changeset
|
99 |
# For some reasons, abiwords can read background style attribute but not background-color |
|
a478cb9786fd
For some reasons, abiwords can read background style attribute but not background-color
gibus
parents:
360
diff
changeset
|
100 |
from cm.cm_settings import USE_ABI |
|
a478cb9786fd
For some reasons, abiwords can read background style attribute but not background-color
gibus
parents:
360
diff
changeset
|
101 |
if USE_ABI: |
|
a478cb9786fd
For some reasons, abiwords can read background style attribute but not background-color
gibus
parents:
360
diff
changeset
|
102 |
ret = "<span style='background:%s;'>%s</span>"%(BCKCOLORS[color], ret) |
|
a478cb9786fd
For some reasons, abiwords can read background style attribute but not background-color
gibus
parents:
360
diff
changeset
|
103 |
else: |
| 0 | 104 |
ret = "<span style='background-color:%s;'>%s</span>"%(BCKCOLORS[color], ret) |
105 |
||
106 |
return ret |
|
107 |
||
| 103 | 108 |
# comments are comments and replies : |
| 0 | 109 |
def insert_comment_markers(htmlcontent, comments, with_markers, with_colors) : |
110 |
||
111 |
html = get_the_soup(htmlcontent) ; |
|
112 |
||
|
58
a480a91d63ca
BUG FIX : pdf export PhA tests, TODO fix special html caracters in comments
reno
parents:
0
diff
changeset
|
113 |
if comments : |
|
a480a91d63ca
BUG FIX : pdf export PhA tests, TODO fix special html caracters in comments
reno
parents:
0
diff
changeset
|
114 |
max_wrapper = max([comment.end_wrapper for comment in comments]) |
|
a480a91d63ca
BUG FIX : pdf export PhA tests, TODO fix special html caracters in comments
reno
parents:
0
diff
changeset
|
115 |
min_wrapper = min([comment.start_wrapper for comment in comments]) |
|
a480a91d63ca
BUG FIX : pdf export PhA tests, TODO fix special html caracters in comments
reno
parents:
0
diff
changeset
|
116 |
|
| 0 | 117 |
datas = {} # { wrapper_id : {'start_color':nb_of_comments_unterminated_at_wrapper_start, 'offsets':{offset: [[ids of wrappers starting at offset], [ids of wrappers ending at offset]]}} |
118 |
# datas['offsets'][someoffset][0] and idem[1] will be ordered the way comments are (should be ('start_wrapper', 'start_offset', 'end_wrapper', 'end_offset') important) |
|
119 |
cpt = 1 # starting numbered comment |
|
120 |
for comment in comments : |
|
121 |
if comment.is_reply() : |
|
122 |
continue ; |
|
123 |
||
124 |
# start |
|
125 |
wrapper_data = datas.get(comment.start_wrapper, {'start_color':0, 'offsets':{}}) |
|
126 |
offset = wrapper_data.get('offsets').get(comment.start_offset, [[],[]]) |
|
127 |
offset[0].append(cpt) |
|
128 |
wrapper_data['offsets'][comment.start_offset] = offset |
|
129 |
datas[comment.start_wrapper] = wrapper_data |
|
130 |
||
131 |
# end |
|
132 |
wrapper_data = datas.get(comment.end_wrapper, {'start_color':0, 'offsets':{}}) |
|
133 |
offset = wrapper_data.get('offsets').get(comment.end_offset, [[],[]]) |
|
134 |
offset[1].append(cpt) |
|
135 |
wrapper_data['offsets'][comment.end_offset] = offset |
|
136 |
datas[comment.end_wrapper] = wrapper_data |
|
137 |
||
138 |
for cc in range(comment.start_wrapper + 1, comment.end_wrapper + 1) : |
|
139 |
wrapper_data = datas.get(cc, {'start_color':0, 'offsets':{}}) |
|
140 |
wrapper_data['start_color'] += 1 |
|
141 |
datas[cc] = wrapper_data |
|
142 |
||
143 |
cpt = cpt + 1 |
|
144 |
||
145 |
# order ee values |
|
146 |
for (wrapper_id, wrapper_data) in datas.items() : |
|
147 |
start_color = wrapper_data['start_color'] |
|
148 |
offsets = sorted(wrapper_data['offsets'].items(), key=operator.itemgetter(0)) |
|
| 290 | 149 |
|
| 308 | 150 |
d = html.find(id = "sv-%d"%wrapper_id) |
151 |
if not d: # comment detached |
|
152 |
continue |
|
153 |
content = d.contents[0] |
|
| 0 | 154 |
|
155 |
spans = "" |
|
156 |
||
157 |
if offsets : |
|
158 |
color = start_color |
|
159 |
||
160 |
start = 0 |
|
161 |
start_ids = [] |
|
162 |
end_ids = [] |
|
163 |
||
164 |
for offset, ids in offsets : |
|
165 |
||
166 |
end_ids = ids[1] |
|
167 |
end = offset |
|
168 |
||
169 |
spans += add_marker(content[start:end], color, start_ids, end_ids, with_markers, with_colors) |
|
170 |
||
171 |
start_ids = ids[0] |
|
172 |
start = end |
|
173 |
||
174 |
color += (len(ids[0]) - len(ids[1])) |
|
175 |
||
176 |
end_ids = [] |
|
177 |
spans += add_marker(content[end:], color,start_ids, end_ids, with_markers, with_colors) |
|
178 |
else : # the whole content is to be colored with start_color |
|
179 |
spans += add_marker(content, start_color, [], [], with_markers, with_colors) |
|
180 |
||
181 |
content.replaceWith(spans) |
|
182 |
||
183 |
return unicode(html) |