# pyjupyter

**pyjupyter** is a lightweight LaTeX package that provides a clean and structured way to typeset Python code with a visual style inspired by Jupyter notebooks.

The package combines the syntax highlighting capabilities of the `listings` package with the flexible layout and framing features of `tcolorbox`. The result is a simple and elegant environment for presenting Python code in scientific reports, programming assignments, lecture notes, and reproducible research documents.

A key motivation behind **pyjupyter** is to offer a minimal and native alternative to traditional Jupyter-to-LaTeX export tools. Many existing solutions rely on external tools such as **Pygments**, produce extremely verbose LaTeX code, and introduce numerous formatting macros that make the document difficult to read and maintain.
The goal of this package is to provide a clean solution that integrates naturally into standard LaTeX workflows.

---

# Installation

If you are using a modern LaTeX distribution such as **TeX Live** or **MiKTeX**, the package can be installed automatically through the package manager.

Alternatively, you can install the package manually:

1. Download the package from the CTAN repository
   https://mirrors.ctan.org/macros/latex/contrib/pyjupyter
2. Place `pyjupyter.sty` in your project directory or in your local `texmf` tree.
3. Run `texhash` if required to refresh the file database.

---

# Loading the package

Load the package in the preamble of your document:

```
\usepackage{pyjupyter}
```

The package automatically loads all required dependencies.

---

# The `jupyter` environment

The package defines a single environment called `jupyter` for displaying Python code.

```
\begin{jupyter}[]
# Python code
print("Hello world")
\end{jupyter}
```

This environment produces a framed code block with Python syntax highlighting.

Example:

```
\begin{jupyter}[]
def square(x):
    return x ** 2

print(square(4))
\end{jupyter}
```

---

# Important notes

## About the brackets

The `jupyter` environment must always be called with brackets immediately after `\begin{jupyter}`:

```
\begin{jupyter}[]
...
\end{jupyter}
```

This applies even when no options are specified.

Python comments begin with the character `#`, which is also used internally by TeX to denote macro parameters.
If the environment is started without the optional argument brackets and the first line of code begins with a comment, TeX may misinterpret the character during argument parsing.

Providing the brackets ensures that the environment is fully initialized before the code content is processed by the `listings` engine.

---

## About operator highlighting

The `listings` engine highlights operators only when they are surrounded by spaces.

Example:

Correct highlighting:

```
a = 10
b = 5
result = a + b
```

Without spaces the operators remain in the default color:

```
result=a+b
```

Although this is a limitation of the underlying engine, it is consistent with the **PEP 8** Python style guidelines which recommend surrounding operators with spaces.

---

# Line numbering

Line numbering can be activated using the `numbered` option.

```
\begin{jupyter}[numbered]
for i in range(5):
    print(i)
\end{jupyter}
```

---

# Font and size configuration

By default the package uses the **Source Code Pro** font family at `small` size.

Both the font family and code size can be configured globally when loading the package.

Example:

```
\usepackage[font=inconsolata, codesize=footnotesize]{pyjupyter}
```

Supported fonts:

* sourcecodepro (default)
* inconsolata
* beramono
* lmtt
* courier
* txtt

Supported sizes:

* tiny
* scriptsize
* footnotesize
* small (default)
* normalsize
* large

Large sizes are technically supported but generally not recommended for code listings.

---

# Customization

Additional options can be passed directly to the underlying `tcolorbox`.

Example:

```
\begin{jupyter}[colback=blue!3, colframe=Navy, title=Example]
print("Custom box")
\end{jupyter}
```

Advanced users may also pass options directly to the `listings` engine using:

```
\begin{jupyter}[listing options={basicstyle=\ttfamily\small}]
print("Custom listings configuration")
\end{jupyter}
```

---

# Embedding LaTeX code

LaTeX code can be inserted inside a Python block using escape delimiters.

The escape characters are `@ ... @`.

Example:

```
\begin{jupyter}[]
x = 10
y = 20
print(x+y) @\hspace*{3cm}\color{orange}$\alpha$ Result@
\end{jupyter}
```

Everything between `@` delimiters is processed as normal LaTeX code.

---

# Including Python files

The package provides a command for including external Python files directly in the document.

```
\inputpythonfile{example.py}
```

This command wraps the file inside a Jupyter-style box with syntax highlighting.

---

## Line numbering

```
\inputpythonfile[numbered]{example.py}
```

---

## Selecting specific lines

It is possible to display only a portion of the file.

```
\inputpythonfile[numbered, startline=5, endline=10]{example.py}
```

This is useful when showing only the relevant part of a larger script.

---

## Custom box options

Box styling can also be customized.

```
\inputpythonfile[title=Included Python code, colframe=Navy, colback=blue!2]{example.py}
```

---

# Syntax highlighting

Syntax highlighting is provided by the `listings` engine using a custom style named `pyjupyter-syntax`.

The style includes:

* Python keyword highlighting
* operator highlighting
* colored comments
* colored strings
* support for triple-quoted strings
* automatic line breaking

---

# UTF-8 characters

The package supports common UTF-8 accented characters inside code listings.

Example:

```
\begin{jupyter}[]
print("L'étudiant Ouyèté se débrouille en LaTeX !")
\end{jupyter}
```

---

# Version history

**v1.2.1 (2026/04/07)**
Minor update about numbering. It consists in a redesigning of the \texttt{numbered} style.

**v1.2.0 (2026/03/15)**
Added support for including external Python files.

* New command `\inputpythonfile`
* Ability to display only selected lines using `startline` and `endline`
* Full support for syntax highlighting, numbering, and custom box options for included files

**v1.1.0 (2026/03/10)**
Major update with enhanced flexibility.

* Global font selection
* Improved numbering compatibility
* New `codesize` option for global code size configuration

**v1.0.0 (2026/03/06)**
Initial release.

* Jupyter-style code blocks using `tcolorbox`
* Python syntax highlighting via `listings`
* Default integration of Source Code Pro font

---

# Author

Ouyèté Bright BARA
[barabright62@gmail.com](mailto:barabright62@gmail.com)
