diff options
author | Karl Berry <karl@freefriends.org> | 2013-09-12 23:36:12 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2013-09-12 23:36:12 +0000 |
commit | 88cc357fc8d3e1b57e21eb762fef36e4ef2dd3f4 (patch) | |
tree | 51244daaeef0622ddd48de2d1464daa5b235b1c1 /Master/texmf-dist/scripts/pythontex/pythontex_install_texlive.py | |
parent | 3ce8f395f1980ebc8f4e95d66e79ac7f29f99222 (diff) |
pythontex (import from $0 symlink works after all)
git-svn-id: svn://tug.org/texlive/trunk@31638 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/scripts/pythontex/pythontex_install_texlive.py')
-rwxr-xr-x | Master/texmf-dist/scripts/pythontex/pythontex_install_texlive.py | 343 |
1 files changed, 343 insertions, 0 deletions
diff --git a/Master/texmf-dist/scripts/pythontex/pythontex_install_texlive.py b/Master/texmf-dist/scripts/pythontex/pythontex_install_texlive.py new file mode 100755 index 00000000000..28176e8b704 --- /dev/null +++ b/Master/texmf-dist/scripts/pythontex/pythontex_install_texlive.py @@ -0,0 +1,343 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +''' +Install PythonTeX + +This installation script should work with most TeX distributions. It is +primarily written for TeX Live. It should work with other TeX distributions +that use the Kpathsea library (such as MiKTeX), though with reduced +functionality in some cases. It will require manual input when used with a +distribution that does not include Kpathsea. + +The script will overwrite (and thus update) all previously installed PythonTeX +files. When Kpathsea is available, files may be installed in TEXMFDIST, +TEXMFHOME, or a manually specified location. Otherwise, the installation +location must be specified manually. Installing in TEXMFDIST is useful if +you want to install PythonTeX and then update it in the future from CTAN. +The mktexlsr command is executed at the end of the script, to make the system +aware of any new files. + +The script attempts to create a binary wrapper (Windows) or symlink +(Linux and OS X) for launching the main PythonTeX scripts, pythontex*.py and +depythontex*.py. + + +Copyright (c) 2012-2013, Geoffrey M. Poore +All rights reserved. +Licensed under the BSD 3-Clause License: + http://www.opensource.org/licenses/BSD-3-Clause + +''' + + +# Imports +import sys +import platform +from os import path, mkdir, makedirs +if platform.system() != 'Windows': + # Only create symlinks if not under Windows + # (os.symlink doesn't exist under Windows) + from os import symlink, chmod, unlink +from subprocess import call, check_call, check_output +from shutil import copy +import textwrap + + +# We need a version of input that works under both Python 2 and 3 +try: + input = raw_input +except: + pass + + +# Print startup messages and warnings +print('Preparing to install PythonTeX') +if platform.system() != 'Windows': + message = ''' + You may need to run this script with elevated permissions + and/or specify the environment. For example, you may need + "sudo env PATH=$PATH". That is typically necessary when your + system includes a TeX distribution, and you have manually + installed another distribution (common with Ubuntu etc.). If + the installation path you want is not automatically detected, + it may indicate a permissions issue. + ''' + print(textwrap.dedent(message)) + + +# Make sure all necessary files are present +# The pythontex_gallery and pythontex_quickstart are optional; we check for them when installing doc +needed_files = ['pythontex.py', 'pythontex2.py', 'pythontex3.py', + 'pythontex_engines.py', 'pythontex_utils.py', + 'depythontex.py', 'depythontex2.py', 'depythontex3.py', + 'pythontex.sty', 'pythontex.ins', 'pythontex.dtx', + 'pythontex.pdf', 'README'] +missing_files = False +# Print a list of all files that are missing, and exit if any are +for eachfile in needed_files: + if not path.exists(eachfile): + print('Could not find file ' + eachfile) + missing_files = True +if missing_files: + print('Exiting.') + sys.exit(1) + + +# Retrieve the location of valid TeX trees +# Attempt to use kpsewhich; otherwise, resort to manual input +should_exit = False # Can't use sys.exit() in try; will trigger except +try: + if sys.version_info[0] == 2: + texmf_dist = check_output(['kpsewhich', '-var-value', 'TEXMFDIST']).rstrip('\r\n') + texmf_local = check_output(['kpsewhich', '-var-value', 'TEXMFLOCAL']).rstrip('\r\n') + texmf_home = check_output(['kpsewhich', '-var-value', 'TEXMFHOME']).rstrip('\r\n') + else: + texmf_dist = check_output(['kpsewhich', '-var-value', 'TEXMFDIST']).decode('utf-8').rstrip('\r\n') + texmf_local = check_output(['kpsewhich', '-var-value', 'TEXMFLOCAL']).decode('utf-8').rstrip('\r\n') + texmf_home = check_output(['kpsewhich', '-var-value', 'TEXMFHOME']).decode('utf-8').rstrip('\r\n') + message = ''' + Choose an installation location. + + TEXMFDIST is a good choice if you want to update PythonTeX + in the future using your TeX distribution's package manager. + + 1. TEXMFDIST + {0} + 2. TEXMFLOCAL + {1} + 3. TEXMFHOME + {2} + 4. Manual location + '''.format(texmf_dist, texmf_local, texmf_home) + print(textwrap.dedent(message)) + path_choice = input('Installation location (number): ') + if path_choice not in ('1', '2', '3', '4'): + should_exit = True + else: + if path_choice == '1': + texmf_path = texmf_dist + elif path_choice == '2': + texmf_path = texmf_local + elif path_choice == '3': + texmf_path = texmf_home + else: + texmf_path = input('Enter a path:\n') +except: + print('Cannot automatically find TEXMF paths.') + print('kpsewhich does not exist or could not be used.') + texmf_path = input('Please enter a valid installation path:\n') +if should_exit: + sys.exit() +# Make sure path slashes are compatible with the operating system +# Kpathsea returns forward slashes, but Windows needs back slashes +texmf_path = path.expandvars(path.expanduser(path.normcase(texmf_path))) + +# Check to make sure the path is valid +# This is only really needed for manual input +# The '' check is for empty manual input +if texmf_path == '' or not path.exists(texmf_path): + print('Invalid installation path. Exiting.') + sys.exit(1) + + +# Now check that all other needed paths are present +if path_choice != '2': + doc_path = path.join(texmf_path, 'doc', 'latex') + package_path = path.join(texmf_path, 'tex', 'latex') + scripts_path = path.join(texmf_path, 'scripts') + source_path = path.join(texmf_path, 'source', 'latex') +else: + doc_path = path.join(texmf_path, 'doc', 'latex', 'local') + package_path = path.join(texmf_path, 'tex', 'latex', 'local') + scripts_path = path.join(texmf_path, 'scripts', 'local') + source_path = path.join(texmf_path, 'source', 'latex', 'local') +make_paths = False +for eachpath in [doc_path, package_path, scripts_path, source_path]: + if not path.exists(eachpath): + if make_paths: + makedirs(eachpath) + print(' * Created ' + eachpath) + else: + choice = input('Some directories do not exist. Create them? [y/n]\n') + if choice not in ('y', 'n'): + sys.exit('Invalid choice') + elif choice == 'y': + make_paths = True + makedirs(eachpath) + print(' * Created ' + eachpath) + else: + message = ''' + Paths were not created. The following will be needed. + * {0} + * {1} + * {2} + * {3} + + Exiting. + '''.format(doc_path, package_path, scripts_path, source_path) + print(textwrap.dedent(message)) + sys.exit() +# Modify the paths by adding the pythontex directory, which will be created +doc_path = path.join(doc_path, 'pythontex') +package_path = path.join(package_path, 'pythontex') +scripts_path = path.join(scripts_path, 'pythontex') +source_path = path.join(source_path, 'pythontex') + + +# Install files +# Use a try/except in case elevated permissions are needed (Linux and OS X) +print('\nPythonTeX will be installed in \n ' + texmf_path) +try: + # Install docs + if not path.exists(doc_path): + mkdir(doc_path) + copy('pythontex.pdf', doc_path) + copy('README', doc_path) + for doc in ('pythontex_quickstart.tex', 'pythontex_quickstart.pdf', + 'pythontex_gallery.tex', 'pythontex_gallery.pdf'): + if path.isfile(doc): + copy(doc, doc_path) + else: + doc = path.join('..', doc.rsplit('.', 1)[0], doc) + if path.isfile(doc): + copy(doc, doc_path) + # Install package + if not path.exists(package_path): + mkdir(package_path) + copy('pythontex.sty', package_path) + # Install scripts + if not path.exists(scripts_path): + mkdir(scripts_path) + copy('pythontex.py', scripts_path) + copy('depythontex.py', scripts_path) + copy('pythontex_utils.py', scripts_path) + copy('pythontex_engines.py', scripts_path) + for ver in [2, 3]: + copy('pythontex{0}.py'.format(ver), scripts_path) + copy('depythontex{0}.py'.format(ver), scripts_path) + # Install source + if not path.exists(source_path): + mkdir(source_path) + copy('pythontex.ins', source_path) + copy('pythontex.dtx', source_path) +except OSError as e: + if e.errno == 13: + print('Insufficient permission to install PythonTeX') + print('(For example, you may need "sudo", or possibly "sudo env PATH=$PATH")\n') + sys.exit(1) + else: + raise + + +# Install binary wrappers, create symlinks, or suggest the creation of +# wrappers/batch files/symlinks. This part is operating system dependent. +if platform.system() == 'Windows': + # If under Windows, we create a binary wrapper if under TeX Live and + # otherwise alert the user regarding the need for a wrapper or batch file. + + # Assemble the binary path, assuming TeX Live + # The directory bin/ should be at the same level as texmf + bin_path = path.join(path.split(texmf_path)[0], 'bin', 'win32') + if path.exists(path.join(bin_path, 'runscript.exe')): + copy(path.join(bin_path, 'runscript.exe'), path.join(bin_path, 'pythontex.exe')) + copy(path.join(bin_path, 'runscript.exe'), path.join(bin_path, 'depythontex.exe')) + print('\nCreated binary wrapper...') + else: + message = ''' + Could not create a wrapper for launching pythontex.py and + depythontex.py; did not find runscript.exe. You will need + to create a wrapper manually, or use a batch file. Sample + batch files are included with the main PythonTeX files. + The wrapper or batch file should be in a location on the + Windows PATH. The bin/ directory in your TeX distribution + may be a good location. + + The scripts pythontex.py and depythontex.py are located in + the following directory: + {0} + '''.format(scripts_path) + print(textwrap.dedent(message)) +else: + # Optimistically proceed as if every system other than Windows can share + # one set of code. + root_path = path.split(texmf_path)[0] + # Create a list of all possible subdirectories of bin/ for TeX Live + # Source: http://www.tug.org/texlive/doc/texlive-en/texlive-en.html#x1-250003.2.1 + texlive_platforms = ['alpha-linux', 'amd64-freebsd', 'amd64-kfreebsd', + 'armel-linux', 'i386-cygwin', 'i386-freebsd', + 'i386-kfreebsd', 'i386-linux', 'i386-solaris', + 'mips-irix', 'mipsel-linux', 'powerpc-aix', + 'powerpc-linux', 'sparc-solaris', 'universal-darwin', + 'x86_64-darwin', 'x86_64-linux', 'x86_64-solaris'] + symlink_created = False + # Try to create a symlink in the standard TeX Live locations + for pltfrm in texlive_platforms: + bin_path = path.join(root_path, 'bin', pltfrm) + if path.exists(bin_path): + # Create symlink for pythontex*.py + link = path.join(bin_path, 'pythontex.py') + # Unlink any old symlinks if they exist, and create new ones + # Not doing this gave permissions errors under Ubuntu + if path.exists(link): + unlink(link) + symlink(path.join(scripts_path, 'pythontex.py'), link) + chmod(link, 0o775) + # Now repeat for depythontex*.py + link = path.join(bin_path, 'depythontex.py') + if path.exists(link): + unlink(link) + symlink(path.join(scripts_path, 'depythontex.py'), link) + chmod(link, 0o775) + symlink_created = True + + # If the standard TeX Live bin/ locations didn't work, try the typical + # location for MacPorts TeX Live. This should typically be + # /opt/local/bin, but instead of assuming that location, we just climb + # two levels up from texmf-dist and then look for a bin/ directory that + # contains a tex executable. (For MacPorts, texmf-dist should be at + # /opt/local/share/texmf-dist.) + if not symlink_created and platform.system() == 'Darwin': + bin_path = path.join(path.split(root_path)[0], 'bin') + if path.exists(bin_path): + try: + # Make sure this bin/ is the bin/ we're looking for, by + # seeing if pdftex exists + check_output([path.join(bin_path, 'pdftex'), '--version']) + # Create symlinks + link = path.join(bin_path, 'pythontex.py') + if path.exists(link): + unlink(link) + symlink(path.join(scripts_path, 'pythontex.py'), link) + chmod(link, 0o775) + link = path.join(bin_path, 'depythontex.py') + if path.exists(link): + unlink(link) + symlink(path.join(scripts_path, 'depythontex.py'), link) + chmod(link, 0o775) + symlink_created = True + except: + pass + if symlink_created: + print("\nCreated symlink in Tex's bin/ directory...") + else: + print('\nCould not automatically create a symlink to pythontex*.py and depythontex*.py.') + print('You may wish to create one manually, and make it executable via chmod.') + print('The scripts pythontex*.py and depythontex*.py are located in the following directory:') + print(' ' + scripts_path) + + +# Alert TeX to the existence of the package via mktexlsr +try: + print('\nRunning mktexlsr to make TeX aware of new files...') + check_call(['mktexlsr']) +except: + print('Could not run mktexlsr.') + print('Your system may not be aware of newly installed files.') + + +if platform.system() == 'Windows': + # Pause so that the user can see any errors or other messages + # input('\n[Press ENTER to exit]') + print('\n') + call(['pause'], shell=True) |