import unicodedata
import sys, os
-from parser_tools import find_token, find_end_of, find_tokens, get_value
+from parser_tools import find_token, find_end_of, find_tokens, get_value, get_value_string
####################################################################
# Private helper functions
def wrap_into_ert(string, src, dst):
" Wrap a something into an ERT"
- return string.replace(src, '\n\\begin_inset ERT\nstatus collapsed\n\\begin_layout Standard\n'
+ return string.replace(src, '\n\\begin_inset ERT\nstatus collapsed\n\\begin_layout Standard\n'
+ dst + '\n\\end_layout\n\\end_inset\n')
def add_to_preamble(document, text):
document.preamble.extend(text)
+# Convert a LyX length into a LaTeX length
+def convert_len(len):
+ units = {"text%":"\\backslash\ntextwidth", "col%":"\\backslash\ncolumnwidth",
+ "page%":"\\backslash\npagewidth", "line%":"\\backslash\nlinewidth",
+ "theight%":"\\backslash\ntextheight", "pheight%":"\\backslash\npageheight"}
+
+ # Convert LyX units to LaTeX units
+ for unit in units.keys():
+ if len.find(unit) != -1:
+ len = '%f' % (len2value(len) / 100)
+ len = len.strip('0') + units[unit]
+ break
+
+ return len
+
+# Return the value of len without the unit in numerical form.
+def len2value(len):
+ result = re.search('([+-]?[0-9.]+)', len)
+ if result:
+ return float(result.group(1))
+ # No number means 1.0
+ return 1.0
+
+# Unfortunately, this doesn't really work, since Standard isn't always default.
+# But it's as good as we can do right now.
+def find_default_layout(document, start, end):
+ l = find_token(document.body, "\\begin_layout Standard", start, end)
+ if l == -1:
+ l = find_token(document.body, "\\begin_layout PlainLayout", start, end)
+ if l == -1:
+ l = find_token(document.body, "\\begin_layout Plain Layout", start, end)
+ return l
+
+def get_option(document, m, option, default):
+ l = document.body[m].find(option)
+ val = default
+ if l != -1:
+ val = document.body[m][l:].split('"')[1]
+ return val
+
+def remove_option(document, m, option):
+ l = document.body[m].find(option)
+ if l != -1:
+ val = document.body[m][l:].split('"')[1]
+ document.body[m] = document.body[m][:l-1] + document.body[m][l+len(option + '="' + val + '"'):]
+ return l
+
+def set_option(document, m, option, value):
+ l = document.body[m].find(option)
+ if l != -1:
+ oldval = document.body[m][l:].split('"')[1]
+ l = l + len(option + '="')
+ document.body[m] = document.body[m][:l] + value + document.body[m][l+len(oldval):]
+ else:
+ document.body[m] = document.body[m][:-1] + ' ' + option + '="' + value + '">'
+ return l
+
+
####################################################################
+def convert_ltcaption(document):
+ i = 0
+ while True:
+ i = find_token(document.body, "\\begin_inset Tabular", i)
+ if i == -1:
+ return
+ j = find_end_of_inset(document.body, i + 1)
+ if j == -1:
+ document.warning("Malformed LyX document: Could not find end of tabular.")
+ continue
+
+ nrows = int(document.body[i+1].split('"')[3])
+ ncols = int(document.body[i+1].split('"')[5])
+
+ m = i + 1
+ for k in range(nrows):
+ m = find_token(document.body, "<row", m)
+ r = m
+ caption = 'false'
+ for k in range(ncols):
+ m = find_token(document.body, "<cell", m)
+ if (k == 0):
+ mend = find_token(document.body, "</cell>", m + 1)
+ # first look for caption insets
+ mcap = find_token(document.body, "\\begin_inset Caption", m + 1, mend)
+ # then look for ERT captions
+ if mcap == -1:
+ mcap = find_token(document.body, "caption", m + 1, mend)
+ if mcap > -1:
+ mcap = find_token(document.body, "\\backslash", mcap - 1, mcap)
+ if mcap > -1:
+ caption = 'true'
+ if caption == 'true':
+ if (k == 0):
+ set_option(document, r, 'caption', 'true')
+ set_option(document, m, 'multicolumn', '1')
+ set_option(document, m, 'bottomline', 'false')
+ set_option(document, m, 'topline', 'false')
+ set_option(document, m, 'rightline', 'false')
+ set_option(document, m, 'leftline', 'false')
+ #j = find_end_of_inset(document.body, j + 1)
+ else:
+ set_option(document, m, 'multicolumn', '2')
+ m = m + 1
+ m = m + 1
+
+ i = j + 1
+
+def revert_ltcaption(document):
+ i = 0
+ while True:
+ i = find_token(document.body, "\\begin_inset Tabular", i)
+ if i == -1:
+ return
+ j = find_end_of_inset(document.body, i + 1)
+ if j == -1:
+ document.warning("Malformed LyX document: Could not find end of tabular.")
+ continue
+
+ m = i + 1
+ nrows = int(document.body[i+1].split('"')[3])
+ ncols = int(document.body[i+1].split('"')[5])
+
+ for k in range(nrows):
+ m = find_token(document.body, "<row", m)
+ caption = get_option(document, m, 'caption', 'false')
+ if caption == 'true':
+ remove_option(document, m, 'caption')
+ for k in range(ncols):
+ m = find_token(document.body, "<cell", m)
+ remove_option(document, m, 'multicolumn')
+ if k == 0:
+ m = find_token(document.body, "\\begin_inset Caption", m)
+ if m == -1:
+ return
+ m = find_end_of_inset(document.body, m + 1)
+ document.body[m] += wrap_into_ert("","","\\backslash\n\\backslash\n%")
+ m = m + 1
+ m = m + 1
+ i = j + 1
+
+
+def convert_tablines(document):
+ i = 0
+ while True:
+ i = find_token(document.body, "\\begin_inset Tabular", i)
+ if i == -1:
+ # LyX 1.3 inserted an extra space between \begin_inset
+ # and Tabular so let us try if this is the case and fix it.
+ i = find_token(document.body, "\\begin_inset Tabular", i)
+ if i == -1:
+ return
+ else:
+ document.body[i] = "\\begin_inset Tabular"
+ j = find_end_of_inset(document.body, i + 1)
+ if j == -1:
+ document.warning("Malformed LyX document: Could not find end of tabular.")
+ continue
+
+ m = i + 1
+ nrows = int(document.body[i+1].split('"')[3])
+ ncols = int(document.body[i+1].split('"')[5])
+
+ col_info = []
+ for k in range(ncols):
+ m = find_token(document.body, "<column", m)
+ left = get_option(document, m, 'leftline', 'false')
+ right = get_option(document, m, 'rightline', 'false')
+ col_info.append([left, right])
+ remove_option(document, m, 'leftline')
+ remove_option(document, m, 'rightline')
+ m = m + 1
+
+ row_info = []
+ for k in range(nrows):
+ m = find_token(document.body, "<row", m)
+ top = get_option(document, m, 'topline', 'false')
+ bottom = get_option(document, m, 'bottomline', 'false')
+ row_info.append([top, bottom])
+ remove_option(document, m, 'topline')
+ remove_option(document, m, 'bottomline')
+ m = m + 1
+
+ m = i + 1
+ mc_info = []
+ for k in range(nrows*ncols):
+ m = find_token(document.body, "<cell", m)
+ mc_info.append(get_option(document, m, 'multicolumn', '0'))
+ m = m + 1
+ m = i + 1
+ for l in range(nrows):
+ for k in range(ncols):
+ m = find_token(document.body, '<cell', m)
+ if mc_info[l*ncols + k] == '0':
+ r = set_option(document, m, 'topline', row_info[l][0])
+ r = set_option(document, m, 'bottomline', row_info[l][1])
+ r = set_option(document, m, 'leftline', col_info[k][0])
+ r = set_option(document, m, 'rightline', col_info[k][1])
+ elif mc_info[l*ncols + k] == '1':
+ s = k + 1
+ while s < ncols and mc_info[l*ncols + s] == '2':
+ s = s + 1
+ if s < ncols and mc_info[l*ncols + s] != '1':
+ r = set_option(document, m, 'rightline', col_info[k][1])
+ if k > 0 and mc_info[l*ncols + k - 1] == '0':
+ r = set_option(document, m, 'leftline', col_info[k][0])
+ m = m + 1
+ i = j + 1
+
+
+def revert_tablines(document):
+ i = 0
+ while True:
+ i = find_token(document.body, "\\begin_inset Tabular", i)
+ if i == -1:
+ return
+ j = find_end_of_inset(document.body, i + 1)
+ if j == -1:
+ document.warning("Malformed LyX document: Could not find end of tabular.")
+ continue
+
+ m = i + 1
+ nrows = int(document.body[i+1].split('"')[3])
+ ncols = int(document.body[i+1].split('"')[5])
+
+ lines = []
+ for k in range(nrows*ncols):
+ m = find_token(document.body, "<cell", m)
+ top = get_option(document, m, 'topline', 'false')
+ bottom = get_option(document, m, 'bottomline', 'false')
+ left = get_option(document, m, 'leftline', 'false')
+ right = get_option(document, m, 'rightline', 'false')
+ lines.append([top, bottom, left, right])
+ m = m + 1
+
+ # we will want to ignore longtable captions
+ m = i + 1
+ caption_info = []
+ for k in range(nrows):
+ m = find_token(document.body, "<row", m)
+ caption = get_option(document, m, 'caption', 'false')
+ caption_info.append([caption])
+ m = m + 1
+
+ m = i + 1
+ col_info = []
+ for k in range(ncols):
+ m = find_token(document.body, "<column", m)
+ left = 'true'
+ for l in range(nrows):
+ left = lines[l*ncols + k][2]
+ if left == 'false' and caption_info[l] == 'false':
+ break
+ set_option(document, m, 'leftline', left)
+ right = 'true'
+ for l in range(nrows):
+ right = lines[l*ncols + k][3]
+ if right == 'false' and caption_info[l] == 'false':
+ break
+ set_option(document, m, 'rightline', right)
+ m = m + 1
+
+ row_info = []
+ for k in range(nrows):
+ m = find_token(document.body, "<row", m)
+ top = 'true'
+ for l in range(ncols):
+ top = lines[k*ncols + l][0]
+ if top == 'false':
+ break
+ if caption_info[k] == 'false':
+ top = 'false'
+ set_option(document, m, 'topline', top)
+ bottom = 'true'
+ for l in range(ncols):
+ bottom = lines[k*ncols + l][1]
+ if bottom == 'false':
+ break
+ if caption_info[k] == 'false':
+ bottom = 'false'
+ set_option(document, m, 'bottomline', bottom)
+ m = m + 1
+
+ i = j + 1
+
+
def fix_wrong_tables(document):
i = 0
while True:
document.warning("Malformed LyX document: show_label neither false nor true.")
else:
document.warning("Malformed LyX document: show_label missing in CharStyle.")
-
+
i += 1
# Discard PDF options for hyperref
def revert_pdf_options(document):
"Revert PDF options for hyperref."
+ # store the PDF options and delete the entries from the Lyx file
i = 0
+ hyperref = False
+ title = ""
+ author = ""
+ subject = ""
+ keywords = ""
+ bookmarks = ""
+ bookmarksnumbered = ""
+ bookmarksopen = ""
+ bookmarksopenlevel = ""
+ breaklinks = ""
+ pdfborder = ""
+ colorlinks = ""
+ backref = ""
+ pagebackref = ""
+ pagemode = ""
+ otheroptions = ""
i = find_token(document.header, "\\use_hyperref", i)
if i != -1:
+ hyperref = get_value(document.header, "\\use_hyperref", i) == 'true'
del document.header[i]
i = find_token(document.header, "\\pdf_store_options", i)
if i != -1:
del document.header[i]
i = find_token(document.header, "\\pdf_title", 0)
if i != -1:
+ title = get_value_string(document.header, '\\pdf_title', 0, 0, True)
+ title = ' pdftitle={' + title + '}'
del document.header[i]
i = find_token(document.header, "\\pdf_author", 0)
if i != -1:
+ author = get_value_string(document.header, '\\pdf_author', 0, 0, True)
+ if title == "":
+ author = ' pdfauthor={' + author + '}'
+ else:
+ author = ',\n pdfauthor={' + author + '}'
del document.header[i]
i = find_token(document.header, "\\pdf_subject", 0)
if i != -1:
+ subject = get_value_string(document.header, '\\pdf_subject', 0, 0, True)
+ if title == "" and author == "":
+ subject = ' pdfsubject={' + subject + '}'
+ else:
+ subject = ',\n pdfsubject={' + subject + '}'
del document.header[i]
i = find_token(document.header, "\\pdf_keywords", 0)
if i != -1:
+ keywords = get_value_string(document.header, '\\pdf_keywords', 0, 0, True)
+ if title == "" and author == "" and subject == "":
+ keywords = ' pdfkeywords={' + keywords + '}'
+ else:
+ keywords = ',\n pdfkeywords={' + keywords + '}'
del document.header[i]
i = find_token(document.header, "\\pdf_bookmarks", 0)
if i != -1:
+ bookmarks = get_value_string(document.header, '\\pdf_bookmarks', 0)
+ bookmarks = ',\n bookmarks=' + bookmarks
del document.header[i]
i = find_token(document.header, "\\pdf_bookmarksnumbered", i)
if i != -1:
+ bookmarksnumbered = get_value_string(document.header, '\\pdf_bookmarksnumbered', 0)
+ bookmarksnumbered = ',\n bookmarksnumbered=' + bookmarksnumbered
del document.header[i]
i = find_token(document.header, "\\pdf_bookmarksopen", i)
if i != -1:
+ bookmarksopen = get_value_string(document.header, '\\pdf_bookmarksopen', 0)
+ bookmarksopen = ',\n bookmarksopen=' + bookmarksopen
del document.header[i]
i = find_token(document.header, "\\pdf_bookmarksopenlevel", i)
if i != -1:
+ bookmarksopenlevel = get_value_string(document.header, '\\pdf_bookmarksopenlevel', 0, 0, True)
+ bookmarksopenlevel = ',\n bookmarksopenlevel=' + bookmarksopenlevel
del document.header[i]
i = find_token(document.header, "\\pdf_breaklinks", i)
if i != -1:
+ breaklinks = get_value_string(document.header, '\\pdf_breaklinks', 0)
+ breaklinks = ',\n breaklinks=' + breaklinks
del document.header[i]
i = find_token(document.header, "\\pdf_pdfborder", i)
if i != -1:
+ pdfborder = get_value_string(document.header, '\\pdf_pdfborder', 0)
+ if pdfborder == 'true':
+ pdfborder = ',\n pdfborder={0 0 0}'
+ else:
+ pdfborder = ',\n pdfborder={0 0 1}'
del document.header[i]
i = find_token(document.header, "\\pdf_colorlinks", i)
if i != -1:
+ colorlinks = get_value_string(document.header, '\\pdf_colorlinks', 0)
+ colorlinks = ',\n colorlinks=' + colorlinks
del document.header[i]
i = find_token(document.header, "\\pdf_backref", i)
if i != -1:
+ backref = get_value_string(document.header, '\\pdf_backref', 0)
+ backref = ',\n backref=' + backref
del document.header[i]
i = find_token(document.header, "\\pdf_pagebackref", i)
if i != -1:
+ pagebackref = get_value_string(document.header, '\\pdf_pagebackref', 0)
+ pagebackref = ',\n pagebackref=' + pagebackref
del document.header[i]
i = find_token(document.header, "\\pdf_pagemode", 0)
if i != -1:
+ pagemode = get_value_string(document.header, '\\pdf_pagemode', 0)
+ pagemode = ',\n pdfpagemode=' + pagemode
del document.header[i]
i = find_token(document.header, "\\pdf_quoted_options", 0)
if i != -1:
+ otheroptions = get_value_string(document.header, '\\pdf_quoted_options', 0, 0, True)
+ if title == "" and author == "" and subject == "" and keywords == "":
+ otheroptions = ' ' + otheroptions
+ else:
+ otheroptions = ',\n ' + otheroptions
del document.header[i]
+ # write to the preamble when hyperref was used
+ if hyperref == True:
+ # preamble write preparations
+ # bookmark numbers are only output when they are turned on
+ if bookmarksopen == ',\n bookmarksopen=true':
+ bookmarksopen = bookmarksopen + bookmarksopenlevel
+ if bookmarks == ',\n bookmarks=true':
+ bookmarks = bookmarks + bookmarksnumbered + bookmarksopen
+ else:
+ bookmarks = bookmarks
+ # hypersetup is only output when there are things to be set up
+ setupstart = '\\hypersetup{%\n'
+ setupend = ' }\n'
+ if otheroptions == "" and title == "" and author == ""\
+ and subject == "" and keywords == "":
+ setupstart = ""
+ setupend = ""
+ # write the preamble
+ add_to_preamble(document,
+ ['% Commands inserted by lyx2lyx for PDF properties',
+ '\\usepackage[unicode=true'
+ + bookmarks
+ + breaklinks
+ + pdfborder
+ + backref
+ + pagebackref
+ + colorlinks
+ + pagemode
+ + ']\n'
+ ' {hyperref}\n'
+ + setupstart
+ + title
+ + author
+ + subject
+ + keywords
+ + otheroptions
+ + setupend])
+
def remove_inzip_options(document):
"Remove inzipName and embed options from the Graphics inset"
def convert_inset_command(document):
"""
Convert:
- \begin_inset LatexCommand cmd
- to
+ \begin_inset LatexCommand cmd
+ to
\begin_inset CommandInset InsetType
LatexCommand cmd
"""
Convert:
\begin_inset CommandInset InsetType
LatexCommand cmd
- to
- \begin_inset LatexCommand cmd
+ to
+ \begin_inset LatexCommand cmd
Some insets may end up being converted to insets earlier versions of LyX
will not be able to recognize. Not sure what to do about that.
"""
def convert_latexcommand_index(document):
"Convert from LatexCommand form to collapsable form."
- i = 0
+ i = 0
while True:
i = find_token(document.body, "\\begin_inset CommandInset index", i)
if i == -1:
document.body.insert(i + 4, "\\end_inset")
i += 2
# Generic, \\ -> \backslash:
- g = wrap_into_ert(g, r'\\', '\\backslash{}')
+ g = wrap_into_ert(g, r'\\', '\\backslash')
g = wrap_into_ert(g, '{', '{')
g = wrap_into_ert(g, '}', '}')
document.body.insert(i + 3, g)
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"):
- line = line[16:]
+ 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:]
- line = line.replace(u'ä', r'\\\"a').replace(u'ö', r'\\\"o').replace(u'ü', r'\\\"u')
+ 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:
+ line = line.replace(u'ä', r'\\\"a').replace(u'ö', r'\\\"o').replace(u'ü', r'\\\"u')
+ 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):
document.header[j] = "\\inputencoding JIS"
k = 0
k = find_token(document.header, "\\inputencoding SJIS-plain", 0)
- if k != -1: # convert to UTF8 since there is currently no SJIS encoding
+ if k != -1: # convert to UTF8 since there is currently no SJIS encoding
document.header[k] = "\\inputencoding UTF8"
i = k
continue
newstuff = ["\\begin_inset Flex URL",
- "status collapsed", "",
+ "status collapsed", "",
"\\begin_layout Standard",
"",
target,
return
m = r.match(document.body[i])
if m == None:
- document.warning("Weirdly formed \\begin_layout at line " + i + " of body!")
+ document.warning("Weirdly formed \\begin_layout at line %d of body!" % i)
i += 1
continue
m = m.group(1)
cmd = m.group(1)
fn = m.group(2)
opt = m.group(3)
- insertion = ["\\begin_inset CommandInset include",
+ insertion = ["\\begin_inset CommandInset include",
"LatexCommand " + cmd, previewline,
"filename \"" + fn + "\""]
newlines = 2
i = 0
while 1:
i = find_tokens(document.body, ["\\begin_inset Note Framed", "\\begin_inset Note Shaded"], i)
-
if i == -1:
return
- document.body[i] = document.body[i].replace("\\begin_inset Note", "\\begin_inset Box")
- document.body.insert(i + 1, 'position "t"\nhor_pos "c"\nhas_inner_box 0\ninner_pos "t"\n' \
- 'use_parbox 0\nwidth "100col%"\nspecial "none"\nheight "1in"\n' \
- 'height_special "totalheight"')
- i = i + 1
+ subst = [document.body[i].replace("\\begin_inset Note", "\\begin_inset Box"),
+ 'position "t"',
+ 'hor_pos "c"',
+ 'has_inner_box 0'
+ 'inner_pos "t"',
+ 'use_parbox 0',
+ 'width "100col%"',
+ 'special "none"',
+ 'height "1in"',
+ 'height_special "totalheight"']
+ document.body[i:i+1] = subst
+ i = i + 9
def convert_module_names(document):
document.warning("Malformed LyX document: Missing `status' tag in Box inset.")
return
status = document.body[k]
- l = find_token(document.body, "\\begin_layout Standard", i + 1, j)
+ l = find_default_layout(document, i + 1, j)
if l == -1:
- document.warning("Malformed LyX document: Missing `\\begin_layout Standard' in Box inset.")
+ document.warning("Malformed LyX document: Missing `\\begin_layout' in Box inset.")
return
m = find_token(document.body, "\\end_layout", i + 1, j)
if m == -1:
del document.body[i+1:k]
else:
document.body[i] = document.body[i].replace("\\begin_inset Box Shaded", "\\begin_inset Box Frameless")
- document.body.insert(l + 1, "\\begin_inset Note Shaded\n" + status + "\n\\begin_layout Standard\n")
- document.body.insert(m + 1, "\\end_layout\n\\end_inset")
+ subst1 = [document.body[l],
+ "\\begin_inset Note Shaded",
+ status,
+ '\\begin_layout Standard']
+ document.body[l:l + 1] = subst1
+ subst2 = [document.body[m], "\\end_layout", "\\end_inset"]
+ document.body[m:m + 1] = subst2
i = i + 1
def revert_slash(document):
'Revert \\SpecialChar \\slash{} to ERT'
+ r = re.compile(r'\\SpecialChar \\slash{}')
for i in range(len(document.body)):
- document.body[i] = document.body[i].replace('\\SpecialChar \\slash{}', \
- '\\begin_inset ERT\nstatus collapsed\n\n' \
- '\\begin_layout Standard\n\n\n\\backslash\n' \
- 'slash{}\n\\end_layout\n\n\\end_inset\n\n')
+ m = r.match(document.body[i])
+ if m:
+ subst = ['\\begin_inset ERT',
+ 'status collapsed', '',
+ '\\begin_layout Standard',
+ '', '', '\\backslash',
+ 'slash{}',
+ '\\end_layout', '',
+ '\\end_inset', '']
+ document.body[i: i+1] = subst
def revert_nobreakdash(document):
r = re.compile(r'\\SpecialChar \\nobreakdash-')
m = r.match(line)
if m:
- found = 1
- document.body[i] = document.body[i].replace('\\SpecialChar \\nobreakdash-', \
- '\\begin_inset ERT\nstatus collapsed\n\n' \
- '\\begin_layout Standard\n\n\n\\backslash\n' \
- 'nobreakdash-\n\\end_layout\n\n\\end_inset\n\n')
- if not found:
- return
- j = find_token(document.header, "\\use_amsmath", 0)
- if j == -1:
- document.warning("Malformed LyX document: Missing '\\use_amsmath'.")
- return
- document.header[j] = "\\use_amsmath 2"
+ subst = ['\\begin_inset ERT',
+ 'status collapsed', '',
+ '\\begin_layout Standard', '', '',
+ '\\backslash',
+ 'nobreakdash-',
+ '\\end_layout', '',
+ '\\end_inset', '']
+ document.body[i:i+1] = subst
+ j = find_token(document.header, "\\use_amsmath", 0)
+ if j == -1:
+ document.warning("Malformed LyX document: Missing '\\use_amsmath'.")
+ return
+ document.header[j] = "\\use_amsmath 2"
def revert_nocite_key(body, start, end):
return
revert_nocite_key(document.body, i + 1, j)
document.body[i-1] = "\\begin_inset ERT"
- document.body[i] = "status collapsed\n\n" \
- "\\begin_layout Standard"
- document.body.insert(j, "\\end_layout\n");
+ document.body[i:i+1] = ["status collapsed", "", "\\begin_layout Standard"]
+ document.body[j+1:j+1] = ["\\end_layout", ""]
i = j
for k in range(i, j):
if (document.body[k] == 'btprint "btPrintAll"'):
del document.body[k]
- document.body.insert(i, "\\begin_inset ERT\n" \
- "status collapsed\n\n\\begin_layout Standard\n\n" \
- "\\backslash\nnocite{*}\n" \
- "\\end_layout\n\\end_inset\n")
+ subst = ["\\begin_inset ERT",
+ "status collapsed", "",
+ "\\begin_layout Standard", "",
+ "\\backslash",
+ "nocite{*}",
+ "\\end_layout",
+ "\\end_inset"]
+ document.body[i:i] = subst
i = j
" Revert sideways custom floats. "
i = 0
while 1:
- i = find_token(document.body, "\\begin_inset Float", i)
+ # whitespace intended (exclude \\begin_inset FloatList)
+ i = find_token(document.body, "\\begin_inset Float ", i)
if i == -1:
return
line = document.body[i]
r = re.compile(r'\\begin_inset Float (.*)$')
m = r.match(line)
+ if m == None:
+ document.warning("Unable to match line " + str(i) + " of body!")
+ i += 1
+ continue
floattype = m.group(1)
if floattype == "figure" or floattype == "table":
i = i + 1
i = i + 1
continue
if get_value(document.body, 'sideways', i, j) != "false":
- l = find_token(document.body, "\\begin_layout Standard", i + 1, j)
+ l = find_default_layout(document, i + 1, j)
if l == -1:
- document.warning("Malformed LyX document: Missing `\\begin_layout Standard' in Float inset.")
+ document.warning("Malformed LyX document: Missing `\\begin_layout' in Float inset.")
return
document.body[j] = '\\begin_layout Standard\n\\begin_inset ERT\nstatus collapsed\n\n' \
'\\begin_layout Standard\n\n\n\\backslash\n' \
" Revert wide sideways floats. "
i = 0
while 1:
- i = find_token(document.body, '\\begin_inset Float', i)
+ # whitespace intended (exclude \\begin_inset FloatList)
+ i = find_token(document.body, '\\begin_inset Float ', i)
if i == -1:
return
line = document.body[i]
r = re.compile(r'\\begin_inset Float (.*)$')
m = r.match(line)
+ if m == None:
+ document.warning("Unable to match line " + str(i) + " of body!")
+ i += 1
+ continue
floattype = m.group(1)
if floattype != "figure" and floattype != "table":
i = i + 1
continue
if get_value(document.body, 'sideways', i, j) != "false":
if get_value(document.body, 'wide', i, j) != "false":
- l = find_token(document.body, "\\begin_layout Standard", i + 1, j)
+ l = find_default_layout(document, i + 1, j)
if l == -1:
- document.warning("Malformed LyX document: Missing `\\begin_layout Standard' in Float inset.")
+ document.warning("Malformed LyX document: Missing `\\begin_layout' in Float inset.")
return
document.body[j] = '\\begin_layout Standard\n\\begin_inset ERT\nstatus collapsed\n\n' \
'\\begin_layout Standard\n\n\n\\backslash\n' \
i = i + 1
+def revert_inset_embedding(document, type):
+ ' Remove embed tag from certain type of insets'
+ i = 0
+ while 1:
+ i = find_token(document.body, "\\begin_inset %s" % type, i)
+ if i == -1:
+ return
+ j = find_end_of_inset(document.body, i)
+ if j == -1:
+ document.warning("Malformed lyx document: Missing '\\end_inset'.")
+ i = i + 1
+ continue
+ k = find_token(document.body, "\tembed", i, j)
+ if k == -1:
+ k = find_token(document.body, "embed", i, j)
+ if k != -1:
+ del document.body[k]
+ i = i + 1
+
+
+def revert_external_embedding(document):
+ ' Remove embed tag from external inset '
+ revert_inset_embedding(document, 'External')
+
+
def convert_subfig(document):
" Convert subfigures to subfloats. "
i = 0
del document.body[l]
del document.body[k]
document.body[i] = '\\begin_inset Float figure\nwide false\nsideways false\n' \
- 'status open\n\n\\begin_layout PlainLayout\n\\begin_inset Caption\n\n\\begin_layout PlainLayout\n' \
- + caption + '\n\\end_layout\n\n\\end_inset\n\n\\end_layout\n\n\\begin_layout PlainLayout\n' + savestr
+ 'status open\n\n\\begin_layout Plain Layout\n\\begin_inset Caption\n\n\\begin_layout Plain Layout\n' \
+ + caption + '\n\\end_layout\n\n\\end_inset\n\n\\end_layout\n\n\\begin_layout Plain Layout\n' + savestr
savestr = document.body[j]
document.body[j] = '\n\\end_layout\n\n\\end_inset\n' + savestr
" Revert subfloats. "
i = 0
while 1:
- i = find_token(document.body, '\\begin_inset Float', i)
+ # whitespace intended (exclude \\begin_inset FloatList)
+ i = find_token(document.body, '\\begin_inset Float ', i)
if i == -1:
return
while 1:
i = i + 1
continue
# look for embedded float (= subfloat)
- k = find_token(document.body, '\\begin_inset Float', i + 1, j)
+ # whitespace intended (exclude \\begin_inset FloatList)
+ k = find_token(document.body, '\\begin_inset Float ', i + 1, j)
if k == -1:
break
l = find_end_of_inset(document.body, k)
document.warning("Malformed lyx document: Missing '\\end_inset' (embedded float).")
i = i + 1
continue
- m = find_token(document.body, "\\begin_layout PlainLayout", k + 1, l)
+ m = find_default_layout(document, k + 1, l)
# caption?
cap = find_token(document.body, '\\begin_inset Caption', k + 1, l)
caption = ''
if optend == -1:
document.warning("Malformed lyx document: Missing '\\end_inset' (OptArg).")
return
- optc = find_token(document.body, "\\begin_layout PlainLayout", opt, optend)
+ optc = find_default_layout(document, opt, optend)
if optc == -1:
- document.warning("Malformed LyX document: Missing `\\begin_layout PlainLayout' in Float inset.")
+ document.warning("Malformed LyX document: Missing `\\begin_layout' in Float inset.")
return
optcend = find_end_of(document.body, optc, "\\begin_layout", "\\end_layout")
for line in document.body[optc:optcend]:
caption += line.strip()
if len(label) > 0:
caption += "\\backslash\nlabel{" + label + "}"
- document.body[l] = '\\begin_layout PlainLayout\n\\begin_inset ERT\nstatus collapsed\n\n' \
- '\\begin_layout PlainLayout\n\n}\n\\end_layout\n\n\\end_inset\n\n\\end_layout\n\n\\begin_layout PlainLayout\n'
+ document.body[l] = '\\begin_layout Plain Layout\n\\begin_inset ERT\nstatus collapsed\n\n' \
+ '\\begin_layout Plain Layout\n\n}\n\\end_layout\n\n\\end_inset\n\n\\end_layout\n\n\\begin_layout Plain Layout\n'
del document.body[cap:capend+1]
del document.body[k+1:m-1]
insertion = '\\begin_inset ERT\nstatus collapsed\n\n' \
- '\\begin_layout PlainLayout\n\n\\backslash\n' \
+ '\\begin_layout Plain Layout\n\n\\backslash\n' \
'subfloat'
if len(shortcap) > 0:
insertion = insertion + "[" + shortcap + "]"
" Remove \extra_embedded_files from buffer params "
i = find_token(document.header, '\\extra_embedded_files', 0)
if i == -1:
- document.warning("Malformed lyx document: Missing '\\extra_embedded_files'.")
return
document.header.pop(i)
def convert_spaceinset(document):
- " Convert '\\InsetSpace foo' to '\\begin_inset Space foo\n\\end_inset' "
- i = 0
- while True:
- i = find_token(document.body, "\\InsetSpace", i)
- if i == -1:
- return
- document.body[i] = document.body[i].replace('\\InsetSpace', '\\begin_inset Space')
- document.body[i] = document.body[i] + "\n\\end_inset"
+ " Convert '\\InsetSpace foo' to '\\begin_inset Space foo\n\\end_inset' "
+ for i in range(len(document.body)):
+ m = re.match(r'(.*)\\InsetSpace (.*)', document.body[i])
+ if m:
+ before = m.group(1)
+ after = m.group(2)
+ subst = [before, "\\begin_inset Space " + after, "\\end_inset"]
+ document.body[i: i+1] = subst
def revert_spaceinset(document):
'hspace{' + length + '}\n\\end_layout\n\n\\end_inset\n\n')
+def revert_protected_hfill(document):
+ ' Revert \\begin_inset Space \\hspace*{\\fill} to ERT '
+ i = 0
+ while True:
+ i = find_token(document.body, '\\begin_inset Space \\hspace*{\\fill}', i)
+ if i == -1:
+ return
+ j = find_end_of_inset(document.body, i)
+ if j == -1:
+ document.warning("Malformed LyX document: Could not find end of space inset.")
+ continue
+ del document.body[j]
+ document.body[i] = document.body[i].replace('\\begin_inset Space \\hspace*{\\fill}', \
+ '\\begin_inset ERT\nstatus collapsed\n\n' \
+ '\\begin_layout Standard\n\n\n\\backslash\n' \
+ 'hspace*{\n\\backslash\nfill}\n\\end_layout\n\n\\end_inset\n\n')
+
+
+def revert_leftarrowfill(document):
+ ' Revert \\begin_inset Space \\leftarrowfill{} to ERT '
+ i = 0
+ while True:
+ i = find_token(document.body, '\\begin_inset Space \\leftarrowfill{}', i)
+ if i == -1:
+ return
+ j = find_end_of_inset(document.body, i)
+ if j == -1:
+ document.warning("Malformed LyX document: Could not find end of space inset.")
+ continue
+ del document.body[j]
+ document.body[i] = document.body[i].replace('\\begin_inset Space \\leftarrowfill{}', \
+ '\\begin_inset ERT\nstatus collapsed\n\n' \
+ '\\begin_layout Standard\n\n\n\\backslash\n' \
+ 'leftarrowfill{}\n\\end_layout\n\n\\end_inset\n\n')
+
+
+def revert_rightarrowfill(document):
+ ' Revert \\begin_inset Space \\rightarrowfill{} to ERT '
+ i = 0
+ while True:
+ i = find_token(document.body, '\\begin_inset Space \\rightarrowfill{}', i)
+ if i == -1:
+ return
+ j = find_end_of_inset(document.body, i)
+ if j == -1:
+ document.warning("Malformed LyX document: Could not find end of space inset.")
+ continue
+ del document.body[j]
+ document.body[i] = document.body[i].replace('\\begin_inset Space \\rightarrowfill{}', \
+ '\\begin_inset ERT\nstatus collapsed\n\n' \
+ '\\begin_layout Standard\n\n\n\\backslash\n' \
+ 'rightarrowfill{}\n\\end_layout\n\n\\end_inset\n\n')
+
+
+def revert_upbracefill(document):
+ ' Revert \\begin_inset Space \\upbracefill{} to ERT '
+ i = 0
+ while True:
+ i = find_token(document.body, '\\begin_inset Space \\upbracefill{}', i)
+ if i == -1:
+ return
+ j = find_end_of_inset(document.body, i)
+ if j == -1:
+ document.warning("Malformed LyX document: Could not find end of space inset.")
+ continue
+ del document.body[j]
+ document.body[i] = document.body[i].replace('\\begin_inset Space \\upbracefill{}', \
+ '\\begin_inset ERT\nstatus collapsed\n\n' \
+ '\\begin_layout Standard\n\n\n\\backslash\n' \
+ 'upbracefill{}\n\\end_layout\n\n\\end_inset\n\n')
+
+
+def revert_downbracefill(document):
+ ' Revert \\begin_inset Space \\downbracefill{} to ERT '
+ i = 0
+ while True:
+ i = find_token(document.body, '\\begin_inset Space \\downbracefill{}', i)
+ if i == -1:
+ return
+ j = find_end_of_inset(document.body, i)
+ if j == -1:
+ document.warning("Malformed LyX document: Could not find end of space inset.")
+ continue
+ del document.body[j]
+ document.body[i] = document.body[i].replace('\\begin_inset Space \\downbracefill{}', \
+ '\\begin_inset ERT\nstatus collapsed\n\n' \
+ '\\begin_layout Standard\n\n\n\\backslash\n' \
+ 'downbracefill{}\n\\end_layout\n\n\\end_inset\n\n')
+
+
+def revert_local_layout(document):
+ ' Revert local layout headers.'
+ i = 0
+ while True:
+ i = find_token(document.header, "\\begin_local_layout", i)
+ if i == -1:
+ return
+ j = find_end_of(document.header, i, "\\begin_local_layout", "\\end_local_layout")
+ if j == -1:
+ # this should not happen
+ break
+ document.header[i : j + 1] = []
+
+
+def convert_pagebreaks(document):
+ ' Convert inline Newpage insets to new format '
+ i = 0
+ while True:
+ i = find_token(document.body, '\\newpage', i)
+ if i == -1:
+ break
+ document.body[i:i+1] = ['\\begin_inset Newpage newpage',
+ '\\end_inset']
+ i = 0
+ while True:
+ i = find_token(document.body, '\\pagebreak', i)
+ if i == -1:
+ break
+ document.body[i:i+1] = ['\\begin_inset Newpage pagebreak',
+ '\\end_inset']
+ i = 0
+ while True:
+ i = find_token(document.body, '\\clearpage', i)
+ if i == -1:
+ break
+ document.body[i:i+1] = ['\\begin_inset Newpage clearpage',
+ '\\end_inset']
+ i = 0
+ while True:
+ i = find_token(document.body, '\\cleardoublepage', i)
+ if i == -1:
+ break
+ document.body[i:i+1] = ['\\begin_inset Newpage cleardoublepage',
+ '\\end_inset']
+
+
+def revert_pagebreaks(document):
+ ' Revert \\begin_inset Newpage to previous inline format '
+ i = 0
+ while True:
+ i = find_token(document.body, '\\begin_inset Newpage', i)
+ if i == -1:
+ return
+ j = find_end_of_inset(document.body, i)
+ if j == -1:
+ document.warning("Malformed LyX document: Could not find end of Newpage inset.")
+ continue
+ del document.body[j]
+ document.body[i] = document.body[i].replace('\\begin_inset Newpage newpage', '\\newpage')
+ document.body[i] = document.body[i].replace('\\begin_inset Newpage pagebreak', '\\pagebreak')
+ document.body[i] = document.body[i].replace('\\begin_inset Newpage clearpage', '\\clearpage')
+ document.body[i] = document.body[i].replace('\\begin_inset Newpage cleardoublepage', '\\cleardoublepage')
+
+
+def convert_linebreaks(document):
+ ' Convert inline Newline insets to new format '
+ i = 0
+ while True:
+ i = find_token(document.body, '\\newline', i)
+ if i == -1:
+ break
+ document.body[i:i+1] = ['\\begin_inset Newline newline',
+ '\\end_inset']
+ i = 0
+ while True:
+ i = find_token(document.body, '\\linebreak', i)
+ if i == -1:
+ break
+ document.body[i:i+1] = ['\\begin_inset Newline linebreak',
+ '\\end_inset']
+
+
+def revert_linebreaks(document):
+ ' Revert \\begin_inset Newline to previous inline format '
+ i = 0
+ while True:
+ i = find_token(document.body, '\\begin_inset Newline', i)
+ if i == -1:
+ return
+ j = find_end_of_inset(document.body, i)
+ if j == -1:
+ document.warning("Malformed LyX document: Could not find end of Newline inset.")
+ continue
+ del document.body[j]
+ document.body[i] = document.body[i].replace('\\begin_inset Newline newline', '\\newline')
+ document.body[i] = document.body[i].replace('\\begin_inset Newline linebreak', '\\linebreak')
+
+
+def convert_japanese_plain(document):
+ ' Set language japanese-plain to japanese '
+ i = 0
+ if document.language == "japanese-plain":
+ document.language = "japanese"
+ i = find_token(document.header, "\\language", 0)
+ if i != -1:
+ document.header[i] = "\\language japanese"
+ j = 0
+ while True:
+ j = find_token(document.body, "\\lang japanese-plain", j)
+ if j == -1:
+ return
+ document.body[j] = document.body[j].replace("\\lang japanese-plain", "\\lang japanese")
+ j = j + 1
+
+
+def revert_pdfpages(document):
+ ' Revert pdfpages external inset to ERT '
+ i = 0
+ while 1:
+ i = find_token(document.body, "\\begin_inset External", i)
+ if i == -1:
+ return
+ j = find_end_of_inset(document.body, i)
+ if j == -1:
+ document.warning("Malformed lyx document: Missing '\\end_inset'.")
+ i = i + 1
+ continue
+ if get_value(document.body, 'template', i, j) == "PDFPages":
+ filename = get_value(document.body, 'filename', i, j)
+ extra = ''
+ r = re.compile(r'\textra PDFLaTeX \"(.*)\"$')
+ for k in range(i, j):
+ m = r.match(document.body[k])
+ if m:
+ extra = m.group(1)
+ angle = get_value(document.body, 'rotateAngle', i, j)
+ width = get_value(document.body, 'width', i, j)
+ height = get_value(document.body, 'height', i, j)
+ scale = get_value(document.body, 'scale', i, j)
+ keepAspectRatio = find_token(document.body, "\tkeepAspectRatio", i, j)
+ options = extra
+ if angle != '':
+ if options != '':
+ options += ",angle=" + angle
+ else:
+ options += "angle=" + angle
+ if width != '':
+ if options != '':
+ options += ",width=" + convert_len(width)
+ else:
+ options += "width=" + convert_len(width)
+ if height != '':
+ if options != '':
+ options += ",height=" + convert_len(height)
+ else:
+ options += "height=" + convert_len(height)
+ if scale != '':
+ if options != '':
+ options += ",scale=" + scale
+ else:
+ options += "scale=" + scale
+ if keepAspectRatio != '':
+ if options != '':
+ options += ",keepaspectratio"
+ else:
+ options += "keepaspectratio"
+ if options != '':
+ options = '[' + options + ']'
+ del document.body[i+1:j+1]
+ document.body[i:i+1] = ['\\begin_inset ERT',
+ 'status collapsed',
+ '',
+ '\\begin_layout Standard',
+ '',
+ '\\backslash',
+ 'includepdf' + options + '{' + filename + '}',
+ '\\end_layout',
+ '',
+ '\\end_inset']
+ add_to_preamble(document, ['\\usepackage{pdfpages}\n'])
+ i = i + 1
+ continue
+ i = i + 1
+
+
+def revert_mexican(document):
+ ' Set language Spanish(Mexico) to Spanish '
+ i = 0
+ if document.language == "spanish-mexico":
+ document.language = "spanish"
+ i = find_token(document.header, "\\language", 0)
+ if i != -1:
+ document.header[i] = "\\language spanish"
+ j = 0
+ while True:
+ j = find_token(document.body, "\\lang spanish-mexico", j)
+ if j == -1:
+ return
+ document.body[j] = document.body[j].replace("\\lang spanish-mexico", "\\lang spanish")
+ j = j + 1
+
+
+def remove_embedding(document):
+ ' Remove embed tag from all insets '
+ revert_inset_embedding(document, 'Graphics')
+ revert_inset_embedding(document, 'External')
+ revert_inset_embedding(document, 'CommandInset include')
+ revert_inset_embedding(document, 'CommandInset bibtex')
+
+
+def revert_master(document):
+ ' Remove master param '
+ i = find_token(document.header, "\\master", 0)
+ if i != -1:
+ del document.header[i]
+
+
+def revert_graphics_group(document):
+ ' Revert group information from graphics insets '
+ i = 0
+ while 1:
+ i = find_token(document.body, "\\begin_inset Graphics", i)
+ if i == -1:
+ return
+ j = find_end_of_inset(document.body, i)
+ if j == -1:
+ document.warning("Malformed lyx document: Missing '\\end_inset'.")
+ i = i + 1
+ continue
+ k = find_token(document.body, " groupId", i, j)
+ if k == -1:
+ i = i + 1
+ continue
+ del document.body[k]
+ i = i + 1
+
+
+def update_apa_styles(document):
+ ' Replace obsolete styles '
+
+ if document.textclass != "apa":
+ return
+
+ obsoletedby = { "Acknowledgments": "Acknowledgements",
+ "Section*": "Section",
+ "Subsection*": "Subsection",
+ "Subsubsection*": "Subsubsection",
+ "Paragraph*": "Paragraph",
+ "Subparagraph*": "Subparagraph"}
+ i = 0
+ while 1:
+ i = find_token(document.body, "\\begin_layout", i)
+ if i == -1:
+ return
+
+ layout = document.body[i][14:]
+ if layout in obsoletedby:
+ document.body[i] = "\\begin_layout " + obsoletedby[layout]
+
+ i += 1
+
+
+def convert_paper_sizes(document):
+ ' exchange size options legalpaper and executivepaper to correct order '
+ # routine is needed to fix http://bugzilla.lyx.org/show_bug.cgi?id=4868
+ i = 0
+ j = 0
+ i = find_token(document.header, "\\papersize executivepaper", 0)
+ if i != -1:
+ document.header[i] = "\\papersize legalpaper"
+ return
+ j = find_token(document.header, "\\papersize legalpaper", 0)
+ if j != -1:
+ document.header[j] = "\\papersize executivepaper"
+
+
+def revert_paper_sizes(document):
+ ' exchange size options legalpaper and executivepaper to correct order '
+ i = 0
+ j = 0
+ i = find_token(document.header, "\\papersize executivepaper", 0)
+ if i != -1:
+ document.header[i] = "\\papersize legalpaper"
+ return
+ j = find_token(document.header, "\\papersize legalpaper", 0)
+ if j != -1:
+ document.header[j] = "\\papersize executivepaper"
+
+
+def convert_InsetSpace(document):
+ " Convert '\\begin_inset Space foo' to '\\begin_inset space foo'"
+ i = 0
+ while True:
+ i = find_token(document.body, "\\begin_inset Space", i)
+ if i == -1:
+ return
+ document.body[i] = document.body[i].replace('\\begin_inset Space', '\\begin_inset space')
+
+
+def revert_InsetSpace(document):
+ " Revert '\\begin_inset space foo' to '\\begin_inset Space foo'"
+ i = 0
+ while True:
+ i = find_token(document.body, "\\begin_inset space", i)
+ if i == -1:
+ return
+ document.body[i] = document.body[i].replace('\\begin_inset space', '\\begin_inset Space')
+
+
##
# Conversion hub
#
[316, [convert_subfig]],
[317, []],
[318, []],
- [319, [convert_spaceinset, convert_hfill]]
+ [319, [convert_spaceinset, convert_hfill]],
+ [320, []],
+ [321, [convert_tablines]],
+ [322, []],
+ [323, [convert_pagebreaks]],
+ [324, [convert_linebreaks]],
+ [325, [convert_japanese_plain]],
+ [326, []],
+ [327, []],
+ [328, [remove_embedding, remove_extra_embedded_files, remove_inzip_options]],
+ [329, []],
+ [330, []],
+ [331, [convert_ltcaption]],
+ [332, []],
+ [333, [update_apa_styles]],
+ [334, [convert_paper_sizes]],
+ [335, [convert_InsetSpace]],
]
-revert = [[318, [revert_spaceinset, revert_hfills, revert_hspace]],
+revert = [[334, [revert_InsetSpace]],
+ [333, [revert_paper_sizes]],
+ [332, []],
+ [331, [revert_graphics_group]],
+ [330, [revert_ltcaption]],
+ [329, [revert_leftarrowfill, revert_rightarrowfill, revert_upbracefill, revert_downbracefill]],
+ [328, [revert_master]],
+ [327, []],
+ [326, [revert_mexican]],
+ [325, [revert_pdfpages]],
+ [324, []],
+ [323, [revert_linebreaks]],
+ [322, [revert_pagebreaks]],
+ [321, [revert_local_layout]],
+ [320, [revert_tablines]],
+ [319, [revert_protected_hfill]],
+ [318, [revert_spaceinset, revert_hfills, revert_hspace]],
[317, [remove_extra_embedded_files]],
[316, [revert_wrapplacement]],
[315, [revert_subfig]],
[313, []],
[312, [revert_module_names]],
[311, [revert_rotfloat, revert_widesideways]],
- [310, []],
+ [310, [revert_external_embedding]],
[309, [revert_btprintall]],
[308, [revert_nocite]],
[307, [revert_serbianlatin]],