module Text.Wordlint.Linters where
import Prelude hiding (Word)
import Control.Monad
import Data.List
import Data.Function
import Text.Wordlint.Args
import Text.Wordlint.Words
import Text.Wordlint.Wordpairs
data Linter = Linter {
inputdata :: String
,wordlength :: Int
,allornot :: Bool
,maybeblacklist :: Maybe [String]
,maybewhitelist :: Maybe [String]
,word' :: Int
,line' :: Int
,percent' :: Double
,args :: Arguments
,result :: Wordpairs Double
}
getLinter :: Arguments -> IO Linter
getLinter cargs = do
dat <- accessInputFileData . checkFileStdin $ file cargs
blist <- liftM setListData $ accessListFileData. checkFileStdin $ blacklist cargs
wlist <- liftM setListData $ accessListFileData. checkFileStdin $ whitelist cargs
let mlen = matchlength cargs
let isall = all_ cargs
let w' = words_ cargs
let l = lines_ cargs
let p = percent_ cargs
let w = if l == 0 && p == 0.0 && w' == 0
then 250
else w'
return $ Linter dat mlen isall blist wlist w l p cargs []
runAllLinters :: Linter -> Wordpairs Double
runAllLinters linter = intersectWordpairs y
where words'' = distorall linter (getWordpairListWords linter) (word' linter)
cwords = commensurateWordpairs words''
lines'' = distorall linter (getWordpairListLines linter) (line' linter)
clines = commensurateWordpairs lines''
perc = distorall linter (getWordpairListPercent linter) (percent' linter)
y = sortBy (flip compare `on` length) [cwords,clines,perc]
intersectWordpairs :: [Wordpairs Double] -> Wordpairs Double
intersectWordpairs [] = []
intersectWordpairs [a,[],[]] = a
intersectWordpairs [a,b,[]] = a `intersect` b
intersectWordpairs [a,b,c] = a `intersect` intersect b c
intersectWordpairs _ = []
getWordpairList :: (Num a, NumOps a) => Linter -> String -> Wordpairs a
getWordpairList linter type' = instring
where instring = sortWordsByString . filterMatchingWords $ dwords
dwords = checkWordList fwords wordlen
fwords = runFilterFlags cwords arg blist wlist
cwords = zipWords in' type'
wordlen = wordlength linter
in' = inputdata linter
arg = args linter
blist = maybeblacklist linter
wlist = maybewhitelist linter
distorall :: (Eq a, Ord a, Num a, NumOps a) => Linter -> Wordpairs a -> a -> Wordpairs a
distorall linter wordpairs num =
if allornot linter
then wordpairs
else filterWordpairsByDistance wordpairs num
getWordpairListWords :: Linter -> Wordpairs Int
getWordpairListWords l = if word' l /= 0 then getWordpairList l "word" else []
getWordpairListLines :: Linter -> Wordpairs Int
getWordpairListLines l = if line' l /= 0 then getWordpairList l "line" else []
getWordpairListPercent :: Linter -> Wordpairs Double
getWordpairListPercent l = if percent' l /= 0 then getWordpairList l "percent" else []
commensurateWordpairs :: Wordpairs Int -> Wordpairs Double
commensurateWordpairs = map commensurateWordpair
commensurateWordpair :: Wordpair Int -> Wordpair Double
commensurateWordpair x = Wordpair a b c
where a = commensurateWords $ wone x
b = commensurateWords $ wtwo x
c = fromIntegral $ pdiff x
commensurateWords :: Word Int -> Word Double
commensurateWords x = Word (lemma x) pos (line x) (column x)
where pos = fromIntegral $ position x