From 5107f6e24a6d7d2beb574450f042bbcc0da8423c Mon Sep 17 00:00:00 2001 From: David Moon Date: Tue, 3 Sep 2024 00:23:29 -0400 Subject: [PATCH] color child border based on sort --- src/core/structure/Wald.re | 4 +- src/web/style.css | 3 ++ src/web/view/dec/Meld.re | 86 +++++++++++++++++++++++--------------- 3 files changed, 59 insertions(+), 34 deletions(-) diff --git a/src/core/structure/Wald.re b/src/core/structure/Wald.re index f8542e5c..d4f1e3c0 100644 --- a/src/core/structure/Wald.re +++ b/src/core/structure/Wald.re @@ -37,7 +37,9 @@ let is_grout = (w: t): option(list(Token.Grout.t)) => let extend = tl => map(Chain.extend(tl)); -let sort = w => Token.sort(hd(w)); +let sort = w => + Token.sort(hd(w)) + |> Mtrl.map(~space=Fun.const(), ~grout=Fun.id, ~tile=Fun.id); let fold = (f, g, W(w)) => Chain.fold_left(f, g, w); diff --git a/src/web/style.css b/src/web/style.css index 3435028f..bd7a4f0f 100644 --- a/src/web/style.css +++ b/src/web/style.css @@ -349,6 +349,9 @@ stroke: var(--pat-shadow-color); /* stroke: var(--pat-bg-color); */ } +.child-line.Space { + display: none; +} /*TODO(andrew): clean up text classes*/ diff --git a/src/web/view/dec/Meld.re b/src/web/view/dec/Meld.re index cdb7a885..4ade3c35 100644 --- a/src/web/view/dec/Meld.re +++ b/src/web/view/dec/Meld.re @@ -6,11 +6,14 @@ module Profile = { type t = { indent: Loc.Col.t, range: (Loc.t, Loc.t), - tokens: list(T.Profile.t), + chain: Chain.t(Mtrl.Sorted.t, T.Profile.t), }; + let cells = p => Chain.loops(p.chain); + let tokens = p => Chain.links(p.chain); + let sort = (p: t) => - switch (p.tokens) { + switch (tokens(p)) { | [] => failwith("meld profile with no tokens") | [hd, ..._] => hd.style |> Option.map((style: T.Style.t) => style.sort) }; @@ -25,31 +28,41 @@ module Profile = { let (s_end, states) = Layout.states(~init=state, lyt); let s_l = null_l ? L.State.jump_cell(state, ~over=t_l) : state; let s_r = null_r ? Chain.ft(states) : s_end; - { - indent: state.ind, - range: (s_l.loc, s_r.loc), - tokens: - Chain.combine(states, Meld.to_chain(m)) - |> Chain.mapi_link((i, lk) => (i, lk)) - |> Chain.links - |> List.map(((step, (state: L.State.t, tok))) => { - let null = ( - step == 1 && null_l, - step == Meld.length(m) - 2 && null_r, - ); - T.Profile.mk(~loc=state.loc, ~null, tok); - }), - }; + let chain = + Chain.combine(states, Meld.to_chain(m)) + |> Chain.map_loop(((_, c)) => + switch (Cell.get(c)) { + | None => Mtrl.Space() + | Some(M(_, w, _)) => Wald.sort(w) + } + ) + |> Chain.mapi_link((step, (state: L.State.t, tok)) => { + let null = ( + step == 1 && null_l, + step == Meld.length(m) - 2 && null_r, + ); + T.Profile.mk(~loc=state.loc, ~null, tok); + }); + {indent: state.ind, range: (s_l.loc, s_r.loc), chain}; }; }; -let mk_lines = (~font, prof: Profile.t) => - switch (Profile.sort(prof)) { +let sort_clss = (s: Mtrl.Sorted.t) => + switch (s) { + | Space(_) => ["Space"] + | Grout(s) => ["Grout", Sort.to_str(s)] + | Tile(s) => ["Tile", Sort.to_str(s)] + }; + +let mk_lines = (~font, p: Profile.t) => + switch (Profile.sort(p)) { | None => [] - | Some(s) => + | Some(_) => + let (sorts, toks) = + Chain.mapi((i, c) => (i, c), (i, t) => (i, t), p.chain); let tok_rows = - prof.tokens - |> Base.List.group(~break=(l: T.Profile.t, r: T.Profile.t) => + toks + |> Base.List.group(~break=((_, l: T.Profile.t), (_, r: T.Profile.t)) => l.loc.row != r.loc.row ); let h_trunc = 0.15; @@ -57,14 +70,17 @@ let mk_lines = (~font, prof: Profile.t) => tok_rows |> List.map(Stds.Lists.neighbors) |> List.concat_map( - List.map(((l: T.Profile.t, r: T.Profile.t)) => + List.map((((step, l: T.Profile.t), (_, r: T.Profile.t))) => Util.Svgs.Path.[ m(~x=0, ~y=1) |> cmdfudge(~x=T.concave_adj +. h_trunc), h(~x=r.loc.col - (l.loc.col + l.len)) |> cmdfudge(~x=-. T.concave_adj -. h_trunc), ] |> Util.Svgs.Path.view - |> Util.Nodes.add_classes(["child-line", Sort.to_str(s)]) + |> Util.Nodes.add_classes([ + "child-line", + ...sort_clss(List.assoc(step + 1, sorts)), + ]) |> Stds.Lists.single |> Box.mk(~font, ~loc={...l.loc, col: l.loc.col + l.len}) ), @@ -72,27 +88,31 @@ let mk_lines = (~font, prof: Profile.t) => let v_trunc = 0.05; let v_lines = Stds.Lists.neighbors(tok_rows) - |> List.map(((l: list(T.Profile.t), r: list(T.Profile.t))) => { + |> List.map( + ((l: list((_, T.Profile.t)), r: list((_, T.Profile.t)))) => { assert(l != [] && r != []); - let l_start = List.hd(l).loc; - let r_start = List.hd(r).loc; + let l_start = snd(List.hd(l)).loc; + let r_start = snd(List.hd(r)).loc; // should this line extend to top or bottom (respectively) of row r? let v_delta = - r_start.col == prof.indent ? -. (1. +. 2. *. v_trunc) : 0.; + r_start.col == p.indent ? -. (1. +. 2. *. v_trunc) : 0.; // if the line extends to bottom, adjust to account for concave tip - let h_delta = r_start.col == prof.indent ? 0. : -. T.concave_adj; + let h_delta = r_start.col == p.indent ? 0. : -. T.concave_adj; Util.Svgs.Path.[ m(~x=0, ~y=1) |> cmdfudge(~x=-. T.concave_adj, ~y=v_trunc), V_({dy: Float.of_int(r_start.row - l_start.row) +. v_delta}), - H_({dx: Float.of_int(r_start.col - prof.indent) +. h_delta}), + H_({dx: Float.of_int(r_start.col - p.indent) +. h_delta}), ] |> Util.Svgs.Path.view - |> Util.Nodes.add_classes(["child-line", Sort.to_str(s)]) + |> Util.Nodes.add_classes([ + "child-line", + ...sort_clss(List.assoc(fst(List.hd(r)) - 1, sorts)), + ]) |> Stds.Lists.single |> Box.mk(~font, ~loc=l_start); }); h_lines @ v_lines; }; -let mk = (~font, prof: Profile.t) => - List.map(T.mk(~font), prof.tokens) @ mk_lines(~font, prof); +let mk = (~font, p: Profile.t) => + List.map(T.mk(~font), Profile.tokens(p)) @ mk_lines(~font, p);