packages feed

hspresent 0.1 → 0.2

raw patch · 3 files changed

+105/−33 lines, 3 filesdep +array

Dependencies added: array

Files

Main.hs view
@@ -1,10 +1,30 @@ import System.Environment import System.Exit import System.IO+import Data.Array.IArray  import Data.ByteString.Char8 (pack) import Graphics.Vty +-- pad left fills the left side with pad chars, pad right fills the right side+-- with pad chars+data Pad = Pad { padLeft     :: String -> String+               , padRight    :: String -> String }++type Frame = [String]++-- an immutable array of frames, one-indexed+type Presentation = Array Int Frame++newPad :: Char -> Int -> Pad+newPad c w = Pad { padLeft     = padl+                 , padRight    = padr }+    where+      pad' t = replicate (w - length t) c+      shorten = take w+      padl t = pad' t ++ shorten t+      padr t = shorten t ++ pad' t+ -- |Split an input list split :: Eq a => [a] -> [[a]] -> [[[a]]] split _ [] = [[]]@@ -12,48 +32,80 @@       | tok == x  = [] : split tok xs       | otherwise = let (x':xs') = split tok xs in (x:x') : xs' --- |Render a string as an Image, and right pad it with some character.-bsLine :: String -> Char -> Int -> Image-bsLine txt fill width = renderBS attr $ pack txt'+-- |Convert a string to an image+toImage :: String -> Image+toImage = renderBS attr . pack++-- |Render a frame. The first pair of Ints is the tuple (screen width, screen+-- height), the second pair of Ints is the two numbers to display in the lower+-- right corner, likely the tuple (slide num, total slides).+renderFrame :: Frame -> (Int, Int) -> (Int, Int) -> Image+renderFrame (title:body) (w, h) (num, tot) = vertcat $ map toImage text     where-      txt' = ' ' : txt ++ (replicate (width - length txt - 2) fill)+      p = newPad ' ' w+      t = padRight p (' ' : title)+      sep = replicate w '-'+      body' = take (min (h - 3) (length body)) body -- maybe shorten body+      bodyLines = [padRight p (' ':b) | b <- body']+      vsep = [padRight p "" | _ <- [1 .. h - length body - 3]]+      foot = padLeft p (show num ++ " / " ++ show tot)+      text = foldl (++) [] [[t, sep], bodyLines, vsep, [foot]] + -- |Take a Vty and a list of frames, and do the presentation; this function -- terminates when q or Ctrl-C are entered.-loop :: Vty -> [[String]] -> IO ()-loop vty frames = loop' 0+loop :: Vty -> Presentation -> IO ()+loop vty pres = loop' minFrame     where-      maxframe = length frames - 1-      formatText w [] = empty-      formatText w (x:xs) = (bsLine x ' ' w) <-> (formatText w xs)+      (minFrame, maxFrame) = bounds pres       loop' n = do-        let (title:text) = frames !! n-        (w, h) <- getSize vty-        let im = bsLine title ' ' w <->-                 bsLine "" '-' w <->-                 formatText w text-        update vty (pic { pCursor = NoCursor,-                          pImage = im })-        ev <- getEvent vty-        case ev of-          EvKey KLeft _  -> loop' (max 0 (n-1))-          EvKey KRight _ -> loop' (min maxframe (n+1))-          EvKey (KASCII 'q') _       -> return ()-          EvKey (KASCII 'c') [MCtrl] -> return ()-          _              -> loop' n+        let frame = pres ! n+        dims <- getSize vty+        blankVty vty+        update vty $ pic { pCursor = NoCursor,+                           pImage  = renderFrame frame dims (n, maxFrame) }+        eventLoop+        where+          eventLoop = do ev <- getEvent vty+                         case ev of+                           EvKey KLeft _  -> loop' (max minFrame (n-1))+                           EvKey KRight _ -> loop' (min maxFrame (n+1))+                           EvKey KHome _  -> loop' minFrame+                           EvKey KEnd _   -> loop' maxFrame+                           EvKey (KASCII 'q') _       -> return ()+                           EvKey (KASCII 'c') [MCtrl] -> return ()+                           EvKey (KASCII 'r') _ -> blankVty vty >> loop' n+                           _              -> eventLoop +-- |Sometimes the vty module gets confused and leaves artifacts from previous+-- slides on the screen. Calling blankvty a few times seems to fix this.+blankVty :: Vty -> IO ()+blankVty vty = do+  (w, h) <- getSize vty+  let lines = [replicate w ' ' | _ <- [1..h]]+  update vty $ pic { pCursor = NoCursor+                   , pImage = vertcat $ map toImage lines}+  refresh vty++-- |Parse an input file, representing a presentation, into a presentation+makeFrames :: String -> Presentation+makeFrames xs = listArray (1, length frames) frames+    where+      frames = concatMap copyFrames $ basicSplit xs+      basicSplit = split "--" . lines+      copyFrames = cf [] . split "."+      cf _ [] = []+      cf h (x:xs) = let p = h ++ x in p : cf (p ++ [[]]) xs+ main = do   args <- getArgs   presentation <- parse args   h <- openFile presentation ReadMode   frames <- fmap makeFrames $ hGetContents h   vty <- mkVty-  refresh vty   loop vty frames   shutdown vty   where-    makeFrames s = split "--" $ lines s-     parse ["-h"] = usage     parse [x]    = return x     parse _      = usage
README.md view
@@ -10,15 +10,23 @@  This will compile hspresent, and install an `hspresent` command line program. +You can download the latest stable release of hspresent on+[Hackage](http://hackage.haskell.org/package/hspresent). The git repository is+online at `git://github.com/eklitzke/hspresent.git`.+ Usage ----- Invoke like `hspresent /path/to/your/presentation`. Left and right arrow keys move between slides, and hitting `q` or `Ctrl-C` quits the presentation.  The file format is really simple right now. Slides are separated by lines-consisting of the characters `--`. That's it. Here's an example presentation:+consisting of the characters `--`. You can put the single character `.` on a+line to demarcate a "split" frame. A split frame really creates a new frame with+the contents of the previous frame copied at the front (this is similar to how+beamer works). That's it. Here's an example presentation:     the title of the first slide     this is+    .     really cool     --     the title of the second slide
hspresent.cabal view
@@ -1,7 +1,7 @@ Author:        Evan Klitzke Maintainer:    Evan Klitzke <evan@eklitzke.org> Name:          hspresent-Version:       0.1+Version:       0.2 Cabal-Version: >= 1.2 License:       BSD3 License-File:  LICENSE@@ -9,14 +9,26 @@ Copyright:     (c) 2009 by Evan Klitzke Synopsis:      A terminal presentation tool Description:-  Give fancy presentations in your terminal.- +  Hspresent is a simple program that lets you give powerpoint-like presentations+  in your terminal (for certain definitions of powerpoint-like). It's extremely+  basic and unintelligent. Don't expect much.+  .+  Invoke like `hspresent /path/to/your/presentation`. Left and right arrow keys+  move between slides, and hitting `q` or `Ctrl-C` quits the presentation.+  .+  The file format is really simple right now. Slides are separated by lines+  consisting of the characters `--`. You can put the single character `.` on a+  line to demarcate a split frame. A split frame really creates a new frame with+  the contents of the previous frame copied at the front (this is similar to how+  beamer works).+ Build-Type: Simple  Executable hspresent   Main-Is: Main.hs  Library-  Build-Depends: base < 5-               , bytestring-               , vty+  Build-Depends:  array+                , base < 5+                , bytestring+                , vty