]> git.lyx.org Git - lyx.git/blobdiff - lib/configure.py
Merge remote-tracking branch 'features/str-metrics'
[lyx.git] / lib / configure.py
index 522da331c1e098831faad4febb945106bc9534ef..08384bf90e4e1946076440bc18f61ddc1667c52e 100644 (file)
@@ -8,7 +8,7 @@
 # \author Bo Peng
 # Full author contact details are available in file CREDITS.
 
-import glob, logging, os, re, shutil, subprocess, sys
+import glob, logging, os, re, shutil, subprocess, sys, stat
 
 # set up logging
 logging.basicConfig(level = logging.DEBUG,
@@ -56,23 +56,40 @@ def removeFiles(filenames):
             pass
 
 
-def cmdOutput(cmd):
+def cmdOutput(cmd, async = False):
     '''utility function: run a command and get its output as a string
         cmd: command to run
+        async: if False, return whole output as a string, otherwise
+               return the stdout handle from which the output can be
+               read (the caller is then responsible for closing it)
     '''
     if os.name == 'nt':
         b = False
-        cmd = 'cmd /d /c ' + cmd
+        cmd = 'cmd /d /c pushd ' + shortPath(os.getcwdu()) + '&' + 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()
+    if async:
+        return pipe.stdout
     output = pipe.stdout.read()
     pipe.stdout.close()
     return output.strip()
 
 
+def shortPath(path):
+    ''' On Windows, return the short version of "path" if possible '''
+    if os.name == 'nt':
+        from ctypes import windll, create_unicode_buffer
+        GetShortPathName = windll.kernel32.GetShortPathNameW
+        shortlen = GetShortPathName(path, 0, 0)
+        shortpath = create_unicode_buffer(shortlen)
+        if GetShortPathName(path, shortpath, shortlen):
+            return shortpath.value
+    return path
+
+
 def setEnviron():
     ''' I do not really know why this is useful, but we might as well keep it.
         NLS nuisances.
@@ -87,6 +104,73 @@ def setEnviron():
     os.environ['LC_CTYPE'] = os.getenv('LC_CTYPE', 'C')
 
 
+def copy_tree(src, dst, preserve_symlinks=False, level=0):
+    ''' Copy an entire directory tree 'src' to a new location 'dst'.
+    Code inspired from distutils.copy_tree.
+        Copying ignores non-regular files and the cache directory.
+    Pipes may be present as leftovers from LyX for lyx-server.
+
+    If 'preserve_symlinks' is true, symlinks will be
+    copied as symlinks (on platforms that support them!); otherwise
+    (the default), the destination of the symlink will be copied.
+    '''
+    if not os.path.isdir(src):
+        raise FileError, \
+              "cannot copy tree '%s': not a directory" % src
+    try:
+        names = os.listdir(src)
+    except os.error, (errno, errstr):
+        raise FileError, \
+              "error listing files in '%s': %s" % (src, errstr)
+    if not os.path.isdir(dst):
+        os.makedirs(dst)
+    outputs = []
+    for name in names:
+        src_name = os.path.join(src, name)
+        dst_name = os.path.join(dst, name)
+        if preserve_symlinks and os.path.islink(src_name):
+            link_dest = os.readlink(src_name)
+            os.symlink(link_dest, dst_name)
+            outputs.append(dst_name)
+        elif level == 0 and name == 'cache':
+            logger.info("Skip cache %s", src_name)
+        elif os.path.isdir(src_name):
+            outputs.extend(
+                copy_tree(src_name, dst_name, preserve_symlinks, level=(level + 1)))
+        elif stat.S_ISREG(os.stat(src_name).st_mode) or os.path.islink(src_name):
+            shutil.copy2(src_name, dst_name)
+            outputs.append(dst_name)
+        else:
+            logger.info("Ignore non-regular file %s", src_name)
+    return outputs
+
+
+def checkUpgrade():
+    ''' Check for upgrade from previous version '''
+    cwd = os.getcwd()
+    basename = os.path.basename( cwd )
+    lyxrc = os.path.join(cwd, outfile)
+    if not os.path.isfile( lyxrc ) and basename.endswith( version_suffix ) :
+        logger.info('Checking for upgrade from previous version.')
+        parent = os.path.dirname(cwd)
+        appname = basename[:(-len(version_suffix))]
+        for version in ['-2.1', '-2.0', '-1.6' ]:
+            logger.debug('Checking for upgrade from previous version ' + version)
+            previous = os.path.join(parent, appname + version)
+            logger.debug('previous = ' + previous)
+            if os.path.isdir( previous ):
+                logger.info('Found directory "%s".', previous)
+                copy_tree( previous, cwd )
+                logger.info('Content copied to directory "%s".', cwd)
+                return
+
+
 def createDirectories():
     ''' Create the build directories if necessary '''
     for dir in ['bind', 'clipart', 'doc', 'examples', 'images', 'kbd', \
@@ -109,18 +193,14 @@ def checkTeXPaths():
         from tempfile import mkstemp
         fd, tmpfname = mkstemp(suffix='.ltx')
         if os.name == 'nt':
-            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('\\', '/')
+            from locale import getdefaultlocale
+            language, encoding = getdefaultlocale()
+            if encoding == None:
+                encoding = 'latin1'
+            inpname = shortPath(unicode(tmpfname, encoding)).replace('\\', '/')
         else:
             inpname = cmdOutput('cygpath -m ' + tmpfname)
-        logname = os.path.basename(inpname.replace('.ltx', '.log'))
+        logname = os.path.basename(re.sub("(?i).ltx", ".log", inpname))
         inpname = inpname.replace('~', '\\string~')
         os.write(fd, r'\relax')
         os.close(fd)
@@ -170,19 +250,33 @@ 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 = ['']
         if "PATHEXT" in os.environ:
             extlist = extlist + os.environ["PATHEXT"].split(os.pathsep)
         for ac_dir in path:
+            if hasattr(os, "access") and not os.access(ac_dir, os.F_OK):
+                continue
             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))
@@ -211,10 +305,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 = ['']
@@ -222,11 +321,20 @@ def checkProgAlternatives(description, progs, rc_entry = [], alt_rc_entry = [],
             extlist = extlist + os.environ["PATHEXT"].split(os.pathsep)
         found_alt = False
         for ac_dir in path:
+            if hasattr(os, "access") and not os.access(ac_dir, os.F_OK):
+                continue
             for ext in extlist:
                 if os.path.isfile( os.path.join(ac_dir, ac_word + ext) ):
                     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:
@@ -284,13 +392,13 @@ def addAlternatives(rcs, alt_type):
         if len(rcs) == 1:
             m = r.match(rcs[0])
             if m:
-                alt = '\n'.join([s + m.group(1) + " %%" for s in alt_tokens])
+                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 += '\n'.join([s + m.group(1) + " %%" for s in alt_tokens])
+                alt += '\n'.join([s + m.group(1) + ' "%%"' for s in alt_tokens])
     return alt
 
 
@@ -456,156 +564,151 @@ def checkModule(module):
 def checkFormatEntries(dtl_tools):
     ''' Check all formats (\Format entries) '''
     checkViewerEditor('a Tgif viewer and editor', ['tgif'],
-        rc_entry = [r'\Format tgif       obj     Tgif                   "" "%%"        "%%"    "vector"'])
+        rc_entry = [r'\Format tgif      "obj, tgo" Tgif                 "" "%%"        "%%"    "vector"        "application/x-tgif"'])
     #
     checkViewerEditor('a FIG viewer and editor', ['xfig', 'jfig3-itext.jar', 'jfig3.jar'],
-        rc_entry = [r'\Format fig        fig     FIG                    "" "%%"        "%%"    "vector"'])
+        rc_entry = [r'\Format fig        fig     FIG                    "" "%%"        "%%"    "vector"        "application/x-xfig"'])
     #
     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", "application/x-dia-diagram"'])
+    #
+    checkViewerEditor('an OpenOffice drawing viewer and editor', ['libreoffice', 'lodraw', 'ooffice', 'oodraw', 'soffice'],
+        rc_entry = [r'\Format odg        "odg, sxd" "OpenOffice drawing"   "" "%%"     "%%"    "vector,zipped=native"  "application/vnd.oasis.opendocument.graphics"'])
     #
     checkViewerEditor('a Grace viewer and editor', ['xmgrace'],
-        rc_entry = [r'\Format agr        agr     Grace                  "" "%%"        "%%"    "vector"'])
+        rc_entry = [r'\Format agr        agr     Grace                  "" "%%"        "%%"    "vector"        ""'])
     #
     checkViewerEditor('a FEN viewer and editor', ['xboard -lpf $$i -mode EditPosition'],
-        rc_entry = [r'\Format fen        fen     FEN                    "" "%%"        "%%"    ""'])
+        rc_entry = [r'\Format fen        fen     FEN                    "" "%%"        "%%"    ""      ""'])
     #
     checkViewerEditor('a SVG viewer and editor', ['inkscape'],
-        rc_entry = [r'\Format svg        svg     SVG                    "" "%%" "%%"   "vector"'])
+        rc_entry = [r'\Format svg        svg     SVG                    "" "%%" "%%"   "vector"        "image/svg+xml"'])
     #
-    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 pbm        pbm     PBM                    "" "%s"      "%s"    ""
-\Format pgm        pgm     PGM                    "" "%s"      "%s"    ""
-\Format png        png     PNG                    "" "%s"      "%s"    ""
-\Format ppm        ppm     PPM                    "" "%s"      "%s"    ""
-\Format tiff       tif     TIFF                   "" "%s"      "%s"    ""
-\Format xbm        xbm     XBM                    "" "%s"      "%s"    ""
-\Format xpm        xpm     XPM                    "" "%s"      "%s"    ""'''])
-    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 pbm        pbm     PBM                    "" "%s"      "%s"    ""
-\Format pgm        pgm     PGM                    "" "%s"      "%s"    ""
-\Format png        png     PNG                    "" "%s"      "%s"    ""
-\Format ppm        ppm     PPM                    "" "%s"      "%s"    ""
-\Format tiff       tif     TIFF                   "" "%s"      "%s"    ""
-\Format xbm        xbm     XBM                    "" "%s"      "%s"    ""
-\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 pbm        pbm     PBM                    "" "%s"      "%s"    ""
-\Format pgm        pgm     PGM                    "" "%s"      "%s"    ""
-\Format png        png     PNG                    "" "%s"      "%s"    ""
-\Format ppm        ppm     PPM                    "" "%s"      "%s"    ""
-\Format tiff       tif     TIFF                   "" "%s"      "%s"    ""
-\Format xbm        xbm     XBM                    "" "%s"      "%s"    ""
-\Format xpm        xpm     XPM                    "" "%s"      "%s"    ""''' % \
+    imageformats = r'''\Format bmp        bmp     BMP                    "" "%s"       "%s"    ""      "image/x-bmp"
+\Format gif        gif     GIF                    "" "%s"      "%s"    ""      "image/gif"
+\Format jpg       "jpg, jpeg" JPEG                "" "%s"      "%s"    ""      "image/jpeg"
+\Format pbm        pbm     PBM                    "" "%s"      "%s"    ""      "image/x-portable-bitmap"
+\Format pgm        pgm     PGM                    "" "%s"      "%s"    ""      "image/x-portable-graymap"
+\Format png        png     PNG                    "" "%s"      "%s"    ""      "image/x-png"
+\Format ppm        ppm     PPM                    "" "%s"      "%s"    ""      "image/x-portable-pixmap"
+\Format tiff       tif     TIFF                   "" "%s"      "%s"    ""      "image/tiff"
+\Format xbm        xbm     XBM                    "" "%s"      "%s"    ""      "image/x-xbitmap"
+\Format xpm        xpm     XPM                    "" "%s"      "%s"    ""      "image/x-xpixmap"'''
+    path, iv = checkViewerNoRC('a raster image viewer', ['xv', 'kview', 'gimp-remote', 'gimp'], rc_entry = [imageformats])
+    path, ie = checkEditorNoRC('a raster image editor', ['gimp-remote', 'gimp'], rc_entry = [imageformats])
+    addToRC(imageformats % \
         (iv, ie, iv, ie, iv, ie, iv, ie, iv, ie, iv, ie, iv, ie, iv, ie, iv, ie, iv, ie) )
     #
     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 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,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"
-\Format xetex      tex    "LaTeX (XeTeX)"         "" ""        "%%"    "document,menu=export"
-\Format text       txt    "Plain text"            a  ""        "%%"    "document,menu=export"
-\Format text2      txt    "Plain text (pstotext)" "" ""        "%%"    "document"
-\Format text3      txt    "Plain text (ps2ascii)" "" ""        "%%"    "document"
-\Format text4      txt    "Plain text (catdvi)"   "" ""        "%%"    "document"
-\Format textparagraph txt "Plain Text, Join Lines" "" ""       "%%"    "document"''' ])
+        'nedit', 'gedit', 'notepad', 'geany', 'leafpad', 'mousepad'],
+        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"  "application/docbook+xml"
+\Format dot        dot    "Graphviz Dot"          "" ""        "%%"    "vector"        "text/vnd.graphviz"
+\Format dviluatex  tex    "LaTeX (dviluatex)"     "" "" "%%"   "document,menu=export"  ""
+\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 knitr      Rnw    "Rnw (knitr)"           "" "" "%%"   "document,menu=export"  ""
+\Format lilypond   ly     "LilyPond music"        "" ""        "%%"    "vector"        "text/x-lilypond"
+\Format lilypond-book    lytex "LilyPond book (LaTeX)"   "" "" "%%"    "document,menu=export"  ""
+\Format latex      tex    "LaTeX (plain)"         L  ""        "%%"    "document,menu=export"  "text/x-tex"
+\Format luatex     tex    "LaTeX (LuaTeX)"        "" ""        "%%"    "document,menu=export"  ""
+\Format pdflatex   tex    "LaTeX (pdflatex)"      "" ""        "%%"    "document,menu=export"  ""
+\Format xetex      tex    "LaTeX (XeTeX)"         "" ""        "%%"    "document,menu=export"  ""
+\Format latexclipboard tex "LaTeX (clipboard)"    "" ""        "%%"    ""      ""
+\Format text       txt    "Plain text"            a  ""        "%%"    "document,menu=export"  "text/plain"
+\Format text2      txt    "Plain text (pstotext)" "" ""        "%%"    "document"      ""
+\Format text3      txt    "Plain text (ps2ascii)" "" ""        "%%"    "document"      ""
+\Format text4      txt    "Plain text (catdvi)"   "" ""        "%%"    "document"      ""
+\Format textparagraph txt "Plain Text, Join Lines" "" ""       "%%"    "document"      ""
+\Format beamer.info pdf.info   "Info (Beamer)"         "" ""   "%%"    "document,menu=export"  ""''' ])
    #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"'''])
+      rc_entry = [r'''\Format gnumeric gnumeric "Gnumeric spreadsheet" "" ""    "%%"   "document"      "application/x-gnumeric"
+\Format excel      xls    "Excel spreadsheet"      "" "" "%%"    "document"    "application/vnd.ms-excel"
+\Format oocalc     ods    "OpenOffice spreadsheet" "" "" "%%"    "document"    "application/vnd.oasis.opendocument.spreadsheet"'''])
  #
     checkViewer('an HTML previewer', ['firefox', 'mozilla file://$$p$$i', 'netscape'],
-        rc_entry = [r'\Format xhtml      xhtml   "LyXHTML"              y "%%" ""    "document,menu=export"'])
+        rc_entry = [r'\Format xhtml      xhtml   "LyXHTML"              y "%%" ""    "document,menu=export"    "application/xhtml+xml"'])
  #
     checkEditor('a BibTeX editor', ['jabref', 'JabRef', \
         'pybliographic', 'bibdesk', 'gbib', 'kbib', \
         'kbibtex', 'sixpack', 'bibedit', 'tkbibtex' \
         'xemacs', 'gvim', 'kedit', 'kwrite', 'kate', \
-        'nedit', 'gedit', 'notepad'],
-        rc_entry = [r'''\Format bibtex bib    "BibTeX"         "" ""   "%%"    ""''' ])
+        'jedit', 'TeXnicCenter', 'WinEdt', 'WinShell', 'PSPad', \
+        'nedit', 'gedit', 'notepad', 'geany', 'leafpad', 'mousepad'],
+        rc_entry = [r'''\Format bibtex bib    "BibTeX"         "" ""   "%%"    ""      "text/x-bibtex"''' ])
     #
     #checkProg('a Postscript interpreter', ['gs'],
     #  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,menu=export"'''])
+    checkViewer('a Postscript previewer', ['kghostview', 'okular', 'qpdfview --unique', 'evince', 'gv', 'ghostview -swap', 'gsview64', 'gsview32'],
+        rc_entry = [r'''\Format eps        eps     EPS                    "" "%%"      ""      "vector"        "image/x-eps"
+\Format eps2       eps    "EPS (uncropped)"       "" "%%"      ""      "vector"        ""
+\Format eps3       eps    "EPS (cropped)"         "" "%%"      ""      "document,menu=export"  ""
+\Format ps         ps      Postscript             t  "%%"      ""      "document,vector,menu=export"   "application/postscript"'''])
     # 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'],
-        rc_entry = [r'''\Format pdf        pdf    "PDF (ps2pdf)"          P  "%%"      ""      "document,vector,menu=export"
-\Format pdf2       pdf    "PDF (pdflatex)"        F  "%%"      ""      "document,vector,menu=export"
-\Format pdf3       pdf    "PDF (dvipdfm)"         m  "%%"      ""      "document,vector,menu=export"
-\Format pdf4       pdf    "PDF (XeTeX)"           X  "%%"      ""      "document,vector,menu=export"
-\Format pdf5       pdf    "PDF (LuaTeX)"          u  "%%"      ""      "document,vector,menu=export"'''])
+    # the MIME type is set for pdf6, because that one needs to be autodetectable by libmime
+    checkViewer('a PDF previewer', ['pdfview', 'kpdf', 'okular', 'qpdfview --unique', 'evince', 'kghostview', 'xpdf', 'SumatraPDF', 'acrobat', 'acroread', 'mupdf', \
+                   'gv', 'ghostview', 'AcroRd32', 'gsview64', 'gsview32'],
+        rc_entry = [r'''\Format pdf        pdf    "PDF (ps2pdf)"          P  "%%"      ""      "document,vector,menu=export"   ""
+\Format pdf2       pdf    "PDF (pdflatex)"        F  "%%"      ""      "document,vector,menu=export"   ""
+\Format pdf3       pdf    "PDF (dvipdfm)"         m  "%%"      ""      "document,vector,menu=export"   ""
+\Format pdf4       pdf    "PDF (XeTeX)"           X  "%%"      ""      "document,vector,menu=export"   ""
+\Format pdf5       pdf    "PDF (LuaTeX)"          u  "%%"      ""      "document,vector,menu=export"   ""
+\Format pdf6       pdf    "PDF (graphics)"        "" "%%"      ""      "vector"        "application/pdf"
+\Format pdf7       pdf    "PDF (cropped)"         "" "%%"      ""      "document,menu=export"  ""'''])
     #
     checkViewer('a DVI previewer', ['xdvi', 'kdvi', 'okular', 'yap', 'dviout -Set=!m'],
-        rc_entry = [r'''\Format dvi        dvi     DVI                    D  "%%"      ""      "document,vector,menu=export"
-\Format dvi3       dvi     "DVI (LuaTeX)"          V  "%%"     ""      "document,vector,menu=export"'''])
+        rc_entry = [r'''\Format dvi        dvi     DVI                    D  "%%"      ""      "document,vector,menu=export"   "application/x-dvi"
+\Format dvi3       dvi     "DVI (LuaTeX)"          V  "%%"     ""      "document,vector,menu=export"   ""'''])
     if dtl_tools:
         # Windows only: DraftDVI
-        addToRC(r'\Format dvi2       dvi     DraftDVI               "" ""      ""      "vector"')
+        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"  "text/html"'])
     #
     checkViewerEditor('Noteedit', ['noteedit'],
-        rc_entry = [r'\Format noteedit   not     Noteedit               "" "%%"        "%%"    "vector"'])
+        rc_entry = [r'\Format noteedit   not     Noteedit               "" "%%"        "%%"    "vector"        ""'])
     #
-    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('an OpenDocument/OpenOffice viewer', ['libreoffice', 'lwriter', 'lowriter', 'oowriter', 'swriter', 'abiword'],
+        rc_entry = [r'''\Format odt        odt     OpenDocument           "" "%%"      "%%"    "document,vector,menu=export"   "application/vnd.oasis.opendocument.text"
+\Format sxw        sxw    "OpenOffice.Org (sxw)"  "" ""        ""      "document,vector"       "application/vnd.sun.xml.writer"'''])
     #
-    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"'''])
+    checkViewerEditor('a Rich Text and Word viewer', ['libreoffice', 'lwriter', 'lowriter', 'oowriter', 'swriter', 'abiword'],
+        rc_entry = [r'''\Format rtf        rtf    "Rich Text Format"      "" "%%"      "%%"    "document,vector,menu=export"   "application/rtf"
+\Format word       doc    "MS Word"               W  "%%"      "%%"    "document,vector,menu=export"   "application/msword"'''])
     #
     # entries that do not need checkProg
-    addToRC(r'''\Format date       ""     "date command"          "" ""        ""      ""
-\Format csv        csv    "Table (CSV)"  "" "" ""      "document"
-\Format fax        ""      Fax                    "" ""        ""      "document"
-\Format lyx        lyx     LyX                    "" ""        ""      ""
-\Format lyx13x     13.lyx  "LyX 1.3.x"             "" ""       ""      "document"
-\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 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"
+    addToRC(r'''\Format date       ""     "date command"          "" ""        ""      ""      ""
+\Format csv        csv    "Table (CSV)"           "" ""        ""      "document"      "text/csv"
+\Format fax        ""      Fax                    "" ""        ""      "document"      ""
+\Format lyx        lyx     LyX                    "" ""        ""      ""      "application/x-lyx"
+\Format lyx13x     13.lyx "LyX 1.3.x"             "" ""        ""      "document"      ""
+\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"      ""
+\Format lyx20x     20.lyx "LyX 2.0.x"             "" ""        ""      "document"      ""
+\Format lyx21x     21.lyx "LyX 2.1.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 pdftex     pdftex_t PDFTEX                "" ""        ""      ""      ""
+\Format program    ""      Program                "" ""        ""      ""      ""
+\Format pstex      pstex_t PSTEX                  "" ""        ""      ""      ""
+\Format wmf        wmf    "Windows Metafile"      "" ""        ""      "vector"        "image/x-wmf"
+\Format emf        emf    "Enhanced Metafile"     "" ""        ""      "vector"        "image/x-emf"
+\Format wordhtml  "html, htm" "HTML (MS Word)"    "" "" ""     "document"      ""
 ''')
 
 
-def checkConverterEntries(java='', perl=''):
+def checkConverterEntries():
     ''' Check all converters (\converter entries) '''
     checkProg('the pdflatex program', ['pdflatex $$i'],
         rc_entry = [ r'\converter pdflatex   pdf2       "%%"   "latex=pdflatex"' ])
@@ -616,42 +719,57 @@ def checkConverterEntries(java='', perl=''):
     checkLuatex()
 
     # 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
+    #   1)  If we're building LyX with autotools then tex2lyx is found
+    #       in the subdirectory tex2lyx with respect to the binary dir.
+    #   2)  If we're building LyX with cmake then tex2lyx is found
+    #       in the binary dir.
+    #   3)  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)
+    #   4)  Otherwise always use tex2lyx.
+    in_binary_subdir = os.path.join(lyx_binary_dir, 'tex2lyx', 'tex2lyx')
+    in_binary_subdir = os.path.abspath(in_binary_subdir)
+
+    in_binary_dir = os.path.join(lyx_binary_dir, 'tex2lyx')
+    in_binary_dir = os.path.abspath(in_binary_dir)
 
-    path, t2l = checkProg('a LaTeX/Noweb -> LyX converter', [in_place, 'tex2lyx' + version_suffix, 'tex2lyx'],
+    path, t2l = checkProg('a LaTeX/Noweb -> LyX converter', [in_binary_subdir, in_binary_subdir + version_suffix, in_binary_dir, in_binary_dir + version_suffix, 'tex2lyx' + version_suffix, 'tex2lyx'],
         rc_entry = [r'''\converter latex      lyx        "%% -f $$i $$o"       ""
-\converter literate   lyx        "%% -n -f $$i $$o"    ""'''], not_found = 'tex2lyx')
+\converter latexclipboard lyx        "%% -fixedenc utf8 -f $$i $$o"    ""
+\converter literate   lyx        "%% -n -m noweb -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      "%%"       ""'''])
+\converter literate   pdflatex      "%%"       ""
+\converter literate   xetex         "%%"       ""
+\converter literate   luatex        "%%"       ""'''])
     #
     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   xetex      "%%"    ""
 \converter sweave   luatex     "%%"    ""'''])
+    #
+    checkProg('a knitr -> LaTeX converter', ['Rscript --verbose --no-save --no-restore $$s/scripts/lyxknitr.R $$p$$i $$p$$o $$e $$r'],
+        rc_entry = [r'''\converter knitr   latex      "%%"     ""
+\converter knitr   pdflatex   "%%"     ""
+\converter knitr   xetex      "%%"     ""
+\converter knitr   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      "%%"    ""' ])
     #
-    path, htmltolatex = checkProg('an HTML -> LaTeX converter', ['html2latex $$i',
-        'gnuhtml2latex $$i', 'htmltolatex -input $$i -output $$o', 'htmltolatex.jar'],
-        rc_entry = [ r'\converter html       latex      "%%"   ""',
-                     r'\converter html       latex      "%%"   ""',
-                     r'\converter html       latex      "%%"   ""', '', ''] )
-    if htmltolatex == 'htmltolatex.jar' and java != '':
-        addToRC(r'\converter html       latex      "%s -jar \"%s\" -input $$i -output $$o"     ""'
-            % (java, os.path.join(path, htmltolatex)))
+    checkProg('a knitr -> R/S code converter', ['Rscript --verbose --no-save --no-restore $$s/scripts/lyxknitr.R $$p$$i $$p$$o $$e $$r tangle'],
+        rc_entry = [ r'\converter knitr      r      "%%"    ""' ])
+    #
+    checkProg('an HTML -> LaTeX converter', ['html2latex $$i', 'gnuhtml2latex',
+        'htmltolatex -input $$i -output $$o', 'htmltolatex.jar -input $$i -output $$o'],
+        rc_entry = [ r'\converter html       latex      "%%"   ""', \
+                     r'\converter html       latex      "python -tt $$s/scripts/html2latexwrapper.py %% $$i $$o"       ""', \
+                     r'\converter html       latex      "%%"   ""', \
+                     r'\converter html       latex      "%%"   ""', '' ])
     #
     checkProg('an MS Word -> LaTeX converter', ['wvCleanLatex $$i $$o'],
         rc_entry = [ r'\converter word       latex      "%%"   ""' ])
@@ -690,7 +808,7 @@ def checkConverterEntries(java='', perl=''):
     # Check if LyXBlogger is installed
     lyxblogger_found = checkModule('lyxblogger')
     if lyxblogger_found:
-      addToRC(r'\Format    blog       blog       "LyXBlogger"           "" "" ""  "document"')
+      addToRC(r'\Format    blog       blog       "LyXBlogger"           "" "" ""  "document"  ""')
       addToRC(r'\converter xhtml      blog       "python -m lyxblogger $$i"       ""')
 
     #
@@ -699,6 +817,10 @@ def checkConverterEntries(java='', perl=''):
     #
     checkProg('an OpenDocument -> LaTeX converter', ['w2l -clean $$i'],
         rc_entry = [ r'\converter odt        latex      "%%"   ""' ])
+    # Only define a converter to pdf6, otherwise the odt format could be
+    # used as an intermediate step for export to pdf, which is not wanted.
+    checkProg('an OpenDocument -> PDF converter', ['unoconv -f pdf --stdout $$i > $$o'],
+        rc_entry = [ r'\converter odt        pdf6       "%%"   ""' ])
     # According to http://www.tug.org/applications/tex4ht/mn-commands.html
     # the command mk4ht oolatex $$i has to be used as default,
     # but as this would require to have Perl installed, in MiKTeX oolatex is
@@ -715,8 +837,8 @@ def checkConverterEntries(java='', perl=''):
     #
     checkProg('a RTF -> HTML converter', ['unrtf --html  $$i > $$o'],
         rc_entry = [ r'\converter rtf      html        "%%"    ""' ])
-    #
-    checkProg('a PS to PDF converter', ['ps2pdf13 $$i $$o'],
+    # Do not define a converter to pdf6, ps is a pure export format 
+    checkProg('a PS to PDF converter', ['ps2pdf $$i $$o'],
         rc_entry = [ r'\converter ps         pdf        "%%"   ""' ])
     #
     checkProg('a PS to TXT converter', ['pstotext $$i > $$o'],
@@ -724,15 +846,27 @@ def checkConverterEntries(java='', perl=''):
     #
     checkProg('a PS to TXT converter', ['ps2ascii $$i $$o'],
         rc_entry = [ r'\converter ps         text3      "%%"   ""' ])
-    #
-    checkProg('a PS to EPS converter', ['ps2eps $$i'],
-        rc_entry = [ r'\converter ps         eps      "%%"     ""' ])
+    # Need to call ps2eps in a pipe, otherwise it would name the output file
+    # depending on the extension of the input file. We do not know the input
+    # file extension in general, so the resultfile= flag would not help.
+    # Since ps2eps crops the image, we do not use it to convert from ps->eps.
+    # This would create additional paths in the converter graph with unwanted
+    # side effects (e.g. ps->pdf via ps2pdf would create a different result
+    # than ps->eps->pdf via ps2eps and epstopdf).
+    checkProg('a PS to EPS converter', ['ps2eps -- < $$i > $$o'],
+        rc_entry = [ r'\converter eps2       eps      "%%"     ""' ])
     #
     checkProg('a PDF to PS converter', ['pdf2ps $$i $$o', 'pdftops $$i $$o'],
         rc_entry = [ r'\converter pdf         ps        "%%"   ""' ])
-    #
+    # Only define a converter from pdf6 for graphics
     checkProg('a PDF to EPS converter', ['pdftops -eps -f 1 -l 1 $$i $$o'],
-        rc_entry = [ r'\converter pdf         eps        "%%"  ""' ])
+        rc_entry = [ r'\converter pdf6        eps        "%%"  ""' ])
+    #
+    checkProg('a PDF cropping tool', ['pdfcrop $$i $$o'],
+        rc_entry = [ r'\converter pdf2   pdf7       "%%"       ""' ])
+    #
+    checkProg('a Beamer info extractor', ['makebeamerinfo -p $$i'],
+        rc_entry = [ r'\converter pdf2         beamer.info        "%%" ""' ])
     #
     checkProg('a DVI to TXT converter', ['catdvi $$i > $$o'],
         rc_entry = [ r'\converter dvi        text4      "%%"   ""' ])
@@ -740,22 +874,12 @@ def checkConverterEntries(java='', perl=''):
     checkProg('a DVI to PS converter', ['dvips -o $$o $$i'],
         rc_entry = [ r'\converter dvi        ps         "%%"   ""' ])
     #
+    checkProg('a DVI to cropped EPS converter', ['dvips -E -o $$o $$i'],
+        rc_entry = [ r'\converter dvi        eps3         "%%" ""' ])
+    #
     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 --png" ""')
-    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 --ppm" ""')
-    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,50 +892,56 @@ def checkConverterEntries(java='', perl=''):
 \converter fig        pstex      "python -tt $$s/scripts/fig2pstex.py $$i $$o" ""''')
     #
     checkProg('a TIFF -> PS converter', ['tiff2ps $$i > $$o'],
-        rc_entry = [ r'\converter tiff       eps        "%%"   ""', ''])
+        rc_entry = [ r'\converter tiff       eps        "%%"   ""'])
     #
     checkProg('a TGIF -> EPS/PPM converter', ['tgif'],
         rc_entry = [
             r'''\converter tgif       eps        "tgif -print -color -eps -stdout $$i > $$o"   ""
 \converter tgif       png        "tgif -print -color -png -o $$d $$i"  ""
-\converter tgif       pdf        "tgif -print -color -pdf -stdout $$i > $$o"   ""''',
-            ''])
+\converter tgif       pdf6       "tgif -print -color -pdf -stdout $$i > $$o"   ""'''])
     #
     checkProg('a WMF -> EPS converter', ['metafile2eps $$i $$o', 'wmf2eps -o $$o $$i'],
         rc_entry = [ r'\converter wmf        eps        "%%"   ""'])
     #
     checkProg('an EMF -> EPS converter', ['metafile2eps $$i $$o', 'wmf2eps -o $$o $$i'],
         rc_entry = [ r'\converter emf        eps        "%%"   ""'])
-    #
+    # Only define a converter to pdf6 for graphics
     checkProg('an EPS -> PDF converter', ['epstopdf'],
-        rc_entry = [ r'\converter eps        pdf        "epstopdf --outfile=$$o $$i"   ""', ''])
+        rc_entry = [ r'\converter eps        pdf6       "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
+    # no agr -> pdf6 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
-    # convert from agr to pdf via eps without loss of quality.
+    # convert from agr to pdf6 via eps without loss of quality.
     checkProg('a Grace -> Image converter', ['gracebat'],
         rc_entry = [
             r'''\converter agr        eps        "gracebat -hardcopy -printfile $$o -hdevice EPS $$i 2>/dev/null"      ""
 \converter agr        png        "gracebat -hardcopy -printfile $$o -hdevice PNG $$i 2>/dev/null"      ""
 \converter agr        jpg        "gracebat -hardcopy -printfile $$o -hdevice JPEG $$i 2>/dev/null"     ""
-\converter agr        ppm        "gracebat -hardcopy -printfile $$o -hdevice PNM $$i 2>/dev/null"      ""''',
-            ''])
+\converter agr        ppm        "gracebat -hardcopy -printfile $$o -hdevice PNM $$i 2>/dev/null"      ""'''])
     #
     checkProg('a Dot -> Image converter', ['dot'],
         rc_entry = [
             r'''\converter dot        eps        "dot -Teps $$i -o $$o"        ""
-\converter dot        png        "dot -Tpng $$i -o $$o"        ""''',
-            ''])
+\converter dot        png        "dot -Tpng $$i -o $$o"        ""'''])
     #
     checkProg('a Dia -> PNG converter', ['dia -e $$o -t png $$i'],
         rc_entry = [ r'\converter dia        png        "%%"   ""'])
     #
     checkProg('a Dia -> EPS converter', ['dia -e $$o -t eps $$i'],
         rc_entry = [ r'\converter dia        eps        "%%"   ""'])
-    #
+    # Actually, this produces EPS, but with a wrong bounding box (usually A4 or letter).
+    # The eps2->eps converter then fixes the bounding box by cropping.
+    # Although unoconv can convert to png and pdf as well, do not define
+    # odg->png and odg->pdf converters, since the bb would be too large as well.
+    checkProg('an OpenOffice -> EPS converter', ['libreoffice -headless -nologo -convert-to eps $$i', 'unoconv -f eps --stdout $$i > $$o'],
+        rc_entry = [ r'\converter odg        eps2       "%%"   ""'])
+    # Only define a converter to pdf6 for graphics
     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        "%%"   ""'])
+        rc_entry = [ r'\converter svg        pdf6       "%%"   ""'])
     #
     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        "%%"   ""'])
@@ -824,8 +954,7 @@ def checkConverterEntries(java='', perl=''):
     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" ""''',
-''])
+\converter excel  latex "ssconvert --export-type=Gnumeric_html:latex $$i $$o" ""'''])
 
     path, lilypond = checkProg('a LilyPond -> EPS/PDF/PNG converter', ['lilypond'])
     if (lilypond != ''):
@@ -837,13 +966,13 @@ def checkConverterEntries(java='', perl=''):
             if int(version[0]) > 2 or (len(version) > 1 and int(version[0]) == 2 and int(version[1]) >= 11):
                 addToRC(r'''\converter lilypond   eps        "lilypond -dbackend=eps -dsafe --ps $$i"  ""
 \converter lilypond   png        "lilypond -dbackend=eps -dsafe --png $$i"     ""''')
-                addToRC(r'\converter lilypond   pdf        "lilypond -dbackend=eps -dsafe --pdf $$i"   ""')
+                addToRC(r'\converter lilypond   pdf6       "lilypond -dbackend=eps -dsafe --pdf $$i"   ""')
                 logger.info('+  found LilyPond version %s.' % version_number)
             elif int(version[0]) > 2 or (len(version) > 1 and int(version[0]) == 2 and int(version[1]) >= 6):
                 addToRC(r'''\converter lilypond   eps        "lilypond -b eps --ps --safe $$i" ""
 \converter lilypond   png        "lilypond -b eps --png $$i"   ""''')
                 if int(version[0]) > 2 or (len(version) > 1 and int(version[0]) == 2 and int(version[1]) >= 9):
-                    addToRC(r'\converter lilypond   pdf        "lilypond -b eps --pdf --safe $$i"      ""')
+                    addToRC(r'\converter lilypond   pdf6       "lilypond -b eps --pdf --safe $$i"      ""')
                 logger.info('+  found LilyPond version %s.' % version_number)
             else:
                 logger.info('+  found LilyPond, but version %s is too old.' % version_number)
@@ -876,17 +1005,17 @@ def checkConverterEntries(java='', perl=''):
             logger.info('+  found LilyPond-book, but could not extract version number.')
     #
     checkProg('a Noteedit -> LilyPond converter', ['noteedit --export-lilypond $$i'],
-        rc_entry = [ r'\converter noteedit   lilypond   "%%"   ""', ''])
+        rc_entry = [ r'\converter noteedit   lilypond   "%%"   ""' ])
     #
     # Currently, lyxpak outputs a gzip compressed tar archive on *nix
     # and a zip archive on Windows.
     # So, we configure the appropriate version according to the platform.
-    cmd = r'\converter lyx %s "python -tt $$s/scripts/lyxpak.py $$r/$$i" ""'
+    cmd = r'\converter lyx %s "python -tt $$s/scripts/lyxpak.py $$r/$$f" ""'
     if os.name == 'nt':
-        addToRC(r'\Format lyxzip     zip    "LyX Archive (zip)"     "" "" ""  "document,menu=export"')
+        addToRC(r'\Format lyxzip     zip    "LyX Archive (zip)"     "" "" ""  "document,menu=export"   ""')
         addToRC(cmd % "lyxzip")
     else:
-        addToRC(r'\Format lyxgz      gz     "LyX Archive (tar.gz)"  "" "" ""  "document,menu=export"')
+        addToRC(r'\Format lyxgz      gz     "LyX Archive (tar.gz)"  "" "" ""  "document,menu=export"   ""')
         addToRC(cmd % "lyxgz")
 
     #
@@ -904,12 +1033,15 @@ def checkConverterEntries(java='', perl=''):
 \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        lyx21x     "python -tt $$s/lyx2lyx/lyx2lyx -t 474 $$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"   ""
 ''')
 
 
@@ -918,7 +1050,8 @@ def checkDocBook():
     path, DOCBOOK = checkProg('SGML-tools 2.x (DocBook), db2x scripts or xsltproc', ['sgmltools', 'db2dvi', 'xsltproc'],
         rc_entry = [
             r'''\converter docbook    dvi        "sgmltools -b dvi $$i"        ""
-\converter docbook    html       "sgmltools -b html $$i"       ""''',
+\converter docbook    html       "sgmltools -b html $$i"       ""
+\converter docbook    ps         "sgmltools -b ps $$i" ""''',
             r'''\converter docbook    dvi        "db2dvi $$i"  ""
 \converter docbook    html       "db2html $$i" ""''',
             r'''\converter docbook    dvi        ""    ""
@@ -932,7 +1065,7 @@ def checkDocBook():
         return ('no', 'false', '')
 
 
-def checkOtherEntries(java='', perl=''):
+def checkOtherEntries():
     ''' entries other than Format and Converter '''
     checkProg('ChkTeX', ['chktex -n1 -n3 -n6 -n9 -n22 -n25 -n30 -n38'],
         rc_entry = [ r'\chktex_command "%%"' ])
@@ -946,12 +1079,8 @@ def checkOtherEntries(java='', perl=''):
         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',
-        'splitindex.class'], rc_entry = ['', r'\splitindex_command "%%"', '', ''])
-    if splitindex == 'splitindex.pl' and perl != '':
-        addToRC(r'\splitindex_command "%s -w \"%s\""' % (perl, os.path.join(path, splitindex)))
-    elif splitindex == 'splitindex.class' and java != '':
-        addToRC(r'\splitindex_command "%s \"%s\""' % (java, os.path.join(path, '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
@@ -976,17 +1105,29 @@ def checkOtherEntries(java='', perl=''):
 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)
+        Declare lines look like this:
 
+        \DeclareLaTeXClass[<requirements>]{<description>}
+        
+        Optionally, a \DeclareCategory line follows:
+        
+        \DeclareCategory{<category>}
+        
+        So for example (article.layout, scrbook.layout, svjog.layout)
+        
         \DeclareLaTeXClass{article}
+        \DeclareCategory{Articles}
+        
         \DeclareLaTeXClass[scrbook]{book (koma-script)}
+        \DeclareCategory{Books}
+        
         \DeclareLaTeXClass[svjour,svjog.clo]{article (Springer - svjour/jog)}
 
-        we expect output:
+        we'd expect this 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"
+        "article" "article" "article" "false" "article.cls" "Articles"
+        "scrbook" "scrbook" "book (koma-script)" "false" "scrbook.cls" "Books"
+        "svjog" "svjour" "article (Springer - svjour/jog)" "false" "svjour.cls,svjog.clo" ""
     '''
     def checkForClassExtension(x):
         '''if the extension for a latex class is not
@@ -998,8 +1139,12 @@ def processLayoutFile(file, bool_docbook):
     classname = file.split(os.sep)[-1].split('.')[0]
     # return ('LaTeX', '[a,b]', 'a', ',b,c', 'article') for \DeclareLaTeXClass[a,b,c]{article}
     p = re.compile(r'\Declare(LaTeX|DocBook)Class\s*(\[([^,]*)(,.*)*\])*\s*{(.*)}')
+    q = re.compile(r'\DeclareCategory{(.*)}')
+    classdeclaration = ""
+    categorydeclaration = '""'
     for line in open(file).readlines():
         res = p.search(line)
+        qres = q.search(line)
         if res != None:
             (classtype, optAll, opt, opt1, desc) = res.groups()
             avai = {'LaTeX':'false', 'DocBook':bool_docbook}[classtype]
@@ -1012,7 +1157,15 @@ def processLayoutFile(file, bool_docbook):
                 prereq_latex = ','.join(prereq_list)
             prereq_docbook = {'true':'', 'false':'docbook'}[bool_docbook]
             prereq = {'LaTeX':prereq_latex, 'DocBook':prereq_docbook}[classtype]
-            return '"%s" "%s" "%s" "%s" "%s"\n' % (classname, opt, desc, avai, prereq)
+            classdeclaration = '"%s" "%s" "%s" "%s" "%s"' % (classname, opt, desc, avai, prereq)
+            if categorydeclaration != '""':
+                return classdeclaration + " " + categorydeclaration
+        if qres != None:
+             categorydeclaration = '"%s"' % (qres.groups()[0])
+             if classdeclaration != "":
+                 return classdeclaration + " " + categorydeclaration
+    if classdeclaration != "":
+        return classdeclaration + " " + categorydeclaration
     logger.warning("Layout file " + file + " has no \DeclareXXClass line. ")
     return ""
 
@@ -1061,6 +1214,12 @@ def checkLatexConfig(check_config, bool_docbook):
                     tx.write(retval)
         tx.close()
         logger.info('\tdone')
+    if not os.path.isfile('packages.lst') or not check_config:
+        logger.info('+generating default list of packages... ')
+        removeFiles(['packages.lst'])
+        tx = open('packages.lst', 'w')
+        tx.close()
+        logger.info('\tdone')
     if not check_config:
         return None
     # the following will generate textclass.lst.tmp, and packages.lst.tmp
@@ -1076,6 +1235,7 @@ def checkLatexConfig(check_config, bool_docbook):
     # build the list of available layout files and convert it to commands
     # for chkconfig.ltx
     declare = re.compile(r'\Declare(LaTeX|DocBook)Class\s*(\[([^,]*)(,.*)*\])*\s*{(.*)}')
+    category = re.compile(r'\DeclareCategory{(.*)}')
     empty = re.compile(r'^\s*$')
     testclasses = list()
     for file in glob.glob( os.path.join('layouts', '*.layout') ) + \
@@ -1084,14 +1244,23 @@ def checkLatexConfig(check_config, bool_docbook):
         if not os.path.isfile(file):
             continue
         classname = file.split(os.sep)[-1].split('.')[0]
+        decline = ""
+        catline = ""
         for line in open(file).readlines():
             if not empty.match(line) and line[0] != '#':
-                logger.warning("Failed to find valid \Declare line for layout file `" + file + "'.\n\t=> Skipping this file!")
-                nodeclaration = True
+                if decline == "":
+                    logger.warning("Failed to find valid \Declare line for layout file `" + file + "'.\n\t=> Skipping this file!")
+                    nodeclaration = True
+                # A class, but no category declaration. Just break.
                 break
-            if declare.search(line) == None:
+            if declare.search(line) != None:
+                decline = "\\TestDocClass{%s}{%s}" % (classname, line[1:].strip())
+                testclasses.append(decline)
+            elif category.search(line) != None:
+                catline = "\\DeclareCategory{%s}{%s}" % (classname, category.search(line).groups()[0])
+                testclasses.append(catline)
+            if catline == "" or decline == "":
                 continue
-            testclasses.append("\\TestDocClass{%s}{%s}" % (classname, line[1:].strip()))
             break
         if nodeclaration:
             continue
@@ -1102,20 +1271,21 @@ def checkLatexConfig(check_config, bool_docbook):
     cl.close()
     #
     # we have chklayouts.tex, then process it
-    ret = 1
-    latex_out = cmdOutput(LATEX + ' wrap_chkconfig.ltx')
-    for line in latex_out.splitlines():
+    latex_out = cmdOutput(LATEX + ' wrap_chkconfig.ltx', True)
+    while True:
+        line = latex_out.readline()
+        if not line:
+            break;
         if re.match('^\+', line):
             logger.info(line.strip())
-            # return None if the command succeeds
-            if line == "+Inspection done.":
-                ret = None
+    # if the command succeeds, None will be returned
+    ret = latex_out.close()
     #
     # remove the copied file
     if rmcopy:
         removeFiles( [ 'chkconfig.ltx' ] )
     #
-    # currently, values in chhkconfig are only used to set
+    # currently, values in chkconfig are only used to set
     # \font_encoding
     values = {}
     for line in open('chkconfig.vars').readlines():
@@ -1286,6 +1456,17 @@ def checkTeXAllowSpaces():
         removeFiles( [ 'a b.tex', 'a b.log', 'texput.log' ])
 
 
+def rescanTeXFiles():
+    ''' Run kpsewhich to update information about TeX files '''
+    logger.info("+Indexing TeX files... ")
+    if not os.path.isfile( os.path.join(srcdir, 'scripts', 'TeXFiles.py') ):
+        logger.error("configure: error: cannot find TeXFiles.py script")
+        sys.exit(1)
+    tfp = cmdOutput("python -tt " + os.path.join(srcdir, 'scripts', 'TeXFiles.py'))
+    logger.info(tfp)
+    logger.info("\tdone")
+
+
 def removeTempFiles():
     # Final clean-up
     if not lyx_keep_temps:
@@ -1296,11 +1477,13 @@ def removeTempFiles():
 
 if __name__ == '__main__':
     lyx_check_config = True
+    lyx_kpsewhich = True
     outfile = 'lyxrc.defaults'
-    lyxrc_fileformat = 1
+    lyxrc_fileformat = 17
     rc_entries = ''
     lyx_keep_temps = False
     version_suffix = ''
+    lyx_binary_dir = ''
     ## Parse the command line
     for op in sys.argv[1:]:   # default shell/for list is $*, the options
         if op in [ '-help', '--help', '-h' ]:
@@ -1308,16 +1491,22 @@ if __name__ == '__main__':
 Options:
     --help                   show this help lines
     --keep-temps             keep temporary files (for debug. purposes)
+    --without-kpsewhich      do not update TeX files information via kpsewhich
     --without-latex-config   do not run LaTeX to determine configuration
     --with-version-suffix=suffix suffix of binary installed files
+    --binary-dir=directory   directory of binary installed files
 '''
             sys.exit(0)
+        elif op == '--without-kpsewhich':
+            lyx_kpsewhich = False
         elif op == '--without-latex-config':
             lyx_check_config = False
         elif op == '--keep-temps':
             lyx_keep_temps = True
         elif op[0:22] == '--with-version-suffix=':  # never mind if op is not long enough
             version_suffix = op[22:]
+        elif op[0:13] == '--binary-dir=':
+            lyx_binary_dir = op[13:]
         else:
             print "Unknown option", op
             sys.exit(1)
@@ -1330,6 +1519,8 @@ Options:
         logger.error("configure: error: cannot find chkconfig.ltx script")
         sys.exit(1)
     setEnviron()
+    if sys.platform == 'darwin' and len(version_suffix) > 0:
+        checkUpgrade()
     createDirectories()
     dtl_tools = checkDTLtools()
     ## Write the first part of outfile
@@ -1345,16 +1536,19 @@ Format %i
 ''' % lyxrc_fileformat)
     # check latex
     LATEX = checkLatex(dtl_tools)
-    checkFormatEntries(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]
-    checkConverterEntries(java, perl)
+    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(java, perl)
+    checkOtherEntries()
+    if lyx_kpsewhich:
+        rescanTeXFiles()
     checkModulesConfig()
     # --without-latex-config can disable lyx_check_config
     ret = checkLatexConfig(lyx_check_config and LATEX != '', bool_docbook)