]> git.lyx.org Git - lyx.git/blobdiff - lib/lyx2lyx/lyx_2_0.py
lyx_2_0.py: coding style fixes
[lyx.git] / lib / lyx2lyx / lyx_2_0.py
index 041eac058e5c3004ab9215e3317c551d8efa7cb5..ad9a5618e5c15388ee27d76de7093fc872710750 100644 (file)
@@ -32,7 +32,7 @@ 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 + '"'):]
+        document.body[m] = document.body[m][:l - 1] + document.body[m][l+len(option + '="' + val + '"'):]
     return l
 
 def find_end_of_inset(lines, i):
@@ -108,34 +108,41 @@ def old_put_cmd_in_ert(string):
     return string
 
 
-# This routine wraps some content in an ERT inset. It returns a 
-# LIST of strings. This is how lyx2lyx works: with a list of strings, 
-# each representing a line of a LyX file. Embedded newlines confuse
+# This routine wraps some content in an ERT inset. 
+#
+# NOTE: The function accepts either a single string or a LIST of strings as
+# argument. But it returns a LIST of strings, split on \n, so that it does 
+# not have embedded newlines.
+# 
+# This is how lyx2lyx represents a LyX document: as a list of strings, 
+# each representing a line of a LyX file. Embedded newlines confuse 
 # lyx2lyx very much.
-# For this same reason, we expect as input a LIST of strings, not
-# something with embedded newlines. That said, if any of your strings
-# do have embedded newlines, the string will eventually get split on
-# them and you'll get a list back.
 #
 # A call to this routine will often go something like this:
 #   i = find_token('\\begin_inset FunkyInset', ...)
 #   ...
 #   j = find_end_of_inset(document.body, i)
 #   content = ...extract content from insets
+#   # that could be as simple as: 
+#   # content = lyx2latex(document[i:j + 1])
 #   ert = put_cmd_in_ert(content)
 #   document.body[i:j] = ert
 # Now, before we continue, we need to reset i appropriately. Normally,
 # this would be: 
 #   i += len(ert)
 # That puts us right after the ERT we just inserted.
-def put_cmd_in_ert(strlist):
+#
+def put_cmd_in_ert(arg):
     ret = ["\\begin_inset ERT", "status collapsed", "\\begin_layout Plain Layout", ""]
     # Despite the warnings just given, it will be faster for us to work
     # with a single string internally. That way, we only go through the
     # unicode_reps loop once.
-    s = "\n".join(strlist)
+    if type(arg) is list:
+      s = "\n".join(arg)
+    else:
+      s = arg
     for rep in unicode_reps:
-        s = s.replace(rep[1], rep[0].replace('\\\\', '\\'))
+      s = s.replace(rep[1], rep[0].replace('\\\\', '\\'))
     s = s.replace('\\', "\\backslash\n")
     ret += s.splitlines()
     ret += ["\\end_layout", "\\end_inset"]
@@ -147,6 +154,7 @@ def lyx2latex(document, lines):
     # clean up multiline stuff
     content = ""
     ert_end = 0
+    note_end = 0
 
     for curline in range(len(lines)):
       line = lines[curline]
@@ -174,6 +182,10 @@ def lyx2latex(document, lines):
                   line = "''"
               else:
                   line = "'"
+      elif line.startswith("\\begin_inset Note Note"):
+          # We want to skip LyX notes, so remember where the inset ends
+          note_end = find_end_of_inset(lines, curline + 1)
+          continue
       elif line.isspace() or \
             line.startswith("\\begin_layout") or \
             line.startswith("\\end_layout") or \
@@ -185,6 +197,10 @@ def lyx2latex(document, lines):
           #skip all that stuff
           continue
 
+      # Skip LyX notes
+      if note_end >= curline:
+          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',
@@ -246,15 +262,15 @@ def latex_length(string):
                 end = string[i + len(unit):]
                 string = value + latex_unit + end
             if plus > minus:
-                value = string[plus+1:i]
+                value = string[plus + 1:i]
                 value = str(float(value)/100)
-                begin = string[:plus+1]
+                begin = string[:plus + 1]
                 end = string[i+len(unit):]
                 string = begin + value + latex_unit + end
             if plus < minus:
-                value = string[minus+1:i]
+                value = string[minus + 1:i]
                 value = str(float(value)/100)
-                begin = string[:minus+1]
+                begin = string[:minus + 1]
                 string = begin + value + latex_unit
 
     # replace + and -, but only if the - is not the first character
@@ -273,54 +289,52 @@ def latex_length(string):
 
 def revert_flex_inset(document, name, LaTeXname, position):
   " Convert flex insets to TeX code "
-  i = 0
-  z = 0
+  i = position
   while True:
-    i = find_token(document.body, '\\begin_inset Flex ' + name, position)
+    i = find_token(document.body, '\\begin_inset Flex ' + name, i)
     if i == -1:
       return
-    else:
-      z = find_end_of_inset(document.body, i)
-      if z == -1:
-        document.warning("Malformed LyX document: Can't find end of Flex " + name + " inset.")
-        return
-      # remove the \end_inset
-      document.body[z - 2:z + 1] = put_cmd_in_ert("}")
-      # we need to reset character layouts if necessary
-      j = find_token(document.body, '\\emph on', i)
-      k = find_token(document.body, '\\noun on', i)
-      l = find_token(document.body, '\\series', i)
-      m = find_token(document.body, '\\family', i)
-      n = find_token(document.body, '\\shape', i)
-      o = find_token(document.body, '\\color', i)
-      p = find_token(document.body, '\\size', i)
-      q = find_token(document.body, '\\bar under', i)
-      r = find_token(document.body, '\\uuline on', i)
-      s = find_token(document.body, '\\uwave on', i)
-      t = find_token(document.body, '\\strikeout on', i)
-      if j != -1 and j < z:
-        document.body.insert(z-2, "\\emph default")
-      if k != -1 and k < z:
-        document.body.insert(z-2, "\\noun default")
-      if l != -1 and l < z:
-        document.body.insert(z-2, "\\series default")
-      if m != -1 and m < z:
-        document.body.insert(z-2, "\\family default")
-      if n != -1 and n < z:
-        document.body.insert(z-2, "\\shape default")
-      if o != -1 and o < z:
-        document.body.insert(z-2, "\\color inherit")
-      if p != -1 and p < z:
-        document.body.insert(z-2, "\\size default")
-      if q != -1 and q < z:
-        document.body.insert(z-2, "\\bar default")
-      if r != -1 and r < z:
-        document.body.insert(z-2, "\\uuline default")
-      if s != -1 and s < z:
-        document.body.insert(z-2, "\\uwave default")
-      if t != -1 and t < z:
-        document.body.insert(z-2, "\\strikeout default")
-      document.body[i:i+4] = put_cmd_in_ert(LaTeXname + "{")
+    z = find_end_of_inset(document.body, i)
+    if z == -1:
+      document.warning("Malformed LyX document: Can't find end of Flex " + name + " inset.")
+      return
+    # remove the \end_inset
+    document.body[z - 2:z + 1] = put_cmd_in_ert("}")
+    # we need to reset character layouts if necessary
+    j = find_token(document.body, '\\emph on', i)
+    k = find_token(document.body, '\\noun on', i)
+    l = find_token(document.body, '\\series', i)
+    m = find_token(document.body, '\\family', i)
+    n = find_token(document.body, '\\shape', i)
+    o = find_token(document.body, '\\color', i)
+    p = find_token(document.body, '\\size', i)
+    q = find_token(document.body, '\\bar under', i)
+    r = find_token(document.body, '\\uuline on', i)
+    s = find_token(document.body, '\\uwave on', i)
+    t = find_token(document.body, '\\strikeout on', i)
+    if j != -1 and j < z:
+      document.body.insert(z - 2, "\\emph default")
+    if k != -1 and k < z:
+      document.body.insert(z - 2, "\\noun default")
+    if l != -1 and l < z:
+      document.body.insert(z - 2, "\\series default")
+    if m != -1 and m < z:
+      document.body.insert(z - 2, "\\family default")
+    if n != -1 and n < z:
+      document.body.insert(z - 2, "\\shape default")
+    if o != -1 and o < z:
+      document.body.insert(z - 2, "\\color inherit")
+    if p != -1 and p < z:
+      document.body.insert(z - 2, "\\size default")
+    if q != -1 and q < z:
+      document.body.insert(z - 2, "\\bar default")
+    if r != -1 and r < z:
+      document.body.insert(z - 2, "\\uuline default")
+    if s != -1 and s < z:
+      document.body.insert(z - 2, "\\uwave default")
+    if t != -1 and t < z:
+      document.body.insert(z - 2, "\\strikeout default")
+    document.body[i:i + 4] = put_cmd_in_ert(LaTeXname + "{")
     i += 1
 
 
@@ -331,18 +345,45 @@ def revert_charstyles(document, name, LaTeXname, changed):
     i = find_token(document.body, name + ' on', i)
     if i == -1:
       return changed
+    j = find_token(document.body, name + ' default', i)
+    k = find_token(document.body, name + ' on', i + 1)
+    # if there is no default set, the style ends with the layout
+    # assure hereby that we found the correct layout end
+    if j != -1 and (j < k or k == -1):
+      document.body[j:j + 1] = put_cmd_in_ert("}")
     else:
-      j = find_token(document.body, name + ' default', i)
-      k = find_token(document.body, name + ' on', i + 1)
-      # if there is no default set, the style ends with the layout
-      # assure hereby that we found the correct layout end
-      if j != -1 and (j < k or k ==-1):
-       document.body[j:j+1] = put_cmd_in_ert("}")
+      j = find_token(document.body, '\\end_layout', i)
+      document.body[j:j] = put_cmd_in_ert("}")
+    document.body[i:i + 1] = put_cmd_in_ert(LaTeXname + "{")
+    changed = True
+    i += 1
+
+
+def revert_layout_command(document, name, LaTeXname, position):
+  " Reverts a command from a layout to TeX code "
+  i = position
+  while True:
+    i = find_token(document.body, '\\begin_layout ' + name, i)
+    if i == -1:
+      return
+    k = -1
+    # find the next layout
+    j = i + 1
+    while k == -1:
+      j = find_token(document.body, '\\begin_layout', j)
+      l = len(document.body)
+      # if nothing was found it was the last layout of the document
+      if j == -1:
+        document.body[l - 4:l - 4] = put_cmd_in_ert("}")
+        k = 0
+      # exclude plain layout because this can be TeX code or another inset
+      elif document.body[j] != '\\begin_layout Plain Layout':
+        document.body[j - 2:j - 2] = put_cmd_in_ert("}")
+        k = 0
       else:
-        j = find_token(document.body, '\\end_layout', i)
-        document.body[j:j] = put_cmd_in_ert("}")
-      document.body[i:i+1] = put_cmd_in_ert(LaTeXname + "{")
-      changed = True
+        j += 1
+    document.body[i] = '\\begin_layout Standard'
+    document.body[i + 1:i + 1] = put_cmd_in_ert(LaTeXname + "{")
     i += 1
 
 
@@ -380,29 +421,29 @@ def revert_tabularvalign(document):
            continue
        # don't set a box for longtables, only delete tabularvalignment
        # the alignment is 2 lines below \\begin_inset Tabular
-       p = document.body[i+2].find("islongtable")
+       p = document.body[i + 2].find("islongtable")
        if p > -1:
-           q = document.body[i+2].find("tabularvalignment")
+           q = document.body[i + 2].find("tabularvalignment")
            if q > -1:
-               document.body[i+2] = document.body[i+2][:q-1]
-               document.body[i+2] = document.body[i+2] + '>'
+               document.body[i + 2] = document.body[i + 2][:q - 1]
+               document.body[i + 2] = document.body[i + 2] + '>'
            i = i + 1
 
        # when no longtable
        if p == -1:
          tabularvalignment = 'c'
          # which valignment is specified?
-         m = document.body[i+2].find('tabularvalignment="top"')
+         m = document.body[i + 2].find('tabularvalignment="top"')
          if m > -1:
              tabularvalignment = 't'
-         m = document.body[i+2].find('tabularvalignment="bottom"')
+         m = document.body[ i+ 2].find('tabularvalignment="bottom"')
          if m > -1:
              tabularvalignment = 'b'
          # delete tabularvalignment
-         q = document.body[i+2].find("tabularvalignment")
+         q = document.body[i + 2].find("tabularvalignment")
          if q > -1:
-             document.body[i+2] = document.body[i+2][:q-1]
-             document.body[i+2] = document.body[i+2] + '>'
+             document.body[i + 2] = document.body[i + 2][:q - 1]
+             document.body[i + 2] = document.body[i + 2] + '>'
 
          # don't add a box when centered
          if tabularvalignment == 'c':
@@ -441,7 +482,7 @@ def revert_phantom(document):
                 '\\begin_layout Plain Layout\n\n\n\\backslash\n' \
                 'phantom{\n\\end_layout\n\n\\end_inset\n')
       substi = substi.split('\n')
-      document.body[i : i+4] = substi
+      document.body[i:i + 4] = substi
       i += len(substi)
       j = find_token(document.body, "\\end_layout", i)
       if j == -1:
@@ -452,7 +493,7 @@ def revert_phantom(document):
                 '\\begin_layout Plain Layout\n\n' \
                 '}\n\\end_layout\n\n\\end_inset\n')
       substj = substj.split('\n')
-      document.body[j : j+4] = substj
+      document.body[j:j + 4] = substj
       i += len(substj)
 
 
@@ -469,7 +510,7 @@ def revert_hphantom(document):
                 '\\begin_layout Plain Layout\n\n\n\\backslash\n' \
                 'hphantom{\n\\end_layout\n\n\\end_inset\n')
       substi = substi.split('\n')
-      document.body[i : i+4] = substi
+      document.body[i:i + 4] = substi
       i += len(substi)
       j = find_token(document.body, "\\end_layout", i)
       if j == -1:
@@ -480,7 +521,7 @@ def revert_hphantom(document):
                 '\\begin_layout Plain Layout\n\n' \
                 '}\n\\end_layout\n\n\\end_inset\n')
       substj = substj.split('\n')
-      document.body[j : j+4] = substj
+      document.body[j:j + 4] = substj
       i += len(substj)
 
 
@@ -497,7 +538,7 @@ def revert_vphantom(document):
                 '\\begin_layout Plain Layout\n\n\n\\backslash\n' \
                 'vphantom{\n\\end_layout\n\n\\end_inset\n')
       substi = substi.split('\n')
-      document.body[i : i+4] = substi
+      document.body[i:i + 4] = substi
       i += len(substi)
       j = find_token(document.body, "\\end_layout", i)
       if j == -1:
@@ -508,7 +549,7 @@ def revert_vphantom(document):
                 '\\begin_layout Plain Layout\n\n' \
                 '}\n\\end_layout\n\n\\end_inset\n')
       substj = substj.split('\n')
-      document.body[j : j+4] = substj
+      document.body[j:j + 4] = substj
       i += len(substj)
 
 
@@ -677,7 +718,7 @@ def revert_splitindex(document):
         ishortcut = get_value(document.header, '\\shortcut', i, k)
         if ishortcut != "" and indices == "true":
             preamble += "\\newindex[" + iname + "]{" + ishortcut + "}\n"
-        del document.header[i:k+1]
+        del document.header[i:k + 1]
         i = 0
     if preamble != "":
         insert_to_preamble(0, document, preamble)
@@ -700,7 +741,7 @@ def revert_splitindex(document):
             # escape quotes
             content = content.replace('"', r'\"')
             subst = [old_put_cmd_in_ert("\\sindex[" + itype + "]{" + content + "}")]
-            document.body[i:k+1] = subst
+            document.body[i:k + 1] = subst
         i = i + 1
     i = 0
     while True:
@@ -713,10 +754,10 @@ def revert_splitindex(document):
             j = find_token(document.body, "type", i, k)
             del document.body[j]
         elif indices == "false":
-            del document.body[i:k+1]
+            del document.body[i:k + 1]
         else:
             subst = [old_put_cmd_in_ert("\\printindex[" + ptype + "]{}")]
-            document.body[i:k+1] = subst
+            document.body[i:k + 1] = subst
         i = i + 1
 
 
@@ -763,10 +804,10 @@ def revert_subindex(document):
             continue
         ptype = get_value(document.body, 'type', i, k).strip('"')
         if indices == "false":
-            del document.body[i:k+1]
+            del document.body[i:k + 1]
         else:
             subst = [old_put_cmd_in_ert("\\printsubindex[" + ptype + "]{}")]
-            document.body[i:k+1] = subst
+            document.body[i:k + 1] = subst
         i = i + 1
 
 
@@ -788,10 +829,10 @@ def revert_printindexall(document):
             i = i + 1
             continue
         if indices == "false":
-            del document.body[i:k+1]
+            del document.body[i:k + 1]
         else:
             subst = [old_put_cmd_in_ert("\\" + ctype + "{}")]
-            document.body[i:k+1] = subst
+            document.body[i:k + 1] = subst
         i = i + 1
 
 
@@ -904,11 +945,11 @@ def revert_longtable_align(document):
       if i == -1:
           break
       # the alignment is 2 lines below \\begin_inset Tabular
-      j = document.body[i+2].find("longtabularalignment")
+      j = document.body[i + 2].find("longtabularalignment")
       if j == -1:
           break
-      document.body[i+2] = document.body[i+2][:j-1]
-      document.body[i+2] = document.body[i+2] + '>'
+      document.body[i + 2] = document.body[i + 2][:j - 1]
+      document.body[i + 2] = document.body[i + 2] + '>'
       i = i + 1
 
 
@@ -998,7 +1039,7 @@ def revert_percent_vspace_lengths(document):
                   subst = [old_put_cmd_in_ert("\\vspace*{" + length + "}")]
               else:
                   subst = [old_put_cmd_in_ert("\\vspace{" + length + "}")]
-              document.body[i:i+2] = subst
+              document.body[i:i + 2] = subst
       i = i + 1
 
 
@@ -1012,7 +1053,7 @@ def revert_percent_hspace_lengths(document):
       protected = (document.body[i].find("\\hspace*{}") != -1)
       # only revert if a custom length was set and if
       # it used a percent length
-      length = get_value(document.body, '\\length', i+1)
+      length = get_value(document.body, '\\length', i + 1)
       if length == '':
           document.warning("Malformed lyx document: Missing '\\length' in Space inset.")
           return
@@ -1027,7 +1068,7 @@ def revert_percent_hspace_lengths(document):
               subst = [old_put_cmd_in_ert("\\hspace*{" + length + "}")]
           else:
               subst = [old_put_cmd_in_ert("\\hspace{" + length + "}")]
-          document.body[i:i+3] = subst
+          document.body[i:i + 3] = subst
       i = i + 2
 
 
@@ -1039,7 +1080,7 @@ def revert_hspace_glue_lengths(document):
       if i == -1:
           break
       protected = (document.body[i].find("\\hspace*{}") != -1)
-      length = get_value(document.body, '\\length', i+1)
+      length = get_value(document.body, '\\length', i + 1)
       if length == '':
           document.warning("Malformed lyx document: Missing '\\length' in Space inset.")
           return
@@ -1054,7 +1095,7 @@ def revert_hspace_glue_lengths(document):
               subst = [old_put_cmd_in_ert("\\hspace*{" + length + "}")]
           else:
               subst = [old_put_cmd_in_ert("\\hspace{" + length + "}")]
-          document.body[i:i+3] = subst
+          document.body[i:i + 3] = subst
       i = i + 2
 
 def convert_author_id(document):
@@ -1363,13 +1404,13 @@ def revert_inset_preview(document):
       #If the layout is Standard we need to remove it, otherwise there
       #will be paragraph breaks that shouldn't be there.
       k = find_token(document.body, "\\begin_layout Standard", i)
-      if k == i+2:
-          del document.body[i : i+3]
-          del document.body[j-5 : j-2]
+      if k == i + 2:
+          del document.body[i:i + 3]
+          del document.body[j - 5:j - 2]
           i -= 6
       else:
           del document.body[i]
-          del document.body[j-1]
+          del document.body[j - 1]
           i -= 2
                 
 
@@ -1397,9 +1438,9 @@ def revert_equalspacing_xymatrix(document):
       if found != -1:
           has_equal_spacing = True
           content = [document.body[i][21:]]
-          content += document.body[i+1:j]
+          content += document.body[i + 1:j]
           subst = put_cmd_in_ert(content)
-          document.body[i:j+1] = subst
+          document.body[i:j + 1] = subst
           i += len(subst)
       else:
           for curline in range(i,j):
@@ -1570,7 +1611,7 @@ def revert_lyx_version(document):
             if document.body[k].startswith("type"):
                 typ = document.body[k][4:].strip().strip('"')
         if arg != "version" or typ != "lyxinfo":
-            i = j+1
+            i = j + 1
             continue
 
         # We do not actually know the version of LyX used to produce the document.
@@ -1578,11 +1619,11 @@ def revert_lyx_version(document):
         s = [version]
         # Now we want to check if the line after "\end_inset" is empty. It normally
         # is, so we want to remove it, too.
-        lastline = j+1
-        if document.body[j+1].strip() == "":
-            lastline = j+2
+        lastline = j + 1
+        if document.body[j + 1].strip() == "":
+            lastline = j + 2
         document.body[i: lastline] = s
-        i = i+1
+        i = i + 1
 
 
 def revert_math_scale(document):
@@ -1780,8 +1821,8 @@ def revert_argument(document):
     i = find_token(document.body, '\\begin_inset Argument', i)
     if i == -1:
       return
-      document.body[i] = "\\begin_inset OptArg"
-      i += 1
+    document.body[i] = "\\begin_inset OptArg"
+    i += 1
 
 
 def revert_makebox(document):
@@ -1792,39 +1833,73 @@ def revert_makebox(document):
     i = find_token(document.body, '\\begin_inset Box Frameless', i)
     if i == -1:
       return
-    else:
-      z = find_end_of_inset(document.body, i)
-      if z == -1:
-        document.warning("Malformed LyX document: Can't find end of box inset.")
-        return
-      j = find_token(document.body, 'use_makebox 1', i)
-      # assure we found the makebox of the current box
-      if j > i + 7 or j == -1:
-       return
-      else:
-        # remove the \end_inset
-        document.body[z - 2:z + 1] = put_cmd_in_ert("}")
-        # determine the alignment
-        k = find_token(document.body, 'hor_pos', j - 4)
-        align = document.body[k][9]
-        # determine the width
-        l = find_token(document.body, 'width "', j + 1)
-        length = document.body[l][7:]
-        # remove trailing '"'
-        length = length[:-1]
-        # latex_length returns "bool,length"
-        length = latex_length(length).split(",")[1]
-        subst = "\\makebox[" + length + "][" \
-         + align + "]{"
-        document.body[i:i+13] = put_cmd_in_ert(subst)
+    z = find_end_of_inset(document.body, i)
+    if z == -1:
+      document.warning("Malformed LyX document: Can't find end of box inset.")
+      return
+    j = find_token(document.body, 'use_makebox 1', i)
+    # assure we found the makebox of the current box
+    if j > z or j == -1:
+      return
+    y = find_token(document.body, "\\begin_layout", i)
+    if y > z or y == -1:
+      document.warning("Malformed LyX document: Can't find layout in box.")
+      return
+    # remove the \end_layout \end_inset pair
+    document.body[z - 2:z + 1] = put_cmd_in_ert("}")
+    # determine the alignment
+    k = find_token(document.body, 'hor_pos', j - 4)
+    align = document.body[k][9]
+    # determine the width
+    l = find_token(document.body, 'width "', j + 1)
+    length = document.body[l][7:]
+    # remove trailing '"'
+    length = length[:-1]
+    # latex_length returns "bool,length"
+    length = latex_length(length).split(",")[1]
+    subst = "\\makebox[" + length + "][" \
+      + align + "]{"
+    document.body[i:y + 1] = put_cmd_in_ert(subst)
     i += 1
 
 
 def revert_IEEEtran(document):
   " Convert IEEEtran layouts and styles to TeX code "
+  if document.textclass != "IEEEtran":
+    return
+
   revert_flex_inset(document, "IEEE membership", "\\IEEEmembership", 0)
   revert_flex_inset(document, "Lowercase", "\\MakeLowercase", 0)
 
+  layouts = ("Special Paper Notice", "After Title Text", "Publication ID",
+             "Page headings", "Biography without photo")
+
+  latexcmd = {"Special Paper Notice": "\\IEEEspecialpapernotice",
+              "After Title Text":     "\\IEEEaftertitletext",
+              "Publication ID":       "\\IEEEpubid"}
+
+  obsoletedby = {"Page headings":            "MarkBoth",
+                 "Biography without photo":  "BiographyNoPhoto"}
+
+  for layout in layouts:
+    i = 0
+    while True:
+        i = find_token(document.body, '\\begin_layout ' + layout, i)
+        if i == -1:
+          break
+        j = find_end_of(document.body, i, '\\begin_layout', '\\end_layout')
+        if j == -1:
+          document.warning("Malformed LyX document: Can't find end of " + layout + " layout.")
+          i += 1
+          continue
+        if layout in obsoletedby:
+          document.body[i] = "\\begin_layout " + obsoletedby[layout]
+          i = j
+        else:
+          content = lyx2latex(document, document.body[i:j + 1])
+          add_to_preamble(document, [latexcmd[layout] + "{" + content + "}"])
+          del document.body[i:j + 1]
+
 
 ##
 # Conversion hub