Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into reproduce-441
Browse files Browse the repository at this point in the history
  • Loading branch information
MiWeiss committed Jan 18, 2024
2 parents f93cd26 + 4db7d59 commit ac13c69
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 1 deletion.
1 change: 1 addition & 0 deletions bibtexparser/middlewares/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
LatexDecodingMiddleware,
LatexEncodingMiddleware,
)
from bibtexparser.middlewares.middleware import BlockMiddleware, LibraryMiddleware
from bibtexparser.middlewares.month import (
MonthAbbreviationMiddleware,
MonthIntMiddleware,
Expand Down
18 changes: 18 additions & 0 deletions bibtexparser/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,16 @@ def set_field(self, field: Field):
else:
self._fields.append(field)

def pop_field(self, key: str) -> Optional[Field]:
"""Removes and returns the field with the given key, if present."""
try:
field = self.fields_dict.pop(key)
except KeyError:
return None

self._fields = [f for f in self._fields if f.key != key]
return field

def __getitem__(self, key: str) -> Any:
"""Dict-mimicking index.
Expand All @@ -326,6 +336,14 @@ def __setitem__(self, key: str, value: Any):
"""
self.set_field(Field(key, value))

def __delitem__(self, key):
"""Dict-mimicking index.
This serves for partial v1.x backwards compatibility,
as well as for a shorthand for `pop_field`.
"""
self.pop_field(key)

def items(self):
"""Dict-mimicking, for partial v1.x backwards compatibility.
Expand Down
2 changes: 1 addition & 1 deletion docs/source/customize.rst
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ and share them with the community.
We will be happy to provide a list of community-provided middleware layers here, so please let us know if you have written one!

.. note::
To write your own middleware, simply extend the :class:`bibtexparser.middlewares.Blockmiddleware`
To write your own middleware, simply extend the :class:`bibtexparser.middlewares.BlockMiddleware`
(for functions working on blocks individually, such as encoding) or :class:`bibtexparser.middlewares.LibraryMiddleware`
(for library-wide transformations, such as sorting blocks) and implement the superclass methods
according to the python docstrings. Make sure to check out some core middleware layers for examples.
Expand Down
33 changes: 33 additions & 0 deletions tests/middleware_tests/test_custom_middleware_smoke.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
"""Smoke test for custom middleware, based on the #440 by @tdegeus"""

import bibtexparser
from bibtexparser.middlewares.middleware import BlockMiddleware

bibtex_str = """
@ARTICLE{Cesar2013,
author = {Jean César and T. W. J. de Geus},
title = {An amazing title},
year = {2013},
pages = {12--23},
volume = {12},
journal = {Nice Journal}
}
"""


abbreviations = {"Nice Journal": "NJ", "Another Nice Journal": "ANJ"}


class JournalAbbreviate(BlockMiddleware):
def transform_entry(self, entry, *args, **kwargs):
if entry["journal"] in abbreviations:
entry["journal"] = abbreviations[entry["journal"]]
return entry


def test_custom_middleware_smoke():
"""Test that the very simple custom middleware above works."""
library = bibtexparser.parse_string(
bibtex_str, append_middleware=[JournalAbbreviate(True)]
)
assert library.entries[0]["journal"] == "NJ"
8 changes: 8 additions & 0 deletions tests/test_model.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from copy import copy, deepcopy
from textwrap import dedent

import pytest

from bibtexparser.model import (
Entry,
ExplicitComment,
Expand Down Expand Up @@ -311,3 +313,9 @@ def test_entry_fields_shorthand():
assert entry.fields_dict["myNewField"].key == "myNewField"
assert entry.fields_dict["myNewField"].value == "new_value"
assert entry.fields_dict["myNewField"].start_line is None

del entry["myNewField"]
assert "myNewField" not in entry.fields_dict
assert len([f for f in entry.fields if f.key == "myNewField"]) == 0
with pytest.raises(KeyError):
entry["myNewField"]

0 comments on commit ac13c69

Please sign in to comment.