引入代码来源:深入分析markdown-it-quote插件的魔法
引入代码来源:深入分析markdown-it-quote插件的魔法
markdown-it-quote是一个用于markdown-it的插件,支持多种代码围栏功能。

这是 SourceCodeTrace 项目之一,提供一种 Markdown Fence 的解析方案,包括对代码块的引用、高亮、链接等功能。
SourceCodeTrace Project 帮助您在博客、文章记录的过程中,引入对应项目以及版本,行号等信息,让后续的读者,通过引用来源,能够进行更加深入的学习,在博客或文章中引入代码块时,尽量提供代码的来源信息。
对于新的Markdown格式,如果你觉得写起来很复杂, 可以用 MarkdownQuote 插件,让你在IDE中高效地复制代码块。
更多细节请参阅 SourceCodeTrace 项目。
Markdown 写法
以下是一些用法示例,演示代码块包含的不同信息,方便大家在博客的记录中,引入代码块的来源信息。
代码块归属 第3125到3131行,并且将第3126到3130行标记为高亮,并链接到URL:
```java {3125-3131} {3129,3131} (https://github.com/10cl/fwkdev/blob/android-13.0.0_r52/dev/src/frameworks/base/services/core/java/com/android/server/am/OomAdjuster.java#L3125-L3131)
// 冻结时使用当前调整,解冻时设置调整。
if (state.getCurAdj() >= ProcessList.CACHED_APP_MIN_ADJ && !opt.isFrozen()
&& !opt.shouldNotFreeze()) {
mCachedAppOptimizer.freezeAppAsyncLSP(app);
} else if (state.getSetAdj() < ProcessList.CACHED_APP_MIN_ADJ) {
mCachedAppOptimizer.unfreezeAppLSP(app, oomAdjReason);
}
}
代码块归属 第3125到3131行,并链接到URL:
```java {3125-3131} (https://github.com/10cl/fwkdev/blob/android-13.0.0_r52/dev/src/frameworks/base/services/core/java/com/android/server/am/OomAdjuster.java#L3125-L3131)
// 冻结时使用当前调整,解冻时设置调整。
if (state.getCurAdj() >= ProcessList.CACHED_APP_MIN_ADJ && !opt.isFrozen()
&& !opt.shouldNotFreeze()) {
mCachedAppOptimizer.freezeAppAsyncLSP(app);
} else if (state.getSetAdj() < ProcessList.CACHED_APP_MIN_ADJ) {
mCachedAppOptimizer.unfreezeAppLSP(app, oomAdjReason);
}
}
只链接到URL:
```java (https://github.com/10cl/fwkdev/blob/android-13.0.0_r52/dev/src/frameworks/base/services/core/java/com/android/server/am/OomAdjuster.java#L3125-L3131)
// 冻结时使用当前调整,解冻时设置调整。
if (state.getCurAdj() >= ProcessList.CACHED_APP_MIN_ADJ && !opt.isFrozen()
&& !opt.shouldNotFreeze()) {
mCachedAppOptimizer.freezeAppAsyncLSP(app);
} else if (state.getSetAdj() < ProcessList.CACHED_APP_MIN_ADJ) {
mCachedAppOptimizer.unfreezeAppLSP(app, oomAdjReason);
}
}
仅高亮第1至2行:
```java {1-2}
// 冻结时使用当前调整,解冻时设置调整。
if (state.getCurAdj() >= ProcessList.CACHED_APP_MIN_ADJ && !opt.isFrozen()
&& !opt.shouldNotFreeze()) {
mCachedAppOptimizer.freezeAppAsyncLSP(app);
} else if (state.getSetAdj() < ProcessList.CACHED_APP_MIN_ADJ) {
mCachedAppOptimizer.unfreezeAppLSP(app, oomAdjReason);
}
}
高亮第3行:
```java{3}
// 冻结时使用当前调整,解冻时设置调整。
if (state.getCurAdj() >= ProcessList.CACHED_APP_MIN_ADJ && !opt.isFrozen()
&& !opt.shouldNotFreeze()) {
mCachedAppOptimizer.freezeAppAsyncLSP(app);
} else if (state.getSetAdj() < ProcessList.CACHED_APP_MIN_ADJ) {
mCachedAppOptimizer.unfreezeAppLSP(app, oomAdjReason);
}
}
仅指定语言:
```java
// 冻结时使用当前调整,解冻时设置调整。
if (state.getCurAdj() >= ProcessList.CACHED_APP_MIN_ADJ && !opt.isFrozen()
&& !opt.shouldNotFreeze()) {
mCachedAppOptimizer.freezeAppAsyncLSP(app);
} else if (state.getSetAdj() < ProcessList.CACHED_APP_MIN_ADJ) {
mCachedAppOptimizer.unfreezeAppLSP(app, oomAdjReason);
}
}
使用方法
要使用markdown-it-quote,首先通过NPM安装该包:
npm i markdown-it-quote
然后,您可以在JavaScript代码中这样使用它:
const MarkdownIt = require('markdown-it');
const markdownQuote = require('markdown-it-quote');
const md = new MarkdownIt();
md.use(markdownQuote);
md.render(markdownString);
请注意,语言名称和左大括号之间的高亮行是可选的。
为了增加自定义样式,您可以使用以下CSS代码为代码引入链接一些自定义样式:
.gist-meta-quote {
font-size: 12px;
padding: 10px;
overflow: hidden;
color: white;
border-radius: 0 0 6px 6px;
}
.gist-meta-quote a {
float: right;
color: white;
text-decoration: underline;
}
vurepress 使用详解
- package.json 中引入依赖
"markdown-it-quote": "^1.0.3"
- config.json 里面加入 markdown 拓展
markdown: {
extendMarkdown: md => {
const markdownQuote = require('markdown-it-quote')
md.use(markdownQuote);
}
},
/source/.vuepress/config.js?#L12-L17
- md 文件中直接用新的形式来写代码
```java {3125-3131} {3126-3130} (https://github.com/10cl/fwkdev/blob/android-13.0.0_r52/dev/src/frameworks/base/services/core/java/com/android/server/am/OomAdjuster.java#L3125-L3131)
// Use current adjustment when freezing, set adjustment when unfreezing.
if (state.getCurAdj() >= ProcessList.CACHED_APP_MIN_ADJ && !opt.isFrozen()
&& !opt.shouldNotFreeze()) {
mCachedAppOptimizer.freezeAppAsyncLSP(app);
} else if (state.getSetAdj() < ProcessList.CACHED_APP_MIN_ADJ) {
mCachedAppOptimizer.unfreezeAppLSP(app, oomAdjReason);
}
}
```
完整的可以参考Vuepress集成的patch。
随心定制样式以适合您自己的需要。
原理解析
fence 拓展
export default (md) => {
const fence = md.renderer.rules.fence;
md.renderer.rules.fence = (...args) => {
const [tokens, idx, options, , self] = args;
const token = tokens[idx];
markdown-it 的拓展是通过重写 md.renderer.rules.fence 来实现对 fence的重新解析。
关键格式的解析
通过解析得到核心的解析块
java {3125-3131} {3129,3131} (https://github.com/10cl/fwkdev/blob/android-13.0.0_r52/dev/src/frameworks/base/services/core/java/com/android/server/am/OomAdjuster.java#3125-L3131)
从中解析出 代码块所在的起始行、结束行、高亮块、以及链接。
然后通过预定义的模板将其渲染出来。
从用户的角度来说,其中核心的要点就是要支持多种格式,比如原始的格式,以及为了推动代码块来源的可追溯性,还需要支持之前默认的格式。
核心的几块逻辑,就是通过正则表达式来解析出来的。
const regex1 = /(\S+)\s?(\{([\d,-]+)})\s?(\{([\d,-]+)})\s?([\S]+)/i;
const regex2 = /(\S+)\s+(\{\d+-\d+\})?\s+(\S+)/i;
const regex3 = /(\S+)\s?(\{([\d,-]+)})/i;
const regex4 = /(\S+)\s+([^\{]\S+)/i;
const regex5 = /(\S+)/i;

https://regex101.com/r/osOtEv/1
高亮支持
对于高亮的支持,需要支持两种形式,一种是
- 起始行-结束行
- 通过,分割的单行
lines.map((split, index) => {
const lineNumber = index + wrapLineNumStart;
lineNumbersCode += `<span class="line-number">${lineNumber}</span><br>`;
let inRange = false;
if (highLightLineNumbers !== undefined) {
inRange = highLightLineNumbers.some(([start, end]) => {
if (start && end) {
return lineNumber >= start && lineNumber <= end;
}
return lineNumber === start;
});
if (inRange) {
highlightWrapCode += `<div class="highlighted"> </div>`;
} else {
highlightWrapCode += `<br>`;
}
}
});
链接的定义
const gistInfo = `<div class="gist-meta-quote"><a href="${linkUrl}" target="_blank">view raw</a></div>`;
/src/index.js?#L168-L169
这里通过解析到 url 转换成html格式,点击 view raw 即新窗口打开原始的代码源链接。
这里如果不通过这种新的markdown格式,也可以仅采用默认代码块,然后加一条链接的形式,指明你的代码来源。
贡献
如果您想为此项目做出贡献,请按照以下步骤进行:
- Fork仓库。
- 创建您的特性分支:
git checkout -b my-new-feature - 提交您的更改:
git commit -am 'Add some feature' - 推送到分支:
git push origin my-new-feature - 提交拉取请求
作者
markdown-it-quote由10cl编写和维护,并在MIT许可证下发布。
希望得到各位老铁的支持,使这个项目变得更好。
引入代码来源:深入分析markdown-it-quote插件的魔法的更多相关文章
- Markdown For EditPlus插件发布(基于EditPlus快速编辑Markdonw文件,写作爱好的福音来啦)
详细介绍: Markdown For EditPlus插件使用说明 开发缘由 特点好处: 中文版使用说明 相关命令(输入字符敲空格自动输出): EditPlus常用快捷键: 相关教程: English ...
- Markdown For EditPlus插件使用说明(基于EditPlus快速编辑Markdonw文件,写作爱好者的福音来啦)
Markdown For EditPlus插件使用说明 开发缘由 特点好处: 中文版使用说明 相关命令(输入字符敲空格自动输出): EditPlus常用快捷键: 相关教程: English descr ...
- Markdown学习和插件介绍
markdown能干啥 亲们github上的项目首页的 内容+样式,都是项目中README.md文件控制的.将md风格的代码,转化成html. 而且markdown语法非常简单,5-10分钟即可学会! ...
- SpringBoot入门篇--整合mybatis+generator自动生成代码+druid连接池+PageHelper分页插件
原文链接 我们这一篇博客讲的是如何整合Springboot和Mybatis框架,然后使用generator自动生成mapper,pojo等文件.然后再使用阿里巴巴提供的开源连接池druid,这个连接池 ...
- MarkDown的vim插件安装
作用:可以使markdown语法高亮.1.安装.使用pathogen插件管理. cd ~/.vim/bundle git clone https://github.com/plasticb ...
- uni-app微信小程序开发之引入腾讯视频小程序播放插件
登录微信小程序管理后台添加腾讯视频播放插件: 正式开始使用腾讯视频小程序插件之前需先在微信公众平台 -> 第三方设置 -> 插件管理处添加插件,如下图所示: 在uni-app中引入插件代码 ...
- Sublime Markdown预览插件安装流程
使用方法 在sublime中已编辑好的markdown使用快捷键 Alt+M 即可在浏览器预览效果. 需要安装的插件 Markdown Editting:主要用来做 Markdown 编辑时的语法高亮 ...
- 《Three.js 入门指南》3.1.2 - 一份整齐的代码结构以及使用ORBIT CONTROLS插件(轨道控制)实现模型控制
3.1.2 正式代码结构 & ORBIT CONTROLS插件(轨道控制) 说明 本节内容属于插入节,<Three.js入门指南>这本书中,只是简单的介绍了一些概念,是一本基础的入 ...
- 80行代码教你写一个Webpack插件并发布到npm
1. 前言 最近在学习 Webpack 相关的原理,以前只知道 Webpack 的配置方法,但并不知道其内部流程,经过一轮的学习,感觉获益良多,为了巩固学习的内容,我决定尝试自己动手写一个插件. 这个 ...
- ubuntu自带的gedit编辑器添加Markdown预览插件
gedit安装Markdown Preview Ubuntu自带的gedit编辑器也是有很强大的功能的,且支持插件的安装.对于喜欢用Markdown的我来说,这当然是很好的了,gedit本身 就支持M ...
随机推荐
- Uniswap V2 — 从代码解释 DeFi 协议
Uniswap V2 - 从代码解释 DeFi 协议 为了理解我们在分析代码时将要经历的不同组件,首先了解哪些是主要概念以及它们的作用是很重要的.所以,和我一起裸露吧,因为这是值得的. 我在 5 个段 ...
- 世界读书日:推荐15本AI从入门到放弃的书
hi,我是熵减,见字如面. 在世界读书日即将到来的前,以及借着ChatGPT的火热,各种AI大模型的创业东风,今天给大家推荐一些AI相关的图书,希望大家能从入门到放弃,找到适合自己的热爱. 本次推荐图 ...
- python 快速替换csv数据集字符串列表中的表情符号为空,asyncio,re,pandas
传统的字符串列表替换字符串使用遍历非常慢 比如下面这段代码,如果处理几十万或上百万的数据集时,会非常的慢,几小时几天都可能 import re p = re.compile(u'['u'\U0001F ...
- Gusfield算法学习
算法详解 等价流树正如其名,树上两点间的路径上的边权最小值为图上两点间的最小割. Gusfield算法就是建等价流树的一种算法.设当前正在处理的集合为 \(S(|S|\ge 2)\),从 \(S\) ...
- 群论中的 Lagrange 定理
今天跟 hym 打球时讲到了这个东西,突然发现证明拉格朗日定理的思想有许多跟轨道-稳定集定理很像,所以这里又记录一下. 为了证明 Lagrange 定理,我们需要了解一些关于子群和陪集的性质. 首先给 ...
- Azure DevOps(三)Azure Pipeline 自动化将程序包上传到 Azure Bolb Storage
一,引言 结合前几篇文章,我们了解到 Azure Pipeline 完美的解决了持续集成,自动编译.同时也兼顾了 Sonarqube 作为代码扫描工具.接下来另外一个问题出现了,Azure DevOp ...
- 一文梳理z-index和层叠上下文
前言 最近参与某前端项目架构改造,发现项目中滥用z-index,设置的值有几十种并且不统一.在对项目的z-index进行梳理和统一过程中也深入学习了一下z-index,并撰写成文,希望也能帮助到陌生的 ...
- MVC 三层架构案例详细讲解
MVC 三层架构案例详细讲解 @ 目录 MVC 三层架构案例详细讲解 每博一文案 1. MVC 概述 2. MVC设计思想 3. 三层架构 4. MVC 与 三层架构的关系: 5. 案例举例:用户账户 ...
- Luogu1772 [ZJOI2006] 物流运输
传送门 简化题意 给你 \(m\) 个码头,码头之间有双向边连接,\(n\) 天,其中一些码头在某些天会不可用,这 \(n\) 天都要有一条从 \(1\) 到 \(m\) 的路,每一次更换道路会需要 ...
- flutter 中使用 WebView加载H5页面异常net:ERR_CLEARTEXT_NOT_PERMITTED
最近有个flutter项目中根据搜索结果跳转到相应的H5页面发现老是报错,曾现在闲暇拉出来解决哈 先来看一个搜索功能的测试 已进入详情页面就提示错误,尴尬了. 只有去检测代码了撒 Search.dar ...