加载中...
不想等待可以点我关掉

前言

一直以来我都面临着一个问题:我要在文章中引用一段大几百行的代码,一眼看去md文件里5/6都是英文,要是有改动还得找到代码快开始的地方从头覆盖到尾。

前一阵子发现gist,对他的Embed爱不释手,但是我所引用的文件大部分都是在Github仓库上的,而对于普通文件并没有Embed功能。如果说直接用gist的话文件发生改动时我又要手动将更改覆盖到gist上,屮,太痛了。

思路

从解决痛点问题出发,我认为需要具备以下功能。

  1. 类似gist可以嵌入到页面中

  2. 自动同步改动

对gist提供嵌入的js分析了一下,发现它包括两部分:

  1. 插入代码区,这部分包括已进行高亮的代码

  2. 引入css

那接下来就好办了,我们只需要将文件内容获取下来,进行高亮后显示即可。

然后从网上搜了一下,能进行代码高亮的库,发现了highlight(js)以及pygments(py)。 对于纯静态博客而言,肯定是使用highlight直接在前端处理好,但是这可能产生跨域问题以及因为网络问题无法获取到文件内容。况且现在无服务器函数遍地走了,那就直接pass掉吧。翻了下pygments的文档,嗯,懂了,开整。

写code

这简单,跳过了

部署🎇

因为我是直接用Vercel的cli进行部署的,所以这一步需要先安装一下

也可以直接部署: Develop To Vercel

$

然后登录

$

再clone下仓库到本地,你可以打开api\main.py来修改一下/删除提供者信息

$

如有需要,可在vercel.json里配置可信来源,防止滥用

部署到生产环境

$

若出现Vercel报错Error: Unable to find any supported Python versions.记得把项目的node版本改成 18.x

随后引用即可

1
<script src="https://{yourdomain}/api/v1/generate?url={fileurl}&lang={language}"></script>

{fileurl}为所需引入文件的链接,{language}为对应语言(自动识别我试了下精准度堪忧,只好手动指定

可传入参数:

参数名默认值解释
code\需要的高亮的代码
url\需要的高亮的代码的链接
lang[为空时根据后缀名判断]语言
withcsstrue是否附带css
jsonfalse是否以json形式返回({“result”: “…”})

扩展

更便捷的使用

诚然,修改主题来添加coding标签是一种更高效的方法,所以我跑路了

文章在这里Coding远程代码标签 - 星日语~

我修改了部分以兼容新版本:

themes/stellar/scripts/tags/lib/coding.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/**
* coding.js v1.1 | https://github.com/thun888/hexo-theme-stellar/
* 格式与官方标签插件一致,使用空格分隔;中括号内的是可选参数(中括号不需要写出来)
*
* {% coding url [lang:string] [withcss:boolean] %}
*/

'use strict'

module.exports = (ctx) => {
return function (args) {
// 映射并提取参数
args = ctx.args.map(args, ['lang', 'withcss'], ['url'])

// 获取 API 地址并去除末尾斜杠
const api = ctx.theme.config.tag_plugins.coding?.api.replace(/\/$/, '')

// 拼接完整的请求 URL
args.url = api + '/api/v1/generate?usejson=true&showsupporter=false' + '&url=' + args.url + '&lang=' + args.lang

// 设置默认 withcss 参数
args.withcss = args.withcss || 'true'

// 构造最终的 HTML 元素字符串
let el = ''
el += `<div class="tag-plugin ds-coding" `
el += ctx.args.joinTags(args, ['url', 'withcss']).join(' ')
// 懒加载
el += ' lazyload'
el += '>'
el += '</div>'

return el
}
}

themes/stellar/source/js/services/coding.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// 前端处理的
utils.jq(() => {
$(function () {
const els = document.getElementsByClassName('ds-coding');
let cssLoaded = false;

for (let i = 0; i < els.length; i++) {
const el = els[i];

const loadContent = () => {
const srcBase = el.getAttribute('url');
const css = el.getAttribute('withcss') === 'true';
let src = srcBase;

if (css && !cssLoaded) {
utils.css('https://static.hzchu.top/pygments-css/default.css');
cssLoaded = true;
}

utils.request(el, src, async (resp) => {
const data = await resp.json();
$(el).append(data.result);
});
};

const lazyload = el.hasAttribute('lazyload');
util.viewportLazyload(el, loadContent, lazyload);
}
});
});

static.hzchu.top下资源开启了防盗链,请使用 https://cdn.jsdelivr.net/gh/thun888/assets@master/files/pygments-css/default.css替代

样式参考:Styles — Pygments

@星日语的启发,我做了个插件:hexo-dynamic-codeblock

安装:

$

配置:

_config.yml
1
2
3
4
5
dynamic_codeblock:
loading: true
showsupporter: true
api: https://{yourdomain}/api/v1/generate
css: https://jsd.hzchu.top/gh/thun888/assets@master/files/pygments-css/default.css

loading只针对Stellar主题。同时,为使copycode正常工作,你需要将/js/plugins/copycode.js修改为这样

使用:

1
{% coding [url] [lang] %}

在其它主题中的表现:

landscape
landscape

从传统方式迁移:

​ 使用正则表达式,将<script src="https://hightlight-code-api\.hzchu\.top/api/v1/generate\?url=(.*)&lang=(.*)"></script>替换为{% coding $1 $2 %}

Todo

  • [ ] 添加 /preview

效果

该处引用本程序代码

1
<script src="https://hightlight-code-api.hzchu.top/api/v1/generate?url=https://raw.githubusercontent.com/thun888/hightlight-code-api/main/api/main.py&lang=python"></script>