bibtex-ruby 1.2.1 → 1.3.0
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 +6 -1
- data/Gemfile.lock +48 -5
- data/History.txt +16 -1
- data/Manifest +43 -19
- data/README.md +178 -167
- data/Rakefile +26 -5
- data/auto.watchr +6 -0
- data/bibtex-ruby.gemspec +8 -5
- data/examples/bib2html.rb +28 -18
- data/features/bibtex.feature +96 -0
- data/features/entries.feature +67 -0
- data/features/issues/slash_keys.feature +21 -0
- data/features/names.feature +72 -0
- data/features/preambles.feature +27 -0
- data/features/query.feature +56 -0
- data/features/replacement.feature +68 -0
- data/features/step_definitions/bibtex_steps.rb +74 -0
- data/features/step_definitions/name_steps.rb +13 -0
- data/features/strings.feature +52 -0
- data/features/support/env.rb +7 -0
- data/lib/bibtex.rb +5 -1
- data/lib/bibtex/bibliography.rb +218 -95
- data/lib/bibtex/bibtex.y +18 -15
- data/lib/bibtex/elements.rb +130 -136
- data/lib/bibtex/entry.rb +133 -69
- data/lib/bibtex/extensions.rb +0 -35
- data/lib/bibtex/lexer.rb +9 -9
- data/lib/bibtex/name_parser.output +464 -0
- data/lib/bibtex/name_parser.rb +490 -0
- data/lib/bibtex/names.rb +162 -0
- data/lib/bibtex/names.y +196 -0
- data/lib/bibtex/parser.output +5 -5
- data/lib/bibtex/parser.rb +19 -16
- data/lib/bibtex/replaceable.rb +52 -0
- data/lib/bibtex/utilities.rb +23 -5
- data/lib/bibtex/value.rb +201 -0
- data/lib/bibtex/version.rb +1 -1
- data/test/benchmark.rb +52 -0
- data/test/bibtex/test_bibliography.rb +141 -0
- data/test/bibtex/test_elements.rb +40 -0
- data/test/bibtex/test_entry.rb +99 -0
- data/test/bibtex/test_names.rb +23 -0
- data/test/bibtex/test_parser.rb +79 -0
- data/test/bibtex/test_string.rb +83 -0
- data/test/bibtex/test_utilities.rb +34 -0
- data/test/bibtex/test_value.rb +70 -0
- data/test/{bib/10_bibdesk.bib → fixtures/bibdesk.bib} +1 -1
- data/test/{bib/05_comment.bib → fixtures/comment.bib} +0 -0
- data/test/{bib/08_decoret.bib → fixtures/decoret.bib} +0 -0
- data/test/{bib/00_empty.bib → fixtures/empty.bib} +0 -0
- data/test/{bib/07_entry.bib → fixtures/entry.bib} +0 -0
- data/test/{bib/09_errors.bib → fixtures/errors.bib} +0 -0
- data/test/{bib/01_no_bibtex.bib → fixtures/no_bibtex.bib} +0 -0
- data/test/{bib/06_preamble.bib → fixtures/preamble.bib} +1 -1
- data/test/{bib/11_roundtrip.bib → fixtures/roundtrip.bib} +1 -1
- data/test/helper.rb +17 -2
- data/test/test_bibtex.rb +87 -93
- data/test/test_export.rb +18 -22
- metadata +85 -30
- data/test/bib/02_string.bib +0 -1
- data/test/bib/03_string.bib +0 -25
- data/test/bib/04_string_replacement.bib +0 -16
- data/test/test_comment.rb +0 -21
- data/test/test_entry.rb +0 -98
- data/test/test_preamble.rb +0 -39
- data/test/test_string.rb +0 -97
- data/test/test_utilities.rb +0 -36
@@ -0,0 +1,52 @@
|
|
1
|
+
#--
|
2
|
+
# BibTeX-Ruby
|
3
|
+
# Copyright (C) 2010 Sylvester Keil <sylvester.keil.or.at>
|
4
|
+
#
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
#++
|
18
|
+
|
19
|
+
module BibTeX
|
20
|
+
|
21
|
+
#
|
22
|
+
# The Replaceable module provides methods that expose a Value attribute
|
23
|
+
# and the ability to join or replace the contained BibTeX symbols.
|
24
|
+
#
|
25
|
+
module Replaceable
|
26
|
+
extend Forwardable
|
27
|
+
|
28
|
+
attr_reader :value
|
29
|
+
|
30
|
+
def value=(value)
|
31
|
+
@value = Value.new(value)
|
32
|
+
end
|
33
|
+
|
34
|
+
def replace(*arguments)
|
35
|
+
@value.replace(*arguments)
|
36
|
+
self
|
37
|
+
end
|
38
|
+
|
39
|
+
def join
|
40
|
+
@value.join
|
41
|
+
self
|
42
|
+
end
|
43
|
+
|
44
|
+
def <<(value)
|
45
|
+
@value << value
|
46
|
+
self
|
47
|
+
end
|
48
|
+
|
49
|
+
alias :v :value
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
data/lib/bibtex/utilities.rb
CHANGED
@@ -19,20 +19,38 @@
|
|
19
19
|
module BibTeX
|
20
20
|
|
21
21
|
class << self
|
22
|
-
|
23
|
-
|
24
|
-
|
22
|
+
|
23
|
+
# Opens a BibTeX file or URI and returns a corresponding +Bibliography+
|
24
|
+
# object or, if a block is given, yields the Bibliography to the block,
|
25
|
+
# ensuring that the file is saved.
|
26
|
+
def open(file, options = {}, &block)
|
27
|
+
Bibliography.open(file, options, &block)
|
25
28
|
end
|
26
29
|
|
27
30
|
# Parses the given string and returns a corresponding +Bibliography+ object.
|
28
|
-
|
29
|
-
|
31
|
+
# Delegates to BibTeX.open if the string is a filename or URI.
|
32
|
+
def parse(string, options = {}, &block)
|
33
|
+
if File.exists?(string) || string =~ /^[a-z]+:\/\//i
|
34
|
+
open(string, options, &block)
|
35
|
+
else
|
36
|
+
Bibliography.parse(string, options)
|
37
|
+
end
|
30
38
|
end
|
31
39
|
|
32
40
|
# Returns true if the given file is a valid BibTeX bibliography.
|
33
41
|
def valid?(file)
|
34
42
|
Bibliography.open(file).valid?
|
35
43
|
end
|
44
|
+
|
45
|
+
# Parses the given string as a BibTeX name value and returns a Names object.
|
46
|
+
def names(string)
|
47
|
+
Names.parse(string)
|
48
|
+
end
|
49
|
+
|
50
|
+
alias :name :names
|
51
|
+
alias :parse_name :names
|
52
|
+
alias :parse_names :names
|
53
|
+
|
36
54
|
end
|
37
55
|
|
38
56
|
end
|
data/lib/bibtex/value.rb
ADDED
@@ -0,0 +1,201 @@
|
|
1
|
+
#--
|
2
|
+
# BibTeX-Ruby
|
3
|
+
# Copyright (C) 2010-2011 Sylvester Keil <sylvester.keil.or.at>
|
4
|
+
#
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
#++
|
18
|
+
|
19
|
+
require 'forwardable'
|
20
|
+
|
21
|
+
module BibTeX
|
22
|
+
|
23
|
+
#
|
24
|
+
# A BibTeX Value is something very much like a string. In BibTeX files it
|
25
|
+
# can appear on the right hand side of @string or @entry field assignments
|
26
|
+
# or as @preamble contents. In the example below [VALUE] indicates possible
|
27
|
+
# occurences of values in BibTeX:
|
28
|
+
#
|
29
|
+
# @preamble{ "foo" [VALUE] }
|
30
|
+
# @string{ foo = "foo" [VALUE] }
|
31
|
+
# @book{id,
|
32
|
+
# author = {John Doe} [VALUE],
|
33
|
+
# title = foo # "bar" [VALUE]
|
34
|
+
# }
|
35
|
+
#
|
36
|
+
# All Values have in common that they can be simple strings in curly braces
|
37
|
+
# or double quotes or complex BibTeX string-concatenations (using the '#'
|
38
|
+
# symbol).
|
39
|
+
#
|
40
|
+
# Generally, Values try to behave as much as normal Ruby strings as possible;
|
41
|
+
# If you do not require any of the advanced BibTeX functionality (string
|
42
|
+
# replacement or concatentaion) you can simply convert them to strings using
|
43
|
+
# +to_s+. Note that BibTeX Names are special instances of Values which
|
44
|
+
# currently do not support string concatenation or replacement.
|
45
|
+
#
|
46
|
+
class Value
|
47
|
+
extend Forwardable
|
48
|
+
include Comparable
|
49
|
+
|
50
|
+
attr_reader :tokens
|
51
|
+
alias :to_a :tokens
|
52
|
+
|
53
|
+
def_delegators :to_s, :empty?, :=~, :match, :intern, :to_sym, :to_i, :to_f, :end_with?, :start_with?, :include?, :upcase, :downcase, :reverse, :chop, :chomp, :rstrip, :gsub, :sub, :size, :strip, :succ, :to_c, :to_r, :to_str, :split, :each_byte, :each_char, :each_line
|
54
|
+
def_delegators :@tokens, :[], :length
|
55
|
+
|
56
|
+
def initialize(*arguments)
|
57
|
+
@tokens = []
|
58
|
+
arguments.flatten.compact.each do |argument|
|
59
|
+
add(argument)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def initialize_copy(other)
|
64
|
+
@tokens = other.tokens.dup
|
65
|
+
end
|
66
|
+
|
67
|
+
def add(argument)
|
68
|
+
case argument
|
69
|
+
when Value
|
70
|
+
@tokens += argument.tokens.dup
|
71
|
+
when ::String
|
72
|
+
@tokens << argument
|
73
|
+
when Symbol
|
74
|
+
@tokens << argument
|
75
|
+
else
|
76
|
+
raise(ArgumentError, "Failed to create Value from argument #{ argument.inspect }; expected String, Symbol or Value instance.")
|
77
|
+
end
|
78
|
+
self
|
79
|
+
end
|
80
|
+
|
81
|
+
alias :<< :add
|
82
|
+
alias :push :add
|
83
|
+
|
84
|
+
[:strip!, :upcase!, :downcase!, :sub!, :gsub!, :chop!, :chomp!, :rstrip!].each do |method_id|
|
85
|
+
define_method(method_id) do |*arguments, &block|
|
86
|
+
@tokens.each do |part|
|
87
|
+
part.send(method_id, *arguments, &block)
|
88
|
+
end
|
89
|
+
self
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def replace(*arguments)
|
94
|
+
return self unless has_symbol?
|
95
|
+
arguments.flatten.each do |argument|
|
96
|
+
case argument
|
97
|
+
when ::String # simulates Ruby's String#replace
|
98
|
+
@tokens = [argument]
|
99
|
+
when String
|
100
|
+
@tokens = @tokens.map { |v| argument.key == v ? argument.value.tokens : v }.flatten
|
101
|
+
when Hash
|
102
|
+
@tokens = @tokens.map { |v| argument[v] || v }
|
103
|
+
end
|
104
|
+
end
|
105
|
+
self
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
# Returns the Value instance with all consecutive String tokens joined.
|
110
|
+
#
|
111
|
+
# call-seq:
|
112
|
+
# Value.new('foo', 'bar').join #=> <'foobar'>
|
113
|
+
# Value.new(:foo, 'bar').join #=> <:foo, 'bar'>
|
114
|
+
#
|
115
|
+
def join
|
116
|
+
@tokens = @tokens.inject([]) do |a,b|
|
117
|
+
a[-1].is_a?(::String) && b.is_a?(::String) ? a[-1] += b : a << b; a
|
118
|
+
end
|
119
|
+
self
|
120
|
+
end
|
121
|
+
|
122
|
+
# Returns a the Value as a string. @see #value; the only difference is
|
123
|
+
# that single symbols are returned as String, too.
|
124
|
+
# If the Value is atomic and the option :quotes is given, the string
|
125
|
+
# will be quoted using the quote symbols specified.
|
126
|
+
#
|
127
|
+
# call-seq:
|
128
|
+
# Value.new('foo').to_s #=> "foo"
|
129
|
+
# Value.new(:foo).to_s #=> "foo"
|
130
|
+
# Value.new('foo').to_s(:quotes => '"') #=> "\"foo\""
|
131
|
+
# Value.new('foo').to_s(:quotes => ['"','"']) #=> "\"foo\""
|
132
|
+
# Value.new('foo').to_s(:quotes => ['{','}']) #=> "{foo}"
|
133
|
+
# Value.new(:foo, 'bar').to_s #=> "foo # \"bar\""
|
134
|
+
# Value.new('foo', 'bar').to_s #=> "\"foo\" # \"bar\""
|
135
|
+
#
|
136
|
+
def to_s(options = {})
|
137
|
+
return value.to_s unless options.has_key?(:quotes) && atomic?
|
138
|
+
*q = options[:quotes]
|
139
|
+
[q[0], value, q[-1]].compact.join
|
140
|
+
end
|
141
|
+
|
142
|
+
# Returns the Value as a string or, if it consists of a single symbol, as
|
143
|
+
# a Symbol instance. If the Value contains multiple tokens, they will be
|
144
|
+
# joined by a '#', additionally, all string tokens will be turned into
|
145
|
+
# string literals (i.e., delimitted by quotes).
|
146
|
+
def value
|
147
|
+
atomic? ? @tokens[0] : @tokens.map { |v| v.is_a?(::String) ? v.inspect : v }.join(' # ')
|
148
|
+
end
|
149
|
+
|
150
|
+
alias :v :value
|
151
|
+
|
152
|
+
def inspect
|
153
|
+
'<' + @tokens.map(&:inspect).join(', ') + '>'
|
154
|
+
end
|
155
|
+
|
156
|
+
# Returns true if the Value is empty or consists of a single token.
|
157
|
+
def atomic?
|
158
|
+
@tokens.length < 2
|
159
|
+
end
|
160
|
+
|
161
|
+
# Returns true if the Value looks like a BibTeX name value.
|
162
|
+
def name?
|
163
|
+
end
|
164
|
+
|
165
|
+
alias :names? :name?
|
166
|
+
alias :is_name? :name?
|
167
|
+
|
168
|
+
def to_name
|
169
|
+
Names.parse(to_s)
|
170
|
+
end
|
171
|
+
|
172
|
+
alias :to_names :to_name
|
173
|
+
|
174
|
+
|
175
|
+
|
176
|
+
# Returns true if the Value's content is numeric.
|
177
|
+
def numeric?
|
178
|
+
to_s =~ /^\s*[+-]?\d+[\/\.]?\d*\s*$/
|
179
|
+
end
|
180
|
+
|
181
|
+
alias :is_numeric? :numeric?
|
182
|
+
|
183
|
+
# Returns true if the Value contains at least one symbol.
|
184
|
+
def symbol?
|
185
|
+
@tokens.detect { |v| v.is_a?(Symbol) }
|
186
|
+
end
|
187
|
+
|
188
|
+
alias :has_symbol? :symbol?
|
189
|
+
|
190
|
+
# Returns all symbols contained in the Value.
|
191
|
+
def symbols
|
192
|
+
@tokens.select { |v| v.is_a?(Symbol) }
|
193
|
+
end
|
194
|
+
|
195
|
+
def <=>(other)
|
196
|
+
to_s <=> other.to_s
|
197
|
+
end
|
198
|
+
|
199
|
+
end
|
200
|
+
|
201
|
+
end
|
data/lib/bibtex/version.rb
CHANGED
data/test/benchmark.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require File.expand_path('../../lib/bibtex.rb', __FILE__)
|
2
|
+
require 'profile'
|
3
|
+
|
4
|
+
module BibTeX
|
5
|
+
module Benchmark
|
6
|
+
def self.open
|
7
|
+
BibTeX.parse <<-END
|
8
|
+
@book{rails,
|
9
|
+
Address = {Raleigh, North Carolina},
|
10
|
+
Author = {Ruby, Sam, and Thomas, Dave, and Hansson Heinemeier, David},
|
11
|
+
Booktitle = {Agile Web Development with Rails},
|
12
|
+
Date-Added = {2010-08-05 10:01:36 +0200},
|
13
|
+
Date-Modified = {2010-08-05 10:06:46 +0200},
|
14
|
+
Edition = {third},
|
15
|
+
Isbn = {978-1-9343561-6-6},
|
16
|
+
Keywords = {ruby, rails},
|
17
|
+
Publisher = {The Pragmatic Bookshelf},
|
18
|
+
Series = {The Facets of Ruby},
|
19
|
+
Title = {Agile Web Development with Rails},
|
20
|
+
Year = {2009}
|
21
|
+
}
|
22
|
+
|
23
|
+
@book{dragon,
|
24
|
+
Address = {Boston},
|
25
|
+
Author = {Aho, Alfred V., and Lam, Monica S., and Ullman, Jeffrey D.},
|
26
|
+
Booktitle = {Compilers: Principles, Techniques, and Tools},
|
27
|
+
Date-Added = {2010-08-05 09:57:15 +0200},
|
28
|
+
Date-Modified = {2010-08-05 10:06:32 +0200},
|
29
|
+
Edition = {second},
|
30
|
+
Keywords = {compiler, lex, yacc},
|
31
|
+
Publisher = {Addison Wesley},
|
32
|
+
Title = {Compilers: Principles, Techniques, and Tools},
|
33
|
+
Year = {2007}
|
34
|
+
}
|
35
|
+
|
36
|
+
@book{pickaxe,
|
37
|
+
Address = {Raleigh, North Carolina},
|
38
|
+
Author = {Thomas, Dave, and Fowler, Chad, and Hunt, Andy},
|
39
|
+
Date-Added = {2010-08-05 09:54:07 +0200},
|
40
|
+
Date-Modified = {2010-08-05 10:07:01 +0200},
|
41
|
+
Keywords = {ruby},
|
42
|
+
Publisher = {The Pragmatic Bookshelf},
|
43
|
+
Series = {The Facets of Ruby},
|
44
|
+
Title = {Programming Ruby 1.9: The Pragmatic Programmer's Guide},
|
45
|
+
Year = {2009}
|
46
|
+
}
|
47
|
+
END
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
BibTeX::Benchmark.open
|
@@ -0,0 +1,141 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module BibTeX
|
4
|
+
|
5
|
+
class BibliographyTest < MiniTest::Spec
|
6
|
+
|
7
|
+
context 'when newly created' do
|
8
|
+
should 'not be nil' do
|
9
|
+
assert Bibliography.new
|
10
|
+
end
|
11
|
+
should 'be empty' do
|
12
|
+
assert Bibliography.new.empty?
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context '#open' do
|
17
|
+
should 'accept a block and save the file after execution' do
|
18
|
+
tmp = Tempfile.new('bibtex')
|
19
|
+
tmp.close
|
20
|
+
b = BibTeX.open(Test.fixtures(:bibdesk)).save_to(tmp.path)
|
21
|
+
|
22
|
+
BibTeX.open(tmp.path) do |bib|
|
23
|
+
bib.delete(:rails)
|
24
|
+
end
|
25
|
+
|
26
|
+
assert_equal b.length - 1, BibTeX.open(tmp.path).length
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'given a populated biliography' do
|
31
|
+
setup do
|
32
|
+
@bib = BibTeX.parse <<-END
|
33
|
+
@book{rails,
|
34
|
+
address = {Raleigh, North Carolina},
|
35
|
+
author = {Ruby, Sam, and Thomas, Dave, and Hansson Heinemeier, David},
|
36
|
+
booktitle = {Agile Web Development with Rails},
|
37
|
+
edition = {third},
|
38
|
+
keywords = {ruby, rails},
|
39
|
+
publisher = {The Pragmatic Bookshelf},
|
40
|
+
series = {The Facets of Ruby},
|
41
|
+
title = {Agile Web Development with Rails},
|
42
|
+
year = {2009}
|
43
|
+
}
|
44
|
+
@book{flanagan2008,
|
45
|
+
title={{The ruby programming language}},
|
46
|
+
author={Flanagan, D. and Matsumoto, Y.},
|
47
|
+
keywords = {ruby},
|
48
|
+
year={2008},
|
49
|
+
publisher={O'Reilly}
|
50
|
+
}
|
51
|
+
@article{segaran2007,
|
52
|
+
title={{Programming collective intelligence}},
|
53
|
+
author={Segaran, T.},
|
54
|
+
year={2007},
|
55
|
+
publisher={O'Reilly}
|
56
|
+
}
|
57
|
+
END
|
58
|
+
end
|
59
|
+
|
60
|
+
should 'support access by index' do
|
61
|
+
assert_equal 'ruby', @bib[1].keywords
|
62
|
+
end
|
63
|
+
|
64
|
+
should 'support access by range' do
|
65
|
+
assert_equal %w{2008 2007}, @bib[1..2].map(&:year)
|
66
|
+
end
|
67
|
+
|
68
|
+
should 'support access by index and offset' do
|
69
|
+
assert_equal %w{2008 2007}, @bib[1,2].map(&:year)
|
70
|
+
end
|
71
|
+
|
72
|
+
should 'support queries by symbol key' do
|
73
|
+
refute_nil @bib[:rails]
|
74
|
+
assert_nil @bib[:ruby]
|
75
|
+
end
|
76
|
+
|
77
|
+
should 'support queries by symbol key and selector' do
|
78
|
+
assert_equal 1, @bib.q(:all, :rails).length
|
79
|
+
refute_nil @bib.q(:first, :rails)
|
80
|
+
assert_nil @bib.q(:first, :railss)
|
81
|
+
end
|
82
|
+
|
83
|
+
should 'support queries by string key' do
|
84
|
+
assert_equal 1, @bib['rails'].length
|
85
|
+
assert_equal 0, @bib['ruby'].length
|
86
|
+
end
|
87
|
+
|
88
|
+
should 'support queries by type string' do
|
89
|
+
assert_equal 2, @bib['@book'].length
|
90
|
+
assert_equal 1, @bib['@article'].length
|
91
|
+
assert_equal 0, @bib['@collection'].length
|
92
|
+
end
|
93
|
+
|
94
|
+
should 'support queries by type string and selector' do
|
95
|
+
assert_equal 2, @bib.q(:all, '@book').length
|
96
|
+
refute_nil @bib.q(:first, '@book')
|
97
|
+
assert_equal 1, @bib.q(:all, '@article').length
|
98
|
+
refute_nil @bib.q(:first, '@article')
|
99
|
+
assert_equal 0, @bib.q(:all, '@collection').length
|
100
|
+
assert_nil @bib.q(:first, '@collection')
|
101
|
+
end
|
102
|
+
|
103
|
+
|
104
|
+
should 'support queries by pattern' do
|
105
|
+
assert_equal 0, @bib[/reilly/].length
|
106
|
+
assert_equal 2, @bib[/reilly/i].length
|
107
|
+
end
|
108
|
+
|
109
|
+
should 'support queries by type string and conditions' do
|
110
|
+
assert_equal 1, @bib['@book[keywords=ruby]'].length
|
111
|
+
end
|
112
|
+
|
113
|
+
should 'support queries by bibtex element' do
|
114
|
+
entry = Entry.parse(<<-END).first
|
115
|
+
@article{segaran2007,
|
116
|
+
title = {{Programming collective intelligence}},
|
117
|
+
author = {Segaran, T.},
|
118
|
+
year = {2007},
|
119
|
+
publisher = {O'Reilly}
|
120
|
+
}
|
121
|
+
END
|
122
|
+
assert_equal 1, @bib[entry].length
|
123
|
+
entry.year = '2006'
|
124
|
+
assert_equal 0, @bib[entry].length
|
125
|
+
end
|
126
|
+
|
127
|
+
should 'support query and additional block' do
|
128
|
+
assert_equal 1, @bib.q('@book') { |e| e.keywords.split(/,/).length > 1 }.length
|
129
|
+
end
|
130
|
+
|
131
|
+
should 'support saving the bibliography to a file' do
|
132
|
+
tmp = Tempfile.new('bibtex')
|
133
|
+
tmp.close
|
134
|
+
@bib.save_to(tmp.path)
|
135
|
+
assert_equal @bib, BibTeX.open(tmp.path)
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
141
|
+
end
|