|
下面的是maven网友根据我的需要写的python代码,我在自己的tex里运行了一下,目前没发现什么问题。
- # tex 文档必须在同一目录中,并且文档名必须是 c.s.tex 格式,其中 c,s 都是补前导零的两位数字,例如 01.02.tex
- # tex 文档中,环境起始和标签必须在同一行,例如 \begin{theorem}[Cauchy]\label{thm:01}
- # 用法:复制本文件到 tex 文档所在目录,在终端跳转到此目录,并运行 python3 auto_label.py,将备份被修改的文档并为这些文档加标签
- import os, re, uuid
- from collections import OrderedDict
- from datetime import datetime
- import shutil
- def process_file(text, chapter, section, env_name, env_short_name):
- """
- 处理单个文本,将指定环境都添加标签,并生成新旧标签的对应字典。
- :param text: 被处理的文本
- :param chapter: 章号,例如 01
- :param section: 节号,例如 02
- :param env_name: 环境名,例如 theorem
- :param env_short_name: 环境短名,例如 thm,用于标签前缀
- :return: 返回二元数组,第 0 个元素是将指定环境都添加标签后的文本,第 1 个元素是此文本中所有标签的新旧名对应字典。
- """
- pattern = re.compile(fr'\\begin{{{env_name}}}(\[.*?\])*(.*)')
- # 将文本中的环境全部增加 label 后的新文本。已有 label 不变,缺失 label 由 uuid 生成
- new_tex = ''
- # pdf 中可见的 label
- label_number = 0
- # 原 label 和 可见 label 的对应字典
- label_dict = OrderedDict({})
- for line_num, line in enumerate(text.splitlines(), start=1):
- result = re.match(pattern, line)
- # 匹配到环境起始行
- if result:
- label_number += 1
- new_line = f'\\begin{{{env_name}}}'
- if result.group(1) != None:
- new_line += str(result.group(1))
- env_label = str(result.group(2))
- old_label = uuid.uuid4().hex
- if env_label != '':
- old_label = re.match(r'\\label\{(.*)\}', env_label).group(1)
- new_line += f'\\label{{{old_label}}}'
- new_tex += new_line+'\n'
- new_label = f"{env_short_name}:{chapter}:{section}:{str(label_number).zfill(2)}"
- label_dict[old_label] = new_label
- # 非环境起始行,直接追加
- else:
- new_tex += line+'\n'
- # 字典逆序,替换时从 可见 label 的最大编号开始替换
- label_dict = OrderedDict(reversed(label_dict.items()))
- return [new_tex, label_dict]
- # 所有要处理的 tex 文档的环境标签字典。复数加 s,这就叫懂英文
- label_dicts = OrderedDict({})
- # 需要更新 label 的环境名和短名
- envs = [['definition', 'def'], ['theorem', 'thm'], ['proposition', 'ps']]
- # 待写入的文件键值对(文件名:新文本内容)
- new_files = {}
- # 处理所有 m.n.tex 文件,将文件名与新文本内容对应
- for fname in os.listdir('.'):
- if match := re.fullmatch(r'(\d{2})\.(\d{2})\.tex', fname):
- chapter, section = match.groups()
- with open(fname, 'r', encoding='utf-8') as f:
- text = f.read()
- for env in envs:
- text, label_dict = process_file(text, str(chapter), str(section), env[0], env[1])
- label_dicts.update(label_dict)
- new_files[fname] = text
- # 备份文件目录
- timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
- bak_dir = f'bak{timestamp}'
- os.makedirs(bak_dir, exist_ok=True)
- # 替换 label,备份并重新写入 tex 文件
- for fname, text in new_files.items():
- shutil.copy(fname, bak_dir)
- for old_label, label in label_dicts.items():
- text = text.replace(old_label, label)
- with open(fname, 'w', encoding='utf-8') as f:
- f.write(text)
复制代码 |
|