想用md记一些笔记,特别是一些日常需要快速查阅的命令或者手册, 因为用有道笔记之类的笔记软件,感觉过于庞大和笨重,用txt文件记录,格式上又不够清晰并且不能快速跳转。写成md,然后转成html似乎是个不错的选择。
md转html的工具遍地都是,但是这些工具转成的html都没有侧边栏目录,除非这个html非常短,这样的html页面查阅起来就跟txt也区别不大了。
想找个简单的工具,竟然很难找到合适的。要么就是可以生成目录,但是在目录在页面顶部,一滚动就看不见了;要么,就是特别笨重和麻烦,比如给你一个模板文件夹,文件夹里还有各种资源文件(图标,css, js库之类的),你得把你转好的html中<body>的内容拷贝到html模板文件里面的指定区域,这样每次都需要拷贝并且一个md文件竟然还搞出一个目录来实在让人崩溃。
其实,我需要的只是一个自动化的工具,能够生成有很简陋的侧边栏的html就行。
最后,实在没办法了,只能自己来搞,写了个简单的Python脚本。 (在Python2.7下运行没问题,对Python3不熟,没试过)
import argparse
import markdown
import os, os.path
import string, codecs
parser = argparse.ArgumentParser(add_help=True)
parser.add_argument('files', metavar='mdFile', type=str, nargs='+',
help='md files to be converted')
parser.add_argument('--aside-width', dest='asideWidth',type= int,
default=20, help='the width of the aside toc, specified as percents. e.g., 15 means 15 percents')
parser.add_argument('--no-number', dest='noNumber',action='store_true',
default=False, help='do not prepend numbers for headers')
args = parser.parse_args()
htmlTemplate = string.Template('''
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
<style>
html, body {width: 100%}
body {margin: 0px;}
aside.toc { position:fixed; top:0px; left: 0px; width: ${asideWidth}%; border-right: 2px solid grey; overflow: scroll}
main { position: relative; width: ${mainWidth}%; left: ${asideWidth}%; margin-left: 25px; }
${css_for_header_number}
</style>
</head>
<body>
<aside class="toc">$toc</aside>
<main>$mainContent</main>
<script>
var tocElem = document.querySelector("aside.toc");
tocElem.style.setProperty("height", window.innerHeight+'px');
window.addEventListener("resize", resizeThrottler, false);
var resizeTimeout;
function resizeThrottler() {
// ignore resize events as long as an actualResizeHandler execution is in the queue
if ( !resizeTimeout ) {
resizeTimeout = setTimeout(function() {
resizeTimeout = null;
actualResizeHandler();
}, 300);
}
}
function actualResizeHandler() {
tocElem.style.setProperty("height", window.innerHeight+'px');
}
</script>
<body>
''')
css_for_header_number = ''
if not args.noNumber:
css_for_header_number = '''
body { counter-reset: h1counter}
h1 { counter-reset: h2counter} /* cannot use the same counter as h2 is not the child of h1*/
h1::before {counter-increment: h1counter; content: counter(h1counter) " ";}
h2 { counter-reset: h3counter}
h2::before {counter-increment: h2counter; content: counter(h1counter) "." counter(h2counter) " "}
h3 { counter-reset: h4counter}
h3::before {counter-increment: h3counter; content: counter(h1counter) "." counter(h2counter) "." counter(h3counter) " "}
h4::before {counter-increment: h4counter; content: counter(h1counter) "." counter(h2counter) "." counter(h3counter) "." counter(h4counter) " "}
aside ul { counter-reset: section; list-style-type: none; }
aside li::before { counter-increment: section; content: counters(section,".") " "; }
aside ul ul ul ul ul li::before {content: none} /* number depth : 4 */
'''
if (args.files[0] == '*'):
files = filter(os.path.isfile, os.listdir(os.getcwd()))
files = filter(lambda x: x.endswith('.md'), files)
else:
files = filter(lambda x: x.endswith('.md'), args.files)
md = markdown.Markdown(extensions=['markdown.extensions.toc'], output_format="html5")
if not files:
print 'Error: File not found!'
else:
for fname in files:
# md.convert() accepts only unicode
infile = codecs.open(fname, mode="r", encoding="utf-8")
mdtext =infile.read()
# use convert() instead of convertFile() as convertFile() output the result to either a file or stdout.
mainContent = md.reset().convert(mdtext)
# warning: there should not be a marker such as [TOC] for toc in the converted .md file,
# or else md would not have attribute toc
# 100-3 : 3 percent for margin
html = htmlTemplate.substitute(asideWidth = args.asideWidth, mainWidth =(100-3-args.asideWidth), toc= md.toc, mainContent=mainContent, css_for_header_number=css_for_header_number)
outfile = open(fname[:-2]+'html', 'w')
outfile.write(html.encode('utf-8'))
infile.close()
outfile.close()
很简陋,脚本很简陋,生成的页面也很简陋,但是对我来说够用了。
使用前提: 1. md文件必须是utf-8编码的 2. 安装python markdown 库, pip install markdown
使用方式( 假定上面的代码保存成文件 md_conv.py) :
python md_conv.py --aside-width 25 someFile.md
25 表示侧边栏宽度是 25%,默认是20%; 如果把 someFile.md 改成 * 则转换当前目录下所有 .md文件。
默认会给标题生成编号(编号只到第四级标题;并且md文件里必须有至少一个一级标题,否则编号会有错误), 如果不想要编号, 可以指定选项 --no-number