<commit_before>module Main where

import System.Exit (exitFailure)

import Graphics.Vty.UnicodeWidthTable.Types
import Graphics.Vty.UnicodeWidthTable.IO
import Graphics.Vty.UnicodeWidthTable.Query

main :: IO ()
main = do
    let r1 = WidthTableRange 0 100 1
        r2 = WidthTableRange 101 200 2
        t = UnicodeWidthTable { unicodeWidthTableRanges = [r1, r2]
                              }

    writeUnicodeWidthTable "testfile.dat" t
    result <- readUnicodeWidthTable "testfile.dat"

    case result of
        Left msg -> do
            putStrLn $ "Error reading table: " <> msg
            exitFailure
        Right t2 -> do
            putStrLn "Original table:"
            print t
            putStrLn "New table:"
            print t2

    builtTable <- buildUnicodeWidthTable
    print builtTable
    writeUnicodeWidthTable "terminal_widths.dat" builtTable
<commit_msg>vty-build-table: use GetOpt to clean up and improve command line UI<commit_after>module Main where

import Control.Monad (when)
import Data.Maybe (fromMaybe)
import System.Environment (getArgs, getProgName)
import System.Exit (exitFailure)
import System.Console.GetOpt

import Graphics.Vty.Config (terminalWidthTablePath)
import Graphics.Vty.UnicodeWidthTable.Types
import Graphics.Vty.UnicodeWidthTable.IO
import Graphics.Vty.UnicodeWidthTable.Query

data Arg = Help
         | OutputPath String
         deriving (Eq, Show)

options :: Config -> [OptDescr Arg]
options config =
    [ Option "h" ["help"] (NoArg Help)
      "This help output"
    , Option "p" ["path"] (ReqArg OutputPath "PATH")
      ("The output path to write to (default: " <> fromMaybe "<none>" (configOutputPath config) <> ")")
    ]

data Config =
    Config { configOutputPath :: Maybe FilePath
           }
           deriving (Show)

mkDefaultConfig :: IO Config
mkDefaultConfig = do
    Config <$> terminalWidthTablePath

usage :: IO ()
usage = do
    config <- mkDefaultConfig
    pn <- getProgName
    putStrLn $ "Usage: " <> pn <> " [options]"
    putStrLn ""
    putStrLn "This tool queries the terminal on stdout to determine the widths"
    putStrLn "of Unicode characters rendered to the terminal. The resulting data"
    putStrLn "is written to a table at the specified output path for later"
    putStrLn "loading by Vty-based applications."
    putStrLn ""

    putStrLn $ usageInfo pn (options config)

configFromArgs :: [Arg] -> Config -> Config
configFromArgs [] c =
    c
configFromArgs (Help:as) c =
    configFromArgs as c
configFromArgs (OutputPath p:as) c =
    configFromArgs as (c { configOutputPath = Just p })

main :: IO ()
main = do
    defConfig <- mkDefaultConfig
    strArgs <- getArgs
    let (args, unused, errors) = getOpt Permute (options defConfig) strArgs

    when (not $ null errors) $ do
        mapM_ putStrLn errors
        exitFailure

    when ((not $ null unused) || (Help `elem` args)) $ do
        usage
        exitFailure

    let config = configFromArgs args defConfig

    outputPath <- case configOutputPath config of
        Nothing -> do
            putStrLn "Error: could not obtain terminal width table path"
            exitFailure
        Just path -> return path

    putStrLn "Querying terminal:"
    builtTable <- buildUnicodeWidthTable
    writeUnicodeWidthTable outputPath builtTable
    putStrLn $ "\nOutput table written to " <> outputPath

{'fraction_non_alphanumeric': 0.08172362555720654, 'fraction_numerical': 0.005349182763744428, 'mean_word_length': 2.860091743119266, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 18, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '785336', 'n_tokens_mistral': 998, 'n_tokens_neox': 957, 'n_words': 320}