From 6fe2c4d921efcf83280ba0ccbfbd6d8dfeda07d5 Mon Sep 17 00:00:00 2001 From: Claudius Ellsel Date: Thu, 16 Jul 2026 15:15:57 +0200 Subject: [PATCH] Require exact special command types Treat custom entry types that extend comment, preamble, or string names as ordinary entries. --- bibtexparser/splitter.py | 7 ++++--- .../test_splitter_block_start_detection.py | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/bibtexparser/splitter.py b/bibtexparser/splitter.py index bbc3e97..cd8d4d5 100644 --- a/bibtexparser/splitter.py +++ b/bibtexparser/splitter.py @@ -300,6 +300,7 @@ def split(self, library: Library | None = None) -> Library: m_val = m.group(0).lower() if m_val.startswith("@"): + block_type = m_val[1:].strip() # Clean up previous block implicit_comment implicit_comment = self._end_implicit_comment(m.start()) if implicit_comment is not None: @@ -309,11 +310,11 @@ def split(self, library: Library | None = None) -> Library: start_line = self._current_line try: # Start new block parsing - if m_val.startswith("@comment"): + if block_type == "comment": library.add(self._handle_explicit_comment()) - elif m_val.startswith("@preamble"): + elif block_type == "preamble": library.add(self._handle_preamble()) - elif m_val.startswith("@string"): + elif block_type == "string": library.add(self._handle_string(m), fail_on_duplicate_key=False) else: library.add(self._handle_entry(m, m_val), fail_on_duplicate_key=False) diff --git a/tests/splitter_tests/test_splitter_block_start_detection.py b/tests/splitter_tests/test_splitter_block_start_detection.py index 3d7553e..7121096 100644 --- a/tests/splitter_tests/test_splitter_block_start_detection.py +++ b/tests/splitter_tests/test_splitter_block_start_detection.py @@ -154,6 +154,25 @@ def test_mixed_blocks_same_line( assert len(library.comments) == expected_comments +@pytest.mark.parametrize( + "entry_type", + [ + pytest.param("commentary", id="comment-prefix"), + pytest.param("preamble_study", id="preamble-prefix"), + pytest.param("string_theory", id="string-prefix"), + ], +) +def test_entry_type_extending_special_command_name_is_entry(entry_type: str): + """Special commands require an exact type match; longer custom types remain entries.""" + library = Splitter(f"@{entry_type}{{key, title = {{Custom entry type}}}}").split() + + assert len(library.failed_blocks) == 0 + assert len(library.comments) == 0 + assert len(library.preambles) == 0 + assert len(library.strings) == 0 + assert [(entry.entry_type, entry.key) for entry in library.entries] == [(entry_type, "key")] + + # ============================================================================= # Test: Error recovery when new block starts at line start # =============================================================================