1#! /usr/bin/env ruby
2
3# Ruby script to split up translations for mhwaveedit help pages
4# Syntax: ruby splithelp.rb pofile pofile2 ...
5
6require 'pathname'
7
8Encoding.default_external="ASCII-8BIT"
9
10
11# Process a PO file.
12# Yields to block once for each entry in the PO file.
13
14def poproc(fn)
15  p = Pathname.new(fn);
16  pt = p.sub_ext(".tmp");
17  p.rename(pt);
18
19  tc = 0
20  lines = Array.new
21
22  x = p.open("w");
23
24  pt.each_line do |l|
25    if l[/\A\s*\z/] # empty line or whitespace only
26      if lines.length > 0
27        yield(lines,x,tc);
28      	tc = tc+1
29      	lines = Array.new
30      end
31    else
32      lines << l;
33    end
34  end
35  if lines.length > 0
36    yield(lines,x,tc)
37  end
38
39  x.close
40  pt.unlink
41  tc
42end
43
44# Takes an array of lines and returns an array of array of lines
45# Each sub-array contains lines correspoding to one line of translation
46# text (the last one contains a newline character). Empty lines are skipped
47def linegroup(la)
48  r = Array.new
49  g = Array.new
50  la.each do |l|
51    g << l
52    if l.strip.end_with?('\n"')
53      if g.length > 1 or g[0].strip != '"\n"'
54        r << g
55      end
56      g = Array.new
57    end
58  end
59  if g.length > 0
60    r << g
61  end
62  return r
63end
64
65
66ARGV.each do |fn|
67  scount = 0
68  e=poproc(fn) do |l,f,c|
69    hsline = l.grep(/\A\#: src\/help.c:/)
70    idl = l.find_index("msgid \"\"\n")
71    stl = l.find_index("msgstr \"\"\n")
72    # puts "hsline:#{hsline} idl:#{idl} stl:#{stl}"
73
74    if c==0 then
75      # Pass on header unchanged
76      l.each do |x| f.puts x end
77    elsif hsline.length>0 and stl==l.length-1 then
78      # Empty message - skip
79      puts "Skipping untranslated entry #{hsline[0].strip}"
80    elsif hsline.length>0 and idl and stl then
81      # This PO entry should be processed
82
83      # Group lines of translation together
84      idlg = linegroup(l[idl+1...stl])
85      stlg = linegroup(l[stl+1..-1])
86
87      # If there are more lines in translation, include all trailing
88      # lines in the last entry
89      if stlg.length > idlg.length
90        stlg[idlg.length-1] = stlg[(idlg.length-1) .. -1].flatten
91        stlg = stlg[1...idlg.length]
92      end
93      # If there are more lines in original than in translation,
94      # create empty translation.
95      while stlg.length < idlg.length
96        stlg << [ "\" \\n\"\n" ]
97      end
98
99      for i in 0...idlg.length do
100        f.puts ""
101        l[0...idl].each { |x| f.puts(x) }
102        if idlg[i].length > 1
103          f.puts 'msgid ""'
104          idlg[i].each do |x| f.puts x end
105        else
106          f.puts "msgid #{idlg[i][0]}"
107        end
108        if stlg[i].length > 1
109          f.puts 'msgstr ""'
110          stlg[i].each do |x| f.puts x end
111        else
112          f.puts "msgstr #{stlg[i][0]}"
113        end
114      end
115
116      puts "Split entry #{hsline[0].strip} into #{idlg.length} entries"
117      scount = scount+1
118    else
119      # Pass on entry unchanged
120      f.puts ""
121      l.each do |x| f.puts x end
122    end
123  end
124  puts "#{fn}: #{scount} entries were split (#{e} total)"
125end
126