背景

工作、生活中有很多写文档的需求,如何才能提高写作效率?选择合适的工具恰当的方法。下面分享一些工具和方法,为你的写作助力。

写作工具

对于我来说MarkDown+思维导图是一种效率极佳的写作方式。思维导图可以将我的思考清晰的展示,然后按照知识脉络完善文章内容。文章写作使用MarkDownMarkDown 编辑工具很多,经过使用比较我最终选择 Typora + MindNode

Typora 正式版本已经开始付费,89元买断机制,免费版可以下载历史Beta版本

正式版本

文档格式互转

有的时候,我们需要做文件的各种转换以满足展示场景,比如 Markdown转思维导图。

Mind to Markdown

思维导图转换为 Markdown ,MindNode 和 XMind 这两个工具直接导出 Markdown格式文件即可。

Markdown to Mind

使用 markmap 可以将 Markdown 转换为可视化、可交互的 HTML 格式的思维导图。

本文转换出来的效果如下

markmap

方式一:在线转换(https://markmap.js.org/repl)粘贴 markdown 到编辑区就可以导出Html或SVG。

markmap

方式二:在 vscode 中使用,安装插件(https://marketplace.visualstudio.com/items?itemName=gera2ld.markmap-vscode)

方式三:安装 markmap-cli 命令工具。

1
2
3
4
npm install -g markmap-cli
# 转换
markmap index.md -o index.html

万能转换

一个强大的命令行工具 Pandoc,用于将文件从一种标记语言转换为另一种标记语言。常用的标记语言包括 Markdown、ReStructuredText、HTML、LaTex、ePub 和 Microsoft Word DOCX。

在线转换地址(https://pandoc.org/try)。

Mac上直接使用 brew 安装

1
2
brew install pandoc

支持格式如下:

1
2
3
4
5
6
7
8
9
Input formats: native, json, markdown, markdown+lhs, rst, rst+lhs, docbook,
textile, html, latex, latex+lhs
Output formats: native, json, html, html5, html+lhs, html5+lhs, s5, slidy,
slideous, dzslides, docbook, opendocument, latex, latex+lhs,
beamer, beamer+lhs, context, texinfo, man, markdown,
markdown+lhs, plain, rst, rst+lhs, mediawiki, textile, rtf, org,
asciidoc, odt, docx, epub

Markdown 转 Html

1
2
pandoc index.md -o index.html -c Github.css

Markdown 转 Word

1
2
pandoc index.md -o index.docx -c Github.css

Markdown 转 PDF,PDF 转换相对复杂一些。转换分两步骤,所以需要先安装TeX Live 或者 MiKTeX

  • 第一步, Markdown 文件被转为 LaTeX 源文件。
  • 第二步,调用系统的 pdflatex (默认使用), xelatex 或者其他 TeX 命令,将 .tex 文件转换为最终的 PDF 文件。
1
2
3
brew install texlive
pandoc index.md -o index.pdf

如果内容包含中文会出现如下报错,这是因为 Pandoc 默认使用的 pdflatex 命令无法处理 Unicode 字符,我们需要使用 xelatex ,并通过 CJKmainfont 指定中文字体。可以通过 fc-list :lang=zh 命令查询支持的中文字体。

1
2
3
4
Error producing PDF.
! LaTeX Error: Unicode character 大 (U+5927)
not set up for use with LaTeX.

Macos 下面我们选择 PingFang SC。

1
2
pandoc --pdf-engine=xelatex -V CJKmainfont="PingFang SC" index.md -o index.pdf

如果内容需要对图表,方程式,表格和交叉引用进行编号,可以安装 pandoc-crossref。安装和语法如下:

1
2
brew install pandoc-crossref
  • {#fig:label}: 图片 ![img](img.png){#fig:key_img} 标记图片引用Key,然后在需要引用的位置加上[@fig: key_img]
  • {#eq:label}: 公式 $$ math $${#eq:math}
  • {#sec:label}: 章节
  • {#tbl:label}: 表格
1
2
3
4
5
6
# 转换 PDF
pandoc -F pandoc-crossref --pdf-engine=xelatex -V CJKmainfont="PingFang SC" index.md -o index.pdf
# 转换 Html
pandoc -F pandoc-crossref index.md -o index.html

Pandoc 还支持 YAML 格式的 header,通过 header 可以指定文章的标题,作者,更新时间等信息,如下:

1
2
3
4
5
6
---
title: "文章标题"
author: "lixp"
date: 2022-06-11
---

代码块高亮

1
2
3
4
5
# 代码块高亮
pandoc --list-highlight-styles
# 显示支持的语言
pandoc --list-highlight-languages

要使用语法高亮,Markdown 文件中的 block code 必须指定语言,同时在命令行使用--highlight-style 选项,例如:

1
2
pandoc -F pandoc-crossref --pdf-engine=xelatex -V CJKmainfont="PingFang SC" index.md --highlight-style espresso -o index.pdf

各种画图

写文档时,画图对于大多数人来说都比较痛苦吧。我们可以利用Mermaid 帮我们快速制作出想要的各种图等。它是一个基于 Javascript 的图表绘制工具,通过解析类 Markdown 的文本语法来实现图表的创建和动态修改。在线尝试一下。下面介绍一下 Markdown 里面画各种图。

Mermaid详细语法可查看:https://mermaid-js.github.io/mermaid

Mermaid

流程图

横向流程图

1
2
3
4
5
6
7
8
```mermaid
graph LR
A[开始] -->B(审批)
B --> C{年龄?}
C -->|年龄>=18| D[通过]
C -->|年龄<18| E[拒绝]
```

年龄>=18

年龄<18

开始

审批

年龄?

通过

拒绝

竖向流程图

1
2
3
4
5
6
7
8
```mermaid
graph TD
A[开始] -->B(审批)
B --> C{年龄?}
C -->|年龄>=18| D[通过]
C -->|年龄<18| E[拒绝]
```

年龄>=18

年龄<18

开始

审批

年龄?

通过

拒绝

标准横向流程图

1
2
3
4
5
6
7
8
9
10
11
12
```flow
st=>start: 开始
op=>operation: 审批
cond=>condition: 年龄是否大于18
sub1=>subroutine: 返回审批
io=>inputoutput: 通过
e=>end: 结束
st(right)->op(right)->cond
cond(yes)->io(bottom)->e
cond(no)->sub1(right)->op
```
Created with Raphaël 2.2.0开始审批年龄是否大于18通过结束返回审批yesno

标准竖向流程图

1
2
3
4
5
6
7
8
9
10
11
12
```flow
st=>start: 开始框
op=>operation: 处理框
cond=>condition: 判断框(是或否?)
sub1=>subroutine: 子流程
io=>inputoutput: 输入输出框
e=>end: 通过
st->op->cond
cond(yes)->io->e
cond(no)->sub1(right)->op
```
Created with Raphaël 2.2.0开始审批年龄是否大于18通过结束返回审批yesno

时序图

1
2
3
4
5
6
7
8
```sequence
对象A->对象B: 对象B你好吗?(请求)
Note right of 对象B: 对象B的描述
Note left of 对象A: 对象A的描述(提示)
对象B-->对象A: 我很好(响应)
对象A->对象B: 你真的好吗?
```
Created with Raphaël 2.2.0对象A对象A对象B对象B对象B你好吗?(请求)对象B的描述对象A的描述(提示)我很好(响应)你真的好吗?

复杂时序图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
```sequence
Title: 标题:复杂使用
对象A->对象B: 对象B你好吗?(请求)
Note right of 对象B: 对象B的描述
Note left of 对象A: 对象A的描述(提示)
对象B-->对象A: 我很好(响应)
对象B->小三: 你好吗
小三-->>对象A: 对象B找我了
对象A->对象B: 你真的好吗?
Note over 小三,对象B: 我们是朋友
participant C
Note right of C: 没人陪我玩
```
Created with Raphaël 2.2.0标题:复杂使用对象A对象A对象B对象B小三小三CC对象B你好吗?(请求)对象B的描述对象A的描述(提示)我很好(响应)你好吗对象B找我了你真的好吗?我们是朋友没人陪我玩

UML标准时序图:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
```mermaid
%% 时序图例子,-> 直线,-->虚线,->>实线箭头
sequenceDiagram
participant 张三
participant 李四
张三->王五: 王五你好吗?
loop 健康检查
王五->王五: 与疾病战斗
end
Note right of 王五: 合理 食物 <br/>看医生...
李四-->>张三: 很好!
王五->李四: 你怎么样?
李四-->王五: 很好!
```
王五李四张三王五李四张三loop[健康检查]合理 食物 看医生...王五你好吗?与疾病战斗很好!你怎么样?很好!

甘特图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
```mermaid
%% 语法示例
gantt
dateFormat YYYY-MM-DD
title 软件开发甘特图
section 设计
需求 :done, des1, 2022-01-06,2014-01-08
原型 :active, des2, 2022-01-09, 3d
UI设计 : des3, after des2, 5d
未来任务 : des4, after des3, 5d
section 开发
学习准备理解需求 :crit, done, 2022-01-06,24h
设计框架 :crit, done, after des2, 2d
开发 :crit, active, 3d
未来任务 :crit, 5d
耍 :2d
section 测试
功能测试 :active, a1, after des3, 3d
压力测试 :after a1 , 20h
测试报告 : 48h
```
2022-01-072022-01-092022-01-112022-01-132022-01-152022-01-172022-01-192022-01-212022-01-23需求 学习准备理解需求 原型 UI设计 设计框架 开发 未来任务 未来任务 功能测试 压力测试 测试报告 设计开发测试软件开发甘特图

类图

1
2
3
4
5
6
7
8
9
10
11
12
```mermaid
classDiagram
class Account
Account : +String owner
Account <|-- BankAccount
class BankAccount
BankAccount : +String owner
BankAccount : +Bigdecimal balance
BankAccount : +deposit(amount)
BankAccount : +withdrawl(amount)
```

Account

+String owner

BankAccount

+String owner

+Bigdecimal balance

+deposit(amount)

+withdrawl(amount)

状态图

1
2
3
4
5
6
7
8
9
```mermaid
stateDiagram-v2
[*] --> First
state First {
[*] --> second
second --> [*]
}
```
First

second

并图

1
2
3
4
5
6
7
```mermaid
pie
"苹果" : 386
"香蕉" : 85
"菠萝" : 15
```
79%17%3%苹果香蕉菠萝

用户体验旅程图

1
2
3
4
5
6
7
8
9
10
11
12
```mermaid
journey
title My working day
section Go to work
Make tea: 5: Me
Go upstairs: 3: Me
Do work: 1: Me, Cat
section Go home
Go downstairs: 5: Me
Sit down: 3: Me
```
CatMe
Go to work
Go to work
Me
Make tea
Make tea
Me
Go upstairs
Go upstairs
MeCat
Do work
Do work
Go home
Go home
Me
Go downstairs
Go downstairs
Me
Sit down
Sit down
My working day

Goat Ascii 图

Goat 可以将 ASCII 渲染成 SVG

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
```goat
+-------------------+ ^ .---.
| A Box |__.--.__ __.--> | .-. | |
| | '--' v | * |<--- | |
+-------------------+ '-' | |
Round *---(-. |
.-----------------. .-------. .----------. .-------. | | |
| Mixed Rounded | | | / Diagonals \ | | | | | |
| & Square Corners | '--. .--' / \ |---+---| '-)-' .--------.
'--+------------+-' .--. | '-------+--------' | | | | / Search /
| | | | '---. | '-------' | '-+------'
|<---------->| | | | v Interior | ^
' <---' '----' .-----------. ---. .--- v |
.------------------. Diag line | .-------. +---. \ / . |
| if (a > b) +---. .--->| | | | | Curved line \ / / \ |
| obj->fcn() | \ / | '-------' |<--' + / \ |
'------------------' '--' '--+--------' .--. .--. | .-. +Done?+-'
.---+-----. | ^ |\ | | /| .--+ | | \ /
| | | Join \|/ | | Curved | \| |/ | | \ | \ /
| | +----> o --o-- '-' Vertical '--' '--' '-- '--' + .---.
<--+---+-----' | /|\ | | 3 |
v not:line 'quotes' .-' '---'
.-. .---+--------. / A || B *bold* | ^
| | | Not a dot | <---+---<-- A dash--is not a line v |
'-' '---------+--' / Nor/is this. ---
```
& A M S i o i q f b B x u j o e a ( - x d r a > e f R > c o C n u o b ( n r ) ) d n e e J d r o s i n N o R D t o i u a a n g d d l o i t n e D i a g o n a l s C V u e r r v t e i d c a l n o t A N C : o u l d r r i A a / I v n s i n e e h s t d - e - t r l B i h i i s i o n ' s r e q n . u * o o b t t o e l a s d ' * l i n e D o n S e e ? a r c 3 h

让Hugo支持图表显示

我个人博客是使用 Hugo 创建,所以需要让它支持图表显示。

支持 mermaid

创建 layouts/_default/_markup/render-codeblock-mermaid.html 文件并添加下面代码:

1
2
3
4
5
<div class="mermaid">
{{- .Inner | safeHTML }}
</div>
{{ .Page.Store.Set "hasMermaid" true }}

然后在内容模板的底部(在 .Content 下方)添加下面代码:

1
2
3
4
5
6
7
{{ if .Page.Store.Get "hasMermaid" }}
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
<script>
mermaid.initialize({ startOnLoad: true });
</script>
{{ end }}

自定义Goat

通过(https://arthursonzogni.com/Diagon/)这个网站可以快速生成ASCII值。然后通过hugo渲染,下面是几个例子

流程图

O L _ D F _ K I _ B O _ O L _ A N _ U N _ O _ Y E _ T E _ Y W _ , _ S _ I O _ L _ Y _ U C _ Y A _ O L _ L H H _ O B _ U A _ I A U A _ _ U E _ _ B _ S T N R _ L _ S E _ T E D T _ n _ S E _ n _ E L _ n E E S _ o _ E D _ o _ E E _ o N Y R ? _ _ E _ _ D _ . O S _ _ ' _ _ T _ U T _ _ T Y _ _ H ' _ A _ _ H E _ _ E N _ N _ _ E S _ _ O _ D _ _ ' _ _ ' _ _ ? _ _ ? _ _ y _ e _ y _ y _ s _ e _ e _ _ s _ s _ _ _ _ W _ _ A _ _ I _ _ T _ _ , _ _ _ _ W _ _ H _ _ A _ _ T _ _ ? _ _ _ _ _ T _ _ H _ B F _ _ E _ U O _ _ _ T L _ _ A O _ L _ _ N N _ Y O _ _ D E _ O W _ _ S _ U E _ _ Y _ D _ _ O L _ _ J _ _ U A _ U T _ _ B _ n _ S H _ n _ C E _ o _ T E _ o ( A _ A L _ _ M _ T _ N E _ _ _ H Q S _ D _ _ T _ A U C _ S _ _ W _ T E R _ E ' _ _ I _ S E _ E N _ _ C _ W T W _ O _ _ E _ A I _ ' _ _ ? _ S O I _ ? _ N N T H I _ ' ) E N _ _ y T L Y S _ _ y _ e E , T _ _ e _ s T A _ _ s ' I L _ S L _ G S I _ O G H N _ O O O G _ D U _ D L F R D R G I E O N T E O G R B D Y S ! D !

编辑界面

1 2 3 4 5 6 7 8 # u i { } i s n n i t c n l g m c r u a o e d n i u t e a n t u m ( r < e ) n i s o p 0 s a " ; t c H r e e e l a s l m t o > d , ; W o r l d ! " ;

展示项目目录,安装 tree,将ASCII粘贴进来即可,非常方便

1
2
brew install tree
s t a       t       i c f i l o m i n g b t s c i r f f h j j s t h c e a l i q s l i a o w n o g u - i m n n a c w h e s d e c f r y c l r e e a e o d b h i y q o g r n o a g u u o y t x r h e t t t n D c i e a - g d r i a a m g s r a m s

如果上述画图不能满足,也可以使用图说在线制表,然后导出图片。