From 948cfd3b7b40ae419c21c1688122f9c51a0e869f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Matox?= Date: Tue, 24 Jul 2007 14:58:41 +0000 Subject: [PATCH] Backport lyx2lyx from 1.5.0 git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/branches/BRANCH_1_4_X@19183 a592a061-630c-0410-9148-cb99ea01b6c8 --- lib/ChangeLog | 4 + lib/lyx2lyx/ChangeLog | 9 +- lib/lyx2lyx/LyX.py | 174 +- lib/lyx2lyx/Makefile.am | 15 +- lib/lyx2lyx/lyx2lyx | 26 +- lib/lyx2lyx/lyx2lyx_lang.py | 102 + .../{lyx_1_0_1.py => lyx2lyx_version.py} | 10 +- lib/lyx2lyx/lyx_0_06.py | 28 + lib/lyx2lyx/lyx_0_08.py | 34 + lib/lyx2lyx/lyx_0_10.py | 138 ++ lib/lyx2lyx/lyx_0_12.py | 161 +- lib/lyx2lyx/{lyx_1_0_0.py => lyx_1_0.py} | 35 +- lib/lyx2lyx/{lyx_1_1_4.py => lyx_1_1.py} | 7 +- lib/lyx2lyx/lyx_1_1_5.py | 129 +- lib/lyx2lyx/{lyx_1_1_6.py => lyx_1_1_6_0.py} | 38 +- .../{lyx_1_1_6fix3.py => lyx_1_1_6_3.py} | 35 +- lib/lyx2lyx/lyx_1_2.py | 218 +- lib/lyx2lyx/lyx_1_3.py | 35 +- lib/lyx2lyx/lyx_1_4.py | 1573 +++++++------ lib/lyx2lyx/lyx_1_5.py | 2080 +++++++++++++++++ lib/lyx2lyx/parser_tools.py | 253 +- lib/lyx2lyx/profiling.py | 4 +- lib/unicodesymbols | 1399 +++++++++++ 23 files changed, 5310 insertions(+), 1197 deletions(-) create mode 100644 lib/lyx2lyx/lyx2lyx_lang.py rename lib/lyx2lyx/{lyx_1_0_1.py => lyx2lyx_version.py} (83%) create mode 100644 lib/lyx2lyx/lyx_0_06.py create mode 100644 lib/lyx2lyx/lyx_0_08.py create mode 100644 lib/lyx2lyx/lyx_0_10.py rename lib/lyx2lyx/{lyx_1_0_0.py => lyx_1_0.py} (71%) rename lib/lyx2lyx/{lyx_1_1_4.py => lyx_1_1.py} (78%) rename lib/lyx2lyx/{lyx_1_1_6.py => lyx_1_1_6_0.py} (91%) rename lib/lyx2lyx/{lyx_1_1_6fix3.py => lyx_1_1_6_3.py} (80%) create mode 100644 lib/lyx2lyx/lyx_1_5.py create mode 100644 lib/unicodesymbols diff --git a/lib/ChangeLog b/lib/ChangeLog index 115ca58c28..1449591be8 100644 --- a/lib/ChangeLog +++ b/lib/ChangeLog @@ -1,3 +1,7 @@ +2007-07-24 José Matos + + * unicodesymbols: new file to read documents from 1.5.x + 2007-07-12 Jean-Pierre Chrétien * layouts/beamer.layout: reorder layouts (bug 3141). diff --git a/lib/lyx2lyx/ChangeLog b/lib/lyx2lyx/ChangeLog index 9a9c311646..64a1a6e6fa 100644 --- a/lib/lyx2lyx/ChangeLog +++ b/lib/lyx2lyx/ChangeLog @@ -1,3 +1,8 @@ +2007-07-24 José Matos + + * (several) Backport lyx2lyx from 1.5.0 (modulo some files used + for testing). + 2006-08-09 Jean-Marc Lasgouttes * Makefile.am (dist_lyx2lyx_DATA): rename to dist_lyx2lyx_PYTHON; @@ -5,9 +10,11 @@ (install-data-hook): new target: sets executable bit on lyx2lyx. 2006-07-15 Bo Peng + * replace all tab in .py files by spaces -2006-04-10 José Matos +2006-04-10 José Matos + * parser_tools.py (find_tokens_exact, find_tokens): replace range with xrange. diff --git a/lib/lyx2lyx/LyX.py b/lib/lyx2lyx/LyX.py index a23c68e590..9f907f35c6 100644 --- a/lib/lyx2lyx/LyX.py +++ b/lib/lyx2lyx/LyX.py @@ -1,6 +1,7 @@ # This file is part of lyx2lyx -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2002-2004 Dekel Tsur , José Matos +# -*- coding: utf-8 -*- +# Copyright (C) 2002-2004 Dekel Tsur +# Copyright (C) 2002-2006 José Matos # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -17,36 +18,66 @@ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. from parser_tools import get_value, check_token, find_token,\ - find_tokens, find_end_of, find_end_of_inset + find_tokens, find_end_of import os.path import gzip +import locale import sys import re -import string import time -version_lyx2lyx = "1.4.1" +try: + import lyx2lyx_version + version_lyx2lyx = lyx2lyx_version.version +except: # we are running from build directory so assume the last version + version_lyx2lyx = '1.4.5' + default_debug_level = 2 +#################################################################### +# Private helper functions + +def find_end_of_inset(lines, i): + " Find beginning of inset, where lines[i] is included." + return find_end_of(lines, i, "\\begin_inset", "\\end_inset") + +def generate_minor_versions(major, last_minor_version): + """ Generate minor versions, using major as prefix and minor + versions from 0 until last_minor_version, plus the generic version. + + Example: + + generate_minor_versions("1.2", 4) -> + [ "1.2", "1.2.0", "1.2.1", "1.2.2", "1.2.3"] + """ + return [major] + [major + ".%d" % i for i in range(last_minor_version + 1)] + + +# End of helper functions +#################################################################### + + # Regular expressions used format_re = re.compile(r"(\d)[\.,]?(\d\d)") fileformat = re.compile(r"\\lyxformat\s*(\S*)") -original_version = re.compile(r"\#LyX (\S*)") +original_version = re.compile(r".*?LyX ([\d.]*)") ## # file format information: # file, supported formats, stable release versions -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.5","1.3.6","1.3"]), - ("1_4", range(222,246), ["1.4.0cvs","1.4"])] +format_relation = [("0_06", [200], generate_minor_versions("0.6" , 4)), + ("0_08", [210], generate_minor_versions("0.8" , 6) + ["0.7"]), + ("0_10", [210], generate_minor_versions("0.10", 7) + ["0.9"]), + ("0_12", [215], generate_minor_versions("0.12", 1) + ["0.11"]), + ("1_0", [215], generate_minor_versions("1.0" , 4)), + ("1_1", [215], generate_minor_versions("1.1" , 4)), + ("1_1_5", [216], ["1.1.5","1.1.5.1","1.1.5.2","1.1"]), + ("1_1_6_0", [217], ["1.1.6","1.1.6.1","1.1.6.2","1.1"]), + ("1_1_6_3", [218], ["1.1.6.3","1.1.6.4","1.1"]), + ("1_2", [220], generate_minor_versions("1.2" , 4)), + ("1_3", [221], generate_minor_versions("1.3" , 7)), + ("1_4", range(222,246), generate_minor_versions("1.4" , 5)), + ("1_5", range(246,277), generate_minor_versions("1.5" , 0))] def formats_list(): @@ -81,12 +112,37 @@ def trim_eol(line): return line[:-1] +def get_encoding(language, inputencoding, format, cjk_encoding): + if format > 248: + return "utf8" + # CJK-LyX encodes files using the current locale encoding. + # This means that files created by CJK-LyX can only be converted using + # the correct locale settings unless the encoding is given as commandline + # argument. + if cjk_encoding == 'auto': + return locale.getpreferredencoding() + elif cjk_encoding != '': + return cjk_encoding + from lyx2lyx_lang import lang + if inputencoding == "auto" or inputencoding == "default": + return lang[language][3] + if inputencoding == "": + return "latin1" + # python does not know the alias latin9 + if inputencoding == "latin9": + return "iso-8859-15" + return inputencoding + ## # Class # class LyX_Base: """This class carries all the information of the LyX file.""" - def __init__(self, end_format = 0, input = "", output = "", error = "", debug = default_debug_level, try_hard = 0): + + def __init__(self, end_format = 0, input = "", output = "", error + = "", debug = default_debug_level, try_hard = 0, cjk_encoding = '', + language = "english", encoding = "auto"): + """Arguments: end_format: final format that the file should be converted. (integer) input: the name of the input source, if empty resort to standard input. @@ -103,6 +159,7 @@ class LyX_Base: self.debug = debug self.try_hard = try_hard + self.cjk_encoding = cjk_encoding if end_format: self.end_format = self.lyxformat(end_format) @@ -119,6 +176,8 @@ class LyX_Base: self.preamble = [] self.body = [] self.status = 0 + self.encoding = encoding + self.language = language def warning(self, message, debug_level= default_debug_level): @@ -156,7 +215,7 @@ class LyX_Base: if check_token(line, '\\end_preamble'): break - if string.split(line)[:0] in ("\\layout", "\\begin_layout", "\\begin_body"): + if line.split()[:0] in ("\\layout", "\\begin_layout", "\\begin_body"): self.warning("Malformed LyX file: Missing '\\end_preamble'.") self.warning("Adding it now and hoping for the best.") @@ -165,35 +224,45 @@ class LyX_Base: if check_token(line, '\\end_preamble'): continue - line = string.strip(line) + line = line.strip() if not line: continue - if string.split(line)[0] in ("\\layout", "\\begin_layout", "\\begin_body"): + if line.split()[0] in ("\\layout", "\\begin_layout", "\\begin_body", "\\begin_deeper"): self.body.append(line) break self.header.append(line) - while 1: - line = self.input.readline() - if not line: - break - self.body.append(trim_eol(line)) - self.textclass = get_value(self.header, "\\textclass", 0) self.backend = get_backend(self.textclass) self.format = self.read_format() - self.language = get_value(self.header, "\\language", 0) - if self.language == "": - self.language = "english" + self.language = get_value(self.header, "\\language", 0, default = "english") + self.inputencoding = get_value(self.header, "\\inputencoding", 0, default = "auto") + self.encoding = get_encoding(self.language, self.inputencoding, self.format, self.cjk_encoding) self.initial_version = self.read_version() + # Second pass over header and preamble, now we know the file encoding + for i in range(len(self.header)): + self.header[i] = self.header[i].decode(self.encoding) + for i in range(len(self.preamble)): + self.preamble[i] = self.preamble[i].decode(self.encoding) + + # Read document body + while 1: + line = self.input.readline().decode(self.encoding) + if not line: + break + self.body.append(trim_eol(line)) + def write(self): " Writes the LyX file to self.output." self.set_version() self.set_format() + self.set_textclass() + if self.encoding == "auto": + self.encoding = get_encoding(self.language, self.encoding, self.format, self.cjk_encoding) if self.preamble: i = find_token(self.header, '\\textclass', 0) + 1 @@ -206,7 +275,7 @@ class LyX_Base: header = self.header for line in header + [''] + self.body: - self.output.write(line+"\n") + self.output.write(line.encode(self.encoding)+"\n") def choose_io(self, input, output): @@ -227,6 +296,7 @@ class LyX_Base: except: self.input = open(input) else: + self.dir = '' self.input = sys.stdin @@ -235,6 +305,8 @@ class LyX_Base: result = format_re.match(format) if result: format = int(result.group(1) + result.group(2)) + elif format == '2': + format = 200 else: self.error(str(format) + ": " + "Invalid LyX file.") @@ -252,9 +324,19 @@ class LyX_Base: if line[0] != "#": return None + line = line.replace("fix",".") result = original_version.match(line) if result: - return result.group(1) + # Special know cases: reLyX and KLyX + if line.find("reLyX") != -1 or line.find("KLyX") != -1: + return "0.12" + + res = result.group(1) + if not res: + self.warning(line) + #self.warning("Version %s" % result.group(1)) + return res + self.warning(str(self.header[:2])) return None @@ -286,6 +368,11 @@ class LyX_Base: self.header[i] = "\\lyxformat %s" % format + def set_textclass(self): + i = find_token(self.header, "\\textclass", 0) + self.header[i] = "\\textclass %s" % self.textclass + + def set_parameter(self, param, value): " Set the value of the header parameter." i = find_token(self.header, '\\' + param, 0) @@ -359,7 +446,7 @@ class LyX_Base: if not correct_version: if format <= 215: - self.warning("Version does not match file format, discarding it.") + self.warning("Version does not match file format, discarding it. (Version %s, format %d)" %(self.initial_version, self.format)) for rel in format_relation: if format in rel[1]: initial_step = rel[0] @@ -426,7 +513,7 @@ class LyX_Base: self.warning('Incomplete file.', 0) break - section = string.split(self.body[i])[1] + section = self.body[i].split()[1] if section[-1] == '*': section = section[:-1] @@ -434,12 +521,12 @@ class LyX_Base: k = i + 1 # skip paragraph parameters - while not string.strip(self.body[k]) or string.split(self.body[k])[0] in allowed_parameters: + while not self.body[k].strip() or self.body[k].split()[0] in allowed_parameters: k = k +1 while k < j: if check_token(self.body[k], '\\begin_inset'): - inset = string.split(self.body[k])[1] + inset = self.body[k].split()[1] end = find_end_of_inset(self.body, k) if end == -1 or end > j: self.warning('Malformed file.', 0) @@ -452,7 +539,7 @@ class LyX_Base: k = k + 1 # trim empty lines in the end. - while string.strip(par[-1]) == '' and par: + while par[-1].strip() == '' and par: par.pop() toc_par.append(Paragraph(section, par)) @@ -464,8 +551,8 @@ class LyX_Base: class File(LyX_Base): " This class reads existing LyX files." - def __init__(self, end_format = 0, input = "", output = "", error = "", debug = default_debug_level, try_hard = 0): - LyX_Base.__init__(self, end_format, input, output, error, debug, try_hard) + def __init__(self, end_format = 0, input = "", output = "", error = "", debug = default_debug_level, try_hard = 0, cjk_encoding = ''): + LyX_Base.__init__(self, end_format, input, output, error, debug, try_hard, cjk_encoding) self.read() @@ -481,7 +568,14 @@ class NewFile(LyX_Base): "\\textclass article", "\\language english", "\\inputencoding auto", - "\\fontscheme default", + "\\font_roman default", + "\\font_sans default", + "\\font_typewriter default", + "\\font_default_family default", + "\\font_sc false", + "\\font_osf false", + "\\font_sf_scale 100", + "\\font_tt_scale 100", "\\graphics default", "\\paperfontsize default", "\\papersize default", diff --git a/lib/lyx2lyx/Makefile.am b/lib/lyx2lyx/Makefile.am index 4de3c2c374..3c3aeb5e0d 100644 --- a/lib/lyx2lyx/Makefile.am +++ b/lib/lyx2lyx/Makefile.am @@ -7,18 +7,23 @@ CHMOD = chmod lyx2lyxdir = $(pkgdatadir)/lyx2lyx dist_lyx2lyx_PYTHON = \ lyx2lyx \ + lyx2lyx_version.py \ + lyx2lyx_lang.py \ parser_tools.py \ LyX.py \ + lyx_0_06.py \ + lyx_0_08.py \ + lyx_0_10.py \ lyx_0_12.py \ - lyx_1_0_0.py \ - lyx_1_0_1.py \ - lyx_1_1_4.py \ + lyx_1_0.py \ + lyx_1_1.py \ lyx_1_1_5.py \ - lyx_1_1_6.py \ - lyx_1_1_6fix3.py \ + lyx_1_1_6_0.py \ + lyx_1_1_6_3.py \ lyx_1_2.py \ lyx_1_3.py \ lyx_1_4.py \ + lyx_1_5.py \ profiling.py install-data-hook: diff --git a/lib/lyx2lyx/lyx2lyx b/lib/lyx2lyx/lyx2lyx index ce0e45278d..8c7b98b263 100755 --- a/lib/lyx2lyx/lyx2lyx +++ b/lib/lyx2lyx/lyx2lyx @@ -1,6 +1,6 @@ #! /usr/bin/env python -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2002-2004 José Matos +# -*- coding: utf-8 -*- +# Copyright (C) 2002-2004 José Matos # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -36,25 +36,30 @@ Options: -t, --to version final version (optional) -o, --output name name of the output file or else goes to stdout -n, --try-hard try hard (ignore any convertion errors) + -c, --cjk [encoding] files in format 248 and lower are read and + written in the format of CJK-LyX. + If encoding is not given or 'auto' the encoding + is determined from the locale. -q, --quiet same as --debug=0""" def parse_options(argv): - _options = ["help", "version", "list", "debug=", "err=", "from=", "to=", "output=", "try-hard", "quiet"] + _options = ["help", "version", "list", "debug=", "err=", "from=", "to=", "output=", "try-hard", "cjk", "quiet"] try: - opts, args = getopt.getopt(argv[1:], "d:e:f:hlno:qt:v", _options) + opts, args = getopt.getopt(argv[1:], "c:d:e:f:hlno:qt:v", _options) except getopt.error: usage() sys.exit(2) end_format, input, output, error, debug, try_hard = 0, "", "", "", LyX.default_debug_level, 0 + cjk_encoding = '' for o, a in opts: if o in ("-h", "--help"): usage() sys.exit() if o in ("-v", "--version"): print "lyx2lyx, version %s" %(LyX.version_lyx2lyx) - print "Copyright (C) 2002-2004 José Matos and Dekel Tsur" + print "Copyright (C) 2002-2004 José Matos and Dekel Tsur" sys.exit() if o in ("-d", "--debug"): debug = int(a) @@ -71,15 +76,20 @@ def parse_options(argv): error = a if o in ("-n", "--try-hard"): try_hard = 1 + if o in ("-c", "--cjk"): + if a == '': + cjk_encoding = 'auto' + else: + cjk_encoding = a if args: input = args[0] - return end_format, input, output, error, debug, try_hard + return end_format, input, output, error, debug, try_hard, cjk_encoding def main(argv): - end_format, input, output, error, debug, try_hard = parse_options(argv) - file = LyX.File(end_format, input, output, error, debug, try_hard) + end_format, input, output, error, debug, try_hard, cjk_encoding = parse_options(argv) + file = LyX.File(end_format, input, output, error, debug, try_hard, cjk_encoding) file.convert() file.write() diff --git a/lib/lyx2lyx/lyx2lyx_lang.py b/lib/lyx2lyx/lyx2lyx_lang.py new file mode 100644 index 0000000000..d5b76d2d03 --- /dev/null +++ b/lib/lyx2lyx/lyx2lyx_lang.py @@ -0,0 +1,102 @@ +# This file is generated by generate_incoding_info.py from lib/languages file. +# Do not change this file directly. + +lang = {'afrikaans': ['afrikaans', 'Afrikaans', 'false', 'iso8859-1', 'af_ZA', ''], + 'american': ['american', 'American', 'false', 'iso8859-1', 'en_US', ''], + 'arabic': ['arabic', 'Arabic', 'true', 'iso8859-6', 'ar_SA', ''], + 'austrian': ['austrian', 'Austrian', 'false', 'iso8859-1', 'de_AT', ''], + 'bahasa': ['bahasa', 'Bahasa', 'false', 'iso8859-1', 'in_ID', ''], + 'basque': ['basque', 'Basque', 'false', 'iso8859-1', 'eu_ES', ''], + 'belarusian': ['belarusian', 'Belarusian', 'false', 'cp1251', 'be_BY', ''], + 'brazil': ['brazil', + 'Portuguese (Brazil)', + 'false', + 'iso8859-1', + 'pt_BR', + ''], + 'breton': ['breton', 'Breton', 'false', 'iso8859-1', 'br_FR', ''], + 'british': ['british', 'British', 'false', 'iso8859-1', 'en_GB', ''], + 'bulgarian': ['bulgarian', 'Bulgarian', 'false', 'cp1251', 'bg_BG', ''], + 'canadian': ['canadian', 'Canadian', 'false', 'iso8859-1', 'en_CA', ''], + 'canadien': ['canadien', + 'French Canadian', + 'false', + 'iso8859-1', + 'fr_CA', + ''], + 'catalan': ['catalan', 'Catalan', 'false', 'iso8859-1', 'ca_ES', ''], + 'croatian': ['croatian', 'Croatian', 'false', 'iso8859-2', 'hr_HR', ''], + 'czech': ['czech', 'Czech', 'false', 'iso8859-2', 'cs_CZ', ''], + 'danish': ['danish', 'Danish', 'false', 'iso8859-1', 'da_DK', ''], + 'dutch': ['dutch', 'Dutch', 'false', 'iso8859-1', 'nl_NL', ''], + 'english': ['english', 'English', 'false', 'iso8859-1', 'en_US', ''], + 'esperanto': ['esperanto', 'Esperanto', 'false', 'iso8859-3', 'eo', ''], + 'estonian': ['estonian', 'Estonian', 'false', 'iso8859-1', 'et_EE', ''], + 'finnish': ['finnish', 'Finnish', 'false', 'iso8859-1', 'fi_FI', ''], + 'french': ['french', + 'French', + 'false', + 'iso8859-1', + 'fr_FR', + '\\addto\\extrasfrench{\\providecommand{\\og}{\\leavevmode\\flqq~}\\providecommand{\\fg}{\\ifdim\\lastskip>\\z@\\unskip\\fi~\\frqq}}'], + 'frenchb': ['french', 'French', 'false', 'iso8859-1', 'fr_FR', ''], # for compatibility reasons + 'galician': ['galician', 'Galician', 'false', 'iso8859-1', 'gl_ES', ''], + 'german': ['german', 'German', 'false', 'iso8859-1', 'de_DE', ''], + 'greek': ['greek', 'Greek', 'false', 'iso8859-7', 'el_GR', ''], + 'hebrew': ['hebrew', 'Hebrew', 'true', 'cp1255', 'he_IL', ''], + 'icelandic': ['icelandic', 'Icelandic', 'false', 'iso8859-1', 'is_IS', ''], + 'irish': ['irish', 'Irish', 'false', 'iso8859-1', 'ga_IE', ''], + 'italian': ['italian', 'Italian', 'false', 'iso8859-1', 'it_IT', ''], + 'kazakh': ['kazakh', 'Kazakh', 'false', 'pt154', 'kk_KZ', ''], + 'latvian': ['latvian', 'Latvian', 'false', 'iso8859-13', 'lv_LV', ''], + 'lithuanian': ['lithuanian', + 'Lithuanian', + 'false', + 'iso8859-13', + 'lt_LT', + ''], + 'magyar': ['magyar', 'Magyar', 'false', 'iso8859-2', 'hu_HU', ''], + 'naustrian': ['naustrian', + 'Austrian (new spelling)', + 'false', + 'iso8859-1', + 'de_AT', + ''], + 'ngerman': ['ngerman', + 'German (new spelling)', + 'false', + 'iso8859-1', + 'de_DE', + ''], + 'norsk': ['norsk', 'Norsk', 'false', 'iso8859-1', 'no_NO', ''], + 'nynorsk': ['nynorsk', 'Nynorsk', 'false', 'iso8859-1', 'nn_NO', ''], + 'polish': ['polish', 'Polish', 'false', 'iso8859-2', 'pl_PL', ''], + 'portuges': ['portuges', 'Portugese', 'false', 'iso8859-1', 'pt_PT', ''], + 'romanian': ['romanian', 'Romanian', 'false', 'iso8859-2', 'ro_RO', ''], + 'russian': ['russian', 'Russian', 'false', 'koi8', 'ru_RU', ''], + 'scottish': ['scottish', 'Scottish', 'false', 'iso8859-1', 'gd_GB', ''], + 'serbian': ['croatian', 'Serbian', 'false', 'iso8859-5', 'sr_HR', ''], + 'serbocroatian': ['croatian', + 'Serbo-Croatian', + 'false', + 'iso8859-2', + 'sh_HR', + ''], + 'slovak': ['slovak', 'Slovak', 'false', 'iso8859-2', 'sk_SK', ''], + 'slovene': ['slovene', 'Slovene', 'false', 'iso8859-2', 'sl_SI', ''], + 'spanish': ['spanish', + 'Spanish', + 'false', + 'iso8859-1', + 'es_ES', + '\\deactivatetilden'], + 'swedish': ['swedish', 'Swedish', 'false', 'iso8859-1', 'sv_SE', ''], + 'thai': ['thai', + 'Thai', + 'false', + 'tis620-0', + 'th_TH', + '\\usepackage{thswitch}'], + 'turkish': ['turkish', 'Turkish', 'false', 'iso8859-9', 'tr_TR', ''], + 'ukrainian': ['ukrainian', 'Ukrainian', 'false', 'koi8-u', 'uk_UA', ''], + 'welsh': ['welsh', 'Welsh', 'false', 'iso8859-1', 'cy_GB', '']} diff --git a/lib/lyx2lyx/lyx_1_0_1.py b/lib/lyx2lyx/lyx2lyx_version.py similarity index 83% rename from lib/lyx2lyx/lyx_1_0_1.py rename to lib/lyx2lyx/lyx2lyx_version.py index 199fb3022a..35378747c3 100644 --- a/lib/lyx2lyx/lyx_1_0_1.py +++ b/lib/lyx2lyx/lyx2lyx_version.py @@ -1,6 +1,6 @@ -# This file is part of lyx2lyx -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2004 José Matos +# This file is part of lyx2lyx -*- python -*- +# -*- coding: utf-8 -*- +# Copyright (C) 2006 José Matos # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -16,9 +16,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -convert = [[215, []]] -revert = [] - +version = "1.4.5" if __name__ == "__main__": pass diff --git a/lib/lyx2lyx/lyx_0_06.py b/lib/lyx2lyx/lyx_0_06.py new file mode 100644 index 0000000000..f518cbcde6 --- /dev/null +++ b/lib/lyx2lyx/lyx_0_06.py @@ -0,0 +1,28 @@ +# This file is part of lyx2lyx +# -*- coding: utf-8 -*- +# Copyright (C) 2006 José Matos +# +# 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. + +""" Convert files to the file format generated by lyx 0.6""" + +supported_versions = ["0.6.%d" % i for i in range(5)] + ["0.6"] +convert = [[200, []]] +revert = [] + + +if __name__ == "__main__": + pass + diff --git a/lib/lyx2lyx/lyx_0_08.py b/lib/lyx2lyx/lyx_0_08.py new file mode 100644 index 0000000000..0186decbf2 --- /dev/null +++ b/lib/lyx2lyx/lyx_0_08.py @@ -0,0 +1,34 @@ +# This file is part of lyx2lyx +# -*- coding: utf-8 -*- +# Copyright (C) 2006 José Matos +# +# 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. + +""" Convert files to the file format generated by lyx 0.8""" + +def add_inputencoding(document): + " Add the input encoding, latin1" + document.header.append('\\inputencoding latin1') + document.inputencoding = "latin1" + + +supported_versions = ["0.8.%d" % i for i in range(7)] + ["0.8"] +convert = [[210, [add_inputencoding]]] +revert = [] + + +if __name__ == "__main__": + pass + diff --git a/lib/lyx2lyx/lyx_0_10.py b/lib/lyx2lyx/lyx_0_10.py new file mode 100644 index 0000000000..ebbbf0fc46 --- /dev/null +++ b/lib/lyx2lyx/lyx_0_10.py @@ -0,0 +1,138 @@ +# This file is part of lyx2lyx +# -*- coding: utf-8 -*- +# Copyright (C) 2006 José Matos +# +# 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. + +""" Convert files to the file format generated by lyx 0.10""" + +def regularise_header(document): + " Put each entry in header into a separate line. " + i = 0 + while i < len(document.header): + line = document.header[i] + if len(line.split('\\')) > 1: + tmp = [ '\\'+ token.strip() for token in line.split('\\')][1:] + document.header[i: i+1] = tmp + i += len(tmp) + i += 1 + + +def find_next_space(line, j): + """ Return position of next space or backslash, which one comes + first, starting from position k, if not existing return last + position in line.""" + l = line.find(' ', j) + if l == -1: + l = len(line) + k = line.find('\\', j) + if k == -1: + k = len(line) + + if k < l: + return k + return l + + +def regularise_body(document): + """ Place tokens starting with a backslash into a separate line. """ + + getline_tokens = ["added_space_bottom", "added_space_top", + "align", "layout", "fill_bottom", "fill_top", + "labelwidthstring", "pagebreak_top", + "pagebreak_bottom", "noindent"] + + noargs_tokens = ["backslash", "begin_deeper", "end_deeper", + "end_float", "end_inset", "hfill", "newline", + "protected_separator"] + + onearg_tokens = ["bar", "begin_float", "family", "latex", "shape", + "size", "series", "cursor"] + + i = 0 + while i < len(document.body): + line = document.body[i] + j = 0 + tmp = [] + while j < len(line): + k = line.find('\\', j) + + if k == -1: + tmp += [line[j:]] + break + + if k != j: + tmp += [line[j: k]] + j = k + + k = find_next_space(line, j+1) + + # These tokens take the rest of the line + token = line[j+1:k] + if token in getline_tokens: + tmp += [line[j:]] + break + + # These tokens take no arguments + if token in noargs_tokens: + tmp += [line[j:k]] + j = k + continue + + # These tokens take one argument + if token in onearg_tokens: + k = find_next_space(line, k + 1) + tmp += [line[j:k]] + j = k + continue + + # Special treatment for insets + if token in ["begin_inset"]: + l = find_next_space(line, k + 1) + inset = line[k+1: l] + + if inset == "Latex": + tmp += [line[j:l]] + j = l + continue + + if inset in ["LatexCommand", "LatexDel"]: + tmp += [line[j:]] + break + + if inset == "Quotes": + l = find_next_space(line, l + 1) + tmp += [line[j:l]] + j = l + continue + + document.warning("unkown inset %s" % line) + assert(False) + + # We are inside a latex inset, pass the text verbatim + tmp += [line[j:]] + break + + document.body[i: i+1] = tmp + i += len(tmp) + + +supported_versions = ["0.10.%d" % i for i in range(8)] + ["0.10"] +convert = [[210, [regularise_header, regularise_body]]] +revert = [] + + +if __name__ == "__main__": + pass diff --git a/lib/lyx2lyx/lyx_0_12.py b/lib/lyx2lyx/lyx_0_12.py index 8b07ac493d..f381eb817d 100644 --- a/lib/lyx2lyx/lyx_0_12.py +++ b/lib/lyx2lyx/lyx_0_12.py @@ -1,6 +1,6 @@ # This file is part of lyx2lyx -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2003-2004 José Matos +# -*- coding: utf-8 -*- +# Copyright (C) 2003-2004 José Matos # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -16,41 +16,46 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +""" Convert files to the file format generated by lyx 0.12""" + import re -import string from parser_tools import find_token, find_re, check_token -def space_before_layout(file): - lines = file.body +def space_before_layout(document): + " Remove empty line before \\layout. " + lines = document.body 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: + prot_space = lines[i-2].find('\\protected_separator') + if lines[i - 1] == '' and prot_space == -1: del lines[i-1] i = i + 1 -def formula_inset_space_eat(file): - lines = file.body - i=0 +def formula_inset_space_eat(document): + " Remove space after inset formula." + lines = document.body + i = 0 while 1: i = find_token(lines, "\\begin_inset Formula", i) - if i == -1: break + 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 1 or 2 to 4 -def update_tabular(file): - lines = file.body +def update_tabular(document): + " Update from tabular format 1 or 2 to 4." + lines = document.body lyxtable_re = re.compile(r".*\\LyXTable$") - i=0 + i = 0 while 1: i = find_re(lines, lyxtable_re, i) if i == -1: @@ -58,10 +63,10 @@ def update_tabular(file): i = i + 1 format = lines[i][8:] - lines[i]='multicol4' + lines[i] = 'multicol4' i = i + 1 - rows = int(string.split(lines[i])[0]) - columns = int(string.split(lines[i])[1]) + rows = int(lines[i].split()[0]) + columns = int(lines[i].split()[1]) lines[i] = lines[i] + ' 0 0 -1 -1 -1 -1' i = i + 1 @@ -74,27 +79,34 @@ def update_tabular(file): lines[i] = lines[i] + ' ' i = i + 1 - while string.strip(lines[i]): + while lines[i].strip(): if not format: lines[i] = lines[i] + ' 1 1' lines[i] = lines[i] + ' 0 0 0' i = i + 1 - lines[i] = string.strip(lines[i]) + lines[i] = lines[i].strip() -def final_dot(file): - lines = file.body + +def final_dot(document): + " Merge lines if the dot is the final character." + lines = document.body 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] != '': + + 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(file): - lines = file.body +def update_inset_label(document): + " Update inset Label." + lines = document.body i = 0 while 1: i = find_token(lines, '\\begin_inset Label', i) @@ -104,26 +116,32 @@ def update_inset_label(file): i = i + 1 -def update_latexdel(file): - lines = file.body +def update_latexdel(document): + " Update inset LatexDel." + lines = document.body 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') + lines[i] = lines[i].replace('\\begin_inset LatexDel', + '\\begin_inset LatexCommand') i = i + 1 -def update_vfill(file): - lines = file.body +def update_vfill(document): + " Update fill_top and fill_bottom." + lines = document.body 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') + lines[i] = lines[i].replace('\\fill_top', + '\\added_space_top vfill') + lines[i] = lines[i].replace('\\fill_bottom', + '\\added_space_bottom vfill') -def update_space_units(file): - lines = file.body +def update_space_units(document): + " Update space units." + lines = document.body added_space_bottom = re.compile(r'\\added_space_bottom ([^ ]*)') added_space_top = re.compile(r'\\added_space_top ([^ ]*)') for i in range(len(lines)): @@ -131,17 +149,18 @@ def update_space_units(file): 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) + lines[i] = lines[i].replace(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) + lines[i] = lines[i].replace(old, new) -def remove_cursor(file): - lines = file.body +def remove_cursor(document): + " Remove cursor, it is not saved on the file anymore." + lines = document.body i = 0 cursor_re = re.compile(r'.*(\\cursor \d*)') while 1: @@ -149,15 +168,16 @@ def remove_cursor(file): if i == -1: break cursor = cursor_re.search(lines[i]).group(1) - lines[i]= string.replace(lines[i], cursor, '') + lines[i] = lines[i].replace(cursor, '') i = i + 1 -def remove_empty_insets(file): - lines = file.body +def remove_empty_insets(document): + " Remove empty insets." + lines = document.body i = 0 while 1: - i = find_token(lines, '\\begin_inset ',i) + i = find_token(lines, '\\begin_inset ', i) if i == -1: break if lines[i] == '\\begin_inset ' and lines[i+1] == '\\end_inset ': @@ -166,8 +186,9 @@ def remove_empty_insets(file): i = i + 1 -def remove_formula_latex(file): - lines = file.body +def remove_formula_latex(document): + " Remove formula latex." + lines = document.body i = 0 while 1: i = find_token(lines, '\\latex formula_latex ', i) @@ -181,15 +202,17 @@ def remove_formula_latex(file): del lines[i] -def add_end_document(file): - lines = file.body +def add_end_document(document): + " Add \\the_end to the end of the document." + lines = document.body i = find_token(lines, '\\the_end', 0) if i == -1: lines.append('\\the_end') -def header_update(file): - lines = file.header +def header_update(document): + " Update document header." + lines = document.header i = 0 l = len(lines) while i < l: @@ -197,12 +220,12 @@ def header_update(file): lines[i] = lines[i][:-1] if check_token(lines[i], '\\epsfig'): - lines[i] = string.replace(lines[i], '\\epsfig', '\\graphics') + lines[i] = lines[i].replace('\\epsfig', '\\graphics') i = i + 1 continue if check_token(lines[i], '\\papersize'): - size = string.split(lines[i])[1] + size = lines[i].split()[1] new_size = size paperpackage = "" @@ -225,7 +248,7 @@ def header_update(file): if check_token(lines[i], '\\baselinestretch'): - size = string.split(lines[i])[1] + size = lines[i].split()[1] if size == '1.00': name = 'single' elif size == '1.50': @@ -241,17 +264,18 @@ def header_update(file): i = i + 1 -def update_latexaccents(file): - body = file.body +def update_latexaccents(document): + " Update latex accent insets." + body = document.body i = 1 while 1: i = find_token(body, '\\i ', i) if i == -1: return - contents = string.strip(body[i][2:]) + contents = body[i][2:].strip() - if string.find(contents, '{') != -1 and string.find(contents, '}') != -1: + if contents.find('{') != -1 and contents.find('}') != -1: i = i + 1 continue @@ -269,26 +293,47 @@ def update_latexaccents(file): i = i + 1 -def obsolete_latex_title(file): - body = file.body +def obsolete_latex_title(document): + " Replace layout Latex_Title with Title." + body = document.body i = 0 while 1: i = find_token(body, '\\layout', i) if i == -1: return - if string.find(string.lower(body[i]),'latex_title') != -1: + if body[i].lower().find('latex_title') != -1: body[i] = '\\layout Title' i = i + 1 +def remove_inset_latex(document): + "Replace inset latex with layout LaTeX" + body = document.body + + i = 0 + while 1: + i = find_token(body, '\\begin_inset Latex', i) + if i == -1: + return + + body[i] = body[i].replace('\\begin_inset Latex', '\\layout LaTeX') + i = find_token(body, '\\end_inset', i) + if i == -1: + #this should not happen + return + del body[i] + + +supported_versions = ["0.12.0","0.12.1","0.12"] convert = [[215, [header_update, add_end_document, remove_cursor, final_dot, update_inset_label, update_latexdel, update_space_units, space_before_layout, formula_inset_space_eat, update_tabular, update_vfill, remove_empty_insets, - remove_formula_latex, update_latexaccents, obsolete_latex_title]]] + remove_formula_latex, update_latexaccents, + obsolete_latex_title, remove_inset_latex]]] revert = [] diff --git a/lib/lyx2lyx/lyx_1_0_0.py b/lib/lyx2lyx/lyx_1_0.py similarity index 71% rename from lib/lyx2lyx/lyx_1_0_0.py rename to lib/lyx2lyx/lyx_1_0.py index 6ca27628b4..7862b61d96 100644 --- a/lib/lyx2lyx/lyx_1_0_0.py +++ b/lib/lyx2lyx/lyx_1_0.py @@ -1,6 +1,6 @@ # This file is part of lyx2lyx -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2004 José Matos +# -*- coding: utf-8 -*- +# Copyright (C) 2004 José Matos # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -16,29 +16,33 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +""" Convert files to the file format generated by lyx 1.0""" + import re -import string from parser_tools import find_token, find_re -def obsolete_latex_title(file): - body = file.body +def obsolete_latex_title(document): + " Replace LatexTitle layout with Title. " + + body = document.body i = 0 while 1: i = find_token(body, '\\layout', i) if i == -1: return - if string.find(string.lower(body[i]),'latex title') != -1: + if body[i].lower().find('latex title') != -1: body[i] = '\\layout Title' i = i + 1 -# Update from tabular format 3 to 4 if necessary -def update_tabular(file): - lines = file.body +def update_tabular(document): + " Update from tabular format 3 to 4 if necessary." + + lines = document.body lyxtable_re = re.compile(r".*\\LyXTable$") - i=0 + i = 0 while 1: i = find_re(lines, lyxtable_re, i) if i == -1: @@ -49,10 +53,10 @@ def update_tabular(file): if format != '3': continue - lines[i]='multicol4' + lines[i] = 'multicol4' i = i + 1 - rows = int(string.split(lines[i])[0]) - columns = int(string.split(lines[i])[1]) + rows = int(lines[i].split()[0]) + columns = int(lines[i].split()[1]) lines[i] = lines[i] + ' 0 0 -1 -1 -1 -1' i = i + 1 @@ -65,13 +69,14 @@ def update_tabular(file): lines[i] = lines[i] + ' ' i = i + 1 - while string.strip(lines[i]): + while lines[i].strip(): lines[i] = lines[i] + ' 0 0 0' i = i + 1 - lines[i] = string.strip(lines[i]) + lines[i] = lines[i].strip() +supported_versions = ["1.0.%d" % i for i in range(5)] + ["1.0"] convert = [[215, [obsolete_latex_title, update_tabular]]] revert = [] diff --git a/lib/lyx2lyx/lyx_1_1_4.py b/lib/lyx2lyx/lyx_1_1.py similarity index 78% rename from lib/lyx2lyx/lyx_1_1_4.py rename to lib/lyx2lyx/lyx_1_1.py index 199fb3022a..5927c0f37e 100644 --- a/lib/lyx2lyx/lyx_1_1_4.py +++ b/lib/lyx2lyx/lyx_1_1.py @@ -1,6 +1,6 @@ # This file is part of lyx2lyx -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2004 José Matos +# -*- coding: utf-8 -*- +# Copyright (C) 2004 José Matos # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -16,6 +16,9 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +""" Convert files to the file format generated by lyx 1.1 series, until 1.1.4""" + +supported_versions = ["1.1.%d" % i for i in range(5)] + ["1.1"] convert = [[215, []]] revert = [] diff --git a/lib/lyx2lyx/lyx_1_1_5.py b/lib/lyx2lyx/lyx_1_1_5.py index d8dc59006e..8720cfcefb 100644 --- a/lib/lyx2lyx/lyx_1_1_5.py +++ b/lib/lyx2lyx/lyx_1_1_5.py @@ -1,6 +1,6 @@ -# This file is part of lyx2lyx -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2002-2004 José Matos +# This document is part of lyx2lyx +# -*- coding: utf-8 -*- +# Copyright (C) 2002-2004 José Matos # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -16,15 +16,29 @@ # 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, get_layout +""" Convert files to the file format generated by lyx 1.1.5""" +import re +from parser_tools import find_token, find_token_backwards, find_re + +#################################################################### +# Private helper functions + +def get_layout(line, default_layout): + " Get the line layout, beware of the empty layout." + tokens = line.split() + if len(tokens) > 1: + return tokens[1] + return default_layout + + +#################################################################### math_env = ["\\[","\\begin{eqnarray*}","\\begin{eqnarray}","\\begin{equation}"] -def replace_protected_separator(file): - lines = file.body +def replace_protected_separator(document): + " Replace protected separator. " + lines = document.body i=0 while 1: i = find_token(lines, "\\protected_separator", i) @@ -32,7 +46,7 @@ def replace_protected_separator(file): break j = find_token_backwards(lines, "\\layout", i) #if j == -1: print error - layout = get_layout(lines[j], file.default_layout) + layout = get_layout(lines[j], document.default_layout) if layout == "LyX-Code": result = "" @@ -47,8 +61,9 @@ def replace_protected_separator(file): del lines[i] -def merge_formula_inset(file): - lines = file.body +def merge_formula_inset(document): + " Merge formula insets. " + lines = document.body i=0 while 1: i = find_token(lines, "\\begin_inset Formula", i) @@ -59,9 +74,9 @@ def merge_formula_inset(file): i = i + 1 -# Update from tabular format 4 to 5 if necessary -def update_tabular(file): - lines = file.body +def update_tabular(document): + " Update from tabular format 4 to 5 if necessary. " + lines = document.body lyxtable_re = re.compile(r".*\\LyXTable$") i=0 while 1: @@ -75,16 +90,16 @@ def update_tabular(file): lines[i]='multicol5' i = i + 1 - rows = int(string.split(lines[i])[0]) - columns = int(string.split(lines[i])[1]) + rows = int(lines[i].split()[0]) + columns = int(lines[i].split()[1]) i = i + rows + 1 for j in range(columns): - col_info = string.split(lines[i]) + col_info = lines[i].split() if len(col_info) == 3: lines[i] = lines[i] + '"" ""' else: - lines[i] = string.join(col_info[:3]) + ' "%s" ""' % col_info[3] + lines[i] = " ".join(col_info[:3]) + ' "%s" ""' % col_info[3] i = i + 1 while lines[i]: @@ -92,26 +107,30 @@ def update_tabular(file): i = i + 1 -def update_toc(file): - lines = file.body +def update_toc(document): + " Update table of contents. " + lines = document.body i = 0 while 1: - i = find_token(lines, '\\begin_inset LatexCommand \\tableofcontents', i) + i = find_token(lines, + '\\begin_inset LatexCommand \\tableofcontents', i) if i == -1: break lines[i] = lines[i] + '{}' i = i + 1 -def remove_cursor(file): - lines = file.body +def remove_cursor(document): + " Remove cursor. " + lines = document.body i = find_token(lines, '\\cursor', 0) if i != -1: del lines[i] -def remove_vcid(file): - lines = file.header +def remove_vcid(document): + " Remove \\lyxvcid and \\lyxrcsid. " + lines = document.header i = find_token(lines, '\\lyxvcid', 0) if i != -1: del lines[i] @@ -120,16 +139,18 @@ def remove_vcid(file): del lines[i] -def first_layout(file): - lines = file.body +def first_layout(document): + " Fix first layout, if empty use the default layout." + lines = document.body while (lines[0] == ""): del lines[0] if lines[0][:7] != "\\layout": - lines[:0] = ['\\layout %s' % file.default_layout, ''] + lines[:0] = ['\\layout %s' % document.default_layout, ''] -def remove_space_in_units(file): - lines = file.header +def remove_space_in_units(document): + " Remove space in units. " + lines = document.header margins = ["\\topmargin","\\rightmargin", "\\leftmargin","\\bottommargin"] @@ -148,8 +169,9 @@ def remove_space_in_units(file): i = i + 1 -def latexdel_getargs(file, i): - lines = file.body +def latexdel_getargs(document, i): + " Get arguments from latexdel insets. " + lines = document.body # play safe, clean empty lines while 1: @@ -162,10 +184,10 @@ def latexdel_getargs(file, i): if i == j: del lines[i] else: - file.warning("Unexpected end of inset.") + document.warning("Unexpected end of inset.") j = find_token(lines, '\\begin_inset LatexDel }{', i) - ref = string.join(lines[i:j]) + ref = " ".join(lines[i:j]) del lines[i:j + 1] # play safe, clean empty lines @@ -178,57 +200,64 @@ def latexdel_getargs(file, i): if i == j: del lines[i] else: - file.warning("Unexpected end of inset.") + document.warning("Unexpected end of inset.") j = find_token(lines, '\\begin_inset LatexDel }', i) - label = string.join(lines[i:j]) + label = " ".join(lines[i:j]) del lines[i:j + 1] return ref, label -def update_ref(file): - lines = file.body +def update_ref(document): + " Update reference inset. " + lines = document.body i = 0 while 1: i = find_token(lines, '\\begin_inset LatexCommand', i) if i == -1: return - if string.split(lines[i])[-1] == "\\ref{": + if lines[i].split()[-1] == "\\ref{": i = i + 1 - ref, label = latexdel_getargs(file, i) + ref, label = latexdel_getargs(document, i) lines[i - 1] = "%s[%s]{%s}" % (lines[i - 1][:-1], ref, label) i = i + 1 -def update_latexdel(file): - lines = file.body +def update_latexdel(document): + " Remove latexdel insets. " + lines = document.body i = 0 latexdel_re = re.compile(r".*\\begin_inset LatexDel") while 1: i = find_re(lines, latexdel_re, i) if i == -1: return - lines[i] = string.replace(lines[i],'\\begin_inset LatexDel', '\\begin_inset LatexCommand') + lines[i] = lines[i].replace('\\begin_inset LatexDel', + '\\begin_inset LatexCommand') - j = string.find(lines[i],'\\begin_inset') + j = lines[i].find('\\begin_inset') lines.insert(i+1, lines[i][j:]) - lines[i] = string.strip(lines[i][:j]) + lines[i] = lines[i][:j].strip() i = i + 1 - if string.split(lines[i])[-1] in ("\\url{", "\\htmlurl{"): + if lines[i].split()[-1] in ("\\url{", "\\htmlurl{"): i = i + 1 - ref, label = latexdel_getargs(file, i) + ref, label = latexdel_getargs(document, i) lines[i -1] = "%s[%s]{%s}" % (lines[i-1][:-1], label, ref) i = i + 1 -convert = [[216, [first_layout, remove_vcid, remove_cursor, update_toc, - replace_protected_separator, merge_formula_inset, - update_tabular, remove_space_in_units, update_ref, update_latexdel]]] +supported_versions = ["1.1.5","1.1.5fix1","1.1.5fix2","1.1"] +convert = [[216, [first_layout, remove_vcid, remove_cursor, + update_toc, replace_protected_separator, + merge_formula_inset, update_tabular, + remove_space_in_units, update_ref, + update_latexdel]]] + revert = [] if __name__ == "__main__": diff --git a/lib/lyx2lyx/lyx_1_1_6.py b/lib/lyx2lyx/lyx_1_1_6_0.py similarity index 91% rename from lib/lyx2lyx/lyx_1_1_6.py rename to lib/lyx2lyx/lyx_1_1_6_0.py index 8d9773235f..56de363325 100644 --- a/lib/lyx2lyx/lyx_1_1_6.py +++ b/lib/lyx2lyx/lyx_1_1_6_0.py @@ -1,6 +1,6 @@ # This file is part of lyx2lyx -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2002-2004 José Matos +# -*- coding: utf-8 -*- +# Copyright (C) 2002-2004 José Matos # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -16,14 +16,15 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +""" Convert files to the file format generated by lyx 1.1.6, until fix2""" + 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(file): - lines = file.body +def update_tabular(document): + " Update tabular to version 1 (xml like syntax). " + lines = document.body i=0 while 1: i = find_re(lines, lyxtable_re, i) @@ -41,7 +42,7 @@ def update_tabular(file): i = i + 1 lines[i] = "\\begin_inset Tabular" i = i + 1 - head = string.split(lines[i]) + head = lines[i].split() rows = int(head[0]) columns = int(head[1]) @@ -54,8 +55,8 @@ def update_tabular(file): row_info = [] cont_row = [] for j in range(rows): - row_info.append(string.split(lines[i])) - if string.split(lines[i])[2] == '1': + row_info.append(lines[i].split()) + if lines[i].split()[2] == '1': cont_row.append(j) del lines[i] @@ -100,13 +101,13 @@ def update_tabular(file): continue if l == ncells -1: - # the end variable refers to cell end, not to file end. + # the end variable refers to cell end, not to document end. end = find_tokens(lines, ['\\layout','\\the_end','\\end_deeper','\\end_float'], i) else: end = find_token(lines, '\\newline', i) if end == -1: - file.error("Malformed LyX file.") + document.error("Malformed LyX file.") end = end - i while end > 0: @@ -114,7 +115,7 @@ def update_tabular(file): del lines[i] end = end -1 - if string.find(lines[i],'\\newline') != -1: + if lines[i].find('\\newline') != -1: del lines[i] l = l + 1 @@ -146,7 +147,7 @@ def update_tabular(file): tmp.append('' % (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 %s' % file.default_layout) + tmp.append('\\layout %s' % document.default_layout) tmp.append('') if cell_info[m][0] != '2': @@ -179,8 +180,8 @@ def update_tabular(file): prop_exp = re.compile(r"\\(\S*)\s*(\S*)") - def set_paragraph_properties(lines, prop_dict): + " Set paragraph properties." # we need to preserve the order of options properties = ["family","series","shape","size", "emph","bar","noun","latex","color"] @@ -263,19 +264,22 @@ def set_paragraph_properties(lines, prop_dict): return result[:] -def update_language(file): - header = file.header +def update_language(document): + """ Update document language, if language is default convert it to + english.""" + header = document.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': + if header[i].split()[1] == 'default': header[i] = '\\language english' return +supported_versions = ["1.1.6","1.1.6fix1","1.1.6fix2","1.1"] convert = [[217, [update_tabular, update_language]]] revert = [] diff --git a/lib/lyx2lyx/lyx_1_1_6fix3.py b/lib/lyx2lyx/lyx_1_1_6_3.py similarity index 80% rename from lib/lyx2lyx/lyx_1_1_6fix3.py rename to lib/lyx2lyx/lyx_1_1_6_3.py index f7656d796a..f0be612103 100644 --- a/lib/lyx2lyx/lyx_1_1_6fix3.py +++ b/lib/lyx2lyx/lyx_1_1_6_3.py @@ -1,6 +1,6 @@ # This file is part of lyx2lyx -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2002-2004 José Matos +# -*- coding: utf-8 -*- +# Copyright (C) 2002-2004 José Matos # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -16,11 +16,13 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +""" Convert files to the file format generated by lyx 1.1.6, fix3 and fix4""" + import re -import string from parser_tools import find_token, find_re def bool_table(item): + " Convert 0, 1 to false, true." if item == "0": return "false" # should emit a warning if item != "1" @@ -32,9 +34,10 @@ align_table = {"0": "top", "2": "left", "4": "right", "8": "center"} use_table = {"0": "none", "1": "parbox"} table_meta_re = re.compile(r'') -def update_tabular(file): +def update_tabular(document): + " Update tabular format to version 2 (xml like syntax)." regexp = re.compile(r'^\\begin_inset\s+Tabular') - lines = file.body + lines = document.body i=0 while 1: i = find_re(lines, regexp, i) @@ -51,7 +54,7 @@ def update_tabular(file): j = find_token(lines, '', i) + 1 if j == 0: - file.warning( "Error: Bad lyx format i=%d j=%d" % (i,j)) + document.warning( "Error: Bad lyx format i=%d j=%d" % (i,j)) break new_table = table_update(lines[i:j]) @@ -65,7 +68,8 @@ features_re = re.compile(r'') def table_update(lines): - lines[1] = string.replace(lines[1], ' -# Copyright (C) 2004 José Matos +# Copyright (C) 2004 José Matos # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -17,13 +17,86 @@ # 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 +""" Convert files to the file format generated by lyx 1.2""" + 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, get_layout +from parser_tools import find_token, find_token_backwards, \ + find_tokens, find_tokens_backwards, \ + find_beginning_of, find_end_of, find_re, \ + is_nonempty_line, find_nonempty_line, \ + get_value, check_token + +#################################################################### +# Private helper functions + +def get_layout(line, default_layout): + " Get layout, if empty return the default layout." + tokens = line.split() + if len(tokens) > 1: + return tokens[1] + return default_layout + + +def get_paragraph(lines, i, format): + " Finds the paragraph that contains line i." + begin_layout = "\\layout" + + while i != -1: + i = find_tokens_backwards(lines, ["\\end_inset", begin_layout], i) + if i == -1: return -1 + if check_token(lines[i], begin_layout): + return i + i = find_beginning_of_inset(lines, i) + return -1 + + +def get_next_paragraph(lines, i, format): + " Finds the paragraph after the paragraph that contains line i." + tokens = ["\\begin_inset", "\\layout", "\\end_float", "\\the_end"] + + while i != -1: + i = find_tokens(lines, tokens, i) + if not check_token(lines[i], "\\begin_inset"): + return i + i = find_end_of_inset(lines, i) + return -1 + + +def find_beginning_of_inset(lines, i): + " Find beginning of inset, where lines[i] is included." + return find_beginning_of(lines, i, "\\begin_inset", "\\end_inset") + + +def find_end_of_inset(lines, i): + " Finds the matching \end_inset" + return find_end_of(lines, i, "\\begin_inset", "\\end_inset") + + +def find_end_of_tabular(lines, i): + " Finds the matching end of tabular." + return find_end_of(lines, i, " i+1: - j2 = get_next_paragraph(lines, j + 1, file.format + 1) + j2 = get_next_paragraph(lines, j + 1, document.format + 1) lines[j2:j2] = ["\\end_deeper "]*(i2-(i+1)) new = floats[floattype]+[""] @@ -116,7 +188,7 @@ def remove_oldfloat(file): # 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, file.format + 1) + k = get_paragraph(lines, i, document.format + 1) flag = 0 for token in font_tokens: if find_token(lines, token, k, i) != -1: @@ -126,7 +198,7 @@ def remove_oldfloat(file): flag = 1 new.append("") if token == "\\lang": - new.append(token+" "+ file.language) + new.append(token+" "+ document.language) else: new.append(token+" default ") @@ -138,8 +210,9 @@ pextra_type2_rexp = re.compile(r".*\\pextra_type\s+[12]") pextra_type2_rexp2 = re.compile(r".*(\\layout|\\pextra_type\s+2)") pextra_widthp = re.compile(r"\\pextra_widthp") -def remove_pextra(file): - lines = file.body +def remove_pextra(document): + " Remove pextra token." + lines = document.body i = 0 flag = 0 while 1: @@ -179,10 +252,10 @@ def remove_pextra(file): if hfill: start = ["","\hfill",""]+start else: - start = ['\\layout %s' % file.default_layout,''] + start + start = ['\\layout %s' % document.default_layout,''] + start j0 = find_token_backwards(lines,"\\layout", i-1) - j = get_next_paragraph(lines, i, file.format + 1) + j = get_next_paragraph(lines, i, document.format + 1) count = 0 while 1: @@ -210,6 +283,7 @@ def remove_pextra(file): def is_empty(lines): + " Are all the lines empty?" return filter(is_nonempty_line, lines) == [] @@ -218,13 +292,14 @@ ert_rexp = re.compile(r"\\begin_inset|\\hfill|.*\\SpecialChar") spchar_rexp = re.compile(r"(.*)(\\SpecialChar.*)") -def remove_oldert(file): +def remove_oldert(document): + " Remove old ERT inset." ert_begin = ["\\begin_inset ERT", "status Collapsed", "", - '\\layout %s' % file.default_layout, + '\\layout %s' % document.default_layout, ""] - lines = file.body + lines = document.body i = 0 while 1: i = find_tokens(lines, ["\\latex latex", "\\layout LaTeX"], i) @@ -249,7 +324,7 @@ def remove_oldert(file): new = [] new2 = [] if check_token(lines[i], "\\layout LaTeX"): - new = ['\layout %s' % file.default_layout, "", ""] + new = ['\layout %s' % document.default_layout, "", ""] k = i+1 while 1: @@ -331,9 +406,9 @@ def remove_oldert(file): del lines[i] -# ERT insert are hidden feature of lyx 1.1.6. This might be removed in the future. -def remove_oldertinset(file): - lines = file.body +def remove_oldertinset(document): + " ERT insert are hidden feature of lyx 1.1.6. This might be removed in the future." + lines = document.body i = 0 while 1: i = find_token(lines, "\\begin_inset ERT", i) @@ -341,7 +416,7 @@ def remove_oldertinset(file): break j = find_end_of_inset(lines, i) k = find_token(lines, "\\layout", i+1) - l = get_paragraph(lines, i, file.format + 1) + l = get_paragraph(lines, i, document.format + 1) if lines[k] == lines[l]: # same layout k = k+1 new = lines[k:j] @@ -349,11 +424,12 @@ def remove_oldertinset(file): i = i+1 -def is_ert_paragraph(file, i): - lines = file.body +def is_ert_paragraph(document, i): + " Is this a ert paragraph? " + lines = document.body if not check_token(lines[i], "\\layout"): return 0 - if not file.is_default_layout(get_layout(lines[i], file.default_layout)): + if not document.is_default_layout(get_layout(lines[i], document.default_layout)): return 0 i = find_nonempty_line(lines, i+1) @@ -365,17 +441,18 @@ def is_ert_paragraph(file, i): return check_token(lines[k], "\\layout") -def combine_ert(file): - lines = file.body +def combine_ert(document): + " Combine ERT paragraphs." + lines = document.body i = 0 while 1: i = find_token(lines, "\\begin_inset ERT", i) if i == -1: break - j = get_paragraph(lines, i, file.format + 1) + j = get_paragraph(lines, i, document.format + 1) count = 0 text = [] - while is_ert_paragraph(file, j): + while is_ert_paragraph(document, j): count = count+1 i2 = find_token(lines, "\\layout", j+1) @@ -395,20 +472,23 @@ def combine_ert(file): oldunits = ["pt", "cm", "in", "text%", "col%"] def get_length(lines, name, start, end): + " Get lenght." i = find_token(lines, name, start, end) if i == -1: return "" - x = string.split(lines[i]) + x = lines[i].split() return x[2]+oldunits[int(x[1])] def write_attribute(x, token, value): + " Write attribute." if value != "": x.append("\t"+token+" "+value) -def remove_figinset(file): - lines = file.body +def remove_figinset(document): + " Remove figinset." + lines = document.body i = 0 while 1: i = find_token(lines, "\\begin_inset Figure", i) @@ -416,9 +496,9 @@ def remove_figinset(file): 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" + if ( len(lines[i].split()) > 2 ): + lyxwidth = lines[i].split()[3]+"pt" + lyxheight = lines[i].split()[4]+"pt" else: lyxwidth = "" lyxheight = "" @@ -476,15 +556,13 @@ def remove_figinset(file): lines[i:j+1] = new -## -# Convert tabular format 2 to 3 -# attr_re = re.compile(r' \w*="(false|0|)"') line_re = re.compile(r'<(features|column|row|cell)') -def update_tabular(file): +def update_tabular(document): + " Convert tabular format 2 to 3." regexp = re.compile(r'^\\begin_inset\s+Tabular') - lines = file.body + lines = document.body i = 0 while 1: i = find_re(lines, regexp, i) @@ -493,9 +571,9 @@ def update_tabular(file): for k in get_tabular_lines(lines, i): if check_token(lines[k], "') + " Insert attribute in lines[i]." + last = lines[i].find('>') lines[i] = lines[i][:last] + ' ' + attribute + lines[i][last:] @@ -611,9 +692,10 @@ rows_re = re.compile(r'rows="(\d*)"') longtable_re = re.compile(r'islongtable="(\w)"') ltvalues_re = re.compile(r'endhead="(-?\d*)" endfirsthead="(-?\d*)" endfoot="(-?\d*)" endlastfoot="(-?\d*)"') lt_features_re = re.compile(r'(endhead="-?\d*" endfirsthead="-?\d*" endfoot="-?\d*" endlastfoot="-?\d*")') -def update_longtables(file): +def update_longtables(document): + " Update longtables to new format." regexp = re.compile(r'^\\begin_inset\s+Tabular') - body = file.body + body = document.body i = 0 while 1: i = find_re(body, regexp, i) @@ -643,7 +725,7 @@ def update_longtables(file): # remove longtable elements from features features = lt_features_re.search(body[i]) if features: - body[i] = string.replace(body[i], features.group(1), "") + body[i] = body[i].replace(features.group(1), "") continue row_info = row() * rows @@ -680,9 +762,9 @@ def update_longtables(file): i = i + 1 -# Figure insert are hidden feature of lyx 1.1.6. This might be removed in the future. -def fix_oldfloatinset(file): - lines = file.body +def fix_oldfloatinset(document): + " Figure insert are hidden feature of lyx 1.1.6. This might be removed in the future." + lines = document.body i = 0 while 1: i = find_token(lines, "\\begin_inset Float ", i) @@ -694,8 +776,9 @@ def fix_oldfloatinset(file): i = i+1 -def change_listof(file): - lines = file.body +def change_listof(document): + " Change listof insets." + lines = document.body i = 0 while 1: i = find_token(lines, "\\begin_inset LatexCommand \\listof", i) @@ -706,14 +789,15 @@ def change_listof(file): i = i+1 -def change_infoinset(file): - lines = file.body +def change_infoinset(document): + " Change info inset." + lines = document.body i = 0 while 1: i = find_token(lines, "\\begin_inset Info", i) if i == -1: break - txt = string.lstrip(lines[i][18:]) + txt = lines[i][18:].lstrip() new = ["\\begin_inset Note", "collapsed true", ""] j = find_token(lines, "\\end_inset", i) if j == -1: @@ -724,8 +808,8 @@ def change_infoinset(file): note_lines = [txt]+note_lines for line in note_lines: - new = new + ['\layout %s' % file.default_layout, ""] - tmp = string.split(line, '\\') + new = new + ['\layout %s' % document.default_layout, ""] + tmp = line.split('\\') new = new + [tmp[0]] for x in tmp[1:]: new = new + ["\\backslash ", x] @@ -733,8 +817,9 @@ def change_infoinset(file): i = i+5 -def change_header(file): - lines = file.header +def change_header(document): + " Update header." + lines = document.header i = find_token(lines, "\\use_amsmath", 0) if i == -1: return @@ -742,6 +827,7 @@ def change_header(file): "\use_numerical_citations 0"] +supported_versions = ["1.2.%d" % i for i in range(5)] + ["1.2"] convert = [[220, [change_header, change_listof, fix_oldfloatinset, update_tabular, update_longtables, remove_pextra, remove_oldfloat, remove_figinset, remove_oldertinset, diff --git a/lib/lyx2lyx/lyx_1_3.py b/lib/lyx2lyx/lyx_1_3.py index acb8d9f62f..91dae09ec0 100644 --- a/lib/lyx2lyx/lyx_1_3.py +++ b/lib/lyx2lyx/lyx_1_3.py @@ -1,7 +1,7 @@ # This file is part of lyx2lyx -# -*- coding: iso-8859-1 -*- +# -*- coding: utf-8 -*- # Copyright (C) 2002 Dekel Tsur -# Copyright (C) 2004 José Matos +# Copyright (C) 2004 José Matos # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -17,13 +17,26 @@ # 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 +""" Convert files to the file format generated by lyx 1.3""" + import re -from parser_tools import find_token, find_end_of_inset, get_value,\ +from parser_tools import find_token, find_end_of, get_value,\ find_token_exact, del_token -def change_insetgraphics(file): - lines = file.body +#################################################################### +# Private helper functions + +def find_end_of_inset(lines, i): + "Finds the matching \end_inset" + return find_end_of(lines, i, "\\begin_inset", "\\end_inset") + +# End of helper functions +#################################################################### + + +def change_insetgraphics(document): + " Change inset Graphics." + lines = document.body i = 0 while 1: i = find_token(lines, "\\begin_inset Graphics", i) @@ -49,7 +62,7 @@ def change_insetgraphics(file): if k == -1: k = find_token_exact(lines, "size_kind", i, j) if k != -1: - size_type = string.split(lines[k])[1] + size_type = lines[k].split()[1] del lines[k] j = j-1 if size_type in ["0", "original"]: @@ -68,7 +81,7 @@ def change_insetgraphics(file): if k == -1: k = find_token_exact(lines, "lyxsize_kind", i, j) if k != -1: - lyxsize_type = string.split(lines[k])[1] + lyxsize_type = lines[k].split()[1] del lines[k] j = j-1 j = del_token(lines, "lyxwidth", i, j) @@ -80,8 +93,9 @@ def change_insetgraphics(file): i = i+1 -def change_tabular(file): - lines = file.body +def change_tabular(document): + " Change tabular." + lines = document.body i = 0 while 1: i = find_token(lines, " -# Copyright (C) 2002-2004 José Matos +# Copyright (C) 2002-2004 José Matos # Copyright (C) 2004-2005 Georg Baum # # This program is free software; you can redistribute it and/or @@ -18,53 +18,108 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +""" Convert files to the file format generated by lyx 1.4""" + import re from os import access, F_OK import os.path -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, find_token_exact, find_tokens_exact,\ - find_re, get_layout +from parser_tools import check_token, find_token, \ + get_value, del_token, is_nonempty_line, \ + find_tokens, find_end_of, find_beginning_of, find_token_exact, find_tokens_exact, \ + find_re, find_tokens_backwards from sys import stdin -from string import replace, split, find, strip, join from lyx_0_12 import update_latexaccents -## -# Remove \color default -# -def remove_color_default(file): +#################################################################### +# Private helper functions + +def get_layout(line, default_layout): + " Get layout, if empty return the default layout." + tokens = line.split() + if len(tokens) > 1: + return tokens[1] + return default_layout + + +def get_paragraph(lines, i, format): + "Finds the paragraph that contains line i." + + if format < 225: + begin_layout = "\\layout" + else: + begin_layout = "\\begin_layout" + while i != -1: + i = find_tokens_backwards(lines, ["\\end_inset", begin_layout], i) + if i == -1: return -1 + if check_token(lines[i], begin_layout): + return i + i = find_beginning_of_inset(lines, i) + return -1 + + +def find_beginning_of_inset(lines, i): + " Find beginning of inset, where lines[i] is included." + return find_beginning_of(lines, i, "\\begin_inset", "\\end_inset") + + +def get_next_paragraph(lines, i, format): + "Finds the paragraph after the paragraph that contains line i." + + if format < 225: + tokens = ["\\begin_inset", "\\layout", "\\end_float", "\\the_end"] + elif format < 236: + tokens = ["\\begin_inset", "\\begin_layout", "\\end_float", "\\end_document"] + else: + tokens = ["\\begin_inset", "\\begin_layout", "\\end_float", "\\end_body", "\\end_document"] + while i != -1: + i = find_tokens(lines, tokens, i) + if not check_token(lines[i], "\\begin_inset"): + return i + i = find_end_of_inset(lines, i) + return -1 + + +def find_end_of_inset(lines, i): + "Finds the matching \end_inset" + return find_end_of(lines, i, "\\begin_inset", "\\end_inset") + +# End of helper functions +#################################################################### + +def remove_color_default(document): + " Remove \color default" i = 0 while 1: - i = find_token(file.body, "\\color default", i) + i = find_token(document.body, "\\color default", i) if i == -1: return - file.body[i] = replace(file.body[i], "\\color default", - "\\color inherit") + document.body[i] = document.body[i].replace("\\color default", + "\\color inherit") -## -# Add \end_header -# -def add_end_header(file): - file.header.append("\\end_header"); +def add_end_header(document): + " Add \end_header" + document.header.append("\\end_header"); -def rm_end_header(file): - i = find_token(file.header, "\\end_header", 0) +def rm_end_header(document): + " Remove \end_header" + i = find_token(document.header, "\\end_header", 0) if i == -1: return - del file.header[i] + del document.header[i] -def convert_amsmath(file): - i = find_token(file.header, "\\use_amsmath", 0) +def convert_amsmath(document): + " Convert \\use_amsmath" + i = find_token(document.header, "\\use_amsmath", 0) if i == -1: - file.warning("Malformed LyX file: Missing '\\use_amsmath'.") + document.warning("Malformed LyX document: Missing '\\use_amsmath'.") return - tokens = split(file.header[i]) + tokens = document.header[i].split() if len(tokens) != 2: - file.warning("Malformed LyX file: Could not parse line '%s'." % file.header[i]) + document.warning("Malformed LyX document: Could not parse line '%s'." % document.header[i]) use_amsmath = '0' else: use_amsmath = tokens[1] @@ -72,19 +127,20 @@ def convert_amsmath(file): # new: 0 == off, 1 == auto, 2 == on # translate off -> auto, since old format 'off' means auto in reality if use_amsmath == '0': - file.header[i] = "\\use_amsmath 1" + document.header[i] = "\\use_amsmath 1" else: - file.header[i] = "\\use_amsmath 2" + document.header[i] = "\\use_amsmath 2" -def revert_amsmath(file): - i = find_token(file.header, "\\use_amsmath", 0) +def revert_amsmath(document): + " Revert \\use_amsmath" + i = find_token(document.header, "\\use_amsmath", 0) if i == -1: - file.warning("Malformed LyX file: Missing '\\use_amsmath'.") + document.warning("Malformed LyX document: Missing '\\use_amsmath'.") return - tokens = split(file.header[i]) + tokens = document.header[i].split() if len(tokens) != 2: - file.warning("Malformed LyX file: Could not parse line '%s'." % file.header[i]) + document.warning("Malformed LyX document: Could not parse line '%s'." % document.header[i]) use_amsmath = '0' else: use_amsmath = tokens[1] @@ -92,58 +148,61 @@ def revert_amsmath(file): # new: 0 == off, 1 == auto, 2 == on # translate auto -> off, since old format 'off' means auto in reality if use_amsmath == '2': - file.header[i] = "\\use_amsmath 1" + document.header[i] = "\\use_amsmath 1" else: - file.header[i] = "\\use_amsmath 0" + document.header[i] = "\\use_amsmath 0" -## -# \SpecialChar ~ -> \InsetSpace ~ -# -def convert_spaces(file): - for i in range(len(file.body)): - file.body[i] = replace(file.body[i],"\\SpecialChar ~","\\InsetSpace ~") +def convert_spaces(document): + " \SpecialChar ~ -> \InsetSpace ~" + for i in range(len(document.body)): + document.body[i] = document.body[i].replace("\\SpecialChar ~", + "\\InsetSpace ~") -def revert_spaces(file): +def revert_spaces(document): + " \InsetSpace ~ -> \SpecialChar ~" regexp = re.compile(r'(.*)(\\InsetSpace\s+)(\S+)') i = 0 while 1: - i = find_re(file.body, regexp, i) + i = find_re(document.body, regexp, i) if i == -1: break - space = regexp.match(file.body[i]).group(3) - prepend = regexp.match(file.body[i]).group(1) + space = regexp.match(document.body[i]).group(3) + prepend = regexp.match(document.body[i]).group(1) if space == '~': - file.body[i] = regexp.sub(prepend + '\\SpecialChar ~', file.body[i]) + document.body[i] = regexp.sub(prepend + '\\SpecialChar ~', document.body[i]) i = i + 1 else: - file.body[i] = regexp.sub(prepend, file.body[i]) - file.body[i+1:i+1] = '' + document.body[i] = regexp.sub(prepend, document.body[i]) + document.body[i+1:i+1] = '' if space == "\\space": space = "\\ " - i = insert_ert(file.body, i+1, 'Collapsed', space, file.format - 1, file.default_layout) - -## -# \InsetSpace \, -> \InsetSpace \thinspace{} -# \InsetSpace \space -> \InsetSpace \space{} -# -def rename_spaces(file): - for i in range(len(file.body)): - file.body[i] = replace(file.body[i],"\\InsetSpace \\space","\\InsetSpace \\space{}") - file.body[i] = replace(file.body[i],"\\InsetSpace \,","\\InsetSpace \\thinspace{}") + i = insert_ert(document.body, i+1, 'Collapsed', space, document.format - 1, document.default_layout) -def revert_space_names(file): - for i in range(len(file.body)): - file.body[i] = replace(file.body[i],"\\InsetSpace \\space{}","\\InsetSpace \\space") - file.body[i] = replace(file.body[i],"\\InsetSpace \\thinspace{}","\\InsetSpace \\,") +def rename_spaces(document): + """ \InsetSpace \, -> \InsetSpace \thinspace{} + \InsetSpace \space -> \InsetSpace \space{}""" + for i in range(len(document.body)): + document.body[i] = document.body[i].replace("\\InsetSpace \\space", + "\\InsetSpace \\space{}") + document.body[i] = document.body[i].replace("\\InsetSpace \,", + "\\InsetSpace \\thinspace{}") + + +def revert_space_names(document): + """ \InsetSpace \thinspace{} -> \InsetSpace \, + \InsetSpace \space{} -> \InsetSpace \space""" + for i in range(len(document.body)): + document.body[i] = document.body[i].replace("\\InsetSpace \\space{}", + "\\InsetSpace \\space") + document.body[i] = document.body[i].replace("\\InsetSpace \\thinspace{}", + "\\InsetSpace \\,") -## -# equivalent to lyx::support::escape() -# def lyx_support_escape(lab): + " Equivalent to pre-unicode lyx::support::escape()" hexdigit = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'] enc = "" @@ -158,62 +217,55 @@ def lyx_support_escape(lab): return enc; -## -# \begin_inset LatexCommand \eqref -> ERT -# -def revert_eqref(file): +def revert_eqref(document): + "\\begin_inset LatexCommand \\eqref -> ERT" regexp = re.compile(r'^\\begin_inset\s+LatexCommand\s+\\eqref') i = 0 while 1: - i = find_re(file.body, regexp, i) + i = find_re(document.body, regexp, i) if i == -1: break - eqref = lyx_support_escape(regexp.sub("", file.body[i])) - file.body[i:i+1] = ["\\begin_inset ERT", "status Collapsed", "", - '\\layout %s' % file.default_layout, "", "\\backslash ", + eqref = lyx_support_escape(regexp.sub("", document.body[i])) + document.body[i:i+1] = ["\\begin_inset ERT", "status Collapsed", "", + '\\layout %s' % document.default_layout, "", "\\backslash ", "eqref" + eqref] i = i + 7 -## -# BibTeX changes -# -def convert_bibtex(file): - for i in range(len(file.body)): - file.body[i] = replace(file.body[i],"\\begin_inset LatexCommand \\BibTeX", - "\\begin_inset LatexCommand \\bibtex") +def convert_bibtex(document): + " Convert BibTeX changes." + for i in range(len(document.body)): + document.body[i] = document.body[i].replace("\\begin_inset LatexCommand \\BibTeX", + "\\begin_inset LatexCommand \\bibtex") -def revert_bibtex(file): - for i in range(len(file.body)): - file.body[i] = replace(file.body[i], "\\begin_inset LatexCommand \\bibtex", - "\\begin_inset LatexCommand \\BibTeX") +def revert_bibtex(document): + " Revert BibTeX changes." + for i in range(len(document.body)): + document.body[i] = document.body[i].replace("\\begin_inset LatexCommand \\bibtex", + "\\begin_inset LatexCommand \\BibTeX") -## -# Remove \lyxparent -# -def remove_insetparent(file): +def remove_insetparent(document): + " Remove \lyxparent" i = 0 while 1: - i = find_token(file.body, "\\begin_inset LatexCommand \\lyxparent", i) + i = find_token(document.body, "\\begin_inset LatexCommand \\lyxparent", i) if i == -1: break - del file.body[i:i+3] + del document.body[i:i+3] -## -# Inset External -# -def convert_external(file): +def convert_external(document): + " Convert inset External." external_rexp = re.compile(r'\\begin_inset External ([^,]*),"([^"]*)",') external_header = "\\begin_inset External" i = 0 while 1: - i = find_token(file.body, external_header, i) + i = find_token(document.body, external_header, i) if i == -1: break - look = external_rexp.search(file.body[i]) + look = external_rexp.search(document.body[i]) args = ['',''] if look: args[0] = look.group(1) @@ -225,7 +277,7 @@ def convert_external(file): top = "\\begin_inset Graphics" if args[1]: filename = "\tfilename " + args[1] - file.body[i:i+1] = [top, filename] + document.body[i:i+1] = [top, filename] i = i + 1 else: # Convert the old External Inset format to the new. @@ -233,137 +285,136 @@ def convert_external(file): template = "\ttemplate " + args[0] if args[1]: filename = "\tfilename " + args[1] - file.body[i:i+1] = [top, template, filename] + document.body[i:i+1] = [top, template, filename] i = i + 2 else: - file.body[i:i+1] = [top, template] + document.body[i:i+1] = [top, template] i = i + 1 -def revert_external_1(file): +def revert_external_1(document): + " Revert inset External." external_header = "\\begin_inset External" i = 0 while 1: - i = find_token(file.body, external_header, i) + i = find_token(document.body, external_header, i) if i == -1: break - template = split(file.body[i+1]) + template = document.body[i+1].split() template.reverse() - del file.body[i+1] + del document.body[i+1] - filename = split(file.body[i+1]) + filename = document.body[i+1].split() filename.reverse() - del file.body[i+1] + del document.body[i+1] - params = split(file.body[i+1]) + params = document.body[i+1].split() params.reverse() - if file.body[i+1]: del file.body[i+1] + if document.body[i+1]: del document.body[i+1] - file.body[i] = file.body[i] + " " + template[0]+ ', "' + filename[0] + '", " '+ join(params[1:]) + '"' + document.body[i] = document.body[i] + " " + template[0]+ ', "' + filename[0] + '", " '+ " ".join(params[1:]) + '"' i = i + 1 -def revert_external_2(file): +def revert_external_2(document): + " Revert inset External. (part II)" draft_token = '\tdraft' i = 0 while 1: - i = find_token(file.body, '\\begin_inset External', i) + i = find_token(document.body, '\\begin_inset External', i) if i == -1: break - j = find_end_of_inset(file.body, i + 1) + j = find_end_of_inset(document.body, i + 1) if j == -1: #this should not happen break - k = find_token(file.body, draft_token, i+1, j-1) - if (k != -1 and len(draft_token) == len(file.body[k])): - del file.body[k] + k = find_token(document.body, draft_token, i+1, j-1) + if (k != -1 and len(draft_token) == len(document.body[k])): + del document.body[k] i = j + 1 -## -# Comment -# -def convert_comment(file): +def convert_comment(document): + " Convert \\layout comment" i = 0 comment = "\\layout Comment" while 1: - i = find_token(file.body, comment, i) + i = find_token(document.body, comment, i) if i == -1: return - file.body[i:i+1] = ['\\layout %s' % file.default_layout,"","", + document.body[i:i+1] = ['\\layout %s' % document.default_layout,"","", "\\begin_inset Comment", "collapsed true","", - '\\layout %s' % file.default_layout] + '\\layout %s' % document.default_layout] i = i + 7 while 1: old_i = i - i = find_token(file.body, "\\layout", i) + i = find_token(document.body, "\\layout", i) if i == -1: - i = len(file.body) - 1 - file.body[i:i] = ["\\end_inset","",""] + i = len(document.body) - 1 + document.body[i:i] = ["\\end_inset","",""] return - j = find_token(file.body, '\\begin_deeper', old_i, i) + j = find_token(document.body, '\\begin_deeper', old_i, i) if j == -1: j = i + 1 - k = find_token(file.body, '\\begin_inset', old_i, i) + k = find_token(document.body, '\\begin_inset', old_i, i) if k == -1: k = i + 1 if j < i and j < k: i = j - del file.body[i] - i = find_end_of( file.body, i, "\\begin_deeper","\\end_deeper") + del document.body[i] + i = find_end_of( document.body, 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(file.body) - 1 - file.body[i:i] = ["\end_deeper",""] + i = len(document.body) - 1 + document.body[i:i] = ["\\end_deeper",""] return else: - del file.body[i] + del document.body[i] continue if k < i: i = k - i = find_end_of( file.body, i, "\\begin_inset","\\end_inset") + i = find_end_of( document.body, 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(file.body) - 1 - file.body[i:i] = ["\\end_inset","","","\\end_inset","",""] + i = len(document.body) - 1 + document.body[i:i] = ["\\end_inset","","","\\end_inset","",""] return else: i = i + 1 continue - if find(file.body[i], comment) == -1: - file.body[i:i] = ["\\end_inset"] + if document.body[i].find(comment) == -1: + document.body[i:i] = ["\\end_inset"] i = i + 1 break - file.body[i:i+1] = ['\\layout %s' % file.default_layout] + document.body[i:i+1] = ['\\layout %s' % document.default_layout] i = i + 1 -def revert_comment(file): +def revert_comment(document): + " Revert comments" i = 0 while 1: - i = find_tokens(file.body, ["\\begin_inset Comment", "\\begin_inset Greyedout"], i) + i = find_tokens(document.body, ["\\begin_inset Comment", "\\begin_inset Greyedout"], i) if i == -1: return - file.body[i] = "\\begin_inset Note" + document.body[i] = "\\begin_inset Note" i = i + 1 -## -# Add \end_layout -# -def add_end_layout(file): - i = find_token(file.body, '\\layout', 0) +def add_end_layout(document): + " Add \end_layout" + i = find_token(document.body, '\\layout', 0) if i == -1: return @@ -372,15 +423,15 @@ def add_end_layout(file): struct_stack = ["\\layout"] while 1: - i = find_tokens(file.body, ["\\begin_inset", "\\end_inset", "\\layout", + i = find_tokens(document.body, ["\\begin_inset", "\\end_inset", "\\layout", "\\begin_deeper", "\\end_deeper", "\\the_end"], i) if i != -1: - token = split(file.body[i])[0] + token = document.body[i].split()[0] else: - file.warning("Truncated file.") - i = len(file.body) - file.body.insert(i, '\\the_end') + document.warning("Truncated document.") + i = len(document.body) + document.body.insert(i, '\\the_end') token = "" if token == "\\begin_inset": @@ -391,8 +442,8 @@ def add_end_layout(file): if token == "\\end_inset": tail = struct_stack.pop() if tail == "\\layout": - file.body.insert(i,"") - file.body.insert(i,"\\end_layout") + document.body.insert(i,"") + document.body.insert(i,"\\end_layout") i = i + 2 #Check if it is the correct tag struct_stack.pop() @@ -402,8 +453,8 @@ def add_end_layout(file): if token == "\\layout": tail = struct_stack.pop() if tail == token: - file.body.insert(i,"") - file.body.insert(i,"\\end_layout") + document.body.insert(i,"") + document.body.insert(i,"\\end_layout") i = i + 3 else: struct_stack.append(tail) @@ -412,192 +463,196 @@ def add_end_layout(file): continue if token == "\\begin_deeper": - file.body.insert(i,"") - file.body.insert(i,"\\end_layout") + document.body.insert(i,"") + document.body.insert(i,"\\end_layout") i = i + 3 + # consecutive begin_deeper only insert one end_layout + while document.body[i].startswith('\\begin_deeper'): + i += 1 struct_stack.append(token) continue if token == "\\end_deeper": if struct_stack[-1] == '\\layout': - file.body.insert(i, '\\end_layout') + document.body.insert(i, '\\end_layout') i = i + 1 struct_stack.pop() i = i + 1 continue #case \end_document - file.body.insert(i, "") - file.body.insert(i, "\\end_layout") + document.body.insert(i, "") + document.body.insert(i, "\\end_layout") return -def rm_end_layout(file): +def rm_end_layout(document): + " Remove \end_layout" i = 0 while 1: - i = find_token(file.body, '\\end_layout', i) + i = find_token(document.body, '\\end_layout', i) if i == -1: return - del file.body[i] + del document.body[i] -## -# Handle change tracking keywords -# -def insert_tracking_changes(file): - i = find_token(file.header, "\\tracking_changes", 0) +def insert_tracking_changes(document): + " Handle change tracking keywords." + i = find_token(document.header, "\\tracking_changes", 0) if i == -1: - file.header.append("\\tracking_changes 0") + document.header.append("\\tracking_changes 0") -def rm_tracking_changes(file): - i = find_token(file.header, "\\author", 0) +def rm_tracking_changes(document): + " Remove change tracking keywords." + i = find_token(document.header, "\\author", 0) if i != -1: - del file.header[i] + del document.header[i] - i = find_token(file.header, "\\tracking_changes", 0) + i = find_token(document.header, "\\tracking_changes", 0) if i == -1: return - del file.header[i] + del document.header[i] -def rm_body_changes(file): +def rm_body_changes(document): + " Remove body changes." i = 0 while 1: - i = find_token(file.body, "\\change_", i) + i = find_token(document.body, "\\change_", i) if i == -1: return - del file.body[i] + del document.body[i] -## -# \layout -> \begin_layout -# -def layout2begin_layout(file): +def layout2begin_layout(document): + " \layout -> \begin_layout " i = 0 while 1: - i = find_token(file.body, '\\layout', i) + i = find_token(document.body, '\\layout', i) if i == -1: return - file.body[i] = replace(file.body[i], '\\layout', '\\begin_layout') + document.body[i] = document.body[i].replace('\\layout', '\\begin_layout') i = i + 1 -def begin_layout2layout(file): +def begin_layout2layout(document): + " \begin_layout -> \layout " i = 0 while 1: - i = find_token(file.body, '\\begin_layout', i) + i = find_token(document.body, '\\begin_layout', i) if i == -1: return - file.body[i] = replace(file.body[i], '\\begin_layout', '\\layout') + document.body[i] = document.body[i].replace('\\begin_layout', '\\layout') i = i + 1 -## -# valignment="center" -> valignment="middle" -# def convert_valignment_middle(body, start, end): + 'valignment="center" -> valignment="middle"' for i in range(start, end): if re.search('^<(column|cell) .*valignment="center".*>$', body[i]): - body[i] = replace(body[i], 'valignment="center"', 'valignment="middle"') + body[i] = body[i].replace('valignment="center"', 'valignment="middle"') -def convert_table_valignment_middle(file): +def convert_table_valignment_middle(document): + " Convert table valignment, center -> middle" regexp = re.compile(r'^\\begin_inset\s+Tabular') i = 0 while 1: - i = find_re(file.body, regexp, i) + i = find_re(document.body, regexp, i) if i == -1: return - j = find_end_of_inset(file.body, i + 1) + j = find_end_of_inset(document.body, i + 1) if j == -1: #this should not happen - convert_valignment_middle(file.body, i + 1, len(file.body)) + convert_valignment_middle(document.body, i + 1, len(document.body)) return - convert_valignment_middle(file.body, i + 1, j) + convert_valignment_middle(document.body, i + 1, j) i = j + 1 def revert_table_valignment_middle(body, start, end): + " valignment, middle -> center" for i in range(start, end): if re.search('^<(column|cell) .*valignment="middle".*>$', body[i]): - body[i] = replace(body[i], 'valignment="middle"', 'valignment="center"') + body[i] = body[i].replace('valignment="middle"', 'valignment="center"') -def revert_valignment_middle(file): +def revert_valignment_middle(document): + " Convert table valignment, middle -> center" regexp = re.compile(r'^\\begin_inset\s+Tabular') i = 0 while 1: - i = find_re(file.body, regexp, i) + i = find_re(document.body, regexp, i) if i == -1: return - j = find_end_of_inset(file.body, i + 1) + j = find_end_of_inset(document.body, i + 1) if j == -1: #this should not happen - revert_table_valignment_middle(file.body, i + 1, len(file.body)) + revert_table_valignment_middle(document.body, i + 1, len(document.body)) return - revert_table_valignment_middle(file.body, i + 1, j) + revert_table_valignment_middle(document.body, i + 1, j) i = j + 1 -## -# \the_end -> \end_document -# -def convert_end_document(file): - i = find_token(file.body, "\\the_end", 0) +def convert_end_document(document): + "\\the_end -> \\end_document" + i = find_token(document.body, "\\the_end", 0) if i == -1: - file.body.append("\\end_document") + document.body.append("\\end_document") return - file.body[i] = "\\end_document" + document.body[i] = "\\end_document" -def revert_end_document(file): - i = find_token(file.body, "\\end_document", 0) +def revert_end_document(document): + "\\end_document -> \\the_end" + i = find_token(document.body, "\\end_document", 0) if i == -1: - file.body.append("\\the_end") + document.body.append("\\the_end") return - file.body[i] = "\\the_end" + document.body[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 ERT -#\begin layout Standard -#\backslash -#vspace{-1\backslash -#parskip} -#\end_layout -#\end_inset -# -#\begin_inset VSpace xxx -#\end_inset -# -#0 -# -#\begin_inset VSpace xxx -#\end_inset -#\lyxline -# -#\newpage -# -#\end_layout -def convert_breaks(file): +def convert_breaks(document): + r""" +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 ERT +\begin layout Standard +\backslash +vspace{-1\backslash +parskip} +\end_layout +\end_inset + +\begin_inset VSpace xxx +\end_inset + +0 + +\begin_inset VSpace xxx +\end_inset +\lyxline + +\newpage + +\end_layout + """ par_params = ('added_space_bottom', 'added_space_top', 'align', 'labelwidthstring', 'line_bottom', 'line_top', 'noindent', 'pagebreak_bottom', 'pagebreak_top', 'paragraph_spacing', @@ -605,28 +660,28 @@ def convert_breaks(file): font_attributes = ['\\family', '\\series', '\\shape', '\\emph', '\\numeric', '\\bar', '\\noun', '\\color', '\\lang'] attribute_values = ['default', 'default', 'default', 'default', - 'default', 'default', 'default', 'none', file.language] + 'default', 'default', 'default', 'none', document.language] i = 0 while 1: - i = find_token(file.body, "\\begin_layout", i) + i = find_token(document.body, "\\begin_layout", i) if i == -1: return - layout = get_layout(file.body[i], file.default_layout) + layout = get_layout(document.body[i], document.default_layout) i = i + 1 # Merge all paragraph parameters into a single line # We cannot check for '\\' only because paragraphs may start e.g. # with '\\backslash' - while file.body[i + 1][:1] == '\\' and split(file.body[i + 1][1:])[0] in par_params: - file.body[i] = file.body[i + 1] + ' ' + file.body[i] - del file.body[i+1] + while document.body[i + 1][:1] == '\\' and document.body[i + 1][1:].split()[0] in par_params: + document.body[i] = document.body[i + 1] + ' ' + document.body[i] + del document.body[i+1] - line_top = find(file.body[i],"\\line_top") - line_bot = find(file.body[i],"\\line_bottom") - pb_top = find(file.body[i],"\\pagebreak_top") - pb_bot = find(file.body[i],"\\pagebreak_bottom") - vspace_top = find(file.body[i],"\\added_space_top") - vspace_bot = find(file.body[i],"\\added_space_bottom") + line_top = document.body[i].find("\\line_top") + line_bot = document.body[i].find("\\line_bottom") + pb_top = document.body[i].find("\\pagebreak_top") + pb_bot = document.body[i].find("\\pagebreak_bottom") + vspace_top = document.body[i].find("\\added_space_top") + vspace_bot = document.body[i].find("\\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 @@ -638,41 +693,41 @@ def convert_breaks(file): # We want to avoid new paragraphs if possible becauase we want to # inherit font sizes. nonstandard = 0 - if (not file.is_default_layout(layout) or - find(file.body[i],"\\align") != -1 or - find(file.body[i],"\\labelwidthstring") != -1 or - find(file.body[i],"\\noindent") != -1): + if (not document.is_default_layout(layout) or + document.body[i].find("\\align") != -1 or + document.body[i].find("\\labelwidthstring") != -1 or + document.body[i].find("\\noindent") != -1): nonstandard = 1 # get the font size of the beginning of this paragraph, since we need # it for the lyxline inset j = i + 1 - while not is_nonempty_line(file.body[j]): + while not is_nonempty_line(document.body[j]): j = j + 1 size_top = "" - if find(file.body[j], "\\size") != -1: - size_top = split(file.body[j])[1] + if document.body[j].find("\\size") != -1: + size_top = document.body[j].split()[1] for tag in "\\line_top", "\\line_bottom", "\\pagebreak_top", "\\pagebreak_bottom": - file.body[i] = replace(file.body[i], tag, "") + document.body[i] = document.body[i].replace(tag, "") if vspace_top != -1: # the position could be change because of the removal of other # paragraph properties above - vspace_top = find(file.body[i],"\\added_space_top") - tmp_list = split(file.body[i][vspace_top:]) + vspace_top = document.body[i].find("\\added_space_top") + tmp_list = document.body[i][vspace_top:].split() vspace_top_value = tmp_list[1] - file.body[i] = file.body[i][:vspace_top] + join(tmp_list[2:]) + document.body[i] = document.body[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(file.body[i],"\\added_space_bottom") - tmp_list = split(file.body[i][vspace_bot:]) + vspace_bot = document.body[i].find("\\added_space_bottom") + tmp_list = document.body[i][vspace_bot:].split() vspace_bot_value = tmp_list[1] - file.body[i] = file.body[i][:vspace_bot] + join(tmp_list[2:]) + document.body[i] = document.body[i][:vspace_bot] + " ".join(tmp_list[2:]) - file.body[i] = strip(file.body[i]) + document.body[i] = document.body[i].strip() i = i + 1 # Create an empty paragraph or paragraph fragment for line and @@ -682,7 +737,7 @@ def convert_breaks(file): paragraph_above = list() if nonstandard: # We need to create an extra paragraph for nonstandard environments - paragraph_above = ['\\begin_layout %s' % file.default_layout, ''] + paragraph_above = ['\\begin_layout %s' % document.default_layout, ''] if pb_top != -1: paragraph_above.extend(['\\newpage ','']) @@ -697,21 +752,21 @@ def convert_breaks(file): # We can't use the vspace inset because it does not know \parskip. paragraph_above.extend(['\\lyxline ', '', '']) insert_ert(paragraph_above, len(paragraph_above) - 1, 'Collapsed', - '\\vspace{-1\\parskip}\n', file.format + 1, file.default_layout) + '\\vspace{-1\\parskip}\n', document.format + 1, document.default_layout) paragraph_above.extend(['']) if nonstandard: paragraph_above.extend(['\\end_layout ','']) # insert new paragraph above the current paragraph - file.body[i-2:i-2] = paragraph_above + document.body[i-2:i-2] = paragraph_above else: # insert new lines at the beginning of the current paragraph - file.body[i:i] = paragraph_above + document.body[i:i] = paragraph_above i = i + len(paragraph_above) # Ensure that nested style are converted later. - k = find_end_of(file.body, i, "\\begin_layout", "\\end_layout") + k = find_end_of(document.body, i, "\\begin_layout", "\\end_layout") if k == -1: return @@ -722,22 +777,22 @@ def convert_breaks(file): size_bot = size_top j = i + 1 while j < k: - if find(file.body[j], "\\size") != -1: - size_bot = split(file.body[j])[1] + if document.body[j].find("\\size") != -1: + size_bot = document.body[j].split()[1] j = j + 1 - elif find(file.body[j], "\\begin_inset") != -1: + elif document.body[j].find("\\begin_inset") != -1: # skip insets - j = find_end_of_inset(file.body, j) + j = find_end_of_inset(document.body, j) else: j = j + 1 paragraph_below = list() if nonstandard: # We need to create an extra paragraph for nonstandard environments - paragraph_below = ['', '\\begin_layout %s' % file.default_layout, ''] + paragraph_below = ['', '\\begin_layout %s' % document.default_layout, ''] else: for a in range(len(font_attributes)): - if find_token(file.body, font_attributes[a], i, k) != -1: + if find_token(document.body, font_attributes[a], i, k) != -1: paragraph_below.extend([font_attributes[a] + ' ' + attribute_values[a]]) if line_bot != -1: @@ -756,47 +811,44 @@ def convert_breaks(file): if nonstandard: paragraph_below.extend(['\\end_layout ']) # insert new paragraph below the current paragraph - file.body[k+1:k+1] = paragraph_below + document.body[k+1:k+1] = paragraph_below else: # insert new lines at the end of the current paragraph - file.body[k:k] = paragraph_below + document.body[k:k] = paragraph_below -## -# Notes -# -def convert_note(file): +def convert_note(document): + " Convert Notes. " i = 0 while 1: - i = find_tokens(file.body, ["\\begin_inset Note", + i = find_tokens(document.body, ["\\begin_inset Note", "\\begin_inset Comment", "\\begin_inset Greyedout"], i) if i == -1: break - file.body[i] = file.body[i][0:13] + 'Note ' + file.body[i][13:] + document.body[i] = document.body[i][0:13] + 'Note ' + document.body[i][13:] i = i + 1 -def revert_note(file): +def revert_note(document): + " Revert Notes. " note_header = "\\begin_inset Note " i = 0 while 1: - i = find_token(file.body, note_header, i) + i = find_token(document.body, note_header, i) if i == -1: break - file.body[i] = "\\begin_inset " + file.body[i][len(note_header):] + document.body[i] = "\\begin_inset " + document.body[i][len(note_header):] i = i + 1 -## -# Box -# -def convert_box(file): +def convert_box(document): + " Convert Boxes. " i = 0 while 1: - i = find_tokens(file.body, ["\\begin_inset Boxed", + i = find_tokens(document.body, ["\\begin_inset Boxed", "\\begin_inset Doublebox", "\\begin_inset Frameless", "\\begin_inset ovalbox", @@ -805,29 +857,28 @@ def convert_box(file): if i == -1: break - file.body[i] = file.body[i][0:13] + 'Box ' + file.body[i][13:] + document.body[i] = document.body[i][0:13] + 'Box ' + document.body[i][13:] i = i + 1 -def revert_box(file): +def revert_box(document): + " Revert Boxes." box_header = "\\begin_inset Box " i = 0 while 1: - i = find_token(file.body, box_header, i) + i = find_token(document.body, box_header, i) if i == -1: break - file.body[i] = "\\begin_inset " + file.body[i][len(box_header):] + document.body[i] = "\\begin_inset " + document.body[i][len(box_header):] i = i + 1 -## -# Collapse -# -def convert_collapsable(file): +def convert_collapsable(document): + " Convert collapsed insets. " i = 0 while 1: - i = find_tokens_exact(file.body, ["\\begin_inset Box", + i = find_tokens_exact(document.body, ["\\begin_inset Box", "\\begin_inset Branch", "\\begin_inset CharStyle", "\\begin_inset Float", @@ -844,24 +895,25 @@ def convert_collapsable(file): # (_always_ present) then break with a warning message i = i + 1 while 1: - if (file.body[i] == "collapsed false"): - file.body[i] = "status open" + if (document.body[i] == "collapsed false"): + document.body[i] = "status open" break - elif (file.body[i] == "collapsed true"): - file.body[i] = "status collapsed" + elif (document.body[i] == "collapsed true"): + document.body[i] = "status collapsed" break - elif (file.body[i][:13] == "\\begin_layout"): - file.warning("Malformed LyX file: Missing 'collapsed'.") + elif (document.body[i][:13] == "\\begin_layout"): + document.warning("Malformed LyX document: Missing 'collapsed'.") break i = i + 1 i = i + 1 -def revert_collapsable(file): +def revert_collapsable(document): + " Revert collapsed insets. " i = 0 while 1: - i = find_tokens_exact(file.body, ["\\begin_inset Box", + i = find_tokens_exact(document.body, ["\\begin_inset Box", "\\begin_inset Branch", "\\begin_inset CharStyle", "\\begin_inset Float", @@ -878,28 +930,26 @@ def revert_collapsable(file): # (_always_ present) then break with a warning message i = i + 1 while 1: - if (file.body[i] == "status open"): - file.body[i] = "collapsed false" + if (document.body[i] == "status open"): + document.body[i] = "collapsed false" break - elif (file.body[i] == "status collapsed" or - file.body[i] == "status inlined"): - file.body[i] = "collapsed true" + elif (document.body[i] == "status collapsed" or + document.body[i] == "status inlined"): + document.body[i] = "collapsed true" break - elif (file.body[i][:13] == "\\begin_layout"): - file.warning("Malformed LyX file: Missing 'status'.") + elif (document.body[i][:13] == "\\begin_layout"): + document.warning("Malformed LyX document: Missing 'status'.") break i = i + 1 i = i + 1 -## -# ERT -# -def convert_ert(file): +def convert_ert(document): + " Convert ERT. " i = 0 while 1: - i = find_token(file.body, "\\begin_inset ERT", i) + i = find_token(document.body, "\\begin_inset ERT", i) if i == -1: break @@ -908,27 +958,28 @@ def convert_ert(file): # (_always_ present) then break with a warning message i = i + 1 while 1: - if (file.body[i] == "status Open"): - file.body[i] = "status open" + if (document.body[i] == "status Open"): + document.body[i] = "status open" break - elif (file.body[i] == "status Collapsed"): - file.body[i] = "status collapsed" + elif (document.body[i] == "status Collapsed"): + document.body[i] = "status collapsed" break - elif (file.body[i] == "status Inlined"): - file.body[i] = "status inlined" + elif (document.body[i] == "status Inlined"): + document.body[i] = "status inlined" break - elif (file.body[i][:13] == "\\begin_layout"): - file.warning("Malformed LyX file: Missing 'status'.") + elif (document.body[i][:13] == "\\begin_layout"): + document.warning("Malformed LyX document: Missing 'status'.") break i = i + 1 i = i + 1 -def revert_ert(file): +def revert_ert(document): + " Revert ERT. " i = 0 while 1: - i = find_token(file.body, "\\begin_inset ERT", i) + i = find_token(document.body, "\\begin_inset ERT", i) if i == -1: break @@ -937,27 +988,24 @@ def revert_ert(file): # (_always_ present) then break with a warning message i = i + 1 while 1: - if (file.body[i] == "status open"): - file.body[i] = "status Open" + if (document.body[i] == "status open"): + document.body[i] = "status Open" break - elif (file.body[i] == "status collapsed"): - file.body[i] = "status Collapsed" + elif (document.body[i] == "status collapsed"): + document.body[i] = "status Collapsed" break - elif (file.body[i] == "status inlined"): - file.body[i] = "status Inlined" + elif (document.body[i] == "status inlined"): + document.body[i] = "status Inlined" break - elif (file.body[i][:13] == "\\begin_layout"): - file.warning("Malformed LyX file : Missing 'status'.") + elif (document.body[i][:13] == "\\begin_layout"): + document.warning("Malformed LyX document : Missing 'status'.") break i = i + 1 i = i + 1 -## -# Minipages -# -def convert_minipage(file): +def convert_minipage(document): """ Convert minipages to the box inset. We try to use the same order of arguments as lyx does. """ @@ -966,55 +1014,55 @@ def convert_minipage(file): i = 0 while 1: - i = find_token(file.body, "\\begin_inset Minipage", i) + i = find_token(document.body, "\\begin_inset Minipage", i) if i == -1: return - file.body[i] = "\\begin_inset Box Frameless" + document.body[i] = "\\begin_inset Box Frameless" i = i + 1 # convert old to new position using the pos list - if file.body[i][:8] == "position": - file.body[i] = 'position "%s"' % pos[int(file.body[i][9])] + if document.body[i][:8] == "position": + document.body[i] = 'position "%s"' % pos[int(document.body[i][9])] else: - file.body.insert(i, 'position "%s"' % pos[0]) + document.body.insert(i, 'position "%s"' % pos[0]) i = i + 1 - file.body.insert(i, 'hor_pos "c"') + document.body.insert(i, 'hor_pos "c"') i = i + 1 - file.body.insert(i, 'has_inner_box 1') + document.body.insert(i, 'has_inner_box 1') i = i + 1 # convert the inner_position - if file.body[i][:14] == "inner_position": - innerpos = inner_pos[int(file.body[i][15])] - del file.body[i] + if document.body[i][:14] == "inner_position": + innerpos = inner_pos[int(document.body[i][15])] + del document.body[i] else: innerpos = inner_pos[0] # We need this since the new file format has a height and width # in a different order. - if file.body[i][:6] == "height": - height = file.body[i][6:] + if document.body[i][:6] == "height": + height = document.body[i][6:] # test for default value of 221 and convert it accordingly if height == ' "0pt"' or height == ' "0"': height = ' "1pt"' - del file.body[i] + del document.body[i] else: height = ' "1pt"' - if file.body[i][:5] == "width": - width = file.body[i][5:] - del file.body[i] + if document.body[i][:5] == "width": + width = document.body[i][5:] + del document.body[i] else: width = ' "0"' - if file.body[i][:9] == "collapsed": - if file.body[i][9:] == "true": + if document.body[i][:9] == "collapsed": + if document.body[i][9:] == "true": status = "collapsed" else: status = "open" - del file.body[i] + del document.body[i] else: status = "collapsed" @@ -1022,26 +1070,27 @@ def convert_minipage(file): if height == ' "1pt"' and innerpos == 'c': innerpos = 't' - file.body.insert(i, 'inner_pos "' + innerpos + '"') + document.body.insert(i, 'inner_pos "' + innerpos + '"') i = i + 1 - file.body.insert(i, 'use_parbox 0') + document.body.insert(i, 'use_parbox 0') i = i + 1 - file.body.insert(i, 'width' + width) + document.body.insert(i, 'width' + width) i = i + 1 - file.body.insert(i, 'special "none"') + document.body.insert(i, 'special "none"') i = i + 1 - file.body.insert(i, 'height' + height) + document.body.insert(i, 'height' + height) i = i + 1 - file.body.insert(i, 'height_special "totalheight"') + document.body.insert(i, 'height_special "totalheight"') i = i + 1 - file.body.insert(i, 'status ' + status) + document.body.insert(i, 'status ' + status) i = i + 1 -# ------------------------------------------------------------------------------------------- -# Convert backslashes and '\n' into valid ERT code, append the converted -# text to body[i] and return the (maybe incremented) line index i def convert_ertbackslash(body, i, ert, format, default_layout): + r""" ------------------------------------------------------------------------------------------- + Convert backslashes and '\n' into valid ERT code, append the converted + text to body[i] and return the (maybe incremented) line index i""" + for c in ert: if c == '\\': body[i] = body[i] + '\\backslash ' @@ -1059,9 +1108,10 @@ def convert_ertbackslash(body, i, ert, format, default_layout): return i -# Converts lines in ERT code to LaTeX -# The surrounding \begin_layout ... \end_layout pair must not be included def ert2latex(lines, format): + r""" Converts lines in ERT code to LaTeX + The surrounding \begin_layout ... \end_layout pair must not be included""" + backslash = re.compile(r'\\backslash\s*$') newline = re.compile(r'\\newline\s*$') if format <= 224: @@ -1086,9 +1136,9 @@ def ert2latex(lines, format): return ert -# get all paragraph parameters. They can be all on one line or on several lines. -# lines[i] must be the first parameter line def get_par_params(lines, i): + """ get all paragraph parameters. They can be all on one line or on several lines. + lines[i] must be the first parameter line""" par_params = ('added_space_bottom', 'added_space_top', 'align', 'labelwidthstring', 'line_bottom', 'line_top', 'noindent', 'pagebreak_bottom', 'pagebreak_top', 'paragraph_spacing', @@ -1096,14 +1146,14 @@ def get_par_params(lines, i): # We cannot check for '\\' only because paragraphs may start e.g. # with '\\backslash' params = '' - while lines[i][:1] == '\\' and split(lines[i][1:])[0] in par_params: - params = params + ' ' + strip(lines[i]) + while lines[i][:1] == '\\' and lines[i][1:].split()[0] in par_params: + params = params + ' ' + lines[i].strip() i = i + 1 - return strip(params) + return params.strip() -# convert LyX font size to LaTeX fontsize def lyxsize2latexsize(lyxsize): + " Convert LyX font size to LaTeX fontsize. " sizes = {"tiny" : "tiny", "scriptsize" : "scriptsize", "footnotesize" : "footnotesize", "small" : "small", "normal" : "normalsize", "large" : "large", "larger" : "Large", @@ -1113,16 +1163,16 @@ def lyxsize2latexsize(lyxsize): return '' -# Change vspace insets, page breaks and lyxlines to paragraph options -# (if possible) or ERT -def revert_breaks(file): +def revert_breaks(document): + """ Change vspace insets, page breaks and lyxlines to paragraph options + (if possible) or ERT""" # Get default spaceamount - i = find_token(file.header, '\\defskip', 0) + i = find_token(document.header, '\\defskip', 0) if i == -1: defskipamount = 'medskip' else: - defskipamount = split(file.header[i])[1] + defskipamount = document.header[i].split()[1] keys = {"\\begin_inset" : "vspace", "\\lyxline" : "lyxline", "\\newpage" : "newpage"} @@ -1135,31 +1185,31 @@ def revert_breaks(file): # Convert the insets i = 0 while 1: - i = find_tokens(file.body, tokens, i) + i = find_tokens(document.body, tokens, i) if i == -1: return # Are we at the beginning of a paragraph? paragraph_start = 1 - this_par = get_paragraph(file.body, i, file.format - 1) + this_par = get_paragraph(document.body, i, document.format - 1) start = this_par + 1 - params = get_par_params(file.body, start) + params = get_par_params(document.body, start) size = "normal" # Paragraph parameters may be on one or more lines. # Find the start of the real paragraph text. - while file.body[start][:1] == '\\' and split(file.body[start])[0] in params: + while document.body[start][:1] == '\\' and document.body[start].split()[0] in params: start = start + 1 for k in range(start, i): - if find(file.body[k], "\\size") != -1: + if document.body[k].find("\\size") != -1: # store font size - size = split(file.body[k])[1] - elif is_nonempty_line(file.body[k]): + size = document.body[k].split()[1] + elif is_nonempty_line(document.body[k]): paragraph_start = 0 break # Find the end of the real paragraph text. - next_par = get_next_paragraph(file.body, i, file.format - 1) + next_par = get_next_paragraph(document.body, i, document.format - 1) if next_par == -1: - file.warning("Malformed LyX file: Missing next paragraph.") + document.warning("Malformed LyX document: Missing next paragraph.") i = i + 1 continue @@ -1184,28 +1234,28 @@ def revert_breaks(file): n = 0 k = inset_start while k < next_par: - if find_tokens(file.body, tokens, k) == k: + if find_tokens(document.body, tokens, k) == k: # inset to convert - lines.append(split(file.body[k])) + lines.append(document.body[k].split()) insets.append(keys[lines[n][0]]) del_lines.append([k, k]) top.append(0) sizes.append(size) n = n + 1 inset_end = k - elif find(file.body[k], "\\size") != -1: + elif document.body[k].find("\\size") != -1: # store font size - size = split(file.body[k])[1] - elif find_token(file.body, "\\begin_inset ERT", k) == k: - ert_begin = find_token(file.body, "\\layout", k) + 1 + size = document.body[k].split()[1] + elif find_token(document.body, "\\begin_inset ERT", k) == k: + ert_begin = find_token(document.body, "\\layout", k) + 1 if ert_begin == 0: - file.warning("Malformed LyX file: Missing '\\layout'.") + document.warning("Malformed LyX document: Missing '\\layout'.") continue - ert_end = find_end_of_inset(file.body, k) + ert_end = find_end_of_inset(document.body, k) if ert_end == -1: - file.warning("Malformed LyX file: Missing '\\end_inset'.") + document.warning("Malformed LyX document: Missing '\\end_inset'.") continue - ert = ert2latex(file.body[ert_begin:ert_end], file.format - 1) + ert = ert2latex(document.body[ert_begin:ert_end], document.format - 1) if (n > 0 and insets[n - 1] == "lyxline" and ert == '\\vspace{-1\\parskip}\n'): # vspace ERT created by convert_breaks() for top lyxline @@ -1217,11 +1267,11 @@ def revert_breaks(file): paragraph_end = 0 break elif (n > 0 and insets[n - 1] == "vspace" and - find_token(file.body, "\\end_inset", k) == k): + find_token(document.body, "\\end_inset", k) == k): # ignore end of vspace inset del_lines[n - 1][1] = k inset_end = k - elif is_nonempty_line(file.body[k]): + elif is_nonempty_line(document.body[k]): paragraph_end = 0 break k = k + 1 @@ -1270,23 +1320,23 @@ def revert_breaks(file): # First try to merge with the previous paragraph. # We try the previous paragraph first because we would # otherwise need ERT for two subsequent vspaces. - prev_par = get_paragraph(file.body, this_par - 1, file.format - 1) + 1 + prev_par = get_paragraph(document.body, this_par - 1, document.format - 1) + 1 if prev_par > 0 and not before: - prev_params = get_par_params(file.body, prev_par + 1) + prev_params = get_par_params(document.body, prev_par + 1) ert = 0 # determine font size prev_size = "normal" k = prev_par + 1 - while file.body[k][:1] == '\\' and split(file.body[k])[0] in prev_params: + while document.body[k][:1] == '\\' and document.body[k].split()[0] in prev_params: k = k + 1 while k < this_par: - if find(file.body[k], "\\size") != -1: - prev_size = split(file.body[k])[1] + if document.body[k].find("\\size") != -1: + prev_size = document.body[k].split()[1] break - elif find(file.body[k], "\\begin_inset") != -1: + elif document.body[k].find("\\begin_inset") != -1: # skip insets - k = find_end_of_inset(file.body, k) - elif is_nonempty_line(file.body[k]): + k = find_end_of_inset(document.body, k) + elif is_nonempty_line(document.body[k]): break k = k + 1 for k in range(n): @@ -1296,25 +1346,25 @@ def revert_breaks(file): break if not ert: for k in range(n): - file.body.insert(prev_par + 1, + document.body.insert(prev_par + 1, keywords_bot[insets[k]] + arguments[k]) - del file.body[this_par+n:next_par-1+n] + del document.body[this_par+n:next_par-1+n] i = this_par + n continue # Then try next paragraph if next_par > 0 and not after: - next_params = get_par_params(file.body, next_par + 1) + next_params = get_par_params(document.body, next_par + 1) ert = 0 - while file.body[k][:1] == '\\' and split(file.body[k])[0] in next_params: + while document.body[k][:1] == '\\' and document.body[k].split()[0] in next_params: k = k + 1 # determine font size next_size = "normal" k = next_par + 1 while k < this_par: - if find(file.body[k], "\\size") != -1: - next_size = split(file.body[k])[1] + if document.body[k].find("\\size") != -1: + next_size = document.body[k].split()[1] break - elif is_nonempty_line(file.body[k]): + elif is_nonempty_line(document.body[k]): break k = k + 1 for k in range(n): @@ -1324,9 +1374,9 @@ def revert_breaks(file): break if not ert: for k in range(n): - file.body.insert(next_par + 1, + document.body.insert(next_par + 1, keywords_top[insets[k]] + arguments[k]) - del file.body[this_par:next_par-1] + del document.body[this_par:next_par-1] i = this_par continue elif paragraph_start or paragraph_end: @@ -1344,12 +1394,12 @@ def revert_breaks(file): break if not ert: for k in range(n): - file.body.insert(this_par + 1, + document.body.insert(this_par + 1, keywords[insets[k]] + arguments[k]) for j in range(k, n): del_lines[j][0] = del_lines[j][0] + 1 del_lines[j][1] = del_lines[j][1] + 1 - del file.body[del_lines[k][0]:del_lines[k][1]+1] + del document.body[del_lines[k][0]:del_lines[k][1]+1] deleted = del_lines[k][1] - del_lines[k][0] + 1 for j in range(k + 1, n): del_lines[j][0] = del_lines[j][0] - deleted @@ -1360,8 +1410,8 @@ def revert_breaks(file): # Convert the first inset to ERT. # The others are converted in the next loop runs (if they exist) if insets[0] == "vspace": - file.body[i:i+1] = ['\\begin_inset ERT', 'status Collapsed', '', - '\\layout %s' % file.default_layout, '', '\\backslash '] + document.body[i:i+1] = ['\\begin_inset ERT', 'status Collapsed', '', + '\\layout %s' % document.default_layout, '', '\\backslash '] i = i + 6 if spaceamount[0][-1] == '*': spaceamount[0] = spaceamount[0][:-1] @@ -1387,36 +1437,36 @@ def revert_breaks(file): # Finally output the LaTeX code if (spaceamount[0] == 'smallskip' or spaceamount[0] == 'medskip' or spaceamount[0] == 'bigskip' or spaceamount[0] == 'vfill'): - file.body.insert(i, spaceamount[0] + '{}') + document.body.insert(i, spaceamount[0] + '{}') else : if keep: - file.body.insert(i, 'vspace*{') + document.body.insert(i, 'vspace*{') else: - file.body.insert(i, 'vspace{') - i = convert_ertbackslash(file.body, i, spaceamount[0], file.format - 1, file.default_layout) - file.body[i] = file.body[i] + '}' + document.body.insert(i, 'vspace{') + i = convert_ertbackslash(document.body, i, spaceamount[0], document.format - 1, document.default_layout) + document.body[i] = document.body[i] + '}' i = i + 1 elif insets[0] == "lyxline": - file.body[i] = '' + document.body[i] = '' latexsize = lyxsize2latexsize(size) if latexsize == '': - file.warning("Could not convert LyX fontsize '%s' to LaTeX font size." % size) + document.warning("Could not convert LyX fontsize '%s' to LaTeX font size." % size) latexsize = '\\normalsize' - i = insert_ert(file.body, i, 'Collapsed', + i = insert_ert(document.body, i, 'Collapsed', '\\lyxline{%s}' % latexsize, - file.format - 1, file.default_layout) + document.format - 1, document.default_layout) # We use \providecommand so that we don't get an error if native # lyxlines are used (LyX writes first its own preamble and then # the user specified one) - add_to_preamble(file, + add_to_preamble(document, ['% Commands inserted by lyx2lyx for lyxlines', '\\providecommand{\\lyxline}[1]{', ' {#1 \\vspace{1ex} \\hrule width \\columnwidth \\vspace{1ex}}' '}']) elif insets[0] == "newpage": - file.body[i] = '' - i = insert_ert(file.body, i, 'Collapsed', '\\newpage{}', - file.format - 1, file.default_layout) + document.body[i] = '' + i = insert_ert(document.body, i, 'Collapsed', '\\newpage{}', + document.format - 1, document.default_layout) # Convert a LyX length into a LaTeX length @@ -1431,22 +1481,22 @@ def convert_len(len, special): # Convert LyX units to LaTeX units for unit in units.keys(): - if find(len, unit) != -1: + if len.find(unit) != -1: len = '%f' % (len2value(len) / 100) + units[unit] break return len -# Convert a LyX length into valid ERT code and append it to body[i] -# Return the (maybe incremented) line index i def convert_ertlen(body, i, len, special, format, default_layout): - # Convert backslashes and insert the converted length into body + """ Convert a LyX length into valid ERT code and append it to body[i] + Return the (maybe incremented) line index i + Convert backslashes and insert the converted length into body. """ return convert_ertbackslash(body, i, convert_len(len, special), format, default_layout) -# Return the value of len without the unit in numerical form def len2value(len): + " Return the value of len without the unit in numerical form. " result = re.search('([+-]?[0-9.]+)', len) if result: return float(result.group(1)) @@ -1454,9 +1504,10 @@ def len2value(len): return 1.0 -# Convert text to ERT and insert it at body[i] -# Return the index of the line after the inserted ERT def insert_ert(body, i, status, text, format, default_layout): + """ Convert text to ERT and insert it at body[i] + Return the index of the line after the inserted ERT""" + body[i:i] = ['\\begin_inset ERT', 'status ' + status, ''] i = i + 3 if format <= 224: @@ -1473,29 +1524,31 @@ def insert_ert(body, i, status, text, format, default_layout): return i -# Add text to the preamble if it is not already there. -# Only the first line is checked! -def add_to_preamble(file, text): - if find_token(file.preamble, text[0], 0) != -1: +def add_to_preamble(document, text): + """ Add text to the preamble if it is not already there. + Only the first line is checked!""" + + if find_token(document.preamble, text[0], 0) != -1: return - file.preamble.extend(text) + document.preamble.extend(text) -def convert_frameless_box(file): +def convert_frameless_box(document): + " Convert frameless box." pos = ['t', 'c', 'b'] inner_pos = ['c', 't', 'b', 's'] i = 0 while 1: - i = find_token(file.body, '\\begin_inset Frameless', i) + i = find_token(document.body, '\\begin_inset Frameless', i) if i == -1: return - j = find_end_of_inset(file.body, i) + j = find_end_of_inset(document.body, i) if j == -1: - file.warning("Malformed LyX file: Missing '\\end_inset'.") + document.warning("Malformed LyX document: Missing '\\end_inset'.") i = i + 1 continue - del file.body[i] + del document.body[i] j = j - 1 # Gather parameters @@ -1504,7 +1557,7 @@ def convert_frameless_box(file): 'special':'none', 'height':'1in', 'height_special':'totalheight', 'collapsed':'false'} for key in params.keys(): - value = replace(get_value(file.body, key, i, j), '"', '') + value = get_value(document.body, key, i, j).replace('"', '') if value != "": if key == 'position': # convert new to old position: 'position "t"' -> 0 @@ -1518,7 +1571,7 @@ def convert_frameless_box(file): params[key] = value else: params[key] = value - j = del_token(file.body, key, i, j) + j = del_token(document.body, key, i, j) i = i + 1 # Convert to minipage or ERT? @@ -1559,7 +1612,7 @@ def convert_frameless_box(file): # Otherwise we will get LaTeX errors if this document is # converted to format 225 or above again (LyX 1.4 uses all # optional arguments). - add_to_preamble(file, + add_to_preamble(document, ['% Commands inserted by lyx2lyx for frameless boxes', '% Save the original minipage environment', '\\let\\lyxtolyxrealminipage\\minipage', @@ -1605,10 +1658,10 @@ def convert_frameless_box(file): ert = ert + '\\let\\endminipage\\endlyxtolyxminipage%\n' old_i = i - i = insert_ert(file.body, i, 'Collapsed', ert, file.format - 1, file.default_layout) + i = insert_ert(document.body, i, 'Collapsed', ert, document.format - 1, document.default_layout) j = j + i - old_i - 1 - file.body[i:i] = ['\\begin_inset Minipage', + document.body[i:i] = ['\\begin_inset Minipage', 'position %d' % params['position'], 'inner_position 1', 'height "1in"', @@ -1620,23 +1673,23 @@ def convert_frameless_box(file): # Restore the original minipage environment since we may have # minipages inside this box. # Start a new paragraph because the following may be nonstandard - file.body[i:i] = ['\\layout %s' % file.default_layout, '', ''] + document.body[i:i] = ['\\layout %s' % document.default_layout, '', ''] i = i + 2 j = j + 3 ert = '\\let\\minipage\\lyxtolyxrealminipage%\n' ert = ert + '\\let\\endminipage\\lyxtolyxrealendminipage%' old_i = i - i = insert_ert(file.body, i, 'Collapsed', ert, file.format - 1, file.default_layout) + i = insert_ert(document.body, i, 'Collapsed', ert, document.format - 1, document.default_layout) j = j + i - old_i - 1 # Redefine the minipage end before the inset end. # Start a new paragraph because the previous may be nonstandard - file.body[j:j] = ['\\layout %s' % file.default_layout, '', ''] + document.body[j:j] = ['\\layout %s' % document.default_layout, '', ''] j = j + 2 ert = '\\let\\endminipage\\endlyxtolyxminipage' - j = insert_ert(file.body, j, 'Collapsed', ert, file.format - 1, file.default_layout) + j = insert_ert(document.body, j, 'Collapsed', ert, document.format - 1, document.default_layout) j = j + 1 - file.body.insert(j, '') + document.body.insert(j, '') j = j + 1 # LyX writes '%\n' after each box. Therefore we need to end our @@ -1645,7 +1698,7 @@ def convert_frameless_box(file): ert = '}%\n' else: ert = '\\end{lyxtolyxrealminipage}%\n' - j = insert_ert(file.body, j, 'Collapsed', ert, file.format - 1, file.default_layout) + j = insert_ert(document.body, j, 'Collapsed', ert, document.format - 1, document.default_layout) # We don't need to restore the original minipage after the inset # end because the scope of the redefinition is the original box. @@ -1653,7 +1706,7 @@ def convert_frameless_box(file): else: # Convert to minipage - file.body[i:i] = ['\\begin_inset Minipage', + document.body[i:i] = ['\\begin_inset Minipage', 'position %d' % params['position'], 'inner_position %d' % params['inner_pos'], 'height "' + params['height'] + '"', @@ -1662,103 +1715,99 @@ def convert_frameless_box(file): i = i + 6 -def remove_branches(file): +def remove_branches(document): + " Remove branches. " i = 0 while 1: - i = find_token(file.header, "\\branch", i) + i = find_token(document.header, "\\branch", i) if i == -1: break - file.warning("Removing branch %s." % split(file.header[i])[1]) - j = find_token(file.header, "\\end_branch", i) + document.warning("Removing branch %s." % document.header[i].split()[1]) + j = find_token(document.header, "\\end_branch", i) if j == -1: - file.warning("Malformed LyX file: Missing '\\end_branch'.") + document.warning("Malformed LyX document: Missing '\\end_branch'.") break - del file.header[i:j+1] + del document.header[i:j+1] i = 0 while 1: - i = find_token(file.body, "\\begin_inset Branch", i) + i = find_token(document.body, "\\begin_inset Branch", i) if i == -1: return - j = find_end_of_inset(file.body, i) + j = find_end_of_inset(document.body, i) if j == -1: - file.warning("Malformed LyX file: Missing '\\end_inset'.") + document.warning("Malformed LyX document: Missing '\\end_inset'.") i = i + 1 continue - del file.body[i] - del file.body[j - 1] + del document.body[i] + del document.body[j - 1] # Seach for a line starting 'collapsed' # If, however, we find a line starting '\layout' # (_always_ present) then break with a warning message collapsed_found = 0 while 1: - if (file.body[i][:9] == "collapsed"): - del file.body[i] + if (document.body[i][:9] == "collapsed"): + del document.body[i] collapsed_found = 1 continue - elif (file.body[i][:7] == "\\layout"): + elif (document.body[i][:7] == "\\layout"): if collapsed_found == 0: - file.warning("Malformed LyX file: Missing 'collapsed'.") + document.warning("Malformed LyX document: Missing 'collapsed'.") # Delete this new paragraph, since it would not appear in # .tex output. This avoids also empty paragraphs. - del file.body[i] + del document.body[i] break i = i + 1 -## -# Convert jurabib -# - -def convert_jurabib(file): - i = find_token(file.header, '\\use_numerical_citations', 0) +def convert_jurabib(document): + " Convert jurabib. " + i = find_token(document.header, '\\use_numerical_citations', 0) if i == -1: - file.warning("Malformed lyx file: Missing '\\use_numerical_citations'.") + document.warning("Malformed lyx document: Missing '\\use_numerical_citations'.") return - file.header.insert(i + 1, '\\use_jurabib 0') + document.header.insert(i + 1, '\\use_jurabib 0') -def revert_jurabib(file): - i = find_token(file.header, '\\use_jurabib', 0) +def revert_jurabib(document): + " Revert jurabib. " + i = find_token(document.header, '\\use_jurabib', 0) if i == -1: - file.warning("Malformed lyx file: Missing '\\use_jurabib'.") + document.warning("Malformed lyx document: Missing '\\use_jurabib'.") return - if get_value(file.header, '\\use_jurabib', 0) != "0": - file.warning("Conversion of '\\use_jurabib = 1' not yet implemented.") + if get_value(document.header, '\\use_jurabib', 0) != "0": + document.warning("Conversion of '\\use_jurabib = 1' not yet implemented.") # Don't remove '\\use_jurabib' so that people will get warnings by lyx return - del file.header[i] + del document.header[i] -## -# Convert bibtopic -# -def convert_bibtopic(file): - i = find_token(file.header, '\\use_jurabib', 0) +def convert_bibtopic(document): + " Convert bibtopic. " + i = find_token(document.header, '\\use_jurabib', 0) if i == -1: - file.warning("Malformed lyx file: Missing '\\use_jurabib'.") + document.warning("Malformed lyx document: Missing '\\use_jurabib'.") return - file.header.insert(i + 1, '\\use_bibtopic 0') + document.header.insert(i + 1, '\\use_bibtopic 0') -def revert_bibtopic(file): - i = find_token(file.header, '\\use_bibtopic', 0) +def revert_bibtopic(document): + " Revert bibtopic. " + i = find_token(document.header, '\\use_bibtopic', 0) if i == -1: - file.warning("Malformed lyx file: Missing '\\use_bibtopic'.") + document.warning("Malformed lyx document: Missing '\\use_bibtopic'.") return - if get_value(file.header, '\\use_bibtopic', 0) != "0": - file.warning("Conversion of '\\use_bibtopic = 1' not yet implemented.") + if get_value(document.header, '\\use_bibtopic', 0) != "0": + document.warning("Conversion of '\\use_bibtopic = 1' not yet implemented.") # Don't remove '\\use_jurabib' so that people will get warnings by lyx - del file.header[i] + del document.header[i] -## -# Sideway Floats -# -def convert_float(file): +def convert_float(document): + " Convert sideway floats. " i = 0 while 1: - i = find_token_exact(file.body, '\\begin_inset Float', i) + i = find_token_exact(document.body, '\\begin_inset Float', i) if i == -1: return # Seach for a line starting 'wide' @@ -1766,107 +1815,105 @@ def convert_float(file): # (_always_ present) then break with a warning message i = i + 1 while 1: - if (file.body[i][:4] == "wide"): - file.body.insert(i + 1, 'sideways false') + if (document.body[i][:4] == "wide"): + document.body.insert(i + 1, 'sideways false') break - elif (file.body[i][:13] == "\\begin_layout"): - file.warning("Malformed lyx file: Missing 'wide'.") + elif (document.body[i][:13] == "\\begin_layout"): + document.warning("Malformed lyx document: Missing 'wide'.") break i = i + 1 i = i + 1 -def revert_float(file): +def revert_float(document): + " Revert sideway floats. " i = 0 while 1: - i = find_token_exact(file.body, '\\begin_inset Float', i) + i = find_token_exact(document.body, '\\begin_inset Float', i) if i == -1: return - j = find_end_of_inset(file.body, i) + j = find_end_of_inset(document.body, i) if j == -1: - file.warning("Malformed lyx file: Missing '\\end_inset'.") + document.warning("Malformed lyx document: Missing '\\end_inset'.") i = i + 1 continue - if get_value(file.body, 'sideways', i, j) != "false": - file.warning("Conversion of 'sideways true' not yet implemented.") + if get_value(document.body, 'sideways', i, j) != "false": + document.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(file.body, 'sideways', i, j) + del_token(document.body, 'sideways', i, j) i = i + 1 -def convert_graphics(file): - """ Add extension to filenames of insetgraphics if necessary. +def convert_graphics(document): + """ Add extension to documentnames of insetgraphics if necessary. """ i = 0 while 1: - i = find_token(file.body, "\\begin_inset Graphics", i) + i = find_token(document.body, "\\begin_inset Graphics", i) if i == -1: return - j = find_token_exact(file.body, "filename", i) + j = find_token_exact(document.body, "documentname", i) if j == -1: return i = i + 1 - filename = split(file.body[j])[1] - absname = os.path.normpath(os.path.join(file.dir, filename)) - if file.input == stdin and not os.path.isabs(filename): - # We don't know the directory and cannot check the file. + filename = document.body[j].split()[1] + absname = os.path.normpath(os.path.join(document.dir, filename)) + if document.input == stdin and not os.path.isabs(filename): + # We don't know the directory and cannot check the document. # We could use a heuristic and take the current directory, - # and we could try to find out if filename has an extension, + # and we could try to find out if documentname has an extension, # but that would be just guesses and could be wrong. - file.warning("""Warning: Can not determine whether file + document.warning("""Warning: Cannot determine whether document %s needs an extension when reading from standard input. - You may need to correct the file manually or run - lyx2lyx again with the .lyx file as commandline argument.""" % filename) + You may need to correct the document manually or run + lyx2lyx again with the .lyx document as commandline argument.""" % filename) continue # This needs to be the same algorithm as in pre 233 insetgraphics if access(absname, F_OK): continue if access(absname + ".ps", F_OK): - file.body[j] = replace(file.body[j], filename, filename + ".ps") + document.body[j] = document.body[j].replace(filename, filename + ".ps") continue if access(absname + ".eps", F_OK): - file.body[j] = replace(file.body[j], filename, filename + ".eps") + document.body[j] = document.body[j].replace(filename, filename + ".eps") -## -# Convert firstname and surname from styles -> char styles -# -def convert_names(file): +def convert_names(document): """ Convert in the docbook backend from firstname and surname style to charstyles. """ - if file.backend != "docbook": + if document.backend != "docbook": return i = 0 while 1: - i = find_token(file.body, "\\begin_layout Author", i) + i = find_token(document.body, "\\begin_layout Author", i) if i == -1: return i = i + 1 - while file.body[i] == "": + while document.body[i] == "": i = i + 1 - if file.body[i][:11] != "\\end_layout" or file.body[i+2][:13] != "\\begin_deeper": + if document.body[i][:11] != "\\end_layout" or document.body[i+2][:13] != "\\begin_deeper": i = i + 1 continue k = i - i = find_end_of( file.body, i+3, "\\begin_deeper","\\end_deeper") + i = find_end_of( document.body, i+3, "\\begin_deeper","\\end_deeper") if i == -1: # something is really wrong, abort - file.warning("Missing \\end_deeper, after style Author.") - file.warning("Aborted attempt to parse FirstName and Surname.") + document.warning("Missing \\end_deeper, after style Author.") + document.warning("Aborted attempt to parse FirstName and Surname.") return firstname, surname = "", "" - name = file.body[k:i] + name = document.body[k:i] j = find_token(name, "\\begin_layout FirstName", 0) if j != -1: @@ -1883,13 +1930,13 @@ def convert_names(file): j = j + 1 # delete name - del file.body[k+2:i+1] + del document.body[k+2:i+1] - file.body[k-1:k-1] = ["", "", + document.body[k-1:k-1] = ["", "", "\\begin_inset CharStyle Firstname", "status inlined", "", - '\\begin_layout %s' % file.default_layout, + '\\begin_layout %s' % document.default_layout, "", "%s" % firstname, "\end_layout", @@ -1900,7 +1947,7 @@ def convert_names(file): "\\begin_inset CharStyle Surname", "status inlined", "", - '\\begin_layout %s' % file.default_layout, + '\\begin_layout %s' % document.default_layout, "", "%s" % surname, "\\end_layout", @@ -1909,38 +1956,37 @@ def convert_names(file): ""] -def revert_names(file): +def revert_names(document): """ Revert in the docbook backend from firstname and surname char style to styles. """ - if file.backend != "docbook": + if document.backend != "docbook": return -## -# \use_natbib 1 \cite_engine