如何使用 Google S2 Converter 将 markdown() 中的链接转换为与 favicon 链接?

Posted

技术标签:

【中文标题】如何使用 Google S2 Converter 将 markdown() 中的链接转换为与 favicon 链接?【英文标题】:How to transform link in markdown() to link with favicon using Google S2 Converter? 【发布时间】:2018-03-31 21:13:43 【问题描述】:

我希望 Markdown 链接在转换后的链接中有一个网站图标。

https://www.google.com/s2/favicons?domain=http://cnn.com - 将返回来自任何域的网站图标。

标记 (https://github.com/chjj/marked) - 将我代码中的所有链接转换为 href 的

http://cnn.com 变成 <a href="http://cnn.com">http://cnn.com</a>

那么,我将如何修改marked.js 以便 - http://cnn.com

会变成 <a href="http://cnn.com"><img src="https://www.google.com/s2/favicons?domain=http://cnn.com">http://cnn.com</a>

我确实看到了这行 452 标记的.js autolink: /^<([^ >]+(@|:\/)[^ >]+)>/, 参考: https://github.com/chjj/marked/blob/master/lib/marked.js

我正在使用 expressjs 和 NodeJS

谢谢 抢

【问题讨论】:

【参考方案1】:

你可以override a renderer method。

Marked 分两个步骤工作:(1) 它将 Markdown 解析为一堆标记;(2) 将这些标记呈现为 html。由于您不想更改 Markdown 解析(它已经正确识别链接),但您确实想更改 HTML 输出,因此您想覆盖链接的渲染器。

var renderer = new marked.Renderer();

get_favicon = function (text) 
    // return replacement text here...
    var out = '<img src="https://www.google.com/s2/favicons?domain='
    out += text + '">' + text + '</a>'
    return out


renderer.link = function (href, title, text) 
  if (this.options.sanitize) 
    try 
      var prot = decodeURIComponent(unescape(href))
        .replace(/[^\w:]/g, '')
        .toLowerCase();
     catch (e) 
      return '';
    
    if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0 || prot.indexOf('data:') === 0) 
      return '';
    
  
  var out = '<a href="' + href + '"';
  if (title) 
    out += ' title="' + title + '"';
  
  out += '>' + get_favicon(text) + '</a>';
  return out;
;


// Pass the custom renderer to marked with the input.
markdown(input, renderer=renderer)

请注意,我只是使用了 default link method 并对其稍作修改以通过 get_favicon 函数传递 textget_favicon 函数接受文本字符串并返回替换文本(在本例中为图像)。它可能会得到改进,因为并非所有链接都只有一个域作为其文本内容。如果文本包含的域多于域(路径、片段、查询字符串等),则仅将域用于 favicon 链接。或者,如果文本根本不包含链接(因为所有链接都使用相同的渲染器,而不仅仅是自动链接),那么文本应该原封不动地返回。我会将这些改进留给读者作为练习。

【讨论】:

谢谢,Google S2 转换器似乎可以处理大多数包含远不止域的链接,但我认为有时子域会出现问题。这例如有效: ***.com/questions/7653483/…"> google.com/s2/favicons?domain=https://***.com/… 与 Google S2 的长链接 看来 *** 正在所有 cmets 上使用链接描述截断器......出于同样的原因,我想在可能的 ExpressJS 应用程序中使用。【参考方案2】:

您不必弄乱标记的源代码。

这个简单的正则表达式应该可以解决问题:

const markedOutput = '<a href="http://cnn.com">http://cnn.com</a>';
const withFavIcons = markedOutput.replace(/(<a[^>]+>)(https?:\/\/[^<]+)(<\/a>)/gi, (m, open, url, close) => 
    const favicon = '<img src="https://www.google.com/s2/favicons?domain=' + url + '">';
    const truncated = url.length > 50 ? url.slice(0, 47) + '...' : url;
    return open + favicon + truncated + close;
);

【讨论】:

我更新了我的答案以满足新的要求。没有足够的声誉来评论除此帖子之外的任何内容。 您更新后的答案效果很好。我不确定要采用哪种方法,覆盖渲染方法或您的方法。我认为很多人可能希望将此作为标记()中的内置功能。对于我的应用,我只有简单的网络链接。 好吧,如果你问我,我仍然会坚持使用这个,因为我不喜欢重复代码。但是,如果性能是问题,则其他变体更可取,因为使用正则表达式没有额外的开销。 我想知道是否可以将 YouTube 缩略图用于图像而不是网站图标,缩略图很容易获取。 img.youtube.com/vi/erLk59H86ww/1.jpg 是视频链接的拇指:youtube.com/watch?v=erLk59H86ww 谢谢, 这有点离题了。

以上是关于如何使用 Google S2 Converter 将 markdown() 中的链接转换为与 favicon 链接?的主要内容,如果未能解决你的问题,请参考以下文章

Google S2 对 Hilbert Curve 的使用如何解决(如果不是,则最小化)具有不同前缀值的更接近单元格的问题,例如 Geohash 中的问题?

高效的多维空间点索引算法 — Geohash 和 Google S2

高效的多维空间点索引算法 — Geohash 和 Google S2

电源硬件设计----全桥变换器(Full-Bridge Converter)基础

电源硬件设计----半桥变换器(Half-Bridge Converter)基础

电源硬件设计----半桥变换器(Half-Bridge Converter)基础