From d073e607116e57749954a27ef463687ac5cb5779 Mon Sep 17 00:00:00 2001 From: Jonas Kulhanek Date: Wed, 26 Feb 2020 14:19:29 +0100 Subject: [PATCH] add tests for pubkey generation --- pubs/bibstruct.py | 39 +++++++++++++++++---------------------- pubs/config/spec.py | 22 ++++++++++++++-------- tests/test_bibstruct.py | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 30 deletions(-) diff --git a/pubs/bibstruct.py b/pubs/bibstruct.py index ce905bb..e47caae 100644 --- a/pubs/bibstruct.py +++ b/pubs/bibstruct.py @@ -61,6 +61,18 @@ class CitekeyFormatter(Formatter): def __init__(self): super(CitekeyFormatter, self).__init__() + def format_field(self, val, fmt): + if len(fmt) > 0 and fmt[0] == 'u': + s = str(val).upper() + fmt = fmt[1:] + elif len(fmt) > 0 and fmt[0] == 'l': + s = str(val).lower() + fmt = fmt[1:] + else: + s = val + return str2citekey(s.__format__(fmt)) + + def get_value(self, key, args, kwds): if len(args) == 0: raise ValueError('Must pass bibtex entry to the format method') @@ -73,41 +85,24 @@ class CitekeyFormatter(Formatter): key = 'author' if key == 'first_word' and 'title' in entry: - return CitekeyFormatter._U(entry['title'].split(' ')[0]) + return entry['title'].split(' ')[0] if key == 'author_last_name' and 'author' in entry: - return CitekeyFormatter._U(author_last(entry['author'][0])) + return author_last(entry['author'][0]) else: if key in entry: - return CitekeyFormatter._U(entry[key]) + return entry[key] else: raise ValueError( "No {} defined: cannot generate a citekey.".format(okey)) - class _U(str): - def __init__(self, value): - super(CitekeyFormatter._U, self).__init__(value) - - def __format__(self, fmt): - val = self - if len(fmt) > 0 and fmt[0] == 'u': - s = val.upper() - fmt = fmt[1:] - elif len(fmt) > 0 and fmt[0] == 'l': - s = val.lower() - fmt = fmt[1:] - else: - s = str(val) - return s.__format__(fmt) - - -def generate_citekey(bibdata, format_string='{author_last_name:l}{year}{first_word:l}'): +def generate_citekey(bibdata, format_string='{author_last_name}{year}'): """ Generate a citekey from bib_data. :raise ValueError: if no author nor editor is defined. """ citekey, entry = get_entry(bibdata) citekey = CitekeyFormatter().format(format_string, entry) - return str2citekey(citekey) + return citekey def extract_docfile(bibdata, remove=False): diff --git a/pubs/config/spec.py b/pubs/config/spec.py index 42097ad..86ed265 100644 --- a/pubs/config/spec.py +++ b/pubs/config/spec.py @@ -34,15 +34,21 @@ debug = boolean(default=False) # If true the citekey is normalized using the 'citekey_format' on adding new publications. normalize_citekey = boolean(default=False) -# String specifying how to format the citekey. The following +# String specifying how to format the citekey. All strings of +# the form '{{substitution:modifier}}' and '{{substitution}}' will +# be substituted with their appropriate values. The following # substitutions are used: -# %a: last name of the first author in lowercase -# %A: last name of the first author in PascalCase -# %Y: four letter year of release (e.g. 2019) -# %y: two last letters of release year (e.g. 19) -# %w: first word in the title in lowercase -# %W: first work in the title -citekey_format = string(default='%a%Y') +# author_last_name: last name of the first author +# year: year of publication +# first_word: first word of the title +# modifiers: +# l: converts the text to lowercase +# u: converts the text to uppercase +# examples: +# {{author_last_name:l}}{{year}} generates 'yang2020' +# {{author_last_name}}{{year}}{{first_word}} generates 'Yang2020Towards' +# {{author_last_name:u}}{{year}} generates 'YANG2020' +citekey_format = string(default='{{author_last_name:l}}{{year}}') [formating] diff --git a/tests/test_bibstruct.py b/tests/test_bibstruct.py index 05af028..d06b0d8 100644 --- a/tests/test_bibstruct.py +++ b/tests/test_bibstruct.py @@ -32,6 +32,46 @@ class TestGenerateCitekey(unittest.TestCase): key = bibstruct.generate_citekey(bibentry) self.assertEqual(key, 'Salinger1961') + def test_no_modifier(self): + template = '{author_last_name}{year}' + bibentry = copy.deepcopy(fixtures.doe_bibentry) + key = bibstruct.generate_citekey(bibentry, template) + self.assertEqual(key, 'Doe2013') + + bibentry = copy.deepcopy(fixtures.franny_bibentry) + key = bibstruct.generate_citekey(bibentry, template) + self.assertEqual(key, 'Salinger1961') + + def test_all_keys(self): + template = '{author_last_name}-{year}-{first_word}' + bibentry = copy.deepcopy(fixtures.doe_bibentry) + key = bibstruct.generate_citekey(bibentry, template) + self.assertEqual(key, 'Doe-2013-Nice') + + bibentry = copy.deepcopy(fixtures.franny_bibentry) + key = bibstruct.generate_citekey(bibentry, template) + self.assertEqual(key, 'Salinger-1961-Franny') + + def test_l_modifier(self): + template = '{author_last_name:l}{year:l}' + bibentry = copy.deepcopy(fixtures.doe_bibentry) + key = bibstruct.generate_citekey(bibentry, template) + self.assertEqual(key, 'doe2013') + + bibentry = copy.deepcopy(fixtures.franny_bibentry) + key = bibstruct.generate_citekey(bibentry, template) + self.assertEqual(key, 'salinger1961') + + def test_u_modifier(self): + template = '{author_last_name:u}{year:u}' + bibentry = copy.deepcopy(fixtures.doe_bibentry) + key = bibstruct.generate_citekey(bibentry, template) + self.assertEqual(key, 'DOE2013') + + bibentry = copy.deepcopy(fixtures.franny_bibentry) + key = bibstruct.generate_citekey(bibentry, template) + self.assertEqual(key, 'SALINGER1961', template) + if __name__ == '__main__': unittest.main()