我是如何折腾我的毕业论文的

本文最后更新于:2024年4月30日 晚上

经过了历时几个月的论文写作,我的毕业设计的论文部分总算完成了,在此记录一下写论文时使用到的方法。

第一阶段,查资料、写论文。这个阶段我使用纯 markdown 编写论文内容并使用 git 做版本管理,不涉及 word 文档。

第二阶段,快交初稿了。开始有对 word 调格式的需求,在这个阶段我引入了 pandoc,并研究了一下使用 pandoc 直接套用模板排版的方法。

第三阶段,要定稿了。由于需要对论文的排版进行较精确的微调,pandoc + 模板 无法胜任这一任务,于是我开始放弃 markdown 格式,全面转到 docx 格式,为了避免 word 文档出问题,我写了一个脚本(详见下面 justfile 的 final 部分),在每次编辑后生成一份纯文本并将其和第二阶段的最后一版进行比较,并记录下每次比较的结果。

下面进入正题,主要是我第二阶段的做法。

Why

  • markdown 作为一种纯文本格式,方便备份,配合 git 也能实现较细粒度的版本管理。
  • 利用 pandoc + 模板来生成 docx 能减少一些重复的格式修改工作。
  • 用这种方式生成的 docx 可以很方便的自动生成目录!(要不然就得手动标注标题以及正文的大纲级别)

How

第一步,把 Git 与 Pandoc 安装好。

第二步,导出 docx 参考模板。

执行下面命令创建模板

1
pandoc.exe -o pandoc/custom-reference.docx --print-default-data-file reference.docx

第三步,按照自己学校要求修改 custom-reference.docx 中的格式

  • 各级标题字体格式
  • 正文字体与段落格式
  • 页码
  • 页边距
  • 等等

第四步,把下面的代码粘贴到到每一个需要插入分页符的位置(我会在文末提供我的 markdown 框架)

1
2
3
4
5
6
7
```{=openxml}
<w:p>
<w:r>
<w:br w:type="page"/>
</w:r>
</w:p>
```

然后可以导出 docx,执行下面命令即可:

1
2
3
4
5
# 使用pandoc默认模板
pandoc.exe -f markdown <你的文档的文件名>.md -o <要生成的文档的文件名>.docx

# 使用你自定义的模板
pandoc.exe -f markdown <你的文档的文件名>.md -o <要生成的文档的文件名>.docx --reference-doc=custom-reference.docx

折腾完毕

其他

本文所述方法在 Gitee 上还有一个 Git 仓库 [2],有需要的话可以去看看。

一些调整 docx 排版的技巧

注:下面的格式修改操作适用于 MS Office 2019 中的 Word,其他版本的 MS Office 以及金山 WPS 中对应配置的位置与此略有不同

1、添加页码后,删除页眉多出的横线

选中页眉,然后使用 Ctrl+Shift+N 快捷键即可

2、为摘要以及正文设置不同的页码格式

首先,选中 布局 选项卡,在摘要的尾部,正文之前插入 分隔符->分节符->下一页,作用是将 word 分节,并自动换页。此时选中页码会提示不同节的序号。

然后选中正文部分的页码,在 页眉和页脚 选项卡中取消选中 链接到前一节,就可以分别调整不同‘节’的页码格式了

3、自动生成的表格宽度不够

选中某个表格,在 表格工具->布局 选项卡中选中 自动调整->根据窗口自动调整表格 即可

4、修改正文的格式不要改 正文,应该改 正文文本

因为标题等元素会自动继承 正文 的格式,修改它会导致一些问题

偷懒神器

just[1],一个和 make 有点像的命令运行器。

贴一下我用到的 justfile

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
crlf_format := if os_family() == "windows" { 'fd -e md -x sd "\n" "\r\n" && sd "\n" "\r\n" .justfile' } else { "uname -sm" }

# 格式化源代码
fmt:
fd -e md -x mdfmt -w
just cc
just --fmt --unstable
{{ crlf_format }}、

# 生成docx用来预览
doc: fmt
pandoc -f markdown 论文.md -o output/论文预览-`date +"%Y-%m-%d_%H-%M"`.docx --reference-doc=pandoc/custom-reference-MyFormat.docx
@pandoc.exe -t plain -i 论文.md -o count.txt
just cc
@rm count.txt

# 重新生成docx模板
regen_ref:
pandoc -o pandoc/custom-reference.docx --print-default-data-file reference.docx

# 应用更改并提交至多个远程仓库
done: fmt
git commit -a -m "update"
git remote | xargs -I _ git push _

# 字数统计
cc:
#!/usr/bin/env python3
import re
with open("count.txt", "r", encoding="utf-8") as f:
# 读取文件内容
text = f.read()
# 统计汉字数量
pattern = re.compile(r'[\u4e00-\u9fa5]')
chinese_chars = pattern.findall(text)
chinese_count = len(chinese_chars)
# 统计英文字母数量
pattern = re.compile(r'[a-zA-Z]')
english_chars = pattern.findall(text)
english_count = len(english_chars)
# 统计标点符号数量
pattern = re.compile(r'[^\u4e00-\u9fa5a-zA-Z0-9\s]')
punctuation_chars = pattern.findall(text)
punctuation_count = len(punctuation_chars)
# 统计英文单词数量
words = re.findall(r'\b[A-Za-z]+\b', text)
word_count = len(words)
# 输出统计结果
print("汉字数量:", chinese_count)
print("英文字母数量:", english_count)
print("标点符号数量:", punctuation_count)
print("英文单词数量:", word_count)
print("汉字+字母+标点:", chinese_count+english_count+punctuation_count)
final:
pandoc.exe -t plain -i 论文.md -o 1.txt
pandoc.exe -t plain -i path/to/论文.docx -o count.txt
sed -i 's/。/。\n/g' 1.txt # 以句号为界断行
sed -i 's/。/。\n/g' count.txt
echo '最后的论文懒得往 `论文.md` 里更新了,把最后的 word 转换出的 txt diff 一下放这里吧' > diff.md
echo -e "\n\`\`\`diff\n$(diff --color -u 1.txt count.txt)\n\`\`\`" >> diff.md
mdfmt -w diff.md
sed -i 's/^ //g' diff.md
#mdcat README.md
rm 1.txt
just cc
@mv count.txt new.txt

markdown 模板

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
###### 标题

# 摘要

我能吞下玻璃而不伤身体

```{=openxml}
<w:p>
<w:r>
<w:br w:type="page"/>
</w:r>
</w:p>
```

###### Title

# Abstract

I can eat glass, it does not hurt me

```{=openxml}
<w:p>
<w:r>
<w:br w:type="page"/>
</w:r>
</w:p>
```

<!-- 占位用,转成 docx 后在此处添加目录:引用 → 目录 → 自动目录1 -->

```{=openxml}
<w:p>
<w:r>
<w:br w:type="page"/>
</w:r>
</w:p>
```

# 一、绪论

## 1.1 项目背景

我能吞下玻璃而不伤身体

## 1.2 行业现状

我能吞下玻璃而不伤身体

## 1.3 要解决的问题

我能吞下玻璃而不伤身体

```{=openxml}
<w:p>
<w:r>
<w:br w:type="page"/>
</w:r>
</w:p>
```

# 二、相关技术简介

我能吞下玻璃而不伤身体

```{=openxml}
<w:p>
<w:r>
<w:br w:type="page"/>
</w:r>
</w:p>
```

# 三、需求分析与设计

## 3.1 可行性分析

我能吞下玻璃而不伤身体

### 3.1.1 技术可行性

我能吞下玻璃而不伤身体

### 3.1.2 操作可行性

我能吞下玻璃而不伤身体

### 3.1.3 经济可行性

我能吞下玻璃而不伤身体

## 3.2 任务概述

我能吞下玻璃而不伤身体

## 3.3 需求分析

### 3.3.1 AA 需求

我能吞下玻璃而不伤身体

### 3.3.2 BB 需求

我能吞下玻璃而不伤身体

```{=openxml}
<w:p>
<w:r>
<w:br w:type="page"/>
</w:r>
</w:p>
```

# 五、实现

我能吞下玻璃而不伤身体

```{=openxml}
<w:p>
<w:r>
<w:br w:type="page"/>
</w:r>
</w:p>
```

# 六、测试

我能吞下玻璃而不伤身体

```{=openxml}
<w:p>
<w:r>
<w:br w:type="page"/>
</w:r>
</w:p>
```

# 七、总结与展望

我能吞下玻璃而不伤身体

# 致谢

我能吞下玻璃而不伤身体

```{=openxml}
<w:p>
<w:r>
<w:br w:type="page"/>
</w:r>
</w:p>
```

# 参考文献

我能吞下玻璃而不伤身体

```{=openxml}
<w:p>
<w:r>
<w:br w:type="page"/>
</w:r>
</w:p>
```

# 附录

我能吞下玻璃而不伤身体

参考


我是如何折腾我的毕业论文的
https://blog.oopsky.top/post/67e81ff3/
作者
waleslau
发布于
2023年4月24日
更新于
2024年4月30日
许可协议