]> git.lyx.org Git - lyx.git/blobdiff - lib/configure.py
linguistics.lyx: document how to insert footnotes in glosses.
[lyx.git] / lib / configure.py
index 00b2fa71104f65589d723481e11c20bc1a317bea..0b06cdecc2f81cebc19ae6664cd0e13990430dfa 100644 (file)
@@ -8,7 +8,7 @@
 # \author Bo Peng
 # Full author contact details are available in file CREDITS.
 
 # \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,
 
 # set up logging
 logging.basicConfig(level = logging.DEBUG,
@@ -104,6 +104,73 @@ def setEnviron():
     os.environ['LC_CTYPE'] = os.getenv('LC_CTYPE', 'C')
 
 
     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', \
 def createDirectories():
     ''' Create the build directories if necessary '''
     for dir in ['bind', 'clipart', 'doc', 'examples', 'images', 'kbd', \
@@ -198,6 +265,8 @@ def checkProg(description, progs, rc_entry = [], path = [], not_found = ''):
         if "PATHEXT" in os.environ:
             extlist = extlist + os.environ["PATHEXT"].split(os.pathsep)
         for ac_dir in path:
         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')
             for ext in extlist:
                 if os.path.isfile( os.path.join(ac_dir, ac_word + ext) ):
                     logger.info(msg + ' yes')
@@ -252,6 +321,8 @@ 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:
             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')
             for ext in extlist:
                 if os.path.isfile( os.path.join(ac_dir, ac_word + ext) ):
                     logger.info(msg + ' yes')
@@ -408,8 +479,7 @@ def checkLatex(dtl_tools):
         # run platex on chklatex.ltx and check result
         if cmdOutput(PLATEX + ' chklatex.ltx').find('pLaTeX2e') != -1:
             # We have the Japanese pLaTeX2e
         # 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 -kanji=$$E $$i"     "latex=platex"' % PLATEX)
-            addToRC(r'\converter platex     dvi4       "%s $$i"                 "latex=platex"' % PLATEX)
+            addToRC(r'\converter platex   dvi       "%s"   "latex=platex"' % PLATEX)
         else:
             PLATEX = ''
             removeFiles(['chklatex.ltx', 'chklatex.log'])
         else:
             PLATEX = ''
             removeFiles(['chklatex.ltx', 'chklatex.log'])
@@ -512,7 +582,7 @@ def checkFormatEntries(dtl_tools):
         rc_entry = [r'\Format fen        fen     FEN                    "" "%%"        "%%"    ""      ""'])
     #
     checkViewerEditor('a SVG viewer and editor', ['inkscape'],
         rc_entry = [r'\Format fen        fen     FEN                    "" "%%"        "%%"    ""      ""'])
     #
     checkViewerEditor('a SVG viewer and editor', ['inkscape'],
-        rc_entry = [r'\Format svg        svg     SVG                    "" "%%" "%%"   "vector"        "image/svg+xml"'])
+        rc_entry = [r'\Format svg        "svg, svgz" SVG                "" "%%" "%%"   "vector,zipped=native"  "image/svg+xml"'])
     #
     imageformats = r'''\Format bmp        bmp     BMP                    "" "%s"       "%s"    ""      "image/x-bmp"
 \Format gif        gif     GIF                    "" "%s"      "%s"    ""      "image/gif"
     #
     imageformats = r'''\Format bmp        bmp     BMP                    "" "%s"       "%s"    ""      "image/x-bmp"
 \Format gif        gif     GIF                    "" "%s"      "%s"    ""      "image/gif"
@@ -550,6 +620,7 @@ def checkFormatEntries(dtl_tools):
 \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 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 text       txt    "Plain text"            a  ""        "%%"    "document,menu=export"  "text/plain"
 \Format text2      txt    "Plain text (pstotext)" "" ""        "%%"    "document"      ""
 \Format text3      txt    "Plain text (ps2ascii)" "" ""        "%%"    "document"      ""
@@ -575,23 +646,27 @@ def checkFormatEntries(dtl_tools):
     #
     #checkProg('a Postscript interpreter', ['gs'],
     #  rc_entry = [ r'\ps_command "%%"' ])
     #
     #checkProg('a Postscript interpreter', ['gs'],
     #  rc_entry = [ r'\ps_command "%%"' ])
-    checkViewer('a Postscript previewer', ['kghostview', 'okular', 'evince', 'gv', 'ghostview -swap'],
+    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"        ""
         rc_entry = [r'''\Format eps        eps     EPS                    "" "%%"      ""      "vector"        "image/x-eps"
 \Format eps2       eps    "EPS (uncropped)"       "" "%%"      ""      "vector"        ""
+\Format eps3       eps    "EPS (cropped)"         "" "%%"      ""      "document"      ""
 \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
 \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', ['pdfview', 'kpdf', 'okular', 'evince', 'kghostview', 'xpdf', 'acrobat', 'acroread', \
-                   'gv', 'ghostview'],
-        rc_entry = [r'''\Format pdf        pdf    "PDF (ps2pdf)"          P  "%%"      ""      "document,vector,menu=export"   "application/pdf"
+    # 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 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 pdf5       pdf    "PDF (LuaTeX)"          u  "%%"      ""      "document,vector,menu=export"   ""
+\Format pdf6       pdf    "PDF (graphics)"        "" "%%"      ""      "vector"        "application/pdf"
+\Format pdf7       pdf    "PDF (cropped)"         "" "%%"      ""      "document,vector"       ""
+\Format pdf8       pdf    "PDF (lower resolution)"         "" "%%"     ""      "document,vector"       ""'''])
     #
     checkViewer('a DVI previewer', ['xdvi', 'kdvi', 'okular', 'yap', 'dviout -Set=!m'],
         rc_entry = [r'''\Format dvi        dvi     DVI                    D  "%%"      ""      "document,vector,menu=export"   "application/x-dvi"
     #
     checkViewer('a DVI previewer', ['xdvi', 'kdvi', 'okular', 'yap', 'dviout -Set=!m'],
         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"   ""
-\Format dvi4       dvi     "DVI (pLaTeX)"          V  "%%"     ""      "document,vector,menu=export"   ""'''])
+\Format dvi3       dvi     "DVI (LuaTeX)"          V  "%%"     ""      "document,vector,menu=export"   ""'''])
     if dtl_tools:
         # Windows only: DraftDVI
         addToRC(r'\Format dvi2       dvi     DraftDVI               "" ""      ""      "vector"        ""')
     if dtl_tools:
         # Windows only: DraftDVI
         addToRC(r'\Format dvi2       dvi     DraftDVI               "" ""      ""      "vector"        ""')
@@ -618,8 +693,9 @@ def checkFormatEntries(dtl_tools):
 \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 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 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 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"      ""
@@ -644,17 +720,25 @@ def checkConverterEntries():
     checkLuatex()
 
     # Look for tex2lyx in this order (see bugs #3308 and #6986):
     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.
     #       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).replace('\\', '/')
+
+    in_binary_dir = os.path.join(lyx_binary_dir, 'tex2lyx')
+    in_binary_dir = os.path.abspath(in_binary_dir).replace('\\', '/')
 
 
-    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"       ""
         rc_entry = [r'''\converter latex      lyx        "%% -f $$i $$o"       ""
-\converter literate   lyx        "%% -n -m noweb -f $$i $$o"   ""'''], not_found = 'tex2lyx')
+\converter latexclipboard lyx        "%% -fixedenc utf8 -f $$i $$o"    ""
+\converter literate   lyx        "%% -n -m noweb -f $$i $$o"   ""
+\converter sweave   lyx        "%% -n -m sweave -f $$i $$o"    ""
+\converter knitr   lyx        "%% -n -m knitr -f $$i $$o"      ""'''], not_found = 'tex2lyx')
     if path == '':
         logger.warning("Failed to find tex2lyx on your system.")
 
     if path == '':
         logger.warning("Failed to find tex2lyx on your system.")
 
@@ -662,6 +746,7 @@ def checkConverterEntries():
     checkProg('a Noweb -> LaTeX converter', ['noweave -delay -index $$i > $$o'],
         rc_entry = [r'''\converter literate   latex      "%%"  ""
 \converter literate   pdflatex      "%%"       ""
     checkProg('a Noweb -> LaTeX converter', ['noweave -delay -index $$i > $$o'],
         rc_entry = [r'''\converter literate   latex      "%%"  ""
 \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'],
 \converter literate   luatex        "%%"       ""'''])
     #
     checkProg('a Sweave -> LaTeX converter', ['Rscript --verbose --no-save --no-restore $$s/scripts/lyxsweave.R $$p$$i $$p$$o $$e $$r'],
@@ -679,12 +764,15 @@ def checkConverterEntries():
     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('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('a knitr -> R/S code converter', ['Rscript --verbose --no-save --no-restore $$s/scripts/lyxknitr.R $$p$$i $$p$$o $$e $$r tangle'], 
+    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      "%%"    ""' ])
     #
         rc_entry = [ r'\converter knitr      r      "%%"    ""' ])
     #
-    checkProg('an HTML -> LaTeX converter', ['html2latex $$i', 'gnuhtml2latex $$i',
+    checkProg('an HTML -> LaTeX converter', ['html2latex $$i', 'gnuhtml2latex',
         'htmltolatex -input $$i -output $$o', 'htmltolatex.jar -input $$i -output $$o'],
         'htmltolatex -input $$i -output $$o', 'htmltolatex.jar -input $$i -output $$o'],
-        rc_entry = [ r'\converter html       latex      "%%"   ""' ])
+        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      "%%"   ""' ])
     #
     checkProg('an MS Word -> LaTeX converter', ['wvCleanLatex $$i $$o'],
         rc_entry = [ r'\converter word       latex      "%%"   ""' ])
@@ -732,9 +820,10 @@ def checkConverterEntries():
     #
     checkProg('an OpenDocument -> LaTeX converter', ['w2l -clean $$i'],
         rc_entry = [ r'\converter odt        latex      "%%"   ""' ])
     #
     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'],
     checkProg('an OpenDocument -> PDF converter', ['unoconv -f pdf --stdout $$i > $$o'],
-        rc_entry = [ r'\converter odt        pdf        "%%"   ""' ])
+        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
     # 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
@@ -751,8 +840,8 @@ def checkConverterEntries():
     #
     checkProg('a RTF -> HTML converter', ['unrtf --html  $$i > $$o'],
         rc_entry = [ r'\converter rtf      html        "%%"    ""' ])
     #
     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'],
         rc_entry = [ r'\converter ps         pdf        "%%"   ""' ])
     #
     checkProg('a PS to TXT converter', ['pstotext $$i > $$o'],
@@ -772,9 +861,21 @@ def checkConverterEntries():
     #
     checkProg('a PDF to PS converter', ['pdf2ps $$i $$o', 'pdftops $$i $$o'],
         rc_entry = [ r'\converter pdf         ps        "%%"   ""' ])
     #
     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'],
     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        "%%"  ""' ])
+    # Create one converter for a PDF produced using TeX fonts and one for a
+    # PDF produced using non-TeX fonts. This does not produce non-unique
+    # conversion paths, since a given document either uses TeX fonts or not.
+    checkProg('a PDF cropping tool', ['pdfcrop $$i $$o'],
+        rc_entry = [ r'''\converter pdf2   pdf7       "%%"     ""
+\converter pdf4   pdf7       "%%"      ""''' ])
+    # Create one converter for a PDF produced using TeX fonts and one for a
+    # PDF produced using non-TeX fonts. This does not produce non-unique
+    # conversion paths, since a given document either uses TeX fonts or not.
+    checkProg('Ghostscript', ["gswin32c", "gswin64c", "gs"],
+        rc_entry = [ r'''\converter pdf2   pdf8       "python -tt $$s/scripts/convert_pdf.py $$i $$o ebook"    ""
+\converter pdf4   pdf8       "python -tt $$s/scripts/convert_pdf.py $$i $$o ebook"     ""''' ])
     #
     checkProg('a Beamer info extractor', ['makebeamerinfo -p $$i'],
         rc_entry = [ r'\converter pdf2         beamer.info        "%%" ""' ])
     #
     checkProg('a Beamer info extractor', ['makebeamerinfo -p $$i'],
         rc_entry = [ r'\converter pdf2         beamer.info        "%%" ""' ])
@@ -785,6 +886,9 @@ def checkConverterEntries():
     checkProg('a DVI to PS converter', ['dvips -o $$o $$i'],
         rc_entry = [ r'\converter dvi        ps         "%%"   ""' ])
     #
     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       "%%"   ""' ])
     #
     checkProg('a DVI to PDF converter', ['dvipdfmx -o $$o $$i', 'dvipdfm -o $$o $$i'],
         rc_entry = [ r'\converter dvi        pdf3       "%%"   ""' ])
     #
@@ -800,44 +904,41 @@ def checkConverterEntries():
 \converter fig        pstex      "python -tt $$s/scripts/fig2pstex.py $$i $$o" ""''')
     #
     checkProg('a TIFF -> PS converter', ['tiff2ps $$i > $$o'],
 \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"  ""
     #
     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        "%%"   ""'])
     #
     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'],
     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'],
     #
     checkProg('an EPS -> PNG converter', ['convert $$i $$o'],
-        rc_entry = [ r'\converter eps        png        "%%"   ""', ''])
+        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
     # 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"     ""
     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"        ""
     #
     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 -> PNG converter', ['dia -e $$o -t png $$i'],
         rc_entry = [ r'\converter dia        png        "%%"   ""'])
@@ -850,9 +951,9 @@ def checkConverterEntries():
     # 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       "%%"   ""'])
     # 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'],
     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        "%%"   ""'])
     #
     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        "%%"   ""'])
@@ -865,8 +966,7 @@ def checkConverterEntries():
     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" ""
     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 != ''):
 
     path, lilypond = checkProg('a LilyPond -> EPS/PDF/PNG converter', ['lilypond'])
     if (lilypond != ''):
@@ -878,13 +978,13 @@ def checkConverterEntries():
             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"     ""''')
             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):
                 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)
                 logger.info('+  found LilyPond version %s.' % version_number)
             else:
                 logger.info('+  found LilyPond, but version %s is too old.' % version_number)
@@ -917,7 +1017,7 @@ def checkConverterEntries():
             logger.info('+  found LilyPond-book, but could not extract version number.')
     #
     checkProg('a Noteedit -> LilyPond converter', ['noteedit --export-lilypond $$i'],
             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.
     #
     # Currently, lyxpak outputs a gzip compressed tar archive on *nix
     # and a zip archive on Windows.
@@ -945,6 +1045,7 @@ def checkConverterEntries():
 \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        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 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"   ""
@@ -961,7 +1062,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"        ""
     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        ""    ""
             r'''\converter docbook    dvi        "db2dvi $$i"  ""
 \converter docbook    html       "db2html $$i" ""''',
             r'''\converter docbook    dvi        ""    ""
@@ -1372,7 +1474,7 @@ def rescanTeXFiles():
     if not os.path.isfile( os.path.join(srcdir, 'scripts', 'TeXFiles.py') ):
         logger.error("configure: error: cannot find TeXFiles.py script")
         sys.exit(1)
     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'))
+    tfp = cmdOutput("python -tt " + '"' + os.path.join(srcdir, 'scripts', 'TeXFiles.py') + '"')
     logger.info(tfp)
     logger.info("\tdone")
 
     logger.info(tfp)
     logger.info("\tdone")
 
@@ -1389,10 +1491,11 @@ if __name__ == '__main__':
     lyx_check_config = True
     lyx_kpsewhich = True
     outfile = 'lyxrc.defaults'
     lyx_check_config = True
     lyx_kpsewhich = True
     outfile = 'lyxrc.defaults'
-    lyxrc_fileformat = 7
+    lyxrc_fileformat = 17
     rc_entries = ''
     lyx_keep_temps = False
     version_suffix = ''
     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' ]:
     ## Parse the command line
     for op in sys.argv[1:]:   # default shell/for list is $*, the options
         if op in [ '-help', '--help', '-h' ]:
@@ -1403,6 +1506,7 @@ Options:
     --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
     --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':
 '''
             sys.exit(0)
         elif op == '--without-kpsewhich':
@@ -1413,6 +1517,8 @@ Options:
             lyx_keep_temps = True
         elif op[0:22] == '--with-version-suffix=':  # never mind if op is not long enough
             version_suffix = op[22:]
             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)
         else:
             print "Unknown option", op
             sys.exit(1)
@@ -1425,6 +1531,8 @@ Options:
         logger.error("configure: error: cannot find chkconfig.ltx script")
         sys.exit(1)
     setEnviron()
         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
     createDirectories()
     dtl_tools = checkDTLtools()
     ## Write the first part of outfile