bibtex-ruby 4.4.7 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of bibtex-ruby might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Gemfile +23 -24
- data/History.txt +4 -0
- data/Rakefile +23 -25
- data/bibtex-ruby.gemspec +1 -1
- data/examples/bib2html.rb +5 -6
- data/examples/bib2yaml.rb +2 -2
- data/features/step_definitions/bibtex_steps.rb +3 -6
- data/features/step_definitions/name_steps.rb +1 -2
- data/lib/bibtex.rb +11 -13
- data/lib/bibtex/bibliography.rb +45 -58
- data/lib/bibtex/compatibility.rb +3 -5
- data/lib/bibtex/elements.rb +49 -42
- data/lib/bibtex/entry.rb +80 -84
- data/lib/bibtex/entry/citeproc_converter.rb +47 -52
- data/lib/bibtex/entry/rdf_converter.rb +97 -63
- data/lib/bibtex/error.rb +10 -11
- data/lib/bibtex/extensions.rb +2 -5
- data/lib/bibtex/filters.rb +4 -9
- data/lib/bibtex/filters/latex.rb +0 -2
- data/lib/bibtex/filters/linebreaks.rb +0 -2
- data/lib/bibtex/lexer.rb +81 -81
- data/lib/bibtex/names.rb +24 -28
- data/lib/bibtex/replaceable.rb +15 -17
- data/lib/bibtex/utilities.rb +5 -10
- data/lib/bibtex/value.rb +28 -34
- data/lib/bibtex/version.rb +6 -6
- data/test/benchmark.rb +20 -22
- data/test/bibtex/entry/test_rdf_converter.rb +3 -5
- data/test/bibtex/test_bibliography.rb +22 -35
- data/test/bibtex/test_elements.rb +7 -15
- data/test/bibtex/test_entry.rb +78 -87
- data/test/bibtex/test_filters.rb +8 -7
- data/test/bibtex/test_lexer.rb +10 -13
- data/test/bibtex/test_name_parser.rb +6 -9
- data/test/bibtex/test_names.rb +50 -55
- data/test/bibtex/test_parser.rb +30 -34
- data/test/bibtex/test_string.rb +8 -9
- data/test/bibtex/test_utilities.rb +6 -9
- data/test/bibtex/test_value.rb +41 -43
- data/test/helper.rb +3 -6
- data/test/macruby.rb +12 -13
- data/test/profile.rb +16 -16
- data/test/test_bibtex.rb +10 -15
- data/test/test_export.rb +5 -13
- metadata +4 -4
data/test/bibtex/test_filters.rb
CHANGED
@@ -2,31 +2,32 @@ require 'helper.rb'
|
|
2
2
|
|
3
3
|
module BibTeX
|
4
4
|
class FiltersTest < Minitest::Spec
|
5
|
-
|
6
|
-
it "should Filters should be singleton classes" do
|
5
|
+
it 'should Filters should be singleton classes' do
|
7
6
|
assert_equal false, Filter.respond_to?(:new)
|
8
7
|
assert_equal Filter.instance.object_id, Filter.instance.object_id
|
9
8
|
end
|
10
9
|
|
11
10
|
describe 'Filters.resolve' do
|
12
|
-
it
|
11
|
+
it 'should return the filter if a filter is given' do
|
13
12
|
assert_equal Filter.instance.object_id, Filters.resolve(Filter.instance).object_id
|
14
13
|
end
|
15
14
|
|
16
|
-
it
|
15
|
+
it 'should return the parameter if it quacks like a filter' do
|
17
16
|
f = Object.new
|
18
|
-
def f.apply
|
17
|
+
def f.apply
|
18
|
+
nil
|
19
|
+
end
|
19
20
|
assert_equal f.object_id, Filters.resolve(f).object_id
|
20
21
|
end
|
21
22
|
|
22
|
-
it
|
23
|
+
it 'should return the filter if there is a filter by that name' do
|
23
24
|
class FooBar < Filter; end
|
24
25
|
assert_equal FooBar.instance.object_id, Filters.resolve(:foobar).object_id
|
25
26
|
assert_equal FooBar.instance.object_id, Filters.resolve('foobar').object_id
|
26
27
|
Filter.subclasses.delete(FooBar)
|
27
28
|
end
|
28
29
|
|
29
|
-
it
|
30
|
+
it 'should return nil if there is no filter by that name' do
|
30
31
|
assert_equal nil, Filters.resolve(:foobar)
|
31
32
|
assert_equal nil, Filters.resolve('foobar')
|
32
33
|
assert_equal nil, Filters.resolve(nil)
|
data/test/bibtex/test_lexer.rb
CHANGED
@@ -1,42 +1,39 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
1
|
require 'helper.rb'
|
4
2
|
|
5
3
|
module BibTeX
|
6
4
|
class LexerTest < Minitest::Spec
|
7
|
-
|
8
5
|
it 'correctly scans a string literal' do
|
9
|
-
assert_equal Lexer.new.analyse(
|
6
|
+
assert_equal Lexer.new.analyse('@string{ x = "foo" }').symbols, [:AT, :STRING, :LBRACE, :NAME, :EQ, :STRING_LITERAL, :RBRACE, false]
|
10
7
|
end
|
11
8
|
|
12
9
|
it 'strips line breaks by default' do
|
13
|
-
Lexer.new.analyse(%
|
14
|
-
|
10
|
+
Lexer.new.analyse(%(@string{ x = "foo\nbar" })).stack[-3].must_be :==,
|
11
|
+
[:STRING_LITERAL, 'foo bar']
|
15
12
|
end
|
16
13
|
|
17
14
|
it 'strips whitespace after line breaks by default' do
|
18
|
-
Lexer.new.analyse(%
|
19
|
-
|
15
|
+
Lexer.new.analyse(%(@string{ x = "foo\n bar" })).stack[-3].must_be :==,
|
16
|
+
[:STRING_LITERAL, 'foo bar']
|
20
17
|
end
|
21
18
|
|
22
19
|
it 'matches KEY tokens' do
|
23
|
-
Lexer.new.analyse(
|
20
|
+
Lexer.new.analyse('@misc{foo, }').symbols.must_be :==, [:AT, :NAME, :LBRACE, :KEY, :RBRACE, false]
|
24
21
|
end
|
25
22
|
|
26
23
|
it 'matches KEY tokens with non-ascii characters' do
|
27
|
-
Lexer.new.analyse(
|
24
|
+
Lexer.new.analyse('@misc{löwe, }').symbols.must_be :==, [:AT, :NAME, :LBRACE, :KEY, :RBRACE, false]
|
28
25
|
end
|
29
26
|
|
30
27
|
it 'matches KEY tokens after whitespace' do
|
31
|
-
Lexer.new.analyse(
|
28
|
+
Lexer.new.analyse('@misc{ foo, }').symbols.must_be :==, [:AT, :NAME, :LBRACE, :KEY, :RBRACE, false]
|
32
29
|
end
|
33
30
|
|
34
31
|
it "doesn't start a comment for types starting with but not equal @comment" do
|
35
|
-
Lexer.new.analyse(
|
32
|
+
Lexer.new.analyse('@commentary{staudinger, }').symbols.must_be :==, [:AT, :NAME, :LBRACE, :KEY, :RBRACE, false]
|
36
33
|
end
|
37
34
|
|
38
35
|
it "doesn't start a preamble for types starting with but not equal @preamble" do
|
39
|
-
Lexer.new.analyse(
|
36
|
+
Lexer.new.analyse('@preamblestring{ preamble }').symbols.must_be :==, [:AT, :NAME, :LBRACE, :NAME, :RBRACE, false]
|
40
37
|
end
|
41
38
|
end
|
42
39
|
end
|
@@ -2,7 +2,6 @@ require 'helper'
|
|
2
2
|
|
3
3
|
module BibTeX
|
4
4
|
class NameParserTest < Minitest::Spec
|
5
|
-
|
6
5
|
describe "parse a number of entries having a 'van' or 'van den' name prefix" do
|
7
6
|
before do
|
8
7
|
@a = Names.parse('van den Bout, D. E.')
|
@@ -10,20 +9,18 @@ module BibTeX
|
|
10
9
|
end
|
11
10
|
|
12
11
|
it "should parse 'van den' part starting with lowercase letter" do
|
13
|
-
assert_equal(@a[0].to_s,
|
14
|
-
assert_equal(@a[0].prefix,
|
12
|
+
assert_equal(@a[0].to_s, 'van den Bout, D. E.')
|
13
|
+
assert_equal(@a[0].prefix, 'van den')
|
15
14
|
end
|
16
15
|
|
17
16
|
it "should parse 'Van den' part starting with uppercase letter" do
|
18
|
-
assert_equal(@b[0].to_s,
|
19
|
-
assert_equal(@b[0].prefix,
|
17
|
+
assert_equal(@b[0].to_s, 'Van den Bout, D. E.')
|
18
|
+
assert_equal(@b[0].prefix, 'Van den')
|
20
19
|
end
|
21
20
|
|
22
|
-
it
|
23
|
-
assert_equal '', Names.parse(
|
21
|
+
it 'should accept empty strings' do
|
22
|
+
assert_equal '', Names.parse('').to_s
|
24
23
|
end
|
25
|
-
|
26
24
|
end
|
27
|
-
|
28
25
|
end
|
29
26
|
end
|
data/test/bibtex/test_names.rb
CHANGED
@@ -1,17 +1,14 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
1
|
require 'helper'
|
4
2
|
|
5
3
|
module BibTeX
|
6
4
|
class NamesTest < Minitest::Spec
|
7
|
-
|
8
5
|
before do
|
9
|
-
@poe = Name.new(:
|
6
|
+
@poe = Name.new(first: 'Edgar Allen', last: 'Poe')
|
10
7
|
end
|
11
8
|
|
12
9
|
describe 'string behaviour' do
|
13
10
|
before do
|
14
|
-
@name = Name.new(:
|
11
|
+
@name = Name.new(first: 'Charles Louis Xavier Joseph', prefix: 'de la', last: 'Vallee Poussin', suffix: 'Jr.')
|
15
12
|
end
|
16
13
|
it 'should implement upcase!' do
|
17
14
|
assert_equal 'DE LA VALLEE POUSSIN, JR., CHARLES LOUIS XAVIER JOSEPH', @name.upcase!.to_s
|
@@ -30,7 +27,7 @@ module BibTeX
|
|
30
27
|
end
|
31
28
|
|
32
29
|
it 'accepts the :initials option' do
|
33
|
-
@poe.display_order(:
|
30
|
+
@poe.display_order(initials: true).must_be :==, 'E.A. Poe'
|
34
31
|
end
|
35
32
|
end
|
36
33
|
|
@@ -40,7 +37,7 @@ module BibTeX
|
|
40
37
|
end
|
41
38
|
|
42
39
|
it 'accepts the :initials option' do
|
43
|
-
@poe.sort_order(:
|
40
|
+
@poe.sort_order(initials: true).must_be :==, 'Poe, E.A.'
|
44
41
|
end
|
45
42
|
end
|
46
43
|
|
@@ -64,26 +61,26 @@ module BibTeX
|
|
64
61
|
|
65
62
|
describe '#rename_if' do
|
66
63
|
it 'renames the name to the given attributes if no condition is given' do
|
67
|
-
@poe.rename_if(
|
64
|
+
@poe.rename_if(first: 'E.A.').first.must_equal 'E.A.'
|
68
65
|
end
|
69
66
|
|
70
67
|
it 'renames the name to the given attributes if all conditions match' do
|
71
|
-
@poe.rename_if({ :
|
72
|
-
@poe.rename_if({ :
|
68
|
+
@poe.rename_if({ first: 'E.A.' }, last: @poe.last).first.must_equal 'E.A.'
|
69
|
+
@poe.rename_if({ first: 'E.A.' }, last: @poe.last, first: @poe.first).first.must_equal 'E.A.'
|
73
70
|
end
|
74
71
|
|
75
72
|
it 'renames the name to the given attributes if the block returns true' do
|
76
|
-
@poe.rename_if(
|
73
|
+
@poe.rename_if(first: 'E.A.') { |_n| true }.first.must_equal 'E.A.'
|
77
74
|
end
|
78
75
|
|
79
76
|
it 'does not rename the name to the given attributes if at least one condition does not match' do
|
80
|
-
@poe.rename_if({ :
|
81
|
-
@poe.rename_if({ :
|
82
|
-
@poe.rename_if({ :
|
77
|
+
@poe.rename_if({ first: 'E.A.' }, last: 'foo').first.wont_equal 'E.A.'
|
78
|
+
@poe.rename_if({ first: 'E.A.' }, last: 'foo', first: @poe.first).first.wont_equal 'E.A.'
|
79
|
+
@poe.rename_if({ first: 'E.A.' }, last: @poe.last, first: 'foo').first.wont_equal 'E.A.'
|
83
80
|
end
|
84
81
|
|
85
82
|
it 'does not rename the name to the given attributes if the block returns false' do
|
86
|
-
@poe.rename_if(
|
83
|
+
@poe.rename_if(first: 'E.A.') { |_n| false }.first.wont_equal 'E.A.'
|
87
84
|
end
|
88
85
|
end
|
89
86
|
|
@@ -96,73 +93,71 @@ module BibTeX
|
|
96
93
|
|
97
94
|
it 'merges different names' do
|
98
95
|
n1 = Names.new(@poe)
|
99
|
-
n2 = Names.new(Name.new(:
|
100
|
-
assert_equal "#{@poe
|
96
|
+
n2 = Names.new(Name.new(last: 'Plato'))
|
97
|
+
assert_equal "#{@poe} and Plato", n1.merge!(n2).to_s
|
101
98
|
end
|
102
99
|
end
|
103
100
|
|
104
101
|
describe '#normalize_initials' do
|
105
102
|
it 'returns normalized initials of existing initials only' do
|
106
|
-
Name.new(:
|
107
|
-
Name.new(:
|
108
|
-
Name.new(:
|
109
|
-
Name.new(:
|
110
|
-
Name.new(:
|
111
|
-
Name.new(:
|
103
|
+
Name.new(first: 'Edgar A.', last: 'Poe').normalize_initials.must_equal 'Edgar A.'
|
104
|
+
Name.new(first: 'E.A.', last: 'Poe').normalize_initials.must_equal 'E.A.'
|
105
|
+
Name.new(first: 'E. A.', last: 'Poe').normalize_initials.must_equal 'E.A.'
|
106
|
+
Name.new(first: 'E. A', last: 'Poe').normalize_initials.must_equal 'E.A.'
|
107
|
+
Name.new(first: 'E A', last: 'Poe').normalize_initials.must_equal 'E.A.'
|
108
|
+
Name.new(first: 'Edgar A P', last: 'Poe').normalize_initials.must_equal 'Edgar A.P.'
|
112
109
|
end
|
113
110
|
end
|
114
111
|
|
115
112
|
describe '#extend_initials' do
|
116
113
|
it 'extends the first name if the last name and initials match' do
|
117
|
-
Name.new(:
|
118
|
-
Name.new(:
|
119
|
-
Name.new(:
|
120
|
-
Name.new(:
|
121
|
-
Name.new(:
|
122
|
-
Name.new(:
|
123
|
-
Name.new(:
|
114
|
+
Name.new(first: 'E.A.', last: 'Poe').extend_initials('Edgar Allen', 'Poe').first.must_equal 'Edgar Allen'
|
115
|
+
Name.new(first: 'Edgar A.', last: 'Poe').extend_initials('Edgar Allen', 'Poe').first.must_equal 'Edgar Allen'
|
116
|
+
Name.new(first: 'E. A.', last: 'Poe').extend_initials('Edgar Allen', 'Poe').first.must_equal 'Edgar Allen'
|
117
|
+
Name.new(first: 'E. A', last: 'Poe').extend_initials('Edgar Allen', 'Poe').first.must_equal 'Edgar Allen'
|
118
|
+
Name.new(first: 'E A', last: 'Poe').extend_initials('Edgar Allen', 'Poe').first.must_equal 'Edgar Allen'
|
119
|
+
Name.new(first: 'E. Allen', last: 'Poe').extend_initials('Edgar Allen', 'Poe').first.must_equal 'Edgar Allen'
|
120
|
+
Name.new(first: 'E.A.', last: 'Poe').extend_initials('Edgar A.', 'Poe').first.must_equal 'Edgar A.'
|
124
121
|
|
125
|
-
Name.new(:
|
126
|
-
Name.new(:
|
127
|
-
Name.new(:
|
128
|
-
Name.new(:
|
129
|
-
Name.new(:
|
122
|
+
Name.new(first: 'Edgar-A.', last: 'Poe').extend_initials('Edgar-Allen', 'Poe').first.must_equal 'Edgar-Allen'
|
123
|
+
Name.new(first: 'E.-Allen', last: 'Poe').extend_initials('Edgar-Allen', 'Poe').first.must_equal 'Edgar-Allen'
|
124
|
+
Name.new(first: 'E.-A.', last: 'Poe').extend_initials('Edgar-Allen', 'Poe').first.must_equal 'Edgar-Allen'
|
125
|
+
Name.new(first: 'E.-A', last: 'Poe').extend_initials('Edgar-Allen', 'Poe').first.must_equal 'Edgar-Allen'
|
126
|
+
Name.new(first: 'E-A', last: 'Poe').extend_initials('Edgar-Allen', 'Poe').first.must_equal 'Edgar-Allen'
|
130
127
|
end
|
131
128
|
|
132
129
|
it 'extends the first name if the last name and initials name match with extra middle names' do
|
133
|
-
Name.new(:
|
134
|
-
Name.new(:
|
135
|
-
Name.new(:
|
130
|
+
Name.new(first: 'E.', last: 'Poe').extend_initials('Edgar Allen', 'Poe').first.must_equal 'Edgar Allen'
|
131
|
+
Name.new(first: 'E', last: 'Poe').extend_initials('Edgar Allen', 'Poe').first.must_equal 'Edgar Allen'
|
132
|
+
Name.new(first: 'Edgar', last: 'Poe').extend_initials('Edgar Allen', 'Poe').first.must_equal 'Edgar Allen'
|
136
133
|
|
137
|
-
Name.new(:
|
138
|
-
Name.new(:
|
134
|
+
Name.new(first: 'E.A.', last: 'Poe').extend_initials('Edgar', 'Poe').first.must_equal 'E.A.'
|
135
|
+
Name.new(first: 'A.', last: 'Poe').extend_initials('Edgar', 'Poe').first.must_equal 'A.'
|
139
136
|
end
|
140
137
|
|
141
138
|
it 'does not extend the first name if the last name or initials do not match' do
|
142
|
-
Name.new(:
|
143
|
-
Name.new(:
|
144
|
-
Name.new(:
|
139
|
+
Name.new(first: 'E.A.', last: 'Poe').extend_initials('Edgar Allen', 'Poser').first.wont_equal 'Edgar Allen'
|
140
|
+
Name.new(first: 'E.A.', last: 'Poe').extend_initials('Edgar Ellen', 'Poe').first.wont_equal 'Edgar Ellen'
|
141
|
+
Name.new(first: 'E.R.', last: 'Poe').extend_initials('Edgar Allen', 'Poe').first.wont_equal 'Edgar Allen'
|
145
142
|
end
|
146
143
|
end
|
147
144
|
|
148
|
-
|
145
|
+
describe 'conversions' do
|
149
146
|
class UpcaseAll < BibTeX::Filter
|
150
|
-
def apply
|
147
|
+
def apply(value)
|
151
148
|
value.upcase
|
152
149
|
end
|
153
150
|
end
|
154
151
|
|
155
|
-
describe
|
156
|
-
it
|
157
|
-
|
152
|
+
describe '#convert' do
|
153
|
+
it 'converts the value when given a filter instance' do
|
154
|
+
Names.parse('Poe and Hawthorne').convert(UpcaseAll.instance).to_s.must_be :==, 'POE and HAWTHORNE'
|
158
155
|
end
|
159
156
|
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
157
|
+
it 'converts LaTeX umlauts' do
|
158
|
+
Names.parse("S{\\o}ren Kirkegaard and Emmanuel L\\'evinas").convert(:latex).to_s.must_be :==, 'Kirkegaard, Søren and Lévinas, Emmanuel'
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
166
162
|
end
|
167
|
-
|
168
163
|
end
|
data/test/bibtex/test_parser.rb
CHANGED
@@ -2,10 +2,9 @@ require 'helper.rb'
|
|
2
2
|
|
3
3
|
module BibTeX
|
4
4
|
class ParserTest < Minitest::Spec
|
5
|
-
|
6
5
|
describe 'given a set of valid @entries' do
|
7
6
|
before do
|
8
|
-
@bib = Parser.new(:
|
7
|
+
@bib = Parser.new(debug: false).parse(File.read(Test.fixtures(:entry)))
|
9
8
|
end
|
10
9
|
|
11
10
|
it 'returns a Bibliography instance' do
|
@@ -18,11 +17,11 @@ module BibTeX
|
|
18
17
|
end
|
19
18
|
|
20
19
|
it 'parses the key values' do
|
21
|
-
assert_equal %w
|
20
|
+
assert_equal %w[key:0 key:1 foo staudinger], @bib.map(&:key)
|
22
21
|
end
|
23
22
|
|
24
23
|
it 'should parse the entry types' do
|
25
|
-
assert_equal [
|
24
|
+
assert_equal %i[book article article commentary], @bib.map(&:type)
|
26
25
|
end
|
27
26
|
|
28
27
|
it 'should parse all values correctly' do
|
@@ -35,63 +34,62 @@ module BibTeX
|
|
35
34
|
assert_equal 'American Library', @bib[:'key:0'].publisher
|
36
35
|
assert_equal 'American Library', @bib[:'key:1'].publisher
|
37
36
|
|
38
|
-
assert_equal %q
|
37
|
+
assert_equal %q(Selected \emph{Poetry} and `Tales'), @bib[:'key:0'].title
|
39
38
|
assert_equal 'Tales and Sketches', @bib[:'key:1'].title
|
40
39
|
end
|
41
40
|
end
|
42
41
|
|
43
42
|
describe 'key parsing' do
|
44
43
|
it 'handles whitespace in keys' do
|
45
|
-
input =
|
46
|
-
bib = Parser.new(:
|
47
|
-
assert_equal
|
44
|
+
input = '@Misc{George Martin06,title = {FEAST FOR CROWS}}'
|
45
|
+
bib = Parser.new(debug: false, strict: false).parse(input)
|
46
|
+
assert_equal 'George Martin06', bib.first.key
|
48
47
|
assert bib[:"George Martin06"]
|
49
48
|
end
|
50
49
|
|
51
50
|
it 'handles plus symbols in keys' do
|
52
|
-
input =
|
53
|
-
bib = Parser.new(:
|
54
|
-
assert_equal
|
51
|
+
input = '@Misc{foo+bar,title = {Foobar}}'
|
52
|
+
bib = Parser.new(debug: false, strict: false).parse(input)
|
53
|
+
assert_equal 'foo+bar', bib.first.key
|
55
54
|
assert bib[:"foo+bar"]
|
56
55
|
end
|
57
56
|
|
58
57
|
it 'allows semicolons in keys' do
|
59
|
-
input =
|
60
|
-
bib = Parser.new(:
|
61
|
-
assert_equal
|
58
|
+
input = '@Misc{Gomez;,title = {Foobar}}'
|
59
|
+
bib = Parser.new(debug: false, strict: false).parse(input)
|
60
|
+
assert_equal 'Gomez;', bib.first.key
|
62
61
|
assert bib[:"Gomez;"]
|
63
62
|
end
|
64
63
|
|
65
64
|
it 'allows quotes in keys' do
|
66
|
-
input =
|
67
|
-
bib = Parser.new(:
|
68
|
-
assert_equal %
|
65
|
+
input = %(@Misc{Gomez'1",title = {Foobar}})
|
66
|
+
bib = Parser.new(debug: false, strict: false).parse(input)
|
67
|
+
assert_equal %(Gomez'1"), bib.first.key
|
69
68
|
assert bib[:"Gomez'1\""]
|
70
69
|
end
|
71
70
|
|
72
71
|
it 'fails when there is no cite-key' do
|
73
|
-
input =
|
72
|
+
input = '@misc{title = {Crime and Punishment}}'
|
74
73
|
assert_raises ParseError do
|
75
|
-
Parser.new(:
|
74
|
+
Parser.new(debug: false, strict: false).parse(input)
|
76
75
|
end
|
77
76
|
end
|
78
77
|
|
79
78
|
it 'tolerates missing key with :allow_missing_keys set' do
|
80
|
-
input =
|
81
|
-
assert_equal :misc, Parser.new(
|
82
|
-
:
|
83
|
-
|
79
|
+
input = '@misc{title = {Crime and Punishment}}'
|
80
|
+
assert_equal :misc, Parser.new(
|
81
|
+
debug: false, strict: false, allow_missing_keys: true
|
82
|
+
).parse(input)[0].type
|
84
83
|
end
|
85
84
|
end
|
86
85
|
|
87
86
|
describe 'backslashes and escape sequences' do
|
88
|
-
|
89
87
|
it 'leaves backslashes intact' do
|
90
88
|
Parser.new.parse(%q(@misc{key, title = "a backslash: \"}))[0].title.must_be :==, 'a backslash: \\'
|
91
89
|
end
|
92
90
|
|
93
91
|
it 'parses LaTeX escaped quotes {"}' do
|
94
|
-
Parser.new.parse(
|
92
|
+
Parser.new.parse('@misc{key, title = "{"}"}')[0].title.must_be :==, '{"}'
|
95
93
|
end
|
96
94
|
|
97
95
|
it 'parses complex LaTeX markup' do
|
@@ -110,12 +108,11 @@ module BibTeX
|
|
110
108
|
b.booktitle.must_be :==, "Perception et Intermodalit\\'{e}: Approches Actuelles De La Question De Molyneux"
|
111
109
|
b.editor.to_s.must_be :==, 'Proust, Jo\"{e}lle'
|
112
110
|
end
|
113
|
-
|
114
111
|
end
|
115
112
|
|
116
113
|
describe 'given a set of explicit and implicit comments' do
|
117
114
|
before do
|
118
|
-
@bib = Parser.new(:
|
115
|
+
@bib = Parser.new(debug: false, include: [:meta_content]).parse(File.read(Test.fixtures(:comment)))
|
119
116
|
end
|
120
117
|
|
121
118
|
it 'should parses all @comments' do
|
@@ -128,13 +125,13 @@ module BibTeX
|
|
128
125
|
|
129
126
|
it 'should parse @comment content as string' do
|
130
127
|
assert_equal ' A comment can contain pretty much anything ', @bib.comments[0].content
|
131
|
-
assert_equal %
|
128
|
+
assert_equal %(\n@string{ foo = "bar" }\n\n@string{ bar = "foo" }\n), @bib.comments[1].content
|
132
129
|
end
|
133
130
|
end
|
134
131
|
|
135
132
|
describe 'given a set of @preambles' do
|
136
133
|
before do
|
137
|
-
@bib = Parser.new(:
|
134
|
+
@bib = Parser.new(debug: false).parse(File.read(Test.fixtures(:preamble)))
|
138
135
|
end
|
139
136
|
|
140
137
|
it 'should parse all @preambles' do
|
@@ -150,8 +147,8 @@ module BibTeX
|
|
150
147
|
|
151
148
|
describe 'given an entry containing a multi-line literals' do
|
152
149
|
before do
|
153
|
-
@braces = %
|
154
|
-
@string = %
|
150
|
+
@braces = %(@TechReport{key,\n author = {Donald,\n Duck}\n})
|
151
|
+
@string = %(@TechReport{key,\n author = "Donald,\n Duck"\n})
|
155
152
|
end
|
156
153
|
|
157
154
|
it 'should parse string literals' do
|
@@ -161,18 +158,17 @@ module BibTeX
|
|
161
158
|
it 'should parse braced literals' do
|
162
159
|
refute_nil Parser.new.parse(@braces)[:key]
|
163
160
|
end
|
164
|
-
|
165
161
|
end
|
166
162
|
|
167
163
|
describe 'year values' do
|
168
164
|
it 'parses non-numeric year literals' do
|
169
165
|
assert_equal 'to appear',
|
170
|
-
|
166
|
+
Parser.new.parse('@article{x, year = {to appear}}')['x'].year.to_s
|
171
167
|
end
|
172
168
|
|
173
169
|
it 'parses numeric year literals' do
|
174
170
|
assert_equal 1993,
|
175
|
-
|
171
|
+
Parser.new.parse('@article{x, year = { 1993 }}')['x'].year.to_i
|
176
172
|
end
|
177
173
|
end
|
178
174
|
|