bibtex-ruby 2.0.7 → 2.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of bibtex-ruby might be problematic. Click here for more details.
- data/Gemfile +3 -0
- data/Gemfile.lock +6 -2
- data/History.txt +6 -0
- data/README.md +7 -1
- data/Rakefile +2 -0
- data/lib/bibtex/bibliography.rb +29 -1
- data/lib/bibtex/entry.rb +211 -23
- data/lib/bibtex/names.rb +143 -65
- data/lib/bibtex/version.rb +1 -1
- data/test/bibtex/test_bibliography.rb +14 -0
- data/test/bibtex/test_names.rb +83 -1
- metadata +18 -12
    
        data/Gemfile
    CHANGED
    
    
    
        data/Gemfile.lock
    CHANGED
    
    | @@ -1,13 +1,14 @@ | |
| 1 1 | 
             
            PATH
         | 
| 2 2 | 
             
              remote: .
         | 
| 3 3 | 
             
              specs:
         | 
| 4 | 
            -
                bibtex-ruby (2.0. | 
| 4 | 
            +
                bibtex-ruby (2.0.8)
         | 
| 5 5 | 
             
                  latex-decode (>= 0.0.6)
         | 
| 6 6 | 
             
                  multi_json (~> 1.3)
         | 
| 7 7 |  | 
| 8 8 | 
             
            GEM
         | 
| 9 9 | 
             
              remote: http://rubygems.org/
         | 
| 10 10 | 
             
              specs:
         | 
| 11 | 
            +
                addressable (2.2.7)
         | 
| 11 12 | 
             
                autowatchr (0.1.5)
         | 
| 12 13 | 
             
                  watchr
         | 
| 13 14 | 
             
                builder (3.0.0)
         | 
| @@ -39,7 +40,7 @@ GEM | |
| 39 40 | 
             
                linecache (0.46)
         | 
| 40 41 | 
             
                  rbx-require-relative (> 0.0.4)
         | 
| 41 42 | 
             
                minitest (2.11.3)
         | 
| 42 | 
            -
                multi_json (1.3. | 
| 43 | 
            +
                multi_json (1.3.4)
         | 
| 43 44 | 
             
                mynyml-redgreen (0.7.1)
         | 
| 44 45 | 
             
                  term-ansicolor (>= 1.0.4)
         | 
| 45 46 | 
             
                racc (1.4.8)
         | 
| @@ -52,6 +53,8 @@ GEM | |
| 52 53 | 
             
                  columnize
         | 
| 53 54 | 
             
                  rbx-linecache (~> 1.3)
         | 
| 54 55 | 
             
                  rbx-require-relative (>= 0.0.4)
         | 
| 56 | 
            +
                rdf (0.3.5.2)
         | 
| 57 | 
            +
                  addressable (>= 2.2.6)
         | 
| 55 58 | 
             
                rdoc (3.12)
         | 
| 56 59 | 
             
                  json (~> 1.4)
         | 
| 57 60 | 
             
                ruby-debug (0.10.4)
         | 
| @@ -79,6 +82,7 @@ DEPENDENCIES | |
| 79 82 | 
             
              racc (~> 1.4)
         | 
| 80 83 | 
             
              rake (~> 0.9)
         | 
| 81 84 | 
             
              rbx-trepanning
         | 
| 85 | 
            +
              rdf (~> 0.3)
         | 
| 82 86 | 
             
              rdoc (~> 3.9)
         | 
| 83 87 | 
             
              ruby-debug
         | 
| 84 88 | 
             
              ruby-prof (~> 0.10)
         | 
    
        data/History.txt
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -35,7 +35,7 @@ Select a BibTeX entry and access individual fields: | |
| 35 35 | 
             
                b[:pickaxe].author.length
         | 
| 36 36 | 
             
                #=> 3
         | 
| 37 37 | 
             
                b[:pickaxe].author.to_s
         | 
| 38 | 
            -
                #=> "Thomas,  | 
| 38 | 
            +
                #=> "Thomas, D. and Fowler, Chad and Hunt, Andy"
         | 
| 39 39 | 
             
                b[:pickaxe].author[2].first
         | 
| 40 40 | 
             
                #=> "Andy"
         | 
| 41 41 |  | 
| @@ -48,6 +48,12 @@ Query a bibliography: | |
| 48 48 | 
             
                b['@book[year=2009]'].length
         | 
| 49 49 | 
             
                #=> 1 - the number of books published in 2009
         | 
| 50 50 |  | 
| 51 | 
            +
            Extend first name initials throughout your bibliography:
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                b.extend_initials ['Dave', 'Thomas']
         | 
| 54 | 
            +
                b[:pickaxe].author.to_s
         | 
| 55 | 
            +
                #=> "Thomas, Dave and Fowler, Chad and Hunt, Andy"
         | 
| 56 | 
            +
             | 
| 51 57 | 
             
            Render your bibliography in one of
         | 
| 52 58 | 
             
            [many different citation styles](https://github.com/citation-style-language/styles)
         | 
| 53 59 | 
             
            (requires the **citeproc-ruby** gem):
         | 
    
        data/Rakefile
    CHANGED
    
    
    
        data/lib/bibtex/bibliography.rb
    CHANGED
    
    | @@ -89,8 +89,9 @@ module BibTeX | |
| 89 89 | 
             
                  :comment, :meta_content
         | 
| 90 90 |  | 
| 91 91 | 
             
                def_delegators :@data, :length, :size, :empty?
         | 
| 92 | 
            -
                def_delegators :@entries, :key?, :has_key | 
| 92 | 
            +
                def_delegators :@entries, :key?, :has_key?, :values_at
         | 
| 93 93 |  | 
| 94 | 
            +
                alias entries_at values_at
         | 
| 94 95 |  | 
| 95 96 | 
             
                # Creates a new bibliography.
         | 
| 96 97 | 
             
                def initialize(options = {})
         | 
| @@ -285,6 +286,17 @@ module BibTeX | |
| 285 286 | 
             
                  self
         | 
| 286 287 | 
             
                end
         | 
| 287 288 |  | 
| 289 | 
            +
                # call-seq:
         | 
| 290 | 
            +
                #   b.extend_initials(['Edgar Allen', 'Poe'], ['Nathaniel', 'Hawthorne'])
         | 
| 291 | 
            +
                #   #=> Extends the initials in names like 'E.A. Poe' or 'Hawethorne, N.'
         | 
| 292 | 
            +
                #       in the bibliography.
         | 
| 293 | 
            +
                def extend_initials(*arguments)
         | 
| 294 | 
            +
                  arguments.each do |with_first, for_last|
         | 
| 295 | 
            +
                    names.each do |name|
         | 
| 296 | 
            +
                      name.extend_initials(with_first, for_last)
         | 
| 297 | 
            +
                    end
         | 
| 298 | 
            +
                  end
         | 
| 299 | 
            +
                end
         | 
| 288 300 |  | 
| 289 301 | 
             
                def sort(*arguments, &block)
         | 
| 290 302 | 
             
                  data.sort(*arguments, &block)
         | 
| @@ -341,6 +353,22 @@ module BibTeX | |
| 341 353 | 
             
                  xml
         | 
| 342 354 | 
             
                end
         | 
| 343 355 |  | 
| 356 | 
            +
                # Returns an RDF::Graph representation of the bibliography. The graph
         | 
| 357 | 
            +
                # can be serialized using any of the RDF serializer plugins.
         | 
| 358 | 
            +
                def to_rdf(options = {})
         | 
| 359 | 
            +
                  require 'rdf'
         | 
| 360 | 
            +
                  
         | 
| 361 | 
            +
                  graph = RDF::Graph.new
         | 
| 362 | 
            +
             | 
| 363 | 
            +
                  q('@entry').each do |entry|
         | 
| 364 | 
            +
                    graph << entry.to_rdf(options)
         | 
| 365 | 
            +
                  end
         | 
| 366 | 
            +
                  
         | 
| 367 | 
            +
                  graph
         | 
| 368 | 
            +
                rescue LoadError
         | 
| 369 | 
            +
                  BibTeX.log.error "Please gem install rdf for RDF support."
         | 
| 370 | 
            +
                end
         | 
| 371 | 
            +
                
         | 
| 344 372 | 
             
                # call-seq:
         | 
| 345 373 | 
             
                #   bib.query()          #=> returns all elements
         | 
| 346 374 | 
             
                #   bib.query('@book')   #=> returns all books
         | 
    
        data/lib/bibtex/entry.rb
    CHANGED
    
    | @@ -107,6 +107,35 @@ module BibTeX | |
| 107 107 | 
             
                  article        article-journal
         | 
| 108 108 | 
             
                }.map(&:intern)]).freeze
         | 
| 109 109 |  | 
| 110 | 
            +
                BIBO_FIELDS = Hash[*%w{
         | 
| 111 | 
            +
                  pages      pages
         | 
| 112 | 
            +
                  number     issue
         | 
| 113 | 
            +
                  isbn       isbn
         | 
| 114 | 
            +
                  issn       issn
         | 
| 115 | 
            +
                  doi        doi
         | 
| 116 | 
            +
                  edition    edition
         | 
| 117 | 
            +
                  abstract   abstract
         | 
| 118 | 
            +
                  volume     volume
         | 
| 119 | 
            +
                }.map(&:intern)].freeze
         | 
| 120 | 
            +
             | 
| 121 | 
            +
                BIBO_TYPES = Hash.new(:Document).merge(Hash[*%w{
         | 
| 122 | 
            +
                  booklet        Book
         | 
| 123 | 
            +
                  book           Book
         | 
| 124 | 
            +
                  conference     Conference
         | 
| 125 | 
            +
                  inbook         Article
         | 
| 126 | 
            +
                  incollection   Article
         | 
| 127 | 
            +
                  inproceedings  Article
         | 
| 128 | 
            +
                  manual         Manual
         | 
| 129 | 
            +
                  mastersthesis  Thesis
         | 
| 130 | 
            +
                  phdthesis      Thesis
         | 
| 131 | 
            +
                  proceedings    Proceedings
         | 
| 132 | 
            +
                  techreport     Report
         | 
| 133 | 
            +
                  journal        Journal
         | 
| 134 | 
            +
                  periodical     Periodical
         | 
| 135 | 
            +
                  unpublished    Manuscript
         | 
| 136 | 
            +
                  article        Article
         | 
| 137 | 
            +
                }.map(&:intern)]).freeze
         | 
| 138 | 
            +
             | 
| 110 139 |  | 
| 111 140 | 
             
                attr_reader :fields, :type
         | 
| 112 141 |  | 
| @@ -198,20 +227,33 @@ module BibTeX | |
| 198 227 | 
             
                alias type? has_type?
         | 
| 199 228 |  | 
| 200 229 |  | 
| 201 | 
            -
                def has_field?( | 
| 202 | 
            -
                   | 
| 230 | 
            +
                def has_field?(*names)
         | 
| 231 | 
            +
                  names.flatten.any? do |name|
         | 
| 232 | 
            +
                    name.respond_to?(:to_sym) ? fields.has_key?(name.to_sym) : false
         | 
| 233 | 
            +
                  end
         | 
| 203 234 | 
             
                end
         | 
| 204 235 |  | 
| 205 236 | 
             
                alias field? has_field?
         | 
| 206 237 |  | 
| 207 | 
            -
                def inherits?( | 
| 208 | 
            -
                   | 
| 238 | 
            +
                def inherits?(*names)
         | 
| 239 | 
            +
                  names.flatten.any? do |name|
         | 
| 240 | 
            +
                    !has_field(name) && has_parent? && parent.provides?(name)
         | 
| 241 | 
            +
                  end
         | 
| 209 242 | 
             
                end
         | 
| 210 243 |  | 
| 211 | 
            -
                # Returns true if the Entry has a field (or alias) for the passed-in  | 
| 212 | 
            -
                def provides?( | 
| 213 | 
            -
                   | 
| 214 | 
            -
             | 
| 244 | 
            +
                # Returns true if the Entry has a field (or alias) for any of the passed-in names.
         | 
| 245 | 
            +
                def provides?(*names)
         | 
| 246 | 
            +
                  names.flatten.any? do |name|
         | 
| 247 | 
            +
                    if name.respond_to?(:to_sym)
         | 
| 248 | 
            +
                      has_field?(name) || has_field?(aliases[name.to_sym])
         | 
| 249 | 
            +
                    else
         | 
| 250 | 
            +
                      false
         | 
| 251 | 
            +
                    end
         | 
| 252 | 
            +
                  end
         | 
| 253 | 
            +
                end
         | 
| 254 | 
            +
                
         | 
| 255 | 
            +
                def provides_or_inherits?(*names)
         | 
| 256 | 
            +
                  provides?(names) || inherits?(names)
         | 
| 215 257 | 
             
                end
         | 
| 216 258 |  | 
| 217 259 | 
             
                # Returns the field value referenced by the passed-in name.
         | 
| @@ -327,6 +369,16 @@ module BibTeX | |
| 327 369 | 
             
                  add(name.to_sym, value)
         | 
| 328 370 | 
             
                end
         | 
| 329 371 |  | 
| 372 | 
            +
                # Author, Editor and Translator readers
         | 
| 373 | 
            +
                NAME_FIELDS.each do |contributor|
         | 
| 374 | 
            +
                  define_method(contributor) do
         | 
| 375 | 
            +
                    get(contributor)
         | 
| 376 | 
            +
                  end
         | 
| 377 | 
            +
                  
         | 
| 378 | 
            +
                  alias_method "#{contributor}s", contributor
         | 
| 379 | 
            +
                end
         | 
| 380 | 
            +
                
         | 
| 381 | 
            +
                
         | 
| 330 382 | 
             
                # Adds a new field (name-value pair) or multiple fields to the entry.
         | 
| 331 383 | 
             
                # Returns the entry for chainability.
         | 
| 332 384 | 
             
                #
         | 
| @@ -364,6 +416,19 @@ module BibTeX | |
| 364 416 | 
             
                  Digest::MD5.hexdigest(field_names(filter).map { |k| [k, fields[k]] }.flatten.join)
         | 
| 365 417 | 
             
                end
         | 
| 366 418 |  | 
| 419 | 
            +
                def identifier
         | 
| 420 | 
            +
                  case
         | 
| 421 | 
            +
                  when provides?(:doi)
         | 
| 422 | 
            +
                    "info:doi/#{get(:doi)}"
         | 
| 423 | 
            +
                  when provides?(:isbn)
         | 
| 424 | 
            +
                    "urn:isbn:#{get(:isbn)}"
         | 
| 425 | 
            +
                  when provides?(:issn)
         | 
| 426 | 
            +
                    "urn:issn:#{get(:issn)}"
         | 
| 427 | 
            +
                  else
         | 
| 428 | 
            +
                    "urn:bibtex:#{key}"
         | 
| 429 | 
            +
                  end
         | 
| 430 | 
            +
                end
         | 
| 431 | 
            +
                
         | 
| 367 432 | 
             
                # Called when the element was added to a bibliography.
         | 
| 368 433 | 
             
                def added_to_bibliography(bibliography)
         | 
| 369 434 | 
             
                  super
         | 
| @@ -431,6 +496,9 @@ module BibTeX | |
| 431 496 |  | 
| 432 497 | 
             
                alias parse_months parse_month
         | 
| 433 498 |  | 
| 499 | 
            +
                def date
         | 
| 500 | 
            +
                  get(:date) || get(:year)
         | 
| 501 | 
            +
                end
         | 
| 434 502 |  | 
| 435 503 | 
             
                # Parses all name values of the entry. Tries to replace and join the
         | 
| 436 504 | 
             
                # value prior to parsing.
         | 
| @@ -494,6 +562,43 @@ module BibTeX | |
| 494 562 |  | 
| 495 563 | 
             
                alias cross_referenced_by children
         | 
| 496 564 |  | 
| 565 | 
            +
                def container_title
         | 
| 566 | 
            +
                  get(:booktitle) || get(:journal) || get(:container)
         | 
| 567 | 
            +
                end
         | 
| 568 | 
            +
                
         | 
| 569 | 
            +
                def pages_from
         | 
| 570 | 
            +
                  fetch(:pages, '').split(/\D+/)[0]
         | 
| 571 | 
            +
                end
         | 
| 572 | 
            +
             | 
| 573 | 
            +
                def pages_to
         | 
| 574 | 
            +
                  fetch(:pages, '').split(/\D+/)[-1]
         | 
| 575 | 
            +
                end
         | 
| 576 | 
            +
                
         | 
| 577 | 
            +
                # Returns true if this entry is published inside a book, collection or journal
         | 
| 578 | 
            +
                def contained?
         | 
| 579 | 
            +
                  has_field?(:booktitle, :container, :journal)
         | 
| 580 | 
            +
                end
         | 
| 581 | 
            +
                
         | 
| 582 | 
            +
                
         | 
| 583 | 
            +
                # Returns a duplicate entry with all values converted using the filter.
         | 
| 584 | 
            +
                # If an optional block is given, only those values will be converted where
         | 
| 585 | 
            +
                # the block returns true (the block will be called with each key-value pair).
         | 
| 586 | 
            +
                #
         | 
| 587 | 
            +
                # @see #convert!
         | 
| 588 | 
            +
                def convert(filter)
         | 
| 589 | 
            +
                  block_given? ? dup.convert!(filter, &Proc.new) : dup.convert!(filter)
         | 
| 590 | 
            +
                end
         | 
| 591 | 
            +
                
         | 
| 592 | 
            +
                # In-place variant of @see #convert
         | 
| 593 | 
            +
                def convert!(filter)
         | 
| 594 | 
            +
                  fields.each_pair { |k,v| !block_given? || yield(k,v) ? v.convert!(filter) : v }
         | 
| 595 | 
            +
                  self
         | 
| 596 | 
            +
                end
         | 
| 597 | 
            +
                
         | 
| 598 | 
            +
                def <=>(other)
         | 
| 599 | 
            +
                  type != other.type ? type <=> other.type : key != other.key ? key <=> other.key : to_s <=> other.to_s
         | 
| 600 | 
            +
                end
         | 
| 601 | 
            +
                
         | 
| 497 602 |  | 
| 498 603 | 
             
                # Returns a string of all the entry's fields.
         | 
| 499 604 | 
             
                def content(options = {})
         | 
| @@ -562,24 +667,106 @@ module BibTeX | |
| 562 667 | 
             
                  xml
         | 
| 563 668 | 
             
                end
         | 
| 564 669 |  | 
| 565 | 
            -
                # Returns a  | 
| 566 | 
            -
                #  | 
| 567 | 
            -
                 | 
| 568 | 
            -
             | 
| 569 | 
            -
             | 
| 570 | 
            -
             | 
| 571 | 
            -
                   | 
| 670 | 
            +
                # Returns a RDF::Graph representation of the entry using the BIBO ontology.
         | 
| 671 | 
            +
                # TODO: improve level of detail captured by export
         | 
| 672 | 
            +
                def to_rdf(options = {})
         | 
| 673 | 
            +
                  require 'rdf'
         | 
| 674 | 
            +
                  
         | 
| 675 | 
            +
                  bibo = RDF::Vocabulary.new('http://purl.org/ontology/bibo/')
         | 
| 676 | 
            +
                  
         | 
| 677 | 
            +
                  graph = RDF::Graph.new
         | 
| 678 | 
            +
                  entry = RDF::URI.new(identifier)
         | 
| 679 | 
            +
             | 
| 680 | 
            +
                  graph << [entry, RDF.type, bibo[BIBO_TYPES[type]]]
         | 
| 681 | 
            +
                  
         | 
| 682 | 
            +
                  [:title, :language].each do |key|        
         | 
| 683 | 
            +
                    graph << [entry, RDF::DC[key], get(key).to_s] if field?(key)
         | 
| 684 | 
            +
                  end
         | 
| 685 | 
            +
             | 
| 686 | 
            +
                  graph << [entry, RDF::DC.date, get(:year).to_s] if field?(:year)
         | 
| 687 | 
            +
                  
         | 
| 688 | 
            +
                  if field?(:publisher)
         | 
| 689 | 
            +
                    address = RDF::Vocabulary.new('http://schemas.talis.com/2005/address/schema#')
         | 
| 690 | 
            +
                    pub = RDF::Node.new
         | 
| 691 | 
            +
             | 
| 692 | 
            +
                    graph << [pub, RDF.type, RDF::FOAF[:Organization]]
         | 
| 693 | 
            +
                    graph << [pub, RDF::FOAF.name, get(:publisher)]
         | 
| 694 | 
            +
                    
         | 
| 695 | 
            +
                    graph << [pub, address[:localityName], get(:address)] if field?(:address)
         | 
| 696 | 
            +
                    
         | 
| 697 | 
            +
                    graph << [entry, RDF::DC.published, pub]
         | 
| 698 | 
            +
                  end
         | 
| 699 | 
            +
             | 
| 700 | 
            +
                  [:doi, :edition, :volume].each do |key|        
         | 
| 701 | 
            +
                    graph << [entry, bibo[key], get(key).to_s] if field?(key)
         | 
| 702 | 
            +
                  end
         | 
| 703 | 
            +
                  
         | 
| 704 | 
            +
                  if has_field?(:pages)
         | 
| 705 | 
            +
                    if get(:pages).to_s =~ /^\s*(\d+)\s*-+\s*(\d+)\s*$/
         | 
| 706 | 
            +
                      graph << [entry, bibo[:pageStart], $1]
         | 
| 707 | 
            +
                      graph << [entry, bibo[:pageEnd], $2]
         | 
| 708 | 
            +
                    else
         | 
| 709 | 
            +
                      graph << [entry, bibo[:pages], get(:pages).to_s]
         | 
| 710 | 
            +
                    end
         | 
| 711 | 
            +
                  end
         | 
| 712 | 
            +
             | 
| 713 | 
            +
                  if has_field?(:author)
         | 
| 714 | 
            +
                    seq = RDF::Node.new
         | 
| 715 | 
            +
             | 
| 716 | 
            +
                    graph << [seq, RDF.type, RDF[:Seq]]
         | 
| 717 | 
            +
                    graph << [entry, bibo[:authorList], seq]
         | 
| 718 | 
            +
                    
         | 
| 719 | 
            +
                    authors.each do |author|
         | 
| 720 | 
            +
                      a = RDF::Node.new
         | 
| 721 | 
            +
                    
         | 
| 722 | 
            +
                      graph << [a, RDF.type, RDF::FOAF[:Person]]
         | 
| 723 | 
            +
                      
         | 
| 724 | 
            +
                      if author.is_a?(Name)       
         | 
| 725 | 
            +
                        [:given, :family, :prefix, :suffix].each do |part|
         | 
| 726 | 
            +
                          graph << [a, bibo["#{part}Name"], author.send(part).to_s]
         | 
| 727 | 
            +
                        end
         | 
| 728 | 
            +
                      else
         | 
| 729 | 
            +
                        graph << [a, RDF::FOAF.name, author.to_s]
         | 
| 730 | 
            +
                      end
         | 
| 731 | 
            +
             | 
| 732 | 
            +
                      graph << [entry, RDF::DC.creator, a]
         | 
| 733 | 
            +
                      graph << [seq, RDF.li, a]
         | 
| 734 | 
            +
                    end
         | 
| 735 | 
            +
                  end
         | 
| 736 | 
            +
             | 
| 737 | 
            +
                  if has_field?(:editor)
         | 
| 738 | 
            +
                    seq = RDF::Node.new
         | 
| 739 | 
            +
             | 
| 740 | 
            +
                    graph << [seq, RDF.type, RDF[:Seq]]
         | 
| 741 | 
            +
                    graph << [entry, bibo[:editorList], seq]
         | 
| 742 | 
            +
             | 
| 743 | 
            +
                    editors.each do |editor|
         | 
| 744 | 
            +
                      e = RDF::Node.new
         | 
| 745 | 
            +
             | 
| 746 | 
            +
                      graph << [e, RDF.type, RDF::FOAF[:Person]]
         | 
| 747 | 
            +
             | 
| 748 | 
            +
                      if editor.is_a?(Name)
         | 
| 749 | 
            +
                        [:given, :family, :prefix, :suffix].each do |part|
         | 
| 750 | 
            +
                          graph << [e, bibo["#{part}Name"], editor.send(part).to_s]
         | 
| 751 | 
            +
                        end
         | 
| 752 | 
            +
                      else
         | 
| 753 | 
            +
                        graph << [e, RDF::FOAF.name, editor.to_s]
         | 
| 754 | 
            +
                      end
         | 
| 755 | 
            +
             | 
| 756 | 
            +
                      graph << [entry, bibo.editor, a]
         | 
| 757 | 
            +
                      graph << [seq, RDF.li, e]
         | 
| 758 | 
            +
                    end
         | 
| 759 | 
            +
                  end
         | 
| 760 | 
            +
                  
         | 
| 761 | 
            +
                  graph
         | 
| 762 | 
            +
                rescue LoadError
         | 
| 763 | 
            +
                  BibTeX.log.error "Please gem install rdf for RDF support."
         | 
| 572 764 | 
             
                end
         | 
| 573 765 |  | 
| 574 | 
            -
                 | 
| 575 | 
            -
                def convert!(filter)
         | 
| 576 | 
            -
                  fields.each_pair { |k,v| !block_given? || yield(k,v) ? v.convert!(filter) : v }
         | 
| 577 | 
            -
                  self
         | 
| 578 | 
            -
                end
         | 
| 766 | 
            +
                alias to_bibo to_rdf
         | 
| 579 767 |  | 
| 580 | 
            -
                 | 
| 581 | 
            -
             | 
| 582 | 
            -
                end
         | 
| 768 | 
            +
                
         | 
| 769 | 
            +
             | 
| 583 770 |  | 
| 584 771 | 
             
                private
         | 
| 585 772 |  | 
| @@ -594,5 +781,6 @@ module BibTeX | |
| 594 781 | 
             
                  k
         | 
| 595 782 | 
             
                end
         | 
| 596 783 |  | 
| 784 | 
            +
                
         | 
| 597 785 | 
             
              end
         | 
| 598 786 | 
             
            end
         | 
    
        data/lib/bibtex/names.rb
    CHANGED
    
    | @@ -20,6 +20,7 @@ require 'forwardable' | |
| 20 20 |  | 
| 21 21 | 
             
            module BibTeX
         | 
| 22 22 |  | 
| 23 | 
            +
              # A BibTeX Names value is an ordered list of name values.
         | 
| 23 24 | 
             
              class Names < Value
         | 
| 24 25 | 
             
                include Enumerable
         | 
| 25 26 |  | 
| @@ -27,9 +28,9 @@ module BibTeX | |
| 27 28 |  | 
| 28 29 | 
             
                def self.parse(string)
         | 
| 29 30 | 
             
                  new(NameParser.new.parse(string))
         | 
| 30 | 
            -
             | 
| 31 | 
            -
             | 
| 32 | 
            -
             | 
| 31 | 
            +
                rescue => e
         | 
| 32 | 
            +
                  BibTeX.log.info(e.message)
         | 
| 33 | 
            +
                  nil
         | 
| 33 34 | 
             
                end
         | 
| 34 35 |  | 
| 35 36 | 
             
                def initialize(*arguments)
         | 
| @@ -39,12 +40,16 @@ module BibTeX | |
| 39 40 | 
             
                  end
         | 
| 40 41 | 
             
                end
         | 
| 41 42 |  | 
| 42 | 
            -
                def replace(*arguments) | 
| 43 | 
            +
                def replace(*arguments)
         | 
| 44 | 
            +
                  self
         | 
| 45 | 
            +
                end
         | 
| 43 46 |  | 
| 44 | 
            -
                def join | 
| 47 | 
            +
                def join
         | 
| 48 | 
            +
                  self
         | 
| 49 | 
            +
                end
         | 
| 45 50 |  | 
| 46 | 
            -
                def value
         | 
| 47 | 
            -
                  @tokens.join(' and ')
         | 
| 51 | 
            +
                def value(options = {})
         | 
| 52 | 
            +
                  @tokens.map { |n| n.to_s(options) }.join(' and ')
         | 
| 48 53 | 
             
                end
         | 
| 49 54 |  | 
| 50 55 | 
             
                def to_s(options = {})
         | 
| @@ -53,14 +58,24 @@ module BibTeX | |
| 53 58 | 
             
                  [q[0], value, q[-1]].compact.join
         | 
| 54 59 | 
             
                end
         | 
| 55 60 |  | 
| 56 | 
            -
                def name | 
| 57 | 
            -
             | 
| 58 | 
            -
                 | 
| 61 | 
            +
                def name?
         | 
| 62 | 
            +
                  true
         | 
| 63 | 
            +
                end
         | 
| 64 | 
            +
                
         | 
| 65 | 
            +
                def numeric?
         | 
| 66 | 
            +
                  false
         | 
| 67 | 
            +
                end
         | 
| 59 68 |  | 
| 60 | 
            -
                 | 
| 61 | 
            -
             | 
| 69 | 
            +
                def atomic?
         | 
| 70 | 
            +
                  true
         | 
| 71 | 
            +
                end
         | 
| 62 72 |  | 
| 63 | 
            -
                 | 
| 73 | 
            +
                alias names? name?
         | 
| 74 | 
            +
                alias symbol? numeric?
         | 
| 75 | 
            +
                
         | 
| 76 | 
            +
                def to_name
         | 
| 77 | 
            +
                  self
         | 
| 78 | 
            +
                end
         | 
| 64 79 |  | 
| 65 80 | 
             
                def to_citeproc(options = {})
         | 
| 66 81 | 
             
                  map { |n| n.to_citeproc(options) }
         | 
| @@ -82,13 +97,14 @@ module BibTeX | |
| 82 97 | 
             
                  self
         | 
| 83 98 | 
             
                end
         | 
| 84 99 |  | 
| 85 | 
            -
                alias  | 
| 86 | 
            -
                alias  | 
| 100 | 
            +
                alias << add
         | 
| 101 | 
            +
                alias push add
         | 
| 87 102 |  | 
| 88 | 
            -
                 | 
| 89 | 
            -
             | 
| 90 | 
            -
             | 
| 91 | 
            -
             | 
| 103 | 
            +
                [:convert!, :rename_if, :rename_unless, :extend_initials].each do |method_id|
         | 
| 104 | 
            +
                  define_method(method_id) do |*arguments|
         | 
| 105 | 
            +
                    tokens.each { |t| t.send(method_id, *arguments) }
         | 
| 106 | 
            +
                    self
         | 
| 107 | 
            +
                  end
         | 
| 92 108 | 
             
                end
         | 
| 93 109 |  | 
| 94 110 | 
             
                def <=>(other)
         | 
| @@ -97,20 +113,21 @@ module BibTeX | |
| 97 113 |  | 
| 98 114 | 
             
              end
         | 
| 99 115 |  | 
| 116 | 
            +
              # A Name comprises individual name parts (first, last, prefix and suffix),
         | 
| 117 | 
            +
              # but behaves almost like an atomic string value.
         | 
| 100 118 | 
             
              class Name < Struct.new(:first, :last, :prefix, :suffix)
         | 
| 101 119 | 
             
                extend Forwardable
         | 
| 102 | 
            -
             | 
| 103 120 | 
             
                include Comparable
         | 
| 104 | 
            -
             | 
| 121 | 
            +
                
         | 
| 105 122 | 
             
                BibTeXML = {
         | 
| 106 | 
            -
             | 
| 107 | 
            -
             | 
| 108 | 
            -
             | 
| 109 | 
            -
             | 
| 110 | 
            -
             | 
| 111 | 
            -
             | 
| 123 | 
            +
                  :first  => :first,
         | 
| 124 | 
            +
                  :last   => :last,
         | 
| 125 | 
            +
                  :prefix => :prelast,
         | 
| 126 | 
            +
                  :suffix => :lineage
         | 
| 127 | 
            +
                }.freeze
         | 
| 128 | 
            +
                
         | 
| 112 129 | 
             
                def_delegators :to_s, :=~, :===,
         | 
| 113 | 
            -
             | 
| 130 | 
            +
                  *String.instance_methods(false).reject { |m| m =~ /^\W|to_s|replace|each|first|last|!$/ }
         | 
| 114 131 |  | 
| 115 132 | 
             
                class << self    
         | 
| 116 133 | 
             
                  def parse(string)
         | 
| @@ -125,53 +142,114 @@ module BibTeX | |
| 125 142 | 
             
                end
         | 
| 126 143 |  | 
| 127 144 | 
             
                def initialize(attributes = {})
         | 
| 128 | 
            -
                  attributes | 
| 129 | 
            -
                    send("#{key}=", value) if respond_to?(key)
         | 
| 130 | 
            -
                  end
         | 
| 145 | 
            +
                  set(attributes)
         | 
| 131 146 | 
             
                end
         | 
| 132 147 |  | 
| 133 148 | 
             
                def initalize_copy(other)
         | 
| 134 | 
            -
                  each_pair { |k,v| self[k] = v }
         | 
| 149 | 
            +
                  each_pair { |k,v| self[k] = v.dup }
         | 
| 150 | 
            +
                end
         | 
| 151 | 
            +
                
         | 
| 152 | 
            +
                # Set the name tokens to the values defined in the passed-in hash.
         | 
| 153 | 
            +
                def set(attributes = {})
         | 
| 154 | 
            +
                  attributes.each do |key, value|
         | 
| 155 | 
            +
                    send("#{key}=", value) if respond_to?(key)
         | 
| 156 | 
            +
                  end
         | 
| 157 | 
            +
                  
         | 
| 158 | 
            +
                  self
         | 
| 135 159 | 
             
                end
         | 
| 136 160 |  | 
| 137 161 | 
             
                def blank?
         | 
| 138 162 | 
             
                  to_a.compact.empty?
         | 
| 139 163 | 
             
                end
         | 
| 164 | 
            +
             | 
| 165 | 
            +
                # Returns the first name (or the passed-in string) as initials.
         | 
| 166 | 
            +
                def initials(token = first)
         | 
| 167 | 
            +
                  token.to_s.gsub(/([[:upper:]])[[:lower:]]+\s*/, '\1.')
         | 
| 168 | 
            +
                end
         | 
| 140 169 |  | 
| 141 | 
            -
                 | 
| 142 | 
            -
             | 
| 170 | 
            +
                # Returns true if the first name consists solely of initials.
         | 
| 171 | 
            +
                def initials?
         | 
| 172 | 
            +
                  !(first.nil? || first.empty? || first.to_s =~ /[[:alpha:]]{2,}[^\.]/)
         | 
| 173 | 
            +
                end
         | 
| 174 | 
            +
             | 
| 175 | 
            +
                # Sets the name's first name to the passed-in name if the last name equals
         | 
| 176 | 
            +
                # for_last and the current first name has the same initials as with_first.
         | 
| 177 | 
            +
                def extend_initials(with_first, for_last)
         | 
| 178 | 
            +
                  rename_if :first => with_first do |name|
         | 
| 179 | 
            +
                    name.last == for_last && name.initials.gsub(/\s+/, '') == initials(with_first).gsub(/\s+/, '')
         | 
| 180 | 
            +
                  end
         | 
| 181 | 
            +
                end
         | 
| 182 | 
            +
                
         | 
| 183 | 
            +
                # Renames the tokens according to the passed-in attributes if all of the
         | 
| 184 | 
            +
                # conditions match or if the given block returns true.
         | 
| 185 | 
            +
                def rename_if(attributes, conditions = {})
         | 
| 186 | 
            +
                  if block_given?
         | 
| 187 | 
            +
                    set(attributes) if yield self
         | 
| 188 | 
            +
                  else
         | 
| 189 | 
            +
                    set(attributes) if conditions.all? do |key, value|
         | 
| 190 | 
            +
                      respond_to?(key) && send(key) == value
         | 
| 191 | 
            +
                    end
         | 
| 192 | 
            +
                  end
         | 
| 193 | 
            +
                  
         | 
| 194 | 
            +
                  self
         | 
| 195 | 
            +
                end
         | 
| 196 | 
            +
                
         | 
| 197 | 
            +
                def rename_unless(attributes, conditions = {})
         | 
| 198 | 
            +
                  if block_given?
         | 
| 199 | 
            +
                    set(attributes) unless yield self
         | 
| 200 | 
            +
                  else
         | 
| 201 | 
            +
                    set(attributes) unless conditions.all? do |key, value|
         | 
| 202 | 
            +
                      respond_to?(key) && send(key) == value
         | 
| 203 | 
            +
                    end
         | 
| 204 | 
            +
                  end
         | 
| 205 | 
            +
                  
         | 
| 206 | 
            +
                  self
         | 
| 207 | 
            +
                end
         | 
| 208 | 
            +
                
         | 
| 209 | 
            +
                # call-seq:
         | 
| 210 | 
            +
                #   name.display_order #=> 'Edgar Allen Poe'
         | 
| 211 | 
            +
                #   name.display_order :initials => true #=> 'E.A. Poe'
         | 
| 212 | 
            +
                #
         | 
| 213 | 
            +
                # Returns the name as a string in display order.
         | 
| 214 | 
            +
                def display_order(options = {})
         | 
| 215 | 
            +
                  [options[:initials] ? initials : first, prefix, last, suffix].compact.join(' ')
         | 
| 143 216 | 
             
                end
         | 
| 144 217 |  | 
| 145 218 | 
             
                alias display display_order
         | 
| 146 219 |  | 
| 147 | 
            -
                 | 
| 148 | 
            -
             | 
| 220 | 
            +
                # call-seq:
         | 
| 221 | 
            +
                #   name.sort_order #=> 'Poe, Edgar Allen'
         | 
| 222 | 
            +
                #   name.sort_order :initials => true #=> 'Poe, E.A.'
         | 
| 223 | 
            +
                #
         | 
| 224 | 
            +
                # Returns the name as a string in sort order.
         | 
| 225 | 
            +
                def sort_order(options = {})
         | 
| 226 | 
            +
                  [[prefix, last].compact.join(' '), suffix, options[:initials] ? initials : first].compact.join(', ')
         | 
| 149 227 | 
             
                end
         | 
| 150 228 |  | 
| 151 229 | 
             
                alias to_s sort_order
         | 
| 152 | 
            -
             | 
| 230 | 
            +
                    
         | 
| 153 231 | 
             
                def <=>(other)
         | 
| 154 | 
            -
                  other.is_a?(Name) ?  | 
| 232 | 
            +
                  other.is_a?(Name) ? sort_order <=> other.sort_order : super
         | 
| 155 233 | 
             
                end
         | 
| 156 234 |  | 
| 157 235 | 
             
                def to_hash
         | 
| 158 236 | 
             
                  Hash[each_pair.to_a]
         | 
| 159 237 | 
             
                end
         | 
| 160 238 |  | 
| 161 | 
            -
             | 
| 162 | 
            -
             | 
| 163 | 
            -
             | 
| 239 | 
            +
                def to_xml
         | 
| 240 | 
            +
                  require 'rexml/document'      
         | 
| 241 | 
            +
                  xml = REXML::Element.new('bibtex:person')
         | 
| 164 242 |  | 
| 165 | 
            -
             | 
| 166 | 
            -
             | 
| 167 | 
            -
             | 
| 168 | 
            -
             | 
| 169 | 
            -
             | 
| 170 | 
            -
             | 
| 171 | 
            -
             | 
| 172 | 
            -
             | 
| 173 | 
            -
             | 
| 174 | 
            -
             | 
| 243 | 
            +
                  each_pair do |part, text|
         | 
| 244 | 
            +
                    unless text.nil?
         | 
| 245 | 
            +
                      element = REXML::Element.new("bibtex:#{BibTeXML[part]}")
         | 
| 246 | 
            +
                      element.text = text
         | 
| 247 | 
            +
                      xml.add_element(element)
         | 
| 248 | 
            +
                    end
         | 
| 249 | 
            +
                  end
         | 
| 250 | 
            +
                  
         | 
| 251 | 
            +
                  xml
         | 
| 252 | 
            +
                end
         | 
| 175 253 |  | 
| 176 254 | 
             
                [:strip!, :upcase!, :downcase!, :sub!, :gsub!, :chop!, :chomp!, :rstrip!].each do |method_id|
         | 
| 177 255 | 
             
                  define_method(method_id) do |*arguments, &block|
         | 
| @@ -182,20 +260,20 @@ module BibTeX | |
| 182 260 | 
             
                  end
         | 
| 183 261 | 
             
                end
         | 
| 184 262 |  | 
| 185 | 
            -
             | 
| 186 | 
            -
             | 
| 187 | 
            -
             | 
| 188 | 
            -
             | 
| 189 | 
            -
             | 
| 190 | 
            -
             | 
| 191 | 
            -
             | 
| 192 | 
            -
             | 
| 193 | 
            -
             | 
| 194 | 
            -
             | 
| 263 | 
            +
                def convert(filter)
         | 
| 264 | 
            +
                  dup.convert!(filter)
         | 
| 265 | 
            +
                end
         | 
| 266 | 
            +
                
         | 
| 267 | 
            +
                def convert!(filter)
         | 
| 268 | 
            +
                  if f = Filters.resolve(filter)
         | 
| 269 | 
            +
                    each_pair { |k,v| self[k] = f.apply(v) unless v.nil? }
         | 
| 270 | 
            +
                  else
         | 
| 271 | 
            +
                    raise ArgumentError, "Failed to load filter #{filter.inspect}"
         | 
| 272 | 
            +
                  end
         | 
| 195 273 |  | 
| 196 | 
            -
             | 
| 197 | 
            -
             | 
| 198 | 
            -
             | 
| 274 | 
            +
                  self
         | 
| 275 | 
            +
                end
         | 
| 276 | 
            +
                
         | 
| 199 277 | 
             
                def to_citeproc(options = {})
         | 
| 200 278 | 
             
                  hash = {}
         | 
| 201 279 | 
             
                  hash['family'] = family unless family.nil?
         | 
| @@ -213,6 +291,6 @@ module BibTeX | |
| 213 291 | 
             
                alias jr= suffix=
         | 
| 214 292 | 
             
                alias von prefix
         | 
| 215 293 | 
             
                alias von= prefix=    
         | 
| 216 | 
            -
             | 
| 294 | 
            +
               
         | 
| 217 295 | 
             
              end
         | 
| 218 296 | 
             
            end
         | 
    
        data/lib/bibtex/version.rb
    CHANGED
    
    
| @@ -71,6 +71,20 @@ module BibTeX | |
| 71 71 | 
             
                    END
         | 
| 72 72 | 
             
                  end
         | 
| 73 73 |  | 
| 74 | 
            +
                  describe '#entries_at' do
         | 
| 75 | 
            +
                    it 'returns a list of all entries identified by the passed-in keys' do
         | 
| 76 | 
            +
                      assert_equal [@bib['segaran2007'], @bib['rails']], @bib.entries_at('segaran2007', :rails)
         | 
| 77 | 
            +
                    end
         | 
| 78 | 
            +
                  end
         | 
| 79 | 
            +
                  
         | 
| 80 | 
            +
                  describe '#extend_initials' do
         | 
| 81 | 
            +
                    it 'extends the initials in matching names' do
         | 
| 82 | 
            +
                      @bib.names.map(&:to_s).wont_include 'Flanagan, Dave'
         | 
| 83 | 
            +
                      @bib.extend_initials(['Dave', 'Flanagan'])
         | 
| 84 | 
            +
                      @bib.names.map(&:to_s).must_include 'Flanagan, Dave'
         | 
| 85 | 
            +
                    end
         | 
| 86 | 
            +
                  end
         | 
| 87 | 
            +
                  
         | 
| 74 88 | 
             
                  it 'supports access by index' do
         | 
| 75 89 | 
             
                    assert_equal 'ruby', @bib[1].keywords 
         | 
| 76 90 | 
             
                  end
         | 
    
        data/test/bibtex/test_names.rb
    CHANGED
    
    | @@ -5,6 +5,10 @@ require 'helper' | |
| 5 5 | 
             
            module BibTeX
         | 
| 6 6 | 
             
              class NamesTest < MiniTest::Spec
         | 
| 7 7 |  | 
| 8 | 
            +
                before do
         | 
| 9 | 
            +
                  @poe = Name.new(:first => 'Edgar Allen', :last => 'Poe')
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
                
         | 
| 8 12 | 
             
                describe 'string behaviour' do
         | 
| 9 13 | 
             
                  before do
         | 
| 10 14 | 
             
                    @name = Name.new(:first => 'Charles Louis Xavier Joseph', :prefix => 'de la', :last => 'Vallee Poussin', :suffix => 'Jr.')
         | 
| @@ -18,7 +22,85 @@ module BibTeX | |
| 18 22 | 
             
                  it 'should implement gsub!' do
         | 
| 19 23 | 
             
                    assert_equal 'dX la VallXX PoussXn, Jr., CharlXs LouXs XavXXr JosXph', @name.gsub!(/[ei]/, 'X').to_s        
         | 
| 20 24 | 
             
                  end
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
                
         | 
| 27 | 
            +
                describe '#display_order' do
         | 
| 28 | 
            +
                  it 'returns the name as "first last"' do
         | 
| 29 | 
            +
                    @poe.display_order.must_be :==, 'Edgar Allen Poe'
         | 
| 30 | 
            +
                  end
         | 
| 31 | 
            +
                  
         | 
| 32 | 
            +
                  it 'accepts the :initials option' do
         | 
| 33 | 
            +
                    @poe.display_order(:initials => true).must_be :==, 'E.A. Poe'
         | 
| 34 | 
            +
                  end
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                describe '#sort_order' do
         | 
| 38 | 
            +
                  it 'returns the name as "last, first"' do
         | 
| 39 | 
            +
                    @poe.sort_order.must_be :==, 'Poe, Edgar Allen'
         | 
| 40 | 
            +
                  end
         | 
| 41 | 
            +
                  
         | 
| 42 | 
            +
                  it 'accepts the :initials option' do
         | 
| 43 | 
            +
                    @poe.sort_order(:initials => true).must_be :==, 'Poe, E.A.'
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
                
         | 
| 47 | 
            +
                describe '#initials?' do
         | 
| 48 | 
            +
                  it 'returns true if the name contains a solely initials as a first name' do
         | 
| 49 | 
            +
                    @poe.initials?.must_equal false
         | 
| 50 | 
            +
                    
         | 
| 51 | 
            +
                    @poe.first = 'Edgar A.'
         | 
| 52 | 
            +
                    @poe.initials?.must_equal false
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                    @poe.first = 'E.A.'
         | 
| 55 | 
            +
                    @poe.initials?.must_equal true
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                    @poe.first = ''
         | 
| 58 | 
            +
                    @poe.initials?.must_equal false
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                    @poe.first = nil
         | 
| 61 | 
            +
                    @poe.initials?.must_equal false
         | 
| 62 | 
            +
                  end
         | 
| 63 | 
            +
                end
         | 
| 64 | 
            +
                
         | 
| 65 | 
            +
                describe '#rename_if' do
         | 
| 66 | 
            +
                  it 'renames the name to the given attributes if no condition is given' do
         | 
| 67 | 
            +
                    @poe.rename_if({ :first => 'E.A.' }).first.must_equal 'E.A.'
         | 
| 68 | 
            +
                  end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                  it 'renames the name to the given attributes if all conditions match' do
         | 
| 71 | 
            +
                    @poe.rename_if({ :first => 'E.A.' }, { :last => @poe.last }).first.must_equal 'E.A.'
         | 
| 72 | 
            +
                    @poe.rename_if({ :first => 'E.A.' }, { :last => @poe.last, :first => @poe.first }).first.must_equal 'E.A.'
         | 
| 73 | 
            +
                  end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                  it 'renames the name to the given attributes if the block returns true' do
         | 
| 76 | 
            +
                    @poe.rename_if({ :first => 'E.A.' }) {|n| true}.first.must_equal 'E.A.'
         | 
| 77 | 
            +
                  end
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                  it 'does not rename the name to the given attributes if at least one condition does not match' do
         | 
| 80 | 
            +
                    @poe.rename_if({ :first => 'E.A.' }, { :last => 'foo' }).first.wont_equal 'E.A.'
         | 
| 81 | 
            +
                    @poe.rename_if({ :first => 'E.A.' }, { :last => 'foo', :first => @poe.first }).first.wont_equal 'E.A.'
         | 
| 82 | 
            +
                    @poe.rename_if({ :first => 'E.A.' }, { :last => @poe.last, :first => 'foo' }).first.wont_equal 'E.A.'
         | 
| 83 | 
            +
                  end
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                  it 'does not rename the name to the given attributes if the block returns false' do
         | 
| 86 | 
            +
                    @poe.rename_if({ :first => 'E.A.' }) {|n| false}.first.wont_equal 'E.A.'
         | 
| 87 | 
            +
                  end
         | 
| 88 | 
            +
                end
         | 
| 89 | 
            +
                
         | 
| 90 | 
            +
                describe '#extend_initials' do
         | 
| 91 | 
            +
                  it 'extends the first name if the last name and initials match' do
         | 
| 92 | 
            +
                    Name.new(:first => 'E.A.', :last => 'Poe').extend_initials('Edgar Allen', 'Poe').first.must_equal 'Edgar Allen'
         | 
| 93 | 
            +
                    Name.new(:first => 'Edgar A.', :last => 'Poe').extend_initials('Edgar Allen', 'Poe').first.must_equal 'Edgar Allen'
         | 
| 94 | 
            +
                    Name.new(:first => 'E. A.', :last => 'Poe').extend_initials('Edgar Allen', 'Poe').first.must_equal 'Edgar Allen'
         | 
| 95 | 
            +
                    Name.new(:first => 'E. Allen', :last => 'Poe').extend_initials('Edgar Allen', 'Poe').first.must_equal 'Edgar Allen'
         | 
| 96 | 
            +
                    Name.new(:first => 'E.A.', :last => 'Poe').extend_initials('Edgar A.', 'Poe').first.must_equal 'Edgar A.'
         | 
| 97 | 
            +
                  end
         | 
| 21 98 |  | 
| 99 | 
            +
                  it 'does not extend the first name if the last name or initials do not match' do
         | 
| 100 | 
            +
                    Name.new(:first => 'E.A.', :last => 'Poe').extend_initials('Edgar Allen', 'Poser').first.wont_equal 'Edgar Allen'
         | 
| 101 | 
            +
                    Name.new(:first => 'E.A.', :last => 'Poe').extend_initials('Edgar Ellen', 'Poe').first.wont_equal 'Edgar Ellen'
         | 
| 102 | 
            +
                    Name.new(:first => 'E.R.', :last => 'Poe').extend_initials('Edgar Allen', 'Poe').first.wont_equal 'Edgar Allen'
         | 
| 103 | 
            +
                  end
         | 
| 22 104 | 
             
                end
         | 
| 23 105 |  | 
| 24 106 | 
             
            		describe "conversions" do
         | 
| @@ -39,8 +121,8 @@ module BibTeX | |
| 39 121 | 
             
            					Names.parse("S{\\o}ren Kirkegaard and Emmanuel L\\'evinas").convert(:latex).to_s.must_be :==, 'Kirkegaard, Søren and Lévinas, Emmanuel'
         | 
| 40 122 | 
             
            				end
         | 
| 41 123 | 
             
            			end
         | 
| 42 | 
            -
             | 
| 43 124 | 
             
            		end
         | 
| 44 125 |  | 
| 45 126 | 
             
              end
         | 
| 127 | 
            +
              
         | 
| 46 128 | 
             
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: bibtex-ruby
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 2.0. | 
| 4 | 
            +
              version: 2.0.8
         | 
| 5 5 | 
             
              prerelease: 
         | 
| 6 6 | 
             
            platform: ruby
         | 
| 7 7 | 
             
            authors:
         | 
| @@ -9,11 +9,11 @@ authors: | |
| 9 9 | 
             
            autorequire: 
         | 
| 10 10 | 
             
            bindir: bin
         | 
| 11 11 | 
             
            cert_chain: []
         | 
| 12 | 
            -
            date: 2012- | 
| 12 | 
            +
            date: 2012-05-11 00:00:00.000000000 Z
         | 
| 13 13 | 
             
            dependencies:
         | 
| 14 14 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 15 15 | 
             
              name: latex-decode
         | 
| 16 | 
            -
              requirement: & | 
| 16 | 
            +
              requirement: &70229986220740 !ruby/object:Gem::Requirement
         | 
| 17 17 | 
             
                none: false
         | 
| 18 18 | 
             
                requirements:
         | 
| 19 19 | 
             
                - - ! '>='
         | 
| @@ -21,10 +21,10 @@ dependencies: | |
| 21 21 | 
             
                    version: 0.0.6
         | 
| 22 22 | 
             
              type: :runtime
         | 
| 23 23 | 
             
              prerelease: false
         | 
| 24 | 
            -
              version_requirements: * | 
| 24 | 
            +
              version_requirements: *70229986220740
         | 
| 25 25 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 26 26 | 
             
              name: multi_json
         | 
| 27 | 
            -
              requirement: & | 
| 27 | 
            +
              requirement: &70229986220220 !ruby/object:Gem::Requirement
         | 
| 28 28 | 
             
                none: false
         | 
| 29 29 | 
             
                requirements:
         | 
| 30 30 | 
             
                - - ~>
         | 
| @@ -32,10 +32,10 @@ dependencies: | |
| 32 32 | 
             
                    version: '1.3'
         | 
| 33 33 | 
             
              type: :runtime
         | 
| 34 34 | 
             
              prerelease: false
         | 
| 35 | 
            -
              version_requirements: * | 
| 35 | 
            +
              version_requirements: *70229986220220
         | 
| 36 36 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 37 37 | 
             
              name: rake
         | 
| 38 | 
            -
              requirement: & | 
| 38 | 
            +
              requirement: &70229986219680 !ruby/object:Gem::Requirement
         | 
| 39 39 | 
             
                none: false
         | 
| 40 40 | 
             
                requirements:
         | 
| 41 41 | 
             
                - - ~>
         | 
| @@ -43,10 +43,10 @@ dependencies: | |
| 43 43 | 
             
                    version: '0.9'
         | 
| 44 44 | 
             
              type: :development
         | 
| 45 45 | 
             
              prerelease: false
         | 
| 46 | 
            -
              version_requirements: * | 
| 46 | 
            +
              version_requirements: *70229986219680
         | 
| 47 47 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 48 48 | 
             
              name: racc
         | 
| 49 | 
            -
              requirement: & | 
| 49 | 
            +
              requirement: &70229986219200 !ruby/object:Gem::Requirement
         | 
| 50 50 | 
             
                none: false
         | 
| 51 51 | 
             
                requirements:
         | 
| 52 52 | 
             
                - - ~>
         | 
| @@ -54,10 +54,10 @@ dependencies: | |
| 54 54 | 
             
                    version: '1.4'
         | 
| 55 55 | 
             
              type: :development
         | 
| 56 56 | 
             
              prerelease: false
         | 
| 57 | 
            -
              version_requirements: * | 
| 57 | 
            +
              version_requirements: *70229986219200
         | 
| 58 58 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 59 59 | 
             
              name: rdoc
         | 
| 60 | 
            -
              requirement: & | 
| 60 | 
            +
              requirement: &70229986218720 !ruby/object:Gem::Requirement
         | 
| 61 61 | 
             
                none: false
         | 
| 62 62 | 
             
                requirements:
         | 
| 63 63 | 
             
                - - ~>
         | 
| @@ -65,7 +65,7 @@ dependencies: | |
| 65 65 | 
             
                    version: '3.9'
         | 
| 66 66 | 
             
              type: :development
         | 
| 67 67 | 
             
              prerelease: false
         | 
| 68 | 
            -
              version_requirements: * | 
| 68 | 
            +
              version_requirements: *70229986218720
         | 
| 69 69 | 
             
            description: ! "\t\tBibTeX-Ruby is the Rubyist's swiss-army-knife for all things BibTeX.
         | 
| 70 70 | 
             
              It\n    includes a parser for all common BibTeX objects (@string, @preamble,\n    @comment
         | 
| 71 71 | 
             
              and regular entries) and a sophisticated name parser that\n    tokenizes correctly
         | 
| @@ -180,12 +180,18 @@ required_ruby_version: !ruby/object:Gem::Requirement | |
| 180 180 | 
             
              - - ! '>='
         | 
| 181 181 | 
             
                - !ruby/object:Gem::Version
         | 
| 182 182 | 
             
                  version: '0'
         | 
| 183 | 
            +
                  segments:
         | 
| 184 | 
            +
                  - 0
         | 
| 185 | 
            +
                  hash: -4363834808819370688
         | 
| 183 186 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 184 187 | 
             
              none: false
         | 
| 185 188 | 
             
              requirements:
         | 
| 186 189 | 
             
              - - ! '>='
         | 
| 187 190 | 
             
                - !ruby/object:Gem::Version
         | 
| 188 191 | 
             
                  version: '0'
         | 
| 192 | 
            +
                  segments:
         | 
| 193 | 
            +
                  - 0
         | 
| 194 | 
            +
                  hash: -4363834808819370688
         | 
| 189 195 | 
             
            requirements: []
         | 
| 190 196 | 
             
            rubyforge_project: 
         | 
| 191 197 | 
             
            rubygems_version: 1.8.10
         |