From 29655be3705b4b4e1c6aca0c68a35a5ceaba2295 Mon Sep 17 00:00:00 2001 From: plk Date: Sun, 10 Sep 2023 14:19:42 +0200 Subject: [PATCH] Adding support for new uniquename options --- data/schemata/bcf.rnc | 8 +++++--- data/schemata/bcf.rng | 8 ++++++-- lib/Biber.pm | 15 +++++++++++---- lib/Biber/Constants.pm | 16 +++++++++------- t/tdata/uniqueness7.bib | 30 ++++++++++++++++++++++++++++++ t/uniqueness.t | 27 ++++++++++++++++++++++++++- 6 files changed, 87 insertions(+), 17 deletions(-) diff --git a/data/schemata/bcf.rnc b/data/schemata/bcf.rnc index 3453fa660..4b0c4eee0 100644 --- a/data/schemata/bcf.rnc +++ b/data/schemata/bcf.rnc @@ -683,8 +683,10 @@ nosortothers = # full (true) = disambiguate with full name or initials, only up to maxcitenames/uniquelist # allinit = disambiguate with initials, ignore maxcitenames/uniquelist # allfull = disambiguate with full name or initials, ignore maxcitenames/uniquelist -# mininit = disambiguate with initials, only between identical lists in different entries -# minfull = disambiguate with full name or initials, only between identical lists in different entries +# mininit = disambiguate with initials, only between identical lists of base names in different entries +# minfull = disambiguate with full name or initials, only between identical lists of base names in different entries +# minyearinit = disambiguate with initials, only between identical lists of base names and years in different entries +# minyearfull = disambiguate with full name or initials, only between identical lists of base names and years in different entries pluralothers = element bcf:option { attribute type { "singlevalued" }, @@ -695,7 +697,7 @@ uniquename = element bcf:option { attribute type { "singlevalued" }, element bcf:key { "uniquename" }, - element bcf:value { "false" | "init" | "full" | "allinit" | "allfull" | "mininit" | "minfull" } + element bcf:value { "false" | "init" | "full" | "allinit" | "allfull" | "mininit" | "minfull" | "minyearinit" | "minyearfull" } } uniqueprimaryauthor = element bcf:option { diff --git a/data/schemata/bcf.rng b/data/schemata/bcf.rng index b45e3c80a..7f9cc8c1f 100644 --- a/data/schemata/bcf.rng +++ b/data/schemata/bcf.rng @@ -1673,8 +1673,10 @@ full (true) = disambiguate with full name or initials, only up to maxcitenames/uniquelist allinit = disambiguate with initials, ignore maxcitenames/uniquelist allfull = disambiguate with full name or initials, ignore maxcitenames/uniquelist - mininit = disambiguate with initials, only between identical lists in different entries - minfull = disambiguate with full name or initials, only between identical lists in different entries + mininit = disambiguate with initials, only between identical lists of base names in different entries + minfull = disambiguate with full name or initials, only between identical lists of base names in different entries + minyearinit = disambiguate with initials, only between identical lists of base names and years in different entries + minyearfull = disambiguate with full name or initials, only between identical lists of base names and years in different entries --> @@ -1706,6 +1708,8 @@ allfull mininit minfull + minyearinit + minyearfull diff --git a/lib/Biber.pm b/lib/Biber.pm index 7bb668394..0029a6501 100644 --- a/lib/Biber.pm +++ b/lib/Biber.pm @@ -3538,24 +3538,25 @@ sub create_uniquename_info { # Uniquelist is not set, a name list is longer than the maxcitenames truncation # and the name appears before the mincitenames truncation - if ($un eq 'allinit' or $un eq 'allfull' or + if ($un eq 'allinit' or $un eq 'allfull' or $un eq 'minyearinit' or $un eq 'minyearfull' or ($ul and $n->get_index <= $ul) or $morenames or $num_names <= $maxcn or $n->get_index <= $mincn) { # implicitly, $num_names > $maxcn here $truncnames{$nid} = 1; - if ($un eq 'mininit' or $un eq 'minfull') { + if ($un eq 'mininit' or $un eq 'minfull' or $un eq 'minyearinit' or $un eq 'minyearfull') { push @basenames, $dlist->get_basenamestring($nlid, $nid); push @allnames, $dlist->get_namestring($nlid, $nid); } } } + # Information for mininit or minfull, here the basename # and non-basename is all names in the namelist, not just the current name my $min_basename; my $min_namestring; - if ($un eq 'mininit' or $un eq 'minfull') { + if ($un eq 'mininit' or $un eq 'minfull' or $un eq 'minyearinit' or $un eq 'minyearfull') { $min_basename = join("\x{10FFFD}", @basenames); $min_namestring = join("\x{10FFFD}", @allnames); if ($#basenames + 1 < $num_names or $morenames) { @@ -3582,6 +3583,12 @@ sub create_uniquename_info { $nskey = $min_namestring; $dlist->set_unmininfo($nlid, $nid, $min_basename); } + elsif ($un eq 'minyearinit' or $un eq 'minyearfull') { + my $lyear = $be->get_field('labelyear') // ''; + $namedisamiguationscope = $min_basename . $lyear; + $nskey = $min_namestring . $lyear; + $dlist->set_unmininfo($nlid, $nid, $min_basename . $lyear); + } if ($truncnames{$nid}) { # Record uniqueness information entry for all name contexts @@ -3690,7 +3697,7 @@ MAIN: foreach my $citekey ( $section->get_citekeys ) { my $namedisschema = $dlist->get_namedisschema($nlid, $nid); my $namescope = 'global'; # default - if ($un eq 'mininit' or $un eq 'minfull') { + if ($un eq 'mininit' or $un eq 'minfull' or $un eq 'minyearinit' or $un eq 'minyearfull') { $namescope = $dlist->get_unmininfo($nlid, $nid); } diff --git a/lib/Biber/Constants.pm b/lib/Biber/Constants.pm index 2536eba48..86c38e219 100644 --- a/lib/Biber/Constants.pm +++ b/lib/Biber/Constants.pm @@ -218,13 +218,15 @@ our %DS_EXTENSIONS = ( ); # Mapping of biblatex uniquename option to disambiguation level -our %UNIQUENAME_CONTEXTS = ('false' => 'none', - 'init' => 'init', - 'full' => 'initorfull', - 'allinit' => 'init', - 'allfull' => 'initorfull', - 'mininit' => 'init', - 'minfull' => 'initorfull'); +our %UNIQUENAME_CONTEXTS = ('false' => 'none', + 'init' => 'init', + 'full' => 'initorfull', + 'allinit' => 'init', + 'allfull' => 'initorfull', + 'mininit' => 'init', + 'minfull' => 'initorfull', + 'minyearinit' => 'init', + 'minyearfull' => 'initorfull'); # Mapping of strings to numeric uniquename values for easier biblatex processing our %UNIQUENAME_VALUES = ('none' => 0, 'init' => 1, full => 2); diff --git a/t/tdata/uniqueness7.bib b/t/tdata/uniqueness7.bib index 1810f63e5..5b5fd2c07 100644 --- a/t/tdata/uniqueness7.bib +++ b/t/tdata/uniqueness7.bib @@ -21,3 +21,33 @@ @BOOK{po4 TITLE = {Title Two}, DATE = {2022} } + +@BOOK{un1, + AUTHOR = {Neil Smith}, + TITLE = {Title One}, + DATE = {2022} +} + +@BOOK{un2, + AUTHOR = {Neil Smith}, + TITLE = {Title Two}, + DATE = {2022} +} + +@BOOK{un3, + AUTHOR = {Neil Smith}, + TITLE = {Title Three}, + DATE = {2023} +} + +@BOOK{un4, + AUTHOR = {Arthur Smith}, + TITLE = {Title One}, + DATE = {2000} +} + +@BOOK{un5, + AUTHOR = {Brian Smith}, + TITLE = {Title One}, + DATE = {2000} +} \ No newline at end of file diff --git a/t/uniqueness.t b/t/uniqueness.t index 60f39c13e..a3eb52be9 100644 --- a/t/uniqueness.t +++ b/t/uniqueness.t @@ -4,7 +4,7 @@ use warnings; use utf8; no warnings 'utf8'; -use Test::More tests => 222; +use Test::More tests => 227; use Test::Differences; unified_diff; @@ -750,3 +750,28 @@ my $po3 = q| \entry{po3}{book}{}{} eq_or_diff($main->get_visible_cite($bibentries->entry('po3')->get_field($bibentries->entry('po3')->get_labelname_info)->get_id), '4', 'Pluralothers test - 3'); ok(is_undef($main->get_extranamedata_for_key('po3')), 'Pluralothers test - 4'); eq_or_diff( $out->get_output_entry('po3', $main), $po3, 'Pluralothers test - 5'); + +############################################################################# +# Testing uniquename minyearinit and minyearfull + +$biber = Biber->new(noconf => 1); +$biber->parse_ctrlfile('uniqueness7.bcf'); +$biber->set_output_obj(Biber::Output::bbl->new()); +# Biblatex options +Biber::Config->setblxoption(undef,'uniquelist', 'true'); +Biber::Config->setblxoption(undef,'uniquename', 'minyearinit'); +Biber::Config->setblxoption(undef,'pluralothers', 'false'); +Biber::Config->setblxoption(undef,'maxcitenames', 3); +Biber::Config->setblxoption(undef,'mincitenames', 1); +# Now generate the information +$biber->prepare; +$out = $biber->get_output_obj; +$section = $biber->sections->get_section(0); +$bibentries = $section->bibentries; +$main = $biber->datalists->get_list('nty/global//global/global/global'); + +eq_or_diff($main->get_unsummary($bibentries->entry('un1')->get_field($bibentries->entry('un1')->get_labelname_info)->get_id, $bibentries->entry('un1')->get_field($bibentries->entry('un1')->get_labelname_info)->nth_name(1)->get_id), '0', 'Uniquename minyearinit - 1'); +eq_or_diff($main->get_unsummary($bibentries->entry('un2')->get_field($bibentries->entry('un2')->get_labelname_info)->get_id, $bibentries->entry('un2')->get_field($bibentries->entry('un2')->get_labelname_info)->nth_name(1)->get_id), '0', 'Uniquename minyearinit - 2'); +eq_or_diff($main->get_unsummary($bibentries->entry('un3')->get_field($bibentries->entry('un3')->get_labelname_info)->get_id, $bibentries->entry('un3')->get_field($bibentries->entry('un3')->get_labelname_info)->nth_name(1)->get_id), '0', 'Uniquename minyearinit - 3'); +eq_or_diff($main->get_unsummary($bibentries->entry('un4')->get_field($bibentries->entry('un4')->get_labelname_info)->get_id, $bibentries->entry('un4')->get_field($bibentries->entry('un4')->get_labelname_info)->nth_name(1)->get_id), '1', 'Uniquename minyearinit - 4'); +eq_or_diff($main->get_unsummary($bibentries->entry('un5')->get_field($bibentries->entry('un5')->get_labelname_info)->get_id, $bibentries->entry('un5')->get_field($bibentries->entry('un5')->get_labelname_info)->nth_name(1)->get_id), '1', 'Uniquename minyearinit - 5');