@@ -3,7 +3,8 @@ This module introduces our pretty printing monad.
3
3
-}
4
4
module Vatras.Show.Lines where
5
5
6
- open import Data.Bool using (true; false; if_then_else_)
6
+ open import Data.Bool using (true; false; if_then_else_; _∧_)
7
+ open import Data.Char as Char using (Char)
7
8
open import Data.Nat using (ℕ; _*_; _∸_; ⌊_/2⌋; ⌈_/2⌉; _≤ᵇ_)
8
9
open import Data.List as List using (List; _∷_; [_]; concat; splitAt; _∷ʳ_)
9
10
open import Data.Maybe using (nothing; just)
@@ -34,11 +35,26 @@ open Line public
34
35
manipulate : (String → String) → Line → Line
35
36
manipulate f l = record l { content = f (content l) }
36
37
37
- align : ℕ → Line → Line
38
- align width line = manipulate (fromAlignment (alignment line) width) line
38
+ -- Rough approximation for how monospaced fonts are typically rendered.
39
+ -- Only currently used characters are included so this will need to be extended
40
+ -- if more/different symbols/emojis are used.
41
+ charWidth : Char → ℕ
42
+ charWidth c =
43
+ -- All the symbols starting at the Emoticons block.
44
+ if (0x1f300 ≤ᵇ codePoint) ∧ (codePoint ≤ᵇ 0x1fbff)
45
+ then 2
46
+ else 1
47
+ where
48
+ codePoint = Char.toℕ c
49
+
50
+ stringLength : String → ℕ
51
+ stringLength line = List.sum (List.map charWidth (Data.String.toList line))
39
52
40
53
length : Line → ℕ
41
- length line = Data.String.length (content line)
54
+ length line = stringLength (content line)
55
+
56
+ align : ℕ → Line → Line
57
+ align width line = manipulate (fromAlignment (alignment line) (width ∸ (length line ∸ Data.String.length (content line)))) line
42
58
43
59
{-|
44
60
Lines monad.
@@ -126,7 +142,7 @@ infix 1 >_
126
142
infix 1 >∷_
127
143
128
144
phantom : String → String
129
- phantom s = replicate (Data.String.length s) ' '
145
+ phantom s = replicate (stringLength s) ' '
130
146
131
147
mantle : String → String → Lines → Lines
132
148
mantle prefix suffix = map (manipulate (λ s → prefix ++ s ++ suffix))
@@ -188,7 +204,7 @@ boxed width title content =
188
204
tr = '╮'
189
205
br = '╯'
190
206
191
- total-titlebar-len = width ∸ (Data.String.length title) ∸ 4 -- 2x whitespace + 2x corners
207
+ total-titlebar-len = width ∸ (stringLength title) ∸ 4 -- 2x whitespace + 2x corners
192
208
left-titlebar-len = ⌊ total-titlebar-len /2⌋
193
209
right-titlebar-len = ⌈ total-titlebar-len /2⌉
194
210
@@ -198,7 +214,7 @@ boxed width title content =
198
214
199
215
title-spacing = fromChar (if (title == "" ) then h else ' ' )
200
216
header = (replicate left-titlebar-len h) ++ title-spacing ++ title ++ title-spacing ++ (replicate right-titlebar-len h)
201
- footer = replicate (Data.String.length header) h
217
+ footer = replicate (stringLength header) h
202
218
in do
203
219
-- print the header of the box
204
220
> (fromChar tl) ++ header ++ (fromChar tr)
0 commit comments