使用gitlab里面的pages,实现gitbook(骚)

 Pages入口:

 

 仅作为了解学习

官方例子:

https://gitlab.com/pages

第一页:

vuepress有自己的目录格式

第二页:

 

 

gitbook有自己的格式

GitBook 3.2.3入门

GitBook目录结构

基本结构如下:
├── book.json
├── README.md
├── SUMMARY.md
├── chapter-1/
 | ├── README.md
 | └── something.md
└── chapter-2/
├── README.md
└── something.md
book.json:全局配置数据 (可选)
README.md:介绍电子书(必须)
SUMMARY.md:目录 (可选)
GLOSSARY.md:词汇、术语列表(可选)
  • SUMMARY.md格式
基本格式为:* [描述](文件路径或者http超链接)。文件路径是相对于SUMMARY.md所在的目录的。
支持多级目录,每级目录多缩进4个空格。例如:
* [介绍](README.md)
* [概述](index.md)
* [接口](api.md)
* [注意事项](note.md)
 
直接简单粗暴的使用上:(项目用的是下面这种方式)
book.json文件
复制代码
{
  "title": "项目技术特点",
  "author": "王云鹏",
  "language": "zh-hans",
  "ignores": [
    "node_modules",
    "**/resources"
  ]
}
book.json
复制代码

.gitlab-ci.yml文件,直接创建,需要SUMMARY.md

复制代码
default:
  tags:
    - docker
    - company

# requiring the environment of NodeJS 10
image: node:10

# add 'node_modules' to cache for speeding up builds
cache:
  paths:
    - node_modules/ # Node modules and dependencies

before_script:
  - npm install gitbook-cli -g # install gitbook
  - gitbook fetch 3.2.3 # fetch final stable version
  - gitbook install # add any requested plugins in book.json

# the 'pages' job will deploy and build your site to the 'public' path
pages:
  stage: deploy
  script:
#    - node generateSummary.js
    - gitbook build . public # build to public path
  artifacts:
    paths:
      - public
    expire_in: 1 week
  only:
    - master # this job will affect only the 'master' branch
.gitlab-ci.yml
复制代码

.gitlab-ci.yml文件,用自己创建的镜像实现,不需要写SUMMAY.md

复制代码
default:
  tags:
    - docker
    - company

# requiring the environment of NodeJS 10
image: nexus3:8089/wangyp/gitbook:1.0.1
test:
  stage: test
  script:
    - gitbook build . public # build to public path
  only:
    - branches # this job will affect every branch except 'master'
  except:
    - master
    
# the 'pages' job will deploy and build your site to the 'public' path
pages:
  stage: deploy
  script:
    - book sm
    - gitbook build . public # build to public path
  artifacts:
    paths:
      - public
    expire_in: 1 day
  only:
    - master # this job will affect only the 'master' branch
.gitlab-ci.yml
复制代码

generateSummary.js文件

复制代码
const IGNORE_FILES = [
  /* gitignore style */
  'SUMMARY.md',
];
const DEFAULT_README_TITLE = 'Introduction';

////////////////////////////////////////////////
const fs = require('fs');
const path = require('path');

const isNotIgnored = (() => {
  const ignoredPatterns = fs.readFileSync('./.gitignore', 'utf8')
    .split('\n')
    .map(f => f.trim())
    .filter(f => f.length > 0)
    .filter(f => f[0] !== '#')
    .concat(IGNORE_FILES)
    .map(f => new RegExp(f.replace(/\*/g, '(.*?)')));

  return (f) => {
    if(!(f instanceof File)) throw "Error: expecting File";
    return ignoredPatterns.reduce((bool, p) => bool && !p.test(f.path, true));
  };
})();

const indent = (s, n=4) => {
  const spaces = (new Array(n + 1)).join(' ');
  return spaces + s.replace(/\n/g, '\n' + spaces);
};

class File{
  constructor(path){
    this.path = path;
  }

  get filename(){
    return this.path.substring(this.path.lastIndexOf('/') + 1);
  }

  get name(){
    const p = this.filename;
    if(p.lastIndexOf('.') === -1) return p;
    return p.substring(0, p.lastIndexOf('.'));
  }

  get prettyname(){
    const capitalize = (s) => {
      if(s.length === 0) return '';
      return [s[0].toUpperCase(), ...s.substring(1).toLowerCase()].join('');
    };
    const sepWords = (p) => p.replace(/[-_]/g, ' ');
    return capitalize(sepWords(this.name));
  }

  get ext(){
    return this.path.substring(this.path.lastIndexOf('.'));
  }

}

class Dir extends File{
  ls(){
    const isVisible = (f) => f[0] !== '.';

    return fs.readdirSync(this.path)
      .filter(isVisible)
      .map((f) => path.join(this.path, f))
      .map(p => new (fs.statSync(p).isDirectory()? Dir: File)(p));
  }

  lsdirs(){
    return this.ls().filter(f => f instanceof Dir);
  }
}

class Root extends Dir{
  /* directories are viewed as Parts
   * files are Articles */
  ls(){
    return super.ls()
      .filter(isNotIgnored)
      .map(f => new (f instanceof Dir? Part: Article)(f.path))
      .filter(f => f instanceof Article? f.ext === '.md': f);
  }

  getHeader(){
    return `# Summary`;
  }

  articlesSummary(){
    return this.ls()
      .filter(f => f instanceof Article)
      .map(f => f.toSummary())
      .join('\n');
  }

  directoriesSummary(){
    return this.lsdirs()
      .map(part => part.toSummary())
      .join('\n');
  }

  getSummary(){
    const artSum = this.articlesSummary()
    const dirsSum = this.directoriesSummary();
    return [artSum, dirsSum].filter(s => s.trim() !== '').join('\n\n');
  }

  toSummary(){
    return this.getHeader() + '\n' + this.getSummary() + '\n';
  }
}

class Part extends Root{
  /* directories are viewed as Chapters
   * files are Articles */
  ls(){
    return super.ls()
      .map(f => f instanceof Part? new Chapter(f.path): f)
  }

  getHeader(){
    return `## ${this.prettyname}`;
  }
}

class Chapter extends Part{
  ls(){
    return super.ls().filter(f => f.filename !== 'README.md');
  }

  getHeader(){
    const readme_path = path.join(this.path, 'README.md');
    return `* [${this.prettyname}](${readme_path})`
  }

  getSummary(){
    return indent(super.getSummary());
  }
}

class Article extends File{
  get prettyname(){
    const original_prettyname = super.prettyname;
    if(original_prettyname !== 'Readme') return original_prettyname;
    return DEFAULT_README_TITLE;
  }

  toSummary(){
    return `* [${this.prettyname}](${this.path})`;
  }
}

const summary = new Root('.').toSummary();

fs.writeFileSync('SUMMARY.md', summary);
generateSummary.js
复制代码

本地安装node环境,直接直接运行:

node generateSummary.js

也能生成Summary。

提交代码之后,gitlab-ci也可以自动生成gitbook。

然后windows系统里设置hosts文件,浏览器访问

192.168.0.82 root.gitlab-server

 

 

 

posted @   —八戒—  阅读(3608)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示