]> git.lyx.org Git - features.git/blob - lib/lyx2lyx/lyx2lyx
add bibtopic support (bug 870).
[features.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           230, 231, 232]
45
46 def usage():
47     print """Usage: lyx2lyx [options] [file]
48 Convert old lyx file <file> to newer format, files can be compressed with gzip.
49 If there no file is specified then the standard input is assumed, in this case
50 gziped files are not handled.
51 Options:
52     -h, --help                  this information
53     -v, --version               output version information and exit
54     -l, --list                  list all available formats
55     -d, --debug level           level=0..2 (O_ no debug information,2_verbose)
56                                 default: level=1
57     -e, --err error_file        name of the error file or else goes to stderr
58     -f, --from version          initial version (optional)
59     -t, --to version            final version (optional)
60     -o, --output name           name of the output file or else goes to stdout
61     -q, --quiet                 same as --debug=0"""
62
63
64 def parse_options(argv):
65     _options =  ["help", "version", "list", "debug=", "err=", "from=", "to=", "output=", "quiet"]
66     try:
67        opts, args = getopt.getopt(argv[1:], "d:e:f:hlo:qt:v", _options)
68     except getopt.error:
69         usage()
70         sys.exit(2)
71
72     for o, a in opts:
73         if o in ("-h", "--help"):
74             usage()
75             sys.exit()
76         if o in ("-v", "--version"):
77             print "lyxconvert, version %s" %(version)
78             print "Copyright (C) 2002-2003 José Matos and Dekel Tsur"
79             sys.exit()
80         if o in ("-d", "--debug"):
81             opt.debug = int(a)
82         if o in ("-q", "--quiet"):
83             opt.debug = 0
84         if o in ("-l", "--list"):
85             print lst_ft
86             sys.exit()
87         if o in ("-o", "--output"):
88             opt.output = open(a, "w")
89         if o in ("-f", "--from"):
90             opt.start = lyxformat(a)
91         if o in ("-t", "--to"):
92             opt.end = lyxformat(a)
93         if o in ("-e","--err"):
94             opt.err = open(a, "w")
95
96     if not opt.end:
97         opt.end = lst_ft[len(lst_ft)-1]
98
99     if args:
100         file = args[0]
101         try:
102             gzip.open(file).readline()
103             opt.output = gzip.GzipFile("","wb",6,opt.output)
104             opt.input = gzip.open(file)
105         except:
106             opt.input = open(file)
107
108 def lyxformat(fmt):
109     result = format.match(fmt)
110     if result:
111         fmt = int(result.group(1) + result.group(2))
112     else:
113         opt.err.write(str(fmt) + ": " + error.invalid_format)
114         sys.exit(2)
115
116     if fmt in lst_ft:
117         return fmt
118
119     opt.err.write(str(fmt) + ": " + error.format_not_supported)
120     sys.exit(1)
121
122 def read_file(file, header, body):
123     """Reads a file into the header and body parts"""
124     fmt = None
125     preamble = 0
126
127     while 1:
128         line = file.readline()
129         if not line:
130             opt.err.write(error.invalid_file)
131             sys.exit(3)
132
133         line = line[:-1]
134         if check_token(line, '\\begin_preamble'):
135             preamble = 1
136         if check_token(line, '\\end_preamble'):
137             preamble = 0
138
139         if not preamble:
140             line = string.strip(line)
141
142         if not line and not preamble:
143             break
144
145         header.append(line)
146         result = fileformat.match(line)
147         if result:
148             fmt = lyxformat(result.group(1))
149
150     while 1:
151         line = file.readline()
152         if not line:
153             break
154         body.append(line[:-1])
155
156     if not fmt:
157         opt.err.write(error.invalid_file)
158         sys.exit(3)
159     return fmt
160
161 def write_file(file, header, body):
162     for line in header:
163         file.write(line+"\n")
164     file.write("\n")
165     for line in body:
166         file.write(line+"\n")
167
168 def main(argv):
169     parse_options(argv)
170
171     header, body = [], []
172     fmt =  read_file(opt.input, header, body)
173
174     if opt.start:
175         if opt.start != fmt:
176             opt.err.write("%s: %s %s\n" % (warning.dont_match, opt.start, fmt))
177     else:
178         opt.start = fmt
179
180     # Convertion chain
181     if opt.start < opt.end:
182         mode = "lyxconvert_"
183     else:
184         lst_ft.reverse()
185         mode = "lyxrevert_"
186
187     start = lst_ft.index(opt.start)
188     end = lst_ft.index(opt.end)
189
190     for fmt in lst_ft[start:end]:
191         __import__(mode + str(fmt)).convert(header,body)
192
193     set_comment(header, version)
194     set_format(header, opt.end)
195     write_file(opt.output, header, body)
196
197 if __name__ == "__main__":
198     main(sys.argv)