1 # This file is part of lyx2lyx
2 # Copyright (C) 2003 José Matos <jamatos@fep.up.pt>
3 # Copyright (C) 2003 Georg Baum <Georg.Baum@post.rwth-aachen.de>
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.
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.
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.
20 from parser_tools import find_token, find_end_of_inset, get_next_paragraph, \
21 get_paragraph, get_value, del_token, is_nonempty_line
22 from string import find, replace, split
25 def rm_end_layout(lines):
28 i = find_token(lines, '\\end_layout', i)
35 def begin_layout2layout(lines):
38 i = find_token(lines, '\\begin_layout', i)
42 lines[i] = replace(lines[i], '\\begin_layout', '\\layout')
45 def table_valignment_middle(lines, start, end):
46 for i in range(start, end):
47 if re.search('^<(column|cell) .*valignment="middle".*>$', lines[i]):
48 lines[i] = replace(lines[i], 'valignment="middle"', 'valignment="center"')
50 def valignment_middle(lines):
53 i = find_token(lines, '\\begin_inset Tabular', i)
56 j = find_end_of_inset(lines, i + 1)
58 #this should not happen
59 valignment_middle(lines, i + 1, len(lines))
61 valignment_middle(lines, i + 1, j)
64 def end_document(lines):
65 i = find_token(lines, "\\end_document", 0)
67 lines.append("\\the_end")
69 lines[i] = "\\the_end"
71 # Convert backslashes into valid ERT code, append the converted text to
72 # lines[i] and return the (maybe incremented) line index i
73 def convert_ertbackslash(lines, i, ert):
76 lines[i] = lines[i] + '\\backslash '
80 lines[i] = lines[i] + c
83 def convert_vspace(header, lines):
85 # Get default spaceamount
86 i = find_token(header, '\\defskip', 0)
88 defskipamount = 'medskip'
90 defskipamount = split(header[i])[1]
95 i = find_token(lines, '\\begin_inset VSpace', i)
98 spaceamount = split(lines[i])[2]
100 # Are we at the beginning or end of a paragraph?
102 start = get_paragraph(lines, i) + 1
103 for k in range(start, i):
104 if is_nonempty_line(lines[k]):
108 j = find_end_of_inset(lines, i)
110 sys.stderr.write("Malformed lyx file: Missing '\\end_inset'\n")
113 end = get_next_paragraph(lines, i)
114 for k in range(j + 1, end):
115 if is_nonempty_line(lines[k]):
119 # Convert to paragraph formatting if we are at the beginning or end
120 # of a paragraph and the resulting paragraph would not be empty
121 if ((paragraph_start and not paragraph_end) or
122 (paragraph_end and not paragraph_start)):
123 # The order is important: del and insert invalidate some indices
127 lines.insert(start, '\\added_space_top ' + spaceamount + ' ')
129 lines.insert(start, '\\added_space_bottom ' + spaceamount + ' ')
133 lines[i:i+1] = ['\\begin_inset ERT', 'status Collapsed', '',
134 '\\layout Standard', '', '\\backslash ']
136 if spaceamount[-1] == '*':
137 spaceamount = spaceamount[:-1]
142 # Replace defskip by the actual value
143 if spaceamount == 'defskip':
144 spaceamount = defskipamount
146 # LaTeX does not know \\smallskip* etc
148 if spaceamount == 'smallskip':
149 spaceamount = '\\smallskipamount'
150 elif spaceamount == 'medskip':
151 spaceamount = '\\medskipamount'
152 elif spaceamount == 'bigskip':
153 spaceamount = '\\bigskipamount'
154 elif spaceamount == 'vfill':
155 spaceamount = '\\fill'
157 # Finally output the LaTeX code
158 if (spaceamount == 'smallskip' or spaceamount == 'medskip' or
159 spaceamount == 'bigskip' or spaceamount == 'vfill'):
160 lines.insert(i, spaceamount)
163 lines.insert(i, 'vspace*{')
165 lines.insert(i, 'vspace{')
166 i = convert_ertbackslash(lines, i, spaceamount)
167 lines[i] = lines[i] + '}'
170 # Convert a LyX length into valid ERT code and append it to lines[i]
171 # Return the (maybe incremented) line index i
172 def convert_ertlen(lines, i, len, special):
173 units = {"text%":"\\textwidth", "col%":"\\columnwidth",
174 "page%":"\\pagewidth", "line%":"\\linewidth",
175 "theight%":"\\textheight", "pheight%":"\\pageheight"}
177 # Convert special lengths
178 if special != 'none':
179 len = '%f\\' % len2value(len) + special
181 # Convert LyX units to LaTeX units
182 for unit in units.keys():
183 if find(len, unit) != -1:
184 len = '%f' % (len2value(len) / 100) + units[unit]
187 # Convert backslashes and insert the converted length into lines
188 return convert_ertbackslash(lines, i, len)
190 # Return the value of len without the unit in numerical form
192 result = re.search('([+-]?[0-9.]+)', len)
194 return float(result.group(1))
195 # No number means 1.0
198 def convert_frameless_box(lines):
199 pos = ['t', 'c', 'b']
200 inner_pos = ['c', 't', 'b', 's']
203 i = find_token(lines, '\\begin_inset Frameless', i)
206 j = find_end_of_inset(lines, i)
208 sys.stderr.write("Malformed lyx file: Missing '\\end_inset'\n")
214 params = {'position':'0', 'hor_pos':'c', 'has_inner_box':'1',
215 'inner_pos':'1', 'use_parbox':'0', 'width':'100col%',
216 'special':'none', 'height':'1in',
217 'height_special':'totalheight', 'collapsed':'false'}
218 for key in params.keys():
219 value = replace(get_value(lines, key, i, j), '"', '')
221 if key == 'position':
222 # convert new to old position: 'position "t"' -> 0
223 value = find_token(pos, value, 0)
226 elif key == 'inner_pos':
227 # convert inner position
228 value = find_token(inner_pos, value, 0)
233 j = del_token(lines, key, i, j)
236 # Convert to minipage or ERT?
237 # Note that the inner_position and height parameters of a minipage
238 # inset are ignored and not accessible for the user, although they
239 # are present in the file format and correctly read in and written.
240 # Therefore we convert to ERT if they do not have their LaTeX
241 # defaults. These are:
242 # - the value of "position" for "inner_pos"
243 # - "\totalheight" for "height"
244 if (params['use_parbox'] != '0' or
245 params['has_inner_box'] != '1' or
246 params['special'] != 'none' or
247 inner_pos[params['inner_pos']] != pos[params['position']] or
248 params['height_special'] != 'totalheight' or
249 len2value(params['height']) != 1.0):
252 if params['collapsed'] == 'true':
253 params['collapsed'] = 'Collapsed'
255 params['collapsed'] = 'Open'
256 lines[i : i] = ['\\begin_inset ERT', 'status ' + params['collapsed'],
257 '', '\\layout Standard', '', '\\backslash ']
259 if params['use_parbox'] == '1':
260 lines.insert(i, 'parbox')
262 lines.insert(i, 'begin{minipage}')
263 lines[i] = lines[i] + '[' + pos[params['position']] + ']['
264 i = convert_ertlen(lines, i, params['height'], params['height_special'])
265 lines[i] = lines[i] + '][' + inner_pos[params['inner_pos']] + ']{'
266 i = convert_ertlen(lines, i, params['width'], params['special'])
267 lines[i] = lines[i] + '}{'
269 lines[i:i] = ['', '\\end_inset ']
271 j = find_end_of_inset(lines, i)
273 sys.stderr.write("Malformed lyx file: Missing '\\end_inset'\n")
275 lines[j-1:j-1] += ['\\begin_inset ERT', 'status ' + params['collapsed'],
276 '', '\\layout Standard', '']
278 if params['use_parbox'] == '1':
281 lines[j:j] = ['\\backslash ', 'end{minipage}']
284 # Convert to minipage
285 lines[i:i] = ['\\begin_inset Minipage',
286 'position %d' % params['position'],
287 'inner_position %d' % params['inner_pos'],
288 'height "' + params['height'] + '"',
289 'width "' + params['width'] + '"',
290 'collapsed ' + params['collapsed']]
293 def convert(header, body):
295 begin_layout2layout(body)
297 valignment_middle(body)
298 convert_vspace(header, body)
299 convert_frameless_box(body)
301 if __name__ == "__main__":