citeproc 0.0.8 → 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +5 -0
- data/.travis.yml +13 -0
- data/.yardopts +2 -0
- data/AGPL +662 -0
- data/{LICENSE → BSDL} +2 -1
- data/Gemfile +13 -2
- data/README.md +32 -1
- data/Rakefile +39 -0
- data/citeproc.gemspec +18 -11
- data/lib/citeproc.rb +13 -11
- data/lib/citeproc/abbreviate.rb +1 -4
- data/lib/citeproc/assets.rb +11 -4
- data/lib/citeproc/attributes.rb +102 -95
- data/lib/citeproc/bibliography.rb +66 -42
- data/lib/citeproc/citation_data.rb +57 -46
- data/lib/citeproc/compatibility.rb +161 -4
- data/lib/citeproc/date.rb +517 -225
- data/lib/citeproc/engine.rb +0 -2
- data/lib/citeproc/errors.rb +4 -4
- data/lib/citeproc/extensions.rb +6 -5
- data/lib/citeproc/item.rb +85 -22
- data/lib/citeproc/names.rb +642 -543
- data/lib/citeproc/variable.rb +149 -70
- data/lib/citeproc/version.rb +1 -1
- data/spec/citeproc/assets_spec.rb +10 -4
- data/spec/citeproc/date_spec.rb +274 -8
- data/spec/citeproc/item_spec.rb +23 -4
- data/spec/citeproc/names_spec.rb +601 -486
- data/spec/citeproc/variable_spec.rb +4 -12
- data/spec/spec_helper.rb +13 -0
- metadata +64 -31
data/{LICENSE → BSDL}
RENAMED
@@ -1,4 +1,5 @@
|
|
1
|
-
Copyright
|
1
|
+
Copyright 2012 President and Fellows of Harvard College.
|
2
|
+
Copyright 2009-2012 Sylvester Keil. All rights reserved.
|
2
3
|
|
3
4
|
Redistribution and use in source and binary forms, with or without
|
4
5
|
modification, are permitted provided that the following conditions are met:
|
data/Gemfile
CHANGED
@@ -2,10 +2,21 @@ source :rubygems
|
|
2
2
|
gemspec
|
3
3
|
|
4
4
|
group :debug do
|
5
|
-
|
6
|
-
gem 'ruby-debug19', :require => 'ruby-debug', :platforms => [:ruby_19]
|
5
|
+
gem 'debugger', '~>1.1.3', :platform => :mri_19
|
7
6
|
end
|
8
7
|
|
9
8
|
group :optional do
|
10
9
|
gem 'chronic', '~>0.6'
|
10
|
+
gem 'edtf', '~>1.0.0'
|
11
|
+
|
12
|
+
gem 'bibtex-ruby', '~>2.0.10', :require => 'bibtex'
|
13
|
+
|
14
|
+
gem 'simplecov', '~>0.6.4'
|
15
|
+
|
16
|
+
gem 'unicode_utils', '~>1.3.0', :platform => :mri_19
|
17
|
+
gem 'unicode', '~>0.4.2', :platform => :mri_18
|
18
|
+
end
|
19
|
+
|
20
|
+
group :extra do
|
21
|
+
gem 'oniguruma', '~>1.1.0', :platform => :mri_18
|
11
22
|
end
|
data/README.md
CHANGED
@@ -1,4 +1,35 @@
|
|
1
1
|
CiteProc
|
2
2
|
========
|
3
|
+
CiteProc is a cite processor interface and citation data API based on the
|
4
|
+
Citation Style Language (CSL) specifications. To actually process citations
|
5
|
+
a dedicated processor engine is required; these can be installed as separate
|
6
|
+
gems.
|
3
7
|
|
4
|
-
|
8
|
+
### A word of caution
|
9
|
+
As work on this and on the related packages is still in progress, please
|
10
|
+
be aware of the following caveats: the 0.0.x branch of citeproc-ruby is still
|
11
|
+
a standalone package and will conflict with this release of citeproc; support
|
12
|
+
will be added in future versions of the 1.x.x branch.
|
13
|
+
|
14
|
+
[![Build Status](https://secure.travis-ci.org/berkmancenter/citeproc.png)](http://travis-ci.org/berkmancenter/citeproc)
|
15
|
+
|
16
|
+
|
17
|
+
Citation Data
|
18
|
+
-------------
|
19
|
+
|
20
|
+
Processor Interface
|
21
|
+
-------------------
|
22
|
+
|
23
|
+
Credits
|
24
|
+
-------
|
25
|
+
|
26
|
+
|
27
|
+
Copyright
|
28
|
+
---------
|
29
|
+
Copyright 2012 President and Fellows of Harvard College.
|
30
|
+
|
31
|
+
Copyright 2009-2012 Sylvester Keil. All rights reserved.
|
32
|
+
|
33
|
+
License
|
34
|
+
-------
|
35
|
+
CiteProc is dual licensed under the AGPL and the FreeBSD license.
|
data/Rakefile
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'bundler'
|
4
|
+
begin
|
5
|
+
Bundler.setup
|
6
|
+
rescue Bundler::BundlerError => e
|
7
|
+
$stderr.puts e.message
|
8
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
9
|
+
exit e.status_code
|
10
|
+
end
|
11
|
+
|
12
|
+
$:.unshift(File.join(File.dirname(__FILE__), './lib'))
|
13
|
+
require 'citeproc/version'
|
14
|
+
|
15
|
+
|
16
|
+
desc 'Run an IRB session with CiteProc loaded'
|
17
|
+
task :console, [:script] do |t,args|
|
18
|
+
ARGV.clear
|
19
|
+
|
20
|
+
require 'irb'
|
21
|
+
require 'citeproc'
|
22
|
+
|
23
|
+
IRB.conf[:SCRIPT] = args.script
|
24
|
+
IRB.start
|
25
|
+
end
|
26
|
+
|
27
|
+
require 'rspec/core'
|
28
|
+
require 'rspec/core/rake_task'
|
29
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
30
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
31
|
+
end
|
32
|
+
|
33
|
+
require 'cucumber/rake/task'
|
34
|
+
Cucumber::Rake::Task.new(:cucumber)
|
35
|
+
|
36
|
+
task :default => :spec
|
37
|
+
|
38
|
+
require 'yard'
|
39
|
+
YARD::Rake::YardocTask.new
|
data/citeproc.gemspec
CHANGED
@@ -8,28 +8,35 @@ Gem::Specification.new do |s|
|
|
8
8
|
s.name = 'citeproc'
|
9
9
|
s.version = CiteProc::VERSION.dup
|
10
10
|
s.platform = Gem::Platform::RUBY
|
11
|
+
|
11
12
|
s.authors = ['Sylvester Keil']
|
12
|
-
s.email = '
|
13
|
-
|
13
|
+
s.email = ['sylvester@keil.or.at']
|
14
|
+
|
15
|
+
s.homepage = 'https://github.com/inukshuk/citeproc'
|
14
16
|
s.summary = 'A cite processor interface.'
|
15
|
-
s.description =
|
16
|
-
|
17
|
+
s.description =
|
18
|
+
"""
|
19
|
+
A cite processor interface for Citation Style Language (CSL) styles.
|
20
|
+
"""
|
21
|
+
|
22
|
+
s.license = 'AGPL'
|
17
23
|
s.date = Time.now.strftime('%Y-%m-%d')
|
18
24
|
|
19
|
-
s.add_runtime_dependency('multi_json', '~>1.
|
25
|
+
s.add_runtime_dependency('multi_json', '~>1.3.5')
|
26
|
+
s.add_runtime_dependency('namae', '~>0.1')
|
20
27
|
|
21
|
-
s.add_development_dependency('cucumber', ['
|
22
|
-
s.add_development_dependency('rspec', ['
|
23
|
-
s.add_development_dependency('watchr', ['
|
28
|
+
s.add_development_dependency('cucumber', ['~>1.2.0'])
|
29
|
+
s.add_development_dependency('rspec', ['~>2.10.0'])
|
30
|
+
s.add_development_dependency('watchr', ['~>0.7'])
|
31
|
+
s.add_development_dependency('rake', ['~>0.9.2'])
|
32
|
+
s.add_development_dependency('yard', ['~>0.8.1'])
|
24
33
|
|
25
34
|
s.files = `git ls-files`.split("\n")
|
26
35
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
27
36
|
s.executables = []
|
28
37
|
s.require_path = 'lib'
|
29
38
|
|
30
|
-
s.
|
31
|
-
s.extra_rdoc_files = %w{README.md}
|
32
|
-
|
39
|
+
s.has_rdoc = 'yard'
|
33
40
|
end
|
34
41
|
|
35
42
|
# vim: syntax=ruby
|
data/lib/citeproc.rb
CHANGED
@@ -1,13 +1,11 @@
|
|
1
1
|
|
2
|
-
require '
|
2
|
+
require 'date'
|
3
3
|
require 'forwardable'
|
4
4
|
require 'observer'
|
5
5
|
require 'uri'
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
Debugger.start
|
10
|
-
end
|
7
|
+
require 'multi_json'
|
8
|
+
require 'namae'
|
11
9
|
|
12
10
|
require 'citeproc/version'
|
13
11
|
|
@@ -17,7 +15,11 @@ require 'citeproc/version'
|
|
17
15
|
#
|
18
16
|
module CiteProc
|
19
17
|
|
20
|
-
module Converters
|
18
|
+
module Converters
|
19
|
+
end
|
20
|
+
|
21
|
+
module Utilities
|
22
|
+
end
|
21
23
|
|
22
24
|
end
|
23
25
|
|
@@ -34,11 +36,11 @@ require 'citeproc/date'
|
|
34
36
|
require 'citeproc/names'
|
35
37
|
|
36
38
|
CiteProc::Variable.class_eval do
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
39
|
+
@factories = Hash.new { |h,k| h.fetch(k.to_s.intern, CiteProc::Variable) }.merge(
|
40
|
+
Hash[*@types.map { |n,k|
|
41
|
+
[n, CiteProc.const_get(k.to_s.capitalize)]
|
42
|
+
}.flatten]
|
43
|
+
).freeze
|
42
44
|
end
|
43
45
|
|
44
46
|
require 'citeproc/item'
|
data/lib/citeproc/abbreviate.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'multi_json'
|
2
|
-
|
3
1
|
module CiteProc
|
4
2
|
module Abbreviate
|
5
3
|
|
@@ -20,8 +18,7 @@ module CiteProc
|
|
20
18
|
end
|
21
19
|
end
|
22
20
|
|
23
|
-
#
|
24
|
-
# abbreviate(namespace = :default, context, word)
|
21
|
+
# @overload abbreviate(namespace = :default, context, word)
|
25
22
|
def abbreviate(*arguments)
|
26
23
|
raise ArgumentError, "wrong number of arguments (#{arguments.length} for 2..3)" unless (2..3).include?(arguments.length)
|
27
24
|
arguments.unshift(namespace || :default) if arguments.length < 3
|
data/lib/citeproc/assets.rb
CHANGED
@@ -39,8 +39,7 @@ module CiteProc
|
|
39
39
|
|
40
40
|
self
|
41
41
|
rescue => e
|
42
|
-
|
43
|
-
raise ArgumentError, "failed to open asset #{input.inspect}: #{e.message}"
|
42
|
+
raise ArgumentError, "failed to open asset #@location (#{input.inspect}): #{e.message}"
|
44
43
|
end
|
45
44
|
|
46
45
|
def name
|
@@ -66,8 +65,16 @@ module CiteProc
|
|
66
65
|
end
|
67
66
|
|
68
67
|
def extend_name(input)
|
69
|
-
|
70
|
-
|
68
|
+
if File.extname(input) != extension
|
69
|
+
name = [input, extension].compact.join
|
70
|
+
else
|
71
|
+
name = input.to_s.dup
|
72
|
+
end
|
73
|
+
|
74
|
+
unless name.start_with?(prefix.to_s)
|
75
|
+
name = [prefix, name].join
|
76
|
+
end
|
77
|
+
|
71
78
|
name
|
72
79
|
end
|
73
80
|
|
data/lib/citeproc/attributes.rb
CHANGED
@@ -1,16 +1,8 @@
|
|
1
|
-
|
2
1
|
module CiteProc
|
3
|
-
|
4
|
-
# TODO refactor using a Struct instead of a hash. This will have to convert
|
5
|
-
# the CiteProc/CSL names which are no proper method names.
|
6
|
-
|
7
|
-
|
2
|
+
|
8
3
|
module Attributes
|
9
4
|
extend Forwardable
|
10
|
-
|
11
5
|
|
12
|
-
FALSE_PATTERN = (/^(false|no|never)$/i).freeze
|
13
|
-
|
14
6
|
def self.included(base)
|
15
7
|
base.extend(ClassMethods)
|
16
8
|
end
|
@@ -19,104 +11,119 @@ module CiteProc
|
|
19
11
|
@attributes ||= {}
|
20
12
|
end
|
21
13
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
14
|
+
def_delegators :attributes, :length, :empty?, :values_at, :key?, :value?
|
15
|
+
|
16
|
+
alias size length
|
17
|
+
|
18
|
+
def [](key)
|
19
|
+
attributes[filter_key(key)]
|
20
|
+
end
|
21
|
+
|
22
|
+
def []=(key, value)
|
23
|
+
attributes[filter_key(key)] = filter_value(value)
|
24
|
+
end
|
25
|
+
|
26
|
+
def filter_key(key)
|
27
|
+
key.to_sym
|
28
|
+
end
|
29
|
+
|
30
|
+
def filter_value(value, key = nil)
|
31
|
+
value.respond_to?(:deep_copy) ? value.deep_copy : value.dup
|
32
|
+
rescue
|
33
|
+
value
|
34
|
+
end
|
35
|
+
|
42
36
|
def merge(other)
|
43
37
|
return self if other.nil?
|
44
38
|
|
45
|
-
case
|
46
|
-
when String
|
47
|
-
other =
|
48
|
-
when
|
49
|
-
|
50
|
-
when
|
39
|
+
case
|
40
|
+
when other.is_a?(String) && /^\s*\{/ =~ other
|
41
|
+
other = MultiJson.decode(other, :symbolize_keys => true)
|
42
|
+
when other.respond_to?(:each_pair)
|
43
|
+
# do nothing
|
44
|
+
when other.respond_to?(:to_hash)
|
51
45
|
other = other.to_hash
|
52
|
-
|
53
|
-
|
46
|
+
else
|
47
|
+
raise ParseError, "failed to merge attributes and #{other.inspect}"
|
54
48
|
end
|
55
49
|
|
56
50
|
other.each_pair do |key, value|
|
57
|
-
|
58
|
-
|
59
|
-
|
51
|
+
attributes[filter_key(key)] = filter_value(value, key)
|
52
|
+
end
|
53
|
+
|
60
54
|
self
|
61
55
|
end
|
62
56
|
|
63
57
|
alias update merge
|
64
58
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
59
|
+
def reverse_merge(other)
|
60
|
+
fail "not implemented yet"
|
61
|
+
end
|
62
|
+
|
63
|
+
def to_hash
|
64
|
+
attributes.deep_copy
|
65
|
+
end
|
66
|
+
|
67
|
+
# @return [Hash] a hash-based representation of the attributes
|
68
|
+
def to_citeproc
|
69
|
+
Hash[attributes.map { |k,v|
|
70
|
+
[k.to_s, v.respond_to?(:to_citeproc) ? v.to_citeproc : v.to_s]
|
71
|
+
}]
|
72
|
+
end
|
73
|
+
|
74
|
+
# @return [String] a JSON string representation of the attributes
|
75
|
+
def to_json
|
76
|
+
MultiJson.encode(to_citeproc)
|
77
|
+
end
|
78
|
+
|
79
|
+
# Don't expose internals to public API
|
80
|
+
private :filter_key, :filter_value
|
81
|
+
|
82
|
+
# initialize_copy should be able to access attributes
|
83
|
+
protected :attributes
|
84
|
+
|
85
|
+
|
86
|
+
# Two Attribute-based objects are equal if they are the same object,
|
87
|
+
# or if all their attributes are equal using _#eql?_.
|
88
|
+
#
|
89
|
+
# @param other [Object] the other object
|
90
|
+
# @return [Boolean] whether or not self and passed-in object are equal
|
91
|
+
def eql?(other)
|
92
|
+
case
|
93
|
+
when equal?(other)
|
94
|
+
true
|
95
|
+
when self.class != other.class, length != other.length
|
96
|
+
false
|
97
|
+
else
|
98
|
+
other.attributes.each_pair do |key, value|
|
99
|
+
return false unless attributes[key].eql?(value)
|
100
|
+
end
|
101
|
+
|
102
|
+
true
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# @return [Fixnum] a hash value based on the object's attributes
|
107
|
+
def hash
|
108
|
+
digest = size
|
109
|
+
attributes.each do |attribute|
|
110
|
+
digest ^= attribute.hash
|
111
|
+
end
|
112
|
+
|
113
|
+
digest
|
114
|
+
end
|
115
|
+
|
109
116
|
module ClassMethods
|
110
117
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
118
|
+
def create(parameters)
|
119
|
+
create!(parameters)
|
120
|
+
rescue
|
121
|
+
nil
|
122
|
+
end
|
116
123
|
|
117
|
-
|
118
|
-
|
119
|
-
|
124
|
+
def create!(parameters)
|
125
|
+
new.merge(parameters)
|
126
|
+
end
|
120
127
|
|
121
128
|
def attr_predicates(*arguments)
|
122
129
|
arguments.flatten.each do |field|
|
@@ -152,12 +159,12 @@ module CiteProc
|
|
152
159
|
attributes[field.to_sym] = value
|
153
160
|
end
|
154
161
|
end
|
155
|
-
|
162
|
+
|
156
163
|
predicate_id = [method_id, '?'].join
|
157
164
|
if predicate && !instance_methods.include?(predicate_id)
|
158
165
|
define_method(predicate_id) do
|
159
|
-
|
160
|
-
|
166
|
+
v = attributes[field.to_sym]
|
167
|
+
!(!v || (v.respond_to?(:empty?) && v.empty?) || v.to_s =~ /^(false|no|never)$/i)
|
161
168
|
end
|
162
169
|
|
163
170
|
has_predicate = ['has_', predicate_id].join
|