diff options
author | Karl Berry <karl@freefriends.org> | 2016-09-21 20:56:17 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2016-09-21 20:56:17 +0000 |
commit | 28785b63ec8b8ca1cc6bdab4fe0208a9509e46b1 (patch) | |
tree | 53504e12b92110550b3352d8cbdf9f00aff365c1 /Master/texmf-dist/doc/latex/revquantum | |
parent | 8547630a54bd0e2f5e818bbce37ff41587b34254 (diff) |
revquantum (21sep16)
git-svn-id: svn://tug.org/texlive/trunk@42122 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/doc/latex/revquantum')
-rw-r--r-- | Master/texmf-dist/doc/latex/revquantum/README.md | 70 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/revquantum/build.py | 295 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/revquantum/revquantum.pdf | bin | 0 -> 180157 bytes |
3 files changed, 365 insertions, 0 deletions
diff --git a/Master/texmf-dist/doc/latex/revquantum/README.md b/Master/texmf-dist/doc/latex/revquantum/README.md new file mode 100644 index 00000000000..c29c76a4f70 --- /dev/null +++ b/Master/texmf-dist/doc/latex/revquantum/README.md @@ -0,0 +1,70 @@ +# revquantum # + +This package attempts to solve, or at least mitigate, standard problems with +writing quantum information papers in ``{revtex4-1}``. In particular: + +- Includes titles in BibTeX. +- Allows for use of nicer-looking fonts via ``{mathpazo}``. +- Configures ``{hyperref}`` to make nicer-looking links and to correctly use ``\autoref``. +- Sets up ``{listings}`` for common scientific languages and legacy environments (Python, Mathematica and MATLAB). +- Provides notation for quantum information and makes defining new notation easier. +- Reduces boilerplate for author affiliations by providing a (rudimentary) database for a few departments. + +A major goal of this package is to reduce the amount of useless crap that needs to be copied and pasted between documents. In particular, a complete document can be written in just a few lines: + +```latex +\documentclass[pra,aps,twocolumn,superscriptaddress,10pt]{revtex4-1} +\usepackage[pretty,uselistings]{revquantum} + +\begin{document} + +\title{Example \textsf{revquantum} Document} + +\author{Christopher Granade} +\email{cgranade@cgranade.com} +\affilUSydPhys \affilEQUS + +\date{\today} + +\begin{abstract} + \TODO +\end{abstract} + +\maketitle + +\bibliography{example} +\appendix + +\end{document} +``` + +## Installing ## + +Installing LaTeX packages outside of CTAN is a pain, and this is no exception. I'll submit there at some point to remove that difficulty. In the meantime, I think the following works on Unix-like systems. If not, let me know or pull request with better instructions. + +```bash +$ latex revquantum.ins # Makes the actual .sty from the .dtx file. +$ pdflatex revquantum.dtx # Makes documentation, such as it is. +$ mkdir texdir/tex/latex/revquantum # Replace texdir with where you actually installed TeX (e.g. ~/texmf). +$ cp revquantum.sty texdir/tex/latex/revquantum # As with above, replace texdir. +$ texhash +``` + +Directions for Windows/MikTeX can be found thanks to [this useful StackOverflow answer](http://tex.stackexchange.com/questions/2063/how-can-i-manually-install-a-package-on-miktex-windows). + +## Using ## + +I'll write more complete documentation later (hopefully), but for now: + +- ``{braket}`` is automatically imported, defining ``\ket``, ``\bra`` and ``\braket``. +- The notation commands ``\ii`` and ``\dd`` typeset roman "i" and "d" characters, respectively. More generally, ``\newrm{foo}`` creates a new command ``\foo`` that typesets ``foo`` in math-roman. ``{revquantum}`` comes with ``\e``, ``\TVD`` and ``\T`` predefined using ``\newrm``. +- Similarly, ``\newoperator`` defines new commands which typeset using ``\operatorname``. By default, this is used to define ``\Tr``, ``\Cov``, ``\supp``, ``\diag`` and ``\rank``. +- The commands ``\defeq``, ``\expect`` and ``\id`` define the common notation ``:=``, double-struck E and double-struck 1 (respectively). +- ``\newaffil{NAME}{DESCRIPTION}`` defines a new affiliation command ``\affilNAME``. +- The ``\todo`` command typesets its argument in purple and raises a warning when built. If ``{revquantum}`` is loaded with the ``[final]`` option, this warning is escalated to an error. Similarly, ``\TODO`` takes no argument but inserts the placeholder "TODO" and ``\todolist`` typesets an ``{itemize}`` environment in ``\todo``. + +## Known Issues ## + +- The BibTeX thing is an unforgivable hack. Thankfully, I'm not asking for anyone's forgiveness. +- ``\autoref`` chokes on appendices, giving nonsense like "Section A". This should be fixable, though. +- The use of the "UW" prefix for the University of Waterloo was probably a bad idea, and will likely change so as to not preclude other universities whose names start with "W". diff --git a/Master/texmf-dist/doc/latex/revquantum/build.py b/Master/texmf-dist/doc/latex/revquantum/build.py new file mode 100644 index 00000000000..6217d29d198 --- /dev/null +++ b/Master/texmf-dist/doc/latex/revquantum/build.py @@ -0,0 +1,295 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from __future__ import print_function, unicode_literals + +PACKAGE_NAME = 'revquantum' +TEX_DIR = None + +import errno +import sys +import os +import tempfile +import shutil +import zipfile +from subprocess import Popen, PIPE + +from io import StringIO + +def print_usage(): + print(""" +Usage: +------ + +python build.py tds + Builds a *.tds.zip file for this package. + +python build.py install + Installs this package into the main TeX directory. + May require administrator privileges. +""") + sys.exit(1) + +def is_writable(dir_name): + # Technique adapted from: + # http://stackoverflow.com/a/25868839/267841 + # We modify by not raising on other OSErrors, as + # we don't care *why* a directory isn't writable, + # so much as that we need to know that it isn't. + # We also note that tempfile raises an IOError + # on Windows if it can't write, so we catch that, + # too. + try: + with tempfile.TemporaryFile(dir=dir_name): + pass + except (OSError, IOError) as ex: + return False + + return True + +def mkdir_p(path): + # Copied from http://stackoverflow.com/a/600612/267841, + # in keeping with the CC-BY-SA 3.0 license on StackOverflow + # user contributions. + if os.path.isdir(path): + return + try: + os.makedirs(path) + except OSError as exc: # Python > 2.5 + if exc.errno == errno.EEXIST and os.path.isdir(path): + pass + else: + raise + except WindowsError as exc: + if exc.errno == 183 and os.path.isdir(path): + pass + else: + raise + +def try_until(condition, *fns): + for fn in fns: + retval = fn() + if condition(retval): + return retval + + # This is likely a terrible error for any poor user, + # so we should probably catch it. Probably. + raise RuntimeError("No candidates found matching the given condition.") + +def is_miktek(): + # Assume MikTeX if and only if Windows. + # This is a bad assumption, but we can encapsulate + # it here and generalize later. + return os.name == 'nt' + +def find_tex_root(): + proc = Popen(['kpsewhich', 'article.cls'], stdout=PIPE) + stdout, stderr = proc.communicate() + + head, tail = os.path.split(stdout.strip()) + + # Note that kpsewhich returns with / characters, even + # under Windows, so we must use str.split to override + # os.path's behavior. + head_parts = head.split('/') + + # If we're on Windows, then that destroyed the drive + # part of the pathspec. + if os.name == 'nt': + head_parts = [head_parts[0] + '\\'] + head_parts[1:] + + # Remove "tex/latex/base" from head_parts, since that's where + # article.cls should live. + tex_root = os.path.join(*head_parts[:-3]) + + return tex_root + +def find_tex_user(): + if is_miktek(): + # Use MikTeX's initexmf utility to find the user install + # dir. + # http://tex.stackexchange.com/a/69484/615 + initexmf = Popen(['initexmf', '--report'], stdout=PIPE) + stdout, stderr = initexmf.communicate() + + for line in stdout.split('\n'): + try: + key, value = line.split(':', 1) + if key.strip().lower() == 'userinstall': + return value.strip() + except: + continue + + raise RuntimeError("MikTeX did not report a UserInstall directory.") + + else: + return os.path.expanduser('~/texmf') + +def find_tex(): + global TEX_DIR + + if TEX_DIR is None: + TEX_DIR = try_until(is_writable, + find_tex_root, + find_tex_user + ) + + return TEX_DIR + +def copy_to_tex(what, tex_path=['tex', 'latex']): + tex_root = find_tex() + where = os.path.join(tex_root, *tex_path) + full_path = os.path.join(where, what) + + # Check if the directory exists, make it if it doesn't. + mkdir_p(where) + + print("Installing: {} ---> {}".format(what, full_path)) + shutil.copyfile(what, full_path) + +def write_to_zip(zip_file, filename, arcname=None, normalize_crlf=None): + """ + normalize_crlf = None: automatically detect from filename. + """ + + if normalize_crlf is None: + root, ext = os.path.splitext(filename) + if ext in ('.dtx', '.ins', '.txt', '.md', '.py', '.tex'): + normalize_crlf = True + else: + normalize_crlf = False + + if arcname is None: + arcname = filename + + if not normalize_crlf: + print("\tPacking: {} ---> {}".format(filename, arcname)) + zip_file.write(filename, arcname=arcname) + else: + print("\tPacking: {} ---> {} (normalized line endings)".format(filename, arcname)) + contents = StringIO(newline='\n') + with open(filename, 'r') as f: + for line in f: + contents.write(line.decode('utf-8')) + zip_file.writestr( + arcname, + contents.getvalue() + ) + +def yes_proc(args, yes="yes"): + proc = Popen(args, stdin=PIPE) + while proc.returncode is None: + proc.communicate(yes) + proc.poll() + + return proc.returncode == 0 + +class LaTeXStyleBuilder(object): + """ + Builds a DocStrip-formatted LaTeX style by running + the LaTeX processor on the appropriate *.dtx file. + """ + style_name = None + manifest = {} + ctan_manifest = {} + + def __init__(self, style_name): + self.style_name = style_name + + self.manifest = { + '{}.{}'.format(style_name, ext): + path + [style_name] + for ext, path in + { + 'sty': ['tex', 'latex'], + 'pdf': ['doc', 'latex'] + }.items() + } + + self.ctan_manifest = [ + '{}.dtx'.format(style_name), + '{}.ins'.format(style_name), + '{}.pdf'.format(style_name), + 'build.py', + 'README.md' + ] + + def build_sty(self): + print("Building: {}.sty".format(self.style_name)) + if not yes_proc(['latex', '{}.ins'.format(self.style_name)]): + raise RuntimeError + print("\n\n\n") + return self + + def build_doc_pdf(self): + print("Building: {}.pdf".format(self.style_name)) + if not yes_proc(['pdflatex', '{}.dtx'.format(self.style_name)]): + raise RuntimeError + print("\n\n\n") + return self + + def build_tds_zip(self): + print("Building: {}.tds.zip".format(self.style_name)) + tds_zip = zipfile.ZipFile('{}.tds.zip'.format(self.style_name), 'w') + + for what, where in self.manifest.items(): + assert os.path.isfile(what) + write_to_zip(tds_zip, what, arcname=os.path.join(*where + [what])) + + print("\n\n\n") + return self + + def build_ctan_zip(self): + print("Building: {}.zip".format(self.style_name)) + ctan_zip = zipfile.ZipFile('{}.zip'.format(self.style_name), 'w') + + for what in self.ctan_manifest: + assert os.path.isfile(what) + write_to_zip(ctan_zip, what, arcname=os.path.join(self.style_name, what)) + + print("\n\n\n") + return self + + def install(self): + for what, where in self.manifest.items(): + assert os.path.isfile(what) + copy_to_tex(what, where) + + # Make sure to run texhash if we're not using MikTeX. + if not is_miktek(): + print("Rehashing...") + texhash = Popen(['texhash']) + texhash.wait() + + return self + +if __name__ == "__main__": + print(""" +WARNING: This installer is still in alpha, and is provided + as a convenience only. That said, this installer + may cause you to say unkind words in frustration + instead of providing the intended convenience. +""") + + if len(sys.argv) < 2: + print_usage() + + else: + subcommand = sys.argv[1] + if subcommand not in ('tds', 'install', 'ctan'): + print("No such command {}, try either 'tds', 'install' or 'ctan'.") + print_usage() + + builder = LaTeXStyleBuilder(PACKAGE_NAME) + builder.build_sty().build_doc_pdf() + + if subcommand == 'tds': + builder.build_tds_zip() + + elif subcommand == 'install': + builder.install() + + elif subcommand == 'ctan': + builder.build_ctan_zip() + + else: + assert False diff --git a/Master/texmf-dist/doc/latex/revquantum/revquantum.pdf b/Master/texmf-dist/doc/latex/revquantum/revquantum.pdf Binary files differnew file mode 100644 index 00000000000..50bdd6038b5 --- /dev/null +++ b/Master/texmf-dist/doc/latex/revquantum/revquantum.pdf |