vito / chyrp
- Source
- Commits
- Network (23)
- Issues (0)
- Downloads (9)
- Wiki (21)
- Graphs
-
Tree:
953c354
chyrp / gettext.rb
| b8168e30 » | vito | 2008-03-04 | 1 | require "find" | |
| 2 | require "yaml" | ||||
| 5940b9cd » | vito | 2008-06-08 | 3 | require "optparse" | |
| 4 | |||||
| 5 | OPTIONS = { | ||||
| 3544192d » | vito | 2008-10-31 | 6 | :project => "Chyrp v2.0 RC3", | |
| 78e15e45 » | vito | 2008-07-19 | 7 | :maintainer => "Alex Suraci <suracil.icio.us@gmail.com>", | |
| 5940b9cd » | vito | 2008-06-08 | 8 | :domain => nil, | |
| aa78437e » | vito | 2008-06-09 | 9 | :msgstr => "",#"XXX", | |
| 10 | :msgstr_filter => "",#"XXX :: %s", | ||||
| 95b4870b » | vito | 2008-07-29 | 11 | :exclude => [".git", "modules", "lib", "feathers", "themes", "config.yaml.php"], | |
| 5940b9cd » | vito | 2008-06-08 | 12 | :keys => ["name", "description", "plural", "notifications", "confirm"] | |
| 13 | } | ||||
| 14 | |||||
| 44d3e953 » | vito | 2008-07-30 | 15 | # Shamelessly taken from the Twig lexer. :P | |
| 16 | STRING = /(?:"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)')/sm | ||||
| 17 | |||||
| 5940b9cd » | vito | 2008-06-08 | 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 | 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 | 30 | o.on("--domain=[val]", String, | |
| 78e15e45 » | vito | 2008-07-19 | 31 | "Domain to scan for translations.") { |OPTIONS[:domain]| } | |
| 65c64fed » | vito | 2008-06-09 | 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 | 34 | o.on("--exclude=[val1,val2]", Array, | |
| 5940b9cd » | vito | 2008-06-08 | 35 | "A list of directories to exclude from the scan.") { |OPTIONS[:exclude]| } | |
| 78e15e45 » | vito | 2008-07-19 | 36 | o.on("--keys=[val1,val2]", Array, | |
| 5940b9cd » | vito | 2008-06-08 | 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 | 53 | @domain = (OPTIONS[:domain].nil?) ? "" : ', "'+OPTIONS[:domain]+'"' | |
| aa7ed3a5 » | vito | 2008-07-06 | 54 | @twig_domain = (OPTIONS[:domain].nil? or OPTIONS[:domain] == "theme") ? "" : '\("'+OPTIONS[:domain]+'"\)' | |
| 5940b9cd » | vito | 2008-06-08 | 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 | 63 | cleaned = path.sub("./", "") | |
| 5940b9cd » | vito | 2008-06-08 | 64 | if FileTest.directory?(path) | |
| 523339b3 » | vito | 2008-06-09 | 65 | if OPTIONS[:exclude].include?(cleaned) | |
| 5940b9cd » | vito | 2008-06-08 | 66 | Find.prune | |
| 67 | else | ||||
| 68 | next | ||||
| b8168e30 » | vito | 2008-03-04 | 69 | end | |
| 5940b9cd » | vito | 2008-06-08 | 70 | else | |
| 71 | next unless path =~ /\.(php|twig|yaml)/ | ||||
| 44d3e953 » | vito | 2008-07-30 | 72 | @files << [cleaned, path] if File.read(path) =~ /(__|_f|_p)\((#{STRING})#{@domain}\)/ | |
| 850de9c6 » | vito | 2008-07-31 | 73 | @files << [cleaned, path] if File.read(path) =~ /Group::add_permission\(([^,]+), (#{STRING})\)/ | |
| 44d3e953 » | vito | 2008-07-30 | 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 | 76 | @files << [cleaned, path] if path =~ /\.yaml/ | |
| b8168e30 » | vito | 2008-03-04 | 77 | end | |
| 5940b9cd » | vito | 2008-06-08 | 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 | 86 | end | |
| 5940b9cd » | vito | 2008-06-08 | 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 | 92 | scan_permissions line, counter, file, cleaned | |
| 5940b9cd » | vito | 2008-06-08 | 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 | 99 | end | |
| 100 | end | ||||
| 5940b9cd » | vito | 2008-06-08 | 101 | end | |
| 102 | end | ||||
| 103 | |||||
| 104 | def scan_normal(text, line, filename, clean_filename) | ||||
| 44d3e953 » | vito | 2008-07-30 | 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 | 117 | text.gsub(/Group::add_permission\(([^,]+), (#{STRING})\)/) do | |
| d68881c7 » | vito | 2008-07-22 | 118 | if @translations[$2].nil? | |
| 119 | @translations[$2] = { :places => [clean_filename + ":" + line.to_s], | ||||
| 5940b9cd » | vito | 2008-06-08 | 120 | :filter => false, | |
| 121 | :plural => false } | ||||
| d68881c7 » | vito | 2008-07-22 | 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 | 124 | end | |
| 125 | end | ||||
| 5940b9cd » | vito | 2008-06-08 | 126 | end | |
| 127 | |||||
| 128 | def scan_filter(text, line, filename, clean_filename) | ||||
| 44d3e953 » | vito | 2008-07-30 | 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 | 132 | :filter => true, | |
| 133 | :plural => false } | ||||
| 44d3e953 » | vito | 2008-07-30 | 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 | 136 | end | |
| 137 | end | ||||
| 138 | end | ||||
| 139 | |||||
| 140 | def scan_plural(text, line, filename, clean_filename) | ||||
| 44d3e953 » | vito | 2008-07-30 | 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 | 144 | :filter => true, | |
| 850de9c6 » | vito | 2008-07-31 | 145 | :plural => $4 } | |
| 44d3e953 » | vito | 2008-07-30 | 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 | 148 | end | |
| 149 | end | ||||
| 150 | end | ||||
| 151 | |||||
| 152 | def scan_twig(text, line, filename, clean_filename) | ||||
| 44d3e953 » | vito | 2008-07-30 | 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 | 156 | :filter => false, | |
| 157 | :plural => false } | ||||
| 44d3e953 » | vito | 2008-07-30 | 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 | 160 | end | |
| 161 | end | ||||
| 162 | end | ||||
| 163 | |||||
| 164 | def scan_twig_filter(text, line, filename, clean_filename) | ||||
| 44d3e953 » | vito | 2008-07-30 | 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 | 168 | :filter => true, | |
| 169 | :plural => false } | ||||
| 44d3e953 » | vito | 2008-07-30 | 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 | 172 | end | |
| 173 | end | ||||
| 174 | end | ||||
| 175 | |||||
| 176 | def scan_twig_plural(text, line, filename, clean_filename) | ||||
| 44d3e953 » | vito | 2008-07-30 | 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 | 180 | :filter => true, | |
| 850de9c6 » | vito | 2008-07-31 | 181 | :plural => $4 } | |
| 44d3e953 » | vito | 2008-07-30 | 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 | 184 | end | |
| 185 | end | ||||
| 186 | end | ||||
| 187 | |||||
| ea726f75 » | vito | 2008-06-09 | 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 | 196 | val.gsub!("\"", "\\\"") | |
| 197 | val = '"'+val+'"' | ||||
| ea726f75 » | vito | 2008-06-09 | 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 | 202 | elsif not @translations[val][:places].include?(clean_filename + ":" + counter.to_s) | |
| ea726f75 » | vito | 2008-06-09 | 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 | 208 | val.gsub!("\"", "\\\"") | |
| 209 | val = '"'+val+'"' | ||||
| ea726f75 » | vito | 2008-06-09 | 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 | 214 | elsif not @translations[val][:places].include?(clean_filename + ":" + counter.to_s) | |
| ea726f75 » | vito | 2008-06-09 | 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 | 223 | def print_pofile | |
| 78e15e45 » | vito | 2008-07-19 | 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 | 228 | puts '#' | |
| 229 | puts '#, fuzzy' | ||||
| 230 | puts 'msgid ""' | ||||
| 231 | puts 'msgstr ""' | ||||
| 78e15e45 » | vito | 2008-07-19 | 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 | 238 | puts '"MIME-Version: 1.0\n"' | |
| 78e15e45 » | vito | 2008-07-19 | 239 | puts '"Content-Type: text/plain; charset=CHARSET\n"' | |
| 5940b9cd » | vito | 2008-06-08 | 240 | puts '"Content-Transfer-Encoding: 8bit\n"' | |
| 78e15e45 » | vito | 2008-07-19 | 241 | puts '"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"' | |
| 5940b9cd » | vito | 2008-06-08 | 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 | 250 | output << "msgid "+text+"\n" | |
| 251 | output << "msgid_plural "+attr[:plural]+"\n" if attr[:plural] | ||||
| 5940b9cd » | vito | 2008-06-08 | 252 | ||
| 253 | if attr[:plural] | ||||
| 65c64fed » | vito | 2008-06-09 | 254 | output << "msgstr[0] \"#{OPTIONS[:msgstr]}\"\n" | |
| 255 | output << "msgstr[1] \"#{OPTIONS[:msgstr]}\"\n" | ||||
| 5940b9cd » | vito | 2008-06-08 | 256 | else | |
| 65c64fed » | vito | 2008-06-09 | 257 | output << "msgstr \"#{(attr[:filter]) ? OPTIONS[:msgstr_filter] || OPTIONS[:msgstr] : OPTIONS[:msgstr]}\"\n" | |
| 5940b9cd » | vito | 2008-06-08 | 258 | end | |
| 259 | |||||
| 260 | output << "\n" | ||||
| 261 | end | ||||
| 44d3e953 » | vito | 2008-07-30 | 262 | puts output | |
| 5940b9cd » | vito | 2008-06-08 | 263 | end | |
| b8168e30 » | vito | 2008-03-04 | 264 | end | |
| 5940b9cd » | vito | 2008-06-08 | 265 | ||
| c5ada11b » | vito | 2008-10-11 | 266 | Gettext.new ARGV[0] || "." | |

