-[一键制作CheatingPaper!]:从Markdown到Latex[未完成]

相较于从Word到Markdown,从Markdown到Latex的转换就简单多了,因为Markdown的语法本身就是Latex的子集,所以只需要将Markdown的语法转换为Latex的语法即可。

为什么使用Latex?

因为Latex的排版及其自由且高度自动化!用来制作CheatingPaper再合适不过了!(之前我用的是Adobe Illustrator,对于大量内容操作繁琐,排版复杂)

在这种情况下,我制作了一个简单的Python脚本,可以将Markdown转换为Latex。

Markdown转Latex

Latex设置

我们首先看看怎么样才能搞一个好的Latex模板,用来生成CheatingPaper。

别废话,直接上代码:

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
\documentclass{ctexart}  % 使用ctexart文档类,支持中文
\usepackage{amsmath} % 使用amsmath宏包,支持数学公式
\usepackage{multicol} % 用于多列布局
\usepackage[most]{tcolorbox} % 引入 tcolorbox 的 most 库以获得额外功能

\usepackage[ % 设置页面边距
a4paper, % 纸张大小
top=1mm,
bottom=1mm,
left=1mm,
right=1mm
marginparwidth=0mm,
marginparsep=0mm,
centering,
includefoot]{geometry}

% 设置 section 的样式
\usepackage{titlesec}
\titleformat{\section}
{\normalfont\large\bfseries\centering}{\thesection}{1em}{}
\titlespacing{\section}{0pt}{*1.5}{*1.5}
% 创建一个自定义的 box
\newtcolorbox{mybox}[2][]{
colback=white, % 盒子背景颜色
colframe=black, % 盒子边框颜色
coltitle=black, % 标题文本颜色
boxsep=1px, % 内部与边框的空间
top=1px, % 盒子顶部的空间
bottom=1px, % 盒子底部的空间
left=1px, % 盒子左边的空间
right=1px, % 盒子右边的空间
boxrule=0.5pt, % 边框宽度
sharp corners, % 设置为直角边框
fonttitle=\bfseries\scriptsize, % 标题字体加粗和大小
title={#2}, % 标题文本
attach title to upper, % 将标题文本放在盒子上方的内容顶部
% before=\vspace{-0.2px}, % 减小盒子前的垂直间距
after=\vspace{-8pt}, % 减小盒子后的垂直间距
#1
}

\begin{document}
\begin{multicols*}{3} % 创建一个三列的布局

% 第一个 section
\section*{Section 1}
\begin{mybox}{Box 1 Title}
\scriptsize % 设置最小字号
Box 1 content goes here.
\end{mybox}

\begin{mybox}{Box 2 Title}
\scriptsize % 设置最小字号
Box 2 content goes here.
\end{mybox}

% 第二个 section
\section*{Section 2}
\begin{mybox}{Box 3 Title}
\scriptsize % 设置最小字号
Box 3 content goes here.
\end{mybox}

% ... 更多 sections 和 boxes ...

\end{multicols*}
\end{document}

转换规则

  • Markdown的一级标题转换为Latex的section
  • Markdown的二级标题转换为Latex的box的标题
  • Markdown二级标题下的内容转换为box中的内容

完整代码

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
import os
import re


def escape_latex_chars(text):
"""
Escape LaTeX special characters in the text.
"""
# Escape % by replacing it with \%
text = text.replace('%', '\\%')
return text

def md_to_latex_box(md_content):
"""
Convert markdown content to LaTeX box content.
"""
# Convert lists first
# md_content = convert_md_list_to_latex(md_content)
# Add \end{mybox} before starting a new box
box_content = re.sub(r'^(## .+)$', r'\\end{mybox}\n\n\\begin{mybox}{\g<1>}', md_content, flags=re.MULTILINE)
# Correct the beginning of each box
box_content = re.sub(r'\\begin{mybox}{## (.+)}', r'\\begin{mybox}{\1}', box_content)
# Handle the content of the box, excluding the ones that are already part of itemize environment
box_content = re.sub(r'^(?!\\begin{mybox}|\\end{itemize})(.+)$', lambda match: ' ' + escape_latex_chars(match.group(0)), box_content, flags=re.MULTILINE)
# Add \end{mybox} to the end of the last box
if '\\begin{mybox}' in box_content:
box_content += r'\end{mybox}' + '\n'
return box_content

def md_to_latex_section(md_content):
# Convert markdown sections to LaTeX sections
# Add \end{mybox} before starting a new section if there was a box before
md_content = re.sub(r'^(# .+)$', r'\\end{mybox}\n\n\\section*{\g<1>}', md_content, flags=re.MULTILINE)
md_content = re.sub(r'\\section\*{# (.+)}', r'\\section*{\1}', md_content)
md_content = escape_latex_chars(md_content)
return md_content

def convert_md_file_to_latex(md_file_path, latex_file_path):
with open(md_file_path, 'r', encoding='utf-8') as md_file:
md_content = md_file.read()

# Convert markdown to LaTeX
latex_content = md_to_latex_section(md_content)
latex_content = md_to_latex_box(latex_content)

# Add LaTeX document preamble and ending
preamble = r'''\documentclass{article}
\usepackage{amsmath}
\usepackage{multicol} % 用于多列布局
\usepackage[most]{tcolorbox} % 引入 tcolorbox 的 most 库以获得额外功能

\usepackage[
a4paper,
top=0mm,
bottom=0mm,
left=0mm,
marginparwidth=0mm,
marginparsep=0mm,
centering,
includefoot]{geometry}

% 设置 section 的样式
\usepackage{titlesec}
\titleformat{\section}
{\normalfont\large\bfseries\centering}{\thesection}{1em}{}
\titlespacing{\section}{0pt}{*1.5}{*1.5}
% 创建一个自定义的 box
\newtcolorbox{mybox}[2][]{
colback=white, % 盒子背景颜色
colframe=black, % 盒子边框颜色
coltitle=black, % 标题文本颜色
boxsep=1px, % 内部与边框的空间
top=1px, % 盒子顶部的空间
bottom=1px, % 盒子底部的空间
left=1px, % 盒子左边的空间
right=1px, % 盒子右边的空间
boxrule=0.5pt, % 边框宽度
sharp corners, % 设置为直角边框
fonttitle=\bfseries\scriptsize, % 标题字体加粗和大小
title={#2}, % 标题文本
attach title to upper, % 将标题文本放在盒子上方的内容顶部
% before=\vspace{-0.2px}, % 减小盒子前的垂直间距
after=\vspace{-8pt}, % 减小盒子后的垂直间距
#1
}

\begin{document}
\begin{multicols*}{2} % 创建一个三列的布局
'''

ending = r'''
\end{multicols*}
\end{document}
'''

full_latex_content = preamble + latex_content + ending

# Write the converted content to a .tex file
with open(latex_file_path, 'w', encoding='utf-8') as latex_file:
latex_file.write(full_latex_content)

# Convert all markdown files in the current directory
for file in os.listdir('./'):
if file.endswith('.md'):
md_file_path = os.path.join('./', file)
latex_file_path = os.path.join('./', os.path.splitext(file)[0] + '.tex')
convert_md_file_to_latex(md_file_path, latex_file_path)
print(f"Converted {md_file_path} to {latex_file_path}")