资讯专栏INFORMATION COLUMN

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

番茄西红柿 / 225人阅读

摘要:就像,等组件都有自己的帮助文档。然后,引入修改后的支持中文搜索的控件,修正代码如下添加对中文的支持上述是缩减之后的代码,其中主要是对的使用。

      当今大多数的团队都实现了前、后端分支。前端与后端的沟通都是通过接口来实现的(一般情况下都是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);
  };
}))

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/1997.html

相关文章

  • 「运维之美」技术周刊 ( 第 3 期 )

    摘要:运维之美是一个有情怀有态度,专注于运维相关技术文章分享的公众号。公众号致力于为广大运维工作者分享各类技术文章和发布最前沿的科技信息。在此次变更之后,配置行便可直接移除。 showImg(https://segmentfault.com/img/remote/1460000019868009); 本文首发于:微信公众号「运维之美」,公众号 ID:Hi-Linux。 ​「运维之美」是一个...

    Keagan 评论0 收藏0
  • 给准备着手写博客小白一些实用建议

    摘要:针对一些想写博客提升能力,但是很迷茫不知道怎么开始的同学,我会尽我所能给出一些建议。它允许人们使用易读易写的纯文本格式编写文档,然后转换成有效的或者文档。 目录 ...

    ad6623 评论0 收藏0
  • Markdown-Temp,一款免费开源编辑器(附源码)

    摘要:什么是是一款在线编辑器,她不仅免费开源,而且简单适用。适用于编写临时文档与在线分享。演示地址演示图片源码地址 Markdown-Temp 什么是Markdown-Temp? Markdown-Temp是一款在线Markdown编辑器,她不仅免费开源,而且简单适用。Markdown-Temp适用于编写临时文档与在线分享。 Markdown-Temp说明 编辑器使用Editor.md开发...

    JerryC 评论0 收藏0
  • 五分钟搭建一个MarkDown文档解析器

    摘要:字数阅读时间分钟前言本文的旨在讲述如何从零开始搭建一个文档展示工具。整个过程非常简单,咱稍微花五分钟就可以搭建一个定制化的文档解析器,是不是很酷呀首先我们晒一张成果图看看效果吧正文环境准备插件一款最受欢迎的文件解析插件。 字数:790 阅读时间:5分钟 前言   本文的旨在讲述如何从零开始搭建一个MarkDown文档展示工具。整个过程非常简单,咱稍微花五分钟就可以搭建一个定制化的MD文...

    tinna 评论0 收藏0
  • 基于Hexo搭建个人博客

    摘要:买完域名后在阿里云控制台产品与服务域名与网站域名选择购买的域名快速解析填写的地址就行如何获得的地址你的用户名就可获得,获得后复制进去便可自后,你还要在工作目录下的目录下新建文件,并填写你的域名进去。 写在前面的话 一直想做一个自己的博客,用来记录自己学习的点点滴滴,无奈个人懒癌晚期,一直行动不起来。现在逼迫自己写点东西来充实自己,上网查询了各个写博客的平台。总结下来,还是拥有一个自己私...

    sshe 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<