]> git.lyx.org Git - features.git/blobdiff - lib/lyx2lyx/lyx_2_1.py
acmsiggraph: complete revision of layout and template file
[features.git] / lib / lyx2lyx / lyx_2_1.py
index ec4ed6c7c8a27d3b01e641f8e89a45e0d7794021..a0b8111b5f88bb9517250cd536c55a24e1244ea9 100644 (file)
@@ -25,13 +25,13 @@ import sys, os
 
 # 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
 
@@ -1133,37 +1133,174 @@ def revert_uop(document):
 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):
@@ -1181,13 +1318,21 @@ 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
 
@@ -1229,38 +1374,66 @@ def revert_IEEEtran(document):
         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
@@ -1292,12 +1465,12 @@ def convert_IEEEtran(document):
       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
@@ -1308,7 +1481,7 @@ def convert_IEEEtran(document):
         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
@@ -1336,7 +1509,7 @@ def convert_AASTeX(document):
       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
@@ -1364,7 +1537,7 @@ def convert_AGUTeX(document):
       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
@@ -1392,11 +1565,80 @@ def convert_IJMP(document):
       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):
@@ -1409,6 +1651,7 @@ def revert_literate(document):
         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)    
@@ -1429,6 +1672,25 @@ def convert_literate(document):
         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
 #
@@ -1468,13 +1730,15 @@ convert = [
            [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]],