5

ブラウジング中に、 JavaScriptからウィキペディア APIを使用して単一の検索用語をその定義にリンクすることに関するこのブログ投稿に出くわしました。ブログ投稿の最後で、著者は次のような拡張機能について言及しています。

用語をウィキペディアの記事に自動リンクするプラグイン。

これは、私が取り組んでいるプロジェクトの要件に完全に適合しますが、残念ながら、元のソース コードを拡張するためのプログラミング スキルがありません。私が望むのは、Web ページに追加できる純粋な JavaScript スニペットを用意することです。これは、その Web ページ上の内部ウィキの記事を含むすべての用語をそのウィキにリンクします。

私はこれが多くを求めているかもしれないことを知っていますが、コードはもうすぐそこにあるように見えます.誰かがその仮想クレジットのために残りの仕事をしてくれるなら、喜んで報奨金を追加します.. ;)同様のリクエストを見たことがありますが、機能する実装はありません (これは単なる JavaScript (したがって移植可能な) ライブラリ/スニペット インクルードです)。

元のソース コードのサンプルを次に示します。だれかがこれに追加したり、自分でこれを実装する場合に追加する必要があるものを教えてくれたりしてくれることを願っています (その場合、うまくいけばコードを共有します)。何かをまとめる)。

<script type="text/javascript"><!--
var spellcheck = function (data) {
    var found = false; var url=''; var text = data [0];
    if (text != document.getElementById ('spellcheckinput').value)
        return;
    for (i=0; i<data [1].length; i++) {
        if (text.toLowerCase () == data [1] [i].toLowerCase ()) {
            found = true;
            url ='http://en.wikipedia.org/wiki/' + text;
            document.getElementById ('spellcheckresult').innerHTML = '<b style="color:green">Correct</b> - <a target="_top" href="' + url + '">link</a>';
        }
    }
    if (! found)
        document.getElementById ('spellcheckresult').innerHTML = '<b style="color:red">Incorrect</b>';
};

var getjs = function (value) {
    if (! value)
        return;
    url = 'http://en.wikipedia.org/w/api.php?action=opensearch&search='+value+'&format=json&callback=spellcheck';
    document.getElementById ('spellcheckresult').innerHTML = 'Checking ...';
    var elem = document.createElement ('script');
    elem.setAttribute ('src', url);
    elem.setAttribute ('type','text/javascript');
    document.getElementsByTagName ('head') [0].appendChild (elem);
};--></script>
<form action="#" method="get" onsubmit="return false"> 
<p>Enter a word - <input id="spellcheckinput" onkeyup="getjs (this.value);" type="text"> <span id="spellcheckresult"></span></p></form>

更新
コメントで指摘されているように、すべての単語をリンクするのにかかる時間と、記事名にまたがる複数の単語を処理する方法の両方が私の懸念事項でもありました..

英語で最も一般的な 500 の単語をスキップすると、パフォーマンス上の利点が得られる可能性がありますが、このアプローチがどれほど実現可能かはまだわかりません。 ..

良い面としては、これはすべてクライアント側であり、用語のリンクの遅れは完全に許容されます。

または、マウスがホバリングしている/選択されている用語を検索することもできますが、これが複雑さを軽減または増加させるかどうかはわかりません..


更新 2

'Pointy' は、 から記事のトピックのリストを取得した後、いくつかのかなり標準的なハイライト スクリプトを変更することで、この機能を実現できると以下で説明しましたapi.php?action=query&list=allpages
繰り返しになりますが、私たちは内部ウィキを使用しているため、記事のリストは限定的で、あいまいさがなく、単語の一致で予想される問題のいくつかを克服するのに十分なドメイン固有のものである可能性があります。

これまでにいくつかの良い提案といくつかの実行可能なアイデアがあったので、これについていくつかの答えを得ることができるかどうかを確認するために報奨金を開始しています..

4

1 に答える 1

5

おそらく、次のようなものが役立つかもしれません:

次のような非常に単純な HTML/Text を想定します。

<div id="theText">Testing the auto link system here...</div>

そして、2 つの非常に小さなスクリプトです。

dictionary.js用語のリストを設定します。私の考えでは、必要に応じて記事データベースにクエリを実行することで、これを php で生成できると考えていました。また、クロスドメインでロードすることもできます (設定されているためwindow.termsRE)。データベースからリストを生成する必要がない場合は、 を使用して手動で配置することもできますtermlinker.js

terms正規表現を生成するこのコードは、正規表現を使用して一致するように適切にフォーマットされた文字列が配列に含まれていることを前提としているため、必ず使用\\してエスケープしてください[]\.?*+|(){}^&

// dictionary.js - define some terms
var terms = ['testing', 'auto link'];
window.termsRE = new RegExp("\\b("+terms.join("|")+")\\b",'gi');

termlinker.js定義された用語の単純な正規表現検索置換です。インライン<script>でも構いません。dictionary.js実行する前に がロードされている必要があります。

// termlinker.js - add some tags
var element = document.getElementById("theText");

element.innerHTML = element.innerHTML.replace(termsRE, function(term) {
  return "<a href='http://en.wikipedia.org/wiki/"+escape(term)+"'>"+term+"</a>";
}); 

これは、単に用語配列内の任意の単語を検索し、それらを用語へのリンクに置き換えます。もちろん、HTML タグ内のプロパティと値にも一致するため、マークアップが少し壊れる可能性があります。

すべてをまとめると、これが得られます(jsbinプレビュー)


API の使用

以前の「最小ケース」に基づいて、API を使用して単語のリストを直接受け取り、jsbin プレビューを表示するコード サンプルを次に示します。

// Utility Function
RegExp.escape = function(text) {
  if (!arguments.callee.sRE) {
    var specials = [
      '/', '.', '*', '+', '?', '|',
      '(', ')', '[', ']', '{', '}', '\\'
    ];
    arguments.callee.sRE = new RegExp(
      '(\\' + specials.join('|\\') + ')', 'g'
    );
  }
  return text.replace(arguments.callee.sRE, '\\$1');
};

// JSONP Callback for receiving the API
function receiveAPI(data) {
  var terms = [];
  if (!data || !data['query'] || !data['query']['allpages']) return false;  
  var pages = data.query.allpages
  for (var x in pages) {
    terms.push(RegExp.escape(pages[x].title));
  }
  window.termsRE = new RegExp("\\b("+terms.reverse().join("|")+")\\b",'gi');
  linkterms();
}  

function linkterms() {
  var element = document.getElementById("theText");

  element.innerHTML = element.innerHTML.replace(termsRE, function(term) {
    return "<a href='http://en.wikipedia.org/wiki/"+escape(term)+"'>"+term+"</a>";
  });
}


// the apfrom=testing can be removed, it is only there so that
// we can get some useful terms near "testing" to work with.
// we are limited to 500 terms for the purpose of this demo:
url = 'http://en.wikipedia.org/w/api.php?action=query&list=allpages&aplimit=500&format=json&callback=receiveAPI' + '&apfrom=testing';
var elem = document.createElement('script');
elem.setAttribute('src', url);
elem.setAttribute('type','text/javascript');
document.getElementsByTagName('head')[0].appendChild (elem);
于 2010-03-09T17:58:09.660 に答える