@@ -17,6 +17,80 @@ const CHUNK_SIZE = 15;
1717/** @type {IntersectionObserver|null } */
1818let _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' ) ;
0 commit comments