]> git.lyx.org Git - lyx.git/blobdiff - lib/configure.py
Update a bibitem label also when it is emptied.
[lyx.git] / lib / configure.py
index b8cd6e1f02004a03a367a711afc5d40d1c92631b..40e53b14d3ec086473671c8903976ef5b992ab6d 100644 (file)
@@ -8,7 +8,7 @@
 # \author Bo Peng
 # Full author contact details are available in file CREDITS.
 
-import sys, os, re, shutil, glob, logging
+import glob, logging, os, re, shutil, subprocess, sys
 
 # set up logging
 logging.basicConfig(level = logging.DEBUG,
@@ -60,9 +60,16 @@ def cmdOutput(cmd):
     '''utility function: run a command and get its output as a string
         cmd: command to run
     '''
-    fout = os.popen(cmd)
-    output = fout.read()
-    fout.close()
+    if os.name == 'nt':
+        b = False
+        cmd = 'cmd /d /c ' + cmd
+    else:
+        b = True
+    pipe = subprocess.Popen(cmd, shell=b, close_fds=b, stdin=subprocess.PIPE, \
+                            stdout=subprocess.PIPE, universal_newlines=True)
+    pipe.stdin.close()
+    output = pipe.stdout.read()
+    pipe.stdout.close()
     return output.strip()
 
 
@@ -96,18 +103,30 @@ def createDirectories():
 def checkTeXPaths():
     ''' Determine the path-style needed by the TeX engine on Win32 (Cygwin) '''
     windows_style_tex_paths = ''
+    if LATEX == '':
+        return windows_style_tex_paths
     if os.name == 'nt' or sys.platform == 'cygwin':
         from tempfile import mkstemp
         fd, tmpfname = mkstemp(suffix='.ltx')
         if os.name == 'nt':
-            inpname = tmpfname.replace('\\', '/')
+            from ctypes import windll, create_unicode_buffer
+            GetShortPathName = windll.kernel32.GetShortPathNameW
+            longname = unicode(tmpfname)
+            shortlen = GetShortPathName(longname, 0, 0)
+            shortname = create_unicode_buffer(shortlen)
+            if GetShortPathName(longname, shortname, shortlen):
+                inpname = shortname.value.replace('\\', '/')
+            else:
+                inpname = tmpfname.replace('\\', '/')
         else:
             inpname = cmdOutput('cygpath -m ' + tmpfname)
         logname = os.path.basename(inpname.replace('.ltx', '.log'))
         inpname = inpname.replace('~', '\\string~')
         os.write(fd, r'\relax')
         os.close(fd)
-        latex_out = cmdOutput(r'latex "\nonstopmode\input{%s}"' % inpname)
+        latex_out = cmdOutput(r'latex "\nonstopmode\input{%s}\makeatletter\@@end"' % inpname)
+        if 'Error' in latex_out:
+            latex_out = cmdOutput(r'latex "\nonstopmode\input{\"%s\"}\makeatletter\@@end"' % inpname)
         if 'Error' in latex_out:
             logger.warning("configure: TeX engine needs posix-style paths in latex files")
             windows_style_tex_paths = 'false'
@@ -136,9 +155,9 @@ def checkProg(description, progs, rc_entry = [], path = [], not_found = ''):
             1. emtpy: no rc entry will be added
             2. one pattern: %% will be replaced by the first found program,
                 or '' if no program is found.
-            3. several patterns for each prog and not_found. This is used 
-                when different programs have different usages. If you do not 
-                want not_found entry to be added to the RC file, you can specify 
+            3. several patterns for each prog and not_found. This is used
+                when different programs have different usages. If you do not
+                want not_found entry to be added to the RC file, you can specify
                 an entry for each prog and use '' for the not_found entry.
 
         not_found: the value that should be used instead of '' if no program
@@ -151,10 +170,15 @@ def checkProg(description, progs, rc_entry = [], path = [], not_found = ''):
         sys.exit(2)
     logger.info('checking for ' + description + '...')
     ## print '(' + ','.join(progs) + ')',
+    global java, perl
     for idx in range(len(progs)):
         # ac_prog may have options, ac_word is the command name
         ac_prog = progs[idx]
         ac_word = ac_prog.split(' ')[0]
+        if (ac_word.endswith('.class') or ac_word.endswith('.jar')) and java == '':
+            continue
+        if ac_word.endswith('.pl') and perl == '':
+            continue
         msg = '+checking for "' + ac_word + '"... '
         path = os.environ["PATH"].split(os.pathsep) + path
         extlist = ['']
@@ -164,6 +188,13 @@ def checkProg(description, progs, rc_entry = [], path = [], not_found = ''):
             for ext in extlist:
                 if os.path.isfile( os.path.join(ac_dir, ac_word + ext) ):
                     logger.info(msg + ' yes')
+                    # deal with java and perl
+                    if ac_word.endswith('.class'):
+                        ac_prog = ac_prog.replace(ac_word, r'%s \"%s\"' % (java, os.path.join(ac_dir, ac_word[:-6])))
+                    elif ac_word.endswith('.jar'):
+                        ac_prog = ac_prog.replace(ac_word, r'%s -jar \"%s\"' % (java, os.path.join(ac_dir, ac_word)))
+                    elif ac_word.endswith('.pl'):
+                        ac_prog = ac_prog.replace(ac_word, r'%s -w \"%s\"' % (perl, os.path.join(ac_dir, ac_word)))
                     # write rc entries for this command
                     if len(rc_entry) == 1:
                         addToRC(rc_entry[0].replace('%%', ac_prog))
@@ -179,7 +210,7 @@ def checkProg(description, progs, rc_entry = [], path = [], not_found = ''):
 
 
 def checkProgAlternatives(description, progs, rc_entry = [], alt_rc_entry = [], path = [], not_found = ''):
-    ''' 
+    '''
         The same as checkProg, but additionally, all found programs will be added
         as alt_rc_entries
     '''
@@ -192,10 +223,15 @@ def checkProgAlternatives(description, progs, rc_entry = [], alt_rc_entry = [],
     found_prime = False
     real_ac_dir = ''
     real_ac_word = not_found
+    global java, perl
     for idx in range(len(progs)):
         # ac_prog may have options, ac_word is the command name
         ac_prog = progs[idx]
         ac_word = ac_prog.split(' ')[0]
+        if (ac_word.endswith('.class') or ac_word.endswith('.jar')) and java == '':
+            continue
+        if ac_word.endswith('.pl') and perl == '':
+            continue
         msg = '+checking for "' + ac_word + '"... '
         path = os.environ["PATH"].split(os.pathsep) + path
         extlist = ['']
@@ -208,6 +244,13 @@ def checkProgAlternatives(description, progs, rc_entry = [], alt_rc_entry = [],
                     logger.info(msg + ' yes')
                     pr = re.compile(r'(\\\S+)(.*)$')
                     m = None
+                    # deal with java and perl
+                    if ac_word.endswith('.class'):
+                        ac_prog = ac_prog.replace(ac_word, r'%s \"%s\"' % (java, os.path.join(ac_dir, ac_word[:-6])))
+                    elif ac_word.endswith('.jar'):
+                        ac_prog = ac_prog.replace(ac_word, r'%s -jar \"%s\"' % (java, os.path.join(ac_dir, ac_word)))
+                    elif ac_word.endswith('.pl'):
+                        ac_prog = ac_prog.replace(ac_word, r'%s -w \"%s\"' % (perl, os.path.join(ac_dir, ac_word)))
                     # write rc entries for this command
                     if found_prime == False:
                         if len(rc_entry) == 1:
@@ -248,44 +291,38 @@ def checkProgAlternatives(description, progs, rc_entry = [], alt_rc_entry = [],
     return ['', not_found]
 
 
-def addViewerAlternatives(rcs):
-    r = re.compile(r'\\Format (\S+).*$')
-    m = None
-    alt = ''
-    for idxx in range(len(rcs)):
-        if len(rcs) == 1:
-            m = r.match(rcs[0])
-            if m:
-                alt = r'\viewer_alternatives ' + m.group(1) + " %%"
-        elif len(rcs) > 1:
-            m = r.match(rcs[idxx])
-            if m:
-                if idxx > 0:
-                    alt += '\n'
-                alt += r'\viewer_alternatives ' + m.group(1) + " %%"
-    return alt
-
-
-def addEditorAlternatives(rcs):
+def addAlternatives(rcs, alt_type):
+    '''
+        Returns a \\prog_alternatives string to be used as an alternative
+        rc entry.  alt_type can be a string or a list of strings.
+    '''
     r = re.compile(r'\\Format (\S+).*$')
     m = None
     alt = ''
+    alt_token = '\\%s_alternatives '
+    if isinstance(alt_type, str):
+        alt_tokens = [alt_token % alt_type]
+    else:
+        alt_tokens = map(lambda s: alt_token % s, alt_type)
     for idxx in range(len(rcs)):
         if len(rcs) == 1:
             m = r.match(rcs[0])
             if m:
-                alt = r'\editor_alternatives ' + m.group(1) + " %%"
+                alt = '\n'.join([s + m.group(1) + ' "%%"' for s in alt_tokens])
         elif len(rcs) > 1:
             m = r.match(rcs[idxx])
             if m:
                 if idxx > 0:
                     alt += '\n'
-                alt += r'\editor_alternatives ' + m.group(1) + " %%"
+                alt += '\n'.join([s + m.group(1) + ' "%%"' for s in alt_tokens])
     return alt
 
 
-def checkViewer(description, progs, rc_entry = [], path = []):
-    ''' The same as checkProgAlternatives, but for viewers '''
+def listAlternatives(progs, alt_type, rc_entry = []):
+    '''
+        Returns a list of \\prog_alternatives strings to be used as alternative
+        rc entries.  alt_type can be a string or a list of strings.
+    '''
     if len(rc_entry) > 1 and len(rc_entry) != len(progs) + 1:
         logger.error("rc entry should have one item or item for each prog and not_found.")
         sys.exit(2)
@@ -293,75 +330,45 @@ def checkViewer(description, progs, rc_entry = [], path = []):
     for idx in range(len(progs)):
         if len(rc_entry) == 1:
             rcs = rc_entry[0].split('\n')
-            alt = addViewerAlternatives(rcs)
+            alt = addAlternatives(rcs, alt_type)
             alt_rc_entry.insert(0, alt)
         elif len(rc_entry) > 1:
             rcs = rc_entry[idx].split('\n')
-            alt = addViewerAlternatives(rcs)
+            alt = addAlternatives(rcs, alt_type)
             alt_rc_entry.insert(idx, alt)
+    return alt_rc_entry
+
+
+def checkViewer(description, progs, rc_entry = [], path = []):
+    ''' The same as checkProgAlternatives, but for viewers '''
+    alt_rc_entry = listAlternatives(progs, 'viewer', rc_entry)
     return checkProgAlternatives(description, progs, rc_entry, alt_rc_entry, path, not_found = 'auto')
 
 
 def checkEditor(description, progs, rc_entry = [], path = []):
     ''' The same as checkProgAlternatives, but for editors '''
-    if len(rc_entry) > 1 and len(rc_entry) != len(progs) + 1:
-        logger.error("rc entry should have one item or item for each prog and not_found.")
-        sys.exit(2)
-    alt_rc_entry = []
-    for idx in range(len(progs)):
-        if len(rc_entry) == 1:
-            rcs = rc_entry[0].split('\n')
-            alt = addEditorAlternatives(rcs)
-            alt_rc_entry.insert(0, alt)
-        elif len(rc_entry) > 1:
-            rcs = rc_entry[idx].split('\n')
-            alt = addEditorAlternatives(rcs)
-            alt_rc_entry.insert(idx, alt)
+    alt_rc_entry = listAlternatives(progs, 'editor', rc_entry)
     return checkProgAlternatives(description, progs, rc_entry, alt_rc_entry, path, not_found = 'auto')
 
 
 def checkViewerNoRC(description, progs, rc_entry = [], path = []):
     ''' The same as checkViewer, but do not add rc entry '''
-    if len(rc_entry) > 1 and len(rc_entry) != len(progs) + 1:
-        logger.error("rc entry should have one item or item for each prog and not_found.")
-        sys.exit(2)
-    alt_rc_entry = []
-    for idx in range(len(progs)):
-        if len(rc_entry) == 1:
-            rcs = rc_entry[0].split('\n')
-            alt = addViewerAlternatives(rcs)
-            alt_rc_entry.insert(0, alt)
-        elif len(rc_entry) > 1:
-            rcs = rc_entry[idx].split('\n')
-            alt = addViewerAlternatives(rcs)
-            alt_rc_entry.insert(idx, alt)
+    alt_rc_entry = listAlternatives(progs, 'viewer', rc_entry)
     rc_entry = []
     return checkProgAlternatives(description, progs, rc_entry, alt_rc_entry, path, not_found = 'auto')
 
 
 def checkEditorNoRC(description, progs, rc_entry = [], path = []):
     ''' The same as checkViewer, but do not add rc entry '''
-    if len(rc_entry) > 1 and len(rc_entry) != len(progs) + 1:
-        logger.error("rc entry should have one item or item for each prog and not_found.")
-        sys.exit(2)
-    alt_rc_entry = []
-    for idx in range(len(progs)):
-        if len(rc_entry) == 1:
-            rcs = rc_entry[0].split('\n')
-            alt = addEditorAlternatives(rcs)
-            alt_rc_entry.insert(0, alt)
-        elif len(rc_entry) > 1:
-            rcs = rc_entry[idx].split('\n')
-            alt = addEditorAlternatives(rcs)
-            alt_rc_entry.insert(idx, alt)
+    alt_rc_entry = listAlternatives(progs, 'editor', rc_entry)
     rc_entry = []
     return checkProgAlternatives(description, progs, rc_entry, alt_rc_entry, path, not_found = 'auto')
 
 
 def checkViewerEditor(description, progs, rc_entry = [], path = []):
     ''' The same as checkProgAlternatives, but for viewers and editors '''
-    checkEditorNoRC(description, progs, rc_entry, path)
-    return checkViewer(description, progs, rc_entry, path)
+    alt_rc_entry = listAlternatives(progs, ['editor', 'viewer'], rc_entry)
+    return checkProgAlternatives(description, progs, rc_entry, alt_rc_entry, path, not_found = 'auto')
 
 
 def checkDTLtools():
@@ -384,19 +391,16 @@ def checkLatex(dtl_tools):
     path, PLATEX = checkProg('pLaTeX, the Japanese LaTeX', ['platex $$i'])
     if PLATEX != '':
         # check if PLATEX is pLaTeX2e
-        writeToFile('chklatex.ltx', '''
-\\nonstopmode
-\\@@end
-''')
+        writeToFile('chklatex.ltx', r'\nonstopmode\makeatletter\@@end')
         # run platex on chklatex.ltx and check result
         if cmdOutput(PLATEX + ' chklatex.ltx').find('pLaTeX2e') != -1:
             # We have the Japanese pLaTeX2e
-            addToRC(r'\converter platex   dvi       "%s"   "latex=platex"' % PLATEX)
+            addToRC(r'\converter platex     dvi        "%s -kanji=$$E $$i"     "latex=platex"' % PLATEX)
         else:
             PLATEX = ''
             removeFiles(['chklatex.ltx', 'chklatex.log'])
     #-----------------------------------------------------------------
-    # use LATEX to convert from latex to dvi if PPLATEX is not available    
+    # use LATEX to convert from latex to dvi if PPLATEX is not available
     if PPLATEX == '':
         PPLATEX = LATEX
     if dtl_tools:
@@ -408,12 +412,13 @@ def checkLatex(dtl_tools):
     # no latex
     if LATEX != '':
         # Check if latex is usable
-        writeToFile('chklatex.ltx', '''
-\\nonstopmode\\makeatletter
-\\ifx\\undefined\\documentclass\\else
-  \\message{ThisIsLaTeX2e}
-\\fi
-\\@@end
+        writeToFile('chklatex.ltx', r'''
+\nonstopmode
+\ifx\undefined\documentclass\else
+  \message{ThisIsLaTeX2e}
+\fi
+\makeatletter
+\@@end
 ''')
         # run latex on chklatex.ltx and check result
         if cmdOutput(LATEX + ' chklatex.ltx').find('ThisIsLaTeX2e') != -1:
@@ -426,6 +431,40 @@ def checkLatex(dtl_tools):
     return ''
 
 
+def checkLuatex():
+    ''' Check if luatex is there and usable '''
+    path, LUATEX = checkProg('LuaTeX', ['lualatex $$i'])
+    path, DVILUATEX = checkProg('LuaTeX (DVI)', ['dvilualatex $$i'])
+    if LUATEX != '':
+    # luatex binary is there
+        msg = "checking if LuaTeX is usable ..."
+        # Check if luatex is usable
+        writeToFile('luatest.tex', r'''
+\nonstopmode
+\documentclass{minimal}
+\usepackage{fontspec}
+\begin{document}
+.
+\end{document}
+''')
+        # run lualatex on luatest.tex and check result
+        luatest = cmdOutput(LUATEX + ' luatest.tex')
+        if luatest.find('XeTeX is required to compile this document') != -1:
+            # fontspec/luatex too old! We do not support this version.
+            logger.info(msg + ' no (probably not recent enough)')
+        elif luatest.find('! LaTeX Error: File `fontspec.sty\' not found') != -1:
+            # fontspec missing
+            logger.info(msg + ' no (missing fontspec)')
+        else:
+            # working luatex
+            logger.info(msg + ' yes')
+            addToRC(r'\converter luatex      pdf5       "%s"   "latex=lualatex"' % LUATEX)
+            if DVILUATEX != '':
+                addToRC(r'\converter luatex      dvi3        "%s"      "latex=dvilualatex"' % DVILUATEX)
+        # remove temporary files
+        removeFiles(['luatest.tex', 'luatest.log', 'luatest.aux', 'luatest.pdf'])
+
+
 def checkModule(module):
     ''' Check for a Python module, return the status '''
     msg = 'checking for "' + module + ' module"... '
@@ -438,7 +477,7 @@ def checkModule(module):
       return False
 
 
-def checkFormatEntries(dtl_tools):  
+def checkFormatEntries(dtl_tools):
     ''' Check all formats (\Format entries) '''
     checkViewerEditor('a Tgif viewer and editor', ['tgif'],
         rc_entry = [r'\Format tgif       obj     Tgif                   "" "%%"        "%%"    "vector"'])
@@ -447,7 +486,10 @@ def checkFormatEntries(dtl_tools):
         rc_entry = [r'\Format fig        fig     FIG                    "" "%%"        "%%"    "vector"'])
     #
     checkViewerEditor('a Dia viewer and editor', ['dia'],
-        rc_entry = [r'\Format dia        dia     DIA                    "" "%%"        "%%"    "vector"'])
+        rc_entry = [r'\Format dia        dia     DIA                    "" "%%"        "%%"    "vector,zipped=native"'])
+    #
+    checkViewerEditor('an OpenOffice drawing viewer and editor', ['libreoffice', 'ooffice', 'oodraw', 'soffice'],
+        rc_entry = [r'\Format odg        "odg, sxd" "OpenOffice drawing"   "" "%%"     "%%"    "vector,zipped=native"'])
     #
     checkViewerEditor('a Grace viewer and editor', ['xmgrace'],
         rc_entry = [r'\Format agr        agr     Grace                  "" "%%"        "%%"    "vector"'])
@@ -461,7 +503,7 @@ def checkFormatEntries(dtl_tools):
     path, iv = checkViewerNoRC('a raster image viewer', ['xv', 'kview', 'gimp-remote', 'gimp'],
         rc_entry = [r'''\Format bmp        bmp     BMP                    "" "%s"      "%s"    ""
 \Format gif        gif     GIF                    "" "%s"      "%s"    ""
-\Format jpg        jpg     JPEG                   "" "%s"      "%s"    ""
+\Format jpg       "jpg, jpeg" JPEG                "" "%s"      "%s"    ""
 \Format pbm        pbm     PBM                    "" "%s"      "%s"    ""
 \Format pgm        pgm     PGM                    "" "%s"      "%s"    ""
 \Format png        png     PNG                    "" "%s"      "%s"    ""
@@ -472,7 +514,7 @@ def checkFormatEntries(dtl_tools):
     path, ie = checkEditorNoRC('a raster image editor', ['gimp-remote', 'gimp'],
         rc_entry = [r'''\Format bmp        bmp     BMP                    "" "%s"      "%s"    ""
 \Format gif        gif     GIF                    "" "%s"      "%s"    ""
-\Format jpg        jpg     JPEG                   "" "%s"      "%s"    ""
+\Format jpg       "jpg, jpeg" JPEG                "" "%s"      "%s"    ""
 \Format pbm        pbm     PBM                    "" "%s"      "%s"    ""
 \Format pgm        pgm     PGM                    "" "%s"      "%s"    ""
 \Format png        png     PNG                    "" "%s"      "%s"    ""
@@ -482,7 +524,7 @@ def checkFormatEntries(dtl_tools):
 \Format xpm        xpm     XPM                    "" "%s"      "%s"    ""'''])
     addToRC(r'''\Format bmp        bmp     BMP                    "" "%s"      "%s"    ""
 \Format gif        gif     GIF                    "" "%s"      "%s"    ""
-\Format jpg        jpg     JPEG                   "" "%s"      "%s"    ""
+\Format jpg       "jpg, jpeg" JPEG                "" "%s"      "%s"    ""
 \Format pbm        pbm     PBM                    "" "%s"      "%s"    ""
 \Format pgm        pgm     PGM                    "" "%s"      "%s"    ""
 \Format png        png     PNG                    "" "%s"      "%s"    ""
@@ -492,20 +534,21 @@ def checkFormatEntries(dtl_tools):
 \Format xpm        xpm     XPM                    "" "%s"      "%s"    ""''' % \
         (iv, ie, iv, ie, iv, ie, iv, ie, iv, ie, iv, ie, iv, ie, iv, ie, iv, ie, iv, ie) )
     #
-    checkViewerEditor('a text editor', ['sensible-editor', 'xemacs', 'gvim', 'kedit', 'kwrite', 'kate', \
+    checkViewerEditor('a text editor', ['xemacs', 'gvim', 'kedit', 'kwrite', 'kate', \
         'nedit', 'gedit', 'notepad'],
         rc_entry = [r'''\Format asciichess asc    "Plain text (chess output)"  "" ""   "%%"    ""
 \Format asciiimage asc    "Plain text (image)"         "" ""   "%%"    ""
 \Format asciixfig  asc    "Plain text (Xfig output)"   "" ""   "%%"    ""
 \Format dateout    tmp    "date (output)"         "" ""        "%%"    ""
 \Format docbook    sgml    DocBook                B  ""        "%%"    "document,menu=export"
-\Format docbook-xml xml   "Docbook (XML)"         "" ""        "%%"    "document,menu=export"
+\Format docbook-xml xml   "DocBook (XML)"         "" ""        "%%"    "document,menu=export"
 \Format dot        dot    "Graphviz Dot"          "" ""        "%%"    "vector"
 \Format platex     tex    "LaTeX (pLaTeX)"        "" "" "%%"    "document,menu=export"
 \Format literate   nw      NoWeb                  N  ""        "%%"    "document,menu=export"
 \Format sweave     Rnw    "Sweave"                S  "" "%%"    "document,menu=export"
+\Format r          R      "R/S code"              "" "" "%%"    "document,menu=export"
 \Format lilypond   ly     "LilyPond music"        "" ""        "%%"    "vector"
-\Format lilypond-book    lytex "LilyPond book (LaTeX)"   "" "" "%%"    "document"
+\Format lilypond-book    lytex "LilyPond book (LaTeX)"   "" "" "%%"    "document,menu=export"
 \Format latex      tex    "LaTeX (plain)"         L  ""        "%%"    "document,menu=export"
 \Format luatex     tex    "LaTeX (LuaTeX)"        "" ""        "%%"    "document,menu=export"
 \Format pdflatex   tex    "LaTeX (pdflatex)"      "" ""        "%%"    "document,menu=export"
@@ -516,17 +559,15 @@ def checkFormatEntries(dtl_tools):
 \Format text4      txt    "Plain text (catdvi)"   "" ""        "%%"    "document"
 \Format textparagraph txt "Plain Text, Join Lines" "" ""       "%%"    "document"''' ])
    #Spreadsheets using ssconvert from gnumeric
-    checkViewer('gnumeric spreadsheet software', ['gnumeric'], 
-      rc_entry = [r'''\Format gnumeric gnumeric "Gnumeric spreadsheet" "" ""    "%%"   "document" 
-\Format excel      xls    "Excel spreadsheet"      "" "" "%%"    "document" 
-\Format oocalc     ods    "OpenOffice spreadsheet" "" "" "%%"    "document"''']) 
+    checkViewer('gnumeric spreadsheet software', ['gnumeric'],
+      rc_entry = [r'''\Format gnumeric gnumeric "Gnumeric spreadsheet" "" ""    "%%"   "document"
+\Format excel      xls    "Excel spreadsheet"      "" "" "%%"    "document"
+\Format oocalc     ods    "OpenOffice spreadsheet" "" "" "%%"    "document"'''])
  #
-    path, xhtmlview = checkViewer('an HTML previewer', ['firefox', 'mozilla file://$$p$$i', 'netscape'],
+    checkViewer('an HTML previewer', ['firefox', 'mozilla file://$$p$$i', 'netscape'],
         rc_entry = [r'\Format xhtml      xhtml   "LyXHTML"              y "%%" ""    "document,menu=export"'])
-    if xhtmlview == "":
-        addToRC(r'\Format xhtml      xhtml   "LyXHTML"              y "" ""  "document,menu=export"')
  #
-    checkEditor('a BibTeX editor', ['sensible-editor', 'jabref', 'JabRef', \
+    checkEditor('a BibTeX editor', ['jabref', 'JabRef', \
         'pybliographic', 'bibdesk', 'gbib', 'kbib', \
         'kbibtex', 'sixpack', 'bibedit', 'tkbibtex' \
         'xemacs', 'gvim', 'kedit', 'kwrite', 'kate', \
@@ -537,7 +578,7 @@ def checkFormatEntries(dtl_tools):
     #  rc_entry = [ r'\ps_command "%%"' ])
     checkViewer('a Postscript previewer', ['kghostview', 'okular', 'evince', 'gv', 'ghostview -swap'],
         rc_entry = [r'''\Format eps        eps     EPS                    "" "%%"      ""      "vector"
-\Format ps         ps      Postscript             t  "%%"      ""      "document,vector"'''])
+\Format ps         ps      Postscript             t  "%%"      ""      "document,vector,menu=export"'''])
     # for xdg-open issues look here: http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg151818.html
     checkViewer('a PDF previewer', ['kpdf', 'okular', 'evince', 'kghostview', 'xpdf', 'acrobat', 'acroread', \
                    'gv', 'ghostview'],
@@ -555,7 +596,7 @@ def checkFormatEntries(dtl_tools):
         addToRC(r'\Format dvi2       dvi     DraftDVI               "" ""      ""      "vector"')
     #
     checkViewer('an HTML previewer', ['firefox', 'mozilla file://$$p$$i', 'netscape'],
-        rc_entry = [r'\Format html       html    HTML                   H  "%%"        ""      "document,menu=export"'])
+        rc_entry = [r'\Format html      "html, htm" HTML                H  "%%"        ""      "document,menu=export"'])
     #
     checkViewerEditor('Noteedit', ['noteedit'],
         rc_entry = [r'\Format noteedit   not     Noteedit               "" "%%"        "%%"    "vector"'])
@@ -563,7 +604,7 @@ def checkFormatEntries(dtl_tools):
     checkViewerEditor('an OpenDocument/OpenOffice viewer', ['swriter', 'oowriter', 'abiword'],
         rc_entry = [r'''\Format odt        odt     OpenDocument           "" "%%"      "%%"    "document,vector,menu=export"
 \Format sxw        sxw    "OpenOffice.Org (sxw)"  "" ""        ""      "document,vector"'''])
-    # 
+    #
     checkViewerEditor('a Rich Text and Word viewer', ['swriter', 'oowriter', 'abiword'],
         rc_entry = [r'''\Format rtf        rtf    "Rich Text Format"      "" "%%"      "%%"    "document,vector,menu=export"
 \Format word       doc    "MS Word"               W  "%%"      "%%"    "document,vector,menu=export"'''])
@@ -577,18 +618,17 @@ def checkFormatEntries(dtl_tools):
 \Format lyx14x     14.lyx  "LyX 1.4.x"             "" ""       ""      "document"
 \Format lyx15x     15.lyx  "LyX 1.5.x"             "" ""       ""      "document"
 \Format lyx16x     16.lyx  "LyX 1.6.x"             "" ""       ""      "document,menu=export"
+\Format lyx20x     20.lyx  "LyX 2.0.x"             "" ""       ""      "document,menu=export"
 \Format clyx       cjklyx "CJK LyX 1.4.x (big5)"  "" ""        ""      "document"
 \Format jlyx       cjklyx "CJK LyX 1.4.x (euc-jp)" "" ""       ""      "document"
 \Format klyx       cjklyx "CJK LyX 1.4.x (euc-kr)" "" ""       ""      "document"
 \Format lyxpreview lyxpreview "LyX Preview"       "" ""        ""      ""
-\Format lyxpreview-lytex  lyxpreview-lytex  "LyX Preview (LilyPond book)" "" ""        ""      ""
-\Format lyxpreview-platex lyxpreview-platex "LyX Preview (pLaTeX)"       "" "" ""      ""
 \Format pdftex     pdftex_t PDFTEX                "" ""        ""      ""
 \Format program    ""      Program                "" ""        ""      ""
 \Format pstex      pstex_t PSTEX                  "" ""        ""      ""
 \Format wmf        wmf    "Windows Metafile"      "" ""        ""      "vector"
 \Format emf        emf    "Enhanced Metafile"     "" ""        ""      "vector"
-\Format wordhtml   html   "HTML (MS Word)"        "" "" ""     "document"
+\Format wordhtml  "html, htm" "HTML (MS Word)"    "" "" ""     "document"
 ''')
 
 
@@ -600,39 +640,39 @@ def checkConverterEntries():
     checkProg('XeTeX', ['xelatex $$i'],
         rc_entry = [ r'\converter xetex      pdf4       "%%"   "latex=xelatex"' ])
 
-    checkProg('LuaTeX', ['lualatex $$i'],
-        rc_entry = [ r'\converter luatex      pdf5       "%%"  "latex=lualatex"' ])
+    checkLuatex()
 
-    checkProg('LuaTeX (DVI)', ['dvilualatex $$i'],
-        rc_entry = [ r'\converter luatex      dvi3        "%%" "latex=lualatex"' ])
-    
-    ''' If we're running LyX in-place then tex2lyx will be found in
-            ../src/tex2lyx. Add this directory to the PATH temporarily and
-            search for tex2lyx.
-            Use PATH to avoid any problems with paths-with-spaces.
-    '''
-    path_orig = os.environ["PATH"]
-    os.environ["PATH"] = os.path.join('..', 'src', 'tex2lyx') + \
-        os.pathsep + path_orig
+    # Look for tex2lyx in this order (see bugs #3308 and #6986):
+    #   1)  If we're running LyX in-place then tex2lyx will be found
+    #       in ../src/tex2lyx with respect to the srcdir.
+    #   2)  If LyX was configured with a version suffix then tex2lyx
+    #       will also have this version suffix.
+    #   3)  Otherwise always use tex2lyx.
+    in_place = os.path.join(srcdir, '..', 'src', 'tex2lyx', 'tex2lyx')
+    in_place = os.path.abspath(in_place)
 
-# First search for tex2lyx with version suffix (bug 6986)
-    checkProg('a LaTeX/Noweb -> LyX converter', ['tex2lyx' + version_suffix, 'tex2lyx'],
+    path, t2l = checkProg('a LaTeX/Noweb -> LyX converter', [in_place, 'tex2lyx' + version_suffix, 'tex2lyx'],
         rc_entry = [r'''\converter latex      lyx        "%% -f $$i $$o"       ""
-\converter literate   lyx        "%% -n -f $$i $$o"    ""'''])
-
-    os.environ["PATH"] = path_orig
+\converter literate   lyx        "%% -n -f $$i $$o"    ""'''], not_found = 'tex2lyx')
+    if path == '':
+        logger.warning("Failed to find tex2lyx on your system.")
 
     #
     checkProg('a Noweb -> LaTeX converter', ['noweave -delay -index $$i > $$o'],
         rc_entry = [r'''\converter literate   latex      "%%"  ""
 \converter literate   pdflatex      "%%"       ""'''])
     #
-    checkProg('a Sweave -> LaTeX converter', ['Rscript --no-save --no-restore $$s/scripts/lyxsweave.R $$p$$i $$e $$r'],
+    checkProg('a Sweave -> LaTeX converter', ['Rscript --verbose --no-save --no-restore $$s/scripts/lyxsweave.R $$p$$i $$p$$o $$e $$r'],
         rc_entry = [r'''\converter sweave   latex      "%%"    ""
-\converter sweave   pdflatex      "%%" ""'''])
+\converter sweave   pdflatex   "%%"    ""
+\converter sweave   xetex      "%%"    ""
+\converter sweave   luatex     "%%"    ""'''])
+    #
+    checkProg('a Sweave -> R/S code converter', ['Rscript --verbose --no-save --no-restore $$s/scripts/lyxstangle.R $$i $$e $$r'], 
+        rc_entry = [ r'\converter sweave      r      "%%"    ""' ])
     #
-    checkProg('an HTML -> LaTeX converter', ['html2latex $$i', 'gnuhtml2latex $$i', \
-        'htmltolatex -input $$i -output $$o', 'java -jar htmltolatex.jar -input $$i -output $$o'],
+    checkProg('an HTML -> LaTeX converter', ['html2latex $$i', 'gnuhtml2latex $$i',
+        'htmltolatex -input $$i -output $$o', 'htmltolatex.jar -input $$i -output $$o'],
         rc_entry = [ r'\converter html       latex      "%%"   ""' ])
     #
     checkProg('an MS Word -> LaTeX converter', ['wvCleanLatex $$i $$o'],
@@ -708,7 +748,9 @@ def checkConverterEntries():
         rc_entry = [ r'\converter ps         text3      "%%"   ""' ])
     #
     checkProg('a PS to EPS converter', ['ps2eps $$i'],
-        rc_entry = [ r'\converter ps         eps      "%%"     ""' ])
+        rc_entry = [ r'''\Format eps2       eps    "EPS (ps2eps)"          "" "" ""    "vector"
+\converter ps         eps      "%%"    ""
+\converter eps2       eps      "%%"    "resultfile=$$b.eps.eps"''' ])
     #
     checkProg('a PDF to PS converter', ['pdf2ps $$i $$o', 'pdftops $$i $$o'],
         rc_entry = [ r'\converter pdf         ps        "%%"   ""' ])
@@ -725,19 +767,6 @@ def checkConverterEntries():
     checkProg('a DVI to PDF converter', ['dvipdfmx -o $$o $$i', 'dvipdfm -o $$o $$i'],
         rc_entry = [ r'\converter dvi        pdf3       "%%"   ""' ])
     #
-    path, dvipng = checkProg('dvipng', ['dvipng'])
-    path, dv2dt  = checkProg('DVI to DTL converter', ['dv2dt'])
-    if dvipng == "dvipng" and dv2dt == 'dv2dt':
-        addToRC(r'\converter lyxpreview png        "python -tt $$s/scripts/lyxpreview2bitmap.py"       ""')
-    else:
-        # set empty converter to override the default imagemagick
-        addToRC(r'\converter lyxpreview png        ""  ""')
-    if dv2dt == 'dv2dt':
-        addToRC(r'\converter lyxpreview ppm        "python -tt $$s/scripts/lyxpreview2bitmap.py"       ""')
-    else:
-        # set empty converter to override the default imagemagick
-        addToRC(r'\converter lyxpreview ppm        ""  ""')
-    #  
     checkProg('a fax program', ['kdeprintfax $$i', 'ksendfax $$i', 'hylapex $$i'],
         rc_entry = [ r'\converter ps         fax        "%%"   ""'])
     #
@@ -768,6 +797,9 @@ def checkConverterEntries():
     checkProg('an EPS -> PDF converter', ['epstopdf'],
         rc_entry = [ r'\converter eps        pdf        "epstopdf --outfile=$$o $$i"   ""', ''])
     #
+    checkProg('an EPS -> PNG converter', ['convert $$i $$o'],
+        rc_entry = [ r'\converter eps        png        "%%"   ""', ''])
+    #
     # no agr -> pdf converter, since the pdf library used by gracebat is not
     # free software and therefore not compiled in in many installations.
     # Fortunately, this is not a big problem, because we will use epstopdf to
@@ -792,22 +824,25 @@ def checkConverterEntries():
     checkProg('a Dia -> EPS converter', ['dia -e $$o -t eps $$i'],
         rc_entry = [ r'\converter dia        eps        "%%"   ""'])
     #
-    checkProg('a SVG -> PDF converter', ['rsvg-convert -f pdf -o $$o $$i', 'inkscape --file=$$p/$$i --export-area-drawing --without-gui --export-pdf=$$p/$$o'],
+    checkProg('an OpenOffice -> EPS converter', ['libreoffice -headless -nologo -convert-to eps $$i'],
+        rc_entry = [ r'\converter odg        eps2       "%%"   ""'])
+    #
+    checkProg('a SVG -> PDF converter', ['rsvg-convert -f pdf -o $$o $$i', 'inkscape --file=$$i --export-area-drawing --without-gui --export-pdf=$$o'],
         rc_entry = [ r'\converter svg        pdf        "%%"   ""'])
     #
-    checkProg('a SVG -> EPS converter', ['rsvg-convert -f ps -o $$o $$i', 'inkscape --file=$$p/$$i --export-area-drawing --without-gui --export-eps=$$p/$$o'],
+    checkProg('a SVG -> EPS converter', ['rsvg-convert -f ps -o $$o $$i', 'inkscape --file=$$i --export-area-drawing --without-gui --export-eps=$$o'],
         rc_entry = [ r'\converter svg        eps        "%%"   ""'])
-    # the PNG export via Inkscape must not have the full path ($$p) for the file
+    #
     checkProg('a SVG -> PNG converter', ['rsvg-convert -f png -o $$o $$i', 'inkscape --without-gui --file=$$i --export-png=$$o'],
         rc_entry = [ r'\converter svg        png        "%%"   ""'])
-    
+
     #
     # gnumeric/xls/ods to tex
-    checkProg('a spreadsheet -> latex converter', ['ssconvert'], 
-       rc_entry = [ r'''\converter gnumeric latex "ssconvert --export-type=Gnumeric_html:latex $$i $$o" "" 
-\converter ods latex "ssconvert --export-type=Gnumeric_html:latex $$i $$o" "" 
-\converter xls latex "ssconvert --export-type=Gnumeric_html:latex $$i $$o" ""''', 
-'']) 
+    checkProg('a spreadsheet -> latex converter', ['ssconvert'],
+       rc_entry = [ r'''\converter gnumeric latex "ssconvert --export-type=Gnumeric_html:latex $$i $$o" ""
+\converter oocalc latex "ssconvert --export-type=Gnumeric_html:latex $$i $$o" ""
+\converter excel  latex "ssconvert --export-type=Gnumeric_html:latex $$i $$o" ""''',
+''])
 
     path, lilypond = checkProg('a LilyPond -> EPS/PDF/PNG converter', ['lilypond'])
     if (lilypond != ''):
@@ -840,16 +875,6 @@ def checkConverterEntries():
             version_number = match.groups()[0]
             version = version_number.split('.')
             if int(version[0]) > 2 or (len(version) > 1 and int(version[0]) == 2 and int(version[1]) >= 13):
-                if dv2dt == 'dv2dt':
-                    addToRC(r'\converter lyxpreview-lytex ppm "python -tt $$s/scripts/lyxpreview-lytex2bitmap.py" ""')
-                else:
-                    # set empty converter to override the default imagemagick
-                    addToRC(r'\converter lyxpreview-lytex ppm "" ""')
-                if dvipng == "dvipng" and dv2dt == 'dv2dt':
-                    addToRC(r'\converter lyxpreview-lytex png "python -tt $$s/scripts/lyxpreview-lytex2bitmap.py" ""')
-                else:
-                    # set empty converter to override the default imagemagick
-                    addToRC(r'\converter lyxpreview-lytex png "" ""')
                 # Note: The --lily-output-dir flag is required because lilypond-book
                 #       does not process input again unless the input has changed,
                 #       even if the output format being requested is different. So
@@ -859,6 +884,8 @@ def checkConverterEntries():
                 #       this, use different output folders for eps and pdf outputs.
                 addToRC(r'\converter lilypond-book latex    "lilypond-book --safe --lily-output-dir=ly-eps $$i"                                ""')
                 addToRC(r'\converter lilypond-book pdflatex "lilypond-book --safe --pdf --latex-program=pdflatex --lily-output-dir=ly-pdf $$i" ""')
+                addToRC(r'\converter lilypond-book xetex    "lilypond-book --safe --pdf --latex-program=xelatex --lily-output-dir=ly-pdf $$i"  ""')
+                addToRC(r'\converter lilypond-book luatex   "lilypond-book --safe --pdf --latex-program=lualatex --lily-output-dir=ly-pdf $$i" ""')
                 logger.info('+  found LilyPond-book version %s.' % version_number)
             else:
                 logger.info('+  found LilyPond-book, but version %s is too old.' % version_number)
@@ -878,13 +905,13 @@ def checkConverterEntries():
     else:
         addToRC(r'\Format lyxgz      gz     "LyX Archive (tar.gz)"  "" "" ""  "document,menu=export"')
         addToRC(cmd % "lyxgz")
-        
+
     #
     # FIXME: no rc_entry? comment it out
     # checkProg('Image converter', ['convert $$i $$o'])
     #
     # Entries that do not need checkProg
-    addToRC(r'''\converter lyxpreview-platex ppm        "python -tt $$s/scripts/lyxpreview-platex2bitmap.py"   ""
+    addToRC(r'''
 \converter csv        lyx        "python -tt $$s/scripts/csv2lyx.py $$i $$o"   ""
 \converter date       dateout    "python -tt $$s/scripts/date.py %d-%m-%Y > $$o"       ""
 \converter docbook    docbook-xml "cp $$i $$o" "xml"
@@ -893,12 +920,15 @@ def checkConverterEntries():
 \converter lyx        lyx14x     "python -tt $$s/lyx2lyx/lyx2lyx -t 245 $$i > $$o"     ""
 \converter lyx        lyx15x     "python -tt $$s/lyx2lyx/lyx2lyx -t 276 $$i > $$o"     ""
 \converter lyx        lyx16x     "python -tt $$s/lyx2lyx/lyx2lyx -t 345 $$i > $$o"     ""
+\converter lyx        lyx20x     "python -tt $$s/lyx2lyx/lyx2lyx -t 413 $$i > $$o"     ""
 \converter lyx        clyx       "python -tt $$s/lyx2lyx/lyx2lyx -c big5 -t 245 $$i > $$o"     ""
 \converter lyx        jlyx       "python -tt $$s/lyx2lyx/lyx2lyx -c euc_jp -t 245 $$i > $$o"   ""
 \converter lyx        klyx       "python -tt $$s/lyx2lyx/lyx2lyx -c euc_kr -t 245 $$i > $$o"   ""
 \converter clyx       lyx        "python -tt $$s/lyx2lyx/lyx2lyx -c big5 $$i > $$o"    ""
 \converter jlyx       lyx        "python -tt $$s/lyx2lyx/lyx2lyx -c euc_jp $$i > $$o"  ""
 \converter klyx       lyx        "python -tt $$s/lyx2lyx/lyx2lyx -c euc_kr $$i > $$o"  ""
+\converter lyxpreview png        "python -tt $$s/scripts/lyxpreview2bitmap.py --png"   ""
+\converter lyxpreview ppm        "python -tt $$s/scripts/lyxpreview2bitmap.py --ppm"   ""
 ''')
 
 
@@ -935,11 +965,8 @@ def checkOtherEntries():
         alt_rc_entry = [ r'\index_alternatives "%%"' ])
     checkProg('an index processor appropriate to Japanese', ['mendex -c -q', 'jmakeindex -c -q', 'makeindex -c -q'],
         rc_entry = [ r'\jindex_command "%%"' ])
-    path, splitindex = checkProg('the splitindex processor', ['splitindex.pl', 'splitindex'],
-        rc_entry = [ r'\splitindex_command "%%"' ])
-    if splitindex == '':
-        checkProg('the splitindex processor (java version)', ['splitindex.class'],
-            rc_entry = [ r'\splitindex_command "java splitindex"' ])
+    checkProg('the splitindex processor', ['splitindex.pl', 'splitindex',
+        'splitindex.class'], rc_entry = [ r'\splitindex_command "%%"' ])
     checkProg('a nomenclature processor', ['makeindex'],
         rc_entry = [ r'\nomencl_command "makeindex -s nomencl.ist"' ])
     ## FIXME: OCTAVE is not used anywhere
@@ -963,15 +990,15 @@ def checkOtherEntries():
 
 def processLayoutFile(file, bool_docbook):
     ''' process layout file and get a line of result
-        
+
         Declare lines look like this: (article.layout, scrbook.layout, svjog.layout)
-        
+
         \DeclareLaTeXClass{article}
         \DeclareLaTeXClass[scrbook]{book (koma-script)}
         \DeclareLaTeXClass[svjour,svjog.clo]{article (Springer - svjour/jog)}
 
         we expect output:
-        
+
         "article" "article" "article" "false" "article.cls"
         "scrbook" "scrbook" "book (koma-script)" "false" "scrbook.cls"
         "svjog" "svjour" "article (Springer - svjour/jog)" "false" "svjour.cls,svjog.clo"
@@ -1006,11 +1033,11 @@ def processLayoutFile(file, bool_docbook):
 
 
 def checkLatexConfig(check_config, bool_docbook):
-    ''' Explore the LaTeX configuration 
+    ''' Explore the LaTeX configuration
         Return None (will be passed to sys.exit()) for success.
     '''
     msg = 'checking LaTeX configuration... '
-    # if --without-latex-config is forced, or if there is no previous 
+    # if --without-latex-config is forced, or if there is no previous
     # version of textclass.lst, re-generate a default file.
     if not os.path.isfile('textclass.lst') or not check_config:
         # remove the files only if we want to regenerate
@@ -1034,7 +1061,7 @@ def checkLatexConfig(check_config, bool_docbook):
         for file in glob.glob( os.path.join('layouts', '*.layout') ) + \
             glob.glob( os.path.join(srcdir, 'layouts', '*.layout' ) ) :
             # valid file?
-            if not os.path.isfile(file): 
+            if not os.path.isfile(file):
                 continue
             # get stuff between /xxxx.layout .
             classname = file.split(os.sep)[-1].split('.')[0]
@@ -1053,8 +1080,8 @@ def checkLatexConfig(check_config, bool_docbook):
         return None
     # the following will generate textclass.lst.tmp, and packages.lst.tmp
     logger.info(msg + '\tauto')
-    removeFiles(['wrap_chkconfig.ltx', 'chkconfig.vars', \
-        'chkconfig.classes', 'chklayouts.tex'])
+    removeFiles(['chkconfig.classes', 'chkconfig.vars', 'chklayouts.tex',
+        'wrap_chkconfig.ltx'])
     rmcopy = False
     if not os.path.isfile( 'chkconfig.ltx' ):
         shutil.copyfile( os.path.join(srcdir, 'chkconfig.ltx'), 'chkconfig.ltx' )
@@ -1068,17 +1095,21 @@ def checkLatexConfig(check_config, bool_docbook):
     testclasses = list()
     for file in glob.glob( os.path.join('layouts', '*.layout') ) + \
         glob.glob( os.path.join(srcdir, 'layouts', '*.layout' ) ) :
+        nodeclaration = False
         if not os.path.isfile(file):
             continue
         classname = file.split(os.sep)[-1].split('.')[0]
         for line in open(file).readlines():
             if not empty.match(line) and line[0] != '#':
-                logger.error("Failed to find \Declare line for layout file `" + file + "'")
-                sys.exit(3)
+                logger.warning("Failed to find valid \Declare line for layout file `" + file + "'.\n\t=> Skipping this file!")
+                nodeclaration = True
+                break
             if declare.search(line) == None:
                 continue
             testclasses.append("\\TestDocClass{%s}{%s}" % (classname, line[1:].strip()))
             break
+        if nodeclaration:
+            continue
     testclasses.sort()
     cl = open('chklayouts.tex', 'w')
     for line in testclasses:
@@ -1086,15 +1117,18 @@ def checkLatexConfig(check_config, bool_docbook):
     cl.close()
     #
     # we have chklayouts.tex, then process it
-    fout = os.popen(LATEX + ' wrap_chkconfig.ltx')
-    while True:
-        line = fout.readline()
-        if not line:
-            break;
+    ret = 1
+    latex_out = cmdOutput(LATEX + ' wrap_chkconfig.ltx')
+    for line in latex_out.splitlines():
         if re.match('^\+', line):
             logger.info(line.strip())
-    # if the command succeeds, None will be returned
-    ret = fout.close()
+            # return None if the command succeeds
+            if line == "+Inspection done.":
+                ret = None
+    #
+    # remove the copied file
+    if rmcopy:
+        removeFiles( [ 'chkconfig.ltx' ] )
     #
     # currently, values in chhkconfig are only used to set
     # \font_encoding
@@ -1103,13 +1137,11 @@ def checkLatexConfig(check_config, bool_docbook):
         key, val = re.sub('-', '_', line).split('=')
         val = val.strip()
         values[key] = val.strip("'")
-    # chk_fontenc may not exist 
+    # chk_fontenc may not exist
     try:
         addToRC(r'\font_encoding "%s"' % values["chk_fontenc"])
     except:
         pass
-    if rmcopy:   # remove the copied file
-        removeFiles( [ 'chkconfig.ltx' ] )
     # if configure successed, move textclass.lst.tmp to textclass.lst
     # and packages.lst.tmp to packages.lst
     if os.path.isfile('textclass.lst.tmp') and len(open('textclass.lst.tmp').read()) > 0 \
@@ -1127,25 +1159,35 @@ def checkModulesConfig():
   tx.write('''## This file declares modules and their associated definition files.
 ## It has been automatically generated by configure
 ## Use "Options/Reconfigure" if you need to update it after a
-## configuration change. 
+## configuration change.
 ## "ModuleName" "filename" "Description" "Packages" "Requires" "Excludes" "Category"
 ''')
+
   # build the list of available modules
-  foundClasses = []
+  seen = []
+  # note that this searches the local directory first, then the
+  # system directory. that way, we pick up the user's version first.
   for file in glob.glob( os.path.join('layouts', '*.module') ) + \
       glob.glob( os.path.join(srcdir, 'layouts', '*.module' ) ) :
       # valid file?
       logger.info(file)
-      if not os.path.isfile(file): 
+      if not os.path.isfile(file):
+          continue
+
+      filename = file.split(os.sep)[-1]
+      filename = filename[:-7]
+      if seen.count(filename):
           continue
-      retval = processModuleFile(file, bool_docbook)
+
+      seen.append(filename)
+      retval = processModuleFile(file, filename, bool_docbook)
       if retval != "":
           tx.write(retval)
   tx.close()
   logger.info('\tdone')
 
 
-def processModuleFile(file, bool_docbook):
+def processModuleFile(file, filename, bool_docbook):
     ''' process module file and get a line of result
 
         The top of a module file should look like this:
@@ -1170,8 +1212,6 @@ def processModuleFile(file, bool_docbook):
     modname = desc = pkgs = req = excl = catgy = ""
     readingDescription = False
     descLines = []
-    filename = file.split(os.sep)[-1]
-    filename = filename[:-7]
 
     for line in open(file).readlines():
       if readingDescription:
@@ -1236,7 +1276,6 @@ def processModuleFile(file, bool_docbook):
         cm.close()
 
     return '"%s" "%s" "%s" "%s" "%s" "%s" "%s"\n' % (modname, filename, desc, pkgs, req, excl, catgy)
-    
 
 
 def checkTeXAllowSpaces():
@@ -1246,10 +1285,10 @@ def checkTeXAllowSpaces():
         msg = "Checking whether TeX allows spaces in file names... "
         writeToFile('a b.tex', r'\message{working^^J}' )
         if LATEX != '':
-            if os.name == 'nt':
-                latex_out = cmdOutput(LATEX + r""" "\nonstopmode\input{\"a b\"}" """)
+            if os.name == 'nt' or sys.platform == 'cygwin':
+                latex_out = cmdOutput(LATEX + r""" "\nonstopmode\input{\"a b\"}\makeatletter\@@end" """)
             else:
-                latex_out = cmdOutput(LATEX + r""" '\nonstopmode\input{"a b"}' """)
+                latex_out = cmdOutput(LATEX + r""" '\nonstopmode\input{"a b"}\makeatletter\@@end' """)
         else:
             latex_out = ''
         if 'working' in latex_out:
@@ -1265,15 +1304,15 @@ def checkTeXAllowSpaces():
 def removeTempFiles():
     # Final clean-up
     if not lyx_keep_temps:
-        removeFiles(['chkconfig.vars',  \
-            'wrap_chkconfig.ltx', 'wrap_chkconfig.log', \
-            'chklayouts.tex', 'chkmodules.tex', 'missfont.log', 
-            'chklatex.ltx', 'chklatex.log'])
+        removeFiles(['chkconfig.vars', 'chklatex.ltx', 'chklatex.log',
+            'chklayouts.tex', 'chkmodules.tex', 'missfont.log',
+            'wrap_chkconfig.ltx', 'wrap_chkconfig.log'])
 
 
 if __name__ == '__main__':
     lyx_check_config = True
     outfile = 'lyxrc.defaults'
+    lyxrc_fileformat = 3
     rc_entries = ''
     lyx_keep_temps = False
     version_suffix = ''
@@ -1307,22 +1346,28 @@ Options:
         sys.exit(1)
     setEnviron()
     createDirectories()
-    windows_style_tex_paths = checkTeXPaths()
     dtl_tools = checkDTLtools()
     ## Write the first part of outfile
     writeToFile(outfile, '''# This file has been automatically generated by LyX' lib/configure.py
 # script. It contains default settings that have been determined by
 # examining your system. PLEASE DO NOT MODIFY ANYTHING HERE! If you
-# want to customize LyX, use LyX' Preferences dialog or modify directly 
+# want to customize LyX, use LyX' Preferences dialog or modify directly
 # the "preferences" file instead. Any setting in that file will
 # override the values given here.
-''')
+
+Format %i
+
+''' % lyxrc_fileformat)
     # check latex
     LATEX = checkLatex(dtl_tools)
+    # check java and perl before any checkProg that may require them
+    java = checkProg('a java interpreter', ['java'])[1]
+    perl = checkProg('a perl interpreter', ['perl'])[1]
     checkFormatEntries(dtl_tools)
     checkConverterEntries()
     (chk_docbook, bool_docbook, docbook_cmd) = checkDocBook()
     checkTeXAllowSpaces()
+    windows_style_tex_paths = checkTeXPaths()
     if windows_style_tex_paths != '':
         addToRC(r'\tex_expects_windows_paths %s' % windows_style_tex_paths)
     checkOtherEntries()