利用Python生成LaTeX词典的指令码(二)

在之前的部落格中,我介绍了如何用Python生成LaTeX词典的指令码,方便我们在参考语法后添加词表。但当时生成的词典却有以下缺陷:

  • 词项没有按字母顺序排列。
  • 词项没有按首字母分开。
  • 没有首字母的标题。

没有了这些特点,看起来怎么也不像真正的词典。所以,我们要想办法解决。今天我们就来讨论解决的办法。

上次,我们生成了一个wl.tex的文件,那么我们就在它的基础上修改。

如果我们仔细研究词典的template,我们会发现,它的结构是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
\section*{首字母}

\begin{multicols}{2}

\entry{词1}

\entry{词2}

\entry{词3}

...

\end{multicols
}

所以我们的任务是:首先,想办法让词项按字母顺序排列,第二,让所有含有相同首字母的词都归在一个\section底下,然后再让这些词被\begin{multicols}{2} ... \end{multicols}包围。这三个任务基本上可以用一个Python的for语句完成。思路如下:

先用Python的sorted()功能开始排序,然后我们开始一行一行地写到新的.tex文件中。那这一行一行写什么呢?我们要让Python帮我们写:

1
2
3
4
5
\end{multicols}

\section*{首字母}

\begin{multicols}{2
}

因为所有的\section*{}下边都有\begin{multicols}{2},而且除了第一个,所有的\section*{}上边都有\end{multicols}。所以我们先照顾多数情况。

然后,我们希望把所有词条的首字母都找出来,如果后一个词的首字母跟前一个词的一样,我们就不写\section*{},直接写\entry{}。这样,我们就可以保证首字母相同的词都在一起。这时我们希望看到的指令码是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
\end{multicols}

\section*{首字母1}

\begin{multicols}{2}

\entry{词1}

\entry{词2}

\end{multicols}

\section*{首字母2}

\begin{multicols}{2}

\entry{词3}

\entry{词4
}

接下来,由于我们刚刚没有让Python写最后一个\end{multicols},所以我们就追加一个放在最后的\end{multicols}。所以就会变成如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
\end{multicols}

\section*{首字母1}

\begin{multicols}{2}

\entry{词1}

\entry{词2}

\end{multicols}

\section*{首字母2}

\begin{multicols}{2}

\entry{词3}

\entry{词4}

\end{multicols
}

但还没完,因为这个文件的第一行也有一个\end{multicols},我们要想办法删除它,最终我们要看到:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
\section*{首字母1}

\begin{multicols}{2}

\entry{词1}

\entry{词2}

\end{multicols}

\section*{首字母2}

\begin{multicols}{2}

\entry{词3}

\entry{词4}

\end{multicols
}

我写了以下的Python指令码来实现,当然,肯定有更快捷的办法,但我只好如此:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
with open('wl.tex','r') as r:
    sec='' #我先设了一个sec,后边可以用来比较前一个首字母和后一个首字母
    for line in sorted(r): #排序
        if len(line) > 10: #当行的长度大于10(其实大于1也可以,因为有些是空行,我不想理会这些行)
            sections = '\\end{multicols}\n\n'+'\\section*{\ipa{'+line[13]+'}}\n\n\\begin{multicols}{2}\n\n' #写!
            if sections != sec: #如果刚刚写的跟sec不一样
                print(sections, file=open('nwl.tex',"a")) #继续写到新的.tex文件里
                sec = sections #我们重新定义sec,让它变成刚刚写的东西。
            print (line, file=open('nwl.tex',"a")) #我们在把\entry填进去。注意这一行在if语句之外
    print  ('\\end{multicols}\n\n', file=open('nwl.tex',"a")) #我们在最后加上\end{multicols}

#接下里我们把第一行的\end{multicols}切掉。
with open('nwl.tex', 'r') as cut:
    lines = cut.read().splitlines(True)
with open('nwl.tex', 'w') as coot:
    coot.writelines(lines[1:])

编译以后,我们会得到一个叫nwl.tex的文件,打开一看,正是我们想要的样子!太好了,那我们赶紧使用\input大法,放到词典的template里,空批累(compiler [kõpile])!我们会得到如图的词典:

很不错吧,你的词项多起来的话,看起来就像真的一样了!所以,现在就把词典加入到你的参考语法里,增加你论文的厚度吧!

示例词典和Python程式可以在此下载

Author: Lai, Yunfan

目前是马克斯普朗克协会人类历史科学研究所(Max-Planck Institut für Menschheitsgeschichte)的博士后。

2 条评论

评论