]> git.lyx.org Git - lyx.git/blobdiff - lib/lyx2lyx/lyx_2_0.py
Math.lyx: describe new supported font \mathscr
[lyx.git] / lib / lyx2lyx / lyx_2_0.py
index 075f68c279be6a946fc2c7243102cd19ca0b5a51..02cc1f0fca0fed11505156d2f187cd620965c9dd 100644 (file)
@@ -1,7 +1,7 @@
 # -*- coding: utf-8 -*-
 # This file is part of lyx2lyx
 # -*- coding: utf-8 -*-
-# Copyright (C) 2008 José Matos  <jamatos@lyx.org>
+# Copyright (C) 2010 The LyX team
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -40,10 +40,17 @@ def find_end_of_inset(lines, i):
     return find_end_of(lines, i, "\\begin_inset", "\\end_inset")
 
 
+# Note that text can be either a list of lines or a single line.
 def add_to_preamble(document, text):
     """ Add text to the preamble if it is not already there.
     Only the first line is checked!"""
 
+    if not type(text) is list:
+      # split on \n just in case
+      # it'll give us the one element list we want
+      # if there's no \n, too
+      text = text.split('\n')
+
     if find_token(document.preamble, text[0], 0) != -1:
         return
 
@@ -1561,7 +1568,6 @@ def revert_fontcolor(document):
                            + ', ' + str(blueout) + '}\n'
                            + '\\color{document_fontcolor}\n')
 
-
 def revert_shadedboxcolor(document):
     " Reverts shaded box color to preamble code "
     i = 0
@@ -1670,6 +1676,18 @@ def revert_pagesizes(document):
       del document.header[i]
 
 
+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:
+    size = document.header[i][11:]
+    if size == "c0paper" or size == "c1paper" or size == "c2paper" \
+    or size == "c3paper" or size == "c4paper" or size == "c5paper" \
+    or size == "c6paper":
+      del document.header[i]
+
+
 def convert_html_quotes(document):
   " Remove quotes around html_latex_start and html_latex_end "
 
@@ -1849,6 +1867,8 @@ 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:
@@ -1856,48 +1876,70 @@ def revert_makebox(document):
       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:
+    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]
+      # 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_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
-    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.")
+    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
-    # 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
+    k = find_token(document.body, 'use_parbox', i)
+    if k == -1:
+      document.warning("Malformed LyX document: Can't find use_parbox statement in box.")
+      return
+    document.body.insert(k + 1, "use_makebox 0")
+    i = k + 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:
@@ -1918,6 +1960,249 @@ def revert_IEEEtran(document):
           del document.body[i:j + 1]
 
 
+def revert_nameref(document):
+  " Convert namerefs to regular references "
+  cmds = ["Nameref", "nameref"]
+  foundone = False
+  rx = re.compile(r'reference "(.*)"')
+  for cmd in cmds:
+    i = 0
+    oldcmd = "LatexCommand " + cmd
+    while 1:
+      # It seems better to look for this, as most of the reference
+      # insets won't be ones we care about.
+      i = find_token(document.body, oldcmd, i)
+      if i == -1:
+        break
+      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 + "!!")
+        continue
+      if endins < cmdloc:
+        continue
+      refline = find_token(document.body, "reference", stins)
+      if refline == -1 or refline > endins:
+        document.warning("Can't find reference for inset at line " + stinst + "!!")
+        continue
+      m = rx.match(document.body[refline])
+      if not m:
+        document.warning("Can't match reference line: " + document.body[ref])
+        continue
+      foundone = True
+      ref = m.group(1)
+      newcontent = ['\\begin_inset ERT', 'status collapsed', '', \
+        '\\begin_layout Plain Layout', '', '\\backslash', \
+        cmd + '{' + ref + '}', '\\end_layout', '', '\\end_inset']
+      document.body[stins:endins + 1] = newcontent
+  if foundone:
+    add_to_preamble(document, "\usepackage{nameref}")
+
+
+def remove_Nameref(document):
+  " Convert Nameref commands to nameref commands "
+  i = 0
+  while 1:
+    # It seems better to look for this, as most of the reference
+    # insets won't be ones we care about.
+    i = find_token(document.body, "LatexCommand Nameref" , i)
+    if i == -1:
+      break
+    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 + "!!")
+      continue
+    if endins < cmdloc:
+      continue
+    document.body[cmdloc] = "LatexCommand nameref"
+
+
+def revert_mathrsfs(document):
+    " Load mathrsfs if \mathrsfs us use in the document "
+    i = 0
+    end = len(document.body) - 1
+    while True:
+      j = document.body[i].find("\\mathscr{")
+      if j != -1:
+        add_to_preamble(document, ["% this command was inserted by lyx2lyx"])
+        add_to_preamble(document, ["\\usepackage{mathrsfs}"])
+        break
+      if i == end:
+        break
+      i += 1
+
+
+def convert_mathdots(document):
+    " Load mathdots automatically "
+    while True:
+      i = find_token(document.header, "\\use_esint" , 0)
+      if i != -1:
+        document.header.insert(i + 1, "\\use_mathdots 1")
+      break
+
+
+def revert_mathdots(document):
+    " Load mathdots if used in the document "
+    i = 0
+    ddots = re.compile(r'\\begin_inset Formula .*\\ddots', re.DOTALL)
+    vdots = re.compile(r'\\begin_inset Formula .*\\vdots', re.DOTALL)
+    iddots = re.compile(r'\\begin_inset Formula .*\\iddots', re.DOTALL)
+    mathdots = find_token(document.header, "\\use_mathdots" , 0)
+    no = find_token(document.header, "\\use_mathdots 0" , 0)
+    auto = find_token(document.header, "\\use_mathdots 1" , 0)
+    yes = find_token(document.header, "\\use_mathdots 2" , 0)
+    if mathdots != -1:
+      del document.header[mathdots]
+    while True:
+      i = find_token(document.body, '\\begin_inset Formula', i)
+      if i == -1:
+        return
+      j = find_end_of_inset(document.body, i)
+      if j == -1:
+        document.warning("Malformed LyX document: Can't find end of Formula inset.")
+        return 
+      k = ddots.search("\n".join(document.body[i:j]))
+      l = vdots.search("\n".join(document.body[i:j]))
+      m = iddots.search("\n".join(document.body[i:j]))
+      if (yes == -1) and ((no != -1) or (not k and not l and not m) or (auto != -1 and not m)):
+        i += 1
+        continue
+      # use \@ifundefined to catch also the "auto" case
+      add_to_preamble(document, ["% this command was inserted by lyx2lyx"])
+      add_to_preamble(document, ["\\@ifundefined{iddots}{\\usepackage{mathdots}}\n"])
+      return
+
+
+def convert_rule(document):
+    " Convert \\lyxline to CommandInset line "
+    i = 0
+    while True:
+      i = find_token(document.body, "\\lyxline" , i)
+      if i != -1:
+        j = find_token(document.body, "\\color" , i - 2)
+        if j == i - 2:
+          color = document.body[j] + '\n'
+        else:
+          color = ''
+        k = find_token(document.body, "\\begin_layout Standard" , i - 4)
+        # we need to handle the case that \lyxline is in a separate paragraph and that it is colored
+        # the result is then an extra empty paragraph which we get by adding an empty ERT inset
+        if k == i - 4 and j == i - 2 and document.body[i - 1] == '':
+          layout = '\\begin_inset ERT\nstatus collapsed\n\n\\begin_layout Plain Layout\n\n\n\\end_layout\n\n\\end_inset\n' \
+            + '\\end_layout\n\n' \
+            + '\\begin_layout Standard\n'
+        elif k == i - 2 and document.body[i - 1] == '':
+          layout = ''
+        else:
+          layout = '\\end_layout\n\n' \
+            + '\\begin_layout Standard\n'
+        l = find_token(document.body, "\\begin_layout Standard" , i + 4)
+        if l == i + 4 and document.body[i + 1] == '':
+          layout2 = ''
+        else:
+          layout2 = '\\end_layout\n' \
+            + '\n\\begin_layout Standard\n'
+        subst = layout \
+          + '\\noindent\n\n' \
+          + color \
+          + '\\begin_inset CommandInset line\n' \
+          + 'LatexCommand rule\n' \
+          + 'offset "0.5ex"\n' \
+          + 'width "100line%"\n' \
+          + 'height "1pt"\n' \
+          + '\n\\end_inset\n\n\n' \
+          + layout2
+        document.body[i] = subst
+        i += 1
+      else:
+        return
+
+
+def revert_rule(document):
+    " Revert line insets to Tex code "
+    i = 0
+    while 1:
+      i = find_token(document.body, "\\begin_inset CommandInset line" , i)
+      if i != -1:
+        # find end of inset
+        j = find_token(document.body, "\\end_inset" , i)
+        # assure we found the end_inset of the current inset
+        if j > i + 6 or j == -1:
+          document.warning("Malformed LyX document: Can't find end of line inset.")
+          return
+        # determine the optional offset
+        k = find_token(document.body, 'offset', i)
+        if k != -1 and k < j:
+          offset = document.body[k][8:]
+        else:
+          offset = '0"'
+        # determine the width
+        l = find_token(document.body, 'width', k + 1)
+        width = document.body[l][7:]
+        # determine the height
+        m = find_token(document.body, 'height', l + 1)
+        height = document.body[m][8:]
+        # remove trailing '"'
+        offset = offset[:-1]
+        width = width[:-1]
+        height = height[:-1]
+        # output the \rule command
+        if offset <> "0":
+          subst = "\\rule[" + offset + "]{" + width + "}{" + height + "}"
+        else:
+          subst = "\\rule{" + width + "}{" + height + "}"
+        document.body[i:j + 1] = put_cmd_in_ert(subst)
+        i += 1
+      else:
+        return
+
+def revert_diagram(document):
+  " Add the feyn package if \\Diagram is used in math "
+  i = 0
+  re_diagram = re.compile(r'\\begin_inset Formula .*\\Diagram', re.DOTALL)
+  while True:
+    i = find_token(document.body, '\\begin_inset Formula', i)
+    if i == -1:
+      return
+    j = find_end_of_inset(document.body, i)
+    if j == -1:
+        document.warning("Malformed LyX document: Can't find end of Formula inset.")
+        return 
+    m = re_diagram.search("\n".join(document.body[i:j]))
+    if not m:
+      i += 1
+      continue
+    add_to_preamble(document, ["% this command was inserted by lyx2lyx"])
+    add_to_preamble(document, "\\usepackage{feyn}")
+    # only need to do it once!
+    return
+
+
+
 ##
 # Conversion hub
 #
@@ -1971,10 +2256,24 @@ convert = [[346, []],
            [391, []],
            [392, [convert_beamer_args]],
            [393, [convert_optarg]],
-           [394, []]
+           [394, [convert_use_makebox]],
+           [395, []],
+           [396, []],
+           [397, [remove_Nameref]],
+           [398, []],
+           [399, [convert_mathdots]],
+           [400, [convert_rule]],
+           [401, []]
           ]
 
-revert =  [[393, [revert_makebox]],
+revert =  [[400, [revert_diagram]],
+           [399, [revert_rule]],
+           [398, [revert_mathdots]],
+           [397, [revert_mathrsfs]],
+           [396, []],
+           [395, [revert_nameref]],
+           [394, [revert_DIN_C_pagesizes]],
+           [393, [revert_makebox]],
            [392, [revert_argument]],
            [391, [revert_beamer_args]],
            [390, [revert_align_decimal, revert_IEEEtran]],