4 # USAGE: update-snippets.py REFERENCE-DIR TARGET-DIR FILES
6 # update ly snippets in TARGET-DIR/FILES with snippets from REFERENCE-DIR/FILES
8 # More precisely, each existing FILE in TARGET-DIR is matched to the FILE in
9 # REFERENCE-DIR (it the latter does not exist, a warning is given).
11 # Shell wildcards expansion is performed on FILES.
12 # This script currently supports Texinfo format.
13 # Ly snippets preceded with a line containing '@c KEEP LY' in TARGET-DIR/FILES
14 # will not be updated.
15 # An error occurs if REFERENCE-DIR/FILE and TARGET-DIR/FILE do not have the
16 # same snippets count.
23 print "update-snippets.py"
25 comment_re = re.compile (r'(?<!@)(@c(?:omment)? .*?\n|^@ignore\n.*?\n@end ignore\n)', re.M | re.S)
26 snippet_re = re.compile (r'^(@lilypond(?:file)?(?:\[.*?\])?\s*\{.+?\}|@lilypond(?:\[.*?\])?(?:.|\n)+?@end lilypond)', re.M)
29 def snippet_split (l):
31 for s in [s for s in l if s]:
32 if s.startswith ('@c ') or s.startswith ('@ignore\n') or s.startswith ('@comment '):
35 r += [t for t in snippet_re.split (s) if t]
38 def count_snippet (l):
41 if s.startswith ('@lilypond'):
45 def find_next_snippet (l, k):
46 while not l[k].startswith ('@lilypond'):
52 def update_exit_code (code):
54 exit_code = max (code, exit_code)
56 ref_dir, target_dir = sys.argv [1:3]
57 file_patterns = sys.argv[3:]
59 total_snippet_count = 0
60 changed_snippets_count = 0
62 for pattern in file_patterns:
63 files = glob.glob (os.path.join (target_dir, pattern))
65 ref_file = os.path.join (ref_dir, os.path.basename (file))
66 if not os.path.isfile (ref_file):
67 sys.stderr.write ("Warning: %s: no such file.\nReference file for %s not found.\n" % (ref_file, file))
70 target_source = comment_re.split (f.read ())
72 if reduce (lambda x, y: x or y, ['-- SKELETON FILE --' in s for s in target_source]):
73 sys.stderr.write ("Skipping skeleton file %s\n" % file)
75 g = open (ref_file, 'r')
76 ref_source = comment_re.split (g.read ())
77 target_source = snippet_split (target_source)
78 ref_source = snippet_split (ref_source)
79 if '' in target_source or '' in ref_source:
80 raise "AAAAARGH: unuseful empty string"
81 snippet_count = count_snippet (target_source)
82 if not snippet_count == count_snippet (ref_source):
84 sys.stderr.write ("Error: %s and %s have different snippet counts.\n\
85 Update translation by at least adding a @lilypond block where necessary, then rerun this script.\n" % (ref_file, file))
87 total_snippet_count += snippet_count
90 for j in range (len (target_source)):
91 if target_source[j].startswith ('@lilypond'):
92 k = find_next_snippet (ref_source, k+1)
93 if j > 0 and (not target_source[j-1].startswith ('@c KEEP LY')) and target_source[j] != ref_source[k]:
94 target_source[j] = ref_source[k]
96 changed_snippets_count += 1
98 f.write (''.join (target_source))
99 sys.stderr.write ('%s: %d/%d snippets updated\n' % (file, c, snippet_count))
101 sys.stderr.write ('\nTotal: %d snippets, %d updated snippets.\n' % (total_snippet_count, changed_snippets_count))