src/Pure/General/pretty.ML
changeset 30667 53fbf7c679b0
parent 30624 e755b8b76365
child 32738 15bb09ca0378
equal deleted inserted replaced
30666:d6248d4508d5 30667:53fbf7c679b0
   102 
   102 
   103 
   103 
   104 (** printing items: compound phrases, strings, and breaks **)
   104 (** printing items: compound phrases, strings, and breaks **)
   105 
   105 
   106 datatype T =
   106 datatype T =
   107   Block of Markup.T * T list * int * int |  (*markup, body, indentation, length*)
   107   Block of (output * output) * T list * int * int |  (*markup output, body, indentation, length*)
   108   String of output * int |                  (*text, length*)
   108   String of output * int |                           (*text, length*)
   109   Break of bool * int;                      (*mandatory flag, width if not taken*)
   109   Break of bool * int;                               (*mandatory flag, width if not taken*)
   110 
   110 
   111 fun length (Block (_, _, _, len)) = len
   111 fun length (Block (_, _, _, len)) = len
   112   | length (String (_, len)) = len
   112   | length (String (_, len)) = len
   113   | length (Break (_, wd)) = wd;
   113   | length (Break (_, wd)) = wd;
   114 
   114 
   122 val fbrk = Break (true, 2);
   122 val fbrk = Break (true, 2);
   123 
   123 
   124 fun breaks prts = Library.separate (brk 1) prts;
   124 fun breaks prts = Library.separate (brk 1) prts;
   125 fun fbreaks prts = Library.separate fbrk prts;
   125 fun fbreaks prts = Library.separate fbrk prts;
   126 
   126 
   127 fun markup_block m (indent, es) =
   127 fun block_markup m (indent, es) =
   128   let
   128   let
   129     fun sum [] k = k
   129     fun sum [] k = k
   130       | sum (e :: es) k = sum es (length e + k);
   130       | sum (e :: es) k = sum es (length e + k);
   131   in Block (m, es, indent, sum es 0) end;
   131   in Block (m, es, indent, sum es 0) end;
   132 
   132 
       
   133 fun markup_block m arg = block_markup (Markup.output m) arg;
       
   134 
   133 val blk = markup_block Markup.none;
   135 val blk = markup_block Markup.none;
   134 fun block prts = blk (2, prts);
   136 fun block prts = blk (2, prts);
   135 val strs = block o breaks o map str;
   137 val strs = block o breaks o map str;
   136 
   138 
   137 fun markup m prts = markup_block m (0, prts);
   139 fun markup m prts = markup_block m (0, prts);
   195 fun setdepth dp = (depth := dp);
   197 fun setdepth dp = (depth := dp);
   196 
   198 
   197 local
   199 local
   198   fun pruning dp (Block (m, bes, indent, wd)) =
   200   fun pruning dp (Block (m, bes, indent, wd)) =
   199         if dp > 0
   201         if dp > 0
   200         then markup_block m (indent, map (pruning (dp - 1)) bes)
   202         then block_markup m (indent, map (pruning (dp - 1)) bes)
   201         else str "..."
   203         else str "..."
   202     | pruning dp e = e
   204     | pruning dp e = e
   203 in
   205 in
   204   fun prune e = if ! depth > 0 then pruning (! depth) e else e;
   206   fun prune e = if ! depth > 0 then pruning (! depth) e else e;
   205 end;
   207 end;
   261   blockin is the indentation of the current block;
   263   blockin is the indentation of the current block;
   262   after is the width of the following context until next break.*)
   264   after is the width of the following context until next break.*)
   263 fun format ([], _, _) text = text
   265 fun format ([], _, _) text = text
   264   | format (e :: es, block as (blockind, blockin), after) (text as {ind, pos, nl, ...}) =
   266   | format (e :: es, block as (blockind, blockin), after) (text as {ind, pos, nl, ...}) =
   265       (case e of
   267       (case e of
   266         Block (markup, bes, indent, wd) =>
   268         Block ((bg, en), bes, indent, wd) =>
   267           let
   269           let
   268             val {emergencypos, ...} = ! margin_info;
   270             val {emergencypos, ...} = ! margin_info;
   269             val pos' = pos + indent;
   271             val pos' = pos + indent;
   270             val pos'' = pos' mod emergencypos;
   272             val pos'' = pos' mod emergencypos;
   271             val block' =
   273             val block' =
   272               if pos' < emergencypos then (ind |> add_indent indent, pos')
   274               if pos' < emergencypos then (ind |> add_indent indent, pos')
   273               else (add_indent pos'' Buffer.empty, pos'');
   275               else (add_indent pos'' Buffer.empty, pos'');
   274             val (bg, en) = Markup.output markup;
       
   275             val btext: text = text
   276             val btext: text = text
   276               |> control bg
   277               |> control bg
   277               |> format (bes, block', breakdist (es, after))
   278               |> format (bes, block', breakdist (es, after))
   278               |> control en;
   279               |> control en;
   279             (*if this block was broken then force the next break*)
   280             (*if this block was broken then force the next break*)
   301 (* special output *)
   302 (* special output *)
   302 
   303 
   303 (*symbolic markup -- no formatting*)
   304 (*symbolic markup -- no formatting*)
   304 fun symbolic prt =
   305 fun symbolic prt =
   305   let
   306   let
   306     fun out (Block (m, [], _, _)) = Buffer.markup m I
   307     fun out (Block ((bg, en), [], _, _)) = Buffer.add bg #> Buffer.add en
   307       | out (Block (m, prts, indent, _)) =
   308       | out (Block ((bg, en), prts, indent, _)) =
   308           Buffer.markup m (Buffer.markup (Markup.block indent) (fold out prts))
   309           Buffer.add bg #> Buffer.markup (Markup.block indent) (fold out prts) #> Buffer.add en
   309       | out (String (s, _)) = Buffer.add s
   310       | out (String (s, _)) = Buffer.add s
   310       | out (Break (false, wd)) = Buffer.markup (Markup.break wd) (Buffer.add (output_spaces wd))
   311       | out (Break (false, wd)) = Buffer.markup (Markup.break wd) (Buffer.add (output_spaces wd))
   311       | out (Break (true, _)) = Buffer.markup Markup.fbreak (Buffer.add (output_spaces 1));
   312       | out (Break (true, _)) = Buffer.markup Markup.fbreak (Buffer.add (output_spaces 1));
   312   in out prt Buffer.empty end;
   313   in out prt Buffer.empty end;
   313 
   314 
   314 (*unformatted output*)
   315 (*unformatted output*)
   315 fun unformatted prt =
   316 fun unformatted prt =
   316   let
   317   let
   317     fun fmt (Block (m, prts, _, _)) = Buffer.markup m (fold fmt prts)
   318     fun fmt (Block ((bg, en), prts, _, _)) = Buffer.add bg #> fold fmt prts #> Buffer.add en
   318       | fmt (String (s, _)) = Buffer.add s
   319       | fmt (String (s, _)) = Buffer.add s
   319       | fmt (Break (false, wd)) = Buffer.add (output_spaces wd)
   320       | fmt (Break (false, wd)) = Buffer.add (output_spaces wd)
   320       | fmt (Break (true, _)) = Buffer.add (output_spaces 1);
   321       | fmt (Break (true, _)) = Buffer.add (output_spaces 1);
   321   in fmt (prune prt) Buffer.empty end;
   322   in fmt (prune prt) Buffer.empty end;
   322 
   323 
   323 
   324 
   324 (* ML toplevel pretty printing *)
   325 (* ML toplevel pretty printing *)
   325 
   326 
   326 fun to_ML (Block (m, prts, ind, _)) = ML_Pretty.Block (Markup.output m, map to_ML prts, ind)
   327 fun to_ML (Block (m, prts, ind, _)) = ML_Pretty.Block (m, map to_ML prts, ind)
   327   | to_ML (String s) = ML_Pretty.String s
   328   | to_ML (String s) = ML_Pretty.String s
   328   | to_ML (Break b) = ML_Pretty.Break b;
   329   | to_ML (Break b) = ML_Pretty.Break b;
   329 
   330 
   330 fun from_ML (ML_Pretty.Block (_, prts, ind)) = blk (ind, map from_ML prts)
   331 fun from_ML (ML_Pretty.Block (m, prts, ind)) = block_markup m (ind, map from_ML prts)
   331   | from_ML (ML_Pretty.String s) = String s
   332   | from_ML (ML_Pretty.String s) = String s
   332   | from_ML (ML_Pretty.Break b) = Break b;
   333   | from_ML (ML_Pretty.Break b) = Break b;
   333 
   334 
   334 
   335 
   335 (* output interfaces *)
   336 (* output interfaces *)