Gar 是一个 Bash 脚本程序,用于治理 Markdown 文档我的项目,可将 Markdown 文档汇合其转化为 HTML 文档汇合。Gar 的运行,依赖 pandoc,git,tree 以及一个能在 Shell(命令行)里关上指定网页文件的网页浏览器。Gar 默认将 Firefox 作为网页浏览器,然而可在文档我的项目根目录的 gar.conf 文件中指定其它符合要求的网页浏览器。
文档我的项目初始化
命令:gar init 文档我的项目名
例如:
$ gar init demo[master (root-commit) 6f7dd1c] init 1 file changed, 2 insertions(+) create mode 100644 gar.conf
以下命令可察看 gar init
发明了什么:
$ cd demo$ ls -a .. gar.conf .git output source 图片
$ gar treedemo├── gar.conf├── output├── source└── 图片
$ git logcommit 6f7dd1c23c0cc8b18eb84b6a5236605eebd2bfbf (HEAD -> master)Author: xxx <xxx@yyy.zzz>Date: Tue Mar 9 07:30:53 2021 +0800 init
文档我的项目初始化后,文档的撰写和编辑工作次要在 source
目录进行。Gar 将 Markdown 文档转化为 HTML 文档后,放在 output
子目录内。
文集创立与删除
进入 source
目录:
$ cd source
创立文集 foo:
$ gar new-class foo
可应用 gar tree
查看文档我的项目的目录变动,察看 gar new-class
发明了什么:
$ gar treedemo├── gar.conf├── output│ └── foo├── source│ └── foo└── 图片 └── foo
可一次创立多个文集:
$ gar new-class a b c
后果为:
$ gar treedemo├── gar.conf├── output│ ├── a│ ├── b│ ├── c│ └── foo├── source│ ├── a│ ├── b│ ├── c│ └── foo└── 图片 ├── a ├── b ├── c └── foo
删除文集:
$ gar remove-class a b c$ gar treedemo├── gar.conf├── output│ └── foo├── source│ └── foo└── 图片 └── foo
可在文集里创立子文集:
$ cd foo$ gar new-class a$ gar treedemo├── gar.conf├── output│ └── foo│ └── a├── source│ └── foo│ └── a└── 图片 └── foo └── a
可创立文集档次序列:
$ gar new-class b/c/d/e/f$ gar treedemo├── gar.conf├── output│ └── foo│ ├── a│ └── b│ └── c│ └── d│ └── e│ └── f├── source│ └── foo│ ├── a│ └── b│ └── c│ └── d│ └── e│ └── f└── 图片 └── foo ├── a └── b └── c └── d └── e └── f
将试验复盘:
$ gar remove-class a b$ gar treedemo├── gar.conf├── output│ └── foo├── source│ └── foo└── 图片 └── foo
提醒,目前工作目录仍为 source/foo。
创立和删除文档
在文集目录内,应用 gar new-post
创立内容为空的文档。例如,在 source/foo 内创立 test.md 文档:
$ gar new-post test.md[master 6a894eb] Added test.md 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 source/foo/test.md
查看产生了什么:
$ gar treedemo├── gar.conf├── output│ └── foo├── source│ └── foo│ └── test.md└── 图片 └── foo └── test
$ git logcommit 6a894eb44cf66e95b4ff938e05c019b7218039e0 (HEAD -> master)Author: xxx <xxx@yyy.zzz>Date: Tue Mar 9 08:16:49 2021 +0800 Added test.mdcommit 6f7dd1c23c0cc8b18eb84b6a5236605eebd2bfbfAuthor: xxx <xxx@yyy.zzz>Date: Tue Mar 9 07:30:53 2021 +0800 init
每次创立文档时,Gar 会调用 git 记录文档创立历史。
可一次创立多份空文档:
$ gar new-post a.md b.md c.md[master 25e7d65] Added a.md b.md c.md 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 source/foo/a.md create mode 100644 source/foo/b.md create mode 100644 source/foo/c.md
$ gar treedemo├── gar.conf├── output│ └── foo├── source│ └── foo│ ├── a.md│ ├── b.md│ ├── c.md│ └── test.md└── 图片 └── foo ├── a ├── b ├── c └── test
应用 gar remove-post
可删除当前工作目录下的文档。以下命令可将上述创立的文档一举删除:
$ gar remove-post test.md a.md b.md c.md[master 189da8b] Remove test.md a.md b.md c.md 4 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 source/foo/a.md delete mode 100644 source/foo/b.md delete mode 100644 source/foo/c.md delete mode 100644 source/foo/test.md
每次删除文档,git 会记录文档的删除历史。
通过上述操作后,这个试验性的文档我的项目又复盘为:
$ gar treedemo├── gar.conf├── output│ └── foo├── source│ └── foo└── 图片 └── foo
网页的生成和预览
记住,以后的工作目录仍然是 source/foo
。上面的命令从新创立 test.md:
$ gar new-post test.md
而后用文本编辑器关上 test.md,减少以下内容:
<!--.. title: Hello Gar!-->这只是一份无用的示例文档。
应用 gar convert
命令可将文档 test.md 转换为网页文件 test.html,并将其置于 文档我的项目根目录/output/foo
目录内:
$ gar convert test.md
查看文档目录产生的变动:
$ gar treedemo├── gar.conf├── output│ └── foo│ └── test.html├── source│ └── foo│ └── test.md└── 图片 └── foo └── test
假使工作目录(以后文集)内有多份文档,也能够一次性将其转换为一组网页文件,例如:
$ gar convert test.md a.md b.md c.md
应用 gar preview
命令,可将文档转化为网页文件,并由 Gar 默认的网页浏览器关上:
$ gar preview test.md
gar preview
不反对多份文档一次性转换和预览。
附录
Gar 的全副代码:
#!/bin/bashSCRIPT_PATH=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)GAR_CONF=gar.confSOURCE=sourceIMAGES=图片OUTPUT=outputfunction error_msg { echo $1 exit -1}function goto_root { if [ ! -e $GAR_CONF ] then if [ $(pwd) = / ] then echo "gar.conf Not found!" else cd .. goto_root fi fi}function class_name { TARGET_PATH=$1 goto_root SOURCE_PATH=$(pwd)/$SOURCE/ echo ${TARGET_PATH//$SOURCE_PATH/}}function get_title { NAME=${1%.md} # 将文件名里用于距离中文和英文的短线替换为空格 L_SPACE_PAT='s/\([^a-zA-Z]\)-/\1 /g' R_SPACE_PAT='s/-\([^a-zA-Z]\)/ \1/g' FANCY_NAME="$(echo $NAME | sed -e "$L_SPACE_PAT; $R_SPACE_PAT")" # 文章题目 PREFIX="^[[:space:]]*\.\.[[:space:]]*title:[[:space:]]*" TITLE=$(grep -o "${PREFIX}.*$" $1 | sed -e "s/${PREFIX}\(.*\)$/\1/g") if [ -z "$TITLE" ] then TITLE=$FANCY_NAME fi echo $TITLE}function markdown_to_html { HTML=$OUTPUT/$1/${2%.*}.html pandoc $SOURCE/$1/$2 -s --mathjax \ -c $SCRIPT_PATH/gar.css \ --highlight-style pygments \ --metadata title="$TITLE" -o $HTML}case $1 in init) case $2 in "") error_msg "You should tell me the name of the project!" ;; *) mkdir $2 cd $2 echo '#!/bin/bash' > $GAR_CONF echo "BROWSER_FOR_GAR=firefox" >> $GAR_CONF mkdir $SOURCE $OUTPUT $IMAGES git init -q git add . git commit -a -m "init" ;; esac ;; new-class) case $2 in "") error_msg "You should tell me the name of the posts class!" ;; *) for i in ${@:2} do MARK=$(pwd) mkdir -p $i cd $i CLASS_NAME=$(class_name $MARK/$i) goto_root mkdir -p $IMAGES/$CLASS_NAME mkdir -p $OUTPUT/$CLASS_NAME cd $MARK done ;; esac ;; remove-class) case $2 in "") error_msg "You should tell me the name of the posts class!" ;; *) for i in ${@:2} do MARK=$(pwd) rm -rf $i CLASS_NAME=$(class_name $MARK/$i) goto_root rm -rf $IMAGES/$CLASS_NAME rm -rf $OUTPUT/$CLASS_NAME cd $MARK done ;; esac ;; new-post) case $2 in "") error_msg "You should tell me the name of the post!" ;; *) MARK=$(pwd) CLASS_NAME=$(class_name $MARK) for i in ${@:2} do touch $i goto_root mkdir -p $IMAGES/$CLASS_NAME/${i%.*} cd $MARK done goto_root git add . DOCUMENTS="${@:2}" git commit -a -m "Added $DOCUMENTS" ;; esac ;; remove-post) case $2 in "") error_msg "You should tell me the name of the post!" ;; *) MARK=$(pwd) for i in ${@:2} do if [ ! -e $i ] then error_msg "The file you want to remove is not found!" fi rm $i CLASS_NAME=$(class_name $MARK) goto_root rm -rf $IMAGES/$CLASS_NAME/${i%.*} HTML_OF_POST=$OUTPUT/$CLASS_NAME/${i%.*}.html if [ -e HTML_OF_POST ] then rm $HTML_OF_POST fi cd $MARK done goto_root git add . DOCUMENTS="${@:2}" git commit -a -m "Remove $DOCUMENTS" ;; esac ;; rename) case $2 in "") error_msg "You should tell me the name of the post you want to rename!" ;; *) if [ ! -e $2 ] then error_msg "The file you want to rename is not found!" fi case $3 in "") error_msg "You should tell me new name of the post!" ;; *) mv $2 $3 CLASS_NAME=$(class_name $(pwd)) goto_root mv $IMAGES/$CLASS_NAME/${2%.*} $IMAGES/$CLASS_NAME/${3%.*} mv $OUTPUT/$CLASS_NAME/${2%.*} $OUTPUT/$CLASS_NAME/${3%.*} git add . git commit -a -m "Rename $2 $3" ;; esac ;; esac ;; convert) case $2 in "") error_msg "You should tell me the name of the post!" ;; *) MARK=$(pwd) for i in ${@:2} do TITLE=$(get_title $i) CLASS_NAME=$(class_name $MARK) goto_root markdown_to_html $CLASS_NAME $i cd $MARK done ;; esac ;; preview) case $2 in "") error_msg "You should tell me the name of the post!" ;; *) TITLE=$(get_title $2) CLASS_NAME=$(class_name $(pwd)) goto_root source gar.conf $BROWSER_FOR_GAR $OUTPUT/$CLASS_NAME/${2%.*}.html ;; esac ;; tree) goto_root GAR_ROOT=$(basename $(pwd)) cd .. tree $GAR_ROOT cd $GAR_ROOT ;; *) error_msg "I do not know what you want to do!" ;;esac
Gar 在应用 pandoc 将 Markdown 文档转化为网页时,须要一个 CSS 文件 gar.css,其内容如下:
html { font-size: 16px; line-height: 1.8rem;}body { margin: 0 auto; max-width: 50rem; padding: 50px; hyphens: auto; word-wrap: break-word; font-kerning: normal;}header { text-align: center; margin-bottom: 4rem;}h1, h2, h3, h4, h5 { margin-top: 2rem; margin-bottom: 2rem; color: #d35400;}h1.title { font-size: 2.5rem; }h1 { font-size: 1.8rem; }h2 { font-size: 1.65rem; }h3 { font-size: 1.5em; }h4 { font-size: 1.35rem; }h5 { font-size: 1.2rem; }p { margin: 1.3rem 0; text-align: justify;}figure { text-align: center;}figure img { width: 80%;}figure figcaption { font-size: 0.9rem;}pre { padding: 1rem; font-size: 0.9rem; line-height: 1.6em; overflow:auto; background: #f8f8f8; border: 1px solid #ccc; border-radius: 0.25rem;}p code { color: #d35400;}/* 文章里大节题目的序号与题目名称之间的间距 */span.section-sep { margin-left: 0.5rem; margin-right: 0.5rem; }blockquote { margin: 0px !important; border-left: 4px solid #009A61;}blockquote p { font-size: 1rem; line-height: 1.8rem; margin: 0px !important; text-align: justify; padding:0.5em;}
上述 gar.css 并无特别之处,齐全可依据本人对 css 的相熟水平并联合须要自行定制,然而要记得将它放在 gar 脚本同一目录下。