Skip to content

Commit 70cc812

Browse files
committed
Fix publication BibTeX output
1 parent dc73537 commit 70cc812

2 files changed

Lines changed: 87 additions & 19 deletions

File tree

javascript/pubs.js

Lines changed: 75 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,80 @@ const CHUNK_SIZE = 15;
1717
/** @type {IntersectionObserver|null} */
1818
let _sentinel_observer = null;
1919

20+
/**
21+
* Map site-local publication types to canonical BibTeX entry types.
22+
* @param {string} type
23+
* @returns {string}
24+
*/
25+
function bibtex_entry_type(type) {
26+
if (type === 'conference') return 'inproceedings';
27+
if (type === 'journal') return 'article';
28+
if (type === 'course') return 'misc';
29+
if (type === 'arxiv') return 'misc';
30+
return type;
31+
}
32+
33+
/**
34+
* Map the JSON venue field to the appropriate BibTeX field for the entry type.
35+
* @param {string} type
36+
* @returns {string|null}
37+
*/
38+
function bibtex_venue_field(type) {
39+
if (type === 'conference') return 'booktitle';
40+
if (type === 'journal') return 'journal';
41+
if (type === 'techreport') return 'institution';
42+
if (type === 'course') return 'howpublished';
43+
if (type === 'arxiv') return 'note';
44+
return null;
45+
}
46+
47+
/**
48+
* @param {string} field
49+
* @param {string} value
50+
* @returns {string}
51+
*/
52+
function bibtex_field(field, value) {
53+
const wrapped = field === 'title' ? '{' + value + '}' : value;
54+
return ",\n " + field + "={" + wrapped + "}";
55+
}
56+
57+
/**
58+
* Build BibTeX from a publication record using BibTeX field names rather than
59+
* the site's JSON field names.
60+
* @param {Publication} entry
61+
* @returns {string}
62+
*/
63+
function make_bibtex(entry) {
64+
const entry_any = /** @type {any} */ (entry);
65+
/** @type {Array<[string, string]>} */
66+
const fields = [
67+
['title', entry.title],
68+
['author', entry.authors.join(' and\n ')],
69+
];
70+
71+
const venue_field = bibtex_venue_field(entry.type);
72+
if (venue_field && entry.venue) fields.push([venue_field, entry.venue]);
73+
74+
fields.push(['year', entry.year]);
75+
76+
['volume', 'number', 'pages'].forEach(function(field) {
77+
if (entry_any[field] != undefined) fields.push([field, String(entry_any[field])]);
78+
});
79+
80+
if (entry.notes != undefined && entry.notes.length > 0) {
81+
fields.push(['note', entry.notes.join(', ')]);
82+
}
83+
84+
const url = entry.arxiv || entry.pdf || entry.homepage;
85+
if (url != undefined) fields.push(['url', url]);
86+
87+
let bibtex_text = "@" + bibtex_entry_type(entry.type) + "{" + entry.key;
88+
fields.forEach(function(field) {
89+
bibtex_text += bibtex_field(field[0], field[1]);
90+
});
91+
return bibtex_text + "\n}";
92+
}
93+
2094
/**
2195
* Build and append one publication entry to #pubs_list.
2296
* @param {Publication} entry
@@ -127,18 +201,7 @@ function make_pub(entry) {
127201
if (entry.arxiv != undefined) links.appendChild(make_link(entry.arxiv, "arxiv"));
128202

129203
// Bibtex toggle
130-
const blacklist = ["key", "special", "source", "slides", "video", "datasets", "pdf", "homepage", "icon", "type", "media"];
131-
let bibtex_text = "@" + entry.type + "{" + entry.key;
132-
for (const tag_name in entry) {
133-
if (Object.prototype.hasOwnProperty.call(entry, tag_name) && !blacklist.includes(tag_name)) {
134-
/** @type {any} */
135-
let value = (/** @type {any} */ (entry))[tag_name];
136-
if (tag_name === "authors")
137-
value = value.toString().replace(/,/g, " and ");
138-
bibtex_text += ",\n " + tag_name + "={" + value + "}";
139-
}
140-
}
141-
bibtex_text += "\n}";
204+
const bibtex_text = make_bibtex(entry);
142205
const bibtex_area = document.createElement('pre');
143206
bibtex_area.className = 'publication_bibtex';
144207
const bibtex_text_box = document.createElement('p');

python/bib_json_to_bibtex.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
title={\\normalfont{``TITLE''}},
3434
author={AUTHORS},
3535
year={YEAR},
36-
venue={arXiv preprint},
36+
note={arXiv preprint},
3737
url={URL},
3838
}"""
3939

@@ -100,21 +100,26 @@ def list_to_string(mylist):
100100
mylist = [author.replace(name, ulinename) for author in mylist]
101101
# --- underlined as a whole
102102
# mylist = [author.replace(name, f"\\ul{{{name}}}") for author in mylist]
103-
return " and ".join(mylist)
103+
return " and\n ".join(mylist)
104104

105105
def notes_to_string(mylist):
106106
ret = ", ".join(mylist)
107107
ret = f"({ret})"
108108
return ret
109109

110+
def replace_notes(template, pub):
111+
if "notes" in pub:
112+
return template.replace("NOTES", notes_to_string(pub['notes']))
113+
return template.replace(" note={\\textbf{NOTES}},\n", "")
114+
110115
def conference(pub):
111116
ret = _conference_template
112117
ret = ret.replace("KEY", pub['key'])
113118
ret = ret.replace("TITLE", pub['title'])
114119
ret = ret.replace("AUTHORS", list_to_string(pub['authors']))
115120
ret = ret.replace("CONFERENCE", pub['venue'])
116121
ret = ret.replace("YEAR", pub['year'])
117-
ret = ret.replace("NOTES", notes_to_string(pub['notes']) if "notes" in pub else "")
122+
ret = replace_notes(ret, pub)
118123
return ret
119124

120125
def journal(pub):
@@ -124,17 +129,17 @@ def journal(pub):
124129
ret = ret.replace("AUTHORS", list_to_string(pub['authors']))
125130
ret = ret.replace("CONFERENCE", pub['venue'])
126131
ret = ret.replace("YEAR", pub['year'])
127-
ret = ret.replace("NOTES", notes_to_string(pub['notes']) if "notes" in pub else "")
132+
ret = replace_notes(ret, pub)
128133
return ret
129134

130135
def techreport(pub):
131136
ret = _techreport_template
132137
ret = ret.replace("KEY", pub['key'])
133138
ret = ret.replace("TITLE", pub['title'])
134139
ret = ret.replace("AUTHORS", list_to_string(pub['authors']))
135-
ret = ret.replace("CONFERENCE", pub['venue'])
140+
ret = ret.replace("INSTITUTION", pub['venue'])
136141
ret = ret.replace("YEAR", pub['year'])
137-
ret = ret.replace("NOTES", notes_to_string(pub['notes']) if "notes" in pub else "")
142+
ret = replace_notes(ret, pub)
138143
return ret
139144

140145
def arxiv(pub):
@@ -167,7 +172,7 @@ def course(pub):
167172
ret = ret.replace("AUTHORS", list_to_string(pub['authors']))
168173
ret = ret.replace("HOWPUBLISHED", pub['venue'])
169174
ret = ret.replace("YEAR", pub['year'])
170-
ret = ret.replace("NOTES", notes_to_string(pub['notes']) if "notes" in pub else "")
175+
ret = replace_notes(ret, pub)
171176
return ret
172177

173178
def dispatcher(pub):

0 commit comments

Comments
 (0)