citeproc 0.0.3 → 0.0.6

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.
@@ -1,22 +1,22 @@
1
1
  require 'forwardable'
2
2
 
3
3
  module CiteProc
4
-
4
+
5
5
  class Engine
6
-
7
6
  extend Forwardable
8
- include Abbreviate
9
-
7
+
8
+ include Converters
9
+
10
10
  @subclasses ||= []
11
11
 
12
12
  class << self
13
-
13
+
14
14
  attr_reader :subclasses, :type, :version
15
-
15
+
16
16
  attr_writer :default
17
-
17
+
18
18
  private :new
19
-
19
+
20
20
  def inherited(subclass)
21
21
  subclass.public_class_method :new
22
22
  @subclasses << subclass
@@ -34,33 +34,33 @@ module CiteProc
34
34
  subclasses.detect { |e| e.name == name } ||
35
35
  block_given? ? yield(subclasses) : nil
36
36
  end
37
-
37
+
38
38
  # Loads the engine with the given name and returns the engine class.
39
39
  def detect!(name)
40
40
  load(name)
41
41
  block_given? ? detect(name, &Proc.new) : detect(name)
42
42
  end
43
-
43
+
44
44
  # Returns the best available engine class or nil.
45
45
  def autodetect(options = {})
46
46
  subclasses.detect { |e|
47
47
  !options.has_key?(:engine) || e.name == options[:engine] and
48
48
  !options.has_key?(:name) || e.name == options[:name]
49
- } || subclasses.first
49
+ } || subclasses.first
50
50
  end
51
-
51
+
52
52
  # Loads the engine by requiring the engine name.
53
53
  def load(name)
54
54
  require name.gsub(/-/,'/')
55
55
  rescue LoadError
56
56
  warn "failed to load #{name} engine: try to gem install #{name}"
57
57
  end
58
-
58
+
59
59
  # Returns a list of all available engine names.
60
60
  def available
61
61
  subclasses.map(&:engine_name)
62
62
  end
63
-
63
+
64
64
  def engine_name
65
65
  @name ||= name.gsub(/::/, '-').downcase # returns class name as fallback
66
66
  end
@@ -70,64 +70,45 @@ module CiteProc
70
70
  end
71
71
  end
72
72
 
73
- attr_accessor :processor, :locales, :style, :items
74
-
75
- def initialize(attributes = {})
76
- @processor = attributes[:processor]
77
-
78
- @items = attributes[:items] || {}
79
- @abbreviations = attributes[:abbreviations] || { :default => {} }
80
-
73
+ attr_accessor :processor
74
+
75
+ def_delegators :@processor, :options, :abbreviations, :style, :locale,
76
+ :items, :language, :region, :abbreviate
77
+
78
+ def initialize(processor = nil)
79
+ @processor = processor
81
80
  yield self if block_given?
82
81
  end
83
82
 
84
- def start
85
- @started = true
86
- self
87
- end
88
-
89
- def stop
90
- @started = false
91
- self
92
- end
93
-
94
- def started?; !!@started; end
95
-
96
- alias running? started?
97
-
98
83
  [[:name, :engine_name], :type, :version].each do |method_id, target|
99
84
  define_method(method_id) do
100
85
  self.class.send(target || method_id)
101
86
  end
102
87
  end
103
-
88
+
104
89
  def process
105
90
  raise NotImplementedByEngine
106
91
  end
107
-
108
- alias process_citation_cluster process
109
92
 
110
93
  def append
111
94
  raise NotImplementedByEngine
112
95
  end
113
-
114
- alias append_citation_cluster append
115
96
 
116
-
117
97
  def bibliography
118
98
  raise NotImplementedByEngine
119
99
  end
120
-
121
- alias make_bibliography bibliography
122
-
100
+
123
101
  def update_items
124
102
  raise NotImplementedByEngine
125
103
  end
126
-
104
+
127
105
  def update_uncited_items
128
106
  raise NotImplementedByEngine
129
107
  end
130
-
108
+
109
+ def inspect
110
+ "#<CiteProc::Engine #{name}-#{type}-#{version}>"
111
+ end
131
112
  end
132
113
 
133
114
  end
data/lib/citeproc/item.rb CHANGED
@@ -1,113 +1,122 @@
1
1
  module CiteProc
2
-
3
- # Items are similar to a Ruby Hash but pose a number of constraints on their
4
- # contents: keys are always (implicitly converted to) symbols and values
5
- # are strictly instances of CiteProc::Variable. When Items are constructed
6
- # from (or merged with) JSON objects or Hashes Variable instances are
7
- # automatically created using by passing the variables key as type to
8
- # Variable.create this will create the expected Variable type for all
9
- # fields defined in CSL (for example, the `issued' field will become a
10
- # CiteProc::Date object); unknown types will be converted to simple
11
- # CiteProc::Variable instances, which should be fine for numeric or string
12
- # values but may cause problems for more complex types.
13
- #
14
- # Every Item provides accessor methods for all known field names; unknown
15
- # fields can still be accessed using array accessor syntax.
16
- #
17
- # i = Item.new(:edition => 3, :unknown_field => 42)
18
- # i.edition -> #<CiteProc::Number "3">
19
- # i[:edition] -> #<CiteProc::Number "3">
20
- # i[:unknown_field] -> #<CiteProc::Variable "42">
21
- #
22
- # Items can be converted to the CiteProc JSON format via #to_citeproc (or
23
- # #to_json to get a JSON string).
24
- class Item
25
-
26
- @types = [
27
- :article, :'article-journal', :'article-magazine', :'article-newspaper',
28
- :bill, :book, :broadcast, :chapter, :entry, :'entry-dictionary',
29
- :'entry-encyclopedia', :figure, :graphic, :interview, :legal_case,
30
- :legislation, :manuscript, :map, :motion_picture, :musical_score,
31
- :pamphlet, :'paper-conference', :patent, :personal_communication, :post,
32
- :'post-weblog', :report, :review, :'review-book', :song, :speech,
33
- :thesis, :treaty, :webpage].freeze
34
-
35
- @bibtex_types = Hash.new { |h,k| :misc }.merge(Hash[*%w{
36
- pamphlet booklet
37
- paper-conference conference
38
- chapter inbook
39
- chapter incollection
40
- paper-conference inproceedings
41
- book manual
42
- thesis phdthesis
43
- paper-conference proceedings
44
- report techreport
45
- manuscript unpublished
46
- article article
47
- article-journal article
48
- article-magazine article
49
- }.map(&:intern)]).freeze
50
-
51
- class << self
52
- attr_reader :types, :bibtex_types
53
- end
54
-
55
- include Attributes
56
- include Enumerable
57
-
58
- attr_predicates :id, :'short-title', :'journal-abbreviation',
59
- *Variable.fields[:all]
60
-
61
- def initialize(attributes = nil)
62
- merge(attributes)
63
- end
64
-
65
- def initialize_copy(other)
66
- @attributes = other.attributes.deep_copy
67
- end
2
+
3
+
4
+ # Items are similar to a Ruby Hash but pose a number of constraints on their
5
+ # contents: keys are always (implicitly converted to) symbols and values
6
+ # are strictly instances of CiteProc::Variable. When Items are constructed
7
+ # from (or merged with) JSON objects or Hashes Variable instances are
8
+ # automatically created using by passing the variables key as type to
9
+ # Variable.create this will create the expected Variable type for all
10
+ # fields defined in CSL (for example, the `issued' field will become a
11
+ # CiteProc::Date object); unknown types will be converted to simple
12
+ # CiteProc::Variable instances, which should be fine for numeric or string
13
+ # values but may cause problems for more complex types.
14
+ #
15
+ # Every Item provides accessor methods for all known field names; unknown
16
+ # fields can still be accessed using array accessor syntax.
17
+ #
18
+ # i = Item.new(:edition => 3, :unknown_field => 42)
19
+ # i.edition -> #<CiteProc::Number "3">
20
+ # i[:edition] -> #<CiteProc::Number "3">
21
+ # i[:unknown_field] -> #<CiteProc::Variable "42">
22
+ #
23
+ # Items can be converted to the CiteProc JSON format via #to_citeproc (or
24
+ # #to_json to get a JSON string).
25
+ class Item
68
26
 
69
- # Don't expose attributes. Items need to mimic Hash functionality in a controlled way.
70
- private :attributes
71
-
72
- def each
73
- if block_given?
74
- attributes.each(&Proc.new)
75
- self
76
- else
77
- to_enum
78
- end
79
- end
80
-
81
- # Returns a corresponding BibTeX::Entry if the bibtex-ruby gem is installed;
82
- # otherwise returns a BibTeX string.
83
- def to_bibtex
84
- # hash = to_hash
85
- #
86
- # hash[:type] = Item.bibtex_types[hash[:type]]
87
- #
88
- # if hash.has_key?(:issued)
89
- # date = hash.delete(:issued)
90
- # hash[:year] = date.year
91
- # hash[:month] = date.month
92
- # end
93
- #
94
- # Variable.fields[:date].each do |field|
95
- # hash[field] = hash[field].to_s if hash.has_key?(field)
96
- # end
97
- #
98
- # Variable.fields[:names].each do |field|
99
- # hash[field] = hash[field].map(&:sort_order!).join(' and ')
100
- # end
101
-
102
- raise 'not implemented yet'
103
- end
104
-
105
- private
106
-
107
- def filter_value(value, key)
108
- Variable.create!(value, key)
109
- end
27
+ @types = [
28
+ :article, :'article-journal', :'article-magazine', :'article-newspaper',
29
+ :bill, :book, :broadcast, :chapter, :entry, :'entry-dictionary',
30
+ :'entry-encyclopedia', :figure, :graphic, :interview, :legal_case,
31
+ :legislation, :manuscript, :map, :motion_picture, :musical_score,
32
+ :pamphlet, :'paper-conference', :patent, :personal_communication, :post,
33
+ :'post-weblog', :report, :review, :'review-book', :song, :speech,
34
+ :thesis, :treaty, :webpage].freeze
35
+
36
+ @bibtex_types = Hash.new { |h,k| :misc }.merge(Hash[*%w{
37
+ pamphlet booklet
38
+ paper-conference conference
39
+ chapter inbook
40
+ chapter incollection
41
+ paper-conference inproceedings
42
+ book manual
43
+ thesis phdthesis
44
+ paper-conference proceedings
45
+ report techreport
46
+ manuscript unpublished
47
+ article article
48
+ article-journal article
49
+ article-magazine article
50
+ }.map(&:intern)]).freeze
51
+
52
+ class << self
53
+ attr_reader :types, :bibtex_types
54
+ end
55
+
56
+ include Attributes
57
+ include Enumerable
58
+
59
+ attr_predicates :id, :'short-title', :'journal-abbreviation',
60
+ *Variable.fields[:all]
61
+
62
+ def initialize(attributes = nil)
63
+ merge(attributes)
64
+ end
65
+
66
+ def initialize_copy(other)
67
+ @attributes = other.attributes.deep_copy
68
+ end
69
+
70
+ # Don't expose attributes. Items need to mimic Hash functionality in a controlled way.
71
+ private :attributes
72
+
73
+ def each
74
+ if block_given?
75
+ attributes.each(&Proc.new)
76
+ self
77
+ else
78
+ to_enum
79
+ end
80
+ end
81
+
82
+ # Returns a corresponding BibTeX::Entry if the bibtex-ruby gem is installed;
83
+ # otherwise returns a BibTeX string.
84
+ def to_bibtex
85
+ # hash = to_hash
86
+ #
87
+ # hash[:type] = Item.bibtex_types[hash[:type]]
88
+ #
89
+ # if hash.has_key?(:issued)
90
+ # date = hash.delete(:issued)
91
+ # hash[:year] = date.year
92
+ # hash[:month] = date.month
93
+ # end
94
+ #
95
+ # Variable.fields[:date].each do |field|
96
+ # hash[field] = hash[field].to_s if hash.has_key?(field)
97
+ # end
98
+ #
99
+ # Variable.fields[:names].each do |field|
100
+ # hash[field] = hash[field].to_bibtex
101
+ # end
102
+
103
+ raise 'not implemented yet'
104
+ end
105
+
106
+ def to_sym
107
+ id.to_s.to_sym
108
+ end
109
+
110
+ def inspect
111
+ "#<CiteProc::Item id=#{id.inspect} attributes={#{attributes.length}}>"
112
+ end
113
+
114
+ private
110
115
 
111
- end
116
+ def filter_value(value, key)
117
+ Variable.create!(value, key)
118
+ end
112
119
 
120
+ end
121
+
113
122
  end
@@ -1,8 +1,11 @@
1
1
 
2
2
  module CiteProc
3
+
3
4
  class Processor
4
-
5
5
  extend Forwardable
6
+
7
+ include Abbreviate
8
+ include Converters
6
9
 
7
10
  @defaults = {
8
11
  :locale => 'en-US',
@@ -15,41 +18,105 @@ module CiteProc
15
18
  attr_reader :defaults
16
19
  end
17
20
 
18
- attr_reader :options, :engine, :items, :style
21
+ attr_reader :options, :items
22
+ attr_writer :engine
23
+
24
+ def_delegators :@locale, :language, :region
25
+
26
+ def_delegators :@items, :key?, :value?, :has_key?, :has_value?,
27
+ :include?, :member?, :length, :empty?
19
28
 
20
- def_delegators :@engine, :abbreviate, :abbreviations, :abbreviations=
21
-
22
29
  def initialize(options = {})
23
- @options = Processor.defaults.merge(options)
24
- @engine = Engine.autodetect(@options).new(:processor => self)
25
- @style = Style.load(@options[:style])
26
- @locales = @options[:locale]
27
- @items = {}
28
- end
29
-
30
- def style=(style)
31
- @style = Style.load(style.to_s)
32
- @engine.style = @style
33
- @style
34
- end
35
-
36
- def locales=(locale)
37
- @locales = { locale.to_sym => Locale.load(locale.to_s) }
38
- @engine.locales = @locales
39
- @locales
40
- end
41
-
42
- def process(*arguments)
43
- @engine.process(CitationData(arguments.flatten(1)))
44
- end
45
-
46
- def append(*arguments)
47
- @engine.append(CitationData(arguments.flatten(1)))
48
- end
49
-
50
- def bibliography(*arguments, &block)
51
- @engine.bibliography(Selector.new(*arguments, &block))
52
- end
53
-
30
+ @options, @items = Processor.defaults.merge(options), {}
31
+ yield self if block_given?
32
+ end
33
+
34
+ def engine
35
+ @engine ||= Engine.autodetect(options).new(self)
36
+ end
37
+
38
+ def style
39
+ @style || load_style
40
+ end
41
+
42
+ def locale
43
+ @locale || load_locale
44
+ end
45
+
46
+ def load_style(new_style = nil)
47
+ options[:style] = new_style unless new_style.nil?
48
+ @style = Style.open(options[:style])
49
+ end
50
+
51
+ def load_locale(new_locale = nil)
52
+ options[:locale] = new_locale unless new_locale.nil?
53
+ @locale = Locale.open(options[:locale])
54
+ end
55
+
56
+ def [](id)
57
+ items[id.to_sym]
58
+ end
59
+
60
+ def []=(id, item)
61
+ items[id.to_sym] = Item(item)
62
+ end
63
+
64
+ def register(item)
65
+ item = Item(item)
66
+ items[item.to_sym] = item
67
+ rescue => e
68
+ raise "failed to register item #{item.inspect}: #{e.message}"
69
+ end
70
+
71
+ def <<(item)
72
+ register(item)
73
+ self
74
+ end
75
+
76
+ def update(*arguments)
77
+ arguments.flatten(1).each do |argument|
78
+ case argument
79
+ when Item
80
+ register(argument)
81
+ when Array
82
+ argument.each { |item| register(item) }
83
+ when Hash
84
+ argument.each do |id, item|
85
+ id, item = id.to_sym, Item(item)
86
+
87
+ if items.key?(id) && block_given?
88
+ items[id] = yield items[id], item
89
+ else
90
+ items[id] = item
91
+ end
92
+ end
93
+ else
94
+ raise "failed to register items #{argument.inspect}"
95
+ end
96
+ end
97
+
98
+ self
99
+ ensure
100
+ # notify engine
101
+ end
102
+
103
+
104
+
105
+ def process(*arguments)
106
+ engine.process(CitationData(arguments.flatten(1)))
107
+ end
108
+
109
+ def append(*arguments)
110
+ engine.append(CitationData(arguments.flatten(1)))
111
+ end
112
+
113
+ def bibliography(*arguments, &block)
114
+ engine.bibliography(Selector.new(*arguments, &block))
115
+ end
116
+
117
+ def inspect
118
+ "#<CiteProc::Processor style=#{style.name.inspect} locale=#{locale.name.inspect} items=[#{items.length}]>"
119
+ end
120
+
54
121
  end
55
122
  end