sloane 1.7.1 → 1.8
raw patch · 5 files changed
+122/−95 lines, 5 filesdep +optparse-applicativedep −cmdargs
Dependencies added: optparse-applicative
Dependencies removed: cmdargs
Files
- CHANGELOG.md +5/−0
- README.md +19/−17
- sloane.1 +26/−17
- sloane.cabal +2/−2
- sloane.hs +70/−59
CHANGELOG.md view
@@ -1,5 +1,10 @@ # Changelog +## sloane 1.8++Use optparse-applicative instead of cmdargs for command line parsing.+Deprecate '-u', '-?', '-V', '--limit', and '--keys'.+ ## sloane 1.7.1 - April 30, 2014 * Clean up the README / man page.
README.md view
@@ -1,6 +1,6 @@ ----title: SLOANE(1) Sloane User Manual | Version 1.7.1-date: April 30, 2014+title: SLOANE(1) Sloane User Manual | Version 1.8+date: May 27, 2014 --- # NAME@@ -10,7 +10,9 @@ # SYNOPSIS -sloane [*options*] *search-terms*+sloane [-a | --all | -k *keys* | --url] [-n *entries*] *search-terms* ... +sloane (--update | --version | --help) +sloane # DESCRIPTION @@ -39,32 +41,32 @@ sloane <FILE | xargs -L1 --verbose sloane -Sloane crops long lines to fit the widths of the terminal. If this is-unwanted, pipe the output through cat.+Sloane normally crops long lines to fit the widths of the terminal. If+this is unwanted, pipe the output through cat. # OPTIONS --a --all+-a, --all : Print all fields --k --keys=KEYS+-k *keys* : Keys of fields to print (default: SN) --n --limit=INT+--url+: Print URLs of found entries (but nothing else)++-n *entries* : Fetch at most this many entries (default: 5) --update : Update the local sequence cache --u --url-: Print URLs of found entries (but nothing else)+--version+: Print version information --? --help+--help : Display a short help message --V --version-: Print version information- # EXAMPLES The most common search is for entries matching a sequence of consecutive terms:@@ -81,16 +83,16 @@ option. For instance, the following search shows the sequence, name, comments, and formula fields of the sequence whose A-number is A006531: - sloane --keys=SNCF id:A006531+ sloane -k SNCF id:A006531 The next example returns at most 3 results of a free text search: - sloane -n3 "(2+2)-free posets"+ sloane -n 3 "(2+2)-free posets" To view the full entries of these 3 results in a browser (e.g., Firefox) one can use the url option: - firefox `sloane --url -n3 "(2+2)-free posets"`+ firefox `sloane --url -n 3 "(2+2)-free posets"` In the final example the local cache is used to filter out sequences from the standard input that are in the OEIS:
sloane.1 view
@@ -1,11 +1,20 @@-.TH "SLOANE" "1" "April 30, 2014" "Sloane User Manual" "Version 1.7.1"+.TH "SLOANE" "1" "May 27, 2014" "Sloane User Manual" "Version 1.8" .SH NAME .PP sloane \- a command line interface to Sloane\[aq]s On\-Line Encyclopedia of Integer Sequences <http://oeis.org> .SH SYNOPSIS .PP-sloane [\f[I]options\f[]] \f[I]search\-terms\f[]+sloane [\-a | \-\-all | \-k \f[I]keys\f[] | \-\-url] [\-n+\f[I]entries\f[]] \f[I]search\-terms\f[] ...+.PD 0+.P+.PD+sloane (\-\-update | \-\-version | \-\-help)+.PD 0+.P+.PD+sloane .SH DESCRIPTION .PP The sloane command searches Sloane\[aq]s On\-Line Encyclopedia of@@ -51,21 +60,26 @@ \f[] .fi .PP-Sloane crops long lines to fit the widths of the terminal.+Sloane normally crops long lines to fit the widths of the terminal. If this is unwanted, pipe the output through cat. .SH OPTIONS .TP-.B \-a \-\-all+.B \-a, \-\-all Print all fields .RS .RE .TP-.B \-k \-\-keys=KEYS+.B \-k \f[I]keys\f[] Keys of fields to print (default: SN) .RS .RE .TP-.B \-n \-\-limit=INT+.B \-\-url+Print URLs of found entries (but nothing else)+.RS+.RE+.TP+.B \-n \f[I]entries\f[] Fetch at most this many entries (default: 5) .RS .RE@@ -75,20 +89,15 @@ .RS .RE .TP-.B \-u \-\-url-Print URLs of found entries (but nothing else)+.B \-\-version+Print version information .RS .RE .TP-.B \-? \-\-help+.B \-\-help Display a short help message .RS .RE-.TP-.B \-V \-\-version-Print version information-.RS-.RE .SH EXAMPLES .PP The most common search is for entries matching a sequence of consecutive@@ -117,7 +126,7 @@ .IP .nf \f[C]-sloane\ \-\-keys=SNCF\ id:A006531+sloane\ \-k\ SNCF\ id:A006531 \f[] .fi .PP@@ -125,7 +134,7 @@ .IP .nf \f[C]-sloane\ \-n3\ "(2+2)\-free\ posets"+sloane\ \-n\ 3\ "(2+2)\-free\ posets" \f[] .fi .PP@@ -134,7 +143,7 @@ .IP .nf \f[C]-firefox\ `sloane\ \-\-url\ \-n3\ "(2+2)\-free\ posets"`+firefox\ `sloane\ \-\-url\ \-n\ 3\ "(2+2)\-free\ posets"` \f[] .fi .PP
sloane.cabal view
@@ -1,5 +1,5 @@ Name: sloane-Version: 1.7.1+Version: 1.8 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,7 +20,7 @@ Executable sloane Main-is: sloane.hs- Build-depends: base >=3 && <5, cmdargs >=0.9, HTTP >=4000.0.9, network >=2.4,+ Build-depends: base >=3 && <5, optparse-applicative >=0.9, HTTP >=4000.0.9, network >=2.4, bytestring >=0.9, ansi-terminal >=0.6, terminal-size >=0.2, filepath >=1.3, directory >=1.2, stringsearch >=0.3, zlib >=0.5, time >=1.4
sloane.hs view
@@ -1,32 +1,41 @@-{-# LANGUAGE DeriveDataTypeable #-}- -- | -- Copyright : Anders Claesson 2012-2014 -- Maintainer : Anders Claesson <anders.claesson@gmail.com> -- License : BSD-3 ---import Prelude hiding (all)-import qualified Data.ByteString.Char8 as B-import qualified Data.ByteString.Lazy.Char8 as BL-import qualified Data.ByteString.Lazy.Search as Search-import qualified Codec.Compression.GZip as GZip-import System.IO (stdin, stderr)-import System.Directory-import System.FilePath ((</>))-import System.Console.ANSI-import System.Console.CmdArgs-import System.Console.Terminal.Size (Window(..), size)-import Data.Time (getCurrentTime, diffUTCTime)-import Data.Maybe (maybe, fromJust)-import Control.Monad (when, unless)-import Network.HTTP-import Network.URI (parseURI)+import qualified Codec.Compression.GZip as GZip+import Control.Monad (unless, when)+import qualified Data.ByteString.Char8 as B+import qualified Data.ByteString.Lazy.Char8 as BL+import qualified Data.ByteString.Lazy.Search as Search+import Data.Maybe (fromJust, maybe)+import Data.Time (diffUTCTime, getCurrentTime)+import Network.HTTP+import Network.URI (parseURI)+import Options.Applicative+import System.Console.ANSI+import System.Console.Terminal.Size (Window (..), size)+import System.Directory+import System.FilePath ((</>))+import System.IO (stderr, stdin) type OEISEntries = [String] type ANumbers = [String] type Query = String type Keys = String +data Args = Args+ { all :: Bool+ , keys :: String+ , limit :: Int+ , update :: Bool+ , url :: Bool+ , ver :: Bool+ , terms :: [String]+ }++version = "sloane 1.8"+ oeisHost = "http://oeis.org/" oeisURL = oeisHost ++ "search?fmt=text" oeisKeys = "ISTUVWXNDHFYAOEeptoKC"@@ -46,30 +55,10 @@ [ "No sequence cache found. You need to run \"sloane --update\"" ] msgOldCache = unlines- [ "The sequence cache is more than two weeks old"+ [ "The sequence cache is more than 100 days old" , "You may want to run \"sloane --update\"" ] -data Sloane = Sloane { all :: Bool- , keys :: String- , limit :: Int- , update :: Bool- , url :: Bool- , terms :: [String]- }- deriving (Data, Typeable)--sloane = cmdArgsMode $ Sloane- { all = False &= name "a" &= help "Print all fields"- , keys = "SN" &= typ "KEYS" &= help "Keys of fields to print (default: SN)"- , limit = 5 &= name "n" &= help "Fetch at most this many entries (default: 5)"- , update = False &= help "Update the local sequence cache"- , url = False &= name "u" &= help "Print URLs of found entries"- , terms = def &= args &= typ "SEARCH-TERMS"- }- &= versionArg [summary "sloane 1.7.1"]- &= summary "Search Sloane's On-Line Encyclopedia of Integer Sequences"- select :: Keys -> OEISEntries -> OEISEntries select ks = filter (\line -> null line || head line `elem` ks) @@ -132,6 +121,9 @@ isInfixOf :: B.ByteString -> BL.ByteString -> Bool isInfixOf q = not . null . Search.indices q +dropPreamble :: BL.ByteString -> BL.ByteString+dropPreamble = BL.unlines . drop 4 . BL.lines+ readCache :: FilePath -> IO BL.ByteString readCache home = do let name = home </> cacheDir </> cacheFile@@ -140,10 +132,10 @@ then do c <- getCurrentTime m <- getModificationTime name- let week = 60*60*24*7- let expired = c `diffUTCTime` m > 2*week+ let day = 60*60*24+ let expired = c `diffUTCTime` m > 100*day when expired $ putErr msgOldCache- GZip.decompress `fmap` BL.readFile name+ (dropPreamble . GZip.decompress) `fmap` BL.readFile name else error msgNoCache @@ -161,20 +153,39 @@ cache <- readCache home B.getContents >>= mapM_ B.putStrLn . filter (`isInfixOf` cache) . seqs -main = do- home <- getHomeDirectory- args <- cmdArgsRun sloane- let query = unwords $ terms args- case (update args, null query) of- (True, _) -> updateCache home- (_, True) -> filterSeqs home- _ -> do- ncols <- getWidth- hits <- searchOEIS (limit args) query- let pick = if all args then id else select (keys args)- unless (null hits) $ do- newline- if url args- then put (urls hits)- else putEntries (ncols - 10) (pick hits)- newline+args :: Parser Args+args = Args+ <$> switch (short 'a' <> long "all" <> help "Print all fields")+ <*> strOption+ ( short 'k'+ <> metavar "KEYS"+ <> value "SN"+ <> help "Keys of fields to print [default: SN]" )+ <*> option+ ( short 'n'+ <> metavar "N"+ <> value 5+ <> help "Fetch at most this many entries [default: 5]" )+ <*> switch (long "update" <> help "Update the local sequence cache")+ <*> switch (long "url" <> help "Print URLs of found entries")+ <*> switch (hidden <> long "version")+ <*> many (argument str (metavar "TERMS..."))++sloane :: Args -> IO ()+sloane (Args all keys n update url True terms) = put version >> newline+sloane (Args all keys n True url ver terms) = getHomeDirectory >>= updateCache+sloane (Args all keys n update url ver [] ) = getHomeDirectory >>= filterSeqs+sloane (Args all keys n update url ver terms) = do+ ncols <- getWidth+ hits <- searchOEIS n (unwords terms)+ let pick = if all then id else select keys+ unless (null hits) $ do+ newline+ if url+ then put (urls hits)+ else putEntries (ncols - 10) (pick hits)+ newline++main = execParser (info (h <*> args) (fullDesc <> header version)) >>= sloane+ where+ h = abortOption ShowHelpText $ hidden <> long "help"