document.preamble.extend(text)
+def insert_to_preamble(index, document, text):
+ """ Insert text to the preamble at a given line"""
+
+ document.preamble.insert(index, text)
+
# Convert a LyX length into a LaTeX length
def convert_len(len):
units = {"text%":"\\backslash\ntextwidth", "col%":"\\backslash\ncolumnwidth",
retval = ""
## FIXME Escaped \ ??
- labelre = re.compile(r'(.*?)\\(\\(?:[a-zA-Z]+|.))(.*)')
+ # This regex looks for a LaTeX command---i.e., something of the form
+ # "\alPhaStuFF", or "\X", where X is any character---where the command
+ # may also be preceded by an additional backslash, which is how it would
+ # appear (e.g.) in an InsetIndex.
+ labelre = re.compile(r'(.*?)\\?(\\(?:[a-zA-Z]+|.))(.*)')
m = labelre.match(line)
while m != None:
break
cmd += arg
end = rest
+ # If we wanted to put labels into an InsetLabel, for example, then we
+ # would just need to test here for cmd == "label" and then take some
+ # appropriate action, i.e., to use arg to get the content and then
+ # wrap it appropriately.
cmd = put_cmd_in_ert(cmd)
retval += "\n" + cmd + "\n"
line = end
return retval
+#Bug 5022....
+#Might should do latex2ert first, then deal with stuff that DOESN'T
+#end up inside ERT. That routine could be modified so that it returned
+#a list of lines, and we could then skip ERT bits and only deal with
+#the other bits.
def latex2lyx(data):
- '''Takes a string, possibly multi-line, and returns the result of
+ '''Takes a string, possibly multi-line, and returns the result of
converting LaTeX constructs into LyX constructs. Returns a list of
lines, suitable for insertion into document.body.'''
# Commands of this sort need to be checked to make sure they are
# followed by a non-alpha character, lest we replace too much.
hardone = re.compile(r'^\\\\[a-zA-Z]+$')
-
+
for rep in reps:
if hardone.match(rep[0]):
pos = 0
if pos == -1:
break
nextpos = pos + len(rep[0])
- nextchar = data[nextpos - 1 : nextpos]
- if nextchar.isalpha():
+ if nextpos < len(data) and data[nextpos].isalpha():
# not the end of that command
pos = nextpos
continue
return retval
+def lyx2latex(document, lines):
+ 'Convert some LyX stuff into corresponding LaTeX stuff, as best we can.'
+ # clean up multiline stuff
+ content = ""
+ ert_end = 0
+ reps = read_unicodesymbols()
+
+ for curline in range(len(lines)):
+ line = lines[curline]
+ if line.startswith("\\begin_inset ERT"):
+ # We don't want to replace things inside ERT, so figure out
+ # where the end of the inset is.
+ ert_end = find_end_of_inset(lines, curline + 1)
+ continue
+ elif line.startswith("\\begin_inset Formula"):
+ line = line[20:]
+ elif line.startswith("\\begin_inset Quotes"):
+ # For now, we do a very basic reversion. Someone who understands
+ # quotes is welcome to fix it up.
+ qtype = line[20:].strip()
+ # lang = qtype[0]
+ side = qtype[1]
+ dbls = qtype[2]
+ if side == "l":
+ if dbls == "d":
+ line = "``"
+ else:
+ line = "`"
+ else:
+ if dbls == "d":
+ line = "''"
+ else:
+ line = "'"
+ elif line.isspace() or \
+ line.startswith("\\begin_layout") or \
+ line.startswith("\\end_layout") or \
+ line.startswith("\\begin_inset") or \
+ line.startswith("\\end_inset") or \
+ line.startswith("\\lang") or \
+ line.strip() == "status collapsed" or \
+ line.strip() == "status open":
+ #skip all that stuff
+ continue
+
+ # this needs to be added to the preamble because of cases like
+ # \textmu, \textbackslash, etc.
+ add_to_preamble(document, ['% added by lyx2lyx for converted index entries',
+ '\\@ifundefined{textmu}',
+ ' {\\usepackage{textcomp}}{}'])
+ # a lossless reversion is not possible
+ # try at least to handle some common insets and settings
+ if ert_end >= curline:
+ line = line.replace(r'\backslash', r'\\')
+ else:
+ line = line.replace('&', '\\&{}')
+ line = line.replace('#', '\\#{}')
+ line = line.replace('^', '\\^{}')
+ line = line.replace('%', '\\%{}')
+ line = line.replace('_', '\\_{}')
+ line = line.replace('$', '\\${}')
+
+ # Do the LyX text --> LaTeX conversion
+ for rep in reps:
+ line = line.replace(rep[1], rep[0] + "{}")
+ line = line.replace(r'\backslash', r'\textbackslash{}')
+ line = line.replace(r'\series bold', r'\bfseries{}').replace(r'\series default', r'\mdseries{}')
+ line = line.replace(r'\shape italic', r'\itshape{}').replace(r'\shape smallcaps', r'\scshape{}')
+ line = line.replace(r'\shape slanted', r'\slshape{}').replace(r'\shape default', r'\upshape{}')
+ line = line.replace(r'\emph on', r'\em{}').replace(r'\emph default', r'\em{}')
+ line = line.replace(r'\noun on', r'\scshape{}').replace(r'\noun default', r'\upshape{}')
+ line = line.replace(r'\bar under', r'\underbar{').replace(r'\bar default', r'}')
+ line = line.replace(r'\family sans', r'\sffamily{}').replace(r'\family default', r'\normalfont{}')
+ line = line.replace(r'\family typewriter', r'\ttfamily{}').replace(r'\family roman', r'\rmfamily{}')
+ line = line.replace(r'\InsetSpace ', r'').replace(r'\SpecialChar ', r'')
+ content += line
+ return content
+
+
####################################################################
def convert_ltcaption(document):
i = find_token(document.body, "\\begin_inset CharStyle", i)
if i == -1:
return
- document.body[i] = document.body[i].replace("CharStyle CharStyle:", "CharStyle")
+ document.body[i] = document.body[i].replace("CharStyle CharStyle:", "CharStyle ")
i += 1
setupstart = ""
setupend = ""
# write the preamble
- add_to_preamble(document,
- ['% Commands inserted by lyx2lyx for PDF properties',
- '\\usepackage[unicode=true'
+ # babel must be loaded before hyperref and hyperref the first part
+ # of the preamble, like in LyX 1.6
+ insert_to_preamble(0, document,
+ '% Commands inserted by lyx2lyx for PDF properties\n'
+ + '\\usepackage{babel}\n'
+ + '\\usepackage[unicode=true'
+ bookmarks
+ breaklinks
+ pdfborder
+ colorlinks
+ pagemode
+ ']\n'
- ' {hyperref}\n'
+ + ' {hyperref}\n'
+ setupstart
+ title
+ author
+ subject
+ keywords
+ otheroptions
- + setupend])
+ + setupend)
def remove_inzip_options(document):
return
if document.body[i + 1] != "LatexCommand index": # Might also be index_print
return
+ j = find_end_of_inset(document.body, i + 2)
+ if j == -1:
+ document.warning("Unable to find end of index inset at line " + i + "!")
+ i += 2
+ continue
m = r1.match(document.body[i + 2])
if m == None:
document.warning("Unable to match: " + document.body[i+2])
i += 1
continue
fullcontent = m.group(1)
- #document.warning(fullcontent)
- document.body[i:i + 3] = ["\\begin_inset Index",
- "status collapsed",
- "\\begin_layout Standard"]
- i += 3
- # We are now on the blank line preceding "\end_inset"
- # We will write the content here, into the inset.
-
linelist = latex2lyx(fullcontent)
- document.body[i+1:i+1] = linelist
- i += len(linelist)
+ #document.warning(fullcontent)
- document.body.insert(i + 1, "\\end_layout")
- i += 1
+ linelist = ["\\begin_inset Index", "status collapsed", "\\begin_layout Standard", ""] + \
+ linelist + ["\\end_layout"]
+ document.body[i : j] = linelist
+ i += len(linelist) - (j - i)
def revert_latexcommand_index(document):
j = find_end_of_inset(document.body, i + 1)
if j == -1:
return
- del document.body[j - 1]
- del document.body[j - 2] # \end_layout
- document.body[i] = "\\begin_inset CommandInset index"
- document.body[i + 1] = "LatexCommand index"
- # clean up multiline stuff
- content = ""
- ert_end = 0
- for k in range(i + 3, j - 2):
- line = document.body[k]
- if line.startswith("\\begin_inset ERT"):
- ert_end = find_end_of_inset(document.body, k + 1)
- line = line[16:]
- if line.startswith("\\begin_inset Formula"):
- line = line[20:]
- if line.startswith("\\begin_layout Standard"):
- line = line[22:]
- if line.startswith("\\begin_layout Plain Layout"):
- line = line[26:]
- if line.startswith("\\end_layout"):
- line = line[11:]
- if line.startswith("\\end_inset"):
- line = line[10:]
- if line.startswith("status collapsed"):
- line = line[16:]
- if line.startswith("status open"):
- line = line[11:]
- # a lossless reversion is not possible
- # try at least to handle some common insets and settings
- # do not replace inside ERTs
- if ert_end < k:
- # Do the LyX text --> LaTeX conversion
- for rep in replacements:
- line = line.replace(rep[1], rep[0])
- line = line.replace(r'\backslash', r'\textbackslash{}')
- line = line.replace(r'\series bold', r'\bfseries{}').replace(r'\series default', r'\mdseries{}')
- line = line.replace(r'\shape italic', r'\itshape{}').replace(r'\shape smallcaps', r'\scshape{}')
- line = line.replace(r'\shape slanted', r'\slshape{}').replace(r'\shape default', r'\upshape{}')
- line = line.replace(r'\emph on', r'\em{}').replace(r'\emph default', r'\em{}')
- line = line.replace(r'\noun on', r'\scshape{}').replace(r'\noun default', r'\upshape{}')
- line = line.replace(r'\bar under', r'\underbar{').replace(r'\bar default', r'}')
- line = line.replace(r'\family sans', r'\sffamily{}').replace(r'\family default', r'\normalfont{}')
- line = line.replace(r'\family typewriter', r'\ttfamily{}').replace(r'\family roman', r'\rmfamily{}')
- line = line.replace(r'\InsetSpace ', r'').replace(r'\SpecialChar ', r'')
- else:
- line = line.replace(r'\backslash', r'\\')
- content = content + line;
- document.body[i + 3] = "name " + '"' + content + '"'
- for k in range(i + 4, j - 2):
- del document.body[i + 4]
- document.body.insert(i + 4, "")
- del document.body[i + 2] # \begin_layout standard
- i = i + 5
+
+ content = lyx2latex(document, document.body[i:j])
+ # escape quotes
+ content = content.replace('"', r'\"')
+ document.body[i:j] = ["\\begin_inset CommandInset index", "LatexCommand index",
+ "name " + '"' + content + '"', ""]
+ i += 5
def revert_wraptable(document):
return
m = r.match(document.body[i])
if m == None:
- document.warning("Weirdly formed \\begin_layout at line %d of body!" % i)
+ # This is an empty layout
+ # document.warning("Weirdly formed \\begin_layout at line %d of body!" % i)
i += 1
continue
m = m.group(1)
'position "t"',
'hor_pos "c"',
'has_inner_box 0',
- 'inner_pos "t"',
+ 'inner_pos "t"',
'use_parbox 0',
'width "100col%"',
'special "none"',
#Returns number of lines added/removed
def revert_nocite_key(body, start, end):
- 'key "..." -> \nocite{...}'
+ 'key "..." -> \nocite{...}'
r = re.compile(r'^key "(.*)"')
i = start
j = end
subst = ['\\begin_layout Standard',
'\\begin_inset ERT',
'status collapsed', '',
- '\\begin_layout Standard', '', '',
+ '\\begin_layout Standard', '', '',
'\\backslash', '',
'end{sideways' + floattype + '}',
'\\end_layout', '', '\\end_inset']
document.body[j : j+1] = subst
addedLines = len(subst) - 1
del document.body[i+1 : l]
- addedLines -= (l-1) - (i+1)
+ addedLines -= (l-1) - (i+1)
subst = ['\\begin_inset ERT', 'status collapsed', '',
- '\\begin_layout Standard', '', '', '\\backslash',
- 'begin{sideways' + floattype + '}',
+ '\\begin_layout Standard', '', '', '\\backslash',
+ 'begin{sideways' + floattype + '}',
'\\end_layout', '', '\\end_inset', '',
'\\end_layout', '']
document.body[i : i+1] = subst
if l == -1:
document.warning("Malformed LyX document: Missing `\\begin_layout' in Float inset.")
return
- subst = ['\\begin_layout Standard', '\\begin_inset ERT',
- 'status collapsed', '',
+ subst = ['\\begin_layout Standard', '\\begin_inset ERT',
+ 'status collapsed', '',
'\\begin_layout Standard', '', '', '\\backslash',
- 'end{sideways' + floattype + '*}',
+ 'end{sideways' + floattype + '*}',
'\\end_layout', '', '\\end_inset']
document.body[j : j+1] = subst
addedLines = len(subst) - 1
del document.body[l]
del document.body[k]
addedLines = -2
- subst = ['\\begin_inset Float figure', 'wide false', 'sideways false',
- 'status open', '', '\\begin_layout Plain Layout', '\\begin_inset Caption',
+ subst = ['\\begin_inset Float figure', 'wide false', 'sideways false',
+ 'status open', '', '\\begin_layout Plain Layout', '\\begin_inset Caption',
'', '\\begin_layout Plain Layout'] + latex2lyx(caption) + \
- [ '\\end_layout', '', '\\end_inset', '',
+ [ '\\end_layout', '', '\\end_inset', '',
'\\end_layout', '', '\\begin_layout Plain Layout']
document.body[i : i] = subst
addedLines += len(subst)
def convert_plain_layout(document):
- " Convert 'PlainLayout' to 'Plain Layout'"
+ " Convert 'PlainLayout' to 'Plain Layout'"
i = 0
while True:
i = find_token(document.body, '\\begin_layout PlainLayout', i)
def revert_plain_layout(document):
- " Convert 'PlainLayout' to 'Plain Layout'"
+ " Convert 'PlainLayout' to 'Plain Layout'"
i = 0
while True:
i = find_token(document.body, '\\begin_layout Plain Layout', i)
def revert_plainlayout(document):
- " Convert 'PlainLayout' to 'Plain Layout'"
+ " Convert 'PlainLayout' to 'Plain Layout'"
i = 0
while True:
i = find_token(document.body, '\\begin_layout PlainLayout', i)
j = j + 1
+def revert_removed_modules(document):
+ i = 0
+ while True:
+ i = find_token(document.header, "\\begin_remove_modules", i)
+ if i == -1:
+ return
+ j = find_end_of(document.header, i, "\\begin_remove_modules", "\\end_remove_modules")
+ if j == -1:
+ # this should not happen
+ break
+ document.header[i : j + 1] = []
+
+
+def add_plain_layout(document):
+ i = 0
+ while True:
+ i = find_token(document.body, "\\begin_layout", i)
+ if i == -1:
+ return
+ if len(document.body[i].split()) == 1:
+ document.body[i] = "\\begin_layout Plain Layout"
+ i += 1
+
##
# Conversion hub
#
[336, []],
[337, [convert_display_enum]],
[338, []],
+ [339, []],
+ [340, [add_plain_layout]]
]
-revert = [[337, [revert_polytonicgreek]],
+revert = [[339, []],
+ [338, [revert_removed_modules]],
+ [337, [revert_polytonicgreek]],
[336, [revert_display_enum]],
[335, [remove_fontsCJK]],
[334, [revert_InsetSpace]],