1package Biber::Section; 2use v5.16; 3use strict; 4use warnings; 5 6use Biber::Entries; 7use Biber::Utils; 8use List::Util qw( first ); 9 10=encoding utf-8 11 12=head1 NAME 13 14Biber::Section 15 16=head2 new 17 18 Initialize a Biber::Section object 19 20=cut 21 22sub new { 23 my ($class, %params) = @_; 24 my $self = bless {%params}, $class; 25 $self->{bibentries} = new Biber::Entries; 26 $self->{keytorelclone} = {}; 27 $self->{relclonetokey} = {}; 28 $self->{relkeys} = {}; 29 $self->{allkeys} = 0; 30 $self->{citekeys} = []; 31 $self->{citekeys_h} = {}; # For faster hash-based lookup of individual keys 32 $self->{labelcache_l} = {}; 33 $self->{everykey} = {}; 34 $self->{everykey_lc} = {}; 35 $self->{bcfkeycache} = {}; 36 $self->{labelcache_v} = {}; 37 $self->{sortcache} = []; 38 $self->{dkeys} = {}; 39 $self->{keytods} = {}; 40 $self->{orig_order_citekeys} = []; 41 $self->{undef_citekeys} = []; 42 $self->{citekey_alias} = {}; 43 return $self; 44} 45 46=head2 reset_caches 47 48 Reset section caches which need it 49 50=cut 51 52sub reset_caches { 53 my $self = shift; 54 $self->{sortcache} = []; 55 $self->{labelcache_l} = {}; 56 $self->{labelcache_v} = {}; 57 $self->{bcfkeycache} = {}; 58 return; 59} 60 61=head2 set_keytods 62 63 Save information about citekey->datasource name mapping. Used for error reporting. 64 65=cut 66 67sub set_keytods { 68 my ($self, $key, $ds) = @_; 69 $self->{keytods}{$key} = $ds; 70 return; 71} 72 73=head2 get_keytods 74 75 Get information about citekey->datasource name mapping. Used for error reporting. 76 77=cut 78 79sub get_keytods { 80 my ($self, $key) = @_; 81 return $self->{keytods}{$key}; 82} 83 84=head2 has_badcasekey 85 86 Returns a value to say if we've seen a key differing only in case before 87 <previouskey> - we've seen a differently cased variant of this key so we can warn about this 88 undef - Not seen this key at all in any case variant before 89 90=cut 91 92sub has_badcasekey { 93 my ($self, $key) = @_; 94 my $ckey = $self->{everykey_lc}{lc($key)}; 95 return undef unless $ckey; 96 return $ckey ne $key ? $ckey : undef; 97} 98 99 100=head2 add_related 101 102 Record that a key is used as a related entry 103 104=cut 105 106sub add_related { 107 my ($self, $key) = @_; 108 $self->{relkeys}{$key} = 1; 109 return; 110} 111 112=head2 is_related 113 114 Check if a key is used as a related entry key 115 116=cut 117 118sub is_related { 119 my ($self, $key) = @_; 120 return $self->{relkeys}{$key}; 121} 122 123 124=head2 keytorelclone 125 126 Record a key<->clone key mapping. 127 128=cut 129 130sub keytorelclone { 131 my ($self, $key, $clonekey) = @_; 132 $self->{keytorelclone}{$key} = $clonekey; 133 $self->{relclonetokey}{$clonekey} = $key; 134 return; 135} 136 137 138=head2 get_keytorelclone 139 140 Fetch a related entry clone key, given a cite key 141 142=cut 143 144sub get_keytorelclone { 145 my ($self, $key) = @_; 146 return $self->{keytorelclone}{$key}; 147} 148 149=head2 get_relclonetokey 150 151 Fetch a related entry key, given a clone key 152 153=cut 154 155sub get_relclonetokey { 156 my ($self, $key) = @_; 157 return $self->{relclonetokey}{$key}; 158} 159 160 161=head2 has_keytorelclone 162 163 Return boolean saying if a cite key has a related entry clone in the current section 164 165=cut 166 167sub has_keytorelclone { 168 my ($self, $key) = @_; 169 return defined($self->{keytorelclone}{$key}) ? 1 : 0; 170} 171 172=head2 has_relclonetokey 173 174 Return boolean saying if a related clone key has a citekey in the current section 175 176=cut 177 178sub has_relclonetokey { 179 my ($self, $key) = @_; 180 return defined($self->{relclonetokey}{$key}) ? 1 : 0; 181} 182 183=head2 add_everykey 184 185 Adds a datasource key to the section list of all datasource keys 186 187=cut 188 189sub add_everykey { 190 my ($self, $key) = @_; 191 $self->{everykey}{$key} = 1; 192 $self->{everykey_lc}{lc($key)} = $key; 193 return; 194} 195 196=head2 del_everykeys 197 198 Delete everykey cache. For use in tests. 199 200=cut 201 202sub del_everykeys { 203 my $self = shift; 204 $self->{everykey} = undef 205 $self->{everykey_lc} = undef; 206 return; 207} 208 209=head2 has_everykey 210 211 Returns a boolean to say if we've seen a key in any datasource for this section. 212 This used to be an array ref which was checked using first() and it 213 was twenty times slower. 214 215=cut 216 217sub has_everykey { 218 my ($self, $key) = @_; 219 return $self->{everykey}{$key} ? 1 : 0; 220} 221 222 223=head2 set_allkeys 224 225 Sets flag to say citekey '*' occurred in citekeys 226 We allow setting it to false too because it's useful in tests 227 228=cut 229 230sub set_allkeys { 231 my ($self, $val) = @_; 232 $self->{allkeys} = $val; 233 return; 234} 235 236=head2 is_allkeys 237 238 Checks flag which says citekey '*' occurred in citekeys 239 240=cut 241 242sub is_allkeys { 243 my $self = shift; 244 return $self->{allkeys}; 245} 246 247 248=head2 bibentry 249 250 Returns a Biber::Entry object for the given citation key 251 Understands citekey aliases 252 253=cut 254 255sub bibentry { 256 my ($self, $key) = @_; 257 if (my $realkey = $self->get_citekey_alias($key)) { 258 return $self->bibentries->entry($realkey); 259 } 260 else { 261 return $self->bibentries->entry($key); 262 } 263} 264 265=head2 bibentries 266 267 Return Biber::Entries object for this section 268 269=cut 270 271sub bibentries { 272 my $self = shift; 273 return $self->{bibentries}; 274} 275 276=head2 del_bibentries 277 278 Delete all Biber::Entry objects from the Biber::Section object 279 280=cut 281 282sub del_bibentries { 283 my $self = shift; 284 $self->{bibentries} = new Biber::Entries; 285 return; 286} 287 288 289=head2 set_citekeys 290 291 Sets the citekeys in a Biber::Section object 292 293=cut 294 295sub set_citekeys { 296 my $self = shift; 297 my $keys = shift; 298 map { $self->{citekeys_h}{$_} = 1} @$keys; 299 $self->{citekeys} = $keys; 300 return; 301} 302 303=head2 set_orig_order_citekeys 304 305 Sets the original order of citekeys in a Biber::Section object 306 307=cut 308 309sub set_orig_order_citekeys { 310 my $self = shift; 311 my $keys = shift; 312 $self->{orig_order_citekeys} = $keys; 313 return; 314} 315 316 317=head2 get_citekeys 318 319 Gets the citekeys of a Biber::Section object 320 Returns a normal array 321 322=cut 323 324sub get_citekeys { 325 my $self = shift; 326 return @{$self->{citekeys}}; 327} 328 329=head2 get_static_citekeys 330 331 Gets the citekeys of a Biber::Section object 332 excluding dynamic set entry keys 333 Returns a normal array 334 335=cut 336 337sub get_static_citekeys { 338 my $self = shift; 339 return reduce_array($self->{citekeys}, $self->dynamic_set_keys); 340} 341 342 343=head2 add_undef_citekey 344 345 Adds a citekey to the Biber::Section object as an undefined 346 key. This allows us to output this information to the .bbl and 347 so biblatex can do better reporting to external utils like latexmk 348 349=cut 350 351sub add_undef_citekey { 352 my $self = shift; 353 my $key = shift; 354 push @{$self->{undef_citekeys}}, $key; 355 return; 356} 357 358=head2 get_undef_citekeys 359 360 Gets the list of undefined citekeys of a Biber::Section object 361 Returns a normal array 362 363=cut 364 365sub get_undef_citekeys { 366 my $self = shift; 367 return @{$self->{undef_citekeys}}; 368} 369 370=head2 get_orig_order_citekeys 371 372 Gets the citekeys of a Biber::Section object in their original order 373 This is just to ensure we have a method that will return this, just in 374 case we mess about with the order at some point. This is needed by 375 citeorder sorting. 376 377=cut 378 379sub get_orig_order_citekeys { 380 my $self = shift; 381 return @{$self->{orig_order_citekeys}}; 382} 383 384=head2 has_citekey 385 386 Returns true when $key is in the Biber::Section object 387 Understands key alaises 388 389=cut 390 391sub has_citekey { 392 my $self = shift; 393 my $key = shift; 394 return $self->{citekeys_h}{$self->get_citekey_alias($key) || $key} ? 1 : 0; 395} 396 397 398=head2 del_citekey 399 400 Deletes a citekey from a Biber::Section object 401 402=cut 403 404sub del_citekey { 405 my $self = shift; 406 my $key = shift; 407 return unless $self->has_citekey($key); 408 $self->{citekeys} = [ grep {$_ ne $key} @{$self->{citekeys}} ]; 409 $self->{orig_order_citekeys} = [ grep {$_ ne $key} @{$self->{orig_order_citekeys}} ]; 410 delete $self->{citekeys_h}{$key}; 411 return; 412} 413 414=head2 del_citekeys 415 416 Deletes all citekeys from a Biber::Section object 417 418=cut 419 420sub del_citekeys { 421 my $self = shift; 422 $self->{citekeys} = []; 423 $self->{citekeys_h} = {}; 424 $self->{orig_order_citekeys} = []; 425 return; 426} 427 428=head2 add_citekeys 429 430 Adds citekeys to the Biber::Section object 431 432=cut 433 434sub add_citekeys { 435 my $self = shift; 436 my @keys = @_; 437 foreach my $key (@keys) { 438 next if $self->has_citekey($key); 439 $self->{citekeys_h}{$key} = 1; 440 push @{$self->{citekeys}}, $key; 441 push @{$self->{orig_order_citekeys}}, $key; 442 } 443 return; 444} 445 446 447=head2 set_citekey_alias 448 449 Set citekey alias information 450 451=cut 452 453sub set_citekey_alias { 454 my $self = shift; 455 my ($alias, $key) = @_; 456 $self->{citekey_alias}{$alias} = $key; 457 return; 458} 459 460=head2 get_citekey_alias 461 462 Get citekey alias information 463 464=cut 465 466sub get_citekey_alias { 467 my $self = shift; 468 my $alias = shift; 469 return $self->{citekey_alias}{$alias}; 470} 471 472=head2 del_citekey_alias 473 474 Delete citekey alias 475 476=cut 477 478sub del_citekey_alias { 479 my $self = shift; 480 my $alias = shift; 481 delete($self->{citekey_alias}{$alias}); 482 return; 483} 484 485 486=head2 get_citekey_aliases 487 488 Get a list of all citekey aliases for the section 489 490=cut 491 492sub get_citekey_aliases { 493 my $self = shift; 494 return ( keys %{$self->{citekey_alias}} ); 495} 496 497 498=head2 set_labelcache_v 499 500 Sets the variable label disambiguation cache for a field 501 502=cut 503 504sub set_labelcache_v { 505 my ($self, $field, $cache) = @_; 506 $self->{labelcache_v}{$field} = $cache; 507 return; 508} 509 510=head2 get_labelcache_v 511 512 Gets the variable label disambiguation cache for a field 513 514=cut 515 516sub get_labelcache_v { 517 my ($self, $field) = @_; 518 return $self->{labelcache_v}{$field}; 519} 520 521=head2 set_labelcache_l 522 523 Sets the list label disambiguation cache for a field 524 525=cut 526 527sub set_labelcache_l { 528 my ($self, $field, $cache) = @_; 529 $self->{labelcache_l}{$field} = $cache; 530 return; 531} 532 533=head2 get_labelcache_l 534 535 Gets the list label disambiguation cache for a field 536 537=cut 538 539sub get_labelcache_l { 540 my ($self, $field) = @_; 541 return $self->{labelcache_l}{$field}; 542} 543 544 545 546=head2 is_dynamic_set 547 548 Test if a key is a dynamic set 549 550=cut 551 552sub is_dynamic_set { 553 my $self = shift; 554 my $dkey = shift; 555 return defined($self->{dkeys}{$dkey}) ? 1 : 0; 556} 557 558=head2 set_dynamic_set 559 560 Record a mapping of dynamic key to member keys 561 562=cut 563 564sub set_dynamic_set { 565 my $self = shift; 566 my $dkey = shift; 567 my @members = @_; 568 $self->{dkeys}{$dkey} = \@members; 569 return; 570} 571 572=head2 get_dynamic_set 573 574 Retrieve member keys for a dynamic set key 575 Check that reference returning anything to stop spurious warnings 576 about empty dereference in return. 577 578=cut 579 580sub get_dynamic_set { 581 my $self = shift; 582 my $dkey = shift; 583 if (my $set_members = $self->{dkeys}{$dkey}) { 584 return @$set_members; 585 } 586 else { 587 return (); 588 } 589} 590 591=head2 dynamic_set_keys 592 593 Retrieve all dynamic set keys 594 595=cut 596 597sub dynamic_set_keys { 598 my $self = shift; 599 return [keys %{$self->{dkeys}}]; 600} 601 602=head2 has_dynamic_sets 603 604 Returns true of false depending on whether the section has any dynamic set keys 605 606=cut 607 608sub has_dynamic_sets { 609 my $self = shift; 610 return defined($self->{dkeys}) ? 1 : 0; 611} 612 613 614=head2 add_datasource 615 616 Adds a data source to a section 617 618=cut 619 620sub add_datasource { 621 my $self = shift; 622 my $source = shift; 623 push @{$self->{datasources}}, $source; 624 return; 625} 626 627=head2 set_datasources 628 629 Sets the data sources for a section 630 631=cut 632 633sub set_datasources { 634 my $self = shift; 635 my $sources = shift; 636 $self->{datasources} = $sources; 637 return; 638} 639 640 641=head2 get_datasources 642 643 Gets an array of data sources for this section 644 645=cut 646 647sub get_datasources { 648 my $self = shift; 649 if (exists($self->{datasources})) { 650 return $self->{datasources}; 651 } 652 else { 653 return undef; 654 } 655} 656 657 658=head2 add_sort_cache 659 660 Adds a scheme/keys pair to the sort cache: 661 [$scheme, $keys, $sortinitdata, $extraalphadata, $extrayeardata ] 662 663=cut 664 665sub add_sort_cache { 666 my $self = shift; 667 my $cacheitem = shift; 668 push @{$self->{sortcache}}, $cacheitem; 669 return; 670} 671 672 673=head2 get_sort_cache 674 675 Retrieves the sort cache 676 677=cut 678 679sub get_sort_cache { 680 my $self = shift; 681 return $self->{sortcache}; 682} 683 684 685 686=head2 number 687 688 Gets the section number of a Biber::Section object 689 690=cut 691 692sub number { 693 my $self = shift; 694 return $self->{number}; 695} 696 6971; 698 699__END__ 700 701=head1 AUTHORS 702 703François Charette, C<< <firmicus at ankabut.net> >> 704Philip Kime C<< <philip at kime.org.uk> >> 705 706=head1 BUGS 707 708Please report any bugs or feature requests on our Github tracker at 709L<https://github.com/plk/biber/issues>. 710 711=head1 COPYRIGHT & LICENSE 712 713Copyright 2009-2015 François Charette and Philip Kime, all rights reserved. 714 715This module is free software. You can redistribute it and/or 716modify it under the terms of the Artistic License 2.0. 717 718This program is distributed in the hope that it will be useful, 719but without any warranty; without even the implied warranty of 720merchantability or fitness for a particular purpose. 721 722=cut 723