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