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

时间:2010-02-27 16:12:28

标签: javascript wikipedia wikipedia-api

在浏览时,我遇到this blog post关于使用Wikipedia API中的JavaScript的问题,将单个搜索字词与其定义相关联。在博客文章的最后,作者提到了可能的扩展,包括:

  

自动将条款链接到维基百科文章的插件。

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

我知道这可能要求很多,但代码看起来几乎就在那里,如果有人为这个虚拟信用做剩下的工作,我愿意加一个赏金..;)我也怀疑这个可能对其他几个人有价值,因为我看过类似的请求,但没有工作实现(这只是一个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获取文章主题列表后,可以通过更改一些相当标准的突出显示脚本来实现此功能。
重新投入:我们正在使用内部维基,所以文章列表可能有限,不含糊不清,特定领域足以克服匹配单词中的一些预期问题。

由于我们到目前为止已经提出了一些很好的建议,以及一些可行的想法,我开始赏金,看看能不能就此得到一些答案。

2 个答案:

答案 0 :(得分:5)

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

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

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

两个非常小的脚本。

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');

termlinker.js只是一个简单的regexp搜索替换定义的术语。它也可以是内联<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>"; });

// 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);

这只是搜索术语数组中的任何单词,并用指向该术语的链接替换它们。当然,它也会匹配HTML标记内的属性和值,这可能会破坏您的标记。

所有人一起抛出this (jsbin preview)


使用API​​

基于之前的“最小案例”,以下是使用API​​直接接收单词列表的代码示例the jsbin preview

{{1}}

答案 1 :(得分:0)

使用更通用的超链接预览脚本(如 Linkz.ai)可以获得类似的体验。只需将定义超链接到维基百科文章,脚本就会显示其定义。

  1. https://linkz.ai 处注册 API 密钥

  2. 将以下代码段添加到您的网页中: