diff options
author | Jagua | 2012-01-28 21:41:50 +0900 |
---|---|---|
committer | Jagua | 2012-01-28 21:41:50 +0900 |
commit | cc0b465847ac7c5ce329ef961a728bc37b444053 (patch) | |
tree | b1483c4a28b8c31ac0209ac4217019e78d009227 /microsoft-translator.js | |
parent | c14b78f3d6c096f3a2c4410959d7c185b9a5ec4f (diff) | |
download | vimperator-plugins-cc0b465847ac7c5ce329ef961a728bc37b444053.tar.bz2 |
initial commit
Diffstat (limited to 'microsoft-translator.js')
-rw-r--r-- | microsoft-translator.js | 397 |
1 files changed, 397 insertions, 0 deletions
diff --git a/microsoft-translator.js b/microsoft-translator.js new file mode 100644 index 0000000..57ced85 --- /dev/null +++ b/microsoft-translator.js @@ -0,0 +1,397 @@ +/* NEW BSD LICENSE {{{ +Copyright (c) 2009-2010, anekos. +Copyright (c) 2012, Jagua. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + 2. 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. + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + + +################################################################################### +# http://sourceforge.jp/projects/opensource/wiki/licenses%2Fnew_BSD_license # +# に参考になる日本語訳がありますが、有効なのは上記英文となります。 # +################################################################################### + +}}} */ + +// PLUGIN_INFO {{{ +let PLUGIN_INFO = +<VimperatorPlugin> + <name>Microsoft Translator</name> + <name lang="ja">Microsoft Translator</name> + <description>Translate with Microsoft AJAX Language API</description> + <version>1.0.0</version> + <author mail="anekos@snca.net" homepage="http://d.hatena.ne.jp/nokturnalmortum/">anekos</author> + <author homepage="https://github.com/Jagua">Jagua</author> + <license>new BSD License (Please read the source code comments of this plugin)</license> + <license lang="ja">修正BSDライセンス (ソースコードのコメントを参照してください)</license> + <updateURL>https://github.com/vimpr/vimperator-plugins/raw/master/microsoft-translator.js</updateURL> + <require>_libly.js</require> + <minVersion>2.3</minVersion> + <maxVersion>3.3</maxVersion> +</VimperatorPlugin>; +// }}} + +// INFO {{{ +let INFO = +<plugin name="Microsoft Translator" version="1.0.0" + href="http://github.com/vimpr/vimperator-plugins/blob/master/microsoft-translator.js" + summary="Translate with Microsoft AJAX Language API" + xmlns="http://vimperator.org/namespaces/liberator"> + <author email="anekos@snca.net">anekos</author> + <author homepage="https://github.com/Jagua">Jagua</author> + <license>New BSD License</license> + <project name="Vimperator" minVersion="2.3"/> + <p> + Translate with Microsoft AJAX Language API. + </p> + <item> + <tags>:mstrans</tags> + <spec>:mstrans <oa>-a<oa>ction</oa>=<a>actionName</a></oa> text</spec> + <description> + <p> + Translate!!!!!!!!!!! + </p> + <p> + You need to get an Access Token from http://www.bing.com/developers/appids.aspx + to use this plugin. and add liberator.globalVariables.mstrans_appid setting + to your ".vimperatorrc". + </p> + <p>The following options are interpreted.</p> + <dl> + <dt>-a<oa>ction</oa></dt> + <dd> + 以下の<oa>actionName</oa>が設定可能 + <ul> + <li>echo</li> + <li>replace(not implemented)</li> + <li>copy</li> + </ul> + </dd> + </dl> + </description> + </item> +</plugin>; +// }}} + +(function () { + + const refererURL = 'https://github.com/vimpr/vimperator-plugins/raw/master/microsoft-translator.js'; + + const languages = [ + ['af', 'Afrikaans'], + ['sq', 'Albanian'], + ['am', 'Amharic'], + ['ar', 'Arabic'], + ['hy', 'Armenian'], + ['az', 'Azerbaijani'], + ['eu', 'Basque'], + ['be', 'Belarusian'], + ['bn', 'Bengali'], + ['bh', 'Bihari'], + ['bg', 'Bulgarian'], + ['my', 'Burmese'], + ['ca', 'Catalan'], + ['chr', 'Cherokee'], + ['zh', 'Chinese'], + ['zh-CN', 'Chinese_simplified'], + ['zh-TW', 'Chinese_traditional'], + ['hr', 'Croatian'], + ['cs', 'Czech'], + ['da', 'Danish'], + ['dv', 'Dhivehi'], + ['nl', 'Dutch'], + ['en', 'English'], + ['eo', 'Esperanto'], + ['et', 'Estonian'], + ['tl', 'Filipino'], + ['fi', 'Finnish'], + ['fr', 'French'], + ['gl', 'Galician'], + ['ka', 'Georgian'], + ['de', 'German'], + ['el', 'Greek'], + ['gn', 'Guarani'], + ['gu', 'Gujarati'], + ['iw', 'Hebrew'], + ['hi', 'Hindi'], + ['hu', 'Hungarian'], + ['is', 'Icelandic'], + ['id', 'Indonesian'], + ['iu', 'Inuktitut'], + ['ga', 'Irish'], + ['it', 'Italian'], + ['ja', 'Japanese'], + ['kn', 'Kannada'], + ['kk', 'Kazakh'], + ['km', 'Khmer'], + ['ko', 'Korean'], + ['ku', 'Kurdish'], + ['ky', 'Kyrgyz'], + ['lo', 'Laothian'], + ['lv', 'Latvian'], + ['lt', 'Lithuanian'], + ['mk', 'Macedonian'], + ['ms', 'Malay'], + ['ml', 'Malayalam'], + ['mt', 'Maltese'], + ['mr', 'Marathi'], + ['mn', 'Mongolian'], + ['ne', 'Nepali'], + ['no', 'Norwegian'], + ['or', 'Oriya'], + ['ps', 'Pashto'], + ['fa', 'Persian'], + ['pl', 'Polish'], + ['pt-PT', 'Portuguese'], + ['pa', 'Punjabi'], + ['ro', 'Romanian'], + ['ru', 'Russian'], + ['sa', 'Sanskrit'], + ['sr', 'Serbian'], + ['sd', 'Sindhi'], + ['si', 'Sinhalese'], + ['sk', 'Slovak'], + ['sl', 'Slovenian'], + ['es', 'Spanish'], + ['sw', 'Swahili'], + ['sv', 'Swedish'], + ['tg', 'Tajik'], + ['ta', 'Tamil'], + ['tl', 'Tagalog'], + ['te', 'Telugu'], + ['th', 'Thai'], + ['bo', 'Tibetan'], + ['tr', 'Turkish'], + ['uk', 'Ukrainian'], + ['ur', 'Urdu'], + ['uz', 'Uzbek'], + ['ug', 'Uighur'], + ['vi', 'Vietnamese'], + ['cy', 'Welsh'], + ['yi', 'Yiddish'], + ['', 'Unknown'] + ]; + + const settings = { + get pair () + (liberator.globalVariables.microsoft_translator_pair || 'ja en').split(' '), + get actions () + (liberator.globalVariables.microsoft_translator_actions || 'echo').split(' ') + }; + + function guessRequest (appId, text, done) { + let url = + 'http://api.microsofttranslator.com/V2/Ajax.svc/Detect' + + '?appId=' + appId + + '&text=' + encodeURIComponent(text); + let req = + new plugins.libly.Request( + url, + { + Referrer: refererURL, + } + ); + req.addEventListener( + 'onSuccess', + function (res) { + var result = res.responseText; + done(result.substring(1,3)); + } + ); + req.get(); + } + + function translateRequest (appId, text, opts /* from, to, done */) { + opts || (opts = {}); + let url = + 'http://api.microsofttranslator.com/V2/Ajax.svc/Translate' + + '?appId=' + appId + + '&text=' + encodeURIComponent(text) + + '&from=' + (opts.from || 'en') + '&to=' + (opts.to || 'ja') + + '&contentType=text/plain' ; + let req = + new plugins.libly.Request( + url, + { + Referrer: refererURL, + } + ); + req.addEventListener( + 'onSuccess', + function (res) { + let translated = res.responseText; + liberator.log('translated: ' + translated); + opts.done(translated); + } + ); + req.get(); + } + + // 何語か妄想する + // XXX 使ってないよ! + function guess (text) { + const codePatterns = { + ja: + /[\u3041-\u3093\u30A1-\u30F6\u30FC\u3005\u3007\u303B\u3400-\u9FFF\uF900-\uFAFF\u20000-\u2FFFF]/g, + en: + /[a-zA-Z]/g, +// ko: +// /[\uac00-\ud79f]/g, + }; + + function matchCount (s, re) { + let r = 0; + s.replace(re, function (m) (r += m.toString().length)); + return r; + } + + let max = {lang: null, length: 0}; + for (let lang in codePatterns) { + let len = matchCount(test, codePatterns[lang]); + if (len > max.length) + max = {lang: lang, length: len}; + } + + return max.lang || 'en'; + } + + + let actions = { + echo: +// function (text) liberator.echo(text,commandline.FORCE_MULTILINE), +// function (text) liberator.echo("<p style='width:200px'>"+text+"</p>",commandline.FORCE_MULTILINE), +// function (text) liberator.echo("<p style='width:"+content.document.documentElement.clientWidth+"px'>"+text+"</p>",commandline.FORCE_MULTILINE), +// function (text) liberator.echo("<div style='white-space:normal;word-break:normal;width:"+content.document.documentElement.clientWidth+"px;height:4em;overflow:auto;'>"+content.document.documentElement.clientWidth+text+"</div>",commandline.FORCE_MULTILINE), +// function (text) liberator.echo("<div style='white-space:normal;word-break:normal;'>"+text+"</div>",commandline.FORCE_MULTILINE), + function (text) liberator.echo("<div style='white-space:normal;'>"+text+"</div>",commandline.FORCE_MULTILINE), + insert: + // FIXME 見えない要素相手だとうまくいかない + function (text) { + let div = content.document.createElement('div'); + div.setAttribute('style', 'border: dotted 2px blue; padding: 5px;'); + div.textContent = text; + let selection = content.window.getSelection(); + if (selection.rangeCount > 0) { + let range = selection.getRangeAt(0); + range.insertNode(div); + } + }, + copy: + function (text) util.copyToClipboard(text, true) + }; + + function makeListValidator (list) + function (vs) (!vs || !vs.some(function (v) !list.some(function (at) (v == at)))); + + commands.addUserCommand( + ['mstrans'], + 'Microsoft Translator', + function (args) { + let appId = liberator.globalVariables.mstrans_appid; + let text = args.literalArg; + let actionNames = args['-action'] || settings.actions; + let [from, to] = [args['-from'], args['-to']]; + + if (appId == undefined) { + liberator.echoerr('The setting of liberator.globalVariables.mstrans_appid in .vimperatorrc is required.'); + return false; + } + + if (!text) + text = buffer.getCurrentWord(); + + if (args['-guess']) { + guessRequest( + appId, + text, + function (lang) [liberator.echo("<p>"+v+"</p>",liberator.commandline.FORCE_MULTILINE) for ([, [k, v]] in Iterator(languages)) if (k == lang)] + ); + return; + } + + if (args.bang) + actionNames.push('insert'); + + if (!actionNames.length) + actionNames.push('echo'); + + function setPair () { + if ((!from ^ !to) && settings.pair.length >= 2) + let (v = settings.pair[(settings.pair[0] == (from || to)) - 0]) + (from ? (to = v) : (from = v)); + } + + function req () { + translateRequest( + appId, + text, + { + done: function (text) actionNames.forEach(function (name) actions[name](text)), + from: from, + to: to + } + ); + } + + if (from) { + setPair(); + req(); + } else { + guessRequest( + appId, + text, + function (fromLang) { + from = fromLang; + liberator.log('lang: ' + fromLang); + setPair(); + if (args['-to']) + to = args['-to']; + req(); + } + ); + } + }, + { + literal: 0, + bang: true, + options: + let (actionTypes = [n for (n in actions)]) + [ + [ + ['-action', '-a'], + commands.OPTION_LIST, + makeListValidator(actionTypes), + actionTypes.map(function (v) [v, v]), + true + ], + [['-from', '-f'], commands.OPTION_STRING, null, languages], + [['-to', '-t'], commands.OPTION_STRING, null, languages], + [['-guess', '-g'], commands.OPTION_NOARG] + ], + }, + true + ); + +})(); + +// vim:sw=2 ts=2 et si fdm=marker: |