唠唠闲话

正则表达式是一个很强大的字符串处理工具,几乎任何关于字符串的操作都可以使用正则表达式来完成。本篇用 Python 的正则表达式编写 LaTeX 工具。


LaTeX 表格

示例

  1. 生成前 8 阶二项式系数表格的 LaTeX 代码

  2. 方法一,使用 LaTeX 的 table 环境

    1
    2
    3
    4
    5
    from mylatex import latex_table
    n = 8
    title = ["(m,n)"] + list(range(1,n+1))
    mat = [ [j] + [binomial(j,i) for i in range(1,n+1)] for j in range(1,n+1)] # binomial 为 sagemath 自带函数
    latex_table(mat,title=title)

    输出效果:表格效果为首行深色,其余各行“灰白交替”
    binomial

  3. 方法二,使用 LaTeX 的 array 环境

    1
    2
    3
    4
    5
    from mylatex import latex_array_table
    n = 8
    title = ["(m,n)"] + list(range(1,n+1))
    mat = [ [j] + [binomial(j,i) for i in range(1,n+1)] for j in range(1,n+1)] # binomial 为 sagemath 自带函数
    latex_array_table(mat,title=title)

    输出效果:
    深度截图_选择区域_20220202104519

注:网页常用的 KaTeX 和 MathJax 均不支持 table 环境,此时可用 array 来显示表格。

表格语法

  1. 示例一基于表格语法:

    • \begin{table} 表格环境
    • \begin{tabular} 表格内容
    • \scalebox{<放缩比例>} 表格较大时,用于缩小
    • \hline 表格行线
    • \rowcolor{gray!50} 设置行颜色,!50 表示 50%
    • & 表格内容对齐符号
  2. 示例二基于 array 的语法,与上边类似。

Python 代码

  1. 方法一,使用 table 环境

    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
    import pyperclip # 用于复制的模块
    def latex_table(mat: list, title = None, scale: int = 1, copy: bool = True) -> str:
    """生成表格的 latex 代码

    Args:
    mat (list(list)): 表格内容
    title (list, optional): 表格标题,默认取 mat 首行
    scale (int, optional): 放大倍数. Defaults to 1.
    copy (bool, optional): 是否复制到剪贴板. Defaults to True.

    Returns:
    str: LaTeX 代码

    表格样式:
    - 表头深色,内容灰白相间
    - 文字居中
    - 带边框线
    """
    # 设置标题
    if title is not None:
    mat = [title] + mat
    # 检查输入
    assert len(mat), "不能输入空列表"
    # 数据格式转字符串
    mat = [[str(i) for i in line] for line in mat]
    # 行数,列数
    m,n = len(mat), len(mat[0])

    # 表格头部
    beg = r"""\begin{table}[h]
    \centering
    \scalebox{%.3f}{
    \rowcolors{2}{gray!25}{white}
    \begin{tabular}{|%s|}
    \rowcolor{gray!50}
    \hline
    """%(scale, 'c' * n)
    # 表格尾部
    end = '\n\\end{tabular}}\n\\end{table}'
    # 内容部分
    content = "\n".join(["&".join(line) + r"\\\hline" for line in mat])

    # 首尾连接
    out = beg + content + end
    if copy: # 复制到剪贴板
    pyperclip.copy(out)
    return out
  2. 方法二,使用 array 环境

    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
    def latex_array_table(mat: list, title = None, copy: bool = True) -> str:
    """生成表格的 latex 代码

    Args:
    mat (list): 表格内容
    title ([type], optional): 表格标题,默认取 mat 首行
    copy (bool, optional): 是否复制到剪贴板. Defaults to True.

    Returns:
    str: LaTex 代码
    """

    # 设置标题
    if title is not None:
    mat = [title] + mat
    # 检查输入
    assert len(mat), "不能输入空列表"
    # 数据格式转字符串
    mat = [[str(i) for i in line] for line in mat]
    # 行数,列数
    n = len(mat[0])

    # 表格头部
    beg = """\\begin{array}{|c|%s|}\n\\hline\n"""%('c'*(n-1))
    # 表格尾部
    end = '\n\\end{array}'
    # 内容部分
    content = "\n".join(["&".join(line) + r"\\\hline" for line in mat])
    # 首尾连接
    out = beg + content + end
    if copy: # 复制到剪贴板
    pyperclip.copy(out)
    return out

注:封装成类,可以更灵活地定制样式,如果用得多了再来重写。

LaTeX 矩阵

示例

  1. 计算矩阵的 5 次幂,并导出 LaTeX 代码

    (123234456)\begin{align*} \left(\begin{array}{ccc} 1&2&3\\ 2&3&4\\ 4&5&6 \end{array}\right) \end{align*}

  2. 输入如下:

    1
    2
    3
    from mylatex import latex_matrix
    mat = matrix([[1,2,3],[2,3,4],[4,5,6]]) # matrix 为 sagemath 自带函数
    latex_matrix(list(mat^5))
  3. tex 代码效果:
    输出:
    matrix

注:示例为 sagemath 代码;实际上,sagemath 自带数据转 tex 格式,但样式固定。

函数代码

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
def latex_matrix(mat: list, hrows = None, hcols = None, copy = True) -> str:
"""矩阵的 latex 代码

Args:
mat (list): 矩阵主体
hrows (set, optional): 设置行线. Defaults to None.
hcols (set, optional): 设置列线. Defaults to None.
copy (bool, optional): 是否复制到剪贴板. Defaults to True.

Returns:
str: LaTeX 代码

注:
hrows = {0, 1} 代表顶行和第 1 行画线
"""
# 检查输入
assert len(mat), "输入为空矩阵"
# 数据转字符串
mat = [[str(i) for i in line] for line in mat]
# 行数,列数
m,n = len(mat), len(mat[0])
# 设置列线
if hcols is None:
hcols = {}
f = lambda i: '|c' if i in hcols else "c"
# 设置行线
if hrows is None:
hrows = {}
g = lambda i: r'\\\hline' if i in hrows else r'\\'

# 头部
s = "".join(f(i) for i in range(n))
if n in hcols: # 设置列线
s += '|'
beg = r"""\begin{align*}
\left(\begin{array}{%s}
"""%s
# 尾部
end = "\n\\end{array}\\right)\n\\end{align*}"
# 内容部分
content = "\\hline\n" if 0 in hrows else ""
content += "\n".join(["&".join(line) + g(i) for i, line in enumerate(mat)])

# 输出结果
out = beg + content[:-2] + end
if copy: # 复制到剪贴板
pyperclip.copy(out)
return out

Markdown 表格

Markdown 语法参看这篇博客 ,因为与 LaTeX 编写思路类似,这里一并介绍。

示例

  1. 示例,打印表格,输入如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    from mylatex import markdown_table, MDtable_to_array_table
    ### 方法一 指定 title ###
    content = [[1,2,3],[2,3,4]]
    title = ["a","b","c"]
    markdown_table(content,title=title)

    ### 方法二 不指定 title ###
    content = [["a","b","c"],[1,2,3],[2,3,4]]
    markdown_table(content)
  2. 显示效果:

    a b c
    1 2 3
    2 3 4

注:使用 MDtable_to_array_table 可将 markdown 的表格代码转为 array 形式

Python 代码

  1. 将列表转为 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
    def markdown_table(content: list, title = None, copy = True) -> str:
    """将列表转化为 Markdown 格式

    Args:
    content (list): 表格内容
    title (list, optional): 表格标题,默认取 mat 首行
    copy (bool, optional): 是否复制到剪贴板. Defaults to True.

    Returns:
    str: markdown 代码
    """
    ''''''
    # 表格第二行格式(居中)
    align = "|".join([":-:"] * len(content[0]))
    # 行内元素用 | 分割
    content = ["|".join(str(i) for i in line) for line in content]
    # 设置标题
    if title is None: # 标题未定义,提取列表第一行作为标题
    title = content[0]
    content = content[1:]
    else:
    title = "|".join(str(i) for i in title)
    # 合并,导出文本
    txt = "\n".join([title, align, *content])
    if copy: # 复制到剪贴板
    pyperclip.copy(txt)
    return txt
  2. 将 markdown 表格转化为 LaTeX 的 array 表格

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    def MDtable_to_array_table(txt: str, copy: bool = True) -> str:
    """markdown 格式的字符串转化为数组形式

    Args:
    txt (str): [description]
    copy (bool, optional): 是否复制到剪贴板. Defaults to True.

    Returns:
    str: [description]
    """
    lines = txt.split("\n") # 按行拆分
    lines.pop(1) # 去掉格式行
    lines = [line.split("|") for line in lines]
    return latex_array_table(lines, copy=copy)

Dynkin 图

毕业论文要画很多图,之前用 tikz + python 写绘图工具,做了一部分。工具完整成型再放上来。