Safe Haskell | Safe-Infered |
---|
The default representation of any type is the string and the show
function, which returns a string for each element
of an instance of the Show
class. But sometimes, it is more intuitive, if a type is represented by a more
three-dimensional layout. For that matter, we not only have a show
function for many types to come, but also a
textFrame
converter, where a TextFrame
is basically defined as a list of strings of equal length.
Similar to the Show
type class, we also define a Display
type class.
- type TextFrame = [String]
- isNonSpaceWhite :: Char -> Bool
- findTextFrameError :: [String] -> Maybe String
- correctTextFrame :: [String] -> TextFrame
- width :: TextFrame -> Int
- height :: TextFrame -> Int
- printTextFrame :: TextFrame -> IO ()
- textFrameBox :: TextFrame -> TextFrame
- textFrameBracket :: TextFrame -> TextFrame
- defaultTextFrame :: Show a => a -> TextFrame
- class Display a where
- type TextFrameTable = [[TextFrame]]
- columnWidthList :: TextFrameTable -> [Int]
- rowHeightList :: TextFrameTable -> [Int]
- correctTextFrameTable :: TextFrameTable -> TextFrameTable
- bottomAlign :: TextFrameTable -> TextFrameTable
- topAlign :: TextFrameTable -> TextFrameTable
- centerAlign :: TextFrameTable -> TextFrameTable
- leftAlign :: TextFrameTable -> TextFrameTable
- rightAlign :: TextFrameTable -> TextFrameTable
- middleAlign :: TextFrameTable -> TextFrameTable
- normalTextFrameTable :: TextFrameTable -> TextFrameTable
- plainMerge :: TextFrameTable -> TextFrame
- gridMerge :: TextFrameTable -> TextFrame
Text frames
A TextFrame is a list of strings. But for a correct TextFrame, there are more constraints that have to hold: 1. The strings must all be of equal length. 2. There must be no white space characters in a string, other than the space character ' '.
isNonSpaceWhite :: Char -> BoolSource
True if the character is any white space character, except the space character itself.
findTextFrameError :: [String] -> Maybe StringSource
A TextFrame is correct iff all its strings are of equal length and (isNonSpaceWhite ch) is false for all characters ch.
correctTextFrame :: [String] -> TextFrameSource
Turns the argument string list into a correct version by adding spaces. But returns an error in case any string contains a character ch with (isNonSpaceWhite ch). IMPROVE the String instance of Display: new line characters should create new lines in the text frame and what about tabs etc? !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
The width of a TextFrame [str1,...,strN] is the maximal length of the strings str1,...,strN. In particular,
(width []) == 0 (width [""]) == 0
The height of a TextFrame [str1,...,strN] is N.
printTextFrame :: TextFrame -> IO ()Source
prints its TextFrame argument.
surrounds the text frame with a solid line
surrounds the text frame with a square bracket
defaultTextFrame :: Show a => a -> TextFrameSource
(defaultTextFrame x) == [show x]
The Display
type class
Display Bool | |
Display Char | |
Display Double | |
Display Float | |
Display Int | |
Display Integer | |
Display String | |
Display () | |
Display IForm | |
(Ord a, Display a) => Display [Valuator a] | |
Display a => Display (PropForm a) | |
Display a => Display (MultiTruthTable a) | |
Display a => Display (TruthTable a) | |
Display a => Display (Valuator a) | |
Display a => Display (LiteralPair a) | |
Display a => Display (MixForm a) | |
Display a => Display (XPCNF a) | |
Display a => Display (XPDNF a) | |
Display a => Display (XForm a) |
textFrame
converts into a TextFrame
.
display
prints the text frame (actually, display = printTextFrame . textFrame
, i.e. to define an instance of Display
,
Actually, when an instance of Display
is defined, only textFrame
needs to be specified.
Text frame tables
type TextFrameTable = [[TextFrame]]Source
A TextFrameTable
is a list of rows, where each cell is a TextFrame
. For example,
[[["aaa","aaa"],["b","b","b"]], [["cccccccc","cccccccc"],["ddddddddd","ddddddddd","ddddddddd"],["eeeee","eeeee","eeeee","eeeee"]], [["ff","ff"],[],["ggg","ggg","ggg","ggg"]]]
or, more intuitively in table layout
"aaa" "b" "aaa" "b" "b" "cccccccc" "ddddddddd" "eeeee" "cccccccc" "ddddddddd" "eeeee" "ddddddddd" "eeeee" "eeeee" "ff" "ggg" "ff" "ggg" "ggg" "ggg"
columnWidthList :: TextFrameTable -> [Int]Source
rowHeightList :: TextFrameTable -> [Int]Source
Column widths and row heights for the previous example text frame table tft
are given by
(columnWidthList tft) == [8,9,5] (rowHeightList tft) == [3,4,4]
A TextFrameTable
is said to be correct, if
(1) each row has the same amount of cells,
(2) there is no column of zero width,
(3) there is no row of zero height.
With correctTextFrameTable
we remove these flaws.
A TextFrameTable
is said to be normal, if it is correct and each of its TextFrame
cells has the width of its according column
and the height of its row.
To convert a text frame table into a normal one, we need to perform two steps (in arbitrary order):
- A row normalization, which makes all text frame cells in one row of equal height. We use three modes to achieve that:
bottomAlign
,topAlign
andcenterAlign
. - A column normalization, which makes all text frame cells in one column of equal width. Again, we have three functions to do that:
leftAlign
,rightAlign
, andmiddleAlign
.
For example, given the correct text frame table tft
, we obtain (we use _
for space characters):
tft = leftAlign tft = middleAlign (leftAlign tft) = "aaa" "b" "" "aaa ____" "b________" "_____" "aaa_____" "b________" "_____" "aaa" "b" "aaa_____" "b________" "aaa_____" "b________" "_____" "b" "b________" "________" "b________" "_____" "cccccccc" "ddddddddd" "eeeee" "cccccccc" "ddddddddd" "eeeee" "________" "ddddddddd" "eeeee" "cccccccc" "ddddddddd" "eeeee" "cccccccc" "ddddddddd" "eeeee" "cccccccc" "ddddddddd" "eeeee" "ddddddddd" "eeeee" "ddddddddd" "eeeee" "cccccccc" "ddddddddd" "eeeee" "eeeee" "eeeee" "________" "_________" "eeeee" "ff" "ggg" "ff______" "_________" "ggg__" "________" "_________" "ggg__" "ff" "ggg" "ff______" "ggg__" "ff______" "_________" "ggg__" "ggg" "ggg__" "ff______" "_________" "ggg__" "ggg" "ggg__" "________" "_________" "ggg__"
The default way to convert any text frame table into a normal one is defined by the normalTextFrameTable
function,
which is defined by
normalTextFrameTable = middleAlign . centerAlign . correctTextFrameTable
There is a plainMerge
and a gridMerge
to turn a normal text frame table into a single text frame. For the example,
tft = plainMerge tft = gridMerge tft = "___aaa__" "____b____" "_____" "___aaa______b_________" "+----------+-----------+-------+" "___aaa__" "____b____" "_____" "___aaa______b_________" "| ___aaa__ | ____b____ | _____ |" "________" "____b____" "_____" "____________b_________" "| ___aaa__ | ____b____ | _____ |" "________dddddddddeeeee" "| ________ | ____b____ | _____ |" "________" "ddddddddd" "eeeee" "ccccccccdddddddddeeeee" "+----------+-----------+-------+" "cccccccc" "ddddddddd" "eeeee" "ccccccccdddddddddeeeee" "| ________ | ddddddddd | eeeee |" "cccccccc" "ddddddddd" "eeeee" "_________________eeeee" "| cccccccc | ddddddddd | eeeee |" "________" "_________" "eeeee" "__________________ggg_" "| cccccccc | ddddddddd | eeeee |" "___ff_____________ggg_" "| ________ | _________ | eeeee |" "________" "_________" "_ggg_" "___ff_____________ggg_" "+----------+-----------+-------+" "___ff___" "_________" "_ggg_" "__________________ggg_" "| ________ | _________ | _ggg_ |" "___ff___" "_________" "_ggg_" "| ___ff___ | _________ | _ggg_ |" "________" "_________" "_ggg_" "| ___ff___ | _________ | _ggg_ |" "| ________ | _________ | _ggg_ |" "+----------+-----------+-------+"