+2004-03-31 Georg Baum <Georg.Baum@post.rwth-aachen.de>
+
+ * lyxconvert_229.py (convert_jurabib): new, add use_jurabib flag
+ * lyxrevert_230.py (convert_jurabib): new, remove use_jurabib flag
+ * lyxconvert_230.py (convert_float): new, add sideways flag
+ * lyxrevert_231.py (convert_float): new, remove sideways flag
+ * lyxconvert_231.py (convert_bibtopic): new, add use_bibtopic flag
+ * lyxrevert_232.py (convert_bibtopic): new, remove use_bibtopic flag
+
2004-03-29 Jürgen Spitzmüller <j.spitzmueller@gmx.de>
* lyx2lyx: up the format to 232.
+++ /dev/null
-# This file is part of lyx2lyx
-# -*- coding: iso-8859-1 -*-
-# Copyright (C) 2002-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.
-
-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()
#! /usr/bin/env python
# -*- coding: iso-8859-1 -*-
-# Copyright (C) 2002-2003 José Matos <jamatos@lyx.org>
+# 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
# 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
+import getopt
import gzip
-
-version = "1.4.0cvs"
+import sys
+from parser_tools import read_file, write_file, read_version, set_version, \
+ read_format, set_format, chain, lyxformat, get_value
# 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.err = sys.stderr
-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, 223, 224, 225, 226, 227, 228, 229,
- 230, 231, 232]
+ def __init__(self):
+ self.output = sys.stdout
+ self.input = sys.stdin
+ self.err = sys.stderr
+ self.debug = 1
+ self.start = None
+ self.end = None
+
+ def warning(self, message, debug_level= 10):
+ if debug_level <= self.debug:
+ self.err.write(message + "\n")
+
+ def error(self, message):
+ self.warning(message)
+ self.warning("Quiting.")
+ sys.exit(1)
def usage():
print """Usage: lyx2lyx [options] [file]
-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)
-q, --quiet same as --debug=0"""
-def parse_options(argv):
+def parse_options(argv, version, opt):
_options = ["help", "version", "list", "debug=", "err=", "from=", "to=", "output=", "quiet"]
try:
opts, args = getopt.getopt(argv[1:], "d:e:f:hlo:qt:v", _options)
usage()
sys.exit()
if o in ("-v", "--version"):
- print "lyxconvert, version %s" %(version)
- print "Copyright (C) 2002-2003 José Matos and Dekel Tsur"
+ print "lyx2lyx, version %s" %(version)
+ print "Copyright (C) 2002-2004 José Matos and Dekel Tsur"
sys.exit()
if o in ("-d", "--debug"):
opt.debug = int(a)
if o in ("-q", "--quiet"):
opt.debug = 0
if o in ("-l", "--list"):
- print lst_ft
+ # list available formats
sys.exit()
if o in ("-o", "--output"):
opt.output = open(a, "w")
if o in ("-f", "--from"):
- opt.start = lyxformat(a)
+ opt.start = lyxformat(a, opt)
if o in ("-t", "--to"):
- opt.end = lyxformat(a)
+ opt.end = lyxformat(a, opt)
if o in ("-e","--err"):
opt.err = open(a, "w")
- if not opt.end:
- opt.end = lst_ft[len(lst_ft)-1]
-
if args:
file = args[0]
try:
except:
opt.input = open(file)
-def lyxformat(fmt):
- result = format.match(fmt)
- if result:
- fmt = int(result.group(1) + result.group(2))
- else:
- opt.err.write(str(fmt) + ": " + error.invalid_format)
- sys.exit(2)
-
- if fmt in lst_ft:
- return fmt
-
- opt.err.write(str(fmt) + ": " + error.format_not_supported)
- sys.exit(1)
-
-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:
- opt.err.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:
- opt.err.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)
+ version = "1.4.0cvs"
+
+ # options object, with default values
+ opt = struct()
+
+ parse_options(argv, version, opt)
header, body = [], []
- fmt = read_file(opt.input, header, body)
-
- if opt.start:
- if opt.start != fmt:
- opt.err.write("%s: %s %s\n" % (warning.dont_match, opt.start, fmt))
- else:
- opt.start = fmt
-
- # Convertion chain
- if opt.start < opt.end:
- mode = "lyxconvert_"
- else:
- lst_ft.reverse()
- mode = "lyxrevert_"
-
- start = lst_ft.index(opt.start)
- end = lst_ft.index(opt.end)
-
- for fmt in lst_ft[start:end]:
- __import__(mode + str(fmt)).convert(header,body)
-
- set_comment(header, version)
- set_format(header, opt.end)
- write_file(opt.output, header, body)
+
+ read_file(header, body, opt)
+
+ initial_version = read_version(header)
+ opt.format = read_format(header, opt)
+ opt.language = get_value(header, "\\language", 0)
+ if opt.language == "":
+ opt.language = "english"
+
+ mode, convertion_chain = chain(opt, initial_version)
+ opt.warning("convertion chain: " + str(convertion_chain), 3)
+
+ for step in convertion_chain:
+ convert = getattr(__import__("lyx_" + step), mode)
+ convert(header,body, opt)
+
+ set_version(header, version)
+ set_format(header, opt.format)
+ write_file(header, body, opt)
if __name__ == "__main__":
main(sys.argv)
--- /dev/null
+# This file is part of lyx2lyx
+# -*- coding: iso-8859-1 -*-
+# Copyright (C) 2003-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.
+
+import re
+import string
+from parser_tools import find_token, find_re, check_token
+
+
+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):
+ i = find_token(lines, '\\the_end', 0)
+ if i == -1:
+ lines.append('\\the_end')
+
+
+def header_update(lines, opt):
+ 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:
+ opt.error('Unfinished preamble')
+ 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, opt):
+ header_update(header, opt)
+ 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)
+ opt.format = 215
+
+
+def revert(header, body, opt):
+ opt.error("The convertion to an older format (%s) is not implemented." % opt.format)
+
+
+if __name__ == "__main__":
+ pass
--- /dev/null
+# This file is part of lyx2lyx
+# -*- coding: iso-8859-1 -*-
+# Copyright (C) 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.
+
+def convert(header, body, opt):
+ opt.format = 215
+
+
+def revert(header, body, opt):
+ opt.error("The convertion to an older format (%s) is not implemented." % opt.format)
+
+
+if __name__ == "__main__":
+ pass
+
--- /dev/null
+# This file is part of lyx2lyx
+# -*- coding: iso-8859-1 -*-
+# Copyright (C) 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.
+
+def convert(header, body, opt):
+ opt.format = 215
+
+
+def revert(header, body, opt):
+ opt.error("The convertion to an older format (%s) is not implemented." % opt.format)
+
+
+if __name__ == "__main__":
+ pass
+
--- /dev/null
+# This file is part of lyx2lyx
+# -*- coding: iso-8859-1 -*-
+# Copyright (C) 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.
+
+def convert(header, body, opt):
+ opt.format = 215
+
+
+def revert(header, body, opt):
+ opt.error("The convertion to an older format (%s) is not implemented." % opt.format)
+
+
+if __name__ == "__main__":
+ pass
+
--- /dev/null
+# 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.
+
+import re
+import string
+from parser_tools import find_token, find_token_backwards, find_re
+
+
+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, opt):
+ 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)
+ opt.format = 216
+
+
+def revert(header, body, opt):
+ opt.error("The convertion to an older format (%s) is not implemented." % opt.format)
+
+if __name__ == "__main__":
+ pass
--- /dev/null
+# 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.
+
+import re
+import string
+from parser_tools import find_re, find_tokens, find_token, check_token
+
+
+lyxtable_re = re.compile(r".*\\LyXTable$")
+def update_tabular(lines, opt):
+ 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:
+ opt.error("Malformed LyX file.")
+
+ 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, opt):
+ update_tabular(body, opt)
+ update_language(header)
+ opt.format = 217
+
+
+def revert(header, body, opt):
+ opt.error("The convertion to an older format (%s) is not implemented." % opt.format)
+
+
+if __name__ == "__main__":
+ pass
--- /dev/null
+# 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.
+
+import re
+import string
+from parser_tools import find_token
+
+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, opt):
+ 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:
+ opt.warning( "Error: Bad lyx format i=%d j=%d" % (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, opt):
+ update_tabular(body, opt)
+ opt.format = 218
+
+
+def revert(header, body, opt):
+ opt.error("The convertion to an older format (%s) is not implemented." % opt.format)
+
+
+if __name__ == "__main__":
+ pass
--- /dev/null
+# This file is part of lyx2lyx
+# -*- coding: iso-8859-1 -*-
+# Copyright (C) 2002 Dekel Tsur <dekel@lyx.org>
+# Copyright (C) 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.
+
+import string
+import re
+
+from parser_tools import find_token, find_token_backwards, get_next_paragraph,\
+ find_tokens, find_end_of_inset, find_re, \
+ is_nonempty_line, get_paragraph, find_nonempty_line, \
+ get_value, get_tabular_lines, check_token
+
+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, opt):
+ 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):
+ opt.warning("Error! Unknown float type " + floattype)
+ 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+" "+ opt.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, opt):
+ change_preamble(header)
+ change_listof(body)
+ fix_oldfloatinset(body)
+ update_tabular(body)
+ remove_pextra(body)
+ remove_oldfloat(body, opt)
+ remove_figinset(body)
+ remove_oldertinset(body)
+ remove_oldert(body)
+ combine_ert(body)
+ change_infoinset(body)
+ opt.format = 220
+
+
+def revert(header, body, opt):
+ opt.error("The convertion to an older format (%s) is not implemented." % opt.format)
+
+
+if __name__ == "__main__":
+ pass
--- /dev/null
+# This file is part of lyx2lyx
+# -*- coding: iso-8859-1 -*-
+# Copyright (C) 2002 Dekel Tsur <dekel@lyx.org>
+# Copyright (C) 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.
+
+import string
+import re
+from parser_tools import find_token, find_end_of_inset, get_value,\
+ find_token2, del_token
+
+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, opt):
+ change_insetgraphics(body)
+ change_tabular(body)
+ opt.format = 221
+
+
+def revert(header, body, opt):
+ opt.error("The convertion to an older format (%s) is not implemented." % opt.format)
+
+
+if __name__ == "__main__":
+ pass
--- /dev/null
+# This file is part of lyx2lyx
+# -*- coding: iso-8859-1 -*-
+# Copyright (C) 2002 Dekel Tsur <dekel@lyx.org>
+# 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.
+
+import re
+from parser_tools import find_token, find_end_of_inset, get_next_paragraph, \
+ get_paragraph, get_value, del_token, is_nonempty_line,\
+ find_tokens, find_end_of
+from string import replace, split, find, strip, join
+
+##
+# Add \end_header
+#
+def add_end_header(header):
+ header.append("\\end_header");
+
+
+def rm_end_header(lines):
+ i = find_token(lines, "\\end_header", 0)
+ if i == -1:
+ return
+ del lines[i]
+
+
+##
+# \SpecialChar ~ -> \InsetSpace ~
+#
+def convert_spaces(lines):
+ for i in range(len(lines)):
+ lines[i] = replace(lines[i],"\\SpecialChar ~","\\InsetSpace ~")
+
+
+def revert_spaces(lines):
+ for i in range(len(lines)):
+ lines[i] = replace(lines[i],"\\InsetSpace ~", "\\SpecialChar ~")
+
+
+##
+# BibTeX changes
+#
+def convert_bibtex(lines):
+ for i in range(len(lines)):
+ lines[i] = replace(lines[i],"\\begin_inset LatexCommand \\BibTeX",
+ "\\begin_inset LatexCommand \\bibtex")
+
+
+def revert_bibtex(lines):
+ for i in range(len(lines)):
+ lines[i] = replace(lines[i], "\\begin_inset LatexCommand \\bibtex",
+ "\\begin_inset LatexCommand \\BibTeX")
+
+
+##
+# Remove \lyxparent
+#
+def remove_insetparent(lines):
+ i = 0
+ while 1:
+ i = find_token(lines, "\\begin_inset LatexCommand \\lyxparent", i)
+ if i == -1:
+ break
+ del lines[i:i+3]
+
+
+##
+# Inset External
+#
+def convert_external(lines):
+ external_rexp = re.compile(r'\\begin_inset External ([^,]*),"([^"]*)",')
+ external_header = "\\begin_inset External"
+ i = 0
+ while 1:
+ i = find_token(lines, external_header, i)
+ if i == -1:
+ break
+ look = external_rexp.search(lines[i])
+ args = ['','']
+ if look:
+ args[0] = look.group(1)
+ args[1] = look.group(2)
+ #FIXME: if the previous search fails then warn
+
+ if args[0] == "RasterImage":
+ # Convert a RasterImage External Inset to a Graphics Inset.
+ top = "\\begin_inset Graphics"
+ if args[1]:
+ filename = "\tfilename " + args[1]
+ lines[i:i+1] = [top, filename]
+ i = i + 1
+ else:
+ # Convert the old External Inset format to the new.
+ top = external_header
+ template = "\ttemplate " + args[0]
+ if args[1]:
+ filename = "\tfilename " + args[1]
+ lines[i:i+1] = [top, template, filename]
+ i = i + 2
+ else:
+ lines[i:i+1] = [top, template]
+ i = i + 1
+
+
+def revert_external_1(lines):
+ external_header = "\\begin_inset External"
+ i = 0
+ while 1:
+ i = find_token(lines, external_header, i)
+ if i == -1:
+ break
+
+ template = split(lines[i+1])
+ template.reverse()
+ del lines[i+1]
+
+ filename = split(lines[i+1])
+ filename.reverse()
+ del lines[i+1]
+
+ params = split(lines[i+1])
+ params.reverse()
+ if lines[i+1]: del lines[i+1]
+
+ lines[i] = lines[i] + " " + template[0]+ ', "' + filename[0] + '", " '+ join(params[1:]) + '"'
+ i = i + 1
+
+
+def revert_external_2(lines):
+ draft_token = '\tdraft'
+ i = 0
+ while 1:
+ i = find_token(lines, '\\begin_inset External', i)
+ if i == -1:
+ break
+ j = find_end_of_inset(lines, i + 1)
+ if j == -1:
+ #this should not happen
+ break
+ k = find_token(lines, draft_token, i+1, j-1)
+ if (k != -1 and len(draft_token) == len(lines[k])):
+ del lines[k]
+ i = j + 1
+
+
+##
+# Comment
+#
+def convert_comment(lines):
+ i = 0
+ comment = "\\layout Comment"
+ while 1:
+ i = find_token(lines, comment, i)
+ if i == -1:
+ return
+
+ lines[i:i+1] = ["\\layout Standard","","",
+ "\\begin_inset Comment",
+ "collapsed true","",
+ "\\layout Standard"]
+ i = i + 7
+
+ while 1:
+ old_i = i
+ i = find_token(lines, "\\layout", i)
+ if i == -1:
+ i = len(lines) - 1
+ lines[i:i] = ["\\end_inset ","",""]
+ return
+
+ j = find_token(lines, '\\begin_deeper', old_i, i)
+ if j == -1: j = i + 1
+ k = find_token(lines, '\\begin_inset', old_i, i)
+ if k == -1: k = i + 1
+
+ if j < i and j < k:
+ i = j
+ del lines[i]
+ i = find_end_of( lines, i, "\\begin_deeper","\\end_deeper")
+ if i == -1:
+ #This case should not happen
+ #but if this happens deal with it greacefully adding
+ #the missing \end_deeper.
+ i = len(lines) - 1
+ lines[i:i] = ["\end_deeper","","","\\end_inset ","",""]
+ return
+ else:
+ del lines[i]
+ continue
+
+ if k < i:
+ i = k
+ i = find_end_of( lines, i, "\\begin_inset","\\end_inset")
+ if i == -1:
+ #This case should not happen
+ #but if this happens deal with it greacefully adding
+ #the missing \end_inset.
+ i = len(lines) - 1
+ lines[i:i] = ["\\end_inset ","","","\\end_inset ","",""]
+ return
+ else:
+ i = i + 1
+ continue
+
+ if find(lines[i], comment) == -1:
+ lines[i:i] = ["\\end_inset"]
+ i = i + 1
+ break
+ lines[i:i+1] = ["\\layout Standard"]
+ i = i + 1
+
+
+def revert_comment(lines):
+ i = 0
+ while 1:
+ i = find_tokens(lines, ["\\begin_inset Comment", "\\begin_inset Greyedout"], i)
+
+ if i == -1:
+ return
+ lines[i] = "\\begin_inset Note"
+ i = i + 1
+
+
+##
+# Add \end_layout
+#
+def add_end_layout(lines):
+ i = find_token(lines, '\\layout', 0)
+
+ if i == -1:
+ return
+
+ i = i + 1
+ struct_stack = ["\\layout"]
+ while 1:
+ i = find_tokens(lines, ["\\begin_inset", "\\end_inset", "\\layout",
+ "\\begin_deeper", "\\end_deeper", "\\the_end"], i)
+
+ token = split(lines[i])[0]
+
+ if token == "\\begin_inset":
+ struct_stack.append(token)
+ i = i + 1
+ continue
+
+ if token == "\\end_inset":
+ tail = struct_stack.pop()
+ if tail == "\\layout":
+ lines.insert(i,"\\end_layout")
+ i = i + 1
+ #Check if it is the correct tag
+ struct_stack.pop()
+ i = i + 1
+ continue
+
+ if token == "\\layout":
+ tail = struct_stack.pop()
+ if tail == token:
+ lines.insert(i,"\\end_layout")
+ i = i + 2
+ else:
+ struct_stack.append(tail)
+ i = i + 1
+ struct_stack.append(token)
+ continue
+
+ if token == "\\begin_deeper" or token == "\\end_deeper":
+ lines.insert(i,"\\end_layout")
+ i = i + 2
+ continue
+
+ #case \end_document
+ lines.insert(i, "\\end_layout")
+ return
+
+
+def rm_end_layout(lines):
+ i = 0
+ while 1:
+ i = find_token(lines, '\\end_layout', i)
+
+ if i == -1:
+ return
+
+ del lines[i]
+
+
+##
+# Remove change tracking keywords
+#
+def rm_tracking_changes(lines):
+ i = find_token(lines, "\\author", 0)
+ if i != -1:
+ del lines[i]
+
+ i = find_token(lines, "\\tracking_changes", 0)
+ if i == -1:
+ return
+ del lines[i]
+
+
+def rm_body_changes(lines):
+ i = 0
+ while 1:
+ i = find_token(lines, "\\change_", i)
+ if i == -1:
+ return
+
+ del lines[i]
+
+
+##
+# \layout -> \begin_layout
+#
+def layout2begin_layout(lines):
+ i = 0
+ while 1:
+ i = find_token(lines, '\\layout', i)
+ if i == -1:
+ return
+
+ lines[i] = replace(lines[i], '\\layout', '\\begin_layout')
+ i = i + 1
+
+
+def begin_layout2layout(lines):
+ i = 0
+ while 1:
+ i = find_token(lines, '\\begin_layout', i)
+ if i == -1:
+ return
+
+ lines[i] = replace(lines[i], '\\begin_layout', '\\layout')
+ i = i + 1
+
+
+##
+# valignment="center" -> valignment="middle"
+#
+def convert_valignment_middle(lines, start, end):
+ for i in range(start, end):
+ if re.search('^<(column|cell) .*valignment="center".*>$', lines[i]):
+ lines[i] = replace(lines[i], 'valignment="center"', 'valignment="middle"')
+
+
+def convert_table_valignment_middle(lines):
+ i = 0
+ while 1:
+ i = find_token(lines, '\\begin_inset Tabular', i)
+ if i == -1:
+ return
+ j = find_end_of_inset(lines, i + 1)
+ if j == -1:
+ #this should not happen
+ convert_valignment_middle(lines, i + 1, len(lines))
+ return
+ convert_valignment_middle(lines, i + 1, j)
+ i = j + 1
+
+
+def revert_table_valignment_middle(lines, start, end):
+ for i in range(start, end):
+ if re.search('^<(column|cell) .*valignment="middle".*>$', lines[i]):
+ lines[i] = replace(lines[i], 'valignment="middle"', 'valignment="center"')
+
+
+def revert_valignment_middle(lines):
+ i = 0
+ while 1:
+ i = find_token(lines, '\\begin_inset Tabular', i)
+ if i == -1:
+ return
+ j = find_end_of_inset(lines, i + 1)
+ if j == -1:
+ #this should not happen
+ revert_table_valignment_middle(lines, i + 1, len(lines))
+ return
+ revert_table_valignment_middle(lines, i + 1, j)
+ i = j + 1
+
+
+##
+# \the_end -> \end_document
+#
+def convert_end_document(lines):
+ i = find_token(lines, "\\the_end", 0)
+ if i == -1:
+ lines.append("\\end_document")
+ return
+ lines[i] = "\\end_document"
+
+
+def revert_end_document(lines):
+ i = find_token(lines, "\\end_document", 0)
+ if i == -1:
+ lines.append("\\the_end")
+ return
+ lines[i] = "\\the_end"
+
+
+##
+# Convert line and page breaks
+# Old:
+#\layout Standard
+#\line_top \line_bottom \pagebreak_top \pagebreak_bottom \added_space_top xxx \added_space_bottom yyy
+#0
+#
+# New:
+#\begin layout Standard
+#
+#\newpage
+#
+#\lyxline
+#\begin_inset VSpace xxx
+#\end_inset
+#
+#\end_layout
+#\begin_layout Standard
+#
+#0
+#\end_layout
+#\begin_layout Standard
+#
+#\begin_inset VSpace xxx
+#\end_inset
+#\lyxline
+#
+#\newpage
+#
+#\end_layout
+def convert_breaks(lines):
+ i = 0
+ while 1:
+ i = find_token(lines, "\\begin_layout", i)
+ if i == -1:
+ return
+ i = i + 1
+ line_top = find(lines[i],"\\line_top")
+ line_bot = find(lines[i],"\\line_bottom")
+ pb_top = find(lines[i],"\\pagebreak_top")
+ pb_bot = find(lines[i],"\\pagebreak_bottom")
+ vspace_top = find(lines[i],"\\added_space_top")
+ vspace_bot = find(lines[i],"\\added_space_bottom")
+
+ if line_top == -1 and line_bot == -1 and pb_bot == -1 and pb_top == -1 and vspace_top == -1 and vspace_bot == -1:
+ continue
+
+ for tag in "\\line_top", "\\line_bottom", "\\pagebreak_top", "\\pagebreak_bottom":
+ lines[i] = replace(lines[i], tag, "")
+
+ if vspace_top != -1:
+ # the position could be change because of the removal of other
+ # paragraph properties above
+ vspace_top = find(lines[i],"\\added_space_top")
+ tmp_list = split(lines[i][vspace_top:])
+ vspace_top_value = tmp_list[1]
+ lines[i] = lines[i][:vspace_top] + join(tmp_list[2:])
+
+ if vspace_bot != -1:
+ # the position could be change because of the removal of other
+ # paragraph properties above
+ vspace_bot = find(lines[i],"\\added_space_bottom")
+ tmp_list = split(lines[i][vspace_bot:])
+ vspace_bot_value = tmp_list[1]
+ lines[i] = lines[i][:vspace_bot] + join(tmp_list[2:])
+
+ lines[i] = strip(lines[i])
+ i = i + 1
+
+ # Create an empty paragraph for line and page break that belong
+ # above the paragraph
+ if pb_top !=-1 or line_top != -1 or vspace_bot != -1:
+
+ paragraph_above = ['','\\begin_layout Standard','','']
+
+ if pb_top != -1:
+ paragraph_above.extend(['\\newpage ',''])
+
+ if vspace_top != -1:
+ paragraph_above.extend(['\\begin_inset VSpace ' + vspace_top_value,'\\end_inset ','',''])
+
+ if line_top != -1:
+ paragraph_above.extend(['\\lyxline ',''])
+
+ paragraph_above.extend(['\\end_layout',''])
+
+ #inset new paragraph above the current paragraph
+ lines[i-2:i-2] = paragraph_above
+ i = i + len(paragraph_above)
+
+ # Ensure that nested style are converted later.
+ k = find_end_of(lines, i, "\\begin_layout", "\\end_layout")
+
+ if k == -1:
+ return
+
+ if pb_top !=-1 or line_top != -1 or vspace_bot != -1:
+
+ paragraph_bellow = ['','\\begin_layout Standard','','']
+
+ if line_bot != -1:
+ paragraph_bellow.extend(['\\lyxline ',''])
+
+ if vspace_bot != -1:
+ paragraph_bellow.extend(['\\begin_inset VSpace ' + vspace_bot_value,'\\end_inset ','',''])
+
+ if pb_bot != -1:
+ paragraph_bellow.extend(['\\newpage ',''])
+
+ paragraph_bellow.extend(['\\end_layout',''])
+
+ #inset new paragraph above the current paragraph
+ lines[k + 1: k + 1] = paragraph_bellow
+
+
+##
+# Notes
+#
+def convert_note(lines):
+ i = 0
+ while 1:
+ i = find_tokens(lines, ["\\begin_inset Note",
+ "\\begin_inset Comment",
+ "\\begin_inset Greyedout"], i)
+ if i == -1:
+ break
+
+ lines[i] = lines[i][0:13] + 'Note ' + lines[i][13:]
+ i = i + 1
+
+
+def revert_note(lines):
+ note_header = "\\begin_inset Note "
+ i = 0
+ while 1:
+ i = find_token(lines, note_header, i)
+ if i == -1:
+ break
+
+ lines[i] = "\\begin_inset " + lines[i][len(note_header):]
+ i = i + 1
+
+
+##
+# Box
+#
+def convert_box(lines):
+ i = 0
+ while 1:
+ i = find_tokens(lines, ["\\begin_inset Boxed",
+ "\\begin_inset Doublebox",
+ "\\begin_inset Frameless",
+ "\\begin_inset ovalbox",
+ "\\begin_inset Ovalbox",
+ "\\begin_inset Shadowbox"], i)
+ if i == -1:
+ break
+
+ lines[i] = lines[i][0:13] + 'Box ' + lines[i][13:]
+ i = i + 1
+
+
+def revert_box(lines):
+ box_header = "\\begin_inset Box "
+ i = 0
+ while 1:
+ i = find_token(lines, box_header, i)
+ if i == -1:
+ break
+
+ lines[i] = "\\begin_inset " + lines[i][len(box_header):]
+ i = i + 1
+
+
+##
+# Collapse
+#
+def convert_collapsable(lines, opt):
+ i = 0
+ while 1:
+ i = find_tokens(lines, ["\\begin_inset Box",
+ "\\begin_inset Branch",
+ "\\begin_inset CharStyle",
+ "\\begin_inset Float",
+ "\\begin_inset Foot",
+ "\\begin_inset Marginal",
+ "\\begin_inset Note",
+ "\\begin_inset OptArg",
+ "\\begin_inset Wrap"], i)
+ if i == -1:
+ break
+
+ # Seach for a line starting 'collapsed'
+ # If, however, we find a line starting '\begin_layout'
+ # (_always_ present) then break with a warning message
+ i = i + 1
+ while 1:
+ if (lines[i] == "collapsed false"):
+ lines[i] = "status open"
+ break
+ elif (lines[i] == "collapsed true"):
+ lines[i] = "status collapsed"
+ break
+ elif (lines[i][:13] == "\\begin_layout"):
+ opt.warning("Malformed LyX file.")
+ break
+ i = i + 1
+
+ i = i + 1
+
+
+def revert_collapsable(lines, opt):
+ i = 0
+ while 1:
+ i = find_tokens(lines, ["\\begin_inset Box",
+ "\\begin_inset Branch",
+ "\\begin_inset CharStyle",
+ "\\begin_inset Float",
+ "\\begin_inset Foot",
+ "\\begin_inset Marginal",
+ "\\begin_inset Note",
+ "\\begin_inset OptArg",
+ "\\begin_inset Wrap"], i)
+ if i == -1:
+ break
+
+ # Seach for a line starting 'status'
+ # If, however, we find a line starting '\begin_layout'
+ # (_always_ present) then break with a warning message
+ i = i + 1
+ while 1:
+ if (lines[i] == "status open"):
+ lines[i] = "collapsed false"
+ break
+ elif (lines[i] == "status collapsed" or
+ lines[i] == "status inlined"):
+ lines[i] = "collapsed true"
+ break
+ elif (lines[i][:13] == "\\begin_layout"):
+ opt.warning("Malformed LyX file.")
+ break
+ i = i + 1
+
+ i = i + 1
+
+
+##
+# ERT
+#
+def convert_ert(lines, opt):
+ i = 0
+ while 1:
+ i = find_token(lines, "\\begin_inset ERT", i)
+ if i == -1:
+ break
+
+ # Seach for a line starting 'status'
+ # If, however, we find a line starting '\begin_layout'
+ # (_always_ present) then break with a warning message
+ i = i + 1
+ while 1:
+ if (lines[i] == "status Open"):
+ lines[i] = "status open"
+ break
+ elif (lines[i] == "status Collapsed"):
+ lines[i] = "status collapsed"
+ break
+ elif (lines[i] == "status Inlined"):
+ lines[i] = "status inlined"
+ break
+ elif (lines[i][:13] == "\\begin_layout"):
+ opt.warning("Malformed LyX file.")
+ break
+ i = i + 1
+
+ i = i + 1
+
+
+def revert_ert(lines, opt):
+ i = 0
+ while 1:
+ i = find_token(lines, "\\begin_inset ERT", i)
+ if i == -1:
+ break
+
+ # Seach for a line starting 'status'
+ # If, however, we find a line starting '\begin_layout'
+ # (_always_ present) then break with a warning message
+ i = i + 1
+ while 1:
+ if (lines[i] == "status open"):
+ lines[i] = "status Open"
+ break
+ elif (lines[i] == "status collapsed"):
+ lines[i] = "status Collapsed"
+ break
+ elif (lines[i] == "status inlined"):
+ lines[i] = "status Inlined"
+ break
+ elif (lines[i][:13] == "\\begin_layout"):
+ opt.warning("Malformed LyX file.")
+ break
+ i = i + 1
+
+ i = i + 1
+
+
+##
+# Minipages
+#
+def convert_minipage(lines):
+ """ Convert minipages to the box inset.
+ We try to use the same order of arguments as lyx does.
+ """
+ pos = ["t","c","b"]
+ inner_pos = ["c","t","b","s"]
+
+ i = 0
+ while 1:
+ i = find_token(lines, "\\begin_inset Minipage", i)
+ if i == -1:
+ return
+
+ lines[i] = "\\begin_inset Box Frameless"
+ i = i + 1
+
+ # convert old to new position using the pos list
+ if lines[i][:8] == "position":
+ lines[i] = 'position "%s"' % pos[int(lines[i][9])]
+ else:
+ lines.insert(i, 'position "%s"' % pos[0])
+ i = i + 1
+
+ lines.insert(i, 'hor_pos "c"')
+ i = i + 1
+ lines.insert(i, 'has_inner_box 1')
+ i = i + 1
+
+ # convert the inner_position
+ if lines[i][:14] == "inner_position":
+ lines[i] = 'inner_pos "%s"' % inner_pos[int(lines[i][15])]
+ else:
+ lines.insert('inner_pos "%s"' % inner_pos[0])
+ i = i + 1
+
+ # We need this since the new file format has a height and width
+ # in a different order.
+ if lines[i][:6] == "height":
+ height = lines[i][6:]
+ # test for default value of 221 and convert it accordingly
+ if height == ' "0pt"':
+ height = ' "1pt"'
+ del lines[i]
+ else:
+ height = ' "1pt"'
+
+ if lines[i][:5] == "width":
+ width = lines[i][5:]
+ del lines[i]
+ else:
+ width = ' "0"'
+
+ if lines[i][:9] == "collapsed":
+ if lines[i][9:] == "true":
+ status = "collapsed"
+ else:
+ status = "open"
+ del lines[i]
+ else:
+ status = "collapsed"
+
+ lines.insert(i, 'use_parbox 0')
+ i = i + 1
+ lines.insert(i, 'width' + width)
+ i = i + 1
+ lines.insert(i, 'special "none"')
+ i = i + 1
+ lines.insert(i, 'height' + height)
+ i = i + 1
+ lines.insert(i, 'height_special "totalheight"')
+ i = i + 1
+ lines.insert(i, 'status ' + status)
+ i = i + 1
+
+
+# -------------------------------------------------------------------------------------------
+# Convert backslashes into valid ERT code, append the converted text to
+# lines[i] and return the (maybe incremented) line index i
+def convert_ertbackslash(lines, i, ert):
+ for c in ert:
+ if c == '\\':
+ lines[i] = lines[i] + '\\backslash '
+ lines.insert(i, '')
+ i = i + 1
+ else:
+ lines[i] = lines[i] + c
+ return i
+
+
+def convert_vspace(header, lines, opt):
+
+ # Get default spaceamount
+ i = find_token(header, '\\defskip', 0)
+ if i == -1:
+ defskipamount = 'medskip'
+ else:
+ defskipamount = split(header[i])[1]
+
+ # Convert the insets
+ i = 0
+ while 1:
+ i = find_token(lines, '\\begin_inset VSpace', i)
+ if i == -1:
+ return
+ spaceamount = split(lines[i])[2]
+
+ # Are we at the beginning or end of a paragraph?
+ paragraph_start = 1
+ start = get_paragraph(lines, i) + 1
+ for k in range(start, i):
+ if is_nonempty_line(lines[k]):
+ paragraph_start = 0
+ break
+ paragraph_end = 1
+ j = find_end_of_inset(lines, i)
+ if j == -1:
+ opt.warning("Malformed LyX file: Missing '\\end_inset'.")
+ i = i + 1
+ continue
+ end = get_next_paragraph(lines, i)
+ for k in range(j + 1, end):
+ if is_nonempty_line(lines[k]):
+ paragraph_end = 0
+ break
+
+ # Convert to paragraph formatting if we are at the beginning or end
+ # of a paragraph and the resulting paragraph would not be empty
+ if ((paragraph_start and not paragraph_end) or
+ (paragraph_end and not paragraph_start)):
+ # The order is important: del and insert invalidate some indices
+ del lines[j]
+ del lines[i]
+ if paragraph_start:
+ lines.insert(start, '\\added_space_top ' + spaceamount + ' ')
+ else:
+ lines.insert(start, '\\added_space_bottom ' + spaceamount + ' ')
+ continue
+
+ # Convert to ERT
+ lines[i:i+1] = ['\\begin_inset ERT', 'status Collapsed', '',
+ '\\layout Standard', '', '\\backslash ']
+ i = i + 6
+ if spaceamount[-1] == '*':
+ spaceamount = spaceamount[:-1]
+ keep = 1
+ else:
+ keep = 0
+
+ # Replace defskip by the actual value
+ if spaceamount == 'defskip':
+ spaceamount = defskipamount
+
+ # LaTeX does not know \\smallskip* etc
+ if keep:
+ if spaceamount == 'smallskip':
+ spaceamount = '\\smallskipamount'
+ elif spaceamount == 'medskip':
+ spaceamount = '\\medskipamount'
+ elif spaceamount == 'bigskip':
+ spaceamount = '\\bigskipamount'
+ elif spaceamount == 'vfill':
+ spaceamount = '\\fill'
+
+ # Finally output the LaTeX code
+ if (spaceamount == 'smallskip' or spaceamount == 'medskip' or
+ spaceamount == 'bigskip' or spaceamount == 'vfill'):
+ lines.insert(i, spaceamount)
+ else :
+ if keep:
+ lines.insert(i, 'vspace*{')
+ else:
+ lines.insert(i, 'vspace{')
+ i = convert_ertbackslash(lines, i, spaceamount)
+ lines[i] = lines[i] + '}'
+ i = i + 1
+
+
+# Convert a LyX length into valid ERT code and append it to lines[i]
+# Return the (maybe incremented) line index i
+def convert_ertlen(lines, i, len, special):
+ units = {"text%":"\\textwidth", "col%":"\\columnwidth",
+ "page%":"\\pagewidth", "line%":"\\linewidth",
+ "theight%":"\\textheight", "pheight%":"\\pageheight"}
+
+ # Convert special lengths
+ if special != 'none':
+ len = '%f\\' % len2value(len) + special
+
+ # Convert LyX units to LaTeX units
+ for unit in units.keys():
+ if find(len, unit) != -1:
+ len = '%f' % (len2value(len) / 100) + units[unit]
+ break
+
+ # Convert backslashes and insert the converted length into lines
+ return convert_ertbackslash(lines, i, len)
+
+
+# Return the value of len without the unit in numerical form
+def len2value(len):
+ result = re.search('([+-]?[0-9.]+)', len)
+ if result:
+ return float(result.group(1))
+ # No number means 1.0
+ return 1.0
+
+
+def convert_frameless_box(lines, opt):
+ pos = ['t', 'c', 'b']
+ inner_pos = ['c', 't', 'b', 's']
+ i = 0
+ while 1:
+ i = find_token(lines, '\\begin_inset Frameless', i)
+ if i == -1:
+ return
+ j = find_end_of_inset(lines, i)
+ if j == -1:
+ opt.warning("Malformed LyX file: Missing '\\end_inset'\n")
+ i = i + 1
+ continue
+ del lines[i]
+
+ # Gather parameters
+ params = {'position':'0', 'hor_pos':'c', 'has_inner_box':'1',
+ 'inner_pos':'1', 'use_parbox':'0', 'width':'100col%',
+ 'special':'none', 'height':'1in',
+ 'height_special':'totalheight', 'collapsed':'false'}
+ for key in params.keys():
+ value = replace(get_value(lines, key, i, j), '"', '')
+ if value != "":
+ if key == 'position':
+ # convert new to old position: 'position "t"' -> 0
+ value = find_token(pos, value, 0)
+ if value != -1:
+ params[key] = value
+ elif key == 'inner_pos':
+ # convert inner position
+ value = find_token(inner_pos, value, 0)
+ if value != -1:
+ params[key] = value
+ else:
+ params[key] = value
+ j = del_token(lines, key, i, j)
+ i = i + 1
+
+ # Convert to minipage or ERT?
+ # Note that the inner_position and height parameters of a minipage
+ # inset are ignored and not accessible for the user, although they
+ # are present in the file format and correctly read in and written.
+ # Therefore we convert to ERT if they do not have their LaTeX
+ # defaults. These are:
+ # - the value of "position" for "inner_pos"
+ # - "\totalheight" for "height"
+ if (params['use_parbox'] != '0' or
+ params['has_inner_box'] != '1' or
+ params['special'] != 'none' or
+ inner_pos[params['inner_pos']] != pos[params['position']] or
+ params['height_special'] != 'totalheight' or
+ len2value(params['height']) != 1.0):
+
+ # Convert to ERT
+ if params['collapsed'] == 'true':
+ params['collapsed'] = 'Collapsed'
+ else:
+ params['collapsed'] = 'Open'
+ lines[i : i] = ['\\begin_inset ERT', 'status ' + params['collapsed'],
+ '', '\\layout Standard', '', '\\backslash ']
+ i = i + 6
+ if params['use_parbox'] == '1':
+ lines.insert(i, 'parbox')
+ else:
+ lines.insert(i, 'begin{minipage}')
+ lines[i] = lines[i] + '[' + pos[params['position']] + ']['
+ i = convert_ertlen(lines, i, params['height'], params['height_special'])
+ lines[i] = lines[i] + '][' + inner_pos[params['inner_pos']] + ']{'
+ i = convert_ertlen(lines, i, params['width'], params['special'])
+ if params['use_parbox'] == '1':
+ lines[i] = lines[i] + '}{'
+ else:
+ lines[i] = lines[i] + '}'
+ i = i + 1
+ lines[i:i] = ['', '\\end_inset ']
+ i = i + 2
+ j = find_end_of_inset(lines, i)
+ if j == -1:
+ opt.warning("Malformed LyX file: Missing '\\end_inset'.")
+ break
+ lines[j-1:j-1] += ['\\begin_inset ERT', 'status ' + params['collapsed'],
+ '', '\\layout Standard', '']
+ j = j + 4
+ if params['use_parbox'] == '1':
+ lines.insert(j, '}')
+ else:
+ lines[j:j] = ['\\backslash ', 'end{minipage}']
+ else:
+
+ # Convert to minipage
+ lines[i:i] = ['\\begin_inset Minipage',
+ 'position %d' % params['position'],
+ 'inner_position %d' % params['inner_pos'],
+ 'height "' + params['height'] + '"',
+ 'width "' + params['width'] + '"',
+ 'collapsed ' + params['collapsed']]
+ i = i + 6
+
+##
+# Convert jurabib
+#
+
+def convert_jurabib(header, opt):
+ i = find_token(header, '\\use_numerical_citations', 0)
+ if i == -1:
+ opt.warning("Malformed lyx file: Missing '\\use_numerical_citations'")
+ return
+ header.insert(i + 1, '\\use_jurabib 0')
+
+
+def revert_jurabib(header, opt):
+ i = find_token(header, '\\use_jurabib', 0)
+ if i == -1:
+ opt.warning("Malformed lyx file: Missing '\\use_jurabib'")
+ return
+ if get_value(header, '\\use_jurabib', 0) != "0":
+ opt.warning("Conversion of '\\use_jurabib = 1' not yet implemented.")
+ # Don't remove '\\use_jurabib' so that people will get warnings by lyx
+ return
+ del header[i]
+
+##
+# Convert bibtopic
+#
+
+def convert_bibtopic(header, opt):
+ i = find_token(header, '\\use_jurabib', 0)
+ if i == -1:
+ opt.warning("Malformed lyx file: Missing '\\use_jurabib'")
+ return
+ header.insert(i + 1, '\\use_bibtopic 0')
+
+
+def revert_bibtopic(header, opt):
+ i = find_token(header, '\\use_bibtopic', 0)
+ if i == -1:
+ opt.warning("Malformed lyx file: Missing '\\use_bibtopic'")
+ return
+ if get_value(header, '\\use_bibtopic', 0) != "0":
+ opt.warning("Conversion of '\\use_bibtopic = 1' not yet implemented.")
+ # Don't remove '\\use_jurabib' so that people will get warnings by lyx
+ del header[i]
+
+##
+# Sideway Floats
+#
+
+def convert_float(lines, opt):
+ i = 0
+ while 1:
+ i = find_token(lines, '\\begin_inset Float', i)
+ if i == -1:
+ return
+ # Seach for a line starting 'wide'
+ # If, however, we find a line starting '\begin_layout'
+ # (_always_ present) then break with a warning message
+ i = i + 1
+ while 1:
+ if (lines[i][:4] == "wide"):
+ lines.insert(i + 1, 'sideways false')
+ break
+ elif (lines[i][:13] == "\\begin_layout"):
+ opt.warning("Malformed lyx file")
+ break
+ i = i + 1
+ i = i + 1
+
+
+def revert_float(lines, opt):
+ i = 0
+ while 1:
+ i = find_token(lines, '\\begin_inset Float', i)
+ if i == -1:
+ return
+ j = find_end_of_inset(lines, i)
+ if j == -1:
+ opt.warning("Malformed lyx file: Missing '\\end_inset'")
+ i = i + 1
+ continue
+ if get_value(lines, 'sideways', i, j) != "false":
+ opt.warning("Conversion of 'sideways true' not yet implemented.")
+ # Don't remove 'sideways' so that people will get warnings by lyx
+ i = i + 1
+ continue
+ del_token(lines, 'sideways', i, j)
+ i = i + 1
+
+##
+# Convertion hub
+#
+
+def convert(header, body, opt):
+ if opt.format < 223:
+ add_end_header(header)
+ convert_spaces(body)
+ convert_bibtex(body)
+ remove_insetparent(body)
+ opt.format = 223
+ if opt.end == opt.format: return
+
+ if opt.format < 224:
+ convert_external(body)
+ convert_comment(body)
+ opt.format = 224
+ if opt.end == opt.format: return
+
+ if opt.format < 225:
+ add_end_layout(body)
+ layout2begin_layout(body)
+ convert_end_document(body)
+ convert_table_valignment_middle(body)
+ convert_breaks(body)
+ opt.format = 225
+ if opt.end == opt.format: return
+
+ if opt.format < 226:
+ convert_note(body)
+ opt.format = 226
+ if opt.end == opt.format: return
+
+ if opt.format < 227:
+ convert_box(body)
+ opt.format = 227
+ if opt.end == opt.format: return
+
+ if opt.format < 228:
+ convert_collapsable(body, opt)
+ convert_ert(body, opt)
+ opt.format = 228
+ if opt.end == opt.format: return
+
+ if opt.format < 229:
+ convert_minipage(body)
+ opt.format = 229
+ if opt.end == opt.format: return
+
+ if opt.format < 230:
+ convert_jurabib(header, opt)
+ opt.format = 230
+ if opt.end == opt.format: return
+
+ if opt.format < 231:
+ convert_float(body, opt)
+ opt.format = 231
+ if opt.end == opt.format: return
+
+ if opt.format < 232:
+ convert_bibtopic(header, opt)
+ opt.format = 232
+
+def revert(header, body, opt):
+ if opt.format > 231:
+ revert_bibtopic(header, opt)
+ opt.format = 231
+ if opt.end == opt.format: return
+
+ if opt.format > 230:
+ revert_float(body, opt)
+ opt.format = 230
+ if opt.end == opt.format: return
+
+ if opt.format > 229:
+ revert_jurabib(header, opt)
+ opt.format = 229
+ if opt.end == opt.format: return
+
+ if opt.format > 228:
+ opt.format = 228
+ if opt.end == opt.format: return
+
+ if opt.format > 227:
+ revert_collapsable(body, opt)
+ revert_ert(body, opt)
+ opt.format = 227
+ if opt.end == opt.format: return
+
+ if opt.format > 226:
+ revert_box(body)
+ revert_external_2(body)
+ opt.format = 226
+ if opt.end == opt.format: return
+
+ if opt.format > 225:
+ revert_note(body)
+ opt.format = 225
+ if opt.end == opt.format: return
+
+ if opt.format > 224:
+ rm_end_layout(body)
+ begin_layout2layout(body)
+ revert_end_document(body)
+ revert_valignment_middle(body)
+ convert_vspace(header, body, opt)
+ convert_frameless_box(body, opt)
+ if opt.end == opt.format: return
+
+ if opt.format > 223:
+ revert_external_2(body)
+ revert_comment(body)
+ opt.format = 223
+ if opt.end == opt.format: return
+
+ if opt.format > 221:
+ rm_end_header(header)
+ revert_spaces(body)
+ revert_bibtex(body)
+ rm_tracking_changes(header)
+ rm_body_changes(body)
+ opt.format = 221
+
+
+if __name__ == "__main__":
+ pass
+++ /dev/null
-# 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
-
+++ /dev/null
-# 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
-
+++ /dev/null
-# 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
-
+++ /dev/null
-# 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
-
+++ /dev/null
-# 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
+++ /dev/null
-# 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
+++ /dev/null
-# 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 string
-from parser_tools import find_token
-
-def add_end(header):
- header.append("\\end_header");
-
-def convert_spaces(lines):
- for i in range(len(lines)):
- lines[i] = string.replace(lines[i],"\\SpecialChar ~","\\InsetSpace ~")
-
-def convert_bibtex(lines):
- for i in range(len(lines)):
- lines[i] = string.replace(lines[i],"\\begin_inset LatexCommand \\BibTeX",
- "\\begin_inset LatexCommand \\bibtex")
-
-def remove_insetparent(lines):
- i = 0
- while 1:
- i = find_token(lines, "\\begin_inset LatexCommand \\lyxparent", i)
- if i == -1:
- break
- del lines[i:i+3]
-
-def convert(header, body):
- add_end(header)
- convert_spaces(body)
- convert_bibtex(body)
- remove_insetparent(body)
-
-if __name__ == "__main__":
- pass
+++ /dev/null
-# 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 string
-import re
-from parser_tools import find_token, find_end_of
-
-def convert_external(lines):
- external_rexp = re.compile(r'\\begin_inset External ([^,]*),"([^"]*)",')
- external_header = "\\begin_inset External"
- i = 0
- while 1:
- i = find_token(lines, external_header, i)
- if i == -1:
- break
- look = external_rexp.search(lines[i])
- args = ['','']
- if look:
- args[0] = look.group(1)
- args[1] = look.group(2)
- #FIXME: if the previous search fails then warn
-
- if args[0] == "RasterImage":
- # Convert a RasterImage External Inset to a Graphics Inset.
- top = "\\begin_inset Graphics"
- if args[1]:
- filename = "\tfilename " + args[1]
- lines[i:i+1] = [top, filename]
- i = i + 1
- else:
- # Convert the old External Inset format to the new.
- top = external_header
- template = "\ttemplate " + args[0]
- if args[1]:
- filename = "\tfilename " + args[1]
- lines[i:i+1] = [top, template, filename]
- i = i + 2
- else:
- lines[i:i+1] = [top, template]
- i = i + 1
-
-
-def convert_comment(lines):
- i = 0
- comment = "\\layout Comment"
- while 1:
- i = find_token(lines, comment, i)
- if i == -1:
- return
-
- lines[i:i+1] = ["\\layout Standard","","",
- "\\begin_inset Comment",
- "collapsed true","",
- "\\layout Standard"]
- i = i + 7
-
- while 1:
- old_i = i
- i = find_token(lines, "\\layout", i)
- if i == -1:
- i = len(lines) - 1
- lines[i:i] = ["\\end_inset ","",""]
- return
-
- j = find_token(lines, '\\begin_deeper', old_i, i)
- if j == -1: j = i + 1
- k = find_token(lines, '\\begin_inset', old_i, i)
- if k == -1: k = i + 1
-
- if j < i and j < k:
- i = j
- del lines[i]
- i = find_end_of( lines, i, "\\begin_deeper","\\end_deeper")
- if i == -1:
- #This case should not happen
- #but if this happens deal with it greacefully adding
- #the missing \end_deeper.
- i = len(lines) - 1
- lines[i:i] = ["\end_deeper","","","\\end_inset ","",""]
- return
- else:
- del lines[i]
- continue
-
- if k < i:
- i = k
- i = find_end_of( lines, i, "\\begin_inset","\\end_inset")
- if i == -1:
- #This case should not happen
- #but if this happens deal with it greacefully adding
- #the missing \end_inset.
- i = len(lines) - 1
- lines[i:i] = ["\\end_inset ","","","\\end_inset ","",""]
- return
- else:
- i = i + 1
- continue
-
- if string.find(lines[i], comment) == -1:
- lines[i:i] = ["\\end_inset"]
- i = i + 1
- break
- lines[i:i+1] = ["\\layout Standard"]
- i = i + 1
-
-def convert(header, body):
- convert_external(body)
- convert_comment(body)
-
-if __name__ == "__main__":
- pass
+++ /dev/null
-# This file is part of lyx2lyx
-# -*- coding: iso-8859-1 -*-
-# Copyright (C) 2003 José Matos <jamatos@fep.up.pt>
-#
-# 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 find_token, find_tokens, find_end_of_inset, find_end_of
-from sys import stderr
-from string import replace, split, find, replace, strip, join
-
-def add_end_layout(lines):
- i = find_token(lines, '\\layout', 0)
-
- if i == -1:
- return
-
- i = i + 1
- struct_stack = ["\\layout"]
- while 1:
- i = find_tokens(lines, ["\\begin_inset", "\\end_inset", "\\layout",
- "\\begin_deeper", "\\end_deeper", "\\the_end"], i)
-
- token = split(lines[i])[0]
-
- if token == "\\begin_inset":
- struct_stack.append(token)
- i = i + 1
- continue
-
- if token == "\\end_inset":
- tail = struct_stack.pop()
- if tail == "\\layout":
- lines.insert(i,"\\end_layout")
- i = i + 1
- #Check if it is the correct tag
- struct_stack.pop()
- i = i + 1
- continue
-
- if token == "\\layout":
- tail = struct_stack.pop()
- if tail == token:
- lines.insert(i,"\\end_layout")
- i = i + 2
- else:
- struct_stack.append(tail)
- i = i + 1
- struct_stack.append(token)
- continue
-
- if token == "\\begin_deeper" or token == "\\end_deeper":
- lines.insert(i,"\\end_layout")
- i = i + 2
- continue
-
- #case \end_document
- lines.insert(i, "\\end_layout")
- return
-
-def layout2begin_layout(lines):
- i = 0
- while 1:
- i = find_token(lines, '\\layout', i)
- if i == -1:
- return
-
- lines[i] = replace(lines[i], '\\layout', '\\begin_layout')
- i = i + 1
-
-def valignment_middle(lines, start, end):
- for i in range(start, end):
- if re.search('^<(column|cell) .*valignment="center".*>$', lines[i]):
- lines[i] = replace(lines[i], 'valignment="center"', 'valignment="middle"')
-
-def table_valignment_middle(lines):
- i = 0
- while 1:
- i = find_token(lines, '\\begin_inset Tabular', i)
- if i == -1:
- return
- j = find_end_of_inset(lines, i + 1)
- if j == -1:
- #this should not happen
- valignment_middle(lines, i + 1, len(lines))
- return
- valignment_middle(lines, i + 1, j)
- i = j + 1
-
-def end_document(lines):
- i = find_token(lines, "\\the_end", 0)
- if i == -1:
- lines.append("\\end_document")
- return
- lines[i] = "\\end_document"
-
-##
-# Convert line and page breaks
-# Old:
-#\layout Standard
-#\line_top \line_bottom \pagebreak_top \pagebreak_bottom \added_space_top xxx \added_space_bottom yyy
-#0
-#
-# New:
-#\begin layout Standard
-#
-#\newpage
-#
-#\lyxline
-#\begin_inset VSpace xxx
-#\end_inset
-#
-#\end_layout
-#\begin_layout Standard
-#
-#0
-#\end_layout
-#\begin_layout Standard
-#
-#\begin_inset VSpace xxx
-#\end_inset
-#\lyxline
-#
-#\newpage
-#
-#\end_layout
-
-def convert_breaks(lines):
- i = 0
- while 1:
- i = find_token(lines, "\\begin_layout", i)
- if i == -1:
- return
- i = i + 1
- line_top = find(lines[i],"\\line_top")
- line_bot = find(lines[i],"\\line_bottom")
- pb_top = find(lines[i],"\\pagebreak_top")
- pb_bot = find(lines[i],"\\pagebreak_bottom")
- vspace_top = find(lines[i],"\\added_space_top")
- vspace_bot = find(lines[i],"\\added_space_bottom")
-
- if line_top == -1 and line_bot == -1 and pb_bot == -1 and pb_top == -1 and vspace_top == -1 and vspace_bot == -1:
- continue
-
- for tag in "\\line_top", "\\line_bottom", "\\pagebreak_top", "\\pagebreak_bottom":
- lines[i] = replace(lines[i], tag, "")
-
- if vspace_top != -1:
- # the position could be change because of the removal of other
- # paragraph properties above
- vspace_top = find(lines[i],"\\added_space_top")
- tmp_list = split(lines[i][vspace_top:])
- vspace_top_value = tmp_list[1]
- lines[i] = lines[i][:vspace_top] + join(tmp_list[2:])
-
- if vspace_bot != -1:
- # the position could be change because of the removal of other
- # paragraph properties above
- vspace_bot = find(lines[i],"\\added_space_bottom")
- tmp_list = split(lines[i][vspace_bot:])
- vspace_bot_value = tmp_list[1]
- lines[i] = lines[i][:vspace_bot] + join(tmp_list[2:])
-
- lines[i] = strip(lines[i])
- i = i + 1
-
- # Create an empty paragraph for line and page break that belong
- # above the paragraph
- if pb_top !=-1 or line_top != -1 or vspace_bot != -1:
-
- paragraph_above = ['','\\begin_layout Standard','','']
-
- if pb_top != -1:
- paragraph_above.extend(['\\newpage ',''])
-
- if vspace_top != -1:
- paragraph_above.extend(['\\begin_inset VSpace ' + vspace_top_value,'\\end_inset ','',''])
-
- if line_top != -1:
- paragraph_above.extend(['\\lyxline ',''])
-
- paragraph_above.extend(['\\end_layout',''])
-
- #inset new paragraph above the current paragraph
- lines[i-2:i-2] = paragraph_above
- i = i + len(paragraph_above)
-
- # Ensure that nested style are converted later.
- k = find_end_of(lines, i, "\\begin_layout", "\\end_layout")
-
- if k == -1:
- return
-
- if pb_top !=-1 or line_top != -1 or vspace_bot != -1:
-
- paragraph_bellow = ['','\\begin_layout Standard','','']
-
- if line_bot != -1:
- paragraph_bellow.extend(['\\lyxline ',''])
-
- if vspace_bot != -1:
- paragraph_bellow.extend(['\\begin_inset VSpace ' + vspace_bot_value,'\\end_inset ','',''])
-
- if pb_bot != -1:
- paragraph_bellow.extend(['\\newpage ',''])
-
- paragraph_bellow.extend(['\\end_layout',''])
-
- #inset new paragraph above the current paragraph
- lines[k + 1: k + 1] = paragraph_bellow
-
-def convert(header, body):
- add_end_layout(body)
- layout2begin_layout(body)
- end_document(body)
- table_valignment_middle(body)
- convert_breaks(body)
-
-if __name__ == "__main__":
- pass
+++ /dev/null
-# This file is part of lyx2lyx
-# -*- coding: iso-8859-1 -*-
-# Copyright (C) 2003 José Matos <jamatos@fep.up.pt>
-#
-# 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.
-
-from parser_tools import find_tokens
-
-def convert_note(lines):
- i = 0
- while 1:
- i = find_tokens(lines, ["\\begin_inset Note",
- "\\begin_inset Comment",
- "\\begin_inset Greyedout"], i)
- if i == -1:
- break
-
- lines[i] = lines[i][0:13] + 'Note ' + lines[i][13:]
- i = i + 1
-
-def convert(header, body):
- convert_note(body)
-
-if __name__ == "__main__":
- pass
+++ /dev/null
-# This file is part of lyx2lyx
-# -*- coding: iso-8859-1 -*-
-# Copyright (C) 2003 José Matos <jamatos@fep.up.pt>
-#
-# 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.
-
-from parser_tools import find_tokens
-
-def convert_box(lines):
- i = 0
- while 1:
- i = find_tokens(lines, ["\\begin_inset Boxed",
- "\\begin_inset Doublebox",
- "\\begin_inset Frameless",
- "\\begin_inset ovalbox",
- "\\begin_inset Ovalbox",
- "\\begin_inset Shadowbox"], i)
- if i == -1:
- break
-
- lines[i] = lines[i][0:13] + 'Box ' + lines[i][13:]
- i = i + 1
-
-def convert(header, body):
- convert_box(body)
-
-if __name__ == "__main__":
- pass
+++ /dev/null
-# This file is part of lyx2lyx
-# -*- coding: iso-8859-1 -*-
-# Copyright (C) 2003 José Matos <jamatos@fep.up.pt>
-#
-# 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
-from parser_tools import find_token, find_tokens
-
-def convert_collapsable(lines):
- i = 0
- while 1:
- i = find_tokens(lines, ["\\begin_inset Box",
- "\\begin_inset Branch",
- "\\begin_inset CharStyle",
- "\\begin_inset Float",
- "\\begin_inset Foot",
- "\\begin_inset Marginal",
- "\\begin_inset Note",
- "\\begin_inset OptArg",
- "\\begin_inset Wrap"], i)
- if i == -1:
- break
-
- # Seach for a line starting 'collapsed'
- # If, however, we find a line starting '\begin_layout'
- # (_always_ present) then break with a warning message
- i = i + 1
- while 1:
- if (lines[i] == "collapsed false"):
- lines[i] = "status open"
- break
- elif (lines[i] == "collapsed true"):
- lines[i] = "status collapsed"
- break
- elif (lines[i][:13] == "\\begin_layout"):
- sys.stderr.write("Malformed lyx file\n")
- break
- i = i + 1
-
- i = i + 1
-
-def convert_ert(lines):
- i = 0
- while 1:
- i = find_token(lines, "\\begin_inset ERT", i)
- if i == -1:
- break
-
- # Seach for a line starting 'status'
- # If, however, we find a line starting '\begin_layout'
- # (_always_ present) then break with a warning message
- i = i + 1
- while 1:
- if (lines[i] == "status Open"):
- lines[i] = "status open"
- break
- elif (lines[i] == "status Collapsed"):
- lines[i] = "status collapsed"
- break
- elif (lines[i] == "status Inlined"):
- lines[i] = "status inlined"
- break
- elif (lines[i][:13] == "\\begin_layout"):
- sys.stderr.write("Malformed lyx file\n")
- break
- i = i + 1
-
- i = i + 1
-
-def convert(header, body):
- convert_collapsable(body)
- convert_ert(body)
-
-if __name__ == "__main__":
- pass
+++ /dev/null
-# This file is part of lyx2lyx
-# -*- coding: iso-8859-1 -*-
-# Copyright (C) 2003 José Matos <jamatos@fep.up.pt>
-#
-# 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
-from parser_tools import find_token
-
-
-def convert_minipage(lines):
- """ Convert minipages to the box inset.
- We try to use the same order of arguments as lyx does.
- """
- pos = ["t","c","b"]
- inner_pos = ["c","t","b","s"]
-
- i = 0
- while 1:
- i = find_token(lines, "\\begin_inset Minipage", i)
- if i == -1:
- return
-
- lines[i] = "\\begin_inset Box Frameless"
- i = i + 1
-
- # convert old to new position using the pos list
- if lines[i][:8] == "position":
- lines[i] = 'position "%s"' % pos[int(lines[i][9])]
- else:
- lines.insert(i, 'position "%s"' % pos[0])
- i = i + 1
-
- lines.insert(i, 'hor_pos "c"')
- i = i + 1
- lines.insert(i, 'has_inner_box 1')
- i = i + 1
-
- # convert the inner_position
- if lines[i][:14] == "inner_position":
- lines[i] = 'inner_pos "%s"' % inner_pos[int(lines[i][15])]
- else:
- lines.insert('inner_pos "%s"' % inner_pos[0])
- i = i + 1
-
- # We need this since the new file format has a height and width
- # in a different order.
- if lines[i][:6] == "height":
- height = lines[i][6:]
- # test for default value of 221 and convert it accordingly
- if height == ' "0pt"':
- height = ' "1pt"'
- del lines[i]
- else:
- height = ' "1pt"'
-
- if lines[i][:5] == "width":
- width = lines[i][5:]
- del lines[i]
- else:
- width = ' "0"'
-
- if lines[i][:9] == "collapsed":
- if lines[i][9:] == "true":
- status = "collapsed"
- else:
- status = "open"
- del lines[i]
- else:
- status = "collapsed"
-
- lines.insert(i, 'use_parbox 0')
- i = i + 1
- lines.insert(i, 'width' + width)
- i = i + 1
- lines.insert(i, 'special "none"')
- i = i + 1
- lines.insert(i, 'height' + height)
- i = i + 1
- lines.insert(i, 'height_special "totalheight"')
- i = i + 1
- lines.insert(i, 'status ' + status)
- i = i + 1
-
-def convert(header, body):
- convert_minipage(body)
-
-if __name__ == "__main__":
- pass
+++ /dev/null
-# This file is part of lyx2lyx
-# -*- coding: iso-8859-1 -*-
-# Copyright (C) 2003 José Matos <jamatos@fep.up.pt>
-#
-# 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
-from parser_tools import find_token
-
-
-def convert(header, body):
- pass
-
-if __name__ == "__main__":
- pass
+++ /dev/null
-# This file is part of lyx2lyx
-# -*- coding: iso-8859-1 -*-
-# Copyright (C) 2003 José Matos <jamatos@fep.up.pt>
-#
-# 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
-from parser_tools import find_token
-
-
-def convert(header, body):
- pass
-
-if __name__ == "__main__":
- pass
+++ /dev/null
-# This file is part of lyx2lyx
-# -*- coding: iso-8859-1 -*-
-# Copyright (C) 2003 José Matos <jamatos@fep.up.pt>
-#
-# 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
-from parser_tools import find_token
-
-
-def convert(header, body):
- pass
-
-if __name__ == "__main__":
- pass
+++ /dev/null
-# This file is part of lyx2lyx
-# -*- coding: iso-8859-1 -*-
-# Copyright (C) 2003 José Matos <jamatos@fep.up.pt>
-#
-# 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 string
-from parser_tools import find_token
-
-def rm_end_header(lines):
- i = find_token(lines, "\\end_header", 0)
- if i == -1:
- return
- del lines[i]
-
-def convert_spaces(lines):
- for i in range(len(lines)):
- lines[i] = string.replace(lines[i],"\\InsetSpace ~", "\\SpecialChar ~")
-
-def convert_bibtex(lines):
- for i in range(len(lines)):
- lines[i] = string.replace(lines[i], "\\begin_inset LatexCommand \\bibtex",
- "\\begin_inset LatexCommand \\BibTeX")
-
-def rm_tracking_changes(lines):
- i = find_token(lines, "\\author", 0)
- if i != -1:
- del lines[i]
-
- i = find_token(lines, "\\tracking_changes", 0)
- if i == -1:
- return
- del lines[i]
-
-def rm_body_changes(lines):
- i = 0
- while 1:
- i = find_token(lines, "\\change_", i)
- if i == -1:
- return
-
- del lines[i]
-
-def convert(header, body):
- rm_end_header(header)
- convert_spaces(body)
- convert_bibtex(body)
- rm_tracking_changes(header)
- rm_body_changes(body)
-
-if __name__ == "__main__":
- pass
+++ /dev/null
-# This file is part of lyx2lyx
-# -*- coding: iso-8859-1 -*-
-# Copyright (C) 2003 José Matos <jamatos@fep.up.pt>
-#
-# 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.
-
-from string import split, join
-from parser_tools import find_token, find_tokens
-
-def convert_external(lines):
- external_header = "\\begin_inset External"
- i = 0
- while 1:
- i = find_token(lines, external_header, i)
- if i == -1:
- break
-
- template = split(lines[i+1])
- template.reverse()
- del lines[i+1]
-
- filename = split(lines[i+1])
- filename.reverse()
- del lines[i+1]
-
- params = split(lines[i+1])
- params.reverse()
- if lines[i+1]: del lines[i+1]
-
- lines[i] = lines[i] + " " + template[0]+ ', "' + filename[0] + '", " '+ join(params[1:]) + '"'
- i = i + 1
-
-def convert_comment(lines):
- i = 0
- while 1:
- i = find_tokens(lines, ["\\begin_inset Comment", "\\begin_inset Greyedout"], i)
-
- if i == -1:
- return
- lines[i] = "\\begin_inset Note"
- i = i + 1
-
-def convert(header, body):
- convert_external(body)
- convert_comment(body)
-
-if __name__ == "__main__":
- pass
+++ /dev/null
-# This file is part of lyx2lyx
-# -*- coding: iso-8859-1 -*-
-# Copyright (C) 2003 José Matos <jamatos@fep.up.pt>
-# Copyright (C) 2003 Georg Baum <Georg.Baum@post.rwth-aachen.de>
-#
-# 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 find_token, find_end_of_inset, get_next_paragraph, \
- get_paragraph, get_value, del_token, is_nonempty_line
-from string import find, replace, split
-import sys
-
-def rm_end_layout(lines):
- i = 0
- while 1:
- i = find_token(lines, '\\end_layout', i)
-
- if i == -1:
- return
-
- del lines[i]
-
-def begin_layout2layout(lines):
- i = 0
- while 1:
- i = find_token(lines, '\\begin_layout', i)
- if i == -1:
- return
-
- lines[i] = replace(lines[i], '\\begin_layout', '\\layout')
- i = i + 1
-
-def table_valignment_middle(lines, start, end):
- for i in range(start, end):
- if re.search('^<(column|cell) .*valignment="middle".*>$', lines[i]):
- lines[i] = replace(lines[i], 'valignment="middle"', 'valignment="center"')
-
-def valignment_middle(lines):
- i = 0
- while 1:
- i = find_token(lines, '\\begin_inset Tabular', i)
- if i == -1:
- return
- j = find_end_of_inset(lines, i + 1)
- if j == -1:
- #this should not happen
- valignment_middle(lines, i + 1, len(lines))
- return
- valignment_middle(lines, i + 1, j)
- i = j + 1
-
-def end_document(lines):
- i = find_token(lines, "\\end_document", 0)
- if i == -1:
- lines.append("\\the_end")
- return
- lines[i] = "\\the_end"
-
-# Convert backslashes into valid ERT code, append the converted text to
-# lines[i] and return the (maybe incremented) line index i
-def convert_ertbackslash(lines, i, ert):
- for c in ert:
- if c == '\\':
- lines[i] = lines[i] + '\\backslash '
- lines.insert(i, '')
- i = i + 1
- else:
- lines[i] = lines[i] + c
- return i
-
-def convert_vspace(header, lines):
-
- # Get default spaceamount
- i = find_token(header, '\\defskip', 0)
- if i == -1:
- defskipamount = 'medskip'
- else:
- defskipamount = split(header[i])[1]
-
- # Convert the insets
- i = 0
- while 1:
- i = find_token(lines, '\\begin_inset VSpace', i)
- if i == -1:
- return
- spaceamount = split(lines[i])[2]
-
- # Are we at the beginning or end of a paragraph?
- paragraph_start = 1
- start = get_paragraph(lines, i) + 1
- for k in range(start, i):
- if is_nonempty_line(lines[k]):
- paragraph_start = 0
- break
- paragraph_end = 1
- j = find_end_of_inset(lines, i)
- if j == -1:
- sys.stderr.write("Malformed lyx file: Missing '\\end_inset'\n")
- i = i + 1
- continue
- end = get_next_paragraph(lines, i)
- for k in range(j + 1, end):
- if is_nonempty_line(lines[k]):
- paragraph_end = 0
- break
-
- # Convert to paragraph formatting if we are at the beginning or end
- # of a paragraph and the resulting paragraph would not be empty
- if ((paragraph_start and not paragraph_end) or
- (paragraph_end and not paragraph_start)):
- # The order is important: del and insert invalidate some indices
- del lines[j]
- del lines[i]
- if paragraph_start:
- lines.insert(start, '\\added_space_top ' + spaceamount + ' ')
- else:
- lines.insert(start, '\\added_space_bottom ' + spaceamount + ' ')
- continue
-
- # Convert to ERT
- lines[i:i+1] = ['\\begin_inset ERT', 'status Collapsed', '',
- '\\layout Standard', '', '\\backslash ']
- i = i + 6
- if spaceamount[-1] == '*':
- spaceamount = spaceamount[:-1]
- keep = 1
- else:
- keep = 0
-
- # Replace defskip by the actual value
- if spaceamount == 'defskip':
- spaceamount = defskipamount
-
- # LaTeX does not know \\smallskip* etc
- if keep:
- if spaceamount == 'smallskip':
- spaceamount = '\\smallskipamount'
- elif spaceamount == 'medskip':
- spaceamount = '\\medskipamount'
- elif spaceamount == 'bigskip':
- spaceamount = '\\bigskipamount'
- elif spaceamount == 'vfill':
- spaceamount = '\\fill'
-
- # Finally output the LaTeX code
- if (spaceamount == 'smallskip' or spaceamount == 'medskip' or
- spaceamount == 'bigskip' or spaceamount == 'vfill'):
- lines.insert(i, spaceamount)
- else :
- if keep:
- lines.insert(i, 'vspace*{')
- else:
- lines.insert(i, 'vspace{')
- i = convert_ertbackslash(lines, i, spaceamount)
- lines[i] = lines[i] + '}'
- i = i + 1
-
-# Convert a LyX length into valid ERT code and append it to lines[i]
-# Return the (maybe incremented) line index i
-def convert_ertlen(lines, i, len, special):
- units = {"text%":"\\textwidth", "col%":"\\columnwidth",
- "page%":"\\pagewidth", "line%":"\\linewidth",
- "theight%":"\\textheight", "pheight%":"\\pageheight"}
-
- # Convert special lengths
- if special != 'none':
- len = '%f\\' % len2value(len) + special
-
- # Convert LyX units to LaTeX units
- for unit in units.keys():
- if find(len, unit) != -1:
- len = '%f' % (len2value(len) / 100) + units[unit]
- break
-
- # Convert backslashes and insert the converted length into lines
- return convert_ertbackslash(lines, i, len)
-
-# Return the value of len without the unit in numerical form
-def len2value(len):
- result = re.search('([+-]?[0-9.]+)', len)
- if result:
- return float(result.group(1))
- # No number means 1.0
- return 1.0
-
-def convert_frameless_box(lines):
- pos = ['t', 'c', 'b']
- inner_pos = ['c', 't', 'b', 's']
- i = 0
- while 1:
- i = find_token(lines, '\\begin_inset Frameless', i)
- if i == -1:
- return
- j = find_end_of_inset(lines, i)
- if j == -1:
- sys.stderr.write("Malformed lyx file: Missing '\\end_inset'\n")
- i = i + 1
- continue
- del lines[i]
-
- # Gather parameters
- params = {'position':'0', 'hor_pos':'c', 'has_inner_box':'1',
- 'inner_pos':'1', 'use_parbox':'0', 'width':'100col%',
- 'special':'none', 'height':'1in',
- 'height_special':'totalheight', 'collapsed':'false'}
- for key in params.keys():
- value = replace(get_value(lines, key, i, j), '"', '')
- if value != "":
- if key == 'position':
- # convert new to old position: 'position "t"' -> 0
- value = find_token(pos, value, 0)
- if value != -1:
- params[key] = value
- elif key == 'inner_pos':
- # convert inner position
- value = find_token(inner_pos, value, 0)
- if value != -1:
- params[key] = value
- else:
- params[key] = value
- j = del_token(lines, key, i, j)
- i = i + 1
-
- # Convert to minipage or ERT?
- # Note that the inner_position and height parameters of a minipage
- # inset are ignored and not accessible for the user, although they
- # are present in the file format and correctly read in and written.
- # Therefore we convert to ERT if they do not have their LaTeX
- # defaults. These are:
- # - the value of "position" for "inner_pos"
- # - "\totalheight" for "height"
- if (params['use_parbox'] != '0' or
- params['has_inner_box'] != '1' or
- params['special'] != 'none' or
- inner_pos[params['inner_pos']] != pos[params['position']] or
- params['height_special'] != 'totalheight' or
- len2value(params['height']) != 1.0):
-
- # Convert to ERT
- if params['collapsed'] == 'true':
- params['collapsed'] = 'Collapsed'
- else:
- params['collapsed'] = 'Open'
- lines[i : i] = ['\\begin_inset ERT', 'status ' + params['collapsed'],
- '', '\\layout Standard', '', '\\backslash ']
- i = i + 6
- if params['use_parbox'] == '1':
- lines.insert(i, 'parbox')
- else:
- lines.insert(i, 'begin{minipage}')
- lines[i] = lines[i] + '[' + pos[params['position']] + ']['
- i = convert_ertlen(lines, i, params['height'], params['height_special'])
- lines[i] = lines[i] + '][' + inner_pos[params['inner_pos']] + ']{'
- i = convert_ertlen(lines, i, params['width'], params['special'])
- if params['use_parbox'] == '1':
- lines[i] = lines[i] + '}{'
- else:
- lines[i] = lines[i] + '}'
- i = i + 1
- lines[i:i] = ['', '\\end_inset ']
- i = i + 2
- j = find_end_of_inset(lines, i)
- if j == -1:
- sys.stderr.write("Malformed lyx file: Missing '\\end_inset'\n")
- break
- lines[j-1:j-1] += ['\\begin_inset ERT', 'status ' + params['collapsed'],
- '', '\\layout Standard', '']
- j = j + 4
- if params['use_parbox'] == '1':
- lines.insert(j, '}')
- else:
- lines[j:j] = ['\\backslash ', 'end{minipage}']
- else:
-
- # Convert to minipage
- lines[i:i] = ['\\begin_inset Minipage',
- 'position %d' % params['position'],
- 'inner_position %d' % params['inner_pos'],
- 'height "' + params['height'] + '"',
- 'width "' + params['width'] + '"',
- 'collapsed ' + params['collapsed']]
- i = i + 6
-
-def convert(header, body):
- rm_end_layout(body)
- begin_layout2layout(body)
- end_document(body)
- valignment_middle(body)
- convert_vspace(header, body)
- convert_frameless_box(body)
-
-if __name__ == "__main__":
- pass
+++ /dev/null
-# This file is part of lyx2lyx
-# -*- coding: iso-8859-1 -*-
-# Copyright (C) 2003 José Matos <jamatos@fep.up.pt>
-#
-# 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.
-
-from parser_tools import find_token
-
-def convert_note(lines):
- note_header = "\\begin_inset Note "
- i = 0
- while 1:
- i = find_token(lines, note_header, i)
- if i == -1:
- break
-
- lines[i] = "\\begin_inset " + lines[i][len(note_header):]
- i = i + 1
-
-def convert(header, body):
- convert_note(body)
-
-if __name__ == "__main__":
- pass
+++ /dev/null
-# This file is part of lyx2lyx
-# -*- coding: iso-8859-1 -*-
-# Copyright (C) 2003 José Matos <jamatos@fep.up.pt>
-#
-# 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.
-
-from parser_tools import find_token, find_end_of_inset
-
-def convert_box(lines):
- box_header = "\\begin_inset Box "
- i = 0
- while 1:
- i = find_token(lines, box_header, i)
- if i == -1:
- break
-
- lines[i] = "\\begin_inset " + lines[i][len(box_header):]
- i = i + 1
-
-def convert_external(lines):
- draft_token = '\tdraft'
- i = 0
- while 1:
- i = find_token(lines, '\\begin_inset External', i)
- if i == -1:
- break
- j = find_end_of_inset(lines, i + 1)
- if j == -1:
- #this should not happen
- break
- k = find_token(lines, draft_token, i+1, j-1)
- if (k != -1 and len(draft_token) == len(lines[k])):
- del lines[k]
- i = j + 1
-
-def convert(header, body):
- convert_box(body)
- convert_external(body)
-
-if __name__ == "__main__":
- pass
+++ /dev/null
-# This file is part of lyx2lyx
-# -*- coding: iso-8859-1 -*-
-# Copyright (C) 2003 José Matos <jamatos@fep.up.pt>
-#
-# 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
-from parser_tools import find_token, find_tokens
-
-def convert_collapsable(lines):
- i = 0
- while 1:
- i = find_tokens(lines, ["\\begin_inset Box",
- "\\begin_inset Branch",
- "\\begin_inset CharStyle",
- "\\begin_inset Float",
- "\\begin_inset Foot",
- "\\begin_inset Marginal",
- "\\begin_inset Note",
- "\\begin_inset OptArg",
- "\\begin_inset Wrap"], i)
- if i == -1:
- break
-
- # Seach for a line starting 'status'
- # If, however, we find a line starting '\begin_layout'
- # (_always_ present) then break with a warning message
- i = i + 1
- while 1:
- if (lines[i] == "status open"):
- lines[i] = "collapsed false"
- break
- elif (lines[i] == "status collapsed" or
- lines[i] == "status inlined"):
- lines[i] = "collapsed true"
- break
- elif (lines[i][:13] == "\\begin_layout"):
- sys.stderr.write("Malformed lyx file\n")
- break
- i = i + 1
-
- i = i + 1
-
-def convert_ert(lines):
- i = 0
- while 1:
- i = find_token(lines, "\\begin_inset ERT", i)
- if i == -1:
- break
-
- # Seach for a line starting 'status'
- # If, however, we find a line starting '\begin_layout'
- # (_always_ present) then break with a warning message
- i = i + 1
- while 1:
- if (lines[i] == "status open"):
- lines[i] = "status Open"
- break
- elif (lines[i] == "status collapsed"):
- lines[i] = "status Collapsed"
- break
- elif (lines[i] == "status inlined"):
- lines[i] = "status Inlined"
- break
- elif (lines[i][:13] == "\\begin_layout"):
- sys.stderr.write("Malformed lyx file\n")
- break
- i = i + 1
-
- i = i + 1
-
-def convert(header, body):
- convert_collapsable(body)
- convert_ert(body)
-
-if __name__ == "__main__":
- pass
+++ /dev/null
-# This file is part of lyx2lyx
-# -*- coding: iso-8859-1 -*-
-# Copyright (C) 2003 José Matos <jamatos@fep.up.pt>
-#
-# 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.
-
-
-
-def convert(header, body):
- pass
-
-if __name__ == "__main__":
- pass
+++ /dev/null
-# This file is part of lyx2lyx
-# -*- coding: iso-8859-1 -*-
-# Copyright (C) 2003 José Matos <jamatos@fep.up.pt>
-#
-# 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
-from parser_tools import find_token
-
-
-def convert(header, body):
- pass
-
-if __name__ == "__main__":
- pass
+++ /dev/null
-# This file is part of lyx2lyx
-# -*- coding: iso-8859-1 -*-
-# Copyright (C) 2003 José Matos <jamatos@fep.up.pt>
-#
-# 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
-from parser_tools import find_token
-
-
-def convert(header, body):
- pass
-
-if __name__ == "__main__":
- pass
+++ /dev/null
-# This file is part of lyx2lyx
-# -*- coding: iso-8859-1 -*-
-# Copyright (C) 2003 José Matos <jamatos@fep.up.pt>
-#
-# 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
-from parser_tools import find_token
-
-
-def convert(header, body):
- pass
-
-if __name__ == "__main__":
- pass
# This file is part of lyx2lyx
# -*- coding: iso-8859-1 -*-
-# Copyright (C) 2002-2003 Dekel Tsur <dekel@lyx.org>, José Matos <jamatos@lyx.org>
+# Copyright (C) 2002-2004 Dekel Tsur <dekel@lyx.org>, 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
# 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:
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):
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
return i
return -1
-def set_comment(lines, version):
+##
+# Tools for file reading
+#
+def read_file(header, body, opt):
+ """Reads a file into the header and body parts"""
+ preamble = 0
+
+ while 1:
+ line = opt.input.readline()
+ if not line:
+ opt.error("Invalid LyX file.")
+
+ 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)
+
+ while 1:
+ line = opt.input.readline()
+ if not line:
+ break
+ body.append(line[:-1])
+
+def write_file(header, body, opt):
+ for line in header:
+ opt.output.write(line+"\n")
+ opt.output.write("\n")
+ for line in body:
+ opt.output.write(line+"\n")
+
+##
+# lyx version
+#
+original_version = re.compile(r"\#LyX (\S*)")
+
+def read_version(header):
+ for line in header:
+ if line[0] != "#":
+ return None
+
+ result = original_version.match(line)
+ if result:
+ return result.group(1)
+ return None
+
+def set_version(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]
+##
+# file format version
+#
+format_re = re.compile(r"(\d)[\.,]?(\d\d)")
+fileformat = re.compile(r"\\lyxformat\s*(\S*)")
+lst_ft = [210, 215, 216, 217, 218, 220, 221, 223, 224, 225, 226, 227, 228, 229,
+ 230, 231, 232]
+
+format_relation = [("0_10", [210], ["0.10.7","0.10"]),
+ ("0_12", [215], ["0.12","0.12.1","0.12"]),
+ ("1_0_0", [215], ["1.0.0","1.0"]),
+ ("1_0_1", [215], ["1.0.1","1.0.2","1.0.3","1.0.4", "1.1.2","1.1"]),
+ ("1_1_4", [215], ["1.1.4","1.1"]),
+ ("1_1_5", [216], ["1.1.5","1.1.5fix1","1.1.5fix2","1.1"]),
+ ("1_1_6", [217], ["1.1.6","1.1.6fix1","1.1.6fix2","1.1"]),
+ ("1_1_6fix3", [218], ["1.1.6fix3","1.1.6fix4","1.1"]),
+ ("1_2", [220], ["1.2.0","1.2.1","1.2.3","1.2.4","1.2"]),
+ ("1_3", [221], ["1.3.0","1.3.1","1.3.2","1.3.3","1.3.4","1.3"]),
+ ("1_4", [223,224,225,226,227,228,229,230,231,232], ["1.4.0cvs","1.4"])]
+
+def lyxformat(format, opt):
+ result = format_re.match(format)
+ if result:
+ format = int(result.group(1) + result.group(2))
+ else:
+ opt.error(str(format) + ": " + "Invalid LyX file.")
+
+ if format in lst_ft:
+ return format
+
+ opt.error(str(format) + ": " + "Format no supported.")
+ return None
+
+def read_format(header, opt):
+ for line in header:
+ result = fileformat.match(line)
+ if result:
+ return lyxformat(result.group(1), opt)
+ else:
+ opt.error("Invalid LyX File.")
+ return None
+
def set_format(lines, number):
if int(number) <= 217:
number = float(number)/100
i = find_token(lines, "\\lyxformat", 0)
lines[i] = "\\lyxformat %s" % number
+
+def get_end_format():
+ return format_relation[-1:][0][1][-1:][0]
+
+def chain(opt, initial_version):
+ """ This is where all the decisions related with the convertion are taken"""
+
+ format = opt.format
+ if opt.start:
+ if opt.start != format:
+ opt.warning("%s: %s %s" % ("Proposed file format and input file formats do not match:", opt.start, format))
+ else:
+ opt.start = format
+
+ if not opt.end:
+ opt.end = get_end_format()
+
+ correct_version = 0
+
+ for rel in format_relation:
+ if initial_version in rel[2]:
+ if format in rel[1]:
+ initial_step = rel[0]
+ correct_version = 1
+ break
+
+ if not correct_version:
+ if format <= 215:
+ opt.warning("Version does not match file format, discarding it.")
+ for rel in format_relation:
+ if format in rel[1]:
+ initial_step = rel[0]
+ break
+ else:
+ # This should not happen, really.
+ opt.error("Format not supported.")
+
+ # Find the final step
+ for rel in format_relation:
+ if opt.end in rel[1]:
+ final_step = rel[0]
+ break
+ else:
+ opt.error("Format not supported.")
+
+ # Convertion mode, back or forth
+ steps = []
+ if (initial_step, opt.start) < (final_step, opt.end):
+ mode = "convert"
+ first_step = 1
+ for step in format_relation:
+ if initial_step <= step[0] <= final_step:
+ if first_step and len(step[1]) == 1:
+ first_step = 0
+ continue
+ steps.append(step[0])
+ else:
+ mode = "revert"
+ for step in format_relation:
+ if final_step <= step[0] <= initial_step:
+ steps.insert(0, step[0])
+
+ if step[1][-1:] == opt.end:
+ del steps[0]
+
+ return mode, steps