]> git.lyx.org Git - lyx.git/blob - lib/lyx2lyx/lyx2lyx
change the file format number to 229 for the sake of a cleaner minipage/box conversion
[lyx.git] / lib / lyx2lyx / lyx2lyx
1 #! /usr/bin/env python
2 # -*- coding: iso-8859-1 -*-
3 # Copyright (C) 2002-2003 José Matos <jamatos@lyx.org>
4 #
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; either version 2
8 # of the License, or (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
19 import getopt, sys, string, re
20 from error import error, warning
21 from parser_tools import set_comment, set_format, check_token
22 import gzip
23
24 version = "1.4.0cvs"
25
26 # Allow the dummy object to be able to carry related data
27 # like a C struct
28 class struct:
29     pass
30
31 # options object, with default values
32 opt = struct()
33
34 opt.output = sys.stdout
35 opt.input = sys.stdin
36 opt.err = sys.stderr
37 opt.start = None
38 opt.end = None
39 opt.quiet = 0
40
41 format = re.compile(r"(\d)[\.,]?(\d\d)")
42 fileformat = re.compile(r"\\lyxformat\s*(\S*)")
43 lst_ft = [210, 215, 216, 217,  218, 220, 221, 223, 224, 225, 226, 227, 228, 229]
44
45 def usage():
46     print """Usage: lyx2lyx [options] [file]
47 Convert old lyx file <file> to newer format, files can be compressed with gzip.
48 If there no file is specified then the standard input is assumed, in this case
49 gziped files are not handled.
50 Options:
51     -h, --help                  this information
52     -v, --version               output version information and exit
53     -l, --list                  list all available formats
54     -d, --debug level           level=0..2 (O_ no debug information,2_verbose)
55                                 default: level=1
56     -e, --err error_file        name of the error file or else goes to stderr
57     -f, --from version          initial version (optional)
58     -t, --to version            final version (optional)
59     -o, --output name           name of the output file or else goes to stdout
60     -q, --quiet                 same as --debug=0"""
61
62
63 def parse_options(argv):
64     _options =  ["help", "version", "list", "debug=", "err=", "from=", "to=", "output=", "quiet"]
65     try:
66        opts, args = getopt.getopt(argv[1:], "d:e:f:hlo:qt:v", _options)
67     except getopt.error:
68         usage()
69         sys.exit(2)
70
71     for o, a in opts:
72         if o in ("-h", "--help"):
73             usage()
74             sys.exit()
75         if o in ("-v", "--version"):
76             print "lyxconvert, version %s" %(version)
77             print "Copyright (C) 2002-2003 José Matos and Dekel Tsur"
78             sys.exit()
79         if o in ("-d", "--debug"):
80             opt.debug = int(a)
81         if o in ("-q", "--quiet"):
82             opt.debug = 0
83         if o in ("-l", "--list"):
84             print lst_ft
85             sys.exit()
86         if o in ("-o", "--output"):
87             opt.output = open(a, "w")
88         if o in ("-f", "--from"):
89             opt.start = lyxformat(a)
90         if o in ("-t", "--to"):
91             opt.end = lyxformat(a)
92         if o in ("-e","--err"):
93             opt.err = open(a, "w")
94
95     if not opt.end:
96         opt.end = lst_ft[len(lst_ft)-1]
97
98     if args:
99         file = args[0]
100         try:
101             gzip.open(file).readline()
102             opt.output = gzip.GzipFile("","wb",6,opt.output)
103             opt.input = gzip.open(file)
104         except:
105             opt.input = open(file)
106
107 def lyxformat(fmt):
108     result = format.match(fmt)
109     if result:
110         fmt = int(result.group(1) + result.group(2))
111     else:
112         opt.err.write(str(fmt) + ": " + error.invalid_format)
113         sys.exit(2)
114
115     if fmt in lst_ft:
116         return fmt
117
118     opt.err.write(str(fmt) + ": " + error.format_not_supported)
119     sys.exit(1)
120
121 def read_file(file, header, body):
122     """Reads a file into the header and body parts"""
123     fmt = None
124     preamble = 0
125
126     while 1:
127         line = file.readline()
128         if not line:
129             opt.err.write(error.invalid_file)
130             sys.exit(3)
131
132         line = line[:-1]
133         if check_token(line, '\\begin_preamble'):
134             preamble = 1
135         if check_token(line, '\\end_preamble'):
136             preamble = 0
137
138         if not preamble:
139             line = string.strip(line)
140
141         if not line and not preamble:
142             break
143
144         header.append(line)
145         result = fileformat.match(line)
146         if result:
147             fmt = lyxformat(result.group(1))
148
149     while 1:
150         line = file.readline()
151         if not line:
152             break
153         body.append(line[:-1])
154
155     if not fmt:
156         opt.err.write(error.invalid_file)
157         sys.exit(3)
158     return fmt
159
160 def write_file(file, header, body):
161     for line in header:
162         file.write(line+"\n")
163     file.write("\n")
164     for line in body:
165         file.write(line+"\n")
166
167 def main(argv):
168     parse_options(argv)
169
170     header, body = [], []
171     fmt =  read_file(opt.input, header, body)
172
173     if opt.start:
174         if opt.start != fmt:
175             opt.err.write("%s: %s %s\n" % (warning.dont_match, opt.start, fmt))
176     else:
177         opt.start = fmt
178
179     # Convertion chain
180     if opt.start < opt.end:
181         mode = "lyxconvert_"
182     else:
183         lst_ft.reverse()
184         mode = "lyxrevert_"
185
186     start = lst_ft.index(opt.start)
187     end = lst_ft.index(opt.end)
188
189     for fmt in lst_ft[start:end]:
190         __import__(mode + str(fmt)).convert(header,body)
191
192     set_comment(header, version)
193     set_format(header, opt.end)
194     write_file(opt.output, header, body)
195
196 if __name__ == "__main__":
197     main(sys.argv)