]> git.lyx.org Git - lyx.git/blob - lib/lyx2lyx/lyx2lyx
2dc120037f4398ca5c3d4c6fbc11af5fcf95da13
[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
22 version = "0.0.2"
23
24 # Allow the dummy object to be able to carry related data
25 # like a C struct
26 class struct:
27     pass
28
29 # options object, with default values
30 opt = struct()
31
32 opt.output = sys.stdout
33 opt.input = sys.stdin
34 opt.start = None
35 opt.end = None
36 opt.quiet = 0
37
38 format = re.compile(r"(\d)[\.,]?(\d\d)")
39 fileformat = re.compile(r"\\lyxformat\s*(\S*)")
40 lst_ft = ["210", "215", "216", "217", "218", "220", "221", "223"]
41
42 def usage():
43     print """Usage: lyx2lyx [options] file1
44 Convert old lyx file <file1> to newer format.
45 Options:
46     -h, --help                  this information
47     -v, --version               output version information and exit
48     -l, --list                  list all available formats
49     -d, --debug level           level=0..2 (O_ no debug information,2_verbose)
50                                 default: level=1
51     -f, --from version          initial version (optional)
52     -t, --to version            final version (optional)
53     -o, --output name           name of the output file or else goes to stdout
54     -q, --quiet                 same as --debug=0"""
55
56
57 def parse_options(argv):
58     _options =  ["help", "version", "list", "debug=", "from=", "to=", "output=", "quiet"]
59     try:
60        opts, args = getopt.getopt(argv[1:], "d:f:hlo:qt:v", _options)
61     except getopt.error:
62         usage()
63         sys.exit(2)
64
65     for o, a in opts:
66         if o in ("-h", "--help"):
67             usage()
68             sys.exit()
69         if o in ("-v", "--version"):
70             print "lyxconvert, version %s" %(version)
71             print "Copyright (C) 2002 LyX Team"
72             sys.exit()
73         if o in ("-d", "--debug"):
74             opt.debug = int(a)
75         if o in ("-q", "--quiet"):
76             opt.debug = 0
77         if o in ("-l", "--list"):
78             print lst_ft
79             sys.exit()
80         if o in ("-o", "--output"):
81             opt.output = open(a, "w")
82         if o in ("-f", "--from"):
83             opt.start = lyxformat(a)
84         if o in ("-t", "--to"):
85             opt.end = lyxformat(a)
86
87     if not opt.end:
88         opt.end = lst_ft[len(lst_ft)-1]
89
90     if opt.start and opt.start == opt.end:
91         sys.stderr.write(error.same_format)
92         sys.exit()
93
94     if opt.start > opt.end:
95         sys.stderr.write(error.newer_format)
96         sys.exit(1)
97
98     if args:
99         opt.input = open(args[0])
100
101 def lyxformat(fmt):
102     result = format.match(fmt)
103     if result:
104         fmt = result.group(1)+result.group(2)
105     else:
106         sys.stderr.write(fmt + ": " + error.invalid_format)
107         sys.exit(2)
108
109     if fmt in lst_ft:
110         return fmt
111
112     x = int(fmt)
113     if x < int(lst_ft[-1]) and x > int(lst_ft[-2]):
114         sys.stderr.write("lyx2lyx: A development version file.\n")
115         return lst_ft[-2]
116
117     sys.stderr.write(fmt + ": " + error.format_not_supported)
118     sys.exit(1)
119
120 def read_file(file, header, body):
121     """Reads a file into the header and body parts"""
122     fmt = None
123     preamble = 0
124
125     while 1:
126         line = file.readline()
127         if not line:
128             sys.stderr.write(error.invalid_file)
129             sys.exit(3)
130
131         line = line[:-1]
132         if check_token(line, '\\begin_preamble'):
133             preamble = 1
134         if check_token(line, '\\end_preamble'):
135             preamble = 0
136
137         if not preamble:
138             line = string.strip(line)
139
140         if not line and not preamble:
141             break
142
143         header.append(line)
144         result = fileformat.match(line)
145         if result:
146             fmt = lyxformat(result.group(1))
147
148     while 1:
149         line = file.readline()
150         if not line:
151             break
152         body.append(line[:-1])
153
154     if not fmt:
155         sys.stderr.write(error.invalid_file)
156         sys.exit(3)
157     return fmt
158
159 def write_file(file, header, body):
160     for line in header:
161         file.write(line+"\n")
162     file.write("\n")
163     for line in body:
164         file.write(line+"\n")
165
166 def main(argv):
167     parse_options(argv)
168
169     header, body = [], []
170     fmt =  read_file(opt.input, header, body)
171
172     if opt.start:
173         if opt.start != fmt:
174             sys.stderr.write("%s: %s %s\n" % (warning.dont_match, opt.start, fmt))
175     else:
176         opt.start = fmt
177
178     # Convertion chain
179     start = lst_ft.index(opt.start)
180     end = lst_ft.index(opt.end)
181
182     for fmt in lst_ft[start:end]:
183         __import__("lyxconvert_" + fmt).convert(header,body)
184
185     set_comment(header, opt.end)
186     set_format(header, opt.end)
187     write_file(opt.output, header, body)
188     
189 if __name__ == "__main__":
190     main(sys.argv)