Google Translate(翻訳)コマンドラインツール
Google Chromeにはhttps://chrome.google.com/extensions/detail/jlhlebbhengjlhmcjebbkambaekglhkfを入れ、FirefoxとThunderbirdにはhttps://addons.mozilla.org/en-US/firefox/addon/58606/を入れて、英語の長文はさっさとGoogle Translateに投げて、大体の文脈を掴むことにしている。一昔前よりは遥かに「読める」日本語文章が返ってくるから、本当に便利になったと思う。
しかし、weechatなど、ターミナル上のソフトウェアによって表示される英文に対して、Google Translateへの適切なショートカットが無かった。
そこで、標準入力から入力した文章をGoogle Translateを通し、翻訳された文章を標準出力に出力するツールを作ることにした。ほとんどは英語→日本語で用いるだろうが、オプションで入力言語と出力言語を指定出来ればなお良いと考えた。
Java(あるいはScalaやClojureなど)だとGoogle Code Archive - Long-term storage for Google Code Project Hosting.があるし、Pythonならurllibとurllib2とjsonを使えば20数行で書ける。
ちょっと頭の体操がてら、Haskellで書いてみた。
HTTP通信のためにhttp package、JSON処理のためにjson packageをcabalでインストールした。他のライブラリはMacPortsからインストールしたHaskell Platformに標準搭載されている。
まず使用例。
$ ghc --make translator.hs $ ./translator -fja -ten # -fまたは--from=で入力言語を指定, -tまたは--to=で出力言語を指定 クリエイティブ・コモンズとは、クリエイティブ・コモンズ・ライセンス(CCライセンス)を提供している国際的非営利組織とそのプロジェクトの総称です。 # <- C-dを押す Creative Commons license Creative Commons (CC license) is a general term for an international nonprofit organization and the project has been provided. $ ./translator # オプションを省略した場合は-fen -tja Creative Commons is a nonprofit corporation dedicated to making it easier for people to share and build upon the work of others, consistent with the rules of copyright. クリエイティブコモンズは、簡単に人々が共有し、他の作品、著作権のルールと一致する時にビルドすることに専念非営利法人です。 $ cat document.txt | ./translator # (出力省略) $ ./translator < document.txt # (出力省略) $ ./translator -fes -tja # Google Translate対応言語は勿論対応 Alguna de estas condiciones puede no aplicarse si se obtiene el permiso del titular de los derechos de autor あなたが著作権の所有者から許可を得ると、これらの条件は免除することができます
コードを以下に掲載する。ちょっと長いので、A Command-line Tool for Google Translate · GitHubにも掲載した。
-- A Command-line Tool for Google Translate -- Copyright : (c) SAEKI Yoshiyasu -- License : MIT-style license <http://www.opensource.org/licenses/mit-license.php> -- last updated: 2010/10/16 import Network.URI import Data.List import Network.HTTP import Text.JSON import System import System.Console.GetOpt import Data.Maybe (fromMaybe) urlencode :: String -> String urlencode s = escapeURIString isAlphaNum s where isAlphaNum c = elem c (['0'..'9'] ++ ['A'..'Z'] ++ ['a'..'z']) mkParams :: [(String, String)] -> String mkParams sss = (intercalate "&") $ map pair sss where pair e = (urlencode $ fst e) ++ "=" ++ (urlencode $ snd e) type URL = String mkGtUrl :: Options -> String -> URL mkGtUrl optlist text = baseurl ++ (mkParams params) where baseurl = "http://ajax.googleapis.com/ajax/services/language/translate?" params = [("v", "1.0"), ("langpair", fl ++ "|" ++ tl), ("q", text)] (Just fl) = froml optlist (Just tl) = tol optlist getHTTPContent :: URL -> IO String getHTTPContent url = (simpleHTTP $ insertHeader HdrReferer myUrl $ getRequest url) >>= getResponseBody where myUrl = "http://d.hatena.ne.jp/LaclefYoshi/" toJV :: String -> JSValue toJV content = let Ok value = decodeStrict content in value getTranslatedtext :: JSValue -> String getTranslatedtext (JSObject v) = let Ok (JSObject rd) = valFromObj "responseData" v in let Ok tt = valFromObj "translatedText" rd in fromJSString tt data Options = Options {froml :: Maybe String, tol :: Maybe String} deriving Show defaultOptions :: Options defaultOptions = Options {froml = Just "en", tol = Just "ja"} options :: [OptDescr (Options -> Options)] options = [ Option ['f'] ["from"] (OptArg ((\f opts -> opts { froml = Just f }) . fromMaybe "en") "lang") "FROM", Option ['t'] ["to"] (OptArg ((\t opts -> opts { tol = Just t }) . fromMaybe "ja") "lang") "TO" ] compilerOpts :: [String] -> IO (Options, [String]) compilerOpts argv = case getOpt Permute options argv of (o,n,[] ) -> return (foldl (flip id) defaultOptions o, n) (_,_,errs) -> ioError (userError (concat errs ++ usageInfo header options)) where header = "Usage: PROGRAM [OPTION...] files..." main :: IO () main = do argv <- getArgs (opts, optvalues) <- compilerOpts argv text <- getContents content <- getHTTPContent $ mkGtUrl opts text putStrLn $ getTranslatedtext $ toJV content
getOptの使い方はライブラリドキュメントのコピペ。"Real World Haskell"だと28.8.4に解説がある。
リファラの設定は、Cloud Translation API documentation | Cloud Translation API | Google Cloudで必ず設定しろとあるので、このブログのURLを設定してある。
相変わらず、Haskellコーディングは手探り状態だ。