drawille (empty) → 0.1.0.0
raw patch · 6 files changed
+162/−0 lines, 6 filesdep +AC-Angledep +QuickCheckdep +basesetup-changed
Dependencies added: AC-Angle, QuickCheck, base, containers, hspec
Files
- LICENSE +16/−0
- Setup.hs +2/−0
- drawille.cabal +45/−0
- examples/Senoid.hs +24/−0
- src/System/Drawille.hs +74/−0
- test/Spec.hs +1/−0
+ LICENSE view
@@ -0,0 +1,16 @@+A tiny library to write to the terminal using Braille characters, a port of+Adam Tauber's (asciimoo) work on python drawille to haskell.+Copyright (C) 2014 Pedro Tacla Yamada++This program is free software: you can redistribute it and/or modify+it under the terms of the GNU General Public License as published by+the Free Software Foundation, either version 3 of the License, or+(at your option) any later version.++This program is distributed in the hope that it will be useful,+but WITHOUT ANY WARRANTY; without even the implied warranty of+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+GNU General Public License for more details.++You should have received a copy of the GNU General Public License+along with this program. If not, see <http://www.gnu.org/licenses/>.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ drawille.cabal view
@@ -0,0 +1,45 @@+Name: drawille+Version: 0.1.0.0+Category: System+Author: Pedro Yamada <tacla.yamada@gmail.com>+Maintainer: Pedro Yamada <tacla.yamada@gmail.com>+License: GPL-3+License-File: LICENSE+Synopsis: A port of asciimoo's drawille to haskell+Description: A tiny library for drawing with braille.+Cabal-Version: >= 1.10+Build-Type: Simple++Library+ Default-Language: Haskell2010+ HS-Source-Dirs: src+ GHC-Options: -Wall+ Exposed-Modules: System.Drawille+ Build-Depends: base >=4 && <5+ , containers >=0.5 && <0.6++Executable senoid+ Default-Language: Haskell2010+ HS-Source-Dirs: examples+ , src+ Ghc-Options: -Wall+ Main-Is: Senoid.hs+ Build-Depends: base >=4 && <5+ , containers >=0.5 && <0.6+ , AC-Angle >=1.0 && <1.1++Test-Suite spec+ Type: exitcode-stdio-1.0+ Default-Language: Haskell2010+ Hs-Source-Dirs: src+ , test+ Ghc-Options: -Wall+ Main-Is: Spec.hs+ Build-Depends: base >=4 && <5+ , hspec >=1.11 && <1.12+ , QuickCheck >=2.6 && <2.7+ , containers >=0.5 && <0.6++Source-Repository head+ Type: git+ Location: git://github.com/yamadapc/haskell-drawille
+ examples/Senoid.hs view
@@ -0,0 +1,24 @@+import Data.Angle+import Data.List (union)+import Control.Arrow ((&&&))+import qualified System.Drawille as D++main :: IO ()+main = do+ let s = D.fromList $ take 1800 senoid+ putStr $ D.frame s++ let cs = D.fromList $ union (take 1800 senoid) (take 1800 cosenoid)+ putStr $ D.frame cs++senoid :: Integral a => [(a, a)]+senoid = map ((`div` 10) &&& (floor . (* 10) . rsine . fromIntegral)) [0..]++cosenoid :: Integral a => [(a, a)]+cosenoid = map ((`div` 10) &&& (floor . (* 10) . rcosine . fromIntegral)) [0..]++rsine :: Double -> Double+rsine = sine . radians . Degrees++rcosine :: Double -> Double+rcosine = cosine . radians . Degrees
+ src/System/Drawille.hs view
@@ -0,0 +1,74 @@+module System.Drawille ( empty -- drawing API+ , frame+ , get+ , set+ , unset+ , toggle+ , fromList++ , toPs -- utility functions+ , toPx+ , pxMap+ , pxOff+ ) where++import qualified Data.Map as M (Map, empty, lookup, insertWith, keys)+import Data.Bits ((.|.), (.&.), complement, xor)+import Data.Char (chr)++type Canvas = M.Map (Int, Int) Int++pxMap :: Num a => [[a]]+pxMap = [ [0x01, 0x08]+ , [0x02, 0x10]+ , [0x04, 0x20]+ , [0x40, 0x80]+ ]++pxOff :: Num a => a+pxOff = 0x2800++toPx :: (Int, Int) -> Int+toPx (px, py) = pxMap !! mod py 4 !! mod px 2++toPs :: (Int, Int) -> (Int, Int)+toPs (x, y) = (x `div` 2, y `div` 4)++empty :: Canvas+empty = M.empty++frame :: Canvas -> String+frame c = unlines $ map (row c mX) [minY..maxY]+ where keys = M.keys c+ mX = maximumMinimum $ map fst keys+ (maxY, minY) = maximumMinimum $ map snd keys++row :: Canvas -> (Int, Int) -> Int -> String+row c (maxX, minX) y = map helper vs+ where vs = map (\x -> M.lookup (x, y) c) [minX..maxX]+ helper (Just v) = chr $ v + pxOff+ helper Nothing = ' '++set :: Canvas -> (Int, Int) -> Canvas+set c p = M.insertWith (.|.) (toPs p) (toPx p) c++get :: Canvas -> (Int, Int) -> Bool+get c p = case M.lookup (toPs p) c of+ Just x -> let px = toPx p in x .&. px == px+ Nothing -> False++unset :: Canvas -> (Int, Int) -> Canvas+unset c p = M.insertWith (.&.) (toPs p) ((complement . toPx) p) c++toggle :: Canvas -> (Int, Int) -> Canvas+toggle c p = M.insertWith xor (toPs p) (toPx p) c++fromList :: [(Int, Int)] -> Canvas+fromList = foldr (flip set) empty++maximumMinimum :: Ord a => [a] -> (a, a)+maximumMinimum (x:xs) = foldr maxMin (x, x) xs+maximumMinimum [] = error "Empty list"++maxMin :: Ord a => a -> (a, a) -> (a, a)+maxMin x (b, s) = (max x b, min x s)
+ test/Spec.hs view
@@ -0,0 +1,1 @@+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}