citeproc 1.3.0 → 2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8708658d44ed66deb17744c846697187edbcd1f6dc308c4bf3bc69933ede3e7e
4
- data.tar.gz: 1d1af4037b6dae14f20adffdbb7e51b35ecd02728586f95932348416788347c1
3
+ metadata.gz: 21838f9d914cb947a14c36bf1b65271170de7a12d40eb069921e3a2ab3fe8a2a
4
+ data.tar.gz: bf916ee190ab7850caacde982b7510ffa045d2d5e276b30e9cd3a112ef644e7b
5
5
  SHA512:
6
- metadata.gz: 4dc2d276583d4071cf17459265a3c706f8eb4091c59527a80506241e8f5187de4eba9f6cb140e560327fde38f8e8225348818dfeda0e1b2b98ef53acb67c5064
7
- data.tar.gz: 33de631e29bd0e3484a0509e4f61bfb4e2b59fe87aeb8e7cbd25c1d9065ce20588637725f00d9f88ab2e19bcee765d3a19bc71d25adced9135d6a74627018279
6
+ metadata.gz: 7e4d56b5e112d3a3b94b931f648a75947efce1613f33ce147991ff9d8e2497ba33c002a547f403c9977ff65f6375ce2ebf7edbbe958ec3ea5b8daebfc819ba4c
7
+ data.tar.gz: 3be138495514a7f85ab8df3e22215c181069d0417aa8a863173592618fab37741e5b5691a3b52770deefcd7fb2bfed95077172c3f994b558e54daa0df11605db
data/README.md CHANGED
@@ -110,6 +110,18 @@ to install all official CSL styles and locales.
110
110
  To make the styles and locales available,
111
111
  simply `require 'csl/styles'`.
112
112
 
113
+ Development
114
+ -----------
115
+ To get started, install the development dependencies and run all tests:
116
+
117
+ $ bundle install
118
+ $ bundle exec rake
119
+
120
+ The [CSL test-suite](https://github.com/citation-style-language/test-suite)
121
+ runs as Cucumber features using CiteProc-Ruby:
122
+
123
+ $ bundle exec cucumber
124
+
113
125
  Credits
114
126
  -------
115
127
  Thanks to Rintze M. Zelle, Sebastian Karcher, Frank G. Bennett, Jr.,
@@ -132,14 +132,28 @@ module CiteProc
132
132
  read_attribute(:label) || ('page' if locator?)
133
133
  end
134
134
 
135
- # Moves a label at the start of the locator into the label
136
- # (e.g., "vol. 1" becomes "1" with the label "volume") unless
137
- # the item has a label other than "page".
135
+ # Only the locator up to the first embedded label (e.g., "fol."
136
+ # in "1, fol. 186") determines whether or not it is plural.
137
+ #
138
+ # @param abbreviations [Hash<String,String>] label abbreviations
139
+ # @return [Boolean] whether or not the locator is plural
140
+ def plural_locator?(abbreviations = CitationItem.locator_abbreviations)
141
+ pattern = CitationItem.locator_label_pattern(abbreviations)
142
+ Number.pluralize?(locator.to_s.split(/\s(?:#{pattern})\s/, 2)[0])
143
+ end
144
+
145
+ # Removes whitespace around the locator and moves a label at the
146
+ # start of the locator into the label (e.g., "vol. 1" becomes "1"
147
+ # with the label "volume") unless the item has a label other than
148
+ # "page".
138
149
  #
139
150
  # @param abbreviations [Hash<String,String>] label abbreviations
140
151
  # @return [self]
141
152
  def parse_locator!(abbreviations = CitationItem.locator_abbreviations)
142
- return self unless locator? && label.to_s == 'page'
153
+ return self unless locator?
154
+
155
+ self.locator = locator.to_s.strip
156
+ return self unless label.to_s == 'page'
143
157
 
144
158
  pattern = CitationItem.locator_label_pattern(abbreviations)
145
159
  match = /\A(#{pattern})\s+(.+)\z/m.match(locator.to_s)
data/lib/citeproc/date.rb CHANGED
@@ -77,7 +77,7 @@ module CiteProc
77
77
  d = arguments[0]
78
78
  super(d.year, d.month, d.day)
79
79
  else
80
- super(*arguments.map(&:to_i))
80
+ super(*arguments.map { |value| to_part(value) })
81
81
  end
82
82
  end
83
83
 
@@ -95,12 +95,18 @@ module CiteProc
95
95
  end
96
96
 
97
97
  parts.each_pair do |part, value|
98
- self[part] = value.nil? ? nil : value.to_i
98
+ self[part] = to_part(value)
99
99
  end
100
100
 
101
101
  self
102
102
  end
103
103
 
104
+ # @return [Integer, nil] the value as a date part; empty values are unset
105
+ def to_part(value)
106
+ value.to_i unless value.to_s.strip.empty?
107
+ end
108
+ private :to_part
109
+
104
110
  # @return [Boolean] whether or not the date parts are unset
105
111
  def empty?
106
112
  to_citeproc.empty?
@@ -126,11 +132,12 @@ module CiteProc
126
132
  !bc? && year < 1000
127
133
  end
128
134
 
129
- # Seasons may be encoded as months 21 to 24 (Spring to Winter).
135
+ # Seasons may be encoded as months 21 to 24 (Spring to Winter)
136
+ # and, as citeproc-js does, 13 to 20 (Spring to Winter, twice).
130
137
  # @return [Integer, nil] the season (1 to 4) or nil if the
131
138
  # month does not encode a season
132
139
  def season
133
- month - 20 if month && month.between?(21, 24)
140
+ (month - 13) % 4 + 1 if month && month.between?(13, 24)
134
141
  end
135
142
 
136
143
  # @return [Boolean] whether or not the month encodes a season
data/lib/citeproc/item.rb CHANGED
@@ -74,11 +74,28 @@ module CiteProc
74
74
  protected :attributes
75
75
 
76
76
 
77
+ # Legacy names of variables in CSL-JSON
78
+ LEGACY_NAMES = {
79
+ :journalAbbreviation => :'container-title-short',
80
+ :shortTitle => :'title-short'
81
+ }.freeze
82
+
77
83
  def initialize(attributes = nil)
78
84
  merge(attributes)
79
85
  yield self if block_given?
80
86
  end
81
87
 
88
+ def merge(other)
89
+ super
90
+
91
+ LEGACY_NAMES.each do |legacy, name|
92
+ value = attributes.delete(legacy)
93
+ write_attribute(name, value) unless value.nil? || attribute?(name)
94
+ end
95
+
96
+ self
97
+ end
98
+
82
99
  def initialize_copy(other)
83
100
  @attributes = other.attributes.deep_copy
84
101
  end
@@ -100,14 +117,24 @@ module CiteProc
100
117
  end
101
118
 
102
119
  def observable_read_attribute(key)
103
- value = original_read_attribute(key)
104
- return if suppressed?(key)
105
- value
120
+ value = original_read_attribute(key) unless suppressed?(key)
106
121
  ensure
107
122
  changed
108
123
  notify_observers :read, key, value
109
124
  end
110
125
 
126
+ # Reads the variable without notifying observers and yields it;
127
+ # observers are notified of the block's result instead
128
+ # (e.g., what a renderer made of the variable).
129
+ # @return the block's result
130
+ def deferred_read_attribute(key)
131
+ value = original_read_attribute(key) unless suppressed?(key)
132
+ result = yield value
133
+ ensure
134
+ changed
135
+ notify_observers :read, key, result
136
+ end
137
+
111
138
  def simulate_read_attribute(key, value)
112
139
  changed
113
140
  notify_observers :read, key, value
@@ -42,6 +42,15 @@ module CiteProc
42
42
  include Attributes
43
43
  include Comparable
44
44
 
45
+ # Leading particle of a family name: "van der Vlist", "d'Alembert", "al-Hassan"
46
+ FAMILY_PARTICLE = /\A(?<particle>\S+[-ʻ’' ] *)(?<name>.+)\z/
47
+
48
+ # Trailing particle of a given name: "Alexander von"
49
+ GIVEN_PARTICLE = /\A(?<name>.+)\s+(?<particle>\S+)\z/
50
+
51
+ # Suffix after a comma in a given name: "John, III" or "John,! Jr."
52
+ SUFFIX = /\A(?<given>.*?)\s*,(?<comma>!?)\s*(?<suffix>.+)\z/
53
+
45
54
  # Class instance variables
46
55
 
47
56
  @romanesque =
@@ -51,7 +60,7 @@ module CiteProc
51
60
  @defaults = {
52
61
  :form => 'long',
53
62
  :'name-as-sort-order' => false,
54
- :'demote-non-dropping-particle' => :never,
63
+ :'demote-non-dropping-particle' => 'display-and-sort',
55
64
  :'sort-separator' => ', ',
56
65
  :initialize => true,
57
66
  :'initialize-with-hyphen' => true,
@@ -126,6 +135,30 @@ module CiteProc
126
135
  end
127
136
 
128
137
 
138
+ # Parses name particles and suffixes out of the family and given names
139
+ # and sets parse-names to false, so the name is not parsed again.
140
+ # Names with parse-names set to false are not parsed.
141
+ # Quotes around the family name are removed
142
+ # and the family name is not parsed.
143
+ # Names without family or given name, or with any particle or suffix set,
144
+ # are not parsed.
145
+ #
146
+ # @return [self]
147
+ def parse!
148
+ return self unless CiteProc.boolean(read_attribute(:'parse-names'), true)
149
+
150
+ quoted = family? && family.match?(/\A".+"\z/)
151
+ self.family = family[1...-1] if quoted
152
+
153
+ if family? && given? && !(particle? || dropping_particle? || suffix?)
154
+ parse_family! unless quoted
155
+ parse_given!
156
+ end
157
+
158
+ write_attribute(:'parse-names', false)
159
+ self
160
+ end
161
+
129
162
  # Resets the object's options to the default settings.
130
163
  # @return [self]
131
164
  def reset!
@@ -166,6 +199,12 @@ module CiteProc
166
199
  static_ordering? || !romanesque?
167
200
  end
168
201
 
202
+ # @return [Boolean] whether or not the name can be printed in sort
203
+ # order (literal names and names in static order cannot)
204
+ def invertible?
205
+ personal? && !static_order?
206
+ end
207
+
169
208
  # Set the name to use static order for printing, i.e., print the family
170
209
  # name before the given name as is customary, for example, in Hungarian
171
210
  # and many Asian languages.
@@ -263,9 +302,10 @@ module CiteProc
263
302
  end
264
303
  end
265
304
 
305
+ # @return [Boolean] whether or not the non-dropping particle is demoted
306
+ # when the name is printed; "sort-only" demotes it only in sort keys
266
307
  def demote_non_dropping_particle?
267
- always_demote_non_dropping_particle? ||
268
- !!(sort_order? && options[:'demote-non-dropping-particle'] =~ /^sort(-only)?$/i)
308
+ always_demote_non_dropping_particle?
269
309
  end
270
310
 
271
311
  alias demote_particle? demote_non_dropping_particle?
@@ -313,30 +353,66 @@ module CiteProc
313
353
  end
314
354
 
315
355
  # @return [String] the name formatted according to the current options
316
- def format
317
- case
318
- when literal?
319
- literal.to_s
320
- when static_order?
321
- [family, initials].compact.join(romanesque? ? ' ' : '')
322
- when !short_form?
323
- case
324
- when !sort_order?
325
- [[initials, dropping_particle, particle, family].compact_join(' '),
326
- suffix].compact_join(comma_suffix? ? comma : ' ')
356
+ # Formats the name according to the formatting options. The name
357
+ # parts may be formatted and enclosed in affixes: the formatter is
358
+ # called with the name part (:given or :family) and its text, and the
359
+ # affixer with the name part and the text it encloses. The given
360
+ # formatting applies to the given name and the dropping particle, the
361
+ # family formatting to the family name and the non-dropping particle.
362
+ # The family affixes enclose all preceding particles and, for names in
363
+ # display order, the suffix; the given affixes enclose the particles
364
+ # following the given name in sort order.
365
+ #
366
+ # @param formatter [#call] formats the text of a name part
367
+ # @param affixer [#call] encloses the text of a name part in affixes
368
+ # @return [String] the formatted name
369
+ def format(formatter = nil, affixer = nil)
370
+ format_part = ->(part, text) { formatter.nil? || text.to_s.empty? ? text : formatter.(part, text) }
371
+ affix_part = ->(part, text) { affixer.nil? || text.to_s.empty? ? text : affixer.(part, text) }
327
372
 
328
- when !demote_particle?
329
- [[particle, family].compact_join(' '), [initials,
330
- dropping_particle].compact_join(' '), suffix].compact_join(comma)
373
+ return affix_part.(:family, format_part.(:family, literal.to_s)) if literal?
331
374
 
332
- else
333
- [family, [initials, dropping_particle, particle].compact_join(' '),
334
- suffix].compact_join(comma)
335
- end
375
+ given = format_part.(:given, initials)
376
+ dropping = format_part.(:given, dropping_particle)
377
+ particle = format_part.(:family, self.particle)
378
+ family = format_part.(:family, self.family)
379
+ particle_family = [particle, family].compact_join(particle_separator)
380
+
381
+ case
382
+ when static_order?
383
+ [affix_part.(:family, family), affix_part.(:given, given)]
384
+ .compact_join(romanesque? ? ' ' : '')
385
+ when short_form?
386
+ affix_part.(:family, particle_family)
387
+ when !sort_order?
388
+ given = affix_part.(:given, given)
389
+ family = [[dropping, particle_family].compact_join(particle_separator(dropping_particle)),
390
+ suffix].compact_join(comma_suffix? ? comma : ' ')
391
+
392
+ # Affixes ending in a space (e.g., a no-break space) replace the space
393
+ [given, affix_part.(:family, family)]
394
+ .compact_join(given.to_s.match?(/[[:space:]]\z/) ? '' : ' ')
395
+ when !demote_particle?
396
+ [affix_part.(:family, particle_family),
397
+ affix_part.(:given, [given, dropping].compact_join(' ')), suffix].compact_join(comma)
336
398
  else
337
- [particle, family].compact_join(' ')
399
+ [affix_part.(:family, family),
400
+ affix_part.(:given, [given, dropping, particle].compact_join(' ')), suffix].compact_join(comma)
338
401
  end
339
402
  end
403
+
404
+ # @return [String] the family name preceded by the non-dropping particle
405
+ def particle_family
406
+ [particle, family].compact_join(particle_separator)
407
+ end
408
+
409
+ # @param particle [String] the dropping or non-dropping particle
410
+ # @return [String] the separator following the particle; particles
411
+ # ending in a hyphen or apostrophe (e.g., "al-" or "d'") are joined
412
+ # without a space
413
+ def particle_separator(particle = self.particle)
414
+ particle.to_s.match?(/[-'’ʻ\s]\z/) ? '' : ' '
415
+ end
340
416
  alias print format
341
417
 
342
418
  # @return [Array<String>] an ordered array of formatted name parts to be used for sorting
@@ -345,9 +421,9 @@ module CiteProc
345
421
  when literal?
346
422
  [literal.to_s.sub(sort_prefix, '')]
347
423
  when never_demote_particle?
348
- [[particle, family].compact_join(' '), dropping_particle, given, suffix].map(&:to_s)
424
+ [particle_family, dropping_particle, given, suffix].map(&:to_s)
349
425
  else
350
- [family, [particle, dropping_particle].compact_join(' '), given, suffix].map(&:to_s)
426
+ [family, [dropping_particle, particle].compact_join(' '), given, suffix].map(&:to_s)
351
427
  end
352
428
  end
353
429
 
@@ -379,6 +455,45 @@ module CiteProc
379
455
  super key
380
456
  end
381
457
 
458
+ # Leading lowercase words of the family name become the non-dropping particle;
459
+ # particles may be joined by hyphens or apostrophes ("d'Alembert", "al-Hassan").
460
+ def parse_family!
461
+ particles, name = '', family.to_s
462
+ while (m = FAMILY_PARTICLE.match(name)) && particle_word?(m[:particle])
463
+ particles, name = particles + m[:particle], m[:name]
464
+ end
465
+
466
+ unless particles.empty?
467
+ self.family = name
468
+ self.particle = particles.match?(/['’] \z/) ? particles.rstrip + ' ' : particles.rstrip
469
+ end
470
+ end
471
+
472
+ # Text after a comma in the given name becomes the suffix
473
+ # ("John, III"; with "John,! Jr." the suffix keeps its comma)
474
+ # and trailing lowercase words the dropping particle.
475
+ def parse_given!
476
+ if (m = SUFFIX.match(given.to_s))
477
+ self.given, self.suffix = m[:given], m[:suffix]
478
+ self.comma_suffix = true unless m[:comma].empty?
479
+ end
480
+
481
+ particles, name = [], given.to_s
482
+ while (m = GIVEN_PARTICLE.match(name)) && particle_word?(m[:particle])
483
+ particles.unshift(m[:particle])
484
+ name = m[:name]
485
+ end
486
+
487
+ unless particles.empty?
488
+ self.given = name
489
+ self.dropping_particle = particles.join(' ')
490
+ end
491
+ end
492
+
493
+ def particle_word?(word)
494
+ word.sub(/\A[-'ʻ’\s]*/, '').match?(/\A\p{Ll}/)
495
+ end
496
+
382
497
  def initials_of(string)
383
498
  return unless string
384
499
 
@@ -386,7 +501,9 @@ module CiteProc
386
501
  string = string.gsub(/\.(?=[[:alpha:]])/, '. ')
387
502
  string = string.tr('-', ' ') if initialize_without_hyphen?
388
503
 
389
- string.scan(/([^\s-]+)\s*(-)?\s*/).map { |part, hyphen|
504
+ # Hyphens followed by a lowercase letter (e.g., "Guo-ping") do not
505
+ # separate parts of the name
506
+ string.scan(/((?:[^\s-]|-(?=\p{Ll}))+)\s*(-)?\s*/).map { |part, hyphen|
390
507
  part = initial_of(part) || " #{part} "
391
508
  hyphen ? "#{part.rstrip}-" : part
392
509
  }.join.gsub(/-\s+/, '-').squeeze(' ').strip
@@ -557,7 +674,7 @@ module CiteProc
557
674
  when value.is_a?(Name)
558
675
  @value << value
559
676
  when value.respond_to?(:each_pair), value.respond_to?(:to_hash)
560
- @value << Name.new(value)
677
+ @value << Name.new(value).parse!
561
678
  when value.respond_to?(:to_s)
562
679
  begin
563
680
  @value.concat Namae.parse!(value.to_s).map { |n| Name.new n }
@@ -19,6 +19,13 @@ module CiteProc
19
19
  # Ranges between numbers; escaped hyphens are not range delimiters
20
20
  RANGE = /(?<![[:alnum:]])#{RANGE_BOUND}\s*[–-]\s*#{RANGE_BOUND}(?![[:alnum:]])/
21
21
 
22
+ PAGE_RANGE = /([[:alnum:]]+)\s*[–-]+\s*([[:alnum:]]+)/
23
+
24
+ # A page number with optional prefix and suffix
25
+ PAGE = /\A(\d*[[:alpha:]]+)?(\d+)([[:alpha:]]*)\z/
26
+
27
+ ROMAN = /\A[ivxlcdm]+\z/i
28
+
22
29
  class << self
23
30
  def pluralize?(string)
24
31
  /\S[\s,&]\S|\df/.match?(string) || RANGE.match?(string)
@@ -37,6 +44,108 @@ module CiteProc
37
44
  code * count
38
45
  }.join
39
46
  end
47
+
48
+ # Formats the page ranges in pages according to format:
49
+ #
50
+ # * "chicago-15" (or "chicago") and "chicago-16": page ranges are
51
+ # abbreviated according to the Chicago Manual of Style rules.
52
+ # * "expanded": Abbreviated page ranges are expanded to
53
+ # their non-abbreviated form: 42-45, 321-328, 2787-2816.
54
+ # * "minimal": All digits repeated in the second number
55
+ # are left out: 42-45, 321-8, 2787-816.
56
+ # * "minimal-two": As "minimal", but at least two digits
57
+ # are kept in the second number: 42-45, 321-28, 2787-816.
58
+ #
59
+ # Without a format only the range delimiter is replaced. Ranges
60
+ # with different prefixes (e.g., "N110-5") keep a plain hyphen;
61
+ # escaped hyphens ("\-") are not range delimiters.
62
+ #
63
+ # @param pages [String] the pages to format
64
+ # @param format [String, nil] the page range format
65
+ # @param delimiter [String] the range delimiter
66
+ # @return [String, nil] the formatted pages
67
+ def format_page_range(pages, format = nil, delimiter = '–')
68
+ return if pages.nil?
69
+
70
+ pages.to_s
71
+ .gsub(PAGE_RANGE) { format_page_bounds($1, $2, format, delimiter) || "#{$1}-#{$2}" }
72
+ .gsub('\\-', '-')
73
+ end
74
+
75
+ private
76
+
77
+ # @return [String, nil] the formatted page range or nil if
78
+ # the bounds do not form a page range
79
+ def format_page_bounds(from, to, format, delimiter)
80
+ if ROMAN.match?(from) && ROMAN.match?(to)
81
+ return "#{from}#{delimiter}#{to}"
82
+ end
83
+
84
+ f, t = PAGE.match(from), PAGE.match(to)
85
+
86
+ # Ranges must have the same prefix on both sides
87
+ return unless f && t && f[1] == t[1]
88
+
89
+ # When there are suffixes or no format was
90
+ # specified we only replace the delimiter
91
+ if format.nil? || !f[3].empty? || !t[3].empty?
92
+ return "#{from}#{delimiter}#{to}"
93
+ end
94
+
95
+ prefix = f[1]
96
+ last = format_page_number(f[2], t[2].dup, format)
97
+
98
+ # The prefix is repeated only for expanded ranges
99
+ "#{prefix}#{f[2]}#{delimiter}#{prefix if format == 'expanded'}#{last}"
100
+ end
101
+
102
+ def format_page_number(f, t, format)
103
+ dim = f.length
104
+ delta = dim - t.length
105
+
106
+ if delta >= 0
107
+ t.prepend f[0, delta] unless delta.zero?
108
+
109
+ format = 'chicago-15' if format == 'chicago'
110
+
111
+ if format == 'chicago-15' || format == 'chicago-16'
112
+ # Only the 15th edition expands four digit
113
+ # numbers when three or more digits change
114
+ changes = dim - f.chars.zip(t.chars).
115
+ take_while { |a,b| a == b }.length if dim == 4
116
+
117
+ format = case
118
+ when dim < 3
119
+ 'expanded'
120
+ when dim == 4 && format == 'chicago-15' && changes > 2
121
+ 'expanded'
122
+ when f[-2, 2] == '00'
123
+ 'expanded'
124
+ when f[-2] == '0'
125
+ 'minimal'
126
+ else
127
+ 'minimal-two'
128
+ end
129
+ end
130
+
131
+ case format
132
+ when 'expanded'
133
+ # nothing to do
134
+ when 'minimal'
135
+ t = t.each_char.drop_while.with_index { |c, i| c == f[i] }.join('')
136
+ when 'minimal-two'
137
+ if dim > 2
138
+ t = t.each_char.drop_while.with_index { |c, i|
139
+ c == f[i] && dim - i > 2
140
+ }.join('')
141
+ end
142
+ else
143
+ raise ArgumentError, "unknown page range format: #{format}"
144
+ end
145
+ end
146
+
147
+ t
148
+ end
40
149
  end
41
150
 
42
151
  def <=>(other)
@@ -15,6 +15,15 @@ module CiteProc
15
15
  process(:bibliography, items, options)
16
16
  end
17
17
 
18
+ # @param string [String, nil]
19
+ # @return [Boolean] whether or not the string starts with a letter of
20
+ # a script which separates words by spaces (as decided by citeproc-js);
21
+ # the Hebrew conjunction "ו" is excluded because it is written as a
22
+ # prefix of the following word
23
+ def romanesque_start?(string)
24
+ /\A(?!ו)[&\p{Latin}\p{Greek}\p{Cyrillic}\p{Hebrew}\p{Arabic}\p{Thai}]/.match?(string.to_s)
25
+ end
26
+
18
27
  # @param value [String, Boolean, nil] an xsd:boolean value
19
28
  # @param default [Boolean] the value if the value is not set
20
29
  # @return [Boolean] the boolean value
@@ -1,3 +1,3 @@
1
1
  module CiteProc
2
- VERSION = '1.3.0'.freeze
2
+ VERSION = '2.0.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: citeproc
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sylvester Keil
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2026-10-07 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: namae
@@ -15,56 +15,56 @@ dependencies:
15
15
  requirements:
16
16
  - - "~>"
17
17
  - !ruby/object:Gem::Version
18
- version: '1.0'
18
+ version: '1.2'
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - "~>"
24
24
  - !ruby/object:Gem::Version
25
- version: '1.0'
25
+ version: '1.2'
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: date
28
28
  requirement: !ruby/object:Gem::Requirement
29
29
  requirements:
30
- - - ">="
30
+ - - "~>"
31
31
  - !ruby/object:Gem::Version
32
- version: '0'
32
+ version: '3.0'
33
33
  type: :runtime
34
34
  prerelease: false
35
35
  version_requirements: !ruby/object:Gem::Requirement
36
36
  requirements:
37
- - - ">="
37
+ - - "~>"
38
38
  - !ruby/object:Gem::Version
39
- version: '0'
39
+ version: '3.0'
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: forwardable
42
42
  requirement: !ruby/object:Gem::Requirement
43
43
  requirements:
44
- - - ">="
44
+ - - "~>"
45
45
  - !ruby/object:Gem::Version
46
- version: '0'
46
+ version: '1.3'
47
47
  type: :runtime
48
48
  prerelease: false
49
49
  version_requirements: !ruby/object:Gem::Requirement
50
50
  requirements:
51
- - - ">="
51
+ - - "~>"
52
52
  - !ruby/object:Gem::Version
53
- version: '0'
53
+ version: '1.3'
54
54
  - !ruby/object:Gem::Dependency
55
55
  name: json
56
56
  requirement: !ruby/object:Gem::Requirement
57
57
  requirements:
58
58
  - - ">="
59
59
  - !ruby/object:Gem::Version
60
- version: '0'
60
+ version: '2.0'
61
61
  type: :runtime
62
62
  prerelease: false
63
63
  version_requirements: !ruby/object:Gem::Requirement
64
64
  requirements:
65
65
  - - ">="
66
66
  - !ruby/object:Gem::Version
67
- version: '0'
67
+ version: '2.0'
68
68
  - !ruby/object:Gem::Dependency
69
69
  name: observer
70
70
  requirement: !ruby/object:Gem::Requirement
@@ -93,6 +93,20 @@ dependencies:
93
93
  - - "<"
94
94
  - !ruby/object:Gem::Version
95
95
  version: '1.0'
96
+ - !ruby/object:Gem::Dependency
97
+ name: citeproc-ruby
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '2.0'
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '2.0'
96
110
  description: A cite processor interface for Citation Style Language (CSL) styles.
97
111
  email:
98
112
  - sylvester@keil.or.at
@@ -124,7 +138,10 @@ files:
124
138
  homepage: https://github.com/inukshuk/citeproc
125
139
  licenses:
126
140
  - BSD-2-Clause
127
- metadata: {}
141
+ metadata:
142
+ source_code_uri: https://github.com/inukshuk/citeproc
143
+ bug_tracker_uri: https://github.com/inukshuk/citeproc/issues
144
+ rubygems_mfa_required: 'true'
128
145
  rdoc_options: []
129
146
  require_paths:
130
147
  - lib