将页面上的术语链接到纯JavaScript中的Wikipedia文章

Tim*_*Tim 5 javascript wikipedia wikipedia-api

在浏览我碰上了这个博客帖子大约使用维基百科的APIJavaScript的,连结一个搜索词给它的定义.在博客文章的最后,作者提到了可能的扩展,包括:

一个插件,自动将术语链接到维基百科文章.

这完全符合我正在处理的项目要求,但遗憾的是我缺乏扩展原始源代码的编程技巧.我想要的是拥有一个我可以添加到网页的纯JavaScript代码段,它将该网页上包含内部维基文章的所有条款链接到该Wiki.

我知道这可能要求很多,但代码看起来几乎就在那里,如果有人为这个虚拟信用做剩下的工作,我愿意加一个赏金..;)我也怀疑这可能是对其他几个人有价值,因为我看过类似的请求,但没有工作实现(这只是一个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>
Run Code Online (Sandbox Code Playgroud)

更新
正如评论中指出的那样,链接所有单词以及如何处理多个单词跨越文章名称所需的时间也是我的关注点.

我认为从单词文章开始已经涵盖了大部分用例,在跳过英语中最常见的500个单词时可能会获得一些性能上的好处,但我仍然不确定这种方法的可行性如何可行..

然而,在好的方面,这将是客户端,并且链接术语的一些延迟是完全可以接受的.

或者,搜索鼠标悬停/选择的术语也是可以接受的,但我不确定这是否会降低或增加复杂性.


更新2

下面解释说'Pointy'可以通过改变一些相当标准的突出显示脚本来实现这个功能api.php?action=query&list=allpages.
重新投入:我们正在使用内部维基,因此文章列表可能有限,不含糊不清且特定于域名,足以克服匹配单词中的一些预期问题.

既然我们到目前为止已经提出了一些很好的建议,并且有一些可行的想法,我现在开始赏金,看看我是否可以得到一些答案.

gna*_*arf 5

也许这样的事情可能有所帮助:

假设非常简单的HTML/Text如下:

<div id="theText">Testing the auto link system here...</div>
Run Code Online (Sandbox Code Playgroud)

还有两个非常小的脚本.

dictionary.js设置您的条款列表.我的想法是,如果你想要的话,可以通过查询文章数据库在php中生成.它也可以跨域加载(因为它设置window.termsRE).如果您不需要从数据库生成列表,也可以手动将其放入termlinker.js.

生成RegExp的代码假定您的terms数组包含使用正则表达式匹配的格式正确的字符串,因此请务必使用\\以逃避[]\.?*+|(){}^&

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

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>";
}); 
Run Code Online (Sandbox Code Playgroud)

这只是搜索术语数组中的任何单词,并用指向该术语的链接替换它们.当然,它也会匹配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);
Run Code Online (Sandbox Code Playgroud)