Improve hatch scripts and create executables
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 75 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
@@ -56,6 +56,10 @@ This is done with [Development containers](https://containers.dev/), and the env
|
||||
|
||||
These commands are defined in the [`pyproject.toml`](https://github.com/rendercv/rendercv/blob/main/pyproject.toml) file.
|
||||
|
||||
- Build the package
|
||||
```bash
|
||||
hatch run build
|
||||
```
|
||||
- Format the code with [Black](https://github.com/psf/black) and [Ruff](https://github.com/astral-sh/ruff)
|
||||
```bash
|
||||
hatch run format
|
||||
@@ -80,6 +84,18 @@ These commands are defined in the [`pyproject.toml`](https://github.com/rendercv
|
||||
```bash
|
||||
hatch run test-and-report
|
||||
```
|
||||
- Update [schema.json](https://github.com/rendercv/rendercv/blob/main/schema.json)
|
||||
```bash
|
||||
hatch run update-schema
|
||||
```
|
||||
- Update [`examples`](https://github.com/rendercv/rendercv/tree/main/examples) folder
|
||||
```bash
|
||||
hatch run update-examples
|
||||
```
|
||||
- Create an executable version of RenderCV with [PyInstaller](https://www.pyinstaller.org/)
|
||||
```bash
|
||||
hatch run create-executables
|
||||
```
|
||||
- Preview the documentation as you write it
|
||||
```bash
|
||||
hatch run docs:serve
|
||||
@@ -88,14 +104,6 @@ These commands are defined in the [`pyproject.toml`](https://github.com/rendercv
|
||||
```bash
|
||||
hatch run docs:build
|
||||
```
|
||||
- Update [schema.json](https://github.com/rendercv/rendercv/blob/main/schema.json)
|
||||
```bash
|
||||
hatch run docs:update-schema
|
||||
```
|
||||
- Update [`examples`](https://github.com/rendercv/rendercv/tree/main/examples) folder
|
||||
```bash
|
||||
hatch run docs:update-examples
|
||||
```
|
||||
- Update figures of the entry types in the "[Structure of the YAML Input File](../user_guide/structure_of_the_yaml_input_file.md)"
|
||||
```bash
|
||||
hatch run docs:update-entry-figures
|
||||
|
||||
@@ -13,12 +13,12 @@ Once the changes are pushed to the `main` branch, the [`deploy-docs.yaml`](https
|
||||
|
||||
The `examples` folder includes example YAML files for all the built-in themes, along with their corresponding PDF outputs. Also, there are PNG files of the first pages of each theme in [`docs/assets/images`](https://github.com/rendercv/rendercv/tree/main/docs/assets/images). These examples are shown in [`README.md`](https://github.com/rendercv/rendercv/blob/main/README.md).
|
||||
|
||||
These files are generated using [`docs/update_examples.py`](https://github.com/rendercv/rendercv/blob/main/docs/update_examples.py). The contents of the examples are taken from the [`create_a_sample_data_model`](https://docs.rendercv.com/reference/data/#rendercv.data.create_a_sample_data_model) function from [`rendercv.data`](https://docs.rendercv.com/reference/data/).
|
||||
These files are generated using [`scripts/update_examples.py`](https://github.com/rendercv/rendercv/blob/main/scripts/update_examples.py). The contents of the examples are taken from the [`create_a_sample_data_model`](https://docs.rendercv.com/reference/data/#rendercv.data.create_a_sample_data_model) function from [`rendercv.data`](https://docs.rendercv.com/reference/data/).
|
||||
|
||||
Run the following command to update the `examples` folder.
|
||||
|
||||
```bash
|
||||
hatch run docs:update-examples
|
||||
hatch run update-examples
|
||||
```
|
||||
|
||||
Once a new release is created on GitHub, the [`publish-to-pypi.yaml`](https://github.com/rendercv/rendercv/blob/main/.github/workflows/publish-to-pypi.yaml) workflow will be automatically triggered, and the `examples` folder will be updated to the most recent version.
|
||||
@@ -27,7 +27,7 @@ Once a new release is created on GitHub, the [`publish-to-pypi.yaml`](https://gi
|
||||
|
||||
There are example figures for each entry type for each theme in the "[Structure of the YAML Input File](../user_guide/structure_of_the_yaml_input_file.md)" page.
|
||||
|
||||
The figures are generated using [`docs/update_entry_figures.py`](https://github.com/rendercv/rendercv/blob/main/docs/update_entry_figures.py).
|
||||
The figures are generated using [`scripts/update_entry_figures.py`](https://github.com/rendercv/rendercv/blob/main/scripts/update_entry_figures.py).
|
||||
|
||||
Run the following command to update the figures.
|
||||
|
||||
@@ -41,12 +41,12 @@ Once a new release is created on GitHub, the [`publish-to-pypi.yaml`](https://gi
|
||||
|
||||
The schema of RenderCV's input file is defined using [Pydantic](https://docs.pydantic.dev/latest/). Pydantic allows automatic creation and customization of JSON schemas from Pydantic models.
|
||||
|
||||
The JSON Schema is also generated using [`docs/update_schema.py`](https://github.com/rendercv/rendercv/blob/main/docs/update_schema.py). It uses [`generate_json_schema`](https://docs.rendercv.com/reference/data/#rendercv.data.generate_json_schema) function from [`rendercv.data`](https://docs.rendercv.com/reference/data/).
|
||||
The JSON Schema is also generated using [`scripts/update_schema.py`](https://github.com/rendercv/rendercv/blob/main/scripts/update_schema.py). It uses [`generate_json_schema`](https://docs.rendercv.com/reference/data/#rendercv.data.generate_json_schema) function from [`rendercv.data`](https://docs.rendercv.com/reference/data/).
|
||||
|
||||
Run the following command to update the JSON Schema.
|
||||
|
||||
```bash
|
||||
hatch run docs:update-schema
|
||||
hatch run update-schema
|
||||
```
|
||||
|
||||
Once a new release is created on GitHub, the [`publish-to-pypi.yaml`](https://github.com/rendercv/rendercv/blob/main/.github/workflows/publish-to-pypi.yaml) workflow will be automatically triggered, and `schema.json` will be updated to the most recent version.
|
||||
|
||||
@@ -7,17 +7,12 @@ are coming from this script.
|
||||
|
||||
import io
|
||||
import pathlib
|
||||
import shutil
|
||||
import tempfile
|
||||
from typing import get_args
|
||||
|
||||
import fitz
|
||||
import pdfCropMargins
|
||||
import pydantic
|
||||
import ruamel.yaml
|
||||
|
||||
import rendercv.data as data
|
||||
import rendercv.renderer as renderer
|
||||
import rendercv.themes.options as theme_options
|
||||
|
||||
repository_root = pathlib.Path(__file__).parent.parent
|
||||
@@ -153,123 +148,3 @@ def define_env(env):
|
||||
env.variables["available_bullets"] = ", ".join(
|
||||
[f"`{bullet}`" for bullet in get_args(theme_options.BulletPoint)]
|
||||
)
|
||||
|
||||
|
||||
def render_pngs_from_pdf(pdf_file_path: pathlib.Path) -> list[pathlib.Path]:
|
||||
"""Render a PNG file for each page of the given PDF file.
|
||||
|
||||
Args:
|
||||
pdf_file_path: The path to the PDF file.
|
||||
|
||||
Returns:
|
||||
The paths to the rendered PNG files.
|
||||
"""
|
||||
# check if the file exists:
|
||||
if not pdf_file_path.is_file():
|
||||
message = f"The file {pdf_file_path} doesn't exist!"
|
||||
raise FileNotFoundError(message)
|
||||
|
||||
# convert the PDF to PNG:
|
||||
png_directory = pdf_file_path.parent
|
||||
png_file_name = pdf_file_path.stem
|
||||
png_files = []
|
||||
pdf = fitz.open(pdf_file_path) # open the PDF file
|
||||
for page in pdf: # iterate the pages
|
||||
image = page.get_pixmap(dpi=300) # type: ignore
|
||||
png_file_path = png_directory / f"{png_file_name}_{page.number + 1}.png" # type: ignore
|
||||
image.save(png_file_path)
|
||||
png_files.append(png_file_path)
|
||||
|
||||
return png_files
|
||||
|
||||
|
||||
def generate_entry_figures():
|
||||
"""Generate an image for each entry type and theme."""
|
||||
# Generate PDF figures for each entry type and theme
|
||||
entries = data.read_a_yaml_file(
|
||||
repository_root / "docs" / "user_guide" / "sample_entries.yaml"
|
||||
)
|
||||
entry_types = entries.keys()
|
||||
entries = SampleEntries(**entries)
|
||||
themes = data.available_themes
|
||||
|
||||
with tempfile.TemporaryDirectory() as temporary_directory:
|
||||
# Create temporary directory
|
||||
temporary_directory_path = pathlib.Path(temporary_directory)
|
||||
for theme in themes:
|
||||
design_dictionary = {
|
||||
"theme": theme,
|
||||
"page": {
|
||||
"show_page_numbering": False,
|
||||
"show_last_updated_date": False,
|
||||
},
|
||||
}
|
||||
|
||||
for entry_type in entry_types:
|
||||
# Create data model with only one section and one entry
|
||||
data_model = data.RenderCVDataModel(
|
||||
cv=data.CurriculumVitae(
|
||||
sections={entry_type: [getattr(entries, entry_type)]}
|
||||
),
|
||||
design=design_dictionary,
|
||||
)
|
||||
|
||||
# Render
|
||||
typst_file_path = renderer.create_a_typst_file_and_copy_theme_files(
|
||||
data_model, temporary_directory_path
|
||||
)
|
||||
pdf_file_path = renderer.render_a_pdf_from_typst(typst_file_path)
|
||||
|
||||
# Prepare output directory and file path
|
||||
output_directory = image_assets_directory / theme
|
||||
output_directory.mkdir(parents=True, exist_ok=True)
|
||||
output_pdf_file_path = output_directory / f"{entry_type}.pdf"
|
||||
|
||||
# Remove file if it exists
|
||||
if output_pdf_file_path.exists():
|
||||
output_pdf_file_path.unlink()
|
||||
|
||||
# Crop margins
|
||||
pdfCropMargins.crop(
|
||||
argv_list=[
|
||||
"-p4",
|
||||
"100",
|
||||
"0",
|
||||
"100",
|
||||
"0",
|
||||
"-a4",
|
||||
"0",
|
||||
"-30",
|
||||
"0",
|
||||
"-30",
|
||||
"-o",
|
||||
str(output_pdf_file_path.absolute()),
|
||||
str(pdf_file_path.absolute()),
|
||||
]
|
||||
)
|
||||
|
||||
# Convert PDF to image
|
||||
png_file_path = render_pngs_from_pdf(output_pdf_file_path)[0]
|
||||
desired_png_file_path = output_pdf_file_path.with_suffix(".png")
|
||||
|
||||
# If image exists, remove it
|
||||
if desired_png_file_path.exists():
|
||||
desired_png_file_path.unlink()
|
||||
|
||||
# Move image to desired location
|
||||
png_file_path.rename(desired_png_file_path)
|
||||
|
||||
# Remove PDF file
|
||||
output_pdf_file_path.unlink()
|
||||
|
||||
|
||||
def update_index():
|
||||
"""Update index.md file by copying README.md file."""
|
||||
index_file_path = repository_root / "docs" / "index.md"
|
||||
readme_file_path = repository_root / "README.md"
|
||||
shutil.copy(readme_file_path, index_file_path)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
generate_entry_figures()
|
||||
print("Entry figures generated successfully.") # NOQA: T201
|
||||
@@ -1,86 +0,0 @@
|
||||
"""This script generates the `examples` folder in the repository root."""
|
||||
|
||||
import os
|
||||
import pathlib
|
||||
import shutil
|
||||
|
||||
import rendercv.cli as cli
|
||||
import rendercv.data as data
|
||||
import rendercv.renderer as renderer
|
||||
|
||||
repository_root = pathlib.Path(__file__).parent.parent
|
||||
rendercv_path = repository_root / "rendercv"
|
||||
image_assets_directory = pathlib.Path(__file__).parent / "assets" / "images"
|
||||
|
||||
|
||||
def generate_examples():
|
||||
"""Generate example YAML and PDF files."""
|
||||
examples_directory_path = pathlib.Path(__file__).parent.parent / "examples"
|
||||
|
||||
# Check if examples directory exists. If not, create it
|
||||
if not examples_directory_path.exists():
|
||||
examples_directory_path.mkdir()
|
||||
|
||||
os.chdir(examples_directory_path)
|
||||
themes = data.available_themes
|
||||
for theme in themes:
|
||||
cli.cli_command_new(
|
||||
"John Doe",
|
||||
theme,
|
||||
dont_create_theme_source_files=True,
|
||||
dont_create_markdown_source_files=True,
|
||||
)
|
||||
yaml_file_path = examples_directory_path / "John_Doe_CV.yaml"
|
||||
|
||||
# Rename John_Doe_CV.yaml
|
||||
proper_theme_name = theme.capitalize() + "Theme"
|
||||
new_yaml_file_path = (
|
||||
examples_directory_path / f"John_Doe_{proper_theme_name}_CV.yaml"
|
||||
)
|
||||
if new_yaml_file_path.exists():
|
||||
new_yaml_file_path.unlink()
|
||||
yaml_file_path.rename(new_yaml_file_path)
|
||||
yaml_file_path = new_yaml_file_path
|
||||
|
||||
# Generate PDF file
|
||||
cli.cli_command_render(yaml_file_path)
|
||||
|
||||
output_pdf_file = (
|
||||
examples_directory_path / "rendercv_output" / "John_Doe_CV.pdf"
|
||||
)
|
||||
output_typst_file = (
|
||||
examples_directory_path / "rendercv_output" / "John_Doe_CV.typ"
|
||||
)
|
||||
|
||||
# Move PDF file to examples directory
|
||||
new_pdf_file_path = examples_directory_path / f"{yaml_file_path.stem}.pdf"
|
||||
if new_pdf_file_path.exists():
|
||||
new_pdf_file_path.unlink()
|
||||
output_pdf_file.rename(new_pdf_file_path)
|
||||
|
||||
# Convert first page of PDF to image
|
||||
png_file_paths = renderer.render_pngs_from_typst(output_typst_file)
|
||||
first_page_png_file_path = png_file_paths[0]
|
||||
if len(png_file_paths) > 1:
|
||||
# Remove other pages
|
||||
for png_file_path in png_file_paths[1:]:
|
||||
png_file_path.unlink()
|
||||
|
||||
desired_png_file_path = image_assets_directory / f"{theme}.png"
|
||||
|
||||
# If image exists, remove it
|
||||
if desired_png_file_path.exists():
|
||||
desired_png_file_path.unlink()
|
||||
|
||||
# Move image to desired location
|
||||
first_page_png_file_path.rename(desired_png_file_path)
|
||||
|
||||
# Remove rendercv_output directory
|
||||
rendercv_output_directory = examples_directory_path / "rendercv_output"
|
||||
|
||||
shutil.rmtree(rendercv_output_directory)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
generate_examples()
|
||||
print("Examples generated successfully.") # NOQA: T201
|
||||
@@ -1,18 +0,0 @@
|
||||
"""This script generates the JSON schema (schema.json) in the repository root."""
|
||||
|
||||
import pathlib
|
||||
|
||||
import rendercv.data as data
|
||||
|
||||
repository_root = pathlib.Path(__file__).parent.parent
|
||||
|
||||
|
||||
def generate_schema():
|
||||
"""Generate the schema."""
|
||||
json_schema_file_path = repository_root / "schema.json"
|
||||
data.generate_json_schema_file(json_schema_file_path)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
generate_schema()
|
||||
print("Schema generated successfully.") # NOQA: T201
|
||||