diff options
Diffstat (limited to 'Master/texmf-dist/source/bibtex/biber/lib/Biber/Input')
6 files changed, 0 insertions, 2420 deletions
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: |