Skip to content

Commit 6bf51d4

Browse files
authored
Update 2024-10-01-CollaborativeEditorPatterns.md
1 parent 5d27ba1 commit 6bf51d4

File tree

1 file changed

+73
-75
lines changed

1 file changed

+73
-75
lines changed

_posts/2024-10-01-CollaborativeEditorPatterns.md

Lines changed: 73 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,18 @@ let gl = ref []
4141

4242
let is_space= function ' ' -> true | _ -> false
4343

44+
let rec printlist l =
45+
match l with
46+
| hd ::tl ->
47+
Printf.printf " %d %d %d %d\n" hd.first hd.last hd.next hd.score;
48+
printlist tl
49+
| [] -> ()
50+
4451
let final_state l (start, idx) =
4552

46-
let e = {first = start; last = idx; next = -1; score = -1} in
53+
(* let e = {first = start; last = idx; next = -1; score = -1} in *)
54+
(* l := !l @ [e]; *)
55+
let e = {first = -1; last = -1; next = -1; score = 0} in
4756
l := !l @ [e];
4857
Printf.printf " Final state %d %d\n" start idx;
4958
Printf.printf " Size of list is %d\n" (List.length !l);
@@ -70,7 +79,8 @@ let parabreak l text ideal_width max_width =
7079
-> Printf.printf "No Space at index %d, skipping\n" idx;
7180
(idx + 1,false)
7281
| (false,_)
73-
->(idx + 1,true)) (0,false) text
82+
->
83+
(idx + 1,true)) (0,false) text
7484
in
7585

7686
if !start < idx then
@@ -102,122 +112,93 @@ let effective text l =
102112
}
103113

104114

105-
type _ Effect.t += Plass_break : int -> unit Effect.t
106-
107115
let rec plassbreak indent idx idealwidth maxwidth =
108-
(* Printf.printf "Size of list in plassbreak is %d\n " (List.length !gl); *)
109116

110-
if idx < (List.length !gl) then(
111-
let jdx = idx + 1 in
117+
let jdx = ref( idx + 1 ) in
112118
let lastrecord = List.nth !gl idx in
113-
Printf.printf "let record = List.nth !gl idx in - %d\n" idx;
114119
let llen = ref (lastrecord.last - lastrecord.first) in
115120
let bscore = idealwidth - !llen in
116121
let bscore = ref (bscore * bscore) in
117-
let btail = ref jdx in
118-
let _ =
119-
List.fold_left (fun acc entry ->
120-
121-
if acc < (List.length !gl) then(
122-
match entry with
123-
| {first; last; next; score} ->
122+
let btail = ref !jdx in
123+
let rec loop_while j_dx =
124+
if j_dx < (List.length !gl) then(
125+
Printf.printf "llen: %d, bscore: %d, btail: %d\n" !llen !bscore !btail;
126+
let {first; last; next; score} = List.nth !gl j_dx in
124127
let wwidth = last - first in
125-
if ((!llen + wwidth) >= maxwidth) then(
126-
perform (Plass_break acc);
127-
acc
128-
)else(
128+
if ((!llen + wwidth) < maxwidth) then(
129129

130130
let lscore = ref (idealwidth - (!llen + wwidth)) in
131-
lscore := !lscore * 2;
131+
lscore := !lscore * !lscore;
132132
llen := !llen + wwidth + 1;
133133

134-
if score == -1 then
135-
plassbreak (indent + 1) acc idealwidth maxwidth;
134+
if score = -1 then
135+
begin
136+
plassbreak (indent + 1) j_dx idealwidth maxwidth;
137+
end;
136138

137-
let
138-
record = List.nth !gl acc in
139-
if ((!lscore + score) < !bscore) then(
140-
bscore := !lscore + record.score;
141-
btail := acc;
139+
let score1 = List.nth !gl !jdx in
140+
if ((!lscore + score1.score) < !bscore) then(
141+
bscore := !lscore + score1.score;
142+
btail := !jdx;
142143
);
143-
144-
acc + 1;
145-
)
146-
)else acc
147-
) jdx !gl in
148-
144+
loop_while (j_dx + 1)
145+
)else ()
146+
)else ()
147+
in
148+
loop_while !jdx;
149149
let record = List.nth !gl idx in
150-
Printf.printf "let record = List.nth !gl idx in - %d\n" idx;
151-
record.next <- !btail;
152150
record.score <- !bscore;
151+
record.next <- !btail;
153152
if (record.next + 1) = List.length !gl then(
154153
record.score <- 0;
155154
)
156-
)
157-
158-
let pbreak () =
159-
160-
match_with (fun () -> plassbreak 0 0 10 29)
161-
()
162-
{ effc = (fun (type c) (eff: c Effect.t) ->
163-
match eff with
164-
| Plass_break s -> Some (fun (k1: (c,_) continuation) ->
165-
Printf.printf "Plass Break %d\n" s ;
166-
(* continue k () *)
167-
)
168-
| _ -> None
169-
);
170-
exnc = (function
171-
| e -> raise e
172-
);
173-
retc = fun _ -> failwith "Fatal error"
174-
(* retc = (fun res -> Printf.printf "Computation returned: \n") *)
175-
176-
}
177-
155+
178156
let rec loop_while line text lines idx next acc =
179-
Printf.printf "%s\n" line;
180157
if acc > next || (acc + 1) >= List.length !gl then
158+
(
181159
line
160+
)
182161
else
183162
let {first; last; _} = List.nth lines acc in
184163
if (last - first) <= 0 then
185-
line
186-
else
164+
(
165+
line;
166+
)
167+
else(
187168
let new_line =
188169
line ^ (if acc == idx then "" else " ") ^
189170
String.sub text first (last - first)
190171
in
191172
loop_while new_line text lines idx next (acc + 1)
173+
)
192174

193175

194176
let layout text idealwidth maxwidth =
195177

196178
let rec loop idx lines line =
197-
Printf.printf "loop %s\n" line;
198-
if idx < List.length !gl then
179+
if (idx < (List.length !gl - 1)) then
199180

200181
let entry = List.nth lines idx in
201182
let line = loop_while line text lines idx entry.next idx in
183+
let line =
202184
if (String.length line < maxwidth)
203185
then
204186
(
205-
let line = String.make (maxwidth - String.length line) ' ' in
206-
Printf.printf "%s\n" line;
207-
)
208-
else(
209-
let subline = String.sub line 0 idealwidth in
210-
let subline1 = String.sub line idealwidth (String.length line - idealwidth) in
211-
let line = subline ^ "+" ^ subline1 ^ "|" in
212-
Printf.printf "else %s" line;
213-
loop entry.next !gl line
214-
)
187+
let line = line ^ String.make (maxwidth - String.length line) ' ' in
188+
line
189+
)else line
190+
in
191+
let line = Bytes.of_string line in
192+
let _ = Bytes.set line idealwidth '+' in
193+
let line = Bytes.to_string line ^ "|" in
194+
Printf.printf " %s \n" line;
195+
loop entry.next !gl ""
215196
in
216197
loop 0 !gl ""
217198

218199
(* read the entire file *)
219200
let read_file() =
220-
let contents = In_channel.with_open_text "/Users/anu/Documents/go/wiki.txt" In_channel.input_all in
201+
let contents = In_channel.with_open_text "/Users/anu/Documents/go/testwiki.txt" In_channel.input_all in
221202
contents
222203

223204
let pbreak_main =
@@ -228,15 +209,32 @@ let pbreak_main =
228209
let l1 = effective file_contents l in
229210
gl := !l1;
230211

231-
pbreak();
212+
let _ = plassbreak 0 0 10 29 in
232213
Printf.printf "Global list %d\n" (List.length !gl) ;
214+
printlist !gl;
233215

234216
let _ = layout file_contents 10 20 in
235217

236218
()
237219

238-
(* List.iter( fun s -> Printf.printf "%d %d %d %d\n" s.first s.next s.last s.score ) !l *)
239220

240221
with
241222
| exn -> Printf.printf "Unhandled exception: %s\n" (Printexc.to_string exn)
242223
{% endhighlight OCaml %}
224+
225+
# Validation of the algorithm
226+
227+
The test is the only validation now. The algorithm is not verified based on the original
228+
reference to the algorithm. This OCaml code is ported from C++.
229+
There is a single bug that increases the _score_ and as a consequence breaks the paragraph
230+
at the wrong position. But even otherwise the breaks don't seem to be perfect.
231+
232+
This has to surely improved when used by an editor. That is a task for the future.
233+
234+
The first + |
235+
first know+ |
236+
known use + |
237+
use of + |
238+
of the + |
239+
the terms.+ |
240+
terms. + |

0 commit comments

Comments
 (0)