1 # This file is part of lyx2lyx
2 # -*- coding: iso-8859-1 -*-
3 # Copyright (C) 2003 José Matos <jamatos@fep.up.pt>
4 # Copyright (C) 2003 Georg Baum <Georg.Baum@post.rwth-aachen.de>
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; either version 2
9 # of the License, or (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 from parser_tools import find_token, find_end_of_inset, get_next_paragraph, \
22 get_paragraph, get_value, del_token, is_nonempty_line
23 from string import find, replace, split
26 def rm_end_layout(lines):
29 i = find_token(lines, '\\end_layout', i)
36 def begin_layout2layout(lines):
39 i = find_token(lines, '\\begin_layout', i)
43 lines[i] = replace(lines[i], '\\begin_layout', '\\layout')
46 def table_valignment_middle(lines, start, end):
47 for i in range(start, end):
48 if re.search('^<(column|cell) .*valignment="middle".*>$', lines[i]):
49 lines[i] = replace(lines[i], 'valignment="middle"', 'valignment="center"')
51 def valignment_middle(lines):
54 i = find_token(lines, '\\begin_inset Tabular', i)
57 j = find_end_of_inset(lines, i + 1)
59 #this should not happen
60 valignment_middle(lines, i + 1, len(lines))
62 valignment_middle(lines, i + 1, j)
65 def end_document(lines):
66 i = find_token(lines, "\\end_document", 0)
68 lines.append("\\the_end")
70 lines[i] = "\\the_end"
72 # Convert backslashes into valid ERT code, append the converted text to
73 # lines[i] and return the (maybe incremented) line index i
74 def convert_ertbackslash(lines, i, ert):
77 lines[i] = lines[i] + '\\backslash '
81 lines[i] = lines[i] + c
84 def convert_vspace(header, lines):
86 # Get default spaceamount
87 i = find_token(header, '\\defskip', 0)
89 defskipamount = 'medskip'
91 defskipamount = split(header[i])[1]
96 i = find_token(lines, '\\begin_inset VSpace', i)
99 spaceamount = split(lines[i])[2]
101 # Are we at the beginning or end of a paragraph?
103 start = get_paragraph(lines, i) + 1
104 for k in range(start, i):
105 if is_nonempty_line(lines[k]):
109 j = find_end_of_inset(lines, i)
111 sys.stderr.write("Malformed lyx file: Missing '\\end_inset'\n")
114 end = get_next_paragraph(lines, i)
115 for k in range(j + 1, end):
116 if is_nonempty_line(lines[k]):
120 # Convert to paragraph formatting if we are at the beginning or end
121 # of a paragraph and the resulting paragraph would not be empty
122 if ((paragraph_start and not paragraph_end) or
123 (paragraph_end and not paragraph_start)):
124 # The order is important: del and insert invalidate some indices
128 lines.insert(start, '\\added_space_top ' + spaceamount + ' ')
130 lines.insert(start, '\\added_space_bottom ' + spaceamount + ' ')
134 lines[i:i+1] = ['\\begin_inset ERT', 'status Collapsed', '',
135 '\\layout Standard', '', '\\backslash ']
137 if spaceamount[-1] == '*':
138 spaceamount = spaceamount[:-1]
143 # Replace defskip by the actual value
144 if spaceamount == 'defskip':
145 spaceamount = defskipamount
147 # LaTeX does not know \\smallskip* etc
149 if spaceamount == 'smallskip':
150 spaceamount = '\\smallskipamount'
151 elif spaceamount == 'medskip':
152 spaceamount = '\\medskipamount'
153 elif spaceamount == 'bigskip':
154 spaceamount = '\\bigskipamount'
155 elif spaceamount == 'vfill':
156 spaceamount = '\\fill'
158 # Finally output the LaTeX code
159 if (spaceamount == 'smallskip' or spaceamount == 'medskip' or
160 spaceamount == 'bigskip' or spaceamount == 'vfill'):
161 lines.insert(i, spaceamount)
164 lines.insert(i, 'vspace*{')
166 lines.insert(i, 'vspace{')
167 i = convert_ertbackslash(lines, i, spaceamount)
168 lines[i] = lines[i] + '}'
171 # Convert a LyX length into valid ERT code and append it to lines[i]
172 # Return the (maybe incremented) line index i
173 def convert_ertlen(lines, i, len, special):
174 units = {"text%":"\\textwidth", "col%":"\\columnwidth",
175 "page%":"\\pagewidth", "line%":"\\linewidth",
176 "theight%":"\\textheight", "pheight%":"\\pageheight"}
178 # Convert special lengths
179 if special != 'none':
180 len = '%f\\' % len2value(len) + special
182 # Convert LyX units to LaTeX units
183 for unit in units.keys():
184 if find(len, unit) != -1:
185 len = '%f' % (len2value(len) / 100) + units[unit]
188 # Convert backslashes and insert the converted length into lines
189 return convert_ertbackslash(lines, i, len)
191 # Return the value of len without the unit in numerical form
193 result = re.search('([+-]?[0-9.]+)', len)
195 return float(result.group(1))
196 # No number means 1.0
199 def convert_frameless_box(lines):
200 pos = ['t', 'c', 'b']
201 inner_pos = ['c', 't', 'b', 's']
204 i = find_token(lines, '\\begin_inset Frameless', i)
207 j = find_end_of_inset(lines, i)
209 sys.stderr.write("Malformed lyx file: Missing '\\end_inset'\n")
215 params = {'position':'0', 'hor_pos':'c', 'has_inner_box':'1',
216 'inner_pos':'1', 'use_parbox':'0', 'width':'100col%',
217 'special':'none', 'height':'1in',
218 'height_special':'totalheight', 'collapsed':'false'}
219 for key in params.keys():
220 value = replace(get_value(lines, key, i, j), '"', '')
222 if key == 'position':
223 # convert new to old position: 'position "t"' -> 0
224 value = find_token(pos, value, 0)
227 elif key == 'inner_pos':
228 # convert inner position
229 value = find_token(inner_pos, value, 0)
234 j = del_token(lines, key, i, j)
237 # Convert to minipage or ERT?
238 # Note that the inner_position and height parameters of a minipage
239 # inset are ignored and not accessible for the user, although they
240 # are present in the file format and correctly read in and written.
241 # Therefore we convert to ERT if they do not have their LaTeX
242 # defaults. These are:
243 # - the value of "position" for "inner_pos"
244 # - "\totalheight" for "height"
245 if (params['use_parbox'] != '0' or
246 params['has_inner_box'] != '1' or
247 params['special'] != 'none' or
248 inner_pos[params['inner_pos']] != pos[params['position']] or
249 params['height_special'] != 'totalheight' or
250 len2value(params['height']) != 1.0):
253 if params['collapsed'] == 'true':
254 params['collapsed'] = 'Collapsed'
256 params['collapsed'] = 'Open'
257 lines[i : i] = ['\\begin_inset ERT', 'status ' + params['collapsed'],
258 '', '\\layout Standard', '', '\\backslash ']
260 if params['use_parbox'] == '1':
261 lines.insert(i, 'parbox')
263 lines.insert(i, 'begin{minipage}')
264 lines[i] = lines[i] + '[' + pos[params['position']] + ']['
265 i = convert_ertlen(lines, i, params['height'], params['height_special'])
266 lines[i] = lines[i] + '][' + inner_pos[params['inner_pos']] + ']{'
267 i = convert_ertlen(lines, i, params['width'], params['special'])
268 if params['use_parbox'] == '1':
269 lines[i] = lines[i] + '}{'
271 lines[i] = lines[i] + '}'
273 lines[i:i] = ['', '\\end_inset ']
275 j = find_end_of_inset(lines, i)
277 sys.stderr.write("Malformed lyx file: Missing '\\end_inset'\n")
279 lines[j-1:j-1] += ['\\begin_inset ERT', 'status ' + params['collapsed'],
280 '', '\\layout Standard', '']
282 if params['use_parbox'] == '1':
285 lines[j:j] = ['\\backslash ', 'end{minipage}']
288 # Convert to minipage
289 lines[i:i] = ['\\begin_inset Minipage',
290 'position %d' % params['position'],
291 'inner_position %d' % params['inner_pos'],
292 'height "' + params['height'] + '"',
293 'width "' + params['width'] + '"',
294 'collapsed ' + params['collapsed']]
297 def convert(header, body):
299 begin_layout2layout(body)
301 valignment_middle(body)
302 convert_vspace(header, body)
303 convert_frameless_box(body)
305 if __name__ == "__main__":