Bundle-PBib
view release on metacpan or search on metacpan
lib/Biblio/bp/lib/bp-medline.pl view on Meta::CPAN
return undef unless $opt =~ /=/;
local($_, $val) = split(/\s*=\s*/, $opt, 2);
&bib'debugs("option split: $_ = $val", 8);
/^html$/ && do { $opt_html = &bib'parse_num_option($val);
return 1; };
undef;
}
######
# We have our own read routine because we would like to handle the case
# of HTML output from Entrez. For example, turn on the HTML option, then
# it can parse the output of:
# <http://atlas.nlm.nih.gov:5700/htbin-post/Entrez/query?
# db=m&form=4&term=ras&field=word&dispmax=10&dopt=l&title=no>
# directly. Unfortunately, we have to do this specially since they don't
# put blank lines between entries.
sub read {
local($file) = @_;
local($record);
&bib'debugs("reading $file<$bib'glb_current_fmt>", 32);
if ($opt_html) {
local($/) = '</pre>';
$record = scalar(<$bib'glb_current_fh>);
$record =~ s/^\s+//;
$record =~ s/^<HR[^>]*>\s*//;
$record =~ s/^<P>\s*//;
$record =~ s/^<pre>\s*//;
# remove some especially troublesome HTML tags
$record =~ s/\n<body [^>]*>//;
$record =~ s/\n<img [^>]*>//;
# Check for the last part of the file. If we think we found it,
# read again. This should yield an eof.
if ($record =~ /^<\/form>\s*\n/i) {
$record = scalar(<$bib'glb_current_fh>);
}
} else {
# read a paragraph
local($/) = '';
$record = scalar(<$bib'glb_current_fh>);
}
$record;
}
######
sub explode {
local($_) = @_;
local(%entry) = ();
local($val);
local($field) = undef;
local(@lines) = split(/\n/);
foreach (@lines) {
if (/^<title>.*<\/title>$/) {
next if $opt_html;
# We could guess that it's html and change options here.
}
if ($opt_html) {
s/^<pre>\s*//i;
next if /^</;
next if /^\s*$/;
}
if (/^\s/) {
return &bib'goterror("Medline explode--Problems parsing entry") unless defined $field;
s/^\s+//;
$entry{$field} .= " " . $_;
next;
}
if (/^[A-Z]/) {
($field, $val) = /^([A-Z]+)\s*-\s*(.*)/;
if (defined $entry{$field}) {
$entry{$field} .= $bib'cs_sep . $val;
} else {
$entry{$field} = $val;
}
next;
}
next if /^\d+$/; # RefMan puts numbers here
&bib'gotwarn("Medline explode--can't parse: $_");
}
%entry;
}
######
sub implode {
local(%entry) = @_;
return &bib'goterror("medline implode isn't supported.");
}
######
# We want to check for any fields we don't recognize, because we don't
# have documentation on the format, so there may be something important
# being missed.
%med_to_can_fields = (
'MH', 'Keywords',
'AD', 'AuthorAddress',
'TI', 'Title',
'AB', 'Abstract',
'BK', 'SuperTitle',
'TA', 'Journal',
'PB', 'Publisher',
'Yr', 'Year',
'Mo', 'Month',
'PG', 'Pages',
'VI', 'Volume',
'IP', 'Number',
'UI', 0,
'RN', 0,
'EM', 0,
'GS', 0,
'SI', 0,
);
sub tocanon {
local(%entry) = @_;
local(%can);
local($type, $field);
# AU
if (defined $entry{'AU'}) {
local($n);
$can{'Authors'} = '';
foreach $n (split(/$bib'cs_sep/, $entry{'AU'})) {
$can{'Authors'} .= $bib'cs_sep . &medname_to_canon($n);
}
$can{'Authors'} =~ s/^$bib'cs_sep//;
}
# ED
if (defined $entry{'ED'}) {
$can{'Editors'} = '';
foreach $n (split(/$bib'cs_sep/, $entry{'ED'})) {
$can{'Editors'} .= $bib'cs_sep . &medname_to_canon($n);
}
$can{'Editors'} =~ s/^$bib'cs_sep//;
}
# Sometimes the SO field is split out into seperate fields, sometimes not.
# We check the DP and VI fields -- if they exist, assume that SO is split.
# XXXXX We ought to check to split SO anyway and compare the results.
# Alternatively, we could have an option for 1) always use split
# fields, 2) always split SO and use the results, 3) what we do now
# which is make a good guess.
if ( (!defined $entry{DP}) || (!defined $entry{VI}) ) {
&parseSO;
}
# split DP into year and month
if ( !(($entry{Yr}, $entry{Mo}) = $entry{DP} =~ /(\S+)\s+(.*)/) ) {
$entry{Yr} = $entry{DP};
delete $entry{Mo};
}
delete $entry{SO};
delete $entry{DP};
# determine entry type
if ($entry{BK}) {
$entry{PB} = $entry{TA};
delete $entry{TA};
if ($entry{AU}) {
$type = 'inbook';
if ($entry{BK} =~ /^proc\w*\.\s/i || /proceeding/i || /conference/i || /workshop/i) {
$type = 'inproceedings';
}
} else {
$type = 'proceedings';
}
} else {
$type = 'article';
# XXXXX We might want to expand this. Entrez doesn't put conference
# notation in the TA field, but instead in the TI field.
# This next line is an attempt to grab conference proceedings out of the
# TI field, which is where Entrez puts them.
if ($entry{TI} =~ s/\.\s+Conference proceedings\.\s+(.*,\s+.*),\s+([A-Z].*),\s+(\d+)\.\s*$//) {
$type = 'proceedings';
$can{'Location'} = $1;
# What to do with the date?
} elsif ($entry{TA} =~ /^proc\w*\.\s/i || /proceeding/i || /conference/i || /workshop/i) {
$type = 'inproceedings';
$entry{BK} = $entry{TA};
delete $entry{TA};
} elsif (!$entry{AU}) {
$type = 'proceedings';
$entry{PB} = $entry{TA};
delete $entry{TA};
}
}
$can{'CiteType'} = $type;
delete $entry{AU};
delete $entry{ED};
# Remove trailing "." from article title
if (defined $entry{TI}) {
$entry{TI} =~ s/\.\s*$//;
}
foreach $field (keys %entry) {
if (!defined $med_to_can_fields{$field}) {
&bib'gotwarn("Unknown field: $field");
} elsif ($med_to_can_fields{$field}) {
$can{$med_to_can_fields{$field}} = $entry{$field};
( run in 1.522 second using v1.01-cache-2.11-cpan-5c0b1e786e0 )