phpmarkdown电⼦书_PHP实现markdown⽂档管理⼯具
⼯作后⼀直在从事PHP开发, 从以前的⼤包⼤揽到现在的退居服务端写接⼝, 当中接触过⼏个的接⼝⽂档管理⼯具或系统, 简单描述
下:showdoc, 功能全⾯⽽且简洁, 有⽤户,权限管理功能, ⽀持markdown, ⽀持导出word, 有多种⽂档模板, ⽬录⽀持两级折叠梦见三条大蟒蛇
confluence, 功能强⼤(权限管理, 邮件提醒, 全⽂搜索, 插件管理等), 重, 收费的⼀个⽂档管理系统
swagger, 需要在代码中写⼤量的注释去配合
readmine, 功能丰富类似confluence, 它的⽂档是以txt保存的, 可以追溯变更, 可以全⽂搜索, 但是写⽂档有点痛苦, 适合任务/bug跟踪管理等
gitbook, nodejs安装, ⽀持markdown, ⽀持npm插件, 左侧的可折叠的⽬录树就需要装插件, 也可以装搜索插件, ⽬录是单独的markdown ⽂件, 我使⽤的时候感觉从md到HTML编译太慢(600+的⽂档, 要编译25分钟多, 如果有增量编译或提⾼编译速度的插件还请各位赐教)
两个⽉前因为项⽬的原因需要⼀个简单的⼯具来管理接⼝⽂档, 这次就把开发过程中的经历记录在这⾥, 抛砖引⽟~
李应升诫子书
主要⽬标可以多⼈编辑
可以在浏览器中查看
有⼀个可以⾃动展开并⾼亮的⽬录
pdf电子书制作
⽀持多级⽬录
⽀持markdown
快, ⽅便
解决⽅法结合git就可以实现, 正好也可以利⽤git的权限管理功能
需要将markdown编译成HTML⽂件部署到内⽹
因为要在浏览器中查看, 这⾥最终选择了接⼊简单, 界⾯清爽, ⽆依赖的dtree.js (不依赖jQuery), 改为了⽤PHP⽣成左侧⽬录树, 并优化css 使之⽀持PC和⼿机端显⽰
这个功能⽤了树的后根序遍历算法实现了对多级⽂件的读取(没有⽤递归, 担⼼写着写着把⾃⼰绕进去), 正好dtree.js 也⽀持多级⽬录折叠
这⾥我选择了segmentfault官⽅出的PHP编译⼯具类,改⽤ parsedown (相较sf的类他没有安全校验, ⽀持单⾏内多个换⾏符)
快: 编译600多个⽂件, PHP⽤时1s左右,可以接受, ⽽且⽀持增量编译; ⽅便: 主要体现在⽬录是⾃动⽣成的, 不需要单独编写⽬录⽂件
其中遇到的问题:
增量编译
~~刚开始判断⼀个md⽂件是否需要编译成HTML, 是拿md⽂件的创建时间和最后修改时间做对⽐进⾏判断的,
但是后来发现, ⼀些复制来的, 重命名的⽂件⽤这个⽅法就不起作⽤.
最后使⽤了⼀个中间⽂件, 去记录本次编译的⽂件的时间, 再跟 max(创建时间, 最后修改时间)对⽐判断是否需要编译~~
2021年2⽉2⽇ 更新:
因为⽂件的复制移动, 剪切移动, 重命名等情况会导致时间判断不准确, ⽽且时间的判断也不便于多⼈合作, 因此改为⽤md5摘要判断内容是否发⽣变化
张丰毅电影删除多余⽂件
后续使⽤过程中发现, 有些md⽂档被删除了, 但是没有⾃动删除最终编译后的html⽂件,
因此, 在编译时会对md⽂件和最后的HTML⽂件求⼀个差集, 删掉那些多余的HTML⽂件
⽀持多级⽬录
开始的时候想着, 按照多级数组来设计保存⽂件的层级关系, 然后再根据这个数组来展⽰⽬录, 后来实现的时候觉得太⿇烦, 实现不了多层级⽬录.
~~后来换了⼀种思路, 其实不同层级的⽂件, 显⽰的时候, 只是缩进不同⽽已: ⽂件名的缩进要⽐⽬录名的缩进⼤⼀些, 下级⽬录要⽐上级⽬录的缩进⼤⼀些;
于是:
⾸先通过树的遍历算法, 把⽂件夹中的所有⽂件的路径读出到⼀维数组中;
然后遍历每个⽂件路径, 将⽬录名和⽂件名拆开, 去重后, 都⽤p标签显⽰, 根据不同的层级, 增减p标签的padding-left, 达到缩进的效果;~~
2020年8⽉23⽇ 更新
原来的想法在交互时,虽然⽣成的HTML结构很简单,但展开与隐藏实现起来太过复杂,就放弃了;
现在引⼊了⼀个php-html类,先通过树的遍历算法把源⽂件夹中的⽂档都读取出来, 然后⽤此类⽣成嵌套的HTML去展⽰菜单
⽬录的折叠与展开效果
~~如果p标签中存放的是⽬录名, 就⽤属性data-path记录当前路径的hash值(MD5(a/b/c/)),
如果p标签中存放的是⽂件名, 就将上层⽬录的hash值存到⽂件p标签的class中,
这样, 点击⽬录名的时候就可以根据其hash值, 通过getElementsByClass()⽅法到所有的下级p标签, 进⾏显⽰或隐藏~~上⼀步⽣成嵌套的HTML时如果是⽂件就添加⼀个class="file", id为⽂件路径的hash值(md5(a/b/c/xxx.md))
如果是中间⽬录就添加⼀个class="dir",id为⽬录路径的hash值(md5(a/b/c))
⽤file_chain.js 记录下每个⽂件对应的所有层级的⽬录的hash值当⽤户点击某⼀个⽂件后跳转到此⽂件的页⾯杜暘
从file_chain.js中到此⽂件的所有上层⽬录
挨个修改其style.display='block'
最后阻⽌事件冒泡公⽤⽬录刚开始, ⽬录是编译后, 每个内容页⾯中都有, 后来发现增加或删除某个⽬录时, 没有被修改的页⾯是不会更新⽬录的
后来, 将⽬录HTML代码抽出来放到menu.js中, 每次修改都重洗⽣成⽬录, 然后由js动态加载; 这样⼀来解决了⽬录公⽤的问题, ⼆来减少了内容⽂件的⼤⼩
美化HTML, ⽀持响应式
⾸先在css中利⽤@media属性, 根据屏幕宽度不同使⽤不同的样式,
其中,
当屏幕宽度⼤于800px时, 当做PC端, ⽤css flex将⽬录和内容同时显⽰在屏幕中
七夕节什么时候
当屏幕宽度⼩于800px时, 当做是⼿机端, 默认将⽬录隐藏起来, 通过点击右下⾓的浮动按钮控制⽬录的显⽰与隐藏, 显⽰时铺满屏幕
隐藏⽬录: ⾸先将⽬录div的宽度设为屏幕的宽度(width:100vw), 然后⽤js将⽬录的div的左边距设为负值(sidebar.style.margin-left = -window.client.width)达到隐藏⽬录的效果
⼿动编译太⿇烦
后来发现, 每次⽤git commit 前要先⼿动在命令⾏⾥编译⼀下(php compile.php)觉得⿇烦,
就给git加了⼀个hook, 在提交之前⾃动执⾏编译命令, 这样就⽅便多了
最后附上源代码
效果图