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); |
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 *) |