i18n_yaml_sorter 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,10 @@
1
+ module I18nYamlSorter
2
+ if defined? Rails::Railtie
3
+ require 'rails'
4
+ class Railtie < Rails::Railtie
5
+ rake_tasks do
6
+ load "tasks/i18n_yaml_sorter.rake"
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,128 @@
1
+ module I18nYamlSorter
2
+ class Sorter
3
+ def initialize(io_input)
4
+ @io_input = io_input
5
+ end
6
+
7
+ def sort
8
+ @array = break_blocks_into_array
9
+ @current_array_index = 0
10
+ sorted_yaml_from_blocks_array
11
+ end
12
+
13
+ private
14
+
15
+ def break_blocks_into_array
16
+ array = []
17
+
18
+ loop do
19
+
20
+ maybe_next_line = @read_line_again || @io_input.gets || break
21
+ @read_line_again = nil
22
+ maybe_next_line.chomp!
23
+
24
+ #Is it blank? Discard!
25
+ next if maybe_next_line.match(/^\s*$/)
26
+
27
+ #Does it look like a key: value line?
28
+ key_value_parse = maybe_next_line.match(/^(\s*)(["']?[\w\-]+["']?)(: )(\s*)(\S.*\S)(\s*)$/)
29
+ if key_value_parse
30
+ array << maybe_next_line.concat("\n") #yes, it is the beginning of a key:value block
31
+
32
+ #Special cases when it should add extra lines to the array element (multi line quoted strings)
33
+
34
+ #Is the value surrounded by quotes?
35
+ starts_with_quote = key_value_parse[5].match(/^["']/)[0] rescue nil
36
+ ends_with_quote = key_value_parse[5].match(/[^\\](["'])$/)[1] rescue nil
37
+ if starts_with_quote and !(starts_with_quote == ends_with_quote)
38
+
39
+ loop do #Append next lines until we find the closing quote
40
+ content_line = @io_input.gets || break
41
+ content_line.chomp!
42
+ array.last << content_line.concat("\n")
43
+ break if content_line.match(/[^\\][#{starts_with_quote}]\s*$/)
44
+ end
45
+
46
+ end # if starts_with_quote
47
+
48
+ next
49
+ end # if key_value_parse
50
+
51
+ # Is it a | or > string alue?
52
+ is_special_string = maybe_next_line.match(/^(\s*)(["']?[\w\-]+["']?)(: )(\s*)([|>])(\s*)$/)
53
+ if is_special_string
54
+ array << maybe_next_line.concat("\n") #yes, it is the beginning of a key block
55
+ indentation = is_special_string[1]
56
+ #Append the next lines until we find one that is not indented
57
+ loop do
58
+ content_line = @io_input.gets || break
59
+ processed_line = content_line.chomp
60
+ this_indentation = processed_line.match(/^\s*/)[0] rescue ""
61
+ if indentation.size < this_indentation.size
62
+ array.last << processed_line.concat("\n")
63
+ else
64
+ @read_line_again = content_line
65
+ break
66
+ end
67
+ end
68
+
69
+ next
70
+ end #if is_special_string
71
+
72
+ # Is it the begining of a multi level hash?
73
+ is_start_of_hash = maybe_next_line.match(/^(\s*)(["']?[\w\-]+["']?)(:)(\s*)$/)
74
+ if is_start_of_hash
75
+ array << maybe_next_line.concat("\n")
76
+ next
77
+ end
78
+
79
+ #If we got here and nothing was done, this line
80
+ # should probably be merged with the previous one.
81
+ if array.last
82
+ array.last << maybe_next_line.concat("\n")
83
+ else
84
+ array << maybe_next_line.concat("\n")
85
+ end
86
+ end #loop
87
+
88
+ #debug:
89
+ #puts array.join("$$$$$$$$$$$$$$$$$$$$$$\n")
90
+
91
+ array
92
+ end
93
+
94
+ def sorted_yaml_from_blocks_array(current_block = nil)
95
+
96
+ unless current_block
97
+ current_block = @array[@current_array_index]
98
+ @current_array_index += 1
99
+ end
100
+
101
+ out_array = []
102
+ current_match = current_block.match(/^(\s*)(["']?[\w\-]+["']?)(:)/)
103
+ current_level = current_match[1] rescue ''
104
+ current_key = current_match[2].downcase.tr(%q{"'}, "") rescue ''
105
+ out_array << [current_key, current_block]
106
+
107
+ loop do
108
+ next_block = @array[@current_array_index] || break
109
+ @current_array_index += 1
110
+
111
+ current_match = next_block.match(/^(\s*)(["']?[\w\-]+["']?)(:)/) || next
112
+ current_key = current_match[2].downcase.tr(%q{"'}, "")
113
+ next_level = current_match[1]
114
+
115
+ if current_level.size < next_level.size
116
+ out_array.last.last << sorted_yaml_from_blocks_array(next_block)
117
+ elsif current_level.size == next_level.size
118
+ out_array << [current_key, next_block]
119
+ elsif current_level.size > next_level.size
120
+ @current_array_index -= 1
121
+ break
122
+ end
123
+ end
124
+
125
+ return out_array.sort.map(&:last).join
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,16 @@
1
+ require 'i18n_yaml_sorter'
2
+
3
+ namespace :i18n do
4
+
5
+ desc "Sort locales keys in alphabetic order. Sort all locales if no path parameter given"
6
+
7
+ task :sort, [:path_to_file] => :environment do |t , args|
8
+ locales = args[:path_to_file] || Dir.glob("#{Rails.root}/config/locales/**/*.yml")
9
+
10
+ locales.each do |locale_path|
11
+ sorted_contents = File.open(locale_path) { |f| I18nYamlSorter::Sorter.new(f).sort }
12
+ File.open(locale_path, 'w') { |f| f << sorted_contents}
13
+ end
14
+ end
15
+
16
+ end
@@ -1,8 +1,17 @@
1
1
  require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
2
10
  require 'test/unit'
11
+ require 'yaml'
3
12
 
4
- $LOAD_PATH.unshift(File.dirname(__FILE__))
5
13
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
6
15
  require 'i18n_yaml_sorter'
7
16
 
8
17
  class Test::Unit::TestCase
@@ -1,4 +1,4 @@
1
-
1
+ # encoding: UTF-8
2
2
 
3
3
  m_13: >
4
4
  Não deve dar problema aqui!
@@ -0,0 +1,239 @@
1
+ # encoding: UTF-8
2
+ # pt-BR translations for Ruby on Rails
3
+ "pt-BR":
4
+ date:
5
+ # formatos de data e hora
6
+ formats:
7
+ default: "%d/%m/%Y"
8
+ short: "%d de %B"
9
+ long: "%d de %B de %Y"
10
+
11
+ day_names:
12
+ - Domingo
13
+ - Segunda
14
+ - Terça
15
+ - Quarta
16
+ - Quinta
17
+ - Sexta
18
+ - Sábado
19
+ abbr_day_names:
20
+ - Dom
21
+ - Seg
22
+ - Ter
23
+ - Qua
24
+ - Qui
25
+ - Sex
26
+ - Sáb
27
+
28
+ month_names:
29
+ - ~
30
+ - Janeiro
31
+ - Fevereiro
32
+ - Março
33
+ - Abril
34
+ - Maio
35
+ - Junho
36
+ - Julho
37
+ - Agosto
38
+ - Setembro
39
+ - Outubro
40
+ - Novembro
41
+ - Dezembro
42
+ abbr_month_names:
43
+ - ~
44
+ - Jan
45
+ - Fev
46
+ - Mar
47
+ - Abr
48
+ - Mai
49
+ - Jun
50
+ - Jul
51
+ - Ago
52
+ - Set
53
+ - Out
54
+ - Nov
55
+ - Dez
56
+ order:
57
+ - :day
58
+ - :month
59
+ - :year
60
+
61
+ time:
62
+ formats:
63
+ default: "%A, %d de %B de %Y, %H:%M h"
64
+ short: "%d/%m, %H:%M h"
65
+ long: "%A, %d de %B de %Y, %H:%M h"
66
+ am: ''
67
+ pm: ''
68
+
69
+ support:
70
+ array:
71
+ # Usado no Array.to_sentence
72
+ words_connector: ", "
73
+ two_words_connector: " e "
74
+ last_word_connector: " e "
75
+
76
+ select:
77
+ prompt: "Por favor selecione"
78
+
79
+ number:
80
+ format:
81
+ separator: ','
82
+ delimiter: '.'
83
+ precision: 3
84
+ significant: false
85
+ strip_insignificant_zeros: false
86
+
87
+ currency:
88
+ format:
89
+ format: '%u %n'
90
+ unit: 'R$'
91
+ separator: ','
92
+ delimiter: '.'
93
+ precision: 2
94
+ significant: false
95
+ strip_insignificant_zeros: false
96
+
97
+ percentage:
98
+ format:
99
+ delimiter: '.'
100
+
101
+ precision:
102
+ format:
103
+ delimiter: '.'
104
+
105
+ human:
106
+ format:
107
+ delimiter: '.'
108
+ precision: 2
109
+ significant: true
110
+ strip_insignificant_zeros: true
111
+ storage_units:
112
+ format: "%n %u"
113
+ units:
114
+ byte:
115
+ one: "Byte"
116
+ other: "Bytes"
117
+ kb: "KB"
118
+ mb: "MB"
119
+ gb: "GB"
120
+ tb: "TB"
121
+ decimal_units:
122
+ # number_to_human()
123
+ # new in rails 3: please add to other locales
124
+ format: "%n %u"
125
+ units:
126
+ unit: ""
127
+ thousand: "mil"
128
+ million:
129
+ one: milhão
130
+ other: milhões
131
+ billion:
132
+ one: bilhão
133
+ other: bilhões
134
+ trillion:
135
+ one: trilhão
136
+ other: trilhões
137
+ quadrillion:
138
+ one: quatrilhão
139
+ other: quatrilhões
140
+
141
+ datetime:
142
+ distance_in_words:
143
+ # distancia do tempo em palavras
144
+ half_a_minute: 'meio minuto'
145
+ less_than_x_seconds:
146
+ one: 'menos de 1 segundo'
147
+ other: 'menos de %{count} segundos'
148
+ x_seconds:
149
+ one: '1 segundo'
150
+ other: '%{count} segundos'
151
+ less_than_x_minutes:
152
+ one: 'menos de um minuto'
153
+ other: 'menos de %{count} minutos'
154
+ x_minutes:
155
+ one: '1 minuto'
156
+ other: '%{count} minutos'
157
+ about_x_hours:
158
+ one: 'aproximadamente 1 hora'
159
+ other: 'aproximadamente %{count} horas'
160
+ x_days:
161
+ one: '1 dia'
162
+ other: '%{count} dias'
163
+ about_x_months:
164
+ one: 'aproximadamente 1 mês'
165
+ other: 'aproximadamente %{count} meses'
166
+ x_months:
167
+ one: '1 mês'
168
+ other: '%{count} meses'
169
+ about_x_years:
170
+ one: 'aproximadamente 1 ano'
171
+ other: 'aproximadamente %{count} anos'
172
+ over_x_years:
173
+ one: 'mais de 1 ano'
174
+ other: 'mais de %{count} anos'
175
+ almost_x_years:
176
+ one: 'quase 1 ano'
177
+ other: 'quase %{count} anos'
178
+ prompts:
179
+ year: "Ano"
180
+ month: "Mês"
181
+ day: "Dia"
182
+ hour: "Hora"
183
+ minute: "Minuto"
184
+ second: "Segundo"
185
+
186
+ helpers:
187
+ select:
188
+ prompt: "Por favor selecione"
189
+
190
+ submit:
191
+ create: 'Criar %{model}'
192
+ update: 'Atualizar %{model}'
193
+ submit: 'Salvar %{model}'
194
+
195
+ errors:
196
+ format: "%{attribute} %{message}"
197
+
198
+ template:
199
+ header:
200
+ one: "Não foi possível gravar %{model}: 1 erro"
201
+ other: "Não foi possível gravar %{model}: %{count} erros."
202
+ body: "Por favor, verifique o(s) seguinte(s) campo(s):"
203
+
204
+ messages: &errors_messages
205
+ inclusion: "não está incluído na lista"
206
+ exclusion: "não está disponível"
207
+ invalid: "não é válido"
208
+ confirmation: "não está de acordo com a confirmação"
209
+ accepted: "deve ser aceito"
210
+ empty: "não pode ficar vazio"
211
+ blank: "não pode ficar em branco"
212
+ too_long: "é muito longo (máximo: %{count} caracteres)"
213
+ too_short: "é muito curto (mínimo: %{count} caracteres)"
214
+ wrong_length: "não possui o tamanho esperado (%{count} caracteres)"
215
+ not_a_number: "não é um número"
216
+ not_an_integer: "não é um número inteiro"
217
+ greater_than: "deve ser maior que %{count}"
218
+ greater_than_or_equal_to: "deve ser maior ou igual a %{count}"
219
+ equal_to: "deve ser igual a %{count}"
220
+ less_than: "deve ser menor que %{count}"
221
+ less_than_or_equal_to: "deve ser menor ou igual a %{count}"
222
+ odd: "deve ser ímpar"
223
+ even: "deve ser par"
224
+
225
+ activerecord:
226
+ errors:
227
+ template:
228
+ header:
229
+ one: "Não foi possível gravar %{model}: 1 erro"
230
+ other: "Não foi possível gravar %{model}: %{count} erros."
231
+ body: "Por favor, verifique o(s) seguinte(s) campo(s):"
232
+
233
+ messages:
234
+ taken: "já está em uso"
235
+ record_invalid: "A validação falhou: %{errors}"
236
+ <<: *errors_messages
237
+
238
+ full_messages:
239
+ format: "%{attribute} %{message}"
@@ -0,0 +1,28 @@
1
+ pt-BR:
2
+ # Note how this is a nice way of inputing
3
+ # paragraphs of text in YAML.
4
+ apples: >
5
+ Maçãs são boas,
6
+ só não coma
7
+ seus iPods!
8
+ grapes: Não comemos elas.
9
+ bananas: |
10
+ Bananas são "legais":
11
+ - Elas são <b> doces </b>.
12
+ isto: não é chave
13
+
14
+ Por isto todos gostam de bananas!
15
+ en-US:
16
+ # Note that our comments are important:
17
+ # Don't let your yaml sorter delete them!
18
+ grapes: We dont' eat them.
19
+ bananas: |
20
+ Bananas are "nice":
21
+ - They are <b> sweet </b>.
22
+ this: not a key
23
+
24
+ That is why everyone like bananas!
25
+ apples: >
26
+ Apples are fine,
27
+ just don't eat your
28
+ iPods!