{"componentChunkName":"component---src-templates-blog-post-js","path":"/how-to-contribute-to-open-source-project/","result":{"data":{"site":{"siteMetadata":{"title":"星雨之夜"}},"markdownRemark":{"id":"692f9132-6a9f-5f41-abf6-a64094260c88","excerpt":"在写 「The Little Schemer」知识点整理 系列的时候，理想状态是我一口气把书看完，并快速概括出其中的要点并写下来。往往事与愿违。本文就是阅读此书过程中，“一口气”被分割成好几口气之后的附属品，根据这几天在 GitHub 上提交的几个有关代码高亮的 PR，谈谈前因后果以及心得体会。…","html":"<p>在写 <a href=\"https://saintwinkle.com/tags/The-Little-Schemer/\">「The Little Schemer」知识点整理</a> 系列的时候，理想状态是我一口气把书看完，并快速概括出其中的要点并写下来。往往事与愿违。本文就是阅读此书过程中，“一口气”被分割成好几口气之后的附属品，根据这几天在 GitHub 上提交的几个有关代码高亮的 PR，谈谈前因后果以及心得体会。</p>\n<!-- more -->\n<h2>1. 博客的代码高亮问题</h2>\n<h3>1.1 起因</h3>\n<p>我在写到系列第三篇时，文章里的代码块比较多，却基本没有高亮。本着就算不是对读者，对自己来说观感也不佳的想法，开始着手解决这个问题。</p>\n<h3>1.2 经过</h3>\n<p>首先分析具体现象，发现不支持 <code class=\"language-text\">scheme</code> 的语法高亮，以前文章里所用到的 <code class=\"language-text\">js</code> <code class=\"language-text\">bash</code> 等语言就没有问题。</p>\n<p>于是我们从源头——此博客的生成框架—— <a href=\"https://github.com/hexojs/hexo\">Hexo</a> 开始一步步查找原因：</p>\n<ol>\n<li>阅读其源码可以知道，它使用了业界运用最广泛的 <a href=\"https://github.com/highlightjs/highlight.js\">highlight.js</a> 来高亮代码；</li>\n<li>再看 highlight.js 文档，发现它是支持像 Scheme 这样的 Lisp 语言的高亮的；</li>\n<li>而后查看生成文章的页面元素，按照 Hexo 和 highlight.js 的设置，格式正确无误。</li>\n</ol>\n<p>排除了框架自身的原因后，我们来看看主题部分。博客现在使用 <a href=\"https://github.com/theme-next/hexo-theme-next\">NexT</a> 主题，按照如下步骤寻找问题：</p>\n<ol>\n<li>找到主题里设置高亮部分的 css，与 highlight.js 对 Scheme 语言的设置进行对比；</li>\n<li>我们发现，在 <a href=\"https://github.com/highlightjs/highlight.js/commit/8616294df138a2895cd71fcb9a1483a1ce00b143\">highlightjs/highlight.js@<code class=\"language-text\">8616294</code></a> 这个 commit 里，引入了对 Lisp 语言更好的支持，其中新的 <code class=\"language-text\">builtin-name</code> 是 NexT 所欠缺的。</li>\n</ol>\n<h3>1.3 结果</h3>\n<p>解决方案：<a href=\"https://github.com/theme-next/hexo-theme-next/pull/492\">theme-next/hexo-theme-next#<code class=\"language-text\">492</code></a></p>\n<p>经过测试，证明上面得出的结论无误，只要在主题里的高亮部分也引入 <code class=\"language-text\">builtin-name</code> 这个新的 css class 就可以实现对 Scheme 的高亮。回去看之前的几篇文章，可以看到代码块的关键字部分已经被高亮为橘色。</p>\n<h2>2. Markdown 文件的代码高亮问题</h2>\n<h3>2.1 起因</h3>\n<p>我是在 Typora 下完成的前三章整理，写作体验相当不错。但是当我从第四章开始使用 VS Code 书写 Markdown 之后，又出现了新的问题：Scheme 代码块不能被高亮，只有预览才可以。</p>\n<h3>2.2 经过</h3>\n<p>有了刚才的经验，我们先与现有的比较，发现常用语言表现良好。</p>\n<p>继续。源头指向 VS Code，查看源码我们找到它用来描述 markdown 的文件： <code class=\"language-text\">/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json</code>。可以看到里面有大量 <code class=\"language-text\">fenced_code_block_language</code> 字段，不言而喻，这些就是用来描述 markdown 里不同语言的代码块的。啊，果然没有 Scheme 语言的实现。</p>\n<p>如果再仔细读每个 <code class=\"language-text\">fenced_code_block_language</code> 字段下的内容，会发现大同小异，有所变化的只有匹配正则以及每个语言所对应的 <code class=\"language-text\">&quot;patterns&quot;: &quot;source.language&quot;</code>。</p>\n<p>那么 <code class=\"language-text\">source.language</code> 是哪里来的呢。是通过叫 <a href=\"https://code.visualstudio.com/docs/languages/identifiers#_new-identifier-guidelines\">language identifier</a> 的东西定义出来的。观察 <code class=\"language-text\">/extensions</code> 目录，包含了一大堆常用语言的目录，这些就是 VS Code 内建的语言支持，一种语言即一个内建插件，也相应地定义了该语言的 <code class=\"language-text\">language identifier</code>。没有列出的语言需要通过插件引入，于是我们可能需要自行创建对 Scheme 语言的定义了。在此之前，最好搜索一下 VS Code 市场，也许会发现目标语言已经有了一份相对完整的定义，比如我找到了 <a href=\"https://github.com/sjhuangx/vscode-scheme\">vscode-scheme</a>。试用一下，咦，<code class=\"language-text\">.scm</code> <code class=\"language-text\">.rkt</code> 等文件的高亮和快捷键什么的倒是有了，markdown 里面代码块的高亮却是不支持。事情到现在应该比较清晰了，我们的目标就是去扩展这个插件。</p>\n<p>下一个问题，如何扩展？天下代码一大抄 😂，我们搜索 VS Code 的 Issues 或者 Pull requests，看是否有过类似的实现。最后找到一个可以直接注入配置的例子：<a href=\"https://github.com/mjbvz/vscode-fenced-code-block-grammar-injection-example\">injection-example</a>。蛋疼的搜索和 debug 过程略去不表，最终实现看上去挺简单的：</p>\n<ol>\n<li>根据例子新建一个该语言 markdown 部分的描述文件 <code class=\"language-text\">scheme.markdown.tmLanguage.json</code>；</li>\n<li>在 <code class=\"language-text\">package.json</code> 里面引入此文件并定义对应的 <code class=\"language-text\">scopeName</code>，注入 markdown 配置；</li>\n<li>这时 VS Code 的 Markdown 插件可以读到这份配置，当在代码块里看到 <code class=\"language-text\">scheme</code> 时，就调用 vscode-scheme 已经定义好的 parser。</li>\n</ol>\n<h3>2.3 结果</h3>\n<p>解决方案：<a href=\"https://github.com/sjhuangx/vscode-scheme/pull/3\">sjhuangx/vscode-scheme#<code class=\"language-text\">3</code></a></p>\n<h2>3. 面向需求编程</h2>\n<p>以前总在想着怎么造轮子，不出意外，想造的轮子都已经有了相应的实现。虽然自己可以继续造一个，但是没有必要。所谓“开源”的目的是什么呢？其中一点就是可以通过社区改进项目中的不足。既然当不成 Maintainer，那就做个 Contributor 吧，解决自己需求的同时，完善和加强原项目的功能。这就是我认为向开源项目贡献代码最直接而简单的方式。</p>\n<p>有一个特别佩服的人—— <a href=\"https://weibo.com/easy\">@Easy</a>，观察他的日常微博不难发现，他通常都会因为某个在市面上暂时没有的功能，而根据自己的需求马上动手实现一份，而且产出速度特别惊人。我很想学习其中的精神，缺什么写什么。</p>\n<p>需求不是经常会有，但是一旦来临，我希望自己有这个能力去完成它。以上就是自己对于这几天提交的 PR 的一个记录。短期目标：Make my life better。至少是开发生活吧。🎉</p>","frontmatter":{"title":"如何向开源项目贡献代码","date":"2018 年 12 月 08 日","description":null}}},"pageContext":{"slug":"/how-to-contribute-to-open-source-project/","previous":{"fields":{"slug":"/the-little-schemer-summary-4/"},"frontmatter":{"title":"The Little Schemer 知识点整理（四）：数字游戏"}},"next":{"fields":{"slug":"/the-little-schemer-summary-5/"},"frontmatter":{"title":"The Little Schemer 知识点整理（五）：我得天！都是星星"}}}}}