csl 1.0.0.pre12 → 1.0.0.pre13
Sign up to get free protection for your applications and to get access to all the features.
- data/AGPL +1 -1
- data/BSDL +1 -1
- data/README.md +1 -1
- data/features/locales/ordinalize.feature +40 -213
- data/features/step_definitions/locale_steps.rb +2 -2
- data/lib/csl.rb +0 -1
- data/lib/csl/locale.rb +45 -0
- data/lib/csl/locale/term.rb +110 -33
- data/lib/csl/version.rb +1 -1
- data/spec/csl/locale/term_spec.rb +4 -0
- data/spec/fixtures/locales/locales-de-DE.xml +15 -23
- data/spec/fixtures/locales/locales-en-GB.xml +5 -13
- data/spec/fixtures/locales/locales-en-US.xml +6 -14
- data/spec/fixtures/styles/apa.csl +30 -33
- metadata +2 -3
- data/lib/csl/locale/ordinalize.rb +0 -137
data/AGPL
CHANGED
@@ -631,7 +631,7 @@ the "copyright" line and a pointer to where the full notice is found.
|
|
631
631
|
|
632
632
|
CSL-Ruby. A Ruby CSL parser and library.
|
633
633
|
Copyright 2012 President and Fellows of Harvard College.
|
634
|
-
Copyright 2009-
|
634
|
+
Copyright 2009-2013 Sylvester Keil. All rights reserved.
|
635
635
|
|
636
636
|
This program is free software: you can redistribute it and/or modify
|
637
637
|
it under the terms of the GNU Affero General Public License as published by
|
data/BSDL
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
CSL-Ruby. A Ruby CSL parser and library.
|
2
2
|
|
3
3
|
Copyright 2012 President and Fellows of Harvard College.
|
4
|
-
Copyright 2009-
|
4
|
+
Copyright 2009-2013 Sylvester Keil. All rights reserved.
|
5
5
|
|
6
6
|
Redistribution and use in source and binary forms, with or without
|
7
7
|
modification, are permitted provided that the following conditions are met:
|
data/README.md
CHANGED
@@ -66,11 +66,9 @@ Feature: Converting numbers to ordinals using CSL locales
|
|
66
66
|
<locale xmlns="http://purl.org/net/xbiblio/csl" version="1.0.1" xml:lang="en">
|
67
67
|
<terms>
|
68
68
|
<term name="ordinal">th</term>
|
69
|
-
|
70
69
|
<term name="ordinal-01">st</term>
|
71
70
|
<term name="ordinal-02">nd</term>
|
72
71
|
<term name="ordinal-03">rd</term>
|
73
|
-
|
74
72
|
<term name="ordinal-11">th</term>
|
75
73
|
<term name="ordinal-12">th</term>
|
76
74
|
<term name="ordinal-13">th</term>
|
@@ -97,9 +95,9 @@ Feature: Converting numbers to ordinals using CSL locales
|
|
97
95
|
| 112 | | | |
|
98
96
|
| 113 | | | |
|
99
97
|
| -102 | | | |
|
100
|
-
|
101
|
-
|
102
|
-
|
98
|
+
| 1 | | masculine | |
|
99
|
+
| 2 | | feminine | |
|
100
|
+
| 3 | | | plural |
|
103
101
|
Then the ordinals should be:
|
104
102
|
| ordinal |
|
105
103
|
| 0th |
|
@@ -120,9 +118,9 @@ Feature: Converting numbers to ordinals using CSL locales
|
|
120
118
|
| 112th |
|
121
119
|
| 113th |
|
122
120
|
| -102nd |
|
123
|
-
|
124
|
-
|
125
|
-
|
121
|
+
| 1st |
|
122
|
+
| 2nd |
|
123
|
+
| 3rd |
|
126
124
|
|
127
125
|
@v1.0.1 @locale @ordinals @i18n @gender @lang-de
|
128
126
|
Scenario: Gendered German CSL 1.0.1 locales
|
@@ -196,7 +194,6 @@ Feature: Converting numbers to ordinals using CSL locales
|
|
196
194
|
<single>e</single>
|
197
195
|
<multiple>es</multiple>
|
198
196
|
</term>
|
199
|
-
|
200
197
|
<term name="ordinal-01" match="whole-number">
|
201
198
|
<single>re</single>
|
202
199
|
<multiple>res</multiple>
|
@@ -268,24 +265,23 @@ Feature: Converting numbers to ordinals using CSL locales
|
|
268
265
|
|
269
266
|
<term name="ordinal-00" match="whole-number">de</term>
|
270
267
|
|
271
|
-
<term name="ordinal-02" match="
|
272
|
-
<term name="ordinal-03" match="
|
273
|
-
<term name="ordinal-04" match="
|
274
|
-
<term name="ordinal-05" match="
|
275
|
-
<term name="ordinal-06" match="
|
276
|
-
<term name="ordinal-07" match="
|
277
|
-
<term name="ordinal-09" match="
|
278
|
-
|
279
|
-
<term name="ordinal-
|
280
|
-
<term name="ordinal-
|
281
|
-
<term name="ordinal-
|
282
|
-
<term name="ordinal-
|
283
|
-
<term name="ordinal-
|
284
|
-
<term name="ordinal-
|
285
|
-
<term name="ordinal-
|
286
|
-
<term name="ordinal-
|
287
|
-
<term name="ordinal-
|
288
|
-
<term name="ordinal-19" match="2-digits">de</term>
|
268
|
+
<term name="ordinal-02" match="last-two-digits">de</term>
|
269
|
+
<term name="ordinal-03" match="last-two-digits">de</term>
|
270
|
+
<term name="ordinal-04" match="last-two-digits">de</term>
|
271
|
+
<term name="ordinal-05" match="last-two-digits">de</term>
|
272
|
+
<term name="ordinal-06" match="last-two-digits">de</term>
|
273
|
+
<term name="ordinal-07" match="last-two-digits">de</term>
|
274
|
+
<term name="ordinal-09" match="last-two-digits">de</term>
|
275
|
+
<term name="ordinal-10">de</term>
|
276
|
+
<term name="ordinal-11">de</term>
|
277
|
+
<term name="ordinal-12">de</term>
|
278
|
+
<term name="ordinal-13">de</term>
|
279
|
+
<term name="ordinal-14">de</term>
|
280
|
+
<term name="ordinal-15">de</term>
|
281
|
+
<term name="ordinal-16">de</term>
|
282
|
+
<term name="ordinal-17">de</term>
|
283
|
+
<term name="ordinal-18">de</term>
|
284
|
+
<term name="ordinal-19">de</term>
|
289
285
|
</terms>
|
290
286
|
</locale>
|
291
287
|
"""
|
@@ -375,24 +371,23 @@ Feature: Converting numbers to ordinals using CSL locales
|
|
375
371
|
<terms>
|
376
372
|
<term name="ordinal">ste</term>
|
377
373
|
|
378
|
-
<term name="ordinal-02" match="
|
379
|
-
<term name="ordinal-03" match="
|
380
|
-
<term name="ordinal-04" match="
|
381
|
-
<term name="ordinal-05" match="
|
382
|
-
<term name="ordinal-06" match="
|
383
|
-
<term name="ordinal-07" match="
|
384
|
-
<term name="ordinal-09" match="
|
385
|
-
|
386
|
-
<term name="ordinal-
|
387
|
-
<term name="ordinal-
|
388
|
-
<term name="ordinal-
|
389
|
-
<term name="ordinal-
|
390
|
-
<term name="ordinal-
|
391
|
-
<term name="ordinal-
|
392
|
-
<term name="ordinal-
|
393
|
-
<term name="ordinal-
|
394
|
-
<term name="ordinal-
|
395
|
-
<term name="ordinal-19" match="2-digits">de</term>
|
374
|
+
<term name="ordinal-02" match="last-two-digits">de</term>
|
375
|
+
<term name="ordinal-03" match="last-two-digits">de</term>
|
376
|
+
<term name="ordinal-04" match="last-two-digits">de</term>
|
377
|
+
<term name="ordinal-05" match="last-two-digits">de</term>
|
378
|
+
<term name="ordinal-06" match="last-two-digits">de</term>
|
379
|
+
<term name="ordinal-07" match="last-two-digits">de</term>
|
380
|
+
<term name="ordinal-09" match="last-two-digits">de</term>
|
381
|
+
<term name="ordinal-10">de</term>
|
382
|
+
<term name="ordinal-11">de</term>
|
383
|
+
<term name="ordinal-12">de</term>
|
384
|
+
<term name="ordinal-13">de</term>
|
385
|
+
<term name="ordinal-14">de</term>
|
386
|
+
<term name="ordinal-15">de</term>
|
387
|
+
<term name="ordinal-16">de</term>
|
388
|
+
<term name="ordinal-17">de</term>
|
389
|
+
<term name="ordinal-18">de</term>
|
390
|
+
<term name="ordinal-19">de</term>
|
396
391
|
</terms>
|
397
392
|
</locale>
|
398
393
|
"""
|
@@ -641,171 +636,3 @@ Feature: Converting numbers to ordinals using CSL locales
|
|
641
636
|
| 21º |
|
642
637
|
| 21º |
|
643
638
|
| 1001º |
|
644
|
-
|
645
|
-
# @v1.0.1 @locale @ordinals @i18n @gender @lang-sv
|
646
|
-
# Scenario: Gendered Swedish CSL 1.0.1 locales
|
647
|
-
# Given the locale:
|
648
|
-
# """
|
649
|
-
# <?xml version="1.0" encoding="utf-8"?>
|
650
|
-
# <locale xmlns="http://purl.org/net/xbiblio/csl" version="1.0.1" xml:lang="sv">
|
651
|
-
# <terms>
|
652
|
-
# <term name="ordinal-00">:e</term>
|
653
|
-
#
|
654
|
-
# <term name="ordinal-01">:a</term>
|
655
|
-
# <term name="ordinal-01" gender-form="masculine">:e</term>
|
656
|
-
# <term name="ordinal-01" gender-form="feminine">:a</term>
|
657
|
-
#
|
658
|
-
# <term name="ordinal-02">:a</term>
|
659
|
-
# <term name="ordinal-02" gender-form="masculine">:e</term>
|
660
|
-
# <term name="ordinal-02" gender-form="feminine">:a</term>
|
661
|
-
#
|
662
|
-
# <term name="ordinal-11">:e</term>
|
663
|
-
# <term name="ordinal-11" gender-form="feminine">:e</term>
|
664
|
-
# <term name="ordinal-12">:e</term>
|
665
|
-
# <term name="ordinal-12" gender-form="feminine">:e</term>
|
666
|
-
#
|
667
|
-
# <term name="ordinal-21">:e</term>
|
668
|
-
# <term name="ordinal-21" gender-form="feminine">:e</term>
|
669
|
-
# <term name="ordinal-22">:e</term>
|
670
|
-
# <term name="ordinal-22" gender-form="feminine">:e</term>
|
671
|
-
#
|
672
|
-
# <term name="ordinal-31">:e</term>
|
673
|
-
# <term name="ordinal-32">:e</term>
|
674
|
-
#
|
675
|
-
# <term name="ordinal-41">:e</term>
|
676
|
-
# <term name="ordinal-42">:e</term>
|
677
|
-
#
|
678
|
-
# <term name="ordinal-51">:e</term>
|
679
|
-
# <term name="ordinal-52">:e</term>
|
680
|
-
#
|
681
|
-
# <term name="ordinal-61">:e</term>
|
682
|
-
# <term name="ordinal-62">:e</term>
|
683
|
-
#
|
684
|
-
# <term name="ordinal-71">:e</term>
|
685
|
-
# <term name="ordinal-72">:e</term>
|
686
|
-
#
|
687
|
-
# <term name="ordinal-81">:e</term>
|
688
|
-
# <term name="ordinal-82">:e</term>
|
689
|
-
#
|
690
|
-
# <term name="ordinal-91">:e</term>
|
691
|
-
# <term name="ordinal-92">:e</term>
|
692
|
-
# </terms>
|
693
|
-
# </locale>
|
694
|
-
# """
|
695
|
-
# When I ordinalize these numbers:
|
696
|
-
# | num | form | gender | number |
|
697
|
-
# | 0 | | | |
|
698
|
-
# | 1 | | | |
|
699
|
-
# | 2 | | | |
|
700
|
-
# | 3 | | | |
|
701
|
-
# | 4 | | | |
|
702
|
-
# | 5 | | | |
|
703
|
-
# | 6 | | | |
|
704
|
-
# | 7 | | | |
|
705
|
-
# | 8 | | | |
|
706
|
-
# | 9 | | | |
|
707
|
-
# | 10 | | | |
|
708
|
-
# | 1 | | feminine | |
|
709
|
-
# | 1 | | masculine | |
|
710
|
-
# | 2 | | feminine | |
|
711
|
-
# | 2 | | masculine | |
|
712
|
-
# | 23 | | | |
|
713
|
-
# | 999 | | | |
|
714
|
-
# | 11 | | | |
|
715
|
-
# | 11 | | feminine | |
|
716
|
-
# | 11 | | masculine | |
|
717
|
-
# | 21 | | | |
|
718
|
-
# # | 101 | | | |
|
719
|
-
# # | 1001 | | feminine | |
|
720
|
-
# # | 301 | | | |
|
721
|
-
# | 21 | | masculine | singular |
|
722
|
-
# | 21 | | masculine | plural |
|
723
|
-
# # | 1001 | | masculine | |
|
724
|
-
# Then the ordinals should be:
|
725
|
-
# | ordinal |
|
726
|
-
# | 0:e |
|
727
|
-
# | 1:a |
|
728
|
-
# | 2:a |
|
729
|
-
# | 3:e |
|
730
|
-
# | 4:e |
|
731
|
-
# | 5:e |
|
732
|
-
# | 6:e |
|
733
|
-
# | 7:e |
|
734
|
-
# | 8:e |
|
735
|
-
# | 9:e |
|
736
|
-
# | 10:e |
|
737
|
-
# | 1:a |
|
738
|
-
# | 1:e |
|
739
|
-
# | 2:a |
|
740
|
-
# | 2:e |
|
741
|
-
# | 23:e |
|
742
|
-
# | 999:e |
|
743
|
-
# | 11:e |
|
744
|
-
# | 11:e |
|
745
|
-
# | 11:e |
|
746
|
-
# | 21:e |
|
747
|
-
# # | 101:e |
|
748
|
-
# # | 1001:e |
|
749
|
-
# # | 301:e |
|
750
|
-
# | 21:e |
|
751
|
-
# | 21:e |
|
752
|
-
# # | 1001:e |
|
753
|
-
|
754
|
-
# @v1.0.1 @locale @ordinals @i18n @gender @lang-pl
|
755
|
-
# Scenario: Gendered Polish CSL 1.0.1 locales
|
756
|
-
# Given the locale:
|
757
|
-
# """
|
758
|
-
# <?xml version="1.0" encoding="utf-8"?>
|
759
|
-
# <locale xmlns="http://purl.org/net/xbiblio/csl" version="1.0.1" xml:lang="pl">
|
760
|
-
# <terms>
|
761
|
-
# <term name="ordinal-00">:e</term>
|
762
|
-
#
|
763
|
-
# </terms>
|
764
|
-
# </locale>
|
765
|
-
# """
|
766
|
-
# When I ordinalize these numbers:
|
767
|
-
# | num | form | gender | number |
|
768
|
-
# | 0 | | | |
|
769
|
-
# | 1 | | | |
|
770
|
-
# | 2 | | | |
|
771
|
-
# | 3 | | | |
|
772
|
-
# | 4 | | | |
|
773
|
-
# | 5 | | | |
|
774
|
-
# | 6 | | | |
|
775
|
-
# | 7 | | | |
|
776
|
-
# | 8 | | | |
|
777
|
-
# | 9 | | | |
|
778
|
-
# | 10 | | | |
|
779
|
-
# | 1 | | feminine | |
|
780
|
-
# | 1 | | masculine | |
|
781
|
-
# | 2 | | feminine | |
|
782
|
-
# | 2 | | masculine | |
|
783
|
-
# | 23 | | | |
|
784
|
-
# | 999 | | | |
|
785
|
-
# | 11 | | | |
|
786
|
-
# | 11 | | feminine | |
|
787
|
-
# | 11 | | masculine | |
|
788
|
-
# | 21 | | | |
|
789
|
-
# Then the ordinals should be:
|
790
|
-
# | ordinal |
|
791
|
-
# | 0:e |
|
792
|
-
# | 1:a |
|
793
|
-
# | 2:a |
|
794
|
-
# | 3:e |
|
795
|
-
# | 4:e |
|
796
|
-
# | 5:e |
|
797
|
-
# | 6:e |
|
798
|
-
# | 7:e |
|
799
|
-
# | 8:e |
|
800
|
-
# | 9:e |
|
801
|
-
# | 10:e |
|
802
|
-
# | 1:a |
|
803
|
-
# | 1:e |
|
804
|
-
# | 2:a |
|
805
|
-
# | 2:e |
|
806
|
-
# | 23:e |
|
807
|
-
# | 999:e |
|
808
|
-
# | 11:e |
|
809
|
-
# | 11:e |
|
810
|
-
# | 11:e |
|
811
|
-
# | 21:e |
|
@@ -7,7 +7,7 @@ When /^I load the locale from the string$/ do |string|
|
|
7
7
|
end
|
8
8
|
|
9
9
|
When /^I ordinalize the number (\d+)(?: using the (long) form(?: and (feminine|masculine) gender))?$/ do |num, form, gender|
|
10
|
-
@ordinal = @locale.ordinalize(num, :form => form, :gender => gender)
|
10
|
+
@ordinal = @locale.ordinalize(num, :form => form, :'gender-form' => gender)
|
11
11
|
end
|
12
12
|
|
13
13
|
Then /^the ordinal should (?:be|equal) "([^"]*)"$/ do |ord|
|
@@ -17,7 +17,7 @@ end
|
|
17
17
|
When /^I ordinalize these numbers:?$/ do |table|
|
18
18
|
@ordinals = table.rows.map do |row|
|
19
19
|
num, form, gender, number = *row
|
20
|
-
@csl.ordinalize(num, :form => form, :gender => gender, :number => number)
|
20
|
+
@csl.ordinalize(num, :form => form, :'gender-form' => gender, :number => number)
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
data/lib/csl.rb
CHANGED
data/lib/csl/locale.rb
CHANGED
@@ -202,6 +202,51 @@ module CSL
|
|
202
202
|
end
|
203
203
|
alias t translate
|
204
204
|
|
205
|
+
# Ordinalizes the passed-in number using either the ordinal or
|
206
|
+
# long-ordinal forms defined by the locale. If a long-ordinal form is
|
207
|
+
# requested but not available, the regular ordinal will be returned
|
208
|
+
# instead.
|
209
|
+
#
|
210
|
+
# @example
|
211
|
+
# Locale.load('en').ordinalize(13)
|
212
|
+
# #-> "13th"
|
213
|
+
#
|
214
|
+
# de = Locale.load('de')
|
215
|
+
# de.ordinalize(13)
|
216
|
+
# #-> "13."
|
217
|
+
#
|
218
|
+
# de.ordinalize(3, :form => :long, :gender => :feminine)
|
219
|
+
# #-> "dritte"
|
220
|
+
#
|
221
|
+
# @note
|
222
|
+
# For CSL 1.0 (and older) locales that do not define an "ordinal-00"
|
223
|
+
# term the algorithm specified by CSL 1.0 is used; otherwise uses the
|
224
|
+
# CSL 1.0.1 algorithm with improved support for languages other than
|
225
|
+
# English.
|
226
|
+
#
|
227
|
+
# @param number [#to_i] the number to ordinalize
|
228
|
+
# @param options [Hash] formatting options
|
229
|
+
#
|
230
|
+
# @option options [:short,:long] :form (:short) which ordinals form to use
|
231
|
+
# @option options [:feminine,:masculine,:neutral] :gender (:neutral)
|
232
|
+
# which ordinals gender-form to use
|
233
|
+
#
|
234
|
+
# @raise [ArgumentError] if number cannot be converted to an integer
|
235
|
+
#
|
236
|
+
# @return [String] the ordinal for the passed-in number
|
237
|
+
def ordinalize(number, options = {})
|
238
|
+
raise ArgumentError, "unable to ordinalize #{number}; integer expected" unless
|
239
|
+
number.respond_to?(:to_i)
|
240
|
+
|
241
|
+
number = number.to_i
|
242
|
+
ordinal = terms.ordinalize number, options
|
243
|
+
|
244
|
+
return number.to_s if ordinal.nil?
|
245
|
+
return ordinal.to_s(options) if ordinal.long_ordinal?
|
246
|
+
|
247
|
+
[number, ordinal.to_s(options)].join
|
248
|
+
end
|
249
|
+
|
205
250
|
# @example
|
206
251
|
# locale.each_term { |term| block } #-> locale
|
207
252
|
# locale.each_term #-> enumerator
|
data/lib/csl/locale/term.rb
CHANGED
@@ -23,58 +23,107 @@ module CSL
|
|
23
23
|
|
24
24
|
# @return [Term, nil] the first term that matches the query
|
25
25
|
def lookup(name, options = {})
|
26
|
+
options = Term.specialize(options)
|
26
27
|
options[:name] = name = name.to_s
|
27
28
|
|
28
|
-
|
29
|
-
|
29
|
+
term = registry[name].detect { |t| t.match?(options) }
|
30
|
+
return term unless term.nil? && options.delete(:'gender-form')
|
30
31
|
|
31
|
-
|
32
|
-
return term unless term.nil? && conditions.delete(:'gender-form')
|
33
|
-
|
34
|
-
registry[name].detect { |t| t.match?(conditions) }
|
32
|
+
registry[name].detect { |t| t.match?(options) }
|
35
33
|
end
|
36
34
|
alias [] lookup
|
37
35
|
|
38
|
-
def ordinalize_modulo(number, divisor, options = {})
|
39
|
-
ordinal = ordinalize(number, options)
|
40
|
-
return unless ordinal && ordinal.match_modulo?(divisor)
|
41
|
-
ordinal
|
42
|
-
end
|
43
|
-
|
44
36
|
def ordinalize(number, options = {})
|
45
37
|
return unless has_ordinals?
|
46
38
|
|
47
|
-
|
48
|
-
|
39
|
+
options = Term.specialize(options)
|
40
|
+
number = number.to_i.abs
|
41
|
+
|
42
|
+
# try to match long-ordinals first
|
43
|
+
if options.delete(:form).to_s =~ /^long/i
|
44
|
+
ordinal = lookup_long_ordinal_for number, options
|
45
|
+
return ordinal unless ordinal.nil?
|
46
|
+
end
|
47
|
+
|
48
|
+
# select CSL 1.0 or 1.0.1 algorithm
|
49
|
+
algorithm = ordinalizer
|
50
|
+
|
51
|
+
ordinal = send algorithm, number, options
|
52
|
+
return ordinal unless ordinal.nil?
|
53
|
+
|
54
|
+
# fallback to non-gendered version
|
55
|
+
if options.delete(:'gender-form')
|
56
|
+
ordinal = send algorithm, number, options
|
57
|
+
end
|
58
|
+
|
59
|
+
ordinal
|
60
|
+
end
|
61
|
+
|
62
|
+
def ordinalizer
|
63
|
+
if has_legacy_ordinals?
|
64
|
+
:lookup_legacy_ordinals_for
|
49
65
|
else
|
50
|
-
|
66
|
+
:lookup_ordinals_for
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def lookup_long_ordinal_for(number, options = {})
|
71
|
+
ordinals[number].detect { |t| t.long_ordinal? && t.match?(options) }
|
72
|
+
end
|
73
|
+
|
74
|
+
def lookup_ordinals_for(number, options = {})
|
75
|
+
ordinal = lookup_ordinal_for(number, nil, options)
|
76
|
+
return ordinal unless ordinal.nil?
|
77
|
+
|
78
|
+
unless number < 100
|
79
|
+
ordinal = lookup_ordinal_for(number, 100, options)
|
80
|
+
return ordinal unless ordinal.nil?
|
51
81
|
end
|
52
82
|
|
53
|
-
|
54
|
-
options
|
55
|
-
|
83
|
+
unless number < 10
|
84
|
+
ordinal = lookup_ordinal_for(number, 10, options)
|
85
|
+
return ordinal unless ordinal.nil?
|
56
86
|
end
|
57
87
|
|
58
|
-
|
59
|
-
|
88
|
+
default_ordinals.detect { |t| t.match?(options) }
|
89
|
+
end
|
90
|
+
|
91
|
+
def lookup_ordinal_for(number, divisor, options = {})
|
92
|
+
modulus = divisor ? (number % divisor) : number
|
93
|
+
ordinals[modulus].detect do |t|
|
94
|
+
t.short_ordinal? && t.match?(options) && t.match_modulo?(number)
|
95
|
+
end
|
96
|
+
end
|
60
97
|
|
61
|
-
|
98
|
+
def lookup_legacy_ordinals_for(number, options = {})
|
99
|
+
case
|
100
|
+
when (11..13).include?(number.abs % 100)
|
101
|
+
ordinals[4].detect { |t| t.match?(options) }
|
102
|
+
when (1..3).include?(number.abs % 10)
|
103
|
+
ordinals[number.abs % 10].detect { |t| t.match?(options) }
|
104
|
+
else
|
105
|
+
ordinals[4].detect { |t| t.match?(options) }
|
106
|
+
end
|
62
107
|
end
|
63
108
|
|
64
109
|
# @return [Boolean] whether or not regular terms are registered at this node
|
65
110
|
def has_terms?
|
66
|
-
|
111
|
+
!registry.empty?
|
67
112
|
end
|
68
113
|
|
69
114
|
# @return [Boolean] whether or not ordinal terms are registered at this node
|
70
115
|
def has_ordinals?
|
71
|
-
|
116
|
+
!ordinals.empty?
|
72
117
|
end
|
73
118
|
|
74
119
|
def has_legacy_ordinals?
|
75
120
|
has_ordinals? && !ordinals.key?(:default)
|
76
121
|
end
|
77
122
|
|
123
|
+
def default_ordinals
|
124
|
+
ordinals[:default]
|
125
|
+
end
|
126
|
+
|
78
127
|
def drop_ordinals
|
79
128
|
tmp = ordinals.values.flatten(1)
|
80
129
|
ordinals.clear
|
@@ -128,25 +177,39 @@ module CSL
|
|
128
177
|
|
129
178
|
def_delegators :attributes, :hash, :eql?, :name, :form, :gender
|
130
179
|
|
180
|
+
class << self
|
181
|
+
def specialize(options)
|
182
|
+
options = options.select do |k,v|
|
183
|
+
!v.nil? && Term::Attributes.keys.include?(k.to_sym)
|
184
|
+
end
|
185
|
+
|
186
|
+
options.delete :'gender-form' unless
|
187
|
+
options[:'gender-form'].to_s =~ /^masculine|feminine$/
|
188
|
+
|
189
|
+
options
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
131
193
|
# This method returns whether or not the ordinal term matchs the
|
132
194
|
# passed-in modulus. This is determined by the ordinal term's match
|
133
|
-
# attribute: a value of '
|
134
|
-
# matches a
|
195
|
+
# attribute: a value of 'last-two-digits' matches a modulus of 100,
|
196
|
+
# 'last-digit' matches a modulus of 10 and 'whole-number' matches
|
197
|
+
# only if the number is identical to the ordinal value.
|
135
198
|
#
|
136
199
|
# If the term is no ordinal term, this methods always returns false.
|
137
200
|
#
|
138
201
|
# @return [Boolean] whether or not the ordinal term matches the
|
139
|
-
# passed-in
|
140
|
-
def match_modulo?(
|
202
|
+
# passed-in number.
|
203
|
+
def match_modulo?(number)
|
141
204
|
return false unless ordinal?
|
142
205
|
|
143
206
|
case attributes.match
|
144
|
-
when '
|
145
|
-
|
146
|
-
when '
|
147
|
-
|
207
|
+
when 'last-two-digits'
|
208
|
+
ordinal == number % 100
|
209
|
+
when 'last-digit'
|
210
|
+
ordinal == number % 10
|
148
211
|
when 'whole-number'
|
149
|
-
|
212
|
+
ordinal == number
|
150
213
|
else
|
151
214
|
true
|
152
215
|
end
|
@@ -158,13 +221,27 @@ module CSL
|
|
158
221
|
/^(long-)?ordinal(-\d\d+)?$/ === attributes.name
|
159
222
|
end
|
160
223
|
|
224
|
+
# @return [Boolean] whether or not this term is a long-ordinal term
|
225
|
+
def long_ordinal?
|
226
|
+
/^long-ordinal(-\d\d+)?$/ === attributes.name
|
227
|
+
end
|
228
|
+
|
229
|
+
# @return [Boolean] whether or not this term is a regular ordinal term
|
230
|
+
def short_ordinal?
|
231
|
+
/^ordinal(-\d\d+)?$/ === attributes.name
|
232
|
+
end
|
233
|
+
|
234
|
+
def default_ordinal?
|
235
|
+
attributes.name == 'ordinal'
|
236
|
+
end
|
237
|
+
|
161
238
|
# @return [Fixnum, :default, nil]
|
162
239
|
def ordinal
|
163
240
|
return unless ordinal?
|
164
241
|
return :default if attributes.name == 'ordinal'
|
165
242
|
attributes.name[/\d+/].to_i
|
166
243
|
end
|
167
|
-
|
244
|
+
|
168
245
|
def gendered?
|
169
246
|
!attributes.gender.blank?
|
170
247
|
end
|
data/lib/csl/version.rb
CHANGED
@@ -22,7 +22,7 @@
|
|
22
22
|
<term name="anonymous">ohne Autor</term>
|
23
23
|
<term name="anonymous" form="short">o. A.</term>
|
24
24
|
<term name="at">auf</term>
|
25
|
-
<term name="available at">
|
25
|
+
<term name="available at">verfügbar unter</term>
|
26
26
|
<term name="by">von</term>
|
27
27
|
<term name="circa">circa</term>
|
28
28
|
<term name="circa" form="short">ca.</term>
|
@@ -54,8 +54,8 @@
|
|
54
54
|
<multiple>Ref.</multiple>
|
55
55
|
</term>
|
56
56
|
<term name="retrieved">abgerufen</term>
|
57
|
-
<term name="scale">
|
58
|
-
<term name="version">
|
57
|
+
<term name="scale">Maßstab</term>
|
58
|
+
<term name="version">Version</term>
|
59
59
|
|
60
60
|
<!-- ANNO DOMINI; BEFORE CHRIST -->
|
61
61
|
<term name="ad">n. Chr.</term>
|
@@ -190,13 +190,9 @@
|
|
190
190
|
</term>
|
191
191
|
|
192
192
|
<!-- LONG ROLE FORMS -->
|
193
|
-
<term name="author">
|
194
|
-
<single/>
|
195
|
-
<multiple/>
|
196
|
-
</term>
|
197
193
|
<term name="director">
|
198
|
-
<single>
|
199
|
-
<multiple>
|
194
|
+
<single>Regisseur</single>
|
195
|
+
<multiple>Regisseure</multiple>
|
200
196
|
</term>
|
201
197
|
<term name="editor">
|
202
198
|
<single>Herausgeber</single>
|
@@ -207,8 +203,8 @@
|
|
207
203
|
<multiple>Herausgeber</multiple>
|
208
204
|
</term>
|
209
205
|
<term name="illustrator">
|
210
|
-
<single>
|
211
|
-
<multiple>
|
206
|
+
<single>Illustrator</single>
|
207
|
+
<multiple>illustratoren</multiple>
|
212
208
|
</term>
|
213
209
|
<term name="translator">
|
214
210
|
<single>Übersetzer</single>
|
@@ -220,13 +216,9 @@
|
|
220
216
|
</term>
|
221
217
|
|
222
218
|
<!-- SHORT ROLE FORMS -->
|
223
|
-
<term name="author" form="short">
|
224
|
-
<single/>
|
225
|
-
<multiple/>
|
226
|
-
</term>
|
227
219
|
<term name="director" form="short">
|
228
|
-
<single>
|
229
|
-
<multiple>
|
220
|
+
<single>Reg.</single>
|
221
|
+
<multiple>Reg..</multiple>
|
230
222
|
</term>
|
231
223
|
<term name="editor" form="short">
|
232
224
|
<single>Hrsg.</single>
|
@@ -237,8 +229,8 @@
|
|
237
229
|
<multiple>Hrsg.</multiple>
|
238
230
|
</term>
|
239
231
|
<term name="illustrator" form="short">
|
240
|
-
<single>
|
241
|
-
<multiple>
|
232
|
+
<single>Ill.</single>
|
233
|
+
<multiple>Ill.</multiple>
|
242
234
|
</term>
|
243
235
|
<term name="translator" form="short">
|
244
236
|
<single>Übers.</single>
|
@@ -253,19 +245,19 @@
|
|
253
245
|
<term name="director" form="verb">directed by</term>
|
254
246
|
<term name="editor" form="verb">herausgegeben von</term>
|
255
247
|
<term name="editorial-director" form="verb">herausgegeben von</term>
|
256
|
-
<term name="illustrator" form="verb">
|
248
|
+
<term name="illustrator" form="verb">illustriert von</term>
|
257
249
|
<term name="interviewer" form="verb">interviewt von</term>
|
258
250
|
<term name="recipient" form="verb">an</term>
|
259
|
-
<term name="reviewed-author" form="verb">
|
251
|
+
<term name="reviewed-author" form="verb">von</term>
|
260
252
|
<term name="translator" form="verb">übersetzt von</term>
|
261
253
|
<term name="editortranslator" form="verb">herausgegeben und übersetzt von</term>
|
262
254
|
|
263
255
|
<!-- SHORT VERB ROLE FORMS -->
|
264
256
|
<term name="container-author" form="verb-short">von</term>
|
265
|
-
<term name="director" form="verb-short">
|
257
|
+
<term name="director" form="verb-short">Reg.</term>
|
266
258
|
<term name="editor" form="verb-short">hg. von</term>
|
267
259
|
<term name="editorial-director" form="verb-short">hg. von</term>
|
268
|
-
<term name="illustrator" form="verb-short">illus
|
260
|
+
<term name="illustrator" form="verb-short">illus. von</term>
|
269
261
|
<term name="translator" form="verb-short">übers. von</term>
|
270
262
|
<term name="editortranslator" form="verb-short">hg. & übers. von</term>
|
271
263
|
|
@@ -196,10 +196,6 @@
|
|
196
196
|
</term>
|
197
197
|
|
198
198
|
<!-- LONG ROLE FORMS -->
|
199
|
-
<term name="author">
|
200
|
-
<single/>
|
201
|
-
<multiple/>
|
202
|
-
</term>
|
203
199
|
<term name="director">
|
204
200
|
<single>director</single>
|
205
201
|
<multiple>directors</multiple>
|
@@ -226,10 +222,6 @@
|
|
226
222
|
</term>
|
227
223
|
|
228
224
|
<!-- SHORT ROLE FORMS -->
|
229
|
-
<term name="author" form="short">
|
230
|
-
<single/>
|
231
|
-
<multiple/>
|
232
|
-
</term>
|
233
225
|
<term name="director" form="short">
|
234
226
|
<single>dir.</single>
|
235
227
|
<multiple>dirs.</multiple>
|
@@ -268,11 +260,11 @@
|
|
268
260
|
|
269
261
|
<!-- SHORT VERB ROLE FORMS -->
|
270
262
|
<term name="container-author" form="verb-short">by</term>
|
271
|
-
<term name="director" form="verb-short">dir
|
272
|
-
<term name="editor" form="verb-short">ed
|
273
|
-
<term name="editorial-director" form="verb-short">ed
|
274
|
-
<term name="illustrator" form="verb-short">illus
|
275
|
-
<term name="translator" form="verb-short">trans
|
263
|
+
<term name="director" form="verb-short">dir. by</term>
|
264
|
+
<term name="editor" form="verb-short">ed. by</term>
|
265
|
+
<term name="editorial-director" form="verb-short">ed. by</term>
|
266
|
+
<term name="illustrator" form="verb-short">illus. by</term>
|
267
|
+
<term name="translator" form="verb-short">trans. by</term>
|
276
268
|
<term name="editortranslator" form="verb-short">ed. & trans. by</term>
|
277
269
|
|
278
270
|
<!-- LONG MONTH FORMS -->
|
@@ -7,7 +7,7 @@
|
|
7
7
|
<style-options punctuation-in-quote="true"/>
|
8
8
|
<date form="text">
|
9
9
|
<date-part name="month" suffix=" "/>
|
10
|
-
<date-part name="day"
|
10
|
+
<date-part name="day" suffix=", "/>
|
11
11
|
<date-part name="year"/>
|
12
12
|
</date>
|
13
13
|
<date form="numeric">
|
@@ -196,10 +196,6 @@
|
|
196
196
|
</term>
|
197
197
|
|
198
198
|
<!-- LONG ROLE FORMS -->
|
199
|
-
<term name="author">
|
200
|
-
<single/>
|
201
|
-
<multiple/>
|
202
|
-
</term>
|
203
199
|
<term name="director">
|
204
200
|
<single>director</single>
|
205
201
|
<multiple>directors</multiple>
|
@@ -226,10 +222,6 @@
|
|
226
222
|
</term>
|
227
223
|
|
228
224
|
<!-- SHORT ROLE FORMS -->
|
229
|
-
<term name="author" form="short">
|
230
|
-
<single/>
|
231
|
-
<multiple/>
|
232
|
-
</term>
|
233
225
|
<term name="director" form="short">
|
234
226
|
<single>dir.</single>
|
235
227
|
<multiple>dirs.</multiple>
|
@@ -268,11 +260,11 @@
|
|
268
260
|
|
269
261
|
<!-- SHORT VERB ROLE FORMS -->
|
270
262
|
<term name="container-author" form="verb-short">by</term>
|
271
|
-
<term name="director" form="verb-short">dir
|
272
|
-
<term name="editor" form="verb-short">ed
|
273
|
-
<term name="editorial-director" form="verb-short">ed
|
274
|
-
<term name="illustrator" form="verb-short">illus
|
275
|
-
<term name="translator" form="verb-short">trans
|
263
|
+
<term name="director" form="verb-short">dir. by</term>
|
264
|
+
<term name="editor" form="verb-short">ed. by</term>
|
265
|
+
<term name="editorial-director" form="verb-short">ed. by</term>
|
266
|
+
<term name="illustrator" form="verb-short">illus. by</term>
|
267
|
+
<term name="translator" form="verb-short">trans. by</term>
|
276
268
|
<term name="editortranslator" form="verb-short">ed. & trans. by</term>
|
277
269
|
|
278
270
|
<!-- LONG MONTH FORMS -->
|
@@ -27,11 +27,15 @@
|
|
27
27
|
<category citation-format="author-date"/>
|
28
28
|
<category field="psychology"/>
|
29
29
|
<category field="generic-base"/>
|
30
|
-
<updated>2012-09-
|
31
|
-
<rights>This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 License
|
30
|
+
<updated>2012-09-27T22:06:38+00:00</updated>
|
31
|
+
<rights license="http://creativecommons.org/licenses/by-sa/3.0/">This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 License</rights>
|
32
32
|
</info>
|
33
33
|
<locale xml:lang="en">
|
34
34
|
<terms>
|
35
|
+
<term name="editortranslator" form="short">
|
36
|
+
<single>ed. & trans.</single>
|
37
|
+
<multiple>eds. & trans.</multiple>
|
38
|
+
</term>
|
35
39
|
<term name="translator" form="short">
|
36
40
|
<single>trans.</single>
|
37
41
|
<multiple>trans.</multiple>
|
@@ -41,12 +45,9 @@
|
|
41
45
|
<macro name="container-contributors">
|
42
46
|
<choose>
|
43
47
|
<if type="chapter paper-conference" match="any">
|
44
|
-
<names variable="editor" delimiter=", " suffix=", ">
|
48
|
+
<names variable="editor translator" delimiter=", " suffix=", ">
|
45
49
|
<name and="symbol" initialize-with=". " delimiter=", "/>
|
46
|
-
<label form="short" prefix=" (" text-case="
|
47
|
-
<substitute>
|
48
|
-
<names variable="translator"/>
|
49
|
-
</substitute>
|
50
|
+
<label form="short" prefix=" (" text-case="title" suffix=")"/>
|
50
51
|
</names>
|
51
52
|
</if>
|
52
53
|
</choose>
|
@@ -54,12 +55,9 @@
|
|
54
55
|
<macro name="secondary-contributors">
|
55
56
|
<choose>
|
56
57
|
<if type="chapter paper-conference" match="none">
|
57
|
-
<names variable="translator" delimiter=", " prefix=" (" suffix=")">
|
58
|
+
<names variable="translator editor" delimiter=", " prefix=" (" suffix=")">
|
58
59
|
<name and="symbol" initialize-with=". " delimiter=", "/>
|
59
|
-
<label form="short" prefix=", " text-case="
|
60
|
-
<substitute>
|
61
|
-
<names variable="editor"/>
|
62
|
-
</substitute>
|
60
|
+
<label form="short" prefix=", " text-case="title" suffix=""/>
|
63
61
|
</names>
|
64
62
|
</if>
|
65
63
|
</choose>
|
@@ -67,7 +65,7 @@
|
|
67
65
|
<macro name="author">
|
68
66
|
<names variable="author">
|
69
67
|
<name name-as-sort-order="all" and="symbol" sort-separator=", " initialize-with=". " delimiter=", " delimiter-precedes-last="always"/>
|
70
|
-
<label form="short" prefix=" (" suffix="
|
68
|
+
<label form="short" prefix=" (" suffix=")" text-case="capitalize-first"/>
|
71
69
|
<substitute>
|
72
70
|
<names variable="editor"/>
|
73
71
|
<names variable="translator"/>
|
@@ -136,11 +134,7 @@
|
|
136
134
|
<group delimiter=" ">
|
137
135
|
<text term="retrieved" text-case="capitalize-first" suffix=" "/>
|
138
136
|
<group>
|
139
|
-
<date variable="accessed" suffix=", "
|
140
|
-
<date-part name="month" suffix=" "/>
|
141
|
-
<date-part name="day" suffix=", "/>
|
142
|
-
<date-part name="year"/>
|
143
|
-
</date>
|
137
|
+
<date variable="accessed" form="text" suffix=", "/>
|
144
138
|
</group>
|
145
139
|
<text term="from"/>
|
146
140
|
<text variable="URL"/>
|
@@ -293,7 +287,7 @@
|
|
293
287
|
<if is-numeric="edition">
|
294
288
|
<group delimiter=" ">
|
295
289
|
<number variable="edition" form="ordinal"/>
|
296
|
-
<text term="edition" form="short"
|
290
|
+
<text term="edition" form="short"/>
|
297
291
|
</group>
|
298
292
|
</if>
|
299
293
|
<else>
|
@@ -322,11 +316,11 @@
|
|
322
316
|
<group prefix=" (" suffix=")" delimiter=", ">
|
323
317
|
<text macro="edition"/>
|
324
318
|
<group>
|
325
|
-
<text term="volume" form="short" plural="true" text-case="capitalize-first" suffix="
|
319
|
+
<text term="volume" form="short" plural="true" text-case="capitalize-first" suffix=" "/>
|
326
320
|
<number variable="number-of-volumes" form="numeric" prefix="1-"/>
|
327
321
|
</group>
|
328
322
|
<group>
|
329
|
-
<text term="volume" form="short" text-case="capitalize-first" suffix="
|
323
|
+
<text term="volume" form="short" text-case="capitalize-first" suffix=" "/>
|
330
324
|
<number variable="volume" form="numeric"/>
|
331
325
|
</group>
|
332
326
|
<group>
|
@@ -338,11 +332,7 @@
|
|
338
332
|
<else-if type="legal_case">
|
339
333
|
<group prefix=" (" suffix=")" delimiter=" ">
|
340
334
|
<text variable="authority"/>
|
341
|
-
<date variable="issued"
|
342
|
-
<date-part name="month" form="short"/>
|
343
|
-
<date-part name="day" suffix=","/>
|
344
|
-
<date-part name="year"/>
|
345
|
-
</date>
|
335
|
+
<date variable="issued" form="text"/>
|
346
336
|
</group>
|
347
337
|
</else-if>
|
348
338
|
<else-if type="bill legislation">
|
@@ -354,16 +344,23 @@
|
|
354
344
|
</macro>
|
355
345
|
<macro name="citation-locator">
|
356
346
|
<group>
|
357
|
-
<
|
347
|
+
<choose>
|
348
|
+
<if locator="chapter">
|
349
|
+
<label variable="locator" form="long" text-case="capitalize-first"/>
|
350
|
+
</if>
|
351
|
+
<else>
|
352
|
+
<label variable="locator" form="short"/>
|
353
|
+
</else>
|
354
|
+
</choose>
|
358
355
|
<text variable="locator" prefix=" "/>
|
359
356
|
</group>
|
360
357
|
</macro>
|
361
358
|
<macro name="container">
|
362
359
|
<group>
|
363
360
|
<choose>
|
364
|
-
|
365
|
-
|
366
|
-
|
361
|
+
<if type="chapter paper-conference entry-encyclopedia" match="any">
|
362
|
+
<text term="in" text-case="capitalize-first" suffix=" "/>
|
363
|
+
</if>
|
367
364
|
</choose>
|
368
365
|
<text macro="container-contributors"/>
|
369
366
|
<text macro="secondary-contributors"/>
|
@@ -382,7 +379,7 @@
|
|
382
379
|
<text variable="volume"/>
|
383
380
|
<text variable="container-title"/>
|
384
381
|
<group delimiter=" ">
|
385
|
-
|
382
|
+
<!--change to label variable="section" as that becomes available -->
|
386
383
|
<text term="section" form="symbol"/>
|
387
384
|
<text variable="section"/>
|
388
385
|
</group>
|
@@ -396,7 +393,7 @@
|
|
396
393
|
<else>
|
397
394
|
<text variable="number" prefix="Pub. L. No. "/>
|
398
395
|
<group delimiter=" ">
|
399
|
-
|
396
|
+
<!--change to label variable="section" as that becomes available -->
|
400
397
|
<text term="section" form="symbol"/>
|
401
398
|
<text variable="section"/>
|
402
399
|
</group>
|
@@ -432,7 +429,7 @@
|
|
432
429
|
<text macro="author"/>
|
433
430
|
<text macro="issued"/>
|
434
431
|
<text macro="title" prefix=" "/>
|
435
|
-
|
432
|
+
<text macro="container"/>
|
436
433
|
</group>
|
437
434
|
<text macro="locators"/>
|
438
435
|
<group delimiter=", " prefix=". ">
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: csl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.
|
4
|
+
version: 1.0.0.pre13
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -115,7 +115,6 @@ files:
|
|
115
115
|
- lib/csl/loader.rb
|
116
116
|
- lib/csl/locale.rb
|
117
117
|
- lib/csl/locale/date.rb
|
118
|
-
- lib/csl/locale/ordinalize.rb
|
119
118
|
- lib/csl/locale/style_options.rb
|
120
119
|
- lib/csl/locale/term.rb
|
121
120
|
- lib/csl/node.rb
|
@@ -183,7 +182,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
183
182
|
version: '0'
|
184
183
|
segments:
|
185
184
|
- 0
|
186
|
-
hash:
|
185
|
+
hash: -2590038154395651463
|
187
186
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
188
187
|
none: false
|
189
188
|
requirements:
|
@@ -1,137 +0,0 @@
|
|
1
|
-
module CSL
|
2
|
-
class Locale
|
3
|
-
|
4
|
-
# Ordinalizes the passed-in number using either the ordinal or
|
5
|
-
# long-ordinal forms defined by the locale. If a long-ordinal form is
|
6
|
-
# requested but not available, the regular ordinal will be returned
|
7
|
-
# instead.
|
8
|
-
#
|
9
|
-
# @example
|
10
|
-
# Locale.load('en').ordinalize(13)
|
11
|
-
# #-> "13th"
|
12
|
-
#
|
13
|
-
# de = Locale.load('de')
|
14
|
-
# de.ordinalize(13)
|
15
|
-
# #-> "13."
|
16
|
-
#
|
17
|
-
# de.ordinalize(3, :form => :long, :gender => :feminine)
|
18
|
-
# #-> "dritte"
|
19
|
-
#
|
20
|
-
# @note
|
21
|
-
# For CSL 1.0 (and older) locales that do not define an "ordinal-00"
|
22
|
-
# term the algorithm specified by CSL 1.0 is used; otherwise uses the
|
23
|
-
# CSL 1.0.1 algorithm with improved support for languages other than
|
24
|
-
# English.
|
25
|
-
#
|
26
|
-
# @param number [#to_i] the number to ordinalize
|
27
|
-
# @param options [Hash] formatting options
|
28
|
-
#
|
29
|
-
# @option options [:short,:long] :form (:short) which ordinals form to use
|
30
|
-
# @option options [:feminine,:masculine,:neutral] :gender (:neutral)
|
31
|
-
# which ordinals gender-form to use
|
32
|
-
#
|
33
|
-
# @raise [ArgumentError] if number cannot be converted to an integer
|
34
|
-
#
|
35
|
-
# @return [String] the ordinal for the passed-in number
|
36
|
-
def ordinalize(number, options = {})
|
37
|
-
raise ArgumentError, "unable to ordinalize #{number}; integer expected" unless
|
38
|
-
number.respond_to?(:to_i)
|
39
|
-
|
40
|
-
number = number.to_i
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
key = query[:name]
|
45
|
-
|
46
|
-
# Try to match long-ordinals first
|
47
|
-
if key.start_with?('l')
|
48
|
-
query[:name] = key % number.abs
|
49
|
-
ordinal = terms[query]
|
50
|
-
|
51
|
-
if ordinal.nil?
|
52
|
-
key = 'ordinal-%02d'
|
53
|
-
else
|
54
|
-
return ordinal.to_s(options)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
# CSL 1.0 (legacy algorithm)
|
59
|
-
return legacy_ordinalize(number) if legacy?
|
60
|
-
|
61
|
-
#
|
62
|
-
# CSL 1.0.1
|
63
|
-
#
|
64
|
-
|
65
|
-
# Calculate initial modulus
|
66
|
-
mod = 10 ** Math.log10([number.abs, 1].max).to_i
|
67
|
-
|
68
|
-
# Try to find direct match first
|
69
|
-
query.merge! :name => key % number.abs
|
70
|
-
ordinal = terms[query]
|
71
|
-
|
72
|
-
# Try to match modulus of number, dividing mod by 10 at each
|
73
|
-
# iteration until a match is found
|
74
|
-
while ordinal.nil? && mod > 1
|
75
|
-
query.merge! :name => key % (number.abs % mod)
|
76
|
-
ordinal = terms.lookup_modulo(query, mod)
|
77
|
-
|
78
|
-
mod = mod / 10
|
79
|
-
end
|
80
|
-
|
81
|
-
# If we have not found a match at this point, we try to match
|
82
|
-
# the default ordinal instead
|
83
|
-
if ordinal.nil?
|
84
|
-
query[:name] = 'ordinal'
|
85
|
-
ordinal = terms[query]
|
86
|
-
|
87
|
-
if ordinal.nil? && query.key?(:'gender-form')
|
88
|
-
query.delete(:'gender-form')
|
89
|
-
ordinal = terms[query]
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
if ordinal.nil?
|
94
|
-
number.to_s
|
95
|
-
else
|
96
|
-
[number, ordinal.to_s(options)].join
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
private
|
101
|
-
|
102
|
-
def normalize_gender_options(options)
|
103
|
-
gender = (options[:'gender-form'] || options[:gender]).to_s
|
104
|
-
unless gender.empty? || gender =~ /^n/i
|
105
|
-
q[:'gender-form'] = (gender =~ /^m/i) ? 'masculine' : 'feminine'
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
def normalize_plural_options(options)
|
110
|
-
end
|
111
|
-
|
112
|
-
def ordinalize_options_for(options)
|
113
|
-
q = { :name => 'ordinal-%02d' }
|
114
|
-
|
115
|
-
unless options.nil?
|
116
|
-
if options.key?(:form) && options[:form].to_s =~ /^long(-ordinal)?$/i
|
117
|
-
q[:name] = 'long-ordinal-%02d'
|
118
|
-
end
|
119
|
-
|
120
|
-
end
|
121
|
-
|
122
|
-
q
|
123
|
-
end
|
124
|
-
|
125
|
-
def legacy_ordinalize(number)
|
126
|
-
case
|
127
|
-
when (11..13).include?(number.abs % 100)
|
128
|
-
[number, terms['ordinal-04']].join
|
129
|
-
when (1..3).include?(number.abs % 10)
|
130
|
-
[number, terms['ordinal-%02d' % (number.abs % 10)]].join
|
131
|
-
else
|
132
|
-
[number, terms['ordinal-04']].join
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
end
|
137
|
-
end
|