使用Zotero软件可以非常方便的将一个文件夹中的数据转换成bib后缀的文件。而如果我们想要在jekyll中发布我们的论文列表,则需要转换成jekyll支持的比如yaml、json格式的数据。因此,我使用python脚本写了一个转换的脚本,暂且将转换过程设计的主要代码说明如下:
安装python包
首先我们需要安装bibtexparser
包,该包可以非常方便的加载bib文件,使用pandas将数据转换成Dataframe,就可以进行下一步处理了。
with open("./papers.bib", encoding='utf-8') as bibtex_file:
bib_database = bibtexparser.load(bibtex_file)
df = pd.DataFrame(bib_database.entries)
格式化数据
由于bib文件包含了一些冗余的信息,如果不是很想要,可以Copy一个Dataframe出来,然后选择目标字段。
# 由于df_sel后续需要执行赋值,因此必须是df的copy版本
df_sel = df.loc[:, ['author', 'title', 'booktitle', 'journaltitle', 'date', 'volume', 'number', 'pages', 'doi']].copy()
# 将null值复制为空字符串
df_sel.fillna('', inplace=True)
需要注意的是,必须使用loc索引以及copy函数,否则后面df_sel进行再次处理的时候会产生SettingwithCopy
错误。
for k, v in df_sel.items():
if k == 'date':
df_sel[k] = df_sel[k].apply(lambda p: p.split('-')[0])
if k == 'author':
df_sel[k] = df_sel[k].apply(lambda p: re.sub(r'(Xing, [a-zA-Z-]+)', r"<u>\1</u>", p))
if k == 'pages':
df_sel[k] = df_sel[k].apply(lambda p: re.sub(r'[-]+', '-', p))
if k == 'title' or k == 'booktitle':
df_sel[k] = df_sel[k].apply(lambda p: re.sub(r'(\{|\}|\\)', '', p))
if k == 'journaltitle':
df_sel[k] = df_sel[k].apply(lambda p: re.sub(r'\\', '', p))
apply类似map函数,可以方便的将列数据当做数组进行处理。其中author
列的操作主要是将当前作者的名字下划线处理。
js = df_sel.groupby('date').apply(lambda x: json.loads(x.to_json(orient='records'))).sort_index(ascending=False)
groupby之后,如果不apply,则每个date对应的是一个字数穿列表,使用apply之后就是一个json列表。
js.to_json('./papers.json', indent=4, force_ascii=False)
至此,一个按照年份分组的JSON格式的文献引用数据文件就生成了。
引用文件
将该文件放在jekyll网站目录的_data
文件夹中,就可以使用json格式的数据了,这些数据可以在markdown、html文件中使用,只需要使用liquid代码即可。下面是一个示例的格式化代码。
<h4>{{kp[0]}}</h4>
{% for paper in kp[1] %}
<li style="margin-bottom: 10px;line-height: 1.5em;">
{{paper.author}},
{% if paper.doi =="" %}
<i>{{paper.title}}</i>
{% else %}
<a href="https://doi.org/{{ paper.doi }}" target="_blank"><i>{{paper.title}}</i></a>
{% endif %}.
{{paper.journaltitle}}
{{paper.booktitle}},
{{paper.date||date: "%Y"}}.
<b>{{paper.volume}}</b>
{% if paper.number != "" %}
({{paper.number}})
{% endif %}: p{{paper.pages}}
</li>
{% endfor %}
{% endfor %}
如果展示Liquid模板内容,参考:https://www.jasongaylord.com/blog/2020/05/31/displaying-liquid-templates-in-jekyll-code-blocks。