]> git.lyx.org Git - features.git/blob - lib/lyx2lyx/lyx_1_6.py
Stupid mistake.
[features.git] / lib / lyx2lyx / lyx_1_6.py
1 # This file is part of lyx2lyx
2 # -*- coding: utf-8 -*-
3 # Copyright (C) 2007 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 """ Convert files to the file format generated by lyx 1.6"""
20
21 import re
22 import unicodedata
23 import sys, os
24
25 from parser_tools import find_token, find_end_of, find_tokens
26
27 ####################################################################
28 # Private helper functions
29
30 def find_end_of_inset(lines, i):
31     " Find end of inset, where lines[i] is included."
32     return find_end_of(lines, i, "\\begin_inset", "\\end_inset")
33
34
35 ####################################################################
36
37 def fix_wrong_tables(document):
38     i = 0
39     while True:
40         i = find_token(document.body, "\\begin_inset Tabular", i)
41         if i == -1:
42             return
43         j = find_end_of_inset(document.body, i + 1)
44         if j == -1:
45             document.warning("Malformed LyX document: Could not find end of tabular.")
46             continue
47
48         m = i + 1
49         nrows = int(document.body[i+1].split('"')[3])
50         ncols = int(document.body[i+1].split('"')[5])
51
52         for l in range(nrows):
53             prev_multicolumn = 0
54             for k in range(ncols):
55                 m = find_token(document.body, '<cell', m)
56
57                 if document.body[m].find('multicolumn') != -1:
58                     multicol_cont = int(document.body[m].split('"')[1])
59
60                     if multicol_cont == 2 and (k == 0 or prev_multicolumn == 0):
61                         document.body[m] = document.body[m][:5] + document.body[m][21:]
62                         prev_multicolumn = 0
63                     else:
64                         prev_multicolumn = multicol_cont
65                 else:
66                     prev_multicolumn = 0
67
68         i = j + 1
69
70
71 def close_begin_deeper(document):
72     i = 0
73     depth = 0
74     while True:
75         i = find_tokens(document.body, ["\\begin_deeper", "\\end_deeper"], i)
76
77         if i == -1:
78             break
79
80         if document.body[i][:13] == "\\begin_deeper":
81             depth += 1
82         else:
83             depth -= 1
84
85         i += 1
86
87     document.body[-2:-2] = ['\\end_deeper' for i in range(depth)]
88
89
90 def long_charstyle_names(document):
91     i = 0
92     while True:
93         i = find_token(document.body, "\\begin_inset CharStyle", i)
94         if i == -1:
95             return
96         document.body[i] = document.body[i].replace("CharStyle ", "CharStyle CharStyle:")
97         i += 1
98
99 def revert_long_charstyle_names(document):
100     i = 0
101     while True:
102         i = find_token(document.body, "\\begin_inset CharStyle", i)
103         if i == -1:
104             return
105         document.body[i] = document.body[i].replace("CharStyle CharStyle:", "CharStyle")
106         i += 1
107
108
109 def axe_show_label(document):
110     i = 0
111     while True:
112         i = find_token(document.body, "\\begin_inset CharStyle", i)
113         if i == -1:
114             return
115         if document.body[i + 1].find("show_label") != -1:
116             if document.body[i + 1].find("true") != -1:
117                 document.body[i + 1] = "status open"
118                 del document.body[ i + 2]
119             else:
120                 if document.body[i + 1].find("false") != -1:
121                     document.body[i + 1] = "status collapsed"
122                     del document.body[ i + 2]
123                 else:
124                     document.warning("Malformed LyX document: show_label neither false nor true.")
125         else:
126             document.warning("Malformed LyX document: show_label missing in CharStyle.")
127             
128         i += 1
129
130
131 def revert_show_label(document):
132     i = 0
133     while True:
134         i = find_token(document.body, "\\begin_inset CharStyle", i)
135         if i == -1:
136             return
137         if document.body[i + 1].find("status open") != -1:
138             document.body.insert(i + 1, "show_label true")
139         else:
140             if document.body[i + 1].find("status collapsed") != -1:
141                 document.body.insert(i + 1, "show_label false")
142             else:
143                 document.warning("Malformed LyX document: no legal status line in CharStyle.")
144         i += 1
145
146 def revert_begin_modules(document):
147     i = 0
148     while True:
149         i = find_token(document.header, "\\begin_modules", i)
150         if i == -1:
151             return
152         j = find_end_of(document.header, i, "\\begin_modules", "\\end_modules")
153         if j == -1:
154             # this should not happen
155             break
156         document.header[i : j + 1] = []
157
158 def convert_flex(document):
159     "Convert CharStyle to Flex"
160     i = 0
161     while True:
162         i = find_token(document.body, "\\begin_inset CharStyle", i)
163         if i == -1:
164             return
165         document.body[i] = document.body[i].replace('\\begin_inset CharStyle', '\\begin_inset Flex')
166
167 def revert_flex(document):
168     "Convert Flex to CharStyle"
169     i = 0
170     while True:
171         i = find_token(document.body, "\\begin_inset Flex", i)
172         if i == -1:
173             return
174         document.body[i] = document.body[i].replace('\\begin_inset Flex', '\\begin_inset CharStyle')
175
176
177 def remove_manifest(document):
178     "Remove the manifest section"
179     document.manifest = None
180
181
182 #  Discard PDF options for hyperref
183 def revert_pdf_options(document):
184         "Revert PDF options for hyperref."
185         i = 0
186         i = find_token(document.header, "\\use_hyperref", i)
187         if i != -1:
188             del document.header[i]
189         i = find_token(document.header, "\\pdf_store_options", i)
190         if i != -1:
191             del document.header[i]
192         i = find_token(document.header, "\\pdf_title", 0)
193         if i != -1:
194             del document.header[i]
195         i = find_token(document.header, "\\pdf_author", 0)
196         if i != -1:
197             del document.header[i]
198         i = find_token(document.header, "\\pdf_subject", 0)
199         if i != -1:
200             del document.header[i]
201         i = find_token(document.header, "\\pdf_keywords", 0)
202         if i != -1:
203             del document.header[i]
204         i = find_token(document.header, "\\pdf_bookmarks", 0)
205         if i != -1:
206             del document.header[i]
207         i = find_token(document.header, "\\pdf_bookmarksnumbered", i)
208         if i != -1:
209             del document.header[i]
210         i = find_token(document.header, "\\pdf_bookmarksopen", i)
211         if i != -1:
212             del document.header[i]
213         i = find_token(document.header, "\\pdf_bookmarksopenlevel", i)
214         if i != -1:
215             del document.header[i]
216         i = find_token(document.header, "\\pdf_breaklinks", i)
217         if i != -1:
218             del document.header[i]
219         i = find_token(document.header, "\\pdf_pdfborder", i)
220         if i != -1:
221             del document.header[i]
222         i = find_token(document.header, "\\pdf_colorlinks", i)
223         if i != -1:
224             del document.header[i]
225         i = find_token(document.header, "\\pdf_backref", i)
226         if i != -1:
227             del document.header[i]
228         i = find_token(document.header, "\\pdf_pagebackref", i)
229         if i != -1:
230             del document.header[i]
231         i = find_token(document.header, "\\pdf_pagemode", 0)
232         if i != -1:
233             del document.header[i]
234         i = find_token(document.header, "\\pdf_quoted_options", 0)
235         if i != -1:
236             del document.header[i]
237
238
239 def remove_inzip_options(document):
240     "Remove inzipName and embed options from the Graphics inset"
241     i = 0
242     while 1:
243         i = find_token(document.body, "\\begin_inset Graphics", i)
244         if i == -1:
245             return
246         j = find_end_of_inset(document.body, i + 1)
247         if j == -1:
248             # should not happen
249             document.warning("Malformed LyX document: Could not find end of graphics inset.")
250         # If there's a inzip param, just remove that
251         k = find_token(document.body, "\tinzipName", i + 1, j)
252         if k != -1:
253             del document.body[k]
254             # embed option must follow the inzipName option
255             del document.body[k+1]
256         i = i + 1
257
258
259 def convert_inset_command(document):
260   """
261     Convert:
262       \begin_inset LatexCommand cmd 
263     to 
264       \begin_inset CommandInset InsetType
265       LatexCommand cmd
266   """
267   i = 0
268   while 1:
269     i = find_token(document.body, "\\begin_inset LatexCommand", i)
270     if i == -1:
271       return
272     line = document.body[i]
273     r = re.compile(r'\\begin_inset LatexCommand (.*)$')
274     m = r.match(line)
275     cmdName = m.group(1)
276     insetName = ""
277     #this is adapted from factory.cpp
278     if cmdName[0:4].lower() == "cite":
279       insetName = "citation"
280     elif cmdName == "url" or cmdName == "htmlurl":
281       insetName = "url"
282     elif cmdName[-3:] == "ref":
283       insetName = "ref"
284     elif cmdName == "tableofcontents":
285       insetName = "toc"
286     elif cmdName == "printnomenclature":
287       insetName = "nomencl_print"
288     elif cmdName == "printindex":
289       insetName = "index_print"
290     else:
291       insetName = cmdName
292     insertion = ["\\begin_inset CommandInset " + insetName, "LatexCommand " + cmdName]
293     document.body[i : i+1] = insertion
294
295
296 def revert_inset_command(document):
297   """
298     Convert:
299       \begin_inset CommandInset InsetType
300       LatexCommand cmd
301     to 
302       \begin_inset LatexCommand cmd 
303     Some insets may end up being converted to insets earlier versions of LyX
304     will not be able to recognize. Not sure what to do about that.
305   """
306   # FIXME, this routine doesn't work, must be fixed before LyX 1.6.0, see
307   # http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg128426.html
308   i = 0
309   while 1:
310     i = find_token(document.body, "\\begin_inset CommandInset", i)
311     if i == -1:
312       return
313     nextline = document.body[i+1]
314     r = re.compile(r'LatexCommand\s+(.*)$')
315     m = r.match(nextline)
316     if not m:
317       document.warning("Malformed LyX document: Missing LatexCommand in " + document.body[i] + ".")
318       continue
319     cmdName = m.group(1)
320     insertion = ["\\begin_inset LatexCommand " + cmdName]
321     document.body[i : i+2] = insertion
322
323
324 def convert_wrapfig_options(document):
325     "Convert optional options for wrap floats (wrapfig)."
326     # adds the tokens "lines", "placement", and "overhang"
327     i = 0
328     while True:
329         i = find_token(document.body, "\\begin_inset Wrap figure", i)
330         if i == -1:
331             return
332         document.body.insert(i + 1, "lines 0")
333         j = find_token(document.body, "placement", i)
334         # placement can be already set or not; if not, set it
335         if j == i+2:
336             document.body.insert(i + 3, "overhang 0col%")
337         else:
338            document.body.insert(i + 2, "placement o")
339            document.body.insert(i + 3, "overhang 0col%")
340         i = i + 1
341
342
343 def revert_wrapfig_options(document):
344     "Revert optional options for wrap floats (wrapfig)."
345     i = 0
346     while True:
347         i = find_token(document.body, "lines", i)
348         if i == -1:
349             return
350         del document.body[i]
351         j = find_token(document.body, "overhang", i+1)
352         if j != i + 1 and j != -1:
353             document.warning("Malformed LyX document: Couldn't find overhang parameter of wrap float.")
354         if j == -1:
355             return
356         del document.body[j]
357         i = i + 1
358
359
360 ##
361 # Conversion hub
362 #
363
364 supported_versions = ["1.6.0","1.6"]
365 convert = [
366            [277, [fix_wrong_tables]],
367            [278, [close_begin_deeper]],
368            [279, [long_charstyle_names]],
369            [280, [axe_show_label]],
370            [281, []],
371            [282, []],
372            [283, [convert_flex]],
373            [284, []],
374            [285, []], # an empty manifest is automatically added
375            [286, []],
376            [287, [convert_wrapfig_options]],
377            [288, [convert_inset_command]]
378           ]
379
380 revert =  [
381            [287, [revert_inset_command]],
382            [286, [revert_wrapfig_options]],
383            [285, [revert_pdf_options]],
384            [284, [remove_manifest, remove_inzip_options]],
385            [283, []],
386            [282, [revert_flex]],
387            [281, []],
388            [280, [revert_begin_modules]],
389            [279, [revert_show_label]],
390            [278, [revert_long_charstyle_names]],
391            [277, []],
392            [276, []]
393           ]
394
395
396 if __name__ == "__main__":
397     pass