]> git.lyx.org Git - lyx.git/blobdiff - lib/lyx2lyx/lyx_2_0.py
Factor out some common code.
[lyx.git] / lib / lyx2lyx / lyx_2_0.py
index e6f0b76b3c4a387b006a096b3cc74bad50eb0866..79f9f1be2f17c2fa826bf22c751038cbea3b0f8f 100644 (file)
@@ -24,7 +24,8 @@ import unicodedata
 import sys, os
 
 from parser_tools import find_token, find_end_of, find_tokens, \
-  find_end_of_inset, find_end_of_layout, get_value, get_value_string
+  find_end_of_inset, find_end_of_layout, find_token_backwards, \
+  get_containing_inset, get_value, get_value_string
   
 from lyx2lyx_tools import add_to_preamble, insert_to_preamble, \
   put_cmd_in_ert, lyx2latex, latex_length, revert_flex_inset, \
@@ -1157,6 +1158,13 @@ def revert_notefontcolor(document):
     i = find_token(document.header, "\\notefontcolor", 0)
     if i == -1:
         return
+
+    # are there any grey notes?
+    if find_token(document.body, "\\begin_inset Note Greyedout", 0) == -1:
+        # no need to do anything, and \renewcommand will throw an error
+        # since lyxgreyedout will not exist.
+        return
+
     colorcode = get_value(document.header, '\\notefontcolor', i)
     del document.header[i]
     # the color code is in the form #rrggbb where every character denotes a hex number
@@ -1168,100 +1176,67 @@ def revert_notefontcolor(document):
       ['% Commands inserted by lyx2lyx to set the font color',
         '% for greyed-out notes',
         '\\@ifundefined{definecolor}{\\usepackage{color}}{}'
-        '\\definecolor{note_fontcolor}{rgb}{'
-          + str(red) + ', ' + str(green)
-          + ', ' + str(blue) + '}',
+        '\\definecolor{note_fontcolor}{rgb}{%s,%s,%s}' % (red, green, blue),
         '\\renewenvironment{lyxgreyedout}',
         ' {\\textcolor{note_fontcolor}\\bgroup}{\\egroup}'])
 
 
 def revert_turkmen(document):
     "Set language Turkmen to English" 
-    i = 0 
+
     if document.language == "turkmen": 
         document.language = "english" 
         i = find_token(document.header, "\\language", 0) 
         if i != -1: 
             document.header[i] = "\\language english" 
+
     j = 0 
     while True: 
         j = find_token(document.body, "\\lang turkmen", j) 
         if j == -1: 
             return 
         document.body[j] = document.body[j].replace("\\lang turkmen", "\\lang english") 
-        j = j + 1 
+        j += 1 
 
 
 def revert_fontcolor(document):
     " Reverts font color to preamble code "
-    i = 0
-    colorcode = ""
-    while True:
-      i = find_token(document.header, "\\fontcolor", i)
-      if i == -1:
-          return
-      colorcode = get_value(document.header, '\\fontcolor', 0)
-      del document.header[i]
-      # don't clutter the preamble if backgroundcolor is not set
-      if colorcode == "#000000":
-          continue
-      # the color code is in the form #rrggbb where every character denotes a hex number
-      # convert the string to an int
-      red = string.atoi(colorcode[1:3],16)
-      # we want the output "0.5" for the value "127" therefore add here
-      if red != 0:
-          red = red + 1
-      redout = float(red) / 256
-      green = string.atoi(colorcode[3:5],16)
-      if green != 0:
-          green = green + 1
-      greenout = float(green) / 256
-      blue = string.atoi(colorcode[5:7],16)
-      if blue != 0:
-          blue = blue + 1
-      blueout = float(blue) / 256
-      # write the preamble
-      insert_to_preamble(0, document,
-                           '% Commands inserted by lyx2lyx to set the font color\n'
-                           + '\\@ifundefined{definecolor}{\\usepackage{color}}{}\n'
-                           + '\\definecolor{document_fontcolor}{rgb}{'
-                           + str(redout) + ', ' + str(greenout)
-                           + ', ' + str(blueout) + '}\n'
-                           + '\\color{document_fontcolor}\n')
+    i = find_token(document.header, "\\fontcolor", 0)
+    if i == -1:
+        return
+    colorcode = get_value(document.header, '\\fontcolor', i)
+    del document.header[i]
+    # don't clutter the preamble if font color is not set
+    if colorcode == "#000000":
+        return
+    # the color code is in the form #rrggbb where every character denotes a hex number
+    red = hex2ratio(colorcode[1:3])
+    green = hex2ratio(colorcode[3:5])
+    blue = hex2ratio(colorcode[5:7])
+    # write the preamble
+    insert_to_preamble(0, document,
+      ['% Commands inserted by lyx2lyx to set the font color',
+      '\\@ifundefined{definecolor}{\\usepackage{color}}{}',
+      '\\definecolor{document_fontcolor}{rgb}{%s,%s,%s}' % (red, green, blue),
+      '\\color{document_fontcolor}'])
+
 
 def revert_shadedboxcolor(document):
     " Reverts shaded box color to preamble code "
-    i = 0
-    colorcode = ""
-    while True:
-      i = find_token(document.header, "\\boxbgcolor", i)
-      if i == -1:
-          return
-      colorcode = get_value(document.header, '\\boxbgcolor', 0)
-      del document.header[i]
-      # the color code is in the form #rrggbb where every character denotes a hex number
-      # convert the string to an int
-      red = string.atoi(colorcode[1:3],16)
-      # we want the output "0.5" for the value "127" therefore increment here
-      if red != 0:
-          red = red + 1
-      redout = float(red) / 256
-      green = string.atoi(colorcode[3:5],16)
-      if green != 0:
-          green = green + 1
-      greenout = float(green) / 256
-      blue = string.atoi(colorcode[5:7],16)
-      if blue != 0:
-          blue = blue + 1
-      blueout = float(blue) / 256
-      # write the preamble
-      insert_to_preamble(0, document,
-                           '% Commands inserted by lyx2lyx to set the color\n'
-                           '% of boxes with shaded background\n'
-                           + '\\@ifundefined{definecolor}{\\usepackage{color}}{}\n'
-                           + '\\definecolor{shadecolor}{rgb}{'
-                           + str(redout) + ', ' + str(greenout)
-                           + ', ' + str(blueout) + '}\n')
+    i = find_token(document.header, "\\boxbgcolor", 0)
+    if i == -1:
+        return
+    colorcode = get_value(document.header, '\\boxbgcolor', i)
+    del document.header[i]
+    # the color code is in the form #rrggbb
+    red = hex2ratio(colorcode[1:3])
+    green = hex2ratio(colorcode[3:5])
+    blue = hex2ratio(colorcode[5:7])
+    # write the preamble
+    insert_to_preamble(0, document,
+      ['% Commands inserted by lyx2lyx to set the color of boxes with shaded background',
+      '\\@ifundefined{definecolor}{\\usepackage{color}}{}',
+      "\\definecolor{shadecolor}{rgb}{%s,%s,%s}" % (red, green, blue)])
 
 
 def revert_lyx_version(document):
@@ -1280,8 +1255,10 @@ def revert_lyx_version(document):
             return
         j = find_end_of_inset(document.body, i + 1)
         if j == -1:
-            # should not happen
             document.warning("Malformed LyX document: Could not find end of Info inset.")
+            i += 1
+            continue
+
         # We expect:
         # \begin_inset Info
         # type  "lyxinfo"
@@ -1324,7 +1301,6 @@ def revert_math_scale(document):
 
 
 def revert_pagesizes(document):
-  i = 0
   " Revert page sizes to default "
   i = find_token(document.header, '\\papersize', 0)
   if i != -1:
@@ -1338,7 +1314,6 @@ def revert_pagesizes(document):
 
 
 def revert_DIN_C_pagesizes(document):
-  i = 0
   " Revert DIN C page sizes to default "
   i = find_token(document.header, '\\papersize', 0)
   if i != -1:
@@ -1357,7 +1332,7 @@ def convert_html_quotes(document):
     line = document.header[i]
     l = re.compile(r'\\html_latex_start\s+"(.*)"')
     m = l.match(line)
-    if m != None:
+    if m:
       document.header[i] = "\\html_latex_start " + m.group(1)
       
   i = find_token(document.header, '\\html_latex_end', 0)
@@ -1365,7 +1340,7 @@ def convert_html_quotes(document):
     line = document.header[i]
     l = re.compile(r'\\html_latex_end\s+"(.*)"')
     m = l.match(line)
-    if m != None:
+    if m:
       document.header[i] = "\\html_latex_end " + m.group(1)
       
 
@@ -1377,14 +1352,22 @@ def revert_html_quotes(document):
     line = document.header[i]
     l = re.compile(r'\\html_latex_start\s+(.*)')
     m = l.match(line)
-    document.header[i] = "\\html_latex_start \"" + m.group(1) + "\""
+    if not m:
+        document.warning("Weird html_latex_start line: " + line)
+        del document.header[i]
+    else:
+        document.header[i] = "\\html_latex_start \"" + m.group(1) + "\""
       
   i = find_token(document.header, '\\html_latex_end', 0)
   if i != -1:
     line = document.header[i]
     l = re.compile(r'\\html_latex_end\s+(.*)')
     m = l.match(line)
-    document.header[i] = "\\html_latex_end \"" + m.group(1) + "\""
+    if not m:
+        document.warning("Weird html_latex_end line: " + line)
+        del document.header[i]
+    else:
+        document.header[i] = "\\html_latex_end \"" + m.group(1) + "\""
 
 
 def revert_output_sync(document):
@@ -1397,98 +1380,7 @@ def revert_output_sync(document):
     del document.header[i]
 
 
-def convert_beamer_args(document):
-  " Convert ERT arguments in Beamer to InsetArguments "
-
-  if document.textclass != "beamer" and document.textclass != "article-beamer":
-    return
-  
-  layouts = ("Block", "ExampleBlock", "AlertBlock")
-  for layout in layouts:
-    blay = 0
-    while True:
-      blay = find_token(document.body, '\\begin_layout ' + layout, blay)
-      if blay == -1:
-        break
-      elay = find_end_of(document.body, blay, '\\begin_layout', '\\end_layout')
-      if elay == -1:
-        document.warning("Malformed LyX document: Can't find end of " + layout + " layout.")
-        blay += 1
-        continue
-      bert = find_token(document.body, '\\begin_inset ERT', blay)
-      if bert == -1:
-        document.warning("Malformed Beamer LyX document: Can't find argument of " + layout + " layout.")
-        blay = elay + 1
-        continue
-      eert = find_end_of_inset(document.body, bert)
-      if eert == -1:
-        document.warning("Malformed LyX document: Can't find end of ERT.")
-        blay = elay + 1
-        continue
-      
-      # So the ERT inset begins at line k and goes to line l. We now wrap it in 
-      # an argument inset.
-      # Do the end first, so as not to mess up the variables.
-      document.body[eert + 1:eert + 1] = ['', '\\end_layout', '', '\\end_inset', '']
-      document.body[bert:bert] = ['\\begin_inset OptArg', 'status open', '', 
-          '\\begin_layout Plain Layout']
-      blay = elay + 9
-
-
-def revert_beamer_args(document):
-  " Revert Beamer arguments to ERT "
-  
-  if document.textclass != "beamer" and document.textclass != "article-beamer":
-    return
-    
-  layouts = ("Block", "ExampleBlock", "AlertBlock")
-  for layout in layouts:
-    blay = 0
-    while True:
-      blay = find_token(document.body, '\\begin_layout ' + layout, blay)
-      if blay == -1:
-        break
-      elay = find_end_of(document.body, blay, '\\begin_layout', '\\end_layout')
-      if elay == -1:
-        document.warning("Malformed LyX document: Can't find end of " + layout + " layout.")
-        blay += 1
-        continue
-      bopt = find_token(document.body, '\\begin_inset OptArg', blay)
-      if bopt == -1:
-        # it is legal not to have one of these
-        blay = elay + 1
-        continue
-      eopt = find_end_of_inset(document.body, bopt)
-      if eopt == -1:
-        document.warning("Malformed LyX document: Can't find end of argument.")
-        blay = elay + 1
-        continue
-      bplay = find_token(document.body, '\\begin_layout Plain Layout', blay)
-      if bplay == -1:
-        document.warning("Malformed LyX document: Can't find plain layout.")
-        blay = elay + 1
-        continue
-      eplay = find_end_of(document.body, bplay, '\\begin_layout', '\\end_layout')
-      if eplay == -1:
-        document.warning("Malformed LyX document: Can't find end of plain layout.")
-        blay = elay + 1
-        continue
-      # So the content of the argument inset goes from bplay + 1 to eplay - 1
-      bcont = bplay + 1
-      if bcont >= eplay:
-        # Hmm.
-        document.warning(str(bcont) + " " + str(eplay))
-        blay = blay + 1
-        continue
-      # we convert the content of the argument into pure LaTeX...
-      content = lyx2latex(document, document.body[bcont:eplay])
-      strlist = put_cmd_in_ert(["{" + content + "}"])
-      
-      # now replace the optional argument with the ERT
-      document.body[bopt:eopt + 1] = strlist
-      blay = blay + 1
-
-
+# FIXME This doesn't do anything!!
 def revert_align_decimal(document):
   l = 0
   while True:
@@ -1528,63 +1420,73 @@ def revert_makebox(document):
     # only revert frameless boxes without an inner box
     i = find_token(document.body, '\\begin_inset Box Frameless', i)
     if i == -1:
-      # remove the option use_makebox
-      revert_use_makebox(document)
       return
     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 and j != -1:
-      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]
-      length = latex_length(length)[1]
-      subst = "\\makebox[" + length + "][" \
-        + align + "]{"
-      document.body[i:y + 1] = put_cmd_in_ert(subst)
+      i += 1
+      continue
+    blay = find_token(document.body, "\\begin_layout", i, z)
+    if blay == -1:
+      document.warning("Malformed LyX document: Can't find layout in box.")
+      i = z
+      continue
+    # by looking before the layout we make sure we're actually finding
+    # an option, not text.
+    j = find_token(document.body, 'use_makebox', i, blay)
+    if j == -1:
+        i = z
+        continue
+    val = get_value(document.body, 'use_makebox', j)
+    if val != "1":
+        del document.body[j]
+        i = z
+        continue
+    bend = find_end_of_layout(document.body, blay)
+    if bend == -1 or bend > z:
+        document.warning("Malformed LyX document: Can't find end of layout in box.")
+        i = z
+        continue
+    # determine the alignment
+    align = get_value(document.body, 'hor_pos', i, blay, "c").strip('"')
+    # determine the width
+    length = get_value(document.body, 'width', i, blay, "50col%").strip('"')
+    length = latex_length(length)[1]
+    # remove the \end_layout \end_inset pair
+    document.body[bend:z + 1] = put_cmd_in_ert("}")
+    subst = "\\makebox[" + length + "][" \
+      + align + "]{"
+    document.body[i:blay + 1] = put_cmd_in_ert(subst)
     i += 1
 
 
-def revert_use_makebox(document):
-  " Deletes use_makebox option of boxes "
-  h = 0
-  while 1:
-    # remove the option use_makebox
-    h = find_token(document.body, 'use_makebox', 0)
-    if h == -1:
-      return
-    del document.body[h]
-    h += 1
-
-
 def convert_use_makebox(document):
   " Adds use_makebox option for boxes "
   i = 0
   while 1:
-    # remove the option use_makebox
     i = find_token(document.body, '\\begin_inset Box', i)
     if i == -1:
       return
-    k = find_token(document.body, 'use_parbox', i)
+    # all of this is to make sure we actually find the use_parbox
+    # that is an option for this box, not some text elsewhere.
+    z = find_end_of_inset(document.body, i)
+    if z == -1:
+      document.warning("Can't find end of box inset!!")
+      i += 1
+      continue
+    blay = find_token(document.body, "\\begin_layout", i, z)
+    if blay == -1:
+      document.warning("Can't find layout in box inset!!")
+      i = z
+      continue
+    # so now we are looking for use_parbox before the box's layout
+    k = find_token(document.body, 'use_parbox', i, blay)
     if k == -1:
       document.warning("Malformed LyX document: Can't find use_parbox statement in box.")
-      return
+      i = z
+      continue
     document.body.insert(k + 1, "use_makebox 0")
-    i = k + 1
+    i = z + 1
 
 
 def revert_IEEEtran(document):
@@ -1606,7 +1508,7 @@ def revert_IEEEtran(document):
         i = find_token(document.body, '\\begin_layout ' + layout, i)
         if i == -1:
           break
-        j = find_end_of(document.body, i, '\\begin_layout', '\\end_layout')
+        j = find_end_of_layout(document.body, i)
         if j == -1:
           document.warning("Malformed LyX document: Can't find end of " + layout + " layout.")
           i += 1
@@ -1614,10 +1516,11 @@ def revert_IEEEtran(document):
         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]
+          continue
+        content = lyx2latex(document, document.body[i:j + 1])
+        add_to_preamble(document, [latexcmd[layout] + "{" + content + "}"])
+        del document.body[i:j + 1]
+        # no need to reset i
 
 
 def convert_prettyref(document):
@@ -1635,8 +1538,8 @@ def convert_prettyref(document):
                        document.warning("Malformed LyX document: No end of InsetRef!")
                        i += 1
                        continue
-               k = find_token(document.body, "LatexCommand prettyref", i)
-               if k != -1 and k < j:
+               k = find_token(document.body, "LatexCommand prettyref", i, j)
+               if k != -1:
                        document.body[k] = "LatexCommand formatted"
                i = j + 1
        document.header.insert(-1, "\\use_refstyle 0")
@@ -1657,8 +1560,8 @@ def revert_refstyle(document):
                        document.warning("Malformed LyX document: No end of InsetRef")
                        i += 1
                        continue
-               k = find_token(document.body, "LatexCommand formatted", i)
-               if k != -1 and k < j:
+               k = find_token(document.body, "LatexCommand formatted", i, j)
+               if k != -1:
                        document.body[k] = "LatexCommand prettyref"
                i = j + 1
        i = find_token(document.header, "\\use_refstyle", 0)
@@ -1683,23 +1586,15 @@ def revert_nameref(document):
       cmdloc = i
       i += 1
       # Make sure it is actually in an inset!
-      # We could just check document.lines[i-1], but that relies
-      # upon something that might easily change.
-      # We'll look back a few lines.
-      stins = cmdloc - 10
-      if stins < 0:
-        stins = 0
-      stins = find_token(document.body, "\\begin_inset CommandInset ref", stins)
-      if stins == -1 or stins > cmdloc:
-        continue
-      endins = find_end_of_inset(document.body, stins)
-      if endins == -1:
-        document.warning("Can't find end of inset at line " + stins + "!!")
+      # A normal line could begin with "LatexCommand nameref"!
+      stins, endins = get_containing_inset(document.body, cmdloc, \
+          "\\begin_inset CommandInset ref")
+      if stins == -1:
         continue
-      if endins < cmdloc:
-        continue
-      refline = find_token(document.body, "reference", stins)
-      if refline == -1 or refline > endins:
+
+      # ok, so it is in an InsetRef
+      refline = find_token(document.body, "reference", stins, endins)
+      if refline == -1:
         document.warning("Can't find reference for inset at line " + stinst + "!!")
         continue
       m = rx.match(document.body[refline])
@@ -1708,10 +1603,9 @@ def revert_nameref(document):
         continue
       foundone = True
       ref = m.group(1)
-      newcontent = ['\\begin_inset ERT', 'status collapsed', '', \
-        '\\begin_layout Plain Layout', '', '\\backslash', \
-        cmd + '{' + ref + '}', '\\end_layout', '', '\\end_inset']
+      newcontent = put_cmd_in_ert('\\' + cmd + '{' + ref + '}')
       document.body[stins:endins + 1] = newcontent
+
   if foundone:
     add_to_preamble(document, "\usepackage{nameref}")
 
@@ -1729,20 +1623,9 @@ def remove_Nameref(document):
     i += 1
     
     # Make sure it is actually in an inset!
-    # We could just check document.lines[i-1], but that relies
-    # upon something that might easily change.
-    # We'll look back a few lines.
-    stins = cmdloc - 10
-    if stins < 0:
-      stins = 0
-    stins = find_token(document.body, "\\begin_inset CommandInset ref", stins)
-    if stins == -1 or stins > cmdloc:
-      continue
-    endins = find_end_of_inset(document.body, stins)
-    if endins == -1:
-      document.warning("Can't find end of inset at line " + stins + "!!")
-      continue
-    if endins < cmdloc:
+    stins, endins = get_containing_inset(document.body, \
+        cmdloc, "\\begin_inset CommandInset ref")
+    if stins == -1:
       continue
     document.body[cmdloc] = "LatexCommand nameref"
 
@@ -2157,7 +2040,7 @@ revert =  [[403, [revert_refstyle]],
            [394, [revert_DIN_C_pagesizes]],
            [393, [revert_makebox]],
            [392, [revert_argument]],
-           [391, [revert_beamer_args]],
+           [391, []],
            [390, [revert_align_decimal, revert_IEEEtran]],
            [389, [revert_output_sync]],
            [388, [revert_html_quotes]],