backport 1.4 lyx2lyx to 1.3.6

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/branches/BRANCH_1_3_X@10154 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Georg Baum 2005-07-08 12:21:24 +00:00
parent df8d04a794
commit 060fcf53a4
11 changed files with 59 additions and 1584 deletions

View File

@ -1,3 +1,8 @@
2005-07-08 Georg Baum <Georg.Baum@post.rwth-aachen.de>
* lyx2lyx: replace with backported 1.4 lyx2lyx. The only difference
to 1.4 is the default fomat of 221 and version_lyx2lyx.
2005-07-06 Michael Schmitt <michael.schmitt@teststep.org>
* layouts/*.layout: fix left margins in various text classes

View File

@ -25,7 +25,7 @@ import re
import string
import time
version_lyx2lyx = "1.4.0cvs"
version_lyx2lyx = "1.3.6"
default_debug_level = 2
# Regular expressions used

View File

@ -1,30 +0,0 @@
# This file is part of lyx2lyx
# -*- coding: iso-8859-1 -*-
# Copyright (C) 2002-2004 José Matos <jamatos@lyx.org>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
class Error:
invalid_file = "Invalid LyX file\n"
invalid_format = "Invalid LyX format\n"
format_not_supported = "Format not supported\n"
same_format = "No convertion because start and ending formats are the same\n"
newer_format = "Starting format is newer than end format\n"
class Warning:
dont_match = "Proposed and input file formats do not match"
error = Error()
warning = Warning()

View File

@ -16,165 +16,77 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
import getopt, sys, string, re
from error import error, warning
from parser_tools import set_comment, set_format, check_token
version = "1.3.4"
# Allow the dummy object to be able to carry related data
# like a C struct
class struct:
pass
# options object, with default values
opt = struct()
opt.output = sys.stdout
opt.input = sys.stdin
opt.start = None
opt.end = None
opt.quiet = 0
format = re.compile(r"(\d)[\.,]?(\d\d)")
fileformat = re.compile(r"\\lyxformat\s*(\S*)")
lst_ft = ["210", "215", "216", "217", "218", "220", "221"]
import getopt
import sys
import LyX
def usage():
print """Usage: lyx2lyx [options] file1
Convert old lyx file <file1> to newer format.
print """Usage: lyx2lyx [options] [file]
Convert old lyx file <file> to newer format, files can be compressed with gzip.
If there no file is specified then the standard input is assumed, in this case
gziped files are not handled.
Options:
-h, --help this information
-v, --version output version information and exit
-l, --list list all available formats
-d, --debug level level=0..2 (O_ no debug information,2_verbose)
-d, --debug level level=0..2 (O_ no debug information, 2_verbose)
default: level=1
-e, --err error_file name of the error file or else goes to stderr
-f, --from version initial version (optional)
-t, --to version final version (optional)
-o, --output name name of the output file or else goes to stdout
-n, --try-hard try hard (ignore any convertion errors)
-q, --quiet same as --debug=0"""
def parse_options(argv):
_options = ["help", "version", "list", "debug=", "from=", "to=", "output=", "quiet"]
_options = ["help", "version", "list", "debug=", "err=", "from=", "to=", "output=", "try-hard", "quiet"]
try:
opts, args = getopt.getopt(argv[1:], "d:f:hlo:qt:v", _options)
opts, args = getopt.getopt(argv[1:], "d:e:f:hlno:qt:v", _options)
except getopt.error:
usage()
sys.exit(2)
end_format, input, output, error, debug, try_hard = 0, "", "", "", LyX.default_debug_level, 0
end_format = '221'
for o, a in opts:
if o in ("-h", "--help"):
usage()
sys.exit()
if o in ("-v", "--version"):
print "lyxconvert, version %s" %(version)
print "lyx2lyx, version %s" %(LyX.version_lyx2lyx)
print "Copyright (C) 2002-2004 José Matos and Dekel Tsur"
sys.exit()
if o in ("-d", "--debug"):
opt.debug = int(a)
debug = int(a)
if o in ("-q", "--quiet"):
opt.debug = 0
debug = 0
if o in ("-l", "--list"):
print lst_ft
print LyX.formats_list()
sys.exit()
if o in ("-o", "--output"):
opt.output = open(a, "w")
if o in ("-f", "--from"):
opt.start = lyxformat(a)
output = a
if o in ("-t", "--to"):
opt.end = lyxformat(a)
if not opt.end:
opt.end = lst_ft[len(lst_ft)-1]
if opt.start > opt.end:
sys.stderr.write(error.newer_format)
sys.exit(1)
end_format = a
if o in ("-e","--err"):
error = a
if o in ("-n", "--try-hard"):
try_hard = 1
if args:
opt.input = open(args[0])
input = args[0]
def lyxformat(fmt):
result = format.match(fmt)
if result:
fmt = result.group(1)+result.group(2)
else:
sys.stderr.write(fmt + ": " + error.invalid_format)
sys.exit(2)
if fmt not in lst_ft:
sys.stderr.write(fmt + ": " + error.format_not_supported)
sys.exit(1)
return fmt
return end_format, input, output, error, debug, try_hard
def read_file(file, header, body):
"""Reads a file into the header and body parts"""
fmt = None
preamble = 0
while 1:
line = file.readline()
if not line:
sys.stderr.write(error.invalid_file)
sys.exit(3)
line = line[:-1]
if check_token(line, '\\begin_preamble'):
preamble = 1
if check_token(line, '\\end_preamble'):
preamble = 0
if not preamble:
line = string.strip(line)
if not line and not preamble:
break
header.append(line)
result = fileformat.match(line)
if result:
fmt = lyxformat(result.group(1))
while 1:
line = file.readline()
if not line:
break
body.append(line[:-1])
if not fmt:
sys.stderr.write(error.invalid_file)
sys.exit(3)
return fmt
def write_file(file, header, body):
for line in header:
file.write(line+"\n")
file.write("\n")
for line in body:
file.write(line+"\n")
def main(argv):
parse_options(argv)
end_format, input, output, error, debug, try_hard = parse_options(argv)
file = LyX.File(end_format, input, output, error, debug, try_hard)
header, body = [], []
fmt = read_file(opt.input, header, body)
file.convert()
file.write()
if opt.start:
if opt.start != fmt:
sys.stderr.write("%s: %s %s\n" % (warning.dont_match, opt.start, fmt))
else:
opt.start = fmt
return file.status
# Convertion chain
start = lst_ft.index(opt.start)
end = lst_ft.index(opt.end)
for fmt in lst_ft[start:end]:
__import__("lyxconvert_" + fmt).convert(header,body)
set_comment(header, version)
set_format(header, opt.end)
write_file(opt.output, header, body)
if __name__ == "__main__":
main(sys.argv)
sys.exit(main(sys.argv))

View File

@ -1,241 +0,0 @@
# This file is part of lyx2lyx
# -*- coding: iso-8859-1 -*-
# Copyright (C) 2003 José Matos <jamatos@lyx.org>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
import re
import string
from parser_tools import *
def space_before_layout(lines):
i = 2 # skip first layout
while 1:
i = find_token(lines, '\\layout', i)
if i == -1:
break
if lines[i - 1] == '' and string.find(lines[i-2],'\\protected_separator') == -1:
del lines[i-1]
i = i + 1
def formula_inset_space_eat(lines):
i=0
while 1:
i = find_token(lines, "\\begin_inset Formula", i)
if i == -1: break
if len(lines[i]) > 22 and lines[i][21] == ' ':
lines[i] = lines[i][:20] + lines[i][21:]
i = i + 1
# Update from tabular format 2 to 4
def update_tabular(lines):
lyxtable_re = re.compile(r".*\\LyXTable$")
i=0
while 1:
i = find_re(lines, lyxtable_re, i)
if i == -1:
break
i = i + 1
format = lines[i][8]
lines[i]='multicol4'
i = i + 1
rows = int(string.split(lines[i])[0])
columns = int(string.split(lines[i])[1])
lines[i] = lines[i] + ' 0 0 -1 -1 -1 -1'
i = i + 1
for j in range(rows):
lines[i] = lines[i] + ' 0 0'
i = i + 1
for j in range(columns):
lines[i] = lines[i] + ' '
i = i + 1
while lines[i]:
lines[i] = lines[i] + ' 0 0 0'
i = i + 1
def final_dot(lines):
i = 0
while i < len(lines):
if lines[i][-1:] == '.' and lines[i+1][:1] != '\\' and lines[i+1][:1] != ' ' and len(lines[i]) + len(lines[i+1])<= 72 and lines[i+1] != '':
lines[i] = lines[i] + lines[i+1]
del lines[i+1]
else:
i = i + 1
def update_inset_label(lines):
i = 0
while 1:
i = find_token(lines, '\\begin_inset Label', i)
if i == -1:
return
lines[i] = '\\begin_inset LatexCommand \label{' + lines[i][19:] + '}'
i = i + 1
def update_latexdel(lines):
i = 0
while 1:
i = find_token(lines, '\\begin_inset LatexDel', i)
if i == -1:
return
lines[i] = string.replace(lines[i],'\\begin_inset LatexDel', '\\begin_inset LatexCommand')
i = i + 1
def update_vfill(lines):
for i in range(len(lines)):
lines[i] = string.replace(lines[i],'\\fill_top','\\added_space_top vfill')
lines[i] = string.replace(lines[i],'\\fill_bottom','\\added_space_bottom vfill')
def update_space_units(lines):
added_space_bottom = re.compile(r'\\added_space_bottom ([^ ]*)')
added_space_top = re.compile(r'\\added_space_top ([^ ]*)')
for i in range(len(lines)):
result = added_space_bottom.search(lines[i])
if result:
old = '\\added_space_bottom ' + result.group(1)
new = '\\added_space_bottom ' + str(float(result.group(1))) + 'cm'
lines[i] = string.replace(lines[i], old, new)
result = added_space_top.search(lines[i])
if result:
old = '\\added_space_top ' + result.group(1)
new = '\\added_space_top ' + str(float(result.group(1))) + 'cm'
lines[i] = string.replace(lines[i], old, new)
def update_inset_accent(lines):
pass
def remove_cursor(lines):
i = 0
cursor_re = re.compile(r'.*(\\cursor \d*)')
while 1:
i = find_re(lines, cursor_re, i)
if i == -1:
break
cursor = cursor_re.search(lines[i]).group(1)
lines[i]= string.replace(lines[i], cursor, '')
i = i + 1
def remove_empty_insets(lines):
i = 0
while 1:
i = find_token(lines, '\\begin_inset ',i)
if i == -1:
break
if lines[i] == '\\begin_inset ' and lines[i+1] == '\\end_inset ':
del lines[i]
del lines[i]
i = i + 1
def remove_formula_latex(lines):
i = 0
while 1:
i = find_token(lines, '\\latex formula_latex ', i)
if i == -1:
break
del lines[i]
i = find_token(lines, '\\latex default', i)
if i == -1:
break
del lines[i]
def add_end_document(lines):
lines.append('\\the_end')
def header_update(lines):
i = 0
l = len(lines)
while i < l:
if check_token(lines[i], '\\begin_preamble'):
i = find_token(lines, '\\end_preamble', i)
if i == -1:
sys.stderr.write('Unfinished preamble')
sys.exit(1)
i = i + 1
continue
if lines[i][-1:] == ' ':
lines[i] = lines[i][:-1]
if check_token(lines[i], '\\epsfig'):
lines[i] = string.replace(lines[i], '\\epsfig', '\\graphics')
i = i + 1
continue
if check_token(lines[i], '\\papersize'):
size = string.split(lines[i])[1]
new_size = size
paperpackage = ""
if size == 'usletter':
new_size = 'letterpaper'
if size == 'a4wide':
new_size = 'Default'
paperpackage = "widemarginsa4"
lines[i] = '\\papersize ' + new_size
i = i + 1
if paperpackage:
lines.insert(i, '\\paperpackage ' + paperpackage)
i = i + 1
lines.insert(i,'\\use_geometry 0')
lines.insert(i + 1,'\\use_amsmath 0')
i = i + 2
continue
if check_token(lines[i], '\\baselinestretch'):
size = string.split(lines[i])[1]
if size == '1.00':
name = 'single'
elif size == '1.50':
name = 'onehalf'
elif size == '2.00':
name = 'double'
else:
name = 'other ' + size
lines[i] = '\\spacing %s ' % name
i = i + 1
continue
i = i + 1
def convert(header,body):
header_update(header)
add_end_document(body)
remove_cursor(body)
final_dot(body)
update_inset_label(body)
update_latexdel(body)
update_space_units(body)
update_inset_accent(body)
space_before_layout(body)
formula_inset_space_eat(body)
update_tabular(body)
update_vfill(body)
remove_empty_insets(body)
remove_formula_latex(body)
if __name__ == "__main__":
pass

View File

@ -1,153 +0,0 @@
# This file is part of lyx2lyx
# -*- coding: iso-8859-1 -*-
# Copyright (C) 2002 José Matos <jamatos@lyx.org>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
import re
from parser_tools import *
layout_exp = re.compile(r"\\layout (\S*)")
math_env = ["\\[","\\begin{eqnarray*}","\\begin{eqnarray}","\\begin{equation}"]
def replace_protected_separator(lines):
i=0
while 1:
i = find_token(lines, "\\protected_separator", i)
if i == -1:
break
j = find_token_backwards(lines, "\\layout", i)
#if j == -1: print error
layout = layout_exp.match(lines[j]).group(1)
if layout == "LyX-Code":
result = ""
while lines[i] == "\\protected_separator ":
result = result + " "
del lines[i]
lines[i-1] = lines[i-1] + result + lines[i]
else:
lines[i-1] = lines[i-1]+ "\\SpecialChar ~"
del lines[i]
def merge_formula_inset(lines):
i=0
while 1:
i = find_token(lines, "\\begin_inset Formula", i)
if i == -1: break
if lines[i+1] in math_env:
lines[i] = lines[i] + lines[i+1]
del lines[i+1]
i = i + 1
# Update from tabular format 4 to 5 if necessary
def update_tabular(lines):
lyxtable_re = re.compile(r".*\\LyXTable$")
i=0
while 1:
i = find_re(lines, lyxtable_re, i)
if i == -1:
break
i = i + 1
format = lines[i][8]
if format != '4':
continue
lines[i]='multicol5'
i = i + 1
rows = int(string.split(lines[i])[0])
columns = int(string.split(lines[i])[1])
i = i + rows + 1
for j in range(columns):
col_info = string.split(lines[i])
if len(col_info) == 3:
lines[i] = lines[i] + '"" ""'
else:
lines[i] = string.join(col_info[:3]) + ' "%s" ""' % col_info[3]
i = i + 1
while lines[i]:
lines[i] = lines[i] + ' "" ""'
i = i + 1
def update_toc(lines):
i = 0
while 1:
i = find_token(lines, '\\begin_inset LatexCommand \\tableofcontents', i)
if i == -1:
break
lines[i] = lines[i] + '{}'
i = i + 1
def remove_cursor(lines):
i = find_token(lines, '\\cursor', 0)
if i != -1:
del lines[i]
def remove_vcid(lines):
i = find_token(lines, '\\lyxvcid', 0)
if i != -1:
del lines[i]
i = find_token(lines, '\\lyxrcsid', 0)
if i != -1:
del lines[i]
def first_layout(lines):
while (lines[0] == ""):
del lines[0]
if lines[0][:7] != "\\layout":
lines[:0] = ["\\layout Standard"]
def remove_space_in_units(lines):
margins = ["\\topmargin","\\rightmargin",
"\\leftmargin","\\bottommargin"]
unit_rexp = re.compile(r'[^ ]* (.*) (.*)')
begin_preamble = find_token(lines,"\\begin_preamble", 0)
end_preamble = find_token(lines, "\\end_preamble", 0)
for margin in margins:
i = 0
while 1:
i = find_token(lines, margin, i)
if i == -1:
break
if i > begin_preamble and i < end_preamble:
i = i + 1
continue
result = unit_rexp.search(lines[i])
if result:
lines[i] = margin + " " + result.group(1) + result.group(2)
i = i + 1
def convert(header,body):
first_layout(body)
remove_vcid(header)
remove_cursor(body)
update_toc(body)
replace_protected_separator(body)
merge_formula_inset(body)
update_tabular(body)
remove_space_in_units(header)
if __name__ == "__main__":
pass

View File

@ -1,278 +0,0 @@
# This file is part of lyx2lyx
# -*- coding: iso-8859-1 -*-
# Copyright (C) 2002 José Matos <jamatos@lyx.org>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
import re, string, sys
from parser_tools import *
lyxtable_re = re.compile(r".*\\LyXTable$")
def update_tabular(lines):
i=0
while 1:
i = find_re(lines, lyxtable_re, i)
if i == -1:
break
prop_dict = {"family" : "default", "series" : "default",
"shape" : "default", "size" : "default",
"emph" : "default", "bar" : "default",
"noun" : "default", "latex" : "default", "color" : "default"}
# remove \LyXTable
lines[i] = lines[i][:-9]
i = i + 1
lines.insert(i,'')
i = i + 1
lines[i] = "\\begin_inset Tabular"
i = i + 1
head = string.split(lines[i])
rows = int(head[0])
columns = int(head[1])
tabular_line = i
i = i +1
lines.insert(i, '<Features rotate="%s" islongtable="%s" endhead="%s" endfirsthead="%s" endfoot="%s" endlastfoot="%s">' % (head[2],head[3],head[4],head[5],head[6],head[7]))
i = i +1
row_info = []
cont_row = []
for j in range(rows):
row_info.append(string.split(lines[i]))
if string.split(lines[i])[2] == '1':
cont_row.append(j)
del lines[i]
column_info = []
col_info_re = re.compile(r'(\d) (\d) (\d) (".*") (".*")')
for j in range(columns):
column_info.append(col_info_re.match(lines[i]).groups())
del lines[i]
cell_info = []
cell_col = []
ncells = 0
cell_re = re.compile(r'(\d) (\d) (\d) (\d) (\d) (\d) (\d) (".*") (".*")')
for j in range(rows):
for k in range(columns):
#add column location to read properties
cell_info.append(cell_re.match(lines[i]).groups())
cell_col.append(k)
if lines[i][0] != "2":
ncells = ncells + 1
del lines[i]
lines[tabular_line] = '<LyXTabular version="1" rows="%s" columns="%s">' % (rows-len(cont_row),columns)
del lines[i]
if not lines[i]:
del lines[i]
# Read cells
l = 0
cell_content = []
for j in range(rows):
cell_content.append([])
for j in range(rows):
for k in range(columns):
cell_content[j].append([])
for j in range(rows):
for k in range(columns):
m = j*columns + k
if cell_info[m][0] == '2':
continue
if l == ncells -1:
# the end variable refers to cell end, not to file end.
end = find_tokens(lines, ['\\layout','\\the_end','\\end_deeper','\\end_float'], i)
else:
end = find_token(lines, '\\newline', i)
if end == -1:
sys.stderr.write("Malformed lyx file\n")
sys.exit(1)
end = end - i
while end > 0:
cell_content[j][k].append(lines[i])
del lines[i]
end = end -1
if string.find(lines[i],'\\newline') != -1:
del lines[i]
l = l + 1
tmp = []
tmp.append("")
for j in range(rows):
if j in cont_row:
continue
tmp.append('<Row topline="%s" bottomline="%s" newpage="%s">' % (row_info[j][0],row_info[j][1],row_info[j][3]))
for k in range(columns):
if j:
tmp.append('<Column>')
else:
tmp.append('<Column alignment="%s" valignment="0" leftline="%s" rightline="%s" width=%s special=%s>' % (column_info[k][0],column_info[k][1], column_info[k][2], column_info[k][3], column_info[k][4]))
m = j*columns + k
leftline = int(column_info[k][1])
if cell_info[m][0] == '1':
n = m + 1
while n < rows * columns - 1 and cell_info[n][0] == '2':
n = n + 1
rightline = int(column_info[cell_col[n-1]][2])
else:
# not a multicolumn main cell
rightline = int(column_info[k][2])
tmp.append('<Cell multicolumn="%s" alignment="%s" valignment="0" topline="%s" bottomline="%s" leftline="%d" rightline="%d" rotate="%s" usebox="%s" width=%s special=%s>' % (cell_info[m][0],cell_info[m][1],cell_info[m][2],cell_info[m][3],leftline,rightline,cell_info[m][5],cell_info[m][6],cell_info[m][7],cell_info[m][8]))
tmp.append('\\begin_inset Text')
tmp.append('')
tmp.append('\\layout Standard')
tmp.append('')
if cell_info[m][0] != '2':
paragraph = []
if cell_info[m][4] == '1':
l = j
paragraph = paragraph + cell_content[j][k]
while cell_info[m][4] == '1':
m = m + columns
l = l + 1
if l >= rows: break
paragraph = paragraph + cell_content[l][k]
else:
paragraph = cell_content[j][k]
tmp = tmp + set_paragraph_properties(paragraph, prop_dict)
tmp.append('\\end_inset ')
tmp.append('</Cell>')
tmp.append('</Column>')
tmp.append('</Row>')
tmp.append('</LyXTabular>')
tmp.append('')
tmp.append('\\end_inset ')
tmp.append('')
tmp.append('')
lines[i:i] = tmp
i = i + len(tmp)
prop_exp = re.compile(r"\\(\S*)\s*(\S*)")
def set_paragraph_properties(lines, prop_dict):
# we need to preserve the order of options
properties = ["family","series","shape","size",
"emph","bar","noun","latex","color"]
prop_value = {"family" : "default", "series" : "medium",
"shape" : "up", "size" : "normal",
"emph" : "off", "bar" : "no",
"noun" : "off", "latex" : "no_latex", "color" : "none"}
start = 0
end = 0
i = 0
n = len(lines)
#skip empty lines
while i<n and lines[i] == "":
i = i + 1
start = i
#catch open char properties
while i<n and lines[i][:1] == "\\":
result = prop_exp.match(lines[i])
# sys.stderr.write(lines[i]+"\n")
prop = result.group(1)
if prop not in properties:
break
else:
prop_dict[prop] = result.group(2)
i = i + 1
end = i
aux = []
insert = 0
for prop in properties:
if prop_dict[prop] != 'default':
insert = 1
if prop == "color":
aux.append("\\%s %s" % (prop, prop_dict[prop]))
elif prop != "family" or prop_dict[prop] != "roman":
aux.append("\\%s %s " % (prop, prop_dict[prop]))
# remove final char properties
n = len(lines)
changed_prop = []
while n:
n = n - 1
if not lines[n]:
del lines[n]
continue
if lines[n][:1] == '\\':
result = prop_exp.match(lines[n])
prop = result.group(1)
if prop in properties:
changed_prop.append(prop)
prop_dict[prop] = result.group(2)
del lines[n]
continue
if check_token(lines[n],'\\end_inset'):
# ensure proper newlines after inset end
lines.append('')
lines.append('')
break
for line in lines[end:]:
if line[:1] == '\\':
result = prop_exp.match(line)
prop = result.group(1)
if prop in properties and prop not in changed_prop:
prop_dict[prop] = result.group(2)
if not lines[start:] and not lines[end:]:
return []
result = lines[:start] + aux[:] + lines[end:]
if insert and result[0] != '':
return [''] + result[:]
return result[:]
def update_language(header):
i = find_token(header, "\\language", 0)
if i == -1:
# no language, should emit a warning
header.append('\\language english')
return
# This is the lyx behaviour: defaults to english
if string.split(header[i])[1] == 'default':
header[i] = '\\language english'
return
def convert(header,body):
update_tabular(body)
update_language(header)
if __name__ == "__main__":
pass

View File

@ -1,117 +0,0 @@
# This file is part of lyx2lyx
# -*- coding: iso-8859-1 -*-
# Copyright (C) 2002 José Matos <jamatos@lyx.org>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
import re, string, sys
from parser_tools import *
def bool_table(item):
if item == "0":
return "false"
# should emit a warning if item != "1"
return "true"
align_table = {"0": "top", "2": "left", "4": "right", "8": "center"}
use_table = {"0": "none", "1": "parbox"}
table_meta_re = re.compile(r'<LyXTabular version="?1"? rows="?(\d*)"? columns="?(\d*)"?>')
def update_tabular(lines):
i=0
while 1:
i = find_token(lines, '\\begin_inset Tabular', i)
if i == -1:
break
i = i +1
# scan table header meta-info
res = table_meta_re.match( lines[i] )
if res:
val = res.groups()
lines[i] = '<lyxtabular version="2" rows="%s" columns="%s">' % val
j = find_token(lines, '</LyXTabular>', i) + 1
if j == 0:
sys.stderr.write( "Error: Bad lyx format i=%d j=%d\n" % (i,j))
break
new_table = table_update(lines[i:j])
lines[i:j] = new_table
i = i + len(new_table)
col_re = re.compile(r'<column alignment="?(\d)"? valignment="?(\d)"? leftline="?(\d)"? rightline="?(\d)"? width="(.*)" special="(.*)">')
cell_re = re.compile(r'<cell multicolumn="?(\d)"? alignment="?(\d)"? valignment="?(\d)"? topline="?(\d)"? bottomline="?(\d)"? leftline="?(\d)"? rightline="?(\d)"? rotate="?(\d)"? usebox="?(\d)"? width="(.*)" special="(.*)">')
features_re = re.compile(r'<features rotate="?(\d)"? islongtable="?(\d)"? endhead="?(-?\d)"? endfirsthead="?(-?\d)"? endfoot="?(-?\d)"? endlastfoot="?(-?\d)"?>')
row_re = re.compile(r'<row topline="?(\d)"? bottomline="?(\d)"? newpage="?(\d)"?>')
def table_update(lines):
lines[1] = string.replace(lines[1], '<Features', '<features')
res = features_re.match( lines[1] )
if res:
val = res.groups()
lines[1] = '<features rotate="%s" islongtable="%s" endhead="%s" endfirsthead="%s" endfoot="%s" endlastfoot="%s">' % (bool_table(val[0]), bool_table(val[1]), val[2], val[3], val[4], val[5])
if lines[2]=="":
del lines[2]
i = 2
col_info = []
while i < len(lines):
lines[i] = string.replace(lines[i], '<Cell', '<cell')
lines[i] = string.replace(lines[i], '</Cell', '</cell')
lines[i] = string.replace(lines[i], '<Row', '<row')
lines[i] = string.replace(lines[i], '</Row', '</row')
lines[i] = string.replace(lines[i], '<Column', '<column')
lines[i] = string.replace(lines[i], '</Column', '</column')
lines[i] = string.replace(lines[i], '</LyXTabular', '</lyxtabular')
k = string.find (lines[i], '<column ')
if k != -1:
col_info.append(lines[i])
del lines[i]
continue
if lines[i] == '</column>' or lines[i] == '<column>':
del lines[i]
continue
res = cell_re.match(lines[i])
if res:
val = res.groups()
lines[i] = '<cell multicolumn="%s" alignment="%s" valignment="%s" topline="%s" bottomline="%s" leftline="%s" rightline="%s" rotate="%s" usebox="%s" width="%s" special="%s">' % ( val[0], align_table[val[1]], align_table[val[2]], bool_table(val[3]), bool_table(val[4]), bool_table(val[5]), bool_table(val[6]), bool_table(val[7]), use_table[val[8]], val[9], val[10])
res = row_re.match(lines[i])
if res:
val = res.groups()
lines[i] = '<row topline="%s" bottomline="%s" newpage="%s">' % (bool_table(val[0]), bool_table(val[1]), bool_table(val[2]))
i = i + 1
j = len(col_info)
for i in range(j):
res = col_re.match(col_info[i])
if res:
val = res.groups()
col_info[i] = '<column alignment="%s" valignment="%s" leftline="%s" rightline="%s" width="%s" special="%s">' \
% ( align_table[val[0]], align_table[val[1]], bool_table(val[2]), bool_table(val[3]), val[4],val[5])
return lines[:2] + col_info + lines[2:]
def convert(header,body):
update_tabular(body)
if __name__ == "__main__":
pass

View File

@ -1,539 +0,0 @@
# This file is part of lyx2lyx
# -*- coding: iso-8859-1 -*-
# Copyright (C) 2002 Dekel Tsur <dekel@lyx.org>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
import sys,string,re
from parser_tools import *
floats = {
"footnote": ["\\begin_inset Foot",
"collapsed true"],
"margin": ["\\begin_inset Marginal",
"collapsed true"],
"fig": ["\\begin_inset Float figure",
"wide false",
"collapsed false"],
"tab": ["\\begin_inset Float table",
"wide false",
"collapsed false"],
"alg": ["\\begin_inset Float algorithm",
"wide false",
"collapsed false"],
"wide-fig": ["\\begin_inset Float figure",
"wide true",
"collapsed false"],
"wide-tab": ["\\begin_inset Float table",
"wide true",
"collapsed false"]
}
font_tokens = ["\\family", "\\series", "\\shape", "\\size", "\\emph",
"\\bar", "\\noun", "\\color", "\\lang", "\\latex"]
pextra_type3_rexp = re.compile(r".*\\pextra_type\s+3")
pextra_rexp = re.compile(r"\\pextra_type\s+(\S+)"+\
r"(\s+\\pextra_alignment\s+(\S+))?"+\
r"(\s+\\pextra_hfill\s+(\S+))?"+\
r"(\s+\\pextra_start_minipage\s+(\S+))?"+\
r"(\s+(\\pextra_widthp?)\s+(\S*))?")
def get_width(mo):
if mo.group(10):
if mo.group(9) == "\\pextra_widthp":
return mo.group(10)+"col%"
else:
return mo.group(10)
else:
return "100col%"
#
# Change \begin_float .. \end_float into \begin_inset Float .. \end_inset
#
def remove_oldfloat(lines, language):
i = 0
while 1:
i = find_token(lines, "\\begin_float", i)
if i == -1:
break
# There are no nested floats, so finding the end of the float is simple
j = find_token(lines, "\\end_float", i+1)
floattype = string.split(lines[i])[1]
if not floats.has_key(floattype):
sys.stderr.write("Error! Unknown float type "+floattype+"\n")
floattype = "fig"
# skip \end_deeper tokens
i2 = i+1
while check_token(lines[i2], "\\end_deeper"):
i2 = i2+1
if i2 > i+1:
j2 = get_next_paragraph(lines, j+1)
lines[j2:j2] = ["\\end_deeper "]*(i2-(i+1))
new = floats[floattype]+[""]
# Check if the float is floatingfigure
k = find_re(lines, pextra_type3_rexp, i, j)
if k != -1:
mo = pextra_rexp.search(lines[k])
width = get_width(mo)
lines[k] = re.sub(pextra_rexp, "", lines[k])
new = ["\\begin_inset Wrap figure",
'width "%s"' % width,
"collapsed false",
""]
new = new+lines[i2:j]+["\\end_inset ", ""]
# After a float, all font attributes are reseted.
# We need to output '\foo default' for every attribute foo
# whose value is not default before the float.
# The check here is not accurate, but it doesn't matter
# as extra '\foo default' commands are ignored.
# In fact, it might be safer to output '\foo default' for all
# font attributes.
k = get_paragraph(lines, i)
flag = 0
for token in font_tokens:
if find_token(lines, token, k, i) != -1:
if not flag:
# This is not necessary, but we want the output to be
# as similar as posible to the lyx format
flag = 1
new.append("")
if token == "\\lang":
new.append(token+" "+language)
else:
new.append(token+" default ")
lines[i:j+1] = new
i = i+1
pextra_type2_rexp = re.compile(r".*\\pextra_type\s+[12]")
pextra_type2_rexp2 = re.compile(r".*(\\layout|\\pextra_type\s+2)")
def remove_pextra(lines):
i = 0
flag = 0
while 1:
i = find_re(lines, pextra_type2_rexp, i)
if i == -1:
break
mo = pextra_rexp.search(lines[i])
width = get_width(mo)
if mo.group(1) == "1":
# handle \pextra_type 1 (indented paragraph)
lines[i] = re.sub(pextra_rexp, "\\leftindent "+width+" ", lines[i])
i = i+1
continue
# handle \pextra_type 2 (minipage)
position = mo.group(3)
hfill = mo.group(5)
lines[i] = re.sub(pextra_rexp, "", lines[i])
start = ["\\begin_inset Minipage",
"position " + position,
"inner_position 0",
'height "0pt"',
'width "%s"' % width,
"collapsed false"
]
if flag:
flag = 0
if hfill:
start = ["","\hfill",""]+start
else:
start = ["\\layout Standard"] + start
j0 = find_token_backwards(lines,"\\layout", i-1)
j = get_next_paragraph(lines, i)
count = 0
while 1:
# collect more paragraphs to the minipage
count = count+1
if j == -1 or not check_token(lines[j], "\\layout"):
break
i = find_re(lines, pextra_type2_rexp2, j+1)
if i == -1:
break
mo = pextra_rexp.search(lines[i])
if not mo:
break
if mo.group(7) == "1":
flag = 1
break
lines[i] = re.sub(pextra_rexp, "", lines[i])
j = find_tokens(lines, ["\\layout", "\\end_float"], i+1)
mid = lines[j0:j]
end = ["\\end_inset "]
lines[j0:j] = start+mid+end
i = i+1
def is_empty(lines):
return filter(is_nonempty_line, lines) == []
move_rexp = re.compile(r"\\(family|series|shape|size|emph|numeric|bar|noun|end_deeper)")
ert_rexp = re.compile(r"\\begin_inset|\\hfill|.*\\SpecialChar")
spchar_rexp = re.compile(r"(.*)(\\SpecialChar.*)")
ert_begin = ["\\begin_inset ERT",
"status Collapsed",
"",
"\\layout Standard"]
def remove_oldert(lines):
i = 0
while 1:
i = find_tokens(lines, ["\\latex latex", "\\layout LaTeX"], i)
if i == -1:
break
j = i+1
while 1:
# \end_inset is for ert inside a tabular cell. The other tokens
# are obvious.
j = find_tokens(lines, ["\\latex default", "\\layout", "\\begin_inset", "\\end_inset", "\\end_float", "\\the_end"],
j)
if check_token(lines[j], "\\begin_inset"):
j = find_end_of_inset(lines, j)+1
else:
break
if check_token(lines[j], "\\layout"):
while j-1 >= 0 and check_token(lines[j-1], "\\begin_deeper"):
j = j-1
# We need to remove insets, special chars & font commands from ERT text
new = []
new2 = []
if check_token(lines[i], "\\layout LaTeX"):
new = ["\layout Standard", "", ""]
# We have a problem with classes in which Standard is not the default layout!
k = i+1
while 1:
k2 = find_re(lines, ert_rexp, k, j)
inset = hfill = specialchar = 0
if k2 == -1:
k2 = j
elif check_token(lines[k2], "\\begin_inset"):
inset = 1
elif check_token(lines[k2], "\\hfill"):
hfill = 1
del lines[k2]
j = j-1
else:
specialchar = 1
mo = spchar_rexp.match(lines[k2])
lines[k2] = mo.group(1)
specialchar_str = mo.group(2)
k2 = k2+1
tmp = []
for line in lines[k:k2]:
# Move some lines outside the ERT inset:
if move_rexp.match(line):
if new2 == []:
# This is not necessary, but we want the output to be
# as similar as posible to the lyx format
new2 = [""]
new2.append(line)
elif not check_token(line, "\\latex"):
tmp.append(line)
if is_empty(tmp):
if filter(lambda x:x != "", tmp) != []:
if new == []:
# This is not necessary, but we want the output to be
# as similar as posible to the lyx format
lines[i-1] = lines[i-1]+" "
else:
new = new+[" "]
else:
new = new+ert_begin+tmp+["\\end_inset ", ""]
if inset:
k3 = find_end_of_inset(lines, k2)
new = new+[""]+lines[k2:k3+1]+[""] # Put an empty line after \end_inset
k = k3+1
# Skip the empty line after \end_inset
if not is_nonempty_line(lines[k]):
k = k+1
new.append("")
elif hfill:
new = new+["\hfill", ""]
k = k2
elif specialchar:
if new == []:
# This is not necessary, but we want the output to be
# as similar as posible to the lyx format
lines[i-1] = lines[i-1]+specialchar_str
new = [""]
else:
new = new+[specialchar_str, ""]
k = k2
else:
break
new = new+new2
if not check_token(lines[j], "\\latex "):
new = new+[""]+[lines[j]]
lines[i:j+1] = new
i = i+1
# Delete remaining "\latex xxx" tokens
i = 0
while 1:
i = find_token(lines, "\\latex ", i)
if i == -1:
break
del lines[i]
# ERT insert are hidden feature of lyx 1.1.6. This might be removed in the future.
def remove_oldertinset(lines):
i = 0
while 1:
i = find_token(lines, "\\begin_inset ERT", i)
if i == -1:
break
j = find_end_of_inset(lines, i)
k = find_token(lines, "\\layout", i+1)
l = get_paragraph(lines, i)
if lines[k] == lines[l]: # same layout
k = k+1
new = lines[k:j]
lines[i:j+1] = new
i = i+1
def is_ert_paragraph(lines, i):
if not check_token(lines[i], "\\layout Standard"):
return 0
i = find_nonempty_line(lines, i+1)
if not check_token(lines[i], "\\begin_inset ERT"):
return 0
j = find_end_of_inset(lines, i)
k = find_nonempty_line(lines, j+1)
return check_token(lines[k], "\\layout")
def combine_ert(lines):
i = 0
while 1:
i = find_token(lines, "\\begin_inset ERT", i)
if i == -1:
break
j = get_paragraph(lines, i)
count = 0
text = []
while is_ert_paragraph(lines, j):
count = count+1
i2 = find_token(lines, "\\layout", j+1)
k = find_token(lines, "\\end_inset", i2+1)
text = text+lines[i2:k]
j = find_token(lines, "\\layout", k+1)
if j == -1:
break
if count >= 2:
j = find_token(lines, "\\layout", i+1)
lines[j:k] = text
i = i+1
oldunits = ["pt", "cm", "in", "text%", "col%"]
def get_length(lines, name, start, end):
i = find_token(lines, name, start, end)
if i == -1:
return ""
x = string.split(lines[i])
return x[2]+oldunits[int(x[1])]
def write_attribute(x, token, value):
if value != "":
x.append("\t"+token+" "+value)
def remove_figinset(lines):
i = 0
while 1:
i = find_token(lines, "\\begin_inset Figure", i)
if i == -1:
break
j = find_end_of_inset(lines, i)
if ( len(string.split(lines[i])) > 2 ):
lyxwidth = string.split(lines[i])[3]+"pt"
lyxheight = string.split(lines[i])[4]+"pt"
else:
lyxwidth = ""
lyxheight = ""
filename = get_value(lines, "file", i+1, j)
width = get_length(lines, "width", i+1, j)
# what does width=5 mean ?
height = get_length(lines, "height", i+1, j)
rotateAngle = get_value(lines, "angle", i+1, j)
if width == "" and height == "":
size_type = "0"
else:
size_type = "1"
flags = get_value(lines, "flags", i+1, j)
x = int(flags)%4
if x == 1:
display = "monochrome"
elif x == 2:
display = "gray"
else:
display = "color"
subcaptionText = ""
subcaptionLine = find_token(lines, "subcaption", i+1, j)
if subcaptionLine != -1:
subcaptionText = lines[subcaptionLine][11:]
if subcaptionText != "":
subcaptionText = '"'+subcaptionText+'"'
k = find_token(lines, "subfigure", i+1,j)
if k == -1:
subcaption = 0
else:
subcaption = 1
new = ["\\begin_inset Graphics FormatVersion 1"]
write_attribute(new, "filename", filename)
write_attribute(new, "display", display)
if subcaption:
new.append("\tsubcaption")
write_attribute(new, "subcaptionText", subcaptionText)
write_attribute(new, "size_type", size_type)
write_attribute(new, "width", width)
write_attribute(new, "height", height)
if rotateAngle != "":
new.append("\trotate")
write_attribute(new, "rotateAngle", rotateAngle)
write_attribute(new, "rotateOrigin", "leftBaseline")
write_attribute(new, "lyxsize_type", "1")
write_attribute(new, "lyxwidth", lyxwidth)
write_attribute(new, "lyxheight", lyxheight)
new = new + ["\end_inset"]
lines[i:j+1] = new
attr_re = re.compile(r' \w*="(false|0|)"')
line_re = re.compile(r'<(features|column|row|cell)')
def update_tabular(lines):
i = 0
while 1:
i = find_token(lines, '\\begin_inset Tabular', i)
if i == -1:
break
for k in get_tabular_lines(lines, i):
if check_token(lines[k], "<lyxtabular"):
lines[k] = string.replace(lines[k], 'version="2"', 'version="3"')
elif check_token(lines[k], "<column"):
lines[k] = string.replace(lines[k], 'width=""', 'width="0pt"')
if line_re.match(lines[k]):
lines[k] = re.sub(attr_re, "", lines[k])
i = i+1
# Figure insert are hidden feature of lyx 1.1.6. This might be removed in the future.
def fix_oldfloatinset(lines):
i = 0
while 1:
i = find_token(lines, "\\begin_inset Float ", i)
if i == -1:
break
j = find_token(lines, "collapsed", i)
if j != -1:
lines[j:j] = ["wide false"]
i = i+1
def change_listof(lines):
i = 0
while 1:
i = find_token(lines, "\\begin_inset LatexCommand \\listof", i)
if i == -1:
break
type = re.search(r"listof(\w*)", lines[i]).group(1)[:-1]
lines[i] = "\\begin_inset FloatList "+type
i = i+1
def change_infoinset(lines):
i = 0
while 1:
i = find_token(lines, "\\begin_inset Info", i)
if i == -1:
break
txt = string.lstrip(lines[i][18:])
new = ["\\begin_inset Note", "collapsed true", ""]
j = find_token(lines, "\\end_inset", i)
if j == -1:
break
note_lines = lines[i+1:j]
if len(txt) > 0:
note_lines = [txt]+note_lines
for line in note_lines:
new = new + ["\layout Standard", ""]
tmp = string.split(line, '\\')
new = new + [tmp[0]]
for x in tmp[1:]:
new = new + ["\\backslash ", x]
lines[i:j] = new
i = i+5
def change_preamble(lines):
i = find_token(lines, "\\use_amsmath", 0)
if i == -1:
return
lines[i+1:i+1] = ["\\use_natbib 0",
"\use_numerical_citations 0"]
def convert(header, body):
language = get_value(header, "\\language", 0)
if language == "":
language = "english"
change_preamble(header)
change_listof(body)
fix_oldfloatinset(body)
update_tabular(body)
remove_pextra(body)
remove_oldfloat(body, language)
remove_figinset(body)
remove_oldertinset(body)
remove_oldert(body)
combine_ert(body)
change_infoinset(body)
if __name__ == "__main__":
pass

View File

@ -1,94 +0,0 @@
# This file is part of lyx2lyx
# -*- coding: iso-8859-1 -*-
# Copyright (C) 2002 Dekel Tsur <dekel@lyx.org>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
import sys,string,re
from parser_tools import *
def change_insetgraphics(lines):
i = 0
while 1:
i = find_token(lines, "\\begin_inset Graphics", i)
if i == -1:
break
j = find_end_of_inset(lines, i)
lines[i] = "\\begin_inset Graphics"
if get_value(lines, "display", i, j) == "default":
j = del_token(lines, "display", i, j)
if get_value(lines, "rotateOrigin", i, j) == "leftBaseline":
j = del_token(lines, "rotateOrigin", i, j)
k = find_token2(lines, "rotate", i, j)
if k != -1:
del lines[k]
j = j-1
else:
j = del_token(lines, "rotateAngle", i, j)
k = find_token2(lines, "size_type", i, j)
if k == -1:
k = find_token2(lines, "size_kind", i, j)
if k != -1:
size_type = string.split(lines[k])[1]
del lines[k]
j = j-1
if size_type in ["0", "original"]:
j = del_token(lines, "width", i, j)
j = del_token(lines, "height", i, j)
j = del_token(lines, "scale", i, j)
elif size_type in ["2", "scale"]:
j = del_token(lines, "width", i, j)
j = del_token(lines, "height", i, j)
if get_value(lines, "scale", i, j) == "100":
j = del_token(lines, "scale", i, j)
else:
j = del_token(lines, "scale", i, j)
k = find_token2(lines, "lyxsize_type", i, j)
if k == -1:
k = find_token2(lines, "lyxsize_kind", i, j)
if k != -1:
lyxsize_type = string.split(lines[k])[1]
del lines[k]
j = j-1
j = del_token(lines, "lyxwidth", i, j)
j = del_token(lines, "lyxheight", i, j)
if lyxsize_type not in ["2", "scale"] or \
get_value(lines, "lyxscale", i, j) == "100":
j = del_token(lines, "lyxscale", i, j)
i = i+1
def change_tabular(lines):
i = 0
while 1:
i = find_token(lines, "<column", i)
if i == -1:
break
if not re.search('width="0pt"', lines[i]):
lines[i] = re.sub(' alignment=".*?"',' alignment="block"',lines[i])
i = i+1
def convert(header, body):
change_insetgraphics(body)
change_tabular(body)
if __name__ == "__main__":
pass

View File

@ -17,12 +17,14 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
import string
import re
def check_token(line, token):
if line[:len(token)] == token:
return 1
return 0
# We need to check that the char after the token is space, but I think
# we can ignore this
def find_token(lines, token, start, end = 0):
@ -34,6 +36,7 @@ def find_token(lines, token, start, end = 0):
return i
return -1
def find_token2(lines, token, start, end = 0):
if end == 0:
end = len(lines)
@ -43,6 +46,7 @@ def find_token2(lines, token, start, end = 0):
return i
return -1
def find_tokens(lines, tokens, start, end = 0):
if end == 0:
end = len(lines)
@ -53,6 +57,7 @@ def find_tokens(lines, tokens, start, end = 0):
return i
return -1
def find_re(lines, rexp, start, end = 0):
if end == 0:
end = len(lines)
@ -61,6 +66,7 @@ def find_re(lines, rexp, start, end = 0):
return i
return -1
def find_token_backwards(lines, token, start):
m = len(token)
for i in xrange(start, -1, -1):
@ -69,6 +75,7 @@ def find_token_backwards(lines, token, start):
return i
return -1
def find_tokens_backwards(lines, tokens, start):
for i in xrange(start, -1, -1):
line = lines[i]
@ -77,6 +84,7 @@ def find_tokens_backwards(lines, tokens, start):
return i
return -1
def get_value(lines, token, start, end = 0):
i = find_token2(lines, token, start, end)
if i == -1:
@ -86,6 +94,7 @@ def get_value(lines, token, start, end = 0):
else:
return ""
def del_token(lines, token, i, j):
k = find_token2(lines, token, i, j)
if k == -1:
@ -94,6 +103,7 @@ def del_token(lines, token, i, j):
del lines[k]
return j-1
# Finds the paragraph that contains line i.
def get_paragraph(lines, i):
while i != -1:
@ -102,6 +112,8 @@ def get_paragraph(lines, i):
if check_token(lines[i], "\\layout"):
return i
i = find_beginning_of_inset(lines, i)
return -1
# Finds the paragraph after the paragraph that contains line i.
def get_next_paragraph(lines, i):
@ -110,6 +122,8 @@ def get_next_paragraph(lines, i):
if not check_token(lines[i], "\\begin_inset"):
return i
i = find_end_of_inset(lines, i)
return -1
def find_end_of(lines, i, start_token, end_token):
count = 1
@ -124,6 +138,7 @@ def find_end_of(lines, i, start_token, end_token):
return i
return -1
# Finds the matching \end_inset
def find_beginning_of(lines, i, start_token, end_token):
count = 1
@ -137,17 +152,21 @@ def find_beginning_of(lines, i, start_token, end_token):
return i
return -1
# Finds the matching \end_inset
def find_end_of_inset(lines, i):
return find_end_of(lines, i, "\\begin_inset", "\\end_inset")
# Finds the matching \end_inset
def find_beginning_of_inset(lines, i):
return find_beginning_of(lines, i, "\\begin_inset", "\\end_inset")
def find_end_of_tabular(lines, i):
return find_end_of(lines, i, "<lyxtabular", "</lyxtabular")
def get_tabular_lines(lines, i):
result = []
i = i+1
@ -163,9 +182,11 @@ def get_tabular_lines(lines, i):
i = i+1
return result
def is_nonempty_line(line):
return line != " "*len(line)
def find_nonempty_line(lines, start, end = 0):
if end == 0:
end = len(lines)
@ -173,14 +194,3 @@ def find_nonempty_line(lines, start, end = 0):
if is_nonempty_line(lines[i]):
return i
return -1
def set_comment(lines, version):
lines[0] = "#LyX %s created this file. For more info see http://www.lyx.org/" % version
if lines[1][0] == '#':
del lines[1]
def set_format(lines, number):
if int(number) <= 217:
number = float(number)/100
i = find_token(lines, "\\lyxformat", 0)
lines[i] = "\\lyxformat %s" % number