src/Tools/Haskell/Pretty.hs
author wenzelm
Tue, 06 Nov 2018 14:53:56 +0100
changeset 69248 9f21381600e3
child 69280 e1d01b351724
permissions -rw-r--r--
more Haskell operations;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
69248
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
     1
{- generated by Isabelle -}
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
     2
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
     3
{-  Title:      Tools/Haskell/Pretty.hs
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
     4
    Author:     Makarius
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
     5
    LICENSE:    BSD 3-clause (Isabelle)
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
     6
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
     7
Generic pretty printing module.
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
     8
-}
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
     9
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    10
module Isabelle.Pretty (
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    11
  T, symbolic, formatted, unformatted,
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    12
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    13
  str, brk_indent, brk, fbrk, breaks, fbreaks, blk, block, strs, markup, mark, mark_str, marks_str,
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    14
  item, text_fold, keyword1, keyword2, text, paragraph, para, quote, cartouche, separate,
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    15
  commas, enclose, enum, list, str_list, big_list)
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    16
where
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    17
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    18
import Isabelle.Library hiding (quote)
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    19
import qualified Data.List as List
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    20
import qualified Isabelle.Buffer as Buffer
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    21
import qualified Isabelle.Markup as Markup
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    22
import qualified Isabelle.XML as XML
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    23
import qualified Isabelle.YXML as YXML
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    24
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    25
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    26
data T =
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    27
    Block Markup.T Bool Int [T]
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    28
  | Break Int Int
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    29
  | Str String
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    30
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    31
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    32
{- output -}
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    33
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    34
output_spaces n = replicate n ' '
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    35
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    36
symbolic_text "" = []
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    37
symbolic_text s = [XML.Text s]
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    38
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    39
symbolic_markup markup body =
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    40
  if Markup.is_empty markup then body
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    41
  else [XML.Elem markup body]
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    42
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    43
symbolic :: T -> XML.Body
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    44
symbolic (Block markup consistent indent prts) =
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    45
  concatMap symbolic prts
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    46
  |> symbolic_markup block_markup
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    47
  |> symbolic_markup markup
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    48
  where block_markup = if null prts then Markup.empty else Markup.block consistent indent
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    49
symbolic (Break wd ind) = [XML.Elem (Markup.break wd ind) (symbolic_text (output_spaces wd))]
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    50
symbolic (Str s) = symbolic_text s
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    51
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    52
formatted :: T -> String
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    53
formatted = YXML.string_of_body . symbolic
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    54
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    55
unformatted :: T -> String
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    56
unformatted prt = Buffer.empty |> out prt |> Buffer.content
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    57
  where
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    58
    out (Block markup _ _ prts) =
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    59
      let (bg, en) = YXML.output_markup markup
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    60
      in Buffer.add bg #> fold out prts #> Buffer.add en
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    61
    out (Break _ wd) = Buffer.add (output_spaces wd)
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    62
    out (Str s) = Buffer.add s
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    63
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    64
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    65
{- derived operations to create formatting expressions -}
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    66
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    67
force_nat n | n < 0 = 0
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    68
force_nat n = n
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    69
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    70
str :: String -> T
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    71
str = Str
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    72
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    73
brk_indent :: Int -> Int -> T
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    74
brk_indent wd ind = Break (force_nat wd) ind
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    75
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    76
brk :: Int -> T
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    77
brk wd = brk_indent wd 0
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    78
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    79
fbrk :: T
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    80
fbrk = str "\n"
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    81
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    82
breaks, fbreaks :: [T] -> [T]
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    83
breaks = List.intersperse (brk 1)
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    84
fbreaks = List.intersperse fbrk
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    85
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    86
blk :: (Int, [T]) -> T
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    87
blk (indent, es) = Block Markup.empty False (force_nat indent) es
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    88
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    89
block :: [T] -> T
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    90
block prts = blk (2, prts)
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    91
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    92
strs :: [String] -> T
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    93
strs = block . breaks . map str
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    94
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    95
markup :: Markup.T -> [T] -> T
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    96
markup m = Block m False 0
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    97
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    98
mark :: Markup.T -> T -> T
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
    99
mark m prt = if m == Markup.empty then prt else markup m [prt]
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   100
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   101
mark_str :: (Markup.T, String) -> T
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   102
mark_str (m, s) = mark m (str s)
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   103
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   104
marks_str :: ([Markup.T], String) -> T
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   105
marks_str (ms, s) = fold_rev mark ms (str s)
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   106
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   107
item :: [T] -> T
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   108
item = markup Markup.item
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   109
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   110
text_fold :: [T] -> T
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   111
text_fold = markup Markup.text_fold
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   112
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   113
keyword1, keyword2 :: String -> T
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   114
keyword1 name = mark_str (Markup.keyword1, name)
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   115
keyword2 name = mark_str (Markup.keyword2, name)
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   116
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   117
text :: String -> [T]
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   118
text = breaks . map str . words
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   119
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   120
paragraph :: [T] -> T
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   121
paragraph = markup Markup.paragraph
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   122
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   123
para :: String -> T
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   124
para = paragraph . text
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   125
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   126
quote :: T -> T
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   127
quote prt = blk (1, [str "\"", prt, str "\""])
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   128
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   129
cartouche :: T -> T
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   130
cartouche prt = blk (1, [str "\92<open>", prt, str "\92<close>"])
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   131
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   132
separate :: String -> [T] -> [T]
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   133
separate sep = List.intercalate [str sep, brk 1] . map single
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   134
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   135
commas :: [T] -> [T]
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   136
commas = separate ","
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   137
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   138
enclose :: String -> String -> [T] -> T
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   139
enclose lpar rpar prts = block (str lpar : prts ++ [str rpar])
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   140
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   141
enum :: String -> String -> String -> [T] -> T
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   142
enum sep lpar rpar = enclose lpar rpar . separate sep
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   143
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   144
list :: String -> String -> [T] -> T
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   145
list = enum ","
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   146
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   147
str_list :: String -> String -> [String] -> T
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   148
str_list lpar rpar = list lpar rpar . map str
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   149
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   150
big_list :: String -> [T] -> T
9f21381600e3 more Haskell operations;
wenzelm
parents:
diff changeset
   151
big_list name prts = block (fbreaks (str name : prts))