diff --git a/invenio_rdm_records/resources/serializers/bibtex/schema.py b/invenio_rdm_records/resources/serializers/bibtex/schema.py index cd976ef42..0bd6f50d5 100644 --- a/invenio_rdm_records/resources/serializers/bibtex/schema.py +++ b/invenio_rdm_records/resources/serializers/bibtex/schema.py @@ -57,6 +57,10 @@ class BibTexSchema(BaseSerializerSchema, CommonFieldsMixin): BibTexFormatter.book, BibTexFormatter.booklet, ], + "publication-section": [ + BibTexFormatter.in_collection, + BibTexFormatter.in_book, + ], "publication-article": [BibTexFormatter.article], "publication-preprint": [BibTexFormatter.unpublished], "publication-thesis": [BibTexFormatter.thesis], diff --git a/invenio_rdm_records/resources/serializers/bibtex/schema_formats.py b/invenio_rdm_records/resources/serializers/bibtex/schema_formats.py index 0f65f3575..f3f41370f 100644 --- a/invenio_rdm_records/resources/serializers/bibtex/schema_formats.py +++ b/invenio_rdm_records/resources/serializers/bibtex/schema_formats.py @@ -72,6 +72,41 @@ class BibTexFormatter: } """A single-volume conference proceedings.""" + in_collection = { + "name": "incollection", + "req_fields": ["author", "title", "booktitle", "year", "publisher"], + "opt_fields": [ + "pages", + "address", + "month", + "editor", + "volume", + "number", + "series", + "doi", + "url", + ], + } + """An article in a book.""" + + in_book = { + "name": "inbook", + "req_fields": ["author", "title", "pages", "year", "publisher"], + "opt_fields": [ + "address", + "month", + "editor", + "edition", + "volume", + "number", + "series", + "note", + "doi", + "url", + ], + } + """A part of a book that doesn't have a title.""" + article = { "name": "article", "req_fields": ["author", "title", "journal", "year"], diff --git a/tests/resources/serializers/test_bibtex_serializer.py b/tests/resources/serializers/test_bibtex_serializer.py index 94bf492c7..8c2c2324f 100644 --- a/tests/resources/serializers/test_bibtex_serializer.py +++ b/tests/resources/serializers/test_bibtex_serializer.py @@ -225,6 +225,62 @@ def test_serialize_publication_conferenceproceeding( assert serialized_record == expected_data +def test_serialize_publication_booksection(running_app, updated_minimal_record): + """Test bibtex formatter for a section of a book. + + It serializes into `incollection` based on + + - incollection (Book title is present) + - inbook (Book title is not present, pages are present) + """ + updated_minimal_record["metadata"]["resource_type"]["id"] = "publication-section" + + # Force serialization into 'incollection' + updated_minimal_record.update( + {"custom_fields": {"imprint:imprint": {"title": "book title", "pages": "1-5"}}} + ) + + serializer = BibtexSerializer() + serialized_record = serializer.serialize_object(updated_minimal_record) + + expected_data = "\n".join( + [ + "@incollection{brown_2023_abcde-fghij,", + " author = {Name and", + " Troy Inc.},", + " title = {A Romans story},", + " booktitle = {book title},", + " year = 2023,", + " publisher = {Acme Inc},", + " pages = {1-5},", + " month = mar,", + "}", + ] + ) + + assert serialized_record == expected_data + + # Force serialization into 'inbook' + del updated_minimal_record["custom_fields"]["imprint:imprint"]["title"] + serialized_record = serializer.serialize_object(updated_minimal_record) + + expected_data = "\n".join( + [ + "@inbook{brown_2023_abcde-fghij,", + " author = {Name and", + " Troy Inc.},", + " title = {A Romans story},", + " pages = {1-5},", + " year = 2023,", + " publisher = {Acme Inc},", + " month = mar,", + "}", + ] + ) + + assert serialized_record == expected_data + + def test_serialize_publication_book(running_app, updated_minimal_record): """Test bibtex formatter for books.