| rev | line source | 
| bsw@2 | 1 slot.put_into("title", _"Diff") | 
| bsw@2 | 2 | 
| bsw@2 | 3 local old_draft_id = param.get("old_draft_id", atom.integer) | 
| bsw@2 | 4 local new_draft_id = param.get("new_draft_id", atom.integer) | 
| bsw@2 | 5 | 
| bsw@10 | 6 if not old_draft_id or not new_draft_id then | 
| bsw@10 | 7   slot.put( _"Please choose two versions of the draft to compare") | 
| bsw@10 | 8   return | 
| bsw@10 | 9 end | 
| bsw@10 | 10 | 
| bsw@10 | 11 if old_draft_id == new_draft_id then | 
| bsw@10 | 12   slot.put( _"Please choose two different versions of the draft to compare") | 
| bsw@10 | 13   return | 
| bsw@10 | 14 end | 
| bsw@10 | 15 | 
| bsw@2 | 16 if old_draft_id > new_draft_id then | 
| bsw@2 | 17   local tmp = old_draft_id | 
| bsw@2 | 18   old_draft_id = new_draft_id | 
| bsw@2 | 19   new_draft_id = tmp | 
| bsw@2 | 20 end | 
| bsw@2 | 21 | 
| bsw@2 | 22 local old_draft = Draft:by_id(old_draft_id) | 
| bsw@2 | 23 local new_draft = Draft:by_id(new_draft_id) | 
| bsw@2 | 24 | 
| bsw@2 | 25 local key = multirand.string(26, "123456789bcdfghjklmnpqrstvwxyz"); | 
| bsw@2 | 26 | 
| bsw@2 | 27 local old_draft_filename = encode.file_path(request.get_app_basepath(), 'tmp', "diff-" .. key .. "-old.tmp") | 
| bsw@2 | 28 local new_draft_filename = encode.file_path(request.get_app_basepath(), 'tmp', "diff-" .. key .. "-new.tmp") | 
| bsw@2 | 29 | 
| bsw@2 | 30 local old_draft_file = assert(io.open(old_draft_filename, "w")) | 
| bsw@2 | 31 old_draft_file:write(old_draft.content) | 
| bsw@2 | 32 old_draft_file:write("\n") | 
| bsw@2 | 33 old_draft_file:close() | 
| bsw@2 | 34 | 
| bsw@2 | 35 local new_draft_file = assert(io.open(new_draft_filename, "w")) | 
| bsw@2 | 36 new_draft_file:write(new_draft.content) | 
| bsw@2 | 37 new_draft_file:write("\n") | 
| bsw@2 | 38 new_draft_file:close() | 
| bsw@2 | 39 | 
| bsw@2 | 40 local output, err, status = os.pfilter(nil, "sh", "-c", "diff -U 100000 '" .. old_draft_filename .. "' '" .. new_draft_filename .. "' | grep -v ^--- | grep -v ^+++ | grep -v ^@") | 
| bsw@2 | 41 | 
| bsw@2 | 42 os.remove(old_draft_filename) | 
| bsw@2 | 43 os.remove(new_draft_filename) | 
| bsw@2 | 44 | 
| bsw@2 | 45 if not status then | 
| bsw@2 | 46   ui.field.text{ value = _"The drafts do not differ" } | 
| bsw@2 | 47 else | 
| bsw@2 | 48   slot.put('<table class="diff">') | 
| bsw@2 | 49   slot.put('<tr><th width="50%">' .. _"Old draft revision" .. '</th><th width="50%">' .. _"New draft revision" .. '</th></tr>') | 
| bsw@2 | 50   local last_state = "unchanged" | 
| bsw@2 | 51   local lines = {} | 
| bsw@2 | 52   local removed_lines = nil | 
| bsw@2 | 53   output = output .. " " | 
| bsw@2 | 54   output = output:gsub("[^\n\r]+", function(line) | 
| bsw@2 | 55     local state = "unchanged" | 
| bsw@2 | 56     local char = line:sub(1,1) | 
| bsw@2 | 57     line = line:sub(2) | 
| bsw@2 | 58     state = "unchanged" | 
| bsw@2 | 59     if char == "-" then | 
| bsw@2 | 60       state = "-" | 
| bsw@2 | 61     elseif char == "+" then | 
| bsw@2 | 62       state = "+" | 
| bsw@2 | 63     end | 
| bsw@2 | 64     if last_state == "unchanged" then | 
| bsw@2 | 65       if state == "unchanged" then | 
| bsw@2 | 66         lines[#lines+1] = line | 
| bsw@2 | 67       elseif (state == "-") or (state == "+") then | 
| bsw@2 | 68         local text = table.concat(lines, "<br />") | 
| bsw@2 | 69         slot.put("<tr><td>", text, "</td><td>", text, "</td></tr>") | 
| bsw@2 | 70         lines = { line } | 
| bsw@2 | 71       end | 
| bsw@2 | 72     elseif last_state == "-" then | 
| bsw@2 | 73       if state == "-" then | 
| bsw@2 | 74         lines[#lines+1] = line | 
| bsw@2 | 75       elseif state == "+" then | 
| bsw@2 | 76         removed_lines = lines | 
| bsw@2 | 77         lines = { line } | 
| bsw@2 | 78       elseif state == "unchanged" then | 
| bsw@2 | 79         local text = table.concat(lines,"<br />") | 
| bsw@2 | 80         slot.put('<tr><td class="removed">', text, "</td><td></td></tr>") | 
| bsw@2 | 81         lines = { line } | 
| bsw@2 | 82       end | 
| bsw@2 | 83     elseif last_state == "+" then | 
| bsw@2 | 84       if state == "+" then | 
| bsw@2 | 85         lines[#lines+1] = line | 
| bsw@2 | 86       elseif (state == "-") or (state == "unchanged") then | 
| bsw@2 | 87         if removed_lines then | 
| bsw@2 | 88           local text = table.concat(lines, "<br />") | 
| bsw@2 | 89           local removed_text = table.concat(removed_lines, "<br />") | 
| bsw@2 | 90           slot.put('<tr><td class="removed">', removed_text, '</td><td class="added">', text, "</td></tr>") | 
| bsw@2 | 91         else | 
| bsw@2 | 92           local text = table.concat(lines, "<br />") | 
| bsw@2 | 93           slot.put('<tr><td></td><td class="added">', text, "</td></tr>") | 
| bsw@2 | 94         end | 
| bsw@2 | 95         removed_lines = nil | 
| bsw@2 | 96         lines = { line } | 
| bsw@2 | 97       end | 
| bsw@2 | 98     end | 
| bsw@2 | 99     last_state = state | 
| bsw@2 | 100   end) | 
| bsw@2 | 101   slot.put("</table>") | 
| bsw@2 | 102 end | 
| bsw@2 | 103 |