Python实现Word转为Markdown:CSDN新手发文窘境——文字篇


前言

  本来想把自己的一些笔记整理好放到CSDN的博客中,然而却被CSDN编辑器搞头大了。无论是科研还是工作中都很少用到Markdown“编辑器”(本文简称md法),它主张专注于打字,但不太符合我记笔记的习惯,换个颜色啥的;虽然它支持html语言实现各种“符合习惯的”的样式,但又丧失了专注于打字的功能。
  CSDN也支持富文本编辑器(本文简称rt法),但是从word中转移到富文本内图片上传的速度不敢苟同,且丧失了很多可以实现的效果,更气人的是,两个编辑器不能协同编辑。部分博主介绍了一种将Writage和Pandoc联动的方法(本文简称wp法)把docx格式转为md格式。个人试了一下,有几个方面的错误:1.公式通配符;2.图片添加不了;3.表格颜色单调;4.文字格式与word中不匹配。
  为了一次性解决众多问题,尝试使用一个Python脚本(doc2md)完成从word转换到CSDN能够支持的Markdown“编辑器”格式。本系列主要包括如下几个方面:1.文字篇;2.段落篇;3.表格篇;4.公式篇;5.图片篇
  
  各位小伙伴还有哪些想要的功能可以在评论区留言

  文字篇我们主要需要修改以及可修改的内容包括:

  文字字体、文字、文字加粗、文字倾斜、文字颜色、文字高亮、添加下划线、添加删除线

  测试所用数据(text.docx)挂这儿了,先对比看下效果

在这里插入图片描述
在这里插入图片描述

  需要系统理解实现过程的可以看前两部分,需要帮忙测试转换正确率的UU可以直接跳到最后一步

1️⃣ 读取Word文件

  工欲善其事必先利其器,这一部分我们会优先介绍word中的几个基本概念,主要用到的是docx库,用该库可以实现word的大部分功能,这里主要用于读取。

1.1 Word文件的几个基本概念

Document:一个Word文档对象List<Paragraph>,不同于 VBA 中 Worksheet 的概念,Document 是独立的,打开不同的 Word 文档,就会有不同的 Document 对象,相互之间没有影响;
Paragraph:一个段落对象List<Run>,一个 Word 文档由多个段落组成,当在文档中输入一个回车键,就会成为新的段落,输入 shift + 回车,不会分段这个地方我一开始就没理解好,正常输入一段文字,到页边距末尾的时候相当于自动输入一个回车键,这样就相当于一个新的段落;
Run :一个节段对象,每个段落由多个节段组成,一个段落中具有相同样式的连续文本,组成一个节段,所以一个段落对象有个Run 列表.

在这里插入图片描述

1.2 安装python-docx库

  能看到这篇博文,应该python编辑器安装都已经没问题了;我也不知道为什么那么多库安装和导入包的名字不一样,反正就是天天踩坑。

  基本动作Win+R,输入“cmd”,点击Enter

pip install python-docx

在这里插入图片描述

  安装完成以后,可以在python-docx官方文档查看相关用法,我在撰写本文的时候同时参考了【2.5万字】详解 Python-docx 自动生成word图文报告一文,当然就解决发文烦恼也可以只参考本文。

1.3 读取.doxc文件

  按照好python-docx后,我们通过如下命令导入该库

import docx

  实例化Document对象

doc=docx.Document(r'filepath')				#filepath应为需要转换的word文件目录
for paragraph in doc.paragraphs:  			# 遍历每一个段落
	print(paragraph.text)  					# 打印段落中的文本

2️⃣ 将文字格式(docx格式)转为CSDN可识别格式(md格式)

2.1 基本思路

  这里我们要弄清楚两种命令格式的区别

  (1)关于python-docx中读写文字格式信息的一些基本命令

			#关于python-docx中去写文字格式信息的一些基本命令
            runs=docx.Document.paragraphs
            #实例化一个r在runs列表内
            r.font.name                     				#文字字体
            r.font.size                     				#文字大小
            r.font.bold                     				#文字加粗
            r.font.italic                   				#文字倾斜
            r.font.color.rgb                				#文字颜色
            r.font.highlight_color          				#文字高亮
            r.font.underline                				#下划线
            r.font.strike                   				#删除线

  (2)关于md格式中可识别的文字格式信息的一些基本命令

			#关于md格式中可识别的文字格式信息的一些基本命令
            #假设我们要显示的字符串变量名为:char
            <font face='字体'> char</font>                  #文字字体
            <font size='字号'> char</font>                  #文字大小
            <b> char</b>                     				#文字加粗
            <i> char</i>                   					#文字倾斜
            <font color=#'16进制RGB颜色标识'> char</font>    #文字颜色
            <mark> char</mark>          					#文字高亮
            <u> char</u>                     				#下划线
            <s> char</s>                     				#删除线

  仔细对比两种格式不难发现,我们的思路可以是:1.获取word中文字格式信息;2.将节段对象的文本(run.text)按照对应格式修改。

2.2 代码实现

格式转换函数
  我们首先定义一个Get_run_format函数:用于读取word文字格式信息并将其转换为html格式,后续节段格式转换代码可以直接加到TODO部分

'''
    Get_run_format(run):   修改节段的格式信息函数
    input:                  实例化节段对象
    output:                修改为html格式的文字字符串
'''
def Get_run_format(run):
    r_text = run.text                                       #文本默认存储节段文本字符
    
    #TODO: 自定义添加你需要的节段格式转换
    
    return r_text											#返回修改后的节段文本字符

main函数
  我们在主函数中打开文件,调用Get_run_format(run)函数完成打印输出,这一部分的代码可以不做修改。

if __name__ == '__main__':
    doc = docx.Document(r'text.docx')  						 # 打开.docx文件
    for paragraph in doc.paragraphs:                         # 实例化文档中一个段落
        for run in paragraph.runs:                           # 实例化段落中一个节段
            run.text = Get_run_format(run)
        print(paragraph.text)                                # 打印段落中的文本

2.2.1 文字加粗

  run.font.bold只会返回两种结果:None-没加粗,True-加粗

# 判断文本是否加粗
    if run.font.bold == None:
        pass
    else:
        r_text = '<b>' + r_text + '</b>'

2.2.2 文字倾斜

  run.font.italic只会返回两种结果:None-没倾斜,True-倾斜

# 判断文本是否为斜体
    if run.font.italic == None:
        pass
    else:
        r_text = '<i>' + r_text + '</i>'

2.2.3 添加下划线

  run.font.underline只会返回两种结果:None-没添加下划线,True-添加下划线

# 判断文本是否有下划线
    if run.font.underline == None:
        pass
    else:
        r_text = '<u>' + r_text + '</u>'

2.2.4 添加删除线

  run.font.strike只会返回两种结果:None-没添加删除线,True-添加删除线

# 判断文本是否添加删除线
    if run.font.strike == None:
        pass
    else:
        r_text = '<s>' + r_text + '</s>'

2.2.5 文字颜色

  run.font.color.rgb返回的是16进制的RGB颜色值,这里是读取到word什么颜色,就修改成什么颜色,当然你也可以根据颜色对照表修改自己喜欢的自定义颜色

# 设置文字颜色
    if run.font.color.rgb == None:
        pass
    else:
        r_text = '<font color=#{}>'.format(run.font.color.rgb) + r_text + '</font>'

2.2.6 文字高亮

  这里我尝试过了下面的语句

         <mark style="background:red" >这里是输入的文本</mark>

  根据此生辽阔博主的介绍是可以更换成红色的, 但是我自己尝试的时候发现背景色并不能更换,只有黄色高亮标记能起作用

# 判断字体是否高亮显示:
    if run.font.highlight_color == None:
        pass
    else:
        r_text = '<mark>' + r_text + '</mark>'

2.2.7 文字字体

  run.font.name返回的是字体名称或“None”(“None”代表的是当前字体为docx文档的默认字体),节段的特性就是会将段落中格式发生变化的文字截断,所以每个节段内的格式应该是一致的,这里我们就只用节段的第一个字符串char[0]进行判断:
  首先,如果是默认字体,那么假设char[0]满足unicode字符中[‘\u4e00’,‘\u9fff’]的范围,则这部分节段应该是中文字符,默认设置为"楷体";否则就将默认设置为"Times New Roman"字体。如果不是默认字体就读取docx的字体为节段的字体格式。

# 设置字体,默认为楷体
    if run.font.name == None:
        if '\u4e00' <= run.text[0] <= '\u9fff':  # 中文字符串unicode范围,设置为楷体\u9fff
            r_text = '<font face="楷体">' + r_text + '</font>'
        else:  									# 数字&英文设置为Times New Roman
        #这里可以将"Times New Roman"替换为"Times"
            r_text = '<font face="Times New Roman">' + r_text + '</font>'
    else:
        r_text = '<font face={}>'.format(run.font.name) + r_text + '</font>'

2.2.8 文字大小

  这里经过简单的测试:markdown语法中,可以供选的大小从1~7,1最小,7最大,默认文字大小为3,根据run.font.size返回的结果

run.font.size输出结果对照表
初号小初一号1号二号2号三号3号四号4号五号5号六号6号
5334004572003302003048002794002286002032001905001778001524001333501143009525082550
# 设置文字大小,默认为3
if run.font.size == None or run.font.size == 152400:
    font_size = 3                                       #默认字体/4号字设置为3
elif run.font.size < 152400:
    if run.font.size < 95250:
        font_size = 1                                   #比六号字小的设置为1
    else:
        font_size = 2                                   #介于六号字到4号字之间的设置为2
else:
    if run.font.size == 177800:
        font_size = 4                                   #四号字置为4
    elif run.font.size < 203200:
        font_size = 5                                   #介于四号字到三号字之间的设置为5
    elif run.font.size < 279400:
        font_size = 6                                   #介于三号字到二号字之间的设置为6
    else:
        font_size = 7                                   #大于二号字之间的设置为7
r_text = '<font size={}>'.format(font_size) + r_text + '</font>'

3️⃣ 全部代码(欢迎UU们帮忙测试转换正确率💕)

  各位小伙伴还有哪些想要的功能可以在评论区留言

import docx                                                 #导入python-docx库
'''
    Get_run_format(run):     修改节段的格式信息
    input:                    实例化节段对象
    output:                  修改为html格式的文字字符串
'''
def Get_run_format(run):
    #TODO: 自定义添加你需要的节段格式转换
    r_text = run.text                                       #文本默认存储节段文本字符

    # 判断文本是否加粗
    if run.font.bold == None:
        pass
    else:
        r_text = '<b>' + r_text + '</b>'

    # 判断文本是否为斜体
    if run.font.italic == None:
        pass
    else:
        r_text = '<i>' + r_text + '</i>'

    # 判断文本是否有下划线
    if run.font.underline == None:
        pass
    else:
        r_text = '<u>' + r_text + '</u>'

    # 判断文本是否添加删除线
    if run.font.strike == None:
        pass
    else:
        r_text = '<s>' + r_text + '</s>'

    # 设置文字颜色
    if run.font.color.rgb == None:
        pass
    else:
        r_text = '<font color=#{}>'.format(run.font.color.rgb) + r_text + '</font>'

    # 判断字体是否高亮显示:
    if run.font.highlight_color == None:
        pass
    else:
        r_text = '<mark>' + r_text + '</mark>'

    # 设置字体,默认为楷体
    if run.font.name == None:
        if '\u4e00' <= run.text[0] <= '\u9fff':  # 中文字符串unicode范围,设置为楷体\u9fff
            r_text = '<font face="楷体">' + r_text + '</font>'
        else:  # 数字&英文设置为Times New Roman
            r_text = '<font face="Times New Roman">' + r_text + '</font>'
    else:
        r_text = '<font face={}>'.format(run.font.name) + r_text + '</font>'

    # 设置文字大小,默认为3
    if run.font.size == None or run.font.size == 152400:
        font_size = 3
    elif run.font.size < 152400:
        if run.font.size < 95250:
            font_size = 1
        else:
            font_size = 2
    else:
        if run.font.size == 177800:
            font_size = 4
        elif run.font.size < 203200:
            font_size = 5
        elif run.font.size < 279400:
            font_size = 6
        else:
            font_size = 7
    r_text = '<font size={}>'.format(font_size) + r_text + '</font>'

    return r_text


if __name__ == '__main__':
    doc = docx.Document(r'text.docx')  # 打开.docx文件
    for paragraph in doc.paragraphs:                         # 实例化文档中一个段落
        for run in paragraph.runs:                           # 实例化段落中一个节段
            run.text = Get_run_format(run)
        print(paragraph.text)                                # 打印段落中的文本

  细心的小伙伴可能发现了,我们的结果还是不能满足首行缩进、标题识别等功能,这部分我们放到下一篇《Python实现Word转为Markdown:CSDN新手发文窘境——段落篇》展开解释

               赶紧点赞、收藏起来吧!不然下次就找不到了💕

  • 7
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

测不绘的返工小渠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值