rbibtex 0.0.1 → 0.0.2
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 +9 -0
- data/InstalledFiles +2 -0
- data/README +4 -0
- data/bin/rbib2bib +116 -45
- data/bin/rbib2html +1 -1
- data/bin/rbib2txt +1 -1
- data/lib/rbibtex/rbibtex.y +67 -29
- data/papers.bib +9 -2
- data/test.bib +5 -0
- metadata +3 -1
data/CHANGELOG
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
0.0.2
|
2
|
+
* Simplified Grammar a bit
|
3
|
+
* Now parsing @comment correctly
|
4
|
+
* Made rbib2bib actually usefull.
|
5
|
+
* Sorting of entries
|
6
|
+
* Sorting of fields
|
7
|
+
* A help
|
8
|
+
* Nicer output respecting formatting.
|
9
|
+
|
1
10
|
0.0.1
|
2
11
|
* Removed unneccessary dependency on pp
|
3
12
|
* Added rbib2bib pretty printer
|
data/InstalledFiles
ADDED
data/README
CHANGED
@@ -52,9 +52,13 @@ Brian
|
|
52
52
|
## ToDo
|
53
53
|
* The binaries are only quick hacks for my specific applications right now,
|
54
54
|
they should be rewritten and extended.
|
55
|
+
* I should transfer functionality from rbib2bib into a library usable by all
|
56
|
+
programs.
|
55
57
|
* The full bibtex format is not parsed, I only allow for a specific subset
|
56
58
|
right now.
|
57
59
|
* Escaping is not implemented.
|
60
|
+
* Create the documentation after having racc'ed the .y files, then cleanup
|
61
|
+
again before packaging.
|
58
62
|
|
59
63
|
## Authors
|
60
64
|
This was implemented by Brian Schroeder.
|
data/bin/rbib2bib
CHANGED
@@ -1,76 +1,147 @@
|
|
1
|
-
#! /
|
2
|
-
|
3
|
-
$:.unshift("~/lib/ruby")
|
4
|
-
|
5
|
-
require "rbibtex"
|
6
|
-
|
7
|
-
file = BibTeX::Parser.new.parse( ARGF.read )
|
8
|
-
|
9
|
-
first = [:author, :title, :year]
|
10
|
-
last = [:note, :pdf, :ps, :www]
|
11
|
-
|
12
|
-
puts "@comment { Pretty Printed using rbib2bib }"
|
13
|
-
|
14
|
-
max_key_length = file.inject(0) { | r, entry |
|
15
|
-
entry.properties.inject(r) { | r, (k, _) |
|
16
|
-
[r, k.to_s.length].max
|
17
|
-
}
|
18
|
-
}
|
19
|
-
|
20
|
-
p max_key_length
|
1
|
+
#! /home/bschroed//bin/ruby
|
21
2
|
|
3
|
+
# Some string handling routines for wordwrapping and tabifying.
|
22
4
|
class String
|
23
5
|
def wrap(width = 78, tabwidth = 8)
|
24
6
|
raise "Invalid width" if width < 0
|
25
7
|
self.untabify(tabwidth).
|
26
|
-
|
27
|
-
|
8
|
+
gsub(/.{1,#{width}}(?:\s|\Z)/) { ($& + 5.chr).gsub(/\n\005/,"\n").gsub(/\005/,"\n") }.
|
9
|
+
gsub(/\s*\Z/m, "")
|
28
10
|
end
|
29
11
|
|
30
12
|
def indent_hanging(indent = 2)
|
31
|
-
|
13
|
+
self.gsub(/\n/, "\n#{" " * indent}")
|
32
14
|
end
|
33
|
-
|
15
|
+
|
34
16
|
def indent(indent = 2)
|
35
|
-
|
17
|
+
self.gsub(/^/, " " * indent)
|
36
18
|
end
|
37
19
|
|
38
20
|
|
39
21
|
def untabify(tab_width = 8)
|
40
22
|
self.gsub(/\t/, " "*tab_width)
|
41
23
|
end
|
42
|
-
|
24
|
+
|
43
25
|
def deindent_hanging(indent = [self[/^\s*/].untabify.length, self[/\n(\s*)/, 1].to_s.untabify.length].max)
|
44
26
|
self.untabify.gsub(/^\s{0,#{indent}}/, "")
|
45
27
|
end
|
46
|
-
|
28
|
+
|
47
29
|
def deindent(indent = self[/^\s*/].untabify.length)
|
48
30
|
self.untabify.gsub(/^\s{0,#{indent}}/, "")
|
49
31
|
end
|
50
32
|
|
51
33
|
def unwrap
|
52
34
|
self.split(/\n\n+/).map { | paragraph |
|
53
|
-
paragraph.gsub(
|
35
|
+
paragraph.gsub(/((?:\n|^)\S[^\n]*)\n(?=\S)/, "\\1 ")
|
54
36
|
}.join("\n\n")
|
55
37
|
end
|
56
38
|
end
|
57
39
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
40
|
+
module Bib2Bib
|
41
|
+
VERSION = "0.0.2"
|
42
|
+
|
43
|
+
require 'optparse'
|
44
|
+
|
45
|
+
class Options < OptionParser
|
46
|
+
attr_reader :wrap, :sort_by, :top_fields, :bottom_fields, :output, :help, :show_version, :comment
|
47
|
+
|
48
|
+
def initialize
|
49
|
+
super()
|
50
|
+
|
51
|
+
# Defaults
|
52
|
+
@top_fields = [:author, :title, :year]
|
53
|
+
@bottom_fields = [:note, :pdf, :ps, :www]
|
54
|
+
@comment = true
|
55
|
+
@output = STDOUT
|
56
|
+
|
57
|
+
# Parser Actions
|
58
|
+
self.banner = "Usage: #{ __FILE__ } [-o OUTPUT] [OPTIONS] INPUT [INPUT_1 ...]"
|
59
|
+
self.on("-o FILENAME", "--output FILENAME", String,
|
60
|
+
"Set the output filename. Writes to stdout if nothing is given") { | v | @output = File.open(v, 'w') }
|
61
|
+
self.on("-s", "--sort-by", "--sort_by Field_1,Field2,...", Array,
|
62
|
+
"Specify fields that shall be used for sorting of the file") { | v | @sort_by = v.map { | e | e.downcase.to_sym } }
|
63
|
+
self.on("-t", "--top_fields Field_1,Field2,...", Array,
|
64
|
+
"Specify a list of fields that are written first in the output") { | v | @top_fields = v.map { | e | e.downcase.to_sym }
|
65
|
+
@bottom_fields -= @top_fields }
|
66
|
+
self.on("-b", "--bottom_fields Field_1,Field2,...", Array,
|
67
|
+
"Specify a list of fields that are written last in the output") { | v | @bottom_fields = v.map { | e | e.downcase.to_sym }
|
68
|
+
@top_fields -= @bottom_fields }
|
69
|
+
self.on("-C", "--no-comment",
|
70
|
+
"Suppress generation of 'Created by' comment") { @comment = false }
|
71
|
+
self.on("-?", "--help",
|
72
|
+
"Show this help") { @help = true }
|
73
|
+
self.on("-v", "--version",
|
74
|
+
"Output version number and exit") { @show_version = true }
|
75
|
+
end
|
76
|
+
|
77
|
+
def parse!(*args)
|
78
|
+
super
|
79
|
+
raise "You can't specify an empty list of fields for sorting" if @sort_by and @sort_by.empty?
|
80
|
+
end
|
72
81
|
end
|
73
|
-
puts "}"
|
74
|
-
puts
|
75
|
-
end
|
76
82
|
|
83
|
+
options = Options.new
|
84
|
+
begin
|
85
|
+
options.parse!(ARGV)
|
86
|
+
rescue => e
|
87
|
+
puts "Invalid Commandline Arguments"
|
88
|
+
puts e
|
89
|
+
puts options
|
90
|
+
exit
|
91
|
+
end
|
92
|
+
|
93
|
+
if options.show_version
|
94
|
+
puts VERSION
|
95
|
+
exit
|
96
|
+
end
|
97
|
+
|
98
|
+
if options.help
|
99
|
+
puts options
|
100
|
+
exit
|
101
|
+
end
|
102
|
+
|
103
|
+
require "rbibtex"
|
104
|
+
|
105
|
+
|
106
|
+
entries = BibTeX::Parser.new.parse( ARGF.read )
|
107
|
+
O = options.output
|
108
|
+
|
109
|
+
if @comment
|
110
|
+
O.puts "@comment { Pretty Printed using rbib2bib }"
|
111
|
+
end
|
112
|
+
|
113
|
+
# Calculate maximum key length
|
114
|
+
max_key_length = entries.entries.inject(0) { | r, entry |
|
115
|
+
entry.properties.inject(r) { | r, (k, _) |
|
116
|
+
[r, k.to_s.length].max
|
117
|
+
}
|
118
|
+
}
|
119
|
+
|
120
|
+
def self.extract_properties(properties, fields)
|
121
|
+
fields.map { | k | [k, properties.delete(k)] }.select { | (_, v) | v }
|
122
|
+
end
|
123
|
+
|
124
|
+
elements = entries.elements.select { | e | e.is_a?(BibTeX::Entry) or e.is_a?(BibTeX::Comment) }
|
125
|
+
if options.sort_by
|
126
|
+
elements = elements.sort_by { | e | e.is_a?(BibTeX::Comment) ? [] : options.sort_by.map { | k | e.properties[k] || "" } }
|
127
|
+
end
|
128
|
+
puts elements.map { | entry |
|
129
|
+
|
130
|
+
if entry.is_a?BibTeX::Comment
|
131
|
+
"@comment { #{entry.to_s.deindent_hanging.unwrap.wrap(78 - 11).indent_hanging(11)} }"
|
132
|
+
else
|
133
|
+
properties = entry.properties.dup
|
134
|
+
top = extract_properties(properties, options.top_fields)
|
135
|
+
bottom = extract_properties(properties, options.bottom_fields)
|
136
|
+
middle = properties.to_a.map { | (k, v) | [k.to_s, v] }.sort
|
137
|
+
|
138
|
+
"@#{entry.type}{#{entry.key},\n" +
|
139
|
+
(
|
140
|
+
(top + middle + bottom).map { | (k, v) |
|
141
|
+
%( #{k}).ljust(max_key_length+2) + " = {#{v.deindent_hanging.unwrap.wrap(78-(max_key_length+6)).indent_hanging(max_key_length+6)}}"
|
142
|
+
}.join(",\n")
|
143
|
+
) + "\n}"
|
144
|
+
end
|
145
|
+
}.join("\n\n\n")
|
146
|
+
|
147
|
+
end
|
data/bin/rbib2html
CHANGED
data/bin/rbib2txt
CHANGED
data/lib/rbibtex/rbibtex.y
CHANGED
@@ -2,8 +2,10 @@ class BibTeX::Parser
|
|
2
2
|
|
3
3
|
rule
|
4
4
|
|
5
|
-
file :
|
6
|
-
|
|
5
|
+
file : opt_space_element { result = File.new(Space.new(val[0])) }
|
6
|
+
| opt_space_element
|
7
|
+
object_list
|
8
|
+
opt_space_element { result = File.new(*([val[0]] + val[1] + [val[2]]) ) }
|
7
9
|
;
|
8
10
|
|
9
11
|
object_list : object { result = [val[0]] }
|
@@ -17,7 +19,7 @@ rule
|
|
17
19
|
| entry { result = val[0] }
|
18
20
|
;
|
19
21
|
|
20
|
-
comment : COMMENT opt_space value { result =
|
22
|
+
comment : COMMENT opt_space value { result = Comment.new(val[2]) }
|
21
23
|
;
|
22
24
|
|
23
25
|
entry : entry_head assignment_list
|
@@ -60,44 +62,52 @@ rule
|
|
60
62
|
| SINGLE_ANFZ value_content_single_del SINGLE_ANFZ { result = val[1] }
|
61
63
|
| DOUBLE_ANFZ value_content_double_del DOUBLE_ANFZ { result = val[1] }
|
62
64
|
| WORD
|
65
|
+
;
|
66
|
+
|
67
|
+
brace : LBRACE
|
68
|
+
| RBRACE
|
69
|
+
;
|
70
|
+
|
71
|
+
anfz : SINGLE_ANFZ
|
72
|
+
| DOUBLE_ANFZ
|
63
73
|
;
|
64
74
|
|
65
75
|
value_content_single_del : { result = "" }
|
66
|
-
| value_content
|
67
|
-
| value_content
|
68
|
-
| value_content COMMA { result << val[1] }
|
69
|
-
/* | value_content "\\" SINGLE_ANFZ { result << val[1] << val[2]} */
|
76
|
+
| value_content general_vc_token { result << val[1] }
|
77
|
+
| value_content brace { result << val[1] }
|
70
78
|
| value_content DOUBLE_ANFZ { result << val[1] }
|
71
|
-
| value_content CHARACTER { result << val[1] }
|
72
|
-
| value_content AT { result << val[1] }
|
73
|
-
| value_content LBRACE { result << val[1] }
|
74
|
-
| value_content RBRACE { result << val[1] }
|
75
79
|
;
|
76
80
|
|
77
81
|
value_content_double_del : { result = "" }
|
78
|
-
| value_content
|
79
|
-
| value_content
|
80
|
-
| value_content COMMA { result << val[1] }
|
82
|
+
| value_content general_vc_token { result << val[1] }
|
83
|
+
| value_content brace { result << val[1] }
|
81
84
|
| value_content SINGLE_ANFZ { result << val[1] }
|
82
|
-
/* | value_content "\\" DOUBLE_ANFZ { result << val[1] << val[2] } */
|
83
|
-
| value_content CHARACTER { result << val[1] }
|
84
|
-
| value_content AT { result << val[1] }
|
85
|
-
| value_content LBRACE { result << val[1] }
|
86
|
-
| value_content RBRACE { result << val[1] }
|
87
85
|
;
|
88
86
|
|
89
|
-
value_content :
|
90
|
-
| value_content
|
91
|
-
| value_content
|
92
|
-
| value_content COMMA { result << val[1] }
|
93
|
-
| value_content SINGLE_ANFZ { result << val[1] }
|
94
|
-
| value_content DOUBLE_ANFZ { result << val[1] }
|
95
|
-
| value_content CHARACTER { result << val[1] }
|
96
|
-
| value_content AT { result << val[1] }
|
87
|
+
value_content : { result = "" }
|
88
|
+
| value_content general_vc_token { result << val[1] }
|
89
|
+
| value_content anfz { result << val[1] }
|
97
90
|
| value_content
|
98
91
|
LBRACE value_content RBRACE { result << val[1] << val[2] << val[3] }
|
99
92
|
;
|
100
93
|
|
94
|
+
general_vc_token : SPACE
|
95
|
+
| WORD
|
96
|
+
| COMMA
|
97
|
+
| EQUALS
|
98
|
+
| CHARACTER
|
99
|
+
| AT
|
100
|
+
;
|
101
|
+
|
102
|
+
opt_space_element :
|
103
|
+
| space_element
|
104
|
+
;
|
105
|
+
|
106
|
+
space_element : SPACE { result = Space.new(val[0]) }
|
107
|
+
|
108
|
+
space : SPACE
|
109
|
+
;
|
110
|
+
|
101
111
|
opt_space :
|
102
112
|
| SPACE
|
103
113
|
;
|
@@ -109,6 +119,34 @@ end
|
|
109
119
|
|
110
120
|
module BibTeX
|
111
121
|
Entry = Struct.new(:type, :key, :properties)
|
122
|
+
|
123
|
+
class Space < String; end
|
124
|
+
|
125
|
+
class Comment
|
126
|
+
def initialize(comment)
|
127
|
+
@comment = comment
|
128
|
+
end
|
129
|
+
|
130
|
+
def to_s
|
131
|
+
@comment
|
132
|
+
end
|
133
|
+
|
134
|
+
alias :to_str :to_s
|
135
|
+
end
|
136
|
+
|
137
|
+
class File
|
138
|
+
def initialize(*elements)
|
139
|
+
@elements = elements.compact
|
140
|
+
end
|
141
|
+
|
142
|
+
def elements
|
143
|
+
@elements
|
144
|
+
end
|
145
|
+
|
146
|
+
def entries
|
147
|
+
@elements.select { | e | e.is_a?Entry }
|
148
|
+
end
|
149
|
+
end
|
112
150
|
end
|
113
151
|
|
114
152
|
---- inner ----
|
@@ -120,13 +158,13 @@ end
|
|
120
158
|
def parse( str )
|
121
159
|
@q = []
|
122
160
|
|
123
|
-
|
161
|
+
# @yydebug = true
|
124
162
|
|
125
163
|
while str.size > 0 do
|
126
164
|
case str
|
127
165
|
when /\A[\t\n\s]+/o
|
128
166
|
@q.push [:SPACE, $&]
|
129
|
-
when /\
|
167
|
+
when /\Acomment/io
|
130
168
|
@q.push [:COMMENT, $&]
|
131
169
|
when /\A\,/o
|
132
170
|
@q.push [:COMMA, $&]
|
data/papers.bib
CHANGED
@@ -184,7 +184,8 @@
|
|
184
184
|
pages = {70--73},
|
185
185
|
year = 2005,
|
186
186
|
Organization = {IEEE},
|
187
|
-
note = {A short overview of applications and methods for lip tracking, automated speech recogniton, person recogniton, etc. Pointers to databases with joint AV material and relevant Publications.}
|
187
|
+
note = {A short overview of applications and methods for lip tracking, automated speech recogniton, person recogniton, etc. Pointers to databases with joint AV material and relevant Publications.},
|
188
|
+
pdf = {}
|
188
189
|
}
|
189
190
|
|
190
191
|
@Article{seyadarabi:facial,
|
@@ -195,5 +196,11 @@ NUMBER = 4 ,
|
|
195
196
|
year = 2004 ,
|
196
197
|
ISSN = {1305-239X},
|
197
198
|
Author = {Hadi Seyedarabi and Ali Aghagolzadeh and Sohrab Khanmohammadi},
|
198
|
-
note = {Written in very bad english and does not contain too much information. They track feature points in 2D video data using optical flow and use these points to interpolate a triangle mesh. They claim to have a muscle-based model, but that shows nowhere.}
|
199
|
+
note = {Written in very bad english and does not contain too much information. They track feature points in 2D video data using optical flow and use these points to interpolate a triangle mesh. They claim to have a muscle-based model, but that shows nowhere.},
|
200
|
+
pdf = {}
|
201
|
+
}
|
202
|
+
|
203
|
+
@comment {
|
204
|
+
todo:
|
205
|
+
pdf = {local/blake_sparse_realtime_tracking.pdf}
|
199
206
|
}
|
data/test.bib
ADDED
metadata
CHANGED
@@ -3,7 +3,7 @@ rubygems_version: 0.8.11
|
|
3
3
|
specification_version: 1
|
4
4
|
name: rbibtex
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.0.
|
6
|
+
version: 0.0.2
|
7
7
|
date: 2005-11-09 00:00:00 +01:00
|
8
8
|
summary: A bibtex parsing library written in pure ruby
|
9
9
|
require_paths:
|
@@ -39,7 +39,9 @@ authors:
|
|
39
39
|
files:
|
40
40
|
- papers.bib
|
41
41
|
- README
|
42
|
+
- test.bib
|
42
43
|
- CHANGELOG
|
44
|
+
- InstalledFiles
|
43
45
|
- papers.html
|
44
46
|
- setup.rb
|
45
47
|
- bin
|