Skip to content

Commit 6714744

Browse files
chore(convert): use Jinja2 for templating (#271)
* chore(convert): use Jinja2 for templating Use Jinja2 templating for more customizable rendering * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fix(deps): jinja2 is no more optional --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 859d48a commit 6714744

File tree

7 files changed

+942
-882
lines changed

7 files changed

+942
-882
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ In an effort to better document changes, this CHANGELOG document is now created.
4949
List of changes: `CONTINUE` to `NEXT`, `BACK` to `PREVIOUS`, and
5050
`REWIND` to `REPLAY`.
5151
[#243](https://github.com/jeertmans/manim-slides/pull/243)
52+
- Conversion to HTML now uses Jinja2 templating. The template file has
53+
been modified accordingly, and old templates will not work anymore.
54+
This is a **breaking change**.
55+
[#271](https://github.com/jeertmans/manim-slides/pull/271)
5256

5357
### Fixed
5458

manim_slides/convert.py

Lines changed: 11 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@
99
from enum import Enum
1010
from importlib import resources
1111
from pathlib import Path
12-
from typing import Any, Callable, Dict, Generator, List, Optional, Type, Union
12+
from typing import Any, Callable, Dict, List, Optional, Type, Union
1313

1414
import click
1515
import cv2
1616
import pptx
1717
from click import Context, Parameter
18+
from jinja2 import Template
1819
from lxml import etree
1920
from PIL import Image
2021
from pydantic import (
@@ -29,35 +30,12 @@
2930
from pydantic_core import CoreSchema, core_schema
3031
from tqdm import tqdm
3132

32-
from . import data
33+
from . import templates
3334
from .commons import folder_path_option, verbosity_option
3435
from .config import PresentationConfig
3536
from .logger import logger
3637
from .present import get_scenes_presentation_config
3738

38-
DATA_URI_FIX = r"""
39-
// Fix found by @t-fritsch on GitHub
40-
// see: https://github.com/hakimel/reveal.js/discussions/3362#discussioncomment-6651475.
41-
function fixBase64VideoBackground(event) {
42-
// event.previousSlide, event.currentSlide, event.indexh, event.indexv
43-
if (event.currentSlide.getAttribute('data-background-video')) {
44-
const background = Reveal.getSlideBackground(event.indexh, event.indexv),
45-
video = background.querySelector('video'),
46-
sources = video.querySelectorAll('source');
47-
48-
sources.forEach((source, i) => {
49-
const src = source.getAttribute('src');
50-
if(src.match(/^data:video.*;base64$/)){
51-
const nextSrc = sources[i+1]?.getAttribute('src');
52-
video.setAttribute('src', `${src},${nextSrc}`);
53-
}
54-
});
55-
}
56-
}
57-
Reveal.on( 'ready', fixBase64VideoBackground );
58-
Reveal.on( 'slidechanged', fixBase64VideoBackground );
59-
"""
60-
6139

6240
def open_with_default(file: Path) -> None:
6341
system = platform.system()
@@ -86,7 +64,7 @@ def validate_config_option(
8664
return config
8765

8866

89-
def data_uri(file: Path) -> str:
67+
def file_to_data_uri(file: Path) -> str:
9068
"""
9169
Reads a video and returns the corresponding data-uri.
9270
"""
@@ -363,39 +341,15 @@ class RevealJS(Converter):
363341
title: str = "Manim Slides"
364342
model_config = ConfigDict(use_enum_values=True, extra="forbid")
365343

366-
def get_sections_iter(self, assets_dir: Path) -> Generator[str, None, None]:
367-
"""Generates a sequence of sections, one per slide, that will be included into the html template."""
368-
for presentation_config in self.presentation_configs:
369-
for slide_config in presentation_config.slides:
370-
file = slide_config.file
371-
372-
logger.debug(f"Writing video section with file {file}")
373-
374-
if self.data_uri:
375-
file = data_uri(file)
376-
else:
377-
file = assets_dir / file.name
378-
379-
# TODO: document this
380-
# Videos are muted because, otherwise, the first slide never plays correctly.
381-
# This is due to a restriction in playing audio without the user doing anything.
382-
# Later, this might be useful to only mute the first video, or to make it optional.
383-
# Read more about this:
384-
# https://developer.mozilla.org/en-US/docs/Web/Media/Autoplay_guide#autoplay_and_autoplay_blocking
385-
if slide_config.loop:
386-
yield f'<section data-background-size={self.background_size.value} data-background-color="{presentation_config.background_color}" data-background-video="{file}" data-background-video-muted data-background-video-loop></section>'
387-
else:
388-
yield f'<section data-background-size={self.background_size.value} data-background-color="{presentation_config.background_color}" data-background-video="{file}" data-background-video-muted></section>'
389-
390344
def load_template(self) -> str:
391345
"""Returns the RevealJS HTML template as a string."""
392346
if isinstance(self.template, Path):
393347
return self.template.read_text()
394348

395349
if sys.version_info < (3, 9):
396-
return resources.read_text(data, "revealjs_template.html")
350+
return resources.read_text(templates, "revealjs.html")
397351

398-
return resources.files(data).joinpath("revealjs_template.html").read_text()
352+
return resources.files(templates).joinpath("revealjs.html").read_text()
399353

400354
def open(self, file: Path) -> bool:
401355
return webbrowser.open(file.absolute().as_uri())
@@ -422,17 +376,13 @@ def convert_to(self, dest: Path) -> None:
422376
presentation_config.copy_to(full_assets_dir)
423377

424378
with open(dest, "w") as f:
425-
sections = "".join(self.get_sections_iter(assets_dir))
379+
revealjs_template = Template(self.load_template())
426380

427-
revealjs_template = self.load_template()
428-
429-
if self.data_uri:
430-
data_uri_fix = DATA_URI_FIX
431-
else:
432-
data_uri_fix = ""
381+
options = self.dict()
382+
options["assets_dir"] = assets_dir
433383

434-
content = revealjs_template.format(
435-
sections=sections, data_uri_fix=data_uri_fix, **self.dict()
384+
content = revealjs_template.render(
385+
file_to_data_uri=file_to_data_uri, **options
436386
)
437387

438388
f.write(content)

0 commit comments

Comments
 (0)