bibtex_parser 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +6 -0
- data/README +31 -6
- data/Rakefile +1 -1
- data/lib/bibtex_author.rb +41 -37
- data/lib/bibtex_entry.rb +135 -131
- data/lib/bibtex_parser.rb +97 -55
- metadata +3 -3
data/CHANGELOG
CHANGED
data/README
CHANGED
@@ -20,12 +20,37 @@ license. Please see LICENSE for more details
|
|
20
20
|
|
21
21
|
== Parsing a BibTeX File
|
22
22
|
|
23
|
-
A BibTeX file can be parsed using the
|
23
|
+
A BibTeX file can be parsed using the BibTeX::Parser class:
|
24
24
|
|
25
25
|
require 'rubygems'
|
26
26
|
require 'bibtex_parser'
|
27
27
|
|
28
|
-
entries =
|
28
|
+
entries = BibTeX::Parser.parse_bibtex_file('thesis.bib')
|
29
|
+
|
30
|
+
entries.each do |entry|
|
31
|
+
puts entry.title
|
32
|
+
puts entry.year
|
33
|
+
end
|
34
|
+
|
35
|
+
== Parsing a BibTeX string
|
36
|
+
|
37
|
+
A string containing BibTeX content can be parse BibTeX file can also be parsed
|
38
|
+
using the BibTeX::Parser class:
|
39
|
+
|
40
|
+
require 'rubygems'
|
41
|
+
require 'bibtex_parser'
|
42
|
+
|
43
|
+
bibtex =<<EOF
|
44
|
+
|
45
|
+
@inproceedings{shantz:2009,
|
46
|
+
author = "Jeffrey Shantz",
|
47
|
+
title = "BibTeX::Parser",
|
48
|
+
year = "2009"
|
49
|
+
}
|
50
|
+
|
51
|
+
EOF
|
52
|
+
|
53
|
+
entries = BibTeX::Parser.parse_bibtex(bibtex)
|
29
54
|
|
30
55
|
entries.each do |entry|
|
31
56
|
puts entry.title
|
@@ -40,7 +65,7 @@ name to get or set, or simply use "dot" notation, as shown below:
|
|
40
65
|
require 'rubygems'
|
41
66
|
require 'bibtex_parser'
|
42
67
|
|
43
|
-
entries =
|
68
|
+
entries = BibTeX::Parser.parse_bibtex_file('thesis.bib')
|
44
69
|
entry = entries[0]
|
45
70
|
|
46
71
|
entry.year = 2010
|
@@ -52,7 +77,7 @@ name to get or set, or simply use "dot" notation, as shown below:
|
|
52
77
|
== Getting author data
|
53
78
|
|
54
79
|
Authors (or editors) are stored under the 'author' key as an array of
|
55
|
-
|
80
|
+
BibTeX::Author objects. A BibTeX::Author contains an author's name parsed into
|
56
81
|
First, Middle, and Last parts. Unlike other BibTeX parsers currently in
|
57
82
|
existence, this parser does not extract "von" and "jr" parts of names. This
|
58
83
|
may be implemented in the future, should demand arise.
|
@@ -60,7 +85,7 @@ may be implemented in the future, should demand arise.
|
|
60
85
|
require 'rubygems'
|
61
86
|
require 'bibtex_parser'
|
62
87
|
|
63
|
-
entries =
|
88
|
+
entries = BibTeX::Parser.parse_bibtex_file('thesis.bib')
|
64
89
|
entry = entries[0]
|
65
90
|
first_author = entry.authors[0]
|
66
91
|
|
@@ -76,7 +101,7 @@ whether or not a citation is valid and, if not, why it is failing.
|
|
76
101
|
require 'rubygems'
|
77
102
|
require 'bibtex_parser'
|
78
103
|
|
79
|
-
entries =
|
104
|
+
entries = BibTeX::Parser.parse_bibtex_file('thesis.bib')
|
80
105
|
entry = entries[0]
|
81
106
|
|
82
107
|
unless (entry.valid?)
|
data/Rakefile
CHANGED
@@ -8,7 +8,7 @@ require 'spec/rake/spectask'
|
|
8
8
|
|
9
9
|
spec = Gem::Specification.new do |s|
|
10
10
|
s.name = 'bibtex_parser'
|
11
|
-
s.version = '1.0.
|
11
|
+
s.version = '1.0.1'
|
12
12
|
s.has_rdoc = true
|
13
13
|
s.extra_rdoc_files = ['README', 'LICENSE','CHANGELOG']
|
14
14
|
s.summary = 'A parser for the BibTeX citation format'
|
data/lib/bibtex_author.rb
CHANGED
@@ -4,47 +4,51 @@
|
|
4
4
|
#
|
5
5
|
# Licensed under the MIT license -- see LICENSE for more details
|
6
6
|
|
7
|
-
|
7
|
+
module BibTeX
|
8
8
|
|
9
|
-
|
9
|
+
class Author
|
10
|
+
|
11
|
+
attr_accessor :first_name, :last_name, :middle_name, :raw_name
|
10
12
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
13
|
+
def initialize(name)
|
14
|
+
@raw_name = name.strip
|
15
|
+
parse
|
16
|
+
end
|
15
17
|
|
16
|
-
|
18
|
+
def parse
|
17
19
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
20
|
+
if @raw_name =~ /^([\w.-]+)\s*(?:(\w\.))?\s*([\w.-]+)$/ # First M. Last
|
21
|
+
@first_name = $1
|
22
|
+
@last_name = $3
|
23
|
+
@middle_name = $2 unless $2.nil?
|
24
|
+
elsif @raw_name =~ /^([\w.-]+)\s*,\s*([\w.-]+)\s*(?:([\w]\.)?)$/ # Last, First M.
|
25
|
+
@first_name = $2
|
26
|
+
@last_name = $1
|
27
|
+
@middle_name = $3 unless $3.nil?
|
28
|
+
elsif @raw_name.index(",") # De Last, First
|
29
|
+
parts = @raw_name.split(/\s*,\s*/)
|
30
|
+
@last_name = parts[0]
|
31
|
+
@first_name = parts[1]
|
32
|
+
@middle_name = nil
|
33
|
+
else # First De Last
|
34
|
+
parts = @raw_name.split(/\s+/)
|
35
|
+
@first_name = parts.shift
|
36
|
+
@last_name = parts.join(" ")
|
37
|
+
@middle_name = nil
|
38
|
+
end
|
37
39
|
|
38
|
-
|
40
|
+
end
|
39
41
|
|
40
|
-
# def inspect
|
41
|
-
#
|
42
|
-
# s = ""
|
43
|
-
# s += "\t\tFIRST : #{@first_name}\n"
|
44
|
-
# s += "\t\tMIDDLE : #{@middle_name}\n"
|
45
|
-
# s += "\t\tLAST : #{@last_name}\n"
|
46
|
-
#
|
47
|
-
# return s
|
48
|
-
#
|
49
|
-
# end
|
42
|
+
# def inspect
|
43
|
+
#
|
44
|
+
# s = ""
|
45
|
+
# s += "\t\tFIRST : #{@first_name}\n"
|
46
|
+
# s += "\t\tMIDDLE : #{@middle_name}\n"
|
47
|
+
# s += "\t\tLAST : #{@last_name}\n"
|
48
|
+
#
|
49
|
+
# return s
|
50
|
+
#
|
51
|
+
# end
|
52
|
+
end
|
53
|
+
|
50
54
|
end
|
data/lib/bibtex_entry.rb
CHANGED
@@ -6,177 +6,181 @@ require 'bibtex_author'
|
|
6
6
|
#
|
7
7
|
# Licensed under the MIT license -- see LICENSE for more details
|
8
8
|
|
9
|
-
|
9
|
+
module BibTeX
|
10
10
|
|
11
|
-
|
11
|
+
class Entry
|
12
|
+
|
13
|
+
attr_accessor :raw_bibtex, :valid, :type, :key, :errors, :authors
|
12
14
|
|
13
|
-
|
15
|
+
def initialize(block)
|
14
16
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
@raw_bibtex = block
|
18
|
+
@valid = true
|
19
|
+
@fields = {}
|
20
|
+
@authors = []
|
21
|
+
@errors = []
|
22
|
+
self.parse
|
21
23
|
|
22
|
-
|
24
|
+
end
|
23
25
|
|
24
|
-
|
25
|
-
|
26
|
-
|
26
|
+
def valid?
|
27
|
+
@valid
|
28
|
+
end
|
27
29
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
30
|
+
def [](key)
|
31
|
+
key = key.strip.downcase.to_sym if (key.is_a?(String))
|
32
|
+
@fields[key]
|
33
|
+
end
|
32
34
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
35
|
+
def []=(key, value)
|
36
|
+
key = key.strip.downcase.to_sym if (key.is_a?(String))
|
37
|
+
@fields[key] = value
|
38
|
+
end
|
37
39
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
40
|
+
def has_key?(key)
|
41
|
+
key = key.strip.downcase.to_sym if (key.is_a?(String))
|
42
|
+
@fields.has_key?(key)
|
43
|
+
end
|
42
44
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
45
|
+
def parse
|
46
|
+
@valid = true
|
47
|
+
@errors = []
|
48
|
+
@raw_bibtex.strip!
|
49
|
+
@parsed = @raw_bibtex
|
48
50
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
51
|
+
return unless parse_type
|
52
|
+
return unless parse_key
|
53
|
+
parse_fields
|
54
|
+
parse_authors
|
53
55
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
56
|
+
if ((! self.has_key?(:year)) || (self[:year].eql?("")))
|
57
|
+
@errors << "Missing year field"
|
58
|
+
@valid = false
|
59
|
+
end
|
58
60
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
61
|
+
if ((! self.has_key?(:title)) || (self[:title].eql?("")))
|
62
|
+
@errors << "Missing title field"
|
63
|
+
@valid = false
|
64
|
+
end
|
63
65
|
|
64
|
-
|
66
|
+
end
|
65
67
|
|
66
|
-
# def inspect
|
67
|
-
#
|
68
|
-
# s = "TYPE: #{@type}\n"
|
69
|
-
# s += "KEY: #{@key}\n"
|
70
|
-
# s += "FIELDS [#{@fields.size}]: \n"
|
71
|
-
# s += "VALID: #{@valid}\n"
|
72
|
-
#
|
73
|
-
# @fields.each do |k,v|
|
74
|
-
# s += "\t#{k}\t=> #{v}\n"
|
75
|
-
# end
|
76
|
-
#
|
77
|
-
# s += "AUTHORS [#{@authors.size}]: \n"
|
78
|
-
# @authors.each do |author|
|
79
|
-
# s+= author.inspect
|
80
|
-
# end
|
81
|
-
# s += "\n\n#{@parsed}"
|
82
|
-
#
|
83
|
-
# s += "ERRORS [#{@errors.size}]: \n"
|
84
|
-
# @errors.each do |error|
|
85
|
-
# s+= "\t\t#{error}\n"
|
86
|
-
# end
|
87
|
-
#
|
88
|
-
# return s
|
89
|
-
#
|
90
|
-
# end
|
91
|
-
|
92
|
-
|
68
|
+
# def inspect
|
69
|
+
#
|
70
|
+
# s = "TYPE: #{@type}\n"
|
71
|
+
# s += "KEY: #{@key}\n"
|
72
|
+
# s += "FIELDS [#{@fields.size}]: \n"
|
73
|
+
# s += "VALID: #{@valid}\n"
|
74
|
+
#
|
75
|
+
# @fields.each do |k,v|
|
76
|
+
# s += "\t#{k}\t=> #{v}\n"
|
77
|
+
# end
|
78
|
+
#
|
79
|
+
# s += "AUTHORS [#{@authors.size}]: \n"
|
80
|
+
# @authors.each do |author|
|
81
|
+
# s+= author.inspect
|
82
|
+
# end
|
83
|
+
# s += "\n\n#{@parsed}"
|
84
|
+
#
|
85
|
+
# s += "ERRORS [#{@errors.size}]: \n"
|
86
|
+
# @errors.each do |error|
|
87
|
+
# s+= "\t\t#{error}\n"
|
88
|
+
# end
|
89
|
+
#
|
90
|
+
# return s
|
91
|
+
#
|
92
|
+
# end
|
93
|
+
|
94
|
+
def method_missing(sym, *arguments)
|
93
95
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
96
|
+
if (sym.to_s =~ /=$/)
|
97
|
+
self.send(:[]=, sym.to_s.chop, *arguments)
|
98
|
+
else
|
99
|
+
self.send(:[], sym)
|
100
|
+
end
|
99
101
|
|
100
|
-
|
102
|
+
end
|
101
103
|
|
102
104
|
|
103
|
-
|
105
|
+
private
|
104
106
|
|
105
|
-
|
107
|
+
def parse_type
|
108
|
+
|
109
|
+
if (@parsed =~ /^(\s*@([[:alpha:]]+)\s*\{)/)
|
110
|
+
@type = $2
|
111
|
+
@parsed = @parsed[$1.length..-1]
|
112
|
+
@valid = true
|
113
|
+
else
|
114
|
+
@errors << "Missing citation type"
|
115
|
+
@valid = false
|
116
|
+
end
|
106
117
|
|
107
|
-
if (@parsed =~ /^(\s*@([[:alpha:]]+)\s*\{)/)
|
108
|
-
@type = $2
|
109
|
-
@parsed = @parsed[$1.length..-1]
|
110
|
-
@valid = true
|
111
|
-
else
|
112
|
-
@errors << "Missing citation type"
|
113
|
-
@valid = false
|
114
118
|
end
|
115
119
|
|
116
|
-
|
120
|
+
def parse_key
|
117
121
|
|
118
|
-
|
122
|
+
idx = @parsed.index(",")
|
119
123
|
|
120
|
-
|
124
|
+
if (idx)
|
121
125
|
|
122
|
-
|
126
|
+
key = @parsed[0...idx].strip
|
123
127
|
|
124
|
-
|
128
|
+
# Quick sanity check to ensure the user specified a key -- don't
|
129
|
+
# want to treat a "KEY = VALUE," pair as the key simply because
|
130
|
+
# there's a comma after the pair
|
131
|
+
if (key =~ /=/)
|
132
|
+
@errors << "Missing citation key"
|
133
|
+
@valid = false
|
125
134
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
135
|
+
else
|
136
|
+
@key = key
|
137
|
+
@parsed = @parsed[idx+1..-1]
|
138
|
+
end
|
139
|
+
else
|
130
140
|
@errors << "Missing citation key"
|
131
141
|
@valid = false
|
132
|
-
|
133
|
-
else
|
134
|
-
@key = key
|
135
|
-
@parsed = @parsed[idx+1..-1]
|
136
142
|
end
|
137
|
-
else
|
138
|
-
@errors << "Missing citation key"
|
139
|
-
@valid = false
|
140
143
|
end
|
141
|
-
end
|
142
144
|
|
143
|
-
|
145
|
+
def parse_fields
|
144
146
|
|
145
|
-
|
147
|
+
pairs = @parsed.scan(/(\s*[[:alpha:]]+\s*=\s*(?:\{.*\}|".*"))/)
|
146
148
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
149
|
+
pairs.each do |pair|
|
150
|
+
parts = pair[0].split("=")
|
151
|
+
key = parts[0].strip.downcase
|
152
|
+
value = parts[1].strip
|
153
|
+
value.sub!(/^\{(.*)\}$/,"\\1") if value
|
154
|
+
value.sub!(/^"(.*)"$/,"\\1") if value
|
155
|
+
self[key] = value.strip
|
156
|
+
end
|
155
157
|
|
156
|
-
|
158
|
+
end
|
157
159
|
|
158
|
-
|
160
|
+
def parse_authors
|
159
161
|
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
162
|
+
unless ((self.has_key?(:author)) || (self.has_key?(:editor)))
|
163
|
+
@errors << "Missing author or editor field"
|
164
|
+
@valid = false
|
165
|
+
return
|
166
|
+
end
|
165
167
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
168
|
+
if ((self.has_key?(:author)) && (self[:author].length > 0))
|
169
|
+
authors = self[:author]
|
170
|
+
elsif ((self.has_key?(:editor)) && (self[:editor].length > 0))
|
171
|
+
authors = self[:editor]
|
172
|
+
else
|
173
|
+
@errors << "Missing author or editor field"
|
174
|
+
@valid = false
|
175
|
+
return
|
176
|
+
end
|
175
177
|
|
176
|
-
|
178
|
+
author_list = authors.split(/\s+and\s+/)
|
177
179
|
|
178
|
-
|
179
|
-
|
180
|
+
author_list.each do |author_name|
|
181
|
+
@authors << BibTeX::Author.new(author_name)
|
182
|
+
end
|
183
|
+
|
180
184
|
end
|
181
185
|
|
182
186
|
end
|
data/lib/bibtex_parser.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'bibtex_entry'
|
2
|
+
require 'stringio'
|
2
3
|
|
3
4
|
# = BibTeXParser - Simple BibTeX parsing
|
4
5
|
#
|
@@ -27,7 +28,32 @@ require 'bibtex_entry'
|
|
27
28
|
# require 'rubygems'
|
28
29
|
# require 'bibtex_parser'
|
29
30
|
#
|
30
|
-
# entries =
|
31
|
+
# entries = BibTeX::Parser.parse_bibtex_file('thesis.bib')
|
32
|
+
#
|
33
|
+
# entries.each do |entry|
|
34
|
+
# puts entry.title
|
35
|
+
# puts entry.year
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# == Parsing a BibTeX string
|
39
|
+
#
|
40
|
+
# A string containing BibTeX content can be parse BibTeX file can also be parsed
|
41
|
+
# using the BibTeX::Parser class:
|
42
|
+
#
|
43
|
+
# require 'rubygems'
|
44
|
+
# require 'bibtex_parser'
|
45
|
+
#
|
46
|
+
# bibtex =<<EOF
|
47
|
+
#
|
48
|
+
# @inproceedings{shantz:2009,
|
49
|
+
# author = "Jeffrey Shantz",
|
50
|
+
# title = "BibTeX::Parser",
|
51
|
+
# year = "2009"
|
52
|
+
# }
|
53
|
+
#
|
54
|
+
# EOF
|
55
|
+
#
|
56
|
+
# entries = BibTeX::Parser.parse_bibtex(bibtex)
|
31
57
|
#
|
32
58
|
# entries.each do |entry|
|
33
59
|
# puts entry.title
|
@@ -42,7 +68,7 @@ require 'bibtex_entry'
|
|
42
68
|
# require 'rubygems'
|
43
69
|
# require 'bibtex_parser'
|
44
70
|
#
|
45
|
-
# entries =
|
71
|
+
# entries = BibTeX::Parser.parse_bibtex_file('thesis.bib')
|
46
72
|
# entry = entries[0]
|
47
73
|
#
|
48
74
|
# entry.year = 2010
|
@@ -54,8 +80,8 @@ require 'bibtex_entry'
|
|
54
80
|
# == Getting author data
|
55
81
|
#
|
56
82
|
# Authors (or editors) are stored under the 'author' key as an array of
|
57
|
-
#
|
58
|
-
# First, Middle, and Last parts. Unlike other BibTeX parsers currently in
|
83
|
+
# BibTeX::Author objects. A BibTeX::Author contains an author's name parsed
|
84
|
+
# into First, Middle, and Last parts. Unlike other BibTeX parsers currently in
|
59
85
|
# existence, this parser does not extract "von" and "jr" parts of names. This
|
60
86
|
# may be implemented in the future, should demand arise.
|
61
87
|
#
|
@@ -78,7 +104,7 @@ require 'bibtex_entry'
|
|
78
104
|
# require 'rubygems'
|
79
105
|
# require 'bibtex_parser'
|
80
106
|
#
|
81
|
-
# entries =
|
107
|
+
# entries = BibTeX::Parser.parse_bibtex_file('thesis.bib')
|
82
108
|
# entry = entries[0]
|
83
109
|
#
|
84
110
|
# unless (entry.valid?)
|
@@ -89,7 +115,7 @@ require 'bibtex_entry'
|
|
89
115
|
#
|
90
116
|
# == Special entry attributes
|
91
117
|
#
|
92
|
-
# The following attributes of the
|
118
|
+
# The following attributes of the BibTex::Entry class may be of interest to you:
|
93
119
|
#
|
94
120
|
# * raw_bibtex - Returns the raw BibTeX citation from which the entry was
|
95
121
|
# created
|
@@ -108,60 +134,56 @@ require 'bibtex_entry'
|
|
108
134
|
#
|
109
135
|
# Send bug reports to: x@y, where x is equal to jshantz4, and y = csd.uwo.ca
|
110
136
|
|
111
|
-
|
137
|
+
module BibTeX
|
112
138
|
|
113
|
-
|
139
|
+
class Parser
|
114
140
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
while (!f.eof?)
|
120
|
-
line = f.gets
|
121
|
-
|
122
|
-
if ((line =~ /^\s*@[[:alpha:]]+/) && (line !~ /@(string|preamble)/i))
|
123
|
-
blocks << extract_block(f,line)
|
124
|
-
end
|
141
|
+
def Parser.parse_bibtex(bibtex_string)
|
142
|
+
|
143
|
+
stream = StringIO.new(bibtex_string)
|
144
|
+
return parse_stream(stream)
|
125
145
|
|
126
146
|
end
|
127
|
-
|
128
|
-
blocks.each do |block|
|
129
|
-
entries << BibTeXEntry.new(block)
|
130
|
-
end
|
131
147
|
|
132
|
-
|
148
|
+
def Parser.parse_bibtex_file(filename)
|
149
|
+
|
150
|
+
f = File.open(filename)
|
151
|
+
return parse_stream(f)
|
133
152
|
|
134
|
-
|
153
|
+
end
|
154
|
+
|
155
|
+
def Parser.parse_stream(stream)
|
156
|
+
|
157
|
+
blocks = []
|
158
|
+
entries = []
|
159
|
+
|
160
|
+
while (!stream.eof?)
|
161
|
+
line = stream.gets
|
135
162
|
|
136
|
-
|
163
|
+
if ((line =~ /^\s*@[[:alpha:]]+/) && (line !~ /@(string|preamble)/i))
|
164
|
+
blocks << extract_block(stream,line)
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
168
|
+
|
169
|
+
blocks.each do |block|
|
170
|
+
entries << BibTeX::Entry.new(block)
|
171
|
+
end
|
172
|
+
|
173
|
+
return entries
|
174
|
+
|
175
|
+
end
|
176
|
+
|
177
|
+
private
|
137
178
|
|
138
|
-
|
179
|
+
def Parser.extract_block(f, start_line)
|
139
180
|
|
140
|
-
|
141
|
-
|
142
|
-
|
181
|
+
stack = []
|
182
|
+
first_brace_seen = false
|
183
|
+
block = ""
|
143
184
|
|
144
|
-
|
185
|
+
start_line.each_char do |c|
|
145
186
|
|
146
|
-
block += c
|
147
|
-
|
148
|
-
if (c.eql?("{"))
|
149
|
-
stack.push("{")
|
150
|
-
first_brace_seen = true
|
151
|
-
elsif (c.eql?("}"))
|
152
|
-
stack.pop()
|
153
|
-
end
|
154
|
-
|
155
|
-
return block if ((first_brace_seen) && (stack.length == 0))
|
156
|
-
|
157
|
-
end
|
158
|
-
|
159
|
-
while (((first_brace_seen) ^ (stack.length == 0)) && (!f.eof?))
|
160
|
-
|
161
|
-
line = f.gets
|
162
|
-
|
163
|
-
line.each_char do |c|
|
164
|
-
|
165
187
|
block += c
|
166
188
|
|
167
189
|
if (c.eql?("{"))
|
@@ -169,19 +191,39 @@ class BibTeXParser
|
|
169
191
|
first_brace_seen = true
|
170
192
|
elsif (c.eql?("}"))
|
171
193
|
stack.pop()
|
172
|
-
end
|
194
|
+
end
|
195
|
+
|
196
|
+
return block if ((first_brace_seen) && (stack.length == 0))
|
173
197
|
|
174
|
-
break if ((first_brace_seen) && (stack.length == 0))
|
175
198
|
end
|
199
|
+
|
200
|
+
while (((first_brace_seen) ^ (stack.length == 0)) && (!f.eof?))
|
201
|
+
|
202
|
+
line = f.gets
|
176
203
|
|
177
|
-
|
204
|
+
line.each_char do |c|
|
205
|
+
|
206
|
+
block += c
|
207
|
+
|
208
|
+
if (c.eql?("{"))
|
209
|
+
stack.push("{")
|
210
|
+
first_brace_seen = true
|
211
|
+
elsif (c.eql?("}"))
|
212
|
+
stack.pop()
|
213
|
+
end
|
214
|
+
|
215
|
+
break if ((first_brace_seen) && (stack.length == 0))
|
216
|
+
end
|
217
|
+
|
218
|
+
end
|
178
219
|
|
179
|
-
|
220
|
+
return block
|
180
221
|
|
181
|
-
|
222
|
+
end
|
182
223
|
|
183
|
-
end
|
224
|
+
end
|
184
225
|
|
226
|
+
end
|
185
227
|
#entries = BibTeXParser.parse_bibtex_file('cs9544a_project.bib')
|
186
228
|
#entries = BibTeXParser.parse_bibtex_file('test.bib')
|
187
229
|
#entries.each do |entry|
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 1
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 1.0.
|
8
|
+
- 1
|
9
|
+
version: 1.0.1
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Jeff Shantz
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-03-
|
17
|
+
date: 2010-03-08 00:00:00 -05:00
|
18
18
|
default_executable:
|
19
19
|
dependencies: []
|
20
20
|
|