Hi,给他介绍一款markdown的帮助文档生成器

      当今大多数的团队都实现了前、后端分支。前端与后端的沟通都是通过接口来实现的(一般情况下都是webapi接口)。这种情况你肯定需要一个接口查询的帮助文档,这个当然用swagger都可以实现。但做为前端开发的我们是否也应该考虑把自己写的组件以帮助文档的方式公开都团队其他人员使用。就像iview,easyui等UI组件都有自己的帮助文档。今天我们都介绍一套工具(其中某些组件经过本人的改造)

一、需要的组件

1. Hexo:静态博客生成器

2. Hexo-theme-doc:基于Hexo实现的帮助文档类型的皮肤,并对其中的某些逻辑进行完善

3. lunr-languages:实现lunr搜索对多语言的支持

二、实现的效果

上述演示效果为本人开发的ko-easyui插件的帮助文档。你可以访问此地址查看https://ko-plugins.gitee.io/koeasyui/index.html

效果看上去是简单了点,但却能达到对一套UI组件的说明,也是不错的。

三、对插件的改造

3.1 Hexo-them-doc的改造

对components.jsx中触发搜索的参数进行调整如下(使用其更快的触发搜索):

class SearchForm extends React.Component {

  constructor (props) {
    super(props);
  }

   handleKeyUp (e) {

     if (query.length < 2) { return; }

   }
    
}

主要就是把query.length < 3改为query.length < 2。

然后,引入修改后的lunr-languages(支持中文搜索的控件),修正代码如下(search/build.js):

let support = require('lunr-languages/lunr.stemmer.support');
let zhcn = require('lunr-languages/lunr.zhcn');
support(lunr);
zhcn(lunr);
module.exports = function build (ctx) {
  const index = lunr(function () {
     //添加对中文的支持
     this.use(lunr.zhcn);

     this.ref('id');
     this.field('title');
     this.field('body');
 }
}

上述是缩减之后的代码,其中主要是对lunr.zhcn的使用。

3.2 lunr-languages的改造

对lunr-languages的改造,增加了lunr.zhcn.js文件,增加对中文搜索的支持,代码如下:

/**
 * lunr对中文分词的支持
 */
;
(function(root, factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    define(factory)
  } else if (typeof exports === 'object') {
    /**
     * Node. Does not work with strict CommonJS, but
     * only CommonJS-like environments that support module.exports,
     * like Node.
     */
    module.exports = factory()
  } else {
    // Browser globals (root is window)
    factory()(root.lunr);
  }
}(this, function() {
  /**
   * Just return a value to define the module export.
   * This example returns an object, but the module
   * can return a function as the exported value.
   */
  return function(lunr) { 
    /* throw error if lunr is not yet included */
    if ('undefined' === typeof lunr) {
      throw new Error('Lunr is not present. Please include / require Lunr before this script.');
    }

    /* throw error if lunr stemmer support is not yet included */
    if ('undefined' === typeof lunr.stemmerSupport) {
      throw new Error('Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.');
    }

    /*
    Thai tokenization is the same to Japanense, which does not take into account spaces.
    So, it uses the same logic to assign tokenization function due to different Lunr versions.
    */
    var isLunr2 = lunr.version[0] == "2";

    /* register specific locale function */
    lunr.zhcn = function() {
        this.pipeline.reset();
        this.pipeline.add(
            lunr.zhcn.trimmer,
            lunr.zhcn.stopWordFilter,
            lunr.zhcn.stemmer
        );

        if (isLunr2) { // for lunr version 2.0.0
            this.tokenizer = lunr.zhcn.tokenizer;
        } else {
            if (lunr.tokenizer) { // for lunr version 0.6.0
                lunr.tokenizer = lunr.zhcn.tokenizer;
            }
            if (this.tokenizerFn) { // for lunr version 0.7.0 -> 1.0.0
                this.tokenizerFn = lunr.zhcn.tokenizer;
            }
        }
    };


    var segmenter = new lunr.TinySegmenter(); 

    lunr.zhcn.tokenizer = function(obj) {
      var i;
      var str;
      var len;
      var segs;
      var tokens;
      var char;
      var sliceLength;
      var sliceStart;
      var sliceEnd;
      var segStart;

      if (!arguments.length || obj == null || obj == undefined)
        return [];

      if (Array.isArray(obj)) {
        return obj.map(
          function(t) {
            return isLunr2 ? new lunr.Token(t.toLowerCase()) : t.toLowerCase();
          }
        );
      }

      str = obj.toString().toLowerCase().replace(/^\s+/, '');
      for (i = str.length - 1; i >= 0; i--) {
        if (/\S/.test(str.charAt(i))) {
          str = str.substring(0, i + 1);
          break;
        }
      }

      tokens = [];
      len = str.length;
      for (sliceEnd = 0, sliceStart = 0; sliceEnd <= len; sliceEnd++) {
        char = str.charAt(sliceEnd);
        sliceLength = sliceEnd - sliceStart;

        if ((char.match(/\s/) || sliceEnd == len)) {
          if (sliceLength > 0) {
            segs = segmenter.segment(str.slice(sliceStart, sliceEnd)).filter(
              function(token) {
                return !!token;
              }
            );

            segStart = sliceStart;
            for (i = 0; i < segs.length; i++) {
              if (isLunr2) {
                tokens.push(
                  new lunr.Token(
                    segs[i], {
                      position: [segStart, segs[i].length],
                      index: tokens.length
                    }
                  )
                );
              } else {
                tokens.push(segs[i]);
              }
              segStart += segs[i].length;
            }
          }

          sliceStart = sliceEnd + 1;
        }
      }

      return tokens;
    }

    lunr.zhcn.stemmer = (function(){
      return function(word) {
        return word;
      }
    })();
    
    lunr.Pipeline.registerFunction(lunr.zhcn.stemmer, 'stemmer-zhcn');

    /* lunr trimmer function */
    lunr.zhcn.wordCharacters = "一二三四五六七八九十百千万億兆一-龠々〆ヵヶぁ-んァ-ヴーア-ン゙a-zA-Za-zA-Z0-90-9";
    lunr.zhcn.trimmer = lunr.trimmerSupport.generateTrimmer(lunr.zhcn.wordCharacters);
    lunr.Pipeline.registerFunction(lunr.zhcn.trimmer, 'trimmer-zhcn');


    /* lunr stop word filter. see https://www.ranks.nl/stopwords/chinese-stopwords */
    lunr.zhcn.stopWordFilter = lunr.generateStopWordFilter('的 一 不 在 人 有 是 为 以 于 上 他 而 后 之 来 及 了 因 下 可 到 由 这 与 也 此 但 并 个 其 已 无 小 我 们 起 最 再 今 去 好 只 又 或 很 亦 某 把 那 你 乃 它 吧 被 比 别 趁 当 从 到 得 打 凡 儿 尔 该 各 给 跟 和 何 还 即 几 既 看 据 距 靠 啦 了 另 么 每 们 嘛 拿 哪 那 您 凭 且 却 让 仍 啥 如 若 使 谁 虽 随 同 所 她 哇 嗡 往 哪 些 向 沿 哟 用 于 咱 则 怎 曾 至 致 着 诸 自'.split(' '));
    lunr.Pipeline.registerFunction(lunr.zhcn.stopWordFilter, 'stopWordFilter-zhcn');
  };
}))

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏IT技术精选文摘

分布式事务原理与实践

事务简介 事务的核心是锁和并发,采用同步控制的方式保证并发的情况下性能尽可能高,且容易理解。这种方式的优势是方便理解;它的劣势是性能比较低。 计算机可以简单的理...

18310
来自专栏智能大石头

NewLife.Net——构建可靠的网络服务

1493
来自专栏针针小站

【Soft】NetSarang Xshell 6 Free for Home & School 申请

2502
来自专栏编程

我是如何利用CSRF Get DedeCms Shell的

说实话,有一两个月没有审计大厂了,然后随便看到群里有人问dede最新有没有漏洞,就下了一套最新的dede,结果我一看还真发现了。 ? 我们发现后台添加广告的地方...

2087
来自专栏谭广健的专栏

【小程序-云开发】手把手教你使用云开发(数据库开发)

继上一次程序员哥哥简单开发了一个照片储存小程序后,感觉还是有些小小缺陷,就是没办法对上传照片进行文字描述。因为主要都是文字,如果将文字描述再保...

3.5K1
来自专栏智能大石头

NewLife.Net——构建可靠的网络服务

老规矩,先上源码:https://github.com/nnhy/NewLife.Net.Tests

1130
来自专栏*坤的Blog

redis性能测试

8652
来自专栏FreeBuf

我是如何利用CSRF Get DedeCms Shell的

说实话,有一两个月没有审计大厂了,然后随便看到群里有人问dede最新有没有漏洞,就下了一套最新的dede,结果我一看还真发现了。 ? 我们发现后台添加广...

2298
来自专栏Youngxj

博客彩虹友链源码

1445
来自专栏北京马哥教育

一万两千字长文,六大问题为你解读计算机

1描述计算机的组成及其功能 电子计算机,亦称电脑,是一种利用电子学原理,根据一系列指令对数据进行处理的工具 计算机及其组成 计算机是什么       电子计...

36710

扫码关注云+社区