csl 1.0.0.pre12 → 1.0.0.pre13
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.
- 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
|