使用 GitBook 进行团队文档协作

GitBook 提供了 GitBook Editor ,GitBook cli 这两个工具,一个是编辑文档,一个可以生成文档。只要本地搭建一个 Git 服务就完全可以实现本地化了。

工具准备

如果没有团队协作要求,只想生成电子书,只在自己机器上安装 GitBook CI 就可以,1,2 就可以省略了。

  1. GitLab 一键安装包 https://about.gitlab.com/downloads/
  2. GitLab Ci Runner https://github.com/gitlabhq/gitlab-ci-runner
  3. GitBook CI https://github.com/GitbookIO/gitbook-cli
  4. GitBook Editor https://www.gitbook.com/editor

GitLab Runner 配置

编辑 .gitlab-ci.yml

# 定义 stages
stages:
  - build
# 定义 job
GenerateHTML:
  stage: build
  script:
    - p=`pwd`
    - echo $p
    - gitbook build

gitlab 执行构建,会在文件夹下生成 _book 的目录。

手工执行 gitbook serve 启动。

打开 ip:4000 就可以查看文档了。

相关命令

$ gitbook init # 初始化一个仓库

$ gitbook install # 安装插件

$ gitbook serve # 本地预览

$ gitbook serve --port 8001 # 指定端口,默认4000

$ gitbook build  # 输出一个静态网站

$ gitbook pdf # 生成pdf文件

$ gitbook help # 查看帮助

可以使用 --log=debug--debug 来获得更详细的错误消息(堆栈跟踪)。例如:

$ gitbook build ./ --log=debug --debug

or

$ gitbook serve ./ --log=debug --debug

Docker 容器化

Dockerfile 文件如下:

From node:10

LABEL version=$VERSION

ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

WORKDIR /gitbook
COPY xxx_deploy /gitbook

RUN npm install gitbook-cli -g && gitbook fetch ${VERSION} && npm cache clear --force && rm -rf /tmp/*
RUN gitbook build

CMD ["gitbook", "serve","--port","4000"]

问题解决

windows 更新报错

gitbook 的新版本,在 windows 下有个 bug,当文件内容发生更新时,gitbook 报错然后退出:

Error: EPERM: operation not permitted, open

gitbook 官方已有 bug,存在半年了,一直没有 fix:

  • git serve can't restart when file changes
  • gitbook-cli crashes with EPERM: operation not permitted on windows

解决方法

在官方 bugfix 之前,暂时只能回避:

  1. 不要在 windows 下使用 gitbook:linux 没有这个问题

  2. 不是办法的办法:

    新建一个 run.bat ,内容如下:

    @Echo off
    :Start
    call gitbook serve
    goto Start

    每次崩溃之后立即重新启动一次,凑合着用吧。

底部链接修改与隐藏

用 GitBook 生成的网页中,在左侧目录下方默认有一个 Published with GitBook 连接,可以将这个连接去掉,或者替换成其它连接。

在 GitBook 站点目录创建 _layouts->website->summary.html

{% raw %}
{% macro articles(_articles) %}
    {% for article in _articles %}
        <li class="chapter {% if article.path == file.path and not article.anchor %}active{% endif %}" data-level="{{ article.level }}" {% if article.path %}data-path="{{ article.path|resolveFile }}"{% endif %}>
            {% if article.path and getPageByPath(article.path) %}
                <a href="{{ article.path|resolveFile }}{{ article.anchor }}">
            {% elif article.url %}
                <a target="_blank" href="{{ article.url }}">
            {% else %}
                <span>
            {% endif %}
                    {% if article.level != "0" and config.pluginsConfig['theme-default'].showLevel %}
                        <b>{{ article.level }}.</b>
                    {% endif %}
                    {{ article.title }}
            {% if article.path  or article.url %}
                </a>
            {% else %}
                </span>
            {% endif %}

            {% if article.articles.length > 0 %}
            <ul class="articles">
                {{ articles(article.articles, file, config) }}
            </ul>
            {% endif %}
        </li>
    {% endfor %}
{% endmacro %}

<ul class="summary">
    {% set _divider = false %}
    {% if config.links.sidebar  %}
    {% for linkTitle, link in config.links.sidebar  %}
        {% set _divider = true %}
        <li>
            <a href="{{ link }}" target="_blank" class="custom-link">{{ linkTitle }}</a>
        </li>
    {% endfor %}
    {% endif %}

    {% if _divider %}
    <li class="divider"></li>
    {% endif %}

    {% for part in summary.parts %}
        {% if part.title %}
        <li class="header">{{ part.title }}</li>
        {% elif not loop.first %}
        <li class="divider"></li>
        {% endif %}
        {{ articles(part.articles, file, config) }}
    {% endfor %}

    <li class="divider"></li>
    
    <!--<li>
        <a href="https://www.gitbook.com" target="blank" class="gitbook-link">
            {{ "GITBOOK_LINK"|t }}
        </a>
    </li>-->
</ul>
{% endraw %}