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

问题描述:

我希望降价链接在转换后的链接中有一个收藏图标。如何将markdown()中的链接转换为使用Google S2 Converter的favicon链接?

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

标记(https://github.com/chjj/marked) - 会变成我的代码中的所有链接到一个HREF的

所以,我将如何修改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个marked.js autolink: /^<([^ >]+(@|:\/)[^ >]+)>/, 编号:https://github.com/chjj/marked/blob/master/lib/marked.js

我使用expressjs和的NodeJS

感谢 罗布

你可以override a renderer method

有标记的作品分两步进行:(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链接的域名。或者,如果文本根本不包含链接(因为所有链接都使用相同的呈现器,而不仅仅是自动链接),那么文本应该保持不变。我将这些改进留给读者作为练习。

+0

谢谢,谷歌S2转换器似乎处理大部分包含域的链接,但我认为有时会出现子域问题。这个例子的作品: \t Sample long link with Google S2 mrmccormack

+0

看来,*使用链接描述truncator对所有评论...出于同样的原因,我想在可能ExpressJS应用程序。 – mrmccormack

你不必混淆标记的源代码。

这个简单的正则表达式应该做的伎俩:

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; 
}); 
+0

我更新了答案以满足新要求。虽然没有足够的声望来评论任何内容,但这篇文章。 –

+0

您的更新答案完美运作。我不确定采取哪种方法,覆盖渲染方法或您的方法。我认为很多人可能会将它作为标记()中的内置功能。对于我的应用程序,我只有简单的网页链接。 – mrmccormack

+0

那么如果你问我,我仍然坚持这一个,因为我不喜欢重复的代码。但是,如果性能是问题,则另一种变体更可取,因为使用regexp没有额外开销。 –