sloane 1.1 → 1.3
raw patch · 3 files changed
+73/−32 lines, 3 filesdep +ansi-terminaldep +terminal-sizedep ~HTTPdep ~cmdargs
Dependencies added: ansi-terminal, terminal-size
Dependency ranges changed: HTTP, cmdargs
Files
- README.md +4/−4
- sloane.cabal +3/−2
- sloane.hs +66/−26
README.md view
@@ -1,6 +1,6 @@ ----title: SLOANE(1) Sloane User Manual | Version 1.0-date: October 28, 2013+title: SLOANE(1) Sloane User Manual | Version 1.3+date: March 9, 2014 --- # NAME@@ -30,7 +30,7 @@ : Only print urls of found entries -n --limit=INT-: Limit the number of entries retrieved (default: 5)+: Retrieve at most this many entries (default: 5) -? --help : Display a short help message@@ -115,7 +115,7 @@ # SEE ALSO The sloane source code may be downloaded from-<http://src.akc.is/sloane>.+<https://github.com/akc/sloane>. # AUTHOR
sloane.cabal view
@@ -1,5 +1,5 @@ Name: sloane-Version: 1.1+Version: 1.3 Synopsis: A command line interface to Sloane's On-Line Encyclopedia of Integer Sequences Description: A command line interface to Sloane's On-Line Encyclopedia of Integer Sequences. For usage see <http://github.com/akc/sloane>.@@ -20,4 +20,5 @@ Executable sloane Main-is: sloane.hs- Build-depends: base >= 3 && < 5, cmdargs, HTTP, url >=2, bytestring >=0.9+ Build-depends: base >=3 && <5, cmdargs >=0.9, HTTP >=4000.0.9, url >=2,+ bytestring >=0.9, ansi-terminal >=0.6, terminal-size >=0.2
sloane.hs view
@@ -5,17 +5,20 @@ -- Maintainer : Anders Claesson <anders.claesson@gmail.com> -- License : BSD-3 ---import Prelude hiding (all, putStrLn)-import Data.ByteString.Char8 (putStrLn, pack)+import Prelude hiding (all, putStrLn, putStr)+import Data.ByteString.Char8 (putStrLn, putStr, pack, empty)+import System.Console.ANSI import System.Console.CmdArgs+import System.Console.Terminal.Size (Window(..), size) import Data.Maybe (fromJust) import Control.Monad (unless, guard) import Network.HTTP (simpleHTTP, getRequest, getResponseBody) import Network.URL (importURL, exportURL, add_param) -type OEISEntries = String+type OEISEntries = [String]+type ANumbers = [String] type Query = String-type Key = Char+type Keys = String oeisHost = "http://oeis.org" oeisURL = fromJust . importURL $ oeisHost ++ "/search?fmt=text"@@ -30,35 +33,72 @@ deriving (Data, Typeable) sloane = cmdArgsMode $ Sloane- { keys = "SN" &= typ "KEYS" &= help "Keys of fields to print (default: SN)"- , all = False &= name "a" &= help "Print all fields"- , url = False &= name "u" &= help "Print urls of found entries"- , limit = 5 &= name "n" &= help "Limit the number of entries retrieved (default: 5)"- , terms = def &= argPos 0 &= typ "SEARCH-TERMS"+ { keys = "SN" &= typ "KEYS" &= help "Keys of fields to print (default: SN)"+ , all = False &= name "a" &= help "Print all fields"+ , url = False &= name "u" &= help "Print urls of found entries"+ , limit = 5 &= name "n" &= help "Retrieve at most this many entries (default: 5)"+ , terms = def &= argPos 0 &= typ "SEARCH-TERMS" }- &= versionArg [summary "sloane 1.1"]+ &= versionArg [summary "sloane 1.3"] &= summary "Search Sloane's On-Line Encyclopedia of Integer Sequences" -select :: [Key] -> OEISEntries -> OEISEntries-select ks = unlines . filter (\xs -> null xs || head xs `elem` ks) . lines+select :: Keys -> OEISEntries -> OEISEntries+select ks = filter (\line -> null line || head line `elem` ks) +aNumbers :: OEISEntries -> ANumbers+aNumbers es = [ words ids !! 1 | ids@(_:_) <- select "I" es ]+ urls :: OEISEntries -> String-urls es = unlines $ do- ids <- lines $ select "I" es- guard $ not (null ids)- let aNum = words ids !! 1- return $ oeisHost ++ "/" ++ aNum+urls = unlines . map ((oeisHost ++ "/") ++ ) . aNumbers searchOEIS :: Int -> Query -> IO OEISEntries searchOEIS n s =- trim `fmap` (simpleHTTP (getRequest url) >>= getResponseBody)- where- trim = unlines . map (drop 1) . reverse . drop 2 . reverse . drop 5 . lines- url = exportURL $ oeisURL `add_param` ("n", show n) `add_param` ("q", s)+ trim `fmap` (simpleHTTP (getRequest url) >>= getResponseBody)+ where+ trim = map (drop 1) . reverse . drop 2 . reverse . drop 5 . lines+ url = exportURL $ oeisURL `add_param` ("n", show n) `add_param` ("q", s) +cropSeq :: Int -> String -> String+cropSeq maxLen = reverse . dropWhile (/= ',') . reverse . take maxLen++cropLine :: Int -> String -> String+cropLine maxLen s+ | maxLen >= length s = s+ | otherwise = take (maxLen-2) s ++ ".."++getWidth :: IO Int+getWidth = do+ win <- size+ case win of+ Nothing -> error "Can't get width of terminal"+ Just win -> return $ width win++put = putStr . pack+putLn = putStrLn . pack+newline = putStrLn empty++putEntries :: Int -> OEISEntries -> IO ()+putEntries width = mapM_ $ \line ->+ case words line of+ [] -> newline+ (key:aNum:rest) -> do+ setSGR [ SetColor Foreground Dull Green ]+ put key+ setSGR [ SetColor Foreground Dull Yellow ]+ put $ ' ' : aNum+ setSGR []+ let crop = if key == "S" then cropSeq else cropLine+ put $ ' ' : crop width (unwords rest) ++ "\n"+ main = do- args <- cmdArgsRun sloane- entries <- searchOEIS (limit args) . filter (`notElem` "[]") $ terms args- let pick = if all args then id else select (keys args)- unless (null entries) $- putStrLn . pack $ '\n' : (if url args then urls else pick) entries+ args <- cmdArgsRun sloane+ ncols <- getWidth+ let pick = if all args then id else select (keys args)+ let query = filter (`notElem` "[{}]") $ terms args+ hits <- searchOEIS (limit args) query+ unless (null hits) $ do+ newline+ if url args+ then put (urls hits)+ else putEntries (ncols - 10) (pick hits)+ newline