今回は SyntaxHighlighter を使ったページを、Google翻訳(Google translate) で翻訳する場合の設定について考えてみます。
個人的には全く使っていない Google翻訳 だが、未知の言語で書かれたページを読むには便利ではないだろうか。とは言っても海外から、このブログを翻訳してでも読みたいという需要は皆無だと思う。ただ需要はないにしても、実際に記事を翻訳した場合、妙な表示になるところだけは直したいと思う。
なお 「Googleウェブサイト翻訳ツール」 での設定については、こちらで 説明しています。
Google翻訳 でのページ表示異常
Google翻訳で何の対策もせず、ブログ記事を表示させると次のようになる。
SyntaxHighlighter を使ったコード部分が妙なことになっているのがわかる。Google翻訳はマウスオーバで原文を表示するために、spanタグを利用して記事に翻訳文と原文が混在したコードを追加してしまう。それでおかしな表示になる。
このような場合次のように、Google翻訳を制御するコードを追加することで解決が可能だ。
- ページ全体を翻訳されないようにする 次のメタタグをHTMLファイルに追加する
<meta name="google" value="notranslate">
- ページの一部分が翻訳されないようにする HTML 要素に class=notranslate を追加する
<span class="notranslate">この部分は翻訳されない</span>
今回の場合、SyntaxHighlighterが動くコード部分が翻訳されないようにすれば良いので、preタグに notranslate を追加して試してみる。
<pre class="brush: py;"> のところを、次のように変更する。 <pre class="brush: py; notranslate">
すると次のようになった。
コード部分は翻訳されないのはよいのだが、それ以降の文書まで翻訳されないようになってしまった・・・。
正しい notranslate の設置方法
GoogleのヘルプにはHTML要素に設置すればよいと書いてあるが、どうも違うようだ。いろいろなパターンで試してみたが、よく分からない。Google翻訳のロジックによって、うまく翻訳を制御する場合としない場合があるようだ。
ただ SyntaxHighlighter に限って言えば、ほぼ100%制御する方法が分かった。それが次の方法である。
preタグをdivタグで包み、divタグにnotranslateを設定する。
<div class="notranslate"> <pre class="brush:html"> ・・・コード・・・ </pre> </div>
先ほどのサンプルのソースを修正し、再度 Google翻訳 にかけた結果は次のようになる。
うまく制御されている。
divタグに notranslate を設定する方法は確実なのだが、全記事を直さなければいけない。もっと簡単な方法はないだろうか?。
SyntaxHighlighter を Google翻訳 に対応させる簡単な方法
最初に考えるのはやはり、Javascript を使用して notranslate付きの divタグを設置する方法である。ただこの方法は成功しない。なぜなら Javascript が動く前に、Google翻訳 がページを改変するからである。
次に考えるのは、Google翻訳が改変するコードを参考に原文を Javascript で拾ってくる方法である。Google翻訳が挿入するコードは次のような構造になっている。
<span onmouseover="_tipon(this)" onmouseout="_tipoff()"> <span class="google-src-text" style="direction: ltr; text-align: left"> 原文</span> 翻訳文</span>
これがセンテンス単位で挿入されてくるので、原文の部分だけ拾って置き換えればよい。例えば次のような javascript(jQuery)を設置すれば可能だ。
<script type='text/javascript'> jQuery(function($) { var v = $('.google-src-text').css('display'); if(v == 'none'){ $('pre > span').each(function() { $(this).replaceWith($(this).contents().filter(function(){return this.nodeType == 3;}).text()); }); } else { $('pre > span').each(function() { $(this).replaceWith($(this).contents().filter('.google-src-text').text()); }); } }); </script>
しかしこの方法で表示した場合、SyntaxHighlighter がタグを誤認して表示が無茶苦茶になる場合がある。
他に良い方法はないだろうか?。ここで思い付いたのは Google翻訳 を使用する場合だけ、SyntaxHighlighter の動作を止める方法である。SyntaxHighlighterが動かなければコードも乱れず表示されるし、マウスオーバで原文表示も可能になる。
<script type='text/javascript'> jQuery(function($) { $('pre[class^="brush"]:has(span[onmouseover])') .css('padding','5px') .css('background-color','#F0F0F0') .removeAttr('class'); }); </script>
このコードは、preタグのclass属性に brush と記述されているタグの中に、onmouseover 属性を持つ spanタグ が子供要素として存在する場合は、preタグのclass属性を削除する。
コードを head タグ内に設置し、Google翻訳を実行すると次のように表示される。
方法は本末転倒であるが、マウスオーバも使用できるし意外と快適だ。コード内のコメントも翻訳してくれる。だたコードとは言っても、Google翻訳は一部原文も変換してしまう。やはり一番確実なのは、divタグに notranslate を設定する方法である。
最終的に SyntaxHighlighter の動作を止める Javascript を設置することになりましたが、最小の変更で正常に(近い形で)表示する方法ではないかと思います。
SyntaxHighlighter は、『Google翻訳』 を使用した場合は記事のように表示が乱れます。しかし 『Googleウェブサイト翻訳ツール』 ではキチンと表示されるようです。これは「Googleウェブサイト翻訳ツール」は、Javascriptが動作した後に翻訳しているのが理由のようです。
参考Google翻訳
Googleウェブサイト翻訳ツール
このため「Googleウェブサイト翻訳ツール」で SyntaxHighlighter のコードを翻訳させないようにする、次のような簡単な方法があります。
SyntaxHighlighter.defaults['class-name'] = 'notranslate';デフォルトクラス名として指定することにより、SyntaxHighlighter が成形する全てのコードのタグに notranslate がクラス属性として設定される。