lib/bio/reference.rb in bio-1.2.1 vs lib/bio/reference.rb in bio-1.3.0

- old
+ new

@@ -1,16 +1,19 @@ # # = bio/reference.rb - Journal reference classes # -# Copyright:: Copyright (C) 2001, 2006 +# Copyright:: Copyright (C) 2001, 2006, 2008 # Toshiaki Katayama <k@bioruby.org>, -# Ryan Raaum <ryan@raaum.org> +# Ryan Raaum <ryan@raaum.org>, +# Jan Aerts <jandot@bioruby.org> # License:: The Ruby License # -# $Id: reference.rb,v 1.24 2007/04/05 23:35:39 trevor Exp $ +# $Id:$ # +require 'enumerator' + module Bio # = DESCRIPTION # # A class for journal reference information. @@ -64,10 +67,13 @@ # pubmed identifier (typically Fixnum) attr_reader :pubmed # medline identifier (typically Fixnum) attr_reader :medline + + # DOI identifier (typically String, e.g. "10.1126/science.1110418") + attr_reader :doi # Abstract text in String. attr_reader :abstract # An URL String. @@ -76,11 +82,20 @@ # MeSH terms in an Array. attr_reader :mesh # Affiliations in an Array. attr_reader :affiliations + + # Sequence number in EMBL/GenBank records + attr_reader :embl_gb_record_number + + # Position in a sequence that this reference refers to + attr_reader :sequence_position + # Comments for the reference (typically Array of String, or nil) + attr_reader :comments + # Create a new Bio::Reference object from a Hash of values. # Data is extracted from the values for keys: # # * authors - expected value: Array of Strings # * title - expected value: String @@ -114,27 +129,27 @@ # --- # *Arguments*: # * (required) _hash_: Hash # *Returns*:: Bio::Reference object def initialize(hash) - hash.default = '' - @authors = hash['authors'] # [ "Hoge, J.P.", "Fuga, F.B." ] - @title = hash['title'] # "Title of the study." - @journal = hash['journal'] # "Theor. J. Hoge" - @volume = hash['volume'] # 12 - @issue = hash['issue'] # 3 - @pages = hash['pages'] # 123-145 - @year = hash['year'] # 2001 - @pubmed = hash['pubmed'] # 12345678 - @medline = hash['medline'] # 98765432 - @abstract = hash['abstract'] + @authors = hash['authors'] || [] # [ "Hoge, J.P.", "Fuga, F.B." ] + @title = hash['title'] || '' # "Title of the study." + @journal = hash['journal'] || '' # "Theor. J. Hoge" + @volume = hash['volume'] || '' # 12 + @issue = hash['issue'] || '' # 3 + @pages = hash['pages'] || '' # 123-145 + @year = hash['year'] || '' # 2001 + @pubmed = hash['pubmed'] || '' # 12345678 + @medline = hash['medline'] || '' # 98765432 + @doi = hash['doi'] + @abstract = hash['abstract'] || '' @url = hash['url'] - @mesh = hash['mesh'] - @affiliations = hash['affiliations'] - @authors = [] if @authors.empty? - @mesh = [] if @mesh.empty? - @affiliations = [] if @affiliations.empty? + @mesh = hash['mesh'] || [] + @embl_gb_record_number = hash['embl_gb_record_number'] || nil + @sequence_position = hash['sequence_position'] || nil + @comments = hash['comments'] + @affiliations = hash['affiliations'] || [] end # Formats the reference in a given style. # # Styles: @@ -164,24 +179,26 @@ # # output in Nature short style (see Bio::Reference#nature) # puts ref.format("nature",true) # alternatively, puts ref.nature(true) # --- # *Arguments*: # * (optional) _style_: String with style identifier - # * (optional) _option_: Option for styles accepting one + # * (optional) _options_: Options for styles accepting one # *Returns*:: String - def format(style = nil, option = nil) + def format(style = nil, *options) case style + when 'embl' + return embl when 'endnote' return endnote when 'bibitem' - return bibitem(option) + return bibitem(*options) when 'bibtex' - return bibtex(option) + return bibtex(*options) when 'rd' - return rd(option) + return rd(*options) when /^nature$/i - return nature(option) + return nature(*options) when /^science$/i return science when /^genome\s*_*biol/i return genome_biol when /^genome\s*_*res/i @@ -229,39 +246,55 @@ lines << "%J #{@journal}" unless @journal.empty? lines << "%V #{@volume}" unless @volume.to_s.empty? lines << "%N #{@issue}" unless @issue.to_s.empty? lines << "%P #{@pages}" unless @pages.empty? lines << "%M #{@pubmed}" unless @pubmed.to_s.empty? - if @pubmed - cgi = "http://www.ncbi.nlm.nih.gov/entrez/query.fcgi" - opts = "cmd=Retrieve&db=PubMed&dopt=Citation&list_uids" - @url = "#{cgi}?#{opts}=#{@pubmed}" - end - lines << "%U #{@url}" unless @url.empty? + u = @url.empty? ? pubmed_url : @url + lines << "%U #{u}" unless u.empty? lines << "%X #{@abstract}" unless @abstract.empty? @mesh.each do |term| lines << "%K #{term}" end lines << "%+ #{@affiliations.join(' ')}" unless @affiliations.empty? return lines.join("\n") end + # Returns reference formatted in the EMBL style. + # + # # ref is a Bio::Reference object + # puts ref.embl + # + # RP 1-1859 + # RX PUBMED; 1907511. + # RA Oxtoby E., Dunn M.A., Pancoro A., Hughes M.A.; + # RT "Nucleotide and derived amino acid sequence of the cyanogenic + # RT beta-glucosidase (linamarase) from white clover (Trifolium repens L.)"; + # RL Plant Mol. Biol. 17(2):209-219(1991). + def embl + r = self + Bio::Sequence::Format::NucFormatter::Embl.new('').instance_eval { + reference_format_embl(r) + } + end + # Returns reference formatted in the bibitem style # # # ref is a Bio::Reference object # puts ref.bibitem # # \bibitem{PMID:12345678} # Hoge, J.P., Fuga, F.B. # Title of the study., # {\em Theor. J. Hoge}, 12(3):123--145, 2001. # --- + # *Arguments*: + # * (optional) _item_: label string (default: <tt>"PMID:#{pubmed}"</tt>). # *Returns*:: String def bibitem(item = nil) item = "PMID:#{@pubmed}" unless item pages = @pages.sub('-', '--') - return <<-"END".collect {|line| line.strip}.join("\n") + return <<-"END".enum_for(:each_line).collect {|line| line.strip}.join("\n") \\bibitem{#{item}} #{@authors.join(', ')} #{@title}, {\\em #{@journal}}, #{@volume}(#{@issue}):#{pages}, #{@year}. END @@ -296,26 +329,52 @@ # pages = {123--145}, # } # --- # *Arguments*: # * (optional) _section_: BiBTeX section as String + # * (optional) _label_: Label string cited by LaTeX documents. + # Default is <tt>"PMID:#{pubmed}"</tt>. + # * (optional) _keywords_: Hash of additional keywords, + # e.g. { 'abstract' => 'This is abstract.' }. + # You can also override default keywords. + # To disable default keywords, specify false as + # value, e.g. { 'url' => false, 'year' => false }. # *Returns*:: String - def bibtex(section = nil) + def bibtex(section = nil, label = nil, keywords = {}) section = "article" unless section authors = authors_join(' and ', ' and ') - pages = @pages.sub('-', '--') - return <<-"END".gsub(/\t/, '') - @#{section}{PMID:#{@pubmed}, - author = {#{authors}}, - title = {#{@title}}, - journal = {#{@journal}}, - year = {#{@year}}, - volume = {#{@volume}}, - number = {#{@issue}}, - pages = {#{pages}}, - } - END + thepages = pages.to_s.empty? ? nil : pages.sub(/\-/, '--') + unless label then + label = "PMID:#{pubmed}" + end + theurl = if !(url.to_s.empty?) then + url + elsif pmurl = pubmed_url and !(pmurl.to_s.empty?) then + pmurl + else + nil + end + hash = { + 'author' => authors.empty? ? nil : authors, + 'title' => title.to_s.empty? ? nil : title, + 'number' => issue.to_s.empty? ? nil : issue, + 'pages' => thepages, + 'url' => theurl + } + keys = %w( author title journal year volume number pages url ) + keys.each do |k| + hash[k] = self.__send__(k.intern) unless hash.has_key?(k) + end + hash.merge!(keywords) { |k, v1, v2| v2.nil? ? v1 : v2 } + bib = [ "@#{section}{#{label}," ] + keys.concat((hash.keys - keys).sort) + keys.each do |kw| + ref = hash[kw] + bib.push " #{kw.ljust(12)} = {#{ref}}," if ref + end + bib.push "}\n" + return bib.join("\n") end # Returns reference formatted in a general/generic style. # # # ref is a Bio::Reference object @@ -497,10 +556,21 @@ authors = authors_join(' and ') end "#{authors} (#{@year}) #{@title} #{@journal} #{@volume}, #{@pages}" end + # Returns a valid URL for pubmed records + # + # *Returns*:: String + def pubmed_url + unless @pubmed.to_s.empty? + cgi = "http://www.ncbi.nlm.nih.gov/entrez/query.fcgi" + opts = "cmd=Retrieve&db=PubMed&dopt=Citation&list_uids" + return "#{cgi}?#{opts}=#{@pubmed}" + end + '' + end private def strip_dots(data) data.tr(',.', '') if data @@ -522,65 +592,9 @@ if name =~ /,/ name, initial = name.split(/,\s+/) name = "#{initial} #{name}" end return name - end - - end - - # = DESCRIPTION - # - # A container class for Bio::Reference objects. - # - # = USAGE - # - # refs = Bio::References.new - # refs.append(Bio::Reference.new(hash)) - # refs.each do |reference| - # ... - # end - # - class References - - # Array of Bio::Reference objects - attr_accessor :references - - # Create a new Bio::References object - # - # refs = Bio::References.new - # --- - # *Arguments*: - # * (optional) __: Array of Bio::Reference objects - # *Returns*:: Bio::References object - def initialize(ary = []) - @references = ary - end - - - # Add a Bio::Reference object to the container. - # - # refs.append(reference) - # --- - # *Arguments*: - # * (required) _reference_: Bio::Reference object - # *Returns*:: current Bio::References object - def append(reference) - @references.push(reference) if reference.is_a? Reference - return self - end - - # Iterate through Bio::Reference objects. - # - # refs.each do |reference| - # ... - # end - # --- - # *Block*:: yields each Bio::Reference object - def each - @references.each do |reference| - yield reference - end end end end