• 引入代码来源:深入分析markdown-it-quote插件的魔法


    引入代码来源:深入分析markdown-it-quote插件的魔法

    NPM版本

    markdown-it-quote是一个用于markdown-it的插件,支持多种代码围栏功能。

    image

    这是 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"
    

    /package.json?#L7-L7

    • 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);
            }
        }
    ```
    

    /source/README.md?#L31-L40

    完整的可以参考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];
    

    /src/index.js?#L7-L11

    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;
    

    /src/index.js?#L1-L5

    image

    https://regex101.com/r/osOtEv/1

    高亮支持

    对于高亮的支持,需要支持两种形式,一种是

    • 起始行-结束行
    • 通过,分割的单行
          lines.map((split, index) => {
            const lineNumber = index + wrapLineNumStart;
            lineNumbersCode += `${lineNumber}
    `
    ; 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 += `
     
    `
    ; } else { highlightWrapCode += `
    `
    ; } } });

    /src/index.js?#L136-L155

    链接的定义

          const gistInfo = ``;
    
    

    /src/index.js?#L168-L169
    这里通过解析到 url 转换成html格式,点击 view raw 即新窗口打开原始的代码源链接。

    这里如果不通过这种新的markdown格式,也可以仅采用默认代码块,然后加一条链接的形式,指明你的代码来源。

    贡献

    如果您想为此项目做出贡献,请按照以下步骤进行:

    1. Fork仓库。
    2. 创建您的特性分支:git checkout -b my-new-feature
    3. 提交您的更改:git commit -am 'Add some feature'
    4. 推送到分支:git push origin my-new-feature
    5. 提交拉取请求 😄

    作者

    markdown-it-quote10cl编写和维护,并在MIT许可证下发布。

    希望得到各位老铁的支持,使这个项目变得更好。

  • 相关阅读:
    关于python类中的魔法方法
    【分享】“MySQL“在集简云平台集成应用的常见问题与解决方案
    在 ubuntu20.04 上安装 Pytorch
    【this指针】
    idea2023+springboot 热部署配置
    手记系列之六 ----- 分享个人使用kafka经验
    全球电梯空气消毒机行业调研及趋势分析报告
    第10章_索引优化与查询优化
    理解subplots, ax.imshow, FuncAnimation
    Nvidia 硬件架构
  • 原文地址:https://www.cnblogs.com/webers/p/markdown-it-quote.html