]> git.lyx.org Git - lyx.git/blob - lib/scripts/prefs2prefs.py
Remove profiling.py
[lyx.git] / lib / scripts / prefs2prefs.py
1 # file prefs2prefs.py
2 # This file is part of LyX, the document processor.
3 # Licence details can be found in the file COPYING.
4
5 # author Richard Kimberly Heck
6
7 # Full author contact details are available in file CREDITS
8
9 # This is the main file for the user preferences conversion system.
10 # There are two subsidiary files:
11 #    prefs2prefs_lfuns.py
12 #    prefs2prefs_prefs.py
13 # The former is used to convert bind and ui files; the latter, to convert
14 # the preferences file. The converter functions are all in the subsidiary 
15 # files. 
16
17 # The format of the existing files was format 0, as of 2.0.alpha6.
18
19 import os, re, string, sys
20 from getopt import getopt
21 import io
22
23 ###########################################################
24 # Utility functions, borrowed from layout2layout.py
25
26 def trim_bom(line):
27         " Remove byte order mark."
28         if line[0:3] == "\357\273\277":
29                 return line[3:]
30         else:
31                 return line
32
33
34 def read(source):
35         " Read input file and strip lineendings."
36         lines = source.read().splitlines() or ['']
37         lines[0] = trim_bom(lines[0])
38         return lines
39
40
41 def write(output, lines):
42         " Write output file with native lineendings."
43         output.write(os.linesep.join(lines) + os.linesep)
44
45
46 # for use by find_format_lines
47 re_comment = re.compile(r'^#')
48 re_empty   = re.compile(r'^\s*$')
49
50 def find_format_line(lines):
51         '''
52         Returns (bool, int), where int is number of the line the `Format'
53         specification is on, or else the number of the first non-blank,
54         non-comment line. The bool tells whether we found a format line.
55         '''
56         for i in range(len(lines)):
57                 l = lines[i]
58                 if re_comment.search(l) or re_empty.search(l):
59                         continue
60                 m = re_format.search(l)
61                 if m:
62                         return (True, i)
63                 # we're done when we have hit a non-comment, non-empty line
64                 break
65         return (False, i)
66
67
68 # for use by get_format
69 re_format  = re.compile(r'^Format\s+(\d+)\s*$')
70
71 def get_format(lines):
72         " Gets format of current file and replaces the format line with a new one "
73         (found, format_line) = find_format_line(lines)
74         if not found:
75                 return 0
76         line = lines[format_line]
77         m = re_format.search(line)
78         if not m:
79                 sys.stderr.write("Couldn't match format line!\n" + line + "\n")
80                 sys.exit(1)
81         return int(m.group(1))
82
83
84 def update_format(lines):
85         " Writes new format line "
86         (found, format_line) = find_format_line(lines)
87         if not found:
88                 lines[format_line:format_line] = ("Format 1", "")
89                 return
90
91         line = lines[format_line]
92         m = re_format.search(line)
93         if not m:
94                 sys.stderr.write("Couldn't match format line!\n" + line + "\n")
95                 sys.exit(1)
96         format = int(m.group(1))
97         lines[format_line] = "Format " + str(format + 1)
98
99
100 def abort(msg):
101         sys.stderr.write("\n%s\n" % (msg))
102         sys.exit(10)
103
104 #
105 ###########################################################
106
107 def usage():
108         print ("%s [-l] [-p] infile outfile" % sys.argv[0])
109         print ("or: %s [-l] [-p] <infile >outfile" % sys.argv[0])
110         print ("  -l: convert LFUNs (bind and ui files)")
111         print ("  -p: convert preferences")
112         print ("Note that exactly one of -l and -p is required.")
113
114
115 def main(argv):
116         try:
117                 (options, args) = getopt(sys.argv[1:], "lp")
118         except:
119                 usage()
120                 abort("Unrecognized option")
121
122         opened_files = False
123         # Open files
124         if len(args) == 0:
125                 source = sys.stdin
126                 output = sys.stdout
127         elif len(args) == 2:
128                 source = open(args[0], encoding='utf_8', errors='surrogateescape')
129                 output = open(args[1], 'w', encoding='utf_8', newline='\n')
130                 opened_files = True
131         else:
132                 usage()
133                 abort("Either zero or two arguments must be given.")
134
135         conversions = False
136
137         for (opt, param) in options:
138                 if opt == "-l":
139                         from prefs2prefs_lfuns import conversions
140                 elif opt == "-p":
141                         from prefs2prefs_prefs import conversions
142
143         if not conversions:
144                 usage()
145                 abort("Neither -l nor -p given.")
146         elif len(options) > 1:
147                 usage()
148                 abort("Only one of -l or -p should be given.")
149
150         current_format = len(conversions)
151         lines = read(source)
152         format = get_format(lines)
153
154         while format < current_format:
155                 target_format, convert = conversions[format]
156                 old_format = format
157
158                 # make sure the conversion list is sequential
159                 if int(old_format) + 1 != target_format:
160                         abort("Something is wrong with the conversion chain.")
161
162                 for c in convert:
163                         try:
164                                 # first see if the routine will accept a list of lines
165                                 c(lines)
166                         except:
167                                 # if not, it wants individual lines
168                                 for i in range(len(lines)):
169                                         (update, newline) = c(lines[i])
170                                         if update:
171                                                 lines[i] = newline
172
173                 update_format(lines)
174                 format = get_format(lines)
175
176                 # sanity check
177                 if int(old_format) + 1 != int(format):
178                         abort("Failed to convert to new format!")
179
180         write(output, lines)
181
182         # Close files
183         if opened_files:
184                 source.close()
185                 output.close()
186
187         return 0
188
189
190 if __name__ == "__main__":
191         main(sys.argv)