Emacs Lisp精简Sumatra PDF的配置文件

背景

Sumatra PDF是一个非常精简的PDF阅读器 打开文件迅速 3.0版还支持多标签非常好用

这个软件会对打开过的文件的阅读位置进行缓存 方便下次打开时直接跳转到上次读到的位置

但它并不会删除不存在文件的项目 对洁癖来说很不好 这里用Emacs Lisp简单处理一下这个文件 精简文件大小

配置文件例子如下

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
FileStates [
[
FilePath = Z:\论道德建设的实践性原则_杜杰.pdf
Favorites [
]
IsPinned = false
IsMissing = false
OpenCount = 0
UseDefaultState = false
DisplayMode = continuous
ScrollPos = -1 182
PageNo = 2
Zoom = 200
Rotation = 0
WindowState = 2
WindowPos = 560 0 799 1034
ShowToc = false
SidebarDx = 483
DisplayR2L = false
ReparseIdx = 0
]
[
FilePath = Z:\1-s2.0-096808969500053J-main.pdf
Favorites [
]
IsPinned = false
IsMissing = false
OpenCount = 1
UseDefaultState = false
DisplayMode = continuous
ScrollPos = -1 414
PageNo = 1
Zoom = 200
Rotation = 0
WindowState = 2
WindowPos = 560 0 799 1034
ShowToc = false
SidebarDx = 483
DisplayR2L = false
ReparseIdx = 0
TocState = 2 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20 21 23 24 25 27 28 30 31 32 33 34 35 36 37 38 39 40
]
]

难点是 需要判断文件是否存在 当然对于Emacs Lisp就是一个函数的事
但文件里面的文件名格式和Emacs里不大一样 需要替换"为"/"

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
(with-temp-buffer
(insert-file-contents "Z:/a.txt")
(while (re-search-forward "^.*FilePath = \\(.*\\.pdf\\)$" nil t)
(let ((filename
(replace-regexp-in-string "\\\\"
"/" (match-string 1) t t))
(p1)
(p2))
(unless (file-exists-p filename)
(beginning-of-line)
(previous-line)
(setq p1 (point))
(forward-sexp)
(setq p2 (point))
(delete-region p1 p2)
(kill-line) ;Remove empty line.
))
)
(write-file "Z:/output.txt"))

总结

  • 需要提取相应的文件名并将其转换为Emacs喜欢的样子
  • 编码问题比较麻烦 我这里是用的记事本替换的内容
  • Emacs Lisp里丰富的文本处理函数让问题简化了

Update:

最近又用了一次 找出来一看 原来写的好垃圾 稍微改一下

1
2
3
4
5
6
7
8
9
10
11
(defun Sumatra-remove-unused-config ()
(interactive)
(while (re-search-forward "^.*FilePath = \\(.*\\.pdf\\)$" nil t)
(let ((filename
(replace-regexp-in-string "\\\\"
"/" (match-string 1) t t)))
(unless (file-exists-p filename)
(previous-logical-line)
(thing-at-point--beginning-of-sexp)
(kill-sexp)
(delete-blank-lines)))))

但我觉得不好的地方是 怎么快速到达[]的外部 总的来说 现在比之前的好多了