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 )