I developed a script to transform a Japanese word in Furigana thanks to the jisho website. But the code is very ugly, especially the extractHiraganaFromHTML
and filterBetween
functions. What kind of improvements are possible?
module Main
where
import Network.HTTP
import Network.URI
import Text.HTML.TagSoup
import Data.Text (unpack)
import Data.Text.Encoding (decodeUtf8)
import Data.ByteString.Char8 (pack)
import System.Environment (getArgs)
jishoUrlFor :: String -> String
jishoUrlFor word = (escapeURIString isUnescapedInURI) $ "http://jisho.org/word/"++word
getJishoHTML :: String -> IO String
getJishoHTML w = simpleHTTP (getRequest $ jishoUrlFor w) >>= getResponseBody
extractHiraganaFromHTML :: String -> String
extractHiraganaFromHTML = unicodeToString . strip . innerText . filter(~== TagText "") . filterBetween . head . partitions (~== "<span class=\"furigana\">") . parseTags
convertWordToHiragana :: String -> IO String
convertWordToHiragana w = do
html <- getJishoHTML w
return $ extractHiraganaFromHTML html
filterBetween :: [Tag String] -> [Tag String]
filterBetween p = fst $ sfoldl step ([],0) $ p
where step (x,a) tag | tag ~== "<span>" = (tag:x,a+1)
step (x,a) tag | tag ~== TagClose "span" = (tag:x,a-1)
step (x,a) tag = (tag:x,a)
sfoldl step (a,1) (TagClose "span":xs) = (reverse (TagClose "span":a),0) -- stop condition
sfoldl step (a,b) (x:xs) = sfoldl step (step (a,b) x) xs
sfoldl step (a,b) [] = (a,b)
wchars = " \t\r\n"
strip :: String -> String
strip = lstrip . rstrip
lstrip :: String -> String
lstrip = dropWhile (`elem` wchars)
rstrip :: String -> String
rstrip = reverse . lstrip . reverse
unicodeToString = Data.Text.unpack . Data.Text.Encoding.decodeUtf8 . Data.ByteString.Char8.pack
main = do
(word:_) <- getArgs
a <- convertWordToHiragana word
putStrLn a