]> git.lyx.org Git - lyx.git/blobdiff - lib/lyx2lyx/lyx_2_0.py
Clarify convert_rule routine. A bit.
[lyx.git] / lib / lyx2lyx / lyx_2_0.py
index 283da64c3873eaa0906387783faa5c4a7fa91504..4d3228abdb8bee5d7b2516eeabe1a5d347263207 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
@@ -1338,7 +1338,7 @@ def revert_includeall(document):
 
 
 def revert_multirow(document):
-    " Revert multirow cells in tables "
+    " Revert multirow cells in tables to TeX-code"
     i = 0
     multirow = False
     while True:
@@ -1386,12 +1386,14 @@ def convert_math_output(document):
         return
     rgx = re.compile(r'\\html_use_mathml\s+(\w+)')
     m = rgx.match(document.header[i])
-    if rgx:
-        newval = "0" # MathML
-        val = m.group(1)
-        if val != "true":
-            newval = "2" # Images
-        document.header[i] = "\\html_math_output " + newval
+    newval = "0" # MathML
+    if m:
+      val = m.group(1)
+      if val != "true":
+        newval = "2" # Images
+    else:
+      document.warning("Can't match " + document.header[i])
+    document.header[i] = "\\html_math_output " + newval
 
 
 def revert_math_output(document):
@@ -1402,7 +1404,7 @@ def revert_math_output(document):
     rgx = re.compile(r'\\html_math_output\s+(\d)')
     m = rgx.match(document.header[i])
     newval = "true"
-    if rgx:
+    if m:
         val = m.group(1)
         if val == "1" or val == "2":
             newval = "false"
@@ -1568,7 +1570,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
@@ -1912,24 +1913,35 @@ def revert_use_makebox(document):
     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)
+    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:
@@ -1950,6 +1962,52 @@ def revert_IEEEtran(document):
           del document.body[i:j + 1]
 
 
+def convert_prettyref(document):
+       " Converts prettyref references to neutral formatted refs "
+       re_ref = re.compile("^\s*reference\s+\"(\w+):(\S+)\"")
+       nm_ref = re.compile("^\s*name\s+\"(\w+):(\S+)\"")
+
+       i = 0
+       while True:
+               i = find_token(document.body, "\\begin_inset CommandInset ref", i)
+               if i == -1:
+                       break
+               j = find_end_of_inset(document.body, i)
+               if j == -1:
+                       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:
+                       document.body[k] = "LatexCommand formatted"
+               i = j + 1
+       document.header.insert(-1, "\\use_refstyle 0")
+               
+def revert_refstyle(document):
+       " Reverts neutral formatted refs to prettyref "
+       re_ref = re.compile("^reference\s+\"(\w+):(\S+)\"")
+       nm_ref = re.compile("^\s*name\s+\"(\w+):(\S+)\"")
+
+       i = 0
+       while True:
+               i = find_token(document.body, "\\begin_inset CommandInset ref", i)
+               if i == -1:
+                       break
+               j = find_end_of_inset(document.body, i)
+               if j == -1:
+                       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:
+                       document.body[k] = "LatexCommand prettyref"
+               i = j + 1
+       i = find_token(document.header, "\\use_refstyle", 0)
+       if i != -1:
+               document.header.pop(i)
+
 def revert_nameref(document):
   " Convert namerefs to regular references "
   cmds = ["Nameref", "nameref"]
@@ -1966,7 +2024,6 @@ def revert_nameref(document):
         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.
@@ -2032,6 +2089,338 @@ def remove_Nameref(document):
     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_flexnames(document):
+    "Convert \\begin_inset Flex Custom:Style to \\begin_inset Flex Style and similarly for CharStyle and Element."
+    
+    i = 0
+    rx = re.compile(r'^\\begin_inset Flex (?:Custom|CharStyle|Element):(.+)$')
+    while True:
+      i = find_token(document.body, "\\begin_inset Flex", i)
+      if i == -1:
+        return
+      m = rx.match(document.body[i])
+      if m:
+        document.body[i] = "\\begin_inset Flex " + m.group(1)
+      i += 1
+
+
+flex_insets = [
+  ["Alert", "CharStyle:Alert"],
+  ["Code", "CharStyle:Code"],
+  ["Concepts", "CharStyle:Concepts"],
+  ["E-Mail", "CharStyle:E-Mail"],
+  ["Emph", "CharStyle:Emph"],
+  ["Expression", "CharStyle:Expression"],
+  ["Initial", "CharStyle:Initial"],
+  ["Institute", "CharStyle:Institute"],
+  ["Meaning", "CharStyle:Meaning"],
+  ["Noun", "CharStyle:Noun"],
+  ["Strong", "CharStyle:Strong"],
+  ["Structure", "CharStyle:Structure"],
+  ["ArticleMode", "Custom:ArticleMode"],
+  ["Endnote", "Custom:Endnote"],
+  ["Glosse", "Custom:Glosse"],
+  ["PresentationMode", "Custom:PresentationMode"],
+  ["Tri-Glosse", "Custom:Tri-Glosse"]
+]
+
+flex_elements = [
+  ["Abbrev", "Element:Abbrev"],
+  ["CCC-Code", "Element:CCC-Code"],
+  ["Citation-number", "Element:Citation-number"],
+  ["City", "Element:City"],
+  ["Code", "Element:Code"],
+  ["CODEN", "Element:CODEN"],
+  ["Country", "Element:Country"],
+  ["Day", "Element:Day"],
+  ["Directory", "Element:Directory"],
+  ["Dscr", "Element:Dscr"],
+  ["Email", "Element:Email"],
+  ["Emph", "Element:Emph"],
+  ["Filename", "Element:Filename"],
+  ["Firstname", "Element:Firstname"],
+  ["Fname", "Element:Fname"],
+  ["GuiButton", "Element:GuiButton"],
+  ["GuiMenu", "Element:GuiMenu"],
+  ["GuiMenuItem", "Element:GuiMenuItem"],
+  ["ISSN", "Element:ISSN"],
+  ["Issue-day", "Element:Issue-day"],
+  ["Issue-months", "Element:Issue-months"],
+  ["Issue-number", "Element:Issue-number"],
+  ["KeyCap", "Element:KeyCap"],
+  ["KeyCombo", "Element:KeyCombo"],
+  ["Keyword", "Element:Keyword"],
+  ["Literal", "Element:Literal"],
+  ["MenuChoice", "Element:MenuChoice"],
+  ["Month", "Element:Month"],
+  ["Orgdiv", "Element:Orgdiv"],
+  ["Orgname", "Element:Orgname"],
+  ["Postcode", "Element:Postcode"],
+  ["SS-Code", "Element:SS-Code"],
+  ["SS-Title", "Element:SS-Title"],
+  ["State", "Element:State"],
+  ["Street", "Element:Street"],
+  ["Surname", "Element:Surname"],
+  ["Volume", "Element:Volume"],
+  ["Year", "Element:Year"]
+]
+
+
+def revert_flexnames(document):
+  if document.backend == "latex":
+    flexlist = flex_insets
+  else:
+    flexlist = flex_elements
+  
+  rx = re.compile(r'^\\begin_inset Flex\s+(.+)$')
+  i = 0
+  while True:
+    i = find_token(document.body, "\\begin_inset Flex", i)
+    if i == -1:
+      return
+    m = rx.match(document.body[i])
+    if not m:
+      document.warning("Illegal flex inset: " + document.body[i])
+      i += 1
+      continue
+    
+    style = m.group(1)
+    for f in flexlist:
+      if f[0] == style:
+        document.body[i] = "\\begin_inset Flex " + f[1]
+        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:
+        return
+        
+      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
+
+
+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:
+        return
+      # 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, j)
+      if k != -1:
+        offset = document.body[k][8:-1]
+      else:
+        offset = ""
+      # determine the width
+      l = find_token(document.body, 'width', i, j)
+      if l != -1:
+        width = document.body[l][7:-1]
+      else:
+        width = "100col%"
+      # determine the height
+      m = find_token(document.body, 'height', i, j)
+      if m != -1:
+        height = document.body[m][8:-1]
+      else:
+        height = "1pt"
+      # output the \rule command
+      if offset:
+        subst = "\\rule[" + offset + "]{" + width + "}{" + height + "}"
+      else:
+        subst = "\\rule{" + width + "}{" + height + "}"
+      document.body[i:j + 1] = put_cmd_in_ert(subst)
+      i += 1
+
+
+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
+
+
+def convert_bibtex_clearpage(document):
+  " insert a clear(double)page bibliographystyle if bibtotoc option is used "
+
+  i = find_token(document.header, '\\papersides', 0)
+  if i == -1:
+    document.warning("Malformed LyX document: Can't find papersides definition.")
+    return
+  sides = int(document.header[i][12])
+
+  j = 0
+  while True:
+    j = find_token(document.body, "\\begin_inset CommandInset bibtex", j)
+    if j == -1:
+      return
+
+    k = find_end_of_inset(document.body, j)
+    if k == -1:
+      document.warning("Can't find end of Bibliography inset at line " + str(j))
+      j += 1
+      continue
+
+    # only act if there is the option "bibtotoc"
+    m = find_token(document.body, 'options', j, k)
+    if m == -1:
+      document.warning("Can't find options for bibliography inset at line " + str(j))
+      j = k
+      continue
+    
+    optline = document.body[m]
+    idx = optline.find("bibtotoc")
+    if idx == -1:
+      j = k
+      continue
+    
+    # so we want to insert a new page right before the paragraph that
+    # this bibliography thing is in. we'll look for it backwards.
+    lay = j - 1
+    while lay >= 0:
+      if document.body[lay].startswith("\\begin_layout"):
+        break
+      lay -= 1
+
+    if lay < 0:
+      document.warning("Can't find layout containing bibliography inset at line " + str(j))
+      j = k
+      continue
+
+    subst1 = '\\begin_layout Standard\n' \
+      + '\\begin_inset Newpage clearpage\n' \
+      + '\\end_inset\n\n\n' \
+      + '\\end_layout\n'
+    subst2 = '\\begin_layout Standard\n' \
+      + '\\begin_inset Newpage cleardoublepage\n' \
+      + '\\end_inset\n\n\n' \
+      + '\\end_layout\n'
+    if sides == 1:
+      document.body.insert(lay, subst1)
+      document.warning(subst1)
+    else:
+      document.body.insert(lay, subst2)
+      document.warning(subst2)
+
+    j = k
+
+
 ##
 # Conversion hub
 #
@@ -2083,15 +2472,29 @@ convert = [[346, []],
            [389, [convert_html_quotes]],
            [390, []],
            [391, []],
-           [392, [convert_beamer_args]],
+           [392, []],
            [393, [convert_optarg]],
-           [394, []],
+           [394, [convert_use_makebox]],
            [395, []],
            [396, []],
-           [397, [remove_Nameref]]
-          ]
-
-revert =  [[396, []],
+           [397, [remove_Nameref]],
+           [398, []],
+           [399, [convert_mathdots]],
+           [400, [convert_rule]],
+           [401, []],
+           [402, [convert_bibtex_clearpage]],
+           [403, [convert_flexnames]],
+           [404, [convert_prettyref]]
+]
+
+revert =  [[403, [revert_refstyle]],
+           [402, [revert_flexnames]],
+           [401, []],
+           [400, [revert_diagram]],
+           [399, [revert_rule]],
+           [398, [revert_mathdots]],
+           [397, [revert_mathrsfs]],
+           [396, []],
            [395, [revert_nameref]],
            [394, [revert_DIN_C_pagesizes]],
            [393, [revert_makebox]],