anchor.diff: -%% Copyright (c) 2008-2013 Robert Virding
  +%% Copyright (c) 2008-2014 Robert Virding
   %%
   %% Licensed under the Apache License, Version 2.0 (the "License");
   %% you may not use this file except in compliance with the License.
  
positive.code:     {break,print1(E, D, I, L)}.
  
  blanks(N, Tail) -> string:chars($\s, N, Tail).
  
  %% indent_type(Form) -> N | none.
  %%  Defines special indentation. None means default, N is number of
  
negative.code: %%  Print a map, one key value pair per line.
  
  print1_map(Map, D, I, L) ->
      [$#,$M,$(,print1_map_body(maps:to_list(Map), I+3, D, I+3, L-1),$)].
  
  print1_map_body([], _, _, _, _) -> [];
  print1_map_body([{K,V}|KVs], CurL, D, I, L) ->
      case print1_map_assoc(K, V, CurL, D, I, L) of
          {join,KVcs,KVl} ->
              [KVcs,print1_map_rest(KVs, CurL+KVl, D-1, I, L)];
          {break,KVcs,KVl} ->
              [KVcs,print1_map_rest(KVs, I+KVl, D-1, I, L)];
          {break,KVcs} ->
              %% Force a break after K/V split.
              [KVcs,print1_map_rest(KVs, L, D-1, I, L)]
      end.
  
  print1_map_rest([], _, _, _, _) -> "";
  print1_map_rest(_, _, 0, _, _) -> " ...";
  print1_map_rest([{K,V}|KVs], CurL, D, I, L) ->
      case print1_map_assoc(K, V, CurL+1, D, I, L) of
          {join,KVcs,KVl} ->
              [$\s,KVcs,print1_map_rest(KVs, CurL+KVl+1, D-1, I, L)];
          {break,KVcs,KVl} ->
              [newline(I, KVcs),print1_map_rest(KVs, I+KVl, D-1, I, L)];
          {break,KVcs} ->
              %% Force a break after K/V split.
              [newline(I, KVcs),print1_map_rest(KVs, L, D-1, I, L)]
      end.
  
  print1_map_assoc(K, V, CurL, D, I, L) ->
      Kcs = print1(K, D, 0, 99999),               %Never break the line
      Kl = flatlength(Kcs),
      Vcs = print1(V, D, 0, 99999),               %Never break the line
      Vl = flatlength(Vcs),
      if CurL+Kl+Vl < L-10 ->                     %Both fit together here
              {join,[Kcs,$\s,Vcs],Kl+1+Vl};
         I+Kl+Vl < L-10 ->                        %Both fit on single line
              {break,[Kcs,$\s,Vcs],Kl+1+Vl};
         true ->                                  %On separate lines
              %% Try to reuse flat prints if they fit on one line.
              Ks = if I+Kl < L-10 -> Kcs;
                      true -> print1(K, D, I, L)
                   end,
              Vs = if I+Vl < L-10 -> Vcs;
                      true -> print1(V, D, I, L)
                   end,
              {break,[Ks,newline(I, Vs)]}
      end.
  
  last_length(S) -> last_length(S, 0).
  
  last_length([H|T], L0) when is_list(H) ->
      L1 = last_length(H, L0),                    %Must go left-to-right
      last_length(T, L1);
  last_length([$\n|T], _) ->
      last_length(T, 0);
  last_length([_|T], L) ->
      last_length(T, L+1);
  last_length([], L) -> L.
  