]> git.lyx.org Git - lyx.git/blobdiff - lib/configure.py
Move DrawStrategy enum to update_flags.h.
[lyx.git] / lib / configure.py
index 92cf561b80c520d51ed249178109e5e7e0a17502..c18ccf405f396d1a4bafebc81ed0ff6c734a89ec 100644 (file)
@@ -1,5 +1,4 @@
 #! /usr/bin/python3
-# -*- coding: utf-8 -*-
 #
 # file configure.py
 # This file is part of LyX, the document processor.
@@ -8,14 +7,8 @@
 # \author Bo Peng
 # Full author contact details are available in file CREDITS.
 
-from __future__ import print_function
 import glob, logging, os, errno, re, shutil, subprocess, sys, stat
 
-if sys.version_info[0] < 3:
-    import codecs
-    open = codecs.open
-
-
 # set up logging
 logging.basicConfig(level = logging.DEBUG,
     format = '%(levelname)s: %(message)s', # ignore application name
@@ -83,10 +76,7 @@ def cmdOutput(cmd, asynchronous = False):
     '''
     if os.name == 'nt':
         b = False
-        if sys.version_info[0] < 3:
-            cmd = 'cmd /d /c pushd ' + shortPath(os.getcwdu()) + '&' + cmd
-        else:
-            cmd = 'cmd /d /c pushd ' + shortPath(os.getcwd()) + '&' + cmd
+        cmd = 'cmd /d /c pushd ' + shortPath(os.getcwd()) + '&' + cmd
     else:
         b = True
     pipe = subprocess.Popen(cmd, shell=b, close_fds=b, stdin=subprocess.PIPE,
@@ -143,7 +133,7 @@ def copy_tree(src, dst, preserve_symlinks=False, level=0):
         names = os.listdir(src)
     except os.error as oserror:
         (errno, errstr) = oserror.args
-        raise FileError("error listing files in '%s': %s" % (src, errstr))
+        raise FileError(f"error listing files in '{src}': {errstr}")
 
     if not os.path.isdir(dst):
         os.makedirs(dst)
@@ -157,8 +147,8 @@ def copy_tree(src, dst, preserve_symlinks=False, level=0):
             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 level == 0 and name in [ 'cache', 'configure.log', 'chkconfig.ltx' ]:
+            logger.info("Skip copy of %s", src_name)
         elif os.path.isdir(src_name):
             outputs.extend(
                 copy_tree(src_name, dst_name, preserve_symlinks, level=(level + 1)))
@@ -180,7 +170,7 @@ def checkUpgrade():
         logger.info('Checking for upgrade from previous version.')
         parent = os.path.dirname(cwd)
         appname = basename[:(-len(version_suffix))]
-        for version in ['-2.3', '-2.2', '-2.1', '-2.0', '-1.6' ]:
+        for version in ['-2.4', '-2.3', '-2.2', '-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)
@@ -214,10 +204,7 @@ def checkTeXPaths():
         fd, tmpfname = mkstemp(suffix='.ltx')
         if os.name == 'nt':
             encoding = sys.getfilesystemencoding()
-            if sys.version_info[0] < 3:
-                inpname = shortPath(unicode(tmpfname, encoding)).replace('\\', '/')
-            else:
-                inpname = shortPath(tmpfname).replace('\\', '/')
+            inpname = shortPath(tmpfname).replace('\\', '/')
         else:
             inpname = cmdOutput('cygpath -m ' + tmpfname)
         logname = os.path.basename(re.sub("(?i).ltx", ".log", inpname))
@@ -329,10 +316,7 @@ def check_java():
     """ Check for Java, don't give up as often as checkProg, using platform-dependent techniques """
     if os.name == 'nt':
         # Check in the registry.
-        try:  # Python 3.
-            import winreg
-        except ImportError:  # Python 2.
-            import _winreg as winreg
+        import winreg
 
         potential_keys_64b = ["SOFTWARE\\JavaSoft\\Java Runtime Environment", "SOFTWARE\\JavaSoft\\Java Development Kit",
                               "SOFTWARE\\JavaSoft\\JDK", "SOFTWARE\\JavaSoft\\JRE"]
@@ -608,10 +592,7 @@ def checkInkscape():
             return 'inkscape-binary'
     elif os.name != 'nt':
         return 'inkscape'
-    if sys.version_info[0] < 3:
-        import _winreg as winreg
-    else:
-        import winreg
+    import winreg
     aReg = winreg.ConnectRegistry(None, winreg.HKEY_CLASSES_ROOT)
     try:
         aKey = winreg.OpenKey(aReg, r"inkscape.svg\DefaultIcon")
@@ -623,17 +604,17 @@ def checkInkscape():
             return valentry.split(',')[0]
         else:
             return 'inkscape'
-    except EnvironmentError:
+    except OSError:
         try:
             aKey = winreg.OpenKey(aReg, r"inkscape.SVG\shell\open\command")
             val = winreg.QueryValueEx(aKey, "")
             return str(val[0]).split('"')[1]
-        except EnvironmentError:
+        except OSError:
             try:
                 aKey = winreg.OpenKey(aReg, r"Applications\inkscape.exe\shell\open\command")
                 val = winreg.QueryValueEx(aKey, "")
                 return str(val[0]).split('"')[1]
-            except EnvironmentError:
+            except OSError:
                 return 'inkscape'
 
 
@@ -877,7 +858,8 @@ def checkFormatEntries(dtl_tools):
 \Format lyx20x     20.lyx "LyX 2.0.x"             "" ""        ""      "document"      ""
 \Format lyx21x     21.lyx "LyX 2.1.x"             "" ""        ""      "document"      ""
 \Format lyx22x     22.lyx "LyX 2.2.x"             "" ""        ""      "document"      ""
-\Format lyx23x     23.lyx "LyX 2.3.x"             "" ""        ""      "document,menu=export"  ""
+\Format lyx23x     23.lyx "LyX 2.3.x"             "" ""        ""      "document"      ""
+\Format lyx24x     24.lyx "LyX 2.4.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"      ""
@@ -1064,7 +1046,7 @@ def checkConverterEntries():
     checkProg('a RTF -> HTML converter', ['unrtf --html  $$i > $$o'],
         rc_entry = [ r'\converter rtf      html        "%%"    ""' ])
     # Do not define a converter to pdf6, ps is a pure export format
-    checkProg('a PS to PDF converter', ['ps2pdf $$i $$o'],
+    checkProg('a PS to PDF converter', ['ps2pdf -dALLOWPSTRANSPARENCY $$i $$o'],
         rc_entry = [ r'\converter ps         pdf        "%%"   "hyperref-driver=dvips"' ])
     #
     checkProg('a PS to TXT converter', ['pstotext $$i > $$o'],
@@ -1087,14 +1069,6 @@ def checkConverterEntries():
     # 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 pdf6        eps        "%%"  ""' ])
-    # Define a converter from pdf6 to png for Macs where pdftops is missing.
-    # The converter utility sips allows to force the dimensions of the resulting
-    # png image. The value of 800 pixel for the width is arbitrary and not
-    # related to the current screen resolution or width.
-    # There is no converter parameter for this information.
-    checkProg('a PDF to PNG converter',
-        ['sips --resampleWidth 800 --setProperty format png $$i --out $$o'],
-        rc_entry = [ r'\converter pdf6        png        "%%" ""' ])
     # 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.
@@ -1190,8 +1164,41 @@ def checkConverterEntries():
     checkProg('an EPS -> PDF converter', ['epstopdf'],
         rc_entry = [ r'\converter eps        pdf6       "epstopdf --outfile=$$o $$i"   ""'])
     #
-    checkProg('an EPS -> PNG converter', ['magick $$i[0] $$o', 'convert $$i[0] $$o'],
-        rc_entry = [ r'\converter eps        png        "%%"   ""'])
+    #prepare for pdf -> png, 2nd part depends on IM ban below
+    pdftopng = ['sips --resampleWidth 800 --setProperty format png $$i --out $$o' ]
+    #
+    # Due to more restrictive policies, it is possible that (image)magick
+    # does not allow conversions from eps to png.
+    # So before setting the converter test it it on a mock file
+    _, cmd = checkProg('an EPS -> PNG converter', ['magick', 'convert'])
+    if cmd:
+        writeToFile('mock.eps', r'%!PS')
+        try:
+            subprocess.check_call([cmd, "mock.eps", "mock.png"])
+            removeFiles(['mock.eps', 'mock.png'])
+            rc_entry = r'\converter eps        png        "%s $$i[0] $$o"      ""'
+            addToRC(rc_entry % cmd)
+        except:
+            removeFiles(['mock.eps'])
+            #needs empty record otherwise default converter will be issued
+            addToRC(r'''\converter eps        png        ""    ""
+\converter png        eps        ""    ""
+\converter jpg        tiff        "convert $$i $$o"    ""
+\converter png        tiff        "convert $$i $$o"    ""''')
+            logger.info('ImageMagick seems to ban conversions from EPS. Disabling direct EPS->PNG.')
+            pdftopng.append('pdftoppm -r 72 -png -singlefile $$i >  $$o')
+    #
+    # PDF -> PNG: sips (mac), IM convert (windows, linux), pdftoppm (linux with IM ban)
+    # sips:Define a converter from pdf6 to png for Macs where pdftops is missing.
+    # The converter utility sips allows to force the dimensions of the resulting
+    # png image. The value of 800 pixel for the width is arbitrary and not
+    # related to the current screen resolution or width.
+    # There is no converter parameter for this information.
+    #
+    #pdftoppm: Some systems ban IM eps->png conversion. We will offer eps->pdf->png route instead.
+    checkProg('a PDF to PNG converter', pdftopng,
+        rc_entry = [ r'\converter pdf6        png        "%%" ""' ])
+
     #
     # no agr -> pdf6 converter, since the pdf library used by gracebat is not
     # free software and therefore not compiled in in many installations.
@@ -1290,15 +1297,15 @@ def checkConverterEntries():
             version_number = match.groups()[0]
             version = version_number.split('.')
             if int(version[0]) > 2 or (len(version) > 1 and int(version[0]) == 2 and int(version[1]) >= 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   pdf6       "lilypond -dbackend=eps -dsafe --pdf $$i"   ""')
+                addToRC(r'''\converter lilypond   eps        "lilypond -dbackend=eps --ps $$i" "needauth"
+\converter lilypond   png        "lilypond -dbackend=eps --png $$i"    "needauth"''')
+                addToRC(r'\converter lilypond   pdf6       "lilypond -dbackend=eps --pdf $$i"  "needauth"')
                 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" ""
+                addToRC(r'''\converter lilypond   eps        "lilypond -b eps --ps $$i"        "needauth"
 \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   pdf6       "lilypond -b eps --pdf --safe $$i"      ""')
+                    addToRC(r'\converter lilypond   pdf6       "lilypond -b eps --pdf $$i"     "needauth"')
                 logger.info('+  found LilyPond version %s.' % version_number)
             else:
                 logger.info('+  found LilyPond, but version %s is too old.' % version_number)
@@ -1328,12 +1335,12 @@ def checkConverterEntries():
                     #       clicks View PDF after having done a View DVI. To circumvent
                     #       this, use different output folders for eps and pdf outputs.
                     cmd = cmd.replace('"', r'\"')
-                    addToRC(r'\converter lilypond-book latex     "' + cmd + ' --safe --lily-output-dir=ly-eps $$i"                                ""')
-                    addToRC(r'\converter lilypond-book pdflatex  "' + cmd + ' --safe --pdf --latex-program=pdflatex --lily-output-dir=ly-pdf $$i" ""')
-                    addToRC(r'\converter lilypond-book-ja platex "' + cmd + ' --safe --pdf --latex-program=platex --lily-output-dir=ly-pdf $$i" ""')
-                    addToRC(r'\converter lilypond-book xetex     "' + cmd + ' --safe --pdf --latex-program=xelatex --lily-output-dir=ly-pdf $$i"  ""')
-                    addToRC(r'\converter lilypond-book luatex    "' + cmd + ' --safe --pdf --latex-program=lualatex --lily-output-dir=ly-pdf $$i" ""')
-                    addToRC(r'\converter lilypond-book dviluatex "' + cmd + ' --safe --latex-program=dvilualatex --lily-output-dir=ly-eps $$i" ""')
+                    addToRC(r'\converter lilypond-book latex     "' + cmd + ' --lily-output-dir=ly-eps $$i"                                "needauth"')
+                    addToRC(r'\converter lilypond-book pdflatex  "' + cmd + ' --pdf --latex-program=pdflatex --lily-output-dir=ly-pdf $$i" "needauth"')
+                    addToRC(r'\converter lilypond-book-ja platex "' + cmd + ' --pdf --latex-program=platex --lily-output-dir=ly-pdf $$i" "needauth"')
+                    addToRC(r'\converter lilypond-book xetex     "' + cmd + ' --pdf --latex-program=xelatex --lily-output-dir=ly-pdf $$i"  "needauth"')
+                    addToRC(r'\converter lilypond-book luatex    "' + cmd + ' --pdf --latex-program=lualatex --lily-output-dir=ly-pdf $$i" "needauth"')
+                    addToRC(r'\converter lilypond-book dviluatex "' + cmd + ' --latex-program=dvilualatex --lily-output-dir=ly-eps $$i" "needauth"')
 
                     # Also create the entry to apply LilyPond on DocBook files. However,
                     # command must be passed as argument, and it might already have
@@ -1352,6 +1359,13 @@ def checkConverterEntries():
                     break
                 else:
                     logger.info('+  found LilyPond-book, but version %s is too old.' % version_number)
+            else:
+                logger.info('+  found LilyPond book, but version string does not match: %s' % version_string)
+
+            # If not on Windows, skip the check as argument to python.
+            if os.name != 'nt':
+                break
+
         if not found_lilypond_book:
             logger.info('+  found LilyPond-book, but could not extract version number.')
     #
@@ -1385,6 +1399,7 @@ def checkConverterEntries():
 \converter lyx        lyx21x     "$${python} $$s/lyx2lyx/lyx2lyx -V 2.1 -o $$o $$i"    ""
 \converter lyx        lyx22x     "$${python} $$s/lyx2lyx/lyx2lyx -V 2.2 -o $$o $$i"    ""
 \converter lyx        lyx23x     "$${python} $$s/lyx2lyx/lyx2lyx -V 2.3 -o $$o $$i"    ""
+\converter lyx        lyx24x     "$${python} $$s/lyx2lyx/lyx2lyx -V 2.4 -o $$o $$i"    ""
 \converter lyx        clyx       "$${python} $$s/lyx2lyx/lyx2lyx -V 1.4 -o $$o -c big5   $$i"  ""
 \converter lyx        jlyx       "$${python} $$s/lyx2lyx/lyx2lyx -V 1.4 -o $$o -c euc_jp $$i"  ""
 \converter lyx        klyx       "$${python} $$s/lyx2lyx/lyx2lyx -V 1.4 -o $$o -c euc_kr $$i"  ""
@@ -1474,7 +1489,7 @@ def processLayoutFile(file):
     q = re.compile('\\s*#\\s*\\\\DeclareCategory{(.*)}\\s*$')
     classdeclaration = ""
     categorydeclaration = '""'
-    for line in open(file, 'r', encoding='utf8').readlines():
+    for line in open(file, encoding='utf8').readlines():
         res = p.match(line)
         qres = q.match(line)
         if res is not None:
@@ -1576,7 +1591,7 @@ def checkLatexConfig(check_config):
         decline = ""
         catline = ""
         try:
-            for line in open(file, 'r', encoding='utf8').readlines():
+            for line in open(file, encoding='utf8').readlines():
                 if not empty.match(line) and line[0] != '#'[0]:
                     if decline == "":
                         logger.warning(r"Failed to find valid \Declare line "
@@ -1585,7 +1600,7 @@ def checkLatexConfig(check_config):
                     # A class, but no category declaration. Just break.
                     break
                 if declare.match(line) is not None:
-                    decline = "\\TestDocClass{%s}{%s}" % (classname, line[1:].strip())
+                    decline = f"\\TestDocClass{{{classname}}}{{{line[1:].strip()}}}"
                     testclasses.append(decline)
                 elif category.match(line) is not None:
                     catline = ("\\DeclareCategory{%s}{%s}"
@@ -1713,7 +1728,7 @@ def processModuleFile(file, filename):
     readingDescription = False
     descLines = []
 
-    for line in open(file, 'r', encoding='utf8').readlines():
+    for line in open(file, encoding='utf8').readlines():
       if readingDescription:
         res = redend.match(line)
         if res != None:
@@ -1840,7 +1855,7 @@ def processCiteEngineFile(file, filename):
     readingDescription = False
     descLines = []
 
-    for line in open(file, 'r', encoding='utf8').readlines():
+    for line in open(file, encoding='utf8').readlines():
       if readingDescription:
         res = redend.match(line)
         if res != None:
@@ -1968,7 +1983,7 @@ def rescanTeXFiles():
     interpreter = sys.executable
     if interpreter == '':
         interpreter = "python"
-    tfp = cmdOutput('"%s" -tt "%s"' % (interpreter, tfscript))
+    tfp = cmdOutput(f'"{interpreter}" "{tfscript}"')
     logger.info(tfp)
     logger.info("\tdone")
 
@@ -1985,12 +2000,13 @@ if __name__ == '__main__':
     lyx_check_config = True
     lyx_kpsewhich = True
     outfile = 'lyxrc.defaults'
-    lyxrc_fileformat = 36
+    lyxrc_fileformat = 38
     rc_entries = ''
     lyx_keep_temps = False
     version_suffix = ''
     lyx_binary_dir = ''
-    logger.info("+Running LyX configure with Python %s.%s.%s", sys.version_info[0], sys.version_info[1], sys.version_info[2])
+    python_version = ".".join([str(n) for n in sys.version_info[:3]])
+    logger.info("+Running LyX configure with Python %s", python_version)
     ## Parse the command line
     for op in sys.argv[1:]:   # default shell/for list is $*, the options
         if op in [ '-help', '--help', '-h' ]: