# Uncomment only what you need to import, please.
-from parser_tools import del_token, find_token, find_end_of, find_end_of_inset, \
+from parser_tools import del_token, find_token, find_token_backwards, find_end_of, find_end_of_inset, \
find_end_of_layout, find_re, get_option_value, get_value, get_quoted_value, \
set_option_value
#from parser_tools import find_token, find_end_of, find_tokens, \
#find_token_exact, find_end_of_inset, find_end_of_layout, \
- #find_token_backwards, is_in_inset, del_token, check_token
+ #is_in_inset, del_token, check_token
from lyx2lyx_tools import add_to_preamble, put_cmd_in_ert, get_ert
def convert_latexargs(document):
" Convert InsetArgument to new syntax "
+ if find_token(document.body, "\\begin_inset Argument", 0) == -1:
+ # nothing to do.
+ return
+
+ # A list of layouts (document classes) with only optional or no arguments.
+ # These can be safely converted to the new syntax
+ # (I took the liberty to add some of my personal layouts/modules here; JSP)
+ safe_layouts = ["aa", "aapaper", "aastex", "achemso", "acmsiggraph", "AEA",
+ "agu-dtd", "agums", "agutex", "amsart", "amsbook", "apa",
+ "arab-article", "armenian-article", "article-beamer", "article",
+ "beamer", "book", "broadway", "chess", "cl2emult", "ctex-article",
+ "ctex-book", "ctex-report", "dinbrief", "docbook-book", "docbook-chapter",
+ "docbook", "docbook-section", "doublecol-new", "dtk", "ectaart", "egs",
+ "elsarticle", "elsart", "entcs", "europecv", "extarticle", "extbook",
+ "extletter", "extreport", "foils", "frletter", "g-brief2", "g-brief",
+ "heb-article", "heb-letter", "hollywood", "IEEEtran", "ijmpc", "ijmpd",
+ "iopart", "isprs", "jarticle", "jasatex", "jbook", "jgrga", "jreport",
+ "jsarticle", "jsbeamer", "jsbook", "jss", "kluwer", "latex8", "letter", "lettre",
+ "literate-article", "literate-book", "literate-report", "llncs", "ltugboat",
+ "memoir", "moderncv", "mwart", "mwbk", "mwrep", "paper", "powerdot",
+ "recipebook", "report", "revtex4", "revtex", "scrartcl", "scrarticle-beamer",
+ "scrbook", "scrlettr", "scrlttr2", "scrreprt", "seminar", "siamltex",
+ "sigplanconf", "simplecv", "singlecol", "singlecol-new", "slides", "spie",
+ "svglobal3", "svglobal", "svjog", "svmono", "svmult", "svprobth", "tarticle",
+ "tbook", "treport", "tufte-book", "tufte-handout"]
+ # A list of "safe" modules, same as above
+ safe_modules = ["biblatex", "beameraddons", "beamersession", "braille", "customHeadersFooters",
+ "endnotes", "enumitem", "eqs-within-sections", "figs-within-sections", "fix-cm",
+ "fixltx2e", "foottoend", "hanging", "jscharstyles", "knitr", "lilypond",
+ "linguistics", "linguisticx", "logicalmkup", "minimalistic", "nomindex", "noweb",
+ "pdfcomment", "sweave", "tabs-within-sections", "theorems-ams-bytype",
+ "theorems-ams-extended-bytype", "theorems-ams-extended", "theorems-ams", "theorems-bytype",
+ "theorems-chap-bytype", "theorems-chap", "theorems-named", "theorems-sec-bytype",
+ "theorems-sec", "theorems-starred", "theorems-std", "todonotes"]
+ # Modules we need to take care of
+ caveat_modules = ["initials"]
+ # information about the relevant styles in caveat_modules (number of opt and req args)
+ # use this if we get more caveat_modules. For now, use hard coding (see below).
+ # initials = [{'Layout' : 'Initial', 'opt' : 1, 'req' : 1}]
+
+ # Is this a known safe layout?
+ safe_layout = document.textclass in safe_layouts
+ if not safe_layout:
+ document.warning("Lyx2lyx knows nothing about textclass '%s'. "
+ "Please check if short title insets have been converted correctly."
+ % document.textclass)
+ # Do we use unsafe or unknown modules
+ mods = document.get_module_list()
+ unknown_modules = False
+ used_caveat_modules = list()
+ for mod in mods:
+ if mod in safe_modules:
+ continue
+ if mod in caveat_modules:
+ used_caveat_modules.append(mod)
+ continue
+ unknown_modules = True
+ document.warning("Lyx2lyx knows nothing about module '%s'. "
+ "Please check if short title insets have been converted correctly."
+ % mod)
+
i = 0
while True:
- i = find_token(document.body, "\\begin_inset Argument", i)
- if i == -1:
- return
- # We cannot do more here since we have no access to the layout.
- # InsetArgument itself will do the real work
- # (see InsetArgument::updateBuffer())
- document.body[i] = "\\begin_inset Argument 999"
- i = i + 1
+ i = find_token(document.body, "\\begin_inset Argument", i)
+ if i == -1:
+ return
+
+ if not safe_layout or unknown_modules:
+ # We cannot do more here since we have no access to this layout.
+ # InsetArgument itself will do the real work
+ # (see InsetArgument::updateBuffer())
+ document.body[i] = "\\begin_inset Argument 999"
+ i = i + 1
+ continue
+
+ # Find beginning and end of the containing paragraph
+ parbeg = find_token_backwards(document.body, "\\begin_layout", i)
+ if parbeg == -1:
+ document.warning("Malformed lyx document: Can't find parent paragraph layout")
+ continue
+ parend = find_end_of_layout(document.body, parbeg)
+ if parend == -1:
+ document.warning("Malformed lyx document: Can't find end of parent paragraph layout")
+ continue
+ allowed_opts = -1
+ first_req = -1
+ if len(used_caveat_modules) > 0:
+ # We know for now that this must be the initials module with the Initial layout
+ # If we get more such modules, we need some automating.
+ layoutname = get_value(document.body, "\\begin_layout", parbeg)
+ if layoutname == "Initial":
+ # Layout has 1 opt and 1 req arg.
+ # Count the actual arguments
+ actualargs = 0
+ for p in range(parbeg, parend):
+ if document.body[p] == "\\begin_inset Argument":
+ actualargs += 1
+ if actualargs == 1:
+ allowed_opts = 0
+ first_req = 2
+ # Collect all arguments in this paragraph
+ argnr = 0
+ for p in range(parbeg, parend):
+ if document.body[p] == "\\begin_inset Argument":
+ argnr += 1
+ if allowed_opts != -1:
+ # We have less arguments than opt + required.
+ # required must take precedence.
+ if argnr > allowed_opts and argnr < first_req:
+ argnr = first_req
+ document.body[p] = "\\begin_inset Argument %d" % argnr
+ i = i + 1
def revert_latexargs(document):
" Revert InsetArgument to old syntax "
- # FIXME: This method does not revert correctly (it does
- # not reorder the arguments)
- # What needs to be done is this:
- # * find all arguments in a paragraph and reorder them
- # according to their ID (which is deleted)
- # So: \\begin_inset Argument 2 ... \\begin_inset Argument 1
- # => \\begin_inset Argument ... \\begin_inset Argument
- # with correct order.
i = 0
+ rx = re.compile(r'^\\begin_inset Argument (\d+)$')
+ args = dict()
while True:
- i = find_token(document.body, "\\begin_inset Argument", i)
- if i == -1:
- return
- # Convert the syntax so that LyX 2.0 can at least open this
- document.body[i] = "\\begin_inset Argument"
- i = i + 1
+ # Search for Argument insets
+ i = find_token(document.body, "\\begin_inset Argument", i)
+ if i == -1:
+ break
+ m = rx.match(document.body[i])
+ if not m:
+ # No ID: inset already reverted
+ i = i + 1
+ continue
+ # Find beginning and end of the containing paragraph
+ parbeg = find_token_backwards(document.body, "\\begin_layout", i)
+ if parbeg == -1:
+ document.warning("Malformed lyx document: Can't find parent paragraph layout")
+ continue
+ parend = find_end_of_layout(document.body, parbeg)
+ if parend == -1:
+ document.warning("Malformed lyx document: Can't find end of parent paragraph layout")
+ continue
+ # Collect all arguments in this paragraph
+ realparend = parend
+ for p in range(parbeg, parend):
+ m = rx.match(document.body[p])
+ if m:
+ val = int(m.group(1))
+ j = find_end_of_inset(document.body, p)
+ # Revert to old syntax
+ document.body[p] = "\\begin_inset Argument"
+ if j == -1:
+ document.warning("Malformed lyx document: Can't find end of Argument inset")
+ continue
+ if val > 0:
+ args[val] = document.body[p : j + 1]
+ # Adjust range end
+ realparend = realparend - len(document.body[p : j + 1])
+ # Remove arg inset at this position
+ del document.body[p : j + 1]
+ if p >= realparend:
+ break
+ # Now sort the arg insets
+ subst = [""]
+ for f in sorted(args):
+ subst += args[f]
+ del args[f]
+ # Insert the sorted arg insets at paragraph begin
+ document.body[parbeg + 1:parbeg + 1] = subst
+
+ i = parbeg + 1 + len(subst)
def revert_Argument_to_TeX_brace(document, line, n, nmax, environment):
lineArg = find_token(document.body, "\\begin_inset Argument " + str(n), line)
if lineArg != -1:
beginPlain = find_token(document.body, "\\begin_layout Plain Layout", lineArg)
- endLayout = find_token(document.body, "\\end_layout", beginPlain)
- endInset = find_token(document.body, "\\end_inset", endLayout)
+ # we have to assure that no other inset is in the Argument
+ beginInset = find_token(document.body, "\\begin_inset", beginPlain)
+ endInset = find_token(document.body, "\\end_inset", beginPlain)
+ k = beginPlain + 1
+ l = k
+ while beginInset < endInset and beginInset != -1:
+ beginInset = find_token(document.body, "\\begin_inset", k)
+ endInset = find_token(document.body, "\\end_inset", l)
+ k = beginInset + 1
+ l = endInset + 1
if environment == False:
- document.body[endLayout : endInset + 1] = put_cmd_in_ert("}{")
+ document.body[endInset - 2 : endInset + 1] = put_cmd_in_ert("}{")
del(document.body[lineArg : beginPlain + 1])
else:
- document.body[endLayout : endInset + 1] = put_cmd_in_ert("}")
+ document.body[endInset - 2 : endInset + 1] = put_cmd_in_ert("}")
document.body[lineArg : beginPlain + 1] = put_cmd_in_ert("{")
n = n + 1
return
-def convert_Argument_to_TeX_brace(document, line, n, nmax, environment):
+def convert_TeX_brace_to_Argument(document, line, n, nmax, inset, environment):
'''
Converts TeX code to an InsetArgument
- !!! Be careful if the braces are different in your case as exppected here:
- - }{ separates mandatory arguments of commands
+ !!! Be careful if the braces are different in your case as expected here:
+ - "}{" separates mandatory arguments of commands
+ - "}" + "{" separates mandatory arguments of commands
+ - "}" + " " + "{" separates mandatory arguments of commands
- { and } surround a mandatory argument of an environment
usage:
- convert_Argument_to_TeX_brace(document, LineOfBeginLayout, StartArgument, EndArgument, isEnvironment)
- LineOfBeginLayout is the line of the \begin_layout statement
+ convert_TeX_brace_to_Argument(document, LineOfBeginLayout/Inset, StartArgument, EndArgument, isInset, isEnvironment)
+ LineOfBeginLayout/Inset is the line of the \begin_layout or \begin_inset statement
StartArgument is the number of the first ERT that needs to be converted
EndArgument is the number of the last ERT that needs to be converted
- isEnvironment must be true, if the layout id for a LaTeX environment
+ isInset must be true, if braces inside an InsetLayout needs to be converted
+ isEnvironment must be true, if the layout is for a LaTeX environment
- Notes:
- - this routine will fail if the user has additional TeX-braces (there is nothing we can do)
- - this routine can currently handle only one mandatory argument of environments
- Todo:
- - support the case that }{ is in the file in 2 separate ERTs
+ Note: this routine can currently handle only one mandatory argument of environments
'''
lineArg = line
while lineArg != -1 and n < nmax + 1:
lineArg = find_token(document.body, "\\begin_inset ERT", lineArg)
if environment == False and lineArg != -1:
bracePair = find_token(document.body, "}{", lineArg)
- # assure that the "}{" is in this ERT (5 is or files saved with LyX 2.0, 4 for files exported by LyX 2.1)
- if bracePair == lineArg + 5 or bracePair == lineArg + 4:
+ # assure that the "}{" is in this ERT
+ if bracePair == lineArg + 5:
end = find_token(document.body, "\\end_inset", bracePair)
document.body[lineArg : end + 1] = ["\\end_layout", "", "\\end_inset"]
- document.body[line + 1 : line + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
+ if n == 1:
+ if inset == False:
+ document.body[line + 1 : line + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
+ else:
+ document.body[line + 4 : line + 4] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
+ else:
+ document.body[endn : endn] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
n = n + 1
+ endn = end
+ # now check the case that we have "}" + "{" in two ERTs
else:
- lineArg = lineArg + 1
+ endBrace = find_token(document.body, "}", lineArg)
+ if endBrace == lineArg + 5:
+ beginBrace = find_token(document.body, "{", endBrace)
+ # assure that the ERTs are consecutive (11 or 12 depending if there is a space between the ERTs or not)
+ if beginBrace == endBrace + 11 or beginBrace == endBrace + 12:
+ end = find_token(document.body, "\\end_inset", beginBrace)
+ document.body[lineArg : end + 1] = ["\\end_layout", "", "\\end_inset"]
+ if n == 1:
+ if inset == False:
+ document.body[line + 1 : line + 1] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
+ else:
+ document.body[line + 4 : line + 4] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
+ else:
+ document.body[endn : endn] = ["\\begin_inset Argument " + str(n), "status open", "", "\\begin_layout Plain Layout"]
+ n = n + 1
+ # set the line where the next argument will be inserted
+ if beginBrace == endBrace + 11:
+ endn = end - 11
+ else:
+ endn = end - 12
+ else:
+ lineArg = lineArg + 1
if environment == True and lineArg != -1:
opening = find_token(document.body, "{", lineArg)
if opening == lineArg + 5 or opening == lineArg + 4: # assure that the "{" is in this ERT
if i != -1:
i = find_token(document.body, "\\begin_layout Page headings", i)
if i != -1:
- convert_Argument_to_TeX_brace(document, i, 1, 1, False)
+ convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
i = i + 1
if j != -1:
j = find_token(document.body, "\\begin_layout Biography without photo", j)
if j != -1:
- convert_Argument_to_TeX_brace(document, j, 1, 1, True)
+ convert_TeX_brace_to_Argument(document, j, 1, 1, False, True)
j = j + 1
if k != -1:
# assure that we don't handle Biography Biography without photo
continue
if k != -1:
# the argument we want to convert is the second one
- convert_Argument_to_TeX_brace(document, k, 2, 2, True)
+ convert_TeX_brace_to_Argument(document, k, 2, 2, False, True)
k = k + 1
if i == -1 and j == -1 and k == -1:
return
if i != -1:
i = find_token(document.body, "\\begin_layout Altaffilation", i)
if i != -1:
- convert_Argument_to_TeX_brace(document, i, 1, 1, False)
+ convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
i = i + 1
if i == -1:
return
if i != -1:
i = find_token(document.body, "\\begin_layout Author affiliation", i)
if i != -1:
- convert_Argument_to_TeX_brace(document, i, 1, 1, False)
+ convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
i = i + 1
if i == -1:
return
if i != -1:
i = find_token(document.body, "\\begin_layout MarkBoth", i)
if i != -1:
- convert_Argument_to_TeX_brace(document, i, 1, 1, False)
+ convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
i = i + 1
if i == -1:
return
+
+def revert_SIGPLAN(document):
+ " Reverts InsetArgument of MarkBoth to TeX-code "
+ if document.textclass == "sigplanconf":
+ i = 0
+ j = 0
+ while True:
+ if i != -1:
+ i = find_token(document.body, "\\begin_layout Conference", i)
+ if i != -1:
+ revert_Argument_to_TeX_brace(document, i, 1, 1, False)
+ i = i + 1
+ if j != -1:
+ j = find_token(document.body, "\\begin_layout Author", j)
+ if j != -1:
+ revert_Argument_to_TeX_brace(document, j, 1, 2, False)
+ j = j + 1
+ if i == -1 and j == -1:
+ return
+
+
+def convert_SIGPLAN(document):
+ " Converts ERT of MarkBoth to InsetArgument "
+ if document.textclass == "sigplanconf":
+ i = 0
+ j = 0
+ while True:
+ if i != -1:
+ i = find_token(document.body, "\\begin_layout Conference", i)
+ if i != -1:
+ convert_TeX_brace_to_Argument(document, i, 1, 1, False, False)
+ i = i + 1
+ if j != -1:
+ j = find_token(document.body, "\\begin_layout Author", j)
+ if j != -1:
+ convert_TeX_brace_to_Argument(document, j, 1, 2, False, False)
+ j = j + 1
+ if i == -1 and j == -1:
+ return
+
+
+def revert_SIGGRAPH(document):
+ " Reverts InsetArgument of Flex CRcat to TeX-code "
+ if document.textclass == "acmsiggraph":
+ i = 0
+ while True:
+ if i != -1:
+ i = find_token(document.body, "\\begin_inset Flex CRcat", i)
+ if i != -1:
+ revert_Argument_to_TeX_brace(document, i, 1, 3, False)
+ i = i + 1
+ if i == -1:
+ return
+
+
+def convert_SIGGRAPH(document):
+ " Converts ERT of Flex CRcat to InsetArgument "
+ if document.textclass == "acmsiggraph":
+ i = 0
+ while True:
+ if i != -1:
+ i = find_token(document.body, "\\begin_inset Flex CRcat", i)
+ if i != -1:
+ convert_TeX_brace_to_Argument(document, i, 1, 3, True, False)
+ i = i + 1
+ if i == -1:
+ return
+
+
def revert_literate(document):
" Revert Literate document to old format "
if del_token(document.header, "noweb", 0):
document.body[i] = "\\begin_layout Scrap"
i = i + 1
+
def convert_literate(document):
" Convert Literate document to new format"
i = find_token(document.header, "\\textclass", 0)
document.body[i] = "\\begin_layout Chunk"
i = i + 1
+
+def revert_itemargs(document):
+ " Reverts \\item arguments to TeX-code "
+ while True:
+ i = find_token(document.body, "\\begin_inset Argument item:", 0)
+ j = find_end_of_inset(document.body, i)
+ if i == -1:
+ break
+ lastlay = find_token_backwards(document.body, "\\begin_layout", i)
+ beginPlain = find_token(document.body, "\\begin_layout Plain Layout", i)
+ endLayout = find_token(document.body, "\\end_layout", beginPlain)
+ endInset = find_token(document.body, "\\end_inset", endLayout)
+ content = document.body[beginPlain + 1 : endLayout]
+ del document.body[i:j+1]
+ subst = put_cmd_in_ert("[") + content + put_cmd_in_ert("]")
+ document.body[lastlay + 1:lastlay + 1] = subst
+ i = i + 1
+
+
##
# Conversion hub
#
[444, []],
[445, []],
[446, [convert_latexargs]],
- [447, [convert_IEEEtran, convert_AASTeX, convert_AGUTeX, convert_IJMP]],
- [448, [convert_literate]]
+ [447, [convert_IEEEtran, convert_AASTeX, convert_AGUTeX, convert_IJMP, convert_SIGPLAN, convert_SIGGRAPH]],
+ [448, [convert_literate]],
+ [449, []]
]
revert = [
+ [448, [revert_itemargs]],
[447, [revert_literate]],
- [446, [revert_IEEEtran, revert_AASTeX, revert_AGUTeX, revert_IJMP]],
+ [446, [revert_IEEEtran, revert_AASTeX, revert_AGUTeX, revert_IJMP, revert_SIGPLAN, revert_SIGGRAPH]],
[445, [revert_latexargs]],
[444, [revert_uop]],
[443, [revert_biolinum]],