# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
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_tokens, find_end_of, find_token2
+from sys import stdin
from string import replace, split, find, strip, join
##
i = i + 1
struct_stack = ["\\layout"]
+
while 1:
i = find_tokens(lines, ["\\begin_inset", "\\end_inset", "\\layout",
"\\begin_deeper", "\\end_deeper", "\\the_end"], i)
if token == "\\end_inset":
tail = struct_stack.pop()
if tail == "\\layout":
+ lines.insert(i,"")
lines.insert(i,"\\end_layout")
- i = i + 1
+ i = i + 2
#Check if it is the correct tag
struct_stack.pop()
i = i + 1
if token == "\\layout":
tail = struct_stack.pop()
if tail == token:
+ lines.insert(i,"")
lines.insert(i,"\\end_layout")
- i = i + 2
+ i = i + 3
else:
struct_stack.append(tail)
i = i + 1
struct_stack.append(token)
continue
- if token == "\\begin_deeper" or token == "\\end_deeper":
+ if token == "\\begin_deeper":
+ lines.insert(i,"")
lines.insert(i,"\\end_layout")
- i = i + 2
+ i = i + 3
+ struct_stack.append(token)
+ continue
+
+ if token == "\\end_deeper":
+ lines.insert(i,"")
+ lines.insert(i,"\\end_layout")
+ i = i + 3
+ while struct_stack[-1] != "\\begin_deeper":
+ struct_stack.pop()
continue
#case \end_document
+ lines.insert(i, "")
lines.insert(i, "\\end_layout")
return
##
-# Remove change tracking keywords
+# Handle change tracking keywords
#
+def insert_tracking_changes(lines):
+ i = find_token(lines, "\\tracking_changes", 0)
+ if i == -1:
+ lines.append("\\tracking_changes 0")
+
def rm_tracking_changes(lines):
i = find_token(lines, "\\author", 0)
if i != -1:
if j == -1:
opt.warning("Malformed LyX file: Missing '\\end_inset'.")
break
- lines[j-1:j-1] += ['\\begin_inset ERT', 'status ' + params['collapsed'],
+ lines[j-1:j-1] = ['\\begin_inset ERT', 'status ' + params['collapsed'],
'', '\\layout Standard', '']
j = j + 4
if params['use_parbox'] == '1':
del_token(lines, 'sideways', i, j)
i = i + 1
+
+def convert_graphics(lines, opt):
+ """ Add extension to filenames of insetgraphics if necessary.
+ """
+ i = 0
+ while 1:
+ i = find_token(lines, "\\begin_inset Graphics", i)
+ if i == -1:
+ return
+
+ j = find_token2(lines, "filename", i)
+ if j == -1:
+ return
+ i = i + 1
+ filename = split(lines[j])[1]
+ absname = os.path.normpath(os.path.join(opt.dir, filename))
+ if opt.input == stdin and not os.path.isabs(filename):
+ # We don't know the directory and cannot check the file.
+ # We could use a heuristic and take the current directory,
+ # and we could try to find out if filename has an extension,
+ # but that would be just guesses and could be wrong.
+ opt.warning("""Warning: Can not determine whether file
+ %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)
+ 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):
+ lines[j] = replace(lines[j], filename, filename + ".ps")
+ continue
+ if access(absname + ".eps", F_OK):
+ lines[j] = replace(lines[j], filename, filename + ".eps")
+
+
+##
+# Convert firstname and surname from styles -> char styles
+#
+def convert_names(lines, opt):
+ """ Convert in the docbook backend from firstname and surname style
+ to charstyles.
+ """
+ if opt.backend != "docbook":
+ return
+
+ i = 0
+
+ while 1:
+ i = find_token(lines, "\\begin_layout Author", i)
+ if i == -1:
+ return
+
+ i = i + 1
+ while lines[i] == "":
+ i = i + 1
+
+ if lines[i][:11] != "\\end_layout" or lines[i+2][:13] != "\\begin_deeper":
+ i = i + 1
+ continue
+
+ k = i
+ i = find_end_of( lines, i+3, "\\begin_deeper","\\end_deeper")
+ if i == -1:
+ # something is really wrong, abort
+ opt.warning("Missing \\end_deeper,after style Author")
+ opt.warning("Aborted attempt to parse FirstName and Surname")
+ return
+ firstname, surname = "", ""
+
+ name = lines[k:i]
+
+ j = find_token(name, "\\begin_layout FirstName", 0)
+ if j != -1:
+ j = j + 1
+ while(name[j] != "\\end_layout"):
+ firstname = firstname + name[j]
+ j = j + 1
+
+ j = find_token(name, "\\begin_layout Surname", 0)
+ if j != -1:
+ j = j + 1
+ while(name[j] != "\\end_layout"):
+ surname = surname + name[j]
+ j = j + 1
+
+ # delete name
+ del lines[k+2:i+1]
+
+ lines[k-1:k-1] = ["", "",
+ "\\begin_inset CharStyle Firstname",
+ "status inlined",
+ "",
+ "\\begin_layout Standard",
+ "",
+ "%s" % firstname,
+ "\end_layout",
+ "",
+ "\end_inset ",
+ "",
+ "",
+ "\\begin_inset CharStyle Surname",
+ "status inlined",
+ "",
+ "\\begin_layout Standard",
+ "",
+ "%s" % surname,
+ "\\end_layout",
+ "",
+ "\\end_inset ",
+ ""]
+
+
+def revert_names(lines, opt):
+ """ Revert in the docbook backend from firstname and surname char style
+ to styles.
+ """
+ if opt.backend != "docbook":
+ return
+
+
+##
+# \use_natbib 1 \cite_engine <style>
+# \use_numerical_citations 0 -> where <style> is one of
+# \use_jurabib 0 "basic", "natbib_authoryear",
+# "natbib_numerical" or "jurabib"
+def convert_cite_engine(header, opt):
+ a = find_token(header, "\\use_natbib", 0)
+ if a == -1:
+ opt.warning("Malformed lyx file: Missing '\\use_natbib'")
+ return
+
+ b = find_token(header, "\\use_numerical_citations", 0)
+ if b == -1 or b != a+1:
+ opt.warning("Malformed lyx file: Missing '\\use_numerical_citations'")
+ return
+
+ c = find_token(header, "\\use_jurabib", 0)
+ if c == -1 or c != b+1:
+ opt.warning("Malformed lyx file: Missing '\\use_jurabib'")
+ return
+
+ use_natbib = int(split(header[a])[1])
+ use_numerical_citations = int(split(header[b])[1])
+ use_jurabib = int(split(header[c])[1])
+
+ cite_engine = "basic"
+ if use_natbib:
+ if use_numerical_citations:
+ cite_engine = "natbib_numerical"
+ else:
+ cite_engine = "natbib_authoryear"
+ elif use_jurabib:
+ cite_engine = "jurabib"
+
+ del header[a:c+1]
+ header.insert(a, "\\cite_engine " + cite_engine)
+
+
+def revert_cite_engine(header, opt):
+ i = find_token(header, "\\cite_engine", 0)
+ if i == -1:
+ opt.warning("Malformed lyx file: Missing '\\cite_engine'")
+ return
+
+ cite_engine = split(header[i])[1]
+
+ use_natbib = '0'
+ use_numerical = '0'
+ use_jurabib = '0'
+ if cite_engine == "natbib_numerical":
+ use_natbib = '1'
+ use_numerical = '1'
+ elif cite_engine == "natbib_authoryear":
+ use_natbib = '1'
+ elif cite_engine == "jurabib":
+ use_jurabib = '1'
+
+ del header[i]
+ header.insert(i, "\\use_jurabib " + use_jurabib)
+ header.insert(i, "\\use_numerical_citations " + use_numerical)
+ header.insert(i, "\\use_natbib " + use_natbib)
+
+
##
# Convertion hub
#
def convert(header, body, opt):
if opt.format < 223:
+ insert_tracking_changes(header)
add_end_header(header)
convert_spaces(body)
convert_bibtex(body)
if opt.format < 232:
convert_bibtopic(header, opt)
opt.format = 232
+ if opt.end == opt.format: return
+
+ if opt.format < 233:
+ convert_graphics(body, opt)
+ convert_names(body, opt)
+ opt.format = 233
+ if opt.end == opt.format: return
+
+ if opt.format < 234:
+ convert_cite_engine(header, opt)
+ opt.format = 234
def revert(header, body, opt):
+ if opt.format > 233:
+ revert_cite_engine(header, opt)
+ opt.format = 233
+ if opt.end == opt.format: return
+
+ if opt.format > 232:
+ revert_names(body, opt)
+ opt.format = 232
+ if opt.end == opt.format: return
+
if opt.format > 231:
revert_bibtopic(header, opt)
opt.format = 231