1 (* COCANWIKI - a wiki written in Objective CAML.
2 * Written by Richard W.M. Jones <rich@merjis.com>.
3 * Copyright (C) 2004 Merjis Ltd.
4 * $Id: cocanwiki_diff.ml,v 1.5 2006/08/01 14:50:47 rich Exp $
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; see the file COPYING. If not, write to
18 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
30 (* Convenience code for generating diffs between versions. See diff.ml
31 * and edit.ml which both use this code.
33 let page_for_diff css sections =
35 (List.map (fun (sectionname, content) ->
36 "HEADING: " ^ sectionname ^ "\n\n" ^
37 content ^ "\n\n") sections)) ^
40 let le_re = Pcre.regexp "\r?\n"
41 let le_subst = Pcre.subst "\n"
43 let diff_cmd old_page new_page =
44 (* Convert line-endings in the input files from \r\n to \n. Diff
45 * can get confused by the \r characters, particularly in side-by-side
46 * mode when asked to expand tabs (-y -t).
48 let f = Pcre.replace ~rex:le_re ~itempl:le_subst in
49 let new_page = f new_page in
50 let old_page = f old_page in
52 let new_filename = output_tempfile new_page in
53 let old_filename = output_tempfile old_page in
55 (* Side-by-side mode was good, but stupidly implemented. It's
58 let diff_sidebyside = false in
61 if not diff_sidebyside then
65 let options = options ^ " -t -b -B" in
67 let cmd = sprintf "diff %s %s %s ||:" options old_filename new_filename in
68 let diff = pget cmd in
70 (* Remove the temporary files. *)
71 unlink new_filename; unlink old_filename;
74 if not diff_sidebyside then
76 _ :: _ :: diff -> diff
80 String.concat "\n" diff
82 let get_version_for_diff dbh version =
83 if version = 0l then ""
87 "select css from pages where id = $version"
89 let css = match css with None -> "" | Some css -> css in
92 "select sectionname, content
93 from contents where pageid = $version
99 | (Some sectionname, content) ->
104 let page = page_for_diff css sections in
109 let get_diff dbh hostid page ?old_version ~version ()=
111 match old_version with
112 | Some version -> version
117 "select id from pages
118 where hostid = $hostid
119 and url_deleted = $page
121 order by 1 desc limit 1"
124 Not_found | ExtList.List.Empty_list | Failure "hd" -> 0l in
126 (* Get the two versions. *)
127 let new_page = get_version_for_diff dbh version in
128 let old_page = get_version_for_diff dbh old_version in
130 (* Compute the diff of the two versions. *)
131 let diff = diff_cmd old_page new_page in