【问题标题】:Link terms on page to Wikipedia articles in pure JavaScript使用纯 JavaScript 将页面上的术语链接到 Wikipedia 文章
【发布时间】:2010-02-27 16:12:27
【问题描述】:

在浏览时,我遇到了this blog post,关于使用来自JavaScriptWikipedia API,将单个搜索词链接到它的定义。在博文末尾,作者提到了可能的扩展,包括:

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

这完全符合我正在处理的项目要求,但遗憾的是我缺乏扩展the original source code 的编程技能。我想要的是有一个纯 JavaScript sn-p 我可以添加到网页中,它将该网页上所有在内部 wiki 上有文章的术语链接到该 wiki。

我知道这可能要求很多,但代码看起来差不多了,如果有人愿意为该虚拟信用完成剩余的工作,我愿意增加赏金.. ;) 我也怀疑这一点可能对其他一些人有价值,因为我已经看到了类似的请求,但没有有效的实现(这只是一个 JavaScript(因此是可移植的)库/sn-p 包含)。

这是原始源代码的示例,我希望任何人都能够添加到这个或指出我需要添加的内容,如果我自己实现这个(在这种情况下,我会分享代码,如果我设法把一些东西放在一起)。

<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>

更新
正如 cmets 中所指出的,链接所有单词所需的时间以及如何处理多个跨单词的文章名称也是我关心的问题。

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

不过,从好的方面来说,这都是客户端,链接条款的一些延迟是完全可以接受的。

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


更新 2

“Pointy”在下面解释说,在从api.php?action=query&amp;list=allpages 获得文章主题列表后,可以通过更改一些相当标准的突出显示脚本来实现此功能。
重申一下:我们使用的是内部 wiki,因此文章列表可能是有限的、明确的和特定领域的,足以克服匹配单词中的一些预期问题。

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

【问题讨论】:

  • 脚本应该如何知道页面中的哪些术语(单词?短语?)在 wiki 上有文章?
  • 提供的代码检查维基百科上是否存在具有给定名称的文章。恐怕它与将您页面上的术语链接到 Wiki 文章无关。
  • 啊,我明白了——如果“本地 wiki”支持 JSONP 回调,那么他当然可以这样做。我想知道您将如何处理多词 Wiki 条目——您如何知道要检查哪些多词序列?检查所有这些?所有这些 wiki HTTP 搜索事务需要多长时间?
  • 如果他想自动将他页面上的所有术语链接到 Wiki 文章,他必须对页面上的每个单词都运行一个 HTTP 请求......这不好。另外,正如 Pointy 所说,脚本如何找到多词 Wiki 文章?基本上不会。
  • 如果提问者可以控制 Wiki,那么一种可能性是制作一个返回当前术语“字典”的 Wiki API。这样脚本就可以获取一大块单词,然后在每一页上搜索这些单词。此脚本:tinyurl.com/6rk6ae 可用于添加标记。

标签: javascript wikipedia wikipedia-api


【解决方案1】:

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

假设像这样非常简单的 HTML/文本:

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

还有两个非常小的脚本。

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

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

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

termlinker.js 只是对已定义术语的简单正则表达式搜索替换。它也可以是内联的&lt;script&gt;。要求 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 标记中的属性和值,这可能会破坏您的标记。

全部放在一起就可以得到this (jsbin preview)


使用 API

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

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

【讨论】:

  • 好的开始,你有没有机会将它与 json api.php?action=query&amp;list=allpages 调用或另一个 api.php 查询结合起来以获取主题标题?我正在寻找纯 Javascript 的东西,所以 PHP 不是一个真正的选择..(如上所述,我几乎不知道 Javascript,所以我需要的不仅仅是一个开始..)
  • 干得好,谢谢!然而,不利的一面是,我发现我现在必须升级我们的本地 wiki 实例以实现 API 兼容性..
  • @gnarf - 有什么方法可以绕过“为了演示目的,我们限制在 500 个条款”的限制?我正在模仿维基百科文章自动超链接的完整维基百科功能。 - - 非常感谢。 --- 我还发布了一个自动超链接到 predefined Wikipedia-articles 的帖子,这样就不会重定向到歧义页面:Auto-hyperlink every occurence of a certain word (or word sequence) to predefined URL (non-ambiguous); but not show full URL,这个帖子仍然需要一些思考。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-15
  • 1970-01-01
  • 2010-09-12
  • 2019-04-20
相关资源
最近更新 更多