diff options
Diffstat (limited to 'Master/texmf-dist/source/bibtex/biber/lib')
24 files changed, 0 insertions, 13903 deletions
diff --git a/Master/texmf-dist/source/bibtex/biber/lib/Biber.pm b/Master/texmf-dist/source/bibtex/biber/lib/Biber.pm deleted file mode 100644 index d15b8034c57..00000000000 --- a/Master/texmf-dist/source/bibtex/biber/lib/Biber.pm +++ /dev/null @@ -1,2178 +0,0 @@ -package Biber; -use strict; -use warnings; -#use feature 'unicode_strings'; -use Carp; -use Encode; -use File::Copy; -use File::Spec; -use IO::File; -use IPC::Cmd qw( can_run run ); -use POSIX qw( locale_h ); # for sorting with built-in "sort" -use Cwd qw( abs_path ); -use Biber::Config; -use Biber::Constants; -use List::Util qw( first ); -use Digest::MD5 qw( md5_hex ); -use Biber::Internals; -use Biber::Entries; -use Biber::Entry; -use Biber::Entry::Name; -use Biber::Sections; -use Biber::Section; -use Biber::Section::List; -use Biber::Structure; -use Biber::Utils; -use Storable qw( dclone ); -use Log::Log4perl qw( :no_extra_logdie_message ); -use base 'Biber::Internals'; -use Config::General qw( ParseConfig ); -use Data::Dump; -use Data::Compare; -use Text::BibTeX qw(:macrosubs); - -=encoding utf-8 - -=head1 NAME - -Biber - main module for biber, a bibtex replacement for users of biblatex - -=cut - -our $VERSION = '0.8'; -our $BETA_VERSION = 0; # Is this a beta version? - -my $logger = Log::Log4perl::get_logger('main'); - - -=head1 SYNOPSIS - - use Biber; - - my $biber = Biber->new(); - $biber->parse_ctrlfile("example.bcf"); - $biber->prepare; - -=cut - -=head1 METHODS - -=head2 new - - Initialize the Biber object, optionally passing named options as arguments. - -=cut - -sub new { - my ($class, %opts) = @_; - my $self = bless {}, $class; - - # Set up config object from config file and defaults - if (defined $opts{configfile}) { - Biber::Config->_initopts( $opts{configfile} ); - } else { - Biber::Config->_initopts(undef, $opts{noconf}); - } - # Command-line overrides everything else - if (%opts) { - foreach (keys %opts) { - Biber::Config->setcmdlineoption($_, $opts{$_}); - } - } - - return $self; -} - -=head2 biber_warn - - Wrapper around various warnings bits and pieces - Logs a warning, increments warning count in Biber object and add warning to - the list of .bbl warnings to add - -=cut - -sub biber_warn { - my $self = shift; - my $entry = shift; - my $warning = shift; - $logger->warn($warning); - $entry->add_warning($warning); - $self->{warnings}++; - return; -} - - -=head2 sections - - my $sections= $biber->sections - - Returns a Biber::Sections object describing the bibliography sections - -=cut - -sub sections { - my $self = shift; - return $self->{sections}; -} - - -=head2 set_output_obj - - Sets the object used to output final results - Must be a subclass of Biber::Output::Base - -=cut - -sub set_output_obj { - my $self = shift; - my $obj = shift; - croak('Output object must be subclass of Biber::Output::Base!') unless $obj->isa('Biber::Output::Base'); - $self->{output_obj} = $obj; - return; -} - - -=head2 get_preamble - - Returns the current preamble as an array ref - -=cut - -sub get_preamble { - my $self = shift; - return $self->{preamble}; -} - - -=head2 get_output_obj - - Returns the object used to output final results - -=cut - -sub get_output_obj { - my $self = shift; - return $self->{output_obj}; -} - -=head2 set_current_section - - Sets the current section number that we are working on to a section number - -=cut - -sub set_current_section { - my $self = shift; - my $secnum = shift; - $self->{current_section} = $secnum; - return; -} - -=head2 get_current_section - - Gets the current section number that we are working on - -=cut - -sub get_current_section { - my $self = shift; - return $self->{current_section}; -} - -=head2 parse_ctrlfile - - This method reads the control file - generated by biblatex to work out the various biblatex options. - See Constants.pm for defaults and example of the data structure being built here. - -=cut - -sub parse_ctrlfile { - my ($self, $ctrl_file) = @_; - - my $ctrl_file_path = locate_biber_file($ctrl_file); - Biber::Config->set_ctrlfile_path($ctrl_file_path); - - $logger->logdie("Cannot find control file '$ctrl_file'! - did you pass the \"backend=biber\" option to BibLaTeX?") unless ($ctrl_file_path and -e $ctrl_file_path); - - # Validate if asked to - if (Biber::Config->getoption('validate_control')) { - require XML::LibXML; - - # Set up XML parser - my $CFxmlparser = XML::LibXML->new(); - $CFxmlparser->line_numbers(1); # line numbers for more informative errors - - # Set up schema - my $CFxmlschema; - - # we assume that the schema files are in the same dir as Biber.pm: - (my $vol, my $biber_path, undef) = File::Spec->splitpath( $INC{"Biber.pm"} ); - - # Deal with the strange world of Par::Packer paths - # We might be running inside a PAR executable and @INC is a bit odd in this case - # Specifically, "Biber.pm" in @INC might resolve to an internal jumbled name - # nowhere near to these files. You know what I mean if you've dealt with pp - my $bcf_rng; - if ($biber_path =~ m|/par\-| and $biber_path !~ m|/inc|) { # a mangled PAR @INC path - $bcf_rng = File::Spec->catpath($vol, "$biber_path/inc/lib/Biber", 'bcf.rng'); - } - else { - $bcf_rng = File::Spec->catpath($vol, "$biber_path/Biber", 'bcf.rng'); - } - - if (-e $bcf_rng) { - $CFxmlschema = XML::LibXML::RelaxNG->new( location => $bcf_rng ) - } - else { - $logger->warn("Cannot find XML::LibXML::RelaxNG schema. Skipping validation : $!"); - $self->{warnings}++; - goto CONVERT; - } - - # Parse file - my $CFxp = $CFxmlparser->parse_file($ctrl_file_path); - - # XPath context - my $CFxpc = XML::LibXML::XPathContext->new($CFxp); - $CFxpc->registerNs('bcf', 'https://sourceforge.net/projects/biblatex'); - - # Validate against schema. Dies if it fails. - if ($CFxmlschema) { - eval { $CFxmlschema->validate($CFxp) }; - if (ref($@)) { - $logger->debug( $@->dump() ); - $logger->logdie("BibLaTeX control file \"$ctrl_file_path\" failed to validate\n$@"); - } - elsif ($@) { - $logger->logdie("BibLaTeX control file \"$ctrl_file_path\" failed to validate\n$@"); - } - else { - $logger->info("BibLaTeX control file \"$ctrl_file_path\" validates"); - } - } - undef $CFxmlparser; - } - - # Convert .bcf to .html using XSLT transform if asked to - CONVERT: - if (Biber::Config->getoption('convert_control')) { - - require XML::LibXSLT; - require XML::LibXML; - - my $xslt = XML::LibXSLT->new(); - my $CFstyle; - - # we assume that the schema files are in the same dir as Biber.pm: - (my $vol, my $biber_path, undef) = File::Spec->splitpath( $INC{"Biber.pm"} ); - - # Deal with the strange world of Par::Packer paths - # We might be running inside a PAR executable and @INC is a bit odd in this case - # Specifically, "Biber.pm" in @INC might resolve to an internal jumbled name - # nowhere near to these files. You know what I mean if you've dealt with pp - my $bcf_xsl; - if ($biber_path =~ m|/par\-| and $biber_path !~ m|/inc|) { # a mangled PAR @INC path - $bcf_xsl = File::Spec->catpath($vol, "$biber_path/inc/lib/Biber", 'bcf.xsl'); - } - else { - $bcf_xsl = File::Spec->catpath($vol, "$biber_path/Biber", 'bcf.xsl'); - } - - if (-e $bcf_xsl) { - $CFstyle = XML::LibXML->load_xml( location => $bcf_xsl, no_cdata=>1 ) - } - else { - $logger->warn("Cannot find XML::LibXSLT stylesheet. Skipping conversion : $!"); - $self->{warnings}++; - goto LOADCF; - } - - my $CF = XML::LibXML->load_xml(location => $ctrl_file_path); - my $stylesheet = $xslt->parse_stylesheet($CFstyle); - my $CFhtml = $stylesheet->transform($CF); - $stylesheet->output_file($CFhtml, $ctrl_file_path . '.html'); - $logger->info("Converted BibLaTeX control file '$ctrl_file_path' to '$ctrl_file_path.html'"); - } - - # Open control file - LOADCF: - my $ctrl = new IO::File "<$ctrl_file_path" - or $logger->logdie("Cannot open $ctrl_file_path: $!"); - - $logger->info("Reading $ctrl_file_path"); - - # Read control file - require XML::LibXML::Simple; - - my $bcfxml = XML::LibXML::Simple::XMLin($ctrl, - 'ForceContent' => 1, - 'ForceArray' => [ - qr/\Acitekey\z/, - qr/\Aoption\z/, - qr/\Aoptions\z/, - qr/\Avalue\z/, - qr/\Asortitem\z/, - qr/\Abibdata\z/, - qr/\Adatasource\z/, - qr/\Asection\z/, - qr/\Asortexclusion\z/, - qr/\Aexclusion\z/, - qr/\Asort\z/, - qr/\Adisplaymode\z/, - qr/\Amode\z/, - qr/\Apresort\z/, - qr/\Atype_pair\z/, - qr/\Ainherit\z/, - qr/\Afieldor\z/, - qr/\Afieldxor\z/, - qr/\Afield\z/, - qr/\Aalias\z/, - qr/\Aconstraints\z/, - qr/\Aconstraint\z/, - qr/\Aentrytype\z/, - qr/\Adatetype\z/, - qr/\Asectionlist\z/, - qr/\A(?:or)?filter\z/, - ], - 'NsStrip' => 1, - 'KeyAttr' => []); - - my $controlversion = $bcfxml->{version}; - Biber::Config->setblxoption('controlversion', $controlversion); - $logger->warn("Warning: Found biblatex control file version $controlversion, expected version $BIBLATEX_VERSION") - unless $controlversion eq $BIBLATEX_VERSION; - - # Look at control file and populate our main data structure with its information - - # OPTIONS - foreach my $bcfopts (@{$bcfxml->{options}}) { - - # Biber options - if (lc($bcfopts->{component}) eq 'biber') { - - # Global options - if (lc($bcfopts->{type}) eq 'global') { - foreach my $bcfopt (@{$bcfopts->{option}}) { - unless (defined(Biber::Config->getcmdlineoption($bcfopt->{key}{content}))) { # already set on cmd line - if (lc($bcfopt->{type}) eq 'singlevalued') { - Biber::Config->setoption($bcfopt->{key}{content}, $bcfopt->{value}[0]{content}); - } - elsif (lc($bcfopt->{type}) eq 'multivalued') { - Biber::Config->setoption($bcfopt->{key}{content}, - [ map {$_->{content}} sort {$a->{order} <=> $b->{order}} @{$bcfopt->{value}} ]); - } - } - } - } - } - - # BibLaTeX options - if (lc($bcfopts->{component}) eq 'biblatex') { - - # Global options - if (lc($bcfopts->{type}) eq 'global') { - foreach my $bcfopt (@{$bcfopts->{option}}) { - if (lc($bcfopt->{type}) eq 'singlevalued') { - Biber::Config->setblxoption($bcfopt->{key}{content}, $bcfopt->{value}[0]{content}); - } elsif (lc($bcfopt->{type}) eq 'multivalued') { - Biber::Config->setblxoption($bcfopt->{key}{content}, - [ map {$_->{content}} sort {$a->{order} <=> $b->{order}} @{$bcfopt->{value}} ]); - } - } - } - - # Entrytype options - else { - my $entrytype = $bcfopts->{type}; - foreach my $bcfopt (@{$bcfopts->{option}}) { - if (lc($bcfopt->{type}) eq 'singlevalued') { - Biber::Config->setblxoption($bcfopt->{key}{content}, $bcfopt->{value}[0]{content}, 'PER_TYPE', $entrytype); - } elsif (lc($bcfopt->{type}) eq 'multivalued') { - Biber::Config->setblxoption($bcfopt->{key}{content}, - [ map {$_->{content}} sort {$a->{order} <=> $b->{order}} @{$bcfopt->{value}} ], - 'PER_TYPE', - $entrytype); - } - } - } - } - } - - # DISPLAYMODES - # This should not be optional any more when biblatex implements this so take - # out this conditional - if (exists($bcfxml->{displaymodes})) { - my $dms; - foreach my $dm (@{$bcfxml->{displaymodes}{displaymode}}) { - $dms->{$dm->{target}{content}} = [ map {$_->{content}} @{$dm->{mode}} ]; - } - Biber::Config->setblxoption('displaymode', $dms); - } - - # INHERITANCE schemes for crossreferences (always global) - Biber::Config->setblxoption('inheritance', $bcfxml->{inheritance}); - - # SORTING - - # sorting excludes - foreach my $sex (@{$bcfxml->{sorting}{sortexclusion}}) { - my $excludes; - foreach my $ex (@{$sex->{exclusion}}) { - $excludes->{$ex->{content}} = 1; - } - Biber::Config->setblxoption('sortexclusion', - $excludes, - 'PER_TYPE', - $sex->{type}); - } - - # presort defaults - foreach my $presort (@{$bcfxml->{sorting}{presort}}) { - # Global presort default - unless (exists($presort->{type})) { - Biber::Config->setblxoption('presort', $presort->{content}); - } - # Per-type default - else { - Biber::Config->setblxoption('presort', - $presort->{content}, - 'PER_TYPE', - $presort->{type}); - } - } - - my $sorting = _parse_sort($bcfxml->{sorting}); - - Biber::Config->setblxoption('sorting', $sorting); - - # STRUCTURE schema (always global) - # This should not be optional any more when biblatex implements this so take - # out this conditional - if (exists($bcfxml->{structure})) { - Biber::Config->setblxoption('structure', $bcfxml->{structure}); - } - - # SECTIONS - # This is also where we set data files as these are associated with a bib section - - # Data sources - my %bibdatasources = (); - foreach my $data (@{$bcfxml->{bibdata}}) { - foreach my $datasource (@{$data->{datasource}}) { - push @{$bibdatasources{$data->{section}[0]}}, { type => $datasource->{type}, - name => $datasource->{content}, - datatype => $datasource->{datatype} }; - } - } - - unless (%bibdatasources or Biber::Config->getoption('bibdata')) { - $logger->logdie("No data files on command line or provided in the file '$ctrl_file_path'! Exiting") - } - - my $key_flag = 0; - my $bib_sections = new Biber::Sections; - -SECTION: foreach my $section (@{$bcfxml->{section}}) { - my $bib_section; - my $secnum = $section->{number}; - # Can be multiple section 0 entries and so re-use that section object if it exists - if (my $existing_section = $bib_sections->get_section($secnum)) { - $bib_section = $existing_section; - } - else { - $bib_section = new Biber::Section('number' => $secnum); - } - - # Set the data files for the section unless we've already done so - # (for example, for multiple section 0 entries) - $bib_section->set_datasources($bibdatasources{$secnum}) unless - $bib_section->get_datasources; - - # Add any list specs to the Biber::Section object - foreach my $list (@{$section->{sectionlist}}) { - my $llabel = $list->{label}; - if ($bib_section->get_list($llabel)) { - $logger->warn("Section list '$llabel' is repeated for section $secnum - ignoring subsequent mentions"); - $self->{warnings}++; - next; - } - - my $seclist = Biber::Section::List->new(label => $llabel); - foreach my $filter (@{$list->{filter}}) { - $seclist->add_filter($filter->{type}, $filter->{content}); - } - # disjunctive filters - foreach my $orfilter (@{$list->{orfilter}}) { - $seclist->add_filter('orfilter', { map {$_->{type} => [$_->{content}]} @{$orfilter->{filter}} }); - } - - if (my $sorting = $list->{sorting}) { # can be undef for fallback to global sorting - $seclist->set_sortscheme(_parse_sort($sorting)); - } - else { - $seclist->set_sortscheme(Biber::Config->getblxoption('sorting')); - } - $seclist->set_type($list->{type} || 'entry'); # lists are entry lists by default - $logger->debug("Adding list '$llabel' to section $secnum"); - $bib_section->add_list($seclist); - } - - # Intermediate code until biblatex moves main \printbibliography to a list - # MAIN list has no filter and no sorting spec so it uses all citekeys and the - # global sort default. - unless ($bib_section->get_list('MAIN')) { - my $mainlist = Biber::Section::List->new(label => 'MAIN'); - $mainlist->set_sortscheme(Biber::Config->getblxoption('sorting')); - $mainlist->set_type('entry'); - $bib_section->add_list($mainlist); - } - - # Intermediate code until biblatex moves SHORTHANDS to a .bcf supported list - unless ($bib_section->get_list('SHORTHANDS')) { - my $los = Biber::Section::List->new(label => 'SHORTHANDS'); - if (Biber::Config->getblxoption('sortlos')) { - $los->set_sortscheme([ [ {}, {'shorthand' => {}} ] ]); - $los->add_filter('field', 'shorthand'); - } - else { - $los->set_sortscheme(Biber::Config->getblxoption('sorting')); - $los->add_filter('field', 'shorthand'); - } - $los->set_type('shorthand'); - $bib_section->add_list($los); - } - - # Stop reading citekeys if we encounter "*" as a citation as this means - # "all keys" - my @keys = (); - foreach my $keyc (@{$section->{citekey}}) { - my $key = $keyc->{content}; - if ($key eq '*') { - $bib_section->allkeys; - # Normalise - when allkeys is true don't need citekeys - just in case someone - # lists "*" and also some other citekeys - $bib_section->del_citekeys; - $key_flag = 1; # There is at least one key, used for error reporting below - $logger->info("Using all citekeys in bib section " . $secnum); - $bib_sections->add_section($bib_section); - next SECTION; - } - elsif (not Biber::Config->get_seenkey($key, $secnum)) { - # Dynamic set definition - # Save dynamic key -> member keys mapping for set entry auto creation later - if (exists($keyc->{type}) and $keyc->{type} eq 'set') { - $bib_section->set_dynamic_set($key, split /\s*,\s*/, $keyc->{members}); - } - push @keys, $key; - $key_flag = 1; # There is at least one key, used for error reporting below - Biber::Config->incr_seenkey($key, $secnum); - } - elsif (Biber::Config->get_keycase($key) ne $key) { - $logger->warn("Case mismatch error between cite keys '$key' and '" . Biber::Config->get_keycase($key) . "'"); - $self->{warnings}++; - next; - } - } - - unless ($bib_section->is_allkeys) { - $logger->info("Found ", $#keys+1 , " citekeys in bib section $secnum") - } - - if (Biber::Config->getoption('debug')) { - my @debug_keys = sort @keys; - unless ($bib_section->is_allkeys) { - $logger->debug("The citekeys for section $secnum are: ", join(', ', @debug_keys), "\n"); - } - } - - $bib_section->add_citekeys(@keys); - $bib_sections->add_section($bib_section); - } - - # Die if there are no citations in any section - unless ($key_flag) { - $logger->warn("The file '$ctrl_file_path' does not contain any citations!"); - $self->{warnings}++; - } - - # Add the Biber::Sections object to the Biber object - $self->{sections} = $bib_sections; - - # Normalise any UTF-8 encoding string immediately to exactly what we want - # We want the strict perl utf8 "UTF-8" - normalise_utf8(); - - return; -} - - -=head2 process_setup - - Place to put misc pre-processing things needed later - -=cut - -sub process_setup { - # Break structure information up into more processing-friendly formats - # for use in verification checks later - # This has to be here as opposed to in parse_control() so that it can pick - # up structure defaults in Constants.pm in case there is no .bcf - Biber::Config->set_structure(Biber::Structure->new(Biber::Config->getblxoption('structure'))); - - # Force bblsafechars flag if output to ASCII - if (Biber::Config->getoption('bblencoding') =~ /(?:x-)ascii/xmsi) { - Biber::Config->setoption('bblsafechars', 1); - } -} - - -=head2 instantiate_dynamic - - This instantiates any dynamic entries so that they are available - for processing later on. This has to be done before most all other - processing so that when we call $section->bibentry($key), as we - do many times in the code, we don't die because there is a key but - no Entry object. - -=cut - -sub instantiate_dynamic { - my $self = shift; - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - - $logger->debug("Creating dynamic entries (sets/related) for section $secnum"); - - # Instantiate any dynamic set entries before we do anything else - foreach my $dset (@{$section->dynamic_set_keys}) { - my @members = $section->get_dynamic_set($dset); - my $be = new Biber::Entry; - $be->set_field('entrytype', 'set'); - $be->set_field('entryset', join(',', @members)); - $be->set_field('dskey', $dset); - $be->set_field('citekey', $dset); - $be->set_field('datatype', 'dynamic'); - $section->bibentries->add_entry($dset, $be); - # Setting dataonly for members is handled by process_sets() - } - - # Instantiate any related entry clones we need - foreach my $citekey ($section->get_citekeys) { - my $be = $section->bibentry($citekey); - if (my $relkeys = $be->get_field('related')) { - $be->del_field('related'); # clear the related field - my @clonekeys; - foreach my $relkey (split /\s*,\s*/, $relkeys) { - my $relentry = $section->bibentry($relkey); - my $clonekey = md5_hex($relkey); - push @clonekeys, $clonekey; - my $relclone = $relentry->clone($clonekey); - # clone doesn't need the related fields - $relclone->del_field('related'); - $relclone->del_field('relatedtype'); - $relclone->del_field('relatedstring'); - $relclone->set_datafield('options', 'dataonly'); - $section->bibentries->add_entry($clonekey, $relclone); - Biber::Config->setblxoption('skiplab', 1, 'PER_ENTRY', $clonekey); - Biber::Config->setblxoption('skiplos', 1, 'PER_ENTRY', $clonekey); - } - # point to clone keys and add to citekeys - $section->add_citekeys(@clonekeys); - $be->set_datafield('related', join(',', @clonekeys)); - } - } - return; -} - - -=head2 process_crossrefs - - $biber->process_crossrefs - - This does several things: - 1. Ensures that all entryset key members will be output in the bbl. - 2. Ensures proper inheritance of data from cross-references. - 3. Ensures that crossrefs/xrefs that are directly cited or cross-referenced - at least mincrossrefs times are included in the bibliography. - -=cut - -sub process_crossrefs { - my $self = shift; - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - - $logger->debug("Processing explicit and implicit crossrefs for section $secnum"); - - # Loop over cited keys and count the cross/xrefs - # Can't do this when parsing entries as this would count them - # for potentially uncited children - foreach my $citekey ($section->get_citekeys) { - my $be = $section->bibentry($citekey); - my $refkey; - if ($refkey = $be->get_field('xref') or $refkey = $be->get_field('crossref')) { - $logger->debug("Incrementing cross/xrefkey count for entry '$refkey' via entry '$citekey'"); - Biber::Config->incr_crossrefkey($refkey); - } - } - - # promote indirectly cited inset set members to fully cited entries - foreach my $citekey ($section->get_citekeys) { - my $be = $section->bibentry($citekey); - if ($be->get_field('entrytype') eq 'set') { - my @inset_keys = split /\s*,\s*/, $be->get_field('entryset'); - foreach my $inset_key (@inset_keys) { - $logger->debug(" Adding set member '$inset_key' to the citekeys (section $secnum)"); - $section->add_citekeys($inset_key); - } - # automatically crossref for the first set member using plain set inheritance - $be->set_inherit_from($section->bibentry($inset_keys[0])); - if ($be->get_field('crossref')) { - $self->biber_warn($be, "Field 'crossref' is no longer needed in set entries in Biber - ignoring in entry '$citekey'"); - $be->del_field('crossref'); - } - } - # Do crossrefs inheritance - if (my $crossrefkey = $be->get_field('crossref')) { - my $parent = $section->bibentry($crossrefkey); - $logger->debug(" Entry $citekey inheriting fields from parent $crossrefkey"); - unless ($parent) { - $self->biber_warn($be, "Cannot inherit from crossref key '$crossrefkey' - does it exist?"); - } - else { - $be->inherit_from($parent); - } - } - } - - # We make sure that crossrefs that are directly cited or cross-referenced - # at least $mincrossrefs times are included in the bibliography. - foreach my $k ( @{Biber::Config->get_crossrefkeys} ) { - # If parent has been crossref'ed more than mincrossref times, upgrade it - # to cited crossref status and add it to the citekeys list - if (Biber::Config->get_crossrefkey($k) >= Biber::Config->getoption('mincrossrefs')) { - $logger->debug("cross/xref key '$k' is cross/xref'ed >= mincrossrefs, adding to citekeys"); - $section->add_citekeys($k); - } - } -} - -=head2 validate_structure - - Validate bib structure according to a bib schema - Note that we are validating the internal Biber::Entries - after they have been created from the datasources so this is - datasource neutral, as it should be. It is here to enforce - adherence to what biblatex expects. - -=cut - -sub validate_structure { - my $self = shift; - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - my $struc = Biber::Config->get_structure; - if (Biber::Config->getoption('validate_structure')) { - foreach my $citekey ($section->get_citekeys) { - my $be = $section->bibentry($citekey); - my $et = $be->get_field('entrytype'); - - # default entrytype to MISC type if not a known type - unless ($struc->is_entrytype($et)) { - $self->biber_warn($be, "Entry '$citekey' - invalid entry type '" . $be->get_field('entrytype') . "' - defaulting to 'misc'"); - $be->set_field('entrytype', 'misc'); - $et = 'misc'; # reset this too - } - - # Are all fields valid fields? - # Each field must be: - # * Valid because it's allowed for "ALL" entrytypes OR - # * Valid field for the specific entrytype OR - # * Valid because entrytype allows "ALL" fields - foreach my $ef ($be->datafields) { - unless ($struc->is_field_for_entrytype($et, $ef)) { - $self->biber_warn($be, "Entry '$citekey' - invalid field '$ef' for entrytype '$et'"); - } - } - - # Mandatory constraints - foreach my $warning ($struc->check_mandatory_constraints($be)) { - $self->biber_warn($be, $warning); - } - - # Conditional constraints - foreach my $warning ($struc->check_conditional_constraints($be)) { - $self->biber_warn($be, $warning); - } - - # Data constraints - foreach my $warning ($struc->check_data_constraints($be)) { - $self->biber_warn($be, $warning); - } - - # Date constraints - foreach my $warning ($struc->check_date_components($be)) { - $self->biber_warn($be, $warning); - } - } - } -} - -=head2 process_entries - - Main processing operations, to generate metadata and entry information - This method is automatically called by C<prepare>. - Here we parse names, generate the "namehash" and the strings for - "labelname", "labelyear", "labelalpha", "sortstrings", etc. - -=cut - -sub process_entries { - my $self = shift; - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - foreach my $citekey ( $section->get_citekeys ) { - $logger->debug("Postprocessing entry '$citekey' from section $secnum"); - - # process "set" entries: - $self->process_sets($citekey); - - # generate labelname name - $self->process_labelname($citekey); - - # generate labelyear name - $self->process_labelyear($citekey); - - # generate namehash,fullhash - $self->process_hashes($citekey); - - # generate uniqueness information - $self->process_unique($citekey); - - # track labelname/year combinations - $self->process_labelnameyear($citekey); - - # generate labelalpha information - $self->process_labelalpha($citekey); - - # push entry-specific presort fields into the presort state - $self->process_presort($citekey); - - } - - $logger->debug("Finished processing entries in section $secnum"); - - return; -} - -=head2 process_sets - - Postprocess set entries - - Checks for common set errors and enforces 'dataonly' for set members - -=cut - -sub process_sets { - my $self = shift; - my $citekey = shift; - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - my $be = $section->bibentry($citekey); - if ($be->get_field('entrytype') eq 'set') { - my @entrysetkeys = split /\s*,\s*/, $be->get_field('entryset'); - - # Enforce Biber parts of virtual "dataonly" for set members - # Also automatically create an "entryset" field for the members - foreach my $member (@entrysetkeys) { - Biber::Config->setblxoption('skiplab', 1, 'PER_ENTRY', $member); - Biber::Config->setblxoption('skiplos', 1, 'PER_ENTRY', $member); - my $me = $section->bibentry($member); - if ($me->get_field('entryset')) { - $self->biber_warn($me, "Field 'entryset' is no longer needed in set member entries in Biber - ignoring in entry '$member'"); - $me->del_field('entryset'); - } - # This ends up setting \inset{} in the bib - $me->set_field('entryset', $citekey); - } - - unless (@entrysetkeys) { - $self->biber_warn($be, "No entryset found for entry $citekey of type 'set'"); - } - } - # check if this non-set entry is in a cited set and if so, we - # have enforced Biber parts of virtual "dataonly" otherwise - # this entry will spuriously generate disambiguation data for itself - # This would only happen if the non-set entry was cited before any set - # in which it occurred of course since otherwise it would have already had - # "dataonly" enforced by the code above - else { - foreach my $pset_key ($section->get_citekeys) { - my $pset_be = $section->bibentry($pset_key); - if ($pset_be->get_field('entrytype') eq 'set') { - my @entrysetkeys = split /\s*,\s*/, $pset_be->get_field('entryset'); - foreach my $member (@entrysetkeys) { - next unless $member eq $citekey; - # Posssible that this has already been set if this set entry member - # was dealt with above but in case we haven't seen the set it's in yet ... - Biber::Config->setblxoption('skiplab', 1, 'PER_ENTRY', $member); - Biber::Config->setblxoption('skiplos', 1, 'PER_ENTRY', $member); - } - } - } - } -} - -=head2 process_labelname - - Generate labelname information. Fields set are: - - * labelnamename - the name of the labelname field to use - * labelnamenamefullhash - the name of the labelname field to use for - fulhash generation. - - We can retreive the actual labelname value later with: - - $entry->get_field($entry->get_field('labelnamename)) - - It's neat this way as we often need to know what the labelname field is - as well as it's actual string value - -=cut - -sub process_labelname { - my $self = shift; - my $citekey = shift; - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - my $be = $section->bibentry($citekey); - my $lnamespec = Biber::Config->getblxoption('labelnamespec', $be->get_field('entrytype')); - - # First we set the normal labelname name - foreach my $ln ( @{$lnamespec} ) { - my $lnameopt; - if ( $ln =~ /\Ashort(.+)\z/ ) { - $lnameopt = $1; - } else { - $lnameopt = $ln; - } - if ($be->get_field($ln) and - Biber::Config->getblxoption("use$lnameopt", $be->get_field('entrytype'), $citekey ) ) { - $be->set_field('labelnamename', $ln); - last; - } - } - - # Then we loop again to set the labelname name for the fullhash generation code - # This is because fullhash generation ignores SHORT* fields (section 4.2.4.1, BibLaTeX - # manual) - foreach my $ln ( @{$lnamespec} ) { - if ( $ln =~ /\Ashort(.+)\z/ ) { - next; - } - if ($be->get_field($ln) and - Biber::Config->getblxoption("use$ln", $be->get_field('entrytype'), $citekey ) ) { - $be->set_field('labelnamenamefullhash', $ln); - last; - } - } - - # Generate the actual labelname - if ($be->get_field('labelnamename')) { - $be->set_field('labelname', $be->get_field($be->get_field('labelnamename'))); - } - else { - $logger->debug("Could not determine the labelname of entry $citekey"); - } -} - -=head2 process_labelyear - - Generate labelyear - Here, "labelyearname" is the name of the labelyear field - and "labelyear" is the actual copy of the relevant field - -=cut - -sub process_labelyear { - my $self = shift; - my $citekey = shift; - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - my $be = $section->bibentry($citekey); - - if (Biber::Config->getblxoption('labelyear', $be->get_field('entrytype'))) { - my $lyearspec = Biber::Config->getblxoption('labelyearspec', $be->get_field('entrytype')); - - if (Biber::Config->getblxoption('skiplab', $be->get_field('entrytype'), $citekey)) { - return; - } - # make sure we gave the correct data type: - $logger->logdie("Invalid value for option labelyear: $lyearspec\n") - unless ref $lyearspec eq 'ARRAY'; - foreach my $ly ( @{$lyearspec} ) { - if ($be->get_field($ly)) { - $be->set_field('labelyearname', $ly); - last; - } - } - - # Construct labelyear - # Might not have been set due to skiplab/dataonly - if (my $yf = $be->get_field('labelyearname')) { - $be->set_field('labelyear', $be->get_field($yf)); - - # ignore endyear if it's the same as year - my ($ytype) = $yf =~ /\A(.*)year\z/xms; - # endyear can be null - if (is_def_and_notnull($be->get_field($ytype . 'endyear')) - and ($be->get_field($yf) ne $be->get_field($ytype . 'endyear'))) { - $be->set_field('labelyear', - $be->get_field('labelyear') . '\bibdatedash ' . $be->get_field($ytype . 'endyear')); - } - } - else { - $logger->debug("Could not determine the labelyearname of entry $citekey"); - } - } -} - -=head2 process_hashes - - Generate namehash and fullhash - -=cut - -sub process_hashes { - my $self = shift; - my $citekey = shift; - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - my $be = $section->bibentry($citekey); - my $bee = $be->get_field('entrytype'); - my $namehash = ''; # biblatex namehash field (manual, section 4.2.4.1) - my $fullhash = ''; # biblatex fullhash field (manual, section 4.2.4.1) - my $nameid = ''; - - # namehash is generated from the labelname - if (my $lname = $be->get_field('labelnamename')) { - if (my $ln = $be->get_field($lname)) { - $namehash .= $self->_getnamehash($citekey, $ln); - $nameid .= makenameid($ln); - } - } - # fullhash is generated from the labelname but ignores SHORT* fields and - # maxnames/minnames settings - if (my $lnamefh = $be->get_field('labelnamenamefullhash')) { - if ($be->get_field($lnamefh)) { - $fullhash .= $self->_getfullhash($citekey, $be->get_field($lnamefh)); - } - } - - # After the initial generation of namehash and fullhash, we have to append - # a suffix as they must be unique. It is possible that different entries have - # the same hashes at this stage. For example: - - # AUTHOR = {Fred Grimble and Bill Bullter} = "FGBB" - # AUTHOR = {Frank Garby and Brian Blunkley} = "FGBB" - - my $hashsuffix = 1; - - # First, check to see if we've already seen this exact name before - if (Biber::Config->get_namehashcount($namehash, $nameid)) { - # If we have, our suffix is already known - $hashsuffix = Biber::Config->get_namehashcount($namehash, $nameid); - } - # Otherwise, if the namehash already exists, we'll make a new entry with a new suffix - elsif (Biber::Config->namehashexists($namehash)) { - # Count the suffixes already defined ... - my $count = Biber::Config->get_numofnamehashes($namehash); - # ... add one to the number ... - $hashsuffix = $count + 1; - # ... and define a new suffix for that name - Biber::Config->set_namehashcount($namehash, $nameid, $hashsuffix); - } - # No entry for the namehash at all so make a new one, a new name and suffix - else { - Biber::Config->del_namehash($namehash); - Biber::Config->set_namehashcount($namehash, $nameid, 1); - } - - # Now append the suffices, making the hashes unique - $namehash .= $hashsuffix; - $fullhash .= $hashsuffix; - - # Set the hashes - $be->set_field('namehash', $namehash); - $be->set_field('fullhash', $fullhash); - - # Don't add to disambiguation data if skiplab is set - unless (Biber::Config->getblxoption('skiplab', $bee, $citekey)) { - Biber::Config->incr_seennamehash($fullhash); - } -} - -=head2 process_unique - - Generate uniqueness information. This is used later to generate unique* fields - -=cut - -sub process_unique { - my $self = shift; - my $citekey = shift; - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - my $be = $section->bibentry($citekey); - my $bee = $be->get_field('entrytype'); - my $namehash = $be->get_field('namehash'); - - # Set uniquename, if required - # Note that we don't determine if a name is unique here - - # we can't, were still processing entries at this point. - # Here we are just recording seen combinations of: - # - # lastnames and what hashes were generated from them (uniquename = 0) - # lastnames+initials and what hashes were generated from them (uniquename = 1) - # - # Naturally, anything which has more than one combination for both of these would - # be uniquename = 2 - # - # See the logic in Internals.pm for generating the actual uniquename count - # from the information collected here - if (Biber::Config->getblxoption('uniquename', $bee)) { - my $lname = $be->get_field('labelnamename'); - my $lastname; - my $namestring; - my $singlename; - - # uniquename only works (currently) with single names - if ($lname) { - $lastname = $be->get_field($lname)->nth_element(1)->get_lastname; - $namestring = $be->get_field($lname)->nth_element(1)->get_nameinitstring; - $singlename = $be->get_field($lname)->count_elements; - } - - # If we need to provide uniquename, labelnamename exists and we are only - # dealing with a single name - if ($lname and $singlename == 1 ) { - # Record a uniqueness information entry for the lastname showing that - # this lastname has been seen in the name with the namehash - Biber::Config->add_uniquenamecount($lastname, $namehash); - - # Record a uniqueness information entry for the lastname+initials showing that - # this lastname_initials has been seen in the name with the namehash - Biber::Config->add_uniquenamecount($namestring, $namehash); - } - else { - $be->set_field('ignoreuniquename', 1); - } - } -} - -=head2 process_labelnameyear - - Track author/year combination - -=cut - -sub process_labelnameyear { - my $self = shift; - my $citekey = shift; - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - my $be = $section->bibentry($citekey); - # This is all used to generate extrayear and the rules for this are: - # * Generate labelname/year combination for tracking extrayear - # * If there is no labelname to use, use empty string - # * If there is no labelyear to use, use empty string - # * Don't increment the seen_extra* count if either name or year string is empty - # (see code in incr_seen_extra* methods). - # * Don't increment if skiplab is set - - my $name_string; - # For tracking name/year combinations, use shorthand only if it exists and we - # are using labelyear - if ( Biber::Config->getblxoption('labelalpha', $be->get_field('entrytype')) and - $be->get_field('shorthand')) { - $name_string = $be->get_field('shorthand'); - } - elsif (my $lnn = $be->get_field('labelnamename')) { - $name_string = $self->_namestring($citekey, $lnn); - } - else { - $name_string = ''; - } - - # extrayear takes into account the labelyear which can be a range - my $year_string_extrayear; - if (my $ly = $be->get_field('labelyear')) { - $year_string_extrayear = $ly; - } - elsif (my $y = $be->get_field('year')) { - $year_string_extrayear = $y; - } - else { - $year_string_extrayear = ''; - } - - # extraalpha takes into account the "year of publication" and not ranges as it - # only has the last two digits of the year and so can't disambiguate using ranges - # so, we have to track it separately to extrayear - my $year_string_extraalpha; - if (my $y = $be->get_field('year')) { - $year_string_extraalpha = $y; - } - else { - $year_string_extraalpha = ''; - } - - # Don't create disambiguation data for skiplab entries - unless (Biber::Config->getblxoption('skiplab', - $be->get_field('entrytype'), - $be->get_field('dskey'))) { - my $nameyear_string_extrayear = "$name_string,$year_string_extrayear"; - $logger->debug("Setting 'nameyear_extrayear' to '$nameyear_string_extrayear' for entry '$citekey'"); - $be->set_field('nameyear_extrayear', $nameyear_string_extrayear); - Biber::Config->incr_seen_nameyear_extrayear($name_string, $year_string_extrayear); - my $nameyear_string_extraalpha = "$name_string,$year_string_extraalpha"; - $logger->debug("Setting 'nameyear_extraalpha' to '$nameyear_string_extraalpha' for entry '$citekey'"); - $be->set_field('nameyear_extraalpha', $nameyear_string_extraalpha); - Biber::Config->incr_seen_nameyear_extraalpha($name_string, $year_string_extraalpha); - } -} - -=head2 process_labelalpha - - Generate the labelalpha and also the variant for sorting - -=cut - -sub process_labelalpha { - my $self = shift; - my $citekey = shift; - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - my $be = $section->bibentry($citekey); - my $bee = $be->get_field('entrytype'); - # Don't add a label if skiplab is set for entry - if (Biber::Config->getblxoption('skiplab', $bee, $citekey)) { - return; - } - if ( Biber::Config->getblxoption('labelalpha', $be->get_field('entrytype')) ) { - my $label; - my $sortlabel; - - if ( $be->get_field('shorthand') ) { - $sortlabel = $label = $be->get_field('shorthand'); - } - else { - if ( $be->get_field('label') ) { - $sortlabel = $label = $be->get_field('label'); - } - elsif ( $be->get_field('labelnamename') and $be->get_field($be->get_field('labelnamename'))) { - ( $label, $sortlabel ) = - @{ $self->_getlabel( $citekey, $be->get_field('labelnamename') ) }; - } - else { - $sortlabel = $label = ''; - } - - # biblatex manual says "publication year" - if ( my $year = $be->get_field('year') ) { - my $yr; - # Make "in press" years look nice in alpha styles - if ($year =~ m/\A\s*in\s*press\s*\z/ixms) { - $yr = 'ip'; - } - # Normal year - else { - $yr = substr $year, 2, 2; - } - $label .= $yr; - $sortlabel .= $yr; - } - } - $be->set_field('labelalpha', $label); - $be->set_field('sortlabelalpha', $sortlabel); - } -} - - -=head2 process_presort - - Put presort fields for an entry into the main Biber bltx state - so that it's all available in the same place since this can be - set per-type and globally too. - -=cut - -sub process_presort { - my $self = shift; - my $citekey = shift; - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - my $be = $section->bibentry($citekey); - # We are treating presort as an option as it can be set per-type and globally too - if (my $ps = $be->get_field('presort')) { - Biber::Config->setblxoption('presort', $ps, 'PER_ENTRY', $citekey); - } -} - -=head2 process_lists - - Sort and filter lists for a section - -=cut - -sub process_lists { - my $self = shift; - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - foreach my $list (@{$section->get_lists}) { - my $llabel = $list->get_label; - - # Last-ditch fallback in case we still don't have a sorting spec - # probably due to being called via biber with -a and -d flags - $list->set_sortscheme(Biber::Config->getblxoption('sorting')) unless $list->get_sortscheme; - - $list->set_keys([ $section->get_citekeys ]); - $logger->debug("Populated list '$llabel' in section $secnum with keys: " . join(', ', $list->get_keys)); - - # Now we check the sorting cache to see if we already have results - # for this scheme since sorting is computationally expensive. - # We know the keys are the same as we just set them - # to a copy of the section citekeys above. If the scheme is the same - # as a previous sort then the results have to also be the same so inherit - # the results which are normally set by sorting: - # - # * sorted keys - # * sortinit data - # * extraalpha data - # * extrayear data - - my $cache_flag = 0; - $logger->debug("Checking sorting cache for list '$llabel'"); - foreach my $cacheitem (@{$section->get_sort_cache}) { - if (Compare($list->get_sortscheme, $cacheitem->[0])) { - $logger->debug("Found sorting cache entry for '$llabel'"); - $list->set_keys($cacheitem->[1]); - $list->set_sortinitdata($cacheitem->[2]); - $list->set_extraalphadata($cacheitem->[3]); - $list->set_extrayeardata($cacheitem->[4]); - $cache_flag = 1; - last; - } - } - - unless ($cache_flag) { - $logger->debug("No sorting cache entry for '$llabel'"); - # Sorting - $self->generate_sortinfo($list); # generate the sort information - $self->sort_list($list); # sort the list - $self->generate_extra($list); # generate the extra* fields - - # Cache the results - $logger->debug("Adding sorting cache entry for '$llabel'"); - $section->add_sort_cache($list->get_listdata); - } - - # Filtering - # This is not really used - filtering is more efficient to do on the biblatex - # side since we are filtering afer sorting anyway. It is used to provide - # a field=shorthand filter for type=shorthand lists though. - if (my $filters = $list->get_filters) { - my $flist = []; -KEYLOOP: foreach my $k ($list->get_keys) { - # Filter out skiplos entries as a special case in 'shorthand' type lists - if ($list->get_type eq 'shorthand') { - next if Biber::Config->getblxoption('skiplos', $section->bibentry($k), $k); - } - - $logger->debug("Checking key '$k' in list '$llabel' against list filters"); - my $be = $section->bibentry($k); - foreach my $t (keys %$filters) { - my $fs = $filters->{$t}; - # Filter disjunction is ok if any of the checks are ok, hence the grep() - if ($t eq 'orfilter') { - next KEYLOOP unless grep {check_list_filter($k, $_, $fs->{$_}, $be)} keys %$fs; - } - else { - next KEYLOOP unless check_list_filter($k, $t, $fs, $be); - } - } - push @$flist, $k; - } - $logger->debug("Keys after filtering list '$llabel' in section $secnum: " . join(', ', @$flist)); - $list->set_keys($flist); # Now save the sorted list in the list object - } - } - return; -} - - -=head2 check_list_filter - - Run an entry through a list filter. Returns a boolean. - -=cut - -sub check_list_filter { - my ($k, $t, $fs, $be) = @_; - $logger->debug(" Checking key '$k' against filter '$t=" . join(',', @$fs) . "'"); - if ($t eq 'type') { - return 0 unless grep {$be->get_field('entrytype') eq $_} @$fs; - } - elsif ($t eq 'nottype') { - return 0 if grep {$be->get_field('entrytype') eq $_} @$fs; - } - elsif ($t eq 'subtype') { - return 0 unless grep {$be->field_exists('entrysubtype') and - $be->get_field('entrysubtype') eq $_} @$fs; - } - elsif ($t eq 'notsubtype') { - return 0 if grep {$be->field_exists('entrysubtype') and - $be->get_field('entrysubtype') eq $_} @$fs; - } - elsif ($t eq 'keyword') { - return 0 unless grep {$be->has_keyword($_)} @$fs; - } - elsif ($t eq 'notkeyword') { - return 0 if grep {$be->has_keyword($_)} @$fs; - } - elsif ($t eq 'field') { - return 0 unless grep {$be->field_exists($_)} @$fs; - } - elsif ($t eq 'notfield') { - return 0 if grep {$be->field_exists($_)} @$fs; - } - return 1; -} - - -=head2 generate_sortinfo - - Generate information for sorting - -=cut - -sub generate_sortinfo { - my $self = shift; - my $list = shift; - - my $sortscheme = $list->get_sortscheme; - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - foreach my $key ($list->get_keys) { - $self->_generatesortinfo($key, $list, $sortscheme); - } - return; -} - -=head2 generate_extra - - Generate: - - * extraalpha - * extrayear - -=cut - -sub generate_extra { - my $self = shift; - my $list = shift; - my $sortscheme = $list->get_sortscheme; - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - Biber::Config->reset_seen_extra(); # Since this sub is per-list, have to reset the - # extra* counters per list - # This loop critically depends on the order of the citekeys which - # is why we have to do a first sorting pass before this - foreach my $key ($list->get_keys) { - my $be = $section->bibentry($key); - my $bee = $be->get_field('entrytype'); - # Only generate extrayear and extraalpha if skiplab is not set. - # Don't forget that skiplab is implied for set members - unless (Biber::Config->getblxoption('skiplab', $bee, $key)) { - if (Biber::Config->getblxoption('labelyear', $be->get_field('entrytype'))) { - my $nameyear_extrayear = $be->get_field('nameyear_extrayear'); - if (Biber::Config->get_seen_nameyear_extrayear($nameyear_extrayear) > 1) { - $list->set_extrayeardata($key, Biber::Config->incr_seen_extrayear($nameyear_extrayear)); - } - } - if (Biber::Config->getblxoption('labelalpha', $be->get_field('entrytype'))) { - my $nameyear_extraalpha = $be->get_field('nameyear_extraalpha'); - if (Biber::Config->get_seen_nameyear_extraalpha($nameyear_extraalpha) > 1) { - $list->set_extraalphadata($key, Biber::Config->incr_seen_extraalpha($nameyear_extraalpha)); - } - } - } - } - return; -} - -=head2 sort_list - - Sort a list using information in entries according to a certain sorting scheme. - Use a flag to skip info messages on first pass - -=cut - -sub sort_list { - my $self = shift; - my $list = shift; - my $sortscheme = $list->get_sortscheme; - my @keys = $list->get_keys; - my $llabel = $list->get_label; - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - - if (Biber::Config->getoption('sortcase')) { - $logger->debug("Sorting is by default case-SENSITIVE"); - } - else { - $logger->debug("Sorting is by default case-INSENSITIVE"); - } - $logger->debug("Keys before sort:\n"); - foreach my $k (@keys) { - $logger->debug("$k => " . $list->get_sortdata($k)->[0] . "\n"); - } - - $logger->trace("Sorting with scheme\n-------------------\n" . Data::Dump::pp($sortscheme) . "\n-------------------\n"); - - # Set up locale. Order of priority is: - # 1. locale value passed to Unicode::Collate::Locale->new() (Unicode::Collate sorts only) - # 2. Biber sortlocale option - # 3. LC_COLLATE env variable - # 4. LANG env variable - # 5. LC_ALL env variable - # 6. Built-in defaults - - my $thislocale = Biber::Config->getoption('sortlocale'); - - if ( Biber::Config->getoption('fastsort') ) { - use locale; - $logger->info("Sorting list '$llabel' keys"); - $logger->debug("Sorting with fastsort (locale $thislocale)"); - unless (setlocale(LC_ALL, $thislocale)) { - $logger->warn("Unavailable locale $thislocale"); - $self->{warnings}++; - } - - # Construct a multi-field Schwartzian Transform with the right number of - # extractions into a string representing an array ref as we musn't eval this yet - my $num_sorts = 0; - my $data_extractor = '['; - my $sorter; - my $sort_extractor; - # Global lowercase setting - my $glc = Biber::Config->getoption('sortcase') ? '' : 'lc '; - - foreach my $sortset (@{$sortscheme}) { - $data_extractor .= '$list->get_sortdata($_)->[1][' . $num_sorts . '],'; - $sorter .= ' || ' if $num_sorts; # don't add separator before first field - my $lc = $glc; # Casing defaults to global default ... - my $sc = $sortset->[0]{sortcase}; - # but is overriden by field setting if it exists - if (defined($sc) and $sc != Biber::Config->getoption('sortcase')) { - unless ($sc) { - $lc = 'lc '; - } - else { - $lc = ''; - } - } - - my $sd = $sortset->[0]{sort_direction}; - if (defined($sd) and $sd eq 'descending') { - # descending field - $sorter .= $lc - . '$b->[' - . $num_sorts - . '] cmp ' - . $lc - . '$a->[' - . $num_sorts - . ']'; - } - else { - # ascending field - $sorter .= $lc - . '$a->[' - . $num_sorts - . '] cmp ' - . $lc - . '$b->[' - . $num_sorts - . ']'; - } - $num_sorts++; - } - $data_extractor .= '$_]'; - # Handily, $num_sorts is now one larger than the number of fields which is the - # correct index for the actual data in the sort array - $sort_extractor = '$_->[' . $num_sorts . ']'; - $logger->trace("Sorting structure is: $sorter"); - - # Schwartzian transform multi-field sort - @keys = map { eval $sort_extractor } - sort { eval $sorter } - map { eval $data_extractor } @keys; - } - else { - require Unicode::Collate::Locale; - my $opts = Biber::Config->getoption('collate_options'); - my $collopts; - unless (ref($opts) eq "HASH") { # opts for this can come in a string from cmd line - $collopts = eval "{ $opts }" or $logger->logcarp("Incorrect collate_options: $@"); - } - else { # options from config file as hash ref - $collopts = $opts; - } - - # UCA level 2 if case insensitive sorting is requested - unless (Biber::Config->getoption('sortcase')) { - $collopts->{level} = 2; - } - - # Add upper_before_lower option - $collopts->{upper_before_lower} = Biber::Config->getoption('sortupper'); - - # Add tailoring locale for Unicode::Collate - if ($thislocale and not $collopts->{locale}) { - $collopts->{locale} = $thislocale; - if ($collopts->{table}) { - my $t = delete $collopts->{table}; - $logger->info("Ignoring collation table '$t' as locale is set ($thislocale)"); - } - } - - # Remove locale from options as we need this to make the object - my $coll_locale = delete $collopts->{locale}; - # Now create the collator object - my $Collator = Unicode::Collate::Locale->new( locale => $coll_locale ) - or $logger->logcarp("Problem with Unicode::Collate options: $@"); - - # Tailor the collation object and report differences from defaults for locale - # Have to do this in ->change method a ->new can croak with conflicting tailoring - # for locales which enforce certain tailorings - my %coll_changed = $Collator->change( %{$collopts} ); - while (my ($k, $v) = each %coll_changed) { - # If we changing something that has no override tailoring in the locale, it - # is undef in this hash and we don't care about such things - next unless defined($coll_changed{$k}); - if ($coll_changed{$k} ne $collopts->{$k}) { - $logger->warn("Overriding locale '$coll_locale' default tailoring '$k = $v' with '$k = " . $collopts->{$k} . "'"); - } - } - - my $UCAversion = $Collator->version(); - $logger->info("Sorting list '$llabel' keys"); - $logger->debug("Sorting with Unicode::Collate (" . stringify_hash($collopts) . ", UCA version: $UCAversion)"); - - # Log if U::C::L currently has no tailoring for used locale - if ($Collator->getlocale eq 'default') { - $logger->info("No sort tailoring available for locale '$thislocale'"); - } - - # Construct a multi-field Schwartzian Transform with the right number of - # extractions into a string representing an array ref as we musn't eval this yet - my $num_sorts = 0; - my $data_extractor = '['; - my $sorter; - my $sort_extractor; - foreach my $sortset (@{$sortscheme}) { - my $fc = ''; - my @fc; - # If the case or upper option on a field is not the global default - # set it locally on the $Collator by constructing a change() method call - my $sc = $sortset->[0]{sortcase}; - if (defined($sc) and $sc != Biber::Config->getoption('sortcase')) { - push @fc, $sc ? 'level => 4' : 'level => 2'; - } - my $su = $sortset->[0]{sortupper}; - if (defined($su) and $su != Biber::Config->getoption('sortupper')) { - push @fc, $su ? 'upper_before_lower => 1' : 'upper_before_lower => 0'; - } - if (@fc) { - # This field has custom collation options - $fc = '->change(' . join(',', @fc) . ')'; - } - else { - # Reset collation options to global defaults if there are no field options - # We have to do this as ->change modifies the Collation object - $fc = '->change(level => ' - . $collopts->{level} - . ' ,upper_before_lower => ' - . $collopts->{upper_before_lower} - . ')'; - } - - $data_extractor .= '$list->get_sortdata($_)->[1][' . $num_sorts . '],'; - $sorter .= ' || ' if $num_sorts; # don't add separator before first field - - my $sd = $sortset->[0]{sort_direction}; - if (defined($sd) and $sd eq 'descending') { - # descending field - $sorter .= '$Collator' - . $fc - . '->cmp($b->[' - . $num_sorts - . '],$a->[' - . $num_sorts - . '])'; - } - else { - # ascending field - $sorter .= '$Collator' - . $fc - . '->cmp($a->[' - . $num_sorts - . '],$b->[' - . $num_sorts - . '])'; - } - $num_sorts++; - } - $data_extractor .= '$_]'; - # Handily, $num_sorts is now one larger than the number of fields which is the - # correct index for the actual data in the sort array - $sort_extractor = '$_->[' . $num_sorts . ']'; - $logger->trace("Sorting structure is: $sorter"); - - # Schwartzian transform multi-field sort - @keys = map { eval $sort_extractor } - sort { eval $sorter } - map { eval $data_extractor } @keys; - } - - $logger->debug("Keys after sort:\n"); - foreach my $k (@keys) { - $logger->debug("$k => " . $list->get_sortdata($k)->[0] . "\n"); - } - - $list->set_keys([ @keys ]); - - return; -} - -=head2 prepare - - Do the main work. - Process and sort all entries before writing the bbl output. - -=cut - -sub prepare { - my $self = shift; - $self->process_setup; # Place to put global pre-processing things - foreach my $section (@{$self->sections->get_sections}) { - # shortcut - skip sections that don't have any keys - next unless $section->get_citekeys or $section->is_allkeys; - my $secnum = $section->number; - - $logger->info("Processing bib section $secnum"); - - $section->reset_sort_cache; # Reset the the sorting cache - Biber::Config->_init; # (re)initialise Config object - $self->set_current_section($secnum); # Set the section number we are working on - $self->fetch_data; # Fetch cited key and dependent data from sources - $self->instantiate_dynamic; # Instantiate any dynamic entries (sets, related) - $self->process_crossrefs; # Process crossrefs/sets - $self->validate_structure; # Check bib structure - $self->process_entries; # Main entry processing loop - $self->process_lists; # process the output lists (sorting and filtering) - $self->create_output_section; # Generate and push the section output into the - # output object ready for writing - } - $self->create_output_misc; # Generate and push the final misc bits of output - # into the output object ready for writing - return; -} - -=head2 fetch_data - - Fetch citekey and dependents data from section datasources - Expects to find datasource packages named: - - Biber::Input::<type>::<datatype> - - and one defined subroutine called: - - Biber::Input::<type>::<datatype>::extract_entries - - which takes args: - - 1: Biber object - 2: Datasource name - 3: Reference to an array of cite keys to look for - - and returns an array of the cite keys it didn't find in the datasource - -=cut - -sub fetch_data { - my $self = shift; - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - # Only looking for static keys, dynamic key entries are not in any datasource ... - my @citekeys = $section->get_static_citekeys; - no strict 'refs'; # symbolic references below ... - - # Clear all T::B macro definitions between sections - # T::B never clears these - $logger->debug('Clearing Text::BibTeX macros definitions'); - Text::BibTeX::delete_all_macros(); - - # (Re-)define the old BibTeX month macros to what biblatex wants unless user stops this - unless (Biber::Config->getoption('nostdmacros')) { - my $mi = 1; - foreach my $mon ('jan','feb','mar','apr','may','jun','jul','aug','sep','oct','nov','dec') { - Text::BibTeX::add_macro_text($mon, $mi++); - } - } - - # First we look for the directly cited keys in each datasource - my @remaining_keys = @citekeys; - $logger->debug('Looking for directly cited keys: ' . join(', ', @remaining_keys)); - foreach my $datasource (@{$section->get_datasources}) { - # shortcut if we have found all the keys now - last unless (@remaining_keys or $section->is_allkeys); - my $type = $datasource->{type}; - my $name = $datasource->{name}; - my $datatype = $datasource->{datatype}; - my $package = 'Biber::Input::' . $type . '::' . $datatype; - eval "require $package" or - $logger->logdie("Error loading data source package '$package': $@"); - $logger->info("Processing $datatype format $type '$name' for section $secnum"); - @remaining_keys = &{"${package}::extract_entries"}($self, $name, \@remaining_keys); - } - - # error reporting - $logger->debug("Directly cited keys not found for section '$secnum': " . join(',', @remaining_keys)); - foreach my $citekey (@remaining_keys) { - $logger->warn("I didn't find a database entry for '$citekey' (section $secnum)"); - $self->{warnings}++; - $section->del_citekey($citekey); - $section->add_undef_citekey($citekey); - } - - $logger->debug('Building dependents for keys: ' . join(',', $section->get_citekeys)); - # dependent key list generation - my @dependent_keys = (); - my $dep_map = {}; # a map of dependent keys to entry keys in case we need to delete - foreach my $citekey ($section->get_citekeys) { - # Dynamic sets don't exist yet but their members do - if (my @dmems = $section->get_dynamic_set($citekey)) { - # skip looking for dependent if it's already been directly cited - foreach my $dm (@dmems) { - unless ($section->bibentry($dm)) { - push @dependent_keys, $dm; - $dep_map->{$dm} = $citekey; - } - } - $logger->debug("Dynamic set entry '$citekey' has members: " . join(', ', @dmems)); - } - else { - # This must exist for all but dynamic sets - my $be = $section->bibentry($citekey); - # crossrefs/xrefs - my $refkey; - if ($refkey = $be->get_field('xref') or - $refkey = $be->get_field('crossref')) { - # skip looking for dependent if it's already been directly cited - push @dependent_keys, $refkey unless $section->bibentry($refkey); - $logger->debug("Entry '$citekey' has cross/xref '$refkey'"); - $dep_map->{$refkey} = $citekey; - } - # static sets - if ($be->get_field('entrytype') eq 'set') { - my @smems = split /\s*,\s*/, $be->get_field('entryset'); - # skip looking for dependent if it's already been directly cited - foreach my $sm (@smems) { - unless ($section->bibentry($sm)) { - push @dependent_keys, $sm; - $dep_map->{$sm} = $citekey; - } - } - $logger->debug("Static set entry '$citekey' has members: " . join(', ', @smems)); - } - # Related entries - if (my $relkeys = $be->get_field('related')) { - my @rmems = split /\s*,\s*/, $relkeys; - # skip looking for dependent if it's already been directly cited - foreach my $rm (@rmems) { - unless ($section->bibentry($rm)) { - push @dependent_keys, $rm; - $dep_map->{$rm} = $citekey; - } - } - $logger->debug("Entry '$citekey' has related entries: " . join(', ', @rmems)); - } - } - } - if (@dependent_keys) { - # Now look for the dependents of the directly cited keys - @remaining_keys = @dependent_keys; - $logger->debug('Looking for dependent keys: ' . join(', ', @remaining_keys)); - - # No need to go back to the datasource if allkeys, just see if the keys - # are in section - if ($section->is_allkeys) { - my @missing; - foreach my $dk (@dependent_keys) { - push @missing, $dk unless first {$_ eq $dk} $section->get_citekeys; - } - @remaining_keys = @missing; - } - else { - foreach my $datasource (@{$section->get_datasources}) { - # shortcut if we have found all the keys now - last unless (@remaining_keys or $section->is_allkeys); - my $type = $datasource->{type}; - my $name = $datasource->{name}; - my $datatype = $datasource->{datatype}; - my $package = 'Biber::Input::' . $type . '::' . $datatype; - eval "require $package" or - $logger->logdie("Error loading data source package '$package': $@"); - @remaining_keys = &{"${package}::extract_entries"}($self, $name, \@remaining_keys); - } - } - - # error reporting - $logger->debug("Dependent keys not found for section '$secnum': " . join(',', @remaining_keys)); - foreach my $citekey (@remaining_keys) { - $logger->debug("Removing missing dependent key '$citekey' from entries"); - $self->remove_undef_dependent($dep_map, $citekey); - } - } - - $logger->debug("Citekeys for section '$secnum' after fetching data: " . join(', ', $section->get_citekeys)); - - # Reset any cache of bibtex data - $Biber::Input::file::bibtex::cache->{data} = undef; - return; -} - -=head2 remove_undef_dependent - - Remove undefined dependent keys from an entries using a map of - depedent keys to entries - -=cut - -sub remove_undef_dependent { - my $self = shift; - my $dep_map = shift; - my $missing_key = shift; - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - my $entry_key = $dep_map->{$missing_key}; - - # remove from any dynamic keys - if (my @dmems = $section->get_dynamic_set($entry_key)) { - $section->set_dynamic_set($entry_key, grep {$_ ne $missing_key} @dmems); - $logger->warn("I didn't find a database entry for dynamic set member '$missing_key' - ignoring (section $secnum)"); - $self->{warnings}++; - } - else { - my $be = $section->bibentry($entry_key); - # remove any xrefs - if ($be->get_field('xref') and ($be->get_field('xref') eq $missing_key)) { - $be->del_field('xref'); - $logger->warn("I didn't find a database entry for xref '$missing_key' in entry '$entry_key' - ignoring (section $secnum)"); - $self->{warnings}++; - } - - # remove any crossrefs - if ($be->get_field('crossref') and ($be->get_field('crossref') eq $missing_key)) { - $be->del_field('crossref'); - $logger->warn("I didn't find a database entry for crossref '$missing_key' in entry '$entry_key' - ignoring (section $secnum)"); - $self->{warnings}++; - } - - # remove static sets - if ($be->get_field('entrytype') eq 'set') { - my @smems = split /\s*,\s*/, $be->get_field('entryset'); - $be->set_datafield('entryset', join(',', grep {$_ ne $missing_key} @smems)); - $logger->warn("I didn't find a database entry for static set member '$missing_key' in entry '$entry_key' - ignoring (section $secnum)"); - $self->{warnings}++; - } - - # remove related entries - if (my $relkeys = $be->get_field('related')) { - my @rmems = split /\s*,\s*/, $relkeys; - $be->set_datafield('related', join(',', grep {$_ ne $missing_key} @rmems)); - # If no more related entries, remove the other related fields - unless ($be->get_field('related')) { - $be->del_field('relatedtype'); - $be->del_field('relatedstring'); - } - $logger->warn("I didn't find a database entry for related entry '$missing_key' in entry '$entry_key' - ignoring (section $secnum)"); - $self->{warnings}++; - } - } - return; -} - -=head2 create_output_section - - Create the output from the sections data and push it into the - output object. You can subclass Biber and - override this method to output things other than .bbl - -=cut - -sub create_output_section { - my $self = shift; - my $output_obj = $self->get_output_obj; - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - - # We rely on the order of this array for the order of the .bbl - my @citekeys = $section->get_citekeys; - foreach my $k (@citekeys) { - # Regular entry - my $be = $section->bibentry($k) or $logger->logdie("Cannot find entry with key '$k' to output"); - $output_obj->set_output_entry($be, $section, Biber::Config->get_structure); - } - - # Make sure the output object knows about the output section - $output_obj->set_output_section($secnum, $section); - - # undef citekeys are global - my @undef_citekeys = $section->get_undef_citekeys; - # Missing citekeys - foreach my $k (@undef_citekeys) { - $output_obj->set_output_undefkey($k, $section); - } - - return; -} - -=head2 create_output_misc - - Create the output for misc bits and pieces like preamble and closing - macro call and add to output object. You can subclass Biber and - override this method to output things other than .bbl - -=cut - -sub create_output_misc { - my $self = shift; - my $output_obj = $self->get_output_obj; - - if (my $pa = $self->{preamble}) { - $pa = join("%\n", @$pa); - # Decode UTF-8 -> LaTeX macros if asked to - if (Biber::Config->getoption('bblsafechars')) { - require Biber::LaTeX::Recode; - $pa = Biber::LaTeX::Recode::latex_encode($pa, - scheme => Biber::Config->getoption('bblsafecharsset')); - } - $output_obj->add_output_head("\\preamble{%\n$pa%\n}\n\n"); - } - - $output_obj->add_output_tail("\\endinput\n\n"); - return; -} - -=head2 _parse_sort - - Convenience sub to parse a .bcf sorting section and return nice - sorting object - -=cut - -sub _parse_sort { - my $root_obj = shift; - my $sorting; - - foreach my $sort (sort {$a->{order} <=> $b->{order}} @{$root_obj->{sort}}) { - my $sortingitems; - - # Generate sorting pass structures - foreach my $sortitem (sort {$a->{order} <=> $b->{order}} @{$sort->{sortitem}}) { - my $sortitemattributes = {}; - if (defined($sortitem->{substring_side})) { # Found sorting substring side attribute - $sortitemattributes->{substring_side} = $sortitem->{substring_side}; - } - if (defined($sortitem->{substring_width})) { # Found sorting substring length attribute - $sortitemattributes->{substring_width} = $sortitem->{substring_width}; - } - if (defined($sortitem->{pad_width})) { # Found sorting pad length attribute - $sortitemattributes->{pad_width} = $sortitem->{pad_width}; - } - if (defined($sortitem->{pad_char})) { # Found sorting pad char attribute - $sortitemattributes->{pad_char} = $sortitem->{pad_char}; - } - if (defined($sortitem->{pad_side})) { # Found sorting pad side attribute - $sortitemattributes->{pad_side} = $sortitem->{pad_side}; - } - push @{$sortingitems}, {$sortitem->{content} => $sortitemattributes}; - } - - # Only push a sortitem if defined. If the item has a conditional "pass" - # attribute, it may be ommitted in which case we don't want an empty array ref - # pushing - # Also, we only push the sort attributes if there are any sortitems otherwise - # we end up with a blank sort - my $sopts; - $sopts->{final} = $sort->{final} if defined($sort->{final}); - $sopts->{sort_direction} = $sort->{sort_direction} if defined($sort->{sort_direction}); - $sopts->{sortcase} = $sort->{sortcase} if defined($sort->{sortcase}); - $sopts->{sortupper} = $sort->{sortupper} if defined($sort->{sortupper}); - if (defined($sortingitems)) { - unshift @{$sortingitems}, $sopts; - push @{$sorting}, $sortingitems; - } - } - return $sorting; -} - -=head2 _filedump and _stringdump - - Dump the biber object with Data::Dump for debugging - -=cut - -sub _filedump { - my ($self, $file) = @_; - my $fh = IO::File->new($file, '>') or croak "Can't open file $file for writing"; - print $fh Data::Dump::pp($self); - close $fh; - return -} - -sub _stringdump { - my $self = shift ; - return Data::Dump::pp($self); -} - -=head1 AUTHORS - -François Charette, C<< <firmicus at gmx.net> >> -Philip Kime C<< <philip at kime.org.uk> >> - -=head1 BUGS - -Please report any bugs or feature requests on our sourceforge tracker at -L<https://sourceforge.net/tracker2/?func=browse&group_id=228270>. - -=head1 COPYRIGHT & LICENSE - -Copyright 2009-2011 François Charette and Philip Kime, all rights reserved. - -This module is free software. You can redistribute it and/or -modify it under the terms of the Artistic License 2.0. - -This program is distributed in the hope that it will be useful, -but without any warranty; without even the implied warranty of -merchantability or fitness for a particular purpose. - -=cut - -1; - -# vim: set tabstop=2 shiftwidth=2 expandtab: diff --git a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Config.pm b/Master/texmf-dist/source/bibtex/biber/lib/Biber/Config.pm deleted file mode 100644 index 297e1f68787..00000000000 --- a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Config.pm +++ /dev/null @@ -1,981 +0,0 @@ -package Biber::Config; -#use feature 'unicode_strings'; -use Biber::Constants; -use IPC::Cmd qw( can_run run ); -use Cwd qw( abs_path ); -use Config::General qw( ParseConfig ); -use Data::Dump; -use Carp; -use List::AllUtils qw(first); -use Log::Log4perl qw( :no_extra_logdie_message ); -my $logger = Log::Log4perl::get_logger('main'); - -=encoding utf-8 - - -=head1 NAME - -Biber::Config - Configuration items which need to be saved across the - lifetime of a Biber object - - This class contains a static object and static methods to access - configuration and state data. There are several classes of data in here - which have separate accessors: - - * Biber options - * Biblatex options - * State information used by Biber as it processes entries - * displaymode date - -=cut - - -# Static (class) data -our $CONFIG; -$CONFIG->{state}{crossrefkeys} = {}; -$CONFIG->{state}{seennamehash} = {}; -$CONFIG->{state}{keycase} = {}; - -# namehashcount holds a hash of namehashes and -# occurences of unique names that generate the hash. For example: -# {AA => { Adams_A => 1, Allport_A => 2 }} -$CONFIG->{state}{namehashcount} = {}; - -# uniquenamecount holds a hash of lastnames and lastname/initials which point to a list -# of name(hashes) which contain them -$CONFIG->{state}{uniquenamecount} = {}; -# Counter for tracking name/year combinations for extrayear -$CONFIG->{state}{seen_nameyear_extrayear} = {}; -# Counter for the actual extrayear value -$CONFIG->{state}{seen_extrayear} = {}; -# Counter for tracking name/year combinations for extraalpha -$CONFIG->{state}{seen_nameyear_extraalpha} = {}; -# Counter for the actual extraalpha value -$CONFIG->{state}{seen_extraalpha} = {}; -$CONFIG->{state}{seenkeys} = {}; - -# Location of the control file -$CONFIG->{state}{control_file_location} = ''; - -# Data files per section being used by biber -$CONFIG->{state}{datafiles} = []; - -=head2 _init - - Reset internal hashes to defaults. This is needed for tests when - prepare() is used more than once - -=cut - -sub _init { - $CONFIG->{options}{biblatex}{PER_ENTRY} = {}; - $CONFIG->{state}{control_file_location} = ''; - $CONFIG->{state}{seennamehash} = {}; - $CONFIG->{state}{crossrefkeys} = {}; - $CONFIG->{state}{namehashcount} = {}; - $CONFIG->{state}{uniquenamecount} = {}; - $CONFIG->{state}{seen_nameyear_extrayear} = {}; - $CONFIG->{state}{seen_extrayear} = {}; - $CONFIG->{state}{seen_nameyear_extraalpha} = {}; - $CONFIG->{state}{seen_extraalpha} = {}; - $CONFIG->{state}{seenkeys} = {}; - $CONFIG->{state}{keycase} = {}; - $CONFIG->{state}{datafiles} = []; - - return; -} - -=head2 _initopts - - Initialise default options, optionally with config file as argument - -=cut - -sub _initopts { - shift; # class method so don't care about class name - my $conffile = shift; - my $noconf = shift; - my %LOCALCONF = (); - - # For testing, need to be able to force ignore of conf file in case user - # already has one which interferes with test settings. - unless ($noconf) { - # if a config file was given as cmd-line arg, it overrides all other - # config file locations - unless ( defined $conffile and -f $conffile ) { - $conffile = config_file(); - } - - if (defined $conffile) { - %LOCALCONF = ParseConfig(-LowerCaseNames => 1, - -MergeDuplicateBlocks => 1, - -AllowMultiOptions => 1, - -ConfigFile => $conffile, - -UTF8 => 1) or - $logger->logcarp("Failure to read config file " . $conffile . "\n $@"); - } - } - - # Config file overrides defaults for biber - my %BIBER_CONFIG = (%CONFIG_DEFAULT_BIBER, %LOCALCONF); - - # Set options internally from config for biber options - foreach (keys %BIBER_CONFIG) { - Biber::Config->setoption($_, $BIBER_CONFIG{$_}); - } - - # Set options internally from config for biblatex options - foreach (keys %CONFIG_DEFAULT_BIBLATEX) { - Biber::Config->setblxoption($_, $CONFIG_DEFAULT_BIBLATEX{$_}); - } - - return; -} - -=head2 config_file - -Returns the full path of the B<Biber> configuration file. -If returns the first file found among: - -=over 4 - -=item * C<biber.conf> in the current directory - -=item * C<$HOME/.biber.conf> - -=item * C<$ENV{XDG_CONFIG_HOME}/biber/biber.conf> - -=item * C<$HOME/Library/biber/biber.conf> (Mac OSX only) - -=item * C<$ENV{APPDATA}/biber.conf> (Windows only) - -=item * the output of C<kpsewhich biber.conf> (if available on the system). - -=back - -If no file is found, it returns C<undef>. - -=cut - -sub config_file { - my $biberconf; - if ( -f $BIBER_CONF_NAME ) { - $biberconf = abs_path($BIBER_CONF_NAME); - } elsif ( -f File::Spec->catfile($ENV{HOME}, ".$BIBER_CONF_NAME" ) ) { - $biberconf = File::Spec->catfile($ENV{HOME}, ".$BIBER_CONF_NAME" ); - } elsif ( defined $ENV{XDG_CONFIG_HOME} and - -f File::Spec->catfile($ENV{XDG_CONFIG_HOME}, "biber", $BIBER_CONF_NAME) ) { - $biberconf = File::Spec->catfile($ENV{XDG_CONFIG_HOME}, "biber", $BIBER_CONF_NAME); - } elsif ( $^O =~ /(?:Mac|darwin)/ and - -f File::Spec->catfile($ENV{HOME}, "Library", "biber", $BIBER_CONF_NAME) ) { - $biberconf = File::Spec->catfile($ENV{HOME}, "Library", "biber", $BIBER_CONF_NAME); - } elsif ( $^O =~ /Win/ and - defined $ENV{APPDATA} and - -f File::Spec->catfile($ENV{APPDATA}, "biber", $BIBER_CONF_NAME) ) { - $biberconf = File::Spec->catfile($ENV{APPDATA}, "biber", $BIBER_CONF_NAME); - } elsif ( can_run('kpsewhich') ) { - scalar run( command => [ 'kpsewhich', $BIBER_CONF_NAME ], - verbose => 0, - buffer => \$biberconf ); - } else { - $biberconf = undef; - } - return $biberconf; -} - -############################## -# Biber options static methods -############################## - -=head2 postprocess_biber_opts - - Place to postprocess biber options when they have been - gathered from all the possible places that set them - -=cut - -sub postprocess_biber_opts { - shift; # class method so don't care about class name - - # Turn sortcase and sortupper into booleans if they are not already - # They are not booleans on the command-line/config file so that they - # mirror biblatex option syntax for users - if (exists($CONFIG->{options}{biber}{sortcase})) { - if ($CONFIG->{options}{biber}{sortcase} eq 'true') { - $CONFIG->{options}{biber}{sortcase} = 1; - } elsif ($CONFIG->{options}{biber}{sortcase} eq 'false') { - $CONFIG->{options}{biber}{sortcase} = 0; - } - unless ($CONFIG->{options}{biber}{sortcase} eq '1' or - $CONFIG->{options}{biber}{sortcase} eq '0') { - $logger->logdie("Invalid value for option 'sortcase'"); - } - } - - if (exists($CONFIG->{options}{biber}{sortupper})) { - if ($CONFIG->{options}{biber}{sortupper} eq 'true') { - $CONFIG->{options}{biber}{sortupper} = 1; - } elsif ($CONFIG->{options}{biber}{sortupper} eq 'false') { - $CONFIG->{options}{biber}{sortupper} = 0; - } - unless ($CONFIG->{options}{biber}{sortupper} eq '1' or - $CONFIG->{options}{biber}{sortupper} eq '0') { - $logger->logdie("Invalid value for option 'sortupper'"); - } - } -} - -=head2 set_structure - - Sets the structure information object - -=cut - -sub set_structure { - shift; - my $obj = shift; - $CONFIG->{structure} = $obj; - return; -} - -=head2 get_structure - - Gets the structure information object - -=cut - -sub get_structure { - shift; - return $CONFIG->{structure}; -} - -=head2 set_ctrlfile_path - - Stores the path to the control file - -=cut - -sub set_ctrlfile_path { - shift; - $CONFIG->{control_file_location} = shift; - return; -} - -=head2 get_ctrlfile_path - - Retrieved the path to the control file - -=cut - -sub get_ctrlfile_path { - shift; - return $CONFIG->{control_file_location}; -} - -=head2 setoption - - Store a Biber config option - -=cut - -sub setoption { - shift; # class method so don't care about class name - my ($opt, $val) = @_; - $CONFIG->{options}{biber}{$opt} = $val; - return; -} - -=head2 getoption - - Get a Biber option - -=cut - -sub getoption { - shift; # class method so don't care about class name - my $opt = shift; - return $CONFIG->{options}{biber}{$opt}; -} - -=head2 setcmdlineoption - - Store a Biber command-line option - -=cut - -sub setcmdlineoption { - shift; # class method so don't care about class name - my ($opt, $val) = @_; - # Command line options are also options ... - $CONFIG->{options}{biber}{$opt} = $CONFIG->{cmdlineoptions}{$opt} = $val; - return; -} - -=head2 getcmdlineoption - - Get a Biber command lineoption - -=cut - -sub getcmdlineoption { - shift; # class method so don't care about class name - my $opt = shift; - return $CONFIG->{cmdlineoptions}{$opt}; -} - -################################# -# BibLaTeX options static methods -################################# - - -=head2 setblxoption - - Set a biblatex option on the global or per entry-type scope - -=cut - -sub setblxoption { - shift; # class method so don't care about class name - my ($opt, $val, $scope, $scopeval) = @_; - if (not defined($scope)) { # global is the default - if ($CONFIG_SCOPE_BIBLATEX{$opt}->{GLOBAL}) { - $CONFIG->{options}{biblatex}{GLOBAL}{$opt} = $val; - } - } - else { # Per-type/entry options need to specify type/entry too - $scopeval = lc($scopeval) if $scope eq 'PER_ENTRY'; - if ($CONFIG_SCOPE_BIBLATEX{$opt}->{$scope}) { - $CONFIG->{options}{biblatex}{$scope}{$scopeval}{$opt} = $val; - } - } - return; -} - -=head2 getblxoption - - Get a biblatex option from the global or per entry-type scope - - getblxoption('option', ['entrytype'], ['citekey']) - - Returns the value of option. In order of decreasing preference, returns: - 1. Biblatex option defined for entry - 2. Biblatex option defined for entry type - 3. Biblatex option defined globally - -=cut - -sub getblxoption { - shift; # class method so don't care about class name - my ($opt, $entrytype, $citekey) = @_; - if ( defined($citekey) and - $CONFIG_SCOPE_BIBLATEX{$opt}->{PER_ENTRY} and - defined $CONFIG->{options}{biblatex}{PER_ENTRY}{lc($citekey)} and - defined $CONFIG->{options}{biblatex}{PER_ENTRY}{lc($citekey)}{$opt}) { - return $CONFIG->{options}{biblatex}{PER_ENTRY}{lc($citekey)}{$opt}; - } - elsif (defined($entrytype) and - $CONFIG_SCOPE_BIBLATEX{$opt}->{PER_TYPE} and - defined $CONFIG->{options}{biblatex}{PER_TYPE}{$entrytype} and - defined $CONFIG->{options}{biblatex}{PER_TYPE}{$entrytype}{$opt}) { - return $CONFIG->{options}{biblatex}{PER_TYPE}{$entrytype}{$opt}; - } - elsif ($CONFIG_SCOPE_BIBLATEX{$opt}->{GLOBAL}) { - return $CONFIG->{options}{biblatex}{GLOBAL}{$opt}; - } -} - - -############################## -# Biber state static methods -############################## - -#============================ -# seenkey -#============================ - -=head2 get_seenkey - - Get the count of a key - - Biber::Config->get_seenkey($hash); - -=cut - -sub get_seenkey { - shift; # class method so don't care about class name - my $key = shift; - my $section = shift; # If passed, return count for just this section - if (defined($section)) { - return $CONFIG->{state}{seenkeys}{$section}{lc($key)}; - } - else { - my $count; - foreach my $section (keys %{$CONFIG->{state}{seenkeys}}) { - $count += $CONFIG->{state}{seenkeys}{$section}{lc($key)}; - } - return $count; - } -} - -=head2 get_keycase - - Return a key in the original case it was cited with so we - can return mismatched cite key errors - - Biber::Config->get_keycase($key); - -=cut - -sub get_keycase { - shift; # class method so don't care about class name - my $key = shift; - return $CONFIG->{state}{keycase}{lc($key)}; -} - -=head2 incr_seenkey - - Increment the seen count of a key - - Biber::Config->incr_seenkey($ay); - -=cut - -sub incr_seenkey { - shift; # class method so don't care about class name - my $key = shift; - my $section = shift; - $CONFIG->{state}{keycase}{lc($key)} = $key; - $CONFIG->{state}{seenkeys}{$section}{lc($key)}++; - return; -} - - -=head2 reset_seen_extra - - Reset the counters for extrayear and extraalpha - - Biber::Config->reset_extra; - -=cut - -sub reset_seen_extra { - shift; # class method so don't care about class name - my $ay = shift; - $CONFIG->{state}{seen_extrayear}= {}; - $CONFIG->{state}{seen_extraalpha}= {}; - return; -} - -#============================ -# seen_extrayear -#============================ - -=head2 incr_seen_extrayear - - Increment and return the counter for extrayear - - Biber::Config->incr_seen_extrayear($ay); - -=cut - -sub incr_seen_extrayear { - shift; # class method so don't care about class name - my $ay = shift; - return ++$CONFIG->{state}{seen_extrayear}{$ay}; -} - - -#============================ -# seen_nameyear_extrayear -#============================ - -=head2 get_seen_nameyear_extrayear - - Get the count of an labelname/labelyear combination for tracking - extrayear. It uses labelyear plus name as we need to disambiguate - entries with different labelyear (like differentiating 1984--1986 from - just 1984) - - Biber::Config->get_seen_nameyear_extrayear($ny); - -=cut - -sub get_seen_nameyear_extrayear { - shift; # class method so don't care about class name - my $ny = shift; - return $CONFIG->{state}{seen_nameyear_extrayear}{$ny}; -} - -=head2 incr_seen_nameyear_extrayear - - Increment the count of an labelname/labelyear combination for extrayear - - Biber::Config->incr_seen_nameyear_extrayear($ns, $ys); - - We pass in the name and year strings seperately as we have to - be careful and only increment this counter beyond 1 if there is - both a name and year component. Otherwise, extrayear gets defined for all - entries with no name but the same year etc. - -=cut - -sub incr_seen_nameyear_extrayear { - shift; # class method so don't care about class name - my ($ns, $ys) = @_; - $tmp = "$ns,$ys"; - # We can always increment this to 1 - unless ($CONFIG->{state}{seen_nameyear_extrayear}{$tmp}) { - $CONFIG->{state}{seen_nameyear_extrayear}{$tmp}++; - } - # But beyond that only if we have a labelname and labelyear in the entry since - # this counter is used to create extrayear which doesn't mean anything for - # entries with only one of these. - else { - if ($ns and $ys) { - $CONFIG->{state}{seen_nameyear_extrayear}{$tmp}++; - } - } - return; -} - -#============================ -# seen_extraalpha -#============================ - -=head2 incr_seen_extraalpha - - Increment and return the counter for extraalpha - - Biber::Config->incr_seen_extraalpha($ay); - -=cut - -sub incr_seen_extraalpha { - shift; # class method so don't care about class name - my $ay = shift; - return ++$CONFIG->{state}{seen_extraalpha}{$ay}; -} - - -#============================ -# seen_nameyear_extraalpha -#============================ - -=head2 get_seen_nameyear_extraalpha - - Get the count of an labelname/labelyear combination for tracking - extraalpha. It uses labelyear plus name as we need to disambiguate - entries with different labelyear (like differentiating 1984--1986 from - just 1984) - - Biber::Config->get_seen_nameyear_extraalpha($ny); - -=cut - -sub get_seen_nameyear_extraalpha { - shift; # class method so don't care about class name - my $ny = shift; - return $CONFIG->{state}{seen_nameyear_extraalpha}{$ny}; -} - -=head2 incr_seen_nameyear_extraalpha - - Increment the count of an labelname/labelyear combination for extraalpha - - Biber::Config->incr_seen_nameyear_extraalpha($ns, $ys); - - We pass in the name and year strings seperately as we have to - be careful and only increment this counter beyond 1 if there is - both a name and year component. Otherwise, extraalpha gets defined for all - entries with no name but the same year etc. - -=cut - -sub incr_seen_nameyear_extraalpha { - shift; # class method so don't care about class name - my ($ns, $ys) = @_; - $tmp = "$ns,$ys"; - # We can always increment this to 1 - unless ($CONFIG->{state}{seen_nameyear_extraalpha}{$tmp}) { - $CONFIG->{state}{seen_nameyear_extraalpha}{$tmp}++; - } - # But beyond that only if we have a labelname and labelyear in the entry since - # this counter is used to create extraalpha which doesn't mean anything for - # entries with only one of these. - else { - if ($ns and $ys) { - $CONFIG->{state}{seen_nameyear_extraalpha}{$tmp}++; - } - } - return; -} - -#============================ -# uniquenamecount -#============================ - -=head2 get_numofuniquenames - - Get the number of uniquenames entries for a name - - Biber::Config->get_numofuniquenames($name); - -=cut - -sub get_numofuniquenames { - shift; # class method so don't care about class name - my $name = shift; - return $#{$CONFIG->{state}{uniquenamecount}{$name}} + 1; -} - -=head2 add_uniquenamecount - - Add a hash to the list of name(hashes) which have the name part in it - - Biber::Config->add_uniquenamecount($name, $hash); - -=cut - -sub add_uniquenamecount { - shift; # class method so don't care about class name - my $namestring = shift; - my $hash = shift; - # name(hash) already recorded as containing namestring - if (first {$hash eq $_} @{$CONFIG->{state}{uniquenamecount}{$namestring}}) { - return; - } - # Record name(hash) as containing namestring - else { - push @{$CONFIG->{state}{uniquenamecount}{$namestring}}, $hash; - } - return; -} - - -=head2 _get_uniquename - - Get the uniquename hash of a lastname/hash combination - Mainly for use in tests - - Biber::Config->get_uniquename($name); - -=cut - -sub _get_uniquename { - shift; # class method so don't care about class name - my $name = shift; - my @list = sort @{$CONFIG->{state}{uniquenamecount}{$name}}; - return \@list; -} - - -#============================ -# namehashcount -#============================ - - -=head2 get_numofnamehashes - - Get the number of name hashes - - Biber::Config->get_numofnamehashes($hash); - -=cut - -sub get_numofnamehashes { - shift; # class method so don't care about class name - my $hash = shift; - return scalar keys %{$CONFIG->{state}{namehashcount}{$hash}}; -} - -=head2 namehashexists - - Check if there is an entry for a namehash - - Biber::Config->namehashexists($hash); - -=cut - -sub namehashexists { - shift; # class method so don't care about class name - my $hash = shift; - return exists($CONFIG->{state}{namehashcount}{$hash}) ? 1 : 0; -} - - -=head2 get_namehashcount - - Get the count of a name hash and name id - - Biber::Config->get_namehashcount($hash, $id); - -=cut - -sub get_namehashcount { - shift; # class method so don't care about class name - my ($hash, $id) = @_; - return $CONFIG->{state}{namehashcount}{$hash}{$id}; -} - -=head2 set_namehashcount - - Set the count of a name hash and name id - - Biber::Config->set_namehashcount($hash, $id, $num); - -=cut - -sub set_namehashcount { - shift; # class method so don't care about class name - my ($hash, $id, $num) = @_; - $CONFIG->{state}{namehashcount}{$hash}{$id} = $num; - return; -} - - -=head2 del_namehash - - Delete the count information for a name hash - - Biber::Config->del_namehashcount($hash); - -=cut - -sub del_namehash { - shift; # class method so don't care about class name - my $hash = shift; - if (exists($CONFIG->{state}{namehashcount}{$hash})) { - delete $CONFIG->{state}{namehashcount}{$hash}; - } - return; -} - -#============================ -# seennamehash -#============================ - - -=head2 get_seennamehash - - Get the count of a seen name hash - - Biber::Config->get_seennamehash($hash); - -=cut - -sub get_seennamehash { - shift; # class method so don't care about class name - my $hash = shift; - return $CONFIG->{state}{seennamehash}{$hash}; -} - - -=head2 incr_seennamehash - - Increment the count of a seen name hash - - Biber::Config->incr_seennamehash($hash); - -=cut - -sub incr_seennamehash { - shift; # class method so don't care about class name - my $hash = shift; - $CONFIG->{state}{seennamehash}{$hash}++; - return; -} - - -#============================ -# crossrefkeys -#============================ - - -=head2 get_crossrefkeys - - Return ref to array of keys which are crossref targets - - Biber::Config->get_crossrefkeys(); - -=cut - -sub get_crossrefkeys { - shift; # class method so don't care about class name - return [ keys %{$CONFIG->{state}{crossrefkeys}} ]; -} - -=head2 get_crossrefkey - - Return an integer representing the number of times a - crossref target key has been ref'ed - - Biber::Config->get_crossrefkey($key); - -=cut - -sub get_crossrefkey { - shift; # class method so don't care about class name - my $k = shift; - return $CONFIG->{state}{crossrefkeys}{lc($k)}; -} - -=head2 del_crossrefkey - - Remove a crossref target key from the crossrefkeys state - - Biber::Config->del_crossrefkey($key); - -=cut - -sub del_crossrefkey { - shift; # class method so don't care about class name - my $k = shift; - if (exists($CONFIG->{state}{crossrefkeys}{lc($k)})) { - delete $CONFIG->{state}{crossrefkeys}{lc($k)}; - } - return; -} - -=head2 incr_crossrefkey - - Increment the crossreferences count for a target crossref key - - Biber::Config->incr_crossrefkey($key); - -=cut - -sub incr_crossrefkey { - shift; # class method so don't care about class name - my $k = shift; - $CONFIG->{state}{crossrefkeys}{lc($k)}++; - return; -} - - -############################ -# Displaymode static methods -############################ - -=head2 set_displaymode - - Set the display mode for a field. - setdisplaymode(['entrytype'], ['field'], ['citekey'], $value) - - This sets the desired displaymode to use for some data in the bib. - Of course, this is entirey seperate semantically from the - displaymodes *defined* in the bib which just tell you what to return - for a particular displaymode request for some data. - -=cut - -sub set_displaymode { - shift; # class method so don't care about class name - my ($val, $entrytype, $fieldtype, $citekey) = @_; - if ($citekey) { - my $key = lc($citekey); - if ($fieldtype) { - $CONFIG->{displaymodes}{PER_FIELD}{$key}{$fieldtype} = $val; - } - else { - $CONFIG->{displaymodes}{PER_ENTRY}{$key} = $val; - } - } - elsif ($fieldtype) { - $CONFIG->{displaymodes}{PER_FIELDTYPE}{$fieldtype} = $val; - } - elsif ($entrytype) { - $CONFIG->{displaymodes}{PER_ENTRYTYPE}{$entrytype} = $val; - } - else { - $CONFIG->{displaymodes}{GLOBAL} = $val ; - } -} - -=head2 get_displaymode - - Get the display mode for a field. - getdisplaymode(['entrytype'], ['field'], ['citekey']) - - Returns the displaymode. In order of decreasing preference, returns: - 1. Mode defined for a specific field in a specific citekey - 2. Mode defined for a citekey - 3. Mode defined for a fieldtype (any citekey) - 4. Mode defined for an entrytype (any citekey) - 5. Mode defined globally (any citekey) - -=cut - -sub get_displaymode { - shift; # class method so don't care about class name - my ($entrytype, $fieldtype, $citekey) = @_; - my $dm; - if ($citekey) { - my $key = lc($citekey); - if ($fieldtype and - defined($CONFIG->{displaymodes}{PER_FIELD}) and - defined($CONFIG->{displaymodes}{PER_FIELD}{$key}) and - defined($CONFIG->{displaymodes}{PER_FIELD}{$key}{$fieldtype})) { - $dm = $CONFIG->{displaymodes}{PER_FIELD}{$key}{$fieldtype}; - } - elsif (defined($CONFIG->{displaymodes}{PER_ENTRY}) and - defined($CONFIG->{displaymodes}{PER_ENTRY}{$key})) { - $dm = $CONFIG->{displaymodes}{PER_ENTRY}{$key}; - } - } - elsif ($fieldtype and - defined($CONFIG->{displaymodes}{PER_FIELDTYPE}) and - defined($CONFIG->{displaymodes}{PER_FIELDTYPE}{$fieldtype})) { - $dm = $CONFIG->{displaymodes}{PER_FIELDTYPE}{$fieldtype}; - } - elsif ($entrytype and - defined($CONFIG->{displaymodes}{PER_ENTRYTYPE}) and - defined($CONFIG->{displaymodes}{PER_ENTRYTYPE}{$entrytype})) { - $dm = $CONFIG->{displaymodes}{PER_ENTRYTYPE}{$entrytype}; - } - $dm = $CONFIG->{displaymodes}{GLOBAL} unless $dm; # Global if nothing else; - $dm = $DISPLAYMODE_DEFAULT unless $dm; # fall back to this constant - if ( ref $dm eq 'ARRAY') { - return $dm; - } - else { - return $DISPLAYMODES{$dm}; - } -} - -=head2 dump - - Dump config information (for debugging) - -=cut - -sub dump { - shift; # class method so don't care about class name - dd($CONFIG); -} - -=head1 AUTHORS - -François Charette, C<< <firmicus at gmx.net> >> -Philip Kime C<< <philip at kime.org.uk> >> - -=head1 BUGS - -Please report any bugs or feature requests on our sourceforge tracker at -L<https://sourceforge.net/tracker2/?func=browse&group_id=228270>. - -=head1 COPYRIGHT & LICENSE - -Copyright 2009-2011 François Charette and Philip Kime, all rights reserved. - -This module is free software. You can redistribute it and/or -modify it under the terms of the Artistic License 2.0. - -This program is distributed in the hope that it will be useful, -but without any warranty; without even the implied warranty of -merchantability or fitness for a particular purpose. - -=cut - -1; - -# vim: set tabstop=2 shiftwidth=2 expandtab: diff --git a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Constants.pm b/Master/texmf-dist/source/bibtex/biber/lib/Biber/Constants.pm deleted file mode 100644 index aa4d4e26d8b..00000000000 --- a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Constants.pm +++ /dev/null @@ -1,1697 +0,0 @@ -package Biber::Constants; -#use feature 'unicode_strings'; -use strict; -use warnings; -use Encode::Alias; -use Readonly; - -use base 'Exporter'; - -our @EXPORT = qw{ - %CONFIG_DEFAULT_BIBER - %CONFIG_DEFAULT_BIBLATEX - %CONFIG_SCOPE_BIBLATEX - %NOSORT_TYPES - %STRUCTURE_DATATYPES - $BIBER_CONF_NAME - $BIBLATEX_VERSION - $BIBER_SORT_FINAL - $BIBER_SORT_NULL - }; - -# Version of biblatex which this release works with. Matched against version -# passed in control file -Readonly::Scalar our $BIBLATEX_VERSION => '1.2'; - -# Global flags needed for sorting -our $BIBER_SORT_FINAL = 0; -our $BIBER_SORT_NULL = 0; - -# the name of the Biber configuration file, which should be -# either returned by kpsewhich or located at "$HOME/.$BIBER_CONF_NAME" -our $BIBER_CONF_NAME = 'biber.conf'; - -## Biber CONFIGURATION DEFAULTS - -# Locale - first try environment ... -my $locale; -if ($ENV{LC_COLLATE}) { - $locale = $ENV{LC_COLLATE}; -} -elsif ($ENV{LANG}) { - $locale = $ENV{LANG}; -} -elsif ($ENV{LC_ALL}) { - $locale = $ENV{LC_ALL}; -} - -# ... if nothing, set a default -unless ($locale) { - if ( $^O =~ /Win/) { - $locale = 'English_United States.1252'; - } - else { - $locale = 'en_US.UTF-8'; - } -} - -# nosort type category shortcuts -our %NOSORT_TYPES = ( - type_name => { - author => 1, - afterword => 1, - annotator => 1, - bookauthor => 1, - commentator => 1, - editor => 1, - editora => 1, - editorb => 1, - editorc => 1, - foreword => 1, - holder => 1, - introduction => 1, - namea => 1, - nameb => 1, - namec => 1, - shortauthor => 1, - shorteditor => 1, - translator => 1 - }, - type_title => { - booktitle => 1, - eventtitle => 1, - issuetitle => 1, - journaltitle => 1, - maintitle => 1, - origtitle => 1, - title => 1 - } -); - -# datatypes for structure validation -our %STRUCTURE_DATATYPES = ( - integer => qr/\A\d+\z/xms -); - -# In general, these defaults are for two reasons: -# * If there is no .bcf to set these options (-a and -d flags for example) -# * New features which are not implemented in .bcf by biblatex yet and so we have -# provide defaults in case they are missing. - -our %CONFIG_DEFAULT_BIBER = ( - bblencoding => 'UTF-8', - bibencoding => 'UTF-8', - bblsafechars => 0, - bblsafecharsset => 'extra', - collate => 1, - collate_options => { level => 4 }, - debug => 0, - decodecharsset => 'extra', - mincrossrefs => 2, - nolog => 0, - nostdmacros => 0, - nosort => { type_name => [ q/\A\p{L}{2}\p{Pd}/, q/[\x{2bf}\x{2018}]/ ] }, - quiet => 0, - sortcase => 1, - sortlocale => $locale, - sortupper => 1, - trace => 0, - wraplines => 0, - validate_control => 0, - validate_structure => 0 - ); - -# default global options for biblatex -# in practice these will be obtained from the control file, -# but we need this for things not yet implemented by biblatex but expected by biber -our %CONFIG_DEFAULT_BIBLATEX = - ( - displaymode => { ALL => ["original", "romanised", "uniform", "translated"] }, - structure => - { constraints => [ - { - constraint => [ - { - fieldxor => [ - { - field => [ - { coerce => "true", content => "date" }, - { content => "year" }, - ], - }, - ], - type => "mandatory", - }, - ], - entrytype => [ - { content => "article" }, - { content => "book" }, - { content => "inbook" }, - { content => "bookinbook" }, - { content => "suppbook" }, - { content => "booklet" }, - { content => "collection" }, - { content => "incollection" }, - { content => "suppcollection" }, - { content => "manual" }, - { content => "misc" }, - { content => "mvbook" }, - { content => "mvcollection" }, - { content => "online" }, - { content => "patent" }, - { content => "periodical" }, - { content => "suppperiodical" }, - { content => "proceedings" }, - { content => "inproceedings" }, - { content => "reference" }, - { content => "inreference" }, - { content => "report" }, - { content => "set" }, - { content => "thesis" }, - { content => "unpublished" }, - ], - }, - { - constraint => [ - { - field => [{ content => "entryset" }, { content => "crossref" }], - type => "mandatory", - }, - ], - entrytype => [{ content => "set" }], - }, - { - constraint => [ - { - field => [ - { content => "author" }, - { content => "journaltitle" }, - { content => "title" }, - ], - type => "mandatory", - }, - ], - entrytype => [{ content => "article" }], - }, - { - constraint => [ - { - field => [{ content => "author" }, { content => "title" }], - type => "mandatory", - }, - ], - entrytype => [ - { content => "book" }, - { content => "mvbook" }, - { content => "mvcollection" }, - { content => "mvreference" }, - ], - }, - { - constraint => [ - { - field => [ - { content => "author" }, - { content => "title" }, - { content => "booktitle" }, - ], - type => "mandatory", - }, - ], - entrytype => [ - { content => "inbook" }, - { content => "bookinbook" }, - { content => "suppbook" }, - ], - }, - { - constraint => [ - { - field => [{ content => "title" }], - fieldor => [ - { field => [{ content => "author" }, { content => "editor" }] }, - ], - type => "mandatory", - }, - ], - entrytype => [{ content => "booklet" }], - }, - { - constraint => [ - { - field => [{ content => "editor" }, { content => "title" }], - type => "mandatory", - }, - ], - entrytype => [{ content => "collection" }, { content => "reference" }], - }, - { - constraint => [ - { - field => [ - { content => "author" }, - { content => "editor" }, - { content => "title" }, - { content => "booktitle" }, - ], - type => "mandatory", - }, - ], - entrytype => [ - { content => "incollection" }, - { content => "suppcollection" }, - { content => "inreference" }, - ], - }, - { - constraint => [{ field => [{ content => "title" }], type => "mandatory" }], - entrytype => [{ content => "manual" }], - }, - { - constraint => [{ field => [{ content => "title" }], type => "mandatory" }], - entrytype => [{ content => "misc" }], - }, - { - constraint => [ - { - field => [{ content => "title" }, { content => "url" }], - type => "mandatory", - }, - ], - entrytype => [{ content => "online" }], - }, - { - constraint => [ - { - field => [ - { content => "author" }, - { content => "title" }, - { content => "number" }, - ], - type => "mandatory", - }, - ], - entrytype => [{ content => "patent" }], - }, - { - constraint => [ - { - field => [{ content => "editor" }, { content => "title" }], - type => "mandatory", - }, - ], - entrytype => [{ content => "periodical" }], - }, - { - constraint => [ - { - field => [{ content => "editor" }, { content => "title" }], - type => "mandatory", - }, - ], - entrytype => [{ content => "proceedings" }, { content => "mvproceedings" }], - }, - { - constraint => [ - { - field => [ - { content => "author" }, - { content => "editor" }, - { content => "title" }, - { content => "booktitle" }, - ], - type => "mandatory", - }, - ], - entrytype => [{ content => "inproceedings" }], - }, - { - constraint => [ - { - field => [ - { content => "author" }, - { content => "title" }, - { content => "type" }, - { content => "institution" }, - ], - type => "mandatory", - }, - ], - entrytype => [{ content => "report" }], - }, - { - constraint => [ - { - field => [ - { content => "author" }, - { content => "title" }, - { content => "type" }, - { content => "institution" }, - ], - type => "mandatory", - }, - ], - entrytype => [{ content => "thesis" }], - }, - { - constraint => [ - { - field => [{ content => "author" }, { content => "title" }], - type => "mandatory", - }, - ], - entrytype => [{ content => "unpublished" }], - }, - ], - datetypes => { - datetype => [ - { content => "date" }, - { content => "origdate" }, - { content => "eventdate" }, - { content => "urldate" }, - ], - }, - entryfields => [ - { - entrytype => [{ content => "ALL" }], - field => [ - { content => "abstract" }, - { content => "annotation" }, - { content => "authortype" }, - { content => "bookpagination" }, - { content => "crossref" }, - { content => "entryset" }, - { content => "entrysubtype" }, - { content => "execute" }, - { content => "file" }, - { content => "gender" }, - { content => "hyphenation" }, - { content => "indextitle" }, - { content => "indexsorttitle" }, - { content => "isan" }, - { content => "ismn" }, - { content => "iswc" }, - { content => "keywords" }, - { content => "label" }, - { content => "library" }, - { content => "lista" }, - { content => "listb" }, - { content => "listc" }, - { content => "listd" }, - { content => "liste" }, - { content => "listf" }, - { content => "nameaddon" }, - { content => "options" }, - { content => "origday" }, - { content => "origendday" }, - { content => "origendmonth" }, - { content => "origendyear" }, - { content => "origmonth" }, - { content => "origyear" }, - { content => "origlocation" }, - { content => "origpublisher" }, - { content => "origtitle" }, - { content => "pagination" }, - { content => "presort" }, - { content => "related" }, - { content => "relatedtype" }, - { content => "relatedstring" }, - { content => "shortauthor" }, - { content => "shorteditor" }, - { content => "shorthand" }, - { content => "shorthandintro" }, - { content => "shortjournal" }, - { content => "shortseries" }, - { content => "shorttitle" }, - { content => "sortkey" }, - { content => "sortname" }, - { content => "sorttitle" }, - { content => "sortyear" }, - { content => "usera" }, - { content => "userb" }, - { content => "userc" }, - { content => "userd" }, - { content => "usere" }, - { content => "userf" }, - { content => "verba" }, - { content => "verbb" }, - { content => "verbc" }, - { content => "xref" }, - ], - }, - { - entrytype => [{ content => "set" }], - field => [{ content => "entryset" }, { content => "crossref" }], - }, - { - entrytype => [{ content => "article" }], - field => [ - { content => "author" }, - { content => "journaltitle" }, - { content => "title" }, - { content => "day" }, - { content => "endday" }, - { content => "endmonth" }, - { content => "endyear" }, - { content => "month" }, - { content => "year" }, - { content => "addendum" }, - { content => "annotator" }, - { content => "commentator" }, - { content => "doi" }, - { content => "editor" }, - { content => "editora" }, - { content => "editorb" }, - { content => "editorc" }, - { content => "editoratype" }, - { content => "editorbtype" }, - { content => "editorctype" }, - { content => "eid" }, - { content => "eprint" }, - { content => "eprintclass" }, - { content => "eprinttype" }, - { content => "issn" }, - { content => "issue" }, - { content => "issuetitle" }, - { content => "issuesubtitle" }, - { content => "journalsubtitle" }, - { content => "language" }, - { content => "note" }, - { content => "number" }, - { content => "origlanguage" }, - { content => "pages" }, - { content => "pubstate" }, - { content => "series" }, - { content => "subtitle" }, - { content => "titleaddon" }, - { content => "translator" }, - { content => "url" }, - { content => "urlday" }, - { content => "urlendday" }, - { content => "urlendmonth" }, - { content => "urlendyear" }, - { content => "urlmonth" }, - { content => "urlyear" }, - { content => "version" }, - { content => "volume" }, - ], - }, - { - entrytype => [{ content => "bibnote" }], - field => [{ content => "note" }], - }, - { - entrytype => [{ content => "book" }], - field => [ - { content => "author" }, - { content => "title" }, - { content => "day" }, - { content => "endday" }, - { content => "endmonth" }, - { content => "endyear" }, - { content => "month" }, - { content => "year" }, - { content => "addendum" }, - { content => "afterword" }, - { content => "annotator" }, - { content => "chapter" }, - { content => "commentator" }, - { content => "doi" }, - { content => "edition" }, - { content => "editor" }, - { content => "editora" }, - { content => "editorb" }, - { content => "editorc" }, - { content => "editoratype" }, - { content => "editorbtype" }, - { content => "editorctype" }, - { content => "eprint" }, - { content => "eprintclass" }, - { content => "eprinttype" }, - { content => "foreword" }, - { content => "introduction" }, - { content => "isbn" }, - { content => "language" }, - { content => "location" }, - { content => "maintitle" }, - { content => "maintitleaddon" }, - { content => "mainsubtitle" }, - { content => "note" }, - { content => "number" }, - { content => "origlanguage" }, - { content => "pages" }, - { content => "pagetotal" }, - { content => "part" }, - { content => "publisher" }, - { content => "pubstate" }, - { content => "series" }, - { content => "subtitle" }, - { content => "titleaddon" }, - { content => "translator" }, - { content => "url" }, - { content => "urlday" }, - { content => "urlendday" }, - { content => "urlendmonth" }, - { content => "urlendyear" }, - { content => "urlmonth" }, - { content => "urlyear" }, - { content => "volume" }, - { content => "volumes" }, - ], - }, - { - entrytype => [{ content => "mvbook" }], - field => [ - { content => "author" }, - { content => "title" }, - { content => "day" }, - { content => "endday" }, - { content => "endmonth" }, - { content => "endyear" }, - { content => "month" }, - { content => "year" }, - { content => "addendum" }, - { content => "afterword" }, - { content => "annotator" }, - { content => "commentator" }, - { content => "doi" }, - { content => "edition" }, - { content => "editor" }, - { content => "editora" }, - { content => "editorb" }, - { content => "editorc" }, - { content => "editoratype" }, - { content => "editorbtype" }, - { content => "editorctype" }, - { content => "eprint" }, - { content => "eprintclass" }, - { content => "eprinttype" }, - { content => "foreword" }, - { content => "introduction" }, - { content => "isbn" }, - { content => "language" }, - { content => "location" }, - { content => "note" }, - { content => "number" }, - { content => "origlanguage" }, - { content => "publisher" }, - { content => "pubstate" }, - { content => "subtitle" }, - { content => "titleaddon" }, - { content => "translator" }, - { content => "url" }, - { content => "urlday" }, - { content => "urlendday" }, - { content => "urlendmonth" }, - { content => "urlendyear" }, - { content => "urlmonth" }, - { content => "urlyear" }, - { content => "volume" }, - { content => "volumes" }, - ], - }, - { - entrytype => [ - { content => "inbook" }, - { content => "bookinbook" }, - { content => "suppbook" }, - ], - field => [ - { content => "author" }, - { content => "title" }, - { content => "booktitle" }, - { content => "day" }, - { content => "endday" }, - { content => "endmonth" }, - { content => "endyear" }, - { content => "month" }, - { content => "year" }, - { content => "addendum" }, - { content => "afterword" }, - { content => "annotator" }, - { content => "bookauthor" }, - { content => "booksubtitle" }, - { content => "booktitleaddon" }, - { content => "chapter" }, - { content => "commentator" }, - { content => "doi" }, - { content => "edition" }, - { content => "editor" }, - { content => "editora" }, - { content => "editorb" }, - { content => "editorc" }, - { content => "editoratype" }, - { content => "editorbtype" }, - { content => "editorctype" }, - { content => "eprint" }, - { content => "eprintclass" }, - { content => "eprinttype" }, - { content => "foreword" }, - { content => "introduction" }, - { content => "isbn" }, - { content => "language" }, - { content => "location" }, - { content => "mainsubtitle" }, - { content => "maintitle" }, - { content => "maintitleaddon" }, - { content => "note" }, - { content => "number" }, - { content => "origlanguage" }, - { content => "part" }, - { content => "publisher" }, - { content => "pages" }, - { content => "pubstate" }, - { content => "series" }, - { content => "subtitle" }, - { content => "titleaddon" }, - { content => "translator" }, - { content => "url" }, - { content => "urlday" }, - { content => "urlendday" }, - { content => "urlendmonth" }, - { content => "urlendyear" }, - { content => "urlmonth" }, - { content => "urlyear" }, - { content => "volume" }, - { content => "volumes" }, - ], - }, - { - entrytype => [{ content => "booklet" }], - field => [ - { content => "author" }, - { content => "editor" }, - { content => "title" }, - { content => "day" }, - { content => "endday" }, - { content => "endmonth" }, - { content => "endyear" }, - { content => "month" }, - { content => "year" }, - { content => "addendum" }, - { content => "chapter" }, - { content => "doi" }, - { content => "eprint" }, - { content => "eprintclass" }, - { content => "eprinttype" }, - { content => "howpublished" }, - { content => "language" }, - { content => "location" }, - { content => "note" }, - { content => "pages" }, - { content => "pagetotal" }, - { content => "pubstate" }, - { content => "subtitle" }, - { content => "titleaddon" }, - { content => "type" }, - { content => "url" }, - { content => "urlday" }, - { content => "urlendday" }, - { content => "urlendmonth" }, - { content => "urlendyear" }, - { content => "urlmonth" }, - { content => "urlyear" }, - ], - }, - { - entrytype => [{ content => "collection" }, { content => "reference" }], - field => [ - { content => "editor" }, - { content => "title" }, - { content => "day" }, - { content => "endday" }, - { content => "endmonth" }, - { content => "endyear" }, - { content => "month" }, - { content => "year" }, - { content => "addendum" }, - { content => "afterword" }, - { content => "annotator" }, - { content => "chapter" }, - { content => "commentator" }, - { content => "doi" }, - { content => "edition" }, - { content => "editora" }, - { content => "editorb" }, - { content => "editorc" }, - { content => "editoratype" }, - { content => "editorbtype" }, - { content => "editorctype" }, - { content => "eprint" }, - { content => "eprintclass" }, - { content => "eprinttype" }, - { content => "foreword" }, - { content => "introduction" }, - { content => "isbn" }, - { content => "language" }, - { content => "location" }, - { content => "mainsubtitle" }, - { content => "maintitle" }, - { content => "maintitleaddon" }, - { content => "note" }, - { content => "number" }, - { content => "origlanguage" }, - { content => "pages" }, - { content => "pagetotal" }, - { content => "part" }, - { content => "publisher" }, - { content => "pubstate" }, - { content => "series" }, - { content => "subtitle" }, - { content => "titleaddon" }, - { content => "translator" }, - { content => "url" }, - { content => "urlday" }, - { content => "urlendday" }, - { content => "urlendmonth" }, - { content => "urlendyear" }, - { content => "urlmonth" }, - { content => "urlyear" }, - { content => "volume" }, - { content => "volumes" }, - ], - }, - { - entrytype => [{ content => "mvcollection" }, { content => "mvreference" }], - field => [ - { content => "author" }, - { content => "title" }, - { content => "day" }, - { content => "endday" }, - { content => "endmonth" }, - { content => "endyear" }, - { content => "month" }, - { content => "year" }, - { content => "addendum" }, - { content => "afterword" }, - { content => "annotator" }, - { content => "commentator" }, - { content => "doi" }, - { content => "edition" }, - { content => "editor" }, - { content => "editora" }, - { content => "editorb" }, - { content => "editorc" }, - { content => "editoratype" }, - { content => "editorbtype" }, - { content => "editorctype" }, - { content => "eprint" }, - { content => "eprintclass" }, - { content => "eprinttype" }, - { content => "foreword" }, - { content => "introduction" }, - { content => "isbn" }, - { content => "language" }, - { content => "location" }, - { content => "note" }, - { content => "number" }, - { content => "origlanguage" }, - { content => "publisher" }, - { content => "pubstate" }, - { content => "subtitle" }, - { content => "titleaddon" }, - { content => "translator" }, - { content => "url" }, - { content => "urlday" }, - { content => "urlendday" }, - { content => "urlendmonth" }, - { content => "urlendyear" }, - { content => "urlmonth" }, - { content => "urlyear" }, - { content => "volume" }, - { content => "volumes" }, - ], - }, - { - entrytype => [ - { content => "incollection" }, - { content => "suppcollection" }, - { content => "inreference" }, - ], - field => [ - { content => "author" }, - { content => "editor" }, - { content => "title" }, - { content => "booktitle" }, - { content => "day" }, - { content => "endday" }, - { content => "endmonth" }, - { content => "endyear" }, - { content => "month" }, - { content => "year" }, - { content => "addendum" }, - { content => "afterword" }, - { content => "annotator" }, - { content => "booksubtitle" }, - { content => "booktitleaddon" }, - { content => "chapter" }, - { content => "commentator" }, - { content => "doi" }, - { content => "edition" }, - { content => "editora" }, - { content => "editorb" }, - { content => "editorc" }, - { content => "editoratype" }, - { content => "editorbtype" }, - { content => "editorctype" }, - { content => "eprint" }, - { content => "eprintclass" }, - { content => "eprinttype" }, - { content => "foreword" }, - { content => "introduction" }, - { content => "isbn" }, - { content => "language" }, - { content => "location" }, - { content => "mainsubtitle" }, - { content => "maintitle" }, - { content => "maintitleaddon" }, - { content => "note" }, - { content => "number" }, - { content => "origlanguage" }, - { content => "pages" }, - { content => "part" }, - { content => "publisher" }, - { content => "pubstate" }, - { content => "series" }, - { content => "subtitle" }, - { content => "titleaddon" }, - { content => "translator" }, - { content => "url" }, - { content => "urlday" }, - { content => "urlendday" }, - { content => "urlendmonth" }, - { content => "urlendyear" }, - { content => "urlmonth" }, - { content => "urlyear" }, - { content => "volume" }, - { content => "volumes" }, - ], - }, - { - entrytype => [{ content => "manual" }], - field => [ - { content => "title" }, - { content => "day" }, - { content => "endday" }, - { content => "endmonth" }, - { content => "endyear" }, - { content => "month" }, - { content => "year" }, - { content => "addendum" }, - { content => "author" }, - { content => "chapter" }, - { content => "doi" }, - { content => "edition" }, - { content => "editor" }, - { content => "eprint" }, - { content => "eprintclass" }, - { content => "eprinttype" }, - { content => "isbn" }, - { content => "language" }, - { content => "location" }, - { content => "note" }, - { content => "number" }, - { content => "organization" }, - { content => "pages" }, - { content => "pagetotal" }, - { content => "publisher" }, - { content => "pubstate" }, - { content => "series" }, - { content => "subtitle" }, - { content => "titleaddon" }, - { content => "type" }, - { content => "url" }, - { content => "urlday" }, - { content => "urlendday" }, - { content => "urlendmonth" }, - { content => "urlendyear" }, - { content => "urlmonth" }, - { content => "urlyear" }, - { content => "version" }, - ], - }, - { - entrytype => [{ content => "misc" }], - field => [ - { content => "title" }, - { content => "day" }, - { content => "endday" }, - { content => "endmonth" }, - { content => "endyear" }, - { content => "day" }, - { content => "endday" }, - { content => "endmonth" }, - { content => "endyear" }, - { content => "month" }, - { content => "year" }, - { content => "addendum" }, - { content => "author" }, - { content => "doi" }, - { content => "editor" }, - { content => "eprint" }, - { content => "eprintclass" }, - { content => "eprinttype" }, - { content => "howpublished" }, - { content => "language" }, - { content => "location" }, - { content => "note" }, - { content => "organization" }, - { content => "pubstate" }, - { content => "subtitle" }, - { content => "titleaddon" }, - { content => "type" }, - { content => "url" }, - { content => "urlday" }, - { content => "urlendday" }, - { content => "urlendmonth" }, - { content => "urlendyear" }, - { content => "urlmonth" }, - { content => "urlyear" }, - { content => "version" }, - ], - }, - { - entrytype => [{ content => "online" }], - field => [ - { content => "title" }, - { content => "url" }, - { content => "addendum" }, - { content => "author" }, - { content => "editor" }, - { content => "language" }, - { content => "month" }, - { content => "note" }, - { content => "organization" }, - { content => "pubstate" }, - { content => "subtitle" }, - { content => "titleaddon" }, - { content => "urlday" }, - { content => "urlendday" }, - { content => "urlendmonth" }, - { content => "urlendyear" }, - { content => "urlmonth" }, - { content => "urlyear" }, - { content => "version" }, - { content => "year" }, - ], - }, - { - entrytype => [{ content => "patent" }], - field => [ - { content => "author" }, - { content => "title" }, - { content => "number" }, - { content => "day" }, - { content => "endday" }, - { content => "endmonth" }, - { content => "endyear" }, - { content => "month" }, - { content => "year" }, - { content => "addendum" }, - { content => "doi" }, - { content => "eprint" }, - { content => "eprintclass" }, - { content => "eprinttype" }, - { content => "holder" }, - { content => "location" }, - { content => "note" }, - { content => "pubstate" }, - { content => "subtitle" }, - { content => "titleaddon" }, - { content => "type" }, - { content => "url" }, - { content => "urlday" }, - { content => "urlendday" }, - { content => "urlendmonth" }, - { content => "urlendyear" }, - { content => "urlmonth" }, - { content => "urlyear" }, - { content => "version" }, - ], - }, - { - entrytype => [{ content => "periodical" }], - field => [ - { content => "editor" }, - { content => "title" }, - { content => "day" }, - { content => "endday" }, - { content => "endmonth" }, - { content => "endyear" }, - { content => "month" }, - { content => "year" }, - { content => "addendum" }, - { content => "doi" }, - { content => "editora" }, - { content => "editorb" }, - { content => "editorc" }, - { content => "editoratype" }, - { content => "editorbtype" }, - { content => "editorctype" }, - { content => "eprint" }, - { content => "eprintclass" }, - { content => "eprinttype" }, - { content => "issn" }, - { content => "issue" }, - { content => "issuesubtitle" }, - { content => "issuetitle" }, - { content => "language" }, - { content => "note" }, - { content => "number" }, - { content => "pubstate" }, - { content => "series" }, - { content => "subtitle" }, - { content => "url" }, - { content => "urlday" }, - { content => "urlendday" }, - { content => "urlendmonth" }, - { content => "urlendyear" }, - { content => "urlmonth" }, - { content => "urlyear" }, - { content => "volume" }, - ], - }, - { - entrytype => [{ content => "mvproceedings" }], - field => [ - { content => "editor" }, - { content => "title" }, - { content => "day" }, - { content => "endday" }, - { content => "endmonth" }, - { content => "endyear" }, - { content => "month" }, - { content => "year" }, - { content => "addendum" }, - { content => "doi" }, - { content => "eprint" }, - { content => "eprintclass" }, - { content => "eprinttype" }, - { content => "eventday" }, - { content => "eventendday" }, - { content => "eventendmonth" }, - { content => "eventendyear" }, - { content => "eventmonth" }, - { content => "eventyear" }, - { content => "eventtitle" }, - { content => "isbn" }, - { content => "language" }, - { content => "location" }, - { content => "note" }, - { content => "number" }, - { content => "organization" }, - { content => "pagetotal" }, - { content => "publisher" }, - { content => "pubstate" }, - { content => "series" }, - { content => "subtitle" }, - { content => "titleaddon" }, - { content => "url" }, - { content => "urlday" }, - { content => "urlendday" }, - { content => "urlendmonth" }, - { content => "urlendyear" }, - { content => "urlmonth" }, - { content => "urlyear" }, - { content => "venue" }, - { content => "volumes" }, - ], - }, - { - entrytype => [{ content => "proceedings" }], - field => [ - { content => "editor" }, - { content => "title" }, - { content => "day" }, - { content => "endday" }, - { content => "endmonth" }, - { content => "endyear" }, - { content => "month" }, - { content => "year" }, - { content => "addendum" }, - { content => "chapter" }, - { content => "doi" }, - { content => "eprint" }, - { content => "eprintclass" }, - { content => "eprinttype" }, - { content => "eventday" }, - { content => "eventendday" }, - { content => "eventendmonth" }, - { content => "eventendyear" }, - { content => "eventmonth" }, - { content => "eventyear" }, - { content => "eventtitle" }, - { content => "isbn" }, - { content => "language" }, - { content => "location" }, - { content => "mainsubtitle" }, - { content => "maintitle" }, - { content => "maintitleaddon" }, - { content => "note" }, - { content => "number" }, - { content => "organization" }, - { content => "pages" }, - { content => "pagetotal" }, - { content => "part" }, - { content => "publisher" }, - { content => "pubstate" }, - { content => "series" }, - { content => "subtitle" }, - { content => "titleaddon" }, - { content => "url" }, - { content => "urlday" }, - { content => "urlendday" }, - { content => "urlendmonth" }, - { content => "urlendyear" }, - { content => "urlmonth" }, - { content => "urlyear" }, - { content => "venue" }, - { content => "volume" }, - { content => "volumes" }, - ], - }, - { - entrytype => [{ content => "inproceedings" }], - field => [ - { content => "author" }, - { content => "editor" }, - { content => "title" }, - { content => "booktitle" }, - { content => "day" }, - { content => "endday" }, - { content => "endmonth" }, - { content => "endyear" }, - { content => "month" }, - { content => "year" }, - { content => "addendum" }, - { content => "booksubtitle" }, - { content => "booktitleaddon" }, - { content => "chapter" }, - { content => "doi" }, - { content => "eprint" }, - { content => "eprintclass" }, - { content => "eprinttype" }, - { content => "eventday" }, - { content => "eventendday" }, - { content => "eventendmonth" }, - { content => "eventendyear" }, - { content => "eventmonth" }, - { content => "eventyear" }, - { content => "eventtitle" }, - { content => "isbn" }, - { content => "language" }, - { content => "location" }, - { content => "mainsubtitle" }, - { content => "maintitle" }, - { content => "maintitleaddon" }, - { content => "note" }, - { content => "number" }, - { content => "organization" }, - { content => "pages" }, - { content => "part" }, - { content => "publisher" }, - { content => "pubstate" }, - { content => "series" }, - { content => "subtitle" }, - { content => "titleaddon" }, - { content => "url" }, - { content => "urlday" }, - { content => "urlendday" }, - { content => "urlendmonth" }, - { content => "urlendyear" }, - { content => "urlmonth" }, - { content => "urlyear" }, - { content => "venue" }, - { content => "volume" }, - { content => "volumes" }, - ], - }, - { - entrytype => [{ content => "report" }], - field => [ - { content => "author" }, - { content => "title" }, - { content => "type" }, - { content => "institution" }, - { content => "day" }, - { content => "endday" }, - { content => "endmonth" }, - { content => "endyear" }, - { content => "month" }, - { content => "year" }, - { content => "addendum" }, - { content => "chapter" }, - { content => "doi" }, - { content => "eprint" }, - { content => "eprintclass" }, - { content => "eprinttype" }, - { content => "isrn" }, - { content => "language" }, - { content => "location" }, - { content => "note" }, - { content => "number" }, - { content => "pages" }, - { content => "pagetotal" }, - { content => "pubstate" }, - { content => "subtitle" }, - { content => "titleaddon" }, - { content => "url" }, - { content => "urlday" }, - { content => "urlendday" }, - { content => "urlendmonth" }, - { content => "urlendyear" }, - { content => "urlmonth" }, - { content => "urlyear" }, - { content => "version" }, - ], - }, - { - entrytype => [{ content => "thesis" }], - field => [ - { content => "author" }, - { content => "title" }, - { content => "type" }, - { content => "institution" }, - { content => "day" }, - { content => "endday" }, - { content => "endmonth" }, - { content => "endyear" }, - { content => "month" }, - { content => "year" }, - { content => "addendum" }, - { content => "chapter" }, - { content => "doi" }, - { content => "eprint" }, - { content => "eprintclass" }, - { content => "eprinttype" }, - { content => "language" }, - { content => "location" }, - { content => "note" }, - { content => "pages" }, - { content => "pagetotal" }, - { content => "pubstate" }, - { content => "subtitle" }, - { content => "titleaddon" }, - { content => "url" }, - { content => "urlday" }, - { content => "urlendday" }, - { content => "urlendmonth" }, - { content => "urlendyear" }, - { content => "urlmonth" }, - { content => "urlyear" }, - ], - }, - { - entrytype => [{ content => "unpublished" }], - field => [ - { content => "author" }, - { content => "title" }, - { content => "day" }, - { content => "endday" }, - { content => "endmonth" }, - { content => "endyear" }, - { content => "month" }, - { content => "year" }, - { content => "addendum" }, - { content => "howpublished" }, - { content => "language" }, - { content => "location" }, - { content => "note" }, - { content => "pubstate" }, - { content => "subtitle" }, - { content => "titleaddon" }, - { content => "url" }, - { content => "urlday" }, - { content => "urlendday" }, - { content => "urlendmonth" }, - { content => "urlendyear" }, - { content => "urlmonth" }, - { content => "urlyear" }, - ], - }, - ], - entrytypes => { - entrytype => [ - { content => "article" }, - { content => "artwork" }, - { content => "audio" }, - { content => "bibnote" }, - { content => "book" }, - { content => "bookinbook" }, - { content => "booklet" }, - { content => "collection" }, - { content => "commentary" }, - { content => "customa" }, - { content => "customb" }, - { content => "customc" }, - { content => "customd" }, - { content => "custome" }, - { content => "customf" }, - { content => "inbook" }, - { content => "incollection" }, - { content => "inproceedings" }, - { content => "inreference" }, - { content => "image" }, - { content => "jurisdiction" }, - { content => "legal" }, - { content => "legislation" }, - { content => "letter" }, - { content => "manual" }, - { content => "misc" }, - { content => "movie" }, - { content => "music" }, - { content => "mvcollection" }, - { content => "mvbook" }, - { content => "online" }, - { content => "patent" }, - { content => "performance" }, - { content => "periodical" }, - { content => "proceedings" }, - { content => "reference" }, - { content => "report" }, - { content => "review" }, - { content => "set" }, - { content => "software" }, - { content => "standard" }, - { content => "suppbook" }, - { content => "suppcollection" }, - { content => "thesis" }, - { content => "unpublished" }, - { content => "video" }, - ], - }, - fields => { - field => [ - { content => "abstract", datatype => "literal", fieldtype => "field" }, - { content => "addendum", datatype => "literal", fieldtype => "field" }, - { content => "afterword", datatype => "name", fieldtype => "list" }, - { content => "annotation", datatype => "literal", fieldtype => "field" }, - { content => "annotator", datatype => "name", fieldtype => "list" }, - { content => "author", datatype => "name", fieldtype => "list" }, - { content => "authortype", datatype => "key", fieldtype => "field" }, - { content => "bookauthor", datatype => "name", fieldtype => "list" }, - { content => "bookpagination", datatype => "key", fieldtype => "field" }, - { content => "booksubtitle", datatype => "literal", fieldtype => "field" }, - { content => "booktitle", datatype => "literal", fieldtype => "field" }, - { - content => "booktitleaddon", - datatype => "literal", - fieldtype => "field", - }, - { content => "chapter", datatype => "literal", fieldtype => "field" }, - { content => "commentator", datatype => "name", fieldtype => "list" }, - { content => "crossref", datatype => "literal", fieldtype => "field" }, - { content => "day", datatype => "literal", fieldtype => "field" }, - { content => "doi", datatype => "verbatim", fieldtype => "field" }, - { content => "edition", datatype => "literal", fieldtype => "field" }, - { content => "editor", datatype => "name", fieldtype => "list" }, - { content => "editora", datatype => "name", fieldtype => "list" }, - { content => "editoratype", datatype => "key", fieldtype => "field" }, - { content => "editorb", datatype => "name", fieldtype => "list" }, - { content => "editorbtype", datatype => "key", fieldtype => "field" }, - { content => "editorc", datatype => "name", fieldtype => "list" }, - { content => "editorctype", datatype => "key", fieldtype => "field" }, - { content => "editortype", datatype => "key", fieldtype => "field" }, - { content => "eid", datatype => "literal", fieldtype => "field" }, - { content => "endday", datatype => "literal", fieldtype => "field" }, - { content => "endmonth", datatype => "literal", fieldtype => "field" }, - { - content => "endyear", - datatype => "literal", - fieldtype => "field", - nullok => "true", - }, - { - content => "entryset", - datatype => "literal", - fieldtype => "field", - skip_output => "true", - }, - { content => "entrysubtype", datatype => "literal", fieldtype => "field" }, - { content => "eprint", datatype => "verbatim", fieldtype => "field" }, - { content => "eprintclass", datatype => "literal", fieldtype => "field" }, - { content => "eprinttype", datatype => "literal", fieldtype => "field" }, - { content => "eventday", datatype => "literal", fieldtype => "field" }, - { content => "eventendday", datatype => "literal", fieldtype => "field" }, - { content => "eventendmonth", datatype => "literal", fieldtype => "field" }, - { - content => "eventendyear", - datatype => "literal", - fieldtype => "field", - nullok => "true", - }, - { content => "eventmonth", datatype => "literal", fieldtype => "field" }, - { content => "eventtitle", datatype => "literal", fieldtype => "field" }, - { content => "eventyear", datatype => "literal", fieldtype => "field" }, - { content => "execute", datatype => "literal", fieldtype => "field" }, - { content => "file", datatype => "verbatim", fieldtype => "field" }, - { content => "foreword", datatype => "name", fieldtype => "list" }, - { content => "gender", datatype => "literal", fieldtype => "field" }, - { content => "holder", datatype => "name", fieldtype => "list" }, - { content => "howpublished", datatype => "literal", fieldtype => "field" }, - { content => "hyphenation", datatype => "literal", fieldtype => "field" }, - { - content => "indexsorttitle", - datatype => "literal", - fieldtype => "field", - }, - { content => "indextitle", datatype => "literal", fieldtype => "field" }, - { content => "institution", datatype => "literal", fieldtype => "list" }, - { content => "introduction", datatype => "name", fieldtype => "list" }, - { content => "isan", datatype => "literal", fieldtype => "field" }, - { content => "isbn", datatype => "literal", fieldtype => "field" }, - { content => "ismn", datatype => "literal", fieldtype => "field" }, - { content => "isrn", datatype => "literal", fieldtype => "field" }, - { content => "issn", datatype => "literal", fieldtype => "field" }, - { content => "issue", datatype => "literal", fieldtype => "field" }, - { content => "issuesubtitle", datatype => "literal", fieldtype => "field" }, - { content => "issuetitle", datatype => "literal", fieldtype => "field" }, - { content => "iswc", datatype => "literal", fieldtype => "field" }, - { - content => "journalsubtitle", - datatype => "literal", - fieldtype => "field", - }, - { content => "journaltitle", datatype => "literal", fieldtype => "field" }, - { content => "keywords", datatype => "special", fieldtype => "field" }, - { content => "label", datatype => "literal", fieldtype => "field" }, - { content => "language", datatype => "key", fieldtype => "list" }, - { content => "library", datatype => "literal", fieldtype => "field" }, - { content => "lista", datatype => "literal", fieldtype => "list" }, - { content => "listb", datatype => "literal", fieldtype => "list" }, - { content => "listc", datatype => "literal", fieldtype => "list" }, - { content => "listd", datatype => "literal", fieldtype => "list" }, - { content => "liste", datatype => "literal", fieldtype => "list" }, - { content => "listf", datatype => "literal", fieldtype => "list" }, - { content => "location", datatype => "literal", fieldtype => "list" }, - { content => "mainsubtitle", datatype => "literal", fieldtype => "field" }, - { content => "maintitle", datatype => "literal", fieldtype => "field" }, - { - content => "maintitleaddon", - datatype => "literal", - fieldtype => "field", - }, - { content => "month", datatype => "integer", fieldtype => "field" }, - { content => "namea", datatype => "name", fieldtype => "list" }, - { content => "nameaddon", datatype => "literal", fieldtype => "field" }, - { content => "nameatype", datatype => "key", fieldtype => "field" }, - { content => "nameb", datatype => "name", fieldtype => "list" }, - { content => "namebtype", datatype => "key", fieldtype => "field" }, - { content => "namec", datatype => "name", fieldtype => "list" }, - { content => "namectype", datatype => "key", fieldtype => "field" }, - { content => "note", datatype => "literal", fieldtype => "field" }, - { content => "number", datatype => "literal", fieldtype => "field" }, - { content => "options", datatype => "special", fieldtype => "field" }, - { content => "organization", datatype => "literal", fieldtype => "list" }, - { content => "origday", datatype => "literal", fieldtype => "field" }, - { content => "origendday", datatype => "literal", fieldtype => "field" }, - { content => "origendmonth", datatype => "literal", fieldtype => "field" }, - { - content => "origendyear", - datatype => "literal", - fieldtype => "field", - nullok => "true", - }, - { content => "origlanguage", datatype => "key", fieldtype => "field" }, - { content => "origlocation", datatype => "literal", fieldtype => "list" }, - { content => "origmonth", datatype => "literal", fieldtype => "field" }, - { content => "origpublisher", datatype => "literal", fieldtype => "list" }, - { content => "origtitle", datatype => "literal", fieldtype => "field" }, - { content => "origyear", datatype => "literal", fieldtype => "field" }, - { content => "pages", datatype => "range", fieldtype => "field" }, - { content => "pagetotal", datatype => "literal", fieldtype => "field" }, - { content => "pagination", datatype => "key", fieldtype => "field" }, - { content => "part", datatype => "literal", fieldtype => "field" }, - { - content => "presort", - datatype => "literal", - fieldtype => "field", - skip_output => "true", - }, - { content => "publisher", datatype => "literal", fieldtype => "list" }, - { content => "pubstate", datatype => "key", fieldtype => "field" }, - { content => "related", datatype => "literal", fieldtype => "field" }, - { content => "relatedtype", datatype => "literal", fieldtype => "field" }, - { content => "relatedstring", datatype => "literal", fieldtype => "field" }, - { content => "reprinttitle", datatype => "literal", fieldtype => "field" }, - { content => "series", datatype => "literal", fieldtype => "field" }, - { content => "shortauthor", datatype => "name", fieldtype => "list" }, - { content => "shorteditor", datatype => "name", fieldtype => "list" }, - { content => "shorthand", datatype => "literal", fieldtype => "field" }, - { - content => "shorthandintro", - datatype => "literal", - fieldtype => "field", - }, - { content => "shortjournal", datatype => "literal", fieldtype => "field" }, - { content => "shortseries", datatype => "literal", fieldtype => "field" }, - { content => "shorttitle", datatype => "literal", fieldtype => "field" }, - { - content => "sortkey", - datatype => "literal", - fieldtype => "field", - skip_output => "true", - }, - { - content => "sortname", - datatype => "name", - fieldtype => "list", - skip_output => "true", - }, - { - content => "sorttitle", - datatype => "literal", - fieldtype => "field", - skip_output => "true", - }, - { - content => "sortyear", - datatype => "literal", - fieldtype => "field", - skip_output => "true", - }, - { content => "subtitle", datatype => "literal", fieldtype => "field" }, - { content => "title", datatype => "literal", fieldtype => "field" }, - { content => "titleaddon", datatype => "literal", fieldtype => "field" }, - { content => "translator", datatype => "name", fieldtype => "list" }, - { content => "type", datatype => "key", fieldtype => "field" }, - { content => "url", datatype => "verbatim", fieldtype => "field" }, - { content => "usera", datatype => "literal", fieldtype => "field" }, - { content => "userb", datatype => "literal", fieldtype => "field" }, - { content => "userc", datatype => "literal", fieldtype => "field" }, - { content => "userd", datatype => "literal", fieldtype => "field" }, - { content => "usere", datatype => "literal", fieldtype => "field" }, - { content => "userf", datatype => "literal", fieldtype => "field" }, - { content => "urlday", datatype => "literal", fieldtype => "field" }, - { content => "urlendday", datatype => "literal", fieldtype => "field" }, - { content => "urlendmonth", datatype => "literal", fieldtype => "field" }, - { - content => "urlendyear", - datatype => "literal", - fieldtype => "field", - nullok => "true", - }, - { content => "urlmonth", datatype => "literal", fieldtype => "field" }, - { content => "urlyear", datatype => "literal", fieldtype => "field" }, - { content => "venue", datatype => "literal", fieldtype => "field" }, - { content => "verba", datatype => "verbatim", fieldtype => "field" }, - { content => "verbb", datatype => "verbatim", fieldtype => "field" }, - { content => "verbc", datatype => "verbatim", fieldtype => "field" }, - { content => "version", datatype => "literal", fieldtype => "field" }, - { content => "volume", datatype => "literal", fieldtype => "field" }, - { content => "volumes", datatype => "literal", fieldtype => "field" }, - { content => "xref", datatype => "literal", fieldtype => "field" }, - { content => "year", datatype => "literal", fieldtype => "field" }, - ], - }, - } -); - - -# Set up some encoding aliases to map \inputen{c,x} encoding names to Encode -# It seems that inputen{c,x} has a different idea of nextstep than Encode -# so we push it to MacRoman -define_alias( 'ansinew' => 'cp1252'); # inputenc alias for cp1252 -define_alias( 'applemac' => 'MacRoman'); -define_alias( 'applemacce' => 'MacCentralEurRoman'); -define_alias( 'next' => 'MacRoman'); -define_alias( 'x-mac-roman' => 'MacRoman'); -define_alias( 'x-mac-centeuro' => 'MacCentralEurRoman'); -define_alias( 'x-mac-cyrillic' => 'MacCyrillic'); -define_alias( 'x-nextstep' => 'MacRoman'); -define_alias( 'x-ascii' => 'ascii'); # Encode doesn't resolve this one by default -define_alias( 'lutf8' => 'UTF-8'); # Luatex -define_alias( 'utf8x' => 'UTF-8'); # UCS (old) - -# Defines the scope of each of the BibLaTeX configuration options -our %CONFIG_SCOPE_BIBLATEX = ( - alphaothers => {GLOBAL => 1, PER_TYPE => 1, PER_ENTRY => 0}, - controlversion => {GLOBAL => 1, PER_TYPE => 0, PER_ENTRY => 0}, - debug => {GLOBAL => 1, PER_TYPE => 0, PER_ENTRY => 0}, - dataonly => {GLOBAL => 0, PER_TYPE => 0, PER_ENTRY => 1}, - displaymode => {GLOBAL => 1, PER_TYPE => 0, PER_ENTRY => 0}, - inheritance => {GLOBAL => 1, PER_TYPE => 0, PER_ENTRY => 0}, - labelalpha => {GLOBAL => 1, PER_TYPE => 1, PER_ENTRY => 0}, - labelnamespec => {GLOBAL => 1, PER_TYPE => 1, PER_ENTRY => 0}, - labelnumber => {GLOBAL => 1, PER_TYPE => 1, PER_ENTRY => 0}, - labelyear => {GLOBAL => 1, PER_TYPE => 1, PER_ENTRY => 0}, - labelyearspec => {GLOBAL => 1, PER_TYPE => 1, PER_ENTRY => 0}, - maxitems => {GLOBAL => 1, PER_TYPE => 0, PER_ENTRY => 0}, - minitems => {GLOBAL => 1, PER_TYPE => 0, PER_ENTRY => 0}, - maxnames => {GLOBAL => 1, PER_TYPE => 0, PER_ENTRY => 0}, - minnames => {GLOBAL => 1, PER_TYPE => 0, PER_ENTRY => 0}, - presort => {GLOBAL => 1, PER_TYPE => 1, PER_ENTRY => 1}, - singletitle => {GLOBAL => 1, PER_TYPE => 1, PER_ENTRY => 0}, - skipbib => {GLOBAL => 0, PER_TYPE => 1, PER_ENTRY => 1}, - skiplab => {GLOBAL => 0, PER_TYPE => 1, PER_ENTRY => 1}, - skiplos => {GLOBAL => 0, PER_TYPE => 1, PER_ENTRY => 1}, - sortalphaothers => {GLOBAL => 1, PER_TYPE => 1, PER_ENTRY => 0}, - sortexclusion => {GLOBAL => 0, PER_TYPE => 1, PER_ENTRY => 0}, - sorting => {GLOBAL => 1, PER_TYPE => 0, PER_ENTRY => 0}, - sortlos => {GLOBAL => 1, PER_TYPE => 0, PER_ENTRY => 0}, - structure => {GLOBAL => 1, PER_TYPE => 0, PER_ENTRY => 0}, - terseinits => {GLOBAL => 1, PER_TYPE => 0, PER_ENTRY => 0}, - uniquename => {GLOBAL => 1, PER_TYPE => 1, PER_ENTRY => 0}, - useauthor => {GLOBAL => 1, PER_TYPE => 1, PER_ENTRY => 1}, - useeditor => {GLOBAL => 1, PER_TYPE => 1, PER_ENTRY => 1}, - useprefix => {GLOBAL => 1, PER_TYPE => 1, PER_ENTRY => 1}, - usetranslator => {GLOBAL => 1, PER_TYPE => 1, PER_ENTRY => 1}, -); - - -1; - -__END__ - -=pod - -=encoding utf-8 - -=head1 NAME - -Biber::Constants - global constants for biber - -=head1 AUTHOR - -François Charette, C<< <firmicus at gmx.net> >> -Philip Kime C<< <philip at kime.org.uk> >> - -=head1 BUGS - -Please report any bugs or feature requests on our sourceforge tracker at -L<https://sourceforge.net/tracker2/?func=browse&group_id=228270>. - -=head1 COPYRIGHT & LICENSE - -Copyright 2009-2011 François Charette and Philip Kime, all rights reserved. - -This module is free software. You can redistribute it and/or -modify it under the terms of the Artistic License 2.0. - -This program is distributed in the hope that it will be useful, -but without any warranty; without even the implied warranty of -merchantability or fitness for a particular purpose. - -=cut - -# vim: set tabstop=2 shiftwidth=2 expandtab: diff --git a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Entries.pm b/Master/texmf-dist/source/bibtex/biber/lib/Biber/Entries.pm deleted file mode 100644 index 90ebff7ce0b..00000000000 --- a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Entries.pm +++ /dev/null @@ -1,111 +0,0 @@ -package Biber::Entries; -#use feature 'unicode_strings'; - -=encoding utf-8 - -=head1 NAME - -Biber::Entries - -=head2 new - - Initialize a Biber::Entries object - -=cut - -sub new { - my ($class) = @_; - my $self = bless {}, $class; - return $self; -} - -=head2 notnull - - Test for an empty object - -=cut - -sub notnull { - my $self = shift; - my @arr = keys %$self; - return $#arr > -1 ? 1 : 0; -} - -=head2 entry_exists - - Boolean values sub to tell if there is an entry - for the passed citation key. - -=cut - -sub entry_exists { - my $self = shift; - my $citekey = lc(shift); - return defined($self->{$citekey}) ? 1 : 0; -} - -=head2 entry - - Returns a Biber::Entry object for a given - citekey - -=cut - -sub entry { - my $self = shift; - my $citekey = lc(shift); - return $self->{$citekey}; -} - -=head2 sorted_keys - - Returns a sorted array of Biber::Entry object keys - -=cut - -sub sorted_keys { - my $self = shift; - use locale; - return sort keys %$self; -} - -=head2 add_entry - - Adds a Biber::Entry to the Biber::Entries object - -=cut - -sub add_entry { - my $self = shift; - my ($key, $entry) = @_; - $key = lc($key); - $self->{$key} = $entry; - return; -} - -=head1 AUTHORS - -François Charette, C<< <firmicus at gmx.net> >> -Philip Kime C<< <philip at kime.org.uk> >> - -=head1 BUGS - -Please report any bugs or feature requests on our sourceforge tracker at -L<https://sourceforge.net/tracker2/?func=browse&group_id=228270>. - -=head1 COPYRIGHT & LICENSE - -Copyright 2009-2011 François Charette and Philip Kime, all rights reserved. - -This module is free software. You can redistribute it and/or -modify it under the terms of the Artistic License 2.0. - -This program is distributed in the hope that it will be useful, -but without any warranty; without even the implied warranty of -merchantability or fitness for a particular purpose. - -=cut - -1; - -# vim: set tabstop=2 shiftwidth=2 expandtab: diff --git a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Entry.pm b/Master/texmf-dist/source/bibtex/biber/lib/Biber/Entry.pm deleted file mode 100644 index 4440a4f3af1..00000000000 --- a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Entry.pm +++ /dev/null @@ -1,397 +0,0 @@ -package Biber::Entry; -#use feature 'unicode_strings'; - -use List::Util qw( first ); -use Biber::Utils; -use Biber::Constants; -use Data::Dump qw( pp ); -use Log::Log4perl qw( :no_extra_logdie_message ); - -my $logger = Log::Log4perl::get_logger('main'); - -=encoding utf-8 - -=head1 NAME - -Biber::Entry - -=head2 new - - Initialize a Biber::Entry object - -=cut - -sub new { - my $class = shift; - my $obj = shift; - my $self; - if (defined($obj) and ref($obj) eq 'HASH') { - $self = bless $obj, $class; - } - else { - $self = bless {}, $class; - } - return $self; -} - -=head2 clone - - Clone a Biber::Entry object and return a copy - Accepts optionally a key for the copy - -=cut - -sub clone { - my $self = shift; - my $newkey = shift; - my $new = new Biber::Entry; - while (my ($k, $v) = each(%{$self->{datafields}})) { - $new->{datafields}{$k} = $v; - } - # Need to add entrytype - $new->{derivedfields}{entrytype} = $self->{derivedfields}{entrytype}; - # put in key if specified - if ($newkey) { - $new->{derivedfields}{dskey} = $newkey; - $new->{derivedfields}{citekey} = $newkey; - } - return $new; -} - -=head2 notnull - - Test for an empty object - -=cut - -sub notnull { - my $self = shift; - my @arr = keys %$self; - return $#arr > -1 ? 1 : 0; -} - -=head2 set_datafield - - Set a field which is in the bib data file - Only set to null if the field is a nullable one - otherwise if value is null, remove the field - -=cut - -sub set_datafield { - my $self = shift; - my ($key, $val) = @_; - my $struc = Biber::Config->get_structure; - # Only set fields which are either not null or are ok to be null - if ( $struc->is_field_type('nullok', $key) or is_notnull($val)) { - $self->{datafields}{$key} = $val; - } - elsif (is_null($val)) { - delete($self->{datafields}{$key}); - } - return; -} - - -=head2 set_field - - Set a derived field for a Biber::Entry object, that is, a field which was not - an actual bibliography field - -=cut - -sub set_field { - my $self = shift; - my ($key, $val) = @_; - # All derived fields can be null - $self->{derivedfields}{$key} = $val; - return; -} - -=head2 get_field - - Get a field for a Biber::Entry object - -=cut - -sub get_field { - my $self = shift; - my $key = shift; - return $self->{datafields}{$key} if exists($self->{datafields}{$key}); - return $self->{derivedfields}{$key} if exists($self->{derivedfields}{$key}); - return undef; -} - -=head2 get_datafield - - Get a field that was in the original data file - -=cut - -sub get_datafield { - my $self = shift; - my $key = shift; - return $self->{datafields}{$key}; -} - - -=head2 del_field - - Delete a field in a Biber::Entry object - -=cut - -sub del_field { - my $self = shift; - my $key = shift; - delete $self->{datafields}{$key}; - delete $self->{derivedfields}{$key}; - return; -} - -=head2 del_datafield - - Delete an original data source data field in a Biber::Entry object - -=cut - -sub del_datafield { - my $self = shift; - my $key = shift; - delete $self->{datafields}{$key}; - return; -} - - -=head2 field_exists - - Check whether a field exists (even if null) - -=cut - -sub field_exists { - my $self = shift; - my $key = shift; - return (exists($self->{datafields}{$key}) or - exists($self->{derivedfields}{$key})) ? 1 : 0; -} - -=head2 datafields - - Returns a sorted array of the fields which came from the data source - -=cut - -sub datafields { - my $self = shift; - use locale; - return sort keys %{$self->{datafields}}; -} - - -=head2 fields - - Returns a sorted array of all field names, including ones - added during processing which are not necessarily fields - which came from the data file - -=cut - -sub fields { - my $self = shift; - use locale; - my %keys = (%{$self->{derivedfields}}, %{$self->{datafields}}); - return sort keys %keys; -} - -=head2 has_keyword - - Check if a Biber::Entry object has a particular keyword in - in the KEYWORDS field. - -=cut - -sub has_keyword { - my $self = shift; - my $keyword = shift; - if (my $keywords = $self->{datafields}{keywords}) { - return (first {lc($_) eq lc($keyword)} split(/\s*,\s*/, $keywords)) ? 1 : 0; - } - else { - return 0; - } - return undef; # shouldn't get here -} - - - -=head2 add_warning - - Append a warning to a Biber::Entry object - -=cut - -sub add_warning { - my $self = shift; - my $warning = shift; - push @{$self->{derivedfields}{'warnings'}}, $warning; - return; -} - -=head2 set_inherit_from - - Inherit fields from parent entry - - $entry->inherit_from($parententry); - - Takes a second Biber::Entry object as argument - Tailored for set inheritance which is a straight 1:1 inheritance, - excluding certain fields for backwards compatibility - -=cut - -sub set_inherit_from { - my $self = shift; - my $parent = shift; - - # Data source fields - foreach my $field ($parent->datafields) { - next if $self->field_exists($field); # Don't overwrite existing fields - $self->set_datafield($field, $parent->get_field($field)); - } - # Datesplit is a special non datafield and needs to be inherited for any - # validation checks which may occur later - if (my $ds = $parent->get_field('datesplit')) { - $self->set_field('datesplit', $ds); - } - return; -} - -=head2 inherit_from - - Inherit fields from parent entry (as indicated by the crossref field) - - $entry->inherit_from($parententry); - - Takes a second Biber::Entry object as argument - Uses the crossref inheritance specifications from the .bcf - -=cut - -sub inherit_from { - my $self = shift; - my $parent = shift; - my $type = $self->get_field('entrytype'); - my $parenttype = $parent->get_field('entrytype'); - my $inheritance = Biber::Config->getblxoption('inheritance'); - my %processed; - # get defaults - my $defaults = $inheritance->{defaults}; - # global defaults ... - my $inherit_all = $defaults->{inherit_all}; - my $override_target = $defaults->{override_target}; - # override with type_pair specific defaults if they exist ... - foreach my $type_pair (@{$defaults->{type_pair}}) { - if (($type_pair->{source} eq '*' or $type_pair->{source} eq $parenttype) and - ($type_pair->{target} eq '*' or $type_pair->{target} eq $type)) { - $inherit_all = $type_pair->{inherit_all} if $type_pair->{inherit_all}; - $override_target = $type_pair->{override_target} if $type_pair->{override_target}; - } - } - - # First process any fields that have special treatment - foreach my $inherit (@{$inheritance->{inherit}}) { - # Match for this combination of entry and crossref parent? - foreach my $type_pair (@{$inherit->{type_pair}}) { - if (($type_pair->{source} eq '*' or $type_pair->{source} eq $parenttype) and - ($type_pair->{target} eq '*' or $type_pair->{target} eq $type)) { - foreach my $field (@{$inherit->{field}}) { - next unless $parent->field_exists($field->{source}); - $processed{$field->{source}} = 1; - # localise defaults according to field, if specified - my $field_override_target = $field->{override_target} - if $field->{override_target}; - # Skip this field if requested - if ($field->{skip}) { - $processed{$field->{source}} = 1; - } - # Set the field if it doesn't exist or override is requested - elsif (not $self->field_exists($field->{target}) or - $field_override_target eq 'true') { - $logger->debug(" Entry '" . - $self->get_field('dskey') . - "' is inheriting field '" . - $field->{source}. - "' as '" . - $field->{target} . - "' from entry '" . - $parent->get_field('dskey') . - "'"); - $self->set_datafield($field->{target}, $parent->get_field($field->{source})); - } - } - } - } - } - - # Now process the rest of the (original data only) fields, if necessary - if ($inherit_all eq 'true') { - foreach my $field ($parent->datafields) { - next if $processed{$field}; # Skip if we already dealt with this field above - # Set the field if it doesn't exist or override is requested - if (not $self->field_exists($field) or $override_target eq 'true') { - $logger->debug(" Entry '" . - $self->get_field('dskey') . - "' is inheriting field '$field' from entry '" . - $parent->get_field('dskey') . - "'"); - $self->set_datafield($field, $parent->get_field($field)); - } - } - } - # Datesplit is a special non datafield and needs to be inherited for any - # validation checks which may occur later - if (my $ds = $parent->get_field('datesplit')) { - $self->set_field('datesplit', $ds); - } - return; -} - -=head2 dump - - Dump Biber::Entry object - -=cut - -sub dump { - my $self = shift; - return pp($self); -} - - -=head1 AUTHORS - -François Charette, C<< <firmicus at gmx.net> >> -Philip Kime C<< <philip at kime.org.uk> >> - -=head1 BUGS - -Please report any bugs or feature requests on our sourceforge tracker at -L<https://sourceforge.net/tracker2/?func=browse&group_id=228270>. - -=head1 COPYRIGHT & LICENSE - -Copyright 2009-2011 François Charette and Philip Kime, all rights reserved. - -This module is free software. You can redistribute it and/or -modify it under the terms of the Artistic License 2.0. - -This program is distributed in the hope that it will be useful, -but without any warranty; without even the implied warranty of -merchantability or fitness for a particular purpose. - -=cut - -1; - -# vim: set tabstop=2 shiftwidth=2 expandtab: diff --git a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Entry/Name.pm b/Master/texmf-dist/source/bibtex/biber/lib/Biber/Entry/Name.pm deleted file mode 100644 index 6fb0899540d..00000000000 --- a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Entry/Name.pm +++ /dev/null @@ -1,506 +0,0 @@ -package Biber::Entry::Name; -#use feature 'unicode_strings'; - -use Regexp::Common qw( balanced ); -use Data::Dump qw( pp ); - -=encoding utf-8 - -=head1 NAME - -Biber::Entry::Name - -=head2 new - - Initialize a Biber::Entry::Name object, optionally with key=>value arguments. - - Ex: Biber::Entry::Name->new( lastname="Bolzmann" firstname=>"Anna Maria" prefix => "von" ) - -=cut - -sub new { - my ($class, %params) = @_; - if (%params) { - my $name = {}; - foreach my $attr (qw/gender - lastname - lastname_i - lastname_it - firstname - firstname_i - firstname_it - middlename - middlename_i - middlename_it - prefix - prefix_i - prefix_it - suffix - suffix_i - suffix_it - namestring - nameinitstring - strip/) { - if (exists $params{$attr}) { - $name->{$attr} = $params{$attr} - } - } - return bless $name, $class; - } else { - return bless {}, $class; - } -} - -=head2 notnull - - Test for an empty object - -=cut - -sub notnull { - my $self = shift; - my @arr = keys %$self; - return $#arr > -1 ? 1 : 0; -} - - -=head2 was_stripped - - Return boolean to tell if the passed field had braces stripped from the original - -=cut - -sub was_stripped { - my ($self, $part) = @_; - return exists($self->{strip}) ? $self->{strip}{$part} : undef; -} - - -=head2 set_firstname - - Set firstname for a Biber::Entry::Name object - -=cut - -sub set_firstname { - my ($self, $val) = @_; - $self->{firstname} = $val; - return; -} - -=head2 get_firstname - - Get firstname for a Biber::Entry::Name object - -=cut - -sub get_firstname { - my $self = shift; - return $self->{firstname}; -} - -=head2 get_firstname_i - - Get firstname initials for a Biber::Entry::Name object - -=cut - -sub get_firstname_i { - my $self = shift; - return $self->{firstname_i}; -} - -=head2 get_firstname_it - - Get firstname terse initials for a Biber::Entry::Name object - -=cut - -sub get_firstname_it { - my $self = shift; - return $self->{firstname_it}; -} - - -=head2 set_middlename - - Set middlename for a Biber::Entry::Name object - -=cut - -sub set_middlename { - my ($self, $val) = @_; - $self->{middlename} = $val; - return; -} - -=head2 get_middlename - - Get middlename for a Biber::Entry::Name object - -=cut - -sub get_middlename { - my $self = shift; - return $self->{middlename}; -} - -=head2 get_middlename_i - - Get middlename initials for a Biber::Entry::Name object - -=cut - -sub get_middlename_i { - my $self = shift; - return $self->{middlename_i}; -} - -=head2 get_middlename_it - - Get middlename terse initials for a Biber::Entry::Name object - -=cut - -sub get_middlename_it { - my $self = shift; - return $self->{middlename_it}; -} - - -=head2 set_lastname - - Set lastname for a Biber::Entry::Name object - -=cut - -sub set_lastname { - my ($self, $val) = @_; - $self->{lastname} = $val; - return; -} - -=head2 get_lastname - - Get lastname for a Biber::Entry::Name object - -=cut - -sub get_lastname { - my $self = shift; - return $self->{lastname}; -} - -=head2 get_lastname_i - - Get lastname initials for a Biber::Entry::Name object - -=cut - -sub get_lastname_i { - my $self = shift; - return $self->{lastname_i}; -} - -=head2 get_lastname_it - - Get lastname terse initials for a Biber::Entry::Name object - -=cut - -sub get_lastname_it { - my $self = shift; - return $self->{lastname_it}; -} - - -=head2 set_suffix - - Set suffix for a Biber::Entry::Name object - -=cut - -sub set_suffix { - my ($self, $val) = @_; - $self->{suffix} = $val; - return; -} - -=head2 get_suffix - - Get suffix for a Biber::Entry::Name object - -=cut - -sub get_suffix { - my $self = shift; - return $self->{suffix}; -} - -=head2 get_suffix_i - - Get suffix initials for a Biber::Entry::Name object - -=cut - -sub get_suffix_i { - my $self = shift; - return $self->{suffix_i}; -} - -=head2 get_suffix_it - - Get suffix terse initials for a Biber::Entry::Name object - -=cut - -sub get_suffix_it { - my $self = shift; - return $self->{suffix_it}; -} - - -=head2 set_prefix - - Set prefix for a Biber::Entry::Name object - -=cut - -sub set_prefix { - my ($self, $val) = @_; - $self->{prefix} = $val; - return; -} - -=head2 get_prefix - - Get prefix for a Biber::Entry::Name object - -=cut - -sub get_prefix { - my $self = shift; - return $self->{prefix}; -} - -=head2 get_prefix_i - - Get prefix initials for a Biber::Entry::Name object - -=cut - -sub get_prefix_i { - my $self = shift; - return $self->{prefix_i}; -} - -=head2 get_prefix_it - - Get prefix terse initials for a Biber::Entry::Name object - -=cut - -sub get_prefix_it { - my $self = shift; - return $self->{prefix_it}; -} - - -=head2 set_gender - - Set gender for a Biber::Entry::Name object - -=cut - -sub set_gender { - my ($self, $val) = @_; - $self->{gender} = $val; - return; -} - -=head2 get_gender - - Get gender for a Biber::Entry::Name object - -=cut - -sub get_gender { - my $self = shift; - return $self->{gender}; -} - - - -=head2 set_namestring - - Set namestring for a Biber::Entry::Name object - -=cut - -sub set_namestring { - my ($self, $val) = @_; - $self->{namestring} = $val; - return; -} - -=head2 get_namestring - - Get namestring for a Biber::Entry::Name object - -=cut - -sub get_namestring { - my $self = shift; - return $self->{namestring}; -} - -=head2 set_nameinitstring - - Set nameinitstring for a Biber::Entry::Name object - -=cut - -sub set_nameinitstring { - my ($self, $val) = @_; - $self->{nameinitstring} = $val; - return; -} - -=head2 get_nameinitstring - - Get nameinitstring for a Biber::Entry::Name object - -=cut - -sub get_nameinitstring { - my $self = shift; - return $self->{nameinitstring}; -} - -=head2 name_to_bbl { - - Return bbl data for a name - -=cut - -sub name_to_bbl { - my $self = shift; - - # lastname is always defined - my $ln = $self->get_lastname; - if ($self->was_stripped('lastname')) { - $ln = Biber::Utils::add_outer($ln); - } - my $lni = Biber::Config->getblxoption('terseinits') ? $self->get_lastname_it : $self->get_lastname_i; - - # firstname - my $fn; - my $fni; - if ($fn = $self->get_firstname) { - if ($self->was_stripped('firstname')) { - $fn = Biber::Utils::add_outer($fn); - } - $fni = Biber::Config->getblxoption('terseinits') ? $self->get_firstname_it : $self->get_firstname_i; - } - else { - $fn = ''; - $fni = ''; - } - - # middlename - my $mn; - my $mni; - if ($mn = $self->get_middlename) { - $mni = Biber::Config->getblxoption('terseinits') ? $self->get_middlename_it : $self->get_middlename_i; - } - else { - $mn = ''; - $mni = ''; - } - - # prefix - my $pre; - my $prei; - if ($pre = $self->get_prefix) { - if ($self->was_stripped('prefix')) { - $pre = Biber::Utils::add_outer($pre); - } - $prei = Biber::Config->getblxoption('terseinits') ? $self->get_prefix_it : $self->get_prefix_i; - } - else { - $pre = ''; - $prei = ''; - } - - # suffix - my $suf; - my $sufi; - if ($suf = $self->get_suffix) { - if ($self->was_stripped('suffix')) { - $suf = Biber::Utils::add_outer($suf); - } - $sufi = Biber::Config->getblxoption('terseinits') ? $self->get_suffix_it : $self->get_suffix_i; - } - else { - $suf = ''; - $sufi = ''; - } - - # Can't just replace all spaces in first names with "~" as this could - # potentially be too long and would do nasty line-break things in LaTeX - # So, be a bit picky and only attach initials/protected things - # J. Frank -> J.~Frank - # {J.\,P.} Frank -> {J.\,P.}~Frank - $fn =~ s/(\p{Lu}\.|$RE{balanced}{-parens=>'{}'})\s+/$1~/g; - # Bernard H. -> Bernard~H. - # Bernard {H.\,P.} -> Bernard~{H.\,P.} - $fn =~ s/\s+(\p{Lu}\.|$RE{balanced}{-parens=>'{}'})/~$1/g; - $pre =~ s/\s/~/g if $pre; # van der -> van~der - # BIBLATEXML supports middle names - if ($self->get_middlename) { - return " {{$ln}{$lni}{$fn}{$fni}{$mn}{$mni}{$pre}{$prei}{$suf}{$sufi}}%\n"; - } - else { - return " {{$ln}{$lni}{$fn}{$fni}{$pre}{$prei}{$suf}{$sufi}}%\n"; - } -} - - -=head2 dump - - Dump Biber::Entry::Name object - -=cut - -sub dump { - my $self = shift; - return pp($self); -} - - -=head1 AUTHORS - -François Charette, C<< <firmicus at gmx.net> >> -Philip Kime C<< <philip at kime.org.uk> >> - -=head1 BUGS - -Please report any bugs or feature requests on our sourceforge tracker at -L<https://sourceforge.net/tracker2/?func=browse&group_id=228270>. - -=head1 COPYRIGHT & LICENSE - -Copyright 2009-2011 François Charette and Philip Kime, all rights reserved. - -This module is free software. You can redistribute it and/or -modify it under the terms of the Artistic License 2.0. - -This program is distributed in the hope that it will be useful, -but without any warranty; without even the implied warranty of -merchantability or fitness for a particular purpose. - -=cut - -1; - -# vim: set tabstop=2 shiftwidth=2 expandtab: diff --git a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Entry/Names.pm b/Master/texmf-dist/source/bibtex/biber/lib/Biber/Entry/Names.pm deleted file mode 100644 index 72cb7dc400d..00000000000 --- a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Entry/Names.pm +++ /dev/null @@ -1,158 +0,0 @@ -package Biber::Entry::Names; -#use feature 'unicode_strings'; - -use Data::Dump; - -=encoding utf-8 - -=head1 NAME - -Biber::Entry::Names - -=head2 new - - Initialize a Biber::Entry::Names object - -=cut - -sub new { - my $class = shift; - return bless [], $class; -} - - -=head2 notnull - - Test for an empty object - -=cut - -sub notnull { - my $self = shift; - my @arr = @$self; - return $#arr > -1 ? 1 : 0; -} - -=head2 names - - Return ref to array of all Biber::Entry::Name objects - in object - -=cut - -sub names { - my $self = shift; - return $self; -} - -=head2 add_element - - Add a Biber::Entry::Name object to the Biber::Entry::Names - object - -=cut - -sub add_element { - my $self = shift; - my $name_obj = shift; - push @$self, $name_obj; - return; -} - -=head2 count_elements - - Returns the number of Biber::Entry::Name objects in the object - -=cut - -sub count_elements { - my $self = shift; - return scalar @$self; -} - -=head2 nth_element - - Returns the nth Biber::Entry::Name object in the object - -=cut - -sub nth_element { - my $self = shift; - my $n = shift; - return @$self[$n-1]; -} - -=head2 first_n_elements - - Returns a new Biber::Entry::Names object containing only - the first n entries of $self - -=cut - -sub first_n_elements { - my $self = shift; - my $n = shift; - return bless [ splice(@$self, 0, $n) ], Biber::Entry::Names; -} - -=head2 del_last_element - - Deletes the last Biber::Entry::Name object in the object - -=cut - -sub del_last_element { - my $self = shift; - pop(@$self); # Don't want the return value of this! - return; -} - -=head2 last_element - - Returns the last Biber::Entry::Name object in the object - -=cut - -sub last_element { - my $self = shift; - return @$self[-1]; -} - -=head2 dump - - Dump a Biber::Entry::Name object for debugging purposes - -=cut - -sub dump { - my $self = shift; - dd($self); - return; -} - -=head1 AUTHORS - -François Charette, C<< <firmicus at gmx.net> >> -Philip Kime C<< <philip at kime.org.uk> >> - -=head1 BUGS - -Please report any bugs or feature requests on our sourceforge tracker at -L<https://sourceforge.net/tracker2/?func=browse&group_id=228270>. - -=head1 COPYRIGHT & LICENSE - -Copyright 2009-2011 François Charette and Philip Kime, all rights reserved. - -This module is free software. You can redistribute it and/or -modify it under the terms of the Artistic License 2.0. - -This program is distributed in the hope that it will be useful, -but without any warranty; without even the implied warranty of -merchantability or fitness for a particular purpose. - -=cut - -1; - -# vim: set tabstop=2 shiftwidth=2 expandtab: diff --git a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Input/file/biblatexml.dcf b/Master/texmf-dist/source/bibtex/biber/lib/Biber/Input/file/biblatexml.dcf deleted file mode 100644 index e17ec28257f..00000000000 --- a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Input/file/biblatexml.dcf +++ /dev/null @@ -1,145 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<?oxygen RNGSchema="../../../../data/schemata/dcf.rnc" type="compact"?> -<dcf:driver-control driver="biblatexml" xmlns:dcf="https://sourceforge.net/projects/biber"> - <!-- - These entry type aliases we might find in the the datasource so - Since biblatexml is specifically for biblatex, there should be no need - for entrytype aliases - a biblatexml file should have only what biblatex expects - --> - - <!-- - Field handlers - --> - <dcf:fields> - <!-- date fields --> - <dcf:field name="date" handler="date"/> - <!-- list fields --> - <dcf:field name="institution" handler="list"/> - <dcf:field name="language" handler="list"/> - <dcf:field name="lista" handler="list"/> - <dcf:field name="listb" handler="list"/> - <dcf:field name="listc" handler="list"/> - <dcf:field name="listd" handler="list"/> - <dcf:field name="liste" handler="list"/> - <dcf:field name="listf" handler="list"/> - <dcf:field name="location" handler="list"/> - <dcf:field name="organization" handler="list"/> - <dcf:field name="origlocation" handler="list"/> - <dcf:field name="origpublisher" handler="list"/> - <dcf:field name="publisher" handler="list"/> - <!-- name fields --> - <dcf:field name="afterword" handler="name"/> - <dcf:field name="annotator" handler="name"/> - <dcf:field name="author" handler="name"/> - <dcf:field name="bookauthor" handler="name"/> - <dcf:field name="commentator" handler="name"/> - <dcf:field name="editor" handler="name"/> - <dcf:field name="editora" handler="name"/> - <dcf:field name="editorb" handler="name"/> - <dcf:field name="editorc" handler="name"/> - <dcf:field name="foreword" handler="name"/> - <dcf:field name="holder" handler="name"/> - <dcf:field name="introduction" handler="name"/> - <dcf:field name="namea" handler="name"/> - <dcf:field name="nameb" handler="name"/> - <dcf:field name="namec" handler="name"/> - <dcf:field name="shortauthor" handler="name"/> - <dcf:field name="shorteditor" handler="name"/> - <dcf:field name="sortname" handler="name"/> - <dcf:field name="translator" handler="name"/> - <!-- range fields --> - <dcf:field name="pages" handler="range"/> - <!-- verbatim fields --> - <dcf:field name="abstract" handler="verbatim"/> - <dcf:field name="addendum" handler="verbatim"/> - <dcf:field name="annotation" handler="verbatim"/> - <dcf:field name="authortype" handler="verbatim"/> - <dcf:field name="bookpagination" handler="verbatim"/> - <dcf:field name="booksubtitle" handler="verbatim"/> - <dcf:field name="booktitle" handler="verbatim"/> - <dcf:field name="booktitleaddon" handler="verbatim"/> - <dcf:field name="chapter" handler="verbatim"/> - <dcf:field name="crossref" handler="verbatim"/> - <dcf:field name="day" handler="verbatim"/> - <dcf:field name="edition" handler="verbatim"/> - <dcf:field name="editoratype" handler="verbatim"/> - <dcf:field name="editorbtype" handler="verbatim"/> - <dcf:field name="editorctype" handler="verbatim"/> - <dcf:field name="editortype" handler="verbatim"/> - <dcf:field name="eid" handler="verbatim"/> - <dcf:field name="entryset" handler="verbatim"/> - <dcf:field name="entrysubtype" handler="verbatim"/> - <dcf:field name="eventtitle" handler="verbatim"/> - <dcf:field name="execute" handler="verbatim"/> - <dcf:field name="hyphenation" handler="verbatim"/> - <dcf:field name="indexsorttitle" handler="verbatim"/> - <dcf:field name="indextitle" handler="verbatim"/> - <dcf:field name="isan" handler="verbatim"/> - <dcf:field name="isbn" handler="verbatim"/> - <dcf:field name="ismn" handler="verbatim"/> - <dcf:field name="isrn" handler="verbatim"/> - <dcf:field name="issn" handler="verbatim"/> - <dcf:field name="issue" handler="verbatim"/> - <dcf:field name="issuesubtitle" handler="verbatim"/> - <dcf:field name="issuetitle" handler="verbatim"/> - <dcf:field name="iswc" handler="verbatim"/> - <dcf:field name="journalsubtitle" handler="verbatim"/> - <dcf:field name="journaltitle" handler="verbatim"/> - <dcf:field name="label" handler="verbatim"/> - <dcf:field name="library" handler="verbatim"/> - <dcf:field name="mainsubtitle" handler="verbatim"/> - <dcf:field name="maintitle" handler="verbatim"/> - <dcf:field name="maintitleaddon" handler="verbatim"/> - <dcf:field name="month" handler="verbatim"/> - <dcf:field name="nameaddon" handler="verbatim"/> - <dcf:field name="nameatype" handler="verbatim"/> - <dcf:field name="namebtype" handler="verbatim"/> - <dcf:field name="namectype" handler="verbatim"/> - <dcf:field name="note" handler="verbatim"/> - <dcf:field name="number" handler="verbatim"/> - <dcf:field name="origlanguage" handler="verbatim"/> - <dcf:field name="origtitle" handler="verbatim"/> - <dcf:field name="pagetotal" handler="verbatim"/> - <dcf:field name="pagination" handler="verbatim"/> - <dcf:field name="part" handler="verbatim"/> - <dcf:field name="presort" handler="verbatim"/> - <dcf:field name="pubstate" handler="verbatim"/> - <dcf:field name="related" handler="verbatim"/> - <dcf:field name="relatedtype" handler="verbatim"/> - <dcf:field name="series" handler="verbatim"/> - <dcf:field name="shorthand" handler="verbatim"/> - <dcf:field name="shorthandintro" handler="verbatim"/> - <dcf:field name="shortjournal" handler="verbatim"/> - <dcf:field name="shortseries" handler="verbatim"/> - <dcf:field name="shorttitle" handler="verbatim"/> - <dcf:field name="sortkey" handler="verbatim"/> - <dcf:field name="sorttitle" handler="verbatim"/> - <dcf:field name="sortyear" handler="verbatim"/> - <dcf:field name="subtitle" handler="verbatim"/> - <dcf:field name="title" handler="verbatim"/> - <dcf:field name="titleaddon" handler="verbatim"/> - <dcf:field name="type" handler="verbatim"/> - <dcf:field name="usera" handler="verbatim"/> - <dcf:field name="userb" handler="verbatim"/> - <dcf:field name="userc" handler="verbatim"/> - <dcf:field name="userd" handler="verbatim"/> - <dcf:field name="usere" handler="verbatim"/> - <dcf:field name="userf" handler="verbatim"/> - <dcf:field name="venue" handler="verbatim"/> - <dcf:field name="version" handler="verbatim"/> - <dcf:field name="volume" handler="verbatim"/> - <dcf:field name="volumes" handler="verbatim"/> - <dcf:field name="xref" handler="verbatim"/> - <dcf:field name="year" handler="verbatim"/> - <dcf:field name="keywords" handler="verbatim"/> - <dcf:field name="options" handler="verbatim"/> - <dcf:field name="doi" handler="verbatim"/> - <dcf:field name="eprint" handler="verbatim"/> - <dcf:field name="file" handler="verbatim"/> - <dcf:field name="url" handler="verbatim"/> - <dcf:field name="verba" handler="verbatim"/> - <dcf:field name="verbb" handler="verbatim"/> - <dcf:field name="verbc" handler="verbatim"/> - </dcf:fields> -</dcf:driver-control> - diff --git a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Input/file/biblatexml.pm b/Master/texmf-dist/source/bibtex/biber/lib/Biber/Input/file/biblatexml.pm deleted file mode 100644 index a16d06e14f3..00000000000 --- a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Input/file/biblatexml.pm +++ /dev/null @@ -1,686 +0,0 @@ -package Biber::Input::file::biblatexml; -#use feature 'unicode_strings'; -use strict; -use warnings; -use Carp; - -use Biber::Constants; -use Biber::Entries; -use Biber::Entry; -use Biber::Entry::Names; -use Biber::Entry::Name; -use Biber::Sections; -use Biber::Section; -use Biber::Structure; -use Biber::Utils; -use Biber::Config; -use Encode; -use File::Spec; -use Log::Log4perl qw(:no_extra_logdie_message); -use base 'Exporter'; -use List::AllUtils qw(first uniq); -use XML::LibXML; -use XML::LibXML::Simple; -use Readonly; -use Data::Dump qw(dump); - -my $logger = Log::Log4perl::get_logger('main'); - -Readonly::Scalar our $BIBLATEXML_NAMESPACE_URI => 'http://biblatex-biber.sourceforge.net/biblatexml'; -Readonly::Scalar our $NS => 'bib'; - -# Handlers for field types -# The names of these have nothing to do whatever with the biblatex field types -# They just started out copying them - they are categories of this specific -# data source date types -my %handlers = ( - 'date' => \&_date, - 'list' => \&_list, - 'name' => \&_name, - 'range' => \&_range, - 'related' => \&_related, - 'verbatim' => \&_verbatim -); - -# we assume that the driver config file is in the same dir as the driver: -(my $vol, my $driver_path, undef) = File::Spec->splitpath( $INC{"Biber/Input/file/biblatexml.pm"} ); - -# Deal with the strange world of Par::Packer paths, see similar code in Biber.pm -my $dcf; -if ($driver_path =~ m|/par\-| and $driver_path !~ m|/inc|) { # a mangled PAR @INC path - $dcf = File::Spec->catpath($vol, "$driver_path/inc/lib/Biber/Input/file", 'biblatexml.dcf'); -} -else { - $dcf = File::Spec->catpath($vol, $driver_path, 'biblatexml.dcf'); -} - -# Read driver config file -my $dcfxml = XML::LibXML::Simple::XMLin($dcf, - 'ForceContent' => 1, - 'ForceArray' => [ - qr/\Aentry-type\z/, - qr/\Afield\z/, - ], - 'NsStrip' => 1, - 'KeyAttr' => ['name']); - -# Check we have the right driver -unless ($dcfxml->{driver} eq 'biblatexml') { - $logger->logdie("Expected driver config type 'biblatexml', got '" . $dcfxml->{driver} . "'"); -} - -=head2 extract_entries - - Main data extraction routine. - Accepts a data source identifier (filename in this case), - preprocesses the file and then looks for the passed keys, - creating entries when it finds them and passes out an - array of keys it didn't find. - -=cut - -sub extract_entries { - my ($biber, $filename, $keys) = @_; - my $secnum = $biber->get_current_section; - my $section = $biber->sections->get_section($secnum); - my $bibentries = $section->bibentries; - my @rkeys = @$keys; - - $logger->trace("Entering extract_entries()"); - - # First make sure we can find the biblatexml file - my $trying_filename = $filename; - unless ($filename = locate_biber_file($filename)) { - $logger->logdie("Cannot find file '$trying_filename'!") - } - - # Set up XML parser and namespace - my $parser = XML::LibXML->new(); - my $bltxml = $parser->parse_file($filename) - or $logger->logcroak("Can't parse file $filename"); - my $xpc = XML::LibXML::XPathContext->new($bltxml); - $xpc->registerNs($NS, $BIBLATEXML_NAMESPACE_URI); - - - - if ($section->is_allkeys) { - $logger->debug("All citekeys will be used for section '$secnum'"); - # Loop over all entries, creating objects - foreach my $entry ($xpc->findnodes("//$NS:entry")) { - $logger->debug('Parsing BibLaTeXML entry object ' . $entry->nodePath); - # We have to pass the datasource cased key to - # create_entry() as this sub needs to know the original case of the - # citation key so we can do case-insensitive key/entry comparisons - # later but we need to put the original citation case when we write - # the .bbl. If we lowercase before this, we lose this information. - # Of course, with allkeys, "citation case" means "datasource entry case" - - # If an entry has no key, ignore it and warn - unless ($entry->hasAttribute('id')) { - $logger->warn("Invalid or undefined BibLaTeXML entry key in file '$filename', skipping ..."); - $biber->{warnings}++; - next; - } - create_entry($biber, $entry->getAttribute('id'), $entry); - } - - # if allkeys, push all bibdata keys into citekeys (if they are not already there) - $section->add_citekeys($section->bibentries->sorted_keys); - $logger->debug("Added all citekeys to section '$secnum': " . join(', ', $section->get_citekeys)); - } - else { - # loop over all keys we're looking for and create objects - $logger->debug('Wanted keys: ' . join(', ', @$keys)); - foreach my $wanted_key (@$keys) { - $logger->debug("Looking for key '$wanted_key' in BibLaTeXML file '$filename'"); - # Cache index keys are lower-cased. This next line effectively implements - # case insensitive citekeys - # This will also get the first match it finds - if (my @entries = $xpc->findnodes("//$NS:entry[\@id='" . lc($wanted_key) . "']")) { - my $entry; - # Check to see if there is more than one entry with this key and warn if so - if ($#entries > 0) { - $logger->warn("Found more than one entry for key '$wanted_key' in '$filename': " . - join(',', map {$_->getAttribute('id')} @entries) . ' - using the first one!'); - $biber->{warnings}++; - } - $entry = $entries[0]; - - $logger->debug("Found key '$wanted_key' in BibLaTeXML file '$filename'"); - $logger->debug('Parsing BibLaTeXML entry object ' . $entry->nodePath); - # See comment above about the importance of the case of the key - # passed to create_entry() - create_entry($biber, $wanted_key, $entry); - # found a key, remove it from the list of keys we want - @rkeys = grep {$wanted_key ne $_} @rkeys; - } - $logger->debug('Wanted keys now: ' . join(', ', @rkeys)); - } - } - - return @rkeys; -} - - - - -=head2 create_entry - - Create a Biber::Entry object from an entry found in a biblatexml data source - -=cut - -sub create_entry { - my ($biber, $dskey, $entry) = @_; - my $secnum = $biber->get_current_section; - my $section = $biber->sections->get_section($secnum); - my $struc = Biber::Config->get_structure; - my $bibentries = $section->bibentries; - - # Want a version of the key that is the same case as any citations which - # reference it, in case they are different. We use this as the .bbl - # entry key - # In case of allkeys, this will just be the datasource key as ->get_citekeys - # returns an empty list - my $citekey = first {lc($dskey) eq lc($_)} $section->get_citekeys; - $citekey = $dskey unless $citekey; - my $lc_key = lc($dskey); - - my $bibentry = new Biber::Entry; - # We record the original keys of both the datasource and citation. They may differ in case. - $bibentry->set_field('dskey', $dskey); - $bibentry->set_field('citekey', $citekey); - - # Set entrytype taking note of any aliases for this datasource driver - if (my $ealias = $dcfxml->{'entry-types'}{'entry-type'}{$entry->getAttribute('entrytype')}) { - $bibentry->set_field('entrytype', $ealias->{aliasof}{content}); - if (my $alsoset = $ealias->{alsoset}) { - unless ($bibentry->field_exists($alsoset->{target})) { - $bibentry->set_field($alsoset->{target}, $alsoset->{value}); - } - } - } - else { - $bibentry->set_field('entrytype', $entry->getAttribute('entrytype')); - } - - # Some entry attributes - if (my $hp = $entry->getAttribute('howpublished')) { - $bibentry->set_datafield('howpublished', $hp); - } - - # We put all the fields we find modulo field aliases into the object. - # Validation happens later and is not datasource dependent - foreach my $f (uniq map {$_->nodeName()} $entry->findnodes("*")) { - - # We have to process local options as early as possible in order - # to make them available for things that need them like name parsing - if (_norm($entry->nodeName) eq 'options') { - if (my $node = _resolve_display_mode($biber, $entry, 'options')) { - $biber->process_entry_options($dskey, $node->textContent()); - } - } - - if (my $fm = $dcfxml->{fields}{field}{_norm($f)}) { - my $to = $f; # By default, field to set internally is the same as data source - # Redirect any alias - if (my $alias = $fm->{aliasof}) { - $logger->debug("Found alias '$alias' of field '$f' in entry '$dskey'"); - # If both a field and its alias is set, warn and delete alias field - if ($entry->findnodes("./$NS:$alias")) { - # Warn as that's wrong - $biber->biber_warn($bibentry, "Field '$f' is aliased to field '$alias' but both are defined in entry with key '$dskey' - skipping field '$f'"); - next; - } - $fm = $dcfxml->{fields}{field}{$alias}; - $to = "$NS:$alias"; # Field to set internally is the alias - } - &{$handlers{$fm->{handler}}}($biber, $bibentry, $entry, $f, $to, $dskey); - } - # Default if no explicit way to set the field - else { - my $node = _resolve_display_mode($biber, $entry, $f); - my $value = $node->textContent(); - $bibentry->set_datafield($f, $value); - } - } - - $bibentry->set_field('datatype', 'biblatexml'); - $bibentries->add_entry($lc_key, $bibentry); - - return; -} - - -# Related entries -sub _related { - my ($biber, $bibentry, $entry, $f, $to, $dskey) = @_; - # Pick out the node with the right mode - my $node = _resolve_display_mode($biber, $entry, $f); - # TODO - # Current biblatex data model doesn't allow for multiple items here - foreach my $item ($node->findnodes("./$NS:item")) { - $bibentry->set_datafield('related', $item->getAttribute('ids')); - $bibentry->set_datafield('relatedtype', $item->getAttribute('type')); - if (my $string = $item->getAttribute('string')) { - $bibentry->set_datafield('relatedstring', $string); - } - } - return; -} - -# Verbatim fields -sub _verbatim { - my ($biber, $bibentry, $entry, $f, $to, $dskey) = @_; - # Pick out the node with the right mode - my $node = _resolve_display_mode($biber, $entry, $f); - - # eprint is special case - if ($f eq "$NS:eprint") { - $bibentry->set_datafield('eprinttype', $node->getAttribute('type')); - if (my $ec = $node->getAttribute('class')) { - $bibentry->set_datafield('eprintclass', $ec); - } - } - else { - $bibentry->set_datafield(_norm($to), $node->textContent()); - } - return; -} - -# List fields -sub _list { - my ($biber, $bibentry, $entry, $f, $to, $dskey) = @_; - # Pick out the node with the right mode - my $node = _resolve_display_mode($biber, $entry, $f); - $bibentry->set_datafield(_norm($to), _split_list($node)); - return; -} - -# Range fields -sub _range { - my ($biber, $bibentry, $entry, $f, $to, $dskey) = @_; - # Pick out the node with the right mode - my $node = _resolve_display_mode($biber, $entry, $f); - # List of ranges/values - if (my @rangelist = $node->findnodes("./$NS:list/$NS:item")) { - my $rl; - foreach my $range (@rangelist) { - push @$rl, _parse_range_list($range); - } - $bibentry->set_datafield(_norm($to), $rl); - } - # Simple range - elsif (my $range = $node->findnodes("./$NS:range")->get_node(1)) { - $bibentry->set_datafield(_norm($to), [ _parse_range_list($range) ]); - } - # simple list - else { - $bibentry->set_datafield(_norm($to), $node->textContent()); - } - return; -} - -# Date fields -sub _date { - my ($biber, $bibentry, $entry, $f, $to, $dskey) = @_; - foreach my $node ($entry->findnodes("./$f")) { - my $datetype = $node->getAttribute('datetype') // ''; - # We are not validating dates here, just syntax parsing - my $date_re = qr/(\d{4}) # year - (?:-(\d{2}))? # month - (?:-(\d{2}))? # day - /xms; - if (my $start = $node->findnodes("./$NS:start")) { # Date range - my $end = $node->findnodes("./$NS:end"); - # Start of range - if (my ($byear, $bmonth, $bday) = - $start->get_node(1)->textContent() =~ m|\A$date_re\z|xms) { - $bibentry->set_datafield($datetype . 'year', $byear) if $byear; - $bibentry->set_datafield($datetype . 'month', $bmonth) if $bmonth; - $bibentry->set_datafield($datetype . 'day', $bday) if $bday; - } - else { - $biber->biber_warn($bibentry, "Invalid format '" . $start->get_node(1)->textContent() . "' of date field '$f' range start in entry '$dskey' - ignoring"); - } - - # End of range - if (my ($eyear, $emonth, $eday) = - $end->get_node(1)->textContent() =~ m|\A(?:$date_re)?\z|xms) { - $bibentry->set_datafield($datetype . 'endmonth', $emonth) if $emonth; - $bibentry->set_datafield($datetype . 'endday', $eday) if $eday; - if ($eyear) { # normal range - $bibentry->set_datafield($datetype . 'endyear', $eyear); - } - else { # open ended range - endyear is defined but empty - $bibentry->set_datafield($datetype . 'endyear', ''); - } - } - else { - $biber->biber_warn($bibentry, "Invalid format '" . $end->get_node(1)->textContent() . "' of date field '$f' range end in entry '$dskey' - ignoring"); - } - } - else { # Simple date - if (my ($byear, $bmonth, $bday) = - $node->textContent() =~ m|\A$date_re\z|xms) { - # did this entry get its year/month fields from splitting an ISO8601 date field? - # We only need to know this for date, year/month as year/month can also - # be explicitly set. It makes a difference on how we do any potential future - # date validation - $bibentry->set_field('datesplit', 1) if $datetype eq ''; - $bibentry->set_datafield($datetype . 'year', $byear) if $byear; - $bibentry->set_datafield($datetype . 'month', $bmonth) if $bmonth; - $bibentry->set_datafield($datetype . 'day', $bday) if $bday; - } - else { - $biber->biber_warn($bibentry, "Invalid format '" . $node->textContent() . "' of date field '$f' in entry '$dskey' - ignoring"); - } - } - } - return; -} - -# Name fields -sub _name { - my ($biber, $bibentry, $entry, $f, $to, $dskey) = @_; - # Pick out the node with the right mode - my $node = _resolve_display_mode($biber, $entry, $f); - my $useprefix = Biber::Config->getblxoption('useprefix', $bibentry->get_field('entrytype'), lc($dskey)); - my $names = new Biber::Entry::Names; - foreach my $name ($node->findnodes("./$NS:person")) { - $names->add_element(parsename($name, $f, {useprefix => $useprefix})); - } - $bibentry->set_datafield(_norm($to), $names); - return; -} - -=head2 parsename - - Given a name node, this function returns a Biber::Entry::Name object - - Returns an object which internally looks a bit like this: - - { firstname => 'John', - firstname_i => 'J.', - firstname_it => 'J', - middlename => 'Fred', - middlename_i => 'F.', - middlename_it => 'F', - lastname => 'Doe', - lastname_i => 'D.', - lastname_it => 'D', - prefix => undef, - prefix_i => undef, - prefix_it => undef, - suffix => undef, - suffix_i => undef, - suffix_it => undef, - namestring => 'Doe, John Fred', - nameinitstring => 'Doe_JF', - gender => sm - -=cut - -sub parsename { - my ($node, $fieldname, $opts) = @_; - $logger->debug('Parsing BibLaTeXML name object ' . $node->nodePath); - my $usepre = $opts->{useprefix}; - - my %namec; - - my $gender = $node->getAttribute('gender'); - - foreach my $n ('last', 'first', 'middle', 'prefix', 'suffix') { - # If there is a name component node for this component ... - if (my $nc_node = $node->findnodes("./$NS:$n")->get_node(1)) { - # name component with parts - if (my @parts = map {$_->textContent()} $nc_node->findnodes("./$NS:namepart")) { - $namec{$n} = _join_name_parts(\@parts); - $logger->debug("Found name component '$n': " . $namec{$n}); - if (my $nin = $node->findnodes("./$NS:${n}initial")->get_node(1)) { - my $ni = $nin->textContent(); - $ni =~ s/\.\z//xms; # normalise initials to without period - $ni =~ s/\s+/~/xms; # normalise spaces to ties - $namec{"${n}_it"} = $ni; - $namec{"${n}_i"} = $ni . '.'; - } - else { - ($namec{"${n}_i"}, $namec{"${n}_it"}) = _gen_initials(\@parts); - } - } - # with no parts - elsif (my $t = $nc_node->textContent()) { - $namec{$n} = $t; - $logger->debug("Found name component '$n': $t"); - if (my $nin = $node->findnodes("./$NS:${n}initial")->get_node(1)) { - my $ni = $nin->textContent(); - $ni =~ s/\.\z//xms; # normalise initials to without period - $ni =~ s/\s+/~/xms; # normalise spaces to ties - $namec{"${n}_it"} = $ni; - $namec{"${n}_i"} = $ni . '.'; - } - else { - ($namec{"${n}_i"}, $namec{"${n}_it"}) = _gen_initials([$t]); - } - } - } - } - - # Only warn about lastnames since there should always be one - $logger->warn("Couldn't determine Lastname for name XPath: " . $node->nodePath) unless exists($namec{last}); - - my $namestring = ''; - - # prefix - if (my $p = $namec{prefix}) { - $namestring .= "$p "; - } - - # lastname - if (my $l = $namec{last}) { - $namestring .= "$l, "; - } - - # suffix - if (my $s = $namec{suffix}) { - $namestring .= "$s, "; - } - - # firstname - if (my $f = $namec{first}) { - $namestring .= "$f"; - } - - # middlename - if (my $m = $namec{middle}) { - $namestring .= "$m, "; - } - - # Remove any trailing comma and space if, e.g. missing firstname - # Replace any nbspes - $namestring =~ s/,\s+\z//xms; - $namestring =~ s/~/ /gxms; - - # Construct $nameinitstring - my $nameinitstr = ''; - $nameinitstr .= $namec{prefix_it} . '_' if ( $usepre and exists($namec{prefix}) ); - $nameinitstr .= $namec{last} if exists($namec{last}); - $nameinitstr .= '_' . $namec{suffix_it} if exists($namec{suffix}); - $nameinitstr .= '_' . $namec{first_it} if exists($namec{first}); - $nameinitstr .= '_' . $namec{middle_it} if exists($namec{middle}); - $nameinitstr =~ s/\s+/_/g; - $nameinitstr =~ s/~/_/g; - - return Biber::Entry::Name->new( - firstname => $namec{first} // undef, - firstname_i => exists($namec{first}) ? $namec{first_i} : undef, - firstname_it => exists($namec{first}) ? $namec{first_it} : undef, - middlename => $namec{middle} // undef, - middlename_i => exists($namec{middle}) ? $namec{middle_i} : undef, - middlename_it => exists($namec{middle}) ? $namec{middle_it} : undef, - lastname => $namec{last} // undef, - lastname_i => exists($namec{last}) ? $namec{last_i} : undef, - lastname_it => exists($namec{last}) ? $namec{last_it} : undef, - prefix => $namec{prefix} // undef, - prefix_i => exists($namec{prefix}) ? $namec{prefix_i} : undef, - prefix_it => exists($namec{prefix}) ? $namec{prefix_it} : undef, - suffix => $namec{suffix} // undef, - suffix_i => exists($namec{suffix}) ? $namec{suffix_i} : undef, - suffix_it => exists($namec{suffix}) ? $namec{suffix_it} : undef, - namestring => $namestring, - nameinitstring => $nameinitstr, - gender => $gender - ); -} - - - - -# Joins name parts using BibTeX tie algorithm. Ties are added: -# -# 1. After the first part if it is less than three characters long -# 2. Before the last part -sub _join_name_parts { - my $parts = shift; - # special case - 1 part - if ($#{$parts} == 0) { - return $parts->[0]; - } - # special case - 2 parts - if ($#{$parts} == 1) { - return $parts->[0] . '~' . $parts->[1]; - } - my $namestring = $parts->[0]; - $namestring .= length($parts->[0]) < 3 ? '~' : ' '; - $namestring .= join(' ', @$parts[1 .. ($#{$parts} - 1)]); - $namestring .= '~' . $parts->[$#{$parts}]; - return $namestring; -} - -# Passed an array ref of strings, returns an array of two strings, -# the first is the TeX initials and the second the terse initials -sub _gen_initials { - my $strings_ref = shift; - my @strings; - foreach my $str (@$strings_ref) { - my $chr = substr($str, 0, 1); - # Keep diacritics with their following characters - if ($chr =~ m/\p{Dia}/) { - push @strings, substr($str, 0, 2); - } - else { - push @strings, substr($str, 0, 1); - } - } - return (join('.~', @strings) . '.', join('', @strings)); -} - -# parses a range and returns a ref to an array of start and end values -sub _parse_range_list { - my $rangenode = shift; - my $start = ''; - my $end = ''; - if (my $s = $rangenode->findnodes("./$NS:start")) { - $start = $s->get_node(1)->textContent(); - } - if (my $e = $rangenode->findnodes("./$NS:end")) { - $end = $e->get_node(1)->textContent(); - } - return [$start, $end]; -} - - - -# Splits a list field into an array ref -sub _split_list { - my $node = shift; - if (my @list = $node->findnodes("./$NS:item")) { - return [ map {$_->textContent()} @list ]; - } - else { - return [ $node->textContent() ]; - } -} - - -# Given an entry and a fieldname, returns the field node with the right language mode -sub _resolve_display_mode { - my ($biber, $entry, $fieldname) = @_; - my @nodelist; - my $dm = Biber::Config->getblxoption('displaymode'); - $logger->debug("Resolving display mode for '$fieldname' in node " . $entry->nodePath ); - # Either a fieldname specific mode or the default - my $modelist = $dm->{_norm($fieldname)} || $dm->{'*'}; - foreach my $mode (@$modelist) { - my $modeattr; - # mode is omissable if it is "original" - if ($mode eq 'original') { - $mode = 'original'; - $modeattr = "\@mode='$mode' or not(\@mode)" - } - else { - $modeattr = "\@mode='$mode'" - } - $logger->debug("Found display mode '$mode' for field '$fieldname'"); - if (@nodelist = $entry->findnodes("./${fieldname}[$modeattr]")) { - # Check to see if there is more than one entry with a mode and warn - if ($#nodelist > 0) { - $logger->warn("Found more than one mode '$mode' '$fieldname' field in entry '" . - $entry->getAttribute('id') . "' - using the first one!"); - $biber->{warnings}++; - } - return $nodelist[0]; - } - } - return undef; # Shouldn't get here -} - -# normalise a node name as they have a namsespace and might not be lowercase -sub _norm { - my $name = lc(shift); - $name =~ s/\A$NS://xms; - return $name; -} - - -1; - -__END__ - -=pod - -=encoding utf-8 - -=head1 NAME - -Biber::Input::file::biblatexml - look in a BibLaTeXML file for an entry and create it if found - -=head1 DESCRIPTION - -Provides the extract_entries() method to get entries from a biblatexml data source -and instantiate Biber::Entry objects for what it finds - -=head1 AUTHOR - -François Charette, C<< <firmicus at gmx.net> >> -Philip Kime C<< <philip at kime.org.uk> >> - -=head1 BUGS - -Please report any bugs or feature requests on our sourceforge tracker at -L<https://sourceforge.net/tracker2/?func=browse&group_id=228270>. - -=head1 COPYRIGHT & LICENSE - -Copyright 2009-2011 François Charette and Philip Kime, all rights reserved. - -This module is free software. You can redistribute it and/or -modify it under the terms of the Artistic License 2.0. - -This program is distributed in the hope that it will be useful, -but without any warranty; without even the implied warranty of -merchantability or fitness for a particular purpose. - -=cut - -# vim: set tabstop=2 shiftwidth=2 expandtab: diff --git a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Input/file/bibtex.dcf b/Master/texmf-dist/source/bibtex/biber/lib/Biber/Input/file/bibtex.dcf deleted file mode 100644 index f87de0cc6ac..00000000000 --- a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Input/file/bibtex.dcf +++ /dev/null @@ -1,191 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<?oxygen RNGSchema="../../../../data/schemata/dcf.rnc" type="compact"?> -<dcf:driver-control driver="bibtex" xmlns:dcf="https://sourceforge.net/projects/biber"> - <!-- - These entry type aliases we might find in the the datasource so - we can decide how to map and convert them into Biber::Entry objects - We are not validating anything here, that comes later and is not - datasource specific - --> - <dcf:entry-types> - <dcf:entry-type name="conference"> - <dcf:aliasof>inproceedings</dcf:aliasof> - </dcf:entry-type> - <dcf:entry-type name="electronic"> - <dcf:aliasof>online</dcf:aliasof> - </dcf:entry-type> - <dcf:entry-type name="www"> - <dcf:aliasof>online</dcf:aliasof> - </dcf:entry-type> - <dcf:entry-type name="mastersthesis"> - <dcf:aliasof>thesis</dcf:aliasof> - <dcf:alsoset target="type" value="mathesis"/> - </dcf:entry-type> - <dcf:entry-type name="phdthesis"> - <dcf:aliasof>thesis</dcf:aliasof> - <dcf:alsoset target="type" value="phdthesis"/> - </dcf:entry-type> - <dcf:entry-type name="techreport"> - <dcf:aliasof>report</dcf:aliasof> - <dcf:alsoset target="type" value="techreport"/> - </dcf:entry-type> - </dcf:entry-types> - <!-- - These are the fields we expect to find in the the datasource so - we can decide how to map and convert them into Biber::Entry fields - This has nothing conceptually to do with the internal structure - setup, it's a datasource driver specific set of settings to allow - parsing into internal objects. It looks very similar to aspects - of the Biber::Structure defaults because biber/biblatex was developed - at first as a solely bibtex datasource project. - --> - <dcf:fields> - <!-- date fields --> - <dcf:field name="date" handler="date"/> - <dcf:field name="eventdate" handler="date"/> - <dcf:field name="origdate" handler="date"/> - <dcf:field name="urldate" handler="date"/> - <!-- list fields --> - <dcf:field name="address" aliasof="location"/> - <dcf:field name="institution" handler="list"/> - <dcf:field name="language" handler="list"/> - <dcf:field name="lista" handler="list"/> - <dcf:field name="listb" handler="list"/> - <dcf:field name="listc" handler="list"/> - <dcf:field name="listd" handler="list"/> - <dcf:field name="liste" handler="list"/> - <dcf:field name="listf" handler="list"/> - <dcf:field name="location" handler="list"/> - <dcf:field name="organization" handler="list"/> - <dcf:field name="origlocation" handler="list"/> - <dcf:field name="origpublisher" handler="list"/> - <dcf:field name="publisher" handler="list"/> - <dcf:field name="school" aliasof="institution"/> - <!-- literal fields --> - <dcf:field name="abstract" handler="literal"/> - <dcf:field name="addendum" handler="literal"/> - <dcf:field name="annotation" handler="literal"/> - <dcf:field name="annote" aliasof="annotation"/> - <dcf:field name="archiveprefix" aliasof="eprinttype"/> - <dcf:field name="authortype" handler="literal"/> - <dcf:field name="bookpagination" handler="literal"/> - <dcf:field name="booksubtitle" handler="literal"/> - <dcf:field name="booktitle" handler="literal"/> - <dcf:field name="booktitleaddon" handler="literal"/> - <dcf:field name="chapter" handler="literal"/> - <dcf:field name="crossref" handler="literal"/> - <dcf:field name="day" handler="literal"/> - <dcf:field name="edition" handler="literal"/> - <dcf:field name="editoratype" handler="literal"/> - <dcf:field name="editorbtype" handler="literal"/> - <dcf:field name="editorctype" handler="literal"/> - <dcf:field name="editortype" handler="literal"/> - <dcf:field name="eid" handler="literal"/> - <dcf:field name="entryset" handler="literal"/> - <dcf:field name="entrysubtype" handler="literal"/> - <dcf:field name="eprintclass" handler="literal"/> - <dcf:field name="eprinttype" handler="literal"/> - <dcf:field name="eventtitle" handler="literal"/> - <dcf:field name="execute" handler="literal"/> - <dcf:field name="gender" handler="literal"/> - <dcf:field name="howpublished" handler="literal"/> - <dcf:field name="hyphenation" handler="literal"/> - <dcf:field name="indexsorttitle" handler="literal"/> - <dcf:field name="indextitle" handler="literal"/> - <dcf:field name="isan" handler="literal"/> - <dcf:field name="isbn" handler="literal"/> - <dcf:field name="ismn" handler="literal"/> - <dcf:field name="isrn" handler="literal"/> - <dcf:field name="issn" handler="literal"/> - <dcf:field name="issue" handler="literal"/> - <dcf:field name="issuesubtitle" handler="literal"/> - <dcf:field name="issuetitle" handler="literal"/> - <dcf:field name="iswc" handler="literal"/> - <dcf:field name="journal" aliasof="journaltitle"/> - <dcf:field name="journalsubtitle" handler="literal"/> - <dcf:field name="journaltitle" handler="literal"/> - <dcf:field name="key" aliasof="sortkey"/> - <dcf:field name="label" handler="literal"/> - <dcf:field name="library" handler="literal"/> - <dcf:field name="mainsubtitle" handler="literal"/> - <dcf:field name="maintitle" handler="literal"/> - <dcf:field name="maintitleaddon" handler="literal"/> - <dcf:field name="month" handler="literal"/> - <dcf:field name="nameaddon" handler="literal"/> - <dcf:field name="nameatype" handler="literal"/> - <dcf:field name="namebtype" handler="literal"/> - <dcf:field name="namectype" handler="literal"/> - <dcf:field name="note" handler="literal"/> - <dcf:field name="number" handler="literal"/> - <dcf:field name="origlanguage" handler="literal"/> - <dcf:field name="origtitle" handler="literal"/> - <dcf:field name="pagetotal" handler="literal"/> - <dcf:field name="pagination" handler="literal"/> - <dcf:field name="part" handler="literal"/> - <dcf:field name="presort" handler="literal"/> - <dcf:field name="primaryclass" aliasof="eprintclass"/> - <dcf:field name="pubstate" handler="literal"/> - <dcf:field name="related" handler="literal"/> - <dcf:field name="relatedtype" handler="literal"/> - <dcf:field name="reprinttitle" handler="literal"/> - <dcf:field name="series" handler="literal"/> - <dcf:field name="shorthand" handler="literal"/> - <dcf:field name="shorthandintro" handler="literal"/> - <dcf:field name="shortjournal" handler="literal"/> - <dcf:field name="shortseries" handler="literal"/> - <dcf:field name="shorttitle" handler="literal"/> - <dcf:field name="sortkey" handler="literal"/> - <dcf:field name="sorttitle" handler="literal"/> - <dcf:field name="sortyear" handler="literal"/> - <dcf:field name="subtitle" handler="literal"/> - <dcf:field name="title" handler="literal"/> - <dcf:field name="titleaddon" handler="literal"/> - <dcf:field name="type" handler="literal"/> - <dcf:field name="usera" handler="literal"/> - <dcf:field name="userb" handler="literal"/> - <dcf:field name="userc" handler="literal"/> - <dcf:field name="userd" handler="literal"/> - <dcf:field name="usere" handler="literal"/> - <dcf:field name="userf" handler="literal"/> - <dcf:field name="venue" handler="literal"/> - <dcf:field name="version" handler="literal"/> - <dcf:field name="volume" handler="literal"/> - <dcf:field name="volumes" handler="literal"/> - <dcf:field name="xref" handler="literal"/> - <dcf:field name="year" handler="literal"/> - <!-- name fields --> - <dcf:field name="afterword" handler="name"/> - <dcf:field name="annotator" handler="name"/> - <dcf:field name="author" handler="name"/> - <dcf:field name="bookauthor" handler="name"/> - <dcf:field name="commentator" handler="name"/> - <dcf:field name="editor" handler="name"/> - <dcf:field name="editora" handler="name"/> - <dcf:field name="editorb" handler="name"/> - <dcf:field name="editorc" handler="name"/> - <dcf:field name="foreword" handler="name"/> - <dcf:field name="holder" handler="name"/> - <dcf:field name="introduction" handler="name"/> - <dcf:field name="namea" handler="name"/> - <dcf:field name="nameb" handler="name"/> - <dcf:field name="namec" handler="name"/> - <dcf:field name="shortauthor" handler="name"/> - <dcf:field name="shorteditor" handler="name"/> - <dcf:field name="sortname" handler="name"/> - <dcf:field name="translator" handler="name"/> - <!-- range fields --> - <dcf:field name="pages" handler="range"/> - <!-- verbatim fields --> - <dcf:field name="keywords" handler="verbatim"/> - <dcf:field name="options" handler="verbatim"/> - <dcf:field name="doi" handler="verbatim"/> - <dcf:field name="eprint" handler="verbatim"/> - <dcf:field name="file" handler="verbatim"/> - <dcf:field name="pdf" aliasof="file"/> - <dcf:field name="url" handler="verbatim"/> - <dcf:field name="verba" handler="verbatim"/> - <dcf:field name="verbb" handler="verbatim"/> - <dcf:field name="verbc" handler="verbatim"/> - </dcf:fields> -</dcf:driver-control> - diff --git a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Input/file/bibtex.pm b/Master/texmf-dist/source/bibtex/biber/lib/Biber/Input/file/bibtex.pm deleted file mode 100644 index 0eb684d21e7..00000000000 --- a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Input/file/bibtex.pm +++ /dev/null @@ -1,820 +0,0 @@ -package Biber::Input::file::bibtex; -#use feature 'unicode_strings'; -use sigtrap qw(handler TBSIG SEGV); -use strict; -use warnings; -use Carp; - -use Text::BibTeX 0.50 qw(:nameparts :joinmethods :metatypes); -use Text::BibTeX::Name; -use Text::BibTeX::NameFormat; -use Biber::Constants; -use Biber::Entries; -use Biber::Entry; -use Biber::Entry::Names; -use Biber::Entry::Name; -use Biber::Sections; -use Biber::Section; -use Biber::Structure; -use Biber::Utils; -use Biber::Config; -use Encode; -use File::Spec; -use Log::Log4perl qw(:no_extra_logdie_message); -use base 'Exporter'; -use List::AllUtils qw(first); -use XML::LibXML::Simple; - -my $logger = Log::Log4perl::get_logger('main'); - -our $cache = {}; - -# Handlers for field types -# The names of these have nothing to do whatever with the biblatex field types -# They just started out copying them - they are categories of this specific -# data source date types -my %handlers = ( - 'date' => \&_date, - 'list' => \&_list, - 'literal' => \&_literal, - 'name' => \&_name, - 'range' => \&_range, - 'verbatim' => \&_verbatim -); - - -# we assume that the driver config file is in the same dir as the driver: -(my $vol, my $driver_path, undef) = File::Spec->splitpath( $INC{"Biber/Input/file/bibtex.pm"} ); - -# Deal with the strange world of Par::Packer paths, see similar code in Biber.pm -my $dcf; -if ($driver_path =~ m|/par\-| and $driver_path !~ m|/inc|) { # a mangled PAR @INC path - $dcf = File::Spec->catpath($vol, "$driver_path/inc/lib/Biber/Input/file", 'bibtex.dcf'); -} -else { - $dcf = File::Spec->catpath($vol, $driver_path, 'bibtex.dcf'); -} - -# Read driver config file -my $dcfxml = XML::LibXML::Simple::XMLin($dcf, - 'ForceContent' => 1, - 'ForceArray' => [ - qr/\Aentry-type\z/, - qr/\Afield\z/, - ], - 'NsStrip' => 1, - 'KeyAttr' => ['name']); - -# Check we have the right driver -unless ($dcfxml->{driver} eq 'bibtex') { - $logger->logdie("Expected driver config type 'bibtex', got '" . $dcfxml->{driver} . "'"); -} - -=head2 TBSIG - - Signal handler to catch fatal Text::BibTex SEGFAULTS. It has bugs - and we want to say at least something if it coredumps - -=cut - -sub TBSIG { - my $sig = shift; - $logger->logdie("Caught signal: $sig\nLikely your .bib has a bad entry: $!"); -} - -=head2 extract_entries - - Main data extraction routine. - Accepts a data source identifier, preprocesses the file and then - looks for the passed keys, creating entries when it finds them and - passes out an array of keys it didn't find. - -=cut - -sub extract_entries { - my ($biber, $filename, $keys) = @_; - my $secnum = $biber->get_current_section; - my $section = $biber->sections->get_section($secnum); - my $bibentries = $section->bibentries; - my @rkeys = @$keys; - my $tf; # Up here so that the temp file has enough scope to survive until we've - # used it - $logger->trace("Entering extract_entries()"); - - # If it's a remote .bib file, fetch it first - if ($filename =~ m/\A(?:https?|ftp):/xms) { - $logger->info("Data source '$filename' is a remote .bib - fetching ..."); - require LWP::Simple; - require File::Temp; - $tf = File::Temp->new(SUFFIX => '.bib'); - unless (LWP::Simple::getstore($filename, $tf->filename) == 200) { - $logger->logdie ("Could not fetch file '$filename'"); - } - $filename = $tf->filename; - } - else { - # Need to get the filename even if using cache so we increment - # the filename count for preambles at the bottom of this sub - my $trying_filename = $filename; - unless ($filename = locate_biber_file($filename)) { - $logger->logdie("Cannot find file '$trying_filename'!") - } - } - - # Text::BibTeX can't be controlled by Log4perl so we have to do something clumsy - if (Biber::Config->getoption('quiet')) { - open OLDERR, '>&', \*STDERR; - open STDERR, '>', '/dev/null'; - } - - # Don't read the file again if it's already cached - unless ($cache->{data}{$filename}) { - $logger->debug("Caching data for bibtex format file '$filename' for section $secnum"); - cache_data($biber, $filename); - } - else { - $logger->debug("Using cached data for bibtex format file '$filename' for section $secnum"); - } - - if ($section->is_allkeys) { - $logger->debug("All cached citekeys will be used for section '$secnum'"); - # Loop over all entries, creating objects - while (my (undef, $entry) = each %{$cache->{data}{$filename}}) { - # We have to pass the datasource cased (and UTF-8ed) key to - # create_entry() as this sub needs to know the original case of the - # citation key so we can do case-insensitive key/entry comparisons - # later but we need to put the original citation case when we write - # the .bbl. If we lowercase before this, we lose this information. - # Of course, with allkeys, "citation case" means "datasource entry case" - create_entry($biber, decode_utf8($entry->key), $entry); - } - - # if allkeys, push all bibdata keys into citekeys (if they are not already there) - $section->add_citekeys($section->bibentries->sorted_keys); - $logger->debug("Added all citekeys to section '$secnum': " . join(', ', $section->get_citekeys)); - } - else { - # loop over all keys we're looking for and create objects - $logger->debug('Text::BibTeX cache keys: ' . join(', ', keys %{$cache->{data}{$filename}})); - $logger->debug('Wanted keys: ' . join(', ', @$keys)); - foreach my $wanted_key (@$keys) { - $logger->debug("Looking for key '$wanted_key' in Text::BibTeX cache"); - # Cache index keys are lower-cased. This next line effectively implements - # case insensitive citekeys - if (my $entry = $cache->{data}{$filename}{lc($wanted_key)}) { - $logger->debug("Found key '$wanted_key' in Text::BibTeX cache"); - # See comment above about the importance of the case of the key - # passed to create_entry() - create_entry($biber, $wanted_key, $entry); - # found a key, remove it from the list of keys we want - @rkeys = grep {$wanted_key ne $_} @rkeys; - } - $logger->debug('Wanted keys now: ' . join(', ', @rkeys)); - } - } - - if (Biber::Config->getoption('quiet')) { - open STDERR, '>&', \*OLDERR; - } - - # Only push the preambles from the file if we haven't seen this data file before - # and there are some preambles to push - if ($cache->{counts}{$filename} < 2 and @{$cache->{preamble}{$filename}}) { - push @{$biber->{preamble}}, @{$cache->{preamble}{$filename}}; - } - - return @rkeys; -} - -=head2 create_entry - - Create a Biber::Entry object from a Text::BibTeX object - -=cut - -sub create_entry { - my ($biber, $dskey, $entry) = @_; - my $secnum = $biber->get_current_section; - my $section = $biber->sections->get_section($secnum); - my $bibentries = $section->bibentries; - - # Want a version of the key that is the same case as any citations which - # reference it, in case they are different. We use this as the .bbl - # entry key - # In case of allkeys, this will just be the datasource key as ->get_citekeys - # returns an empty list - my $citekey = first {lc($dskey) eq lc($_)} $section->get_citekeys; - $citekey = $dskey unless $citekey; - my $lc_key = lc($dskey); - - my $bibentry = new Biber::Entry; - # We record the original keys of both the datasource and citation. They may differ in case. - $bibentry->set_field('dskey', $dskey); - $bibentry->set_field('citekey', $citekey); - - if ( $entry->metatype == BTE_REGULAR ) { - - # Set entrytype taking note of any aliases for this datasource driver - if (my $ealias = $dcfxml->{'entry-types'}{'entry-type'}{$entry->type}) { - $bibentry->set_field('entrytype', $ealias->{aliasof}{content}); - if (my $alsoset = $ealias->{alsoset}) { - unless ($bibentry->field_exists($alsoset->{target})) { - $bibentry->set_field($alsoset->{target}, $alsoset->{value}); - } - } - } - else { - $bibentry->set_field('entrytype', $entry->type); - } - - # We put all the fields we find modulo field aliases into the object - # validation happens later and is not datasource dependent - foreach my $f ($entry->fieldlist) { - # We have to process local options as early as possible in order - # to make them available for things that need them like parsename() - if ($f eq 'options') { - my $value = decode_utf8($entry->get($f)); - $biber->process_entry_options($dskey, $value); - } - - if (my $fm = $dcfxml->{fields}{field}{$f}) { - my $to = $f; # By default, field to set internally is the same as data source - # Redirect any alias - if (my $alias = $fm->{aliasof}) { - $logger->debug("Found alias '$alias' of field '$f' in entry '$dskey'"); - # If both a field and its alias is set, warn and delete alias field - if ($entry->exists($alias)) { - # Warn as that's wrong - $biber->biber_warn($bibentry, "Field '$f' is aliased to field '$alias' but both are defined in entry with key '$dskey' - skipping field '$f'"); - next; - } - $fm = $dcfxml->{fields}{field}{$alias}; - $to = $alias; # Field to set internally is the alias - } - &{$handlers{$fm->{handler}}}($biber, $bibentry, $entry, $f, $to, $dskey); - } - # Default if no explicit way to set the field - else { - my $value = decode_utf8($entry->get($f)); - $bibentry->set_datafield($f, $value); - } - } - - $bibentry->set_field('datatype', 'bibtex'); - $bibentries->add_entry($lc_key, $bibentry); - } - - return; -} - - -# Literal fields -sub _literal { - my ($biber, $bibentry, $entry, $f, $to, $dskey) = @_; - my $value = decode_utf8($entry->get($f)); - - # If we have already split some date fields into literal fields - # like date -> year/month/day, don't overwrite them with explicit - # year/month - return if ($to eq 'year' and $bibentry->get_datafield('year')); - return if ($to eq 'month' and $bibentry->get_datafield('month')); - - # Try to sanitise months to biblatex requirements - if ($to eq 'month') { - $bibentry->set_datafield($to, _hack_month($value)); - } - else { - $bibentry->set_datafield($to, $value); - } - return; -} - -# Verbatim fields -sub _verbatim { - my ($biber, $bibentry, $entry, $f, $to, $dskey) = @_; - my $value = decode_utf8($entry->get($f)); - $bibentry->set_datafield($to, $value); - return; -} - -# Range fields -sub _range { - my ($biber, $bibentry, $entry, $f, $to, $dskey) = @_; - my $values_ref; - my @values = split(/\s*,\s*/, decode_utf8($entry->get($f))); - # Here the "-–" contains two different chars even though they might - # look the same in some fonts ... - # If there is a range sep, then we set the end of the range even if it's null - # If no range sep, then the end of the range is undef - foreach my $value (@values) { - $value =~ m/\A\s*([^-–]+)([-–]*)([^-–]*)\s*\z/xms; - my $end; - if ($2) { - $end = $3; - } - else { - $end = undef; - } - push @$values_ref, [$1 || '', $end]; - } - $bibentry->set_datafield($to, $values_ref); - return; -} - - -# Names -sub _name { - my ($biber, $bibentry, $entry, $f, $to, $dskey) = @_; - my $secnum = $biber->get_current_section; - my $section = $biber->sections->get_section($secnum); - my @tmp = $entry->split($f); - my $lc_key = lc($dskey); - my $useprefix = Biber::Config->getblxoption('useprefix', $bibentry->get_field('entrytype'), $lc_key); - my $names = new Biber::Entry::Names; - foreach my $name (@tmp) { - - # Consecutive "and" causes Text::BibTeX::Name to segfault - unless ($name) { - $biber->biber_warn($bibentry, "Name in key '$dskey' is empty (probably consecutive 'and'): skipping name"); - $section->del_citekey($dskey); - next; - } - - $name = decode_utf8($name); - - # Check for malformed names in names which aren't completely escaped - - # Too many commas - unless ($name =~ m/\A{.+}\z/xms) { # Ignore these tests for escaped names - my @commas = $name =~ m/,/g; - if ($#commas > 1) { - $biber->biber_warn($bibentry, "Name \"$name\" has too many commas: skipping name"); - $section->del_citekey($dskey); - next; - } - - # Consecutive commas cause Text::BibTeX::Name to segfault - if ($name =~ /,,/) { - $biber->biber_warn($bibentry, "Name \"$name\" is malformed (consecutive commas): skipping name"); - $section->del_citekey($dskey); - next; - } - } - - $names->add_element(parsename($name, $f, {useprefix => $useprefix})); - } - $bibentry->set_datafield($to, $names); - return; -} - -# Dates -sub _date { - my ($biber, $bibentry, $entry, $f, $to, $dskey) = @_; - my ($datetype) = $f =~ m/\A(.*)date\z/xms; - my $date = decode_utf8($entry->get($f)); - # We are not validating dates here, just syntax parsing - my $date_re = qr/(\d{4}) # year - (?:-(\d{2}))? # month - (?:-(\d{2}))? # day - /xms; - if (my ($byear, $bmonth, $bday, $r, $eyear, $emonth, $eday) = - $date =~ m|\A$date_re(/)?(?:$date_re)?\z|xms) { - # did this entry get its year/month fields from splitting an ISO8601 date field? - # We only need to know this for date, year/month as year/month can also - # be explicitly set. It makes a difference on how we do any potential future - # date validation - $bibentry->set_field('datesplit', 1) if $datetype eq ''; - # Some warnings for overwriting YEAR and MONTH from DATE - if ($byear and - ($datetype . 'year' eq 'year') and - $entry->get('year')) { - $biber->biber_warn($bibentry, "Overwriting field 'year' with year value from field 'date' for entry '$dskey'"); - } - if ($bmonth and - ($datetype . 'month' eq 'month') and - $entry->get('month')) { - $biber->biber_warn($bibentry, "Overwriting field 'month' with month value from field 'date' for entry '$dskey'"); - } - - $bibentry->set_datafield($datetype . 'year', $byear) if $byear; - $bibentry->set_datafield($datetype . 'month', $bmonth) if $bmonth; - $bibentry->set_datafield($datetype . 'day', $bday) if $bday; - $bibentry->set_datafield($datetype . 'endmonth', $emonth) if $emonth; - $bibentry->set_datafield($datetype . 'endday', $eday) if $eday; - if ($r and $eyear) { # normal range - $bibentry->set_datafield($datetype . 'endyear', $eyear); - } - elsif ($r and not $eyear) { # open ended range - endyear is defined but empty - $bibentry->set_datafield($datetype . 'endyear', ''); - } - } - else { - $biber->biber_warn($bibentry, "Invalid format '$date' of date field '$f' in entry '$dskey' - ignoring"); - } - return; -} - -# List fields -sub _list { - my ($biber, $bibentry, $entry, $f, $to, $dskey) = @_; - my @tmp = $entry->split($f); - - @tmp = map { decode_utf8($_) } @tmp; - @tmp = map { remove_outer($_) } @tmp; - $bibentry->set_datafield($to, [ @tmp ]); - return; -} - - - -=head2 cache_data - - Caches file data into T::B objects indexed by the original - datasource key, decoded into UTF8 - -=cut - -sub cache_data { - my ($biber, $filename) = @_; - - # Initialise this - $cache->{preamble}{$filename} = []; - - # Convert/decode file - my $pfilename = preprocess_file($biber, $filename); - - my $bib = Text::BibTeX::File->new( $pfilename, '<' ) - or $logger->logdie("Cannot create Text::BibTeX::File object from $pfilename: $!"); - while ( my $entry = new Text::BibTeX::Entry $bib ) { - - if ( $entry->metatype == BTE_PREAMBLE ) { - push @{$cache->{preamble}{$filename}}, decode_utf8($entry->value); - next; - } - - # Ignore misc bibtex entry types we don't care about - next if ( $entry->metatype == BTE_MACRODEF or $entry->metatype == BTE_UNKNOWN - or $entry->metatype == BTE_COMMENT ); - - # If an entry has no key, ignore it and warn - unless ($entry->key) { - $logger->warn("Invalid or undefined BibTeX entry key in file '$pfilename', skipping ..."); - next; - } - - # Text::BibTeX >= 0.46 passes through all citekey bits, thus allowing utf8 keys - my $dskey = decode_utf8($entry->key); - - # Bad entry - unless ($entry->parse_ok) { - $logger->warn("Entry $dskey does not parse correctly: skipping"); - next; - } - - # Cache the entry so we don't have to read the file again on next pass. - # Two reasons - So we avoid T::B macro redef warnings and speed - $cache->{data}{$filename}{lc($dskey)} = $entry; - $logger->debug("Cached Text::BibTeX entry for key '$dskey' from bibtex file '$filename'"); - } - - $bib->close; # If we don't do this, we can't unlink the temp file on Windows - - unlink $pfilename if -e $pfilename; - - return; -} - - -=head2 preprocess_file - - Convert file to UTF-8 and potentially decode LaTeX macros to UTF-8 - -=cut - -sub preprocess_file { - my ($biber, $filename) = @_; - my $secnum = $biber->get_current_section; - my $section = $biber->sections->get_section($secnum); - - my $ufilename = "${filename}_$$.utf8"; - - # bib encoding is not UTF-8 - if (Biber::Config->getoption('bibencoding') ne 'UTF-8') { - require File::Slurp::Unicode; - my $buf = File::Slurp::Unicode::read_file($filename, encoding => Biber::Config->getoption('bibencoding')) - or $logger->logdie("Can't read $filename"); - - File::Slurp::Unicode::write_file($ufilename, {encoding => 'UTF-8'}, $buf) - or $logger->logdie("Can't write $ufilename"); - - } - else { - File::Copy::copy($filename, $ufilename); - } - - # Decode LaTeX to UTF8 if output is UTF-8 - if (Biber::Config->getoption('bblencoding') eq 'UTF-8') { - require File::Slurp::Unicode; - my $buf = File::Slurp::Unicode::read_file($ufilename, encoding => 'UTF-8') - or $logger->logdie("Can't read $ufilename"); - require Biber::LaTeX::Recode; - $logger->info('Decoding LaTeX character macros into UTF-8'); - $buf = Biber::LaTeX::Recode::latex_decode($buf, strip_outer_braces => 1, - scheme => Biber::Config->getoption('decodecharsset')); - - File::Slurp::Unicode::write_file($ufilename, {encoding => 'UTF-8'}, $buf) - or $logger->logdie("Can't write $ufilename"); - } - - # Increment the number of times each datafile has been referenced - # For example, a datafile might be referenced in more than one section. - # Some things find this information useful, for example, setting preambles is global - # and so we need to know if we've already saved the preamble for a datafile. - $cache->{counts}{$filename}++; - - return $ufilename; -} - -=head2 parsename - - Given a name string, this function returns a Biber::Entry::Name object - with all parts of the name resolved according to the BibTeX conventions. - - parsename('John Doe') - returns an object which internally looks a bit like this: - - { firstname => 'John', - firstname_i => 'J.', - firstname_it => 'J', - lastname => 'Doe', - lastname_i => 'D.', - lastname_it => 'D', - prefix => undef, - prefix_i => undef, - prefix_it => undef, - suffix => undef, - suffix_i => undef, - suffix_it => undef, - namestring => 'Doe, John', - nameinitstring => 'Doe_J', - strip => {'firstname' => 0, - 'lastname' => 0, - 'prefix' => 0, - 'suffix' => 0} - } - -=cut - -sub parsename { - my ($namestr, $fieldname, $opts) = @_; - $logger->debug(" Parsing namestring '$namestr'"); - my $usepre = $opts->{useprefix}; - # First sanitise the namestring due to Text::BibTeX::Name limitations on whitespace - $namestr =~ s/\A\s*//xms; # leading whitespace - $namestr =~ s/\s*\z//xms; # trailing whitespace - $namestr =~ s/\s+/ /g; # Collapse internal whitespace - - open OLDERR, '>&', \*STDERR; - open STDERR, '>', '/dev/null'; - my $name = new Text::BibTeX::Name($namestr); - open STDERR, '>&', \*OLDERR; - - # Formats so we can get BibTeX compatible nbsp inserted - my $l_f = new Text::BibTeX::NameFormat('l', 0); - my $f_f = new Text::BibTeX::NameFormat('f', 0); - my $p_f = new Text::BibTeX::NameFormat('v', 0); - my $s_f = new Text::BibTeX::NameFormat('j', 0); - $l_f->set_options(BTN_LAST, 0, BTJ_MAYTIE, BTJ_NOTHING); - $f_f->set_options(BTN_FIRST, 0, BTJ_MAYTIE, BTJ_NOTHING); - $p_f->set_options(BTN_VON, 0, BTJ_MAYTIE, BTJ_NOTHING); - $s_f->set_options(BTN_JR, 0, BTJ_MAYTIE, BTJ_NOTHING); - - # Generate name parts - my $lastname = decode_utf8($name->format($l_f)); - my $firstname = decode_utf8($name->format($f_f)); - my $prefix = decode_utf8($name->format($p_f)); - my $suffix = decode_utf8($name->format($s_f)); - - # Variables to hold either the Text::BibTeX::NameFormat generated initials - # or our own generated ones in case we are using a broken version of Text::BibTeX - my $gen_lastname_i; - my $gen_lastname_it; - my $gen_firstname_i; - my $gen_firstname_it; - my $gen_prefix_i; - my $gen_prefix_it; - my $gen_suffix_i; - my $gen_suffix_it; - - # Use a copy of $name so that when we generate the - # initials, we do so without certain things. This is easier than trying - # hack robust initials code into btparse ... - # This is a hard-coded hack - my $nd_namestr = $namestr; - $nd_namestr =~ s/\b\p{L}{2}\p{Pd}//gxms; # strip prefices - $nd_namestr =~ s/[\x{2bf}\x{2018}]//gxms; # strip specific diacritics - my $nd_name = new Text::BibTeX::Name($nd_namestr, $fieldname); - - # Initials formats - my $li_f = new Text::BibTeX::NameFormat('l', 1); - my $fi_f = new Text::BibTeX::NameFormat('f', 1); - my $pi_f = new Text::BibTeX::NameFormat('v', 1); - my $si_f = new Text::BibTeX::NameFormat('j', 1); - - # Truncated initials formats - my $lit_f = new Text::BibTeX::NameFormat('l', 1); - my $fit_f = new Text::BibTeX::NameFormat('f', 1); - my $pit_f = new Text::BibTeX::NameFormat('v', 1); - my $sit_f = new Text::BibTeX::NameFormat('j', 1); - - # Period following normal initials - $li_f->set_text(BTN_LAST, undef, undef, undef, '.'); - $fi_f->set_text(BTN_FIRST, undef, undef, undef, '.'); - $pi_f->set_text(BTN_VON, undef, undef, undef, '.'); - $si_f->set_text(BTN_JR, undef, undef, undef, '.'); - $li_f->set_options(BTN_LAST, 1, BTJ_MAYTIE, BTJ_NOTHING); - $fi_f->set_options(BTN_FIRST, 1, BTJ_MAYTIE, BTJ_NOTHING); - $pi_f->set_options(BTN_VON, 1, BTJ_MAYTIE, BTJ_NOTHING); - $si_f->set_options(BTN_JR, 1, BTJ_MAYTIE, BTJ_NOTHING); - - # Nothing following truncated initials - $lit_f->set_text(BTN_LAST, undef, undef, undef, ''); - $fit_f->set_text(BTN_FIRST, undef, undef, undef, ''); - $pit_f->set_text(BTN_VON, undef, undef, undef, ''); - $sit_f->set_text(BTN_JR, undef, undef, undef, ''); - $lit_f->set_options(BTN_LAST, 1, BTJ_NOTHING, BTJ_NOTHING); - $fit_f->set_options(BTN_FIRST, 1, BTJ_NOTHING, BTJ_NOTHING); - $pit_f->set_options(BTN_VON, 1, BTJ_NOTHING, BTJ_NOTHING); - $sit_f->set_options(BTN_JR, 1, BTJ_NOTHING, BTJ_NOTHING); - - $gen_lastname_i = decode_utf8($nd_name->format($li_f)); - $gen_lastname_it = decode_utf8($nd_name->format($lit_f)); - $gen_firstname_i = decode_utf8($nd_name->format($fi_f)); - $gen_firstname_it = decode_utf8($nd_name->format($fit_f)); - $gen_prefix_i = decode_utf8($nd_name->format($pi_f)); - $gen_prefix_it = decode_utf8($nd_name->format($pit_f)); - $gen_suffix_i = decode_utf8($nd_name->format($si_f)); - $gen_suffix_it = decode_utf8($nd_name->format($sit_f)); - - # Only warn about lastnames since there should always be one - $logger->warn("Couldn't determine Last Name for name \"$namestr\"") unless $lastname; - - my $namestring = ''; - # prefix - my $ps; - my $prefix_stripped; - my $prefix_i; - my $prefix_it; - if ($prefix) { - $prefix_i = $gen_prefix_i; - $prefix_it = $gen_prefix_it; - $prefix_stripped = remove_outer($prefix); - $ps = $prefix ne $prefix_stripped ? 1 : 0; - $namestring .= "$prefix_stripped "; - } - # lastname - my $ls; - my $lastname_stripped; - my $lastname_i; - my $lastname_it; - if ($lastname) { - $lastname_i = $gen_lastname_i; - $lastname_it = $gen_lastname_it; - $lastname_stripped = remove_outer($lastname); - $ls = $lastname ne $lastname_stripped ? 1 : 0; - $namestring .= "$lastname_stripped, "; - } - # suffix - my $ss; - my $suffix_stripped; - my $suffix_i; - my $suffix_it; - if ($suffix) { - $suffix_i = $gen_suffix_i; - $suffix_it = $gen_suffix_it; - $suffix_stripped = remove_outer($suffix); - $ss = $suffix ne $suffix_stripped ? 1 : 0; - $namestring .= "$suffix_stripped, "; - } - # firstname - my $fs; - my $firstname_stripped; - my $firstname_i; - my $firstname_it; - if ($firstname) { - $firstname_i = $gen_firstname_i; - $firstname_it = $gen_firstname_it; - $firstname_stripped = remove_outer($firstname); - $fs = $firstname ne $firstname_stripped ? 1 : 0; - $namestring .= "$firstname_stripped"; - } - - # Remove any trailing comma and space if, e.g. missing firstname - # Replace any nbspes - $namestring =~ s/,\s+\z//xms; - $namestring =~ s/~/ /gxms; - - # Construct $nameinitstring - my $nameinitstr = ''; - $nameinitstr .= $prefix_it . '_' if ( $usepre and $prefix ); - $nameinitstr .= $lastname if $lastname; - $nameinitstr .= '_' . $suffix_it if $suffix; - $nameinitstr .= '_' . $firstname_it if $firstname; - $nameinitstr =~ s/\s+/_/g; - $nameinitstr =~ s/~/_/g; - - # The "strip" entry tells us which of the name parts had outer braces - # stripped during processing so we can add them back when printing the - # .bbl so as to maintain maximum BibTeX compatibility - return Biber::Entry::Name->new( - firstname => $firstname eq '' ? undef : $firstname_stripped, - firstname_i => $firstname eq '' ? undef : $firstname_i, - firstname_it => $firstname eq '' ? undef : $firstname_it, - lastname => $lastname eq '' ? undef : $lastname_stripped, - lastname_i => $lastname eq '' ? undef : $lastname_i, - lastname_it => $lastname eq '' ? undef : $lastname_it, - prefix => $prefix eq '' ? undef : $prefix_stripped, - prefix_i => $prefix eq '' ? undef : $prefix_i, - prefix_it => $prefix eq '' ? undef : $prefix_it, - suffix => $suffix eq '' ? undef : $suffix_stripped, - suffix_i => $suffix eq '' ? undef : $suffix_i, - suffix_it => $suffix eq '' ? undef : $suffix_it, - namestring => $namestring, - nameinitstring => $nameinitstr, - strip => {'firstname' => $fs, - 'lastname' => $ls, - 'prefix' => $ps, - 'suffix' => $ss} - ); -} - - -# Routine to try to hack month into the right biblatex format -# Especially since we support remote .bibs which we potentially have no control over -my %months = ( - 'jan' => '01', - 'feb' => '02', - 'mar' => '03', - 'apr' => '04', - 'may' => '05', - 'jun' => '06', - 'jul' => '07', - 'aug' => '08', - 'sep' => '09', - 'oct' => '10', - 'nov' => '11', - 'dec' => '12' - ); - -sub _hack_month { - my $in_month = shift; - if ($in_month =~ m/\A\s*((?:jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec).*)\s*\z/i) { - return $months{lc(substr($1,0,3))}; - } - else { - return $in_month; - } -} - - -1; - -__END__ - -=pod - -=encoding utf-8 - -=head1 NAME - -Biber::Input::file::bibtex - look in a BibTeX file for an entry and create it if found - -=head1 DESCRIPTION - -Provides the extract_entries() method to get entries from a bibtex data source -and instantiate Biber::Entry objects for what it finds - -=head1 AUTHOR - -François Charette, C<< <firmicus at gmx.net> >> -Philip Kime C<< <philip at kime.org.uk> >> - -=head1 BUGS - -Please report any bugs or feature requests on our sourceforge tracker at -L<https://sourceforge.net/tracker2/?func=browse&group_id=228270>. - -=head1 COPYRIGHT & LICENSE - -Copyright 2009-2011 François Charette and Philip Kime, all rights reserved. - -This module is free software. You can redistribute it and/or -modify it under the terms of the Artistic License 2.0. - -This program is distributed in the hope that it will be useful, -but without any warranty; without even the implied warranty of -merchantability or fitness for a particular purpose. - -=cut - -# vim: set tabstop=2 shiftwidth=2 expandtab: diff --git a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Input/file/ris.dcf b/Master/texmf-dist/source/bibtex/biber/lib/Biber/Input/file/ris.dcf deleted file mode 100644 index 5f779e865b3..00000000000 --- a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Input/file/ris.dcf +++ /dev/null @@ -1,145 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<?oxygen RNGSchema="../../../../data/schemata/dcf.rnc" type="compact"?> -<dcf:driver-control driver="ris" xmlns:dcf="https://sourceforge.net/projects/biber"> - <!-- - These entry type aliases we might find in the the datasource so - we can decide how to map and convert them into Biber::Entry objects - We are not validating anything here, that comes later and is not - datasource specific - --> - <dcf:entry-types> - <dcf:entry-type name="ART"> - <dcf:aliasof>artwork</dcf:aliasof> - </dcf:entry-type> - <dcf:entry-type name="BILL"> - <dcf:aliasof>jurisdiction</dcf:aliasof> - </dcf:entry-type> - <dcf:entry-type name="BOOK"> - <dcf:aliasof>book</dcf:aliasof> - </dcf:entry-type> - <dcf:entry-type name="COMP"> - <dcf:aliasof>software</dcf:aliasof> - </dcf:entry-type> - <dcf:entry-type name="CONF"> - <dcf:aliasof>proceedings</dcf:aliasof> - </dcf:entry-type> - <dcf:entry-type name="GEN"> - <dcf:aliasof>misc</dcf:aliasof> - </dcf:entry-type> - <dcf:entry-type name="JFULL"> - <dcf:aliasof>article</dcf:aliasof> - </dcf:entry-type> - <dcf:entry-type name="JOUR"> - <dcf:aliasof>article</dcf:aliasof> - </dcf:entry-type> - <dcf:entry-type name="MGZN"> - <dcf:aliasof>misc</dcf:aliasof> - </dcf:entry-type> - <dcf:entry-type name="MPCT"> - <dcf:aliasof>movie</dcf:aliasof> - </dcf:entry-type> - <dcf:entry-type name="NEWS"> - <dcf:aliasof>misc</dcf:aliasof> - </dcf:entry-type> - <dcf:entry-type name="PAMP"> - <dcf:aliasof>misc</dcf:aliasof> - </dcf:entry-type> - <dcf:entry-type name="PAT"> - <dcf:aliasof>patent</dcf:aliasof> - </dcf:entry-type> - <dcf:entry-type name="PCOMM"> - <dcf:aliasof>misc</dcf:aliasof> - </dcf:entry-type> - <dcf:entry-type name="RPRT"> - <dcf:aliasof>report</dcf:aliasof> - </dcf:entry-type> - <dcf:entry-type name="SER"> - <dcf:aliasof>misc</dcf:aliasof> - </dcf:entry-type> - <dcf:entry-type name="SLIDE"> - <dcf:aliasof>misc</dcf:aliasof> - </dcf:entry-type> - <dcf:entry-type name="SOUND"> - <dcf:aliasof>audio</dcf:aliasof> - </dcf:entry-type> - <dcf:entry-type name="STAT"> - <dcf:aliasof>legal</dcf:aliasof> - </dcf:entry-type> - <dcf:entry-type name="THES"> - <dcf:aliasof>thesis</dcf:aliasof> - </dcf:entry-type> - <dcf:entry-type name="UNBILL"> - <dcf:aliasof>jurisdiction</dcf:aliasof> - </dcf:entry-type> - <dcf:entry-type name="UNPB"> - <dcf:aliasof>unpublished</dcf:aliasof> - </dcf:entry-type> - </dcf:entry-types> - <!-- - These are the fields we expect to find in the the datasource so - we can decide how to map and convert them into Biber::Entry fields - This has nothing conceptually to do with the internal structure - setup, it's a datasource driver specific set of settings to allow - parsing into internal objects. It looks very similar to aspects - of the Biber::Structure defaults because biber/biblatex was developed - at first as a solely bibtex datasource project. - --> - <dcf:fields> - <!-- date fields --> - <dcf:field name="Y1" aliasof="date"/> - <dcf:field name="PY" aliasof="date"/> - <dcf:field name="date" handler="date"/> - <dcf:field name="Y2" aliasof="eventdate"/> - <dcf:field name="eventdate" handler="date"/> - <!-- name fields --> - <dcf:field name="A1" aliasof="author"/> - <dcf:field name="AU" aliasof="author"/> - <dcf:field name="author" handler="name"/> - <dcf:field name="A2" aliasof="editor"/> - <dcf:field name="A3" aliasof="editor"/> - <dcf:field name="ED" aliasof="editor"/> - <dcf:field name="editor" handler="name"/> - <!-- range fields --> - <dcf:field name="SPEP" aliasof="pages"/> - <dcf:field name="pages" handler="range"/> - <!-- verbatim fields --> - <dcf:field name="N1" aliasof="note"/> - <dcf:field name="note" handler="verbatim"/> - <dcf:field name="N2" aliasof="abstract"/> - <dcf:field name="AB" aliasof="abstract"/> - <dcf:field name="abstract" handler="verbatim"/> - <dcf:field name="JO" aliasof="journaltitle"/> - <dcf:field name="JF" aliasof="journaltitle"/> - <dcf:field name="journaltitle" handler="verbatim"/> - <dcf:field name="JA" aliasof="shortjournal"/> - <dcf:field name="shortjournal" handler="verbatim"/> - <dcf:field name="VL" aliasof="volume"/> - <dcf:field name="volume" handler="verbatim"/> - <dcf:field name="IS" aliasof="issue"/> - <dcf:field name="CP" aliasof="issue"/> - <dcf:field name="issue" handler="verbatim"/> - <dcf:field name="CY" aliasof="location"/> - <dcf:field name="location" aliasof="literal"/> - <dcf:field name="SN" aliasof="isbn"/> - <dcf:field name="isbn" handler="verbatim"/> - <dcf:field name="PB" aliasof="publisher"/> - <dcf:field name="publisher" handler="verbatim"/> - <dcf:field name="KW" aliasof="keywords"/> - <dcf:field name="keywords" handler="verbatim"/> - <dcf:field name="U1" aliasof="usera"/> - <dcf:field name="usera" handler="verbatim"/> - <dcf:field name="U2" aliasof="userb"/> - <dcf:field name="userb" handler="verbatim"/> - <dcf:field name="U3" aliasof="userc"/> - <dcf:field name="userc" handler="verbatim"/> - <dcf:field name="U4" aliasof="userd"/> - <dcf:field name="userd" handler="verbatim"/> - <dcf:field name="U5" aliasof="usere"/> - <dcf:field name="usere" handler="verbatim"/> - <dcf:field name="UR" aliasof="url"/> - <dcf:field name="url" handler="verbatim"/> - <dcf:field name="L1" aliasof="file"/> - <dcf:field name="file" handler="verbatim"/> - </dcf:fields> -</dcf:driver-control> - diff --git a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Input/file/ris.pm b/Master/texmf-dist/source/bibtex/biber/lib/Biber/Input/file/ris.pm deleted file mode 100755 index 2cdc600979c..00000000000 --- a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Input/file/ris.pm +++ /dev/null @@ -1,433 +0,0 @@ -package Biber::Input::file::ris; -#use feature 'unicode_strings'; -use strict; -use warnings; -use Carp; - -use Biber::Constants; -use Biber::Entries; -use Biber::Entry; -use Biber::Entry::Names; -use Biber::Entry::Name; -use Biber::Sections; -use Biber::Section; -use Biber::Structure; -use Biber::Utils; -use Biber::Config; -use Encode; -use File::Spec; -use Log::Log4perl qw(:no_extra_logdie_message); -use base 'Exporter'; -use List::AllUtils qw(first uniq); -use XML::LibXML::Simple; -use Readonly; -use Data::Dump qw(dump); -use Switch; - -my $logger = Log::Log4perl::get_logger('main'); - -# Handlers for field types -# The names of these have nothing to do whatever with the biblatex field types -# They just started out copying them - they are categories of this specific -# data source date types -my %handlers = ( - 'date' => \&_date, - 'name' => \&_name, - 'range' => \&_range, - 'verbatim' => \&_verbatim -); - -# we assume that the driver config file is in the same dir as the driver: -(my $vol, my $driver_path, undef) = File::Spec->splitpath( $INC{"Biber/Input/file/ris.pm"} ); - -# Deal with the strange world of Par::Packer paths, see similar code in Biber.pm -my $dcf; -if ($driver_path =~ m|/par\-| and $driver_path !~ m|/inc|) { # a mangled PAR @INC path - $dcf = File::Spec->catpath($vol, "$driver_path/inc/lib/Biber/Input/file", 'ris.dcf'); -} -else { - $dcf = File::Spec->catpath($vol, $driver_path, 'ris.dcf'); -} - -# Read driver config file -my $dcfxml = XML::LibXML::Simple::XMLin($dcf, - 'ForceContent' => 1, - 'ForceArray' => [ - qr/\Aentry-type\z/, - qr/\Afield\z/, - ], - 'NsStrip' => 1, - 'KeyAttr' => ['name']); - -# Check we have the right driver -unless ($dcfxml->{driver} eq 'ris') { - $logger->logdie("Expected driver config type 'ris', got '" . $dcfxml->{driver} . "'"); -} - - - -=head2 extract_entries - - Main data extraction routine. - Accepts a data source identifier (filename in this case), - preprocesses the file and then looks for the passed keys, - creating entries when it finds them and passes out an - array of keys it didn't find. - -=cut - -sub extract_entries { - my ($biber, $filename, $keys) = @_; - my $secnum = $biber->get_current_section; - my $section = $biber->sections->get_section($secnum); - my $bibentries = $section->bibentries; - my @rkeys = @$keys; - my $tf; - - $logger->trace("Entering extract_entries()"); - - # If it's a remote file, fetch it first - if ($filename =~ m/\A(?:https?|ftp):/xms) { - $logger->info("Data source '$filename' is a remote file - fetching ..."); - require LWP::Simple; - require File::Temp; - $tf = File::Temp->new(SUFFIX => '.ris'); - unless (LWP::Simple::getstore($filename, $tf->filename) == 200) { - $logger->logdie ("Could not fetch file '$filename'"); - } - $filename = $tf->filename; - } - else { - my $trying_filename = $filename; - unless ($filename = locate_biber_file($filename)) { - $logger->logdie("Cannot find file '$trying_filename'!") - } - } - - # pre-process into something a little more sensible, dealing with the multi-line - # fields in RIS - require IO::File; - my $ris = new IO::File; - $ris->open("< $filename"); - my $e; - my @ris_entries; - my $last_tag; - while(<$ris>) { - if (m/\A([A-Z][A-Z0-9])\s\s\-\s*(.+)?\n\z/xms) { - $last_tag = $1; - switch ($1) { - case 'TY' { $e = {'TY' => $2}; } - case 'KW' { push @{$e->{KW}}, $2 } # amalgamate keywords - case 'SP' { $e->{SPEP}{SP} = $2 } # amalgamate page range - case 'EP' { $e->{SPEP}{EP} = $2 } # amalgamate page range - case 'A1' { push @{$e->{A1}}, $2 } # amalgamate names - case 'A2' { push @{$e->{A2}}, $2 } # amalgamate names - case 'A3' { push @{$e->{A3}}, $2 } # amalgamate names - case 'AU' { push @{$e->{AU}}, $2 } # amalgamate names - case 'ED' { push @{$e->{ED}}, $2 } # amalgamate names - case 'ER' { $e->{KW} = join(',', @{$e->{KW}}); - push @ris_entries, $e } - else { $e->{$1} = $2 } - } - } - elsif (m/\A(.+)\n\z/xms) { # Deal with stupid line continuations - $e->{$last_tag} .= " $1"; - } - } - $ris->close; - undef $ris; - - if ($section->is_allkeys) { - $logger->debug("All citekeys will be used for section '$secnum'"); - # Loop over all entries, creating objects - foreach my $entry (@ris_entries) { - $logger->debug('Parsing RIS entry object ' . $entry->{ID}); - # We have to pass the datasource cased key to - # create_entry() as this sub needs to know the original case of the - # citation key so we can do case-insensitive key/entry comparisons - # later but we need to put the original citation case when we write - # the .bbl. If we lowercase before this, we lose this information. - # Of course, with allkeys, "citation case" means "datasource entry case" - - # If an entry has no key, ignore it and warn - unless ($entry->{ID}) { - $logger->warn("RIS entry has no ID key in file '$filename', skipping ..."); - $biber->{warnings}++; - next; - } - create_entry($biber, $entry->{ID}, $entry); - } - - # if allkeys, push all bibdata keys into citekeys (if they are not already there) - $section->add_citekeys($section->bibentries->sorted_keys); - $logger->debug("Added all citekeys to section '$secnum': " . join(', ', $section->get_citekeys)); - } - else { - # loop over all keys we're looking for and create objects - $logger->debug('Wanted keys: ' . join(', ', @$keys)); - foreach my $wanted_key (@$keys) { - $logger->debug("Looking for key '$wanted_key' in RIS file '$filename'"); - # Cache index keys are lower-cased. This next line effectively implements - # case insensitive citekeys - # This will also get the first match it finds - if (my @entries = grep { lc($wanted_key) eq lc($_->{ID}) } @ris_entries) { - if ($#entries > 0) { - $logger->warn("Found more than one entry for key '$wanted_key' in '$filename' - using the first one!"); - $biber->{warnings}++; - } - my $entry = $entries[0]; - - $logger->debug("Found key '$wanted_key' in RIS file '$filename'"); - $logger->debug('Parsing RIS entry object ' . $entry->{ID}); - # See comment above about the importance of the case of the key - # passed to create_entry() - create_entry($biber, $wanted_key, $entry); - # found a key, remove it from the list of keys we want - @rkeys = grep {$wanted_key ne $_} @rkeys; - } - $logger->debug('Wanted keys now: ' . join(', ', @rkeys)); - } - } - return @rkeys; -} - - -=head2 create_entry - - Create a Biber::Entry object from an entry found in a biblatexml data source - -=cut - -sub create_entry { - my ($biber, $dskey, $entry) = @_; - my $secnum = $biber->get_current_section; - my $section = $biber->sections->get_section($secnum); - my $struc = Biber::Config->get_structure; - my $bibentries = $section->bibentries; - - # Want a version of the key that is the same case as any citations which - # reference it, in case they are different. We use this as the .bbl - # entry key - # In case of allkeys, this will just be the datasource key as ->get_citekeys - # returns an empty list - my $citekey = first {lc($dskey) eq lc($_)} $section->get_citekeys; - $citekey = $dskey unless $citekey; - my $lc_key = lc($dskey); - - my $bibentry = new Biber::Entry; - # We record the original keys of both the datasource and citation. They may differ in case. - $bibentry->set_field('dskey', $dskey); - $bibentry->set_field('citekey', $citekey); - - # Set entrytype taking note of any aliases for this datasource driver - if (my $ealias = $dcfxml->{'entry-types'}{'entry-type'}{$entry->{TY}}) { - $bibentry->set_field('entrytype', $ealias->{aliasof}{content}); - if (my $alsoset = $ealias->{alsoset}) { - unless ($bibentry->field_exists($alsoset->{target})) { - $bibentry->set_field($alsoset->{target}, $alsoset->{value}); - } - } - } - else { - $bibentry->set_field('entrytype', $entry->{TY}); - } - - # We put all the fields we find modulo field aliases into the object. - # Validation happens later and is not datasource dependent - foreach my $f (keys %$entry) { - - if (my $fm = $dcfxml->{fields}{field}{$f}) { - my $to = $f; # By default, field to set internally is the same as data source - # Redirect any alias - if (my $alias = $fm->{aliasof}) { - $logger->debug("Found alias '$alias' of field '$f' in entry '$dskey'"); - $fm = $dcfxml->{fields}{field}{$alias}; - $to = $alias; # Field to set internally is the alias - } - &{$handlers{$fm->{handler}}}($biber, $bibentry, $entry, $f, $to, $dskey); - } - # Default if no explicit way to set the field - else { - $bibentry->set_datafield($f, $entry->{$f}); - } - } - - $bibentry->set_field('datatype', 'ris'); - $bibentries->add_entry($lc_key, $bibentry); - - return; -} - -# Verbatim fields -sub _verbatim { - my ($biber, $bibentry, $entry, $f, $to, $dskey) = @_; - $bibentry->set_datafield($to, $entry->{$f}); - return; -} - -# Range fields -sub _range { - my ($biber, $bibentry, $entry, $f, $to, $dskey) = @_; - $bibentry->set_datafield($to, _parse_range_list($entry->{$f})); - return; -} - -# Date fields -sub _date { - my ($biber, $bibentry, $entry, $f, $to, $dskey) = @_; - my $date = $entry->{$f}; - if ($date =~ m|\A([0-9]{4})/([0-9]{2})/([0-9]{2}/([^\n]+))\z|xms) { - $bibentry->set_datafield('year', $1); - $bibentry->set_datafield('month', $2); - $bibentry->set_datafield('day', $3); - } - elsif ($date =~ m|\A([0-9])\z|xms) { - $bibentry->set_datafield('year', $1); - } - else { - $logger->warn("Invalid RIS date format: '$date' - ignoring"); - } - return; -} - -# Name fields -sub _name { - my ($biber, $bibentry, $entry, $f, $to, $dskey) = @_; - my $names = $entry->{$f}; - my $names_obj = new Biber::Entry::Names; - foreach my $name (@$names) { - $logger->debug('Parsing RIS name'); - if ($name =~ m|\A([^,]+)\s*,?\s*([^,]+)?\s*,?\s*([^,]+)?\z|xms) { - my $lastname = $1; - my $firstname = $2; - my $suffix = $3; - $logger->debug("Found name component 'lastname': $lastname") if $lastname; - $logger->debug("Found name component 'firstname': $firstname") if $firstname; - $logger->debug("Found name component 'suffix': $suffix") if $suffix; - - my @fni = _gen_initials([split(/\s/, $firstname)]) if $firstname; - my @lni = _gen_initials([split(/\s/, $lastname)]) if $lastname; - my @si = _gen_initials([split(/\s/, $suffix)]) if $suffix; - - my $namestring = ''; - - # lastname - $namestring .= "$lastname, "; - - # suffix - $namestring .= "$suffix, " if $suffix; - - # firstname - $namestring .= $firstname if $firstname; - - # Remove any trailing comma and space if, e.g. missing firstname - # Replace any nbspes - $namestring =~ s/,\s+\z//xms; - $namestring =~ s/~/ /gxms; - - # Construct $nameinitstring - my $nameinitstr = ''; - $nameinitstr .= $lastname if $lastname; - $nameinitstr .= '_' . $si[1] if $suffix; - $nameinitstr .= '_' . $fni[1] if $firstname; - $nameinitstr =~ s/\s+/_/g; - $nameinitstr =~ s/~/_/g; - - my $name_obj = Biber::Entry::Name->new( - firstname => $firstname || undef, - firstname_i => $firstname ? $fni[0] : undef, - firstname_it => $firstname ? $fni[1] : undef, - lastname => $lastname, - lastname_i => $lni[0], - lastname_it => $lni[1], - suffix => $suffix || undef, - suffix_i => $suffix ? $si[0] : undef, - suffix_it => $suffix ? $si[1] : undef, - namestring => $namestring, - nameinitstring => $nameinitstr - ); - $names_obj->add_element($name_obj); - $bibentry->set_datafield($to, $names_obj); - - # Special case - if ($f eq 'A3') { - $bibentry->set_datafield('editortype', 'series'); - } - } - else { - $logger->warn("Invalid RIS name format: '$name' - ignoring"); - } - } - return; - -} - -# Passed an array ref of strings, returns an array of two strings, -# the first is the TeX initials and the second the terse initials -sub _gen_initials { - my $strings_ref = shift; - my @strings; - foreach my $str (@$strings_ref) { - my $chr = substr($str, 0, 1); - # Keep diacritics with their following characters - if ($chr =~ m/\p{Dia}/) { - push @strings, substr($str, 0, 2); - } - else { - push @strings, substr($str, 0, 1); - } - } - return (join('.~', @strings) . '.', join('', @strings)); -} - - -# parses a range and returns a ref to an array of start and end values -sub _parse_range_list { - my $range = shift; - my $start = $range->{SP} || ''; - my $end = $range->{EP} || ''; - return [[$start, $end]]; -} - - -1; - -__END__ - -=pod - -=encoding utf-8 - -=head1 NAME - -Biber::Input::file::biblatexml - look in a BibLaTeXML file for an entry and create it if found - -=head1 DESCRIPTION - -Provides the extract_entries() method to get entries from a biblatexml data source -and instantiate Biber::Entry objects for what it finds - -=head1 AUTHOR - -François Charette, C<< <firmicus at gmx.net> >> -Philip Kime C<< <philip at kime.org.uk> >> - -=head1 BUGS - -Please report any bugs or feature requests on our sourceforge tracker at -L<https://sourceforge.net/tracker2/?func=browse&group_id=228270>. - -=head1 COPYRIGHT & LICENSE - -Copyright 2009-2011 François Charette and Philip Kime, all rights reserved. - -This module is free software. You can redistribute it and/or -modify it under the terms of the Artistic License 2.0. - -This program is distributed in the hope that it will be useful, -but without any warranty; without even the implied warranty of -merchantability or fitness for a particular purpose. - -=cut - -# vim: set tabstop=2 shiftwidth=2 expandtab: diff --git a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Internals.pm b/Master/texmf-dist/source/bibtex/biber/lib/Biber/Internals.pm deleted file mode 100644 index 2f1c73310a8..00000000000 --- a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Internals.pm +++ /dev/null @@ -1,889 +0,0 @@ -package Biber::Internals; -#use feature 'unicode_strings'; - -use strict; -use warnings; -use Carp; -use Biber::Constants; -use Biber::Utils; -use Text::Wrap; -$Text::Wrap::columns = 80; -use Storable qw( dclone ); -use List::AllUtils qw( :all ); -use Log::Log4perl qw(:no_extra_logdie_message); -use POSIX qw( locale_h ); # for lc() -use Encode; -use charnames ':full'; -use Unicode::Normalize; -use utf8; - -=encoding utf-8 - -=head1 NAME - -Biber::Internals - Internal methods for processing the bibliographic data - -=head1 METHODS - - -=cut - -my $logger = Log::Log4perl::get_logger('main'); - -sub _getnamehash { - my ($self, $citekey, $names) = @_; - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - my $be = $section->bibentry($citekey); - my $initstr = ''; - - if ( $names->count_elements <= Biber::Config->getblxoption('maxnames') ) { # 1 to maxname names - foreach my $n (@{$names->names}) { - if ( $n->get_prefix and - Biber::Config->getblxoption('useprefix', $be->get_field('entrytype'), $citekey ) ) { - $initstr .= $n->get_prefix_it; - } - $initstr .= $n->get_lastname_it; - - if ( $n->get_suffix ) { - $initstr .= $n->get_suffix_it; - } - - if ( $n->get_firstname ) { - $initstr .= $n->get_firstname_it; - } - if ( $n->get_middlename ) { - $initstr .= $n->get_middlename_it; - } - # without useprefix, prefix is not first in the hash - if ( $n->get_prefix and not - Biber::Config->getblxoption('useprefix', $be->get_field('entrytype'), $citekey ) ) { - $initstr .= $n->get_prefix_it; - } - - } - } - # > maxname names: only take initials of first getblxoption('minnames', $citekey) - else { - foreach my $i ( 1 .. Biber::Config->getblxoption('minnames') ) { - if ( $names->nth_element($i)->get_prefix and - Biber::Config->getblxoption('useprefix', $be->get_field('entrytype'), $citekey) ) { - $initstr .= $names->nth_element($i)->get_prefix_it; - } - - if ( $names->nth_element($i)->get_suffix ) { - $initstr .= $names->nth_element($i)->get_suffix_it; - } - - $initstr .= $names->nth_element($i)->get_lastname_it; - if ( $names->nth_element($i)->get_firstname ) { - $initstr .= $names->nth_element($i)->get_firstname_it; - } - if ( $names->nth_element($i)->get_middlename ) { - $initstr .= $names->nth_element($i)->get_middlename_it; - } - - # without useprefix, prefix is not first in the hash - if ( $names->nth_element($i)->get_prefix and not - Biber::Config->getblxoption('useprefix', $be->get_field('entrytype'), $citekey) ) { - $initstr .= $names->nth_element($i)->get_prefix_it; - } - $initstr .= "+"; - } - } - return normalise_string_lite($initstr); -} - -sub _getfullhash { - my ($self, $citekey, $names) = @_; - my $initstr = ''; - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - my $be = $section->bibentry($citekey); - foreach my $n (@{$names->names}) { - if ( $n->get_prefix and - Biber::Config->getblxoption('useprefix', $be->get_field('entrytype'), $citekey ) ) { - $initstr .= $n->get_prefix_it; - } - $initstr .= $n->get_lastname_it; - - if ( $n->get_suffix ) { - $initstr .= $n->get_suffix_it; - } - - if ( $n->get_firstname ) { - $initstr .= $n->get_firstname_it; - } - - if ( $n->get_middlename ) { - $initstr .= $n->get_middlename_it; - } - - # without useprefix, prefix is not first in the hash - if ( $n->get_prefix and not - Biber::Config->getblxoption('useprefix', $be->get_field('entrytype'), $citekey ) ) { - $initstr .= $n->get_prefix_it; - } - - } - return normalise_string_lite($initstr); -} - -sub _getlabel { - my ($self, $citekey, $namefield) = @_; - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - my $be = $section->bibentry($citekey); - my $names = $be->get_field($namefield); - my $alphaothers = Biber::Config->getblxoption('alphaothers', $be->get_field('entrytype')); - my $sortalphaothers = Biber::Config->getblxoption('sortalphaothers', $be->get_field('entrytype')); - my $useprefix = Biber::Config->getblxoption('useprefix', $be->get_field('entrytype'), $citekey); - my $maxnames = Biber::Config->getblxoption('maxnames'); - my $minnames = Biber::Config->getblxoption('minnames'); - my $label = ''; - my $sortlabel = ''; # This contains sortalphaothers instead of alphaothers, if defined - # This is needed in cases where alphaothers is something like - # '\textasteriskcentered' which would mess up sorting. - - my @lastnames = map { strip_nosort(normalise_string($_->get_lastname), $namefield) } @{$names->names}; - my @prefices = map { $_->get_prefix } @{$names->names}; - my $numnames = $names->count_elements; - - # If name list was truncated in bib with "and others", this overrides maxnames - my $morenames = ($names->last_element->get_namestring eq 'others') ? 1 : 0; - my $nametrunc; - my $loopnames; - - # loopnames is the number of names to loop over in the name list when constructing the label - if ($morenames or ($numnames > $maxnames)) { - $nametrunc = 1; - $loopnames = $minnames; # Only look at $minnames names if we are truncating ... - } else { - $loopnames = $numnames; # ... otherwise look at all names - } - - # Now loop over the name list, grabbing a substring of each surname - # The substring length depends on whether we are using prefices and also whether - # we have truncated to one name: - # 1. If there is only one name - # 1. label string is first 3 chars of surname if there is no prefix - # 2. label string is first char of prefix plus first 2 chars of surname if there is a prefix - # 2. If there is more than one name - # 1. label string is first char of each surname (up to minnames) if there is no prefix - # 2. label string is first char of prefix plus first char of each surname (up to minnames) - # if there is a prefix - for (my $i=0; $i<$loopnames; $i++) { - $label .= substr($prefices[$i] , 0, 1) if ($useprefix and $prefices[$i]); - $label .= substr($lastnames[$i], 0, $loopnames == 1 ? (($useprefix and $prefices[$i]) ? 2 : 3) : 1); - } - - $sortlabel = $label; - - # Add alphaothers if name list is truncated - if ($nametrunc) { - $label .= $alphaothers; - $sortlabel .= $sortalphaothers; - } - - return [$label, $sortlabel]; -} - -######### -# Sorting -######### - -our $sorting_sep = ','; - -# The keys are defined by BibLaTeX and passed in the control file -# The value is an array pointer, first element is a code pointer, second is -# a pointer to extra arguments to the code. This is to make code re-use possible -# so the sorting can share code for similar things. -our $dispatch_sorting = { - 'address' => [\&_sort_place, ['place']], - 'author' => [\&_sort_author, []], - 'booksubtitle' => [\&_sort_title, ['booksubtitle']], - 'booktitle' => [\&_sort_title, ['booktitle']], - 'booktitleaddon' => [\&_sort_title, ['booktitleaddon']], - 'citeorder' => [\&_sort_citeorder, []], - 'day' => [\&_sort_dm, ['day']], - 'editor' => [\&_sort_editor, ['editor']], - 'editora' => [\&_sort_editor, ['editora']], - 'editoratype' => [\&_sort_editortc, ['editoratype']], - 'editorb' => [\&_sort_editor, ['editorb']], - 'editorbtype' => [\&_sort_editortc, ['editorbtype']], - 'editorc' => [\&_sort_editor, ['editorc']], - 'editorctype' => [\&_sort_editortc, ['editorctype']], - 'endday' => [\&_sort_dm, ['endday']], - 'endmonth' => [\&_sort_dm, ['endmonth']], - 'endyear' => [\&_sort_year, ['endyear']], - 'entrykey' => [\&_sort_entrykey, []], - 'eventday' => [\&_sort_dm, ['eventday']], - 'eventendday' => [\&_sort_dm, ['eventendday']], - 'eventendmonth' => [\&_sort_dm, ['eventendmonth']], - 'eventendyear' => [\&_sort_year, ['eventendyear']], - 'eventmonth' => [\&_sort_dm, ['eventmonth']], - 'eventtitle' => [\&_sort_title, ['eventtitle']], - 'eventyear' => [\&_sort_year, ['eventyear']], - 'issuesubtitle' => [\&_sort_title, ['issuesubtitle']], - 'issuetitle' => [\&_sort_title, ['issuetitle']], - 'institution' => [\&_sort_place, ['institution']], - 'journalsubtitle' => [\&_sort_title, ['journalsubtitle']], - 'journaltitle' => [\&_sort_title, ['journaltitle']], - 'labelalpha' => [\&_sort_labelalpha, []], - 'labelname' => [\&_sort_labelname, []], - 'labelyear' => [\&_sort_labelyear, []], - 'location' => [\&_sort_place, ['location']], - 'mainsubtitle' => [\&_sort_title, ['mainsubtitle']], - 'maintitle' => [\&_sort_title, ['maintitle']], - 'maintitleaddon' => [\&_sort_title, ['maintitleaddon']], - 'month' => [\&_sort_dm, ['month']], - 'origday' => [\&_sort_dm, ['origday']], - 'origendday' => [\&_sort_dm, ['origendday']], - 'origendmonth' => [\&_sort_dm, ['origendmonth']], - 'origendyear' => [\&_sort_year, ['origendyear']], - 'origmonth' => [\&_sort_dm, ['origmonth']], - 'origtitle' => [\&_sort_title, ['origtitle']], - 'origyear' => [\&_sort_year, ['origyear']], - 'organization' => [\&_sort_place, ['organization']], - 'presort' => [\&_sort_presort, []], - 'publisher' => [\&_sort_publisher, []], - 'pubstate' => [\&_sort_pubstate, []], - 'school' => [\&_sort_place, ['school']], - 'shorthand' => [\&_sort_shorthand, []], - 'shorttitle' => [\&_sort_title, ['shorttitle']], - 'sortkey' => [\&_sort_sortkey, []], - 'sortname' => [\&_sort_sortname, []], - 'sorttitle' => [\&_sort_title, ['sorttitle']], - 'sortyear' => [\&_sort_year, ['sortyear']], - 'subtitle' => [\&_sort_title, ['subtitle']], - 'title' => [\&_sort_title, ['title']], - 'titleaddon' => [\&_sort_title, ['titleaddon']], - 'translator' => [\&_sort_translator, []], - 'urlday' => [\&_sort_dm, ['urlday']], - 'urlendday' => [\&_sort_dm, ['urlendday']], - 'urlendmonth' => [\&_sort_dm, ['urlendmonth']], - 'urlendyear' => [\&_sort_year, ['urlendyear']], - 'urlmonth' => [\&_sort_dm, ['urlmonth']], - 'urlyear' => [\&_sort_year, ['urlyear']], - 'volume' => [\&_sort_volume, []], - 'year' => [\&_sort_year, ['year']], - }; - -# Main sorting dispatch method -sub _dispatch_sorting { - my ($self, $sortfield, $citekey, $sortelementattributes) = @_; - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - my $be = $section->bibentry($citekey); - my $code_ref; - my $code_args_ref; - - # If this field is excluded from sorting for this entrytype, then skip it and return - if (my $se = Biber::Config->getblxoption('sortexclusion', $be->get_field('entrytype'))) { - if ($se->{$sortfield}) { - return ''; - } - } - - # if the field is not found in the dispatch table, assume it's a literal string - unless (exists($dispatch_sorting->{$sortfield})) { - $code_ref = \&_sort_literal; - $code_args_ref = [$sortfield]; - } - else { # real sorting field - $code_ref = ${$dispatch_sorting->{$sortfield}}[0]; - $code_args_ref = ${$dispatch_sorting->{$sortfield}}[1]; - } - return &{$code_ref}($self, $citekey, $sortelementattributes, $code_args_ref); -} - -# Conjunctive set of sorting sets -sub _generatesortinfo { - my ($self, $citekey, $list, $sortscheme) = @_; - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - my $be = $section->bibentry($citekey); - my $sortobj; - $BIBER_SORT_FINAL = 0; - $BIBER_SORT_FINAL = ''; - foreach my $sortset (@{$sortscheme}) { - my $s = $self->_sortset($sortset, $citekey); - # We have already found a "final" item so if this item returns null, - # copy in the "final" item string as it's the master key for this entry now - if ($BIBER_SORT_FINAL and not $BIBER_SORT_NULL) { - push @$sortobj, $BIBER_SORT_FINAL; - } - else { - push @$sortobj, $s; - } - } - - # Record the information needed for sorting later - # sortstring isn't actually used to sort, it's used to generate sortinit and - # for debugging purposes - my $ss = join($sorting_sep, @$sortobj); - $list->set_sortdata($citekey, [$ss, $sortobj]); - - # Generate sortinit - the initial letter of the sortstring. Skip - # if there is no sortstring, which is possible in tests - if ($ss) { - # This must ignore the presort characters, naturally - my $pre = Biber::Config->getblxoption('presort', $be->get_field('entrytype'), $citekey); - - # Strip off the prefix - $ss =~ s/\A$pre$sorting_sep+//; - my $init = substr $ss, 0, 1; - - # Now check if this sortinit is valid in the bblencoding. If not, warn - # and replace with a suitable value - my $bblenc = Biber::Config->getoption('bblencoding'); - if ($bblenc ne 'UTF-8') { - # Can this init be represented in the BBL encoding? - if (encode($bblenc, $init) eq '?') { # Malformed data encoding char - # So convert to macro - require Biber::LaTeX::Recode; - my $initd = Biber::LaTeX::Recode::latex_encode($init, - scheme => Biber::Config->getoption('bblsafecharsset')); - # warn only on second sorting pass to avoid user confusion - $logger->warn("The character '$init' cannot be encoded in '$bblenc'. sortinit will be set to macro '$initd' for entry '$citekey'"); - $self->{warnings}++; - $init = $initd; - } - } - $list->set_sortinitdata($citekey, $init); - } - return; -} - -# Process sorting set -sub _sortset { - my ($self, $sortset, $citekey) = @_; - foreach my $sortelement (@$sortset[1..$#$sortset]) { - my ($sortelementname, $sortelementattributes) = %$sortelement; - $BIBER_SORT_NULL = 0; # reset this per sortset - my $string = $self->_dispatch_sorting($sortelementname, $citekey, $sortelementattributes); - if ($string) { # sort returns something for this key - if ($sortset->[0]{final}) { - # If we encounter a "final" element, we return an empty sort - # string and save the string so it can be copied into all further - # fields as this is now the master sort key. We use an empty string - # where we found it in order to preserve sort field order and so - # that we sort correctly against all other entries without a value - # for this "final" field - $BIBER_SORT_FINAL = $string; - last; - } - return $string; - } - } - $BIBER_SORT_NULL = 1; # set null flag - need this to deal with some cases - return ''; -} - -############################################## -# Sort dispatch routines -############################################## - -sub _sort_author { - my ($self, $citekey, $sortelementattributes) = @_; - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - my $be = $section->bibentry($citekey); - if (Biber::Config->getblxoption('useauthor', $be->get_field('entrytype'), $citekey) and - $be->get_field('author')) { - my $string = $self->_namestring($citekey, 'author'); - return _process_sort_attributes($string, $sortelementattributes); - } - else { - return ''; - } -} - -sub _sort_citeorder { - my ($self, $citekey, $sortelementattributes) = @_; - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - # Pad the numbers so that they sort with "cmp" properly. Assume here max of - # a million bib entries. Probably enough ... - return sprintf('%.7d', (first_index {$_ eq $citekey} $section->get_orig_order_citekeys) + 1); -} - -# This is a meta-sub which uses the optional arguments to the dispatch code -# It's done to avoid having many repetitions of almost identical sorting code -# for the many date sorting options -# It deals with day and month fields -sub _sort_dm { - my ($self, $citekey, $sortelementattributes, $args) = @_; - my $dmtype = $args->[0]; # get day/month field type - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - my $be = $section->bibentry($citekey); - if (my $field = $be->get_field($dmtype)) { - return _process_sort_attributes($field, $sortelementattributes); - } - else { - return ''; - } -} - -# This is a meta-sub which uses the optional arguments to the dispatch code -# It's done to avoid having many repetitions of almost identical sorting code -# for the editor roles -sub _sort_editor { - my ($self, $citekey, $sortelementattributes, $args) = @_; - my $ed = $args->[0]; # get editor field - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - my $be = $section->bibentry($citekey); - if (Biber::Config->getblxoption('useeditor', $be->get_field('entrytype'), $citekey) and - $be->get_field($ed)) { - my $string = $self->_namestring($citekey, $ed); - return _process_sort_attributes($string, $sortelementattributes); - } - else { - return ''; - } -} - -# This is a meta-sub which uses the optional arguments to the dispatch code -# It's done to avoid having many repetitions of almost identical sorting code -# for the editor type/class roles -sub _sort_editortc { - my ($self, $citekey, $sortelementattributes, $args) = @_; - my $edtypeclass = $args->[0]; # get editor type/class field - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - my $be = $section->bibentry($citekey); - if (Biber::Config->getblxoption('useeditor', $be->get_field('entrytype'), $citekey) and - $be->get_field($edtypeclass)) { - my $string = $be->get_field($edtypeclass); - return _process_sort_attributes($string, $sortelementattributes); - } - else { - return ''; - } -} - -# debug sorting -sub _sort_entrykey { - my ($self, $citekey, $sortelementattributes) = @_; - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - return $citekey; -} - - -sub _sort_labelalpha { - my ($self, $citekey, $sortelementattributes) = @_; - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - my $be = $section->bibentry($citekey); - if ($be->get_field('sortlabelalpha')) { - my $string = $be->get_field('sortlabelalpha'); - return _process_sort_attributes($string, $sortelementattributes); - } - else { - return ''; - } -} - -sub _sort_labelname { - my ($self, $citekey, $sortelementattributes, $args) = @_; - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - my $be = $section->bibentry($citekey); - # re-direct to the right sorting routine for the labelname - if (my $ln = $be->get_field('labelnamename')) { - # Don't process attributes as they will be processed in the real sub - return $self->_dispatch_sorting($ln, $citekey, $sortelementattributes); - } - else { - return ''; - } -} - -sub _sort_labelyear { - my ($self, $citekey, $sortelementattributes, $args) = @_; - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - my $be = $section->bibentry($citekey); - # re-direct to the right sorting routine for the labelyear - if (my $ly = $be->get_field('labelyearname')) { - # Don't process attributes as they will be processed in the real sub - return $self->_dispatch_sorting($ly, $citekey, $sortelementattributes); - } - else { - return ''; - } -} - -sub _sort_literal { - my ($self, $citekey, $sortelementattributes, $args) = @_; - my $string = $args->[0]; # get literal string - return _process_sort_attributes($string, $sortelementattributes); -} - -# This is a meta-sub which uses the optional arguments to the dispatch code -# It's done to avoid having many repetitions of almost identical sorting code -# for the place (address/location/institution etc.) sorting options -sub _sort_place { - my ($self, $citekey, $sortelementattributes, $args) = @_; - my $pltype = $args->[0]; # get place field type - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - my $be = $section->bibentry($citekey); - if ($be->get_field($pltype)) { - my $string = $self->_liststring($citekey, $pltype); - return _process_sort_attributes($string, $sortelementattributes); - } - else { - return ''; - } -} - -sub _sort_presort { - my ($self, $citekey, $sortelementattributes) = @_; - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - my $be = $section->bibentry($citekey); - my $string = Biber::Config->getblxoption('presort', $be->get_field('entrytype'), $citekey); - return _process_sort_attributes($string, $sortelementattributes); -} - -sub _sort_publisher { - my ($self, $citekey, $sortelementattributes) = @_; - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - my $be = $section->bibentry($citekey); - if ($be->get_field('publisher')) { - my $string = $self->_liststring($citekey, 'publisher'); - return _process_sort_attributes($string, $sortelementattributes); - } - else { - return ''; - } -} - -sub _sort_pubstate { - my ($self, $citekey, $sortelementattributes) = @_; - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - my $be = $section->bibentry($citekey); - my $string = $be->get_field('pubstate') // ''; - return _process_sort_attributes($string, $sortelementattributes); -} - -sub _sort_shorthand { - my ($self, $citekey, $sortelementattributes) = @_; - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - my $be = $section->bibentry($citekey); - my $string = $be->get_field('shorthand') // ''; - return _process_sort_attributes($string, $sortelementattributes); -} - -sub _sort_sortkey { - my ($self, $citekey, $sortelementattributes) = @_; - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - my $be = $section->bibentry($citekey); - my $string = $be->get_field('sortkey') // ''; - return _process_sort_attributes($string, $sortelementattributes); -} - -sub _sort_sortname { - my ($self, $citekey, $sortelementattributes) = @_; - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - my $be = $section->bibentry($citekey); - - # see biblatex manual §3.4 - sortname is ignored if no use<name> option is defined - if ($be->get_field('sortname') and - (Biber::Config->getblxoption('useauthor', $be->get_field('entrytype'), $citekey) or - Biber::Config->getblxoption('useeditor', $be->get_field('entrytype'), $citekey) or - Biber::Config->getblxoption('useetranslator', $be->get_field('entrytype'), $citekey))) { - my $string = $self->_namestring($citekey, 'sortname'); - return _process_sort_attributes($string, $sortelementattributes); - } - else { - return ''; - } -} - -# This is a meta-sub which uses the optional arguments to the dispatch code -# It's done to avoid having many repetitions of almost identical sorting code -# for the title sorting options -sub _sort_title { - my ($self, $citekey, $sortelementattributes, $args) = @_; - my $ttype = $args->[0]; # get year field type - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - my $be = $section->bibentry($citekey); - if (my $field = $be->get_field($ttype)) { - my $string = normalise_string_sort($field, $ttype); - return _process_sort_attributes($string, $sortelementattributes); - } - else { - return ''; - } -} - -sub _sort_translator { - my ($self, $citekey, $sortelementattributes) = @_; - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - my $be = $section->bibentry($citekey); - if (Biber::Config->getblxoption('usetranslator', $be->get_field('entrytype'), $citekey) and - $be->get_field('translator')) { - my $string = $self->_namestring($citekey, 'translator'); - return _process_sort_attributes($string, $sortelementattributes); - } - else { - return ''; - } -} - -sub _sort_volume { - my ($self, $citekey, $sortelementattributes) = @_; - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - my $be = $section->bibentry($citekey); - if (my $field = $be->get_field('volume')) { - return _process_sort_attributes($field, $sortelementattributes); - } - else { - return ''; - } -} - -# This is a meta-sub which uses the optional arguments to the dispatch code -# It's done to avoid having many repetitions of almost identical sorting code -# for the many date sorting options -# It deals with year fields -sub _sort_year { - my ($self, $citekey, $sortelementattributes, $args) = @_; - my $ytype = $args->[0]; # get year field type - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - my $be = $section->bibentry($citekey); - if (my $field = $be->get_field($ytype)) { - return _process_sort_attributes($field, $sortelementattributes); - } - else { - return ''; - } -} - -#======================================================== -# Utility subs used elsewhere but relying on sorting code -#======================================================== - -sub _process_sort_attributes { - my ($field_string, $sortelementattributes) = @_; - return $field_string unless $sortelementattributes; - # process substring - if ($sortelementattributes->{substring_width} or - $sortelementattributes->{substring_side}) { - my $subs_offset = 0; - my $default_substring_width = 4; - my $default_substring_side = 'left'; - my $subs_width = ($sortelementattributes->{substring_width} or $default_substring_width); - my $subs_side = ($sortelementattributes->{substring_side} or $default_substring_side); - if ($subs_side eq 'right') { - $subs_offset = 0 - $subs_width; - } - $field_string = substr( $field_string, $subs_offset, $subs_width ); - } - # Process padding - if ($sortelementattributes->{pad_side} or - $sortelementattributes->{pad_width} or - $sortelementattributes->{pad_char}) { - my $default_pad_width = 4; - my $default_pad_side = 'left'; - my $default_pad_char = '0'; - my $pad_width = ($sortelementattributes->{pad_width} or $default_pad_width); - my $pad_side = ($sortelementattributes->{pad_side} or $default_pad_side); - my $pad_char = ($sortelementattributes->{pad_char} or $default_pad_char); - my $pad_length = $pad_width - length($field_string); - if ($pad_side eq 'left') { - $field_string = ($pad_char x $pad_length) . $field_string; - } - elsif ($pad_side eq 'right') { - $field_string = $field_string . ($pad_char x $pad_length); - } - } - return $field_string; -} - -sub _namestring { - my $self = shift; - my ($citekey, $field) = @_; - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - my $be = $section->bibentry($citekey); - my $names = $be->get_field($field); - my $str = ''; - my $truncated = 0; - my $truncnames = dclone($names); - - # These should be symbols which can't appear in names - # This means, symbols which normalise_string_sort strips out - my $nsi = '_'; # name separator, internal - my $nse = '+'; # name separator, external - # Guaranteed to sort after everything else as it's the last legal Unicode code point - my $trunc = "\x{10FFFD}"; # sort string for "et al" truncated name - - # perform truncation according to options minnames, maxnames - if ( $names->count_elements > Biber::Config->getblxoption('maxnames') ) { - $truncated = 1; - $truncnames = $truncnames->first_n_elements(Biber::Config->getblxoption('minnames')); - } - - # We strip nosort first otherwise normalise_string_sort damages diacritics - # We strip each individual component instead of the whole thing so we can use - # as name separators things which would otherwise be stripped. This way we - # guarantee that the separators are never in names - foreach my $n ( @{$truncnames->names} ) { - # If useprefix is true, use prefix at start of name for sorting - if ( $n->get_prefix and - Biber::Config->getblxoption('useprefix', $be->get_field('entrytype'), $citekey ) ) { - $str .= normalise_string_sort($n->get_prefix, $field) . $nsi; - } - $str .= normalise_string_sort($n->get_lastname, $field) . $nsi; - $str .= normalise_string_sort($n->get_firstname, $field) . $nsi if $n->get_firstname; - $str .= normalise_string_sort($n->get_middlename, $field) . $nsi if $n->get_middlename; - $str .= normalise_string_sort($n->get_suffix, $field) . $nsi if $n->get_suffix; - - # If useprefix is false, use prefix at end of name - if ( $n->get_prefix and not - Biber::Config->getblxoption('useprefix', $be->get_field('entrytype'), $citekey ) ) { - $str .= normalise_string_sort($n->get_prefix, $field) . $nsi; - } - - $str =~ s/\Q$nsi\E\z//xms; # Remove any trailing internal separator - $str .= $nse; # Add separator in between names - } - - $str =~ s/\s+\Q$nse\E/$nse/gxms; # Remove any whitespace before external separator - $str =~ s/\Q$nse\E\z//xms; # strip final external separator as we are finished - $str .= "$nse$trunc" if $truncated; - return $str; -} - -sub _liststring { - my ( $self, $citekey, $field ) = @_; - my $secnum = $self->get_current_section; - my $section = $self->sections->get_section($secnum); - my $be = $section->bibentry($citekey); - my @items = @{$be->get_field($field)}; - my $str = ''; - my $truncated = 0; - - # These should be symbols which can't appear in lists - # This means, symbols which normalise_string_sort strips out - my $lsi = '_'; # list separator, internal - my $lse = '+'; # list separator, external - # Guaranteed to sort after everything else as it's the last legal Unicode code point - my $trunc = "\x{10FFFD}"; # sort string for truncated list - - # perform truncation according to options minitems, maxitems - if ( $#items + 1 > Biber::Config->getblxoption('maxitems') ) { - $truncated = 1; - @items = splice(@items, 0, Biber::Config->getblxoption('minitems') ); - } - - # separate the items by a string to give some structure - $str = join($lsi, map { normalise_string_sort($_, $field)} @items); - $str .= $lse; - - $str =~ s/\s+\Q$lse\E/$lse/gxms; - $str =~ s/\Q$lse\E\z//xms; - $str .= "$lse$trunc" if $truncated; - return $str; -} - -=head2 process_entry_options - - Set per-entry options - - "dataonly" is a special case and expands to "skiplab,skiplos,skipbib" - but only "skiplab" and "skiplos" are dealt with in Biber, "skipbib" is - dealt with in biblatex. - -=cut - -sub process_entry_options { - my $self = shift; - my $citekey = shift; - my $options = shift; - if ( $options ) { # Just in case it's null - my @entryoptions = split /\s*,\s*/, $options; - foreach (@entryoptions) { - m/^([^=]+)=?(.+)?$/; - if ( $2 and $2 eq 'false' ) { - if (lc($1) eq 'dataonly') { - Biber::Config->setblxoption('skiplab', 0, 'PER_ENTRY', $citekey); - Biber::Config->setblxoption('skiplos', 0, 'PER_ENTRY', $citekey); - } - else { - Biber::Config->setblxoption($1, 0, 'PER_ENTRY', $citekey); - } - } - elsif ( ($2 and $2 eq 'true') or not $2) { - if (lc($1) eq 'dataonly') { - Biber::Config->setblxoption('skiplab', 1, 'PER_ENTRY', $citekey); - Biber::Config->setblxoption('skiplos', 1, 'PER_ENTRY', $citekey); - } - else { - Biber::Config->setblxoption($1, 1, 'PER_ENTRY', $citekey); - } - } - elsif ($2) { - if (lc($1) eq 'dataonly') { - Biber::Config->setblxoption('skiplab', $2, 'PER_ENTRY', $citekey); - Biber::Config->setblxoption('skiplos', $2, 'PER_ENTRY', $citekey); - } - else { - Biber::Config->setblxoption($1, $2, 'PER_ENTRY', $citekey); - } - } - else { - if (lc($1) eq 'dataonly') { - Biber::Config->setblxoption('skiplab', 1, 'PER_ENTRY', $citekey); - Biber::Config->setblxoption('skiplos', 1, 'PER_ENTRY', $citekey); - } - else { - Biber::Config->setblxoption($1, 1, 'PER_ENTRY', $citekey); - } - } - } - } -} - - -=head1 AUTHOR - -François Charette, C<< <firmicus at gmx.net> >> -Philip Kime C<< <philip at kime.org.uk> >> - -=head1 BUGS - -Please report any bugs or feature requests on our sourceforge tracker at -L<https://sourceforge.net/tracker2/?func=browse&group_id=228270>. - -=head1 COPYRIGHT & LICENSE - -Copyright 2009-2011 François Charette and Philip Kime, all rights reserved. - -This module is free software. You can redistribute it and/or -modify it under the terms of the Artistic License 2.0. - -This program is distributed in the hope that it will be useful, -but without any warranty; without even the implied warranty of -merchantability or fitness for a particular purpose. - -=cut - -1; - -# vim: set tabstop=2 shiftwidth=2 expandtab: diff --git a/Master/texmf-dist/source/bibtex/biber/lib/Biber/LaTeX/Recode.pm b/Master/texmf-dist/source/bibtex/biber/lib/Biber/LaTeX/Recode.pm deleted file mode 100644 index d395e808504..00000000000 --- a/Master/texmf-dist/source/bibtex/biber/lib/Biber/LaTeX/Recode.pm +++ /dev/null @@ -1,327 +0,0 @@ -package Biber::LaTeX::Recode; -#use feature 'unicode_strings'; -use strict; -use warnings; -no warnings 'utf8'; -use Unicode::Normalize; -use Biber::LaTeX::Recode::Data; -use Exporter; -use base qw(Exporter); -use Carp; - -our $VERSION = '0.1'; -our @EXPORT = qw(latex_encode latex_decode); - -=encoding utf-8 - -=head1 NAME - -Biber::LaTeX::Recode - Encode/Decode chars to/from UTF-8/lacros in LaTeX - -=head1 VERSION - -Version 0.01 - -=head1 SYNOPSIS - - use Biber::LaTeX:Recode - - my $string = 'Muḥammad ibn Mūsā al-Khwārizmī'; - my $latex_string = latex_encode($string); - # => 'Mu\d{h}ammad ibn M\=us\=a al-Khw\=arizm\={\i}' - - my $string = 'Mu\d{h}ammad ibn M\=us\=a al-Khw\=arizm\={\i}'; - my $utf8_string = latex_decode($string); - # => 'Muḥammad ibn Mūsā al-Khwārizmī' - -=head1 DESCRIPTION - -Allows conversion between Unicode chars and LaTeX macros. - -=head1 GLOBAL OPTIONS - -The decoding scheme can be set with - - $Biber::LaTeX::Recode::DefaultScheme = '<name>'; - -Possible values are 'base', 'extra' and 'full'; default value is 'extra'. - -base => Most common macros and diacritics (sufficient for Western languages - and common symbols) - -extra => Also converts punctuation, larger range of diacritics and macros - (e.g. for IPA, Latin Extended Additional, etc.) - -full => Also converts symbols, Greek letters, dingbats, negated symbols, and - superscript characters and symbols ... - -=cut - - -our $DefaultScheme_d = 'extra'; -our $DefaultScheme_e = 'extra'; - - -=head2 latex_decode($text, @options) - -Converts LaTeX macros in the $text to Unicode characters. - -The function accepts a number of options: - - * normalize => $bool (default 1) - whether the output string should be normalized with Unicode::Normalize - - * normalization => <normalization form> (default 'NFC') - and if yes, the normalization form to use (see the Unicode::Normalize documentation) - - * strip_outer_braces => $bool (default 0) - whether the outer curly braces around letters+combining marks should be - stripped off. By default "fut{\\'e}" becomes fut{é}, to prevent something - like '\\textuppercase{\\'e}' to become '\\textuppercaseé'. Setting this option to - TRUE can be useful for instance when converting BibTeX files. - -=cut - -sub latex_decode { - my $text = shift; - my %opts = @_; - my $norm = exists $opts{normalize} ? $opts{normalize} : 1; - my $norm_form = exists $opts{normalization} ? $opts{normalization} : 'NFC'; - my $scheme = exists $opts{scheme} ? $opts{scheme} : $DefaultScheme_d; - croak "invalid scheme name '$scheme'" - unless ( $scheme eq 'full' or $scheme eq 'base' or $scheme eq 'extra' ); - my $strip_outer_braces = - exists $opts{strip_outer_braces} ? $opts{strip_outer_braces} : 0; - - my %DIAC = _get_diac($scheme); - my ($WORDMAC, $WORDMAC_RE) = _get_mac($scheme); - - my $DIAC_RE; - if ( $scheme eq 'base' ) { - $DIAC_RE = $DIAC_RE_BASE; - } - else { - $DIAC_RE = $DIAC_RE_EXTRA; - } - - if ( $scheme eq 'full' ) { - $text =~ s/\\not\\($NEG_SYMB_RE)/$NEGATEDSYMBOLS{$1}/ge; - $text =~ s/\\textsuperscript{($SUPER_RE)}/$SUPERSCRIPTS{$1}/ge; - $text =~ s/\\textsuperscript{\\($SUPERCMD_RE)}/$CMDSUPERSCRIPTS{$1}/ge; - $text =~ s/\\dings{([2-9AF][0-9A-F])}/$DINGS{$1}/ge; - } - - $text =~ s/(\\[a-zA-Z]+)\\(\s+)/$1\{\}$2/g; # \foo\ bar -> \foo{} bar - $text =~ s/([^{]\\\w)([;,.:%])/$1\{\}$2/g; #} Aaaa\o, -> Aaaa\o{}, - $text =~ s/(\\(?:$DIAC_RE_BASE|$ACCENTS_RE)){\\i}/$1\{i\}/g; - # special cases such as '\={\i}' -> '\={i}' -> "i\x{304}" - - ## remove {} around macros that print one character - ## by default we skip that, as it would break constructions like \foo{\i} - if ($strip_outer_braces) { - $text =~ s/ \{\\($WORDMAC_RE)\} / $WORDMAC->{$1} /gxe; - } - $text =~ s/ \\($WORDMAC_RE)(?: \{\} | \s+ | \b) / $WORDMAC->{$1} /gxe; - - $text =~ s/\\($ACCENTS_RE)\{(\p{L}\p{M}*)\}/$2 . $ACCENTS{$1}/ge; - - $text =~ s/\\($ACCENTS_RE)(\p{L}\p{M}*)/$2 . $ACCENTS{$1}/ge; - - $text =~ s/\\($DIAC_RE)\s*\{(\p{L}\p{M}*)\}/$2 . $DIAC{$1}/ge; - - $text =~ s/\\($DIAC_RE)\s+(\p{L}\p{M}*)/$2 . $DIAC{$1}/ge; - - $text =~ s/\\($ACCENTS_RE)\{(\p{L}\p{M}*)\}/$2 . $ACCENTS{$1}/ge; - - $text =~ s/\\($ACCENTS_RE)(\p{L}\p{M}*)/$2 . $ACCENTS{$1}/ge; - - $text =~ s/\\($DIAC_RE)\s*\{(\p{L}\p{M}*)\}/$2 . $DIAC{$1}/ge; - - $text =~ s/\\($DIAC_RE)\s+(\p{L}\p{M}*)/$2 . $DIAC{$1}/ge; - - ## remove {} around letter+combining mark(s) - ## by default we skip that, as it would destroy constructions like \foo{\`e} - if ($strip_outer_braces) { - $text =~ s/{(\PM\pM+)}/$1/g; - } - - if ($norm) { - return Unicode::Normalize::normalize( $norm_form, $text ); - } - else { - return $text; - } -} - -=head2 latex_encode($text, @options) - -Converts LaTeX character macros to UTF-8 - -=cut - -sub latex_encode { - my $text = NFD(shift); - my %opts = @_; - my $scheme = exists $opts{scheme} ? $opts{scheme} : $DefaultScheme_e; - croak "invalid scheme name '$scheme'" - unless ( $scheme eq 'full' or $scheme eq 'base' or $scheme eq 'extra' ); - # choose the diacritics set to use - my %DIAC_R = _get_diac_r($scheme); - my $DIAC_RE_R; - if ( $scheme eq 'base' ) { - $DIAC_RE_R = $DIAC_RE_BASE_R; - } - else { - $DIAC_RE_R = $DIAC_RE_EXTRA_R; - } - - # choose the macro set to use - my ($WORDMAC_R, $WORDMAC_RE_R) = _get_mac_r($scheme); - - if ( $scheme eq 'full' ) { - $text =~ s/($NEG_SYMB_RE_R)/"\\not\\" . $NEGATEDSYMBOLS_R{$1}/ge; - $text =~ s/($SUPER_RE_R)/"\\textsuperscript{" . $SUPERSCRIPTS_R{$1} . "}"/ge; - $text =~ s/($SUPERCMD_RE_R)/"\\textsuperscript{\\" . $CMDSUPERSCRIPTS_R{$1} . "}"/ge; - $text =~ s/($DINGS_RE_R)/"\\dings{" . $DINGS_R{$1} . "}"/ge; - } - - # Accents - - # special case such as "i\x{304}" -> '\={\i}' - "i" needs the dot removing for accents - $text =~ s/i($ACCENTS_RE_R)/"\\" . $ACCENTS_R{$1} . "{\\i}"/ge; - - $text =~ s/\{(\p{L}\p{M}*)\}($ACCENTS_RE_R)/"\\" . $ACCENTS_R{$2} . "{$1}"/ge; - $text =~ s/(\p{L}\p{M}*)($ACCENTS_RE_R)/"\\" . $ACCENTS_R{$2} . "{$1}"/ge; - - # Diacritics - $text =~ s{ - (\P{M})($DIAC_RE_R)($DIAC_RE_R)($DIAC_RE_R) - }{ - "\\" . $DIAC_R{$4} . "{\\" . $DIAC_R{$3} . "{\\" . $DIAC_R{$2} . _get_diac_last_r($1,$2) . '}}' - }gex; - $text =~ s{ - (\P{M})($DIAC_RE_R)($DIAC_RE_R) - }{ - "\\" . $DIAC_R{$3} . "{\\" . $DIAC_R{$2} . _get_diac_last_r($1,$2) . '}' - }gex; - $text =~ s{ - (\P{M})($DIAC_RE_R) - }{ - "\\" . $DIAC_R{$2} . _get_diac_last_r($1,$2) - }gex; - - # General macros (excluding special encoding excludes) - $text =~ s/($WORDMAC_RE_R)/"{\\" . $WORDMAC_R->{$1} . '}'/ge; - - # Only replace these if using "full" scheme - if ($scheme eq 'full') { - my %WORDMATHMAC_R = ( %PUNCTUATION_R, %SYMBOLS_R, %GREEK_R ); - my $WORDMATHMAC_RE_R = join( '|', sort { length $b <=> length $a } keys %WORDMATHMAC_R ); - # Math mode macros (excluding special encoding excludes) - $text =~ s/($WORDMATHMAC_RE_R)/"{\$\\" . $WORDMATHMAC_R{$1} . '$}'/ge; - } - - return $text; -} - - -# Helper subroutines - -sub _get_diac { - my $scheme = shift; - if ( $scheme eq 'base' ) { - return %DIACRITICS; - } - else { - return ( %DIACRITICS, %DIACRITICSEXTRA ); - } -} - -sub _get_diac_r { - my $scheme = shift; - if ( $scheme eq 'base' ) { - return %DIACRITICS_R; - } - else { - return ( %DIACRITICS_R, %DIACRITICSEXTRA_R); - } -} - - -sub _get_mac { - my $scheme = shift; - my %macs; - if ( $scheme eq 'base' ) { - %macs = %WORDMACROS; - } - elsif ( $scheme eq 'full' ) { - %macs = ( %WORDMACROS, %WORDMACROSEXTRA, %PUNCTUATION, %SYMBOLS, - %GREEK ); - } - else { - %macs = ( %WORDMACROS, %WORDMACROSEXTRA, %PUNCTUATION ); - } - return (\%macs, join( '|', sort { length $b <=> length $a } keys %macs )); -} - -sub _get_mac_r { - my $scheme = shift; - my %macs; - if ( $scheme eq 'base' ) { - %macs = %WORDMACROS_R; - } - elsif ( $scheme eq 'full' ) { - %macs = ( %WORDMACROS_R, %WORDMACROSEXTRA_R ); - } - else { - %macs = ( %WORDMACROS_R, %WORDMACROSEXTRA_R ); - } - - # don't encode things which latex needs like braces etc. - foreach my $e (keys %ENCODE_EXCLUDE_R) { - delete($macs{$e}); - } - return (\%macs, join( '|', sort { length $b <=> length $a } keys %macs )); -} - - -sub _get_diac_last_r { - my ($a,$b) = @_; - if ( $b =~ /$ACCENTS_RE_R/) { - return $a eq 'i' ? '{\\i}' : $a - } - else { - return "{$a}" - } -} - - -=head1 AUTHOR - -François Charette, C<< <firmicus@cpan.org> >> - -=head1 BUGS - -Please report any bugs or feature requests to C<bug-latex-decode at -rt.cpan.org>, or through the web interface at -L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=LaTeX-Decode>. I will be -notified, and then you'll automatically be notified of progress on your bug as -I make changes. - -=head1 COPYRIGHT & LICENSE - -Copyright 2009-2010 François Charette, all rights reserved. - -This module is free software. You can redistribute it and/or -modify it under the terms of the Artistic License 2.0. - -This program is distributed in the hope that it will be useful, -but without any warranty; without even the implied warranty of -merchantability or fitness for a particular purpose. - -=cut - -1; - -# vim: set tabstop=4 shiftwidth=4 expandtab: - diff --git a/Master/texmf-dist/source/bibtex/biber/lib/Biber/LaTeX/Recode/Data.pm b/Master/texmf-dist/source/bibtex/biber/lib/Biber/LaTeX/Recode/Data.pm deleted file mode 100644 index 926045a9d02..00000000000 --- a/Master/texmf-dist/source/bibtex/biber/lib/Biber/LaTeX/Recode/Data.pm +++ /dev/null @@ -1,1013 +0,0 @@ -package Biber::LaTeX::Recode::Data; -#use feature 'unicode_strings'; -use strict; -use warnings; -use base qw(Exporter); -our @EXPORT = qw[ %ACCENTS %ACCENTS_R - %WORDMACROS %WORDMACROS_R - %DIACRITICS %DIACRITICS_R - %WORDMACROSEXTRA %WORDMACROSEXTRA_R - %DIACRITICSEXTRA %DIACRITICSEXTRA_R - %PUNCTUATION %PUNCTUATION_R - %NEGATEDSYMBOLS %NEGATEDSYMBOLS_R - %SUPERSCRIPTS %SUPERSCRIPTS_R - %SYMBOLS %SYMBOLS_R - %CMDSUPERSCRIPTS %CMDSUPERSCRIPTS_R - %DINGS %DINGS_R - %GREEK %GREEK_R - %ENCODE_EXCLUDE_R - $ACCENTS_RE $ACCENTS_RE_R - $DIAC_RE_BASE $DIAC_RE_BASE_R - $DIAC_RE_EXTRA $DIAC_RE_EXTRA_R - $NEG_SYMB_RE $NEG_SYMB_RE_R - $SUPER_RE $SUPER_RE_R - $SUPERCMD_RE $SUPERCMD_RE_R - $DINGS_RE_R - ]; - -our %ACCENTS = ( - chr(0x60) => "\x{300}", #` - chr(0x27) => "\x{301}", #' - chr(0x5e) => "\x{302}", #^ - chr(0x7e) => "\x{303}", #~ - chr(0x3d) => "\x{304}", #= - chr(0x2e) => "\x{307}", #. - chr(0x22) => "\x{308}", #" -); - -our %ACCENTS_R = reverse %ACCENTS; - -our %WORDMACROS = ( - textquotedbl => "\x{0022}", - texthash => "\x{0023}", - textdollar => "\x{0024}", - textpercent => "\x{0025}", - textampersand => "\x{0026}", - textquotesingle => "\x{0027}", - textasteriskcentered => "\x{002A}", - textless => "\x{003C}", - textequals => "\x{003D}", - textgreater => "\x{003E}", - textbackslash => "\x{005C}", - textasciicircum => "\x{005E}", - textunderscore => "\x{005F}", - textasciigrave => "\x{0060}", - textg => "\x{0067}", - textbraceleft => "\x{007B}", - textbar => "\x{007C}", - textbraceright => "\x{007D}", - textasciitilde => "\x{007E}", - nobreakspace => "\x{00A0}", - textexclamdown => "\x{00A1}", - textcent => "\x{00A2}", - pounds => "\x{00A3}", - textsterling => "\x{00A3}", - textcurrency => "\x{00A4}", - textyen => "\x{00A5}", - textbrokenbar => "\x{00A6}", - S => "\x{00A7}", - textsection => "\x{00A7}", - textasciidieresis => "\x{00A8}", - copyright => "\x{00A9}", - textcopyright => "\x{00A9}", - textordfeminine => "\x{00AA}", - guillemotleft => "\x{00AB}", - lnot => "\x{00AC}", - textlogicalnot => "\x{00AC}", - textminus => "\x{2212}", - textregistered => "\x{00AE}", - textasciimacron => "\x{00AF}", - textdegree => "\x{00B0}", - pm => "\x{00B1}", - textpm => "\x{00B1}", - texttwosuperior => "\x{00B2}", - textthreesuperior => "\x{00B3}", - textasciiacute => "\x{00B4}", - mu => "\x{00B5}", - textmu => "\x{00B5}", - P => "\x{00B6}", - textparagraph => "\x{00B6}", - textperiodcentered => "\x{00B7}", - textcentereddot => "\x{00B7}", - textasciicedilla => "\x{00B8}", - textonesuperior => "\x{00B9}", - textordmasculine => "\x{00BA}", - guillemotright => "\x{00BB}", - textonequarter => "\x{00BC}", - textonehalf => "\x{00BD}", - textthreequarters => "\x{00BE}", - textquestiondown => "\x{00BF}", - AA => "\x{00C5}", - AE => "\x{00C6}", - DH => "\x{00D0}", - times => "\x{00D7}", - texttimes => "\x{00D7}", - O => "\x{00D8}", - TH => "\x{00DE}", - Thorn => "\x{00DE}", - ss => "\x{00DF}", - aa => "\x{00E5}", - ae => "\x{00E6}", - dh => "\x{00F0}", - div => "\x{00F7}", - textdiv => "\x{00F7}", - o => "\x{00F8}", - th => "\x{00FE}", - textthorn => "\x{00FE}", - textthornvari => "\x{00FE}", - textthornvarii => "\x{00FE}", - textthornvariii => "\x{00FE}", - textthornvariv => "\x{00FE}", - DJ => "\x{0110}", - dj => "\x{0111}", - textcrd => "\x{0111}", - textHbar => "\x{0126}", - textcrh => "\x{0127}", - texthbar => "\x{0127}", - i => "\x{0131}", - IJ => "\x{0132}", - ij => "\x{0133}", - textkra => "\x{0138}", - L => "\x{0141}", - l => "\x{0142}", - textbarl => "\x{0142}", - NG => "\x{014A}", - ng => "\x{014B}", - OE => "\x{0152}", - oe => "\x{0153}" -); - -our %WORDMACROS_R = reverse %WORDMACROS; - -our %WORDMACROSEXTRA = ( - textTbar => "\x{0166}", - textTstroke => "\x{0166}", - texttbar => "\x{0167}", - texttstroke => "\x{0167}", - textcrb => "\x{0180}", - textBhook => "\x{0181}", - textOopen => "\x{0186}", - textChook => "\x{0187}", - textchook => "\x{0188}", - texthtc => "\x{0188}", - textDafrican => "\x{0189}", - textDhook => "\x{018A}", - textEreversed => "\x{018E}", - textEopen => "\x{0190}", - textFhook => "\x{0191}", - textflorin => "\x{0192}", - textGammaafrican => "\x{0194}", - texthvlig => "\x{0195}", - hv => "\x{0195}", - textIotaafrican => "\x{0196}", - textKhook => "\x{0198}", - textkhook => "\x{0199}", - texthtk => "\x{0199}", - textcrlambda => "\x{019B}", - textNhookleft => "\x{019D}", - OHORN => "\x{01A0}", - ohorn => "\x{01A1}", - textPhook => "\x{01A4}", - textphook => "\x{01A5}", - texthtp => "\x{01A5}", - textEsh => "\x{01A9}", - ESH => "\x{01A9}", - textlooptoprevesh => "\x{01AA}", - textpalhookbelow => "\x{01AB}", - textThook => "\x{01AC}", - textthook => "\x{01AD}", - texthtt => "\x{01AD}", - textTretroflexhook => "\x{01AE}", - UHORN => "\x{01AF}", - uhorn => "\x{01B0}", - textVhook => "\x{01B2}", - textYhook => "\x{01B3}", - textyhook => "\x{01B4}", - textEzh => "\x{01B7}", - texteturned => "\x{01DD}", - textturna => "\x{0250}", - textscripta => "\x{0251}", - textturnscripta => "\x{0252}", - textbhook => "\x{0253}", - texthtb => "\x{0253}", - textoopen => "\x{0254}", - textopeno => "\x{0254}", - textctc => "\x{0255}", - textdtail => "\x{0256}", - textrtaild => "\x{0256}", - textdhook => "\x{0257}", - texthtd => "\x{0257}", - textreve => "\x{0258}", - textschwa => "\x{0259}", - textrhookschwa => "\x{025A}", - texteopen => "\x{025B}", - textepsilon => "\x{025B}", - textrevepsilon => "\x{025C}", - textrhookrevepsilon => "\x{025D}", - textcloserevepsilon => "\x{025E}", - textbardotlessj => "\x{025F}", - texthtg => "\x{0260}", - textscriptg => "\x{0261}", - textscg => "\x{0262}", - textgammalatinsmall => "\x{0263}", - textgamma => "\x{0263}", - textramshorns => "\x{0264}", - textturnh => "\x{0265}", - texthth => "\x{0266}", - texththeng => "\x{0267}", - textbari => "\x{0268}", - textiotalatin => "\x{0269}", - textiota => "\x{0269}", - textsci => "\x{026A}", - textltilde => "\x{026B}", - textbeltl => "\x{026C}", - textrtaill => "\x{026D}", - textlyoghlig => "\x{026E}", - textturnm => "\x{026F}", - textturnmrleg => "\x{0270}", - textltailm => "\x{0271}", - textltailn => "\x{0272}", - textnhookleft => "\x{0272}", - textrtailn => "\x{0273}", - textscn => "\x{0274}", - textbaro => "\x{0275}", - textscoelig => "\x{0276}", - textcloseomega => "\x{0277}", - textphi => "\x{0278}", - textturnr => "\x{0279}", - textturnlonglegr => "\x{027A}", - textturnrrtail => "\x{027B}", - textlonglegr => "\x{027C}", - textrtailr => "\x{027D}", - textfishhookr => "\x{027E}", - textlhti => "\x{027F}", # ?? - textscr => "\x{0280}", - textinvscr => "\x{0281}", - textrtails => "\x{0282}", - textesh => "\x{0283}", - texthtbardotlessj => "\x{0284}", - textraisevibyi => "\x{0285}", # ?? - textctesh => "\x{0286}", - textturnt => "\x{0287}", - textrtailt => "\x{0288}", - texttretroflexhook => "\x{0288}", - textbaru => "\x{0289}", - textupsilon => "\x{028A}", - textscriptv => "\x{028B}", - textvhook => "\x{028B}", - textturnv => "\x{028C}", - textturnw => "\x{028D}", - textturny => "\x{028E}", - textscy => "\x{028F}", - textrtailz => "\x{0290}", - textctz => "\x{0291}", - textezh => "\x{0292}", - textyogh => "\x{0292}", - textctyogh => "\x{0293}", - textglotstop => "\x{0294}", - textrevglotstop => "\x{0295}", - textinvglotstop => "\x{0296}", - textstretchc => "\x{0297}", - textbullseye => "\x{0298}", - textscb => "\x{0299}", - textcloseepsilon => "\x{029A}", - texthtscg => "\x{029B}", - textsch => "\x{029C}", - textctj => "\x{029D}", - textturnk => "\x{029E}", - textscl => "\x{029F}", - texthtq => "\x{02A0}", - textbarglotstop => "\x{02A1}", - textbarrevglotstop => "\x{02A2}", - textdzlig => "\x{02A3}", - textdyoghlig => "\x{02A4}", - textdctzlig => "\x{02A5}", - texttslig => "\x{02A6}", - textteshlig => "\x{02A7}", - texttesh => "\x{02A7}", - texttctclig => "\x{02A8}", - hamza => "\x{02BE}", - ain => "\x{02BF}", - ayn => "\x{02BF}", - textprimstress => "\x{02C8}", - textlengthmark => "\x{02D0}" -); - -our %WORDMACROSEXTDA_R = reverse %WORDMACROSEXTRA; - -our %DIACRITICS = ( - r => "\x{030A}", - H => "\x{030B}", - u => "\x{0306}", - v => "\x{030C}", - G => "\x{030F}", - M => "\x{0322}", - d => "\x{0323}", - c => "\x{0327}", - k => "\x{0328}", - b => "\x{0331}", - B => "\x{0335}", - t => "\x{0311}", -); - -our %DIACRITICS_R = reverse %DIACRITICS; - -our %DIACRITICSEXTRA = ( - textvbaraccent => "\x{030D}", - textdoublevbaraccent => "\x{030E}", - textdotbreve => "\x{0310}", - textturncommaabove => "\x{0312}", - textcommaabove => "\x{0313}", - textrevcommaabove => "\x{0314}", - textcommaabover => "\x{0315}", - textsubgrave => "\x{0316}", - textsubacute => "\x{0317}", - textadvancing => "\x{0318}", - textretracting => "\x{0319}", - textlangleabove => "\x{031A}", - textrighthorn => "\x{031B}", - textsublhalfring => "\x{031C}", - textraising => "\x{031D}", - textlowering => "\x{031E}", - textsubplus => "\x{031F}", - textsubbar => "\x{0320}", - textsubminus => "\x{0320}", - textpalhookbelow => "\x{0321}", - textsubumlaut => "\x{0324}", - textsubring => "\x{0325}", - textcommabelow => "\x{0326}", - textsyllabic => "\x{0329}", - textsubbridge => "\x{032A}", - textsubw => "\x{032B}", - textsubwedge => "\x{032C}", - textsubcircnum => "\x{032D}", - textsubbreve => "\x{032E}", - textundertie => "\x{032E}", - textsubarch => "\x{032F}", - textsubtilde => "\x{0330}", - subdoublebar => "\x{0333}", - textsuperimposetilde => "\x{0334}", - textlstrokethru => "\x{0336}", - textsstrikethru => "\x{0337}", - textlstrikethru => "\x{0338}", - textsubrhalfring => "\x{0339}", - textinvsubbridge => "\x{033A}", - textsubsquare => "\x{033B}", - textseagull => "\x{033C}", - textovercross => "\x{033D}", - overbridge => "\x{0346}", - subdoublebar => "\x{0347}", ## ?? - subdoublevert => "\x{0348}", - subcorner => "\x{0349}", - crtilde => "\x{034A}", - textoverw => "\x{034A}", - dottedtilde => "\x{034B}", - doubletilde => "\x{034C}", - spreadlips => "\x{034D}", - whistle => "\x{034E}", - textrightarrowhead => "\x{0350}", - textlefthalfring => "\x{0351}", - sublptr => "\x{0354}", - subrptr => "\x{0355}", - textrightuparrowhead => "\x{0356}", - textrighthalfring => "\x{0357}", - textdoublebreve => "\x{035D}", - textdoublemacron => "\x{035E}", - textdoublemacronbelow => "\x{035F}", - textdoubletilde => "\x{0360}", - texttoptiebar => "\x{0361}", - sliding => "\x{0362}" -); - -our %DIACRITICSEXTRA_R = reverse %DIACRITICSEXTRA; - -our %PUNCTUATION = ( - textendash => "\x{2013}", - textemdash => "\x{2014}", - textquoteleft => "\x{2018}", - textquoteright => "\x{2019}", - quotesinglbase => "\x{201A}", - textquotedblleft => "\x{201C}", - textquotedblright => "\x{201D}", - quotedblbase => "\x{201E}", - dag => "\x{2020}", - ddag => "\x{2021}", - textbullet => "\x{2022}", - dots => "\x{2026}", - textperthousand => "\x{2030}", - textpertenthousand => "\x{2031}", - guilsinglleft => "\x{2039}", - guilsinglright => "\x{203A}", - textreferencemark => "\x{203B}", - textinterrobang => "\x{203D}", - textoverline => "\x{203E}", - langle => "\x{27E8}", - rangle => "\x{27E9}" -); - -our %PUNCTUATION_R = reverse %PUNCTUATION; - -# \not\xxx -our %NEGATEDSYMBOLS = ( - asymp => "\x{226D}", - lesssim => "\x{2274}", - gtrsim => "\x{2275}", - subset => "\x{2284}", - supset => "\x{2285}", - ni => "\x{220C}", - simeq => "\x{2244}", - approx => "\x{2249}", - equiv => "\x{2262}", - preccurlyeq => "\x{22E0}", - succcurlyeq => "\x{22E1}", - sqsubseteq => "\x{22E2}", - sqsupseteq => "\x{22E3}", -); - -our %NEGATEDSYMBOLS_R = reverse %NEGATEDSYMBOLS; - -# \textsuperscript{x} -our %SUPERSCRIPTS = ( - 0 => "\x{2070}", - i => "\x{2071}", - 4 => "\x{2074}", - 5 => "\x{2075}", - 6 => "\x{2076}", - 7 => "\x{2077}", - 8 => "\x{2078}", - 9 => "\x{2079}", - '+' => "\x{207A}", - '-' => "\x{207B}", - '=' => "\x{207C}", - '(' => "\x{207D}", - ')' => "\x{207E}", - n => "\x{207F}", - SM => "\x{2120}", - h => "\x{02b0}", - j => "\x{02b2}", - r => "\x{02b3}", - w => "\x{02b7}", - y => "\x{02b8}" -); - -our %SUPERSCRIPTS_R = reverse %SUPERSCRIPTS; - -# \textsuperscript{\xxx} -our %CMDSUPERSCRIPTS = ( - texthth => "\x{02b1}", - textturnr => "\x{02b4}", - textturnrrtail => "\x{02b5}", - textinvscr => "\x{02b6}" -); - -our %CMDSUPERSCRIPTS_R = reverse %CMDSUPERSCRIPTS; - -our %SYMBOLS = ( - textcolonmonetary => "\x{20A1}", - textlira => "\x{20A4}", - textnaira => "\x{20A6}", - textwon => "\x{20A9}", - textdong => "\x{20AB}", - euro => "\x{20AC}", - texteuro => "\x{20AC}", - textnumero => "\x{2116}", - texttrademark => "\x{2122}", - leftarrow => "\x{2190}", - uparrow => "\x{2191}", - rightarrow => "\x{2192}", - downarrow => "\x{2193}", - leftrightarrow => "\x{2194}", - updownarrow => "\x{2195}", - leadsto => "\x{219D}", - rightleftharpoons => "\x{21CC}", - Rightarrow => "\x{21D2}", - Leftrightarrow => "\x{21D4}", - forall => "\x{2200}", - complement => "\x{2201}", - partial => "\x{2202}", - exists => "\x{2203}", - nexists => "\x{2204}", - set => "\x{2205}", - Delta => "\x{2206}", - nabla => "\x{2207}", - in => "\x{2208}", - notin => "\x{2209}", - ni => "\x{220B}", - prod => "\x{220F}", - coprod => "\x{2210}", - sum => "\x{2211}", - mp => "\x{2213}", - dotplus => "\x{2214}", - setminus => "\x{2216}", - ast => "\x{2217}", - circ => "\x{2218}", - bullet => "\x{2219}", - surd => "\x{221A}", - propto => "\x{221D}", - infty => "\x{221E}", - angle => "\x{2220}", - measuredangle => "\x{2221}", - sphericalangle => "\x{2222}", - mid => "\x{2223}", - nmid => "\x{2224}", - parallel => "\x{2225}", - nparallel => "\x{2226}", - wedge => "\x{2227}", - vee => "\x{2228}", - cap => "\x{2229}", - cup => "\x{222A}", - int => "\x{222B}", - iint => "\x{222C}", - iiint => "\x{222D}", - oint => "\x{222E}", - therefore => "\x{2234}", - because => "\x{2235}", - sim => "\x{223C}", - backsim => "\x{223D}", - wr => "\x{2240}", - nsim => "\x{2241}", - simeq => "\x{2243}", - cong => "\x{2245}", - ncong => "\x{2247}", - approx => "\x{2248}", - approxeq => "\x{224A}", - asymp => "\x{224D}", - Bumpeq => "\x{224E}", - bumpeq => "\x{224F}", - doteq => "\x{2250}", - doteqdot => "\x{2251}", - fallingdotseq => "\x{2252}", - risingdotseq => "\x{2253}", - eqcirc => "\x{2256}", - circeq => "\x{2257}", - triangleq => "\x{225C}", - neq => "\x{2260}", - equiv => "\x{2261}", - leq => "\x{2264}", - geq => "\x{2265}", - leqq => "\x{2266}", - geqq => "\x{2267}", - lneqq => "\x{2268}", - gneqq => "\x{2269}", - ll => "\x{226A}", - gg => "\x{226B}", - between => "\x{226C}", - nless => "\x{226E}", - ngtr => "\x{226F}", - nleq => "\x{2270}", - ngeq => "\x{2271}", - lesssim => "\x{2272}", - gtrsim => "\x{2273}", - lessgtr => "\x{2276}", - gtrless => "\x{2277}", - prec => "\x{227A}", - succ => "\x{227B}", - preccurlyeq => "\x{227C}", - succcurlyeq => "\x{227D}", - precsim => "\x{227E}", - succsim => "\x{227F}", - nprec => "\x{2280}", - nsucc => "\x{2281}", - subset => "\x{2282}", - supset => "\x{2283}", - subseteq => "\x{2286}", - supseteq => "\x{2287}", - nsubseteq => "\x{2288}", - nsupseteq => "\x{2289}", - subsetneq => "\x{228A}", - supsetneq => "\x{228B}", - uplus => "\x{228E}", - sqsubset => "\x{228F}", - sqsupset => "\x{2290}", - sqsubseteq => "\x{2291}", - sqsupseteq => "\x{2292}", - sqcap => "\x{2293}", - sqcup => "\x{2294}", - oplus => "\x{2295}", - ominus => "\x{2296}", - otimes => "\x{2297}", - oslash => "\x{2298}", - odot => "\x{2299}", - circledcirc => "\x{229A}", - circledast => "\x{229B}", - circleddash => "\x{229D}", - boxplus => "\x{229E}", - boxminus => "\x{229F}", - boxtimes => "\x{22A0}", - boxdot => "\x{22A1}", - vdash => "\x{22A2}", - dashv => "\x{22A3}", - top => "\x{22A4}", - bot => "\x{22A5}", - Vdash => "\x{22A9}", - Vvdash => "\x{22AA}", - nVdash => "\x{22AE}", - lhd => "\x{22B2}", - rhd => "\x{22B3}", - unlhd => "\x{22B4}", - unrhd => "\x{22B5}", - multimap => "\x{22B8}", - intercal => "\x{22BA}", - veebar => "\x{22BB}", - barwedge => "\x{22BC}", - bigwedge => "\x{22C0}", - bigvee => "\x{22C1}", - bigcap => "\x{22C2}", - bigcup => "\x{22C3}", - diamond => "\x{22C4}", - cdot => "\x{22C5}", - star => "\x{22C6}", - divideontimes => "\x{22C7}", - bowtie => "\x{22C8}", - ltimes => "\x{22C9}", - rtimes => "\x{22CA}", - leftthreetimes => "\x{22CB}", - rightthreetimes => "\x{22CC}", - backsimeq => "\x{22CD}", - curlyvee => "\x{22CE}", - curlywedge => "\x{22CF}", - Subset => "\x{22D0}", - Supset => "\x{22D1}", - Cap => "\x{22D2}", - Cup => "\x{22D3}", - pitchfork => "\x{22D4}", - lessdot => "\x{22D6}", - gtrdot => "\x{22D7}", - lll => "\x{22D8}", - ggg => "\x{22D9}", - lesseqgtr => "\x{22DA}", - gtreqless => "\x{22DB}", - curlyeqprec => "\x{22DE}", - curlyeqsucc => "\x{22DF}", - lnsim => "\x{22E6}", - gnsim => "\x{22E7}", - precnsim => "\x{22E8}", - succnsim => "\x{22E9}", - ntriangleleft => "\x{22EA}", - ntriangleright => "\x{22EB}", - ntrianglelefteq => "\x{22EC}", - ntrianglerighteq => "\x{22ED}", - vdots => "\x{22EE}", - cdots => "\x{22EF}", - ddots => "\x{22F1}", - lceil => "\x{2308}", - rceil => "\x{2309}", - lfloor => "\x{230A}", - rfloor => "\x{230B}", - Box => "\x{25A1}", - spadesuit => "\x{2660}", - heartsuit => "\x{2661}", - diamondsuit => "\x{2662}", - clubsuit => "\x{2663}", - flat => "\x{266D}", - natural => "\x{266E}", - sharp => "\x{266F}", - tone5 => "\x{02E5}", - tone4 => "\x{02E6}", - tone3 => "\x{02E7}", - tone2 => "\x{02E8}", - tone1 => "\x{02E9}" -); - -our %SYMBOLS_R = reverse %SYMBOLS; - -our %DINGS = ( - '21' => "\x{2701}", - '22' => "\x{2702}", - '23' => "\x{2703}", - '24' => "\x{2704}", - '25' => "\x{260E}", - '26' => "\x{2706}", - '27' => "\x{2707}", - '28' => "\x{2708}", - '29' => "\x{2709}", - '2A' => "\x{261B}", - '2B' => "\x{261E}", - '2C' => "\x{270C}", - '2D' => "\x{270D}", - '2E' => "\x{270E}", - '2F' => "\x{270F}", - '30' => "\x{2710}", - '31' => "\x{2711}", - '32' => "\x{2712}", - '33' => "\x{2713}", - '34' => "\x{2714}", - '35' => "\x{2715}", - '36' => "\x{2716}", - '37' => "\x{2717}", - '38' => "\x{2718}", - '39' => "\x{2719}", - '3A' => "\x{271A}", - '3B' => "\x{271B}", - '3C' => "\x{271C}", - '3D' => "\x{271D}", - '3E' => "\x{271E}", - '3F' => "\x{271F}", - '40' => "\x{2720}", - '41' => "\x{2721}", - '42' => "\x{2722}", - '43' => "\x{2723}", - '44' => "\x{2724}", - '45' => "\x{2725}", - '46' => "\x{2726}", - '47' => "\x{2727}", - '48' => "\x{2605}", - '49' => "\x{2729}", - '4A' => "\x{272A}", - '4B' => "\x{272B}", - '4C' => "\x{272C}", - '4D' => "\x{272D}", - '4E' => "\x{272E}", - '4F' => "\x{272F}", - '50' => "\x{2730}", - '51' => "\x{2731}", - '52' => "\x{2732}", - '53' => "\x{2733}", - '54' => "\x{2734}", - '55' => "\x{2735}", - '56' => "\x{2736}", - '57' => "\x{2737}", - '58' => "\x{2738}", - '59' => "\x{2739}", - '5A' => "\x{273A}", - '5B' => "\x{273B}", - '5C' => "\x{273C}", - '5D' => "\x{273D}", - '5E' => "\x{273E}", - '5F' => "\x{273F}", - '60' => "\x{2740}", - '61' => "\x{2741}", - '62' => "\x{2742}", - '63' => "\x{2743}", - '64' => "\x{2744}", - '65' => "\x{2745}", - '66' => "\x{2746}", - '67' => "\x{2747}", - '68' => "\x{2748}", - '69' => "\x{2749}", - '6A' => "\x{274A}", - '6B' => "\x{274B}", - '6C' => "\x{25CF}", - '6D' => "\x{274D}", - '6E' => "\x{25A0}", - '6F' => "\x{274F}", - '70' => "\x{2750}", - '71' => "\x{2751}", - '72' => "\x{2752}", - '73' => "\x{25B2}", - '74' => "\x{25BC}", - '75' => "\x{25C6}", - '76' => "\x{2756}", - '77' => "\x{25D7}", - '78' => "\x{2758}", - '79' => "\x{2759}", - '7A' => "\x{275A}", - '7B' => "\x{275B}", - '7C' => "\x{275C}", - '7D' => "\x{275D}", - '7E' => "\x{275E}", - 'A1' => "\x{2761}", - 'A2' => "\x{2762}", - 'A3' => "\x{2763}", - 'A4' => "\x{2764}", - 'A5' => "\x{2765}", - 'A6' => "\x{2766}", - 'A7' => "\x{2767}", - 'A9' => "\x{2666}", - 'AA' => "\x{2665}", - 'AC' => "\x{2460}", - 'AD' => "\x{2461}", - 'AE' => "\x{2462}", - 'AF' => "\x{2463}", - 'B0' => "\x{2464}", - 'B1' => "\x{2465}", - 'B2' => "\x{2466}", - 'B3' => "\x{2467}", - 'B4' => "\x{2468}", - 'B5' => "\x{2469}", - 'B6' => "\x{2776}", - 'B7' => "\x{2777}", - 'B8' => "\x{2778}", - 'B9' => "\x{2779}", - 'BA' => "\x{277A}", - 'BB' => "\x{277B}", - 'BC' => "\x{277C}", - 'BD' => "\x{277D}", - 'BE' => "\x{277E}", - 'BF' => "\x{277F}", - 'C0' => "\x{2780}", - 'C1' => "\x{2781}", - 'C2' => "\x{2782}", - 'C3' => "\x{2783}", - 'C4' => "\x{2784}", - 'C5' => "\x{2785}", - 'C6' => "\x{2786}", - 'C7' => "\x{2787}", - 'C8' => "\x{2788}", - 'C9' => "\x{2789}", - 'CA' => "\x{278A}", - 'CB' => "\x{278B}", - 'CC' => "\x{278C}", - 'CD' => "\x{278D}", - 'CE' => "\x{278E}", - 'CF' => "\x{278F}", - 'D0' => "\x{2790}", - 'D1' => "\x{2791}", - 'D2' => "\x{2792}", - 'D3' => "\x{2793}", - 'D4' => "\x{2794}", - 'D6' => "\x{2194}", - 'D7' => "\x{2195}", - 'D8' => "\x{2798}", - 'D9' => "\x{2799}", - 'DA' => "\x{279A}", - 'DB' => "\x{279B}", - 'DC' => "\x{279C}", - 'DD' => "\x{279D}", - 'DE' => "\x{279E}", - 'DF' => "\x{279F}", - 'E0' => "\x{27A0}", - 'E1' => "\x{27A1}", - 'E2' => "\x{27A2}", - 'E3' => "\x{27A3}", - 'E4' => "\x{27A4}", - 'E5' => "\x{27A5}", - 'E6' => "\x{27A6}", - 'E7' => "\x{27A7}", - 'E8' => "\x{27A8}", - 'E9' => "\x{27A9}", - 'EA' => "\x{27AA}", - 'EB' => "\x{27AB}", - 'EC' => "\x{27AC}", - 'ED' => "\x{27AD}", - 'EE' => "\x{27AE}", - 'EF' => "\x{27AF}", - 'F1' => "\x{27B1}", - 'F2' => "\x{27B2}", - 'F3' => "\x{27B3}", - 'F4' => "\x{27B4}", - 'F5' => "\x{27B5}", - 'F6' => "\x{27B6}", - 'F7' => "\x{27B7}", - 'F8' => "\x{27B8}", - 'F9' => "\x{27B9}", - 'FA' => "\x{27BA}", - 'FB' => "\x{27BB}", - 'FC' => "\x{27BC}", - 'FD' => "\x{27BD}", - 'FE' => "\x{27BE}" -); - -our %DINGS_R = reverse %DINGS; - -our %GREEK = ( - alpha => "\x{3b1}", - beta => "\x{3b2}", - gamma => "\x{3b3}", - delta => "\x{3b4}", - varepsilon => "\x{3b5}", - zeta => "\x{3b6}", - eta => "\x{3b7}", - vartheta => "\x{3b8}", - iota => "\x{3b9}", - kappa => "\x{3ba}", - lambda => "\x{3bb}", - mu => "\x{3bc}", - nu => "\x{3bd}", - xi => "\x{3be}", - omicron => "\x{3bf}", - pi => "\x{3c0}", - varrho => "\x{3c1}", - varsigma => "\x{3c2}", - sigma => "\x{3c3}", - tau => "\x{3c4}", - upsilon => "\x{3c5}", - varphi => "\x{3c6}", - chi => "\x{3c7}", - psi => "\x{3c8}", - omega => "\x{3c9}", - Alpha => "\x{391}", - Beta => "\x{392}", - Gamma => "\x{393}", - Delta => "\x{394}", - Epsilon => "\x{395}", - Zeta => "\x{396}", - Eta => "\x{397}", - Theta => "\x{398}", - Iota => "\x{399}", - Kappa => "\x{39a}", - Lambda => "\x{39b}", - Mu => "\x{39c}", - Nu => "\x{39d}", - Xi => "\x{39e}", - Omicron => "\x{39f}", - Pi => "\x{3a0}", - Rho => "\x{3a1}", - Sigma => "\x{3a3}", - Tau => "\x{3a4}", - Upsilon => "\x{3a5}", - Phi => "\x{3a6}", - Chi => "\x{3a7}", - Psi => "\x{3a8}", - Omega => "\x{3a9}" -); - -our %GREEK_R = reverse %GREEK; - -# Things we don't want to change when encoding as this would break LaTeX -our %ENCODE_EXCLUDE_R = ( - chr(0x22) => 1, # \textquotedbl - chr(0x23) => 1, # \texthash - chr(0x24) => 1, # \textdollar - chr(0x25) => 1, # \textpercent - chr(0x26) => 1, # \textampersand - chr(0x27) => 1, # \textquotesingle - chr(0x2a) => 1, # \textasteriskcentered - chr(0x3c) => 1, # \textless - chr(0x3d) => 1, # \textequals - chr(0x3e) => 1, # \textgreater - chr(0x5c) => 1, # \textbackslash - chr(0x5e) => 1, # \textasciicircum - chr(0x5f) => 1, # \textunderscore - chr(0x60) => 1, # \textasciigrave - chr(0x67) => 1, # \textg - chr(0x7b) => 1, # \textbraceleft - chr(0x7c) => 1, # \textbar - chr(0x7d) => 1, # \textbraceright - chr(0x7e) => 1, # \textasciitilde - chr(0xa0) => 1, # \nobreakspace - chr(0xa3) => 1, # \textsterling - chr(0xb1) => 1, # \pm - chr(0xb5) => 1, # \mu - chr(0xb6) => 1, # \P - ); - -our $ACCENTS_RE = qr{[\^\.`'"~=]}; -our $ACCENTS_RE_R = qr{[\x{300}-\x{304}\x{307}\x{308}]}; - -our $DIAC_RE_BASE = join('|', keys %DIACRITICS); -$DIAC_RE_BASE = qr{$DIAC_RE_BASE}; -our $DIAC_RE_BASE_R = join('|', keys %DIACRITICS_R); -$DIAC_RE_BASE_R = qr{$DIAC_RE_BASE_R}; - -our $DIAC_RE_EXTRA = join('|', sort {length $b <=> length $a} keys %DIACRITICSEXTRA); -$DIAC_RE_EXTRA = qr{$DIAC_RE_EXTRA|$DIAC_RE_BASE}; -our $DIAC_RE_EXTRA_R = join('|', sort {length $b <=> length $a} keys %DIACRITICSEXTRA_R); -$DIAC_RE_EXTRA_R = qr{$DIAC_RE_EXTRA_R|$DIAC_RE_BASE_R}; - -our $NEG_SYMB_RE = join('|', sort keys %NEGATEDSYMBOLS); -$NEG_SYMB_RE = qr{$NEG_SYMB_RE}; -our $NEG_SYMB_RE_R = join('|', sort keys %NEGATEDSYMBOLS_R); -$NEG_SYMB_RE_R = qr{$NEG_SYMB_RE_R}; - -our $SUPER_RE; -my @_ss = keys %SUPERSCRIPTS; -$SUPER_RE = join('|', map { /[\+\-\)\(]/ ? '\\' . $_ : $_ } @_ss); -$SUPER_RE = qr{$SUPER_RE}; -our $SUPER_RE_R; -my @_ss_r = keys %SUPERSCRIPTS_R; -$SUPER_RE_R = join('|', map { /[\+\-\)\(]/ ? '\\' . $_ : $_ } @_ss_r); -$SUPER_RE_R = qr{$SUPER_RE_R}; - -our $SUPERCMD_RE = join('|', keys %CMDSUPERSCRIPTS); -$SUPERCMD_RE = qr{$SUPERCMD_RE}; -our $SUPERCMD_RE_R = join('|', keys %CMDSUPERSCRIPTS_R); -$SUPERCMD_RE_R = qr{$SUPERCMD_RE_R}; - -our $DINGS_RE_R = join('|', keys %DINGS_R); -$DINGS_RE_R = qr{$DINGS_RE_R}; - - -=head1 AUTHOR - -François Charette, C<< <firmicus at gmx.net> >> - -=head1 BUGS - -Please report any bugs or feature requests to C<bug-latex-decode at -rt.cpan.org>, or through the web interface at -L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=LaTeX-Decode>. I will be -notified, and then you'll automatically be notified of progress on your bug as -I make changes. - -=head1 NOTICE - -This module is currently distributed with biber, but it is not unlikely that it -will eventually make its way to CPAN. - -=head1 COPYRIGHT & LICENSE - -Copyright 2009-2010 François Charette, all rights reserved. - -This module is free software. You can redistribute it and/or -modify it under the terms of the Artistic License 2.0. - -This program is distributed in the hope that it will be useful, -but without any warranty; without even the implied warranty of -merchantability or fitness for a particular purpose. - -=cut - -1; - -# vim: set tabstop=4 shiftwidth=4 expandtab: diff --git a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Output/BBL.pm b/Master/texmf-dist/source/bibtex/biber/lib/Biber/Output/BBL.pm deleted file mode 100644 index c6f33f7ae0e..00000000000 --- a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Output/BBL.pm +++ /dev/null @@ -1,501 +0,0 @@ -package Biber::Output::BBL; -#use feature 'unicode_strings'; -use base 'Biber::Output::Base'; - -use Biber::Config; -use Biber::Constants; -use Biber::Entry; -use Biber::Utils; -use IO::File; -use Log::Log4perl qw( :no_extra_logdie_message ); -my $logger = Log::Log4perl::get_logger('main'); - -=encoding utf-8 - -=head1 NAME - -Biber::Output::BBL - class for Biber output of .bbl - -=cut - -=head2 new - - Initialize a Biber::Output::BBL object - -=cut - -sub new { - my $class = shift; - my $self = $class->SUPER::new($obj); - my $ctrlver = Biber::Config->getblxoption('controlversion'); - my $beta = $Biber::BETA_VERSION ? ' (beta)' : ''; - - my $BBLHEAD = <<EOF; -% \$ biblatex auxiliary file \$ -% \$ biblatex version $ctrlver \$ -% \$ biber version $Biber::VERSION$beta \$ -% Do not modify the above lines! -% -% This is an auxiliary file used by the 'biblatex' package. -% This file may safely be deleted. It will be recreated by -% biber or bibtex as required. -% -\\begingroup -\\makeatletter -\\\@ifundefined{ver\@biblatex.sty} - {\\\@latex\@error - {Missing 'biblatex' package} - {The bibliography requires the 'biblatex' package.} - \\aftergroup\\endinput} - {} -\\endgroup - -EOF - - $self->set_output_head($BBLHEAD); - return $self; -} - -=head2 set_output_target_file - - Set the output target file of a Biber::Output::BBL object - A convenience around set_output_target so we can keep track of the - filename - -=cut - -sub set_output_target_file { - my $self = shift; - my $bblfile = shift; - $self->{output_target_file} = $bblfile; - my $enc_out; - if (Biber::Config->getoption('bblencoding')) { - $enc_out = ':encoding(' . Biber::Config->getoption('bblencoding') . ')'; - } - my $BBLFILE = IO::File->new($bblfile, ">$enc_out") or $logger->logdie("Failed to open $bblfile : $!"); - $self->set_output_target($BBLFILE); -} - -=head2 _printfield - - Add the .bbl for a text field to the output accumulator. - -=cut - -sub _printfield { - my ($self, $field, $str) = @_; - my $field_type = 'field'; - # crossref and xref are of type 'strng' in the .bbl - if (lc($field) eq 'crossref' or - lc($field) eq 'xref') { - $field_type = 'strng'; - } - if (Biber::Config->getoption('wraplines')) { - ## 12 is the length of ' \field{}{}' or ' \strng{}{}' - if ( 12 + length($field) + length($str) > 2*$Text::Wrap::columns ) { - return " \\${field_type}{$field}{%\n" . wrap(' ', ' ', $str) . "%\n }\n"; - } - elsif ( 12 + length($field) + length($str) > $Text::Wrap::columns ) { - return wrap(' ', ' ', "\\${field_type}{$field}{$str}" ) . "\n"; - } - else { - return " \\${field_type}{$field}{$str}\n"; - } - } - else { - return " \\${field_type}{$field}{$str}\n"; - } - return; -} - -=head2 set_output_undefkey - - Set the .bbl output for an undefined key - -=cut - -sub set_output_undefkey { - my $self = shift; - my $key = shift; # undefined key - my $section = shift; # Section object the entry occurs in - my $acc = ''; - my $secnum = $section->number; - - $acc .= " \\missing{$key}\n"; - - # Create an index by keyname for easy retrieval - $self->{output_data}{ENTRIES}{$secnum}{index}{lc($key)} = \$acc; - - return; -} - - -=head2 set_output_entry - - Set the .bbl output for an entry. This is the meat of - the .bbl output - -=cut - -sub set_output_entry { - my $self = shift; - my $be = shift; # Biber::Entry object - my $section = shift; # Section object the entry occurs in - my $struc = shift; # Structure object - my $acc = ''; - my $opts = ''; - my $citekey; # entry key in original form (case) from citation - my $secnum = $section->number; - - if ( $be->get_field('citekey') ) { - $citekey = $be->get_field('citekey'); - } - - if ($be->field_exists('options')) { - $opts = $be->get_field('options'); - } - - $acc .= " \\entry{$citekey}{" . $be->get_field('entrytype') . "}{$opts}\n"; - - # Generate set information - if ( $be->get_field('entrytype') eq 'set' ) { # Set parents get \set entry ... - $acc .= " \\set{" . $be->get_field('entryset') . "}\n"; - } - else { # Everything else that isn't a set parent ... - if (my $es = $be->get_field('entryset')) { # ... gets a \inset if it's a set member - $acc .= " \\inset{$es}\n"; - } - } - - # Output name fields - - # first output copy in labelname - # This is essentially doing the same thing twice but in the future, - # labelname will have different things attached than the raw name - my $lnn = $be->get_field('labelnamename'); # save name of labelname field - my $name_others_deleted = ''; - if (my $ln = $be->get_field('labelname')) { - if ( $ln->last_element->get_namestring eq 'others' ) { - $acc .= " \\true{morelabelname}\n"; - $ln->del_last_element; - # record that we have deleted "others" from labelname field - # we will need this below - $name_others_deleted = $lnn; - } - my $total = $ln->count_elements; - $acc .= " \\name{labelname}{$total}{%\n"; - foreach my $n (@{$ln->names}) { - $acc .= $n->name_to_bbl; - } - $acc .= " }\n"; - } - - # then names themselves - foreach my $namefield (@{$struc->get_field_type('name')}) { - next if $struc->is_field_type('skipout', $namefield); - if ( my $nf = $be->get_field($namefield) ) { - # If this name is labelname, we've already deleted the "others" - # so just add the boolean - if ($name_others_deleted eq $namefield) { - $acc .= " \\true{more$namefield}\n"; - } - # otherwise delete and add the boolean - elsif ($nf->last_element->get_namestring eq 'others') { - $acc .= " \\true{more$namefield}\n"; - $nf->del_last_element; - } - my $total = $nf->count_elements; - $acc .= " \\name{$namefield}{$total}{%\n"; - foreach my $n (@{$nf->names}) { - $acc .= $n->name_to_bbl; - } - $acc .= " }\n"; - } - } - - # Output list fields - foreach my $listfield (@{$struc->get_field_type('list')}) { - if (my $lf = $be->get_field($listfield)) { - if ( $be->get_field($listfield)->[-1] eq 'others' ) { - $acc .= " \\true{more$listfield}\n"; - pop @$lf; # remove the last element in the array - }; - my $total = $#$lf + 1; - $acc .= " \\list{$listfield}{$total}{%\n"; - foreach my $f (@$lf) { - $acc .= " {$f}%\n"; - } - $acc .= " }\n"; - } - } - - my $namehash = $be->get_field('namehash'); - $acc .= " \\strng{namehash}{$namehash}\n"; - my $fullhash = $be->get_field('fullhash'); - $acc .= " \\strng{fullhash}{$fullhash}\n"; - - if ( Biber::Config->getblxoption('labelalpha', $be->get_field('entrytype')) ) { - # Might not have been set due to skiplab/dataonly - if (my $label = $be->get_field('labelalpha')) { - $acc .= " \\field{labelalpha}{$label}\n"; - } - } - - # This is special, we have to put a marker for sortinit and then replace this string - # on output as it can vary between lists - $acc .= " <BDS>SORTINIT</BDS>\n"; - - # The labelyear option determines whether "extrayear" is output - if ( Biber::Config->getblxoption('labelyear', $be->get_field('entrytype'))) { - # Might not have been set due to skiplab/dataonly - if (my $nameyear_extrayear = $be->get_field('nameyear_extrayear')) { - if ( Biber::Config->get_seen_nameyear_extrayear($nameyear_extrayear) > 1) { - $acc .= " <BDS>EXTRAYEAR</BDS>\n"; - } - } - if (my $ly = $be->get_field('labelyear')) { - $acc .= " \\field{labelyear}{$ly}\n"; - } - } - - # The labelalpha option determines whether "extraalpha" is output - if ( Biber::Config->getblxoption('labelalpha', $be->get_field('entrytype'))) { - # Might not have been set due to skiplab/dataonly - if (my $nameyear_extraalpha = $be->get_field('nameyear_extraalpha')) { - if ( Biber::Config->get_seen_nameyear_extraalpha($nameyear_extraalpha) > 1) { - $acc .= " <BDS>EXTRAALPHA</BDS>\n"; - } - } - } - - if ( Biber::Config->getblxoption('labelnumber', $be->get_field('entrytype')) ) { - if (my $sh = $be->get_field('shorthand')) { - $acc .= " \\field{labelnumber}{$sh}\n"; - } - elsif (my $lnum = $be->get_field('labelnumber')) { - $acc .= " \\field{labelnumber}{$lnum}\n"; - } - } - - if (my $unopt = Biber::Config->getblxoption('uniquename', $be->get_field('entrytype'))) { - my $lname = $be->get_field('labelnamename'); - my $name; - my $lastname; - my $nameinitstr; - my $un; - - if ($lname) { - $name = $be->get_field($lname)->nth_element(1); - $lastname = $name->get_lastname; - $nameinitstr = $name->get_nameinitstring; - } - # uniquename is requested but there is no labelname or there are more than two names in - # labelname - if ($be->get_field('ignoreuniquename')) { - $un = '0'; - } - # If there is one entry (hash) for the lastname, then it's unique - elsif (Biber::Config->get_numofuniquenames($lastname) == 1 ) { - $un = '0'; - } - # Otherwise, if there is one entry (hash) for the lastname plus initials, - # then it needs the initials to make it unique - elsif (Biber::Config->get_numofuniquenames($nameinitstr) == 1 ) { - $un = '1'; - } - # Otherwise the name needs to be full to make it unique - # but restricted to uniquename biblatex option value just in case - # this is inits only (1); - else { - $un = $unopt; - } - $acc .= " \\count{uniquename}{$un}\n"; - } - - # skiplab entries don't have a seennamehash count so this gives an error - # unless we check for this - if ( Biber::Config->getblxoption('singletitle', $be->get_field('entrytype')) - and (not Biber::Config->get_seennamehash($be->get_field('fullhash')) or - Biber::Config->get_seennamehash($be->get_field('fullhash')) < 2 )) - { - $acc .= " \\true{singletitle}\n"; - } - - foreach my $lfield (@{$struc->get_field_type('literal')}) { - next if $struc->is_field_type('skipout', $lfield); - if ( ($struc->is_field_type('nullok', $lfield) and - $be->field_exists($lfield)) or - $be->get_field($lfield) ) { - # we skip outputting the crossref or xref when the parent is not cited - # (biblatex manual, section 2.23) - # sets are a special case so always output crossref/xref for them since their - # children will always be in the .bbl otherwise they make no sense. - unless ( $be->get_field('entrytype') eq 'set') { - next if ($lfield eq 'crossref' and - not $section->has_citekey($be->get_field('crossref'))); - next if ($lfield eq 'xref' and - not $section->has_citekey($be->get_field('xref'))); - } - $acc .= $self->_printfield( $lfield, $be->get_field($lfield) ); - } - } - - foreach my $rfield (@{$struc->get_field_type('range')}) { - if ( my $rf = $be->get_field($rfield) ) { - # range fields are an array ref of two-element array refs [range_start, range_end] - # range_end can be be empty for open-ended range or undef - my @pr; - foreach my $f (@$rf) { - if (defined($f->[1])) { - push @pr, $f->[0] . '\bibrangedash' . ($f->[1] ? ' ' . $f->[1] : ''); - } - else { - push @pr, $f->[0]; - } - } - my $bbl_rf = join(', ', @pr); - $acc .= " \\field{$rfield}{$bbl_rf}\n"; - } - } - - foreach my $vfield (@{$struc->get_field_type('verbatim')}) { - if ( my $vf = $be->get_field($vfield) ) { - $acc .= " \\verb{$vfield}\n"; - $acc .= " \\verb $vf\n \\endverb\n"; - } - } - if ( my $k = $be->get_field('keywords') ) { - $acc .= " \\keyw{$k}\n"; - } - - # Append any warnings to the entry, if any - if ( my $w = $be->get_field('warnings')) { - foreach my $warning (@$w) { - $acc .= " \\warn{\\item $warning}\n"; - } - } - - $acc .= " \\endentry\n\n"; - - # Create an index by keyname for easy retrieval - $self->{output_data}{ENTRIES}{$secnum}{index}{lc($citekey)} = \$acc; - - return; -} - - -=head2 output - - BBL output method - this takes care to output entries in the explicit order - derived from the virtual order of the citekeys after sortkey sorting. - -=cut - -sub output { - my $self = shift; - my $data = $self->{output_data}; - my $target = $self->{output_target}; - my $target_string = "Target"; # Default - if ($self->{output_target_file}) { - $target_string = $self->{output_target_file}; - } - - # for debugging mainly - unless ($target) { - $target = new IO::File '>-'; - } - - $logger->debug('Preparing final output using class ' . __PACKAGE__ . '...'); - - $logger->info("Writing '$target_string' with encoding '" . Biber::Config->getoption('bblencoding') . "'"); - - print $target $data->{HEAD} or $logger->logdie("Failure to write head to $target_string: $!"); - - foreach my $secnum (sort keys %{$data->{ENTRIES}}) { - $logger->debug("Writing entries for section $secnum"); - - print $target "\n\\refsection{$secnum}\n"; - my $section = $self->get_output_section($secnum); - - # This sort is cosmetic, just to order the lists in a predictable way in the .bbl - foreach my $list (sort {$a->get_label cmp $b->get_label} @{$section->get_lists}) { - my $listlabel = $list->get_label; - my $listtype = $list->get_type; - $logger->debug("Writing entries in list '$listlabel'"); - - # Remove most of this conditional when biblatex supports lists - if ($listlabel eq 'SHORTHANDS') { - print $target " \\lossort\n"; - } - else { - print $target "\n \\sortlist{$listlabel}\n" unless ($listlabel eq 'MAIN'); - } - - # The order of this array is the sorted order - foreach my $k ($list->get_keys) { - $logger->debug("Writing entry for key '$k'"); - if ($listtype eq 'entry') { - my $entry = $data->{ENTRIES}{$secnum}{index}{lc($k)}; - - # Instantiate any dynamic, list specific entry information - my $entry_string = $list->instantiate_entry($entry, $k); - - # If requested to convert UTF-8 to macros ... - if (Biber::Config->getoption('bblsafechars')) { - $entry_string = latex_recode_output($entry_string); - } - - print $target $entry_string or $logger->logdie("Failure to write list element to $target_string: $!"); - } - elsif ($listtype eq 'shorthand') { - print $target " \\key{$k}\n" or $logger->logdie("Failure to write list element to $target_string: $!"); - } - } - - # Remove most of this conditional when biblatex supports lists - if ($listlabel eq 'SHORTHANDS') { - print $target " \\endlossort\n\n"; - } - else { - print $target "\n \\endsortlist\n\n" unless ($listlabel eq 'MAIN'); - } - } - - print $target "\\endrefsection\n" - } - - print $target $data->{TAIL} or $logger->logdie("Failure to write tail to $target_string: $!"); - - $logger->info("Output to $target_string"); - close $target or $logger->logdie("Failure to close $target_string: $!"); - return; -} - - -=head1 AUTHORS - -François Charette, C<< <firmicus at gmx.net> >> -Philip Kime C<< <philip at kime.org.uk> >> - -=head1 BUGS - -Please report any bugs or feature requests on our sourceforge tracker at -L<https://sourceforge.net/tracker2/?func=browse&group_id=228270>. - -=head1 COPYRIGHT & LICENSE - -Copyright 2009-2011 François Charette and Philip Kime, all rights reserved. - -This module is free software. You can redistribute it and/or -modify it under the terms of the Artistic License 2.0. - -This program is distributed in the hope that it will be useful, -but without any warranty; without even the implied warranty of -merchantability or fitness for a particular purpose. - -=cut - -1; - -# vim: set tabstop=2 shiftwidth=2 expandtab: - diff --git a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Output/Base.pm b/Master/texmf-dist/source/bibtex/biber/lib/Biber/Output/Base.pm deleted file mode 100644 index 84f33ee1b84..00000000000 --- a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Output/Base.pm +++ /dev/null @@ -1,334 +0,0 @@ -package Biber::Output::Base; -#use feature 'unicode_strings'; - -use Biber::Entry; -use IO::File; -use Log::Log4perl qw( :no_extra_logdie_message ); -my $logger = Log::Log4perl::get_logger('main'); - -=encoding utf-8 - -=head1 NAME - -Biber::Output::Base - base class for Biber output modules. - -=cut - -=head2 new - - Initialize a Biber::Output::Base object - -=cut - -sub new { - my $class = shift; - my $obj = shift; - my $self; - if (defined($obj) and ref($obj) eq 'HASH') { - $self = bless $obj, $class; - } - else { - $self = bless {}, $class; - } - return $self; -} - -=head2 set_output_target_file - - Set the output target file of a Biber::Output::Base object - A convenience around set_output_target so we can keep track of the - filename - -=cut - -sub set_output_target_file { - my $self = shift; - my $file = shift; - $self->{output_target_file} = $file; - my $enc_out; - if (Biber::Config->getoption('bblencoding')) { - $enc_out = ':encoding(' . Biber::Config->getoption('bblencoding') . ')'; - } - my $TARGET = IO::File->new($file, ">$enc_out") or $logger->logdie("Failed to open $file : $!"); - $self->set_output_target($TARGET); -} - - -=head2 set_output_target - - Set the output target of a Biber::Output::Base object - -=cut - -sub set_output_target { - my $self = shift; - my $target = shift; - $logger->logdie('Output target must be a IO::Handle object!') unless $target->isa('IO::Handle'); - $self->{output_target} = $target; - return; -} - -=head2 set_output_head - - Set the output head of a Biber::Output::Base object - $data could be anything - the caller is expected to know. - -=cut - -sub set_output_head { - my $self = shift; - my $data = shift; - $self->{output_data}{HEAD} = $data; - return; -} - -=head2 set_output_tail - - Set the output tail of a Biber::Output::Base object - $data could be anything - the caller is expected to know. - -=cut - -sub set_output_tail { - my $self = shift; - my $data = shift; - $self->{output_data}{TAIL} = $data; - return; -} - - -=head2 get_output_head - - Get the output head of a Biber::Output object - $data could be anything - the caller is expected to know. - Mainly used in debugging - -=cut - -sub get_output_head { - my $self = shift; - return $self->{output_data}{HEAD}; -} - -=head2 get_output_tail - - Get the output tail of a Biber::Output object - $data could be anything - the caller is expected to know. - Mainly used in debugging - -=cut - -sub get_output_tail { - my $self = shift; - return $self->{output_data}{TAIL}; -} - - -=head2 add_output_head - - Add to the head output data of a Biber::Output::Base object - The base class method just does a string append - -=cut - -sub add_output_head { - my $self = shift; - my $data = shift; - $self->{output_data}{HEAD} .= $data; - return; -} - -=head2 add_output_tail - - Add to the tail output data of a Biber::Output::Base object - The base class method just does a string append - -=cut - -sub add_output_tail { - my $self = shift; - my $data = shift; - $self->{output_data}{TAIL} .= $data; - return; -} - - -=head2 set_output_section - - Records the section object in the output object - We need some information from this when writing the .bbl - -=cut - -sub set_output_section { - my $self = shift; - my $secnum = shift; - my $section = shift; - $self->{section}{$secnum} = $section; - return; -} - -=head2 get_output_section - - Retrieve the output section object - -=cut - -sub get_output_section { - my $self = shift; - my $secnum = shift; - return $self->{section}{$secnum}; -} - - -=head2 get_output_entries - - Get the sorted order output data for all entries in a list as array ref - -=cut - -sub get_output_entries { - my $self = shift; - my $section = shift; - my $list = shift; - return [ map {$self->{output_data}{ENTRIES}{$section}{index}{$_}} @{$list->get_keys}]; -} - -=head2 get_output_entry - - Get the output data for a specific entry. - Used really only in tests as it instantiates list dynamic information so - we can see it in tests - -=cut - -sub get_output_entry { - my $self = shift; - my $list = shift; - my $key = shift; - my $section = shift; - $section = '0' if not defined($section); # default - mainly for tests - # Force a return of undef if there is no output for this key to avoid - # dereferencing errors in tests - my $out = $self->{output_data}{ENTRIES}{$section}{index}{lc($key)}; - my $out_string = $list->instantiate_entry($out, $key); - return $out ? $out_string : undef; -} - -=head2 set_los - - Set the output list of shorthands for a section - -=cut - -sub set_los { - my $self = shift; - my $shs = shift; - my $section = shift; - $self->{output_data}{LOS}{$section} = $shs; - return; -} - -=head2 get_los - - Get the output list of shorthands for a section as an array - -=cut - -sub get_los { - my $self = shift; - my $section = shift; - return @{$self->{output_data}{LOS}{$section}} -} - - -=head2 set_output_entry - - Add an entry output to a Biber::Output::Base object - The base class method just does a dump - -=cut - -sub set_output_entry { - my $self = shift; - my $entry = shift; - my $section = shift; - my $struc = shift; - $self->{output_data}{ENTRIES}{$section}{index}{lc($entry->get_field('citekey'))} = $entry->dump; - return; -} - -=head2 output - - Generic base output method - -=cut - -sub output { - my $self = shift; - my $data = $self->{output_data}; - my $target = $self->{output_target}; - my $target_string = "Target"; # Default - if ($self->{output_target_file}) { - $target_string = $self->{output_target_file}; - } - - $logger->debug('Preparing final output using class ' . __PACKAGE__ . '...'); - - $logger->info("Writing '$target_string' with encoding '" . Biber::Config->getoption('bblencoding') . "'"); - - print $target $data->{HEAD} or $logger->logdie("Failure to write head to $target_string: $!"); - - foreach my $secnum (sort keys %{$data->{ENTRIES}}) { - print $target "SECTION: $secnum\n\n"; - foreach my $list (@{$self->get_output_section($secnum)->get_lists}) { - my $listlabel = $list->get_label; - my $listtype = $list->get_type; - print $target " LIST: $listlabel\n\n"; - foreach my $k ($list->get_keys) { - if ($listtype eq 'entry') { - my $entry_string = $data->{ENTRIES}{$secnum}{index}{$k}; - print $target $entry_string or $logger->logdie("Failure to write entry '$k' to $target_string: $!"); - } - elsif ($listtype eq 'shorthand') { - next if Biber::Config->getblxoption('skiplos', $section->bibentry($k), $k); - print $target $k or $logger->logdie("Failure to write list element to $target_string: $!"); - } - } - } - } - - print $target $data->{TAIL} or $logger->logdie("Failure to write tail to $target_string: $!"); - - $logger->info("Output to $target_string"); - close $target or $logger->logdie("Failure to close $target_string: $!"); - return; -} - -=head1 AUTHORS - -François Charette, C<< <firmicus at gmx.net> >> -Philip Kime C<< <philip at kime.org.uk> >> - -=head1 BUGS - -Please report any bugs or feature requests on our sourceforge tracker at -L<https://sourceforge.net/tracker2/?func=browse&group_id=228270>. - -=head1 COPYRIGHT & LICENSE - -Copyright 2009-2011 François Charette and Philip Kime, all rights reserved. - -This module is free software. You can redistribute it and/or -modify it under the terms of the Artistic License 2.0. - -This program is distributed in the hope that it will be useful, -but without any warranty; without even the implied warranty of -merchantability or fitness for a particular purpose. - -=cut - -1; - -# vim: set tabstop=2 shiftwidth=2 expandtab: - diff --git a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Output/Test.pm b/Master/texmf-dist/source/bibtex/biber/lib/Biber/Output/Test.pm deleted file mode 100644 index e554ccca3b8..00000000000 --- a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Output/Test.pm +++ /dev/null @@ -1,367 +0,0 @@ -package Biber::Output::Test; -#use feature 'unicode_strings'; -use base 'Biber::Output::Base'; - -use Biber::Config; -use Biber::Constants; -use Biber::Entry; -use Biber::Utils; -use IO::File; -use Log::Log4perl qw( :no_extra_logdie_message ); -my $logger = Log::Log4perl::get_logger('main'); - -=encoding utf-8 - -=head1 NAME - -Biber::Output::Test - Output class for loopback testing -Essentially, this outputs to a string so we can look at it internally in tests - -=cut - - -=head2 _printfield - - Add the .bbl for a text field to the output accumulator. - -=cut - -sub _printfield { - my ($self, $field, $str) = @_; - if (Biber::Config->getoption('wraplines')) { - ## 12 is the length of ' \field{}{}' - if ( 12 + length($field) + length($str) > 2*$Text::Wrap::columns ) { - return " \\field{$field}{%\n" . wrap(' ', ' ', $str) . "%\n }\n"; - } - elsif ( 12 + length($field) + length($str) > $Text::Wrap::columns ) { - return wrap(' ', ' ', "\\field{$field}{$str}" ) . "\n"; - } - else { - return " \\field{$field}{$str}\n"; - } - } - else { - return " \\field{$field}{$str}\n"; - } - return; -} - -=head2 set_output_entry - - Set the .bbl output for an entry. This is the meat of - the .bbl output - -=cut - -sub set_output_entry { - my $self = shift; - my $be = shift; # Biber::Entry object - my $section = shift; # Section the entry occurs in - my $struc = shift; # Structure object - my $acc = ''; - my $opts = ''; - my $citekey; # entry key forced to case of any citations(s) which reference it - my $secnum = $section->number; - - if ( $be->get_field('citekey') ) { - $citekey = $be->get_field('citekey'); - } - - if ( $be->field_exists('options') ) { - $opts = $be->get_field('options'); - } - - $acc .= "% sortstring = " . $be->get_field('sortstring') . "\n" - if (Biber::Config->getoption('debug') || Biber::Config->getblxoption('debug')); - - $acc .= " \\entry{$citekey}{" . $be->get_field('entrytype') . "}{$opts}\n"; - - # Generate set information - if ( $be->get_field('entrytype') eq 'set' ) { # Set parents get \set entry ... - $acc .= " \\set{" . $be->get_field('entryset') . "}\n"; - } - else { # Everything else that isn't a set parent ... - if (my $es = $be->get_field('entryset')) { # ... gets a \inset if it's a set member - $acc .= " \\inset{$es}\n"; - } - } - - # Output name fields - - # first output copy in labelname - # This is essentially doing the same thing twice but in the future, - # labelname will have different things attached than the raw name - my $lnn = $be->get_field('labelnamename'); # save name of labelname field - my $name_others_deleted = ''; - if (my $ln = $be->get_field('labelname')) { - if ( $ln->last_element->get_namestring eq 'others' ) { - $acc .= " \\true{morelabelname}\n"; - $ln->del_last_element; - # record that we have deleted "others" from labelname field - # we will need this below - $name_others_deleted = $lnn; - } - my $total = $ln->count_elements; - $acc .= " \\name{labelname}{$total}{%\n"; - foreach my $n (@{$ln->names}) { - $acc .= $n->name_to_bbl; - } - $acc .= " }\n"; - } - - # then names themselves - foreach my $namefield (@{$struc->get_field_type('name')}) { - next if $struc->is_field_type('skipout', $namefield); - if ( my $nf = $be->get_field($namefield) ) { - # If this name is labelname, we've already deleted the "others" - # so just add the boolean - if ($name_others_deleted eq $namefield) { - $acc .= " \\true{more$namefield}\n"; - } - # otherwise delete and add the boolean - elsif ($nf->last_element->get_namestring eq 'others') { - $acc .= " \\true{more$namefield}\n"; - $nf->del_last_element; - } - my $total = $nf->count_elements; - $acc .= " \\name{$namefield}{$total}{%\n"; - foreach my $n (@{$nf->names}) { - $acc .= $n->name_to_bbl; - } - $acc .= " }\n"; - } - } - - foreach my $listfield (@{$struc->get_field_type('list')}) { - if ( my $lf = $be->get_field($listfield) ) { - if ( $be->get_field($listfield)->[-1] eq 'others' ) { - $acc .= " \\true{more$listfield}\n"; - pop @$lf; # remove the last element in the array - }; - my $total = $#$lf + 1; - $acc .= " \\list{$listfield}{$total}{%\n"; - foreach my $f (@$lf) { - $acc .= " {$f}%\n"; - } - $acc .= " }\n"; - } - } - - my $namehash = $be->get_field('namehash'); - $acc .= " \\strng{namehash}{$namehash}\n"; - my $fullhash = $be->get_field('fullhash'); - $acc .= " \\strng{fullhash}{$fullhash}\n"; - - if ( Biber::Config->getblxoption('labelalpha', $be->get_field('entrytype')) ) { - # Might not have been set due to skiplab/dataonly - if (my $label = $be->get_field('labelalpha')) { - $acc .= " \\field{labelalpha}{$label}\n"; - } - } - - # This is special, we have to put a marker for sortinit and then replace this string - # on output as it can vary between lists - $acc .= " <BDS>SORTINIT</BDS>\n"; - - # The labelyear option determines whether "extrayear" is output - # Skip generating extrayear for entries with "skiplab" set - if ( Biber::Config->getblxoption('labelyear', $be->get_field('entrytype'))) { - # Might not have been set due to skiplab/dataonly - if (my $ey = $be->get_field('extrayear')) { - my $nameyear_extrayear = $be->get_field('nameyear_extrayear'); - if ( Biber::Config->get_seen_nameyear_extrayear($nameyear_extrayear) > 1) { - $acc .= " \\field{extrayear}{$ey}\n"; - } - } - if (my $ly = $be->get_field('labelyear')) { - $acc .= " \\field{labelyear}{$ly}\n"; - } - } - - # The labelalpha option determines whether "extraalpha" is output - # Skip generating extraalpha for entries with "skiplab" set - if ( Biber::Config->getblxoption('labelalpha', $be->get_field('entrytype'))) { - # Might not have been set due to skiplab/dataonly - if (my $ea = $be->get_field('extraalpha')) { - my $nameyear_extraalpha = $be->get_field('nameyear_extraalpha'); - if ( Biber::Config->get_seen_nameyear_extraalpha($nameyear_extraalpha) > 1) { - $acc .= " \\field{extraalpha}{$ea}\n"; - } - } - } - - if ( Biber::Config->getblxoption('labelnumber', $be->get_field('entrytype')) ) { - if (my $sh = $be->get_field('shorthand')) { - $acc .= " \\field{labelnumber}{$sh}\n"; - } - elsif (my $ln = $be->get_field('labelnumber')) { - $acc .= " \\field{labelnumber}{$ln}\n"; - } - } - - if (my $unopt = Biber::Config->getblxoption('uniquename', $be->get_field('entrytype'))) { - my $lname = $be->get_field('labelnamename'); - my $name; - my $lastname; - my $nameinitstr; - my $un; - - if ($lname) { - $name = $be->get_field($lname)->nth_element(1); - $lastname = $name->get_lastname; - $nameinitstr = $name->get_nameinitstring; - } - # uniquename is requested but there is no labelname or there are more than two names in - # labelname - if ($be->get_field('ignoreuniquename')) { - $un = '0'; - } - # If there is one entry (hash) for the lastname, then it's unique - elsif (Biber::Config->get_numofuniquenames($lastname) == 1 ) { - $un = '0'; - } - # Otherwise, if there is one entry (hash) for the lastname plus initials, - # the it needs the initials to make it unique - elsif (Biber::Config->get_numofuniquenames($nameinitstr) == 1 ) { - $un = '1'; - } - # Otherwise the name needs to be full to make it unique - # but restricted to uniquename biblatex option value just in case - # this is inits only (1); - else { - $un = $unopt; - } - $acc .= " \\count{uniquename}{$un}\n"; - } - - if ( Biber::Config->getblxoption('singletitle', $be->get_field('entrytype')) - and Biber::Config->get_seennamehash($be->get_field('fullhash')) < 2 ) - { - $acc .= " \\true{singletitle}\n"; - } - - foreach my $lfield (@{$struc->get_field_type('literal')}) { - next if $struc->is_field_type('skipout', $lfield); - if ( ($struc->is_field_type('nullok', $lfield) and - $be->field_exists($lfield)) or - $be->get_field($lfield) ) { - # we skip outputting the crossref or xref when the parent is not cited - # (biblatex manual, section 2.23) - # sets are a special case so always output crossref/xref for them since their - # children will always be in the .bbl otherwise they make no sense. - unless ( $be->get_field('entrytype') eq 'set') { - next if ($lfield eq 'crossref' and - not $section->has_citekey($be->get_field('crossref'))); - next if ($lfield eq 'xref' and - not $section->has_citekey($be->get_field('xref'))); - } - - $acc .= $self->_printfield( $lfield, $be->get_field($lfield) ); - } - } - - foreach my $rfield (@{$struc->get_field_type('range')}) { - if ( my $rf = $be->get_field($rfield)) { - $rf =~ s/[-–]+/\\bibrangedash /g; - $acc .= " \\field{$rfield}{$rf}\n"; - } - } - - foreach my $vfield (@{$struc->get_field_type('verbatim')}) { - if ( my $rf = $be->get_field($vfield) ) { - $acc .= " \\verb{$vfield}\n"; - $acc .= " \\verb $rf\n \\endverb\n"; - } - } - if ( my $k = $be->get_field('keywords') ) { - $acc .= " \\keyw{$k}\n"; - } - - # Append any warnings to the entry, if any - if (my $w = $be->get_field('warnings')) { - foreach my $warning (@$w) { - $acc .= " \\warn{\\item $warning}\n"; - } - } - - $acc .= " \\endentry\n\n"; - - # Create an index by keyname for easy retrieval - $self->{output_data}{ENTRIES}{$secnum}{index}{lc($citekey)} = \$acc; - return; -} - -=head2 output - - BBL output method - this takes care to output entries in the explicit order - derived from the virtual order of the auxcitekeys after sortkey sorting. - -=cut - -sub output { - my $self = shift; - my $data = $self->{output_data}; - my $target = $self->{output_target}; - - $logger->info("Writing output with encoding '" . Biber::Config->getoption('bblencoding') . "'"); - - foreach my $secnum (sort keys %{$data->{ENTRIES}}) { - my $section = $self->get_output_section($secnum); - foreach my $list (@{$section->get_lists}) { - my $listlabel = $list->get_label; - my $listtype = $list->get_type; - foreach my $k ($list->get_keys) { - if ($listtype eq 'entry') { - my $entry = $data->{ENTRIES}{$secnum}{index}{lc($k)}; - - # Instantiate any dynamic, list specific entry information - my $entry_string = $list->instantiate_entry($entry, $k); - - # If requested to convert UTF-8 to macros ... - if (Biber::Config->getoption('bblsafechars')) { - $logger->info('Converting UTF-8 to TeX macros on output to .bbl'); - require Biber::LaTeX::Recode; - $entry_string = Biber::LaTeX::Recode::latex_encode($entry_string, - scheme => Biber::Config->getoption('bblsafecharsset')); - } - print $target $entry_string; - } - elsif ($listtype eq 'shorthand') { - next if Biber::Config->getblxoption('skiplos', $section->bibentry($k), $k); - print $target $k; - } - } - } - } - close $target; - return; -} - - -=head1 AUTHORS - -François Charette, C<< <firmicus at gmx.net> >> -Philip Kime C<< <philip at kime.org.uk> >> - -=head1 BUGS - -Please report any bugs or feature requests on our sourceforge tracker at -L<https://sourceforge.net/tracker2/?func=browse&group_id=228270>. - -=head1 COPYRIGHT & LICENSE - -Copyright 2009-2011 François Charette and Philip Kime, all rights reserved. - -This module is free software. You can redistribute it and/or -modify it under the terms of the Artistic License 2.0. - -This program is distributed in the hope that it will be useful, -but without any warranty; without even the implied warranty of -merchantability or fitness for a particular purpose. - -=cut - -1; - -# vim: set tabstop=2 shiftwidth=2 expandtab: - diff --git a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Section.pm b/Master/texmf-dist/source/bibtex/biber/lib/Biber/Section.pm deleted file mode 100644 index 237f2d9fbfa..00000000000 --- a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Section.pm +++ /dev/null @@ -1,452 +0,0 @@ -package Biber::Section; -#use feature 'unicode_strings'; - -use Biber::Entries; -use Biber::Utils; -use List::Util qw( first ); - -=encoding utf-8 - -=head1 NAME - -Biber::Section - -=head2 new - - Initialize a Biber::Section object - -=cut - -sub new { - my ($class, %params) = @_; - my $self = bless {%params}, $class; - $self->{bibentries} = new Biber::Entries; - $self->{allkeys} = 0; - $self->{citekeys} = []; - $self->{sortcache} = []; - $self->{dkeys} = {}; - $self->{orig_order_citekeys} = []; - $self->{undef_citekeys} = []; - return $self; -} - -=head2 allkeys - - Sets flag to say citekey '*' occurred in citekeys - -=cut - -sub allkeys { - my $self = shift; - $self->{allkeys} = 1; - return; -} - -=head2 is_allkeys - - Checks flag which says citekey '*' occurred in citekeys - -=cut - -sub is_allkeys { - my $self = shift; - return $self->{allkeys}; -} - - -=head2 bibentry - - Returns a Biber::Entry object for the given citation key - -=cut - -sub bibentry { - my $self = shift; - my $key = shift; - $key = lc($key); - return $self->bibentries->entry($key); -} - -=head2 bibentries - - Return Biber::Entries object for this section - -=cut - -sub bibentries { - my $self = shift; - return $self->{bibentries}; -} - -=head2 del_bibentries - - Delete all Biber::Entry objects from the Biber::Section object - -=cut - -sub del_bibentries { - my $self = shift; - $self->{bibentries} = new Biber::Entries; - return; -} - - -=head2 set_citekeys - - Sets the citekeys in a Biber::Section object - -=cut - -sub set_citekeys { - my $self = shift; - my $keys = shift; - $self->{citekeys} = $keys; - return; -} - -=head2 set_orig_order_citekeys - - Sets the original order of citekeys in a Biber::Section object - -=cut - -sub set_orig_order_citekeys { - my $self = shift; - my $keys = shift; - $self->{orig_order_citekeys} = $keys; - return; -} - - -=head2 get_citekeys - - Gets the citekeys of a Biber::Section object - Returns a normal array - -=cut - -sub get_citekeys { - my $self = shift; - return @{$self->{citekeys}}; -} - -=head2 get_static_citekeys - - Gets the citekeys of a Biber::Section object - excluding dynamic set entry keys - Returns a normal array - -=cut - -sub get_static_citekeys { - my $self = shift; - return reduce_array($self->{citekeys}, $self->dynamic_set_keys); -} - - -=head2 get_undef_citekeys - - Gets the list of undefined citekeys of a Biber::Section object - Returns a normal array - -=cut - -sub get_undef_citekeys { - my $self = shift; - return @{$self->{undef_citekeys}}; -} - -=head2 get_orig_order_citekeys - - Gets the citekeys of a Biber::Section object in their original order - This is just to ensure we have a method that will return this, just in - case we mess about with the order at some point. This is needed by - citeorder sorting. - -=cut - -sub get_orig_order_citekeys { - my $self = shift; - return @{$self->{orig_order_citekeys}}; -} - -=head2 has_citekey - - Returns true when $key is in the Biber::Section object - -=cut - -sub has_citekey { - my $self = shift; - my $key = shift; - return defined ( first { lc($_) eq lc($key) } $self->get_citekeys ) ? 1 : 0; -} - - - -=head2 del_citekey - - Deletes a citekey from a Biber::Section object - -=cut - -sub del_citekey { - my $self = shift; - my $key = shift; - return unless $self->has_citekey($key); - $self->{citekeys} = [ grep {$_ ne $key} @{$self->{citekeys}} ]; - $self->{orig_order_citekeys} = [ grep {$_ ne $key} @{$self->{orig_order_citekeys}} ]; - return; -} - -=head2 del_citekeys - - Deletes al citekeys from a Biber::Section object - -=cut - -sub del_citekeys { - my $self = shift; - $self->{citekeys} = [ ]; - $self->{orig_order_citekeys} = [ ]; - return; -} - - -=head2 set_dynamic_set - - Record a mapping of dynamic key to member keys - -=cut - -sub set_dynamic_set { - my $self = shift; - my $dkey = shift; - my @members = @_; - $self->{dkeys}{$dkey} = \@members; - return; -} - -=head2 get_dynamic_set - - Retrieve member keys for a dynamic set key - Check on has reference returning anything stop spurious warnings - about empty dereference in return. - -=cut - -sub get_dynamic_set { - my $self = shift; - my $dkey = shift; - if (my $set_members = $self->{dkeys}{$dkey}) { - return @$set_members; - } - else { - return (); - } -} - -=head2 dynamic_set_keys - - Retrieve all dynamic set keys - -=cut - -sub dynamic_set_keys { - my $self = shift; - return [keys %{$self->{dkeys}}]; -} - - -=head2 add_citekeys - - Adds citekeys to the Biber::Section object - -=cut - -sub add_citekeys { - my $self = shift; - my @keys = @_; - foreach my $key (@keys) { - next if $self->has_citekey($key); - push @{$self->{citekeys}}, $key; - push @{$self->{orig_order_citekeys}}, $key; - } - return; -} - -=head2 add_undef_citekey - - Adds a citekey to the Biber::Section object as an undefined - key. This allows us to output this information to the .bbl and - so biblatex can do better reporting to external utils like latexmk - -=cut - -sub add_undef_citekey { - my $self = shift; - my $key = shift; - push @{$self->{undef_citekeys}}, $key; - return; -} - - -=head2 add_datasource - - Adds a data source to a section - -=cut - -sub add_datasource { - my $self = shift; - my $source = shift; - push @{$self->{datasources}}, $source; - return; -} - -=head2 set_datasources - - Sets the data sources for a section - -=cut - -sub set_datasources { - my $self = shift; - my $sources = shift; - $self->{datasources} = $sources; - return; -} - - -=head2 get_datasources - - Gets an array of data sources for this section - -=cut - -sub get_datasources { - my $self = shift; - if (exists($self->{datasources})) { - return $self->{datasources}; - } - else { - return undef; - } -} - -=head2 add_list - - Adds a section list to this section - -=cut - -sub add_list { - my $self = shift; - my $list = shift; - push @{$self->{lists}}, $list; - return; -} - -=head2 get_lists - - Returns an array ref of all section lists - -=cut - -sub get_lists { - my $self = shift; - return $self->{lists}; -} - -=head2 get_list - - Returns a specific list by label - -=cut - -sub get_list { - my $self = shift; - my $label = shift; - foreach my $list (@{$self->{lists}}) { - return $list if ($list->get_label eq $label); - } - return undef; -} - -=head2 add_sort_cache - - Adds a scheme/keys pair to the sort cache: - [$scheme, $keys, $sortinitdata, $extraalphadata, $extrayeardata ] - -=cut - -sub add_sort_cache { - my $self = shift; - my $cacheitem = shift; - push @{$self->{sortcache}}, $cacheitem; - return; -} - - -=head2 get_sort_cache - - Retrieves the sort cache - -=cut - -sub get_sort_cache { - my $self = shift; - return $self->{sortcache}; -} - -=head2 reset_sort_cache - - Reset the sort cache - -=cut - -sub reset_sort_cache { - my $self = shift; - $self->{sortcache} = []; - return; -} - - - -=head2 number - - Gets the section number of a Biber::Section object - -=cut - -sub number { - my $self = shift; - return $self->{number}; -} - -=head1 AUTHORS - -François Charette, C<< <firmicus at gmx.net> >> -Philip Kime C<< <philip at kime.org.uk> >> - -=head1 BUGS - -Please report any bugs or feature requests on our sourceforge tracker at -L<https://sourceforge.net/tracker2/?func=browse&group_id=228270>. - -=head1 COPYRIGHT & LICENSE - -Copyright 2009-2011 François Charette and Philip Kime, all rights reserved. - -This module is free software. You can redistribute it and/or -modify it under the terms of the Artistic License 2.0. - -This program is distributed in the hope that it will be useful, -but without any warranty; without even the implied warranty of -merchantability or fitness for a particular purpose. - -=cut - -1; - -# vim: set tabstop=2 shiftwidth=2 expandtab: diff --git a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Section/List.pm b/Master/texmf-dist/source/bibtex/biber/lib/Biber/Section/List.pm deleted file mode 100644 index bc3f996b70d..00000000000 --- a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Section/List.pm +++ /dev/null @@ -1,368 +0,0 @@ -package Biber::Section::List; -#use feature 'unicode_strings'; -use Biber::Utils; -use List::Util qw( first ); - -=encoding utf-8 - -=head1 NAME - -Biber::Section::List - -=head2 new - - Initialize a Biber::Section::List object - -=cut - -sub new { - my ($class, %params) = @_; - my $self = bless {%params}, $class; - return $self; -} - -=head2 set_label - - Sets the label of a section list - -=cut - -sub set_label { - my $self = shift; - my $label = shift; - $self->{label} = lc($label); - return; -} - -=head2 get_label - - Gets the label of a section list - -=cut - -sub get_label { - my $self = shift; - return $self->{label}; -} - -=head2 set_type - - Sets the type of a section list - -=cut - -sub set_type { - my $self = shift; - my $type = shift; - $self->{type} = lc($type); - return; -} - -=head2 get_type - - Gets the type of a section list - -=cut - -sub get_type { - my $self = shift; - return $self->{type}; -} - -=head2 get_listdata - - Gets all of the list metadata - -=cut - -sub get_listdata { - my $self = shift; - return [ $self->{sortscheme}, - $self->{keys}, - $self->{sortinitdata}, - $self->{extraalphadata}, - $self->{extrayeardata} ]; -} - -=head2 set_extrayeardata - - Saves extrayear field data for a key - -=cut - -sub set_extrayeardata { - my $self = shift; - my $key = shift; - my $ed = shift; - return unless defined($key); - $self->{extrayeardata}{lc($key)} = $ed; - return; -} - -=head2 get_extrayeardata - - Gets the extrayear field data for a key - -=cut - -sub get_extrayeardata { - my $self = shift; - my $key = shift; - return unless defined($key); - return $self->{extrayeardata}{lc($key)}; -} - -=head2 set_extraalphadata - - Saves extrayear field data for a key - -=cut - -sub set_extraalphadata { - my $self = shift; - my $key = shift; - my $ed = shift; - return unless defined($key); - $self->{extraalphadata}{lc($key)} = $ed; - return; -} - -=head2 get_extraalphadata - - Gets the extraalpha field data for a key - -=cut - -sub get_extraalphadata { - my $self = shift; - my $key = shift; - return unless defined($key); - return $self->{extraalphadata}{lc($key)}; -} - -=head2 set_sortdata - - Saves sorting data in a list for a key - -=cut - -sub set_sortdata { - my $self = shift; - my $key = shift; - my $sd = shift; - return unless defined($key); - $self->{sortdata}{lc($key)} = $sd; - return; -} - -=head2 get_sortdata - - Gets the sorting data in a list for a key - -=cut - -sub get_sortdata { - my $self = shift; - my $key = shift; - return unless defined($key); - return $self->{sortdata}{lc($key)}; -} - - -=head2 set_sortinitdata - - Saves sortinit data in a list for a key - -=cut - -sub set_sortinitdata { - my $self = shift; - my $key = shift; - my $sid = shift; - return unless defined($key); - $self->{sortinitdata}{lc($key)} = $sid; - return; -} - - -=head2 get_sortinitdata - - Gets the sortinit data in a list for a key - -=cut - -sub get_sortinitdata { - my $self = shift; - my $key = shift; - return unless defined($key); - return $self->{sortinitdata}{lc($key)}; -} - - -=head2 set_sortscheme - - Sets the sortscheme of a list - -=cut - -sub set_sortscheme { - my $self = shift; - my $sortscheme = shift; - $self->{sortscheme} = $sortscheme; - return; -} - -=head2 get_sortscheme - - Gets the sortscheme of a list - -=cut - -sub get_sortscheme { - my $self = shift; - return $self->{sortscheme}; -} - - -=head2 add_filter - - Adds a filter to a list object - -=cut - -sub add_filter { - my $self = shift; - my ($type, $values) = @_; - # Disjunctive filters are not simple values - if ($type eq 'orfilter') { - $self->{filters}{$type} = $values; - } - else { - $self->{filters}{$type} = [ split(/\s*,\s*/,$values) ]; - } - return; -} - -=head2 get_filter - - Gets a specific filter from a list object - -=cut - -sub get_filter { - my $self = shift; - my $type = shift; - return $self->{filters}{$type}; -} - -=head2 get_filters - - Gets all filters for a list object - -=cut - -sub get_filters { - my $self = shift; - return $self->{filters}; -} - - -=head2 set_keys - - Sets the keys for the list - -=cut - -sub set_keys { - my $self = shift; - my $keys = shift; - $self->{keys} = $keys; - return; -} - -=head2 get_keys - - Gets the keys for the list - -=cut - -sub get_keys { - my $self = shift; - return @{$self->{keys}}; -} - -=head2 instantiate_entry - - Do any dynamic information replacement for information - which varies in an entry between lists. This is information which - needs to be output to the .bbl for an entry but which is a property - of the sorting list and not the entry per se so it can't be stored - statically in the entry and must be pulled from the specific list - when outputting the entry. - - Currently this means: - - * sortinit - * extrayear - * extraalpha - -=cut - -sub instantiate_entry { - my $self = shift; - my $entry = shift; - my $key = shift; - return '' unless $entry; - - my $entry_string = $$entry; - - my $sid = $self->get_sortinitdata($key); - if (defined($sid)) { - my $si = "\\field{sortinit}{$sid}"; - $entry_string =~ s|<BDS>SORTINIT</BDS>|$si|gxms; - } - - my $eys; - # Might not be set due to skip - if (my $ey = $self->get_extrayeardata($key)) { - $eys = " \\field{extrayear}{$ey}\n"; - } - $entry_string =~ s|^\s*<BDS>EXTRAYEAR</BDS>\n|$eys|gxms; - - my $eas; - # Might not be set due to skip - if (my $ea = $self->get_extraalphadata($key)) { - $eas = " \\field{extraalpha}{$ea}\n"; - } - $entry_string =~ s|^\s*<BDS>EXTRAALPHA</BDS>\n|$eas|gxms; - - return $entry_string; -} - - -=head1 AUTHORS - -François Charette, C<< <firmicus at gmx.net> >> -Philip Kime C<< <philip at kime.org.uk> >> - -=head1 BUGS - -Please report any bugs or feature requests on our sourceforge tracker at -L<https://sourceforge.net/tracker2/?func=browse&group_id=228270>. - -=head1 COPYRIGHT & LICENSE - -Copyright 2009-2011 François Charette and Philip Kime, all rights reserved. - -This module is free software. You can redistribute it and/or -modify it under the terms of the Artistic License 2.0. - -This program is distributed in the hope that it will be useful, -but without any warranty; without even the implied warranty of -merchantability or fitness for a particular purpose. - -=cut - -1; - -# vim: set tabstop=2 shiftwidth=2 expandtab: diff --git a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Sections.pm b/Master/texmf-dist/source/bibtex/biber/lib/Biber/Sections.pm deleted file mode 100644 index 17e5f792b7d..00000000000 --- a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Sections.pm +++ /dev/null @@ -1,114 +0,0 @@ -package Biber::Sections; -#use feature 'unicode_strings'; - -=encoding utf-8 - -=head1 NAME - -Biber::Sections - -=head2 new - - Initialize a Biber::Sections object - -=cut - -sub new { - my ($class) = @_; - my $self = bless {}, $class; - return $self; -} - -=head2 get_num_sections - - Gets the number of Biber::Section objects - -=cut - -sub get_num_sections { - my $self = shift; - my @keys = keys %$self; - return $#keys + 1; -} - - -=head2 get_section - - Gets a Biber::Section by number from the Biber::Sections object - -=cut - -sub get_section { - my $self = shift; - my $number = shift; - return $self->{$number}; -} - -=head2 get_sections - - Gets an sorted array ref of all Biber::Section objects - -=cut - -sub get_sections { - my $self = shift; - return [ sort {$a->number <=> $b->number} values %$self ]; -} - - -=head2 add_section - - Adds a Biber::Section to the Biber::Sections object - -=cut - -sub add_section { - my $self = shift; - my $section = shift; - my $number = $section->number; - $self->{$number} = $section; - return; -} - -=head2 delete_section - - Deletes a section - Mainly used in test scripts - -=cut - -sub delete_section { - my $self = shift; - my $section = shift; - my $number = $section->number; - delete $self->{$number}; - return; -} - - -=head1 AUTHORS - -François Charette, C<< <firmicus at gmx.net> >> -Philip Kime C<< <philip at kime.org.uk> >> - -=head1 BUGS - -Please report any bugs or feature requests on our sourceforge tracker at -L<https://sourceforge.net/tracker2/?func=browse&group_id=228270>. - -=head1 COPYRIGHT & LICENSE - -Copyright 2009-2011 François Charette and Philip Kime, all rights reserved. - -This module is free software. You can redistribute it and/or -modify it under the terms of the Artistic License 2.0. - -This program is distributed in the hope that it will be useful, -but without any warranty; without even the implied warranty of -merchantability or fitness for a particular purpose. - -=cut - -1; - -# vim: set tabstop=2 shiftwidth=2 expandtab: diff --git a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Structure.pm b/Master/texmf-dist/source/bibtex/biber/lib/Biber/Structure.pm deleted file mode 100644 index 362f8d45574..00000000000 --- a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Structure.pm +++ /dev/null @@ -1,526 +0,0 @@ -package Biber::Structure; -#use feature 'unicode_strings'; - -use List::Util qw( first ); -use Biber::Utils; -use Biber::Constants; -use Data::Dump qw( pp ); -use Date::Simple; - -=encoding utf-8 - -=head1 NAME - -Biber::Structure - - -=cut - -my $logger = Log::Log4perl::get_logger('main'); - - -=head2 new - - Initialize a Biber::Structure object - -=cut - -sub new { - my $class = shift; - my $struc = shift; - my $self; - if (defined($struc) and ref($struc) eq 'HASH') { - $self = bless $struc, $class; - } - else { - $self = bless {}, $class; - } - - # Pull out legal entrytypes, fields and constraints and make lookup hash - # for quick tests later - - # field datatypes - my ($nullok, $skipout, @name, @list, @literal, @date, @integer, @range, @verbatim, @key); - - # Create data for field types, including any aliases which might be - # needed when reading the bib data. - foreach my $f (@{$struc->{fields}{field}}) { - if ($f->{fieldtype} eq 'list' and $f->{datatype} eq 'name') { - push @name, $f->{content}; - } - elsif ($f->{fieldtype} eq 'list' and $f->{datatype} eq 'literal') { - push @list, $f->{content}; - } - elsif ($f->{fieldtype} eq 'list' and $f->{datatype} eq 'key') { - push @list, $f->{content}; - } - elsif ($f->{fieldtype} eq 'field' and $f->{datatype} eq 'literal') { - push @literal, $f->{content}; - } - elsif ($f->{fieldtype} eq 'field' and $f->{datatype} eq 'date') { - push @date, $f->{content}; - } - elsif ($f->{fieldtype} eq 'field' and $f->{datatype} eq 'integer') { - push @integer, $f->{content}; - } - elsif ($f->{fieldtype} eq 'field' and $f->{datatype} eq 'range') { - push @range, $f->{content}; - } - elsif ($f->{fieldtype} eq 'field' and $f->{datatype} eq 'verbatim') { - push @verbatim, $f->{content}; - } - elsif ($f->{fieldtype} eq 'field' and $f->{datatype} eq 'key') { - push @key, $f->{content}; - } - - # check null_ok - if ($f->{nullok}) { - $nullok->{$f->{content}} = 1; - } - # check skips - fields we dont' want to output to BBL - if ($f->{skip_output}) { - $skipout->{$f->{content}} = 1; - } - } - - # Store as lookup tables for speed and multiple re-use - $self->{fields}{nullok} = $nullok; - $self->{fields}{skipout} = $skipout; - $self->{fields}{complex} = { map {$_ => 1} (@name, @list, @range, @date) }; - $self->{fields}{literal} = { map {$_ => 1} (@literal, @key, @integer) }; - $self->{fields}{name} = { map {$_ => 1} @name }; - $self->{fields}{list} = { map {$_ => 1} @list }; - $self->{fields}{verbatim} = { map {$_ => 1} @verbatim }; - $self->{fields}{range} = { map {$_ => 1} @range }; - $self->{fields}{date} = { map {$_ => 1} @date }; - - my $leg_ents; - my $ets = [ sort map {$_->{content}} @{$struc->{entrytypes}{entrytype}} ]; - - foreach my $es (@$ets) { - - # fields for entrytypes - my $lfs; - foreach my $ef (@{$struc->{entryfields}}) { - # Found a section describing legal fields for entrytype - if (grep {($_->{content} eq $es) or ($_->{content} eq 'ALL')} @{$ef->{entrytype}}) { - foreach my $f (@{$ef->{field}}) { - $lfs->{$f->{content}} = 1; - } - } - } - - # constraints - my $constraints; - foreach my $cd (@{$struc->{constraints}}) { - # Found a section describing constraints for entrytype - if (grep {($_->{content} eq $es) or ($_->{content} eq 'ALL')} @{$cd->{entrytype}}) { - foreach my $c (@{$cd->{constraint}}) { - if ($c->{type} eq 'mandatory') { - # field - foreach my $f (@{$c->{field}}) { - push @{$constraints->{mandatory}}, $f->{content}; - } - # xor set of fields - # [ XOR, field1, field2, ... , fieldn ] - foreach my $fxor (@{$c->{fieldxor}}) { - my $xorset; - foreach my $f (@{$fxor->{field}}) { - if ($f->{coerce}) { - # put the default override element at the front and flag it - unshift @$xorset, $f->{content}; - } - else { - push @$xorset, $f->{content}; - } - } - unshift @$xorset, 'XOR'; - push @{$constraints->{mandatory}}, $xorset; - } - # or set of fields - # [ OR, field1, field2, ... , fieldn ] - foreach my $for (@{$c->{fieldor}}) { - my $orset; - foreach my $f (@{$for->{field}}) { - push @$orset, $f->{content}; - } - unshift @$orset, 'OR'; - push @{$constraints->{mandatory}}, $orset; - } - } - # Conditional constraints - # [ ANTECEDENT_QUANTIFIER - # [ ANTECEDENT LIST ] - # CONSEQUENT_QUANTIFIER - # [ CONSEQUENT LIST ] - # ] - elsif ($c->{type} eq 'conditional') { - my $cond; - $cond->[0] = $c->{antecedent}{quant}; - $cond->[1] = [ map { $_->{content} } @{$c->{antecedent}{field}} ]; - $cond->[2] = $c->{consequent}{quant}; - $cond->[3] = [ map { $_->{content} } @{$c->{consequent}{field}} ]; - push @{$constraints->{conditional}}, $cond; - } - # data constraints - elsif ($c->{type} eq 'data') { - my $data; - $data->{fields} = [ map { $_->{content} } @{$c->{field}} ]; - $data->{datatype} = $c->{datatype}; - $data->{rangemin} = $c->{rangemin}; - $data->{rangemax} = $c->{rangemax}; - push @{$constraints->{data}}, $data; - } - } - } - } - $leg_ents->{$es}{legal_fields} = $lfs; - $leg_ents->{$es}{constraints} = $constraints; - } - $self->{legal_entrytypes} = $leg_ents; - - # date types - my $dts; - foreach my $dt (@{$struc->{datetypes}{datetype}}) { - push @$dts, $dt->{content}; - } - - $self->{legal_datetypes} = $dts; - - return $self; -} - - -=head2 is_entrytype - - Returns boolean to say if an entrytype is a legal entrytype - -=cut - -sub is_entrytype { - my $self = shift; - my $type = shift; - return $self->{legal_entrytypes}{$type} ? 1 : 0; -} - -=head2 is_field_for_entrytype - - Returns boolean to say if a field is legal for an entrytype - -=cut - -sub is_field_for_entrytype { - my $self = shift; - my ($type, $field) = @_; - if ($self->{legal_entrytypes}{ALL}{legal_fields}{$field} or - $self->{legal_entrytypes}{$type}{legal_fields}{$field} or - $self->{legal_entrytypes}{$type}{legal_fields}{ALL}) { - return 1; - } - else { - return 0; - } -} - - -=head2 get_field_type - - Retrieve fields of a certain biblatex type from structure - Return in sorted order so that bbl order doesn't change when changing - .bcf. This really messes up tests otherwise. - -=cut - -sub get_field_type { - my $self = shift; - my $type = shift; - return $self->{fields}{$type} ? [ sort keys %{$self->{fields}{$type}} ] : ''; -} - -=head2 is_field_type - - Returns boolean depending on whether a field is a certain biblatex type - -=cut - -sub is_field_type { - my $self = shift; - my ($type, $field) = @_; - return $self->{fields}{$type}{$field} // 0; -} - - -=head2 check_mandatory_constraints - - Checks constraints of type "mandatory" on entry and - returns an arry of warnings, if any - -=cut - -sub check_mandatory_constraints { - my $self = shift; - my $be = shift; - my @warnings; - my $et = $be->get_field('entrytype'); - my $citekey = $be->get_field('dskey'); - foreach my $c ((@{$self->{legal_entrytypes}{ALL}{constraints}{mandatory}}, - @{$self->{legal_entrytypes}{$et}{constraints}{mandatory}})) { - if (ref($c) eq 'ARRAY') { - # Exactly one of a set is mandatory - if ($c->[0] eq 'XOR') { - my @fs = @$c[1,-1]; # Lose the first element which is the 'XOR' - my $flag = 0; - my $xorflag = 0; - foreach my $of (@fs) { - if ($be->field_exists($of)) { - if ($xorflag) { - push @warnings, "Mandatory fields - only one of '" . join(', ', @fs) . "' must be defined in entry '$citekey' ignoring field '$of'"; - $be->del_field($of); - } - $flag = 1; - $xorflag = 1; - } - } - unless ($flag) { - push @warnings, "Missing mandatory field - one of '" . join(', ', @fs) . "' must be defined in entry '$citekey'"; - } - } - # One or more of a set is mandatory - elsif ($c->[0] eq 'OR') { - my @fs = @$c[1,-1]; # Lose the first element which is the 'OR' - my $flag = 0; - foreach my $of (@fs) { - if ($be->field_exists($of)) { - $flag = 1; - last; - } - } - unless ($flag) { - push @warnings, "Missing mandatory field - one of '" . join(', ', @fs) . "' must be defined in entry '$citekey'"; - } - } - } - # Simple mandatory field - else { - unless ($be->field_exists($c)) { - push @warnings, "Missing mandatory field '$c' in entry '$citekey'"; - } - } - } - return @warnings; -} - -=head2 check_conditional_constraints - - Checks constraints of type "conditional" on entry and - returns an arry of warnings, if any - -=cut - -sub check_conditional_constraints { - my $self = shift; - my $be = shift; - my @warnings; - my $et = $be->get_field('entrytype'); - my $citekey = $be->get_field('dskey'); - - foreach my $c ((@{$self->{legal_entrytypes}{ALL}{constraints}{conditional}}, - @{$self->{legal_entrytypes}{$et}{constraints}{conditional}})) { - my $aq = $c->[0]; # Antecedent quantifier - my $afs = $c->[1]; # Antecedent fields - my $cq = $c->[2]; # Consequent quantifier - my $cfs = $c->[3]; # Consequent fields - my @actual_afs = (grep {$be->field_exists($_)} @$afs); # antecedent fields in entry - # check antecedent - if ($aq eq 'all') { - next unless $#$afs == $#actual_afs; # ALL -> ? not satisfied - } - elsif ($aq eq 'none') { - next if @actual_afs; # NONE -> ? not satisfied - } - elsif ($aq eq 'one') { - next unless @actual_afs; # ONE -> ? not satisfied - } - - # check consequent - my @actual_cfs = (grep {$be->field_exists($_)} @$cfs); - if ($cq eq 'all') { - unless ($#$cfs == $#actual_cfs) { # ? -> ALL not satisfied - push @warnings, "Constraint violation - $cq of fields (" . - join(', ', @$cfs) . - ") must exist when $aq of fields (" . join(', ', @$afs). ") exist"; - } - } - elsif ($cq eq 'none') { - if (@actual_cfs) { # ? -> NONE not satisfied - push @warnings, "Constraint violation - $cq of fields (" . - join(', ', @actual_cfs) . - ") must exist when $aq of fields (" . join(', ', @$afs). ") exist. Ignoring them."; - # delete the offending fields - foreach my $f (@actual_cfs) { - $be->del_field($f); - } - } - } - elsif ($cq eq 'one') { - unless (@actual_cfs) { # ? -> ONE not satisfied - push @warnings, "Constraint violation - $cq of fields (" . - join(', ', @$cfs) . - ") must exist when $aq of fields (" . join(', ', @$afs). ") exist"; - } - } - } - return @warnings; -} - -=head2 check_data_constraints - - Checks constraints of type "data" on entry and - returns an arry of warnings, if any - -=cut - -sub check_data_constraints { - my $self = shift; - my $be = shift; - my @warnings; - my $et = $be->get_field('entrytype'); - my $citekey = $be->get_field('dskey'); - foreach my $c ((@{$self->{legal_entrytypes}{ALL}{constraints}{data}}, - @{$self->{legal_entrytypes}{$et}{constraints}{data}})) { - if ($c->{datatype} eq 'integer') { - my $dt = $STRUCTURE_DATATYPES{$c->{datatype}}; - foreach my $f (@{$c->{fields}}) { - if (my $fv = $be->get_field($f)) { - unless ( $fv =~ /$dt/ ) { - push @warnings, "Invalid format (integer) of field '$f' - ignoring field in entry '$citekey'"; - $be->del_field($f); - next; - } - if (my $fmin = $c->{rangemin}) { - unless ($fv >= $fmin) { - push @warnings, "Invalid value of field '$f' must be '>=$fmin' - ignoring field in entry '$citekey'"; - $be->del_field($f); - next; - } - } - if (my $fmax = $c->{rangemax}) { - unless ($fv <= $fmax) { - push @warnings, "Invalid value of field '$f' must be '<=$fmax' - ignoring field in entry '$citekey'"; - $be->del_field($f); - next; - } - } - } - } - } - } - return @warnings; -} - -=head2 check_date_components - - Perform content validation checks on date components by trying to - instantiate a Date::Simple object. - -=cut - -sub check_date_components { - my $self = shift; - my $be = shift; - my @warnings; - my $et = $be->get_field('entrytype'); - my $citekey = $be->get_field('dskey'); - - foreach my $f (@{$self->{legal_datetypes}}) { - my ($d) = $f =~ m/\A(.*)date\z/xms; - # Don't bother unless this type of date is defined (has a year) - next unless $be->get_datafield($d . 'year'); - - # When checking date components not split from date fields, have ignore the value - # of an explicit YEAR field as it is allowed to be an arbitrary string - # so we just set it to any valid value for the test - my $byc; - my $byc_d; # Display value for errors so as not to confuse people - if ($d eq '' and not $be->get_field('datesplit')) { - $byc = '1900'; # Any valid value is fine - $byc_d = 'YYYY'; - } - else { - $byc = $be->get_datafield($d . 'year') - } - - # Begin date - if ($byc) { - my $bm = $be->get_datafield($d . 'month') || 'MM'; - my $bmc = $bm eq 'MM' ? '01' : $bm; - my $bd = $be->get_datafield($d . 'day') || 'DD'; - my $bdc = $bd eq 'DD' ? '01' : $bd; - $logger->debug("Checking '${d}date' date value '$byc/$bmc/$bdc' for key '$citekey'"); - unless (Date::Simple->new("$byc$bmc$bdc")) { - push @warnings, "Invalid date value '" . - ($byc_d || $byc) . - "/$bm/$bd' - ignoring its components in entry '$citekey'"; - $be->del_datafield($d . 'year'); - $be->del_datafield($d . 'month'); - $be->del_datafield($d . 'day'); - next; - } - } - # End date - # defined and some value - end*year can be empty but defined in which case, - # we don't need to validate - if (my $eyc = $be->get_datafield($d . 'endyear')) { - my $em = $be->get_datafield($d . 'endmonth') || 'MM'; - my $emc = $em eq 'MM' ? '01' : $em; - my $ed = $be->get_datafield($d . 'endday') || 'DD'; - my $edc = $ed eq 'DD' ? '01' : $ed; - $logger->debug("Checking '${d}date' date value '$eyc/$emc/$edc' for key '$citekey'"); - unless (Date::Simple->new("$eyc$emc$edc")) { - push @warnings, "Invalid date value '$eyc/$em/$ed' - ignoring its components in entry '$citekey'"; - $be->del_datafield($d . 'endyear'); - $be->del_datafield($d . 'endmonth'); - $be->del_datafield($d . 'endday'); - next; - } - } - } - return @warnings; -} - -=head2 dump - - Dump Biber::Structure object - -=cut - -sub dump { - my $self = shift; - return pp($self); -} - -=head1 AUTHORS - -François Charette, C<< <firmicus at gmx.net> >> -Philip Kime C<< <philip at kime.org.uk> >> - -=head1 BUGS - -Please report any bugs or feature requests on our sourceforge tracker at -L<https://sourceforge.net/tracker2/?func=browse&group_id=228270>. - -=head1 COPYRIGHT & LICENSE - -Copyright 2009-2011 François Charette and Philip Kime, all rights reserved. - -This module is free software. You can redistribute it and/or -modify it under the terms of the Artistic License 2.0. - -This program is distributed in the hope that it will be useful, -but without any warranty; without even the implied warranty of -merchantability or fitness for a particular purpose. - -=cut - - -1; diff --git a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Utils.pm b/Master/texmf-dist/source/bibtex/biber/lib/Biber/Utils.pm deleted file mode 100644 index d4b9f85f3a1..00000000000 --- a/Master/texmf-dist/source/bibtex/biber/lib/Biber/Utils.pm +++ /dev/null @@ -1,564 +0,0 @@ -package Biber::Utils; -#use feature 'unicode_strings'; - -use strict; -use warnings; -use Carp; -use Encode; -use File::Find; -use File::Spec; -use IPC::Cmd qw( can_run run ); -use List::Util qw( first ); -use Biber::Constants; -use Biber::LaTeX::Recode; -use Biber::Entry::Name; -use Regexp::Common qw( balanced ); -use re 'eval'; -use base 'Exporter'; -use Log::Log4perl qw(:no_extra_logdie_message); - -my $logger = Log::Log4perl::get_logger('main'); - -=encoding utf-8 - -=head1 NAME - -Biber::Utils - Various utility subs used in Biber - -=cut - -=head1 EXPORT - -All functions are exported by default. - -=cut - -our @EXPORT = qw{ locate_biber_file makenameid stringify_hash - normalise_string normalise_string_lite normalise_string_underscore normalise_string_sort - reduce_array remove_outer add_outer ucinit strip_nosort - is_def is_undef is_def_and_notnull is_def_and_null - is_undef_or_null is_notnull is_null normalise_utf8}; - -=head1 FUNCTIONS - -=head2 locate_biber_file - - Searches for a file by - - For the exact path if the filename is absolute - In the output_directory, if defined - Relative to the current directory - In the same directory as the control file - Using kpsewhich, if available - -=cut - -sub locate_biber_file { - my $filename = shift; - my $filenamepath = $filename; # default if nothing else below applies - my $outfile; - # If output_directory is set, perhaps the file can be found there so - # construct a path to test later - if (my $outdir = Biber::Config->getoption('output_directory')) { - $outfile = File::Spec->catfile($outdir, $filename); - } - - # Filename is absolute - if (File::Spec->file_name_is_absolute($filename) and -e $filename) { - return $filename; - } - - # File is output_directory - if (defined($outfile) and -e $outfile) { - return $outfile; - } - - # File is relative to cwd - if (-e $filename) { - return $filename; - } - - # File is where control file lives - if (my $cfp = Biber::Config->get_ctrlfile_path) { - my ($ctlvolume, $ctldir, undef) = File::Spec->splitpath($cfp); - if ($ctlvolume) { # add vol sep for windows if volume is set and there isn't one - $ctlvolume .= ':' unless $ctlvolume =~ /:\z/; - } - if ($ctldir) { # add path sep if there isn't one - $ctldir .= '/' unless $ctldir =~ /\/\z/; - } - - my $path = "$ctlvolume$ctldir$filename"; - - return $path if -e $path; - } - - # File is in kpse path - if (can_run('kpsewhich')) { - my $found; - scalar run( command => [ 'kpsewhich', $filename ], - verbose => 0, - buffer => \$found ); - if ($found) { - chomp $found; - # filename can be UTF-8 and run() isn't clever with UTF-8 - return decode_utf8($found); - } - } - return undef; -} - -=head2 makenameid - -Given a Biber::Names object, return an underscore normalised -concatenation of all of the full name strings. - -=cut - -sub makenameid { - my $names = shift; - my @namestrings; - foreach my $name (@{$names->names}) { - push @namestrings, $name->get_namestring; - } - my $tmp = join ' ', @namestrings; - return normalise_string_underscore($tmp); -} - -=head2 latex_recode_output - - Tries to convert UTF-8 to TeX macros in passes string - -=cut - -sub latex_recode_output { - my $string = shift; - $logger->info('Converting UTF-8 to TeX macros on output to .bbl'); - require Biber::LaTeX::Recode; - return Biber::LaTeX::Recode::latex_encode($string, - scheme => Biber::Config->getoption('bblsafecharsset')); -}; - -=head2 strip_nosort - -Removes elements which are not to be used in sorting a name from a string - -=cut - -sub strip_nosort { - my $string = shift; - my $fieldname = shift; - return '' unless $string; # Sanitise missing data - my $nosort = Biber::Config->getoption('nosort'); - # Strip user-defined REs from string - my $restrings; - # Specific fieldnames override types - if (exists($nosort->{$fieldname})) { - $restrings = $nosort->{$fieldname}; - } - else { # types - foreach my $ns (keys %$nosort) { - next unless $ns =~ /\Atype_/xms; - if ($NOSORT_TYPES{$ns}{$fieldname}) { - $restrings = $nosort->{$ns}; - } - } - } - # If no nosort to do, just return string - return $string unless $restrings; - # Config::General can't force arrays per option and don't want to set this globally - $restrings = [ $restrings ] unless ref($restrings) eq 'ARRAY'; - foreach my $re (@$restrings) { - $re = qr/$re/; - $string =~ s/$re//gxms; - } - return $string; -} - -=head2 normalise_string_sort - -Removes LaTeX macros, and all punctuation, symbols, separators and control characters, -as well as leading and trailing whitespace for sorting strings. -It also decodes LaTeX character macros into Unicode as this is always safe when -normalising strings for sorting since they don't appear in the output. - -=cut - -sub normalise_string_sort { - my $str = shift; - my $fieldname = shift; - return '' unless $str; # Sanitise missing data - # First strip nosort REs - $str = strip_nosort($str, $fieldname); - # First replace ties with spaces or they will be lost - $str =~ s/([^\\])~/$1 /g; # Foo~Bar -> Foo Bar - # Replace LaTeX chars by Unicode for sorting - # Don't bother if output is UTF-8 as in this case, we've already decoded everthing - # before we read the file (see Biber.pm) - unless (Biber::Config->getoption('bblencoding') eq 'UTF-8') { - $str = latex_decode($str, strip_outer_braces => 1, - scheme => Biber::Config->getoption('decodecharsset')); - } - return normalise_string_common($str); -} - -=head2 normalise_string - -Removes LaTeX macros, and all punctuation, symbols, separators and control characters, -as well as leading and trailing whitespace for sorting strings. -Only decodes LaTeX character macros into Unicode if output is UTF-8 - -=cut - -sub normalise_string { - my $str = shift; - return '' unless $str; # Sanitise missing data - # First replace ties with spaces or they will be lost - $str =~ s/([^\\])~/$1 /g; # Foo~Bar -> Foo Bar - if (Biber::Config->getoption('bblencoding') eq 'UTF-8') { - $str = latex_decode($str, strip_outer_braces => 1, - scheme => Biber::Config->getoption('decodecharsset')); - } - return normalise_string_common($str); -} - -=head2 normalise_string_common - - Common bit for normalisation - -=cut - -sub normalise_string_common { - my $str = shift; - $str =~ s/\\[A-Za-z]+//g; # remove latex macros (assuming they have only ASCII letters) - $str =~ s/[\p{P}\p{S}\p{C}]+//g; # remove punctuation, symbols, separator and control - $str =~ s/^\s+//; # Remove leading spaces - $str =~ s/\s+$//; # Remove trailing spaces - $str =~ s/\s+/ /g; # collapse spaces - return $str; -} - -=head2 normalise_string_lite - - Removes LaTeX macros - -=cut - -sub normalise_string_lite { - my $str = shift; - return '' unless $str; # Sanitise missing data - # First replace ties with spaces or they will be lost - $str =~ s/\\\p{L}+\s*//g; # remove tex macros - $str =~ s/\\[^\p{L}]+\s*//g; # remove accent macros like \"a - $str =~ s/[{}]//g; # Remove any brackets left - $str =~ s/~//g; - $str =~ s/\.//g; - $str =~ s/\s+//g; - return $str; -} - -=head2 normalise_string_underscore - -Like normalise_string, but also substitutes ~ and whitespace with underscore. - -=cut - -sub normalise_string_underscore { - my $str = shift; - return '' unless $str; # Sanitise missing data - $str =~ s/([^\\])~/$1 /g; # Foo~Bar -> Foo Bar - $str = normalise_string($str); - $str =~ s/\s+/_/g; - return $str; -} - -=head2 reduce_array - -reduce_array(\@a, \@b) returns all elements in @a that are not in @b - -=cut - -sub reduce_array { - my ($a, $b) = @_; - my %countb = (); - foreach my $elem (@$b) { - $countb{$elem}++; - } - my @result; - foreach my $elem (@$a) { - push @result, $elem unless $countb{$elem}; - } - return @result; -} - -=head2 remove_outer - - Remove surrounding curly brackets: - '{string}' -> 'string' - -=cut - -sub remove_outer { - my $str = shift; - $str =~ s/^{(.+)}$/$1/; - return $str; -} - -=head2 add_outer - - Add surrounding curly brackets: - 'string' -> '{string}' - -=cut - -sub add_outer { - my $str = shift; - return '{' . $str . '}'; -} - - -=head2 ucinit - - upper case of initial letters in a string - -=cut - -sub ucinit { - my $str = shift; - $str = lc($str); - $str =~ s/\b(\p{Ll})/\u$1/g; - return $str; -} - -=head2 is_undef - - Checks for undefness of arbitrary things, including - composite method chain calls which don't reliably work - with defined() (see perldoc for defined()) - This works because we are just testing the value passed - to this sub. So, for example, this is randomly unreliable - even if the resulting value of the arg to defined() is "undef": - - defined($thing->method($arg)->method) - - wheras: - - is_undef($thing->method($arg)->method) - - works since we only test the return value of all the methods - with defined() - -=cut - -sub is_undef { - my $val = shift; - return defined($val) ? 0 : 1; -} - -=head2 is_def - - Checks for definedness in the same way as is_undef() - -=cut - -sub is_def { - my $val = shift; - return defined($val) ? 1 : 0; -} - -=head2 is_undef_or_null - - Checks for undef or nullness (see is_undef() above) - -=cut - -sub is_undef_or_null { - my $val = shift; - return 1 if is_undef($val); - return $val ? 0 : 1; -} - -=head2 is_def_and_notnull - - Checks for def and unnullness (see is_undef() above) - -=cut - -sub is_def_and_notnull { - my $arg = shift; - if (defined($arg) and is_notnull($arg)) { - return 1; - } - else { - return 0; - } -} - -=head2 is_def_and_null - - Checks for def and nullness (see is_undef() above) - -=cut - -sub is_def_and_null { - my $arg = shift; - if (defined($arg) and is_null($arg)) { - return 1; - } - else { - return 0; - } -} - -=head2 is_null - - Checks for nullness - -=cut - -sub is_null { - my $arg = shift; - return is_notnull($arg) ? 0 : 1; -} - -=head2 is_notnull - - Checks for notnullness - -=cut - -sub is_notnull { - my $arg = shift; - return undef unless defined($arg); - my $st = is_notnull_scalar($arg); - if (defined($st) and $st) { return 1; } - my $at = is_notnull_array($arg); - if (defined($at) and $at) { return 1; } - my $ht = is_notnull_hash($arg); - if (defined($ht) and $ht) { return 1; } - my $ot = is_notnull_object($arg); - if (defined($ot) and $ot) { return 1; } - return 0; -} - -=head2 is_notnull_scalar - - Checks for notnullness of a scalar - -=cut - -sub is_notnull_scalar { - my $arg = shift; - unless (ref \$arg eq 'SCALAR') { - return undef; - } - return $arg ne '' ? 1 : 0; -} - -=head2 is_notnull_array - - Checks for notnullness of an array (passed by ref) - -=cut - -sub is_notnull_array { - my $arg = shift; - unless (ref $arg eq 'ARRAY') { - return undef; - } - my @arr = @$arg; - return $#arr > -1 ? 1 : 0; -} - -=head2 is_notnull_hash - - Checks for notnullness of an hash (passed by ref) - -=cut - -sub is_notnull_hash { - my $arg = shift; - unless (ref $arg eq 'HASH') { - return undef; - } - my @arr = keys %$arg; - return $#arr > -1 ? 1 : 0; -} - -=head2 is_notnull_object - - Checks for notnullness of an object (passed by ref) - -=cut - -sub is_notnull_object { - my $arg = shift; - unless (ref($arg) =~ m/\ABiber::/xms) { - return undef; - } - return $arg->notnull ? 1 : 0; -} - - -=head2 stringify_hash - - Turns a hash into a string of keys and values - -=cut - -sub stringify_hash { - my $hashref = shift; - my $string; - while (my ($k,$v) = each %{$hashref}) { - $string .= "$k => $v, "; - } - # Take off the trailing comma and space - chop $string; - chop $string; - return $string; -} - -=head2 normalise_utf8 - - Normalise any UTF-8 encoding string immediately to exactly what we want - We want the strict perl utf8 "UTF-8" - -=cut - -sub normalise_utf8 { - if (defined(Biber::Config->getoption('bibencoding')) and - Biber::Config->getoption('bibencoding') =~ m/\Autf-?8\z/xmsi) { - Biber::Config->setoption('bibencoding', 'UTF-8'); - } - if (defined(Biber::Config->getoption('bblencoding')) and - Biber::Config->getoption('bblencoding') =~ m/\Autf-?8\z/xmsi) { - Biber::Config->setoption('bblencoding', 'UTF-8'); - } -} - -=head1 AUTHOR - -François Charette, C<< <firmicus at gmx.net> >> -Philip Kime C<< <philip at kime.org.uk> >> - -=head1 BUGS - -Please report any bugs or feature requests on our sourceforge tracker at -L<https://sourceforge.net/tracker2/?func=browse&group_id=228270>. - -=head1 COPYRIGHT & LICENSE - -Copyright 2009-2011 François Charette and Philip Kime, all rights reserved. - -This module is free software. You can redistribute it and/or -modify it under the terms of the Artistic License 2.0. - -This program is distributed in the hope that it will be useful, -but without any warranty; without even the implied warranty of -merchantability or fitness for a particular purpose. - -=cut - -1; - -# vim: set tabstop=2 shiftwidth=2 expandtab: |