bibtex_munge 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +23 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +9 -0
- data/bibtex_munge.gemspec +24 -0
- data/bin/bibtex_munge +69 -0
- data/lib/bibtex_munge.rb +6 -0
- data/lib/bibtex_munge/bcf.rb +52 -0
- data/lib/bibtex_munge/bibliography.rb +135 -0
- data/lib/bibtex_munge/save.rb +13 -0
- data/lib/bibtex_munge/sort.rb +9 -0
- data/lib/bibtex_munge/version.rb +3 -0
- metadata +114 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0570d1639c6e189aa2bf8a5b8f806ee93a549fb0
|
4
|
+
data.tar.gz: 2125c90d8a6a8cb437f16da9898fb4b464f1fd7c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5a1f29d06e2ba3f2f20a5d3c66f9e46a43370c56a84624ce9f2e9e56b78e889afef45eedde00187660ebf984ea9829e4cdc6c0dd7317f412d95bb87b2d19be04
|
7
|
+
data.tar.gz: 14577955753efc43623d95b547c6fade6ec42f8156f9b845d6ca3de6a81ef18f9367c2a2a7e5da7b4ba49c5bc51485ee0e8c3f3d7098f96ec3ecc01c9caac453
|
data/.gitignore
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
*.swp
|
23
|
+
mkmf.log
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Leah Velleman
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# BibtexMunge
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'bibtex_munge'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install bibtex_munge
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it ( https://github.com/[my-github-username]/bibtex_munge/fork )
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'bibtex_munge/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "bibtex_munge"
|
8
|
+
spec.version = BibtexMunge::VERSION
|
9
|
+
spec.authors = ["Leah Velleman"]
|
10
|
+
spec.email = ["leah.velleman@gmail.com"]
|
11
|
+
spec.summary = %q{Automate several cleanup tasks for BibTeX files}
|
12
|
+
spec.homepage = ""
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0")
|
16
|
+
spec.executables = ["bibtex_munge"]
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
21
|
+
spec.add_development_dependency "rake"
|
22
|
+
spec.add_runtime_dependency "bibtex-ruby"
|
23
|
+
spec.add_runtime_dependency "nokogiri"
|
24
|
+
end
|
data/bin/bibtex_munge
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bibtex_munge'
|
4
|
+
replace = false
|
5
|
+
path = nil
|
6
|
+
HELP = <<-EOF
|
7
|
+
Usage: bibtex_munge [-hR] filename
|
8
|
+
|
9
|
+
The filename should be the name of a .bib or .bcf file. If it is a .bib file, the output
|
10
|
+
will consist of cleaned and normalized bibliography entries. If it is a .bcf file,
|
11
|
+
in addition to cleaning and sanitizing, a subset bibliography will be created: only those
|
12
|
+
entries that were actually cited in the document from which the .bcf was created will
|
13
|
+
be retained.
|
14
|
+
|
15
|
+
Options:
|
16
|
+
--help -h show this message
|
17
|
+
--replace -R rather than printing the output to STDOUT, save it as filename.bib, and
|
18
|
+
move the former contents of filename.bib to filename.bib.bak
|
19
|
+
|
20
|
+
EOF
|
21
|
+
|
22
|
+
def bad_input
|
23
|
+
puts "Invalid input!"
|
24
|
+
puts HELP
|
25
|
+
end
|
26
|
+
|
27
|
+
define_method :do_output do |bib|
|
28
|
+
if replace
|
29
|
+
if path.end_with? ".bcf"
|
30
|
+
path = path.chomp('.bcf') + ".bib"
|
31
|
+
end
|
32
|
+
bib.save_and_backup(path)
|
33
|
+
else
|
34
|
+
puts bib
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
while ARGV.length > 0 do
|
39
|
+
o = ARGV.shift
|
40
|
+
case o
|
41
|
+
when '-h', '--help'
|
42
|
+
print HELP
|
43
|
+
exit
|
44
|
+
when '-R', '--replace'
|
45
|
+
replace = true
|
46
|
+
else
|
47
|
+
if File.exists? o
|
48
|
+
path = o
|
49
|
+
else
|
50
|
+
bad_input
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
if path
|
56
|
+
if path.end_with? ".bcf"
|
57
|
+
bib = BibTeX::Bibliography.from_bcf(path)
|
58
|
+
bib.fix_everything!
|
59
|
+
do_output(bib)
|
60
|
+
elsif path.end_with? ".bib"
|
61
|
+
bib = BibTeX::Bibliography.from_bib(path)
|
62
|
+
bib.fix_everything!
|
63
|
+
do_output(bib)
|
64
|
+
else
|
65
|
+
bad_input
|
66
|
+
end
|
67
|
+
else
|
68
|
+
bad_input
|
69
|
+
end
|
data/lib/bibtex_munge.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require "nokogiri"
|
2
|
+
|
3
|
+
module BibTeX
|
4
|
+
class Bibliography
|
5
|
+
attr_accessor :filepath
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def trim_unnecessary_entries!(bib, citekeys)
|
9
|
+
bib.entries.each do |k,v|
|
10
|
+
if !citekeys.include? k
|
11
|
+
bib.delete(k)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def from_bcf(path)
|
17
|
+
File.open(path, "r") do |f|
|
18
|
+
@bcf = Nokogiri::XML(f).remove_namespaces!
|
19
|
+
end
|
20
|
+
filepath = File.dirname(path) + "/" + @bcf.at_xpath("//datasource").content
|
21
|
+
citekeys = @bcf.xpath("//citekey", 'bcf'=>'URI').map(&:content)
|
22
|
+
bib = open(filepath, :filter => 'latex')
|
23
|
+
bib.filepath = filepath
|
24
|
+
trim_unnecessary_entries!(bib, citekeys)
|
25
|
+
bib.sort! { |a,b| a.author <=> b.author }
|
26
|
+
bib.extend(BibtexMunge)
|
27
|
+
bib.fix_everything!
|
28
|
+
return bib
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
|
36
|
+
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
|
44
|
+
|
45
|
+
|
46
|
+
|
47
|
+
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
|
52
|
+
|
@@ -0,0 +1,135 @@
|
|
1
|
+
# TODO:
|
2
|
+
# - DOI fetching?
|
3
|
+
# - Protect math expressions with braces
|
4
|
+
# -
|
5
|
+
|
6
|
+
|
7
|
+
require "bibtex"
|
8
|
+
|
9
|
+
module BibtexMunge
|
10
|
+
@@split_fields = [ # specifying how to handle {PART 1: PART 2}
|
11
|
+
# in fields where it is a frequent issue:
|
12
|
+
[:title, :title, :subtitle], # * if the title contains a separator,
|
13
|
+
# the second part becomes a subtitle
|
14
|
+
[:booktitle, :booktitle, :booksubtitle], # * if the booktitle contains a separator,
|
15
|
+
# the second part becomes a booksubtitle
|
16
|
+
[:publisher, :address, :publisher] # * if the publisher contains a separator,
|
17
|
+
# the first part becomes an address
|
18
|
+
]
|
19
|
+
@@name_fields = [:author, :editor] # specifying which fields shouldn't have
|
20
|
+
# trailing periods removed (because
|
21
|
+
# they might be initials)
|
22
|
+
|
23
|
+
@@prune_fields = [:isbn, :issn, :abstract] # common nuisance fields to delete
|
24
|
+
|
25
|
+
# Run a block on every field in every entry
|
26
|
+
def each_field(options = {})
|
27
|
+
except = options[:except]
|
28
|
+
except ||= []
|
29
|
+
if block_given?
|
30
|
+
each_entry do |e|
|
31
|
+
e.fields.each do |k,v|
|
32
|
+
yield v unless except.include? k
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def normalize_initials!
|
39
|
+
each_entry do |e|
|
40
|
+
@@name_fields.each do |k|
|
41
|
+
if e[k]
|
42
|
+
e[k].each do |name|
|
43
|
+
if name.first
|
44
|
+
name.first = name.normalize_initials
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
self
|
51
|
+
end
|
52
|
+
|
53
|
+
def depunctuate!
|
54
|
+
each_field :except => @@name_fields do |f|
|
55
|
+
f.chomp!(".")
|
56
|
+
end
|
57
|
+
self
|
58
|
+
end
|
59
|
+
|
60
|
+
def extend_braces!
|
61
|
+
each_field do |f|
|
62
|
+
f.gsub! /\ {([^ ])}([^ ]+)/, ' {\1\2}' # The initial space is to avoid
|
63
|
+
# fucking up braces after an accent.
|
64
|
+
# this is *probably* redundant now that we're
|
65
|
+
# unicodifying everything, but better safe than
|
66
|
+
# sorry
|
67
|
+
end
|
68
|
+
self
|
69
|
+
end
|
70
|
+
|
71
|
+
def remove_double_braces!
|
72
|
+
each_field do |f|
|
73
|
+
f.gsub! /{{(.*)}}/, '{\1}' # Eliminate overt double braces
|
74
|
+
|
75
|
+
f.gsub! /^{(.*)}$/, '\1' # Eliminate whole-entry braces (which would have been
|
76
|
+
# double braces in the unparsed BibTeX file, since
|
77
|
+
# publisher = {{Blackwell}}
|
78
|
+
# parses to
|
79
|
+
# @bib[:key].publisher = "{Blackwell}"
|
80
|
+
end
|
81
|
+
self
|
82
|
+
end
|
83
|
+
|
84
|
+
def split_field!(e, oldkey, newsuperkey, newsubkey)
|
85
|
+
if e[oldkey]
|
86
|
+
elements = e[oldkey].split(/([.:?]) /,2) # Split after .:?, retaining the separator
|
87
|
+
if elements.length == 3
|
88
|
+
e[newsubkey] = elements[2]
|
89
|
+
if elements[1] == "?" # Keep the separator as part of the first
|
90
|
+
e[newsuperkey] = elements[0..1].join # field if it is a ?, to handle titles of
|
91
|
+
# the form {Question? An Answer}
|
92
|
+
else
|
93
|
+
e[newsuperkey] = elements[0]
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def split_fields!
|
100
|
+
each_entry do |e|
|
101
|
+
@@split_fields.each do |oldkey, newsuperkey, newsubkey|
|
102
|
+
split_field!(e, oldkey, newsuperkey, newsubkey)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
self
|
106
|
+
end
|
107
|
+
|
108
|
+
def prune_fields!
|
109
|
+
each_entry do |e|
|
110
|
+
@@prune_fields.each do |k|
|
111
|
+
e.delete(k)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
self
|
115
|
+
end
|
116
|
+
|
117
|
+
def normalize_page_ranges!
|
118
|
+
each_entry do |e|
|
119
|
+
if e.pages
|
120
|
+
e.pages.gsub! /^(\d+)\s*(–|—|-|--|---)\s*(\d+)$/, '\1 -- \3'
|
121
|
+
end
|
122
|
+
end
|
123
|
+
self
|
124
|
+
end
|
125
|
+
|
126
|
+
def fix_everything!
|
127
|
+
remove_double_braces!
|
128
|
+
depunctuate!
|
129
|
+
extend_braces!
|
130
|
+
split_fields!
|
131
|
+
prune_fields!
|
132
|
+
normalize_initials!
|
133
|
+
normalize_page_ranges!
|
134
|
+
end
|
135
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# BibTeX-ruby includes prefixes like "von" as part of the last name when sorting names.
|
2
|
+
# This redefinition of Name#sort_order stops it from doing so.
|
3
|
+
module BibTeX
|
4
|
+
class Name
|
5
|
+
def sort_order(options = {})
|
6
|
+
[last, suffix, options[:initials] ? initials : first].compact.join(', ')
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
metadata
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bibtex_munge
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Leah Velleman
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-03-25 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.6'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bibtex-ruby
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: nokogiri
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description:
|
70
|
+
email:
|
71
|
+
- leah.velleman@gmail.com
|
72
|
+
executables:
|
73
|
+
- bibtex_munge
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- .gitignore
|
78
|
+
- Gemfile
|
79
|
+
- LICENSE.txt
|
80
|
+
- README.md
|
81
|
+
- Rakefile
|
82
|
+
- bibtex_munge.gemspec
|
83
|
+
- lib/bibtex_munge.rb
|
84
|
+
- lib/bibtex_munge/bcf.rb
|
85
|
+
- lib/bibtex_munge/bibliography.rb
|
86
|
+
- lib/bibtex_munge/save.rb
|
87
|
+
- lib/bibtex_munge/sort.rb
|
88
|
+
- lib/bibtex_munge/version.rb
|
89
|
+
- bin/bibtex_munge
|
90
|
+
homepage: ''
|
91
|
+
licenses:
|
92
|
+
- MIT
|
93
|
+
metadata: {}
|
94
|
+
post_install_message:
|
95
|
+
rdoc_options: []
|
96
|
+
require_paths:
|
97
|
+
- lib
|
98
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - '>='
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - '>='
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0'
|
108
|
+
requirements: []
|
109
|
+
rubyforge_project:
|
110
|
+
rubygems_version: 2.0.14
|
111
|
+
signing_key:
|
112
|
+
specification_version: 4
|
113
|
+
summary: Automate several cleanup tasks for BibTeX files
|
114
|
+
test_files: []
|