never-write

1.2.3 • Public • Published

never-write

🇨🇳中文 | ENGLISH

never-write 是一个基于 markdown 的静态站点生成工具。

安装

npm i never-write -g

使用

# 初始化,必须在空目录
neverw --init

# 生成
neverw build

NEVERW --INIT

neverw --init 命令会生成一个基础模板。

# 所有文章、发布内容都写在 posts 目录下
- posts/
# 静态资源目录
- public/
# 配置文件
- never-write.yaml

所有文章都写在 posts 目录下,目前只会处理 .md 后缀的文件。

该目录可以在配置文件中重新制定(build.postsRootPath)。

never-write.yaml

never-write.yaml 标记了当前目录为一个处理站点,所以所有配置的路径都要当对于配置文件所在的目录。

该配置可以自己创建,也可以用 neverw --init 生成。

site:
  # 默认 空
  name: 站点名称
  # 默认 空
  desc: 站点描述

build:
  # 默认 ./dist
  outDir: 生成输出目录
  # 默认 /
  publicPath: 资源路径前缀
  # 默认 ./posts
  postsRootPath: markdown文件的查找根目录
  # 默认 ./public
  publicResourcePath: 静态资源,会直接拷贝到 outDir 下
  # 默认 无
  hook: 一些钩子,在文章、索引生成前后阶段调用
  # 默认 true
  htmlMinify: 是否压缩输出的html

render:
  # 可以传递字符串,为内部预设的主题
  # 如果传递对象,则会根据路径对应去找文件
  # 默认 cactus-dark,目前可选 cactus-dark|plain|plain-dark
  template:
    index: 索引页面模板
    post: 文章模板
    tagIndexes: 根据标签聚合的索引页面

  # 默认 15
  pageSize: 索引页一页的索引数量

  # 默认 YYYY/MM/DD hh:mm:ss
  dateFormatter: 会提前处理好一部分时间,方便模板里使用,处理的格式会按这个配置来

  # 默认 100
  summaryLength: 摘要的长度

  # 默认 空
  footerText: 页脚文案,可以是html

默认配置

site:
  name:
  desc:

build:
  outDir: ./dist
  publicPath: /
  postsRootPath: ./posts
  publicResourcePath: ./public
  htmlMinify: true
  hook:

render:
  template: cactus-dark
  pageSize: 15
  dateFormatter: YYYY/MM/DD hh:mm:ss
  summaryLength: 100
  footerText:

注意点

  • 配置文件里的所有路径需要是相对配置文件根目录的路径,参考默认配置

自定义模板、样式、主题

模板引擎为ejs,在创建阶段会提供一些变量使用,所以自定义模板只要提供符合ejs语法的文件传递给配置项即可。

参考:https://github.com/hiNISAL/never-write/blob/main/templates/theme/plain-dark/index.html

传递给EJS的选项

interface PostOptions {
  // markdown文件头部的yaml信息
  meta: Record<string, any>.
  // 拼接 publicPath后的路径
  staticPath: string;
  // 在站点中的相对路径
  relativePath: string;
  // markdown文件的文件信息
  sourceFileStat: fs.Stats;
  // 文件保存的名称
  filename: string;
  // 不包含后缀的文件名
  filenameWithoutExt: string;
  // never-write.yaml 中的 site 配置项
  site: { name: string; desc: string };
  // markdown 转换后的 html
  html: string;
  // md转换后剔除标签的文本内容
  text: string;
  // 摘要 默认取text的前100个字符
  summary: string;
  // 根据配置中 render.dateFormatter 生成的时间
  // mtime 是文件的修改时间
  dateFormat: { mtime: string };
  // 本地保存目录
  postSavedDir: string;
  // 保存在本地的路径
  postSavedFullPath: string;
  namespace: 'post';
  // 首页的路径
  home: string;
  // render config
  render: Record<string, any>;
}

索引页面传递的内容

template.indextemplate.tagIndexes 获得的属性是一样的。

interface IndexesOptions {
  // 由 post 组成的数组,长度为配置的pageSize
  posts: PostOptions[];
  // 当前第几页
  page: number;
  // 共有几页
  pageTotal: number;
  // 共由几篇内容
  totalCount: number;
  // 当前自己的站点相对路径
  selfPath: string;
  // 上一页的站点相对路径
  prevPagePath: string;
  // 下一页的站点相对路径
  nextPagePath: string;
  // 当前自己的站点拼接publicPath后的相对路径
  selfStaticPath: string;
  // 上一页的站点拼接publicPath后的相对路径
  prevPageStaticPath: string;
  // 下一页的站点拼接publicPath后的相对路径
  nextPageStaticPath: string;
  // 是否第一页
  isFirstPage: boolean;
  // 是否最后一页
  isEndPage: boolean;
  // never-write.yaml 中的 site 配置项
  site: { name: string; desc: string };
  namespace: 'indexes'|'tag';
  // 聚合好的tag
  tag: Record<string, {
    posts: PostOptions[];
    staticPath: string;
  }>;
  // 当前页面的tag,如果namespace是indexes,则永远为空
  tag: '';
  // 首页路径
  home: string;
  // render config
  render: Record<string, any>;
}

hook

在配置中加入:

build:
  hook: ./hook/index.js

build过程中就会读取该文件,并且执行对应的钩子。

// ./hook/index.js

module.exports = {
  // 生成每一篇前执行
  eachBeforeRenderPost(opt) {
    console.log(opt);
  },
  // 生成每一篇后执行
  eachAfterRenderPost(opt) {
    console.log(opt);
  },
  // 生成每一页索引前执行
  eachBeforeRenderIndexes(opt): {
    console.log(opt);
  },
  // 生成每一页索引后执行
  eachAfterRenderIndexes(opt): {
    console.log(opt);
  },
  // 生成每一页tag索引前执行
  eachBeforeRenderTagsIndexes(opt) {
    console.log(opt);
  },
  // 生成每一页tag索引后执行
  eachAfterRenderTagsIndexes(opt) {
    console.log(opt);
  },
  // 在索引页中的排序规则
  sortBy(a, b) {
    // ...
  },
};

怎么配置tag

markdown 文件的头部可以用yaml描述一些信息:

---
title: page title
tag: tag1, tag2, tag3
---

## 正文内容

嘻嘻哈哈哈

其中tag会通过,切割后解析成数组(可以直接传递yaml语法中的数组)。

在处理所有markdown文件时,会根据tag聚合。

保留目录

这些目录有特殊用途,在posts目录下不能使用。

  • page 用于存放索引分页
  • tags 用于存放tag索引页

其他

默认主题的样式照搬了hexo的cactus主题,感谢(自己想真的太麻烦了。

Package Sidebar

Install

npm i never-write

Weekly Downloads

1

Version

1.2.3

License

MIT

Unpacked Size

562 kB

Total Files

37

Last publish

Collaborators

  • nisal