Compare commits

..

28 Commits

Author SHA1 Message Date
e60edcc960 fix(ci): remove duplicate info 2024-01-18 23:34:07 +01:00
c1d2dc26b2 fix(ci): avoid dynamic if does not work 2024-01-18 23:33:00 +01:00
0db4a8c260 fix(ci): update 2024-01-18 23:24:49 +01:00
cb4f6f552c fix(docs): typos 2024-01-18 22:20:55 +01:00
9cd50e73b2 chore(docs): nicer placement 2024-01-18 22:15:04 +01:00
cea3d0b0c3 chore(version): bump 5.1.0-rc2 to 5.1.0-rc3 2024-01-18 22:07:43 +01:00
75126d8bab fix(docs): typo 2024-01-18 22:04:10 +01:00
be227bbdea chore(deps): use PDM instead of Poetry (#354)
* chore(deps): use PDM instead of Poetry

* chore(git): move to top

* chore(lint): fixes

* fix(pdm): dynamic version did not work

* chore(ci): fix syntax for Windows

* fix(ci): typo

* wip(docs): updates

* chore(docs): add changelog entry

* chore(docs): admonitions

* chore(docs): update to use manim-slides render

* chore(docs): make it better
2024-01-18 22:02:53 +01:00
62560ea41f chore(ci): create Docker image (#355)
* chore(ci): create Docker image

* fix(ci): run only if tag is pushed

* chore(docs): add changelog entry
2024-01-18 19:57:35 +01:00
4b8f90c1fa chore(LICENSE): update date 2024-01-18 19:04:45 +01:00
8b1c45b84e [pre-commit.ci] pre-commit autoupdate (#352)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.1.11 → v0.1.13](https://github.com/astral-sh/ruff-pre-commit/compare/v0.1.11...v0.1.13)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-01-18 12:02:58 +01:00
34cc66d8be chore(deps): bump actions/cache from 3 to 4 (#353)
Bumps [actions/cache](https://github.com/actions/cache) from 3 to 4.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-18 11:50:35 +01:00
57e11a0ea7 chore(deps): bump jinja2 from 3.1.2 to 3.1.3 (#349)
Bumps [jinja2](https://github.com/pallets/jinja) from 3.1.2 to 3.1.3.
- [Release notes](https://github.com/pallets/jinja/releases)
- [Changelog](https://github.com/pallets/jinja/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets/jinja/compare/3.1.2...3.1.3)

---
updated-dependencies:
- dependency-name: jinja2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-12 16:32:36 +01:00
de342b32bb [pre-commit.ci] pre-commit autoupdate (#347)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.1.9 → v0.1.11](https://github.com/astral-sh/ruff-pre-commit/compare/v0.1.9...v0.1.11)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-01-08 23:06:49 +01:00
6bd431d748 chore(lib): remove useless var 2024-01-04 13:06:56 +01:00
2e996c03a7 chore(deps): bump actions/deploy-pages from 3 to 4 (#342)
Bumps [actions/deploy-pages](https://github.com/actions/deploy-pages) from 3 to 4.
- [Release notes](https://github.com/actions/deploy-pages/releases)
- [Commits](https://github.com/actions/deploy-pages/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/deploy-pages
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-04 13:06:13 +01:00
d9715ccb96 chore(deps): bump actions/upload-pages-artifact from 2 to 3 (#343)
Bumps [actions/upload-pages-artifact](https://github.com/actions/upload-pages-artifact) from 2 to 3.
- [Release notes](https://github.com/actions/upload-pages-artifact/releases)
- [Commits](https://github.com/actions/upload-pages-artifact/compare/v2...v3)

---
updated-dependencies:
- dependency-name: actions/upload-pages-artifact
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-04 13:06:06 +01:00
e3b3dd677f chore(deps): bump github/codeql-action from 2 to 3 (#338)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2 to 3.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-04 13:05:59 +01:00
db91de1412 [pre-commit.ci] pre-commit autoupdate (#337)
* [pre-commit.ci] pre-commit autoupdate

updates:
- [github.com/macisamuele/language-formatters-pre-commit-hooks: v2.11.0 → v2.12.0](https://github.com/macisamuele/language-formatters-pre-commit-hooks/compare/v2.11.0...v2.12.0)
- [github.com/astral-sh/ruff-pre-commit: v0.1.6 → v0.1.9](https://github.com/astral-sh/ruff-pre-commit/compare/v0.1.6...v0.1.9)
- [github.com/pre-commit/mirrors-mypy: v1.7.1 → v1.8.0](https://github.com/pre-commit/mirrors-mypy/compare/v1.7.1...v1.8.0)

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-01-04 13:05:43 +01:00
bf67a7b695 chore(deps): bump actions/upload-artifact from 3 to 4 (#339)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 3 to 4.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-15 11:48:24 +01:00
ea2d352fc1 chore(lib): do not include reversed files in HTML assets (#336)
* chore(lib): do not include reversed files in HTML assets

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-12-11 13:58:39 +01:00
74ddefe519 chore(deps): remove subprocess calls to FFMPEG with av (#335)
* chore(deps): remove subprocess calls to FFMPEG with `av`

Linked to the progess made in https://github.com/ManimCommunity/manim/pull/3501.

The following PR aims at reducing subprocess calls for security and speed reasons. Also, with https://github.com/ManimCommunity/manim/pull/3501 is merged, FFMPEG should not be needed anymore as it is part of `PyAv`.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* fix(lib): oops forgot to commit those changes

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* chore(lib): clear assets and clean code

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* chore(doc): document changes

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-12-11 13:53:58 +01:00
20b7ef4110 chore(deps): bump actions/deploy-pages from 2 to 3 (#329)
* chore(deps): bump actions/deploy-pages from 2 to 3

Bumps [actions/deploy-pages](https://github.com/actions/deploy-pages) from 2 to 3.
- [Release notes](https://github.com/actions/deploy-pages/releases)
- [Commits](https://github.com/actions/deploy-pages/compare/v2...v3)

---
updated-dependencies:
- dependency-name: actions/deploy-pages
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-12-11 13:37:07 +01:00
19a31a9136 chore(deps): bump actions/configure-pages from 3 to 4 (#330)
* chore(deps): bump actions/configure-pages from 3 to 4

Bumps [actions/configure-pages](https://github.com/actions/configure-pages) from 3 to 4.
- [Release notes](https://github.com/actions/configure-pages/releases)
- [Commits](https://github.com/actions/configure-pages/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/configure-pages
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-12-11 13:36:55 +01:00
d2925340aa chore(deps): bump actions/setup-python from 4 to 5 (#333)
* chore(deps): bump actions/setup-python from 4 to 5

Bumps [actions/setup-python](https://github.com/actions/setup-python) from 4 to 5.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-12-07 08:36:32 +01:00
afeaa0d793 chore(version): bump 5.1.0-rc1 to 5.1.0-rc2 2023-12-05 13:29:43 +01:00
af3c4971ae feat(lib): add return_animation option (#331)
* feat(lib): add `return_animation` option

Allow to return animation instead of playing it.

* fix(lib): docs issue

* fix(ci): build with Python 3.10
2023-12-05 13:29:16 +01:00
b3ed127e31 chore(repo): delete unwanted file 2023-11-28 15:56:52 +01:00
48 changed files with 4151 additions and 4811 deletions

View File

@ -1,7 +1,7 @@
[bumpversion]
current_version = 5.1.0-rc1
current_version = 5.1.0-rc3
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(-rc(?P<release>\d+))?
serialize =
serialize =
{major}.{minor}.{patch}-rc{release}
{major}.{minor}.{patch}
commit = True
@ -11,10 +11,6 @@ message = chore(version): bump {current_version} to {new_version}
search = __version__ = "{current_version}"
replace = __version__ = "{new_version}"
[bumpversion:file:pyproject.toml]
search = version = "{current_version}"
replace = version = "{new_version}"
[bumpversion:file:CITATION.cff]
search = version: v{current_version}
replace = version: v{new_version}

View File

@ -42,7 +42,7 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
@ -56,7 +56,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
uses: github/codeql-action/autobuild@v3
# Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
@ -69,4 +69,4 @@ jobs:
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
uses: github/codeql-action/analyze@v3

View File

@ -24,7 +24,7 @@ jobs:
# This should be the path to the paper within your repo.
paper-path: paper/paper.md
- name: Upload
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: paper
# This is the output path where Pandoc will write the compiled

13
.github/workflows/latest_tag.yml vendored Normal file
View File

@ -0,0 +1,13 @@
name: Keep the versions up-to-date
on:
release:
types: [published, edited]
jobs:
actions-tagger:
runs-on: windows-latest
steps:
- uses: Actions-R-Us/actions-tagger@latest
with:
publish_latest_tag: true

View File

@ -33,54 +33,65 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Poetry
run: pipx install poetry
- name: Install Python
uses: actions/setup-python@v4
- name: Install PDM
uses: pdm-project/setup-pdm@v3
with:
python-version: '3.9'
cache: poetry
python-version: '3.10'
cache: true
- name: Setup Pages
uses: actions/configure-pages@v3
uses: actions/configure-pages@v4
- name: Install Linux Dependencies
run: |
sudo apt-get update
sudo apt-get install libcairo2-dev libpango1.0-dev ffmpeg freeglut3-dev
- name: Setup Pandoc
uses: nikeee/setup-pandoc@v1
- name: Install local Python package
run: poetry install --with docs
run: pdm install -dGdocs -dGgithub-action
- name: Install IPython kernel
run: poetry run ipython kernel install --name "manim-slides" --user
run: pdm run ipython kernel install --name "manim-slides" --user
- name: Restore cached media
id: cache-media-restore
uses: actions/cache/restore@v3
uses: actions/cache/restore@v4
with:
path: docs/media
key: ${{ runner.os }}-docs-media
- name: Clear cache
run: |
gh extension install actions/gh-actions-cache
gh actions-cache delete ${{ steps.cache-media-restore.outputs.cache-primary-key }} --confirm || true
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Save media to cache
id: cache-media-save
uses: actions/cache/save@v3
uses: actions/cache/save@v4
with:
path: docs/media
key: ${{ steps.cache-media-restore.outputs.cache-primary-key }}
- name: Build docs
run: cd docs && poetry run make html
run: cd docs && pdm run make html
- name: Upload artifact
if: github.event_name != 'pull_request'
uses: actions/upload-pages-artifact@v2
uses: actions/upload-pages-artifact@v3
with:
# Upload docs/build/html dir
path: docs/build/html/
- name: Show docs/build/html/_static/ dir content (video only)
run: tree -L 3 docs/build/html/_static/ -P '*.mp4'
- name: Deploy to GitHub Pages
id: deployment
if: github.event_name != 'pull_request'
uses: actions/deploy-pages@v2
uses: actions/deploy-pages@v4

71
.github/workflows/publish.yml vendored Normal file
View File

@ -0,0 +1,71 @@
name: Upload Packages
on:
push:
release:
types: [published]
jobs:
publish-python:
name: Build and release
runs-on: ubuntu-latest
environment: release
permissions:
# IMPORTANT: this permission is mandatory for trusted publishing
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install PDM
uses: pdm-project/setup-pdm@v3
with:
python-version: '3.10'
cache: true
- name: Publish to PyPI
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
run: pdm publish
publish-docker:
name: Publish Docker image
runs-on: ubuntu-latest
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}`
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Get Version
id: create_release
shell: python
env:
tag_act: ${{ github.ref }}
run: |
import os
ref_tag = os.getenv('tag_act').split('/')[-1]
with open(os.getenv('GITHUB_OUTPUT'), 'w') as f:
print(f"tag_name={ref_tag}", file=f)
- name: Build and push
uses: docker/build-push-action@v5
with:
platforms: linux/arm64,linux/amd64
file: docker/Dockerfile
push: true
tags: |
jeertmans/manim-slides:latest
jeertmans/manim-slides:${{ steps.create_release.outputs.tag_name }}

View File

@ -1,34 +0,0 @@
name: Upload Python Package
on:
push:
release:
types: [published]
jobs:
build_and_release:
name: Build and release
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Poetry
run: pipx install poetry
- name: Install Python
uses: actions/setup-python@v4
with:
python-version: '3.10'
cache: poetry
- name: Build wheels
run: poetry build
- name: Publish to PyPI
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
env:
POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_API_TOKEN }}
run: poetry publish

View File

@ -25,14 +25,11 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Poetry
run: pipx install poetry
- name: Install Python
uses: actions/setup-python@v4
- name: Install PDM
uses: pdm-project/setup-pdm@v3
with:
python-version: ${{ matrix.pyversion }}
cache: poetry
cache: true
# Path related stuff
- name: Append to Path on MacOS
@ -72,15 +69,15 @@ jobs:
- name: Install Manim Slides
run: |
poetry install --with test --all-extras
pdm install -dGgithub-action -dGtest
- name: Run pytest
if: matrix.os != 'ubuntu-latest' || matrix.pyversion != '3.11'
run: poetry run pytest
run: pdm run pytest
- name: Run pytest and coverage
if: matrix.os == 'ubuntu-latest' && matrix.pyversion == '3.11'
run: poetry run pytest --cov-report xml --cov=manim_slides tests/
run: pdm run pytest --cov-report xml --cov=manim_slides tests/
- name: Upload to codecov.io
if: matrix.os == 'ubuntu-latest' && matrix.pyversion == '3.11'

1
.gitignore vendored
View File

@ -4,6 +4,7 @@ __pycache__/
/build
/dist
*.egg-info/
.pdm-python
# Manim files
images/

View File

@ -7,26 +7,25 @@ repos:
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks
rev: v2.11.0
rev: v2.12.0
hooks:
- id: pretty-format-yaml
args: [--autofix]
- id: pretty-format-toml
exclude: poetry.lock
args: [--autofix]
args: [--autofix, --trailing-commas]
- repo: https://github.com/keewis/blackdoc
rev: v0.3.9
hooks:
- id: blackdoc
additional_dependencies: [black==23.10.1]
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.1.6
rev: v0.1.13
hooks:
- id: ruff
args: [--fix]
- id: ruff-format
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.7.1
rev: v1.8.0
hooks:
- id: mypy
additional_dependencies: [types-requests, types-setuptools]

View File

@ -27,12 +27,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
This is somewhat a **breaking change**, but changes to the CLI
API are not considered to be very important.
[#325](https://github.com/jeertmans/manim-slides/pull/325)
- Added `return_animation` option to slide animations `self.wipe`
and `self.zoom`.
[#331](https://github.com/jeertmans/manim-slides/pull/331)
- Created a Docker image, published on GitHub.
[#355](https://github.com/jeertmans/manim-slides/pull/355)
(v5.1-modified)=
### Modified
- Modified the internal logic to simplify adding configuration options.
[#321](https://github.com/jeertmans/manim-slides/pull/321)
- Remove `reversed` file assets when exporting to HTML, as it was not used.
[#336](https://github.com/jeertmans/manim-slides/pull/336)
(v5.1-chore)=
### Chore
- Removed subrocess calls to FFMPEG with direct `libav` bindings using
the `av` Python module. This should enhance rendering speed and security.
[#335](https://github.com/jeertmans/manim-slides/pull/335)
- Changed build backend to PDM and reflected on docs.
[#354](https://github.com/jeertmans/manim-slides/pull/354)
## [v5](https://github.com/jeertmans/manim-slides/compare/v4.16.0...v5.0.0)

View File

@ -29,4 +29,4 @@ keywords:
- PowerPoint
- Python
license: MIT
version: v5.1.0-rc1
version: v5.1.0-rc3

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2023 Jérome Eertmans
Copyright (c) 2022-2024 Jérome Eertmans
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

149
README.md
View File

@ -14,19 +14,18 @@
# Manim Slides
Tool for live presentations using either [Manim (community edition)](https://www.manim.community/) or [ManimGL](https://3b1b.github.io/manim/). Manim Slides will *automatically* detect the one you are using!
Tool for live presentations using either
[Manim (community edition)](https://www.manim.community/)
or [ManimGL](https://3b1b.github.io/manim/).
Manim Slides will *automatically* detect the one you are using!
> **NOTE:** this project extends the work of [`manim-presentation`](https://github.com/galatolofederico/manim-presentation), with a lot more features!
> [!NOTE]
> This project extends the work of
> [`manim-presentation`](https://github.com/galatolofederico/manim-presentation),
> with a lot more features!
- [Installation](#installation)
* [Dependencies](#dependencies)
* [Pip install](#pip-install)
* [Install From Repository](#install-from-repository)
- [Usage](#usage)
* [Basic Example](#basic-example)
* [Key Bindings](#key-bindings)
* [Interactive Tutorial](#interactive-tutorial)
* [Other Examples](#other-examples)
- [Comparison with Similar Tools](#comparison-with-similar-tools)
- [F.A.Q](#faq)
* [How to increase quality on Windows](#how-to-increase-quality-on-windows)
@ -37,58 +36,21 @@ Tool for live presentations using either [Manim (community edition)](https://www
## Installation
<!-- start install -->
While installing Manim Slides and its dependencies on your global Python is fine, I recommend using a virtual environment (e.g., [venv](https://docs.python.org/3/tutorial/venv.html)) for a local installation.
### Dependencies
<!-- start deps -->
Manim Slides requires either Manim or ManimGL to be installed. Having both packages installed is fine too.
If none of those packages are installed, please refer to their specific installation guidelines:
- [Manim](https://docs.manim.community/en/stable/installation.html)
- [ManimGL](https://3b1b.github.io/manim/getting_started/installation.html)
> **NOTE**: if you install Manim from its git repository, as suggested by ManimGL,
make sure to first check out a supported version (e.g., `git checkout tags/v1.6.1`
for ManimGL), otherwise it might install an unsupported version of Manim!
See [#314](https://github.com/jeertmans/manim-slides/issues/314) for an example.
<!-- end deps -->
### Pip Install
The recommended way to install the latest release is to use pip:
```bash
pip install manim-slides
```
Optionally, you can also install Manim or ManimGL using extras[^1]:
```bash
pip install manim-slides[manim] # For Manim
# or
pip install manim-slides[manimgl] # For ManimGL
```
[^1]: NOTE: you still need to have Manim or ManimGL platform-specific dependencies installed on your computer.
### Install From Repository
An alternative way to install Manim Slides is to clone the git repository, and install from there: read the [contributing guide](https://eertmans.be/manim-slides/contributing/workflow.html) to know how.
<!-- end install -->
Manim Slides requires either Manim or ManimGL to be installed, along
with their dependencies. Please checkout the
[documentation](https://eertmans.be/manim-slides/installation.html)
for detailed install instructions.
## Usage
<!-- start usage -->
Using Manim Slides is a two-step process:
1. Render animations using `Slide` (resp. `ThreeDSlide`) as a base class instead of `Scene` (resp. `ThreeDScene`), and add calls to `self.next_slide()` everytime you want to create a new slide.
2. Run `manim-slides` on rendered animations and display them like a *Power Point* presentation.
1. Render animations using `Slide` (resp. `ThreeDSlide`) as a base class instead
of `Scene` (resp. `ThreeDScene`), and add calls to `self.next_slide()`
everytime you want to create a new slide.
2. Run `manim-slides` on rendered animations and display them like a
*PowerPoint* presentation.
The documentation is available [online](https://eertmans.be/manim-slides/).
@ -99,8 +61,6 @@ animations, and `self.next_slide(loop=True)` if you want the next slide to loop
over animations until the user presses continue:
```python
# example.py
from manim import * # or: from manimlib import *
from manim_slides import Slide
@ -124,18 +84,23 @@ class BasicExample(Slide):
First, render the animation files:
```bash
manim example.py BasicExample
# or
manimgl example.py BasicExample
manim-slides render example.py BasicExample
# or use ManimGL
manim-slides render --GL example.py BasicExample
```
To start the presentation using `Scene1`, `Scene2` and so on simply run:
> [!NOTE]
> Using `manim-slides render` makes sure the use the `manim`
> (or `manimlib`) library that was installed in the Python same environment.
> Put simply, this is a wrapper of `manim render [ARGS]...` (or `manimgl [ARGS]...`).
To start the presentation using `Scene1`, `Scene2` and so on, run:
```bash
manim-slides [OPTIONS] Scene1 Scene2...
```
Or in this example:
In our example:
```bash
manim-slides BasicExample
@ -143,49 +108,30 @@ manim-slides BasicExample
<!-- end usage -->
## Key Bindings
<p align="center">
<img alt="Example GIF" src="https://raw.githubusercontent.com/jeertmans/manim-slides/main/static/example.gif">
</p>
The default key bindings to control the presentation are:
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/jeertmans/manim-slides/main/static/wizard_dark.png">
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/jeertmans/manim-slides/main/static/wizard_light.png">
<img alt="Manim Slides Wizard" src="https://raw.githubusercontent.com/jeertmans/manim-slides/main/static/wizard_light.png">
</picture>
You can run the **configuration wizard** to change those key bindings:
```bash
manim-slides wizard
```
A default file can be created with:
```bash
manim-slides init
```
> **_NOTE:_** `manim-slides` uses key codes, which are platform dependent. Using the configuration wizard is therefore highly recommended.
For detailed usage documentation, run `manim-slides --help`, or go to the
[documentation](https://eertmans.be/manim-slides/reference/cli.html).
## Interactive Tutorial
Click on the image to watch a slides presentation that explains you how to use Manim Slides.
Click on the image to watch a slides presentation that explains to you how
to use Manim Slides.
[![Manim Slides Docs](https://raw.githubusercontent.com/jeertmans/manim-slides/main/static/docs.png)](https://eertmans.be/manim-slides/)
## Other Examples
Other examples are available in the [`example.py`](https://github.com/jeertmans/manim-slides/blob/main/example.py) file, if you downloaded the git repository.
Below is a small recording of me playing with the slides back and forth.
![](https://raw.githubusercontent.com/jeertmans/manim-slides/main/static/example.gif)
## More Examples
More examples are available in the
[`example.py`](https://github.com/jeertmans/manim-slides/blob/main/example.py)
file, if you downloaded the git repository.
## Comparison with Similar Tools
There exists are variety of tools that allows to create slides presentations containing Manim animations.
There exists a variety of tools that allows to create slides presentations
containing Manim animations.
Below is a comparison of the most used ones with Manim Slides:
@ -203,16 +149,23 @@ Below is a comparison of the most used ones with Manim Slides:
### How to increase quality on Windows
On Windows platform, one may encounter a lower image resolution than expected. Usually, this is observed because Windows rescales every application to fit the screen.
As found by [@arashash](https://github.com/arashash), in [#20](https://github.com/jeertmans/manim-slides/issues/20), the problem can be addressed by changing the scaling factor to 100%:
On Windows platform, one may encounter a lower image resolution than expected.
Usually, this is observed because Windows rescales every application to
fit the screen.
As found by [@arashash](https://github.com/arashash),
in [#20](https://github.com/jeertmans/manim-slides/issues/20),
the problem can be addressed by changing the scaling factor to 100%:
![Windows Fix Scaling](https://raw.githubusercontent.com/jeertmans/manim-slides/main/static/windows_quality_fix.png)
<p align="center">
<img alt="Windows Fix Scaling" src="https://raw.githubusercontent.com/jeertmans/manim-slides/main/static/windows_quality_fix.png">
</p>
in *Settings*->*Display*.
## Contributing
Contributions are more than welcome! Please read through [our contributing section](https://eertmans.be/manim-slides/contributing/index.html).
Contributions are more than welcome! Please read through
[our contributing section](https://eertmans.be/manim-slides/contributing/index.html).
### Reporting an Issue

55
docker/Dockerfile Normal file
View File

@ -0,0 +1,55 @@
# Mostly a copy from https://github.com/ManimCommunity/manim/blob/68bd79093e1ebc1ed9f8051942ffe6e72a9e66a7/docker/Dockerfile
FROM python:3.11-slim
RUN apt-get update -qq \
&& apt-get install --no-install-recommends -y \
ffmpeg \
build-essential \
gcc \
cmake \
libcairo2-dev \
libffi-dev \
libpango1.0-dev \
freeglut3-dev \
pkg-config \
make \
wget \
ghostscript
# setup a minimal texlive installation
COPY docker/texlive-profile.txt /tmp/
ENV PATH=/usr/local/texlive/bin/armhf-linux:/usr/local/texlive/bin/aarch64-linux:/usr/local/texlive/bin/x86_64-linux:$PATH
RUN wget -O /tmp/install-tl-unx.tar.gz http://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz && \
mkdir /tmp/install-tl && \
tar -xzf /tmp/install-tl-unx.tar.gz -C /tmp/install-tl --strip-components=1 && \
/tmp/install-tl/install-tl --profile=/tmp/texlive-profile.txt \
&& tlmgr install \
amsmath babel-english cbfonts-fd cm-super ctex doublestroke dvisvgm everysel \
fontspec frcursive fundus-calligra gnu-freefont jknapltx latex-bin \
mathastext microtype ms physics preview ragged2e relsize rsfs \
setspace standalone tipa wasy wasysym xcolor xetex xkeyval
# clone and build manim-slides
COPY . /opt/manim-slides
WORKDIR /opt/manim-slides
RUN pip install --no-cache manim[jupyterlab] .[sphinx-directive]
ARG NB_USER=manimslidesuser
ARG NB_UID=1000
ENV USER ${NB_USER}
ENV NB_UID ${NB_UID}
ENV HOME /manim-slides
RUN adduser --disabled-password \
--gecos "Default user" \
--uid ${NB_UID} \
${NB_USER}
# create working directory for user to mount local directory into
WORKDIR ${HOME}
USER root
RUN chown -R ${NB_USER}:${NB_USER} ${HOME}
RUN chmod 777 ${HOME}
USER ${NB_USER}
CMD [ "/bin/bash" ]

15
docker/README.md Normal file
View File

@ -0,0 +1,15 @@
# Docker Image
Manim Slides Docker image, highly inspired from the Manim Community Docker image.
Building the image can be done with:
```bash
docker build -t manim-slide/manin-slide:TAG -f docker/Dockerfile .
```
from the root directory of the repository.
> [!WARNING]
> If you run the command above from another place,
> Docker will not be able to find expected files.

View File

@ -0,0 +1,10 @@
selected_scheme scheme-minimal
TEXDIR /usr/local/texlive
TEXMFCONFIG ~/.texlive/texmf-config
TEXMFHOME ~/texmf
TEXMFLOCAL /usr/local/texlive/texmf-local
TEXMFSYSCONFIG /usr/local/texlive/texmf-config
TEXMFSYSVAR /usr/local/texlive/texmf-var
TEXMFVAR ~/.texlive/texmf-var
option_doc 0
option_src 0

View File

@ -4,12 +4,20 @@
# For the full list of built-in configuration values, see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
import sys
from datetime import date
from manim_slides import __version__
assert sys.version_info >= (3, 10), "Building docs requires Python 3.10"
# -- Project information -----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
project = "Manim Slides"
copyright = "2023, Jérome Eertmans"
copyright = f"2024-{date.today().year}, Jérome Eertmans"
author = "Jérome Eertmans"
version = __version__
# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration

View File

@ -4,7 +4,7 @@ This document is there to help you recreate a working environment for Manim Slid
## Dependencies
```{include} ../../../README.md
```{include} ../quickstart.md
:start-after: <!-- start deps -->
:end-before: <!-- end deps -->
```
@ -20,64 +20,110 @@ Useful links:
Once you feel comfortable with git and GitHub, [fork](https://github.com/jeertmans/manim-slides/fork) the repository, and clone it locally.
As for every Python project, using virtual environment is recommended to avoid conflicts between modules. For Manim Slides, we use [Poetry](https://python-poetry.org/docs/#installing-with-the-official-installer). If not already, please install it.
As for every Python project, using virtual environment is recommended to avoid
conflicts between modules.
For this project, we use [PDM](https://pdm-project.org/) to easily manage project
and development dependencies. If not already, please install this tool.
## Installing Python modules
With Poetry, installation becomes straightforward:
With PDM, installation becomes straightforward:
```bash
poetry install
pdm install
```
This, however, only installs the minimal set of dependencies to run the package.
If you would like to install Manim or ManimGL, as documented in the [quickstart](../quickstart),
you can use the `--extras` option:
If you would like to install Manim or ManimGL,
as documented in the [quickstart](../quickstart),
you can use the `-G|--group` option:
```bash
poetry install --extras manim # For Manim
pdm install -Gmanim # For Manim
# or
poetry install --extras manimgl # For ManimGL
pdm install -Gmanimgl # For ManimGL
```
Additionnally, Manim Slides comes with group dependencies for development purposes:
Additionnally, Manim Slides comes with groups of dependencies for development purposes:
```bash
poetry install --with dev # For linters and formatters
pdm install -dGdev # For linters and formatters
# or
poetry install --with docs # To build the documentation locally
pdm install --dGdocs # To build the documentation locally
# or
pdm install --dGtests # To run tests
```
Another group is `test`, but it is only used for
[GitHub actions](https://github.com/jeertmans/manim-slides/blob/main/.github/workflows/test_examples.yml).
:::{note}
You can combine any number of groups or extras when installing the package locally.
You can also install everything with `pdm install -G:all`.
:::
## Running commands
As modules were installed in a new Python environment, you cannot use them directly in the shell.
Instead, you either need to prepend `poetry run` to any command, e.g.:
Because modules are installed in a new Python environment,
you cannot use them directly in the shell.
Instead, you either need to prepend `pdm run` to any command, e.g.:
```bash
poetry run manim-slides wizard
pdm run manim-slides wizard
```
or enter a new shell that uses this new Python environment:
or [enter a new shell](https://pdm-project.org/latest/usage/venv/#activate-a-virtualenv)
that uses this new Python environment:
```
poetry shell
```bash
eval $(pdm venv activate) # Click on the link above to see shell-specific command
manim-slides wizard
```
## Testing your code
Most of the tests are done with GitHub actions, thus not on your computer. The only command you should run locally is `pre-commit run --all-files`: this runs a few linter and formatter to make sure the code quality and style stay constant across time. If a warning or an error is displayed, please fix it before going to next step.
Most of the tests are done with GitHub actions, thus not on your computer.
The only command you should run locally is:
```bash
pdm run pre-commit run --all-files
```
This runs a few linter and formatter to make sure the code quality and style stay
constant across time.
If a warning or an error is displayed, please fix it before going to next step.
For testing your code, simply run:
```bash
pdm run pytest
```
## Building the documentation
The documentation is generated using Sphinx, based on the content
in `docs/source` and in the `manim_slides` Python package.
To generate the documentation, run the following:
```bash
cd docs
pdm run make html
```
Then, the output index file is located at `docs/build/html/index.html` and
can be opened with any modern browser.
:::{warning}
Building the documentation can take quite some time, especially
the first time as it needs to render all the animations.
Further builds should run faster.
:::
## Proposing changes
Once you feel ready and think your contribution is ready to be reviewed, create a [pull request](https://github.com/jeertmans/manim-slides/pulls) and wait for a reviewer to check your work!
Once you feel ready and think your contribution is ready to be reviewed,
create a [pull request](https://github.com/jeertmans/manim-slides/pulls)
and wait for a reviewer to check your work!
Many thanks to you!

View File

@ -26,7 +26,6 @@ Manim Slides makes creating slides with Manim super easy!
In a [very few steps](./quickstart),
you can create slides and present them either using the GUI, or your browser.
Slide through the demo below to get a quick glimpse on what you can do with
Manim Slides.
@ -40,6 +39,7 @@ Manim Slides.
:hidden:
quickstart
installation
reference/index
features_table
manim_or_manimgl

104
docs/source/installation.md Normal file
View File

@ -0,0 +1,104 @@
# Installation
While installing Manim Slides and its dependencies on your global Python is fine,
we recommend using a virtual environment
(e.g., [venv](https://docs.python.org/3/tutorial/venv.html)) for a local installation.
Therefore, the following documentation will install Manim Slides using
[pipx](https://pipx.pypa.io/). This tool is a drop-in replacement
for installing Python packages that ship with one or more executable.
The benefit of using pipx is that it will automatically create a new virtual
environment for every package you install.
:::{note}
Everytime you read `pipx install`, you can use `pip install` instead,
if you are working in a virtual environment or else.
:::
## Dependencies
Manim Slides requires either Manim or ManimGL to be installed, along
with their dependencies.
Having both packages installed is fine too.
If none of those packages are installed,
please refer to their specific installation guidelines:
- [Manim](https://docs.manim.community/en/stable/installation.html)
- [ManimGL](https://3b1b.github.io/manim/getting_started/installation.html)
:::{warning}
If you install Manim from its git repository, as suggested by ManimGL,
make sure to first check out a supported version (e.g., `git checkout tags/v1.6.1`
for ManimGL), otherwise it might install an unsupported version of Manim!
See [#314](https://github.com/jeertmans/manim-slides/issues/314).
:::
## Pip Install
The recommended way to install the latest release is to use pip:
```bash
pipx install -U manim-slides
```
:::{tip}
While not necessary, the `-U` indicates that we would
like to upgrade to the latest version available,
if Manim Slides is already installed.
:::
Optionally, you can also install Manim or ManimGL using extras[^1]:
```bash
pipx install -U "manim-slides[manim]" # For Manim
# or
pipx install -U "manim-slides[manimgl]" # For ManimGL
```
You can check that Manim Slides was correctly installed with:
```bash
manim-slides --version
```
:::{warning}
If you are installing with pipx, this is mandatory to at least include
either `manim` or `manimgl`.
:::
[^1]: You still need to have Manim or ManimGL platform-specific dependencies
installed on your computer.
## Optional Dependencies
Along with the optional dependencies for Manim and ManimGL,
Manim Slides offers additional *extras*, that can be activated
using optional dependencies:
- `magic`, to include a Jupyter magic to render
animations inside notebooks. This automatically installs `manim`,
and does not work with ManimGL;
- `manim` and `manimgl`, for installing the corresponding
dependencies;
- `sphinx-directive`, to generate presentation inside your Sphinx
documentation. This automatically installs `manim`,
and does not work with ManimGL;
Installing those extras can be done with the following syntax:
```bash
pipx install -U "manim-slides[extra1,extra2]"
```
:::{note}
The quotes `"` are added because not all shell support unquoted
brackets (e.g., zsh) or commas (e.g., Windows).
:::
## Install From Repository
An alternative way to install Manim Slides is to clone the git repository,
and install from there: read the
[contributing guide](./contributing/workflow)
to know how to process.

View File

@ -1,11 +1,7 @@
# Quickstart
## Installation
```{include} ../../README.md
:start-after: <!-- start install -->
:end-before: <!-- end install -->
```
If not already, install Manim Slides, along with either Manim or ManimGL,
see [installation](./installation).
## Creating your first slides

View File

@ -9,8 +9,10 @@ We will go from the *most restrictive* method, to the least restrictive one.
If you need to present on a computer without prior knowledge on what will be
installed on it, please directly refer to the last sections.
> **NOTES:** in the next sections, we will assume your animations are described
:::{note}
In the next sections, we will assume your animations are described
in `example.py`, and you have one presentation called `BasicExample`.
:::
## With Manim Slides installed on the target machine
@ -32,8 +34,8 @@ the key bindings might not be the same.
Example:
```bash
# If you use ManimGl, replace `manim` with `manimgl`
manim example.py BasicExample
# If you use ManimGl, add `--GL` after `render`
manim-slides render example.py BasicExample
# This or `manim-slides BasicExample` works since
# `present` is implied by default
@ -128,7 +130,6 @@ The additional code comes from
[this article](https://faq.dailymotion.com/hc/en-us/articles/360022841393-How-to-preserve-the-player-aspect-ratio-on-a-responsive-page)
and it there to preserve the original aspect ratio (16:9).
### Sharing ONE HTML file
If you set the `data_uri` option to `true` (with `-cdata_uri=true`),
@ -144,10 +145,11 @@ This is how your are able to watch all the examples on this website. If you want
to know how to share your slide with GitHub pages, see the
[workflow file](https://github.com/jeertmans/manim-slides/blob/main/.github/workflows/pages.yml).
> **WARNING:** keep in mind that playing large video files over the internet
:::{warning}
Keep in mind that playing large video files over the internet network
can take some time, and *glitches* may occur between slide transitions for this
reason.
:::
### Using the Github starter template

View File

@ -1 +1 @@
__version__ = "5.1.0-rc1"
__version__ = "5.1.0-rc3"

View File

@ -305,7 +305,9 @@ class PresentationConfig(BaseModel): # type: ignore[misc]
with open(path, "w") as f:
f.write(self.model_dump_json(indent=2))
def copy_to(self, folder: Path, use_cached: bool = True) -> "PresentationConfig":
def copy_to(
self, folder: Path, use_cached: bool = True, include_reversed: bool = True
) -> "PresentationConfig":
"""Copy the files to a given directory."""
for slide_config in self.slides:
file = slide_config.file
@ -320,7 +322,7 @@ class PresentationConfig(BaseModel): # type: ignore[misc]
if not use_cached or not dest.exists():
shutil.copy(file, dest)
if not use_cached or not rev_dest.exists():
if include_reversed and (not use_cached or not rev_dest.exists()):
shutil.copy(rev_file, rev_dest)
return self

View File

@ -396,7 +396,7 @@ class RevealJS(Converter):
full_assets_dir.mkdir(parents=True, exist_ok=True)
for presentation_config in self.presentation_configs:
presentation_config.copy_to(full_assets_dir)
presentation_config.copy_to(full_assets_dir, include_reversed=False)
dest.parent.mkdir(parents=True, exist_ok=True)

View File

@ -2,4 +2,3 @@ from pathlib import Path
FOLDER_PATH: Path = Path("./slides")
CONFIG_PATH: Path = Path(".manim-slides.toml")
FFMPEG_BIN: Path = Path("ffmpeg")

View File

@ -21,7 +21,9 @@ This directive requires three additional dependencies:
with Sphinx.
You can install them manually, or with the extra keyword:
pip install manim-slides[sphinx-directive]
.. code-block:: bash
pip install "manim-slides[sphinx-directive]"
Note that you will still need to install Manim's platform-specific dependencies,
see

View File

@ -16,12 +16,14 @@ Utilities for using Manim Slides with IPython (in particular: Jupyter notebooks)
This magic requires two additional dependencies: ``manim`` and ``IPython``.
You can install them manually, or with the extra keyword:
pip install manim-slides[magic]
.. code-block:: bash
pip install "manim-slides[magic]"
Note that you will still need to install Manim's platform-specific dependencies,
see
`their installation page <https://docs.manim.community/en/stable/installation.html>`_.
""" # noqa: D400, D415
"""
from __future__ import annotations

View File

@ -41,6 +41,9 @@ def make_logger() -> logging.Logger:
logger.setLevel(logging.getLogger("manim").level)
logger.addHandler(rich_handler)
if not (libav_logger := logging.getLogger("libav")).hasHandlers():
libav_logger.addHandler(rich_handler)
return logger

View File

@ -154,7 +154,7 @@ def start_at_callback(
"--skip-all",
is_flag=True,
help="Skip all slides, useful the test if slides are working. "
"Automatically sets `--exit-after-last-slide` to True.",
"Automatically sets ``--exit-after-last-slide`` to True.",
)
@click.option(
"--exit-after-last-slide",
@ -182,7 +182,7 @@ def start_at_callback(
type=str,
callback=start_at_callback,
default=(None, None),
help="Start presenting at (x, y), equivalent to --sacn x --sasn y, "
help="Start presenting at (x, y), equivalent to ``--sacn x --sasn y``, "
"and overrides values if not None.",
)
@click.option(

View File

@ -29,7 +29,7 @@ import click
envvar="MANIM_RENDERER",
show_envvar=True,
help="If set, use Manim Community Edition (CE) renderer. "
"If this or --GL is not set, default to CE renderer.",
"If this or ``--GL`` is not set, defaults to CE renderer.",
)
@click.option(
"--GL",
@ -44,7 +44,7 @@ def render(ce: bool, gl: bool, args: Tuple[str, ...]) -> None:
Render SCENE(s) from the input FILE, using the specified renderer.
Use ``manim-slides render --help`` to see help information for
a the specified renderer.
a specific renderer.
"""
if ce and gl:
raise click.UsageError("You cannot specify both --CE and --GL renderers.")

View File

@ -1,19 +1,30 @@
from __future__ import annotations
__all__ = ["BaseSlide"]
import platform
from abc import abstractmethod
from pathlib import Path
from typing import Any, List, MutableMapping, Optional, Sequence, Tuple, ValuesView
from typing import (
TYPE_CHECKING,
Any,
MutableMapping,
Sequence,
ValuesView,
)
import numpy as np
from tqdm import tqdm
from ..config import BaseSlideConfig, PresentationConfig, PreSlideConfig, SlideConfig
from ..defaults import FFMPEG_BIN, FOLDER_PATH
from ..defaults import FOLDER_PATH
from ..logger import logger
from ..utils import concatenate_video_files, merge_basenames, reverse_video_file
from . import MANIM
if TYPE_CHECKING:
from .animation import Wipe, Zoom
if MANIM:
from manim.mobject.mobject import Mobject
else:
@ -28,7 +39,7 @@ class BaseSlide:
) -> None:
super().__init__(*args, **kwargs)
self._output_folder: Path = output_folder
self._slides: List[PreSlideConfig] = []
self._slides: list[PreSlideConfig] = []
self._base_slide_config: BaseSlideConfig = BaseSlideConfig()
self._current_slide = 1
self._current_animation = 0
@ -36,11 +47,6 @@ class BaseSlide:
self._canvas: MutableMapping[str, Mobject] = {}
self._wait_time_between_slides = 0.0
@property
def _ffmpeg_bin(self) -> Path:
"""Return the path to the ffmpeg binaries."""
return FFMPEG_BIN
@property
@abstractmethod
def _frame_height(self) -> float:
@ -61,13 +67,13 @@ class BaseSlide:
@property
@abstractmethod
def _resolution(self) -> Tuple[int, int]:
def _resolution(self) -> tuple[int, int]:
"""Return the scene's resolution used during rendering."""
raise NotImplementedError
@property
@abstractmethod
def _partial_movie_files(self) -> List[Path]:
def _partial_movie_files(self) -> list[Path]:
"""Return a list of partial movie files, a.k.a animations."""
raise NotImplementedError
@ -85,7 +91,7 @@ class BaseSlide:
@property
@abstractmethod
def _start_at_animation_number(self) -> Optional[int]:
def _start_at_animation_number(self) -> int | None:
"""If set, return the animation number at which rendering start."""
raise NotImplementedError
@ -453,7 +459,7 @@ class BaseSlide:
scene_files_folder.mkdir(parents=True, exist_ok=True)
files: List[Path] = self._partial_movie_files
files: list[Path] = self._partial_movie_files
# We must filter slides that end before the animation offset
if offset := self._start_at_animation_number:
@ -464,7 +470,7 @@ class BaseSlide:
slide.start_animation = max(0, slide.start_animation - offset)
slide.end_animation -= offset
slides: List[SlideConfig] = []
slides: list[SlideConfig] = []
for pre_slide_config in tqdm(
self._slides,
@ -481,11 +487,11 @@ class BaseSlide:
# We only concat animations if it was not present
if not use_cache or not dst_file.exists():
concatenate_video_files(self._ffmpeg_bin, slide_files, dst_file)
concatenate_video_files(slide_files, dst_file)
# We only reverse video if it was not present
if not use_cache or not rev_file.exists():
reverse_video_file(self._ffmpeg_bin, dst_file, rev_file)
reverse_video_file(dst_file, rev_file)
slides.append(
SlideConfig.from_pre_slide_config_and_files(
@ -513,8 +519,9 @@ class BaseSlide:
self,
*args: Any,
direction: np.ndarray = LEFT,
return_animation: bool = False,
**kwargs: Any,
) -> None:
) -> Wipe | None:
"""
Play a wipe animation that will shift all the current objects outside of the
current scene's scope, and all the future objects inside.
@ -522,6 +529,8 @@ class BaseSlide:
:param args: Positional arguments passed to
:class:`Wipe<manim_slides.slide.animation.Wipe>`.
:param direction: The wipe direction, that will be scaled by the scene size.
:param return_animation: If set, return the animation instead of
playing it. This is useful to combine multiple animations with this one.
:param kwargs: Keyword arguments passed to
:class:`Wipe<manim_slides.slide.animation.Wipe>`.
@ -548,7 +557,13 @@ class BaseSlide:
self.wipe(Group(square, text), beautiful, direction=UP)
self.next_slide()
self.wipe(beautiful, circle, direction=DOWN + RIGHT)
anim = self.wipe(
beautiful,
circle,
direction=DOWN + RIGHT,
return_animation=True
)
self.play(anim)
"""
from .animation import Wipe
@ -563,13 +578,18 @@ class BaseSlide:
**kwargs,
)
if return_animation:
return animation
self.play(animation)
return None
def zoom(
self,
*args: Any,
return_animation: bool = False,
**kwargs: Any,
) -> None:
) -> Zoom | None:
"""
Play a zoom animation that will fade out all the current objects, and fade in
all the future objects. Objects are faded in a direction that goes towards the
@ -577,6 +597,8 @@ class BaseSlide:
:param args: Positional arguments passed to
:class:`Zoom<manim_slides.slide.animation.Zoom>`.
:param return_animation: If set, return the animation instead of
playing it. This is useful to combine multiple animations with this one.
:param kwargs: Keyword arguments passed to
:class:`Zoom<manim_slides.slide.animation.Zoom>`.
@ -598,10 +620,21 @@ class BaseSlide:
self.zoom(circle, square)
self.next_slide()
self.zoom(square, circle, out=True, scale=10.0)
anim = self.zoom(
square,
circle,
out=True,
scale=10.0,
return_animation=True
)
self.play(anim)
"""
from .animation import Zoom
animation = Zoom(*args, **kwargs)
if return_animation:
return animation
self.play(animation)
return None

View File

@ -13,15 +13,6 @@ class Slide(BaseSlide, Scene): # type: ignore[misc]
for slides rendering.
"""
@property
def _ffmpeg_bin(self) -> Path:
# Prior to v0.16.0.post0,
# ffmpeg was stored as a constant in manim.constants
try:
return Path(config.ffmpeg_executable)
except AttributeError:
return super()._ffmpeg_bin
@property
def _frame_height(self) -> float:
return config["frame_height"] # type: ignore

View File

@ -1,45 +1,37 @@
import hashlib
import subprocess
import tempfile
from pathlib import Path
from typing import List
import av
from .logger import logger
def concatenate_video_files(ffmpeg_bin: Path, files: List[Path], dest: Path) -> None:
def concatenate_video_files(files: List[Path], dest: Path) -> None:
"""Concatenate multiple video files into one."""
f = tempfile.NamedTemporaryFile(mode="w", delete=False)
f.writelines(f"file '{path.absolute()}'\n" for path in files)
f.close()
command: List[str] = [
str(ffmpeg_bin),
"-f",
"concat",
"-safe",
"0",
"-i",
f.name,
"-c",
"copy",
str(dest),
"-y",
]
logger.debug(" ".join(command))
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output, error = process.communicate()
input_ = av.open(f.name, options={"safe": "0"}, format="concat")
input_stream = input_.streams.video[0]
output = av.open(str(dest), mode="w")
output_stream = output.add_stream(
template=input_stream,
)
if output:
logger.debug(output.decode())
for packet in input_.demux(input_stream):
# We need to skip the "flushing" packets that `demux` generates.
if packet.dts is None:
continue
if error:
logger.debug(error.decode())
# We need to assign the packet to the new stream.
packet.stream = output_stream
output.mux(packet)
if not dest.exists():
raise ValueError(
"could not properly concatenate files, use `-v DEBUG` for more details"
)
input_.close()
output.close()
def merge_basenames(files: List[Path]) -> Path:
@ -63,15 +55,44 @@ def merge_basenames(files: List[Path]) -> Path:
return dirname.joinpath(basename + ext)
def reverse_video_file(ffmpeg_bin: Path, src: Path, dst: Path) -> None:
"""Reverses a video file, writting the result to `dst`."""
command = [str(ffmpeg_bin), "-y", "-i", str(src), "-vf", "reverse", str(dst)]
logger.debug(" ".join(command))
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output, error = process.communicate()
def link_nodes(*nodes: av.filter.context.FilterContext) -> None:
"""Code from https://github.com/PyAV-Org/PyAV/issues/239."""
for c, n in zip(nodes, nodes[1:]):
c.link_to(n)
if output:
logger.debug(output.decode())
if error:
logger.debug(error.decode())
def reverse_video_file(src: Path, dest: Path) -> None:
"""Reverses a video file, writting the result to `dest`."""
input_ = av.open(str(src))
input_stream = input_.streams.video[0]
output = av.open(str(dest), mode="w")
output_stream = output.add_stream(codec_name="libx264", rate=input_stream.base_rate)
output_stream.width = input_stream.width
output_stream.height = input_stream.height
output_stream.pix_fmt = input_stream.pix_fmt
graph = av.filter.Graph()
link_nodes(
graph.add_buffer(template=input_stream),
graph.add("reverse"),
graph.add("buffersink"),
)
graph.configure()
frames_count = 0
for frame in input_.decode(video=0):
graph.push(frame)
frames_count += 1
graph.push(None) # EOF: https://github.com/PyAV-Org/PyAV/issues/886.
for _ in range(frames_count):
frame = graph.pull()
frame.pict_type = 1 # Otherwise we get a warning saying it is changed
output.mux(output_stream.encode(frame))
for packet in output_stream.encode():
output.mux(packet)
input_.close()
output.close()

3458
pdm.lock generated Normal file

File diff suppressed because it is too large Load Diff

4109
poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,20 +1,9 @@
[build-system]
build-backend = "poetry.core.masonry.api"
requires = ["setuptools", "poetry-core>=1.0.0"]
build-backend = "pdm.backend"
requires = ["pdm-backend", "setuptools"]
[tool.black]
target-version = ["py38"]
[tool.mypy]
disallow_untyped_decorators = false
install_types = true
python_version = "3.8"
strict = true
[tool.poetry]
authors = [
"Jérome Eertmans <jeertmans@icloud.com>"
]
[project]
authors = [{name = "Jérome Eertmans", email = "jeertmans@icloud.com"}]
classifiers = [
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
@ -25,96 +14,106 @@ classifiers = [
"Operating System :: OS Independent",
"Topic :: Multimedia :: Video",
"Topic :: Multimedia :: Graphics",
"Topic :: Scientific/Engineering"
"Topic :: Scientific/Engineering",
]
dependencies = [
"av>=9.0.0",
"click>=8.1.3",
"click-default-group>=1.2.2",
"jinja2>=3.1.2",
"lxml>=4.9.2",
"numpy>=1.19",
"opencv-python>=4.6.0.66",
"pillow>=9.5.0",
"pydantic>=2.0.1",
"pydantic-extra-types>=2.0.0",
"pyside6==6.5.2",
"python-pptx>=0.6.21",
"requests>=2.28.1",
"rich>=13.3.2",
"rtoml>=0.9.0",
"tqdm>=4.64.1",
]
description = "Tool for live presentations using manim"
documentation = "https://eertmans.be/manim-slides"
exclude = ["docs/", "static/"]
homepage = "https://github.com/jeertmans/manim-slides"
dynamic = ["version"]
keywords = ["manim", "slides", "plugin", "manimgl"]
license = "MIT"
license = {text = "MIT"}
name = "manim-slides"
packages = [
{include = "manim_slides"}
]
readme = "README.md"
repository = "https://github.com/jeertmans/manim-slides"
version = "5.1.0-rc1"
requires-python = ">=3.8,<3.12"
[tool.poetry.dependencies]
click = "^8.1.3"
click-default-group = "^1.2.2"
docutils = {version = "^0.20.1", optional = true}
ipython = {version = ">=8.12.2", optional = true}
jinja2 = "^3.1.2"
lxml = "^4.9.2"
manim = {version = "^0.17.3", optional = true}
manimgl = {version = "^1.6.1", optional = true}
numpy = "^1.19"
opencv-python = "^4.6.0.66"
pillow = "^9.5.0"
pydantic = "^2.0.1"
pydantic-extra-types = "^2.0.0"
pyside6 = "6.5.2"
python = ">=3.8.1,<3.12"
python-pptx = "^0.6.21"
requests = "^2.28.1"
rich = "^13.3.2"
rtoml = "^0.9.0"
tqdm = "^4.64.1"
[project.optional-dependencies]
all = [
"manim-slides[magic,manim,manimgl,sphinx-directive]",
]
magic = ["manim-slides[manim]", "ipython>=8.12.2"]
manim = ["manim>=0.17.3"]
manimgl = ["manimgl>=1.6.1"]
sphinx-directive = ["docutils>=0.20.1", "manim-slides[manim]"]
[tool.poetry.extras]
magic = ["manim", "ipython"]
manim = ["manim"]
manimgl = ["manimgl"]
sphinx-directive = ["docutils", "manim"]
[tool.poetry.group.dev]
optional = true
[tool.poetry.group.dev.dependencies]
bump2version = "^1.0.1"
pre-commit = "^3.0.2"
[tool.poetry.group.docs]
optional = true
[tool.poetry.group.docs.dependencies]
furo = "^2023.5.20"
ipykernel = "^6.25.1"
manim = "^0.17.3"
myst-parser = "^2.0.0"
nbsphinx = "^0.9.2"
pandoc = "^2.3"
sphinx = "^7.0.1"
sphinx-click = "^4.4.0"
sphinx-copybutton = "^0.5.1"
sphinxext-opengraph = "^0.7.5"
[tool.poetry.group.test]
optional = true
[tool.poetry.group.test.dependencies]
manim = "^0.17.3"
manimgl = "^1.6.1"
pytest = "^7.4.0"
pytest-cov = "^4.1.0"
pytest-env = "^0.8.2"
pytest-qt = "^4.2.0"
pytest-xdist = "^3.3.1"
[tool.poetry.plugins]
[tool.poetry.plugins."console_scripts"]
[project.scripts]
manim-slides = "manim_slides.__main__:cli"
[project.urls]
Changelog = "https://github.com/jeertmans/manim-slides/releases"
Documentation = "https://eertmans.be/manim-slides"
Founding = "https://github.com/sponsors/jeertmans"
Homepage = "https://github.com/jeertmans/manim-slides"
Repository = "https://github.com/jeertmans/manim-slides"
[tool.coverage.report]
exclude_lines = [
'pragma: no cover',
'raise NotImplementedError',
'if TYPE_CHECKING:',
'if typing.TYPE_CHECKING:',
]
precision = 2
[tool.mypy]
disallow_untyped_decorators = false
install_types = true
python_version = "3.8"
strict = true
[tool.pdm.dev-dependencies]
dev = [
"bump2version>=1.0.1",
"pre-commit>=3.5.0",
]
docs = [
"manim-slides[magic,sphinx-directive]",
"furo>=2023.5.20",
"ipykernel>=6.25.1",
"myst-parser>=2.0.0",
"nbsphinx>=0.9.2",
"pandoc>=2.3",
"sphinx>=7.0.1",
"sphinx-click>=4.4.0",
"sphinx-copybutton>=0.5.1",
"sphinxext-opengraph>=0.7.5",
]
github-action = ["setuptools"]
test = [
"manim-slides[manim,manimgl]",
"pytest>=7.4.0",
"pytest-cov>=4.1.0",
"pytest-env>=0.8.2",
"pytest-qt>=4.2.0",
"pytest-xdist>=3.3.1",
]
[tool.pdm.version]
path = "manim_slides/__version__.py"
source = "file"
[tool.pytest.ini_options]
env = [
"QT_QPA_PLATFORM=offscreen"
"QT_QPA_PLATFORM=offscreen",
]
filterwarnings = [
"error",
"ignore::DeprecationWarning"
"ignore::DeprecationWarning",
]
[tool.ruff]
@ -131,7 +130,7 @@ extend-ignore = [
"D203",
"D205",
"D212",
"E501"
"E501",
]
extend-include = ["*.ipynb"]
extend-select = ["B", "C90", "D", "I", "N", "RUF", "UP", "T"]

View File

@ -1,21 +1,21 @@
#! /bin/bash
MANIM_SLIDES_THEME=light poetry run manim render -qk -s --format png --resolution 2560,1280 static/logo.py && mv media/images/logo/*.png static/logo.png
MANIM_SLIDES_THEME=light pdm run manim-slides render -qk -s --format png --resolution 2560,1280 static/logo.py && mv media/images/logo/*.png static/logo.png
ln -f -r -s static/logo.png docs/source/_static/logo.png
MANIM_SLIDES_THEME=dark_docs poetry run manim render -qk -s --format png --resolution 2560,1280 static/logo.py && mv media/images/logo/*.png static/logo_dark_docs.png
MANIM_SLIDES_THEME=dark_docs pdm run manim-slides render -qk -s --format png --resolution 2560,1280 static/logo.py && mv media/images/logo/*.png static/logo_dark_docs.png
ln -f -r -s static/logo_dark_docs.png docs/source/_static/logo_dark_docs.png
MANIM_SLIDES_THEME=dark_github poetry run manim render -qk -s --format png --resolution 2560,1280 static/logo.py && mv media/images/logo/*.png static/logo_dark_github.png
MANIM_SLIDES_THEME=dark_github pdm run manim-slides render -qk -s --format png --resolution 2560,1280 static/logo.py && mv media/images/logo/*.png static/logo_dark_github.png
ln -f -r -s static/logo_dark_github.png docs/source/_static/logo_dark_github.png
MANIM_SLIDES_THEME=light poetry run manim render -t -qk -s --format png --resolution 2560,1280 static/logo.py && mv media/images/logo/*.png static/logo_light_transparent.png
MANIM_SLIDES_THEME=light pdm run manim-slides render -t -qk -s --format png --resolution 2560,1280 static/logo.py && mv media/images/logo/*.png static/logo_light_transparent.png
ln -f -r -s static/logo_light_transparent.png docs/source/_static/logo_light_transparent.png
MANIM_SLIDES_THEME=dark_docs poetry run manim render -t -qk -s --format png --resolution 2560,1280 static/logo.py && mv media/images/logo/*.png static/logo_dark_transparent.png
MANIM_SLIDES_THEME=dark_docs pdm run manim-slides render -t -qk -s --format png --resolution 2560,1280 static/logo.py && mv media/images/logo/*.png static/logo_dark_transparent.png
ln -f -r -s static/logo_dark_transparent.png docs/source/_static/logo_dark_transparent.png

305
test.html
View File

@ -1,305 +0,0 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>Manim Slides</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/reveal.js/4.6.1/reveal.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/reveal.js/4.6.1/theme/black.min.css">
<!-- Theme used for syntax highlighting of code -->
<!-- <link rel="stylesheet" href="lib/css/zenburn.css"> -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.13.1/styles/zenburn.min.css">
<!-- <link rel="stylesheet" href="index.css"> -->
</head>
<body>
<div class="reveal">
<div class="slides"><section
data-background-size='contain'
data-background-color="black"
data-background-video="test_assets/666c4d3666df4cdb49aaba030b166948270194eee96f1a10eedf33ef7d3c9a7b.mp4"
data-background-video-muted>
</section><section
data-background-size='contain'
data-background-color="black"
data-background-video="test_assets/49d7b9453bdd459c0f7582859468b845a0abd7fd15637246ec1914c5c21ee33a.mp4"
data-background-video-loop>
</section><section
data-background-size='contain'
data-background-color="black"
data-background-video="test_assets/72568c120827bbf8c69201ee416c5bab6f875f1600889d2ee765346bb576887d.mp4"
>
</section></div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/reveal.js/4.6.1/reveal.min.js"></script>
<!-- To include plugins, see: https://revealjs.com/plugins/ -->
<!-- <script src="index.js"></script> -->
<script>
Reveal.initialize({
// The "normal" size of the presentation, aspect ratio will
// be preserved when the presentation is scaled to fit different
// resolutions. Can be specified using percentage units.
width: '100%',
height: '100%',
// Factor of the display size that should remain empty around
// the content
margin: 0.04,
// Bounds for smallest/largest possible scale to apply to content
minScale: 0.2,
maxScale: 2.0,
// Display presentation control arrows
controls: false,
// Help the user learn the controls by providing hints, for example by
// bouncing the down arrow when they first encounter a vertical slide
controlsTutorial: true,
// Determines where controls appear, "edges" or "bottom-right"
controlsLayout: 'bottom-right',
// Visibility rule for backwards navigation arrows; "faded", "hidden"
// or "visible"
controlsBackArrows: 'faded',
// Display a presentation progress bar
progress: false,
// Display the page number of the current slide
// - true: Show slide number
// - false: Hide slide number
//
// Can optionally be set as a string that specifies the number formatting:
// - "h.v": Horizontal . vertical slide number (default)
// - "h/v": Horizontal / vertical slide number
// - "c": Flattened slide number
// - "c/t": Flattened slide number / total slides
//
// Alternatively, you can provide a function that returns the slide
// number for the current slide. The function should take in a slide
// object and return an array with one string [slideNumber] or
// three strings [n1,delimiter,n2]. See #formatSlideNumber().
slideNumber: false,
// Can be used to limit the contexts in which the slide number appears
// - "all": Always show the slide number
// - "print": Only when printing to PDF
// - "speaker": Only in the speaker view
showSlideNumber: 'all',
// Use 1 based indexing for # links to match slide number (default is zero
// based)
hashOneBasedIndex: false,
// Add the current slide number to the URL hash so that reloading the
// page/copying the URL will return you to the same slide
hash: false,
// Flags if we should monitor the hash and change slides accordingly
respondToHashChanges: false,
// Push each slide change to the browser history. Implies `hash: true`
history: false,
// Enable keyboard shortcuts for navigation
keyboard: true,
// Optional function that blocks keyboard events when retuning false
//
// If you set this to 'focused', we will only capture keyboard events
// for embedded decks when they are in focus
keyboardCondition: null,
// Disables the default reveal.js slide layout (scaling and centering)
// so that you can use custom CSS layout
disableLayout: false,
// Enable the slide overview mode
overview: true,
// Vertical centering of slides
center: true,
// Enables touch navigation on devices with touch input
touch: true,
// Loop the presentation
loop: false,
// Change the presentation direction to be RTL
rtl: false,
// Changes the behavior of our navigation directions.
//
// "default"
// Left/right arrow keys step between horizontal slides, up/down
// arrow keys step between vertical slides. Space key steps through
// all slides (both horizontal and vertical).
//
// "linear"
// Removes the up/down arrows. Left/right arrows step through all
// slides (both horizontal and vertical).
//
// "grid"
// When this is enabled, stepping left/right from a vertical stack
// to an adjacent vertical stack will land you at the same vertical
// index.
//
// Consider a deck with six slides ordered in two vertical stacks:
// 1.1 2.1
// 1.2 2.2
// 1.3 2.3
//
// If you're on slide 1.3 and navigate right, you will normally move
// from 1.3 -> 2.1. If "grid" is used, the same navigation takes you
// from 1.3 -> 2.3.
navigationMode: 'default',
// Randomizes the order of slides each time the presentation loads
shuffle: false,
// Turns fragments on and off globally
fragments: true,
// Flags whether to include the current fragment in the URL,
// so that reloading brings you to the same fragment position
fragmentInURL: true,
// Flags if the presentation is running in an embedded mode,
// i.e. contained within a limited portion of the screen
embedded: false,
// Flags if we should show a help overlay when the question-mark
// key is pressed
help: true,
// Flags if it should be possible to pause the presentation (blackout)
pause: true,
// Flags if speaker notes should be visible to all viewers
showNotes: false,
// Global override for autolaying embedded media (video/audio/iframe)
// - null: Media will only autoplay if data-autoplay is present
// - true: All media will autoplay, regardless of individual setting
// - false: No media will autoplay, regardless of individual setting
autoPlayMedia: null,
// Global override for preloading lazy-loaded iframes
// - null: Iframes with data-src AND data-preload will be loaded when within
// the viewDistance, iframes with only data-src will be loaded when visible
// - true: All iframes with data-src will be loaded when within the viewDistance
// - false: All iframes with data-src will be loaded only when visible
preloadIframes: null,
// Can be used to globally disable auto-animation
autoAnimate: true,
// Optionally provide a custom element matcher that will be
// used to dictate which elements we can animate between.
autoAnimateMatcher: null,
// Default settings for our auto-animate transitions, can be
// overridden per-slide or per-element via data arguments
autoAnimateEasing: 'ease',
autoAnimateDuration: 1.0,
autoAnimateUnmatched: true,
// CSS properties that can be auto-animated. Position & scale
// is matched separately so there's no need to include styles
// like top/right/bottom/left, width/height or margin.
autoAnimateStyles: ['opacity', 'color', 'background-color', 'padding', 'font-size', 'line-height', 'letter-spacing', 'border-width', 'border-color', 'border-radius', 'outline', 'outline-offset'],
// Controls automatic progression to the next slide
// - 0: Auto-sliding only happens if the data-autoslide HTML attribute
// is present on the current slide or fragment
// - 1+: All slides will progress automatically at the given interval
// - false: No auto-sliding, even if data-autoslide is present
autoSlide: 0,
// Stop auto-sliding after user input
autoSlideStoppable: true,
// Use this method for navigation when auto-sliding (defaults to navigateNext)
autoSlideMethod: null,
// Specify the average time in seconds that you think you will spend
// presenting each slide. This is used to show a pacing timer in the
// speaker view
defaultTiming: null,
// Enable slide navigation via mouse wheel
mouseWheel: false,
// Opens links in an iframe preview overlay
// Add `data-preview-link` and `data-preview-link="false"` to customise each link
// individually
previewLinks: false,
// Exposes the reveal.js API through window.postMessage
postMessage: true,
// Dispatches all reveal.js events to the parent window through postMessage
postMessageEvents: false,
// Focuses body when page changes visibility to ensure keyboard shortcuts work
focusBodyOnPageVisibilityChange: true,
// Transition style
transition: 'none', // none/fade/slide/convex/concave/zoom
// Transition speed
transitionSpeed: 'default', // default/fast/slow
// Transition style for full page slide backgrounds
backgroundTransition: 'none', // none/fade/slide/convex/concave/zoom
// The maximum number of pages a single slide can expand onto when printing
// to PDF, unlimited by default
pdfMaxPagesPerSlide: Number.POSITIVE_INFINITY,
// Prints each fragment on a separate slide
pdfSeparateFragments: true,
// Offset used to reduce the height of content within exported PDF pages.
// This exists to account for environment differences based on how you
// print to PDF. CLI printing options, like phantomjs and wkpdf, can end
// on precisely the total height of the document whereas in-browser
// printing has to end one pixel before.
pdfPageHeightOffset: -1,
// Number of slides away from the current that are visible
viewDistance: 3,
// Number of slides away from the current that are visible on mobile
// devices. It is advisable to set this to a lower number than
// viewDistance in order to save resources.
mobileViewDistance: 2,
// The display mode that will be used to show slides
display: 'block',
// Hide cursor if inactive
hideInactiveCursor: true,
// Time before the cursor is hidden (in ms)
hideCursorTime: 5000
});
</script>
</body>
</html>

View File

@ -2,7 +2,6 @@ from typing import MutableMapping
import pytest
from manim_slides.defaults import FFMPEG_BIN
from manim_slides.slide.base import BaseSlide
@ -12,9 +11,6 @@ def base_slide() -> BaseSlide:
class TestBaseSlide:
def test_ffmpeg_bin(self, base_slide: BaseSlide) -> None:
assert base_slide._ffmpeg_bin == FFMPEG_BIN
def test_frame_height(self, base_slide: BaseSlide) -> None:
with pytest.raises(NotImplementedError):
_ = base_slide._frame_height

View File

@ -1,7 +1,6 @@
import shutil
from pathlib import Path
from manim_slides.defaults import CONFIG_PATH, FFMPEG_BIN, FOLDER_PATH
from manim_slides.defaults import CONFIG_PATH, FOLDER_PATH
def test_folder_path() -> None:
@ -10,13 +9,3 @@ def test_folder_path() -> None:
def test_config_path() -> None:
assert CONFIG_PATH == Path(".manim-slides.toml")
def test_ffmpeg_bin() -> None:
assert FFMPEG_BIN == Path("ffmpeg")
def test_ffmpeg_bin_exists() -> None:
assert (
shutil.which(str(FFMPEG_BIN)) is not None
), "If this fails, many other tests will fail"