vito / chyrp

The ultra-lightweight ultra-flexible blogging engine with a fetish for birds and misspellings.

This URL has Read+Write access

chyrp / gettext.rb
b8168e30 » vito 2008-03-04 Initial import. 1 require "find"
2 require "yaml"
5940b9cd » vito 2008-06-08 Updated Gettext scanner. 3 require "optparse"
4
5 OPTIONS = {
3544192d » vito 2008-10-31 * Bumped version number to ... 6 :project => "Chyrp v2.0 RC3",
78e15e45 » vito 2008-07-19 * gettext.rb improvements 7 :maintainer => "Alex Suraci <suracil.icio.us@gmail.com>",
5940b9cd » vito 2008-06-08 Updated Gettext scanner. 8 :domain => nil,
aa78437e » vito 2008-06-09 Woops, undid my gettext tes... 9 :msgstr => "",#"XXX",
10 :msgstr_filter => "",#"XXX :: %s",
95b4870b » vito 2008-07-29 * database.yaml.php file is... 11 :exclude => [".git", "modules", "lib", "feathers", "themes", "config.yaml.php"],
5940b9cd » vito 2008-06-08 Updated Gettext scanner. 12 :keys => ["name", "description", "plural", "notifications", "confirm"]
13 }
14
44d3e953 » vito 2008-07-30 * Tons of Gettext catching ... 15 # Shamelessly taken from the Twig lexer. :P
16 STRING = /(?:"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)')/sm
17
5940b9cd » vito 2008-06-08 Updated Gettext scanner. 18 ARGV.options do |o|
19 script_name = File.basename($0)
20
21 o.banner = "Usage: #{script_name} [directory] [OPTIONS]"
22 o.define_head "Scans [directory] recursively for various forms of Gettext translations and outputs to a .po file."
23
24 o.separator ""
25
78e15e45 » vito 2008-07-19 * gettext.rb improvements 26 o.on("--project=[val]", String,
27 "The name of the project the .pot file is for.") { |OPTIONS[:project]| }
28 o.on("--maintainer=[val]", String,
29 "The maintainer of the .pot file. (Firstname Lastname <foo@bar.com>)") { |OPTIONS[:maintainer]| }
5940b9cd » vito 2008-06-08 Updated Gettext scanner. 30 o.on("--domain=[val]", String,
78e15e45 » vito 2008-07-19 * gettext.rb improvements 31 "Domain to scan for translations.") { |OPTIONS[:domain]| }
65c64fed » vito 2008-06-09 Various l10n updates and fi... 32 o.on("--msgstr=[val]", String,
33 "Message string to translate all found translations to. Useful for debugging.") { |OPTIONS[:mststr]| }
78e15e45 » vito 2008-07-19 * gettext.rb improvements 34 o.on("--exclude=[val1,val2]", Array,
5940b9cd » vito 2008-06-08 Updated Gettext scanner. 35 "A list of directories to exclude from the scan.") { |OPTIONS[:exclude]| }
78e15e45 » vito 2008-07-19 * gettext.rb improvements 36 o.on("--keys=[val1,val2]", Array,
5940b9cd » vito 2008-06-08 Updated Gettext scanner. 37 "A list of YAML keys for which to generate translations.") { |OPTIONS[:keys]| }
38
39 o.separator ""
40
41 o.on_tail("-h", "--help", "Show this help message.") do
42 puts o
43 exit
44 end
45
46 o.parse!
47 end
48
49 class Gettext
50 def initialize(start)
51 @start, @files, @translations = start, [], {}
52
19e7f177 » vito 2008-10-27 * Fixed the gettext scanner... 53 @domain = (OPTIONS[:domain].nil?) ? "" : ', "'+OPTIONS[:domain]+'"'
aa7ed3a5 » vito 2008-07-06 Gettext updates. 54 @twig_domain = (OPTIONS[:domain].nil? or OPTIONS[:domain] == "theme") ? "" : '\("'+OPTIONS[:domain]+'"\)'
5940b9cd » vito 2008-06-08 Updated Gettext scanner. 55
56 prepare_files
57 do_scan
58 print_pofile
59 end
60
61 def prepare_files
62 Find.find(@start) do |path|
523339b3 » vito 2008-06-09 * Updated jQuery UI 63 cleaned = path.sub("./", "")
5940b9cd » vito 2008-06-08 Updated Gettext scanner. 64 if FileTest.directory?(path)
523339b3 » vito 2008-06-09 * Updated jQuery UI 65 if OPTIONS[:exclude].include?(cleaned)
5940b9cd » vito 2008-06-08 Updated Gettext scanner. 66 Find.prune
67 else
68 next
b8168e30 » vito 2008-03-04 Initial import. 69 end
5940b9cd » vito 2008-06-08 Updated Gettext scanner. 70 else
71 next unless path =~ /\.(php|twig|yaml)/
44d3e953 » vito 2008-07-30 * Tons of Gettext catching ... 72 @files << [cleaned, path] if File.read(path) =~ /(__|_f|_p)\((#{STRING})#{@domain}\)/
850de9c6 » vito 2008-07-31 * Fixed the gettext lexer a... 73 @files << [cleaned, path] if File.read(path) =~ /Group::add_permission\(([^,]+), (#{STRING})\)/
44d3e953 » vito 2008-07-30 * Tons of Gettext catching ... 74 @files << [cleaned, path] if File.read(path) =~ /(#{STRING})\s*\|\s*translate#{@twig_domain}/
75 @files << [cleaned, path] if File.read(path) =~ /(#{STRING})\s*\|\s*translate_plural\((#{STRING}),\s*.*?#{@domain}\)\s*\|\s*format\(.*?\)/
523339b3 » vito 2008-06-09 * Updated jQuery UI 76 @files << [cleaned, path] if path =~ /\.yaml/
b8168e30 » vito 2008-03-04 Initial import. 77 end
5940b9cd » vito 2008-06-08 Updated Gettext scanner. 78 end
79 end
80
81 def do_scan
82 @files.each do |cleaned, file|
83 if File.basename(file) =~ /\.yaml$/
84 scan_yaml file, cleaned
85 next
b8168e30 » vito 2008-03-04 Initial import. 86 end
5940b9cd » vito 2008-06-08 Updated Gettext scanner. 87
88 counter = 1
89 File.open(file, "r") do |infile|
90 while line = infile.gets
91 scan_normal line, counter, file, cleaned
44d3e953 » vito 2008-07-30 * Tons of Gettext catching ... 92 scan_permissions line, counter, file, cleaned
5940b9cd » vito 2008-06-08 Updated Gettext scanner. 93 scan_filter line, counter, file, cleaned
94 scan_plural line, counter, file, cleaned
95 scan_twig line, counter, file, cleaned
96 scan_twig_filter line, counter, file, cleaned
97 scan_twig_plural line, counter, file, cleaned
98 counter += 1
246c5cb7 » vito 2008-04-30 Gettext updates. 99 end
100 end
5940b9cd » vito 2008-06-08 Updated Gettext scanner. 101 end
102 end
103
104 def scan_normal(text, line, filename, clean_filename)
44d3e953 » vito 2008-07-30 * Tons of Gettext catching ... 105 text.gsub(/__\((#{STRING})#{@domain}\)/) do
106 if @translations[$1].nil?
107 @translations[$1] = { :places => [clean_filename + ":" + line.to_s],
108 :filter => false,
109 :plural => false }
110 elsif not @translations[$1][:places].include?(clean_filename + ":" + line.to_s)
111 @translations[$1][:places] << clean_filename + ":" + line.to_s
112 end
113 end
114 end
115
116 def scan_permissions(text, line, filename, clean_filename)
850de9c6 » vito 2008-07-31 * Fixed the gettext lexer a... 117 text.gsub(/Group::add_permission\(([^,]+), (#{STRING})\)/) do
d68881c7 » vito 2008-07-22 Gettext scanner now accepts... 118 if @translations[$2].nil?
119 @translations[$2] = { :places => [clean_filename + ":" + line.to_s],
5940b9cd » vito 2008-06-08 Updated Gettext scanner. 120 :filter => false,
121 :plural => false }
d68881c7 » vito 2008-07-22 Gettext scanner now accepts... 122 elsif not @translations[$2][:places].include?(clean_filename + ":" + line.to_s)
123 @translations[$2][:places] << clean_filename + ":" + line.to_s
b8168e30 » vito 2008-03-04 Initial import. 124 end
125 end
5940b9cd » vito 2008-06-08 Updated Gettext scanner. 126 end
127
128 def scan_filter(text, line, filename, clean_filename)
44d3e953 » vito 2008-07-30 * Tons of Gettext catching ... 129 text.gsub(/_f\((#{STRING}), .*?#{@domain}\)/) do
130 if @translations[$1].nil?
131 @translations[$1] = { :places => [clean_filename + ":" + line.to_s],
5940b9cd » vito 2008-06-08 Updated Gettext scanner. 132 :filter => true,
133 :plural => false }
44d3e953 » vito 2008-07-30 * Tons of Gettext catching ... 134 elsif not @translations[$1][:places].include?(clean_filename + ":" + line.to_s)
135 @translations[$1][:places] << clean_filename + ":" + line.to_s
5940b9cd » vito 2008-06-08 Updated Gettext scanner. 136 end
137 end
138 end
139
140 def scan_plural(text, line, filename, clean_filename)
44d3e953 » vito 2008-07-30 * Tons of Gettext catching ... 141 text.gsub(/_p\((#{STRING}), (#{STRING}), .*?#{@domain}\)/) do
142 if @translations[$1].nil?
143 @translations[$1] = { :places => [clean_filename + ":" + line.to_s],
5940b9cd » vito 2008-06-08 Updated Gettext scanner. 144 :filter => true,
850de9c6 » vito 2008-07-31 * Fixed the gettext lexer a... 145 :plural => $4 }
44d3e953 » vito 2008-07-30 * Tons of Gettext catching ... 146 elsif not @translations[$1][:places].include?(clean_filename + ":" + line.to_s)
147 @translations[$1][:places] << clean_filename + ":" + line.to_s
5940b9cd » vito 2008-06-08 Updated Gettext scanner. 148 end
149 end
150 end
151
152 def scan_twig(text, line, filename, clean_filename)
44d3e953 » vito 2008-07-30 * Tons of Gettext catching ... 153 text.gsub(/[\s\{\(](#{STRING})\s*\|\s*translate(?!_plural)#{@twig_domain}(?!\s*\|\s*format)/) do
154 if @translations[$1].nil?
155 @translations[$1] = { :places => [clean_filename + ":" + line.to_s],
5940b9cd » vito 2008-06-08 Updated Gettext scanner. 156 :filter => false,
157 :plural => false }
44d3e953 » vito 2008-07-30 * Tons of Gettext catching ... 158 elsif not @translations[$1][:places].include?(clean_filename + ":" + line.to_s)
159 @translations[$1][:places] << clean_filename + ":" + line.to_s
5940b9cd » vito 2008-06-08 Updated Gettext scanner. 160 end
161 end
162 end
163
164 def scan_twig_filter(text, line, filename, clean_filename)
44d3e953 » vito 2008-07-30 * Tons of Gettext catching ... 165 text.gsub(/[\s\{\(](#{STRING})\s*\|\s*translate(?!_plural)#{@twig_domain}\s*\|\s*format\(.*?\).*?/) do
166 if @translations[$1].nil?
167 @translations[$1] = { :places => [clean_filename + ":" + line.to_s],
5940b9cd » vito 2008-06-08 Updated Gettext scanner. 168 :filter => true,
169 :plural => false }
44d3e953 » vito 2008-07-30 * Tons of Gettext catching ... 170 elsif not @translations[$1][:places].include?(clean_filename + ":" + line.to_s)
171 @translations[$1][:places] << clean_filename + ":" + line.to_s
5940b9cd » vito 2008-06-08 Updated Gettext scanner. 172 end
173 end
174 end
175
176 def scan_twig_plural(text, line, filename, clean_filename)
44d3e953 » vito 2008-07-30 * Tons of Gettext catching ... 177 text.gsub(/[\s\{\(](#{STRING})\s*\|\s*translate_plural\((#{STRING}), .*?#{@domain}\)\s*\|\s*format\(.*?\)/) do
178 if @translations[$1].nil?
179 @translations[$1] = { :places => [clean_filename + ":" + line.to_s],
5940b9cd » vito 2008-06-08 Updated Gettext scanner. 180 :filter => true,
850de9c6 » vito 2008-07-31 * Fixed the gettext lexer a... 181 :plural => $4 }
44d3e953 » vito 2008-07-30 * Tons of Gettext catching ... 182 elsif not @translations[$1][:places].include?(clean_filename + ":" + line.to_s)
183 @translations[$1][:places] << clean_filename + ":" + line.to_s
5940b9cd » vito 2008-06-08 Updated Gettext scanner. 184 end
185 end
186 end
187
ea726f75 » vito 2008-06-09 * Gettext scanner now corre... 188 def scan_yaml(filename, clean_filename)
189 info = YAML.load_file(filename)
190 counter = 0
191 info.each do |key, val|
192 counter += 1
193 next unless OPTIONS[:keys].include?(key)
194
195 if val.class == String
44d3e953 » vito 2008-07-30 * Tons of Gettext catching ... 196 val.gsub!("\"", "\\\"")
197 val = '"'+val+'"'
ea726f75 » vito 2008-06-09 * Gettext scanner now corre... 198 if @translations[val].nil?
199 @translations[val] = { :places => [clean_filename + ":" + counter.to_s],
200 :filter => false,
201 :plural => false }
aa7ed3a5 » vito 2008-07-06 Gettext updates. 202 elsif not @translations[val][:places].include?(clean_filename + ":" + counter.to_s)
ea726f75 » vito 2008-06-09 * Gettext scanner now corre... 203 @translations[val][:places] << clean_filename + ":" + counter.to_s
204 end
205 end
206 if val.class == Array
207 val.each do |val|
44d3e953 » vito 2008-07-30 * Tons of Gettext catching ... 208 val.gsub!("\"", "\\\"")
209 val = '"'+val+'"'
ea726f75 » vito 2008-06-09 * Gettext scanner now corre... 210 if @translations[val].nil?
211 @translations[val] = { :places => [clean_filename + ":" + counter.to_s],
212 :filter => false,
213 :plural => false }
aa7ed3a5 » vito 2008-07-06 Gettext updates. 214 elsif not @translations[val][:places].include?(clean_filename + ":" + counter.to_s)
ea726f75 » vito 2008-06-09 * Gettext scanner now corre... 215 @translations[val][:places] << clean_filename + ":" + counter.to_s
216 end
217 counter += 1
218 end
219 end
220 end
221 end
222
5940b9cd » vito 2008-06-08 Updated Gettext scanner. 223 def print_pofile
78e15e45 » vito 2008-07-19 * gettext.rb improvements 224 puts '# '+OPTIONS[:project]+' Translation File.'
225 puts '# Copyright (C) YEAR '+OPTIONS[:maintainer].gsub(/ <([^>]+)>/, "")
226 puts '# This file is distributed under the same license as the '+OPTIONS[:project]+' package.'
227 puts '# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.'
5940b9cd » vito 2008-06-08 Updated Gettext scanner. 228 puts '#'
229 puts '#, fuzzy'
230 puts 'msgid ""'
231 puts 'msgstr ""'
78e15e45 » vito 2008-07-19 * gettext.rb improvements 232 puts '"Project-Id-Version: '+OPTIONS[:project]+'\n"'
233 puts '"Report-Msgid-Bugs-To: '+OPTIONS[:maintainer].gsub(/[^<]+ <([^>]+)>/, "\\1")+'\n"'
234 puts '"POT-Creation-Date: '+Time.now.utc.strftime("%Y-%m-%d %H:%M")+'+0000\n"'
235 puts '"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"'
236 puts '"Last-Translator: FIRST LAST <EMAIL@EXAMPLE.COM>\n"'
237 puts '"Language-Team: LANGUAGE <EMAIL@EXAMPLE.COM>\n"'
5940b9cd » vito 2008-06-08 Updated Gettext scanner. 238 puts '"MIME-Version: 1.0\n"'
78e15e45 » vito 2008-07-19 * gettext.rb improvements 239 puts '"Content-Type: text/plain; charset=CHARSET\n"'
5940b9cd » vito 2008-06-08 Updated Gettext scanner. 240 puts '"Content-Transfer-Encoding: 8bit\n"'
78e15e45 » vito 2008-07-19 * gettext.rb improvements 241 puts '"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"'
5940b9cd » vito 2008-06-08 Updated Gettext scanner. 242 puts ''
243
244 output = ""
245 @translations.each do |text, attr|
246 attr[:places].each do |place|
247 output << "#: "+place+"\n"
248 end
249 output << "#, php-format\n" if attr[:filter]
44d3e953 » vito 2008-07-30 * Tons of Gettext catching ... 250 output << "msgid "+text+"\n"
251 output << "msgid_plural "+attr[:plural]+"\n" if attr[:plural]
5940b9cd » vito 2008-06-08 Updated Gettext scanner. 252
253 if attr[:plural]
65c64fed » vito 2008-06-09 Various l10n updates and fi... 254 output << "msgstr[0] \"#{OPTIONS[:msgstr]}\"\n"
255 output << "msgstr[1] \"#{OPTIONS[:msgstr]}\"\n"
5940b9cd » vito 2008-06-08 Updated Gettext scanner. 256 else
65c64fed » vito 2008-06-09 Various l10n updates and fi... 257 output << "msgstr \"#{(attr[:filter]) ? OPTIONS[:msgstr_filter] || OPTIONS[:msgstr] : OPTIONS[:msgstr]}\"\n"
5940b9cd » vito 2008-06-08 Updated Gettext scanner. 258 end
259
260 output << "\n"
261 end
44d3e953 » vito 2008-07-30 * Tons of Gettext catching ... 262 puts output
5940b9cd » vito 2008-06-08 Updated Gettext scanner. 263 end
b8168e30 » vito 2008-03-04 Initial import. 264 end
5940b9cd » vito 2008-06-08 Updated Gettext scanner. 265
c5ada11b » vito 2008-10-11 * Moved PHP version check f... 266 Gettext.new ARGV[0] || "."