langtag 0.1.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.
data/README ADDED
@@ -0,0 +1,31 @@
1
+ == Langtag version 0.1.0
2
+
3
+ === Overview
4
+ The Langtag class represents IETF Language Tags
5
+ as a subclass of String that provides read/write
6
+ access to specific parts of a language tag, such
7
+ as language, script, region, and so on, as well
8
+ as well-formedness checks and some other simple
9
+ operations.
10
+
11
+ === IETF Language Tags
12
+ IETF Language Tags are defined by BCP 47
13
+ (http://www.ietf.org/rfc/bcp/bcp47.txt),
14
+ which currently consists of RFC 4646
15
+ (http://www.ietf.org/rfc/rfc4646.txt)
16
+ and RFC 4647 (http://www.ietf.org/rfc/rfc467.txt).
17
+ These documents are the work of the LTRU Working
18
+ Group (see http://www.ietf.org/html.charters/ltru-charter.html).
19
+ For further explanatory information on IETF language tags,
20
+ in particular in a Web context, please also see
21
+ http://www.w3.org/International/articles/language-tags/.
22
+
23
+ === Future Work
24
+ - Provide support for various matching/lookup options
25
+ defined in RFC 4647
26
+ - Provide support for validation
27
+
28
+ === Copyright
29
+ Copyright (c) 2007 Martin J. Du"rst (duerst@it.aoyama.ac.jp)
30
+ Licensed under the same terms as Ruby. Absolutely no warranty.
31
+ (see http://www.ruby-lang.org/en/LICENSE.txt)
@@ -0,0 +1,170 @@
1
+ # :include: ../README
2
+
3
+ # :stopdoc:
4
+ # === Helper Functions for Array Class
5
+ class Array
6
+ # Create a new Array by repeatedly calling &block
7
+ # until the returned value is equal to final.
8
+ def Array.collect (final=nil, &block)
9
+ a = Array.new
10
+ while final != (e=block.call)
11
+ a << e
12
+ end
13
+ a
14
+ end
15
+ # Test uniqueness of elements of an Array.
16
+ # This should be available as part of the standard Array class.
17
+ def uniq?
18
+ return self.length == self.uniq.length
19
+ end
20
+ end
21
+ # :startdoc:
22
+
23
+ require 'rubygems'
24
+ gem 'composite'
25
+ require 'composite'
26
+
27
+ # Langtag class, implementing BCP 47 (currently RFC 4646)
28
+ # IETF language tags. Provides decomposition of language
29
+ # tags into components, and wellformedness check.
30
+ #
31
+ # ==== Accessor methods
32
+ # Getting: language, script, region, variants, extensions, private.
33
+ # Setting: language=, script=, region=, variants=, extensions=, private=.
34
+ # Variants and extensions accessors get/set Arrays, the other accessors get/set Strings.
35
+ # Because of the way Ruby assignement methods are implemented,
36
+ # manipulating variants and extensions with e.g.
37
+ # myLangtag.variants += ['e-Extension']
38
+ # (adding 'e-Extension' as an extension to whatever extensions myLangtag
39
+ # already has) is possible. Similarly,
40
+ # myLangtag.variants -= ['e-Extension']
41
+ # will again remove the extension.
42
+ class Langtag < String
43
+ include Composite
44
+ def initialize (s)
45
+ super(s)
46
+ decompose
47
+ end
48
+
49
+ # the parts of a language tag
50
+ # variants and extensions are arrays, the other parts are strings
51
+ part :language, :script, :region, :variants, :extensions, :private
52
+
53
+ # Array of irregular language tags
54
+ Irregular = ['en-gb-oed',
55
+ 'i-ami', 'i-bnn', 'i-default', 'i-enochian', 'i-hak',
56
+ 'i-klingon', 'i-lux', 'i-mingo', 'i-navajo', 'i-pwn',
57
+ 'i-tao', 'i-tay', 'i-tsu', 'sgn-be-fr',
58
+ 'sgn-be-nl', 'sgn-ch-de'];
59
+
60
+ # Array of grandfathered language tags
61
+ Grandfathered = Irregular + ['art-lojban', 'cel-gaulish',
62
+ 'no-bok', 'no-nyn', 'zh-cmn', 'zh-cmn-hans', 'zh-cmn-hant',
63
+ 'zh-gan', 'zh-guoyu', 'zh-hakka', 'zh-min', 'zh-min-nan',
64
+ 'zh-wuu', 'zh-xiang', 'zh-yue'];
65
+
66
+ # returns true if language tag is well-formed, false otherwise
67
+ def wellformed? ()
68
+ decompose
69
+ @wellformed
70
+ end
71
+
72
+ # returns true if language tag is grandfathered, false otherwise
73
+ def grandfathered? ()
74
+ Grandfathered.include? self.to_str.downcase
75
+ end
76
+
77
+ # returns true if language tag is irregular, false otherwise
78
+ def irregular? ()
79
+ Irregular.include? self.to_str.downcase
80
+ end
81
+
82
+ # changes case to look 'nice' (regions are UPPER-CASE,
83
+ # scripts are Title-Case, everything else is lower case
84
+ def nicecase! ()
85
+ @language.downcase!
86
+ @script.capitalize!
87
+ @region.upcase!
88
+ @variants.each { |v| v.downcase! }
89
+ @extensions.each { |e| e.downcase! }
90
+ @private.downcase!
91
+ compose
92
+ end
93
+
94
+ # non-descructive variant of nicecase!: returns a nicecased copy
95
+ def nicecase ()
96
+ result = Langtag.new(self).nicecase!
97
+ end
98
+
99
+ # compose the langtag from parts, joining with '-'
100
+ # flatten first to deal with @variants/@extentsions with are arrays
101
+ # then compact to remove nil values (mainly internal use)
102
+ def compose
103
+ replace([@language, @script, @region, @variants,
104
+ @extensions, @private].flatten.compact.join('-'))
105
+ end
106
+
107
+ # decompose a language tag into parts (mainly internal use)
108
+ def decompose
109
+ # check if we really need to decompose again
110
+ if @saved == self.to_str
111
+ return
112
+ end
113
+ # initialize everything
114
+ s = @saved = self.to_str # save for check next time around
115
+ @wellformed = true # assume well-formed
116
+ @language = @script = @region = @private = nil
117
+ @variants = @extensions = []
118
+
119
+ # deal with irregular and completely private langtags
120
+ if irregular? || s =~ /^x-/i
121
+ @language = s
122
+ return
123
+ end
124
+ # check well-formedness with a single regular expression,
125
+ # except for irregulars (checked above) and multiple
126
+ # occurrences of the same extension (checked below)
127
+ # notice /i modifier for case insensitive matching
128
+ if not(s =~ /^([a-z]{2,3} # shortest ISO 639 language
129
+ (-[a-z]{3}){0,3} # with optional extensions
130
+ |[a-z]{4,8}) # or reserved\registered
131
+ (-[a-z]{4})? # optional script
132
+ (-([a-z]{2}|\d{3}))? # optional region
133
+ (-([a-z0-9]{5,8}|\d[a-z0-9]{3}))* # optional variants
134
+ (-[a-wyz0-9](-[a-z0-9]{2,8})+)* # optional extensions
135
+ (-x(-[a-z0-9]{1,8})+)? # optional private use part
136
+ $/ix)
137
+ @wellformed = false
138
+ end
139
+ # extract language
140
+ if s =~ /^(([a-z]{2,3}(-[a-z]{3}){0,3}|[a-z]{4,8}))(-|$)/i
141
+ @language, s = $1, $'
142
+ end
143
+ # extract private use tail
144
+ if s =~ /(^|-)(x-.*)$/i
145
+ s, @private = $`, $2
146
+ end
147
+ # extract extensions and check for duplicates
148
+ @extensions = Array.collect do
149
+ if s =~ /(^|-)([a-wyz0-9](-[a-z0-9]{2,8})+)$/i
150
+ s = $`
151
+ $2
152
+ else
153
+ nil
154
+ end
155
+ end
156
+ @extensions.reverse! # put back in order
157
+ if !((@extensions.collect {|ext| ext[0..1].downcase}).uniq?)
158
+ @wellformed = false
159
+ end
160
+ if s =~ /(^|-)([a-z]{4})(-|$)/i # extract script
161
+ @script = $2
162
+ end
163
+ if s =~ /(^|-)([a-z]{2}|\d{3})(-|$)/i # extract region
164
+ @region = $2
165
+ end
166
+ # extract variants
167
+ @variants = s.scan(/(^|-)([a-z0-9]{5,8}|\d[a-z0-9]{3})(?=(-|$))/i).
168
+ collect { |match| match[1] }
169
+ end # decompose
170
+ end # class Langtag
@@ -0,0 +1,309 @@
1
+ WELL-FORMED
2
+
3
+ AaBbCcDd
4
+ AaBbCcDd-x-y-any-x
5
+ abcd-Latn
6
+ ab-x-abc-a-a # ditto
7
+ ab-x-abc-a-a # ditto
8
+ ab-x-abc-x-abc # anything goes after x
9
+ ab-x-abc-x-abc # anything goes after x
10
+ ax-TZ # Not in the registry, but well-formed
11
+ az-Arab-x-AZE-derbend
12
+ de-a-value
13
+ de-CH-1996
14
+ de-Latg-1996
15
+ en
16
+ en-a-bbb-x-a-ccc
17
+ en-enx
18
+ en-enx-eny-enz-latn-us
19
+ en-gb-oed
20
+ en-Latn
21
+ en-Latn-001
22
+ en-Latn-GB-boont-r-extended-sequence-x-private
23
+ en-Latn-US
24
+ en-Latn-US-lojban-gaulish
25
+ en-Latn-US-lojban-gaulish-a-12345678-ABCD-b-ABCDEFGH
26
+ en-Latn-US-lojban-gaulish-a-12345678-ABCD-b-ABCDEFGH-x-a-b-c-12345678
27
+ en-US
28
+ en-US
29
+ en-US-boont
30
+ en-x-US
31
+ es-419
32
+ es-Latn-CO-x-private
33
+ fr
34
+ fra
35
+ fra-FX
36
+ fra-Latn # ISO 639 can be 3-letters
37
+ fr-FR
38
+ fr-fra # Extended tag
39
+ fr-Lat # Extended
40
+ fr-Latn
41
+ fr-Latn-419
42
+ fr-Latn-CA
43
+ fr-Latn-CA
44
+ fr-Latn-FR
45
+ fr-shadok # Variant
46
+ fr-y-myext-myext2
47
+ i-default # grandfathered
48
+ i-default # grandfathered
49
+ i-enochian # Grand fathered
50
+ i-klingon # grandfathered
51
+ i-klingon # grandfathered with singleton
52
+ mn-Cyrl-MN
53
+ mN-cYrL-Mn
54
+ no-bok # grandfathered without singleton
55
+ sl-IT-nedis
56
+ sl-nedis
57
+ sr-Latn-CS
58
+ x-12345678-a
59
+ x-fr-CH
60
+
61
+ #all of the grandfathered codes; first the really goofy ones. Cased oddly for an extra test.
62
+ En-Gb-Oed
63
+ I-Ami
64
+ I-Bnn
65
+ I-Default
66
+ I-Enochian
67
+ I-Hak
68
+ I-Klingon
69
+ I-Lux
70
+ I-Mingo
71
+ I-Navajo
72
+ I-Pwn
73
+ I-Tao
74
+ I-Tay
75
+ I-Tsu
76
+ Sgn-Be-Fr
77
+ Sgn-Be-Nl
78
+ Sgn-Ch-De
79
+
80
+ #now the ones that are well-formed, but currently invalid
81
+ art-lojban
82
+ cel-gaulish
83
+ en-boont
84
+ en-scouse
85
+ no-bok
86
+ no-nyn
87
+ zh-cmn
88
+ zh-cmn-Hans
89
+ zh-cmn-Hant
90
+ zh-gan
91
+ zh-guoyu
92
+ zh-hakka
93
+ zh-min
94
+ zh-min-nan
95
+ zh-wuu
96
+ zh-xiang
97
+ zh-yue
98
+
99
+ # Now some randomly generated correct names
100
+
101
+ cfR-wOG-g-UkjoqWt8-ii8S04LL-rbBDq0gl-o-qmzs-ifnRSqVz-241T-lVFJq30L-0JWuHsb-C-WMThK-kbEOuA-tIQ-Lfjt-a-c1gdojdJ-7iv-b-NawXDK
102
+ JP-ubE-JtS-fOa-BOiO
103
+ BYE-fiX-mKH-BKdy
104
+ rc-Ajl-jpl-X-Lh-SPB-ANEXM
105
+ FwtsUTb
106
+ GH-NgZ-rW
107
+ x-GF-E7m-v2-V09q
108
+ qQ-THL-dth
109
+ TDGbw
110
+ Uif-eE
111
+ TDJVhlwx-HEwn-6M9a-4DvI-7WaG-8IRj-7QEk-7yID
112
+ rOO-yUE-UEY-bbcM
113
+ yY-jDQ-eDK-NsZ-a-oJQ-eLc-JTMc31-nhr-h-unOGj8-Os7-JMT5jeVq-pE-QK5
114
+ oJ-57b1OPWP-6MUqYs-Kesk65J-74oa-34Ys
115
+ vX-PCm-mnT-PsQ
116
+ eQh-ewFo-7mvP-EbJ0xx-0OEK-I0I8ju6
117
+ JwdjKtH-WD
118
+ QxxLG-X-lJNNX6Pu-7OfhbLoa
119
+ icb-AAk-EFU-dAyc-1rj2-3upg-8VMx-5nml-DF45sBf
120
+ en-GB-oed
121
+ oHSgh-x-SpoWfaO8-J-NATtSLZ1
122
+ Ehl-hpi-Bbb-zu-x-n6rrcoz0
123
+ UFhQ-GO-X-HULOlod-tkv
124
+ jVVxZr
125
+ HkFqh
126
+ tyg-mMk-YME-Nia-aJab-Ej
127
+ rI-aqM-gkp-ZNW-NW
128
+ Hv-acb-248
129
+ XMXIUasy-Djzc-eW
130
+ DGKW-oZRC-G-1P-SuP-A-GI2SuR-vX-rnH1Y8-heft
131
+ X-C5lAw-Hn-XdR7x
132
+ tsQpkxE-xwuk
133
+ i-pwn
134
+ SQrky-AWCe-xo-x-cU-fo2-u1KhUJ
135
+ aNCzqvs-IVeQ-ZY
136
+ sj
137
+ jeMSw
138
+ UPm-sMd-Dn
139
+ Hho-sG-GpcoS1-IxGcI
140
+ EDrfxBz
141
+ qpW-HBWu-ta
142
+ AIl-FGV
143
+ Lqn-bid-DpI
144
+ Jm
145
+ xE-Lxs-qu
146
+ RliJDAg
147
+ ct-gwQ-SIu
148
+ csneMbEX-Umid-r-AfHD-gDWov-DfxmF4ew-0ENgU-S-pBN9O4c-9HK-c0ElsKnC
149
+ jH-BIYY-pT
150
+ en-GB-oed
151
+
152
+ ILL-FORMED
153
+
154
+ -a
155
+ a-
156
+ a1-Hant-ZH
157
+ aabbccddE
158
+ a--b
159
+ ab-123-abc
160
+ ab-123-abc
161
+ ab-123-abcd
162
+ ab-123-abcd
163
+ ab-1abc-abc
164
+ ab-1abc-abc
165
+ ab-1abc-abcd
166
+ ab-1abc-abcd
167
+ ab--ab
168
+ ab--ab
169
+ ab-a-b
170
+ ab-a-b
171
+ ab-ab-abc
172
+ ab-ab-abc
173
+ ab-ab-abcd
174
+ ab-ab-abcd
175
+ -ab-abc
176
+ -ab-abc
177
+ ab-abc-
178
+ ab-abc-
179
+ ab-abc-abc-abc-abc
180
+ ab-abc-abc-abc-abc
181
+ ab-abcd-abc
182
+ ab-abcd-abc
183
+ ab-abcde-abc
184
+ ab-abcde-abc
185
+ ab-abcde-abcd
186
+ ab-abcde-abcd
187
+ ab-a-x
188
+ ab-a-x
189
+ abcd-efg
190
+ abcdefghi-012345678
191
+ abcdefghi-012345678
192
+ a-foo
193
+ a-Hant-ZH
194
+ a-value
195
+ a-x
196
+ b-fish
197
+ en-enx-eny-enz-enw
198
+ en-UK-oed
199
+ en-US-Latn
200
+ f
201
+ f-Latn
202
+ fr-Latn-F
203
+ overlongone
204
+ tlh-a-b-foo
205
+
206
+ i-notexist # grandfathered but not registered: invalid, even if we only test well-formedness
207
+
208
+ # the following have multiple singletons
209
+ ab-a-abc-a-abc
210
+ en-a-bbb-a-ccc # 'a' appears twice
211
+ ab-c-abc-r-toto-c-abc # 'c' appears twice
212
+
213
+ #mechanically generated ill-formed items
214
+ EdY-z_H791Xx6_m_kj
215
+ qWt85_8S0-L_rbBDq0gl_m_O_zsAx_nRS
216
+ VzyL2
217
+ T_VFJq-L-0JWuH_u2_VW-hK-kbE
218
+ u-t
219
+ Q-f_ZVJXyc-doj_k-i
220
+ JWB7gNa_K-5GB-25t_W-s-ZbGVwDu1-H3E
221
+ b-2T-Qob_L-C9v_2CZxK86
222
+ fQTpX_0_4Vg_L3L_g7VtALh2
223
+ S-Z-E_J
224
+ f6wsq-02_i-F
225
+ 9_GcUPq_G
226
+ QjsIy_9-0-7_Dv2yPV09_D-JXWXM
227
+ D_se-f-k
228
+ ON47Wv1_2_W
229
+ f-z-R_s-ha
230
+ N3APeiw_195_Bx2-mM-pf-Z-Ip5lXWa-5r
231
+ IRjxU-E_6kS_D_b1b_H
232
+ NB-3-5-AyW_FQ-9hB-TrRJg3JV_3C
233
+ yF-3a_V_FoJQAHeL_Z-Mc-u
234
+ n_w_bbunOG_1-s-tJMT5je
235
+ Q-AEWE_X
236
+ 57b1O_k_R6MU_sb
237
+ hK_65J_i-o_SI-Y
238
+ wB4B7u_5I2_I_NZPI
239
+ J24Nb_q_d-zE
240
+ v6-dHjJmvPS_IEb-x_A-O-i
241
+ 8_8_dl-ZgBr84u-P-E
242
+ nIn-xD7EVhe_C
243
+ 5_N-6P_x7Of_Lo_6_YX_R
244
+ 0_46Oo0sZ-YNwiU8Wr_d-M-pg1OriV
245
+ laiY-5
246
+ K-8Mdd-j_ila0sSpo_aO8_J
247
+ wNATtSL-Cp4_gPa_fD41_9z
248
+ H_FGz5V8_n6rrcoz0_1O6d-kH-7-N
249
+ wDOrnHU-odqJ_vWl
250
+ gP_qO-I-jH
251
+ h
252
+ dJ0hX-o_csBykEhU-F
253
+ L-Vf7_BV_eRJ5goSF_Kp
254
+ y-oF-chnavU-H
255
+ 9FkG-8Q-8_v
256
+ W_l_NDQqI-O_SFSAOVq
257
+ kDG3fzXw
258
+ t-nsSp-7-t-mUK2
259
+ Yw-F
260
+ 1-S_3_l
261
+ u-v_brn-Y
262
+ 4_ft_3ZPZC5lA_D
263
+ n_dR-QodsqJnh_e
264
+ Hwvt-bSwZwj_KL-hxg0m-3_hUG
265
+ mQHzvcV-UL-o2O_1KhUJQo_G2_uryk3-a
266
+ b-UTn33HF
267
+ r-Ep-jY-aFM_N_H
268
+ K-k-krEZ0gwD_k_ua-9dm3Oy-s_v
269
+ XS_oS-p
270
+ EIx_h-zf5
271
+ p_z-0_i-omQCo3B
272
+ 1_q0N_jo_9
273
+ 0Ai-6-S
274
+ L-LZEp_HtW
275
+ Zj-A4JD_2A5Aj7_b-m3
276
+ x
277
+ p-qPuXQpp_d-jeKifB-c-7_G-X
278
+ X94cvJ_A
279
+ F2D25R_qk_W-w_Okf_kx
280
+ rc-f
281
+ D
282
+ gD_WrDfxmF-wu-E-U4t
283
+ Z_BN9O4_D9-D_0E_KnCwZF-84b-19
284
+ T-8_g-u-0_E
285
+ lXTtys9j_X_A_m-vtNiNMw_X_b-C6Nr
286
+ V_Ps-4Y-S
287
+ X5wGEA
288
+ mIbHFf_ALu4_Jo1Z1
289
+ ET-TacYx_c
290
+ Z-Lm5cAP_ri88-d_q_fi8-x
291
+ rTi2ah-4j_j_4AlxTs6m_8-g9zqncIf-N5
292
+ FBaLB85_u-0NxhAy-ZU_9c
293
+ x_j_l-5_aV95_s_tY_jp4
294
+ PL768_D-m7jNWjfD-Nl_7qvb_bs_8_Vg
295
+ 9-yOc-gbh
296
+ 6DYxZ_SL-S_Ye
297
+ ZCa-U-muib-6-d-f_oEh_O
298
+ Qt-S-o8340F_f_aGax-c-jbV0gfK_p
299
+ WE_SzOI_OGuoBDk-gDp
300
+ cs-Y_9
301
+ m1_uj
302
+ Y-ob_PT
303
+ li-B
304
+ f-2-7-9m_f8den_J_T_d
305
+ p-Os0dua-H_o-u
306
+ L
307
+ rby-w
308
+
309
+
@@ -0,0 +1,78 @@
1
+ # some unit tests for the Langtag class
2
+
3
+ # Copyright 2007 Martin J. Du"rst (duerst@it.aoyama.ac.jp);
4
+ # available under the same licence as Ruby itself
5
+ # (see http://www.ruby-lang.org/en/LICENSE.txt)
6
+
7
+ $:.unshift File.join(File.dirname(__FILE__), "..", "lib")
8
+ require 'langtag'
9
+
10
+ require 'test/unit'
11
+ class TestLangtag < Test::Unit::TestCase
12
+ # Test to make sure that for a language tag starting with x-,
13
+ # the whole thing is taken as a language part, rather than as a private part
14
+ # (we are using the principle that every (well-formed) language tag
15
+ # has to have a language part).
16
+ def test_private_only
17
+ s = Langtag.new('x-just-private-only')
18
+ assert_equal('x-just-private-only', s.language)
19
+ assert_equal(nil, s.script)
20
+ assert_equal(nil, s.region)
21
+ assert_equal([], s.variants)
22
+ assert_equal([], s.extensions)
23
+ assert_equal(nil, s.private) # this may be somewhat surprising
24
+ assert_equal(true, s.wellformed?)
25
+ end
26
+
27
+ # Test a long language tag
28
+ # Shows some uses of += and -= to manipulate variants and extensions.
29
+ def test_long
30
+ s = Langtag.new('de-Latn-ch-p-abc-q-def-x-myself')
31
+ assert_equal('de', s.language)
32
+ assert_equal('Latn', s.script)
33
+ assert_equal('ch', s.region)
34
+ assert_equal([], s.variants)
35
+ assert_equal(['p-abc', 'q-def'], s.extensions)
36
+ assert_equal('x-myself', s.private)
37
+ s.variants += ['fonipa']
38
+ assert_equal(['fonipa'], s.variants)
39
+ assert_equal('de-Latn-ch-fonipa-p-abc-q-def-x-myself', s)
40
+ assert_equal(true, s.wellformed?)
41
+ s.extensions += ['p-again']
42
+ assert_equal(false, s.wellformed?)
43
+ s.extensions -= ['p-abc']
44
+ assert_equal(true, s.wellformed?)
45
+ assert_equal(['q-def', 'p-again'], s.extensions)
46
+ end
47
+
48
+ # Some nice-casing tests
49
+ def test_nice
50
+ s = Langtag.new('DE-LATN-CH-P-ABC-Q-DEF-X-MYSELF')
51
+ s.nicecase!
52
+ assert_equal('de-Latn-CH-p-abc-q-def-x-myself', s)
53
+ s = Langtag.new('de-latn-ch-p-abc-q-def-x-myself')
54
+ assert_equal('de-Latn-CH-p-abc-q-def-x-myself', s.nicecase)
55
+ assert_equal('Latn', s.nicecase.script)
56
+ end
57
+
58
+ # Mechanical tests for well-formedness, using file langtagTest.txt downloaded from
59
+ # http://unicode.org/cldr/data/tools/java/org/unicode/cldr/util/data/langtagTest.txt,
60
+ # which includes all kinds of tests, many of them collected from the
61
+ # ltru@ietf.org mailing list.
62
+ def test_langtagTest
63
+ wellformed = false # keep track of range in file
64
+ File.open(File.join(File.dirname(__FILE__), 'langtagTest.txt')) do |file|
65
+ file.each_with_index do |line, i|
66
+ tag = line.chomp.sub(/\#.*/, '').strip
67
+ if tag == 'WELL-FORMED'
68
+ wellformed = true
69
+ elsif tag == 'ILL-FORMED'
70
+ wellformed = false
71
+ elsif tag != ''
72
+ assert_equal(wellformed, Langtag.new(tag).wellformed?,
73
+ 'langtagTest.txt, line: '+(i+1).to_s+'; tag: '+tag)
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
metadata ADDED
@@ -0,0 +1,57 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.2
3
+ specification_version: 1
4
+ name: langtag
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.1.0
7
+ date: 2007-03-27 00:00:00 +09:00
8
+ summary: "Support for IETF Language Tags (BCP 47, currently RFC 4646): Wellformedness check, read/write access to parts such as language, script, region, etc."
9
+ require_paths:
10
+ - lib
11
+ email: duerst@it.aoyama.ac.jp
12
+ homepage:
13
+ rubyforge_project:
14
+ description:
15
+ autorequire: langtag
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Martin J. Du"rst
31
+ files:
32
+ - lib/langtag.rb
33
+ - test/langtagTest.txt
34
+ - test/test_langtag.rb
35
+ - README
36
+ test_files:
37
+ - test/test_langtag.rb
38
+ rdoc_options: []
39
+
40
+ extra_rdoc_files:
41
+ - README
42
+ executables: []
43
+
44
+ extensions: []
45
+
46
+ requirements: []
47
+
48
+ dependencies:
49
+ - !ruby/object:Gem::Dependency
50
+ name: composite
51
+ version_requirement:
52
+ version_requirements: !ruby/object:Gem::Version::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: 0.3.0
57
+ version: