bibtex_parser 1.0.0 → 1.0.1
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.
- 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
|
|