Skip to content

Commit

Permalink
Fixed mypy and set title as regular option for simplification
Browse files Browse the repository at this point in the history
  • Loading branch information
MartenBE committed Feb 28, 2025
1 parent 649407c commit 1859c82
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 60 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ slides:
# `dracula`, ... (see https://revealjs.com/themes/)
theme: example-slides-theme.css

# Title of the slides. If this is set for a slide, it will be used for the
# entry in the generated index HTML: string
title: example-title

# Options to be passed to reveal.js: options in yaml format, they will be
# translated to JSON automatically (see https://revealjs.com/config/)
revealjs:
Expand Down Expand Up @@ -213,6 +217,7 @@ Notes:
## Full help

<!-- output-no-command -->

```text
Usage: mkslides [OPTIONS] COMMAND [ARGS]...
Expand All @@ -228,9 +233,11 @@ Commands:
serve Run the builtin development server.
```

<!-- /output-no-command -->

<!-- output-build -->

```text
Usage: mkslides build [OPTIONS] FILENAME|PATH
Expand All @@ -248,9 +255,11 @@ Options:
-h, --help Show this message and exit.
```

<!-- /output-build -->

<!-- output-serve -->

```text
Usage: mkslides serve [OPTIONS] FILENAME|PATH
Expand All @@ -269,4 +278,5 @@ Options:
-h, --help Show this message and exit.
```

<!-- /output-serve -->
1 change: 1 addition & 0 deletions src/mkslides/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class Slides:
separator: Optional[str] = None
template: Optional[str] = None
theme: str = "black"
title: Optional[str] = None


@dataclass
Expand Down
109 changes: 57 additions & 52 deletions src/mkslides/markupgenerator.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,16 @@
from copy import deepcopy
from dataclasses import dataclass
from importlib import resources
from importlib.resources.abc import Traversable
from pathlib import Path
from typing import Any

import frontmatter # type: ignore[import-untyped]
from jinja2 import Template
from emoji import emojize
from jinja2 import Template
from natsort import natsorted
from omegaconf import DictConfig, OmegaConf

from mkslides.config import Config, FRONTMATTER_ALLOWED_KEYS
from mkslides.config import FRONTMATTER_ALLOWED_KEYS
from mkslides.preprocess import load_preprocessing_function
from mkslides.urltype import URLType
from mkslides.utils import get_url_type
Expand All @@ -37,9 +36,8 @@
class MdFileToProcess:
source_path: Path
destination_path: Path
slide_config: Config
slide_config: DictConfig
markdown_content: str
title: str | None = None


class MarkupGenerator:
Expand Down Expand Up @@ -83,9 +81,7 @@ def process_markdown(self) -> None:
################################################################################

def __create_or_clear_output_directory(self) -> None:
"""
Clears or creates the output directory and copies reveal.js.
"""
"""Clear or create the output directory and copy reveal.js."""
if self.output_directory_path.exists():
shutil.rmtree(self.output_directory_path)
logger.debug("Output directory already exists, deleted")
Expand All @@ -98,20 +94,23 @@ def __create_or_clear_output_directory(self) -> None:

def __process_markdown_directory(self) -> None:
logger.debug(
f"Processing markdown directory at '{self.md_root_path.absolute()}'"
f"Processing markdown directory at '{self.md_root_path.absolute()}'",
)

md_files = []

for file in self.md_root_path.rglob("*"):
if file.is_file():
file = file.resolve(strict=True)
if file.suffix == ".md":
destination_path = self.output_directory_path / file.relative_to(
self.md_root_path
).with_suffix(".html")
resolved_file = file.resolve(strict=True)
if resolved_file.suffix == ".md":
destination_path = (
self.output_directory_path
/ resolved_file.relative_to(
self.md_root_path,
).with_suffix(".html")
)

content = file.read_text(encoding="utf-8-sig")
content = resolved_file.read_text(encoding="utf-8-sig")
metadata, markdown_content = frontmatter.parse(content)
if self.preprocess_script_func:
markdown_content = self.preprocess_script_func(markdown_content)
Expand All @@ -122,23 +121,22 @@ def __process_markdown_directory(self) -> None:
logger.debug(slide_config)

md_file_data = MdFileToProcess(
source_path=file,
source_path=resolved_file,
destination_path=destination_path,
slide_config=slide_config,
markdown_content=markdown_content,
title=metadata.get("title", None),
)

md_files.append(md_file_data)
else:
self.__copy(
file,
resolved_file,
self.output_directory_path
/ file.relative_to(self.md_root_path),
)

templates, revealjs_themes, highlight_themes = self.__preprocess_slide_configs(
md_files
md_files,
)

for md_file_data in md_files:
Expand All @@ -152,22 +150,22 @@ def __process_markdown_directory(self) -> None:

relative_theme_path = None
if slide_config.slides.theme in revealjs_themes:
relative_theme_path = revealjs_themes[
slide_config.slides.theme
].relative_to(
md_file_data.destination_path.parent,
walk_up=True,
relative_theme_path = str(
revealjs_themes[slide_config.slides.theme].relative_to(
md_file_data.destination_path.parent,
walk_up=True,
),
)
else:
relative_theme_path = slide_config.slides.theme

relative_highlight_theme_path = None
if slide_config.slides.highlight_theme in highlight_themes:
relative_highlight_theme_path = highlight_themes[
slide_config.slides.highlight_theme
].relative_to(
md_file_data.destination_path.parent,
walk_up=True,
relative_highlight_theme_path = str(
highlight_themes[slide_config.slides.highlight_theme].relative_to(
md_file_data.destination_path.parent,
walk_up=True,
),
)
else:
relative_highlight_theme_path = slide_config.slides.highlight_theme
Expand Down Expand Up @@ -204,7 +202,10 @@ def __process_markdown_directory(self) -> None:

self.__generate_index(md_files)

def __preprocess_slide_configs(self, md_files: list[MdFileToProcess]) -> tuple[
def __preprocess_slide_configs(
self,
md_files: list[MdFileToProcess],
) -> tuple[
dict[str, Template],
dict[str, Path],
dict[str, Path],
Expand All @@ -221,14 +222,14 @@ def __preprocess_slide_configs(self, md_files: list[MdFileToProcess]) -> tuple[
theme = md_file_data.slide_config.slides.theme
if (
theme not in revealjs_themes
and not get_url_type(theme) == URLType.ABSOLUTE
and get_url_type(theme) != URLType.ABSOLUTE
and not theme.endswith(".css")
):
with resources.as_file(
REVEALJS_THEMES_RESOURCE.joinpath(theme)
REVEALJS_THEMES_RESOURCE.joinpath(theme),
) as builtin_theme_path:
theme_path = builtin_theme_path.with_suffix(".css").resolve(
strict=True
strict=True,
)
theme_output_path = self.output_themes_path / theme_path.name
self.__copy(theme_path, theme_output_path)
Expand All @@ -237,25 +238,23 @@ def __preprocess_slide_configs(self, md_files: list[MdFileToProcess]) -> tuple[
highlight_theme = md_file_data.slide_config.slides.highlight_theme
if (
highlight_theme not in highlight_themes
and not get_url_type(highlight_theme) == URLType.ABSOLUTE
and get_url_type(highlight_theme) != URLType.ABSOLUTE
and not highlight_theme.endswith(".css")
):
with resources.as_file(
HIGHLIGHTJS_THEMES_RESOURCE.joinpath(highlight_theme)
HIGHLIGHTJS_THEMES_RESOURCE.joinpath(highlight_theme),
) as builtin_theme_path:
theme_path = builtin_theme_path.with_suffix(".css").resolve(
strict=True
strict=True,
)
theme_output_path = self.output_themes_path / theme_path.name
self.__copy(theme_path, theme_output_path)
highlight_themes[highlight_theme] = theme_output_path

return templates, revealjs_themes, highlight_themes

def __generate_slide_config(self, metadata) -> DictConfig:
"""
Generate the slide configuration by merging the metadata retrieved from the frontmatter of the markdown and the global configuration.
"""
def __generate_slide_config(self, metadata: dict[str, object]) -> DictConfig:
"""Generate the slide configuration by merging the metadata retrieved from the frontmatter of the markdown and the global configuration."""
slide_config: DictConfig = deepcopy(self.global_config)

if metadata:
Expand All @@ -270,22 +269,32 @@ def __generate_index(self, md_files: list[MdFileToProcess]) -> None:

slideshows = []
for md_file in natsorted(md_files, key=lambda x: str(x.destination_path)):
title = md_file.title or md_file.destination_path.stem
title = md_file.slide_config.slides.title or md_file.destination_path.stem
location = md_file.destination_path.relative_to(self.output_directory_path)
slideshows.append(
{
"title": title,
"location": location,
}
},
)

index_path = self.output_directory_path / "index.html"

# Copy the theme CSS

relative_theme_path = None
if theme := self.global_config.index.theme:
if theme_output_path := self.__copy_theme(theme, REVEALJS_THEMES_RESOURCE):
theme = self.global_config.index.theme
if (
theme
and get_url_type(theme) != URLType.ABSOLUTE
and not theme.endswith(".css")
):
with resources.as_file(
REVEALJS_THEMES_RESOURCE.joinpath(theme),
) as builtin_theme_path:
theme_path = builtin_theme_path.with_suffix(".css").resolve(strict=True)
theme_output_path = self.output_themes_path / theme_path.name
self.__copy(theme_path, theme_output_path)
relative_theme_path = theme_output_path.relative_to(
index_path.parent,
walk_up=True,
Expand All @@ -308,9 +317,7 @@ def __generate_index(self, md_files: list[MdFileToProcess]) -> None:
self.__create_or_overwrite_file(index_path, content)

def __create_or_overwrite_file(self, destination_path: Path, content: Any) -> None:
"""
Create or overwrite a file with the given content.
"""
"""Create or overwrite a file with the given content."""
is_overwrite = destination_path.exists()

destination_path.parent.mkdir(parents=True, exist_ok=True)
Expand All @@ -320,9 +327,7 @@ def __create_or_overwrite_file(self, destination_path: Path, content: Any) -> No
logger.debug(f"{action} file '{destination_path}'")

def __copy(self, source_path: Path, destination_path: Path) -> None:
"""
Copy a file or directory from the source path to the destination path.
"""
"""Copy a file or directory from the source path to the destination path."""
is_overwrite = destination_path.exists()
is_directory = source_path.is_dir()

Expand All @@ -334,7 +339,7 @@ def __copy(self, source_path: Path, destination_path: Path) -> None:
shutil.copy(source_path, destination_path)

action = "Overwritten" if is_overwrite else "Copied"
type = "directory" if is_directory else "file"
file_or_directory = "directory" if is_directory else "file"
logger.debug(
f"{action} {type} '{source_path.absolute()}' to '{destination_path.absolute()}'",
f"{action} {file_or_directory} '{source_path.absolute()}' to '{destination_path.absolute()}'",
)
6 changes: 3 additions & 3 deletions tests/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
assert_files_exist,
assert_html_contains,
run_build,
run_build_with_custom_input,
)

# The output can be seen manually by running the following command:
Expand All @@ -18,10 +17,10 @@ def test_process_directory_without_config(setup_paths: Any) -> None:
assert_files_exist(output_path / "mkslides-assets/reveal-js/dist/reveal.css")
assert_files_exist(output_path / "mkslides-assets/reveal-js/dist/reveal.js")
assert_files_exist(
output_path / "mkslides-assets/reveal-js/plugin/markdown/markdown.js"
output_path / "mkslides-assets/reveal-js/plugin/markdown/markdown.js",
)
assert_files_exist(
output_path / "mkslides-assets/reveal-js/plugin/highlight/highlight.js"
output_path / "mkslides-assets/reveal-js/plugin/highlight/highlight.js",
)
assert_files_exist(output_path / "mkslides-assets/reveal-js/plugin/zoom/zoom.js")
assert_files_exist(output_path / "mkslides-assets/themes/black.css")
Expand Down Expand Up @@ -67,6 +66,7 @@ def test_process_directory_without_config(setup_paths: Any) -> None:
'<link rel="stylesheet" href="../mkslides-assets/themes/monokai.css" />',
)


# def test_process_file_without_config(setup_paths: Any) -> None:
# cwd, output_path = setup_paths
# run_build_with_custom_input(cwd, output_path, "test_files/someslides.md")
Expand Down
5 changes: 0 additions & 5 deletions tests/test_strict.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
import re
import subprocess
from typing import Any


# def test_process_file_without_config(setup_paths: Any) -> None:
# cwd, output_path = setup_paths
# result = subprocess.run(
Expand Down

0 comments on commit 1859c82

Please sign in to comment.