mirror of
https://github.com/rendercv/rendercv.git
synced 2025-12-23 21:47:55 -05:00
Improve API
This commit is contained in:
@@ -5,9 +5,41 @@ you to version-control your CV/resume as source code.
|
||||
|
||||
__version__ = "2.1"
|
||||
|
||||
from .api import create_contents_of_a_typst_file
|
||||
from .api import (
|
||||
create_a_markdown_file_from_a_python_dictionary,
|
||||
create_a_markdown_file_from_a_yaml_string,
|
||||
create_a_pdf_from_a_python_dictionary,
|
||||
create_a_pdf_from_a_yaml_string,
|
||||
create_a_typst_file_from_a_python_dictionary,
|
||||
create_a_typst_file_from_a_yaml_string,
|
||||
create_an_html_file_from_a_python_dictionary,
|
||||
create_an_html_file_from_a_yaml_string,
|
||||
create_contents_of_a_markdown_file_from_a_python_dictionary,
|
||||
create_contents_of_a_markdown_file_from_a_yaml_string,
|
||||
create_contents_of_a_typst_file_from_a_python_dictionary,
|
||||
create_contents_of_a_typst_file_from_a_yaml_string,
|
||||
read_a_python_dictionary_and_return_a_data_model,
|
||||
read_a_yaml_string_and_return_a_data_model,
|
||||
)
|
||||
|
||||
__all__ = ["create_contents_of_a_typst_file"]
|
||||
__all__ = [
|
||||
"create_a_markdown_file_from_a_python_dictionary",
|
||||
"create_a_markdown_file_from_a_python_dictionary",
|
||||
"create_a_markdown_file_from_a_yaml_string",
|
||||
"create_a_pdf_from_a_python_dictionary",
|
||||
"create_a_pdf_from_a_yaml_string",
|
||||
"create_a_typst_file_from_a_python_dictionary",
|
||||
"create_a_typst_file_from_a_yaml_string",
|
||||
"create_an_html_file_from_a_python_dictionary",
|
||||
"create_an_html_file_from_a_yaml_string",
|
||||
"create_contents_of_a_markdown_file_from_a_python_dictionary",
|
||||
"create_contents_of_a_markdown_file_from_a_yaml_string",
|
||||
"create_contents_of_a_typst_file_from_a_python_dictionary",
|
||||
"create_contents_of_a_typst_file_from_a_python_dictionary",
|
||||
"create_contents_of_a_typst_file_from_a_yaml_string",
|
||||
"read_a_python_dictionary_and_return_a_data_model",
|
||||
"read_a_yaml_string_and_return_a_data_model",
|
||||
]
|
||||
|
||||
_parial_install_error_message = (
|
||||
"It seems you have a partial installation of RenderCV, so this feature is"
|
||||
|
||||
@@ -3,6 +3,36 @@ The `rendercv.api` package contains the functions to create a clean and simple A
|
||||
RenderCV.
|
||||
"""
|
||||
|
||||
from .functions import create_contents_of_a_typst_file
|
||||
from .functions import (
|
||||
create_a_markdown_file_from_a_python_dictionary,
|
||||
create_a_markdown_file_from_a_yaml_string,
|
||||
create_a_pdf_from_a_python_dictionary,
|
||||
create_a_pdf_from_a_yaml_string,
|
||||
create_a_typst_file_from_a_python_dictionary,
|
||||
create_a_typst_file_from_a_yaml_string,
|
||||
create_an_html_file_from_a_python_dictionary,
|
||||
create_an_html_file_from_a_yaml_string,
|
||||
create_contents_of_a_markdown_file_from_a_python_dictionary,
|
||||
create_contents_of_a_markdown_file_from_a_yaml_string,
|
||||
create_contents_of_a_typst_file_from_a_python_dictionary,
|
||||
create_contents_of_a_typst_file_from_a_yaml_string,
|
||||
read_a_python_dictionary_and_return_a_data_model,
|
||||
read_a_yaml_string_and_return_a_data_model,
|
||||
)
|
||||
|
||||
__all__ = ["create_contents_of_a_typst_file"]
|
||||
__all__ = [
|
||||
"create_a_markdown_file_from_a_python_dictionary",
|
||||
"create_a_markdown_file_from_a_yaml_string",
|
||||
"create_a_pdf_from_a_python_dictionary",
|
||||
"create_a_pdf_from_a_yaml_string",
|
||||
"create_a_typst_file_from_a_python_dictionary",
|
||||
"create_a_typst_file_from_a_yaml_string",
|
||||
"create_an_html_file_from_a_python_dictionary",
|
||||
"create_an_html_file_from_a_yaml_string",
|
||||
"create_contents_of_a_markdown_file_from_a_python_dictionary",
|
||||
"create_contents_of_a_markdown_file_from_a_yaml_string",
|
||||
"create_contents_of_a_typst_file_from_a_python_dictionary",
|
||||
"create_contents_of_a_typst_file_from_a_yaml_string",
|
||||
"read_a_python_dictionary_and_return_a_data_model",
|
||||
"read_a_yaml_string_and_return_a_data_model",
|
||||
]
|
||||
|
||||
@@ -3,17 +3,135 @@ The `rendercv.api.functions` package contains the basic functions that are used
|
||||
interact with the RenderCV.
|
||||
"""
|
||||
|
||||
import pathlib
|
||||
import shutil
|
||||
import tempfile
|
||||
from collections.abc import Callable
|
||||
from typing import Optional
|
||||
|
||||
import pydantic
|
||||
|
||||
from .. import data, renderer
|
||||
|
||||
|
||||
def create_contents_of_a_typst_file(
|
||||
def _create_contents_of_a_something_from_something(
|
||||
input: dict | str, parser: Callable, renderer: Callable
|
||||
) -> str | list[dict]:
|
||||
"""
|
||||
Validate the input, generate a file and return it as a string. If there are any
|
||||
validation errors, return them as a list of dictionaries.
|
||||
|
||||
Args:
|
||||
input: The input file as a dictionary or a string.
|
||||
parser: The parser function.
|
||||
renderer: The renderer function.
|
||||
|
||||
Returns:
|
||||
The file as a string or a list of dictionaries that contain the error messages,
|
||||
locations, and the input values.
|
||||
"""
|
||||
try:
|
||||
data_model = parser(input)
|
||||
except pydantic.ValidationError as e:
|
||||
if isinstance(input, str):
|
||||
return data.parse_validation_errors(e, input)
|
||||
return data.parse_validation_errors(e)
|
||||
|
||||
return renderer(data_model)
|
||||
|
||||
|
||||
def _create_a_file_from_something(
|
||||
input: dict | str,
|
||||
parser: Callable,
|
||||
renderer: Callable,
|
||||
output_file_path: pathlib.Path,
|
||||
) -> Optional[list[dict]]:
|
||||
"""
|
||||
Validate the input, generate a file and save it to the output file path.
|
||||
|
||||
Args:
|
||||
input: The input file as a dictionary or a string.
|
||||
parser: The parser function.
|
||||
renderer: The renderer function.
|
||||
output_file_path: The output file path.
|
||||
|
||||
Returns:
|
||||
The output file path.
|
||||
"""
|
||||
try:
|
||||
data_model = parser(input)
|
||||
except pydantic.ValidationError as e:
|
||||
return data.parse_validation_errors(e)
|
||||
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
temporary_output_path = pathlib.Path(temp_dir)
|
||||
typst_file = renderer(data_model, temporary_output_path)
|
||||
shutil.move(typst_file, output_file_path)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def read_a_python_dictionary_and_return_a_data_model(
|
||||
input_file_as_a_dict: dict,
|
||||
) -> data.RenderCVDataModel:
|
||||
"""
|
||||
Validate the input dictionary and return the data model.
|
||||
|
||||
Args:
|
||||
input_file_as_a_dict: The input file as a dictionary.
|
||||
|
||||
Returns:
|
||||
The data model.
|
||||
"""
|
||||
return data.validate_input_dictionary_and_return_the_data_model(
|
||||
input_file_as_a_dict,
|
||||
)
|
||||
|
||||
|
||||
def read_a_yaml_string_and_return_a_data_model(
|
||||
yaml_file_as_string: str,
|
||||
) -> data.RenderCVDataModel:
|
||||
"""
|
||||
Validate the YAML input file given as a string and return the data model.
|
||||
|
||||
Args:
|
||||
yaml_file_as_string: The input file as a string.
|
||||
|
||||
Returns:
|
||||
The data model.
|
||||
"""
|
||||
input_file_as_a_dict = data.read_a_yaml_file(yaml_file_as_string)
|
||||
return read_a_python_dictionary_and_return_a_data_model(input_file_as_a_dict)
|
||||
|
||||
|
||||
def create_contents_of_a_typst_file_from_a_python_dictionary(
|
||||
input_file_as_a_dict: dict,
|
||||
) -> str | list[dict]:
|
||||
"""
|
||||
Validate the input dictionary, generate a Typst file and return it as a string. If
|
||||
there are any validation errors, return them as a list of dictionaries.
|
||||
|
||||
Args:
|
||||
input_file_as_a_dict: The input file as a dictionary.
|
||||
|
||||
Returns:
|
||||
The Typst file as a string or a list of dictionaries that contain the error
|
||||
messages, locations, and the input values.
|
||||
"""
|
||||
return _create_contents_of_a_something_from_something(
|
||||
input_file_as_a_dict,
|
||||
read_a_python_dictionary_and_return_a_data_model,
|
||||
renderer.create_contents_of_a_typst_file,
|
||||
)
|
||||
|
||||
|
||||
def create_contents_of_a_typst_file_from_a_yaml_string(
|
||||
yaml_file_as_string: str,
|
||||
) -> str | list[dict]:
|
||||
"""
|
||||
Validate the input file given as a string, generate a Typst file and return it as a
|
||||
string. If there are any validation errors, return them as a list of dictionaries.
|
||||
Validate the YAML input file given as a string, generate a Typst file and return it
|
||||
as a string. If there are any validation errors, return them as a list of
|
||||
dictionaries.
|
||||
|
||||
Args:
|
||||
yaml_file_as_string: The input file as a string.
|
||||
@@ -22,13 +140,239 @@ def create_contents_of_a_typst_file(
|
||||
The Typst file as a string or a list of dictionaries that contain the error
|
||||
messages, locations, and the input values.
|
||||
"""
|
||||
return _create_contents_of_a_something_from_something(
|
||||
yaml_file_as_string,
|
||||
read_a_yaml_string_and_return_a_data_model,
|
||||
renderer.create_contents_of_a_typst_file,
|
||||
)
|
||||
|
||||
try:
|
||||
input_file_as_a_dict = data.read_a_yaml_file(yaml_file_as_string)
|
||||
data_model = data.validate_input_dictionary_and_return_the_data_model(
|
||||
input_file_as_a_dict,
|
||||
)
|
||||
except pydantic.ValidationError as e:
|
||||
return data.parse_validation_errors(e, yaml_file_as_string)
|
||||
|
||||
return renderer.create_contents_of_a_typst_file(data_model)
|
||||
def create_contents_of_a_markdown_file_from_a_python_dictionary(
|
||||
input_file_as_a_dict: dict,
|
||||
) -> str | list[dict]:
|
||||
"""
|
||||
Validate the input dictionary, generate a Markdown file and return it as a string.
|
||||
If there are any validation errors, return them as a list of dictionaries.
|
||||
|
||||
Args:
|
||||
input_file_as_a_dict: The input file as a dictionary.
|
||||
|
||||
Returns:
|
||||
The Markdown file as a string or a list of dictionaries that contain the error
|
||||
messages, locations, and the input values.
|
||||
"""
|
||||
return _create_contents_of_a_something_from_something(
|
||||
input_file_as_a_dict,
|
||||
read_a_python_dictionary_and_return_a_data_model,
|
||||
renderer.create_contents_of_a_markdown_file,
|
||||
)
|
||||
|
||||
|
||||
def create_contents_of_a_markdown_file_from_a_yaml_string(
|
||||
yaml_file_as_string: str,
|
||||
) -> str | list[dict]:
|
||||
"""
|
||||
Validate the input file given as a string, generate a Markdown file and return it as
|
||||
a string. If there are any validation errors, return them as a list of dictionaries.
|
||||
|
||||
Args:
|
||||
yaml_file_as_string: The input file as a string.
|
||||
|
||||
Returns:
|
||||
The Markdown file as a string or a list of dictionaries that contain the error
|
||||
messages, locations, and the input values.
|
||||
"""
|
||||
return _create_contents_of_a_something_from_something(
|
||||
yaml_file_as_string,
|
||||
read_a_yaml_string_and_return_a_data_model,
|
||||
renderer.create_contents_of_a_markdown_file,
|
||||
)
|
||||
|
||||
|
||||
def create_a_typst_file_from_a_yaml_string(
|
||||
yaml_file_as_string: str,
|
||||
output_file_path: pathlib.Path,
|
||||
) -> Optional[list[dict]]:
|
||||
"""
|
||||
Validate the input file given as a string, generate a Typst file and save it to the
|
||||
output file path.
|
||||
|
||||
Args:
|
||||
yaml_file_as_string: The input file as a string.
|
||||
output_file_path: The output file path.
|
||||
|
||||
Returns:
|
||||
The output file path.
|
||||
"""
|
||||
|
||||
return _create_a_file_from_something(
|
||||
yaml_file_as_string,
|
||||
read_a_yaml_string_and_return_a_data_model,
|
||||
renderer.create_a_typst_file,
|
||||
output_file_path,
|
||||
)
|
||||
|
||||
|
||||
def create_a_typst_file_from_a_python_dictionary(
|
||||
input_file_as_a_dict: dict,
|
||||
output_file_path: pathlib.Path,
|
||||
) -> Optional[list[dict]]:
|
||||
"""
|
||||
Validate the input dictionary, generate a Typst file and save it to the output file
|
||||
path.
|
||||
|
||||
Args:
|
||||
input_file_as_a_dict: The input file as a dictionary.
|
||||
output_file_path: The output file path.
|
||||
|
||||
Returns:
|
||||
The output file path.
|
||||
"""
|
||||
return _create_a_file_from_something(
|
||||
input_file_as_a_dict,
|
||||
read_a_python_dictionary_and_return_a_data_model,
|
||||
renderer.create_a_typst_file,
|
||||
output_file_path,
|
||||
)
|
||||
|
||||
|
||||
def create_a_markdown_file_from_a_python_dictionary(
|
||||
input_file_as_a_dict: dict,
|
||||
output_file_path: pathlib.Path,
|
||||
) -> Optional[list[dict]]:
|
||||
"""
|
||||
Validate the input dictionary, generate a Markdown file and save it to the output
|
||||
file path.
|
||||
|
||||
Args:
|
||||
input_file_as_a_dict: The input file as a dictionary.
|
||||
output_file_path: The output file path.
|
||||
|
||||
Returns:
|
||||
The output file path.
|
||||
"""
|
||||
return _create_a_file_from_something(
|
||||
input_file_as_a_dict,
|
||||
read_a_python_dictionary_and_return_a_data_model,
|
||||
renderer.create_a_markdown_file,
|
||||
output_file_path,
|
||||
)
|
||||
|
||||
|
||||
def create_a_markdown_file_from_a_yaml_string(
|
||||
yaml_file_as_string: str,
|
||||
output_file_path: pathlib.Path,
|
||||
) -> Optional[list[dict]]:
|
||||
"""
|
||||
Validate the input file given as a string, generate a Markdown file and save it to
|
||||
the output file path.
|
||||
|
||||
Args:
|
||||
yaml_file_as_string: The input file as a string.
|
||||
output_file_path: The output file path.
|
||||
|
||||
Returns:
|
||||
The output file path.
|
||||
"""
|
||||
return _create_a_file_from_something(
|
||||
yaml_file_as_string,
|
||||
read_a_yaml_string_and_return_a_data_model,
|
||||
renderer.create_a_markdown_file,
|
||||
output_file_path,
|
||||
)
|
||||
|
||||
|
||||
def create_an_html_file_from_a_python_dictionary(
|
||||
input_file_as_a_dict: dict,
|
||||
output_file_path: pathlib.Path,
|
||||
) -> Optional[list[dict]]:
|
||||
"""
|
||||
Validate the input dictionary, generate an HTML file and save it to the output file
|
||||
path.
|
||||
|
||||
Args:
|
||||
input_file_as_a_dict: The input file as a dictionary.
|
||||
output_file_path: The output file path.
|
||||
|
||||
Returns:
|
||||
The output file path.
|
||||
"""
|
||||
return _create_a_file_from_something(
|
||||
input_file_as_a_dict,
|
||||
read_a_python_dictionary_and_return_a_data_model,
|
||||
lambda x, y: renderer.render_an_html_from_markdown(
|
||||
renderer.create_a_markdown_file(x, y),
|
||||
),
|
||||
output_file_path,
|
||||
)
|
||||
|
||||
|
||||
def create_an_html_file_from_a_yaml_string(
|
||||
yaml_file_as_string: str,
|
||||
output_file_path: pathlib.Path,
|
||||
) -> Optional[list[dict]]:
|
||||
"""
|
||||
Validate the input file given as a string, generate an HTML file and save it to the
|
||||
output file path.
|
||||
|
||||
Args:
|
||||
yaml_file_as_string: The input file as a string.
|
||||
output_file_path: The output file path.
|
||||
|
||||
Returns:
|
||||
The output file path.
|
||||
"""
|
||||
return _create_a_file_from_something(
|
||||
yaml_file_as_string,
|
||||
read_a_yaml_string_and_return_a_data_model,
|
||||
lambda x, y: renderer.render_an_html_from_markdown(
|
||||
renderer.create_a_markdown_file(x, y),
|
||||
),
|
||||
output_file_path,
|
||||
)
|
||||
|
||||
|
||||
def create_a_pdf_from_a_yaml_string(
|
||||
yaml_file_as_string: str,
|
||||
output_file_path: pathlib.Path,
|
||||
) -> Optional[list[dict]]:
|
||||
"""
|
||||
Validate the input file given as a string, generate a PDF file and save it to the
|
||||
output file path.
|
||||
|
||||
Args:
|
||||
yaml_file_as_string: The input file as a string.
|
||||
output_file_path: The output file path.
|
||||
|
||||
Returns:
|
||||
The output file path.
|
||||
"""
|
||||
return _create_a_file_from_something(
|
||||
yaml_file_as_string,
|
||||
read_a_yaml_string_and_return_a_data_model,
|
||||
renderer.create_a_typst_file,
|
||||
output_file_path,
|
||||
)
|
||||
|
||||
|
||||
def create_a_pdf_from_a_python_dictionary(
|
||||
input_file_as_a_dict: dict,
|
||||
output_file_path: pathlib.Path,
|
||||
) -> Optional[list[dict]]:
|
||||
"""
|
||||
Validate the input dictionary, generate a PDF file and save it to the output file
|
||||
path.
|
||||
|
||||
Args:
|
||||
input_file_as_a_dict: The input file as a dictionary.
|
||||
output_file_path: The output file path.
|
||||
|
||||
Returns:
|
||||
The output file path.
|
||||
"""
|
||||
return _create_a_file_from_something(
|
||||
input_file_as_a_dict,
|
||||
read_a_python_dictionary_and_return_a_data_model,
|
||||
renderer.create_a_typst_file,
|
||||
output_file_path,
|
||||
)
|
||||
|
||||
@@ -15,6 +15,7 @@ from .renderer import (
|
||||
create_a_markdown_file,
|
||||
create_a_typst_file,
|
||||
create_a_typst_file_and_copy_theme_files,
|
||||
create_contents_of_a_markdown_file,
|
||||
create_contents_of_a_typst_file,
|
||||
render_a_pdf_from_typst,
|
||||
render_an_html_from_markdown,
|
||||
@@ -25,6 +26,7 @@ __all__ = [
|
||||
"create_a_markdown_file",
|
||||
"create_a_typst_file",
|
||||
"create_a_typst_file_and_copy_theme_files",
|
||||
"create_contents_of_a_markdown_file",
|
||||
"create_contents_of_a_typst_file",
|
||||
"render_a_pdf_from_typst",
|
||||
"render_an_html_from_markdown",
|
||||
|
||||
@@ -14,6 +14,43 @@ from .. import data
|
||||
from . import templater
|
||||
|
||||
|
||||
def create_a_file_name_without_extension_from_name(name: Optional[str]) -> str:
|
||||
"""Create a file name from the given name by replacing the spaces with underscores
|
||||
and removing typst commands.
|
||||
|
||||
Args:
|
||||
name: The name to be converted.
|
||||
|
||||
Returns:
|
||||
The converted name (without the extension).
|
||||
"""
|
||||
name_without_typst_commands = templater.remove_typst_commands(str(name))
|
||||
return f"{name_without_typst_commands.replace(' ', '_')}_CV"
|
||||
|
||||
|
||||
def create_a_file_and_write_contents_to_it(
|
||||
contents: str, file_name: str, output_directory: pathlib.Path
|
||||
) -> pathlib.Path:
|
||||
"""Create a file with the given contents in the output directory.
|
||||
|
||||
Args:
|
||||
contents: The contents of the file.
|
||||
file_name: The name of the file.
|
||||
output_directory: Path to the output directory.
|
||||
|
||||
Returns:
|
||||
The path to the created file.
|
||||
"""
|
||||
# Create output directory if it doesn't exist:
|
||||
if not output_directory.is_dir():
|
||||
output_directory.mkdir(parents=True)
|
||||
|
||||
file_path = output_directory / file_name
|
||||
file_path.write_text(contents, encoding="utf-8")
|
||||
|
||||
return file_path
|
||||
|
||||
|
||||
def copy_theme_files_to_output_directory(
|
||||
theme_name: str,
|
||||
output_directory_path: pathlib.Path,
|
||||
@@ -102,18 +139,37 @@ def create_a_typst_file(
|
||||
|
||||
typst_contents = create_contents_of_a_typst_file(rendercv_data_model)
|
||||
|
||||
# Create output directory if it doesn't exist:
|
||||
if not output_directory.is_dir():
|
||||
output_directory.mkdir(parents=True)
|
||||
|
||||
name_without_typst_commands = templater.remove_typst_commands(
|
||||
str(rendercv_data_model.cv.name)
|
||||
file_name_without_extension = create_a_file_name_without_extension_from_name(
|
||||
rendercv_data_model.cv.name
|
||||
)
|
||||
file_name = f"{name_without_typst_commands.replace(' ', '_')}_CV.typ"
|
||||
file_path = output_directory / file_name
|
||||
file_path.write_text(typst_contents, encoding="utf-8")
|
||||
file_name = f"{file_name_without_extension}.typ"
|
||||
|
||||
return file_path
|
||||
return create_a_file_and_write_contents_to_it(
|
||||
typst_contents,
|
||||
file_name,
|
||||
output_directory,
|
||||
)
|
||||
|
||||
|
||||
def create_contents_of_a_markdown_file(
|
||||
rendercv_data_model: data.RenderCVDataModel,
|
||||
) -> str:
|
||||
"""Create a Markdown file with the given data model and return it as a string.
|
||||
|
||||
Args:
|
||||
rendercv_data_model: The data model.
|
||||
|
||||
Returns:
|
||||
The path to the generated Markdown file.
|
||||
"""
|
||||
jinja2_environment = templater.Jinja2Environment().environment
|
||||
|
||||
markdown_file_object = templater.MarkdownFile(
|
||||
rendercv_data_model,
|
||||
jinja2_environment,
|
||||
)
|
||||
|
||||
return markdown_file_object.get_full_code()
|
||||
|
||||
|
||||
def create_a_markdown_file(
|
||||
@@ -129,21 +185,18 @@ def create_a_markdown_file(
|
||||
Returns:
|
||||
The path to the rendered Markdown file.
|
||||
"""
|
||||
# create output directory if it doesn't exist:
|
||||
if not output_directory.is_dir():
|
||||
output_directory.mkdir(parents=True)
|
||||
markdown_contents = create_contents_of_a_markdown_file(rendercv_data_model)
|
||||
|
||||
jinja2_environment = templater.Jinja2Environment().environment
|
||||
markdown_file_object = templater.MarkdownFile(
|
||||
rendercv_data_model,
|
||||
jinja2_environment,
|
||||
file_name_without_extension = create_a_file_name_without_extension_from_name(
|
||||
rendercv_data_model.cv.name
|
||||
)
|
||||
file_name = f"{file_name_without_extension}.typ"
|
||||
|
||||
markdown_file_name = f"{str(rendercv_data_model.cv.name).replace(' ', '_')}_CV.md"
|
||||
markdown_file_path = output_directory / markdown_file_name
|
||||
markdown_file_object.create_file(markdown_file_path)
|
||||
|
||||
return markdown_file_path
|
||||
return create_a_file_and_write_contents_to_it(
|
||||
markdown_contents,
|
||||
file_name,
|
||||
output_directory,
|
||||
)
|
||||
|
||||
|
||||
def create_a_typst_file_and_copy_theme_files(
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import copy
|
||||
import filecmp
|
||||
import itertools
|
||||
import json
|
||||
import pathlib
|
||||
import shutil
|
||||
import typing
|
||||
@@ -157,6 +158,17 @@ def rendercv_data_model() -> data.RenderCVDataModel:
|
||||
return data.create_a_sample_data_model()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def rendercv_data_as_python_dictionary(
|
||||
rendercv_data_model,
|
||||
) -> dict:
|
||||
"""Return a sample RenderCV data as a Python dictionary."""
|
||||
data_model_as_json = rendercv_data_model.model_dump_json(
|
||||
exclude_none=False, by_alias=True, exclude={"cv": {"sections", "photo"}}
|
||||
)
|
||||
return json.loads(data_model_as_json)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def rendercv_empty_curriculum_vitae_data_model() -> data.CurriculumVitae:
|
||||
"""Return an empty CurriculumVitae data model."""
|
||||
|
||||
@@ -1,6 +1,134 @@
|
||||
import pathlib
|
||||
import tempfile
|
||||
|
||||
import rendercv
|
||||
import rendercv.data
|
||||
|
||||
|
||||
def test_create_contents_of_a_typst_file(input_file_path):
|
||||
yaml_string = input_file_path.read_text()
|
||||
assert isinstance(rendercv.create_contents_of_a_typst_file(yaml_string), str)
|
||||
assert isinstance(
|
||||
rendercv.create_contents_of_a_typst_file_from_a_yaml_string(yaml_string), str
|
||||
)
|
||||
|
||||
|
||||
def test_create_contents_of_a_typst_file_with_errors(
|
||||
rendercv_data_as_python_dictionary,
|
||||
):
|
||||
rendercv_data_as_python_dictionary["cv"]["email"] = "invalid-email"
|
||||
yaml_string = rendercv.data.generator.dictionary_to_yaml(
|
||||
rendercv_data_as_python_dictionary
|
||||
)
|
||||
assert isinstance(
|
||||
rendercv.create_contents_of_a_typst_file_from_a_yaml_string(yaml_string), list
|
||||
)
|
||||
|
||||
|
||||
def test_create_a_typst_file_from_a_yaml_string(input_file_path):
|
||||
yaml_string = input_file_path.read_text()
|
||||
output_file_path = pathlib.Path(tempfile.mktemp(suffix=".typst"))
|
||||
errors = rendercv.create_a_typst_file_from_a_yaml_string(
|
||||
yaml_string, output_file_path
|
||||
)
|
||||
assert errors is None
|
||||
assert output_file_path.exists()
|
||||
|
||||
|
||||
def test_create_a_typst_file_from_a_python_dictionary(
|
||||
rendercv_data_as_python_dictionary,
|
||||
):
|
||||
output_file_path = pathlib.Path(tempfile.mktemp(suffix=".typst"))
|
||||
errors = rendercv.create_a_typst_file_from_a_python_dictionary(
|
||||
rendercv_data_as_python_dictionary, output_file_path
|
||||
)
|
||||
assert errors is None
|
||||
assert output_file_path.exists()
|
||||
|
||||
|
||||
def test_create_contents_of_a_markdown_file_from_a_yaml_string(input_file_path):
|
||||
yaml_string = input_file_path.read_text()
|
||||
result = rendercv.create_contents_of_a_markdown_file_from_a_yaml_string(yaml_string)
|
||||
assert isinstance(result, str)
|
||||
|
||||
|
||||
def test_create_contents_of_a_markdown_file_from_a_python_dictionary(
|
||||
rendercv_data_as_python_dictionary,
|
||||
):
|
||||
result = rendercv.create_contents_of_a_markdown_file_from_a_python_dictionary(
|
||||
rendercv_data_as_python_dictionary
|
||||
)
|
||||
assert isinstance(result, str)
|
||||
|
||||
|
||||
def test_create_a_markdown_file_from_a_yaml_string(input_file_path):
|
||||
yaml_string = input_file_path.read_text()
|
||||
output_file_path = pathlib.Path(tempfile.mktemp(suffix=".md"))
|
||||
errors = rendercv.create_a_markdown_file_from_a_yaml_string(
|
||||
yaml_string, output_file_path
|
||||
)
|
||||
assert errors is None
|
||||
assert output_file_path.exists()
|
||||
|
||||
|
||||
def test_create_a_markdown_file_from_a_python_dictionary(
|
||||
rendercv_data_as_python_dictionary,
|
||||
):
|
||||
output_file_path = pathlib.Path(tempfile.mktemp(suffix=".md"))
|
||||
errors = rendercv.create_a_markdown_file_from_a_python_dictionary(
|
||||
rendercv_data_as_python_dictionary, output_file_path
|
||||
)
|
||||
assert errors is None
|
||||
assert output_file_path.exists()
|
||||
|
||||
|
||||
def test_create_an_html_file_from_a_yaml_string(input_file_path):
|
||||
yaml_string = input_file_path.read_text()
|
||||
output_file_path = pathlib.Path(tempfile.mktemp(suffix=".html"))
|
||||
errors = rendercv.create_an_html_file_from_a_yaml_string(
|
||||
yaml_string, output_file_path
|
||||
)
|
||||
assert errors is None
|
||||
assert output_file_path.exists()
|
||||
|
||||
|
||||
def test_create_an_html_file_from_a_python_dictionary(
|
||||
rendercv_data_as_python_dictionary,
|
||||
):
|
||||
output_file_path = pathlib.Path(tempfile.mktemp(suffix=".html"))
|
||||
errors = rendercv.create_an_html_file_from_a_python_dictionary(
|
||||
rendercv_data_as_python_dictionary, output_file_path
|
||||
)
|
||||
assert errors is None
|
||||
assert output_file_path.exists()
|
||||
|
||||
|
||||
def test_create_a_pdf_from_a_yaml_string(input_file_path):
|
||||
yaml_string = input_file_path.read_text()
|
||||
output_file_path = pathlib.Path(tempfile.mktemp(suffix=".pdf"))
|
||||
errors = rendercv.create_a_pdf_from_a_yaml_string(yaml_string, output_file_path)
|
||||
assert errors is None
|
||||
assert output_file_path.exists()
|
||||
|
||||
|
||||
def test_create_a_pdf_from_a_python_dictionary(rendercv_data_as_python_dictionary):
|
||||
output_file_path = pathlib.Path(tempfile.mktemp(suffix=".pdf"))
|
||||
errors = rendercv.create_a_pdf_from_a_python_dictionary(
|
||||
rendercv_data_as_python_dictionary, output_file_path
|
||||
)
|
||||
assert errors is None
|
||||
assert output_file_path.exists()
|
||||
|
||||
|
||||
def test_read_a_python_dictionary_and_return_a_data_model(
|
||||
rendercv_data_as_python_dictionary,
|
||||
):
|
||||
result = rendercv.read_a_python_dictionary_and_return_a_data_model(
|
||||
rendercv_data_as_python_dictionary
|
||||
)
|
||||
assert isinstance(result, rendercv.data.RenderCVDataModel)
|
||||
|
||||
|
||||
def test_read_a_yaml_string_and_return_a_data_model(input_file_path):
|
||||
yaml_string = input_file_path.read_text()
|
||||
result = rendercv.read_a_yaml_string_and_return_a_data_model(yaml_string)
|
||||
assert isinstance(result, rendercv.data.RenderCVDataModel)
|
||||
|
||||
@@ -895,81 +895,93 @@ def test_make_keywords_bold_in_a_string():
|
||||
|
||||
|
||||
def test_bold_keywords():
|
||||
data_model = data.RenderCVDataModel(
|
||||
cv=data.CurriculumVitae(
|
||||
name="John Doe",
|
||||
sections={
|
||||
"test": [
|
||||
"test_keyword_1",
|
||||
],
|
||||
data_model_as_dict = {
|
||||
"cv": {
|
||||
"sections": {
|
||||
"test": ["test_keyword_1"],
|
||||
"test2": [
|
||||
data.EducationEntry(
|
||||
institution="Test Institution",
|
||||
area="Test Area",
|
||||
highlights=["test_keyword_2"],
|
||||
summary="test_keyword_3 test_keyword_4",
|
||||
),
|
||||
{
|
||||
"institution": "Test Institution",
|
||||
"area": "Test Area",
|
||||
"degree": None,
|
||||
"date": None,
|
||||
"start_date": None,
|
||||
"end_date": None,
|
||||
"location": None,
|
||||
"summary": "test_keyword_3 test_keyword_4",
|
||||
"highlights": ["test_keyword_2"],
|
||||
}
|
||||
],
|
||||
"test3": [
|
||||
data.ExperienceEntry(
|
||||
company="Test Company",
|
||||
position="Test Position",
|
||||
highlights=["test_keyword_5", "test_keyword_6"],
|
||||
summary="test_keyword_6 test_keyword_7",
|
||||
),
|
||||
{
|
||||
"company": "Test Company",
|
||||
"position": "Test Position",
|
||||
"date": None,
|
||||
"start_date": None,
|
||||
"end_date": None,
|
||||
"location": None,
|
||||
"summary": "test_keyword_6 test_keyword_7",
|
||||
"highlights": ["test_keyword_5", "test_keyword_6"],
|
||||
}
|
||||
],
|
||||
"test4": [
|
||||
data.NormalEntry(
|
||||
name="Test",
|
||||
highlights=["test_keyword_2"],
|
||||
summary="test_keyword_3 test_keyword_4",
|
||||
),
|
||||
],
|
||||
"test5": [
|
||||
data.PublicationEntry(
|
||||
title="Test Institution",
|
||||
authors=["Test Author"],
|
||||
),
|
||||
],
|
||||
"test6": [
|
||||
data.BulletEntry(
|
||||
bullet="test_keyword_3 test_keyword_4",
|
||||
),
|
||||
{
|
||||
"name": "Test",
|
||||
"date": None,
|
||||
"start_date": None,
|
||||
"end_date": None,
|
||||
"location": None,
|
||||
"summary": "test_keyword_3 test_keyword_4",
|
||||
"highlights": ["test_keyword_2"],
|
||||
}
|
||||
],
|
||||
"test6": [{"bullet": "test_keyword_3 test_keyword_4"}],
|
||||
"test7": [
|
||||
data.OneLineEntry(
|
||||
label="Test Institution",
|
||||
details="test_keyword_3 test_keyword_4",
|
||||
),
|
||||
{
|
||||
"label": "Test Institution",
|
||||
"details": "test_keyword_3 test_keyword_4",
|
||||
}
|
||||
],
|
||||
},
|
||||
)
|
||||
},
|
||||
"rendercv_settings": {
|
||||
"bold_keywords": [
|
||||
"test_keyword_1",
|
||||
"test_keyword_2",
|
||||
"test_keyword_3",
|
||||
"test_keyword_4",
|
||||
"test_keyword_5",
|
||||
"test_keyword_6",
|
||||
"test_keyword_7",
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
data_model = data.validate_input_dictionary_and_return_the_data_model(
|
||||
data_model_as_dict
|
||||
)
|
||||
|
||||
for section in data_model.cv.sections:
|
||||
for entry in section.entries:
|
||||
if section.title == "test":
|
||||
if section.title == "Test":
|
||||
assert "**test_keyword_1**" in entry
|
||||
elif section.title == "test2":
|
||||
elif section.title == "Test2":
|
||||
assert "**test_keyword_2**" in entry.highlights[0]
|
||||
assert "**test_keyword_3**" in entry.summary
|
||||
assert "**test_keyword_4**" in entry.summary
|
||||
elif section.title == "test3":
|
||||
elif section.title == "Test3":
|
||||
assert "**test_keyword_5**" in entry.highlights[0]
|
||||
assert "**test_keyword_6**" in entry.highlights[1]
|
||||
assert "**test_keyword_6**" in entry.summary
|
||||
assert "**test_keyword_7**" in entry.summary
|
||||
elif section.title == "test4":
|
||||
elif section.title == "Test4":
|
||||
assert "**test_keyword_2**" in entry.highlights[0]
|
||||
assert "**test_keyword_3**" in entry.summary
|
||||
assert "**test_keyword_4**" in entry.summary
|
||||
elif section.title == "test5":
|
||||
assert "**test_keyword_3**" in entry.summary
|
||||
assert "**test_keyword_4**" in entry.summary
|
||||
elif section.title == "test6":
|
||||
elif section.title == "Test6":
|
||||
assert "**test_keyword_3**" in entry.bullet
|
||||
assert "**test_keyword_4**" in entry.bullet
|
||||
elif section.title == "test7":
|
||||
elif section.title == "Test7":
|
||||
assert "**test_keyword_3**" in entry.details
|
||||
assert "**test_keyword_4**" in entry.details
|
||||
|
||||
|
||||
Reference in New Issue
Block a user