citeproc-ruby 0.0.6 → 1.0.0

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.
Files changed (186) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +1 -0
  3. data/.document +4 -0
  4. data/.gitignore +10 -0
  5. data/.rspec +3 -0
  6. data/.simplecov +4 -0
  7. data/.travis.yml +17 -0
  8. data/.yardopts +2 -0
  9. data/AGPL +662 -0
  10. data/BSDL +29 -0
  11. data/Gemfile +42 -0
  12. data/Guardfile +14 -0
  13. data/README.md +32 -76
  14. data/Rakefile +60 -0
  15. data/citeproc-ruby.gemspec +46 -0
  16. data/cucumber.yml +1 -0
  17. data/features/bibliography.feature +25 -0
  18. data/features/name_options.feature +37 -0
  19. data/features/names.feature +192 -0
  20. data/features/renderer.feature +74 -0
  21. data/features/sort.feature +50 -0
  22. data/features/step_definitions/renderer.rb +80 -0
  23. data/features/support/env.rb +33 -0
  24. data/features/support/hooks.rb +10 -0
  25. data/lib/citeproc/ruby.rb +32 -0
  26. data/lib/citeproc/ruby/engine.rb +122 -0
  27. data/lib/citeproc/ruby/format.rb +303 -0
  28. data/lib/citeproc/ruby/formats/default.rb +25 -0
  29. data/lib/citeproc/ruby/formats/html.rb +221 -0
  30. data/lib/citeproc/ruby/renderer.rb +140 -0
  31. data/lib/citeproc/ruby/renderer/choose.rb +106 -0
  32. data/lib/citeproc/ruby/renderer/date.rb +90 -0
  33. data/lib/citeproc/ruby/renderer/format.rb +129 -0
  34. data/lib/citeproc/ruby/renderer/group.rb +34 -0
  35. data/lib/citeproc/ruby/renderer/history.rb +40 -0
  36. data/lib/citeproc/ruby/renderer/label.rb +66 -0
  37. data/lib/citeproc/ruby/renderer/layout.rb +20 -0
  38. data/lib/citeproc/ruby/renderer/locale.rb +26 -0
  39. data/lib/citeproc/ruby/renderer/macro.rb +20 -0
  40. data/lib/citeproc/ruby/renderer/names.rb +401 -0
  41. data/lib/citeproc/ruby/renderer/number.rb +41 -0
  42. data/lib/citeproc/ruby/renderer/observer.rb +44 -0
  43. data/lib/citeproc/ruby/renderer/state.rb +96 -0
  44. data/lib/citeproc/ruby/renderer/text.rb +62 -0
  45. data/lib/citeproc/ruby/sort.rb +82 -0
  46. data/lib/citeproc/ruby/version.rb +5 -0
  47. data/spec/citeproc/ruby/engine_spec.rb +94 -0
  48. data/spec/citeproc/ruby/formats/default_spec.rb +159 -0
  49. data/spec/citeproc/ruby/formats/html_spec.rb +162 -0
  50. data/spec/citeproc/ruby/renderer/choose_spec.rb +293 -0
  51. data/spec/citeproc/ruby/renderer/date_spec.rb +173 -0
  52. data/spec/citeproc/ruby/renderer/group_spec.rb +88 -0
  53. data/spec/citeproc/ruby/renderer/history_spec.rb +38 -0
  54. data/spec/citeproc/ruby/renderer/label_spec.rb +225 -0
  55. data/spec/citeproc/ruby/renderer/layout_spec.rb +41 -0
  56. data/spec/citeproc/ruby/renderer/macro_spec.rb +31 -0
  57. data/spec/citeproc/ruby/renderer/names_spec.rb +396 -0
  58. data/spec/citeproc/ruby/renderer/number_spec.rb +120 -0
  59. data/spec/citeproc/ruby/renderer/text_spec.rb +120 -0
  60. data/spec/citeproc/ruby/renderer_spec.rb +65 -0
  61. data/spec/fixtures/items.rb +80 -0
  62. data/{resource/locale → spec/fixtures/locales}/locales-en-US.xml +2 -11
  63. data/{resource/locale → spec/fixtures/locales}/locales-fr-FR.xml +77 -66
  64. data/{resource/style → spec/fixtures/styles}/apa.csl +5 -5
  65. data/spec/spec_helper.rb +67 -14
  66. metadata +121 -211
  67. data/lib/citeproc.rb +0 -100
  68. data/lib/citeproc/bibliography.rb +0 -57
  69. data/lib/citeproc/data.rb +0 -149
  70. data/lib/citeproc/date.rb +0 -133
  71. data/lib/citeproc/formatter.rb +0 -38
  72. data/lib/citeproc/item.rb +0 -53
  73. data/lib/citeproc/name.rb +0 -284
  74. data/lib/citeproc/processor.rb +0 -166
  75. data/lib/citeproc/selector.rb +0 -61
  76. data/lib/citeproc/variable.rb +0 -82
  77. data/lib/citeproc/version.rb +0 -3
  78. data/lib/csl/locale.rb +0 -223
  79. data/lib/csl/node.rb +0 -72
  80. data/lib/csl/nodes.rb +0 -1418
  81. data/lib/csl/renderer.rb +0 -88
  82. data/lib/csl/sort.rb +0 -61
  83. data/lib/csl/style.rb +0 -110
  84. data/lib/csl/term.rb +0 -124
  85. data/lib/extensions/core.rb +0 -43
  86. data/lib/plugins/filters/bibtex.rb +0 -12
  87. data/lib/plugins/formats/default.rb +0 -134
  88. data/lib/plugins/formats/html.rb +0 -67
  89. data/lib/support/attributes.rb +0 -99
  90. data/lib/support/compatibility.rb +0 -83
  91. data/lib/support/tree.rb +0 -80
  92. data/resource/locale/locales-af-ZA.xml +0 -305
  93. data/resource/locale/locales-ar-AR.xml +0 -306
  94. data/resource/locale/locales-bg-BG.xml +0 -305
  95. data/resource/locale/locales-ca-AD.xml +0 -305
  96. data/resource/locale/locales-cs-CZ.xml +0 -305
  97. data/resource/locale/locales-da-DK.xml +0 -305
  98. data/resource/locale/locales-de-AT.xml +0 -304
  99. data/resource/locale/locales-de-CH.xml +0 -304
  100. data/resource/locale/locales-de-DE.xml +0 -332
  101. data/resource/locale/locales-el-GR.xml +0 -305
  102. data/resource/locale/locales-en-GB.xml +0 -304
  103. data/resource/locale/locales-es-ES.xml +0 -305
  104. data/resource/locale/locales-et-EE.xml +0 -304
  105. data/resource/locale/locales-eu.xml +0 -305
  106. data/resource/locale/locales-fa-IR.xml +0 -304
  107. data/resource/locale/locales-fi-FI.xml +0 -304
  108. data/resource/locale/locales-fr-CA.xml +0 -306
  109. data/resource/locale/locales-he-IL.xml +0 -304
  110. data/resource/locale/locales-hu-HU.xml +0 -305
  111. data/resource/locale/locales-is-IS.xml +0 -304
  112. data/resource/locale/locales-it-IT.xml +0 -305
  113. data/resource/locale/locales-ja-JP.xml +0 -305
  114. data/resource/locale/locales-kh-KH.xml +0 -303
  115. data/resource/locale/locales-km-KH.xml +0 -304
  116. data/resource/locale/locales-ko-KR.xml +0 -305
  117. data/resource/locale/locales-mn-MN.xml +0 -306
  118. data/resource/locale/locales-nb-NO.xml +0 -304
  119. data/resource/locale/locales-nl-NL.xml +0 -304
  120. data/resource/locale/locales-nn-NO.xml +0 -304
  121. data/resource/locale/locales-pl-PL.xml +0 -305
  122. data/resource/locale/locales-pt-BR.xml +0 -304
  123. data/resource/locale/locales-pt-PT.xml +0 -305
  124. data/resource/locale/locales-ro-RO.xml +0 -305
  125. data/resource/locale/locales-ru-RU.xml +0 -306
  126. data/resource/locale/locales-sk-SK.xml +0 -304
  127. data/resource/locale/locales-sl-SI.xml +0 -305
  128. data/resource/locale/locales-sr-RS.xml +0 -305
  129. data/resource/locale/locales-sv-SE.xml +0 -305
  130. data/resource/locale/locales-th-TH.xml +0 -304
  131. data/resource/locale/locales-tr-TR.xml +0 -305
  132. data/resource/locale/locales-uk-UA.xml +0 -306
  133. data/resource/locale/locales-vi-VN.xml +0 -305
  134. data/resource/locale/locales-zh-CN.xml +0 -304
  135. data/resource/locale/locales-zh-TW.xml +0 -305
  136. data/resource/schema/csl-categories.rnc +0 -39
  137. data/resource/schema/csl-data.rnc +0 -98
  138. data/resource/schema/csl-terms.rnc +0 -106
  139. data/resource/schema/csl-types.rnc +0 -39
  140. data/resource/schema/csl-variables.rnc +0 -182
  141. data/resource/schema/csl.rnc +0 -941
  142. data/resource/style/bibtex.csl +0 -177
  143. data/resource/style/chicago-annotated-bibliography.csl +0 -513
  144. data/resource/style/chicago-author-date-basque.csl +0 -707
  145. data/resource/style/chicago-author-date-de.csl +0 -394
  146. data/resource/style/chicago-author-date-listing.csl +0 -434
  147. data/resource/style/chicago-author-date.csl +0 -425
  148. data/resource/style/chicago-dated-note-biblio-no-ibid.csl +0 -472
  149. data/resource/style/chicago-fullnote-bibliography-bb.csl +0 -928
  150. data/resource/style/chicago-fullnote-bibliography-delimiter-fixes.csl +0 -972
  151. data/resource/style/chicago-fullnote-bibliography-no-ibid-delimiter-fixes.csl +0 -963
  152. data/resource/style/chicago-fullnote-bibliography-no-ibid.csl +0 -785
  153. data/resource/style/chicago-fullnote-bibliography.csl +0 -803
  154. data/resource/style/chicago-library-list.csl +0 -511
  155. data/resource/style/chicago-note-biblio-no-ibid.csl +0 -514
  156. data/resource/style/chicago-note-bibliography.csl +0 -530
  157. data/resource/style/chicago-note.csl +0 -388
  158. data/resource/style/chicago-quick-copy.csl +0 -685
  159. data/resource/style/ieee.csl +0 -299
  160. data/resource/style/mla-notes.csl +0 -796
  161. data/resource/style/mla-underline.csl +0 -175
  162. data/resource/style/mla-url.csl +0 -214
  163. data/resource/style/mla.csl +0 -394
  164. data/resource/style/vancouver-brackets.csl +0 -256
  165. data/resource/style/vancouver-superscript-bracket-only-year.csl +0 -165
  166. data/resource/style/vancouver-superscript.csl +0 -256
  167. data/resource/style/vancouver.csl +0 -256
  168. data/spec/citeproc/bibliography_spec.rb +0 -45
  169. data/spec/citeproc/citeproc_spec.rb +0 -80
  170. data/spec/citeproc/date_spec.rb +0 -89
  171. data/spec/citeproc/formatter_spec.rb +0 -101
  172. data/spec/citeproc/item_spec.rb +0 -71
  173. data/spec/citeproc/name_spec.rb +0 -30
  174. data/spec/citeproc/processor_spec.rb +0 -61
  175. data/spec/citeproc/selector_spec.rb +0 -82
  176. data/spec/citeproc/variable_spec.rb +0 -69
  177. data/spec/csl/locale_spec.rb +0 -208
  178. data/spec/csl/node_spec.rb +0 -25
  179. data/spec/csl/nodes_spec.rb +0 -145
  180. data/spec/csl/style_spec.rb +0 -62
  181. data/spec/csl/term_spec.rb +0 -56
  182. data/spec/fixtures/dates.yaml +0 -80
  183. data/spec/fixtures/names.yaml +0 -115
  184. data/spec/fixtures/nodes.yaml +0 -245
  185. data/spec/support/attributes_spec.rb +0 -39
  186. data/spec/support/tree_spec.rb +0 -163
data/lib/citeproc/item.rb DELETED
@@ -1,53 +0,0 @@
1
- require 'observer'
2
-
3
- module CiteProc
4
-
5
- class Item
6
- include Comparable
7
- include Observable
8
- include Support::Attributes
9
-
10
- attr_fields Variable.fields
11
- attr_fields %w{ locator label suppress-author author-only prefix suffix }
12
-
13
- def initialize(attributes={}, filter=nil)
14
- self.merge!(attributes)
15
- yield self if block_given?
16
- end
17
-
18
- def self.filter(attributes, filter)
19
- # TODO
20
- end
21
-
22
- # @see CSL::Nodes::Group
23
- alias :access :[]
24
- def [](key)
25
- value = access(key)
26
- changed
27
- notify_observers(key, value)
28
- value
29
- end
30
-
31
- def merge!(other)
32
- other = other.attributes unless other.is_a?(Hash)
33
- other.each_pair { |key, value| self.attributes[key] = Variable.parse(value, key) }
34
- self
35
- end
36
-
37
- def reverse_merge!(other)
38
- other = other.attributes unless other.is_a?(Hash)
39
- other.each_pair { |key, value| self.attributes[key] ||= Variable.parse(value, key) }
40
- self
41
- end
42
-
43
- def to_s
44
- self.attributes.inspect
45
- end
46
-
47
-
48
- def <=>(other)
49
- self.attributes <=> other.attributes
50
- end
51
- end
52
-
53
- end
data/lib/citeproc/name.rb DELETED
@@ -1,284 +0,0 @@
1
- module CiteProc
2
-
3
-
4
- # == Name Variables
5
- #
6
- # When present in the item data, CSL name variables must be delivered as a
7
- # list of JavaScript arrays, with one array for each name represented by the
8
- # variable. Simple personal names are composed of family and given elements,
9
- # containing respectively the family and given name of the individual.
10
- #
11
- # { "author" : [
12
- # { "family" : "Doe", "given" : "Jonathan" },
13
- # { "family" : "Roe", "given" : "Jane" }
14
- # ],
15
- # "editor" : [
16
- # { "family" : "Saunders",
17
- # "given" : "John Bertrand de Cusance Morant" }
18
- # ]
19
- # }
20
- #
21
- # Institutional and other names that should always be presented literally
22
- # (such as "The Artist Formerly Known as Prince", "Banksy", or "Ramses IV")
23
- # should be delivered as a single literal element in the name array:
24
- #
25
- # { "author" : [
26
- # { "literal" : "Society for Putting Things on Top of Other Things" }
27
- # ]
28
- # }
29
- #
30
- # If the name is spelled using a 'byzantine' alphabet (i.e., latin or
31
- # cyrillic) its sort and display order is computed according to the given
32
- # arguments.
33
- #
34
- class Name < Variable
35
-
36
- # Based on the regular expression in citeproc-js
37
- ROMANESQUE = /^[a-zA-Z\u0080-\u017f\u0400-\u052f\u0386-\u03fb\u1f00-\u1ffe\.,\s'\u0027\u02bc\u2019-]*$/
38
-
39
- Variable.name_fields.each { |field| Variable.types[field] = Name }
40
-
41
- attr_fields %w{ given family literal suffix dropping-particle
42
- non-dropping-particle comma-suffix static-ordering parse-names }
43
-
44
- [[:last, :family], [:first, :given]].each do |m|
45
- alias_method m[0], m[1]
46
- end
47
-
48
- def defaults
49
- Hash['form', 'long', 'name-as-sort-order', 'false', 'demote-non-dropping-particle', 'display-and-sort']
50
- end
51
-
52
- def options
53
- @options ||= defaults
54
- end
55
-
56
- def merge_options(options)
57
- options.each_pair { |key, value| self.options[key] = value unless value.nil? }
58
- end
59
-
60
- def parse!(argument)
61
- return super unless argument.is_a?(String)
62
- parse_name!(argument)
63
- end
64
-
65
- def merge!(argument)
66
- if argument['parse-names'] && argument.delete('parse-names') != 'false'
67
- parse_family!(argument.delete('family'))
68
- parse_given!(argument.delete('given'))
69
- end
70
-
71
- argument.map { |key, value| self[key] = value }
72
- end
73
-
74
- def given
75
- initialize? ? to_initials(self['given']) : self['given']
76
- end
77
-
78
- def to_initials(name)
79
- return name if name.nil?
80
-
81
- name.split(/\s+|\.\s*/).map do |token|
82
- token.split(/-/).map do |part|
83
- # Keep all-lowercase names; otherwise keep only upper case letters
84
- part.match(/^[[:lower:]]+$/) ? part.center(part.length + 2) : part.scan(/[[:upper:]]/).join.capitalize + options['initialize-with']
85
- end.join(options['initialize-with-hyphen'] == 'false' ? '' : '-' ).gsub(/\s+-/, '-')
86
- end.join
87
- end
88
-
89
- # Parses a string and sets :family, :given, :suffix, and :particles
90
- # correspondingly.
91
- #
92
- # * non-dropping-particle: A string at the beginning of the family field
93
- # consisting of spaces and lowercase roman or Cyrillic characters will
94
- # be treated as a non-dropping-particle. The particles preceding some
95
- # names should be treated as part of the last name, depending on the
96
- # cultural heritage and personal preferences of the individual. To
97
- # suppress parsing and treat such particles as part of the family name
98
- # field, enclose the family name field content in double-quotes
99
- # * dropping-particle: A string at the end of the given name field
100
- # consisting of spaces and lowercase roman or Cyrillic characters will
101
- # be treated as a dropping-particle.
102
- # * suffix: Content following a comma in the given name field will be
103
- # parse out as a name suffix. Modern typographical convention does not
104
- # place a comma between suffixes such as "Jr." and the last name, when
105
- # rendering the name in normal order: "John Doe Jr." If an individual
106
- # prefers that the traditional comma be used in rendering their name,
107
- # the comma can be force by placing a exclamation mark after the comma.
108
- #
109
- def parse_name!(string)
110
- return if string.nil?
111
-
112
- tokens = string.split(/,\s+/)
113
-
114
- parse_family!(tokens[0])
115
- parse_given!(tokens[1])
116
-
117
- self
118
- end
119
-
120
- # @see parse
121
- def parse_family!(string)
122
- return if string.nil?
123
-
124
- tokens = string.scan(/^['"](.+)['"]$|^([[:lower:]\s]+)?([[:upper:]][[:alpha:]\s]*)$/).first
125
-
126
- if tokens.nil?
127
- self['family'] = string
128
- else
129
- self['family'] = tokens[0] || tokens[2] || string
130
- self['non-dropping-particle'] = tokens[1].gsub(/^\s+|\s+$/, '') unless tokens[1].nil?
131
- end
132
-
133
- self
134
- end
135
-
136
- # @see parse
137
- def parse_given!(string)
138
- return if string.nil?
139
-
140
- tokens = string.scan(/^((?:[[:upper:]][[:alpha:]\.]*\s*)+)([[:lower:]\s]+)?(?:,!?\s([[:alpha:]\.\s]+))?$/).first
141
-
142
- if tokens.nil?
143
- self['given'] = string
144
- else
145
- self['given'] = (tokens[0] || string).gsub(/^\s+|\s+$/, '')
146
- self['dropping-particle'] = tokens[1] unless tokens[1].nil?
147
- self['suffix'] = tokens[2] unless tokens[2].nil?
148
- self['comma-suffix'] = 'true' if string.match(/,!/)
149
- end
150
-
151
- self
152
- end
153
-
154
- def personal?
155
- self.family?
156
- end
157
-
158
- def romanesque?
159
- (self['given'].nil? || self['given'].match(ROMANESQUE)) && (self['family'].nil? || self['family'].match(ROMANESQUE))
160
- end
161
-
162
- alias :byzantine? :romanesque?
163
-
164
- def comma_suffix
165
- self.comma_suffix? && self.suffix? ? comma : nil
166
- end
167
-
168
- def comma
169
- options['sort-separator'] || ', '
170
- end
171
-
172
- def delimiter
173
- romanesque? ? ' ' : ''
174
- end
175
-
176
- def value
177
- self
178
- end
179
-
180
- #
181
- # CSL1.0 Warning
182
- #
183
- # @returns true if, using the current options, the name's given name is
184
- # to be displayed using initials. Takes into account whether or not the
185
- # family name is set (if not, given name should not be turned to initials,
186
- # this is *not* sepcified in CSL 1.0).
187
- #
188
- def initialize?
189
- options.has_key?('initialize-with') && family? && romanesque?
190
- end
191
-
192
- def static_order?
193
- static_ordering? || !romanesque?
194
- end
195
-
196
- def sort_order?
197
- ['all', 'true', 'yes', 'always'].include?(options['name-as-sort-order'])
198
- end
199
-
200
- def numeric?
201
- false
202
- end
203
-
204
- # @returns a list of strings, representing a given order of the individual
205
- # tokens when displaying the name.
206
- def display_order(opts={})
207
- merge_options(opts)
208
-
209
- case
210
- when literal?
211
- return %w{ literal }
212
-
213
- when static_order?
214
- return %w{ family given }
215
-
216
- when options['form'] != 'short' && !sort_order?
217
- return %w{ given dropping-particle non-dropping-particle family comma-suffix suffix }
218
-
219
- when options['form'] != 'short' && sort_order? && ['never', 'sort-only'].include?(options['demote-non-dropping-particle'])
220
- return %w{ non-dropping-particle family comma given dropping-particle comma suffix }
221
-
222
- when options['form'] != 'short' && sort_order? && options['demote-non-dropping-particle'] == 'display-and-sort'
223
- return %w{ family comma given dropping-particle non-dropping-particle comma suffix }
224
-
225
- else # options['form'] == 'short'
226
- return %w{ non-dropping-particle family}
227
- end
228
-
229
- end
230
-
231
- # @returns a list of strings, representing the order of precedence of the
232
- # individual tokens when sorting the name.
233
- def sort_order(opts={})
234
- merge_options(opts)
235
-
236
- case
237
- when literal?
238
- return %w{ literal }
239
-
240
- when options['demote-non-dropping-particle'] == 'never'
241
- return %w{ non-dropping-particle+family dropping-particle given suffix }
242
- else
243
- return %w{ family non-dropping-particle+dropping-particle given suffix }
244
- end
245
- end
246
-
247
- # @returns a string representing the name according to the given set of
248
- # display order options.
249
- def display(options={})
250
- normalize((display_order(options).map { |token| send(token.tr('-', '_')) }.compact.join(delimiter)))
251
- end
252
-
253
- def normalize(string)
254
- string.squeeze(' ').gsub(/^[\s,]+|[\s,]+$|\s(,)/, '\1').squeeze(',')
255
- end
256
-
257
- def to_s
258
- display
259
- end
260
-
261
- def literal_as_sort_order
262
- literal.gsub(/^(the|an?|der|die|das|eine?|l[ae])\s+/i, '')
263
- end
264
-
265
- def <=>(other)
266
-
267
- tests = self.sort_order.zip(other.sort_order).map do |pair|
268
- this, that = pair.map { |token| token.gsub(/[\s-]+/,'_').gsub(/literal/, 'literal_sort_order') }
269
-
270
- this = this.split(/\+/).map { |token| self.send(token) }.join.downcase
271
- that = that.split(/\+/).map { |token| other.send(token) }.join.downcase
272
-
273
- # TODO should we ignore '' here?
274
- this <=> that
275
- end
276
-
277
- tests = tests.reject(&:nil?)
278
- zeroes = tests.take_while(&:zero?)
279
-
280
- zeroes.length != tests.length ? tests[zeroes.length] : zeroes.empty? ? nil : 0
281
- end
282
- end
283
-
284
- end
@@ -1,166 +0,0 @@
1
- require 'forwardable'
2
-
3
- module CiteProc
4
-
5
- class Processor
6
- extend Forwardable
7
-
8
- attr_reader :style, :formatter
9
-
10
- def initialize
11
- @formatter = Formatter.new
12
- yield self if block_given?
13
- end
14
-
15
- def self.process(items, options = {})
16
- return '' if items.nil? || items.empty?
17
-
18
- processor = Processor.new do |p|
19
- p.style = options[:style] || CSL.default_style
20
- p.locale = options[:locale] || CSL.default_locale
21
- p.format = options[:format] || :default
22
- p.import(items)
23
- end
24
-
25
- if options[:mode].to_s.match(/cit(e|ation)/i)
26
- processor.cite(:all).map(&:last)
27
- else
28
- processor.bibliography.data.join
29
- end
30
- end
31
-
32
- def self.cite(items, options = {})
33
- process(items, options.merge(:mode => 'citation'))
34
- end
35
-
36
-
37
- def style=(resource)
38
- @style = resource.is_a?(CSL::Style) ? resource : CSL::Style.new(resource)
39
- end
40
-
41
- def format(*args); @formatter.format(*args); end
42
-
43
- def format=(format); @formatter.format = format; end
44
-
45
- def locale=(locale)
46
- @locale = locale.is_a?(CSL::Locale) ? locale : CSL::Locale.new(locale)
47
- end
48
-
49
- def locale
50
- @locale ||= CSL.default_locale
51
- end
52
-
53
- def_delegators :locale, :language, :language=, :region, :region=
54
-
55
- # @returns the abbreviations, a self-recording hash.
56
- def abbreviations
57
- @abbreviations ||= new_abbreviations
58
- end
59
-
60
- alias :transfrom :abbreviations
61
-
62
- def abbreviations=(abbreviations)
63
- @abbreviations = new_abbreviations
64
- add_abbreviations(abbreviations)
65
- end
66
-
67
- def add_abbreviations(abbreviations)
68
- abbreviations.keys.each do |list|
69
- abbreviations[list].keys.each do |category|
70
- abbreviations[list][category].each_pair do |long, short|
71
- self.abbreviations[list] ||= new_self_recording_hash
72
- self.abbreviations[list][category][long] = short
73
- end
74
- end
75
- end
76
- end
77
-
78
- def abbreviate(category, name, list='default')
79
- self.abbreviations[list][category][name]
80
- end
81
-
82
- def items
83
- @items ||= {}
84
- end
85
-
86
- def import(items)
87
- # TODO assign default ids if no id
88
- items = to_a(items)
89
- items.each do |item|
90
- item = Item.new(item)
91
- self.items[item['id'].to_s] = item
92
- end
93
- end
94
-
95
- def bibliography(selector = :all)
96
- data = items.values.select(&Selector.new(selector)).map { |i| { 'id' => i.id } }
97
- data = CitationData.new(data).populate!(items)
98
-
99
- data = style.bibliography.process(data, self)
100
- Bibliography.new(data)
101
- end
102
-
103
-
104
- #
105
- # @param data Symbol :all / or id of item
106
- # @param data String id of item
107
- # @param data Array list of ids or citation data
108
- # @param data Hash citation data or citation items
109
- #
110
- # @returns a list of lists; [[1, 'Doe, 2000, p. 1'], ...]
111
- #
112
- def cite(data)
113
- data = extract_citation_data(data)
114
-
115
- data.populate!(items)
116
- citation = style.citation.render(data, self)
117
-
118
- [[register(citation), citation]]
119
- end
120
-
121
- def nocite(ids, options={})
122
- @bibliography + to_a(ids).map { |id| items[id] }
123
- end
124
-
125
- alias :make_bibliography :bibliography
126
- alias :update_items :cite
127
- alias :update_uncited_items :nocite
128
-
129
-
130
- private
131
-
132
- def register(id)
133
- 1
134
- end
135
-
136
- def to_a(attribute)
137
- attribute.is_a?(Array) ? attribute : [attribute]
138
- end
139
-
140
- # @returns a citation data object
141
- def extract_citation_data(argument)
142
- case
143
- when argument == :all
144
- argument = items.keys.map { |id| { 'id' => id } }
145
-
146
- when items.has_key?(argument.to_s)
147
- argument = { 'id' => argument.to_s }
148
-
149
- when argument.is_a?(Array) && items.has_key?(argument.first.to_s)
150
- argument = argument.map { |id| { 'id' => id } }
151
-
152
- end
153
-
154
- CitationData.new(argument)
155
- end
156
-
157
- def new_abbreviations
158
- { 'default' => new_self_recording_hash }
159
- end
160
-
161
- def new_self_recording_hash
162
- Hash.new { |hash, key| hash[key] = Hash.new { |h,k| h[k] = k } }
163
- end
164
- end
165
-
166
- end