当前位置: 首页 > ds >正文

LaTeX论文转word插入mathtype公式

下面采用的方式是转成markdown然后再导出word,网上有些说用AI转成html并导出word的,自己没有尝试成功。

预处理

LaTeX文件有一些多余的换行符,另外还有一些markdown不识别的环境,需要用AI处理一下。
比如LaTeX原文为

这一段在LaTeX中编译显示为完整段落,但在Word中需要删除多余空行。
人工智能的历史可以追溯到20世纪中叶,其起源与计算机科学的发展密切相关。
1950年,英国数学家艾伦·图灵发表了具有里程碑意义的论文《计算机器与智能》,首次提出了“机器是否能够思考”的问题。
1956年,在美国达特茅斯学院举行的一次学术会议上,麦卡锡等人正式提出了“人工智能”这一术语,标志着该领域作为一门独立学科的诞生。像上面这样, LaTeX的段落之间还可能有大量多余的换行符。这里尝试插入几个行内公式$T$、$\alpha$。
下面是一个行间公式,其中的\eu是正体的e。
\begin{equation}o_t=\left\{R_{k},\dot{R}_{k},\dot{\lambda}_{k}\right\},\; k\in\{MT,MD\}
\end{equation}
下面是align环境的行间公式。
\begin{align}&f_1(x)=\eu^{-\beta_1|x|}+\eu^{-\beta_2|x|}\\[-5pt]&f_2(y)=\alpha[(y\leq R_1)+(y\leq R_2)+(y\leq R_3)]\\[-5pt]&r_t = f_1(R_{MT})+f_2(R_{MT})-f_1(R_{MD})-f_2(R_{MD})
\end{align}

在大模型中输入提示词

下面是论文的latex代码,将以下内容转换为markdown格式,给出可复制的markdown代码。
删除多余的换行符。
其中的\eu是正体的e,改为\mathrm{e}

Qwen输出的结果为(不用开深度思考,不然输出太慢)

人工智能的历史可以追溯到20世纪中叶,其起源与计算机科学的发展密切相关。1950年,英国数学家艾伦·图灵发表了具有里程碑意义的论文《计算机器与智能》,首次提出了“机器是否能够思考”的问题。1956年,在美国达特茅斯学院举行的一次学术会议上,麦卡锡等人正式提出了“人工智能”这一术语,标志着该领域作为一门独立学科的诞生。这里尝试插入几个行内公式 $T$、$\alpha$。下面是一个行间公式,其中的 $\mathrm{e}$ 是正体的 e。
$$
o_t=\left\{R_{k},\dot{R}_{k},\dot{\lambda}_{k}\right\},\; k\in\{MT,MD\}
$$下面是 `align` 环境的行间公式。
$$
\begin{aligned}
f_1(x)&=\mathrm{e}^{-\beta_1|x|}+\mathrm{e}^{-\beta_2|x|} \\
f_2(y)&=\alpha[(y\leq R_1)+(y\leq R_2)+(y\leq R_3)] \\
r_t &= f_1(R_{MT})+f_2(R_{MT})-f_1(R_{MD})-f_2(R_{MD})
\end{aligned}
$$

转换word

下面是一个将AI输出的Markdown文本转成Word的网站,需要注册付费,但不贵。
Markdown转Word

将预处理后的文本粘贴过去
在这里插入图片描述
导出的word公式使用的是内置公式,有些可能没有完全识别,但已经极大减轻工作量。
在这里插入图片描述

公式

接下来需要把公式转为mathtype。
在这里插入图片描述
转换后效果如下
在这里插入图片描述

接下来给行间公式添加右编号。
将光标放在公式后,按Tab键,用mathtype插入编号。
在这里插入图片描述

如果想删除手动换行符可以直接查找替换。
在这里插入图片描述

图片

有时候LaTeX中插入的图片是pdf格式,现在需要插入到word中。
可以使用下面的python程序,将所有子文件夹中的pdf和图片插到word中。然后再插到相应的位置。

import os
from pdf2image import convert_from_path  # 将PDF转换为图像的库
from docx import Document              # 用于创建和操作Word文档
from docx.shared import Cm             # 用于设置厘米单位的尺寸
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT  # 段落对齐方式枚举
from docx.oxml import OxmlElement      # 低级XML操作(用于插入域代码)
from docx.oxml.ns import qn            # XML命名空间处理
import tempfile                        # 用于创建临时目录
import re                              # 正则表达式处理# =====================
# 配置参数
# =====================
DPI_SETTING = 300                      # PDF转图片的分辨率设置(300 DPI保证清晰度)
IMAGE_EXTENSIONS = ['.png', '.jpg', '.jpeg', '.gif', '.bmp', '.tiff']  # 支持的图片格式
base_folder = "pic"                    # 默认图片基础目录(脚本将扫描此目录)# =====================
# 工具函数
# =====================def get_unique_filename(base_path):"""生成不冲突的唯一文件名(自动添加序号后缀):param base_path: 基础文件路径:return: 可用的唯一文件路径"""dir_name = os.path.dirname(base_path)  # 获取目录部分base_name = os.path.basename(base_path)  # 获取文件名部分name, ext = os.path.splitext(base_name)  # 分离文件名和扩展名# 如果文件不存在,直接返回原路径if not os.path.exists(base_path):return base_path# 文件已存在时,循环尝试添加序号后缀counter = 1while True:new_name = f"{name}_{counter}{ext}"  # 生成带序号的文件名new_path = os.path.join(dir_name, new_name)if not os.path.exists(new_path):  # 检查新路径是否可用return new_pathcounter += 1def sanitize_filename(name):"""清理文件名中的非法字符(Windows文件系统限制):param name: 原始文件名:return: 清理后的安全文件名"""# 移除Windows文件名中禁止的字符:\ / * ? " < > |return re.sub(r'[\\/*?:"<>|]', "", name)def add_caption(paragraph, label="图"):"""在段落中插入自动编号的题注域(SEQ域):param paragraph: 要插入题注的段落对象:param label: 题注前缀标签(默认"图")注意:此函数通过操作底层XML实现Word自动编号功能"""run = paragraph.add_run()  # 创建空文本段落# 插入域开始标记(w:fldCharType="begin")fldChar = OxmlElement('w:fldChar')fldChar.set(qn('w:fldCharType'), 'begin')run._r.append(fldChar)# 插入域指令文本(SEQ 图 \* ARABIC 表示按阿拉伯数字编号)instrText = OxmlElement('w:instrText')instrText.set(qn('xml:space'), 'preserve')instrText.text = f" SEQ {label} \\* ARABIC "run._r.append(instrText)# 插入域分隔标记(w:fldCharType="separate")fldChar = OxmlElement('w:fldChar')fldChar.set(qn('w:fldCharType'), 'separate')run._r.append(fldChar)# 插入显示文本(初始显示为"1")text = OxmlElement('w:t')text.text = "1"run._r.append(text)# 插入域结束标记(w:fldCharType="end")fldChar = OxmlElement('w:fldChar')fldChar.set(qn('w:fldCharType'), 'end')run._r.append(fldChar)def insert_centered_picture(doc, img_path, width):"""在文档中插入居中对齐的图片:param doc: Document对象:param img_path: 图片文件路径:param width: 图片显示宽度"""p = doc.add_paragraph()  # 创建新段落p.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER  # 段落居中对齐run = p.add_run()  # 创建运行对象run.add_picture(img_path, width=width)  # 插入图片并设置宽度# =====================
# 主逻辑
# =====================# 从基础目录名生成输出文件名(如"pic汇总.docx")
folder_name = os.path.basename(os.path.normpath(base_folder))
output_docx = f"{folder_name}汇总.docx"# 尝试使用模板文档(如果存在)
template_path = "template.docx"
try:doc = Document(template_path)  # 从模板创建文档print(f"使用模板: {template_path}")
except:doc = Document()  # 模板不存在时创建空白文档print("未找到模板,创建新文档")# 获取当前文档的第一个节(section)用于设置页面布局
section = doc.sections[0]# 设置标准页边距(单位可用 Inches 或 Cm)
section.left_margin = Cm(3.17)   # 左边距,默认值3.175
section.right_margin = Cm(3.17)  # 右边距,默认值3.175
section.top_margin = Cm(2.54)    # 上边距,默认值2.54
section.bottom_margin = Cm(2.54) # 下边距,默认值2.54# 添加居中的主标题(使用一级标题样式)
title = doc.add_heading(folder_name, level=1)
title.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER# 创建临时目录用于存储转换的PDF图片(自动清理)
with tempfile.TemporaryDirectory() as tmpdir:print(f"临时目录:{tmpdir}")print(f"PDF转换分辨率设置为: {DPI_SETTING} DPI")added_dirs = set()  # 记录已添加的目录(避免重复标题)# 递归遍历基础目录for dirpath, dirnames, filenames in os.walk(base_folder):# 计算相对于基础目录的路径(标准化为正斜杠)rel_path = os.path.relpath(dirpath, base_folder).replace(os.sep, '/')# 筛选PDF文件(不区分大小写)pdf_files = [f for f in filenames if f.lower().endswith('.pdf')]# 筛选支持的图片文件image_files = [f for f in filenames if any(f.lower().endswith(ext) for ext in IMAGE_EXTENSIONS)]# 跳过空目录if not pdf_files and not image_files:continue# 添加目录标题(仅当首次遇到该目录时)if rel_path not in added_dirs:if rel_path == '.':doc.add_heading("根目录", level=2)  # 根目录特殊处理else:doc.add_heading(rel_path, level=2)  # 子目录标题added_dirs.add(rel_path)print(f"添加目录: {rel_path}")# 处理PDF文件for filename in sorted(pdf_files):pdf_path = os.path.join(dirpath, filename)print(f"正在处理PDF:{pdf_path}")# 清理文件名作为标题(移除非法字符)title_name = sanitize_filename(os.path.splitext(filename)[0])doc.add_heading(title_name, level=3)  # 三级标题# 生成安全的相对路径标识符(替换斜杠为下划线)safe_rel_path = sanitize_filename(rel_path.replace('/', '_'))img_prefix = f"{safe_rel_path}_{title_name}"  # 图片前缀名try:# 将PDF转换为图像列表(每页一张图)images = convert_from_path(pdf_path, dpi=DPI_SETTING)except Exception as e:print(f"转换失败 {pdf_path}: {e}")# 添加错误提示段落(使用强调引用样式)doc.add_paragraph(f"[PDF转换失败:{filename}]", style='Intense Quote')continue# 处理PDF的每一页for i, image in enumerate(images):# 生成临时图片文件名(格式:目录_文件名_page_序号.png)img_filename = f"{img_prefix}_page_{i+1}.png"img_path = os.path.join(tmpdir, img_filename)image.save(img_path, "PNG")  # 保存为PNG格式# 计算可用页面宽度(考虑页边距)available_width = (section.page_width -section.left_margin -section.right_margin)# 插入居中图片(宽度设为可用宽度的95%)insert_centered_picture(doc, img_path, width=available_width * 0.95)# 添加题注(Caption样式)p = doc.add_paragraph(style='Caption')p.alignment = WD_PARAGRAPH_ALIGNMENT.CENTERp.add_run("图 ")  # 手动添加"图 "前缀add_caption(p, label="图")  # 插入自动编号域p.add_run(f" {title_name}_page_{i+1}")  # 添加描述文本# 处理图片文件for filename in sorted(image_files):img_path = os.path.join(dirpath, filename)print(f"正在处理图片:{img_path}")# 清理文件名作为标题title_name = sanitize_filename(os.path.splitext(filename)[0])doc.add_heading(title_name, level=3)  # 三级标题# 计算可用页面宽度available_width = (section.page_width -section.left_margin -section.right_margin)try:# 插入居中图片insert_centered_picture(doc, img_path, width=available_width * 0.95)except Exception as e:print(f"插入图片失败 {img_path}: {e}")# 添加错误提示段落doc.add_paragraph(f"[图片插入失败:{filename}]", style='Intense Quote')continue# 添加题注(与PDF处理逻辑一致)p = doc.add_paragraph(style='Caption')p.alignment = WD_PARAGRAPH_ALIGNMENT.CENTERp.add_run("图 ")add_caption(p, label="图")p.add_run(f" {title_name}")# 保存文档(自动处理文件名冲突)
unique_output = get_unique_filename(output_docx)
doc.save(unique_output)
print(f"\nWord 文档已生成:{unique_output}")
print(f"输出路径: {os.path.abspath(unique_output)}")# =====================
# 更新Word域(需要 Windows + Word)
# =====================
try:# 尝试通过COM接口更新域(仅Windows有效)import win32com.client as win32word = win32.Dispatch("Word.Application")  # 启动Wordword.Visible = False  # 后台运行docx_path = os.path.abspath(unique_output)docx = word.Documents.Open(docx_path)  # 打开文档docx.Fields.Update()  # 更新所有域(自动编号、目录等)docx.Save()  # 保存更新docx.Close()  # 关闭文档word.Quit()  # 退出Wordprint("已自动更新所有域(编号、目录等)")
except Exception as e:# 非Windows环境或权限问题时的提示print("无法自动更新域,请在Word中手动全选(Ctrl+A)后按F9 刷新。")print(f"错误信息: {e}")# 提示文件名冲突情况
if unique_output != output_docx:counter = unique_output.split('_')[-1].split('.')[0]  # 提取序号print(f"注意: 由于文件名冲突,已自动添加编号后缀(_{counter})")

表格

暂时没有太好的方法,都不如直接插更快。
markdown也行,但不一定比手动插更快。

格式调整建议

善用 F4

http://www.xdnf.cn/news/19082.html

相关文章:

  • C/C++ 数据结构 —— 线索二叉树
  • 【C++】map 容器的使用
  • django配置多个app使用同一个static静态文件目录
  • Android Glide最佳实践:高效图片加载完全指南
  • 滥用Mybatis一级缓存引发OOM问题
  • 网络安全监控中心
  • 阿里云——计算服务深度解析与选型
  • ChatGPT 上线 “学习模式”:全版本开放,重构 AI 教育逻辑
  • 基于单片机步进电机控制电机正反转加减速系统Proteus仿真(含全部资料)
  • 北斗导航|接收机自主完好性监测算法综述
  • java数据类型获取长度方式总结
  • SpringBoot集成 DeepSeek 对话补全功能
  • Spark学习记录
  • Unity 客户端和服务器端 基于网络的账户管理系统
  • 除自身以外数组的乘积是什么意思
  • 【OpenGL】LearnOpenGL学习笔记16 - 帧缓冲(FBO)、渲染缓冲(RBO)
  • 【JUC】——线程池
  • 点评项目(Redis中间件)第一部分Redis基础
  • docker run 后报错/bin/bash: /bin/bash: cannot execute binary file总结
  • 边缘计算:一场由物理定律发起的“计算革命”
  • 预测模型及超参数:2.传统机器学习:PLS及其改进
  • HarmonyOS 高效数据存储全攻略:从本地优化到分布式实战
  • 从 GRIT 到 WebUI:Chromium 内置资源加载与前端展示的完整链路解析
  • AI Agent 发展趋势与架构演进
  • 稳敏双态融合架构--架构师的练就
  • 【MES】工业4.0智能制造数字化工厂(数字车间、MES、ERP)解决方案:智能工厂体系架构、系统集成以及智能设计、生产、管理、仓储物流等
  • uvloop深度实践:从原理到高性能异步应用实战
  • http请求能支持多大内容的请求
  • 通义万相音频驱动视频模型Wan2.2-S2V重磅开源
  • 安卓接入通义千问AI的实现记录