csl 2.3.0 → 2.4.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 +4 -4
- data/lib/csl/locale/term.rb +5 -4
- data/lib/csl/locale.rb +85 -31
- data/lib/csl/node.rb +16 -19
- data/lib/csl/style/names.rb +2 -2
- data/lib/csl/style.rb +10 -1
- data/lib/csl/treelike.rb +18 -12
- data/lib/csl/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c70f967fbf46ada97d0c2b3164d3fc1b843d24d6125f1c6364d2d7f408c5fa7e
|
|
4
|
+
data.tar.gz: 59d241370ed43b45a191e938ebbe20b51ed74419a503feb0c71e37d2770facd3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ee00896662db7e3f7ccdc6644f208428a392ad2a66ae09ad93bb37ac4a6366915d9f4cea1cb274526466e8a0441f6c40afdfcbf953735e2d6a744587f41f6777
|
|
7
|
+
data.tar.gz: 2807a5c96c581af1a9314d75b5b24b09e461c6fbf956b475d9bde1f8c1f7a6bc420095a9af6380ee7879129b80f6dc0ce1505dcd555dafdff7355b89e09979cc
|
data/lib/csl/locale/term.rb
CHANGED
|
@@ -80,10 +80,11 @@ module CSL
|
|
|
80
80
|
return unless has_ordinals?
|
|
81
81
|
|
|
82
82
|
options = Term.specialize(options)
|
|
83
|
+
form, options = options[:form], options.except(:form)
|
|
83
84
|
number = number.to_i.abs
|
|
84
85
|
|
|
85
86
|
# try to match long-ordinals first
|
|
86
|
-
if
|
|
87
|
+
if form.to_s =~ /^long/i
|
|
87
88
|
ordinal = lookup_long_ordinal_for number, options
|
|
88
89
|
return ordinal unless ordinal.nil?
|
|
89
90
|
end
|
|
@@ -94,9 +95,9 @@ module CSL
|
|
|
94
95
|
ordinal = send algorithm, number, options
|
|
95
96
|
return ordinal unless ordinal.nil?
|
|
96
97
|
|
|
97
|
-
# fallback to
|
|
98
|
-
if options.
|
|
99
|
-
ordinal = send algorithm, number, options
|
|
98
|
+
# fallback to neuter
|
|
99
|
+
if options.key?(:'gender-form')
|
|
100
|
+
ordinal = send algorithm, number, options.merge(:'gender-form' => nil)
|
|
100
101
|
end
|
|
101
102
|
|
|
102
103
|
ordinal
|
data/lib/csl/locale.rb
CHANGED
|
@@ -55,7 +55,7 @@ module CSL
|
|
|
55
55
|
error = nil
|
|
56
56
|
|
|
57
57
|
candidates.each do |candidate|
|
|
58
|
-
return super(candidate)
|
|
58
|
+
return super(candidate).tap { |locale| locale.requested = tag }
|
|
59
59
|
rescue ParseError => e
|
|
60
60
|
error ||= e
|
|
61
61
|
end
|
|
@@ -119,6 +119,10 @@ module CSL
|
|
|
119
119
|
|
|
120
120
|
attr_accessor :region, :script
|
|
121
121
|
|
|
122
|
+
# @return [String, nil] the IETF tag the locale was loaded for;
|
|
123
|
+
# this differs from the locale's own tag if the locale is a fallback
|
|
124
|
+
attr_accessor :requested
|
|
125
|
+
|
|
122
126
|
alias_child :metadata, :info
|
|
123
127
|
alias_child :dates, :date
|
|
124
128
|
alias_child :options, :style_options
|
|
@@ -171,6 +175,7 @@ module CSL
|
|
|
171
175
|
def initialize_copy(other)
|
|
172
176
|
@parent, @ancestors, @descendants, @siblings, @root, @depth = nil
|
|
173
177
|
initialize(other.attributes.to_hash.merge(:lang => other.to_s))
|
|
178
|
+
@requested = other.requested
|
|
174
179
|
end
|
|
175
180
|
|
|
176
181
|
def added_to(node)
|
|
@@ -266,8 +271,9 @@ module CSL
|
|
|
266
271
|
# de.ordinalize(13)
|
|
267
272
|
# #-> "13."
|
|
268
273
|
#
|
|
269
|
-
#
|
|
270
|
-
#
|
|
274
|
+
# fr = Locale.load('fr')
|
|
275
|
+
# fr.ordinalize(1, :'gender-form' => 'feminine')
|
|
276
|
+
# #-> "1ʳᵉ"
|
|
271
277
|
#
|
|
272
278
|
# @note
|
|
273
279
|
# For CSL 1.0 (and older) locales that do not define an "ordinal-00"
|
|
@@ -279,8 +285,9 @@ module CSL
|
|
|
279
285
|
# @param options [Hash] formatting options
|
|
280
286
|
#
|
|
281
287
|
# @option options [:short,:long] :form (:short) which ordinals form to use
|
|
282
|
-
# @option options [
|
|
283
|
-
# which ordinals gender-form to use
|
|
288
|
+
# @option options ['feminine','masculine',nil] :'gender-form' (nil)
|
|
289
|
+
# which ordinals gender-form to use; falls back to the neuter
|
|
290
|
+
# ordinals (without gender-form)
|
|
284
291
|
#
|
|
285
292
|
# @raise [ArgumentError] if number cannot be converted to an integer
|
|
286
293
|
#
|
|
@@ -300,8 +307,7 @@ module CSL
|
|
|
300
307
|
|
|
301
308
|
# @return [Boolean] true when the option limit-day-ordinals-to-day-1 is true
|
|
302
309
|
def limit_day_ordinals?
|
|
303
|
-
|
|
304
|
-
!!(options[:'limit-day-ordinals-to-day-1'].to_s =~ /^true$/i)
|
|
310
|
+
has_options? && options.boolean_attribute(:'limit-day-ordinals-to-day-1')
|
|
305
311
|
end
|
|
306
312
|
|
|
307
313
|
def limit_day_ordinals!
|
|
@@ -314,8 +320,7 @@ module CSL
|
|
|
314
320
|
|
|
315
321
|
# @return [Boolean] true when the option punctuation-in-quote is true
|
|
316
322
|
def punctuation_in_quote?
|
|
317
|
-
|
|
318
|
-
!!(options[:'punctuation-in-quote'].to_s =~ /^true$/i)
|
|
323
|
+
has_options? && options.boolean_attribute(:'punctuation-in-quote')
|
|
319
324
|
end
|
|
320
325
|
alias punctuation_in_quotes? punctuation_in_quote?
|
|
321
326
|
|
|
@@ -399,13 +404,13 @@ module CSL
|
|
|
399
404
|
|
|
400
405
|
# @returns [Boolean] whether or not the Locale is the default locale
|
|
401
406
|
def default?
|
|
402
|
-
|
|
407
|
+
default_tag?(language, script, region)
|
|
403
408
|
end
|
|
404
409
|
|
|
405
410
|
# @return [Boolean] whehter or not the Locale's region is the default
|
|
406
411
|
# region for its language
|
|
407
412
|
def default_region?
|
|
408
|
-
|
|
413
|
+
default_region_for?(language, region)
|
|
409
414
|
end
|
|
410
415
|
|
|
411
416
|
# @return [Boolean] whether or not the Locale's language is the default
|
|
@@ -414,11 +419,25 @@ module CSL
|
|
|
414
419
|
language && language == Locale.languages[region]
|
|
415
420
|
end
|
|
416
421
|
|
|
422
|
+
# Whether or not the passed-in locale (e.g., an in-style locale)
|
|
423
|
+
# matches this locale. This is the case for universal locales and
|
|
424
|
+
# for locales of the language this locale was requested for.
|
|
417
425
|
def like?(other)
|
|
418
426
|
return false unless other.is_a? Locale
|
|
419
427
|
return true if other.universal?
|
|
420
428
|
|
|
421
|
-
|
|
429
|
+
requested_language == other.language
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
# @return [Symbol, nil] the language this locale was requested for
|
|
433
|
+
def requested_language
|
|
434
|
+
requested.nil? ? language : requested.split('-')[0].to_sym
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
# @return [Boolean] whether or not the locale was loaded as a
|
|
438
|
+
# fallback for a different locale
|
|
439
|
+
def fallback?
|
|
440
|
+
!requested.nil? && requested != to_s
|
|
422
441
|
end
|
|
423
442
|
|
|
424
443
|
def universal?
|
|
@@ -461,44 +480,76 @@ module CSL
|
|
|
461
480
|
# de-DE will come before de-AT even though the alphabetical order
|
|
462
481
|
# would be different).
|
|
463
482
|
#
|
|
483
|
+
# Fallback locales are compared as the locale they were requested
|
|
484
|
+
# for (see #requested); locale data (terms, dates, and options) is
|
|
485
|
+
# not compared.
|
|
486
|
+
#
|
|
464
487
|
# @param other [Locale] the locale used for comparison
|
|
465
488
|
# @return [1,0,-1,nil] the result of the comparison
|
|
466
489
|
def <=>(other)
|
|
490
|
+
return nil unless other.is_a?(Locale)
|
|
491
|
+
compare(identity, other.identity)
|
|
492
|
+
end
|
|
493
|
+
|
|
494
|
+
# @return [String] the Locale's IETF tag
|
|
495
|
+
def to_s
|
|
496
|
+
[language, script, region].compact.join('-')
|
|
497
|
+
end
|
|
498
|
+
|
|
499
|
+
# @return [String] a string representation of the Locale
|
|
500
|
+
def inspect
|
|
501
|
+
"#<#{self.class.name} #{to_s}>"
|
|
502
|
+
end
|
|
503
|
+
|
|
504
|
+
protected
|
|
505
|
+
|
|
506
|
+
# @return [Array<Symbol, nil>] language, script, and region of the
|
|
507
|
+
# locale or, for fallback locales, of the requested tag
|
|
508
|
+
def identity
|
|
509
|
+
return [language, script, region] unless fallback?
|
|
510
|
+
|
|
511
|
+
language, *rs = requested.split('-').map(&:to_sym)
|
|
512
|
+
region, script = rs.reverse
|
|
513
|
+
|
|
514
|
+
[language, script, region]
|
|
515
|
+
end
|
|
516
|
+
|
|
517
|
+
private
|
|
518
|
+
|
|
519
|
+
# Compares two locale identities (see #identity).
|
|
520
|
+
def compare(a, b)
|
|
521
|
+
language, script, region = a
|
|
522
|
+
other_language, other_script, other_region = b
|
|
523
|
+
|
|
467
524
|
case
|
|
468
|
-
when
|
|
469
|
-
|
|
470
|
-
when
|
|
471
|
-
script <=> other.script
|
|
472
|
-
when default?
|
|
525
|
+
when [language, region] == [other_language, other_region]
|
|
526
|
+
script <=> other_script
|
|
527
|
+
when default_tag?(*a)
|
|
473
528
|
-1
|
|
474
|
-
when
|
|
529
|
+
when default_tag?(*b)
|
|
475
530
|
1
|
|
476
|
-
when language ==
|
|
531
|
+
when language == other_language
|
|
477
532
|
case
|
|
478
|
-
when
|
|
533
|
+
when default_region_for?(language, region)
|
|
479
534
|
-1
|
|
480
|
-
when
|
|
535
|
+
when default_region_for?(other_language, other_region)
|
|
481
536
|
1
|
|
482
537
|
else
|
|
483
|
-
region.to_s <=>
|
|
538
|
+
region.to_s <=> other_region.to_s
|
|
484
539
|
end
|
|
485
540
|
else
|
|
486
|
-
language.to_s <=>
|
|
541
|
+
language.to_s <=> other_language.to_s
|
|
487
542
|
end
|
|
488
543
|
end
|
|
489
544
|
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
[language, script, region].compact.join('-')
|
|
545
|
+
def default_tag?(language, script, region)
|
|
546
|
+
[language, script, region].compact.join('-') == Locale.default
|
|
493
547
|
end
|
|
494
548
|
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
"#<#{self.class.name} #{to_s}>"
|
|
549
|
+
def default_region_for?(language, region)
|
|
550
|
+
region && region == Locale.regions[language]
|
|
498
551
|
end
|
|
499
552
|
|
|
500
|
-
private
|
|
501
|
-
|
|
502
553
|
alias original_locale_attribute_assignments attribute_assignments
|
|
503
554
|
|
|
504
555
|
def attribute_assignments
|
|
@@ -549,6 +600,9 @@ module CSL
|
|
|
549
600
|
def merge_terms(other)
|
|
550
601
|
return self unless other.has_terms?
|
|
551
602
|
|
|
603
|
+
# Ordinals are replaced as a set
|
|
604
|
+
terms.drop_ordinals if has_terms? && other.terms.has_ordinals?
|
|
605
|
+
|
|
552
606
|
other.each_term do |term|
|
|
553
607
|
store term.deep_copy
|
|
554
608
|
end
|
data/lib/csl/node.rb
CHANGED
|
@@ -168,13 +168,10 @@ module CSL
|
|
|
168
168
|
end
|
|
169
169
|
|
|
170
170
|
def fetch(key, default = nil)
|
|
171
|
-
value =
|
|
171
|
+
value = send(:'[]', key) if keys.include?(key.to_sym)
|
|
172
|
+
return value unless value.nil?
|
|
172
173
|
|
|
173
|
-
|
|
174
|
-
value || yield(key)
|
|
175
|
-
else
|
|
176
|
-
value || default
|
|
177
|
-
end
|
|
174
|
+
block_given? ? yield(key) : default
|
|
178
175
|
end
|
|
179
176
|
|
|
180
177
|
# Merges the current with the passed-in attributes.
|
|
@@ -307,6 +304,17 @@ module CSL
|
|
|
307
304
|
attributes.fetch(name, false)
|
|
308
305
|
end
|
|
309
306
|
|
|
307
|
+
# @param name [Symbol] the name of an xsd:boolean attribute
|
|
308
|
+
# @param default [Boolean] the value if the attribute is not set
|
|
309
|
+
# @return [Boolean] the value of the boolean attribute
|
|
310
|
+
def boolean_attribute(name, default = false)
|
|
311
|
+
case attributes.fetch(name, nil).to_s
|
|
312
|
+
when 'true', '1' then true
|
|
313
|
+
when 'false', '0' then false
|
|
314
|
+
else default
|
|
315
|
+
end
|
|
316
|
+
end
|
|
317
|
+
|
|
310
318
|
# @param [[String]] names list of attribute names
|
|
311
319
|
# @return [Boolean] true if the node contains attributes for all
|
|
312
320
|
# passed-in names; false otherwise.
|
|
@@ -466,11 +474,11 @@ module CSL
|
|
|
466
474
|
end
|
|
467
475
|
|
|
468
476
|
def strip_periods?
|
|
469
|
-
|
|
477
|
+
boolean_attribute(:'strip-periods')
|
|
470
478
|
end
|
|
471
479
|
|
|
472
480
|
def quotes?
|
|
473
|
-
|
|
481
|
+
boolean_attribute(:quotes)
|
|
474
482
|
end
|
|
475
483
|
|
|
476
484
|
|
|
@@ -573,17 +581,6 @@ module CSL
|
|
|
573
581
|
CSL.encode_xml_text text.to_s.strip
|
|
574
582
|
end
|
|
575
583
|
|
|
576
|
-
# TextNodes quack like a string.
|
|
577
|
-
# def_delegators :to_s, *String.instance_methods(false).reject do |m|
|
|
578
|
-
# m.to_s =~ /^\W|!$|(?:^(?:hash|eql?|to_s|length|size|inspect)$)/
|
|
579
|
-
# end
|
|
580
|
-
#
|
|
581
|
-
# String.instance_methods(false).select { |m| m.to_s =~ /!$/ }.each do |m|
|
|
582
|
-
# define_method(m) do
|
|
583
|
-
# content.send(m) if content.respond_to?(m)
|
|
584
|
-
# end
|
|
585
|
-
# end
|
|
586
|
-
|
|
587
584
|
def initialize(argument = '')
|
|
588
585
|
case
|
|
589
586
|
when argument.respond_to?(:each_pair)
|
data/lib/csl/style/names.rb
CHANGED
|
@@ -229,7 +229,7 @@ module CSL
|
|
|
229
229
|
# be inserted between before et-al depending on the
|
|
230
230
|
# number of names rendered
|
|
231
231
|
def delimiter_contextually_precedes_et_al?
|
|
232
|
-
return true unless attribute?
|
|
232
|
+
return true unless attribute?(:'delimiter-precedes-et-al')
|
|
233
233
|
!!(attributes[:'delimiter-precedes-et-al'].to_s =~ /^contextual/i)
|
|
234
234
|
end
|
|
235
235
|
|
|
@@ -327,7 +327,7 @@ module CSL
|
|
|
327
327
|
end
|
|
328
328
|
|
|
329
329
|
def ellipsis?
|
|
330
|
-
|
|
330
|
+
boolean_attribute(:'et-al-use-last')
|
|
331
331
|
end
|
|
332
332
|
|
|
333
333
|
def ellipsis
|
data/lib/csl/style.rb
CHANGED
|
@@ -74,6 +74,15 @@ module CSL
|
|
|
74
74
|
@errors = Schema.validate self
|
|
75
75
|
end
|
|
76
76
|
|
|
77
|
+
# Merges the style's overrides into the given locale.
|
|
78
|
+
#
|
|
79
|
+
# @param locale [Locale]
|
|
80
|
+
# @return [Locale]
|
|
81
|
+
def localize(locale)
|
|
82
|
+
overrides = locales.sort.reverse.select { |other| locale.like?(other) }
|
|
83
|
+
overrides.empty? ? locale : locale.merge(*overrides)
|
|
84
|
+
end
|
|
85
|
+
|
|
77
86
|
def valid?
|
|
78
87
|
validate.empty?
|
|
79
88
|
end
|
|
@@ -127,7 +136,7 @@ module CSL
|
|
|
127
136
|
alias demote_particle? demote_non_dropping_particle?
|
|
128
137
|
|
|
129
138
|
def initialize_without_hyphen?
|
|
130
|
-
|
|
139
|
+
!boolean_attribute(:'initialize-with-hyphen', true)
|
|
131
140
|
end
|
|
132
141
|
|
|
133
142
|
def has_page_range_format?
|
data/lib/csl/treelike.rb
CHANGED
|
@@ -33,12 +33,17 @@ module CSL
|
|
|
33
33
|
end
|
|
34
34
|
alias delete delete_children
|
|
35
35
|
|
|
36
|
-
# Deletes
|
|
37
|
-
#
|
|
38
|
-
#
|
|
39
|
-
#
|
|
36
|
+
# Deletes the passed-in child node.
|
|
37
|
+
# Returns the deleted child.
|
|
38
|
+
# If the node is not a child, returns nil or,
|
|
39
|
+
# if the optional block is given, the result of the block.
|
|
40
40
|
def delete_child(child)
|
|
41
|
-
deleted = children.
|
|
41
|
+
deleted = if children.is_a?(Array)
|
|
42
|
+
index = children.index { |node| node.equal?(child) }
|
|
43
|
+
children.delete_at(index) unless index.nil?
|
|
44
|
+
else
|
|
45
|
+
children.delete child
|
|
46
|
+
end
|
|
42
47
|
|
|
43
48
|
case
|
|
44
49
|
when deleted.nil? && block_given?
|
|
@@ -423,18 +428,19 @@ module CSL
|
|
|
423
428
|
|
|
424
429
|
alias << push
|
|
425
430
|
|
|
426
|
-
#
|
|
427
|
-
#
|
|
428
|
-
#
|
|
429
|
-
# result
|
|
431
|
+
# Deletes the passed-in node; other, equal nodes are not deleted.
|
|
432
|
+
# Returns the deleted node or nil if the node is not found.
|
|
433
|
+
# If the optional code block is given,
|
|
434
|
+
# returns the result of the block if the node is not found.
|
|
430
435
|
def delete(node)
|
|
431
436
|
return nil unless node.respond_to?(:nodename)
|
|
432
437
|
|
|
433
438
|
deleted = resolve(node.nodename)
|
|
434
439
|
if deleted.kind_of?(Array)
|
|
435
|
-
|
|
440
|
+
index = deleted.index { |other| other.equal?(node) }
|
|
441
|
+
deleted = index.nil? ? nil : deleted.delete_at(index)
|
|
436
442
|
else
|
|
437
|
-
if deleted
|
|
443
|
+
if deleted.equal?(node)
|
|
438
444
|
self[node.nodename] = nil
|
|
439
445
|
else
|
|
440
446
|
deleted = nil
|
|
@@ -442,7 +448,7 @@ module CSL
|
|
|
442
448
|
end
|
|
443
449
|
|
|
444
450
|
# Delete node from ordered list as well
|
|
445
|
-
@order.
|
|
451
|
+
@order.delete_if { |other| other.equal?(node) }
|
|
446
452
|
|
|
447
453
|
if deleted.nil? && block_given?
|
|
448
454
|
yield
|
data/lib/csl/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: csl
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sylvester Keil
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-10-
|
|
10
|
+
date: 2026-10-07 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: namae
|