├── NEWS.rst ├── README.rst ├── pythontex ├── README ├── depythontex.bat ├── depythontex.py ├── depythontex2.py ├── depythontex3.py ├── pythontex.bat ├── pythontex.dtx ├── pythontex.ins ├── pythontex.pdf ├── pythontex.py ├── pythontex.sty ├── pythontex2.py ├── pythontex3.py ├── pythontex_2to3.py ├── pythontex_engines.py ├── pythontex_install.bat ├── pythontex_install.py ├── pythontex_utils.py └── syncpdb.py ├── pythontex_gallery ├── make_pythontex_gallery_html2.py ├── make_pythontex_gallery_html3.py ├── myplot.png ├── pythontex_gallery.html ├── pythontex_gallery.pdf ├── pythontex_gallery.tex └── pythontex_gallery_2to3.py ├── pythontex_quickstart ├── pythontex_quickstart.pdf └── pythontex_quickstart.tex └── test ├── R ├── R_test.tex └── Rcon_test.tex ├── bash └── bash_test.tex ├── javascript └── javascript_test.tex ├── julia ├── julia_test.tex └── juliacon_test.tex ├── octave └── octave_test.tex ├── perl └── perl_test.tex ├── perl6 └── perl6_test.tex ├── ruby └── ruby_test.tex └── rust └── rust_test.tex /NEWS.rst: -------------------------------------------------------------------------------- 1 | ================================================== 2 | PythonTeX News 3 | ================================================== 4 | 5 | 6 | Version History 7 | =============== 8 | 9 | 10 | v0.18 (2021/06/06) 11 | ------------------ 12 | 13 | * ``\inputpygments`` now checks inputted files for modification, so that 14 | typeset code will correctly update when the source is changed (#162). 15 | 16 | * Julia now uses project flag "``--project=@.``" (#157, #158). 17 | 18 | * Fixed bug in processing Pygments options (``pygopt``) when a key is used 19 | without a value (#181). 20 | 21 | * Some error handling for Windows was incompatible with other operating 22 | systems: replaced checks for ``WindowsError`` with checks for ``OSError`` 23 | (#177). 24 | 25 | * Rust support is now compatible with document and working directory paths 26 | that contain spaces (#167). 27 | 28 | 29 | 30 | v0.17 (2019/09/22) 31 | ------------------ 32 | 33 | * Pygments syntax highlighting for the Python console (``pycon`` lexer) now 34 | uses the ``python3`` option, and the default Python lexer is now 35 | ``python3`` (#156). 36 | 37 | * Added support for JavaScript (#147; thanks to Nathan Carter). 38 | 39 | * Updated Julia support for Julia versions 0.6 (#107), and 0.7 and 1.0 (#126, 40 | #130). 41 | 42 | * There are now meaningful error messages for the Julia console when Weave.jl 43 | is not installed or raises errors (#131). 44 | 45 | * ``pythontexcustomcode`` and ``\pythontexcustomc`` now set 46 | ``pytex.context`` (#65). 47 | 48 | * Added support for R. The ``R`` family of commands and environments 49 | (``\R``, ``\Rc``, ``Rcode``, ...) executes code as a script. 50 | There is currently no utilities class or equivalent. The ``Rcon`` family 51 | (``Rconsole``) executes code to emulate an interactive R session (#121). 52 | 53 | * ``fancyvrb`` settings from ``\setpythontexfv`` and console 54 | environments now work with Julia and R consoles. 55 | 56 | * ``pythontexcustomcode`` now works with ``juliacon``. There are now proper 57 | ``juliaconcode`` and ``Rconcode`` environments that execute code but 58 | typeset nothing, to parallel ``pyconcode`` (#134). 59 | 60 | * Added support for Perl with the ``perl`` and ``pl`` families of commands 61 | and environments. There is currently no utilities class or equivalent. 62 | 63 | * Added support for Perl 6 with the ``perlsix`` and ``psix`` families of 64 | commands and environments (#104). There is currently no utilities class or 65 | equivalent. 66 | 67 | * Updated Rust support by using ``dyn`` with traits in utilities object. 68 | 69 | * Under Windows, capitalization of script paths in ``stderr`` is now 70 | preserved. 71 | 72 | * Fixed a bug that prevented the ``sub`` environment from working with 73 | ``depythontex`` (#155). 74 | 75 | * Fixed a bug in checking mtime of dependencies to see if they have been 76 | modified while ``pythontex`` is running. The check failed for dependencies 77 | that do not exist or were deleted before ``pythontex`` can read them 78 | (#136). 79 | 80 | 81 | 82 | v0.16 (2017/07/20) 83 | ------------------ 84 | 85 | * Added preliminary console support for Julia (#98). 86 | 87 | * Fixed Python console compatibility with Python 3.6 by setting the ``code`` 88 | module's new ``exitmsg`` argument to suppress the exit message (#100). 89 | 90 | * Improved Rust support, including tracking of created files and 91 | dependencies (#91). 92 | 93 | 94 | 95 | v0.15 (2016/07/21) 96 | ------------------ 97 | 98 | New features 99 | ~~~~~~~~~~~~ 100 | 101 | * The ``fvextra`` package is now required. This provides line breaking with 102 | fine-grained control over break locations, the ability to highlight 103 | specific lines or ranges of lines, improved handling of tabs, and several 104 | additional features. 105 | 106 | * Added ``sub`` commands and environments (``\pys``, ``pysub``, ...). These 107 | commands and environments perform string interpolation on text. Fields 108 | delimited by ``!{...}`` are replaced by the result of evaluating and then 109 | printing their content. This works for all families of commands and 110 | environments, not just Python. See the documentation for details about 111 | field delimiters and escaping. 112 | 113 | * Added ``rust`` and ``rs`` families of commands and environments. These 114 | provide essentially complete support for Rust, except that 115 | ``rstex.formatter()``, ``rstex.before()``, and ``rstex.after()`` will 116 | likely need additional refinement (#90). 117 | 118 | * Added the ``sage`` family of commands and environments, which provide 119 | support for Sage (#63). 120 | 121 | * Added ``bash`` family of commands and environments. This provides basic 122 | support for bash (no utilities class or equivalent). Bash works with 123 | Windows if it is installed. 124 | 125 | * Improved ``console`` compatibility under Linux with Python 3 (#70). 126 | 127 | * Counters for default sessions are now created automatically. This prevents 128 | counter errors under some circumstances when working with ``\includeonly``. 129 | 130 | * Commands like ``\py`` can now output verbatim content under LuaTeX. 131 | 132 | Bugfixes 133 | ~~~~~~~~ 134 | 135 | * Fixed a bug that could cause an endless loop when a ``code`` command or 136 | environment printed a ``code`` command or environment of the same family 137 | with ``autoprint=true``. 138 | 139 | 140 | 141 | v0.14 (2014/07/17) 142 | ------------------ 143 | 144 | New features 145 | ~~~~~~~~~~~~ 146 | 147 | * All commands for working with code inline are now robust, via 148 | ``etoolbox``'s ``\newrobustcmd``. Among other things, this allows 149 | commands like ``\py`` to work in standard captions that have not been 150 | redefined to avoid protection issues. 151 | * Upgraded ``syncpdb`` to v0.2, which provides better list formatting. 152 | 153 | Backward-incompatible changes 154 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 155 | 156 | * The default working directory is now the main document directory instead 157 | of the output directory. Using the output directory was a common source 158 | of confusion for new users and was incompatible with plans for future 159 | development. Old documents in which the working directory was not 160 | specified will continue to use the output directory, but PythonTeX will 161 | print an upgrade message; new documents will use the new setting. The 162 | output directory may be selected as the working directory manually, or 163 | with the shorthand 164 | "``\setpythontexworkingdir{}``". 165 | 166 | * Standardized version numbering by removing the "v" prefix from the stored 167 | version numbers in Python variables and LaTeX macros. Standardized the 168 | PythonTeX scripts by renaming ``version`` to ``__version__``. 169 | 170 | 171 | 172 | v0.13 (2014/07/14) 173 | ------------------ 174 | 175 | New features 176 | ~~~~~~~~~~~~ 177 | 178 | * Added ``--interactive`` command-line option. This runs a single 179 | session in interactive mode, allowing user input. Among other things, 180 | this is useful when working with debuggers. 181 | 182 | * Added ``--debug`` command-line option. This runs a single session 183 | with the default debugger in interactive mode. Currently, only 184 | standard (non-console) Python sessions are supported. The default 185 | Python debugger is the new ``syncpdb``, which wraps ``pdb`` and 186 | synchronizes code line numbers with document line numbers. All 187 | ``pdb`` commands that take a line number or filename:lineno as an 188 | argument will refer to document files and line numbers when the 189 | argument has a percent symbol (``%``) as a prefix. For example, 190 | ``list %50`` lists code that came from around line 50 in the 191 | document. The ``--debug`` option will support other languages and 192 | provide for customization in the future. 193 | 194 | * Added command-line option ``--jobs``, which allows the maximum number 195 | of concurrent processes to be specified (#35). 196 | 197 | * Added support for GNU Octave, via the ``octave`` family of commands 198 | and environments (#36). Parsing of Octave stderr is not ideal, though 199 | synchronization works in most cases; this will be addressed by a 200 | future rewrite of the stderr parser. 201 | 202 | * Installer now automatically works with MiKTeX, not just TeX Live. 203 | 204 | * The PythonTeX utilities class has a new ``open()`` method that opens 205 | files and automatically tracks dependencies/created files. 206 | 207 | * When ``pythontex2.py`` and ``pythontex3.py`` are run directly, the 208 | Python interpreter is automatically set to a reasonable default 209 | (``py -2`` or ``py -3`` under Windows, using the Python 3.3+ wrapper; 210 | ``python2`` or ``python3`` under other systems). 211 | 212 | * The installer now creates symlinks for the numbered scripts 213 | ``pythontex*.py`` and ``depythontex*.py``. 214 | 215 | * Added Python version checking to all numbered scripts. 216 | 217 | * Under Python, the type of data passed via ``\setpythontexcontext`` may 218 | now be set using YAML-style tags (``!!str``, ``!!int``, ``!!float``). For 219 | example, ``{myint=!!int 123}``. 220 | 221 | * The ``fancyvrb`` options ``firstline`` and ``lastline`` now work with 222 | the ``pygments`` environment and ``\inputpygments`` command. This required 223 | some additional patching of ``fancyvrb``. 224 | 225 | * The ``pytx@Verbatim`` and ``pytx@SaveVerbatim`` environments are now 226 | used for typesetting verbatim code. These are copies of the 227 | ``fancyvrb`` environments. This prevents conflicts when literal 228 | ``Verbatim`` and ``SaveVerbatim`` environments need to be typeset. 229 | 230 | * Improved ``latexmk`` compatibility (#40). Added discussion of 231 | ``latexmk`` usage to documentation. 232 | 233 | * Tildes ``~`` may now be used in ``outputdir`` and ``workingdir`` to 234 | refer to the user�s home directory, even under Windows. 235 | 236 | Bugfixes 237 | ~~~~~~~~ 238 | 239 | * Fixed a bug that prevented created files from being cleaned up when 240 | the working directory was not the document root directory and the 241 | full path to the files was not provided. 242 | 243 | * Fixed a bug that prevented the ``fvextfile`` option from working when 244 | external files were highlighted. 245 | 246 | 247 | 248 | v0.13-beta (2014/02/06) 249 | ----------------------- 250 | 251 | New features 252 | ~~~~~~~~~~~~ 253 | 254 | * Switching to GitHub's Releases for downloads. 255 | 256 | * TeX information such as page dimensions may now be easily passed to the 257 | programming-language side, using the new ``\setpythontexcontext`` command. 258 | Contextual information is stored in the ``context`` attribute of the 259 | utilities class, which is a dictionary (and also has attributes in Python). 260 | 261 | * The utilities class now has ``pt_to_in()``, ``pt_to_cm()``, and 262 | ``pt_to_mm()`` methods for converting units of TeX points into inches, 263 | centimeters, and millimeters. These work with integers and floats, as 264 | well as strings that consist of numbers and optionally end in "pt". There 265 | is also a ``pt_to_bp()`` for converting TeX points (1/72.27 inch) into big 266 | (DTP or PostScript) points (1/72 inch). 267 | 268 | * Expanded Quickstart. Quickstart is now compatible with all LaTeX engines. 269 | Quickstart now avoids ``microtype`` issues on some systems (#32). 270 | 271 | * Added information on citing PythonTeX (#28). 272 | 273 | * Utilities class has a new attribute ``id``, which is a string that joins 274 | the command family name, session name, and session restart parameters with 275 | underscores. This may be used in creating files that need a name that 276 | contains a unique, session-based identifier (for example, names for 277 | figures that are saved automatically). 278 | 279 | Backward-incompatible changes 280 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 281 | 282 | * All utilities-class attributes with names of the form ``input_*`` have 283 | been renamed with the "``input_``" removed. Among other things, this 284 | makes it easier to access the ``context`` attribute (``pytex.context`` 285 | vs. ``pytex.input_context``). 286 | 287 | * ``depythontex`` now has ``-o`` and ``--output`` command-line options for 288 | specifying the name of the output file. If an output file is not 289 | specified, then output is written to ``stdout``. This allows 290 | ``depythontex`` output to be piped to another program. 291 | 292 | * All scripts ``*2.py`` now have shebangs with ``env python2``, and all 293 | scripts ``*3.py`` now have shebangs with ``env python3``. This allows the 294 | wrapper scripts (``env python`` shebang) to be used with the default 295 | Python installation, and the numbered scripts to be used with specific 296 | versions. Remember that except for console content, the ``--interpreter`` 297 | option is what determines the Python version that actually executes code. 298 | The version of Python used to launch ``pythontex.py`` merely determines 299 | the version that manages code execution. (``--interpreter`` support for 300 | console content is coming.) 301 | 302 | * Changed the template style used in the ``CodeEngine`` class. Replacement 303 | fields are now surrounded by single curly braces (as in Python's format 304 | string syntax), rather than double curly braces. Literal curly braces are 305 | obtained by doubling braces. This allows the use of literal adjacent 306 | double braces in templates, which was not possible previously. 307 | 308 | * The Julia template now uses the new ``in()`` function, replacing 309 | ``contains()``. This requires Julia v0.2.0+. 310 | 311 | Bugfixes 312 | ~~~~~~~~ 313 | 314 | * Modified test for LuaTeX, so that ``\directlua`` is not ``\let`` to 315 | ``\relax`` if it does not exist. This was causing incompatibility with 316 | ``babel`` under pdfTeX and XeTeX (#33). 317 | 318 | * Added missing shebangs to ``depythontex*.py``. Handling of ``utilspath`` 319 | is now more forgiving, so that ``pythontex_utils.py`` can be installed in 320 | alternate locations (#23). 321 | 322 | * ``depythontex`` no longer leaves a blank line where 323 | ``\usepackage{pythontex}`` was removed. 324 | 325 | * Console environments typeset with ``fancyvrb`` no longer end with an 326 | unnecessary empty line. 327 | 328 | * Fixed bug in installer when ``kpsewhich`` was not found (#21). 329 | 330 | 331 | 332 | v0.12 (2013/08/26) 333 | ------------------ 334 | 335 | * Added support for the Julia language, with the ``julia`` and ``jl`` 336 | families of commands and environments. (Note that Pygments only added 337 | Julia support in version 1.6.) 338 | 339 | * Warnings and errors are now synchronized with the line numbers of files 340 | brought in via ``\input``, ``\include``, etc. This is accomplished using 341 | the ``currfile`` package. 342 | 343 | * Added package option ``gobble``. When ``gobble=auto``, all code is 344 | dedented before being executed and/or typeset. The current 345 | implementation is functional but basic; it will be improved and extended 346 | in the future. 347 | 348 | * The document root directory is now always added to ``sys.path`` (or its 349 | equivalent), even when it is not the working directory. (The working 350 | directory has been added to ``sys.path`` since v0.12beta.) The document 351 | directory is added after the working directory, so that the working 352 | directory has precedence. 353 | 354 | * Fixed a bug in ``console`` commands and environments; ``sys.path`` now 355 | contains the working and document directories, and the working directory 356 | is now the output directory by default. This parallels the behavior of 357 | non-``console`` commands and environments. 358 | 359 | * Added command-line option ``--interpreter`` that allows an interpreter to 360 | be invoked via a specific command. This allows, for example, a specific 361 | version of Python to be invoked. 362 | 363 | * Improved synchronization of stderr in cases when an error is triggered 364 | far after its origin (for example, an error caused by a multiline string 365 | that is lacking a closing quote/delimiter, and thus may span several 366 | chunks of user code). 367 | 368 | * Modified usage of the ``shlex`` module to work around its lack of Unicode 369 | support in Python versions prior to 2.7.3. 370 | 371 | * Fixed a bug from v0.12beta that prevented ``\inputpygments`` from working 372 | when ``pygments=true``. 373 | 374 | * Fixed a bug with counters that caused errors when content spanning 375 | multiple columns was created within a ``tabular`` environment. 376 | 377 | * Added checking for compatible Python versions in ``pythontex.py``. 378 | 379 | * Improved execution of ``*.bat`` and ``*.cmd`` files under Windows. The 380 | solution from v0.12beta allowed ``*.bat`` and ``*.cmd`` to be found and 381 | executed when the extension was not given, but did not give correct 382 | return codes. 383 | 384 | 385 | v0.12beta (2013/06/24) 386 | ---------------------- 387 | 388 | * Merged ``pythontex_types*.py`` into a single replacement 389 | ``pythontex_engines.py`` compatible with both Python 2 and 3. It is 390 | now much simpler to add support for additional languages. 391 | 392 | * Added support for the Ruby language as a demonstration of new 393 | capabilities. The ``ruby`` and ``rb`` families of commands and 394 | environments may be enabled via the new ``usefamily`` package option. 395 | Support for additional languages is coming soon. See the new section 396 | in the documentation on support for other languages for more 397 | information. 398 | 399 | * Reimplemented treatment of Pygments content for better efficiency. 400 | Now a Pygments process only runs if there is content to highlight. 401 | Eliminated redundant highlighting of unmodified code. 402 | 403 | * Improved treatment of dependencies. If a dependency is modified 404 | (``os.path.getmtime()``) after the current PythonTeX run starts, then 405 | code that depends on it will be re-executed the next time PythonTeX 406 | runs. A message is also issued to indicate that this is the case. 407 | 408 | * The utilities class now has ``before()`` and ``after()`` methods that 409 | are called immediately before and after user code. These may be 410 | redefined to customize output. For example, LaTeX commands could be 411 | printed before and after user code; stdout could be redirected to 412 | ``StringIO`` for further processing; or matplotlib figures could be 413 | automatically detected, saved, and included in the document. 414 | 415 | * Added explanation of how to track dependencies and created files 416 | automatically, and how to include matplotlib figures automatically, 417 | to the documentation for the PythonTeX utilities class. 418 | 419 | * Created a new system for parsing and synchronizing stderr. 420 | 421 | - Exceptions that do not reference a line number in user code (such 422 | as those from ``warnings.warn()`` in a module) are now traced back 423 | to a single command or environment. Previously no synchronization 424 | was attempted. This is accomplished by writing delimiters to 425 | stderr before executing the code from each command/environment. 426 | 427 | - Exceptions that do reference a line in user code are more 428 | efficiently synchronized with a document line number. This is 429 | accomplished by careful record keeping as each script is 430 | assembled. Line number synchronization no longer involves parsing 431 | the script that was executed. 432 | 433 | - Improved and generalized parsing of stderr, in preparation for 434 | supporting additional languages. Exceptions that cannot be 435 | identified as errors or warnings are treated based on 436 | ``Popen.returncode``. 437 | 438 | * Created a new system for ``console`` content. 439 | 440 | - There are now separate families of ``console`` commands and 441 | environments. No Pygments or ``fancyvrb`` settings are shared with 442 | the non-``console`` families, as was previously the case. There 443 | is a new family of commands and environments based on ``pycon``, 444 | including the ``\pycon`` command (inline reference to console variable), 445 | ``pyconsole`` environment (same as the old one), ``\pyconc`` and 446 | ``pyconcode`` (execute only), and ``\pyconv`` and ``pyconverbatim`` 447 | (typeset only). There are equivalent families based on 448 | ``pylabcon`` and ``sympycon``. 449 | 450 | - Each console session now runs in its own process and is cached 451 | individually. Console output is now cached so that changing 452 | Pygments settings no longer requires re-execution. 453 | 454 | - Unicode is now supported under Python 2. 455 | 456 | - The new package option ``pyconfuture`` allows automatic imports 457 | from ``__future__`` for ``console`` families under Python 2, 458 | paralleling the ``pyfuture`` option. 459 | 460 | - Any errors or warnings caused by code that is not typeset 461 | (``code`` command and environment, startup code) are reported in 462 | the run summary. This ensures that such code does not create 463 | mischief. 464 | 465 | - ``customcode`` is now supported for ``console`` content. 466 | 467 | * Better support for ``latexmk`` and similar build tools. PythonTeX 468 | creates a file of macros (``*.pytxmcr``) that is always included in a 469 | document, and thus can be automatically detected and tracked by 470 | ``latexmk``. This file now contains the time at which PythonTeX last 471 | created files. When new files are created, the macro file will have a 472 | new hash, triggering another document compile. 473 | 474 | * Improved the way in which the PythonTeX ``outputdir`` is added to the 475 | graphics path. This had been done with ``\graphicspath``, but that 476 | overwrites any graphics path previously specified by the user. Now the 477 | ``outputdir`` is appended to any pre-existing path. 478 | 479 | * Added the ``depythontex`` option ``--graphicspath``. This adds the 480 | ``outputdir`` to the graphics path of the ``depythontex`` document. 481 | 482 | * The installer now provides more options for installation locations. 483 | It will now create missing directories if desired. 484 | 485 | * The working directory (``workingdir``) is now appended to 486 | ``sys.path``, so that code there may be imported. 487 | 488 | * Under Windows, ``subprocess.Popen()`` is now invoked with 489 | ``shell=True`` if ``shell=False`` results in a WindowsError. This 490 | allows commands involving ``*.bat`` and ``*.cmd`` files to be 491 | executed when the extension is not specified; otherwise, only ``*.exe`` 492 | can be found and run. 493 | 494 | * The path to utils is now found in ``pythontex.py`` via 495 | ``sys.path[0]`` rather than ``kpsewhich``. This allows the PythonTeX 496 | scripts to be executed in an arbitrary location; they no longer must 497 | be installed in a texmf tree where ``kpsewhich`` can find them. 498 | 499 | * Added ``rerun`` value ``never``. 500 | 501 | * At the end of each run, data and macros are only saved if modified, 502 | improving efficiency. 503 | 504 | * The number of temporary files required by each process was reduced by 505 | one. All macros for commands like ``\py`` are now returned within 506 | stdout, rather than in their own file. 507 | 508 | * Fixed a bug with ``\stderrpythontex``; it was defaulting to ``verb`` 509 | rather than ``verbatim`` mode. 510 | 511 | 512 | v0.11 (2013/04/21) 513 | ------------------ 514 | 515 | * As the first non-beta release, this version adds several features and introduces several changes. You should read these release notes carefully, since some changes are not backwards-compatible. Changes are based on a thorough review of all current and planned features. PythonTeX's capabilities have already grown beyond what was originally intended, and a long list of features still remains to be implemented. As a result, some changes are needed to ensure consistent syntax and naming in the future. Insofar as possible, all command names and syntax will be frozen after this release. 516 | * Added the ``pythontex.py`` and ``depythontex.py`` wrapper scripts. When run, these detect the current version of Python and import the correct PythonTeX code. It is still possible to run ``pythontex*.py`` and ``depythontex*.py`` directly, but the new wrapper scripts should be used instead for simplicity. There is now only a single ``pythontex_utils.py``, which works with both Python 2 and Python 3. 517 | * Added the ``beta`` package option. This makes the current version behave like v0.11beta, for compatibility. This option is temporary and will probably only be retained for a few releases. 518 | * Backward-incompatible changes (require the ``beta`` option to restore old behavior) 519 | 520 | - The ``pyverb`` environment has been renamed ``pyverbatim``. The old name was intended to be concise, but promoted confusion with LaTeX's ``\verb`` macro. 521 | - For ``\printpythontex``, ``\stdoutpythontex``, and ``\stderrpythontex``, the modes ``inlineverb`` and ``v`` have been replaced by ``verb``, and the old mode ``verb`` has been replaced by ``verbatim``. This brings naming conventions in line with standard LaTeX ``\verb`` and ``verbatim``, avoiding a source of potential confusion. 522 | - The ``\setpythontexpyglexer``, ``\setpythontexpygopt``, and ``\setpygmentspygopt`` commands now take an optional argument and a mandatory argument, rather than two mandatory arguments. This creates better uniformity among current and planned settings macros. 523 | - The ``\setpythontexformatter`` and ``\setpygmentsformatter`` commands have been replaced by the ``\setpythontexprettyprinter`` and ``\setpygmentsprettyprinter`` commands. This anticipates possible upcoming features. It also avoids potential confusion with Pygments's formatters and the utilities class's ``formatter()`` method. 524 | 525 | * Deprecated (still work, but raise warnings; after a few releases, they will raise errors instead, and after that eventually be removed) 526 | 527 | - The ``rerun`` setting ``all`` was renamed ``always``, in preparation for upcoming features. 528 | - The ``stderr`` option is replaced by ``makestderr``. The ``print``/``stdout`` option is replaced by ``debug``. These are intended to prevent confusion with future features. 529 | - The ``fixlr`` option is deprecated. It was originally introduced to deal with some of SymPy's LaTeX formatting, which has since changed. 530 | - The utilities class method ``init_sympy_latex()`` is deprecated. The ``sympy_latex()`` and ``set_sympy_latex()`` methods now automatically initialize themselves on first use. 531 | 532 | * Added ``autostdout`` package option and ``\setpythontexautostdout``, to complement ``autoprint``. Added ``prettyprinter`` and ``prettyprintinline`` package options to complement new settings commands. 533 | * Added quickstart guide. 534 | * Installer now installs gallery and quickstart files, if present. 535 | 536 | 537 | v0.11beta (2013/02/17) 538 | ---------------------- 539 | 540 | * Commands like ``\py`` can now bring in any valid LaTeX code, including verbatim content, under the pdfTeX and XeTeX engines. Verbatim content was not allowed previously. LuaTeX cannot bring in verbatim, due to a known bug. 541 | * Added package option ``depythontex`` and scripts ``depythontex*.py``. These allow a PythonTeX document to be converted into a pure LaTeX document, with no Python dependency. The package option creates an auxiliary file with extension ``.depytx``. The ``depythontex*.py`` scripts take this auxiliary file and the original LaTeX document, and combine the two to produce a new document that does not rely on the PythonTeX package. All PythonTeX commands and environments are replaced by their output. All Python-generated content is substituted directly into the document. By default, all typeset code is wrapped in ``\verb`` and ``verbatim``, but ``depythontex*.py`` has a ``--listing`` option that allows ``fancyvrb``, ``listings``, ``minted``, or ``pythontex`` to be used instead. 542 | * The current PythonTeX version is now saved in the ``.pytxcode``. If this does not match the version of the PythonTeX scripts, a warning is issued. This makes it easier to determine errors due to version mismatches. 543 | * Fixed an incompatibility with the latest release of ``xstring`` (version 1.7, 2013/01/13). 544 | * Fixed a bug in the ``console`` environment that could cause problems when switching from Pygments highlighting to ``fancyvrb`` when using the ``fvextfile`` option. Fixed a bug introduced in the v0.10beta series that prevented the ``console`` environment from working with ``fancyvrb``. 545 | * Fixed a bug with PythonTeX verbatim commands and environments that use Pygments. The verbatim commands and environments were incorrectly treated as if they had the attributes of executed code in the v0.10beta series. 546 | * Fixed a bug from the v0.10beta series that sometimes prevented imports from ``__future__`` from working when there were multiple sessions. 547 | * Fixed a bug related to hashing dependencies' mtime under Python 3. 548 | 549 | 550 | v0.10beta2 (2013/01/23) 551 | ----------------------- 552 | 553 | * Improved ``pythontex*.py``'s handling of the name of the file being processed. A warning is no longer raised if the name is given with an extension; extensions are now processed (stripped) automatically. The filename may now contain a path to the file, so you need not run ``pythontex*.py`` from within the document's directory. 554 | * Added command-line option ``--verbose`` for more verbose output. Currently, this prints a list of all processes that are launched. 555 | * Fixed a bug that could crash ``pythontex*.py`` when the package option ``pygments=false``. 556 | * Added documentation about ``autoprint`` behavior in the preamble. Summary: ``code`` commands and environments are allowed in the preamble as of v0.10beta. ``autoprint`` only applies to the body of the document, because nothing can be typeset in the preamble. Content printed in the preamble can be brought in by explicitly using ``\printpythontex``, but this should be used with great care. 557 | * Revised ``\stdoutpythontex`` and ``\printpythontex`` so that they work in the preamble. Again, this should be used with great care if at all. 558 | * Revised treatment of any content that custom code attempts to print. Custom code is not allowed to print to the document (see documentation). If custom code attempts to print, a warning is raised, and the printed content is included in the ``pythontex*.py`` run summary. 559 | * One-line entries in stderr, such as those produced by Python's ``warnings.warn()``, were not previously parsed because they are of the form ``::`` rather than ``line ``. These are now parsed and synchronized with the document. They are also correctly parsed for inclusion in the document via ``\stderrpythontex``. 560 | * If the package option ``stderrfilename`` is changed, all sessions that produced errors or warnings are now re-executed automatically, so that their stderr content is properly updated with the new filename. 561 | 562 | 563 | v0.10beta (2013/01/09) 564 | ---------------------- 565 | 566 | * Backward-incompatible: Redid treatment of command-line options for 567 | ``pythontex*.py``, using Python's ``argparse`` module. Run 568 | ``pythontex*.py`` with option ``-h`` to see new command line options. 569 | * Deprecated: ``\setpythontexcustomcode`` is deprecated in favor of the 570 | ``\pythontexcustomc`` command and ``pythontexcustomcode`` 571 | environment. These allow entry of pure code, unlike 572 | ``\setpythontexcustomcode``. These also allow custom code to be 573 | added to the beginning or end of a session, via an optional argument. 574 | Improved treatment of errors and warnings associated with custom 575 | code. 576 | * The summary of errors and warnings now correctly differentiates 577 | errors and warnings produced by user code, rather than treating all 578 | of them as errors. By default, ``pythontex*.py`` now returns an 579 | exit code of 1 if there were errors. 580 | * The PythonTeX utilities class now allows external file dependencies 581 | to be specified via ``pytex.add_dependencies()``, so that sessions 582 | are automatically re-executed when external dependencies are 583 | modified (modification is determined via either hash or mtime; this 584 | is governed by the new ``hashdependencies`` option). 585 | * The PythonTeX utilities class now allows created files to be 586 | specified via ``pytex.add_created()``, so that created files may be 587 | automatically cleaned up (deleted) when the code that created them 588 | is modified (for example, name change for a saved plot). 589 | * Added the following package options. 590 | 591 | - ``stdout`` (or ``print``): Allows input of stdout to be disabled. 592 | Useful for debugging. 593 | - ``runall``: Executes everything. Useful when code depends on 594 | external data. 595 | - ``rerun``: Determines when code is re-executed. Code may be set 596 | to always run (same as ``runall`` option), or only run when it is 597 | modified or when it produces errors or warnings. By default, 598 | code is always re-executed if there are errors or modifications, 599 | but not re-executed if there are warnings. 600 | - ``hashdependencies``: Determines whether external dependencies 601 | (data, external code files highlighted with Pygments, etc.) are 602 | checked for modification via hashing or modification time. 603 | Modification time is default for performance reasons. 604 | 605 | * Added the following new command line options. The options that are 606 | equivalent to package options are overridden by the package options 607 | when present. 608 | 609 | - ``--error-exit-code``: Determines whether an exit code of 1 is 610 | returned if there were errors. On by default, but can be turned 611 | off since it is undesirable when working with some editors. 612 | - ``--runall``: Equivalent to new package option. 613 | - ``--rerun``: Equivalent to new package option. 614 | - ``--hashdependencies``: Equivalent to new package option. 615 | 616 | * Modified the ``fixlr`` option, so that it only patches commands if 617 | they have not already been patched (avoids package conflicts). 618 | * Added ``\setpythontexautoprint`` command for toggling autoprint 619 | on/off within the body of the document. 620 | * Installer now attempts to create symlinks under OS X and Linux with 621 | TeX Live, and under OS X with MacPorts Tex Live. 622 | * Performed compatibility testing under lualatex and xelatex 623 | (previously, had only tested with pdflatex). Added documentation 624 | for using these TeX engines; at most, slightly different preambles 625 | are needed. Modified the PythonTeX gallery to support all three 626 | engines. 627 | * Code commands and environments may now be used in the preamble. 628 | This, combined with the new treatment of custom code, allows 629 | PythonTeX to be used in creating LaTeX packages. 630 | * Added documentation for using PythonTeX in LaTeX programming. 631 | * Fixed a bug that sometimes caused incorrect line numbers with 632 | ``stderr`` content. Improved processing of stderr. 633 | * Fixed a bug in automatic detection of pre-existing listings 634 | environment. 635 | * Improved the detection of imports from ``__future__``. Detection 636 | should now be stricter, faster, and more accurate. 637 | 638 | 639 | v0.9beta3 (2012/07/17) 640 | ---------------------- 641 | 642 | * Added Unicode support, which required the Python code to be split into 643 | one set for Python 2 and another set for Python 3. This will require 644 | any old installation to be completely removed, and a new installation 645 | created from scratch. 646 | * Refactoring of Python code. Documents should automatically re-execute 647 | all code after updating to the new version. Otherwise, you should delete 648 | the PythonTeX directory and run PythonTeX. 649 | * Improved installation script. 650 | * Added package options: ``pyfuture``, ``stderr``, ``upquote``, 651 | ``pyglexer``, ``pyginline``. Renamed the ``pygextfile`` option to 652 | ``fvextfile``. 653 | * Added custom code and workingdir commands. 654 | * Added the ``console`` environment and associated options. 655 | * Rewrote ``pythontex_utils*.py``, creating a new, context-aware interface to 656 | SymPy's LatexPrinter class. 657 | * Content brought in via macros no longer uses labels. Rather, long defs 658 | are used, which allows line breaks. 659 | * Pygments highlighting is now default for PythonTeX commands and environments. 660 | 661 | 662 | v0.9beta2 (2012/05/09) 663 | ---------------------- 664 | 665 | * Changed Python output extension to ``.stdout``. 666 | 667 | 668 | v0.9beta (2012/04/27) 669 | --------------------- 670 | 671 | * Initial public beta release. 672 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | =============================================== 2 | PythonTeX 3 | =============================================== 4 | 5 | ------------------------------------------------------------------------------------------ 6 | Execute Python and other code in LaTeX documents, or typeset it with syntax highlighting 7 | ------------------------------------------------------------------------------------------ 8 | 9 | 10 | PythonTeX executes code in LaTeX documents and allows the output to be 11 | included in the original document. It supports Python as well as Bash, 12 | JavaScript, Julia, Octave, Perl, R, Raku (Perl 6), Ruby, Rust, and SageMath. 13 | PythonTeX also provides syntax highlighting for typeset code in LaTeX 14 | documents via the `Pygments `_ syntax highlighter. 15 | 16 | See ``pythontex_quickstart.pdf`` to get started, and ``pythontex_gallery.pdf`` 17 | for examples of what is possible with PythonTeX. PythonTeX is included in TeX 18 | Live and MiKTeX and may be installed via the package manager. See 19 | ``pythontex.pdf`` for detailed installation instructions if you want to 20 | install the current development version, or just use the installation script 21 | for TeX Live and MiKTeX. 22 | 23 | The ``depythontex`` utility creates a copy of a PythonTeX document in which 24 | all code has been replaced by its output. This plain LaTeX document is 25 | more suitable for journal submission, sharing, or conversion to other document 26 | formats. See ``pythontex_gallery.html`` and the accompanying conversion 27 | script for an example of a PythonTeX document that was converted to HTML via 28 | ``depythontex`` and `Pandoc `_. 29 | 30 | 31 | Example 32 | ======= 33 | 34 | * LaTeX document ``doc.tex``: 35 | 36 | .. code-block:: latex 37 | 38 | \documentclass{article} 39 | 40 | \usepackage{pythontex} 41 | 42 | \newcommand{\pymultiply}[2]{\py{#1*#2}} 43 | 44 | \begin{document} 45 | 46 | \begin{pycode} 47 | print("Python says ``Hello!''") 48 | \end{pycode} 49 | 50 | $8 \times 256 = \pymultiply{8}{256}$ 51 | 52 | \end{document} 53 | 54 | * Compiling under Windows: 55 | 56 | :: 57 | 58 | pdflatex -interaction=nonstopmode doc.tex 59 | pythontex doc.tex 60 | pdflatex -interaction=nonstopmode doc.tex 61 | 62 | 63 | * Compiling under other operating systems: 64 | 65 | :: 66 | 67 | pdflatex -interaction=nonstopmode doc.tex 68 | pythontex.py doc.tex 69 | pdflatex -interaction=nonstopmode doc.tex 70 | 71 | 72 | 73 | * Output: 74 | 75 | :: 76 | 77 | Python says “Hello!” 78 | 8 × 256 = 2048 79 | 80 | Notice that there is a three-step compile process. This is what makes 81 | possible commands like ``\pymultiply`` that use Python or other languages 82 | internally. You may want to configure your LaTeX editor with a shortcut for 83 | running ``pythontex`` or ``pythontex.py``, or configure your LaTeX build 84 | system to run ``pythontex`` or ``pythontex.py``. 85 | 86 | 87 | Citing PythonTeX 88 | ================ 89 | 90 | If you use PythonTeX in your writing and research, please consider citing it 91 | in any resulting publications. The best and most recent paper is in 92 | `Computational Science & Discovery `_ 93 | (doi:10.1088/1749-4699/8/1/014010). You may also cite the paper in the 94 | `2013 SciPy proceedings `_. 95 | 96 | 97 | Development status 98 | ================== 99 | 100 | Starting in 2020, I have increasingly used Markdown and HTML instead of 101 | PythonTeX and LaTeX when creating new teaching materials. I can no longer 102 | make major time investments in open-source software that I do not use 103 | frequently myself. PythonTeX v0.19 is under development. It will address 104 | some minor bugs and incompatibilities that have developed with Python and 105 | dependencies over the last few years. After v0.19, there should be occasional 106 | releases to keep PythonTeX running, but no major changes or significant new 107 | features are anticipated. 108 | 109 | I have been developing `Codebraid `_ since 2019, 110 | partially to have a PythonTeX equivalent for Markdown but also in the hope 111 | that it could eventually be integrated with LaTeX as a PythonTeX replacement. 112 | I currently have a grant to develop 113 | `minted `_ v3.0, and as part of this am 114 | creating new software for passing data between LaTeX and Python. I cannot 115 | make any guarantees, but I hope that this will eventually make it possible to 116 | create a new LaTeX package based on Codebraid, with significant PythonTeX 117 | compatibility. 118 | 119 | 120 | License 121 | ======= 122 | 123 | LPPL_ for LaTeX code and `BSD 3-Clause`_ for Python code. 124 | 125 | .. _LPPL: http://www.latex-project.org/lppl.txt 126 | 127 | .. _`BSD 3-Clause`: http://www.opensource.org/licenses/BSD-3-Clause 128 | -------------------------------------------------------------------------------- /pythontex/README: -------------------------------------------------------------------------------- 1 | =================================================================== 2 | The PythonTeX Package 3 | =================================================================== 4 | 5 | :Author: Geoffrey Poore 6 | :Version: 0.18 (2021/06/06) 7 | :License: LPPL v1.3 or later (LaTeX code) and BSD 3-Clause (Python code) 8 | :Development: https://github.com/gpoore/pythontex 9 | :Requirements: Python 2.7 or 3.2+; Pygments 10 | 11 | 12 | The PythonTeX package allows you to enter Python code within a LaTeX document, 13 | execute the code, and access its output in the original document. It also 14 | supports the Ruby, Julia, Octave, Sage, Bash, Rust, R, Perl, Perl 6, and 15 | JavaScript languages. 16 | 17 | PythonTeX provides fast, user-friendly access to Python from within LaTeX. 18 | Python code is only executed when it has been modified, or when it meets 19 | user-specified criteria. Code may be divided into user-defined sessions, 20 | which automatically run in parallel. Errors and warnings are synchronized 21 | with the LaTeX document, so that they refer to the document's line numbers. 22 | External dependencies can be tracked, so that code is re-executed when the 23 | data it depends on is modified. PythonTeX also provides syntax highlighting 24 | for code in LaTeX documents via the Pygments syntax highlighter. 25 | 26 | PythonTeX includes a "depythontex" utility that creates a copy of a document 27 | in which all Python code has been replaced by its output. This can be 28 | convenient for journal submissions, sharing documents, and converting to 29 | other formats. 30 | 31 | Consult pythontex_quickstart.pdf and pythontex_gallery.pdf to get 32 | started and for examples of what PythonTeX can do. 33 | 34 | Compiling a PythonTeX document involves three steps: 35 | 36 | 1. Run latex (all Python code is saved to an auxiliary file) 37 | 2. Run pythontex.py (all code is executed) 38 | 3. Run latex again (Python output is inputted) 39 | 40 | See the main documentation in pythontex.pdf for detailed installation 41 | instructions. An installation script is provided for TeX Live and MiKTeX. 42 | Files should be installed in the directories indicated below. In summary, 43 | all files must be installed, and symlinks or launching wrappers should be 44 | created for pythontex.py and depythontex.py. 45 | 46 | * /doc/latex/pythontex/ 47 | 48 | - pythontex.pdf 49 | - README 50 | - pythontex_quickstart.tex 51 | - pythontex_quickstart.pdf 52 | - pythontex_gallery.tex 53 | - pythontex_gallery.pdf 54 | 55 | * /scripts/pythontex/ 56 | 57 | - pythontex.py, pythontex2.py, and pythontex3.py 58 | - pythontex_engines.py 59 | - pythontex_utils.py 60 | - depythontex.py, depythontex2.py, and depythontex3.py 61 | - syncpdb.py 62 | 63 | * /source/latex/pythontex/ 64 | 65 | - pythontex.dtx 66 | - pythontex.ins 67 | 68 | * /tex/latex/pythontex/ 69 | 70 | - pythontex.sty 71 | -------------------------------------------------------------------------------- /pythontex/depythontex.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | depythontex.py %* 3 | -------------------------------------------------------------------------------- /pythontex/depythontex.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | ''' 5 | This is the depythontex wrapper script. It automatically detects the version 6 | of Python, and then imports the correct code from depythontex2.py or 7 | depythontex3.py. It is intended for use with the default Python installation 8 | on your system. If you wish to use a different version of Python, you could 9 | launch depythontex2.py or depythontex3.py directly. The version of Python 10 | does not matter for depythontex, since no code is executed. 11 | 12 | Copyright (c) 2013-2017, Geoffrey M. Poore 13 | All rights reserved. 14 | Licensed under the BSD 3-Clause License: 15 | http://www.opensource.org/licenses/BSD-3-Clause 16 | 17 | ''' 18 | 19 | import sys 20 | if sys.version_info[0] == 2: 21 | import depythontex2 as depythontex 22 | elif sys.version_info[0] == 3: 23 | import depythontex3 as depythontex 24 | -------------------------------------------------------------------------------- /pythontex/pythontex.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | pythontex.py %* 3 | -------------------------------------------------------------------------------- /pythontex/pythontex.ins: -------------------------------------------------------------------------------- 1 | %% Copyright (C) 2012-2019 by Geoffrey M. Poore 2 | %% -------------------------------------------------------------------------- 3 | %% This work may be distributed and/or modified under the 4 | %% conditions of the LaTeX Project Public License, either version 1.3 5 | %% of this license or (at your option) any later version. 6 | %% The latest version of this license is in 7 | %% http://www.latex-project.org/lppl.txt 8 | %% and version 1.3 or later is part of all distributions of LaTeX 9 | %% version 2005/12/01 or later. 10 | %% 11 | %% This work has the LPPL maintenance status `maintained'. 12 | %% 13 | %% The Current Maintainer of this work is Geoffrey M. Poore. 14 | %% 15 | %% This work consists of the files pythontex.dtx and pythontex.ins 16 | %% and the derived filebase pythontex.sty. 17 | %% 18 | 19 | \input docstrip.tex 20 | \keepsilent 21 | 22 | \usedir{tex/latex/pythontex} 23 | 24 | \preamble 25 | 26 | This is a generated file. 27 | 28 | Copyright (C) 2012-2021 by Geoffrey M. Poore 29 | -------------------------------------------------------------------------- 30 | This work may be distributed and/or modified under the 31 | conditions of the LaTeX Project Public License, either version 1.3 32 | of this license or (at your option) any later version. 33 | The latest version of this license is in 34 | http://www.latex-project.org/lppl.txt 35 | and version 1.3 or later is part of all distributions of LaTeX 36 | version 2005/12/01 or later. 37 | 38 | \endpreamble 39 | 40 | \generate{\file{pythontex.sty}{\from{pythontex.dtx}{package}}} 41 | 42 | \obeyspaces 43 | \Msg{*************************************************************} 44 | \Msg{* *} 45 | \Msg{* To finish the installation you have to move the following *} 46 | \Msg{* file into a directory searched by TeX: *} 47 | \Msg{* *} 48 | \Msg{* pythontex.sty *} 49 | \Msg{* *} 50 | \Msg{* To produce the documentation run the file pythontex.dtx *} 51 | \Msg{* through LaTeX. *} 52 | \Msg{* *} 53 | \Msg{* Happy TeXing! *} 54 | \Msg{* *} 55 | \Msg{*************************************************************} 56 | 57 | \endbatchfile 58 | -------------------------------------------------------------------------------- /pythontex/pythontex.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gpoore/pythontex/4ab50a8679f1288935a09d4498de501a387abc00/pythontex/pythontex.pdf -------------------------------------------------------------------------------- /pythontex/pythontex.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | ''' 5 | This is the PythonTeX wrapper script. It automatically detects the version 6 | of Python, and then imports the correct code from pythontex2.py or 7 | pythontex3.py. It is intended for use with the default Python installation 8 | on your system. If you wish to use a different version of Python, you could 9 | launch pythontex2.py or pythontex3.py directly. You should also consider the 10 | command-line option `--interpreter`. This allows you to specify the command 11 | that is actually used to execute the code from your LaTeX documents. Except 12 | for Python console content, it doesn't matter which version of Python is used 13 | to launch pythontex.py; pythontex.py just manages the execution of code from 14 | your LaTeX document. The interpreter setting is what determines the version 15 | under which your code is actually executed. 16 | 17 | Licensed under the BSD 3-Clause License: 18 | 19 | Copyright (c) 2012-2017, Geoffrey M. Poore 20 | 21 | All rights reserved. 22 | 23 | Redistribution and use in source and binary forms, with or without 24 | modification, are permitted provided that the following conditions are met: 25 | * Redistributions of source code must retain the above copyright 26 | notice, this list of conditions and the following disclaimer. 27 | * Redistributions in binary form must reproduce the above copyright 28 | notice, this list of conditions and the following disclaimer in the 29 | documentation and/or other materials provided with the distribution. 30 | * Neither the name of the nor the 31 | names of its contributors may be used to endorse or promote products 32 | derived from this software without specific prior written permission. 33 | 34 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 35 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 36 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 37 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 38 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 39 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 40 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 41 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 42 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 43 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 44 | ''' 45 | 46 | 47 | import sys 48 | if sys.version_info.major == 2: 49 | if sys.version_info.minor >= 7: 50 | import pythontex2 as pythontex 51 | else: 52 | sys.exit('PythonTeX require Python 2.7; you are using 2.{0}'.format(sys.version_info.minor)) 53 | elif sys.version_info.major == 3: 54 | if sys.version_info.minor >= 2: 55 | import pythontex3 as pythontex 56 | else: 57 | sys.exit('PythonTeX require Python 3.2+; you are using 3.{0}'.format(sys.version_info.minor)) 58 | 59 | # The "if" statement is needed for multiprocessing under Windows; see the 60 | # multiprocessing documentation. 61 | if __name__ == '__main__': 62 | pythontex.main() 63 | -------------------------------------------------------------------------------- /pythontex/pythontex_2to3.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | ''' 5 | Convert PythonTeX scripts from Python 2 to Python 3 6 | 7 | It isn't possible to have a single PythonTeX code base, since unicode text 8 | needs to be supported. Under Python 2, this means importing unicode_literals 9 | from __future__, or using the unicode function or "u" prefix. Under Python 3, 10 | all strings are automatically unicode. 11 | 12 | At the same time, the differences between the Python 2 and 3 versions are 13 | usually very small, involving only a few lines of code. To keep the code base 14 | unified, while simultaneously fully supporting both Python 2 and 3, the 15 | following scheme was devised. The code is written for Python 2. Whenever 16 | code is not compatible with Python 3, it is enclosed with the tags 17 | "#// Python 2" and "#\\ End Python 2" (each on its own line, by itself). If 18 | a Python 3 version of the code is needed, it is included between analogous 19 | tags "#// Python 3" and "#\\ End Python 2". The Python 3 code is commented 20 | out with "#", at the same indentation level as the Python 3 tags. 21 | 22 | This script creates Python 3 scripts from the original Python 2 scripts 23 | by commenting out everything between the Python 2 tags, and uncommenting 24 | everything between the Python 3 tags. In this way, full compatibility is 25 | maintained with both Python 2 and 3 while keeping the code base essentially 26 | unified. This approach also allows greater customization of version-specific 27 | code than would be possible if automatic translation with a tool like 2to3 28 | was required. 29 | 30 | Copyright (c) 2012-2017, Geoffrey M. Poore 31 | All rights reserved. 32 | Licensed under the BSD 3-Clause License: 33 | http://www.opensource.org/licenses/BSD-3-Clause 34 | 35 | ''' 36 | 37 | 38 | # Imports 39 | from __future__ import unicode_literals 40 | from io import open 41 | import re 42 | 43 | 44 | files_to_process = ('pythontex2.py', 'depythontex2.py') 45 | encoding = 'utf-8' 46 | 47 | 48 | def from2to3(list_of_code): 49 | fixed = [] 50 | in_2 = False 51 | in_3 = False 52 | indent = '' 53 | 54 | for line in list_of_code: 55 | if r'#// Python 2' in line: 56 | in_2 = True 57 | indent = line.split('#', 1)[0] 58 | elif r'#\\ End Python 2' in line: 59 | in_2 = False 60 | elif r'#// Python 3' in line: 61 | in_3 = True 62 | indent = line.split('#', 1)[0] 63 | elif r'#\\ End Python 3' in line: 64 | in_3 = False 65 | elif in_2: 66 | line = re.sub(indent, indent + '#', line, count=1) 67 | elif in_3: 68 | line = re.sub(indent + '#', indent, line, count=1) 69 | fixed.append(line) 70 | if fixed[0].startswith('#!/usr/bin/env python2'): 71 | fixed[0] = fixed[0].replace('python2', 'python3') 72 | return fixed 73 | 74 | 75 | for file in files_to_process: 76 | f = open(file, 'r', encoding=encoding) 77 | converted_code = from2to3(f.readlines()) 78 | f.close() 79 | f = open(re.sub('2', '3', file), 'w', encoding=encoding) 80 | f.write(''.join(converted_code)) 81 | f.close() 82 | 83 | 84 | -------------------------------------------------------------------------------- /pythontex/pythontex_install.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | @setlocal enableextensions 3 | @cd /d "%~dp0" 4 | pythontex_install.py %* 5 | -------------------------------------------------------------------------------- /pythontex/pythontex_install.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | ''' 5 | Install PythonTeX 6 | 7 | This installation script is written to work with TeX Live and MiKTeX. Note 8 | that PythonTeX is included in TeX Live 2013 and later, and may be installed 9 | via the package manager. Thus, this installation script is only needed with 10 | TeX Live when you wish to install the latest version. PythonTeX is not 11 | currently available via the MiKTeX package manager. 12 | 13 | The script will automatically overwrite (and thus update) all previously 14 | installed PythonTeX files in the designated installation location. When 15 | Kpathsea is available, files may be installed in TEXMFDIST, TEXMFLOCAL, 16 | TEXMFHOME, or a manually specified location. Otherwise, the installation 17 | location must be specified manually. Installing in TEXMFDIST is useful 18 | under TeX Live if you want to install PythonTeX and then update it in the 19 | future via the package manager. 20 | 21 | The `mktexlsr` (TeX Live) or `initexmf --update-fndb` (MiKTeX) command is 22 | executed at the end of the script, to make the system aware of any new files. 23 | 24 | Under TeX Live, the script attempts to create a binary wrapper (Windows) or 25 | symlink (Linux and OS X) for launching the main PythonTeX scripts, 26 | `pythontex*.py` and `depythontex*.py`. Under MiKTeX, it attempts to create 27 | a batch file in `miktex/bin`. 28 | 29 | 30 | Copyright (c) 2012-2014, Geoffrey M. Poore 31 | All rights reserved. 32 | Licensed under the BSD 3-Clause License: 33 | http://www.opensource.org/licenses/BSD-3-Clause 34 | 35 | ''' 36 | 37 | 38 | # Imports 39 | import sys 40 | import platform 41 | from os import path, mkdir, makedirs 42 | if platform.system() != 'Windows': 43 | # Only create symlinks if not under Windows 44 | # (os.symlink doesn't exist under Windows) 45 | from os import symlink, chmod, unlink 46 | from subprocess import call, check_call, check_output 47 | from shutil import copy 48 | import textwrap 49 | 50 | 51 | # We need a version of input that works under both Python 2 and 3 52 | try: 53 | input = raw_input 54 | except: 55 | pass 56 | 57 | 58 | # Print startup messages and notices 59 | print('Preparing to install PythonTeX') 60 | if platform.system() != 'Windows': 61 | message = ''' 62 | You may need to run this script with elevated permissions 63 | and/or specify the environment. For example, you may need 64 | "sudo env PATH=$PATH". That is typically necessary when your 65 | system includes a TeX distribution, and you have manually 66 | installed another distribution (common with Ubuntu etc.). If 67 | the installation path you want is not automatically detected, 68 | it may indicate a permissions issue. 69 | ''' 70 | print(textwrap.dedent(message)) 71 | 72 | 73 | # Attempt to detect the TeX distribution 74 | try: 75 | if sys.version_info.major == 2: 76 | texout = check_output(['latex', '--version']) 77 | else: 78 | texout = check_output(['latex', '--version']).decode('utf-8') 79 | except: 80 | sys.exit('Could not retrieve latex info when running "latex --version"') 81 | if 'TeX Live' in texout: 82 | detected_texdist = True 83 | texlive = True 84 | miktex = False 85 | elif platform.system() == 'Windows' and 'MiKTeX' in texout: 86 | detected_texdist = True 87 | texlive = False 88 | miktex = True 89 | else: 90 | detected_texdist = False 91 | texlive = False 92 | miktex = False 93 | 94 | 95 | # Make sure all necessary files are present 96 | # The pythontex_gallery and pythontex_quickstart are optional; we 97 | # check for them when installing doc, and install if available 98 | needed_files = ['pythontex.py', 'pythontex2.py', 'pythontex3.py', 99 | 'pythontex_engines.py', 'pythontex_utils.py', 100 | 'depythontex.py', 'depythontex2.py', 'depythontex3.py', 101 | 'pythontex.sty', 'pythontex.ins', 'pythontex.dtx', 102 | 'pythontex.pdf', 'README', 103 | 'syncpdb.py'] 104 | missing_files = False 105 | # Print a list of all files that are missing, and exit if any are 106 | for eachfile in needed_files: 107 | if not path.exists(eachfile): 108 | print('Could not find file ' + eachfile) 109 | missing_files = True 110 | if missing_files: 111 | sys.exit('Exiting due to missing files.') 112 | 113 | 114 | # Retrieve the location of valid TeX trees 115 | if sys.version_info[0] == 2: 116 | try: 117 | texmf_dist = check_output(['kpsewhich', '-var-value', 'TEXMFDIST']).rstrip('\r\n') 118 | except: 119 | texmf_dist = None 120 | try: 121 | texmf_local = check_output(['kpsewhich', '-var-value', 'TEXMFLOCAL']).rstrip('\r\n') 122 | except: 123 | texmf_local = None 124 | try: 125 | texmf_home = check_output(['kpsewhich', '-var-value', 'TEXMFHOME']).rstrip('\r\n') 126 | except: 127 | texmf_home = None 128 | else: 129 | try: 130 | texmf_dist = check_output(['kpsewhich', '-var-value', 'TEXMFDIST']).decode('utf-8').rstrip('\r\n') 131 | except: 132 | texmf_dist = None 133 | try: 134 | texmf_local = check_output(['kpsewhich', '-var-value', 'TEXMFLOCAL']).decode('utf-8').rstrip('\r\n') 135 | except: 136 | texmf_local = None 137 | try: 138 | texmf_home = check_output(['kpsewhich', '-var-value', 'TEXMFHOME']).decode('utf-8').rstrip('\r\n') 139 | except: 140 | texmf_home = None 141 | 142 | 143 | # Get installation location from user 144 | texmf_vars = [texmf_dist, texmf_local, texmf_home] 145 | message = ''' 146 | Choose an installation location. 147 | 148 | TEXMFDIST is a good choice if you want to update PythonTeX 149 | in the future using your TeX distribution's package manager 150 | (assuming that is supported). 151 | 152 | 1. TEXMFDIST 153 | {0} 154 | 2. TEXMFLOCAL 155 | {1} 156 | 3. TEXMFHOME 157 | {2} 158 | 4. Manual location 159 | 160 | 5. Exit without installing 161 | '''.format(*[x if x else '' for x in texmf_vars]) 162 | 163 | if any(texmf_vars): 164 | path_choice = '' 165 | while (path_choice not in ('1', '2', '3', '4', '5') or 166 | (int(path_choice) <= 3 and not texmf_vars[int(path_choice)-1])): 167 | print(textwrap.dedent(message)) 168 | path_choice = input('Installation location (number): ') 169 | if path_choice == '': 170 | sys.exit() 171 | if path_choice == '1': 172 | texmf_path = texmf_dist 173 | elif path_choice == '2': 174 | texmf_path = texmf_local 175 | elif path_choice == '3': 176 | texmf_path = texmf_home 177 | elif path_choice == '4': 178 | texmf_path = input('Enter a path:\n') 179 | if texmf_path == '': 180 | sys.exit() 181 | if platform.system() == 'Windows': 182 | if 'texlive' in texmf_path.lower(): 183 | detected_texdist = True 184 | texlive = True 185 | miktex = False 186 | elif 'miktex' in texmf_path.lower(): 187 | detected_texdist = True 188 | texlive = False 189 | miktex = True 190 | else: 191 | sys.exit() 192 | else: 193 | print('Failed to detect possible installation locations automatically.') 194 | print('TEXMF paths could not be located with kpsewhich.') 195 | texmf_path = input('Plese enter an installation path, or press "Enter" to exit:\n') 196 | if texmf_path == '': 197 | sys.exit() 198 | 199 | # Make sure path slashes are compatible with the operating system 200 | # Kpathsea returns forward slashes, but Windows needs back slashes 201 | texmf_path = path.expandvars(path.expanduser(path.normcase(texmf_path))) 202 | 203 | # Check to make sure the path is valid 204 | # This should only be needed for manual input, but it's a good check 205 | if not path.isdir(texmf_path): 206 | sys.exit('Invalid installation path. Exiting.') 207 | 208 | # Now check that all other needed paths are present 209 | if path_choice != '2': 210 | doc_path = path.join(texmf_path, 'doc', 'latex') 211 | package_path = path.join(texmf_path, 'tex', 'latex') 212 | scripts_path = path.join(texmf_path, 'scripts') 213 | source_path = path.join(texmf_path, 'source', 'latex') 214 | else: 215 | doc_path = path.join(texmf_path, 'doc', 'latex', 'local') 216 | package_path = path.join(texmf_path, 'tex', 'latex', 'local') 217 | scripts_path = path.join(texmf_path, 'scripts', 'local') 218 | source_path = path.join(texmf_path, 'source', 'latex', 'local') 219 | # May need to create some local directories 220 | make_paths = False 221 | for eachpath in [doc_path, package_path, scripts_path, source_path]: 222 | if not path.exists(eachpath): 223 | if make_paths: 224 | makedirs(eachpath) 225 | print(' * Created ' + eachpath) 226 | else: 227 | choice = '' 228 | while choice not in ('y', 'n'): 229 | choice = input('Some directories do not exist. Create them? [y/n] ') 230 | if choice == '': 231 | sys.exit() 232 | if choice == 'y': 233 | make_paths = True 234 | try: 235 | makedirs(eachpath) 236 | print(' * Created ' + eachpath) 237 | except (OSError, IOError) as e: 238 | if e.errno == 13: 239 | print('\nInsufficient permission to install PythonTeX') 240 | if platform.system() == 'Windows': 241 | message = ''' 242 | You may need to run the installer as "administrator". 243 | This may be done under Vista and later by right-clicking on 244 | pythontex_install.bat, then selecting "Run as administrator". 245 | Or you can open a command prompt as administrator 246 | (Start, Programs, Accessories, right-click Command Prompt, 247 | Run as administrator), change to the directory in which 248 | pythontex_install.py is located, and run 249 | "python pythontex_install.py". 250 | ''' 251 | print(textwrap.dedent(message)) 252 | call(['pause'], shell=True) 253 | else: 254 | print('(For example, you may need "sudo", or possibly "sudo env PATH=$PATH")\n') 255 | sys.exit(1) 256 | else: 257 | raise 258 | else: 259 | message = ''' 260 | Paths were not created. The following will be needed. 261 | * {0} 262 | * {1} 263 | * {2} 264 | * {3} 265 | 266 | Exiting. 267 | '''.format(doc_path, package_path, scripts_path, source_path) 268 | print(textwrap.dedent(message)) 269 | sys.exit() 270 | 271 | # Modify the paths by adding the pythontex directory, which will be created 272 | doc_path = path.join(doc_path, 'pythontex') 273 | package_path = path.join(package_path, 'pythontex') 274 | scripts_path = path.join(scripts_path, 'pythontex') 275 | source_path = path.join(source_path, 'pythontex') 276 | 277 | 278 | # Install files 279 | # Use a try/except in case elevated permissions are needed (Linux and OS X) 280 | print('\nPythonTeX will be installed in \n ' + texmf_path) 281 | try: 282 | # Install docs 283 | if not path.exists(doc_path): 284 | mkdir(doc_path) 285 | copy('pythontex.pdf', doc_path) 286 | copy('README', doc_path) 287 | for doc in ('pythontex_quickstart.tex', 'pythontex_quickstart.pdf', 288 | 'pythontex_gallery.tex', 'pythontex_gallery.pdf'): 289 | if path.isfile(doc): 290 | copy(doc, doc_path) 291 | else: 292 | doc = path.join('..', doc.rsplit('.', 1)[0], doc) 293 | if path.isfile(doc): 294 | copy(doc, doc_path) 295 | # Install package 296 | if not path.exists(package_path): 297 | mkdir(package_path) 298 | copy('pythontex.sty', package_path) 299 | # Install scripts 300 | if not path.exists(scripts_path): 301 | mkdir(scripts_path) 302 | copy('pythontex.py', scripts_path) 303 | copy('depythontex.py', scripts_path) 304 | copy('pythontex_utils.py', scripts_path) 305 | copy('pythontex_engines.py', scripts_path) 306 | copy('syncpdb.py', scripts_path) 307 | for ver in [2, 3]: 308 | copy('pythontex{0}.py'.format(ver), scripts_path) 309 | copy('depythontex{0}.py'.format(ver), scripts_path) 310 | # Install source 311 | if not path.exists(source_path): 312 | mkdir(source_path) 313 | copy('pythontex.ins', source_path) 314 | copy('pythontex.dtx', source_path) 315 | except (OSError, IOError) as e: 316 | if e.errno == 13: 317 | print('\nInsufficient permission to install PythonTeX') 318 | if platform.system() == 'Windows': 319 | message = ''' 320 | You may need to run the installer as "administrator". 321 | This may be done under Vista and later by right-clicking on 322 | pythontex_install.bat, then selecting "Run as administrator". 323 | Or you can open a command prompt as administrator 324 | (Start, Programs, Accessories, right-click Command Prompt, 325 | Run as administrator), change to the directory in which 326 | pythontex_install.py is located, and run 327 | "python pythontex_install.py". 328 | ''' 329 | print(textwrap.dedent(message)) 330 | call(['pause'], shell=True) 331 | else: 332 | print('(For example, you may need "sudo", or possibly "sudo env PATH=$PATH")\n') 333 | sys.exit(1) 334 | else: 335 | raise 336 | 337 | 338 | # Install binary wrappers, create symlinks, or suggest the creation of 339 | # wrappers/batch files/symlinks. This part is operating system dependent. 340 | if platform.system() == 'Windows': 341 | # If under Windows, we create a binary wrapper if under TeX Live 342 | # or a batch file if under MiKTeX. Otherwise, alert the user 343 | # regarding the need for a wrapper or batch file. 344 | if miktex: 345 | try: 346 | if sys.version_info.major == 2: 347 | bin_path = check_output(['kpsewhich', '-var-value', 'TEXMFDIST']).rstrip('\r\n') 348 | else: 349 | bin_path = check_output(['kpsewhich', '-var-value', 'TEXMFDIST']).decode('utf-8').rstrip('\r\n') 350 | bin_path = path.join(bin_path, 'miktex', 'bin') 351 | 352 | for s in ('pythontex.py', 'depythontex.py'): 353 | batch = '@echo off\n"{0}" %*\n'.format(path.join(scripts_path, s)) 354 | f = open(path.join(bin_path, s.replace('.py', '.bat')), 'w') 355 | f.write(batch) 356 | f.close() 357 | except: 358 | message = ''' 359 | Could not create a batch file for launching pythontex.py and 360 | depythontex.py. You will need to create a batch file manually. 361 | Sample batch files are included with the main PythonTeX files. 362 | The batch files should be in a location on the Windows PATH. 363 | The bin/ directory in your TeX distribution may be a good 364 | location. 365 | 366 | The scripts pythontex.py and depythontex.py are located in 367 | the following directory: 368 | {0} 369 | '''.format(scripts_path) 370 | print(textwrap.dedent(message)) 371 | else: 372 | # Assemble the binary path, assuming TeX Live 373 | # The directory bin/ should be at the same level as texmf 374 | bin_path = path.join(path.split(texmf_path)[0], 'bin', 'win32') 375 | if path.exists(path.join(bin_path, 'runscript.exe')): 376 | for f in ('pythontex.py', 'depythontex.py'): 377 | copy(path.join(bin_path, 'runscript.exe'), path.join(bin_path, '{0}.exe'.format(f.rsplit('.')[0]))) 378 | print('\nCreated binary wrapper...') 379 | else: 380 | message = ''' 381 | Could not create a wrapper for launching pythontex.py and 382 | depythontex.py; did not find runscript.exe. You will need 383 | to create a wrapper manually, or use a batch file. Sample 384 | batch files are included with the main PythonTeX files. 385 | The wrapper or batch file should be in a location on the 386 | Windows PATH. The bin/ directory in your TeX distribution 387 | may be a good location. 388 | 389 | The scripts pythontex.py and depythontex.py are located in 390 | the following directory: 391 | {0} 392 | '''.format(scripts_path) 393 | print(textwrap.dedent(message)) 394 | else: 395 | # Optimistically proceed as if every system other than Windows can 396 | # share one set of code. 397 | root_path = path.split(texmf_path)[0] 398 | # Create a list of all possible subdirectories of bin/ for TeX Live 399 | # Source: http://www.tug.org/texlive/doc/texlive-en/texlive-en.html#x1-250003.2.1 400 | texlive_platforms = ['alpha-linux', 'amd64-freebsd', 'amd64-kfreebsd', 401 | 'armel-linux', 'i386-cygwin', 'i386-freebsd', 402 | 'i386-kfreebsd', 'i386-linux', 'i386-solaris', 403 | 'mips-irix', 'mipsel-linux', 'powerpc-aix', 404 | 'powerpc-linux', 'sparc-solaris', 'universal-darwin', 405 | 'x86_64-darwin', 'x86_64-linux', 'x86_64-solaris'] 406 | symlink_created = False 407 | # Try to create a symlink in the standard TeX Live locations 408 | for pltfrm in texlive_platforms: 409 | bin_path = path.join(root_path, 'bin', pltfrm) 410 | if path.exists(bin_path): 411 | # Unlink any old symlinks if they exist, and create new ones 412 | # Not doing this gave permissions errors under Ubuntu 413 | for f in ('pythontex.py', 'pythontex2.py', 'pythontex3.py', 414 | 'depythontex.py', 'depythontex2.py', 'depythontex3.py'): 415 | link = path.join(bin_path, f) 416 | if path.exists(link): 417 | unlink(link) 418 | symlink(path.join(scripts_path, f), link) 419 | chmod(link, 0o775) 420 | symlink_created = True 421 | 422 | # If the standard TeX Live bin/ locations didn't work, try the typical 423 | # location for MacPorts TeX Live. This should typically be 424 | # /opt/local/bin, but instead of assuming that location, we just climb 425 | # two levels up from texmf-dist and then look for a bin/ directory that 426 | # contains a tex executable. (For MacPorts, texmf-dist should be at 427 | # /opt/local/share/texmf-dist.) 428 | if not symlink_created and platform.system() == 'Darwin': 429 | bin_path = path.join(path.split(root_path)[0], 'bin') 430 | if path.exists(bin_path): 431 | try: 432 | # Make sure this bin/ is the bin/ we're looking for, by 433 | # seeing if pdftex exists 434 | check_output([path.join(bin_path, 'pdftex'), '--version']) 435 | # Create symlinks 436 | for f in ('pythontex.py', 'pythontex2.py', 'pythontex3.py', 437 | 'depythontex.py', 'depythontex2.py', 'depythontex3.py'): 438 | link = path.join(bin_path, f) 439 | if path.exists(link): 440 | unlink(link) 441 | symlink(path.join(scripts_path, f), link) 442 | chmod(link, 0o775) 443 | symlink_created = True 444 | except: 445 | pass 446 | if symlink_created: 447 | print("\nCreated symlink in Tex's bin/ directory...") 448 | else: 449 | print('\nCould not automatically create a symlink to pythontex*.py and depythontex*.py.') 450 | print('You may wish to create one manually, and make it executable via chmod.') 451 | print('The scripts pythontex*.py and depythontex*.py are located in the following directory:') 452 | print(' ' + scripts_path) 453 | 454 | 455 | # Alert TeX to the existence of the package via mktexlsr 456 | if not miktex: 457 | try: 458 | # Need to adjust if under Windows with a user-specified TeX Live 459 | # installation and a default MiKTeX installation; want to call 460 | # mktexlsr for the user-specified TeX Live installation 461 | if platform.system() == 'Windows' and 'MiKTeX' in texout: 462 | check_call(path.join(bin_path, 'mktexlsr')) 463 | else: 464 | check_call(['mktexlsr']) 465 | print('\nRunning "mktexlsr" to make TeX aware of new files...') 466 | except: 467 | print('Could not run "mktexlsr".') 468 | print('Your system may not be aware of newly installed files.') 469 | else: 470 | success = False 471 | try: 472 | check_call(['initexmf', '--admin', '--update-fndb']) 473 | print('\nRunning "initexmf --admin --update-fndb" to make TeX aware of new files...') 474 | check_call(['initexmf', '--update-fndb']) 475 | print('\nRunning "initexmf --update-fndb" to make TeX aware of new files...') 476 | success = True 477 | except: 478 | pass 479 | if not success: 480 | try: 481 | check_call(['initexmf', '--update-fndb']) 482 | print('\nRunning "initexmf --update-fndb" to make TeX aware of new files...') 483 | print('Depending on your installation settings, you may also need to run') 484 | print('"initexmf --admin --update-fndb"') 485 | except: 486 | print('Could not run "initexmf --update-fndb" or "initexmf --admin --update-fndb"') 487 | print('Your system may not be aware of newly installed files.') 488 | 489 | 490 | if platform.system() == 'Windows': 491 | # Pause so that the user can see any errors or other messages 492 | # input('\n[Press ENTER to exit]') 493 | print('\n') 494 | call(['pause'], shell=True) 495 | -------------------------------------------------------------------------------- /pythontex/pythontex_utils.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | ''' 3 | PythonTeX utilities class for Python scripts. 4 | 5 | The utilities class provides variables and methods for the individual 6 | Python scripts created and executed by PythonTeX. An instance of the class 7 | named "pytex" is automatically created in each individual script. 8 | 9 | Copyright (c) 2012-2014, Geoffrey M. Poore 10 | All rights reserved. 11 | Licensed under the BSD 3-Clause License: 12 | http://www.opensource.org/licenses/BSD-3-Clause 13 | 14 | ''' 15 | 16 | 17 | # Imports 18 | import sys 19 | import warnings 20 | if sys.version_info.major == 2: 21 | import io 22 | 23 | # Most imports are only needed for SymPy; these are brought in via 24 | # "lazy import." Importing unicode_literals here shouldn't ever be necessary 25 | # under Python 2. If unicode_literals is imported in the main script, then 26 | # all strings in this script will be treated as bytes, and the main script 27 | # will try to decode the strings from this script as necessary. The decoding 28 | # shouldn't cause any problems, since all strings in this file may be decoded 29 | # as valid ASCII. (The actual file is encoded in utf-8, but only characters 30 | # within the ASCII subset are actually used). 31 | 32 | 33 | class PythonTeXUtils(object): 34 | ''' 35 | A class of PythonTeX utilities. 36 | 37 | Provides variables for keeping track of TeX-side information, and methods 38 | for formatting and saving data. 39 | 40 | The following variables and methods will be created within instances 41 | of the class during execution. 42 | 43 | String variables for keeping track of TeX information. Most are 44 | actually needed; the rest are included for completeness. 45 | * family 46 | * session 47 | * restart 48 | * command 49 | * context 50 | * args 51 | * instance 52 | * line 53 | 54 | Future file handle for output that is saved via macros 55 | * macrofile 56 | 57 | Future formatter function that is used to format output 58 | * formatter 59 | ''' 60 | 61 | def __init__(self, fmtr='str'): 62 | ''' 63 | Initialize 64 | ''' 65 | self.set_formatter(fmtr) 66 | 67 | # We need a function that will process the raw `context` into a 68 | # dictionary with attributes 69 | _context_raw = None 70 | class _DictWithAttr(dict): 71 | pass 72 | def set_context(self, expr): 73 | ''' 74 | Convert the string `{context}` into a dict with attributes 75 | ''' 76 | if not expr or expr == self._context_raw: 77 | pass 78 | else: 79 | self._context_raw = expr 80 | self.context = self._DictWithAttr() 81 | k_and_v = [map(lambda x: x.strip(), kv.split('=')) for kv in expr.split(',')] 82 | for k, v in k_and_v: 83 | if v.startswith('!!int '): 84 | v = int(float(v[6:])) 85 | elif v.startswith('!!float '): 86 | v = float(v[8:]) 87 | elif v.startswith('!!str '): 88 | v = v[6:] 89 | self.context[k] = v 90 | setattr(self.context, k, v) 91 | 92 | # A primary use for contextual information is to pass dimensions from the 93 | # TeX side to the Python side. To make that as convenient as possible, 94 | # we need some length conversion functions. 95 | # Conversion reference: http://tex.stackexchange.com/questions/41370/what-are-the-possible-dimensions-sizes-units-latex-understands 96 | def pt_to_in(self, expr): 97 | ''' 98 | Convert points to inches. Accepts numbers, strings of digits, and 99 | strings of digits that end with `pt`. 100 | ''' 101 | try: 102 | ans = expr/72.27 103 | except: 104 | if expr.endswith('pt'): 105 | expr = expr[:-2] 106 | ans = float(expr)/72.27 107 | return ans 108 | def pt_to_cm(self, expr): 109 | ''' 110 | Convert points to centimeters. 111 | ''' 112 | return self.pt_to_in(expr)*2.54 113 | def pt_to_mm(self, expr): 114 | ''' 115 | Convert points to millimeters. 116 | ''' 117 | return self.pt_to_in(expr)*25.4 118 | def pt_to_bp(self, expr): 119 | ''' 120 | Convert points to big (DTP or PostScript) points. 121 | ''' 122 | return self.pt_to_in(expr)*72 123 | 124 | 125 | # We need a context-aware interface to SymPy's latex printer. The 126 | # appearance of typeset math should depend on where it appears in a 127 | # document. (We will refer to the latex printer, rather than the LaTeX 128 | # printer, because the two are separate. Compare sympy.printing.latex 129 | # and sympy.galgebra.latex_ex.) 130 | # 131 | # Creating this interface takes some work. We don't want to import 132 | # anything from SymPy unless it is actually used, to keep things clean and 133 | # fast. 134 | 135 | # First we create a tuple containing all LaTeX math styles. These are 136 | # the contexts that SymPy's latex printer must adapt to. 137 | # The style order doesn't matter, but it corresponds to that of \mathchoice 138 | _sympy_latex_styles = ('display', 'text', 'script', 'scriptscript') 139 | 140 | # Create the public functions for the user, and private functions that 141 | # they call. Two layers are necessary, because we need to be able to 142 | # redefine the functions that do the actual work, once things are 143 | # initialized. But we don't want to redefine the public functions, since 144 | # that could cause problems if the user defines a new function to be one 145 | # of the public functions--the user's function would not change when 146 | # the method was redefined. 147 | def _sympy_latex(self, expr, **settings): 148 | self._init_sympy_latex() 149 | return self._sympy_latex(expr, **settings) 150 | 151 | def sympy_latex(self, expr, **settings): 152 | return self._sympy_latex(expr, **settings) 153 | 154 | def _set_sympy_latex(self, style, **kwargs): 155 | self._init_sympy_latex() 156 | self._set_sympy_latex(style, **kwargs) 157 | 158 | def set_sympy_latex(self, style, **kwargs): 159 | self._set_sympy_latex(style, **kwargs) 160 | # Temporary compatibility with deprecated methods 161 | def init_sympy_latex(self): 162 | warnings.warn('Method init_sympy_latex() is deprecated; init is now automatic.') 163 | self._init_sympy_latex() 164 | 165 | # Next we create a method that initializes the actual context-aware 166 | # interface to SymPy's latex printer. 167 | def _init_sympy_latex(self): 168 | ''' 169 | Initialize a context-aware interface to SymPy's latex printer. 170 | 171 | This consists of creating the dictionary of settings and creating the 172 | sympy_latex method that serves as an interface to SymPy's 173 | LatexPrinter. This last step is actually performed by calling 174 | self._make_sympy_latex(). 175 | ''' 176 | # Create dictionaries of settings for different contexts. 177 | # 178 | # Currently, the main goal is to use pmatrix (or an equivalent) 179 | # in \displaystyle contexts, and smallmatrix in \textstyle, 180 | # \scriptstyle (superscript or subscript), and \scriptscriptstyle 181 | # (superscript or subscript of a superscript or subscript) 182 | # contexts. Basically, we want matrix size to automatically 183 | # scale based on context. It is expected that additional 184 | # customization may prove useful as SymPy's LatexPrinter is 185 | # further developed. 186 | # 187 | # The 'fold_frac_powers' option is probably the main other 188 | # setting that might sometimes be nice to invoke in a 189 | # context-dependent manner. 190 | # 191 | # In the default settings below, all matrices are set to use 192 | # parentheses rather than square brackets. This is largely a 193 | # matter of personal preference. The use of parentheses is based 194 | # on the rationale that parentheses are less easily confused with 195 | # the determinant and are easier to write by hand than are square 196 | # brackets. The settings for 'script' and 'scriptscript' are set 197 | # to those of 'text', since all of these should in general 198 | # require a more compact representation of things. 199 | self._sympy_latex_settings = {'display': {'mat_str': 'pmatrix', 'mat_delim': None}, 200 | 'text': {'mat_str': 'smallmatrix', 'mat_delim': '('}, 201 | 'script': {'mat_str': 'smallmatrix', 'mat_delim': '('}, 202 | 'scriptscript': {'mat_str': 'smallmatrix', 'mat_delim': '('} } 203 | # Now we create a function for updating the settings. 204 | # 205 | # Note that EVERY time the settings are changed, we must call 206 | # self._make_sympy_latex(). This is because the _sympy_latex() 207 | # method is defined based on the settings, and every time the 208 | # settings change, it may need to be redefined. It would be 209 | # possible to define _sympy_latex() so that its definition remained 210 | # constant, simply drawing on the settings. But most common 211 | # combinations of settings allow more efficient versions of 212 | # _sympy_latex() to be defined. 213 | def _set_sympy_latex(style, **kwargs): 214 | if style in self._sympy_latex_styles: 215 | self._sympy_latex_settings[style].update(kwargs) 216 | elif style == 'all': 217 | for s in self._sympy_latex_styles: 218 | self._sympy_latex_settings[s].update(kwargs) 219 | else: 220 | warnings.warn('Unknown LaTeX math style ' + str(style)) 221 | self._make_sympy_latex() 222 | self._set_sympy_latex = _set_sympy_latex 223 | 224 | # Now that the dictionaries of settings have been created, and 225 | # the function for modifying the settings is in place, we are ready 226 | # to create the actual interface. 227 | self._make_sympy_latex() 228 | 229 | # Finally, create the actual interface to SymPy's LatexPrinter 230 | def _make_sympy_latex(self): 231 | ''' 232 | Create a context-aware interface to SymPy's LatexPrinter class. 233 | 234 | This is an interface to the LatexPrinter class, rather than 235 | to the latex function, because the function is simply a 236 | wrapper for accessing the class and because settings may be 237 | passed to the class more easily. 238 | 239 | Context dependence is accomplished via LaTeX's \mathchoice macro. 240 | This macros takes four arguments: 241 | \mathchoice{}{}{ 210 | 213 | 214 | 215 |
216 |

PythonTeX Gallery

217 |

Geoffrey M. Poore

218 |
219 |

General Python interaction

220 |

We can typeset code that is passed to Python, and bring back the results.

221 |

This can be simple. For example, print('Python says hi!') returns the following:

222 |
223 |

Python says hi!

224 |
225 |

Or we could access the printed content verbatim (it might contain special characters):

226 |
227 |

Python says hi!

228 |
229 |

Python interaction can also be more complex. print(str(2**2**2) + r'\endinput') returns 16. In this case, the printed result includes LaTeX code, which is correctly interpreted by LaTeX to ensure that there is not an extra space after the 16. Printed output is saved to a file and brought back in via \input, and the \endinput command stops input immediately, before LaTeX gets to the end of the line and inserts a space character there, after the 16.

230 |

Printing works, but as the last example demonstrates, you have to be careful about spacing if you have text immediately after the printed content. In that case, it’s usually best to assemble text within a PythonTeX environment and store the text in a variable. Then you can bring in the text later, using the \py command. The \py command brings in a string representation of its argument. First we create the text.

231 |
mytext = '$1 + 1 = {0}$'.format(1 + 1)
232 |

Then we bring it in: \(1 + 1 = 2\). The \py command can even bring in verbatim content.

233 |

We don’t have to typeset the code we’re executing. It can be hidden. And then we can access it later: This is a message from Python.

234 |

It is also possible to perform variable substitution or string interpolation. The earlier result could be recreated: \(1 + 1 = 2\).

235 |

Pygments highlighting

236 |

PythonTeX supports syntax highlighting via Pygments. Any language supported by Pygments can be highlighted. Unicode is supported. Consider this snippet copied and pasted from a Python 3 interactive session. (Using random strings of Unicode for variable names is probably not a good idea, but PythonTeX will happily highlight it for you.)

237 |
>>> âæéöø = 123
238 | >>> ßçñðŠ = 456
239 | >>> âæéöø + ßçñðŠ
240 | 579
241 |

There is also a Pygments command for inline use: \pygment.

242 |

Python console environment

243 |

PythonTeX includes an environment that emulates a Python interactive session. Commands are entered within the environment, each line is treated as input to an interactive session, and the result is typeset.

244 |
>>> x = 123
245 | >>> y = 345
246 | >>> z = x + y
247 | >>> z
248 | 468
249 | >>> def f(expr):
250 | ...     return(expr**4)
251 | ... 
252 | >>> f(x)
253 | 228886641
254 | >>> print('Python says hi from the console!')
255 | Python says hi from the console!
256 |

It is possible to refer to the values of console variables later on in inline contexts, using the \pycon command. For example, the value of \(z\) was 468.

257 |

Basic SymPy interaction

258 |

PythonTeX allows us to perform algebraic manipulations with SymPy and then properly typeset the results.

259 |

We create three variables, and define \(z\) in terms of the other two.

260 |
var('x, y, z')
261 | z = x + y
262 |

Now we can access what \(z\) is equal to:

263 |

\[z=x + y\]

264 |

Many things are possible, including some very nice calculus.

265 |
f = x**3 + cos(x)**5
266 | g = Integral(f, x)
267 |

\[\int \left(x^{3} + \cos^{5}{\left(x \right)}\right)\, dx=\frac{x^{4}}{4} + \frac{\sin^{5}{\left(x \right)}}{5} - \frac{2 \sin^{3}{\left(x \right)}}{3} + \sin{\left(x \right)}\]

268 |

It’s easy to use arbitrary symbols in equations.

269 |
phi = Symbol(r'\phi')
270 | h = Integral(exp(-phi**2), (phi, 0, oo))
271 |

\[\int\limits_{0}^{\infty} e^{- \phi^{2}}\, d\phi=\frac{\sqrt{\pi}}{2}\]

272 |

Plots with matplotlib

273 |

We can create plots with matplotlib, perfectly matching the plot fonts with the document fonts. No more searching for the code that created a figure!

274 |

It is possible to pass page dimensions and similar contextual information from the LaTeX side to the Python side. If you want your figures to be, for example, a particular fraction of the page width, you can pass the value of \textwidth to the Python side, and use it in creating your figures. See \setpythontexcontext in the main documentation for details.

275 |

You may want to use matplotlib’s PGF backend when creating plots.

276 |
rc('text', usetex=True)
277 | rc('font', family='serif')
278 | rc('font', size=10.0)
279 | rc('legend', fontsize=10.0)
280 | rc('font', weight='normal')
281 | x = linspace(0, 10)
282 | figure(figsize=(4, 2.5))
283 | plot(x, sin(x), label='$\sin(x)$')
284 | xlabel(r'$x\mathrm{-axis}$')
285 | ylabel(r'$y\mathrm{-axis}$')
286 | legend(loc='lower right')
287 | savefig('myplot.png', bbox_inches='tight')
288 |
289 |

image

290 |
291 |

Basic pylab interaction

292 |
from scipy.integrate import quad
293 | myintegral = quad(lambda x: e**-x**2, 0, inf)[0]
294 |

\[\int_0^\infty e^{-x^2}\,dx = 0.886226925452758\]

295 |

An automated derivative and integral table

296 |

PythonTeX allows some amazing document automation, such as this derivative and integral table. Try typing that by hand, fast!

297 |
from re import sub
298 | 
299 | var('x')
300 | 
301 | # Create a list of functions to include in the table
302 | funcs = ['sin(x)', 'cos(x)', 'tan(x)', 
303 |          'sin(x)**2', 'cos(x)**2', 'tan(x)**2', 
304 |          'asin(x)', 'acos(x)', 'atan(x)', 
305 |          'sinh(x)', 'cosh(x)', 'tanh(x)']
306 | 
307 | print(r'\begin{align*}')
308 | 
309 | for func in funcs:
310 |     # Put in some vertical space when switching to arc and hyperbolic funcs
311 |     if func == 'asin(x)' or func == 'sinh(x)':
312 |         print(r'&\\')
313 |     myderiv = 'Derivative(' + func + ', x)'
314 |     myint = 'Integral(' + func + ', x)'
315 |     print(latex(eval(myderiv)) + '&=' +
316 |             latex(eval(myderiv + '.doit()')) + r'\quad & \quad')
317 |     print(latex(eval(myint)) + '&=' +
318 |             latex(eval(myint+'.doit()')) + r'\\')
319 | print(r'\end{align*}')
320 |

\[\begin{aligned} 321 | \frac{d}{d x} \sin{\left(x \right)}&=\cos{\left(x \right)}\quad & \quad 322 | \int \sin{\left(x \right)}\, dx&=- \cos{\left(x \right)}\\ 323 | \frac{d}{d x} \cos{\left(x \right)}&=- \sin{\left(x \right)}\quad & \quad 324 | \int \cos{\left(x \right)}\, dx&=\sin{\left(x \right)}\\ 325 | \frac{d}{d x} \tan{\left(x \right)}&=\tan^{2}{\left(x \right)} + 1\quad & \quad 326 | \int \tan{\left(x \right)}\, dx&=- \log{\left(\cos{\left(x \right)} \right)}\\ 327 | \frac{d}{d x} \sin^{2}{\left(x \right)}&=2 \sin{\left(x \right)} \cos{\left(x \right)}\quad & \quad 328 | \int \sin^{2}{\left(x \right)}\, dx&=\frac{x}{2} - \frac{\sin{\left(x \right)} \cos{\left(x \right)}}{2}\\ 329 | \frac{d}{d x} \cos^{2}{\left(x \right)}&=- 2 \sin{\left(x \right)} \cos{\left(x \right)}\quad & \quad 330 | \int \cos^{2}{\left(x \right)}\, dx&=\frac{x}{2} + \frac{\sin{\left(x \right)} \cos{\left(x \right)}}{2}\\ 331 | \frac{d}{d x} \tan^{2}{\left(x \right)}&=\left(2 \tan^{2}{\left(x \right)} + 2\right) \tan{\left(x \right)}\quad & \quad 332 | \int \tan^{2}{\left(x \right)}\, dx&=- x + \frac{\sin{\left(x \right)}}{\cos{\left(x \right)}}\\ 333 | &\\ 334 | \frac{d}{d x} \operatorname{asin}{\left(x \right)}&=\frac{1}{\sqrt{1 - x^{2}}}\quad & \quad 335 | \int \operatorname{asin}{\left(x \right)}\, dx&=x \operatorname{asin}{\left(x \right)} + \sqrt{1 - x^{2}}\\ 336 | \frac{d}{d x} \operatorname{acos}{\left(x \right)}&=- \frac{1}{\sqrt{1 - x^{2}}}\quad & \quad 337 | \int \operatorname{acos}{\left(x \right)}\, dx&=x \operatorname{acos}{\left(x \right)} - \sqrt{1 - x^{2}}\\ 338 | \frac{d}{d x} \operatorname{atan}{\left(x \right)}&=\frac{1}{x^{2} + 1}\quad & \quad 339 | \int \operatorname{atan}{\left(x \right)}\, dx&=x \operatorname{atan}{\left(x \right)} - \frac{\log{\left(x^{2} + 1 \right)}}{2}\\ 340 | &\\ 341 | \frac{d}{d x} \sinh{\left(x \right)}&=\cosh{\left(x \right)}\quad & \quad 342 | \int \sinh{\left(x \right)}\, dx&=\cosh{\left(x \right)}\\ 343 | \frac{d}{d x} \cosh{\left(x \right)}&=\sinh{\left(x \right)}\quad & \quad 344 | \int \cosh{\left(x \right)}\, dx&=\sinh{\left(x \right)}\\ 345 | \frac{d}{d x} \tanh{\left(x \right)}&=1 - \tanh^{2}{\left(x \right)}\quad & \quad 346 | \int \tanh{\left(x \right)}\, dx&=x - \log{\left(\tanh{\left(x \right)} + 1 \right)}\\\end{aligned}\]

347 |

Step-by-step solutions

348 |

Using SymPy, it is possible to typeset step-by-step solutions. In this particular case, we also use the mdframed package to place a colored background behind our code.

349 |
x, y, z = symbols('x,y,z')
350 | f = Symbol('f(x,y,z)')
351 | 
352 | # Define limits of integration
353 | x_llim = 0
354 | x_ulim = 2
355 | y_llim = 0
356 | y_ulim = 3
357 | z_llim = 0
358 | z_ulim = 4
359 | 
360 | print(r'\begin{align*}')
361 | 
362 | # Notice how I define f as a symbol, then later as an actual function
363 | left = Integral(f, (x, x_llim, x_ulim), (y, y_llim, y_ulim), (z, z_llim, z_ulim))
364 | f = x*y + y*sin(z) + cos(x+y)
365 | right = Integral(f, (x, x_llim, x_ulim), (y, y_llim, y_ulim), (z, z_llim, z_ulim))
366 | print(latex(left) + '&=' + latex(right) + r'\\')
367 | 
368 | # For each step, I move limits from an outer integral to an inner, evaluated 
369 | # integral until the outer integral is no longer needed
370 | right = Integral(Integral(f, (z, z_llim, z_ulim)).doit(), (x, x_llim, x_ulim),
371 |                  (y, y_llim, y_ulim))
372 | print('&=' + latex(right) + r'\\')
373 | 
374 | right = Integral(Integral(f, (z, z_llim, z_ulim), (y, y_llim, y_ulim)).doit(),
375 |                  (x, x_llim, x_ulim))
376 | print('&=' + latex(right) + r'\\')
377 | 
378 | right = Integral(f, (z, z_llim, z_ulim), (y, y_llim, y_ulim), 
379 |                  (x, x_llim, x_ulim)).doit()
380 | print('&=' + latex(right) + r'\\')
381 | 
382 | print('&=' + latex(N(right)) + r'\\')
383 | 
384 | print(r'\end{align*}')
385 |

\[\begin{aligned} 386 | \int\limits_{0}^{4}\int\limits_{0}^{3}\int\limits_{0}^{2} f(x,y,z)\, dx\, dy\, dz&=\int\limits_{0}^{4}\int\limits_{0}^{3}\int\limits_{0}^{2} \left(x y + y \sin{\left(z \right)} + \cos{\left(x + y \right)}\right)\, dx\, dy\, dz\\ 387 | &=\int\limits_{0}^{3}\int\limits_{0}^{2} \left(4 x y - y \cos{\left(4 \right)} + y + 4 \cos{\left(x + y \right)}\right)\, dx\, dy\\ 388 | &=\int\limits_{0}^{2} \left(18 x - 4 \sin{\left(x \right)} + 4 \sin{\left(x + 3 \right)} - \frac{9 \cos{\left(4 \right)}}{2} + \frac{9}{2}\right)\, dx\\ 389 | &=4 \cos{\left(3 \right)} + 4 \cos{\left(2 \right)} - 4 \cos{\left(5 \right)} - 9 \cos{\left(4 \right)} + 41\\ 390 | &=40.1235865133293\\\end{aligned}\]

391 |

Including stderr

392 |

PythonTeX allows code to be typset next to the stderr it produces. This requires the package option makestderr.

393 |
x = 123
394 | y = 345
395 | z = x + y +
396 |

This code causes a syntax error:

397 |
  File "py_errorsession_9.py", line 3
398 |     z = x + y +
399 |               ^
400 | SyntaxError: invalid syntax
401 |

The package option stderrfilename allows the file name that appears in the error message to be customized.

402 |
403 |
404 |
    405 |
  1. Since PythonTeX runs Python code (and potentially other code) on your computer, documents using PythonTeX have a greater potential for security risks than do standard LaTeX documents. You should only compile PythonTeX documents from sources you trust.↩︎

  2. 406 |
407 |
408 | 409 | 410 | -------------------------------------------------------------------------------- /pythontex_gallery/pythontex_gallery.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gpoore/pythontex/4ab50a8679f1288935a09d4498de501a387abc00/pythontex_gallery/pythontex_gallery.pdf -------------------------------------------------------------------------------- /pythontex_gallery/pythontex_gallery.tex: -------------------------------------------------------------------------------- 1 | \documentclass[11pt]{article} 2 | 3 | % Engine-specific settings 4 | % Detect pdftex/xetex/luatex, and load appropriate font packages. 5 | % This is inspired by the approach in the iftex package. 6 | % pdftex: 7 | \ifx\pdfmatch\undefined 8 | \else 9 | \usepackage[T1]{fontenc} 10 | \usepackage[utf8]{inputenc} 11 | \fi 12 | % xetex: 13 | \ifx\XeTeXinterchartoks\undefined 14 | \else 15 | \usepackage{fontspec} 16 | \defaultfontfeatures{Ligatures=TeX} 17 | \fi 18 | % luatex: 19 | \ifx\directlua\undefined 20 | \else 21 | \usepackage{fontspec} 22 | \fi 23 | % End engine-specific settings 24 | 25 | \usepackage{amsmath,amssymb} 26 | \usepackage{fullpage} 27 | \usepackage{graphicx} 28 | \usepackage[svgnames]{xcolor} 29 | \usepackage{url} 30 | \urlstyle{same} 31 | 32 | \usepackage[makestderr]{pythontex} 33 | \restartpythontexsession{\thesection} 34 | 35 | 36 | \usepackage[framemethod=TikZ]{mdframed} 37 | 38 | \newcommand{\pytex}{Python\TeX} 39 | \renewcommand*{\thefootnote}{\fnsymbol{footnote}} 40 | 41 | 42 | \title{\pytex\ Gallery} 43 | \author{Geoffrey M.\ Poore} 44 | 45 | 46 | \begin{document} 47 | 48 | 49 | \maketitle 50 | 51 | 52 | \begin{abstract} 53 | \pytex\ allows you to run Python code from within \LaTeX\ documents and automatically include the output. This document serves as an example of what is possible with \pytex.\footnote{Since \pytex\ runs Python code (and potentially other code) on your computer, documents using \pytex\ have a greater potential for security risks than do standard \LaTeX\ documents. You should only compile \pytex\ documents from sources you trust.} 54 | \end{abstract} 55 | 56 | 57 | 58 | \section{General Python interaction} 59 | 60 | We can typeset code that is passed to Python, and bring back the results. 61 | 62 | This can be simple. For example, \pyb{print('Python says hi!')} returns the following: 63 | \begin{quote} 64 | \printpythontex 65 | \end{quote} 66 | 67 | Or we could access the printed content verbatim (it might contain special characters): 68 | \begin{quote} 69 | \printpythontex[verb] 70 | \end{quote} 71 | 72 | Python interaction can also be more complex. \pyb{print(str(2**2**2) + r'\endinput')} returns \printpythontex. In this case, the printed result includes \LaTeX\ code, which is correctly interpreted by \LaTeX\ to ensure that there is not an extra space after the 16. Printed output is saved to a file and brought back in via \verb|\input|, and the \verb|\endinput| command stops input immediately, before \LaTeX\ gets to the end of the line and inserts a space character there, after the 16. 73 | 74 | Printing works, but as the last example demonstrates, you have to be careful about spacing if you have text immediately after the printed content. In that case, it's usually best to assemble text within a \pytex\ environment and store the text in a variable. Then you can bring in the text later, using the \pygment{latex}{\py} command. The \pygment{latex}{\py} command brings in a string representation of its argument. First we create the text. 75 | \begin{pyblock} 76 | mytext = '$1 + 1 = {0}$'.format(1 + 1) 77 | \end{pyblock} 78 | Then we bring it in: \py{mytext}. The \pygment{latex}{\py} command can even bring in verbatim content. 79 | 80 | We don't have to typeset the code we're executing. It can be hidden.\pyc{mystring=r'\textbf{This is a message from Python}'} And then we can access it later: \py{mystring}. 81 | 82 | It is also possible to perform variable substitution or string interpolation. The earlier result could be recreated: \pys{$1 + 1 = !{1+1}$}. 83 | 84 | 85 | \section{Pygments highlighting} 86 | 87 | \pytex\ supports syntax highlighting via Pygments. Any language supported by Pygments can be highlighted. Unicode is supported. Consider this snippet copied and pasted from a Python 3 interactive session. (Using random strings of Unicode for variable names is probably not a good idea, but \pytex\ will happily highlight it for you.) 88 | 89 | \begin{pygments}{pycon} 90 | >>> âæéöø = 123 91 | >>> ßçñðŠ = 456 92 | >>> âæéöø + ßçñðŠ 93 | 579 94 | \end{pygments} 95 | 96 | There is also a Pygments command for inline use: \pygment{latex}{\pygment}. 97 | 98 | 99 | \section{Python console environment} 100 | 101 | \pytex\ includes an environment that emulates a Python interactive session. Commands are entered within the environment, each line is treated as input to an interactive session, and the result is typeset. 102 | 103 | \begin{pyconsole}[][frame=single] 104 | x = 123 105 | y = 345 106 | z = x + y 107 | z 108 | def f(expr): 109 | return(expr**4) 110 | 111 | f(x) 112 | print('Python says hi from the console!') 113 | \end{pyconsole} 114 | 115 | It is possible to refer to the values of console variables later on in inline contexts, using the \pygment{latex}{\pycon} command. For example, the value of $z$ was \pycon{z}. 116 | 117 | 118 | \section{Basic SymPy interaction} 119 | 120 | \pytex\ allows us to perform algebraic manipulations with SymPy and then properly typeset the results. 121 | 122 | We create three variables, and define $z$ in terms of the other two. 123 | 124 | \begin{sympyblock} 125 | var('x, y, z') 126 | z = x + y 127 | \end{sympyblock} 128 | 129 | Now we can access what $z$ is equal to: 130 | 131 | \[z=\sympy{z}\] 132 | 133 | Many things are possible, including some very nice calculus. 134 | 135 | \begin{sympyblock} 136 | f = x**3 + cos(x)**5 137 | g = Integral(f, x) 138 | \end{sympyblock} 139 | 140 | \[\sympy{g}=\sympy{g.doit()}\] 141 | 142 | It's easy to use arbitrary symbols in equations. 143 | 144 | \begin{sympyblock} 145 | phi = Symbol(r'\phi') 146 | h = Integral(exp(-phi**2), (phi, 0, oo)) 147 | \end{sympyblock} 148 | 149 | \[\sympy{h}=\sympy{h.doit()}\] 150 | 151 | 152 | 153 | \section{Plots with matplotlib} 154 | 155 | We can create plots with matplotlib, perfectly matching the plot fonts with the document fonts. No more searching for the code that created a figure! 156 | 157 | It is possible to pass page dimensions and similar contextual information from the \LaTeX\ side to the Python side. If you want your figures to be, for example, a particular fraction of the page width, you can pass the value of \pygment{latex}{\textwidth} to the Python side, and use it in creating your figures. See \pygment{latex}{\setpythontexcontext} in the main documentation for details. 158 | 159 | You may want to use matplotlib's PGF backend when creating plots. 160 | 161 | \begin{pylabblock} 162 | rc('text', usetex=True) 163 | rc('font', family='serif') 164 | rc('font', size=10.0) 165 | rc('legend', fontsize=10.0) 166 | rc('font', weight='normal') 167 | x = linspace(0, 10) 168 | figure(figsize=(4, 2.5)) 169 | plot(x, sin(x), label='$\sin(x)$') 170 | xlabel(r'$x\mathrm{-axis}$') 171 | ylabel(r'$y\mathrm{-axis}$') 172 | legend(loc='lower right') 173 | savefig('myplot.pdf', bbox_inches='tight') 174 | \end{pylabblock} 175 | 176 | \begin{center} 177 | \includegraphics{myplot.pdf} 178 | \end{center} 179 | 180 | 181 | \section{Basic pylab interaction} 182 | 183 | \begin{pylabblock} 184 | from scipy.integrate import quad 185 | myintegral = quad(lambda x: e**-x**2, 0, inf)[0] 186 | \end{pylabblock} 187 | 188 | \[ \int_0^\infty e^{-x^2}\,dx = \pylab{myintegral} \] 189 | 190 | 191 | \section{An automated derivative and integral table} 192 | 193 | \pytex\ allows some amazing document automation, such as this derivative and integral table. Try typing that by hand, fast! 194 | 195 | \begin{sympyblock}[][numbers=left,frame=single,framesep=5mm,label=An Automated Derivative and Integral Table] 196 | from re import sub 197 | 198 | var('x') 199 | 200 | # Create a list of functions to include in the table 201 | funcs = ['sin(x)', 'cos(x)', 'tan(x)', 202 | 'sin(x)**2', 'cos(x)**2', 'tan(x)**2', 203 | 'asin(x)', 'acos(x)', 'atan(x)', 204 | 'sinh(x)', 'cosh(x)', 'tanh(x)'] 205 | 206 | print(r'\begin{align*}') 207 | 208 | for func in funcs: 209 | # Put in some vertical space when switching to arc and hyperbolic funcs 210 | if func == 'asin(x)' or func == 'sinh(x)': 211 | print(r'&\\') 212 | myderiv = 'Derivative(' + func + ', x)' 213 | myint = 'Integral(' + func + ', x)' 214 | print(latex(eval(myderiv)) + '&=' + 215 | latex(eval(myderiv + '.doit()')) + r'\quad & \quad') 216 | print(latex(eval(myint)) + '&=' + 217 | latex(eval(myint+'.doit()')) + r'\\') 218 | print(r'\end{align*}') 219 | \end{sympyblock} 220 | 221 | \printpythontex 222 | 223 | 224 | \section{Step-by-step solutions} 225 | 226 | Using SymPy, it is possible to typeset step-by-step solutions. In this particular case, we also use the \verb|mdframed| package to place a colored background behind our code. 227 | 228 | \begin{mdframed}[linecolor=Green,innerrightmargin=30pt,innerleftmargin=30pt,leftmargin=-30pt,rightmargin=-30pt,backgroundcolor=Black!5,skipabove=10pt,skipbelow=10pt,roundcorner=5pt,frametitle={Step-by-Step Integral Evaluation},frametitlealignment=\center,splitbottomskip=6pt,splittopskip=12pt] 229 | \begin{sympyblock}[][numbers=left] 230 | x, y, z = symbols('x,y,z') 231 | f = Symbol('f(x,y,z)') 232 | 233 | # Define limits of integration 234 | x_llim = 0 235 | x_ulim = 2 236 | y_llim = 0 237 | y_ulim = 3 238 | z_llim = 0 239 | z_ulim = 4 240 | 241 | print(r'\begin{align*}') 242 | 243 | # Notice how I define f as a symbol, then later as an actual function 244 | left = Integral(f, (x, x_llim, x_ulim), (y, y_llim, y_ulim), (z, z_llim, z_ulim)) 245 | f = x*y + y*sin(z) + cos(x+y) 246 | right = Integral(f, (x, x_llim, x_ulim), (y, y_llim, y_ulim), (z, z_llim, z_ulim)) 247 | print(latex(left) + '&=' + latex(right) + r'\\') 248 | 249 | # For each step, I move limits from an outer integral to an inner, evaluated 250 | # integral until the outer integral is no longer needed 251 | right = Integral(Integral(f, (z, z_llim, z_ulim)).doit(), (x, x_llim, x_ulim), 252 | (y, y_llim, y_ulim)) 253 | print('&=' + latex(right) + r'\\') 254 | 255 | right = Integral(Integral(f, (z, z_llim, z_ulim), (y, y_llim, y_ulim)).doit(), 256 | (x, x_llim, x_ulim)) 257 | print('&=' + latex(right) + r'\\') 258 | 259 | right = Integral(f, (z, z_llim, z_ulim), (y, y_llim, y_ulim), 260 | (x, x_llim, x_ulim)).doit() 261 | print('&=' + latex(right) + r'\\') 262 | 263 | print('&=' + latex(N(right)) + r'\\') 264 | 265 | print(r'\end{align*}') 266 | \end{sympyblock} 267 | \end{mdframed} 268 | 269 | \printpythontex 270 | 271 | 272 | \section{Including stderr} 273 | 274 | \pytex\ allows code to be typset next to the stderr it produces. This requires the package option \verb|makestderr|. 275 | 276 | \begin{pyblock}[errorsession][numbers=left] 277 | x = 123 278 | y = 345 279 | z = x + y + 280 | \end{pyblock} 281 | 282 | This code causes a syntax error: 283 | 284 | \stderrpythontex[verbatim][frame=single] 285 | 286 | The package option \verb|stderrfilename| allows the file name that appears in the error message to be customized. 287 | 288 | 289 | 290 | 291 | \end{document} 292 | -------------------------------------------------------------------------------- /pythontex_gallery/pythontex_gallery_2to3.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | ''' 5 | Convert PythonTeX scripts from Python 2 to Python 3 6 | 7 | It isn't possible to have a single PythonTeX code base, since unicode text 8 | needs to be supported. Under Python 2, this means importing unicode_literals 9 | from __future__, or using the unicode function or "u" prefix. Under Python 3, 10 | all strings are automatically unicode. 11 | 12 | At the same time, the differences between the Python 2 and 3 versions are 13 | usually very small, involving only a few lines of code. To keep the code base 14 | unified, while simultaneously fully supporting both Python 2 and 3, the 15 | following scheme was devised. The code is written for Python 2. Whenever 16 | code is not compatible with Python 3, it is enclosed with the tags 17 | "#// Python 2" and "#\\ End Python 2" (each on its own line, by itself). If 18 | a Python 3 version of the code is needed, it is included between analogous 19 | tags "#// Python 3" and "#\\ End Python 2". The Python 3 code is commented 20 | out with "#", at the same indentation level as the Python 3 tags. 21 | 22 | This script creates Python 3 scripts from the original Python 2 scripts 23 | by commenting out everything between the Python 2 tags, and uncommenting 24 | everything between the Python 3 tags. In this way, full compatibility is 25 | maintained with both Python 2 and 3 while keeping the code base essentially 26 | unified. This approach also allows greater customization of version-specific 27 | code than would be possible if automatic translation with a tool like 2to3 28 | was required. 29 | 30 | Copyright (c) 2012-2013, Geoffrey M. Poore 31 | All rights reserved. 32 | Licensed under the BSD 3-Clause License: 33 | http://www.opensource.org/licenses/BSD-3-Clause 34 | 35 | ''' 36 | 37 | 38 | # Imports 39 | from __future__ import unicode_literals 40 | from io import open 41 | import re 42 | 43 | 44 | files_to_process = ('make_pythontex_gallery_html2.py', ) 45 | encoding = 'utf-8' 46 | 47 | 48 | def from2to3(list_of_code): 49 | fixed = [] 50 | in_2 = False 51 | in_3 = False 52 | indent = '' 53 | 54 | for line in list_of_code: 55 | if r'#// Python 2' in line: 56 | in_2 = True 57 | indent = line.split('#', 1)[0] 58 | elif r'#\\ End Python 2' in line: 59 | in_2 = False 60 | elif r'#// Python 3' in line: 61 | in_3 = True 62 | indent = line.split('#', 1)[0] 63 | elif r'#\\ End Python 3' in line: 64 | in_3 = False 65 | elif in_2: 66 | line = re.sub(indent, indent + '#', line, count=1) 67 | elif in_3: 68 | line = re.sub(indent + '#', indent, line, count=1) 69 | fixed.append(line) 70 | return fixed 71 | 72 | 73 | for file in files_to_process: 74 | f = open(file, 'r', encoding=encoding) 75 | converted_code = from2to3(f.readlines()) 76 | f.close() 77 | f = open(re.sub('2', '3', file), 'w', encoding=encoding) 78 | f.write(''.join(converted_code)) 79 | f.close() 80 | 81 | 82 | -------------------------------------------------------------------------------- /pythontex_quickstart/pythontex_quickstart.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gpoore/pythontex/4ab50a8679f1288935a09d4498de501a387abc00/pythontex_quickstart/pythontex_quickstart.pdf -------------------------------------------------------------------------------- /pythontex_quickstart/pythontex_quickstart.tex: -------------------------------------------------------------------------------- 1 | \documentclass[twocolumn]{article} 2 | 3 | % Engine-specific settings 4 | % Detect pdftex/xetex/luatex, and load appropriate font packages. 5 | % This is inspired by the approach in the iftex package. 6 | % pdftex: 7 | \ifx\pdfmatch\undefined 8 | \else 9 | \usepackage[T1]{fontenc} 10 | \usepackage[utf8]{inputenc} 11 | \fi 12 | % xetex: 13 | \ifx\XeTeXinterchartoks\undefined 14 | \else 15 | \usepackage{fontspec} 16 | \defaultfontfeatures{Ligatures=TeX} 17 | \fi 18 | % luatex: 19 | \ifx\directlua\undefined 20 | \else 21 | \usepackage{fontspec} 22 | \fi 23 | % End engine-specific settings 24 | \usepackage{lmodern} 25 | 26 | \usepackage[margin=1in]{geometry} 27 | \usepackage{microtype} 28 | 29 | \usepackage{pythontex} 30 | 31 | \usepackage[svgnames]{xcolor} 32 | 33 | \usepackage{hyperref} 34 | \hypersetup{colorlinks=true,urlcolor=Green,linkcolor=blue} 35 | 36 | \newcommand{\pytex}{Python\TeX} 37 | \renewcommand*{\thefootnote}{\fnsymbol{footnote}} 38 | 39 | \title{\vspace{-0.6in} \pytex\ Quickstart \\ {\normalsize \href{https://github.com/gpoore/pythontex}{github.com/gpoore/pythontex}}} 40 | \author{} 41 | \date{} 42 | 43 | 44 | \begin{document} 45 | 46 | 47 | \maketitle 48 | 49 | 50 | 51 | 52 | \section*{Installing} 53 | 54 | \pytex\ requires Python 2.7 or 3.2+. When using \pytex\ with LyX, be aware that LyX may try to use its own version of Python; you may need to reconfigure LyX to use other Python installations. 55 | 56 | \pytex\ is included in TeX Live and MiKTeX. It may be installed via the package manager. 57 | 58 | A Python installation script is included with the package. It should be able to install the package in most situations. Depending on the configuration of your system, you may have to run the installation script with administrative priviliges. 59 | 60 | Detailed installation information is available in the main documentation, \texttt{pythontex.pdf}. 61 | 62 | \section*{Compiling} 63 | 64 | Compiling a document that uses \pytex\ involves three steps: run \LaTeX, run \texttt{pythontex.py}, and finally run \LaTeX\ again. You may wish to create a symlink or launching wrapper for \texttt{pythontex.py}, if one was not created during installation. \pytex\ is compatible with the pdfTeX, XeTeX, and LuaTeX engines, so you can use \texttt{latex}, \texttt{pdflatex}, \texttt{xelatex}, or \texttt{lualatex}. 65 | 66 | The last two compile steps are \emph{only} necessary when code needs to be executed or highlighted. Otherwise, the document may be compiled just like a normal \LaTeX\ document; all output is cached. 67 | 68 | \pytex\ is compatible with \texttt{latexmk}. Details for configuring \texttt{latexmk} are provided in the main documentation. 69 | 70 | 71 | 72 | \section*{Basic commands} 73 | 74 | \pygment{latex}{\py} returns a string representation of its argument. For example, \pygment{latex}{\py{2 + 4**2}} produces ``\py{2 + 4**2}'', and \pygment{latex}{\py{'ABC'.lower()}} produces ``\py{'ABC'.lower()}''. \pygment{latex}{\py}'s argument can be delimited by curly braces, or by a matched pair of other characters (just like \pygment{latex}{\verb}). 75 | 76 | \pygment{latex}{\pyc} executes code. By default, anything that is printed is automatically included in the document (see \texttt{autoprint}/\texttt{autostdout} in the main documentation). For example, \pygment{latex}{\pyc{var = 2}} \pyc{var = 2} creates a variable, and then its value may be accessed later via \pygment{latex}{\py{var}}: \py{var}. 77 | 78 | \pygment{latex}{\pyb} executes and typesets code. For example, \pygment{latex}{\pyb{var = 2}} typesets \pyb{var = 2} in addition to creating the variable. If anything is printed, it is not automatically included, but can be accessed via \pygment{latex}{\printpythontex} or \pygment{latex}{\stdoutpythontex}. 79 | 80 | \pygment{latex}{\pyv} only typesets code; nothing is executed. For example, \pygment{latex}{\pyv{var = 2}} produces \pyv{var = 2}. 81 | 82 | \pygment{latex}{\pys} performs variable substitution or string interpolation on code. Substitution fields are denoted by \verb|!{...}|; details about escaping are provided in the main documentation. For example, using the pre-existing variable \pyv{var}, \pygment{latex}{\pys{\verb|var = !{var}|}} yields \pys{\verb|var = !{var}|}. 83 | 84 | 85 | \section*{Basic environments} 86 | 87 | There are \texttt{pycode}, \texttt{pyblock}, \texttt{pyverbatim}, and \texttt{pysub} environments, which are the environment equivalents of \pygment{latex}{\pyc}, \pygment{latex}{\pyb}, \pygment{latex}{\pyv}, and \pygment{latex}{\pys}. For example, 88 | \begin{pygments}{text} 89 | \begin{pycode} 90 | print(r'\begin{center}') 91 | print(r'\textit{A message from Python!}') 92 | print(r'\end{center}') 93 | \end{pycode} 94 | \end{pygments} 95 | produces 96 | \begin{pycode} 97 | print(r'\begin{center}') 98 | print(r'\textit{A message from Python!}') 99 | print(r'\end{center}') 100 | \end{pycode} 101 | 102 | The \pygment{latex}{\begin} and \pygment{latex}{\end} of an environment should be on lines by themselves. Code in environments may be indented; see the \texttt{gobble} option in the main documentation for more details. 103 | 104 | 105 | \section*{More commands/environments} 106 | 107 | All commands and environments described so far have names beginning with \texttt{py}. There are equivalent commands and environments that begin with \texttt{sympy}; these automatically include 108 | \begin{pygments}{python} 109 | from sympy import * 110 | \end{pygments} 111 | There are also equivalent commands and environments that begin with \texttt{pylab}; these automatically use matplotlib's \texttt{pylab} module via 112 | \begin{pygments}{python} 113 | from pylab import * 114 | \end{pygments} 115 | The \texttt{sympy} and \texttt{pylab} commands and environments execute code in separate sessions from the \texttt{py} commands and environments. This can make it easier to avoid namespace conflicts. 116 | 117 | There is also a \texttt{pyconsole} environment that emulates a Python interactive console. For example, 118 | \begin{pygments}{text} 119 | \begin{pyconsole} 120 | var = 1 + 1 121 | var 122 | \end{pyconsole} 123 | \end{pygments} 124 | yields 125 | \begin{pyconsole} 126 | var = 1 + 1 127 | var 128 | \end{pyconsole} 129 | Console variable values may be accessed inline via the \pygment{latex}{\pycon} command. More console information is available in the main documentation. 130 | 131 | \section*{Working with Python 2} 132 | \pytex\ supports both Python 2 and 3. Under Python 2, imports from \pygment{python}{__future__} will work so long as they are the first user-entered code in a given session. \pytex\ imports most things from \pygment{python}{__future__} by default. To control what is automatically imported, see the \texttt{pyfuture} and \texttt{pyconfuture} package options in the main documentation. 133 | 134 | 135 | \section*{Support for additional languages} 136 | 137 | \pytex\ also provides support for additional languages. Currently, Ruby, Julia, Octave, Sage, Bash, and Rust support is included. To enable commands and environments for these language, see the \texttt{usefamily} package option in the main documentation. 138 | 139 | Language support is provided via a template system; in most cases, a new language can be added with about 100 lines of template code---and basic support can require less than 20 lines. If you would like support for a new language, please open an issue at \href{https://github.com/gpoore/pythontex}{GitHub}. The main documentation also contains a summary of the process for adding languages. 140 | 141 | \section*{Macro programming} 142 | 143 | \pytex\ commands can be used inside other commands in macro programming. They will usually work fine, but curly braces should be used as delimiters and special \LaTeX\ characters such as \texttt{\%} and \texttt{\#} should be avoided in the Python code. These limitations can be removed by passing arguments verbatim or through catcode trickery. \pytex\ environments cannot normally be used inside \LaTeX\ commands, due to the way \LaTeX\ deals with verbatim content and catcodes. 144 | 145 | 146 | \section*{Additional features} 147 | 148 | \pytex\ provides many additional features. The working and output directories can be specified via \pygment{latex}{\setpythontexworkingdir} and \pygment{latex}{\setpythontexoutputdir}. The user can determine when code is executed with the package option \texttt{rerun}, selecting factors such as modification and exit status. By default, all commands and environments with the same base name (\texttt{py}, \texttt{sympy}, \texttt{pylab}, etc.) run in a single session, providing continuity. Commands and environments accept an optional argument that specifies the session in which the code is executed; sessions run in parallel. \pytex\ provides a utilities class that is always imported into each session. The utilities class provides methods for tracking dependencies and automatically cleaning up created files. The utilities class also allows information such as page width to be passed from the \TeX\ side to Python/other languages. See the main documentation for additional information. 149 | 150 | \pytex\ also provides the \texttt{depythontex} utility, which creates a copy of a document in which all \pytex\ commands and environments have been replaced by their output. The resulting document is more suitable for journal submission, sharing, and conversion to other document formats. 151 | 152 | Code may be run in interactive mode on the command line via the \verb|--interactive| and \verb|--debug| options. This is primarily useful for working with interactive debuggers. 153 | 154 | 155 | \section*{Customizing typesetting} 156 | 157 | \pytex\ typesets code using the \texttt{fancyvrb} package and the \texttt{fvextra} package that extends \texttt{fancyvrb}. There is a \pygment{latex}{\setpythontexfv} command for setting \pytex-specific \texttt{fancyvrb} and \texttt{fvextra} options. The normal \pygment{latex}{\fvset} works as well for document-wide settings. \pytex\ environments take a second optional argument that consists of \texttt{fancyvrb} and \texttt{fvextra} settings. This can be used to customize automatic line breaking or line highlighting for a single environment. 158 | 159 | 160 | 161 | \section*{Unicode support} 162 | 163 | \pytex\ supports Unicode under all \LaTeX\ engines. For example, consider the following example from Python: 164 | \begin{pygments}{python} 165 | my_string = '¥ § ß Ğ Ð Ñ Ö þ ø' 166 | \end{pygments} 167 | This requires some engine-specific packages. Typical packages are listed below. 168 | 169 | \begin{itemize} 170 | \item pdfLaTeX: 171 | \begin{pygments}{latex} 172 | \usepackage[T1]{fontenc} 173 | \usepackage[utf8]{inputenc} 174 | \end{pygments} 175 | \item LuaLaTeX: 176 | \begin{pygments}{latex} 177 | \usepackage{fontspec} 178 | \end{pygments} 179 | \item XeLaTeX: 180 | \begin{pygments}{latex} 181 | \usepackage{fontspec} 182 | \defaultfontfeatures{Ligatures=TeX} 183 | \end{pygments} 184 | \end{itemize} 185 | 186 | If you are using Python 2, you will also need to specify that you are using Unicode. You may want 187 | \begin{pygments}{python} 188 | from __future__ import unicode_literals 189 | \end{pygments} 190 | at the beginning of your Python code. Or you can just load the \pytex\ package with the option \verb|pyfuture=all|, which will import \verb|unicode_literals| automatically. 191 | 192 | 193 | \end{document} 194 | -------------------------------------------------------------------------------- /test/R/R_test.tex: -------------------------------------------------------------------------------- 1 | \documentclass[11pt]{article} 2 | 3 | % Engine-specific settings 4 | % pdftex: 5 | \ifcsname pdfmatch\endcsname 6 | \usepackage[T1]{fontenc} 7 | \usepackage[utf8]{inputenc} 8 | \fi 9 | % xetex: 10 | \ifcsname XeTeXinterchartoks\endcsname 11 | \usepackage{fontspec} 12 | \defaultfontfeatures{Ligatures=TeX} 13 | \fi 14 | % luatex: 15 | \ifcsname directlua\endcsname 16 | \usepackage{fontspec} 17 | \fi 18 | % End engine-specific settings 19 | 20 | \usepackage{lmodern} 21 | \usepackage{amssymb,amsmath} 22 | \usepackage{graphicx} 23 | \usepackage{fullpage} 24 | \usepackage[keeptemps=all, makestderr, usefamily={R}]{pythontex} 25 | 26 | 27 | \begin{document} 28 | 29 | 30 | 31 | \section*{R} 32 | 33 | \subsection*{Commands} 34 | 35 | \R{2^8} 36 | 37 | \Rc{write(2^16, stdout())} 38 | 39 | \Rb{cat(2^32)} 40 | 41 | \printpythontex 42 | 43 | \Rv{cat(2^32)} 44 | 45 | \Rs{\LaTeX\ and then \textcolor{blue}{!{"R"}} and back to \LaTeX.} 46 | 47 | 48 | \subsection*{Environments} 49 | 50 | Code: 51 | \begin{Rcode} 52 | cat("A string.", " ") 53 | cat(2^8) 54 | \end{Rcode} 55 | 56 | Block: 57 | \begin{Rblock} 58 | cat("A string.", " ") 59 | cat(2^8) 60 | \end{Rblock} 61 | 62 | \printpythontex 63 | 64 | Verbatim: 65 | \begin{Rverbatim} 66 | cat("A string.", " ") 67 | cat(2^8) 68 | \end{Rverbatim} 69 | 70 | Sub: 71 | \begin{Rsub} 72 | \LaTeX\ and then \textcolor{blue}{!{"R"}} and back to \LaTeX. 73 | \end{Rsub} 74 | 75 | 76 | \section*{R stderr} 77 | 78 | 79 | \begin{Rblock}[err1][numbers=left] 80 | # Comment 81 | s <- "R a 82 | \end{Rblock} 83 | 84 | \stderrpythontex[][breaklines, breakafter=\\/] 85 | 86 | \begin{Rblock}[err2][numbers=left] 87 | 1++ 88 | \end{Rblock} 89 | 90 | \stderrpythontex[][breaklines, breakafter=\\/] 91 | 92 | \begin{Rblock}[err3][numbers=left] 93 | # Comment 94 | # Another comment 95 | 1 + "ab" 96 | \end{Rblock} 97 | 98 | \stderrpythontex[][breaklines, breakafter=\\/] 99 | 100 | 101 | 102 | \end{document} 103 | 104 | -------------------------------------------------------------------------------- /test/R/Rcon_test.tex: -------------------------------------------------------------------------------- 1 | \documentclass[11pt]{article} 2 | 3 | % Engine-specific settings 4 | % pdftex: 5 | \ifcsname pdfmatch\endcsname 6 | \usepackage[T1]{fontenc} 7 | \usepackage[utf8]{inputenc} 8 | \fi 9 | % xetex: 10 | \ifcsname XeTeXinterchartoks\endcsname 11 | \usepackage{fontspec} 12 | \defaultfontfeatures{Ligatures=TeX} 13 | \fi 14 | % luatex: 15 | \ifcsname directlua\endcsname 16 | \usepackage{fontspec} 17 | \fi 18 | % End engine-specific settings 19 | 20 | \usepackage{lmodern} 21 | \usepackage{amssymb,amsmath} 22 | \usepackage{graphicx} 23 | \usepackage{fullpage} 24 | \usepackage[keeptemps=all, makestderr, usefamily={Rcon}]{pythontex} 25 | 26 | 27 | \begin{document} 28 | 29 | 30 | \section*{R Console} 31 | 32 | 33 | \subsection*{Basics} 34 | 35 | Console math and printing. 36 | 37 | \begin{Rconsole} 38 | 1+4 39 | print("Some text ...") 40 | \end{Rconsole} 41 | 42 | Test \pygment{r}{cat()} without a trailing newline \verb|\n|. This should produce output followed immediately on the same line by the prompt and the next command. 43 | \begin{Rconsole} 44 | cat("Some", "text", "...") 45 | cat("And", "some", "more", "...") 46 | \end{Rconsole} 47 | 48 | After a final \pygment{r}{cat()} without a trailing newline \verb|\n|, the next environment should start normally, with the prompt at the beginning of the line. 49 | 50 | \begin{Rconsole} 51 | write("stdout", stdout()) 52 | write("stderr", stderr()) 53 | \end{Rconsole} 54 | 55 | 56 | \subsection*{Continuity between environments} 57 | 58 | Set a variable. 59 | \begin{Rconsole} 60 | x <- 2^12 61 | \end{Rconsole} 62 | 63 | Retrieve variable value. 64 | \begin{Rconsole} 65 | x 66 | \end{Rconsole} 67 | 68 | 69 | \subsection*{Continue after errors} 70 | 71 | \begin{Rconsole} 72 | 1+"a" 73 | 3*6 74 | \end{Rconsole} 75 | 76 | 77 | 78 | \end{document} 79 | 80 | -------------------------------------------------------------------------------- /test/bash/bash_test.tex: -------------------------------------------------------------------------------- 1 | \documentclass[11pt]{article} 2 | 3 | % Engine-specific settings 4 | % pdftex: 5 | \ifcsname pdfmatch\endcsname 6 | \usepackage[T1]{fontenc} 7 | \usepackage[utf8]{inputenc} 8 | \fi 9 | % xetex: 10 | \ifcsname XeTeXinterchartoks\endcsname 11 | \usepackage{fontspec} 12 | \defaultfontfeatures{Ligatures=TeX} 13 | \fi 14 | % luatex: 15 | \ifcsname directlua\endcsname 16 | \usepackage{fontspec} 17 | \fi 18 | % End engine-specific settings 19 | 20 | \usepackage{lmodern} 21 | \usepackage{amssymb,amsmath} 22 | \usepackage{graphicx} 23 | \usepackage{fullpage} 24 | \usepackage[keeptemps=all, makestderr, usefamily=bash]{pythontex} 25 | 26 | \begin{document} 27 | 28 | 29 | \section*{Bash} 30 | 31 | Inline: \bash{echo "Hello from bash!"} 32 | 33 | Code environment: 34 | \begin{bashcode} 35 | echo "More from bash." 36 | \end{bashcode} 37 | 38 | Block environment: 39 | \begin{bashblock} 40 | ls -a 41 | \end{bashblock} 42 | Printed output: 43 | \printpythontex[verbatim] 44 | 45 | Verbatim: 46 | \begin{bashverbatim} 47 | echo "More from bash." 48 | \end{bashverbatim} 49 | 50 | 51 | Sub environment: 52 | \begin{bashsub} 53 | Some text \textcolor{blue}{!{"followed by things from bash"}} and then more text. 54 | \end{bashsub} 55 | 56 | Again, with command: \bashs{Some text \textcolor{blue}{!{"followed by more things from bash"}} and then more text.} 57 | 58 | \end{document} 59 | -------------------------------------------------------------------------------- /test/javascript/javascript_test.tex: -------------------------------------------------------------------------------- 1 | \documentclass[11pt]{article} 2 | 3 | % Engine-specific settings 4 | % pdftex: 5 | \ifcsname pdfmatch\endcsname 6 | \usepackage[T1]{fontenc} 7 | \usepackage[utf8]{inputenc} 8 | \fi 9 | % xetex: 10 | \ifcsname XeTeXinterchartoks\endcsname 11 | \usepackage{fontspec} 12 | \defaultfontfeatures{Ligatures=TeX} 13 | \fi 14 | % luatex: 15 | \ifcsname directlua\endcsname 16 | \usepackage{fontspec} 17 | \fi 18 | % End engine-specific settings 19 | 20 | \usepackage{lmodern} 21 | \usepackage{amssymb,amsmath} 22 | \usepackage{graphicx} 23 | \usepackage{fullpage} 24 | \usepackage[keeptemps=all, makestderr, usefamily={javascript}]{pythontex} 25 | 26 | 27 | \begin{document} 28 | 29 | 30 | 31 | \section*{JavaScript} 32 | 33 | \subsection*{Commands} 34 | 35 | \javascript{2**8} 36 | 37 | \javascriptc{console.log(2**16);} 38 | 39 | \javascriptb{console.log(2**32);} 40 | 41 | \printpythontex 42 | 43 | \javascriptv{console.log(2**32);} 44 | 45 | \javascripts{\LaTeX\ and then \textcolor{blue}{!{"JavaScript"}} and back to \LaTeX.} 46 | 47 | 48 | \subsection*{Environments} 49 | 50 | Code: 51 | \begin{javascriptcode} 52 | console.log("A string." + " "); 53 | console.log(2**8); 54 | \end{javascriptcode} 55 | 56 | Block: 57 | \begin{javascriptblock} 58 | console.log("A string." + " "); 59 | console.log(2**8); 60 | \end{javascriptblock} 61 | 62 | \printpythontex 63 | 64 | Verbatim: 65 | \begin{javascriptverbatim} 66 | console.log("A string." + " "); 67 | console.log(2**8); 68 | \end{javascriptverbatim} 69 | 70 | Sub: 71 | \begin{javascriptsub} 72 | \LaTeX\ and then \textcolor{blue}{!{"JavaScript"}} and back to \LaTeX. 73 | \end{javascriptsub} 74 | 75 | 76 | \section*{JavaScript stderr} 77 | 78 | 79 | \begin{javascriptblock}[err1][numbers=left] 80 | // Comment 81 | s = "javascript a 82 | \end{javascriptblock} 83 | 84 | \stderrpythontex[][breaklines, breakafter=\\/] 85 | 86 | \begin{javascriptblock}[err2][numbers=left] 87 | 1+; 88 | \end{javascriptblock} 89 | 90 | \stderrpythontex[][breaklines, breakafter=\\/] 91 | 92 | \begin{javascriptblock}[err3][numbers=left] 93 | // Comment 94 | // Another comment 95 | "a" "b"; 96 | \end{javascriptblock} 97 | 98 | \stderrpythontex[][breaklines, breakafter=\\/] 99 | 100 | 101 | 102 | \end{document} 103 | 104 | -------------------------------------------------------------------------------- /test/julia/julia_test.tex: -------------------------------------------------------------------------------- 1 | \documentclass[11pt]{article} 2 | 3 | % Engine-specific settings 4 | % pdftex: 5 | \ifcsname pdfmatch\endcsname 6 | \usepackage[T1]{fontenc} 7 | \usepackage[utf8]{inputenc} 8 | \fi 9 | % xetex: 10 | \ifcsname XeTeXinterchartoks\endcsname 11 | \usepackage{fontspec} 12 | \defaultfontfeatures{Ligatures=TeX} 13 | \fi 14 | % luatex: 15 | \ifcsname directlua\endcsname 16 | \usepackage{fontspec} 17 | \fi 18 | % End engine-specific settings 19 | 20 | \usepackage{lmodern} 21 | \usepackage{amssymb,amsmath} 22 | \usepackage{graphicx} 23 | \usepackage{fullpage} 24 | \usepackage[keeptemps=all, makestderr, usefamily={julia}]{pythontex} 25 | 26 | 27 | \begin{document} 28 | 29 | 30 | 31 | \section*{Julia} 32 | 33 | \subsection*{Commands} 34 | 35 | \julia{2^8} 36 | 37 | \juliac{println(2^16)} 38 | 39 | \juliab{println(2^32)} 40 | 41 | \printpythontex 42 | 43 | \juliav{println(2^32)} 44 | 45 | \julias{\LaTeX\ and then \textcolor{blue}{!{"Julia"}} and back to \LaTeX.} 46 | 47 | 48 | \subsection*{Environments} 49 | 50 | Code: 51 | \begin{juliacode} 52 | println("A string.") 53 | println(2^8) 54 | \end{juliacode} 55 | 56 | Block: 57 | \begin{juliablock} 58 | println("A string.") 59 | println(2^8) 60 | \end{juliablock} 61 | 62 | \printpythontex 63 | 64 | Verbatim: 65 | \begin{juliaverbatim} 66 | println("A string.") 67 | println(2^8) 68 | \end{juliaverbatim} 69 | 70 | Sub: 71 | \begin{juliasub} 72 | \LaTeX\ and then \textcolor{blue}{!{"Julia"}} and back to \LaTeX. 73 | \end{juliasub} 74 | 75 | 76 | \section*{Julia stderr} 77 | 78 | 79 | \begin{juliablock}[err1][numbers=left] 80 | # Comment 81 | s = """ 82 | Julia a 83 | \end{juliablock} 84 | 85 | \stderrpythontex[][breaklines, breakafter=\\/] 86 | 87 | \begin{juliablock}[err2][numbers=left] 88 | 1+ 89 | \end{juliablock} 90 | 91 | \stderrpythontex[][breaklines, breakafter=\\/] 92 | 93 | \begin{juliablock}[err3][numbers=left] 94 | # Comment 95 | # Another comment 96 | 1 + "ab" 97 | \end{juliablock} 98 | 99 | \stderrpythontex[][breaklines, breakafter=\\/] 100 | 101 | 102 | 103 | \end{document} 104 | 105 | -------------------------------------------------------------------------------- /test/julia/juliacon_test.tex: -------------------------------------------------------------------------------- 1 | \documentclass[11pt]{article} 2 | 3 | % Engine-specific settings 4 | % pdftex: 5 | \ifcsname pdfmatch\endcsname 6 | \usepackage[T1]{fontenc} 7 | \usepackage[utf8]{inputenc} 8 | \fi 9 | % xetex: 10 | \ifcsname XeTeXinterchartoks\endcsname 11 | \usepackage{fontspec} 12 | \defaultfontfeatures{Ligatures=TeX} 13 | \fi 14 | % luatex: 15 | \ifcsname directlua\endcsname 16 | \usepackage{fontspec} 17 | \fi 18 | % End engine-specific settings 19 | 20 | \usepackage{lmodern} 21 | \usepackage{amssymb,amsmath} 22 | \usepackage{graphicx} 23 | \usepackage{fullpage} 24 | \usepackage[keeptemps=all, makestderr, usefamily={juliacon,julia}]{pythontex} 25 | 26 | 27 | \begin{document} 28 | 29 | 30 | \section*{Julia Console} 31 | 32 | 33 | \subsection*{Basics} 34 | 35 | Console math and printing. 36 | 37 | \begin{juliaconsole} 38 | 1+4 39 | println("Some text ...") 40 | \end{juliaconsole} 41 | 42 | Test code that generates output without a trailing newline \verb|\n|. Since there is always a newline before the \verb|julia>| prompt, this should affect vertical layout, but not line breaks. 43 | \begin{juliaconsole} 44 | print("Some text ...") 45 | print("And some more ...") 46 | \end{juliaconsole} 47 | 48 | The next environment should start normally, with the prompt at the beginning of the line. 49 | \begin{juliaconsole} 50 | println("After ...") 51 | \end{juliaconsole} 52 | 53 | 54 | 55 | \subsection*{Continuity between environments} 56 | 57 | Set a variable. 58 | \begin{juliaconsole} 59 | x = 2^12 60 | \end{juliaconsole} 61 | 62 | Retrieve variable value. 63 | \begin{juliaconsole} 64 | x 65 | \end{juliaconsole} 66 | 67 | 68 | \subsection*{Continue after errors} 69 | 70 | \begin{juliaconsole}[][breaklines] 71 | 1+"a" 72 | 3*6 73 | \end{juliaconsole} 74 | 75 | 76 | \end{document} 77 | -------------------------------------------------------------------------------- /test/octave/octave_test.tex: -------------------------------------------------------------------------------- 1 | \documentclass[11pt]{article} 2 | 3 | % Engine-specific settings 4 | % pdftex: 5 | \ifcsname pdfmatch\endcsname 6 | \usepackage[T1]{fontenc} 7 | \usepackage[utf8]{inputenc} 8 | \fi 9 | % xetex: 10 | \ifcsname XeTeXinterchartoks\endcsname 11 | \usepackage{fontspec} 12 | \defaultfontfeatures{Ligatures=TeX} 13 | \fi 14 | % luatex: 15 | \ifcsname directlua\endcsname 16 | \usepackage{fontspec} 17 | \fi 18 | % End engine-specific settings 19 | 20 | \usepackage{lmodern} 21 | \usepackage{amssymb,amsmath} 22 | \usepackage{graphicx} 23 | \usepackage{fullpage} 24 | \usepackage[keeptemps=all, makestderr, usefamily={octave}]{pythontex} 25 | 26 | \begin{document} 27 | 28 | 29 | 30 | \section*{Octave} 31 | 32 | \subsection*{Commands} 33 | 34 | \octave{strrep(strrep(pwd(), '\', '/'), '_', '\_')} 35 | 36 | \octavec{disp(num2str(2^8))} 37 | 38 | \octaveb{disp(num2str(2^16))} 39 | 40 | \printpythontex 41 | 42 | \octavev{disp(num2str(2^32))} 43 | 44 | 45 | 46 | \subsection*{Environments} 47 | 48 | Code: 49 | \begin{octavecode} 50 | disp("Octave!") 51 | disp(2^8) 52 | \end{octavecode} 53 | 54 | Block: 55 | \begin{octaveblock} 56 | disp("Octave!") 57 | disp(2^8) 58 | \end{octaveblock} 59 | 60 | \printpythontex 61 | 62 | Verbatim: 63 | \begin{octaveverbatim} 64 | disp("Octave!") 65 | disp(2^8) 66 | \end{octaveverbatim} 67 | 68 | Sub: 69 | \begin{octavesub} 70 | In \LaTeX\ and then \textcolor{blue}{!{strcat(["Octave calculations $2^8=", num2str(2^8), "$"])}} and then back in \LaTeX. 71 | \end{octavesub} 72 | 73 | 74 | 75 | \section*{Octave stderr} 76 | 77 | 78 | \begin{octaveblock}[err1][numbers=left] 79 | % Comment 80 | s = "Octave a 81 | \end{octaveblock} 82 | 83 | \stderrpythontex 84 | 85 | \begin{octaveblock}[err2][numbers=left] 86 | 1+ 87 | \end{octaveblock} 88 | 89 | \stderrpythontex 90 | 91 | \begin{octaveblock}[err3][numbers=left] 92 | % Comment 93 | % Another comment 94 | 1 + qrst 95 | \end{octaveblock} 96 | 97 | \stderrpythontex 98 | 99 | 100 | 101 | \end{document} 102 | 103 | -------------------------------------------------------------------------------- /test/perl/perl_test.tex: -------------------------------------------------------------------------------- 1 | \documentclass[11pt]{article} 2 | 3 | % Engine-specific settings 4 | % pdftex: 5 | \ifcsname pdfmatch\endcsname 6 | \usepackage[T1]{fontenc} 7 | \usepackage[utf8]{inputenc} 8 | \fi 9 | % xetex: 10 | \ifcsname XeTeXinterchartoks\endcsname 11 | \usepackage{fontspec} 12 | \defaultfontfeatures{Ligatures=TeX} 13 | \fi 14 | % luatex: 15 | \ifcsname directlua\endcsname 16 | \usepackage{fontspec} 17 | \fi 18 | % End engine-specific settings 19 | 20 | \usepackage{lmodern} 21 | \usepackage{amssymb,amsmath} 22 | \usepackage{graphicx} 23 | \usepackage{fullpage} 24 | \usepackage[keeptemps=all, makestderr, usefamily={perl}]{pythontex} 25 | 26 | 27 | \begin{document} 28 | 29 | 30 | 31 | \section*{Perl} 32 | 33 | \subsection*{Commands} 34 | 35 | \perl{2**8} 36 | 37 | \perlc{print 2**16;} 38 | 39 | \perlb{print 2**32;} 40 | 41 | \printpythontex 42 | 43 | \perlv{print 2**32;} 44 | 45 | \perls{\LaTeX\ and then \textcolor{blue}{!{"Perl"}} and back to \LaTeX.} 46 | 47 | 48 | \subsection*{Environments} 49 | 50 | Code: 51 | \begin{perlcode} 52 | print "A string." . " "; 53 | print 2**8; 54 | \end{perlcode} 55 | 56 | Block: 57 | \begin{perlblock} 58 | print "A string." . " "; 59 | print 2**8; 60 | \end{perlblock} 61 | 62 | \printpythontex 63 | 64 | Verbatim: 65 | \begin{perlverbatim} 66 | print "A string." . " "; 67 | print 2**8; 68 | \end{perlverbatim} 69 | 70 | Sub: 71 | \begin{perlsub} 72 | \LaTeX\ and then \textcolor{blue}{!{"Perl"}} and back to \LaTeX. 73 | \end{perlsub} 74 | 75 | 76 | \section*{Perl stderr} 77 | 78 | 79 | \begin{perlblock}[err1][numbers=left] 80 | # Comment 81 | my $s = "Perl a 82 | \end{perlblock} 83 | 84 | \stderrpythontex[][breaklines, breakafter=\\/] 85 | 86 | \begin{perlblock}[err2][numbers=left] 87 | 1+; 88 | \end{perlblock} 89 | 90 | \stderrpythontex[][breaklines, breakafter=\\/] 91 | 92 | \begin{perlblock}[err3][numbers=left] 93 | # Comment 94 | # Another comment 95 | "a" "b"; 96 | \end{perlblock} 97 | 98 | \stderrpythontex[][breaklines, breakafter=\\/] 99 | 100 | 101 | 102 | \end{document} 103 | 104 | -------------------------------------------------------------------------------- /test/perl6/perl6_test.tex: -------------------------------------------------------------------------------- 1 | \documentclass[11pt]{article} 2 | 3 | % Engine-specific settings 4 | % pdftex: 5 | \ifcsname pdfmatch\endcsname 6 | \usepackage[T1]{fontenc} 7 | \usepackage[utf8]{inputenc} 8 | \fi 9 | % xetex: 10 | \ifcsname XeTeXinterchartoks\endcsname 11 | \usepackage{fontspec} 12 | \defaultfontfeatures{Ligatures=TeX} 13 | \fi 14 | % luatex: 15 | \ifcsname directlua\endcsname 16 | \usepackage{fontspec} 17 | \fi 18 | % End engine-specific settings 19 | 20 | \usepackage{lmodern} 21 | \usepackage{amssymb,amsmath} 22 | \usepackage{graphicx} 23 | \usepackage{fullpage} 24 | \usepackage[keeptemps=all, makestderr, usefamily={perlsix}]{pythontex} 25 | 26 | 27 | \begin{document} 28 | 29 | 30 | 31 | \section*{Perl 6} 32 | 33 | \subsection*{Commands} 34 | 35 | \perlsix{2**8} 36 | 37 | \perlsixc{put 2**16;} 38 | 39 | \perlsixb{put 2**32;} 40 | 41 | \printpythontex 42 | 43 | \perlsixv{put 2**32;} 44 | 45 | \perlsixs{\LaTeX\ and then \textcolor{blue}{!{"Perl 6"}} and back to \LaTeX.} 46 | 47 | 48 | \subsection*{Environments} 49 | 50 | Code: 51 | \begin{perlsixcode} 52 | put "A string. " ~ "More."; 53 | put 2**8; 54 | \end{perlsixcode} 55 | 56 | Block: 57 | \begin{perlsixblock} 58 | put "A string. " ~ "More."; 59 | put 2**8; 60 | \end{perlsixblock} 61 | 62 | \printpythontex 63 | 64 | Verbatim: 65 | \begin{perlsixverbatim} 66 | put "A string. " ~ "More."; 67 | put 2**8; 68 | \end{perlsixverbatim} 69 | 70 | Sub: 71 | \begin{perlsixsub} 72 | \LaTeX\ and then \textcolor{blue}{!{"Perl 6"}} and back to \LaTeX. 73 | \end{perlsixsub} 74 | 75 | 76 | \section*{Perl 6 stderr} 77 | 78 | 79 | \begin{perlsixblock}[err1][numbers=left] 80 | # Comment 81 | my $s = "Perl a 82 | \end{perlsixblock} 83 | 84 | \stderrpythontex[][breaklines, breakafter=\\/] 85 | 86 | 87 | \begin{perlsixblock}[err2][numbers=left] 88 | 1+; 89 | \end{perlsixblock} 90 | 91 | \stderrpythontex[][breaklines, breakafter=\\/] 92 | 93 | 94 | \begin{perlsixblock}[err3][numbers=left] 95 | # Comment 96 | # Another comment 97 | "a" "b"; 98 | \end{perlsixblock} 99 | 100 | \stderrpythontex[][breaklines, breakafter=\\/] 101 | 102 | 103 | \begin{perlsixblock}[err4][numbers=left] 104 | # Comment 105 | my $idx = "text"; 106 | my @arr = <1, 2, 3>; 107 | my $var = @arr[$idx]; 108 | \end{perlsixblock} 109 | 110 | \stderrpythontex[][breaklines, breakafter=\\/] 111 | 112 | 113 | \begin{perlsixblock}[err5][numbers=left] 114 | sub nums {1 ... 1000} 115 | 116 | for nums { 117 | say "Current element: $_"; 118 | } 119 | \end{perlsixblock} 120 | 121 | \stderrpythontex[][breaklines, breakafter=\\/] 122 | 123 | 124 | 125 | 126 | \end{document} 127 | 128 | -------------------------------------------------------------------------------- /test/ruby/ruby_test.tex: -------------------------------------------------------------------------------- 1 | \documentclass[11pt]{article} 2 | 3 | % Engine-specific settings 4 | % pdftex: 5 | \ifcsname pdfmatch\endcsname 6 | \usepackage[T1]{fontenc} 7 | \usepackage[utf8]{inputenc} 8 | \fi 9 | % xetex: 10 | \ifcsname XeTeXinterchartoks\endcsname 11 | \usepackage{fontspec} 12 | \defaultfontfeatures{Ligatures=TeX} 13 | \fi 14 | % luatex: 15 | \ifcsname directlua\endcsname 16 | \usepackage{fontspec} 17 | \fi 18 | % End engine-specific settings 19 | 20 | \usepackage{lmodern} 21 | \usepackage{amssymb,amsmath} 22 | \usepackage{graphicx} 23 | \usepackage{fullpage} 24 | \usepackage[keeptemps=all, makestderr, usefamily={ruby, rb}]{pythontex} 25 | 26 | \begin{document} 27 | 28 | 29 | \section*{Ruby (\texttt{ruby})} 30 | 31 | \ruby{33*33} 32 | 33 | Code: 34 | \begin{rubycode} 35 | puts "Hello from Ruby!" 36 | \end{rubycode} 37 | 38 | Block: 39 | \begin{rubyblock} 40 | puts "ABC" 41 | \end{rubyblock} 42 | Printed output: \printpythontex 43 | 44 | Verbatim: 45 | \begin{rubyverbatim} 46 | puts "Hello from Ruby! 47 | \end{rubyverbatim} 48 | 49 | Sub: 50 | \begin{rubysub} 51 | In \LaTeX\textcolor{blue}{!{"...then Ruby..."}}and back in \LaTeX! 52 | \end{rubysub} 53 | 54 | 55 | 56 | \section*{Ruby (\texttt{rb})} 57 | 58 | \rb{33*33} 59 | 60 | Code: 61 | \begin{rbcode} 62 | puts "Hello from Ruby!" 63 | \end{rbcode} 64 | 65 | Block: 66 | \begin{rbblock} 67 | puts "ABC" 68 | \end{rbblock} 69 | Printed output: \printpythontex 70 | 71 | Verbatim: 72 | \begin{rbverbatim} 73 | puts "Hello from Ruby! 74 | \end{rbverbatim} 75 | 76 | Sub: 77 | \begin{rbsub} 78 | In \LaTeX\textcolor{blue}{!{"...then Ruby..."}}and back in \LaTeX! 79 | \end{rbsub} 80 | 81 | 82 | 83 | \subsection*{Errors} 84 | 85 | \setpythontexfv{numbers=left, firstnumber=last} 86 | 87 | \begin{rubyblock}[err1] 88 | # Comment 89 | s = <<-QQ Python a 90 | \end{rubyblock} 91 | 92 | Should get no STDERR following this, because the sync system isn't yet sophisticated enough: \stderrpythontex 93 | 94 | \begin{rubyblock}[err1] 95 | # Comment 96 | #s = 'Python a 97 | \end{rubyblock} 98 | 99 | \stderrpythontex 100 | 101 | 102 | \begin{rubyblock}[err2][numbers=left] 103 | 1+ 104 | \end{rubyblock} 105 | 106 | \stderrpythontex 107 | 108 | 109 | \begin{rubyblock}[err3][numbers=left] 110 | # Hmm 111 | # Ah 112 | 1+'ab' 113 | \end{rubyblock} 114 | 115 | \stderrpythontex 116 | 117 | 118 | \end{document} 119 | 120 | -------------------------------------------------------------------------------- /test/rust/rust_test.tex: -------------------------------------------------------------------------------- 1 | \documentclass[11pt]{article} 2 | 3 | % Engine-specific settings 4 | % pdftex: 5 | \ifcsname pdfmatch\endcsname 6 | \usepackage[T1]{fontenc} 7 | \usepackage[utf8]{inputenc} 8 | \fi 9 | % xetex: 10 | \ifcsname XeTeXinterchartoks\endcsname 11 | \usepackage{fontspec} 12 | \defaultfontfeatures{Ligatures=TeX} 13 | \fi 14 | % luatex: 15 | \ifcsname directlua\endcsname 16 | \usepackage{fontspec} 17 | \fi 18 | % End engine-specific settings 19 | 20 | \usepackage{lmodern} 21 | \usepackage{amssymb,amsmath} 22 | \usepackage{graphicx} 23 | \usepackage{fullpage} 24 | \usepackage[keeptemps=all, makestderr, usefamily={rust, rs}]{pythontex} 25 | \fvset{breaklines} 26 | 27 | \begin{document} 28 | 29 | 30 | \section*{Rust (\texttt{rust})} 31 | 32 | Inline: \rust{format!("$3 + 5 = {}$", 3+5)}. \rusts{$4 + 6 = !{4+6}$}. 33 | 34 | 35 | \begin{rustcode} 36 | println!("Hello from Rust!"); 37 | println!("Running command family ``{}'', session ``{}'', restart ``{}''.", rstex.family, rstex.session, rstex.restart); 38 | \end{rustcode} 39 | 40 | 41 | 42 | \begin{rustblock} 43 | println!("{}\\endinput", 2.0_f64.powf(8.0_f64)); 44 | \end{rustblock} 45 | 46 | Printed output: \printpythontex. 47 | 48 | \begin{rustsub} 49 | \color{blue} 50 | \begin{Verbatim} 51 | 2.0_f64.powf(8.0_f64) = !{2.0_f64.powf(8.0_f64)} 52 | \end{Verbatim} 53 | \end{rustsub} 54 | 55 | 56 | \section*{Rust (\texttt{rs})} 57 | 58 | Inline: \rs{format!("$3 + 5 = {}$", 3+5)}. \rss{$4 + 6 = !{4+6}$}. 59 | 60 | 61 | \begin{rscode} 62 | println!("Hello from Rust!"); 63 | println!("Running command family ``{}'', session ``{}'', restart ``{}''.", rstex.family, rstex.session, rstex.restart); 64 | \end{rscode} 65 | 66 | 67 | 68 | \begin{rsblock} 69 | println!("{}\\endinput", 2.0_f64.powf(8.0_f64)); 70 | \end{rsblock} 71 | 72 | Printed output: \printpythontex. 73 | 74 | \begin{rssub} 75 | \color{blue} 76 | \begin{Verbatim} 77 | 2.0_f64.powf(8.0_f64) = !{2.0_f64.powf(8.0_f64)} 78 | \end{Verbatim} 79 | \end{rssub} 80 | 81 | 82 | 83 | \section*{Errors} 84 | 85 | \begin{rustblock}[error] 86 | println!("{}\\endinput", 2.0_f64.powf(8.0_f64); 87 | \end{rustblock} 88 | 89 | \stderrpythontex 90 | 91 | 92 | 93 | \section*{File tracking} 94 | 95 | \begin{rustblock}[file_io] 96 | // Open and write to two files, to check created file tracking 97 | let mut my_file1 = io::BufWriter::new(rstex.open("my_file1.txt", open_mode::W) 98 | .unwrap()); 99 | writeln!(my_file1, "This is a text file.").unwrap(); 100 | writeln!(my_file1, "Some more text.").unwrap(); 101 | writeln!(my_file1, "3 + 2 = {}", 3 + 2).unwrap(); 102 | drop(my_file1); 103 | 104 | let mut my_file2 = io::BufWriter::new(rstex.open("my_file2.txt", open_mode::W) 105 | .unwrap()); 106 | writeln!(my_file2, "This is another text file.").unwrap(); 107 | writeln!(my_file2, "Some more text for another text file.").unwrap(); 108 | writeln!(my_file2, "5 + 8 = {}", 5 + 8).unwrap(); 109 | drop(my_file2); 110 | 111 | 112 | // Open and read from LaTeX file, to check dependency tracking 113 | let in_file = "rust_test.tex"; 114 | println!("Reading from file \"{}\"...", in_file); 115 | for (n, line) in io::BufReader::new(rstex.open(in_file, open_mode::R) 116 | .unwrap()) 117 | .lines() 118 | .map(Result::unwrap) 119 | .enumerate() 120 | { 121 | if n < 8 { 122 | println!("line {}: {}", n + 1, line); 123 | } 124 | } 125 | \end{rustblock} 126 | 127 | Text written to stdout: 128 | 129 | \printpythontex[verbatim] 130 | 131 | \end{document} 132 | --------------------------------------------------------------------------------