使用strapi+mkdocs打造一个在线写书系统

我写书都是采用markdown格式,所以在这里我介绍几款md相关的写书系统。

  1. 写书的工具有很多gitbook,mkdocs等。
    gitbook,是github推出的,目前已经不更新了,安装使用都会遇到一些版本兼容的bug。所以导致我无法使用。gitbook采用的编程语言是JavaScript。
    mkdocs ,目前维护的非常好。material主题也很漂亮,采用Python语言编写。

  2. showdoc
    showdoc 是php语言编写,
    目前支持在线直接书写,免费版本有些限制。毕竟他们也是团队在开发。也需要支付服务器成本。所以收费也是必然的。
    我没有试过收费版本。也无法评价。

  3. mrdoc
    mrdoc 采用python编写,比较符合我的需求。开源可以安装使用。
    并且支持在线写文档。也有开源版本和专业版。

  4. mindoc
    是一款基于go语言编写的在线文档系统。MinDoc 的前身是 SmartWiki 文档系统。SmartWiki 是基于 PHP 框架 laravel 开发的一款文档管理系统。

如果要使用在线的系统,上面的都可以考虑。

自己打造一个,不是为了和他们竞争,是为了自己使用。
我写了几本书都是采用的mkdocs。非常喜欢使用mkdocs。

但是出现了一个问题,就是插入图片操作不方便。所以我想借助一个现成的在线系统去完成。

因为我经常使用strapi来做网站系统。strapi后台功能非常强大,并且支持markdown编写。所以我想让他们结合起来。

mkdocs是python,strapi是nodejs(javascript)。所以估计很多人也不愿意折腾。
不过在这里mkdocs仅仅需要安装即可,安装命令也简单

pip install mkdocs

strapi改造支持mkdocs需要2个步骤

  • 创建一个表 支持 mkdocs.yml (ebook)
  • 创建一个表支持mk文件 (file_md)
image.png
image.png

这就创建一条记录可以把mkdocs.yml 放到ebook表里面

再创建多条记录 *.md 房主 file_md表里

数据的表如何变成mkdocs需要的文件呢?
我写了一个解释代码

const fetch = require('node-fetch');
const YAML  = require('yaml');
const fs    = require('fs')
const path  = require('path')
var exec = require("child_process").exec;


var host = "http://127.0.0.1:1337"
//var host = "http://119.91.153.63:1337"

// bookid
var bookid = 1
var filelist = []
// AIDocs/ oWriter/src/api/ebook/controllers
var father = path.resolve(__dirname,'../../../../')
var bookpath = path.resolve(father,'../tmp')
var bookdocpath = path.resolve(bookpath,'docs')

function parse_nav(n){
    var val = Object.values(n)[0]

    // filename
    if(typeof val === 'string'){
        console.log(val)
        filelist.push(val)
    } else{
        //二级子目录,需要再次循环
        val.forEach(function(item){
            parse_nav(item)
        })
    }

}

async function make_filecontent(filename){

        const file_parse = path.parse(filename)

        const res = await fetch(host+"/api/file-mds?filters[filename][$eq]="+filename+"&filters[ebook][id][$eq]="+bookid)
        const datas = await res.json()

        if (datas.meta.pagination.total == 0) return

        let content = datas.data[0].attributes.content

        //console.log(file_parse.dir,file_parse.base)
        let filepath = path.resolve(bookdocpath,file_parse.dir)
        console.log(filepath)

        //如果目录不存在创建目录,支持创建多级目录
        if (!fs.existsSync(filepath)) fs.mkdirSync(filepath,{ recursive: true });

        fs.writeFileSync(path.resolve(filepath,file_parse.base),content,{flag:"w+"})

        return
}



async function bookupdate(ctx){
        // 读取书的信息
        const res = await fetch(host+"/api/ebooks")
        var datas = await res.json()
        var objdata = ""
        for (var i = 0; i < datas.data.length;i++){
                  var data = datas.data[i]
                  if(data.id == bookid){
                       objdata = data
                       break
                  }
        }
        if (objdata == "") return

        var buffer = objdata.attributes.yml
        var name   = objdata.attributes.name
        var folder = objdata.attributes.folder

        let config = YAML.parse(buffer);
        var nav = config['nav']

        if (folder != ""){
             bookpath = path.resolve(father,'../'+folder)
             bookdocpath = path.resolve(bookpath,'docs')
        }

        //创建mkdocs 项目配置文件
        if (!fs.existsSync(bookpath)) fs.mkdirSync(bookpath,{ recursive: true });
        fs.writeFileSync(path.resolve(bookpath,'mkdocs.yml'),buffer,{flag:"w+"})

        nav.forEach(function(item){
            parse_nav(item)
        })

        //创建所有的markdown 文件
        console.log("---------------------------")
        filelist.forEach(async function(item){
           await make_filecontent(item)
        })


        exec("cd "+ bookpath +";mkdocs build",function(err,stdout,stderr){
            if(err){
                console.error(err);
            }
            console.log("stdout:",stdout)
            console.log("stderr:",stderr);
        });

}

strapi 编辑预览界面


image.png

全部源代码: https://github.com/asmcos/AIDocs/blob/master/oWriter

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,738评论 5 472
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,377评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,774评论 0 333
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,032评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,015评论 5 361
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,239评论 1 278
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,724评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,374评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,508评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,410评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,457评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,132评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,733评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,804评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,022评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,515评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,116评论 2 341

推荐阅读更多精彩内容