如何编程(比如用 Python )实现给本地 Markdown 文件标题添加分级序号?断断续续琢磨两天都没想清楚。。

2020-04-20 14:21:54 +08:00
 Higurashi

现在有一个有很多级目录的 Markdown 文件,如:

# 标题 1

### 标题 2

### 标题 3

#### 标题 4

#### 标题 5

## 标题 6

##### 标题 7

###### 标题 8

该如何编写程序实现在每个标题前添加编号?(如下):

# 1. 标题 1

### 1.1 标题 2

### 1.2 标题 3

#### 1.2.1 标题 4

#### 1.2.2 标题 5

# 2. 标题 6

##### 2.1 标题 7

###### 2.2 标题 8
797 次点击
所在节点    问与答
10 条回复
zictos
2020-04-20 16:39:17 +08:00
服了,我怎么知道你什么时候需要 1.2.1 、1.2.2 啊?之前以为是 1.3 、1.4 。所以写的是 1.3 、1.4,你可以参考下,除了 1.2.1 变成了 1.3,1.2.2 变成了 1.4,其他都是一样的:

with open("test.md", "r+" , encoding='utf-8') as f:
text=f.read()
f.seek(0)
a=0
b=0
c=0
for i in text.splitlines():
print(i)
if 0<i.count('#')<3:
a=a+1
space=i.find(' ')
i=list(i)
i.insert(space+1, str(a)+'. ')
i=''.join(i)
f.write(i+'\n')
f.flush()
b=0
c=a


elif i.count('#')>=3:
b=c+b+0.1
b=round(b,1)
space=i.find(' ')
i=list(i)
i.insert(space+1, str(b)+' ')
i=''.join(i)
f.write(i+'\n')
f.flush()
c=0

else:
f.write(i+'\n')
f.flush()
zictos
2020-04-20 16:41:39 +08:00
Higurashi
2020-04-20 20:22:37 +08:00
@zhybzc 之前我还没说得很清楚,事实上,上面其实只是个例子。这个程序虽然可以实现给这个例子编号,但对下面这类情况:
```
### 标题 1

#### 标题 2

#### 标题 3

#### 标题 4

##### 标题 5

##### 标题 6

## 标题 7

##### 标题 8

##### 标题 9
```
可能就无能为力了,但这样一种情况按照我们平时写 Markdown 的习惯其实是可以如下编号的:
```
### 1. 标题 1

#### 1.1 标题 2

#### 1.2 标题 3

#### 1.3 标题 4

##### 1.3.1 标题 5

##### 1.3.2 标题 6

## 2. 标题 7

##### 2.1 标题 8

#####2.2 标题 9
```
也就是说,这个程序的目的就是帮助我们为平时能够添加编号的各种情况添加编号。
zictos
2020-04-21 02:28:50 +08:00
@Higurashi #号突然变少就从 1 变成 2 是吧?比如你刚举的例子中从 5 个#号变成 2 个#号,序号就从 1 变成 2 了。可是如果 1.3.2 后面还有 1.4 呢? 1.3.2 后面如果是 4 个#号就是 1.4 吗?
大标题中 1 是三个#号,怎么 2 又只有两个#号?

我不太懂 Markdown 的习惯,也不一定每个人都一样吧?序号也本身是手动标的,Markdown 不会默认生成。总之我依然无法完全搞清楚你的所有需求。

只要你能够把需求完全说明白,还是很好实现的。只是稍微有点麻烦,我就懒得再写了。我之前写的你稍微参考下吧,大致套路就是那样的。
Higurashi
2020-04-21 08:55:24 +08:00
@zhybzc 嗯嗯,好。Thanks.
Higurashi
2020-04-22 23:51:37 +08:00
@zhybzc 之前的问题已经完善了。。感兴趣的话可以看看。
zictos
2020-04-23 01:54:21 +08:00
@Higurashi 我用不到,因为我自己本身没这需求。我也不清楚你的需求是什么,按你说的似乎只有自己写笔记的时候#号标得很规则才能有用。既然这样,那还不如手动标。

另外用太多标题作为层级的笔记并不好看,层级太多用项目符号或者缩进更好。你的代码经过我之前的测试发现好像只有#号很规则的情况下才有用,如果随机在某些行加入一些#号,最终标出来的序号是非常乱的。

我之前没事也有试着重新写了一下,我写的代码即便在#号随机标得很乱的情况下添加的序号也还算规则。只是不知道究竟该用什么算法,不知道是相同的#号数量用相同的层级还是用相对的方式增加或减少层级,相对的方式就是说发现#号比上一行多就增加一个层级,比上一行少就减少一个层级。

总之不管用什么方式都无法保证很规则,最终都还是可能标得很乱。我感觉这个程序实在没什么用。除非你能明确自己的需求,确保自己在笔记中的序号一定是规则的,一定是你预先考虑到的情况,不会出现其他特殊情况。

下面是我后来写的代码:
http://note.youdao.com/noteshare?id=3cd18b9191d748c0db3dabb6893da3d1
zictos
2020-04-23 02:20:35 +08:00
@Higurashi 刚还是试了一下,发现有报错,具体错误提示可看这篇笔记:

http://note.youdao.com/noteshare?id=b7397b8746fe671545ea1fe327c89ba5
Higurashi
2020-04-23 11:25:21 +08:00
@zhybzc 嗯,的确不是很常用。

我的实现方式是,一个标题的级别需要根据它之前已经添加了编号的标题来确定。比如当它的级别超过或等于离它最近的一级标题(序号为 1.,2.这种形式的标题)的级别。它会将改标题视作一级标题。而如果它不是一级标题,则再依次判断它是不是一级标题下的第一个标题、它的上一个标题级别是不是比它更高、它的上一个标题级别是不是与它相等、它的上一个标题级别是不是比它更低,并根据情况的不同选择不同的添加编号的方法。
Higurashi
2020-04-23 11:37:37 +08:00
@zhybzc 现在代码已经完善了。可以再试试。
不过虽然我的代码不会报错,但你的代码好像更加“智能”。事实上,在我的代码中,当一个标题在它前面与它最近的一级标题以下找不到与它等级别的标题时,程序会将它视作一级标题,这使得它不善于处理使用者在一级标题下错误设置标题级别时的状况。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/664262

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX