author | wenzelm |
Thu, 28 Mar 2013 15:36:45 +0100 | |
changeset 51570 | 3633828d80fc |
parent 51569 | 4e084727faae |
child 51574 | 2b58d7b139d6 |
permissions | -rw-r--r-- |
36683 | 1 |
/* Title: Pure/General/pretty.scala |
2 |
Author: Makarius |
|
3 |
||
36687 | 4 |
Generic pretty printing module. |
36683 | 5 |
*/ |
6 |
||
7 |
package isabelle |
|
8 |
||
9 |
||
36820 | 10 |
import java.awt.FontMetrics |
11 |
||
12 |
||
36683 | 13 |
object Pretty |
14 |
{ |
|
48704
85a3de10567d
tuned signature -- make Pretty less dependent on Symbol;
wenzelm
parents:
45666
diff
changeset
|
15 |
/* spaces */ |
85a3de10567d
tuned signature -- make Pretty less dependent on Symbol;
wenzelm
parents:
45666
diff
changeset
|
16 |
|
85a3de10567d
tuned signature -- make Pretty less dependent on Symbol;
wenzelm
parents:
45666
diff
changeset
|
17 |
val space = " " |
85a3de10567d
tuned signature -- make Pretty less dependent on Symbol;
wenzelm
parents:
45666
diff
changeset
|
18 |
|
85a3de10567d
tuned signature -- make Pretty less dependent on Symbol;
wenzelm
parents:
45666
diff
changeset
|
19 |
private val static_spaces = space * 4000 |
85a3de10567d
tuned signature -- make Pretty less dependent on Symbol;
wenzelm
parents:
45666
diff
changeset
|
20 |
|
85a3de10567d
tuned signature -- make Pretty less dependent on Symbol;
wenzelm
parents:
45666
diff
changeset
|
21 |
def spaces(k: Int): String = |
85a3de10567d
tuned signature -- make Pretty less dependent on Symbol;
wenzelm
parents:
45666
diff
changeset
|
22 |
{ |
85a3de10567d
tuned signature -- make Pretty less dependent on Symbol;
wenzelm
parents:
45666
diff
changeset
|
23 |
require(k >= 0) |
85a3de10567d
tuned signature -- make Pretty less dependent on Symbol;
wenzelm
parents:
45666
diff
changeset
|
24 |
if (k < static_spaces.length) static_spaces.substring(0, k) |
85a3de10567d
tuned signature -- make Pretty less dependent on Symbol;
wenzelm
parents:
45666
diff
changeset
|
25 |
else space * k |
85a3de10567d
tuned signature -- make Pretty less dependent on Symbol;
wenzelm
parents:
45666
diff
changeset
|
26 |
} |
85a3de10567d
tuned signature -- make Pretty less dependent on Symbol;
wenzelm
parents:
45666
diff
changeset
|
27 |
|
85a3de10567d
tuned signature -- make Pretty less dependent on Symbol;
wenzelm
parents:
45666
diff
changeset
|
28 |
|
51492
eaa1c4cc1106
more explicit Pretty.Metric, with clear distinction of unit (space width) vs. average char width (for visual adjustments) -- NB: Pretty formatting works via full space characters (despite a981a5c8a505 and 70f7483df9cb);
wenzelm
parents:
51470
diff
changeset
|
29 |
/* text metric -- standardized to width of space */ |
eaa1c4cc1106
more explicit Pretty.Metric, with clear distinction of unit (space width) vs. average char width (for visual adjustments) -- NB: Pretty formatting works via full space characters (despite a981a5c8a505 and 70f7483df9cb);
wenzelm
parents:
51470
diff
changeset
|
30 |
|
eaa1c4cc1106
more explicit Pretty.Metric, with clear distinction of unit (space width) vs. average char width (for visual adjustments) -- NB: Pretty formatting works via full space characters (despite a981a5c8a505 and 70f7483df9cb);
wenzelm
parents:
51470
diff
changeset
|
31 |
abstract class Metric |
eaa1c4cc1106
more explicit Pretty.Metric, with clear distinction of unit (space width) vs. average char width (for visual adjustments) -- NB: Pretty formatting works via full space characters (despite a981a5c8a505 and 70f7483df9cb);
wenzelm
parents:
51470
diff
changeset
|
32 |
{ |
eaa1c4cc1106
more explicit Pretty.Metric, with clear distinction of unit (space width) vs. average char width (for visual adjustments) -- NB: Pretty formatting works via full space characters (despite a981a5c8a505 and 70f7483df9cb);
wenzelm
parents:
51470
diff
changeset
|
33 |
val unit: Double |
eaa1c4cc1106
more explicit Pretty.Metric, with clear distinction of unit (space width) vs. average char width (for visual adjustments) -- NB: Pretty formatting works via full space characters (despite a981a5c8a505 and 70f7483df9cb);
wenzelm
parents:
51470
diff
changeset
|
34 |
def apply(s: String): Double |
eaa1c4cc1106
more explicit Pretty.Metric, with clear distinction of unit (space width) vs. average char width (for visual adjustments) -- NB: Pretty formatting works via full space characters (despite a981a5c8a505 and 70f7483df9cb);
wenzelm
parents:
51470
diff
changeset
|
35 |
} |
eaa1c4cc1106
more explicit Pretty.Metric, with clear distinction of unit (space width) vs. average char width (for visual adjustments) -- NB: Pretty formatting works via full space characters (despite a981a5c8a505 and 70f7483df9cb);
wenzelm
parents:
51470
diff
changeset
|
36 |
|
eaa1c4cc1106
more explicit Pretty.Metric, with clear distinction of unit (space width) vs. average char width (for visual adjustments) -- NB: Pretty formatting works via full space characters (despite a981a5c8a505 and 70f7483df9cb);
wenzelm
parents:
51470
diff
changeset
|
37 |
object Metric_Default extends Metric |
eaa1c4cc1106
more explicit Pretty.Metric, with clear distinction of unit (space width) vs. average char width (for visual adjustments) -- NB: Pretty formatting works via full space characters (despite a981a5c8a505 and 70f7483df9cb);
wenzelm
parents:
51470
diff
changeset
|
38 |
{ |
eaa1c4cc1106
more explicit Pretty.Metric, with clear distinction of unit (space width) vs. average char width (for visual adjustments) -- NB: Pretty formatting works via full space characters (despite a981a5c8a505 and 70f7483df9cb);
wenzelm
parents:
51470
diff
changeset
|
39 |
val unit = 1.0 |
eaa1c4cc1106
more explicit Pretty.Metric, with clear distinction of unit (space width) vs. average char width (for visual adjustments) -- NB: Pretty formatting works via full space characters (despite a981a5c8a505 and 70f7483df9cb);
wenzelm
parents:
51470
diff
changeset
|
40 |
def apply(s: String): Double = s.length.toDouble |
eaa1c4cc1106
more explicit Pretty.Metric, with clear distinction of unit (space width) vs. average char width (for visual adjustments) -- NB: Pretty formatting works via full space characters (despite a981a5c8a505 and 70f7483df9cb);
wenzelm
parents:
51470
diff
changeset
|
41 |
} |
eaa1c4cc1106
more explicit Pretty.Metric, with clear distinction of unit (space width) vs. average char width (for visual adjustments) -- NB: Pretty formatting works via full space characters (despite a981a5c8a505 and 70f7483df9cb);
wenzelm
parents:
51470
diff
changeset
|
42 |
|
eaa1c4cc1106
more explicit Pretty.Metric, with clear distinction of unit (space width) vs. average char width (for visual adjustments) -- NB: Pretty formatting works via full space characters (despite a981a5c8a505 and 70f7483df9cb);
wenzelm
parents:
51470
diff
changeset
|
43 |
|
36687 | 44 |
/* markup trees with physical blocks and breaks */ |
45 |
||
38573 | 46 |
def block(body: XML.Body): XML.Tree = Block(2, body) |
47 |
||
36683 | 48 |
object Block |
49 |
{ |
|
38573 | 50 |
def apply(i: Int, body: XML.Body): XML.Tree = |
50201
c26369c9eda6
Isabelle-specific implementation of quasi-abstract markup elements -- back to module arrangement before d83797ef0d2d;
wenzelm
parents:
49843
diff
changeset
|
51 |
XML.Elem(Markup(Markup.BLOCK, Markup.Indent(i)), body) |
36683 | 52 |
|
38573 | 53 |
def unapply(tree: XML.Tree): Option[(Int, XML.Body)] = |
36683 | 54 |
tree match { |
50201
c26369c9eda6
Isabelle-specific implementation of quasi-abstract markup elements -- back to module arrangement before d83797ef0d2d;
wenzelm
parents:
49843
diff
changeset
|
55 |
case XML.Elem(Markup(Markup.BLOCK, Markup.Indent(i)), body) => |
45666 | 56 |
Some((i, body)) |
36683 | 57 |
case _ => None |
58 |
} |
|
59 |
} |
|
60 |
||
61 |
object Break |
|
62 |
{ |
|
38414
49f1f657adc2
more basic Markup.parse_int/print_int (using signed_string_of_int) (ML);
wenzelm
parents:
38230
diff
changeset
|
63 |
def apply(w: Int): XML.Tree = |
50201
c26369c9eda6
Isabelle-specific implementation of quasi-abstract markup elements -- back to module arrangement before d83797ef0d2d;
wenzelm
parents:
49843
diff
changeset
|
64 |
XML.Elem(Markup(Markup.BREAK, Markup.Width(w)), |
48704
85a3de10567d
tuned signature -- make Pretty less dependent on Symbol;
wenzelm
parents:
45666
diff
changeset
|
65 |
List(XML.Text(spaces(w)))) |
36683 | 66 |
|
67 |
def unapply(tree: XML.Tree): Option[Int] = |
|
68 |
tree match { |
|
50201
c26369c9eda6
Isabelle-specific implementation of quasi-abstract markup elements -- back to module arrangement before d83797ef0d2d;
wenzelm
parents:
49843
diff
changeset
|
69 |
case XML.Elem(Markup(Markup.BREAK, Markup.Width(w)), _) => Some(w) |
36683 | 70 |
case _ => None |
71 |
} |
|
72 |
} |
|
73 |
||
36689
379f5b1e7f91
replaced slightly odd fbreak markup by plain "\n", which also coincides with regular linebreaks produced outside the ML pretty engine;
wenzelm
parents:
36687
diff
changeset
|
74 |
val FBreak = XML.Text("\n") |
36687 | 75 |
|
51570
3633828d80fc
basic support for Pretty.item, which is considered as logical markup and interpreted in Isabelle/Scala, but ignored elsewhere (TTY, latex etc.);
wenzelm
parents:
51569
diff
changeset
|
76 |
def item(body: XML.Body): XML.Tree = |
3633828d80fc
basic support for Pretty.item, which is considered as logical markup and interpreted in Isabelle/Scala, but ignored elsewhere (TTY, latex etc.);
wenzelm
parents:
51569
diff
changeset
|
77 |
Block(2, XML.Text(Symbol.decode("\\<bullet>") + " ") :: body) |
3633828d80fc
basic support for Pretty.item, which is considered as logical markup and interpreted in Isabelle/Scala, but ignored elsewhere (TTY, latex etc.);
wenzelm
parents:
51569
diff
changeset
|
78 |
|
50201
c26369c9eda6
Isabelle-specific implementation of quasi-abstract markup elements -- back to module arrangement before d83797ef0d2d;
wenzelm
parents:
49843
diff
changeset
|
79 |
val Separator = List(XML.elem(Markup.SEPARATOR, List(XML.Text(space))), FBreak) |
49843
afddf4e26fac
further refinement of jEdit line range, avoiding lack of final \n;
wenzelm
parents:
49827
diff
changeset
|
80 |
def separate(ts: List[XML.Tree]): XML.Body = Library.separate(Separator, ts.map(List(_))).flatten |
49473 | 81 |
|
36687 | 82 |
|
51570
3633828d80fc
basic support for Pretty.item, which is considered as logical markup and interpreted in Isabelle/Scala, but ignored elsewhere (TTY, latex etc.);
wenzelm
parents:
51569
diff
changeset
|
83 |
/* standard form */ |
36687 | 84 |
|
51570
3633828d80fc
basic support for Pretty.item, which is considered as logical markup and interpreted in Isabelle/Scala, but ignored elsewhere (TTY, latex etc.);
wenzelm
parents:
51569
diff
changeset
|
85 |
def standard_form(body: XML.Body): XML.Body = |
49468 | 86 |
body flatMap { |
49650
9fad6480300d
support for wrapped XML elements, which allows to preserve full markup tree information in to_XML/from_XML conversion;
wenzelm
parents:
49473
diff
changeset
|
87 |
case XML.Wrapped_Elem(markup, body1, body2) => |
51570
3633828d80fc
basic support for Pretty.item, which is considered as logical markup and interpreted in Isabelle/Scala, but ignored elsewhere (TTY, latex etc.);
wenzelm
parents:
51569
diff
changeset
|
88 |
List(XML.Wrapped_Elem(markup, body1, standard_form(body2))) |
3633828d80fc
basic support for Pretty.item, which is considered as logical markup and interpreted in Isabelle/Scala, but ignored elsewhere (TTY, latex etc.);
wenzelm
parents:
51569
diff
changeset
|
89 |
case XML.Elem(markup, body) => |
3633828d80fc
basic support for Pretty.item, which is considered as logical markup and interpreted in Isabelle/Scala, but ignored elsewhere (TTY, latex etc.);
wenzelm
parents:
51569
diff
changeset
|
90 |
if (markup.name == Markup.ITEM) List(item(standard_form(body))) |
3633828d80fc
basic support for Pretty.item, which is considered as logical markup and interpreted in Isabelle/Scala, but ignored elsewhere (TTY, latex etc.);
wenzelm
parents:
51569
diff
changeset
|
91 |
else List(XML.Elem(markup, standard_form(body))) |
48996 | 92 |
case XML.Text(text) => Library.separate(FBreak, split_lines(text).map(XML.Text)) |
36689
379f5b1e7f91
replaced slightly odd fbreak markup by plain "\n", which also coincides with regular linebreaks produced outside the ML pretty engine;
wenzelm
parents:
36687
diff
changeset
|
93 |
} |
379f5b1e7f91
replaced slightly odd fbreak markup by plain "\n", which also coincides with regular linebreaks produced outside the ML pretty engine;
wenzelm
parents:
36687
diff
changeset
|
94 |
|
51570
3633828d80fc
basic support for Pretty.item, which is considered as logical markup and interpreted in Isabelle/Scala, but ignored elsewhere (TTY, latex etc.);
wenzelm
parents:
51569
diff
changeset
|
95 |
|
3633828d80fc
basic support for Pretty.item, which is considered as logical markup and interpreted in Isabelle/Scala, but ignored elsewhere (TTY, latex etc.);
wenzelm
parents:
51569
diff
changeset
|
96 |
/* formatted output */ |
3633828d80fc
basic support for Pretty.item, which is considered as logical markup and interpreted in Isabelle/Scala, but ignored elsewhere (TTY, latex etc.);
wenzelm
parents:
51569
diff
changeset
|
97 |
|
51493
59d8a1031c00
allow fractional pretty margin -- avoid premature rounding;
wenzelm
parents:
51492
diff
changeset
|
98 |
private val margin_default = 76.0 |
36820 | 99 |
|
51493
59d8a1031c00
allow fractional pretty margin -- avoid premature rounding;
wenzelm
parents:
51492
diff
changeset
|
100 |
def formatted(input: XML.Body, margin: Double = margin_default, |
51492
eaa1c4cc1106
more explicit Pretty.Metric, with clear distinction of unit (space width) vs. average char width (for visual adjustments) -- NB: Pretty formatting works via full space characters (despite a981a5c8a505 and 70f7483df9cb);
wenzelm
parents:
51470
diff
changeset
|
101 |
metric: Metric = Metric_Default): XML.Body = |
36687 | 102 |
{ |
51568 | 103 |
sealed case class Text(tx: XML.Body = Nil, pos: Double = 0.0, nl: Int = 0) |
51470
a981a5c8a505
proper metric for blanks -- NB: 70f7483df9cb discontinues coincidence of char_width with space width;
wenzelm
parents:
51469
diff
changeset
|
104 |
{ |
a981a5c8a505
proper metric for blanks -- NB: 70f7483df9cb discontinues coincidence of char_width with space width;
wenzelm
parents:
51469
diff
changeset
|
105 |
def newline: Text = copy(tx = FBreak :: tx, pos = 0.0, nl = nl + 1) |
51492
eaa1c4cc1106
more explicit Pretty.Metric, with clear distinction of unit (space width) vs. average char width (for visual adjustments) -- NB: Pretty formatting works via full space characters (despite a981a5c8a505 and 70f7483df9cb);
wenzelm
parents:
51470
diff
changeset
|
106 |
def string(s: String): Text = copy(tx = XML.Text(s) :: tx, pos = pos + metric(s)) |
eaa1c4cc1106
more explicit Pretty.Metric, with clear distinction of unit (space width) vs. average char width (for visual adjustments) -- NB: Pretty formatting works via full space characters (despite a981a5c8a505 and 70f7483df9cb);
wenzelm
parents:
51470
diff
changeset
|
107 |
def blanks(wd: Int): Text = string(spaces(wd)) |
51470
a981a5c8a505
proper metric for blanks -- NB: 70f7483df9cb discontinues coincidence of char_width with space width;
wenzelm
parents:
51469
diff
changeset
|
108 |
def content: XML.Body = tx.reverse |
a981a5c8a505
proper metric for blanks -- NB: 70f7483df9cb discontinues coincidence of char_width with space width;
wenzelm
parents:
51469
diff
changeset
|
109 |
} |
a981a5c8a505
proper metric for blanks -- NB: 70f7483df9cb discontinues coincidence of char_width with space width;
wenzelm
parents:
51469
diff
changeset
|
110 |
|
36687 | 111 |
val breakgain = margin / 20 |
51569
4e084727faae
maintain integer indentation during formatting -- it needs to be implemented by repeated spaces eventually;
wenzelm
parents:
51568
diff
changeset
|
112 |
val emergencypos = (margin / 2).round.toInt |
36687 | 113 |
|
36817
ed97e877ff2d
more precise pretty printing based on actual font metrics;
wenzelm
parents:
36763
diff
changeset
|
114 |
def content_length(tree: XML.Tree): Double = |
49651 | 115 |
XML.traverse_text(List(tree))(0.0)(_ + metric(_)) |
36817
ed97e877ff2d
more precise pretty printing based on actual font metrics;
wenzelm
parents:
36763
diff
changeset
|
116 |
|
38573 | 117 |
def breakdist(trees: XML.Body, after: Double): Double = |
36817
ed97e877ff2d
more precise pretty printing based on actual font metrics;
wenzelm
parents:
36763
diff
changeset
|
118 |
trees match { |
ed97e877ff2d
more precise pretty printing based on actual font metrics;
wenzelm
parents:
36763
diff
changeset
|
119 |
case Break(_) :: _ => 0.0 |
ed97e877ff2d
more precise pretty printing based on actual font metrics;
wenzelm
parents:
36763
diff
changeset
|
120 |
case FBreak :: _ => 0.0 |
36818 | 121 |
case t :: ts => content_length(t) + breakdist(ts, after) |
36817
ed97e877ff2d
more precise pretty printing based on actual font metrics;
wenzelm
parents:
36763
diff
changeset
|
122 |
case Nil => after |
ed97e877ff2d
more precise pretty printing based on actual font metrics;
wenzelm
parents:
36763
diff
changeset
|
123 |
} |
ed97e877ff2d
more precise pretty printing based on actual font metrics;
wenzelm
parents:
36763
diff
changeset
|
124 |
|
38573 | 125 |
def forcenext(trees: XML.Body): XML.Body = |
36817
ed97e877ff2d
more precise pretty printing based on actual font metrics;
wenzelm
parents:
36763
diff
changeset
|
126 |
trees match { |
ed97e877ff2d
more precise pretty printing based on actual font metrics;
wenzelm
parents:
36763
diff
changeset
|
127 |
case Nil => Nil |
ed97e877ff2d
more precise pretty printing based on actual font metrics;
wenzelm
parents:
36763
diff
changeset
|
128 |
case FBreak :: _ => trees |
ed97e877ff2d
more precise pretty printing based on actual font metrics;
wenzelm
parents:
36763
diff
changeset
|
129 |
case Break(_) :: ts => FBreak :: ts |
ed97e877ff2d
more precise pretty printing based on actual font metrics;
wenzelm
parents:
36763
diff
changeset
|
130 |
case t :: ts => t :: forcenext(ts) |
ed97e877ff2d
more precise pretty printing based on actual font metrics;
wenzelm
parents:
36763
diff
changeset
|
131 |
} |
ed97e877ff2d
more precise pretty printing based on actual font metrics;
wenzelm
parents:
36763
diff
changeset
|
132 |
|
51569
4e084727faae
maintain integer indentation during formatting -- it needs to be implemented by repeated spaces eventually;
wenzelm
parents:
51568
diff
changeset
|
133 |
def format(trees: XML.Body, blockin: Int, after: Double, text: Text): Text = |
36687 | 134 |
trees match { |
135 |
case Nil => text |
|
136 |
||
137 |
case Block(indent, body) :: ts => |
|
51569
4e084727faae
maintain integer indentation during formatting -- it needs to be implemented by repeated spaces eventually;
wenzelm
parents:
51568
diff
changeset
|
138 |
val pos1 = (text.pos + indent).ceil.toInt |
36687 | 139 |
val pos2 = pos1 % emergencypos |
140 |
val blockin1 = |
|
141 |
if (pos1 < emergencypos) pos1 |
|
142 |
else pos2 |
|
143 |
val btext = format(body, blockin1, breakdist(ts, after), text) |
|
144 |
val ts1 = if (text.nl < btext.nl) forcenext(ts) else ts |
|
145 |
format(ts1, blockin, after, btext) |
|
146 |
||
147 |
case Break(wd) :: ts => |
|
51568 | 148 |
if (text.pos + wd <= ((margin - breakdist(ts, after)) max (blockin + breakgain))) |
36687 | 149 |
format(ts, blockin, after, text.blanks(wd)) |
51569
4e084727faae
maintain integer indentation during formatting -- it needs to be implemented by repeated spaces eventually;
wenzelm
parents:
51568
diff
changeset
|
150 |
else format(ts, blockin, after, text.newline.blanks(blockin)) |
4e084727faae
maintain integer indentation during formatting -- it needs to be implemented by repeated spaces eventually;
wenzelm
parents:
51568
diff
changeset
|
151 |
case FBreak :: ts => format(ts, blockin, after, text.newline.blanks(blockin)) |
36687 | 152 |
|
49650
9fad6480300d
support for wrapped XML elements, which allows to preserve full markup tree information in to_XML/from_XML conversion;
wenzelm
parents:
49473
diff
changeset
|
153 |
case XML.Wrapped_Elem(markup, body1, body2) :: ts => |
9fad6480300d
support for wrapped XML elements, which allows to preserve full markup tree information in to_XML/from_XML conversion;
wenzelm
parents:
49473
diff
changeset
|
154 |
val btext = format(body2, blockin, breakdist(ts, after), text.copy(tx = Nil)) |
9fad6480300d
support for wrapped XML elements, which allows to preserve full markup tree information in to_XML/from_XML conversion;
wenzelm
parents:
49473
diff
changeset
|
155 |
val ts1 = if (text.nl < btext.nl) forcenext(ts) else ts |
9fad6480300d
support for wrapped XML elements, which allows to preserve full markup tree information in to_XML/from_XML conversion;
wenzelm
parents:
49473
diff
changeset
|
156 |
val btext1 = btext.copy(tx = XML.Wrapped_Elem(markup, body1, btext.content) :: text.tx) |
9fad6480300d
support for wrapped XML elements, which allows to preserve full markup tree information in to_XML/from_XML conversion;
wenzelm
parents:
49473
diff
changeset
|
157 |
format(ts1, blockin, after, btext1) |
9fad6480300d
support for wrapped XML elements, which allows to preserve full markup tree information in to_XML/from_XML conversion;
wenzelm
parents:
49473
diff
changeset
|
158 |
|
38230
ed147003de4b
simplified type XML.Tree: embed Markup directly, avoid slightly odd triple;
wenzelm
parents:
37374
diff
changeset
|
159 |
case XML.Elem(markup, body) :: ts => |
36734
d9b10c173330
Pretty.formatted operates directly on XML trees, treating XML.Elem like a pro-forma block of indentation 0, like the ML version;
wenzelm
parents:
36689
diff
changeset
|
160 |
val btext = format(body, blockin, breakdist(ts, after), text.copy(tx = Nil)) |
d9b10c173330
Pretty.formatted operates directly on XML trees, treating XML.Elem like a pro-forma block of indentation 0, like the ML version;
wenzelm
parents:
36689
diff
changeset
|
161 |
val ts1 = if (text.nl < btext.nl) forcenext(ts) else ts |
38230
ed147003de4b
simplified type XML.Tree: embed Markup directly, avoid slightly odd triple;
wenzelm
parents:
37374
diff
changeset
|
162 |
val btext1 = btext.copy(tx = XML.Elem(markup, btext.content) :: text.tx) |
36734
d9b10c173330
Pretty.formatted operates directly on XML trees, treating XML.Elem like a pro-forma block of indentation 0, like the ML version;
wenzelm
parents:
36689
diff
changeset
|
163 |
format(ts1, blockin, after, btext1) |
49650
9fad6480300d
support for wrapped XML elements, which allows to preserve full markup tree information in to_XML/from_XML conversion;
wenzelm
parents:
49473
diff
changeset
|
164 |
|
51492
eaa1c4cc1106
more explicit Pretty.Metric, with clear distinction of unit (space width) vs. average char width (for visual adjustments) -- NB: Pretty formatting works via full space characters (despite a981a5c8a505 and 70f7483df9cb);
wenzelm
parents:
51470
diff
changeset
|
165 |
case XML.Text(s) :: ts => format(ts, blockin, after, text.string(s)) |
36687 | 166 |
} |
49650
9fad6480300d
support for wrapped XML elements, which allows to preserve full markup tree information in to_XML/from_XML conversion;
wenzelm
parents:
49473
diff
changeset
|
167 |
|
51570
3633828d80fc
basic support for Pretty.item, which is considered as logical markup and interpreted in Isabelle/Scala, but ignored elsewhere (TTY, latex etc.);
wenzelm
parents:
51569
diff
changeset
|
168 |
format(standard_form(input), 0, 0.0, Text()).content |
36687 | 169 |
} |
36734
d9b10c173330
Pretty.formatted operates directly on XML trees, treating XML.Elem like a pro-forma block of indentation 0, like the ML version;
wenzelm
parents:
36689
diff
changeset
|
170 |
|
51493
59d8a1031c00
allow fractional pretty margin -- avoid premature rounding;
wenzelm
parents:
51492
diff
changeset
|
171 |
def string_of(input: XML.Body, margin: Double = margin_default, |
51492
eaa1c4cc1106
more explicit Pretty.Metric, with clear distinction of unit (space width) vs. average char width (for visual adjustments) -- NB: Pretty formatting works via full space characters (despite a981a5c8a505 and 70f7483df9cb);
wenzelm
parents:
51470
diff
changeset
|
172 |
metric: Metric = Metric_Default): String = |
49416
1053a564dd25
some actual rich text markup via XML.content_markup;
wenzelm
parents:
49414
diff
changeset
|
173 |
XML.content(formatted(input, margin, metric)) |
36736 | 174 |
|
175 |
||
176 |
/* unformatted output */ |
|
177 |
||
38573 | 178 |
def unformatted(input: XML.Body): XML.Body = |
36736 | 179 |
{ |
38573 | 180 |
def fmt(tree: XML.Tree): XML.Body = |
36736 | 181 |
tree match { |
182 |
case Block(_, body) => body.flatMap(fmt) |
|
48704
85a3de10567d
tuned signature -- make Pretty less dependent on Symbol;
wenzelm
parents:
45666
diff
changeset
|
183 |
case Break(wd) => List(XML.Text(spaces(wd))) |
85a3de10567d
tuned signature -- make Pretty less dependent on Symbol;
wenzelm
parents:
45666
diff
changeset
|
184 |
case FBreak => List(XML.Text(space)) |
49650
9fad6480300d
support for wrapped XML elements, which allows to preserve full markup tree information in to_XML/from_XML conversion;
wenzelm
parents:
49473
diff
changeset
|
185 |
case XML.Wrapped_Elem(markup, body1, body2) => |
9fad6480300d
support for wrapped XML elements, which allows to preserve full markup tree information in to_XML/from_XML conversion;
wenzelm
parents:
49473
diff
changeset
|
186 |
List(XML.Wrapped_Elem(markup, body1, body2.flatMap(fmt))) |
38230
ed147003de4b
simplified type XML.Tree: embed Markup directly, avoid slightly odd triple;
wenzelm
parents:
37374
diff
changeset
|
187 |
case XML.Elem(markup, body) => List(XML.Elem(markup, body.flatMap(fmt))) |
36736 | 188 |
case XML.Text(_) => List(tree) |
189 |
} |
|
51570
3633828d80fc
basic support for Pretty.item, which is considered as logical markup and interpreted in Isabelle/Scala, but ignored elsewhere (TTY, latex etc.);
wenzelm
parents:
51569
diff
changeset
|
190 |
standard_form(input).flatMap(fmt) |
36736 | 191 |
} |
192 |
||
49416
1053a564dd25
some actual rich text markup via XML.content_markup;
wenzelm
parents:
49414
diff
changeset
|
193 |
def str_of(input: XML.Body): String = XML.content(unformatted(input)) |
36683 | 194 |
} |