ãããäœã§ããããã©ã®ããã«æ©èœããããææ¡ããGoogleããã¥ã¡ã³ããé¢ããããšãªãããã¥ã¡ã³ãã®ããã¹ãã翻蚳ã§ããå°ããªã¢ããªã±ãŒã·ã§ã³ãäœæããŸãããã
ã¡ãã£ãšããçè«ã
Google Docsã¢ããªã³-JavaScriptã§èšè¿°ãããGoogleãã©ã€ãã§æ¢åããã³åäœããã¢ããªã±ãŒã·ã§ã³ïŒçŸåšã¯Googleããã¥ã¡ã³ãã®ã¿ïŒ ã Google Docsã¢ããªã³ã¯ãGoogle Apps Scriptã®éçºã«ããã次ã®ã¹ãããã§ãã æ¬è³ªçã«ãããã¯ãGoogleããã¥ã¡ã³ãã®ä»ã®ãŠãŒã¶ãŒãé åžããã³ã€ã³ã¹ããŒã«ã§ããGoogle Apps Scriptãããžã§ã¯ãã§ãã
Google Apps Scriptãããžã§ã¯ãã«ã¯ããã€ãã®ã¿ã€ãããããŸããäž»ãªãã®ã¯ãGoogle Driveã®åå¥ã®ãããžã§ã¯ããã¡ã€ã«ïŒGoogle Driveã§ã¯ããã¹ã¿ã³ãã¢ãã³ã¹ã¯ãªããããšåŒã°ããåå¥ã®ãã¡ã€ã«ãšããŠè¡šç€ºãããŸãïŒãŸãã¯ã³ã³ãããŒããã¥ã¡ã³ããå«ããããžã§ã¯ãïŒ ãcontainer-bounds scriptã ïŒã§ãã ããã¥ã¡ã³ãã³ã³ãããŒãéããšãã¡ãã¥ãŒã®[ããŒã«]-> [ã¹ã¯ãªãããšãã£ã¿ãŒ]ã§ç¢ºèªã§ããŸãã Google Docsã¢ããªã³ã¯2çªç®ã®ãªãã·ã§ã³ã«ãããŸãã;äœæããã«ã¯ãã¢ããªã±ãŒã·ã§ã³ã®ãã¹ããšãããã°ã«äœ¿çšããã³ã³ããããã¥ã¡ã³ããå¿ èŠã§ãã
é åž
Chrome Webã¹ãã¢çµç±ã§Google Docsã¢ããªã³ã«ãã£ãŠé åžãããŸãïŒãã ãããã©ãŠã¶æ¡åŒµæ©èœã§ã¯ãããŸããïŒã ã¢ããªã³ãChromeãŠã§ãã¹ãã¢ã«è¿œå ããåã«ãGoogleã«ããã¬ãã¥ãŒãåããå¿ èŠããããŸãã Googleããã¥ã¡ã³ãã®ãŠãŒã¶ãŒã®å Žåããã¹ãŠã®ã¢ããªã³ã¯ãæ°ããã¡ãã¥ãŒé ç®-[ã¢ããªã³]-> [ã¢ããªã³ã®ååŸ]ããã€ã³ã¹ããŒã«ã§ããŸãã
éçºç°å¢
Google Apps Scriptãããžã§ã¯ãã®å ŽåãGoogleã¯Googleãã©ã€ãã«çµ±åãããéçºç°å¢ãæäŸããå®è¡ããããã°ãããã³ã³ãŒãè£å®ãå®è¡ã§ããŸãã å¥ã®éçºç°å¢ã䜿çšããŠãã³ãŒããGoogleãã©ã€ãã§ã¯ãªãCVSã«ä¿åããããšã¯å¯èœã§ããïŒ ããã«ãããè€æ°ã®éçºè ãåæã«ãããžã§ã¯ãã«åãçµã¿ãããŒãžã§ã³ç®¡çããµããŒãã§ããŸãã ãã¹ã¿ã³ãã¢ãã³ããããžã§ã¯ãã«ã¯ããã³ã³ããå¢çãã®ãããªæ©äŒããããŸã-æ®å¿µãªãããŸã ãããŸããã ãããã£ãŠãGoogle Docs Add-on'aã®éçºã«ã¯ãçµ±åéçºç°å¢ã䜿çšããå¿ èŠããããŸãã ããã¯ã ãã¹ã¿ã³ãã¢ãã³ããããžã§ã¯ãããã¡ã€ã«ã·ã¹ãã ã«ããã³ãã¢ãŠããããå€æŽåŸã«Googleãã©ã€ãã§æŽæ°ã§ããPythonã¹ã¯ãªããã®äŸã§ãã
äžèº«ã¯äœã§ãã
Google Apps Scriptã®ä»çµã¿ã«ã€ããŠããå°ã説æããŸãã ãããžã§ã¯ããã¡ã€ã«ã«ã¯ãã¢ããªã±ãŒã·ã§ã³ã®ããµãŒããŒãïŒ.gsïŒéšåãšãã¯ã©ã€ã¢ã³ããïŒ.htmlïŒéšåãå«ãŸããŠããŸãã ããµãŒããŒãéšåã¯ããã®ã¢ããªã³ãã€ã³ã¹ããŒã«ãããŠããããã¥ã¡ã³ãã®APIãå«ãã ãµãŒãããŒãã£ã®ãµãŒãã¹ ãããŸããŸãªGoogle APIïŒãã©ã€ããGMailãã«ã¬ã³ããŒïŒã«ã¢ã¯ã»ã¹ã§ããJavaScripté¢æ°ã®ã»ããã§ãã
ãŸããããgsããã¡ã€ã«ã«ã¯ããŠãŒã¶ãŒãã¢ããªã³ãèšå®/éããšãã«åŒã³åºãããå®çŸ©æžã¿ã®é¢æ°ãå«ãŸããŠããŸããããã«ãããæšæºã®Googleããã¥ã¡ã³ããšãã£ã¿ãŒå ã§ã¢ããªã±ãŒã·ã§ã³ã®UIãäœæã§ããŸãã åæ§ã«ããã¯ã©ã€ã¢ã³ãéšåãã¯æšæºã®htmlãã¡ã€ã«ã§ãããããµãŒããŒããã¡ã€ã«ããä»»æã®é¢æ°ãåŒã³åºãããšãã§ããŸãã ãããŠãã¡ããããµãŒãããŒãã£ã®CSS / javascriptãã¡ã€ã«ãæ¥ç¶ããæ©èœãåããŠããŸãã
äŸ
ããã¥ã¡ã³ãå ã®éžæããããã¹ããè±èªãããã·ã¢èªã«ç¿»èš³ããã¢ããªã±ãŒã·ã§ã³ãäœæããŸãã Googleãã©ã€ãã§æ°ããGoogleããã¥ã¡ã³ãããã¥ã¡ã³ããäœæãã[ããŒã«]ã¡ãã¥ãŒã®[ã¹ã¯ãªãããšãã£ã¿ãŒ]ãéããŸãã 衚瀺ããããã€ã¢ãã°ã§ããã¹ã¯ãªããã®äœæ->ããã¥ã¡ã³ãããéžæããŸãã ãã®åŸãéåžžã«çµ±åãããéçºç°å¢ã衚瀺ãããŸãã ãããžã§ã¯ãã§ã¯ãããã©ã«ãã§ãGoogleã®ãµã³ãã«ã¢ããªã±ãŒã·ã§ã³ãå«ããCode.gsããã¡ã€ã«ãäœæãããŸãã ãŸã å¿ èŠãªãã®ã§ãããã«ãã®å 容ãæ¶å»ãããã¡ã€ã«èªäœã®ååããServer.gsãã«å€æŽããããšãææ¡ããŸãã ãŸããã翻蚳ã®äŸãã®ããã«ããããžã§ã¯ãã®ååããç¡é¡ã®ãããžã§ã¯ããããããã«å€æŽããããšããå§ãããŸãã
ãã®ããããServer.gsãã§ãã¢ããªã³ã®UIãäœæããé¢æ°ãå®çŸ©ããŸãã ãããè¡ãã«ã¯ãé¢æ°ãonOpenãã宣èšããã ãã§ãã
function onOpen() { DocumentApp.getUi().createAddonMenu() .addItem('Translate', 'openSidebar') .addToUi(); } function openSidebar( ) {}
ããã§ããã®ã¢ããªã³ãã€ã³ã¹ããŒã«ãããŠããããã¥ã¡ã³ããéããšãç¹å¥ãªãã¢ããªã³ãã¡ãã¥ãŒã«ã翻蚳ãã¢ã€ãã ã衚瀺ãããŸãã ãã®ã¡ãã¥ãŒé ç®ãã¯ãªãã¯ãããšããopenSidebarãé¢æ°ãåŒã³åºãããŸããããŸã äœãå®è¡ãããŸããã ããã確èªããã«ã¯ãéçºç°å¢ã§ãonOpenãæ©èœãéžæãããå®è¡ããã¯ãªãã¯ããŸã
ããã¥ã¡ã³ãã®ã¡ãã¥ãŒé ç®ãã¢ããªã³ã->ãäŸã®ç¿»èš³ãïŒãããžã§ã¯ãã®ååïŒ->ã翻蚳ã
ã¢ããªã³ã®UIã®éçºãå§ããŸãããã UIã¢ããªã³ã¯htmlããŒãžã§ãããããHTMLããŒã¯ã¢ãããCSSãããã³javascriptã³ãŒããããã«å¥ã®ãã¡ã€ã«ã«åé¢ããããšã¯çã«ããªã£ãŠããŸãã ãããè¡ãã«ã¯ããSidebar.htmlãããStyles.htmlãããScripts.htmlããããã³ãContent.htmlããšãããã¡ã€ã«ãäœæããŸãã ãSidebar.htmlãã¯ãæ®ãã®ãã¡ã€ã«ãå«ããã³ãã¬ãŒããã¡ã€ã«ã§ãã
ãã¹ãŠã®ã¢ããªã³ã®UIã¯ç¹å®ã®ã¹ã¿ã€ã«ã¬ã€ãã«åŸãå¿ èŠããããããGoogleã¯äºåã«å®çŸ©ãããã¹ã¿ã€ã«ãå«ãç¹å¥ãªCSSãã¡ã€ã«ãæäŸããŸãããã®ãªã³ã¯ã¯äŸã«ãããŸãã
ãContent.htmlããšãStyles.htmlããéããããŒã¯ã¢ãããäœæããŸã
<div class="content"> <p>Select text and click 'Translate'</p> <button class="action btn-block">Translate</button> <p class="result"></p> </div>
ãšã¹ã¿ã€ã«
<style> .content { padding: 20px; margin : 20px; } .btn-block { display: block; width: 100%; padding-left: 0; padding-right: 0; } </style>
ãServer.gsãã«é¢æ°ãopenSidebarãã®æ¬æãè¿œå ããŸã
function onOpen() { DocumentApp.getUi().createAddonMenu() .addItem('Translate', 'openSidebar') .addToUi(); } function openSidebar( ) { var html = HtmlService.createTemplateFromFile('Sidebar') .evaluate() .setSandboxMode(HtmlService.SandboxMode.NATIVE) .setTitle('Translate example') .setWidth(300); DocumentApp.getUi().showSidebar(html); }
ããã§ãããã¥ã¡ã³ãã®å·ŠåŽã®[翻蚳]ã¡ãã¥ãŒé ç®ãã¯ãªãã¯ãããšãããµã€ãããŒããéããŸãã
ããã¹ãã翻蚳ããããžãã¯ãè¿œå ããããšã¯æ®ã£ãŠããŸãã ãããè¡ãã«ã¯ãããgsããã¡ã€ã«ã§å©çšå¯èœãªããŸããŸãªGoogleãµãŒãã¹ã®APIã䜿çšããããã¥ã¡ã³ãã§éžæãããããã¹ããèŠã€ããŠéžæããèšèªã«ç¿»èš³ã§ããããã«ããŸãã
ãServer.gsã
function translate(pollingCounter) { var text = getSelectedText(getSingleSeletetedElement()); if (text) { return LanguageApp.translate(text, 'en', 'ru'); } } function getSelectedText(rangeElement) { if (!rangeElement) { return; } var element = rangeElement.getElement(); var from = rangeElement.getStartOffset(); var to = rangeElement.getEndOffsetInclusive() + 1; if (element.getType() === DocumentApp.ElementType.TEXT || element.getType() === DocumentApp.ElementType.PARAGRAPH) { var text = element.getText(); return text.substring(from, to); } } function getSingleSeletetedElement() { var selection = DocumentApp.getActiveDocument().getSelection(); if (selection) { var elements = selection.getSelectedElements(); if (elements.length === 1) { return elements[0]; } } }
ã翻蚳ãæ©èœã¯ãææžå ã®éžæãããèŠçŽ ãæ€çŽ¢ãããããããã¹ããŸãã¯ããã¹ããããã¯ã®å Žåãããã¹ãã®éžæãããéšåãåãåããè±èªãããã·ã¢èªã«ç¿»èš³ããŸãã 次ã«ãäœããã®æ¹æ³ã§ãã®é¢æ°ãUIããåŒã³åºãå¿ èŠããããŸãã ãã®ãããããµã€ãããŒãã§å®è¡ãããŠããJavaScriptã³ãŒãã¯ãã°ããŒãã«ãªããžã§ã¯ããgoogle.script.runãã«ã¢ã¯ã»ã¹ã§ãããããããgsããã¡ã€ã«ããé¢æ°ãåŒã³åºãããšãã§ããŸãã
ãScripts.htmlã
$(function() { $('.action').click(function() { google.script.run.withSuccessHandler(function(text) { if (text) { $('.result').text('Result: ' + text); } else { $('.result').text('Please, select text to translate'); } }).translate(); }); });
ããã§ã¢ããªã³ã¯ãã翻蚳ãããŒãæŒãããšã§éžæããããã¹ãã翻蚳ã§ããããã«ãªããŸããã
ããã«2ã€ã®æ¹åãè¡ãããšãã§ããŸãã ãŸããããµã€ãããŒããéããšãããã«å¿ èŠãªãã¹ãŠã®ãã¡ã€ã«ãããŒããããŠãããšãã«ãäœããã®çš®é¡ã®ããŒãã€ã³ãžã±ãŒã¿ãŒãè¿œå ãããšäŸ¿å©ã§ãã ãã¡ã€ã«ãLoading.htmlããäœæãããSidebar.htmlãã«ãªã³ã¯ãè¿œå ãããã¹ãŠã®ãªãœãŒã¹ãå®å šã«ããŒãããããŸã§ã¡ã€ã³ã³ã³ãã³ããé衚瀺ã«ããŸãã ãã¹ãŠã®æºåãæŽã£ãããã€ã³ãžã±ãŒã¿ãŒãé衚瀺ã«ããŠUIã衚瀺ããŸãã
ãLoading.htmlã
<div class="app-loading" style="text-align:center"> <br><br><br><br><br><br> Loading... </div>
Content.html
<div class="content" style="display:none"> <p>Select text and click 'Translate'</p> <button class="action btn-block">Translate</button> <p class="result"></p> </div>
Sidebar.html
<!-- styles --> <link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons.css"> <?!= HtmlService.createHtmlOutputFromFile('Styles').getContent(); ?> <!-- layout --> <?!= HtmlService.createHtmlOutputFromFile('Loading').getContent(); ?> <?!= HtmlService.createHtmlOutputFromFile('Content').getContent(); ?> <!--3rd party scripts --> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <!-- application scripts --> <?!= HtmlService.createHtmlOutputFromFile('Scripts').getContent(); ?>
æåŸã«Scripts.html
$(function() { $('.app-loading').hide(); $('.content').show(); $('.action').click(function() { google.script.run.withSuccessHandler(function(text) { if (text) { $('.result').text('Result: ' + text); } else { $('.result').text('Please, select text to translate'); } }).translate(); }); });
ãããŠã第äºã«ãã翻蚳ããã¿ã³ãã¯ãªãã¯ããã«ãææžããéžæããããã¹ãã®ç¿»èš³ãèªåçã«åä¿¡ãããšäŸ¿å©ã§ãã ãã®åé¡ã解決ããã«ã¯ãGoogle Docsã¢ããªã³ã«çŸåšååšããå¶éã®1ã€ãåé¿ããæ¹æ³ãç解ããå¿ èŠããããŸããGoogleScriptã¢ããªã³ãããã¥ã¡ã³ãå ã®ãŠãŒã¶ãŒã¢ã¯ã·ã§ã³ã«å¿çã§ããã€ãã³ãã¢ãã«ã¯ãããŸããã é·ãããŒãªã³ã°ã䜿çšããŠã¢ããªã³ã®å¯Ÿè©±æ§ãã·ãã¥ã¬ãŒãããå¿ èŠããããŸã-UIããã®äžå®ã®èŠæ±ã«ããã 'Server.gs'ã¯ããã¥ã¡ã³ãã®åŒ·èª¿è¡šç€ºãšããã¹ãã®ç¿»èš³ã匷å¶çã«å®è¡ããŸãã ãããè¡ãããã«ãç¹å®ã®ééã§2ã€ã®ããã»ã¹ãéå§ããé¢æ°ããScript.htmlãã«èšè¿°ããŸãã æåã®ããã»ã¹ã¯ã翻蚳ãæ©èœãåŒã³åºãã翻蚳çµæãä¿åããã ãã§ãã 2çªç®ã®ããã»ã¹ã¯ã翻蚳çµæã確èªããUIãæŽæ°ããŸãã
ãScripts.htmlã
var LongPollingManager = (function() { var process = function(options) { var pollingTimeout = 1500, notificationTimeout = 1500, pollingCounter = 0, pollingStopped = false, pollingResult, pollingProcess, notificationProcess; var start = function() { pollingStopped = false; pollingProcess = setInterval(function() { if (pollingStopped) { return; } pollingCounter++; google.script.run.withSuccessHandler(function(response) { if (pollingStopped) { return; } if (!pollingResult || response.pollingCounter > pollingResult.pollingCounter) { pollingResult = response; } })[options.method](pollingCounter); }, pollingTimeout); setTimeout(function() { notificationProcess = setInterval(function() { if (pollingStopped) { return; } options.notification(getLastResult()); }, notificationTimeout); }, notificationTimeout/2); }; var getLastResult = function() { return pollingResult; }; var stop = function() { pollingResult = null; pollingStopped = true; clearInterval(pollingProcess); clearInterval(notificationProcess); }; return { start: start, stop : stop, isActive: function() { return !pollingStopped; }, getLastResult : getLastResult };; }; return { process: process }; })(); var showResult = function(result) { if (result && result.text) { $('.result').text('Result: ' + result.text); } else { $('.result').text(''); } }; $(function() { $('.loading').hide(); $('.content').show(); $('.action').click(function() { google.script.run.withSuccessHandler(function(text) { if (text) { $('.result').text('Result: ' + text); } else { $('.result').text('Please, select text to translate'); } }).translate(); }); LongPollingManager.process({ method: 'translate', notification: showResult }).start(); });
ãServer.gsã
function translate(pollingCounter) { var result = { pollingCounter : pollingCounter }; var text = getSelectedText(getSingleSeletetedElement()); if (text) { result.text = LanguageApp.translate(text, 'en', 'ru'); } return result; }
ããã§ãã¢ããªã³ã¯éžæããããã¹ããèªåçã«ç¿»èš³ããŸãã
Googleãã©ã€ãã®ããã¥ã¡ã³ã+ãããžã§ã¯ãã³ãŒã
Githubã³ãŒã
ãããã«
ãããã£ãŠãGoogle Docsã¢ããªã³ã¯ãåºæ¬çãªGoogle Docsãšãã£ã¿ãŒã®æ©èœãæ¡åŒµããã¢ããªã±ãŒã·ã§ã³ãäœæã§ããæ°ãããã©ãããã©ãŒã ã§ãã
ç§ã®æèŠã§ã¯é·æãšçæïŒ
- + Googleããã¥ã¡ã³ããŠãŒã¶ãŒã®å€§å¢ã®ãŠãŒã¶ãŒã
- +å®å šã«JavaScriptã§ã®ã¢ããªã±ãŒã·ã§ã³éçºã
- +å€æ°ã®Google APIããã³ãµãŒãããŒãã£ãµãŒãã¹ïŒHTTPãªã¯ãšã¹ãïŒãžã®ã¢ã¯ã»ã¹ã
- -Googleããã¥ã¡ã³ãå ã§ã®ãããžã§ã¯ãã®éçºãããŒã«ã«ã§éçºãè¡ãæ¹æ³ã¯ãããŸãããè€æ°ã®éçºè éã§äœæ¥ãåå²ããããšã¯å°é£ã§ãã
- -ããã¥ã¡ã³ããšã®ã€ã³ã¿ã©ã¯ãã£ããªããåãã®æ¬ åŠïŒããã¥ã¡ã³ãå ã®ãŠãŒã¶ãŒã¢ã¯ã·ã§ã³ã«é¢ããã¢ã©ãŒããåä¿¡ããæ¹æ³ã¯ãããŸããã
PS
MS OfficeãšGoogle Driveã®ç«¶äºã§ãGoogleã¯ã·ã³ãã«ããå©äŸ¿æ§ãéçºè ã³ãã¥ããã£ã«è³ããããšã«ãããšæããŸãã MS WordãšGoodle Docsã®äŸã説æããŸãã MS Wordã«ã¯ããŠãŒã¶ãŒã䜿çšã§ããèšå€§ãªæ°ã®æ©èœãããïŒãã®çµæããªãŒããŒããŒããããè€éãªUIïŒããªãŒãã³APIã¯ãããŸããã Googleããã¥ã¡ã³ã-ããã©ããããæå°éã®ããŒã«ã»ãããšãªãŒãã³APIããããŸãã Googleããã¥ã¡ã³ãã®ã¢ããªã³ã®ã£ã©ãªãŒã§å¿ èŠãªæ©èœãèŠã€ããããèªåã§äœæãããã§ããããã«ãªããŸããã ãŸãããŠãŒã¶ãŒã¯èªåã®ããã¥ã¡ã³ãã«å¿ èŠãªæ©èœã®ã¿ãè¿œå ã§ããŸãã