@@ -1349,16 +1349,15 @@ def get_structures(self, *args, **kwargs) -> list[Structure]:
13491349 def get_bibtex_string (self ) -> str :
13501350 """Get BibTeX reference from CIF file.
13511351
1352- Args:
1353- data:
1352+ TODO:
1353+ - parse '_publ_section_references' when it exists?
1354+ - CIF specification supports multiple citations.
13541355
13551356 Returns:
13561357 BibTeX string.
13571358 """
1358- try :
1359- from pybtex .database import BibliographyData , Entry
1360- except ImportError :
1361- raise RuntimeError ("Bibliographic data extraction requires pybtex." )
1359+ from bibtexparser .bibdatabase import BibDatabase
1360+ from bibtexparser .bwriter import BibTexWriter
13621361
13631362 bibtex_keys : dict [str , tuple [str , ...]] = {
13641363 "author" : ("_publ_author_name" , "_citation_author_name" ),
@@ -1377,44 +1376,45 @@ def get_bibtex_string(self) -> str:
13771376 "doi" : ("_journal_DOI" , "_citation_DOI" ),
13781377 }
13791378
1380- entries : dict [str , Entry ] = {}
1381-
1382- # TODO: parse '_publ_section_references' when it exists?
1383- # TODO: CIF specification supports multiple citations.
1379+ db = BibDatabase ()
1380+ db .entries = []
13841381
13851382 for idx , data in enumerate (self ._cif .data .values ()):
13861383 # Convert to lower-case keys, some CIF files inconsistent
13871384 _data = {k .lower (): v for k , v in data .data .items ()}
1388-
1389- bibtex_entry = {}
1385+ entry = {"ENTRYTYPE" : "article" , "ID" : f"cifref{ idx } " }
13901386
13911387 for field , tags in bibtex_keys .items ():
13921388 for tag in tags :
13931389 if tag in _data :
1394- if isinstance (_data [tag ], list ):
1395- bibtex_entry [field ] = _data [tag ][0 ]
1396- else :
1397- bibtex_entry [field ] = _data [tag ]
1390+ value = _data [tag ]
1391+ entry [field ] = value [0 ] if isinstance (value , list ) else value
1392+ break
13981393
13991394 # Convert to bibtex author format ("and" delimited)
1400- if "author" in bibtex_entry :
1395+ if "author" in entry :
14011396 # Separate out semicolon authors
1402- if isinstance (bibtex_entry ["author" ], str ) and ";" in bibtex_entry ["author" ]:
1403- bibtex_entry ["author" ] = bibtex_entry ["author" ].split (";" )
1404-
1405- if isinstance (bibtex_entry ["author" ], list ):
1406- bibtex_entry ["author" ] = " and " .join (bibtex_entry ["author" ])
1397+ if isinstance (entry ["author" ], str ) and ";" in entry ["author" ]:
1398+ entry ["author" ] = entry ["author" ].split (";" )
1399+ if isinstance (entry ["author" ], list ):
1400+ entry ["author" ] = " and " .join (entry ["author" ])
14071401
14081402 # Convert to bibtex page range format, use empty string if not specified
1409- if ("page_first" in bibtex_entry ) or ("page_last" in bibtex_entry ):
1410- bibtex_entry ["pages" ] = bibtex_entry .get ("page_first" , "" ) + "--" + bibtex_entry .get ("page_last" , "" )
1411- bibtex_entry .pop ("page_first" , None ) # and remove page_first, page_list if present
1412- bibtex_entry .pop ("page_last" , None )
1403+ if "page_first" in entry or "page_last" in entry :
1404+ entry ["pages" ] = f"{ entry .get ('page_first' , '' )} --{ entry .get ('page_last' , '' )} "
1405+ entry .pop ("page_first" , None ) # and remove page_first, page_list if present
1406+ entry .pop ("page_last" , None )
1407+
1408+ db .entries .append (entry )
14131409
1414- # Cite keys are given as cif-reference-idx in order they are found
1415- entries [f"cifref{ idx } " ] = Entry ("article" , list (bibtex_entry .items ()))
1410+ # NOTE: the following is added to make output consistent with
1411+ # previous pybtex implementation
1412+ writer = BibTexWriter ()
1413+ writer .indent = " "
1414+ writer .display_order = ("author" , "title" , "journal" , "volume" , "year" , "pages" )
14161415
1417- return BibliographyData (entries ).to_string (bib_format = "bibtex" )
1416+ # Replace curly brackets with double quotes (skip the first and last one)
1417+ return re .sub (r"(^\s*\w+\s*=\s*)\{([^{}]*)\}" , r'\1"\2"' , writer .write (db ), flags = re .MULTILINE )
14181418
14191419 def as_dict (self ) -> dict :
14201420 """MSONable dict."""
0 commit comments