tablize (empty) → 1.0.0
raw patch · 5 files changed
+185/−0 lines, 5 filesdep +attoparsecdep +basedep +commasetup-changed
Dependencies added: attoparsec, base, comma, optparse-applicative, tabl, text
Files
- LICENSE +23/−0
- Setup.hs +2/−0
- src/Main.hs +63/−0
- src/Options.hs +67/−0
- tablize.cabal +30/−0
+ LICENSE view
@@ -0,0 +1,23 @@+Copyright (c) 2017 Daniel Lovasko+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright notice,+ this list of conditions and the following disclaimer.+ * Redistributions in binary form must reproduce the above copyright+ notice, this list of conditions and the following disclaimer in the+ documentation and/or other materials provided with the distribution.++THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH+DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ src/Main.hs view
@@ -0,0 +1,63 @@+{-# LANGUAGE OverloadedStrings #-}++import Control.Applicative+import Options.Applicative+import System.Exit+import Text.Comma+import Text.Tabl+import qualified Data.Attoparsec.Text as A+import qualified Data.Text as T+import qualified Data.Text.IO as T++import Options++-- | Parse the visual decoration settings.+parseDecor :: A.Parser Decoration -- ^ parser+parseDecor = A.string "all" *> pure DecorAll+ <|> A.string "none" *> pure DecorNone+ <|> A.string "inner" *> pure DecorInner+ <|> A.string "outer" *> pure DecorOuter+ <|> A.string "only(" *> (DecorOnly <$> decimal) <* A.char ')'+ <|> A.string "except(" *> (DecorExcept <$> decimal) <* A.char ')'+ <|> A.string "union(" *> (DecorUnion <$> recurse) <* A.char ')'+ <|> A.string "isect(" *> (DecorIsect <$> recurse) <* A.char ')'+ A.<?> "invalid decoration"+ where+ recurse = A.sepBy parseDecor (A.char ',')+ decimal = A.sepBy A.decimal (A.char ',')++-- | Parse the column alignment settings.+parseAligns :: A.Parser [Alignment] -- ^ parser+parseAligns = (A.endOfInput *> pure []) <|> A.sepBy1 align (A.char ',')+ where+ align = A.string "left" *> pure AlignLeft+ <|> A.string "centre" *> pure AlignCentre+ <|> A.string "right" *> pure AlignRight+ A.<?> "invalid alignment"++-- | Create a table based on the file content and command-line options.+tablize :: Options -- ^ command-line options+ -> [[T.Text]] -- ^ CSV table+ -> Either String T.Text -- ^ error | table+tablize options cells = do+ hdecor <- A.parseOnly parseDecor (optHorizontal options)+ vdecor <- A.parseOnly parseDecor (optVertical options)+ aligns <- A.parseOnly parseAligns (optAlignment options)+ return $ tabl EnvAscii hdecor vdecor aligns cells++-- | Read the input file text. In case that no file was specified, the+-- standard input is used.+getInput :: Options -- ^ command-line options+ -> IO T.Text -- ^ input+getInput options = case optFile options of+ Just file -> T.readFile file+ Nothing -> T.getContents++-- | Pretty-printing of CSV files.+main :: IO ()+main = do+ options <- execParser Options.parser+ input <- getInput options+ case comma input >>= tablize options of+ Left err -> T.putStrLn ("ERROR: " <> T.pack err) >> exitFailure+ Right res -> T.putStrLn res >> exitSuccess
+ src/Options.hs view
@@ -0,0 +1,67 @@+module Options+( Options(..)+, parser+) where++import Data.Char+import Options.Applicative+import qualified Data.Text as T++-- | Command-line options.+data Options = Options+ { optFile :: Maybe String+ , optHorizontal :: T.Text+ , optVertical :: T.Text+ , optAlignment :: T.Text }++-- | Relevant file extensions options.+parseFile :: Parser (Maybe String) -- ^ parser+parseFile = optional $ strArgument (metavar "FILE")++-- | Helper funciton to remove all whitespace from a string.+noSpace :: String -- ^ old string+ -> String -- ^ new string+noSpace = filter (not . isSpace)++-- | Parse horizontal decoration.+parseHorizontal :: Parser T.Text -- ^ parser+parseHorizontal = fmap (T.pack . noSpace) $ strOption+ $ short 'x'+ <> long "horizontal"+ <> value "union(only(1),outer)"+ <> metavar "HDECOR"+ <> help "Horizontal decoration"+ <> showDefault++-- | Relevant file extensions options.+parseVertical :: Parser T.Text -- ^ parser+parseVertical = fmap (T.pack . noSpace) $ strOption+ $ short 'y'+ <> long "vertical"+ <> value "all"+ <> metavar "VDECOR"+ <> help "Vertical decoration"+ <> showDefault++-- | Relevant file extensions options.+parseAlignment :: Parser T.Text -- ^ parser+parseAlignment = fmap (T.pack . noSpace) $ strOption+ $ short 'a'+ <> long "alignment"+ <> value ""+ <> metavar "ALIGNS"+ <> help "Comma-separated list of column alignments. E.g.: left,right"+ <> showDefault++-- | Command-line user interface.+optionsParser :: Parser Options -- ^ parser+optionsParser = Options+ <$> parseFile+ <*> parseHorizontal+ <*> parseVertical+ <*> parseAlignment++-- | Parser of the command-line options.+parser :: ParserInfo Options -- ^ parser+parser = info (helper <*> optionsParser) (header top <> fullDesc)+ where top = "tablize - CSV file pretty-printer"
+ tablize.cabal view
@@ -0,0 +1,30 @@+name: tablize+version: 1.0.0+synopsis: Pretty-printing of CSV files+description: Command-line utility to pretty-print CSV files with custom+ visual decoration and column alignments.+homepage: https://github.com/lovasko/tablize+license: OtherLicense+license-file: LICENSE+author: Daniel Lovasko <daniel.lovasko@gmail.com>+maintainer: Daniel Lovasko <daniel.lovasko@gmail.com>+copyright: 2017 Daniel Lovasko+category: Text+build-type: Simple+cabal-version: >=1.10++executable tablize+ hs-source-dirs: src+ main-is: Main.hs+ other-modules: Options+ build-depends: base > 4.7 && < 5+ , attoparsec+ , comma+ , optparse-applicative+ , tabl+ , text+ default-language: Haskell2010++source-repository head+ type: git+ location: https://github.com/lovasko/tablize