summaryrefslogtreecommitdiff
path: root/Master
diff options
context:
space:
mode:
Diffstat (limited to 'Master')
-rw-r--r--Master/texmf-dist/doc/latex/pythontex/NEWS.rst (renamed from Master/texmf-dist/doc/latex/pythontex/NEWS)14
-rw-r--r--Master/texmf-dist/doc/latex/pythontex/README2
-rw-r--r--Master/texmf-dist/doc/latex/pythontex/pythontex.pdfbin951758 -> 969134 bytes
-rw-r--r--Master/texmf-dist/doc/latex/pythontex/pythontex_gallery.pdfbin373106 -> 373207 bytes
-rwxr-xr-xMaster/texmf-dist/scripts/pythontex/depythontex.py2
-rwxr-xr-xMaster/texmf-dist/scripts/pythontex/depythontex2.py4
-rwxr-xr-xMaster/texmf-dist/scripts/pythontex/depythontex3.py4
-rwxr-xr-xMaster/texmf-dist/scripts/pythontex/pythontex.py2
-rwxr-xr-xMaster/texmf-dist/scripts/pythontex/pythontex2.py54
-rwxr-xr-xMaster/texmf-dist/scripts/pythontex/pythontex3.py54
-rwxr-xr-xMaster/texmf-dist/scripts/pythontex/pythontex_2to3.py38
-rwxr-xr-xMaster/texmf-dist/scripts/pythontex/pythontex_engines.py259
-rw-r--r--Master/texmf-dist/source/latex/pythontex/pythontex.dtx46
-rw-r--r--Master/texmf-dist/tex/latex/pythontex/pythontex.sty23
-rwxr-xr-xMaster/tlpkg/bin/tlpkg-ctan-check1
-rwxr-xr-xMaster/tlpkg/libexec/ctan2tds2
16 files changed, 385 insertions, 120 deletions
diff --git a/Master/texmf-dist/doc/latex/pythontex/NEWS b/Master/texmf-dist/doc/latex/pythontex/NEWS.rst
index 58fa279d663..016a7407948 100644
--- a/Master/texmf-dist/doc/latex/pythontex/NEWS
+++ b/Master/texmf-dist/doc/latex/pythontex/NEWS.rst
@@ -7,6 +7,20 @@ Version History
===============
+
+v0.16 (2017/07/20)
+------------------
+
+* Added preliminary console support for Julia (#98).
+
+* Fixed Python console compatibility with Python 3.6 by setting the ``code``
+ module's new ``exitmsg`` argument to suppress the exit message (#100).
+
+* Improved Rust support, including tracking of created files and
+ dependencies (#91).
+
+
+
v0.15 (2016/07/21)
------------------
diff --git a/Master/texmf-dist/doc/latex/pythontex/README b/Master/texmf-dist/doc/latex/pythontex/README
index 84ae1cff63b..56259936766 100644
--- a/Master/texmf-dist/doc/latex/pythontex/README
+++ b/Master/texmf-dist/doc/latex/pythontex/README
@@ -3,7 +3,7 @@
===================================================================
:Author: Geoffrey Poore
-:Version: 0.15 (2016/07/21)
+:Version: 0.16 (2017/07/20)
:License: LPPL v1.3 or later (LaTeX code) and BSD 3-Clause (Python code)
:Development: https://github.com/gpoore/pythontex
:Requirements: Python 2.7 or 3.2+; Pygments
diff --git a/Master/texmf-dist/doc/latex/pythontex/pythontex.pdf b/Master/texmf-dist/doc/latex/pythontex/pythontex.pdf
index 2531310f30e..bd919b5a556 100644
--- a/Master/texmf-dist/doc/latex/pythontex/pythontex.pdf
+++ b/Master/texmf-dist/doc/latex/pythontex/pythontex.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/latex/pythontex/pythontex_gallery.pdf b/Master/texmf-dist/doc/latex/pythontex/pythontex_gallery.pdf
index 245ffd5cc08..41f7c982d44 100644
--- a/Master/texmf-dist/doc/latex/pythontex/pythontex_gallery.pdf
+++ b/Master/texmf-dist/doc/latex/pythontex/pythontex_gallery.pdf
Binary files differ
diff --git a/Master/texmf-dist/scripts/pythontex/depythontex.py b/Master/texmf-dist/scripts/pythontex/depythontex.py
index 30256c6d1c3..3d48e3b1daa 100755
--- a/Master/texmf-dist/scripts/pythontex/depythontex.py
+++ b/Master/texmf-dist/scripts/pythontex/depythontex.py
@@ -9,7 +9,7 @@ on your system. If you wish to use a different version of Python, you could
launch depythontex2.py or depythontex3.py directly. The version of Python
does not matter for depythontex, since no code is executed.
-Copyright (c) 2013-2016, Geoffrey M. Poore
+Copyright (c) 2013-2017, Geoffrey M. Poore
All rights reserved.
Licensed under the BSD 3-Clause License:
http://www.opensource.org/licenses/BSD-3-Clause
diff --git a/Master/texmf-dist/scripts/pythontex/depythontex2.py b/Master/texmf-dist/scripts/pythontex/depythontex2.py
index 0975b9b8ca4..7687e0e7244 100755
--- a/Master/texmf-dist/scripts/pythontex/depythontex2.py
+++ b/Master/texmf-dist/scripts/pythontex/depythontex2.py
@@ -47,7 +47,7 @@ example, typeset code may have a different appearance or layout when it is
typeset with a different package.
-Copyright (c) 2013-2016, Geoffrey M. Poore
+Copyright (c) 2013-2017, Geoffrey M. Poore
All rights reserved.
Licensed under the BSD 3-Clause License:
http://www.opensource.org/licenses/BSD-3-Clause
@@ -86,7 +86,7 @@ import codecs
# Script parameters
# Version
-__version__ = '0.15'
+__version__ = '0.16'
# Functions and parameters for customizing the script output
diff --git a/Master/texmf-dist/scripts/pythontex/depythontex3.py b/Master/texmf-dist/scripts/pythontex/depythontex3.py
index 567363eeaa0..bdcea2185e0 100755
--- a/Master/texmf-dist/scripts/pythontex/depythontex3.py
+++ b/Master/texmf-dist/scripts/pythontex/depythontex3.py
@@ -47,7 +47,7 @@ example, typeset code may have a different appearance or layout when it is
typeset with a different package.
-Copyright (c) 2013-2016, Geoffrey M. Poore
+Copyright (c) 2013-2017, Geoffrey M. Poore
All rights reserved.
Licensed under the BSD 3-Clause License:
http://www.opensource.org/licenses/BSD-3-Clause
@@ -86,7 +86,7 @@ import codecs
# Script parameters
# Version
-__version__ = '0.15'
+__version__ = '0.16'
# Functions and parameters for customizing the script output
diff --git a/Master/texmf-dist/scripts/pythontex/pythontex.py b/Master/texmf-dist/scripts/pythontex/pythontex.py
index 0c6e5c70bb1..2fe6de902a2 100755
--- a/Master/texmf-dist/scripts/pythontex/pythontex.py
+++ b/Master/texmf-dist/scripts/pythontex/pythontex.py
@@ -16,7 +16,7 @@ under which your code is actually executed.
Licensed under the BSD 3-Clause License:
-Copyright (c) 2012-2016, Geoffrey M. Poore
+Copyright (c) 2012-2017, Geoffrey M. Poore
All rights reserved.
diff --git a/Master/texmf-dist/scripts/pythontex/pythontex2.py b/Master/texmf-dist/scripts/pythontex/pythontex2.py
index 519b36f3066..871d394e375 100755
--- a/Master/texmf-dist/scripts/pythontex/pythontex2.py
+++ b/Master/texmf-dist/scripts/pythontex/pythontex2.py
@@ -13,7 +13,7 @@ should be in the same directory.
Licensed under the BSD 3-Clause License:
-Copyright (c) 2012-2016, Geoffrey M. Poore
+Copyright (c) 2012-2017, Geoffrey M. Poore
All rights reserved.
@@ -77,7 +77,7 @@ else:
# Script parameters
# Version
-__version__ = '0.15'
+__version__ = '0.16'
@@ -1286,7 +1286,8 @@ def do_multiprocessing(data, temp_data, old_data, engine_dict):
engine_dict[family].warnings,
engine_dict[family].linenumbers,
engine_dict[family].lookbehind,
- keeptemps, hashdependencies)'''
+ keeptemps, hashdependencies,
+ pygments_settings)'''
tasks.append(pool.apply_async(run_code, [encoding, outputdir,
workingdir, code_dict[key],
engine_dict[family].language,
@@ -1299,7 +1300,8 @@ def do_multiprocessing(data, temp_data, old_data, engine_dict):
engine_dict[family].warnings,
engine_dict[family].linenumbers,
engine_dict[family].lookbehind,
- keeptemps, hashdependencies]))
+ keeptemps, hashdependencies,
+ pygments_settings]))
if verbose:
print(' - Code process ' + key.replace('#', ':'))
@@ -1475,7 +1477,7 @@ def do_multiprocessing(data, temp_data, old_data, engine_dict):
def run_code(encoding, outputdir, workingdir, code_list, language, commands,
command_created, extension, makestderr, stderrfilename,
code_index, errorsig, warningsig, linesig, stderrlookbehind,
- keeptemps, hashdependencies):
+ keeptemps, hashdependencies, pygments_settings):
'''
Function for multiprocessing code files
'''
@@ -1526,7 +1528,10 @@ def run_code(encoding, outputdir, workingdir, code_list, language, commands,
exec_cmd = shlex.split(bytes(command.format(file=script.replace('\\', '\\\\'), File=script_full.replace('\\', '\\\\'), workingdir=workingdir.replace('\\', '\\\\'))))
exec_cmd = [unicode(elem) for elem in exec_cmd]
else:
- exec_cmd = shlex.split(command.format(file=script.replace('\\', '\\\\'), File=script_full.replace('\\', '\\\\'), workingdir=workingdir.replace('\\', '\\\\')))
+ if family != 'juliacon':
+ exec_cmd = shlex.split(command.format(file=script.replace('\\', '\\\\'), File=script_full.replace('\\', '\\\\'), workingdir=workingdir.replace('\\', '\\\\')))
+ else:
+ exec_cmd = shlex.split(command.format(file=script.replace('\\', '/'), File=script_full.replace('\\', '/'), workingdir=workingdir.replace('\\', '/')))
# Add any created files due to the command
# This needs to be done before attempts to execute, to prevent orphans
try:
@@ -1563,6 +1568,22 @@ def run_code(encoding, outputdir, workingdir, code_list, language, commands,
messages.append(' Missing output file for ' + key_run.replace('#', ':'))
errors += 1
else:
+ if family == 'juliacon':
+ with open(out_file_name.rsplit('.', 1)[0] + '.tex', 'r', encoding=encoding) as f:
+ tex_data_lines = f.readlines()
+ inst = 0
+ for n, line in enumerate(tex_data_lines):
+ if line.rstrip() == '\\begin{juliaterm}':
+ tex_data_lines[n] = '=>PYTHONTEX:STDOUT#{0}#code#\n'.format(inst)
+ inst += 1
+ if n != 0:
+ tex_data_lines[n-1] = ''
+ if line.rstrip() == '\\end{juliaterm}':
+ tex_data_lines[n] = ''
+ tex_data_lines.append('=>PYTHONTEX:DEPENDENCIES#\n=>PYTHONTEX:CREATED#\n')
+ with open(out_file_name, 'w', encoding=encoding) as f:
+ f.write(''.join(tex_data_lines))
+
f = open(out_file_name, 'r', encoding=encoding)
out = f.read()
f.close()
@@ -1619,6 +1640,18 @@ def run_code(encoding, outputdir, workingdir, code_list, language, commands,
else:
dependencies[dep] = (os.path.getmtime(dep_file), '')
+ if family == 'juliacon':
+ from pygments import highlight
+ from pygments.lexers import get_lexer_by_name
+ from pygments.formatters import LatexFormatter
+ formatter = dict()
+ lexer = dict()
+ for codetype in pygments_settings:
+ if codetype != ':GLOBAL':
+ p = pygments_settings[codetype]['formatter_options'].copy()
+ p['commandprefix'] = 'PYG'
+ formatter[codetype] = LatexFormatter(**p)
+ lexer[codetype] = get_lexer_by_name(pygments_settings[codetype]['lexer'], **p)
for block in out.split('=>PYTHONTEX:STDOUT#')[1:]:
if block:
delims, content = block.split('#\n', 1)
@@ -1649,6 +1682,8 @@ def run_code(encoding, outputdir, workingdir, code_list, language, commands,
# Remove newline added by printing, prevent
# LaTeX from adding a space after content
content = content.rsplit('\n', 1)[0] + '\\endinput\n'
+ if family == 'juliacon':
+ content = highlight(content, lexer[family], formatter[family])
f.write(content)
f.close()
files.append(fname)
@@ -1658,6 +1693,8 @@ def run_code(encoding, outputdir, workingdir, code_list, language, commands,
messages.append('* PythonTeX error')
messages.append(' Missing stderr file for ' + key_run.replace('#', ':'))
errors += 1
+ elif family == 'juliacon':
+ pass
else:
# Open error and code files.
f = open(err_file_name, encoding=encoding)
@@ -2408,7 +2445,10 @@ def python_console(jobname, encoding, outputdir, workingdir, fvextfile,
sys.excepthook = sys.__excepthook__
old_stdout = sys.stdout
sys.stdout = self.iostdout
- self.interact(self.banner)
+ if sys.version_info.major == 3 and sys.version_info.minor >= 6:
+ self.interact(self.banner, exitmsg='')
+ else:
+ self.interact(self.banner)
sys.stdout = old_stdout
self.session_log = self.iostdout.getvalue()
diff --git a/Master/texmf-dist/scripts/pythontex/pythontex3.py b/Master/texmf-dist/scripts/pythontex/pythontex3.py
index b872dbaa2c4..cb96f97d336 100755
--- a/Master/texmf-dist/scripts/pythontex/pythontex3.py
+++ b/Master/texmf-dist/scripts/pythontex/pythontex3.py
@@ -13,7 +13,7 @@ should be in the same directory.
Licensed under the BSD 3-Clause License:
-Copyright (c) 2012-2016, Geoffrey M. Poore
+Copyright (c) 2012-2017, Geoffrey M. Poore
All rights reserved.
@@ -77,7 +77,7 @@ else:
# Script parameters
# Version
-__version__ = '0.15'
+__version__ = '0.16'
@@ -1286,7 +1286,8 @@ def do_multiprocessing(data, temp_data, old_data, engine_dict):
engine_dict[family].warnings,
engine_dict[family].linenumbers,
engine_dict[family].lookbehind,
- keeptemps, hashdependencies)'''
+ keeptemps, hashdependencies,
+ pygments_settings)'''
tasks.append(pool.apply_async(run_code, [encoding, outputdir,
workingdir, code_dict[key],
engine_dict[family].language,
@@ -1299,7 +1300,8 @@ def do_multiprocessing(data, temp_data, old_data, engine_dict):
engine_dict[family].warnings,
engine_dict[family].linenumbers,
engine_dict[family].lookbehind,
- keeptemps, hashdependencies]))
+ keeptemps, hashdependencies,
+ pygments_settings]))
if verbose:
print(' - Code process ' + key.replace('#', ':'))
@@ -1475,7 +1477,7 @@ def do_multiprocessing(data, temp_data, old_data, engine_dict):
def run_code(encoding, outputdir, workingdir, code_list, language, commands,
command_created, extension, makestderr, stderrfilename,
code_index, errorsig, warningsig, linesig, stderrlookbehind,
- keeptemps, hashdependencies):
+ keeptemps, hashdependencies, pygments_settings):
'''
Function for multiprocessing code files
'''
@@ -1526,7 +1528,10 @@ def run_code(encoding, outputdir, workingdir, code_list, language, commands,
exec_cmd = shlex.split(bytes(command.format(file=script.replace('\\', '\\\\'), File=script_full.replace('\\', '\\\\'), workingdir=workingdir.replace('\\', '\\\\'))))
exec_cmd = [unicode(elem) for elem in exec_cmd]
else:
- exec_cmd = shlex.split(command.format(file=script.replace('\\', '\\\\'), File=script_full.replace('\\', '\\\\'), workingdir=workingdir.replace('\\', '\\\\')))
+ if family != 'juliacon':
+ exec_cmd = shlex.split(command.format(file=script.replace('\\', '\\\\'), File=script_full.replace('\\', '\\\\'), workingdir=workingdir.replace('\\', '\\\\')))
+ else:
+ exec_cmd = shlex.split(command.format(file=script.replace('\\', '/'), File=script_full.replace('\\', '/'), workingdir=workingdir.replace('\\', '/')))
# Add any created files due to the command
# This needs to be done before attempts to execute, to prevent orphans
try:
@@ -1563,6 +1568,22 @@ def run_code(encoding, outputdir, workingdir, code_list, language, commands,
messages.append(' Missing output file for ' + key_run.replace('#', ':'))
errors += 1
else:
+ if family == 'juliacon':
+ with open(out_file_name.rsplit('.', 1)[0] + '.tex', 'r', encoding=encoding) as f:
+ tex_data_lines = f.readlines()
+ inst = 0
+ for n, line in enumerate(tex_data_lines):
+ if line.rstrip() == '\\begin{juliaterm}':
+ tex_data_lines[n] = '=>PYTHONTEX:STDOUT#{0}#code#\n'.format(inst)
+ inst += 1
+ if n != 0:
+ tex_data_lines[n-1] = ''
+ if line.rstrip() == '\\end{juliaterm}':
+ tex_data_lines[n] = ''
+ tex_data_lines.append('=>PYTHONTEX:DEPENDENCIES#\n=>PYTHONTEX:CREATED#\n')
+ with open(out_file_name, 'w', encoding=encoding) as f:
+ f.write(''.join(tex_data_lines))
+
f = open(out_file_name, 'r', encoding=encoding)
out = f.read()
f.close()
@@ -1619,6 +1640,18 @@ def run_code(encoding, outputdir, workingdir, code_list, language, commands,
else:
dependencies[dep] = (os.path.getmtime(dep_file), '')
+ if family == 'juliacon':
+ from pygments import highlight
+ from pygments.lexers import get_lexer_by_name
+ from pygments.formatters import LatexFormatter
+ formatter = dict()
+ lexer = dict()
+ for codetype in pygments_settings:
+ if codetype != ':GLOBAL':
+ p = pygments_settings[codetype]['formatter_options'].copy()
+ p['commandprefix'] = 'PYG'
+ formatter[codetype] = LatexFormatter(**p)
+ lexer[codetype] = get_lexer_by_name(pygments_settings[codetype]['lexer'], **p)
for block in out.split('=>PYTHONTEX:STDOUT#')[1:]:
if block:
delims, content = block.split('#\n', 1)
@@ -1649,6 +1682,8 @@ def run_code(encoding, outputdir, workingdir, code_list, language, commands,
# Remove newline added by printing, prevent
# LaTeX from adding a space after content
content = content.rsplit('\n', 1)[0] + '\\endinput\n'
+ if family == 'juliacon':
+ content = highlight(content, lexer[family], formatter[family])
f.write(content)
f.close()
files.append(fname)
@@ -1658,6 +1693,8 @@ def run_code(encoding, outputdir, workingdir, code_list, language, commands,
messages.append('* PythonTeX error')
messages.append(' Missing stderr file for ' + key_run.replace('#', ':'))
errors += 1
+ elif family == 'juliacon':
+ pass
else:
# Open error and code files.
f = open(err_file_name, encoding=encoding)
@@ -2408,7 +2445,10 @@ def python_console(jobname, encoding, outputdir, workingdir, fvextfile,
sys.excepthook = sys.__excepthook__
old_stdout = sys.stdout
sys.stdout = self.iostdout
- self.interact(self.banner)
+ if sys.version_info.major == 3 and sys.version_info.minor >= 6:
+ self.interact(self.banner, exitmsg='')
+ else:
+ self.interact(self.banner)
sys.stdout = old_stdout
self.session_log = self.iostdout.getvalue()
diff --git a/Master/texmf-dist/scripts/pythontex/pythontex_2to3.py b/Master/texmf-dist/scripts/pythontex/pythontex_2to3.py
index 166e6784676..442309c86b1 100755
--- a/Master/texmf-dist/scripts/pythontex/pythontex_2to3.py
+++ b/Master/texmf-dist/scripts/pythontex/pythontex_2to3.py
@@ -4,30 +4,30 @@
'''
Convert PythonTeX scripts from Python 2 to Python 3
-It isn't possible to have a single PythonTeX code base, since unicode text
-needs to be supported. Under Python 2, this means importing unicode_literals
+It isn't possible to have a single PythonTeX code base, since unicode text
+needs to be supported. Under Python 2, this means importing unicode_literals
from __future__, or using the unicode function or "u" prefix. Under Python 3,
all strings are automatically unicode.
-At the same time, the differences between the Python 2 and 3 versions are
+At the same time, the differences between the Python 2 and 3 versions are
usually very small, involving only a few lines of code. To keep the code base
-unified, while simultaneously fully supporting both Python 2 and 3, the
-following scheme was devised. The code is written for Python 2. Whenever
-code is not compatible with Python 3, it is enclosed with the tags
-"#// Python 2" and "#\\ End Python 2" (each on its own line, by itself). If
-a Python 3 version of the code is needed, it is included between analogous
-tags "#// Python 3" and "#\\ End Python 2". The Python 3 code is commented
+unified, while simultaneously fully supporting both Python 2 and 3, the
+following scheme was devised. The code is written for Python 2. Whenever
+code is not compatible with Python 3, it is enclosed with the tags
+"#// Python 2" and "#\\ End Python 2" (each on its own line, by itself). If
+a Python 3 version of the code is needed, it is included between analogous
+tags "#// Python 3" and "#\\ End Python 2". The Python 3 code is commented
out with "#", at the same indentation level as the Python 3 tags.
-This script creates Python 3 scripts from the original Python 2 scripts
-by commenting out everything between the Python 2 tags, and uncommenting
-everything between the Python 3 tags. In this way, full compatibility is
-maintained with both Python 2 and 3 while keeping the code base essentially
-unified. This approach also allows greater customization of version-specific
-code than would be possible if automatic translation with a tool like 2to3
+This script creates Python 3 scripts from the original Python 2 scripts
+by commenting out everything between the Python 2 tags, and uncommenting
+everything between the Python 3 tags. In this way, full compatibility is
+maintained with both Python 2 and 3 while keeping the code base essentially
+unified. This approach also allows greater customization of version-specific
+code than would be possible if automatic translation with a tool like 2to3
was required.
-Copyright (c) 2012-2014, Geoffrey M. Poore
+Copyright (c) 2012-2017, Geoffrey M. Poore
All rights reserved.
Licensed under the BSD 3-Clause License:
http://www.opensource.org/licenses/BSD-3-Clause
@@ -50,7 +50,7 @@ def from2to3(list_of_code):
in_2 = False
in_3 = False
indent = ''
-
+
for line in list_of_code:
if r'#// Python 2' in line:
in_2 = True
@@ -70,8 +70,8 @@ def from2to3(list_of_code):
if fixed[0].startswith('#!/usr/bin/env python2'):
fixed[0] = fixed[0].replace('python2', 'python3')
return fixed
-
-
+
+
for file in files_to_process:
f = open(file, 'r', encoding=encoding)
converted_code = from2to3(f.readlines())
diff --git a/Master/texmf-dist/scripts/pythontex/pythontex_engines.py b/Master/texmf-dist/scripts/pythontex/pythontex_engines.py
index 6bcbd1690db..38fea5efc43 100755
--- a/Master/texmf-dist/scripts/pythontex/pythontex_engines.py
+++ b/Master/texmf-dist/scripts/pythontex/pythontex_engines.py
@@ -17,7 +17,7 @@ document (script for execution).
-Copyright (c) 2012-2016, Geoffrey M. Poore
+Copyright (c) 2012-2017, Geoffrey M. Poore
All rights reserved.
Licensed under the BSD 3-Clause License:
http://www.opensource.org/licenses/BSD-3-Clause
@@ -1113,6 +1113,12 @@ CodeEngine('julia', 'julia', '.jl', '{julia} "{file}.jl"', julia_template,
SubCodeEngine('julia', 'jl')
+CodeEngine('juliacon', 'julia', '.jl', '{julia} -e "using Weave; weave(\\"{File}.jl\\", \\"tex\\")"', '{body}\n',
+ '#+ term=true\n{code}\n', '', '',
+ 'ERROR:', 'WARNING:', ':{number}', True, created='{File}.tex')
+
+
+
octave_template = '''
@@ -1285,42 +1291,133 @@ CodeEngine('bash', 'bash', '.sh',
rust_template = '''
// -*- coding: utf-8 -*-
- #![allow(dead_code)]
- #![allow(unused_imports)]
-
-
+ #![allow(dead_code, unused_imports)]
+ #[warn(unused_imports)]
mod rust_tex_utils {{
- use std::fmt;
- use std::collections;
- use std::io::prelude::*;
-
- pub struct RustTeXUtils {{
- _formatter: Box<FnMut(&fmt::Display) -> String>,
- _before: Box<FnMut()>,
- _after: Box<FnMut()>,
- pub family: &'static str,
- pub session: &'static str,
- pub restart: &'static str,
- pub dependencies: Vec<String>,
- pub created: Vec<String>,
- pub command: &'static str,
- pub context: collections::HashMap<&'static str, &'static str>,
- pub args: collections::HashMap<&'static str, &'static str>,
- pub instance: &'static str,
- pub line: &'static str,
+ use std::{{borrow, collections, fmt, fs, io, iter, ops, path}};
+ use self::OpenMode::{{ReadMode, WriteMode, AppendMode, TruncateMode, CreateMode, CreateNewMode}};
+ pub struct UserAction<'u> {{
+ _act: Box<FnMut() + 'u>
}}
-
- impl RustTeXUtils {{
+ impl<'u> UserAction<'u> {{
+ pub fn new() -> Self {{
+ Self::from(|| {{}})
+ }}
+ pub fn act(&mut self) {{
+ (self._act)();
+ }}
+ pub fn set<F: FnMut() + 'u>(&mut self, f: F) {{
+ self._act = Box::new(f);
+ }}
+ }}
+ impl<'u> Default for UserAction<'u> {{
+ fn default() -> Self {{
+ Self::new()
+ }}
+ }}
+ impl<'u, F: FnMut() + 'u> From<F> for UserAction<'u> {{
+ fn from(f: F) -> Self {{
+ UserAction {{ _act: Box::new(f) }}
+ }}
+ }}
+ impl<'u, U: Into<UserAction<'u>> + 'u> ops::Add<U> for UserAction<'u> {{
+ type Output = UserAction<'u>;
+ fn add(self, f: U) -> Self::Output {{
+ let mut self_act: Box<FnMut() + 'u> = self._act;
+ let mut other_act: Box<FnMut() + 'u> = f.into()._act;
+ Self::from(move || {{ self_act.as_mut()(); other_act.as_mut()(); }})
+ }}
+ }}
+ impl<'u, F: Into<UserAction<'u>> + 'u> iter::FromIterator<F> for UserAction<'u> {{
+ fn from_iter<T>(iter: T) -> Self where T: IntoIterator<Item = F> {{
+ let mut others: Vec<Self> = iter.into_iter().map(F::into).collect();
+ Self::from(move || {{ for other in others.iter_mut() {{ other.act(); }} }})
+ }}
+ }}
+ impl<'u> ops::Deref for UserAction<'u> {{
+ type Target = FnMut() + 'u;
+ fn deref(&self) -> &Self::Target {{
+ &*self._act
+ }}
+ }}
+ impl<'u> ops::DerefMut for UserAction<'u> {{
+ fn deref_mut(&mut self) -> &mut Self::Target {{
+ &mut *self._act
+ }}
+ }}
+ pub struct RustTeXUtils<'u> {{
+ _formatter: Box<FnMut(&fmt::Display) -> String + 'u>,
+ pub before: UserAction<'u>,
+ pub after: UserAction<'u>,
+ pub family: &'u str,
+ pub session: &'u str,
+ pub restart: &'u str,
+ pub dependencies: collections::HashSet<borrow::Cow<'u, path::Path>>,
+ pub created: collections::HashSet<borrow::Cow<'u, path::Path>>,
+ pub command: &'u str,
+ pub context: collections::HashMap<&'u str, borrow::Cow<'u, str>>,
+ pub args: collections::HashMap<&'u str, borrow::Cow<'u, str>>,
+ pub instance: &'u str,
+ pub line: &'u str,
+ }}
+ #[derive(Clone,Copy,Debug,Hash,PartialEq,Eq)]
+ pub enum OpenMode {{
+ /// Open the file for reading
+ ReadMode,
+ /// Open the file for writing
+ WriteMode,
+ /// Open the file for appending
+ AppendMode,
+ /// Truncate the file before opening
+ TruncateMode,
+ /// Create the file before opening if necessary
+ CreateMode,
+ /// Always create the file before opening
+ CreateNewMode,
+ }}
+ pub mod open_mode {{
+ pub use super::OpenMode::{{self, ReadMode, WriteMode, AppendMode, TruncateMode, CreateMode, CreateNewMode}};
+ pub const R: &'static [OpenMode] = &[ReadMode];
+ pub const W: &'static [OpenMode] = &[WriteMode];
+ pub const A: &'static [OpenMode] = &[AppendMode];
+ pub const WC: &'static [OpenMode] = &[WriteMode, CreateMode];
+ pub const CW: &'static [OpenMode] = WC;
+ pub const AC: &'static [OpenMode] = &[AppendMode, CreateMode];
+ pub const CA: &'static [OpenMode] = AC;
+ pub const WT: &'static [OpenMode] = &[WriteMode, TruncateMode];
+ pub const TW: &'static [OpenMode] = WT;
+ pub const WCT: &'static [OpenMode] = &[WriteMode, CreateMode, TruncateMode];
+ pub const WTC: &'static [OpenMode] = WCT;
+ pub const CWT: &'static [OpenMode] = WCT;
+ pub const CTW: &'static [OpenMode] = WCT;
+ pub const TWC: &'static [OpenMode] = WCT;
+ pub const TCW: &'static [OpenMode] = WCT;
+ pub const WN: &'static [OpenMode] = &[WriteMode, CreateNewMode];
+ pub const NW: &'static [OpenMode] = WN;
+ pub const AN: &'static [OpenMode] = &[AppendMode, CreateNewMode];
+ pub const NA: &'static [OpenMode] = AN;
+ }}
+ impl OpenMode {{
+ /// The same options as `fs::File::open`.
+ pub fn open() -> &'static [OpenMode] {{
+ open_mode::R
+ }}
+ /// The same options as `fs::File::create`.
+ pub fn create() -> &'static [OpenMode] {{
+ open_mode::WCT
+ }}
+ }}
+ impl<'u> RustTeXUtils<'u> {{
pub fn new() -> Self {{
RustTeXUtils {{
_formatter: Box::new(|x: &fmt::Display| format!("{{}}", x)),
- _before: Box::new(|| {{}}),
- _after: Box::new(|| {{}}),
+ before: UserAction::new(),
+ after: UserAction::new(),
family: "{family}",
session: "{session}",
restart: "{restart}",
- dependencies: Vec::new(),
- created: Vec::new(),
+ dependencies: collections::HashSet::new(),
+ created: collections::HashSet::new(),
command: "",
context: collections::HashMap::new(),
args: collections::HashMap::new(),
@@ -1328,53 +1425,69 @@ rust_template = '''
line: "",
}}
}}
-
-
pub fn formatter<A: fmt::Display>(&mut self, x: A) -> String {{
- (*self._formatter)(&x)
+ (self._formatter)(&x)
}}
- pub fn set_formatter<F: FnMut(&fmt::Display) -> String + 'static>(&mut self, f: F) {{
+ pub fn set_formatter<F: FnMut(&fmt::Display) -> String + 'u>(&mut self, f: F) {{
self._formatter = Box::new(f);
}}
-
- pub fn before(&mut self) {{
- (*self._before)();
- }}
- pub fn set_before<F: FnMut() + 'static>(&mut self, f: F) {{
- self._before = Box::new(f);
+ pub fn add_dependencies<SS: IntoIterator>(&mut self, deps: SS)
+ where SS::Item: Into<borrow::Cow<'u, path::Path>>
+ {{
+ self.dependencies.extend(deps.into_iter().map(SS::Item::into));
}}
-
- pub fn after(&mut self) {{
- (*self._after)();
- }}
- pub fn set_after<F: FnMut() + 'static>(&mut self, f: F) {{
- self._after = Box::new(f);
- }}
-
- pub fn add_dependencies<SS: IntoIterator>(&mut self, deps: SS) where SS::Item: Into<String> {{
- self.dependencies.append(&mut deps.into_iter().map(|x| x.into()).collect());
+ pub fn add_created<SS: IntoIterator>(&mut self, crts: SS)
+ where SS::Item: Into<borrow::Cow<'u, path::Path>>
+ {{
+ self.created.extend(crts.into_iter().map(SS::Item::into));
}}
-
- pub fn add_created<SS: IntoIterator>(&mut self, crts: SS) where SS::Item: Into<String> {{
- self.created.append(&mut crts.into_iter().map(|x| x.into()).collect());
+ pub fn open<P: 'u, O>(&mut self, name: P, options: O) -> io::Result<fs::File>
+ where P: AsRef<path::Path>,
+ O: IntoIterator,
+ O::Item: borrow::Borrow<OpenMode>
+ {{
+ let opts = options.into_iter()
+ .map(|x| *<O::Item as borrow::Borrow<OpenMode>>::borrow(&x))
+ .collect::<collections::HashSet<OpenMode>>();
+ let mut options = fs::OpenOptions::new();
+ if opts.contains(&ReadMode) {{
+ options.read(true);
+ self.add_dependencies(iter::once(name.as_ref().to_owned()));
+ }}
+ if opts.contains(&WriteMode) {{
+ options.write(true);
+ }}
+ if opts.contains(&AppendMode) {{
+ options.append(true);
+ }}
+ if opts.contains(&TruncateMode) {{
+ options.truncate(true);
+ }}
+ if opts.contains(&CreateMode) {{
+ options.create(true);
+ self.add_created(iter::once(name.as_ref().to_owned()));
+ }}
+ if opts.contains(&CreateNewMode) {{
+ options.create_new(true);
+ self.add_created(iter::once(name.as_ref().to_owned()));
+ }}
+ options.open(name)
}}
-
pub fn cleanup(self) {{
println!("{{}}", "{dependencies_delim}");
for x in self.dependencies {{
- println!("{{}}", x);
+ println!("{{}}", x.to_str().expect(&format!("could not properly display path ({{:?}})", x)));
}}
println!("{{}}", "{created_delim}");
for x in self.created {{
- println!("{{}}", x);
+ println!("{{}}", x.to_str().expect(&format!("could not properly display path ({{:?}})", x)));
}}
}}
-
- pub fn setup_wrapper(&mut self, cmd: &'static str, cxt: &'static str, ags: &'static str, ist: &'static str, lne: &'static str) {{
- fn parse_map(kvs: &'static str) -> collections::HashMap<&'static str, &'static str> {{
+ pub fn setup_wrapper(&mut self, cmd: &'u str, cxt: &'u str, ags: &'u str, ist: &'u str, lne: &'u str) {{
+ fn parse_map<'w>(kvs: &'w str) -> collections::HashMap<&'w str, borrow::Cow<'w, str>> {{
kvs.split(',').filter(|s| !s.is_empty()).map(|kv| {{
let (k, v) = kv.split_at(kv.find('=').expect(&format!("Error parsing supposed key-value pair ({{}})", kv)));
- (k.trim(), v[1..].trim())
+ (k.trim(), v[1..].trim().into())
}}).collect()
}}
self.command = cmd;
@@ -1384,24 +1497,23 @@ rust_template = '''
self.line = lne;
}}
}}
+ impl<'u> Default for RustTeXUtils<'u> {{
+ fn default() -> Self {{
+ Self::new()
+ }}
+ }}
}}
-
-
- use std::{{io, fmt, env, path, ffi, collections}};
+ use std::{{borrow, collections, env, ffi, fmt, fs, hash, io, iter, ops, path}};
use std::io::prelude::*;
-
-
+ use rust_tex_utils::open_mode;
#[allow(unused_mut)]
fn main() {{
let mut rstex = rust_tex_utils::RustTeXUtils::new();
if env::set_current_dir(ffi::OsString::from("{workingdir}".to_string())).is_err() && env::args().all(|x| x != "--manual") {{
panic!("Could not change to the specified working directory ({workingdir})");
}}
-
{extend}
-
{body}
-
rstex.cleanup();
}}
'''
@@ -1410,20 +1522,21 @@ rust_wrapper = '''
rstex.setup_wrapper("{command}", "{context}", "{args}", "{instance}", "{line}");
println!("{stdoutdelim}");
writeln!(io::stderr(), "{stderrdelim}").unwrap();
- rstex.before();
-
+ rstex.before.act();
{code}
-
- rstex.after();
+ rstex.after.act();
'''
-rust_sub = '''println!("{field_delim}");\nprintln!("{{}}", {field});\n'''
+rust_sub = '''
+ println!("{field_delim}");
+ println!("{{}}", {field});
+ '''
CodeEngine('rust', 'rust', '.rs',
# The full script name has to be used in order to make Windows and Unix behave nicely
# together when naming executables. Despite appearances, using `.exe` works on Unix too.
['{rustc} --crate-type bin -o {File}.exe -L {workingdir} {file}.rs', '{File}.exe'],
- rust_template, rust_wrapper, 'println!("{{}}", rstex.formatter({code}));', rust_sub,
+ rust_template, rust_wrapper, '{{ let val = {{ {code} }}; println!("{{}}", rstex.formatter(val)); }}', rust_sub,
errors='error:', warnings='warning:', linenumbers='.rs:{number}',
created='{File}.exe')
diff --git a/Master/texmf-dist/source/latex/pythontex/pythontex.dtx b/Master/texmf-dist/source/latex/pythontex/pythontex.dtx
index 7ec0af93c78..d91e6e1eac0 100644
--- a/Master/texmf-dist/source/latex/pythontex/pythontex.dtx
+++ b/Master/texmf-dist/source/latex/pythontex/pythontex.dtx
@@ -1,6 +1,6 @@
% \iffalse meta-comment
%
-% Copyright (C) 2012-2016 by Geoffrey M. Poore <gpoore@gmail.com>
+% Copyright (C) 2012-2017 by Geoffrey M. Poore <gpoore@gmail.com>
% ---------------------------------------------------------------------------
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
@@ -26,7 +26,7 @@
%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
%<package>\ProvidesPackage{pythontex}
%<*package>
- [2016/07/21 v0.15 execute and typeset Python code and other languages]
+ [2017/07/20 v0.16 execute and typeset Python code and other languages]
%</package>
%
%<*driver>
@@ -134,7 +134,7 @@
%</driver>
% \fi
%
-% \CheckSum{3174}
+% \CheckSum{3218}
%
% \CharacterTable
% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
@@ -153,6 +153,16 @@
% Right brace \} Tilde \~}
%
%
+
+% \begin{changelog}{v0.16}{2017/07/20}
+% \begin{itemize}
+% \item Added preliminary console support for Julia (\#98).
+% \item Fixed Python console compatibility with Python 3.6 by setting the \texttt{code} module's new \texttt{exitmsg} argument to suppress the exit message (\#100).
+% \item Improved Rust support, including tracking of created files and dependencies (\#91).
+% \end{itemize}
+% \end{changelog}
+%
+%
% \begin{changelog}{v0.15}{2016/07/21}
% \textbf{New features}
% \begin{itemize}
@@ -1537,6 +1547,10 @@
%
% Julia exceptions are synchronized with the document, but the line numbering does not always correspond to the Python equivalent. This is because Julia allows expressions to be continued on subsequent lines in ways that Python does not.
%
+% \subsubsection*{Console}
+%
+% Preliminary Julia console support was added in v0.16, under the base name |juliacon|. Unlike the Python console environments that allow invalid input, currently everything entered in a |juliaconsole| environment must be valid. The Julia console uses \href{https://github.com/mpastell/Weave.jl}{\textsf{Weave.jl}} internally to evaluate code, and it currently does not support invalid input.
+%
%
% \subsection{Octave}
%
@@ -1566,7 +1580,11 @@
%
% Because Rust typically gives a long sequence of errors, \pytex\ processing and synchronization of |stderr| is currently verbose and may need to be improved in the future as well. There is no support for encodings other than UTF-8. Currently, executables always use the |.exe| extension, even under non-Windows systems.
%
-% When using |\rust| and |\rs|, keep in mind that these wrap code in |rstex.formatter()|. Because |rstex| is mutable, accessing its fields within |rstex.formatter()| will require |&rstex.|\meta{field}|.to_string()| or similar.
+% Due to the way |rstex| is used in template-generated code, it needs to remain a mutable local variable. This means that, while there should be no problem using it through either shared or mutable references, taking it by value requires that the ``altered'' copy is reassigned to a new variable that shadows the old one. That is, code that needs to work with |rstex| by value should look like
+% \begin{Verbatim}[commandchars=\\\{\}, gobble=2]
+% let mut rstex = \meta{code};
+% \end{Verbatim}
+% Additionally, when using |\rust| and |\rs|, keep in mind that these wrap code in a block, so you \emph{cannot} use |rstex| by value in these contexts (both shared and mutable references are still fine, though).
%
%
% \subsection{Adding support for a new language}
@@ -1795,7 +1813,7 @@
% We store the name of the package in a macro for later use in warnings and error messages.
% \begin{macrocode}
\newcommand{\pytx@packagename}{PythonTeX}
-\newcommand{\pytx@packageversion}{0.15}
+\newcommand{\pytx@packageversion}{0.16}
% \end{macrocode}
%
% \subsection{Required packages}
@@ -4063,6 +4081,24 @@
\ifstrequal{#1}{ruby}{\makepythontexfamily[pyglexer=ruby]{ruby}}{}%
\ifstrequal{#1}{rb}{\makepythontexfamily[pyglexer=ruby]{rb}}{}%
\ifstrequal{#1}{julia}{\makepythontexfamily[pyglexer=julia]{julia}}{}%
+ \ifstrequal{#1}{juliacon}{\pgfkeys{/PYTX/family, name=juliacon, default, pyglexer=jlcon}%
+ \expandafter\xdef\csname pytx@macroformatter@juliacon\endcsname{\pytx@tmp@pprinter}%
+ \expandafter\gdef\csname pytx@fvsettings@juliacon\endcsname{}%
+ \expandafter\xdef\csname pytx@pyglexer@juliacon\endcsname{\pytx@tmp@pyglexer}%
+ \expandafter\xdef\csname pytx@pygopt@juliacon\endcsname{\pytx@tmp@pygopt}%
+ \expandafter\xdef\csname pytx@console@juliacon\endcsname{\pytx@tmp@console}%
+ \AtEndDocument{\immediate\write\pytx@codefile{pygfamily=juliacon|%
+ \csname pytx@pyglexer@juliacon\endcsname|%
+ \csname pytx@pygopt@juliacon\endcsname}%
+ }%
+ \pytx@MakeCodeFV{juliacon}%
+ \newenvironment{juliaconsole}%
+ {\VerbatimEnvironment
+ \def\pytx@type{juliacon}%
+ \pytx@ConfigPygments
+ \begin{juliaconcode}}%
+ {\end{juliaconcode}%
+ \ifbool{pytx@opt@autoprint}{}{\printpythontex{}}}}{}%
\ifstrequal{#1}{jl}{\makepythontexfamily[pyglexer=julia]{jl}}{}%
\ifstrequal{#1}{matlab}{\makepythontexfamily[pyglexer=matlab]{matlab}}{}%
\ifstrequal{#1}{octave}{\makepythontexfamily[pyglexer=octave]{octave}}{}%
diff --git a/Master/texmf-dist/tex/latex/pythontex/pythontex.sty b/Master/texmf-dist/tex/latex/pythontex/pythontex.sty
index 8331043359b..1300db470fc 100644
--- a/Master/texmf-dist/tex/latex/pythontex/pythontex.sty
+++ b/Master/texmf-dist/tex/latex/pythontex/pythontex.sty
@@ -20,10 +20,11 @@
%%
\NeedsTeXFormat{LaTeX2e}[1999/12/01]
\ProvidesPackage{pythontex}
- [2016/07/21 v0.15 execute and typeset Python code and other languages]
+ [2017/07/20 v0.16 execute and typeset Python code and other languages]
+
\newcommand{\pytx@packagename}{PythonTeX}
-\newcommand{\pytx@packageversion}{0.15}
+\newcommand{\pytx@packageversion}{0.16}
\RequirePackage{fvextra}
\RequirePackage{etoolbox}
\RequirePackage{xstring}
@@ -1317,6 +1318,24 @@
\ifstrequal{#1}{ruby}{\makepythontexfamily[pyglexer=ruby]{ruby}}{}%
\ifstrequal{#1}{rb}{\makepythontexfamily[pyglexer=ruby]{rb}}{}%
\ifstrequal{#1}{julia}{\makepythontexfamily[pyglexer=julia]{julia}}{}%
+ \ifstrequal{#1}{juliacon}{\pgfkeys{/PYTX/family, name=juliacon, default, pyglexer=jlcon}%
+ \expandafter\xdef\csname pytx@macroformatter@juliacon\endcsname{\pytx@tmp@pprinter}%
+ \expandafter\gdef\csname pytx@fvsettings@juliacon\endcsname{}%
+ \expandafter\xdef\csname pytx@pyglexer@juliacon\endcsname{\pytx@tmp@pyglexer}%
+ \expandafter\xdef\csname pytx@pygopt@juliacon\endcsname{\pytx@tmp@pygopt}%
+ \expandafter\xdef\csname pytx@console@juliacon\endcsname{\pytx@tmp@console}%
+ \AtEndDocument{\immediate\write\pytx@codefile{pygfamily=juliacon|%
+ \csname pytx@pyglexer@juliacon\endcsname|%
+ \csname pytx@pygopt@juliacon\endcsname}%
+ }%
+ \pytx@MakeCodeFV{juliacon}%
+ \newenvironment{juliaconsole}%
+ {\VerbatimEnvironment
+ \def\pytx@type{juliacon}%
+ \pytx@ConfigPygments
+ \begin{juliaconcode}}%
+ {\end{juliaconcode}%
+ \ifbool{pytx@opt@autoprint}{}{\printpythontex{}}}}{}%
\ifstrequal{#1}{jl}{\makepythontexfamily[pyglexer=julia]{jl}}{}%
\ifstrequal{#1}{matlab}{\makepythontexfamily[pyglexer=matlab]{matlab}}{}%
\ifstrequal{#1}{octave}{\makepythontexfamily[pyglexer=octave]{octave}}{}%
diff --git a/Master/tlpkg/bin/tlpkg-ctan-check b/Master/tlpkg/bin/tlpkg-ctan-check
index 26412f3a4a4..6590c211901 100755
--- a/Master/tlpkg/bin/tlpkg-ctan-check
+++ b/Master/tlpkg/bin/tlpkg-ctan-check
@@ -744,6 +744,7 @@ my @TLP_no_check = (
"lcdftypetools", # binary
"luatex", # binary
"makeindex", # binary
+ "malayalam-latex", # binary
"metafont", # binary
"metapost", # binary
"mex", # gust, requested 2013
diff --git a/Master/tlpkg/libexec/ctan2tds b/Master/tlpkg/libexec/ctan2tds
index e198c214469..da1ccac4ecc 100755
--- a/Master/tlpkg/libexec/ctan2tds
+++ b/Master/tlpkg/libexec/ctan2tds
@@ -135,6 +135,7 @@ chomp ($Build = `cd $Master/../Build/source && pwd`);
'aurora', "die 'skipping, nocommercial license'",
'auto1', "die 'skipping, nonfree font support'",
'autolatex', "die 'skipping, not self-locating'",
+ 'autosp', "die 'skipping, awaiting tl18!'",
'autotab', "die 'skipping, noinfo license, latex 2.09'",
'babel-frenchb', "die 'skipping, use babel-french'",
'babel-serbianc', "&MAKEflatten",
@@ -763,6 +764,7 @@ chomp ($Build = `cd $Master/../Build/source && pwd`);
'mpdinbrief', "die 'skipping, nosell license'",
'mptopdf', "&MAKEcopy",
'msuthesis', "die 'skipping, use msu-thesis'",
+ 'msu-thesis', "die 'skipping, awaiting next package release'",
'mtp2lite', "die 'skipping, nonfree'",
'mtx', "die 'skipping, pascal musixtex binaries'",
'multibox', "die 'skipping, noinfo license, author deceased'",