mirror of
https://github.com/rendercv/rendercv.git
synced 2025-12-23 21:47:55 -05:00
Merge pull request #1 from akib1689/add-settings
feat: Added render cv settings
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 474 KiB After Width: | Height: | Size: 474 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 562 KiB After Width: | Height: | Size: 564 KiB |
Binary file not shown.
@@ -141,3 +141,8 @@ design:
|
||||
bottom: 0.3 cm
|
||||
horizontal_between_connections: 0.5 cm
|
||||
show_timespan_in: []
|
||||
rendercv_settings:
|
||||
output_folder_name: rendercv_output
|
||||
no_html: false
|
||||
no_markdown: false
|
||||
no_png: false
|
||||
|
||||
Binary file not shown.
@@ -139,3 +139,8 @@ design:
|
||||
vertical_between_name_and_connections: 5 pt
|
||||
bottom: 5 pt
|
||||
horizontal_between_connections: 10 pt
|
||||
rendercv_settings:
|
||||
output_folder_name: rendercv_output
|
||||
no_html: false
|
||||
no_markdown: false
|
||||
no_png: false
|
||||
|
||||
Binary file not shown.
@@ -112,3 +112,8 @@ design:
|
||||
content_scale: 0.75
|
||||
show_only_years: false
|
||||
disable_page_numbers: false
|
||||
rendercv_settings:
|
||||
output_folder_name: rendercv_output
|
||||
no_html: false
|
||||
no_markdown: false
|
||||
no_png: false
|
||||
|
||||
Binary file not shown.
@@ -139,3 +139,8 @@ design:
|
||||
vertical_between_name_and_connections: 0.3 cm
|
||||
bottom: 0.3 cm
|
||||
horizontal_between_connections: 0.5 cm
|
||||
rendercv_settings:
|
||||
output_folder_name: rendercv_output
|
||||
no_html: false
|
||||
no_markdown: false
|
||||
no_png: false
|
||||
|
||||
@@ -5,7 +5,7 @@ commands of RenderCV.
|
||||
|
||||
import os
|
||||
import pathlib
|
||||
from typing import Annotated, Literal, Optional
|
||||
from typing import Annotated, Optional
|
||||
|
||||
import typer
|
||||
from rich import print
|
||||
@@ -141,18 +141,38 @@ def cli_command_render(
|
||||
input_file_path: pathlib.Path = utilities.string_to_file_path(
|
||||
input_file_name
|
||||
) # type: ignore
|
||||
output_directory = pathlib.Path.cwd() / output_folder_name
|
||||
|
||||
paths: dict[
|
||||
Literal["latex", "pdf", "markdown", "html", "png"], Optional[pathlib.Path]
|
||||
] = {
|
||||
"latex": utilities.string_to_file_path(latex_path),
|
||||
"pdf": utilities.string_to_file_path(pdf_path),
|
||||
"markdown": utilities.string_to_file_path(markdown_path),
|
||||
"html": utilities.string_to_file_path(html_path),
|
||||
"png": utilities.string_to_file_path(png_path),
|
||||
# dictionary for command line arguments:
|
||||
cli_args = {
|
||||
"use_local_latex_command": use_local_latex_command,
|
||||
"output_folder_name": output_folder_name,
|
||||
"latex_path": utilities.string_to_file_path(latex_path),
|
||||
"pdf_path": utilities.string_to_file_path(pdf_path),
|
||||
"markdown_path": utilities.string_to_file_path(markdown_path),
|
||||
"html_path": utilities.string_to_file_path(html_path),
|
||||
"png_path": utilities.string_to_file_path(png_path),
|
||||
"no_markdown": dont_generate_markdown,
|
||||
"no_html": dont_generate_html,
|
||||
"no_png": dont_generate_png,
|
||||
}
|
||||
|
||||
# Create the default values for the cli_args:
|
||||
cli_args_default = {
|
||||
"use_local_latex_command": None,
|
||||
"output_folder_name": "rendercv_output",
|
||||
"latex_path": None,
|
||||
"pdf_path": None,
|
||||
"markdown_path": None,
|
||||
"html_path": None,
|
||||
"png_path": None,
|
||||
"no_markdown": False,
|
||||
"no_html": False,
|
||||
"no_png": False,
|
||||
}
|
||||
|
||||
# keep the current working directory:
|
||||
working_directory = pathlib.Path.cwd()
|
||||
|
||||
# change the current working directory to the input file's directory (because
|
||||
# the template overrides are looked up in the current working directory):
|
||||
os.chdir(input_file_path.parent)
|
||||
@@ -164,17 +184,8 @@ def cli_command_render(
|
||||
# 4. render PNG files from the PDF
|
||||
# 5. generate the Markdown file
|
||||
# 6. render the Markdown file to a HTML (for Grammarly)
|
||||
number_of_steps = 6
|
||||
if dont_generate_png:
|
||||
number_of_steps = number_of_steps - 1
|
||||
if dont_generate_markdown:
|
||||
# if the Markdown file is not generated, then the HTML file is not generated
|
||||
number_of_steps = number_of_steps - 2
|
||||
else:
|
||||
if dont_generate_html:
|
||||
number_of_steps = number_of_steps - 1
|
||||
|
||||
with printer.LiveProgressReporter(number_of_steps) as progress:
|
||||
initial_steps = 1
|
||||
with printer.LiveProgressReporter(number_of_steps=initial_steps) as progress:
|
||||
progress.start_a_step("Reading and validating the input file")
|
||||
data_as_a_dict = data.read_a_yaml_file(input_file_path)
|
||||
|
||||
@@ -187,60 +198,96 @@ def cli_command_render(
|
||||
data_as_a_dict = utilities.set_or_update_values(
|
||||
data_as_a_dict, key_and_values
|
||||
)
|
||||
# update the data of the rendercv settings:
|
||||
render_cv_settings = data_as_a_dict.get("rendercv_settings", dict())
|
||||
render_cv_settings = utilities.build_rendercv_settings(
|
||||
render_cv_settings, cli_args, cli_args_default
|
||||
)
|
||||
|
||||
# update the data model with the rendercv settings:
|
||||
data_as_a_dict["rendercv_settings"] = render_cv_settings
|
||||
|
||||
data_model = data.validate_input_dictionary_and_return_the_data_model(
|
||||
data_as_a_dict
|
||||
)
|
||||
|
||||
output_directory = (
|
||||
working_directory / data_model.rendercv_settings.output_folder_name
|
||||
)
|
||||
|
||||
progress.finish_the_current_step()
|
||||
|
||||
# Calculate the number of steps:
|
||||
number_of_steps = 6
|
||||
if data_model.rendercv_settings.no_png:
|
||||
number_of_steps -= 1
|
||||
if data_model.rendercv_settings.no_markdown:
|
||||
number_of_steps -= 2
|
||||
else:
|
||||
if data_model.rendercv_settings.no_html:
|
||||
number_of_steps -= 1
|
||||
|
||||
progress.update_total_steps(number_of_steps)
|
||||
|
||||
progress.start_a_step("Generating the LaTeX file")
|
||||
latex_file_path_in_output_folder = (
|
||||
renderer.create_a_latex_file_and_copy_theme_files(
|
||||
data_model, output_directory
|
||||
)
|
||||
)
|
||||
if paths["latex"]:
|
||||
utilities.copy_files(latex_file_path_in_output_folder, paths["latex"])
|
||||
if data_model.rendercv_settings.latex_path:
|
||||
utilities.copy_files(
|
||||
latex_file_path_in_output_folder,
|
||||
data_model.rendercv_settings.latex_path,
|
||||
)
|
||||
progress.finish_the_current_step()
|
||||
|
||||
progress.start_a_step("Rendering the LaTeX file to a PDF")
|
||||
pdf_file_path_in_output_folder = renderer.render_a_pdf_from_latex(
|
||||
latex_file_path_in_output_folder, use_local_latex_command
|
||||
)
|
||||
if paths["pdf"]:
|
||||
utilities.copy_files(pdf_file_path_in_output_folder, paths["pdf"])
|
||||
if data_model.rendercv_settings.pdf_path:
|
||||
utilities.copy_files(
|
||||
pdf_file_path_in_output_folder, data_model.rendercv_settings.pdf_path
|
||||
)
|
||||
progress.finish_the_current_step()
|
||||
|
||||
if not dont_generate_png:
|
||||
if not data_model.rendercv_settings.no_png:
|
||||
progress.start_a_step("Rendering PNG files from the PDF")
|
||||
png_file_paths_in_output_folder = renderer.render_pngs_from_pdf(
|
||||
pdf_file_path_in_output_folder
|
||||
)
|
||||
if paths["png"]:
|
||||
utilities.copy_files(png_file_paths_in_output_folder, paths["png"])
|
||||
if data_model.rendercv_settings.png_path:
|
||||
utilities.copy_files(
|
||||
png_file_paths_in_output_folder,
|
||||
data_model.rendercv_settings.png_path,
|
||||
)
|
||||
progress.finish_the_current_step()
|
||||
|
||||
if not dont_generate_markdown:
|
||||
if not data_model.rendercv_settings.no_markdown:
|
||||
progress.start_a_step("Generating the Markdown file")
|
||||
markdown_file_path_in_output_folder = renderer.create_a_markdown_file(
|
||||
data_model, output_directory
|
||||
)
|
||||
if paths["markdown"]:
|
||||
if data_model.rendercv_settings.markdown_path:
|
||||
utilities.copy_files(
|
||||
markdown_file_path_in_output_folder, paths["markdown"]
|
||||
markdown_file_path_in_output_folder,
|
||||
data_model.rendercv_settings.markdown_path,
|
||||
)
|
||||
progress.finish_the_current_step()
|
||||
|
||||
if not dont_generate_html:
|
||||
if not data_model.rendercv_settings.no_html:
|
||||
progress.start_a_step(
|
||||
"Rendering the Markdown file to a HTML (for Grammarly)"
|
||||
)
|
||||
html_file_path_in_output_folder = renderer.render_an_html_from_markdown(
|
||||
markdown_file_path_in_output_folder
|
||||
)
|
||||
if paths["html"]:
|
||||
utilities.copy_files(html_file_path_in_output_folder, paths["html"])
|
||||
if data_model.rendercv_settings.html_path:
|
||||
utilities.copy_files(
|
||||
html_file_path_in_output_folder,
|
||||
data_model.rendercv_settings.html_path,
|
||||
)
|
||||
progress.finish_the_current_step()
|
||||
|
||||
|
||||
|
||||
@@ -84,6 +84,22 @@ class LiveProgressReporter(rich.live.Live):
|
||||
f"{self.current_step_name} has started."
|
||||
)
|
||||
|
||||
def update_total_steps(self, total_steps: int):
|
||||
"""Update the total number of steps.
|
||||
|
||||
Args:
|
||||
total_steps (int): The total number of steps.
|
||||
"""
|
||||
self.number_of_steps = total_steps
|
||||
self.overall_progress.update(
|
||||
self.overall_task_id,
|
||||
total=total_steps,
|
||||
description=(
|
||||
f"[bold #AAAAAA]({self.current_step} out of"
|
||||
f" {self.number_of_steps} steps finished)"
|
||||
),
|
||||
)
|
||||
|
||||
def finish_the_current_step(self):
|
||||
"""Finish the current step and update the progress bars."""
|
||||
self.step_progress.stop_task(self.current_step_id)
|
||||
|
||||
@@ -260,3 +260,35 @@ def parse_render_command_override_arguments(
|
||||
key_and_values[key] = value
|
||||
|
||||
return key_and_values
|
||||
|
||||
|
||||
def build_rendercv_settings(
|
||||
dictionary: dict,
|
||||
command_line_arguments: dict[str, str],
|
||||
command_line_arguments_default_values: dict[str, str],
|
||||
) -> dict[str, str]:
|
||||
"""Build the RenderCV settings dictionary by combining the dictionary and the command line arguments.
|
||||
|
||||
Args:
|
||||
dictionary (dict): The dictionary to be combined with the command line
|
||||
arguments.
|
||||
command_line_arguments (dict[str, str]): The command line arguments.
|
||||
|
||||
Returns:
|
||||
dict[str, str]: The combined dictionary.
|
||||
"""
|
||||
# Combine the dictionary and the command line arguments if the values are not None:
|
||||
for key, value in command_line_arguments.items():
|
||||
# check if the key is present in the both command line arguments and the default values:
|
||||
if key in command_line_arguments_default_values:
|
||||
default_value = command_line_arguments_default_values[key]
|
||||
if value != default_value:
|
||||
dictionary = set_or_update_a_value(dictionary, key, str(value))
|
||||
else:
|
||||
# The key is not present in the default values, set the value:
|
||||
# throw an error reporting this
|
||||
raise ValueError(
|
||||
f"The key ({key}) is not present in the default values of the command"
|
||||
" line arguments!"
|
||||
)
|
||||
return dictionary
|
||||
|
||||
@@ -12,6 +12,7 @@ from .base import RenderCVBaseModelWithoutExtraKeys
|
||||
from .curriculum_vitae import CurriculumVitae
|
||||
from .design import RenderCVDesign
|
||||
from .locale_catalog import LocaleCatalog
|
||||
from .rendercv_settings import RenderCVSettings
|
||||
|
||||
|
||||
class RenderCVDataModel(RenderCVBaseModelWithoutExtraKeys):
|
||||
@@ -36,6 +37,11 @@ class RenderCVDataModel(RenderCVBaseModelWithoutExtraKeys):
|
||||
),
|
||||
validate_default=True,
|
||||
)
|
||||
rendercv_settings: RenderCVSettings = pydantic.Field(
|
||||
default=RenderCVSettings(),
|
||||
title="RenderCV Settings",
|
||||
description="The settings of the RenderCV.",
|
||||
)
|
||||
|
||||
@pydantic.field_validator("locale_catalog")
|
||||
@classmethod
|
||||
@@ -46,3 +52,15 @@ class RenderCVDataModel(RenderCVBaseModelWithoutExtraKeys):
|
||||
LocaleCatalog()
|
||||
|
||||
return locale_catalog
|
||||
|
||||
@pydantic.field_validator("rendercv_settings")
|
||||
@classmethod
|
||||
def initialize_rendercv_settings(
|
||||
cls, rendercv_settings: RenderCVSettings
|
||||
) -> RenderCVSettings:
|
||||
"""Even if the rendercv settings are not provided, initialize them with the default
|
||||
values."""
|
||||
if rendercv_settings is None:
|
||||
RenderCVSettings()
|
||||
|
||||
return rendercv_settings
|
||||
|
||||
134
rendercv/data/models/rendercv_settings.py
Normal file
134
rendercv/data/models/rendercv_settings.py
Normal file
@@ -0,0 +1,134 @@
|
||||
"""
|
||||
The `rendercv.models.rendercv_settings` module contains the data model of the
|
||||
`rendercv_settings` field of the input file.
|
||||
"""
|
||||
|
||||
from typing import Optional
|
||||
|
||||
import pydantic
|
||||
|
||||
|
||||
class RenderCVSettings(pydantic.BaseModel):
|
||||
"""This class is the data model of the rendercv settings. The values of each field
|
||||
updates the `rendercv_settings` dictionary.
|
||||
"""
|
||||
|
||||
model_config = pydantic.ConfigDict(
|
||||
extra="forbid",
|
||||
validate_default=True, # To initialize the rendercv settings with the default values
|
||||
)
|
||||
|
||||
output_folder_name: Optional[str] = pydantic.Field(
|
||||
default="rendercv_output",
|
||||
title="Output Folder Name",
|
||||
description=(
|
||||
"The name of the folder where the output files will be saved. The default"
|
||||
' value is "rendercv_output".'
|
||||
),
|
||||
)
|
||||
|
||||
use_local_latex_command: Optional[str] = pydantic.Field(
|
||||
default=None,
|
||||
title="Local LaTeX Command",
|
||||
description=(
|
||||
"The command to compile the LaTeX file to a PDF file. The default value is"
|
||||
' "pdflatex".'
|
||||
),
|
||||
)
|
||||
|
||||
pdf_path: Optional[str] = pydantic.Field(
|
||||
default=None,
|
||||
title="PDF Path",
|
||||
description=(
|
||||
"The path of the PDF file. If it is not provided, the PDF file will not be"
|
||||
" generated. The default value is an empty string."
|
||||
),
|
||||
)
|
||||
|
||||
latex_path: Optional[str] = pydantic.Field(
|
||||
default=None,
|
||||
title="LaTeX Path",
|
||||
description=(
|
||||
"The path of the LaTeX file. If it is not provided, the LaTeX file will not"
|
||||
" be generated. The default value is an empty string."
|
||||
),
|
||||
)
|
||||
|
||||
html_path: Optional[str] = pydantic.Field(
|
||||
default=None,
|
||||
title="HTML Path",
|
||||
description=(
|
||||
"The path of the HTML file. If it is not provided, the HTML file will not"
|
||||
" be generated. The default value is an empty string."
|
||||
),
|
||||
)
|
||||
|
||||
png_path: Optional[str] = pydantic.Field(
|
||||
default=None,
|
||||
title="PNG Path",
|
||||
description=(
|
||||
"The path of the PNG file. If it is not provided, the PNG file will not be"
|
||||
" generated. The default value is an empty string."
|
||||
),
|
||||
)
|
||||
|
||||
markdown_path: Optional[str] = pydantic.Field(
|
||||
default=None,
|
||||
title="Markdown Path",
|
||||
description=(
|
||||
"The path of the Markdown file. If it is not provided, the Markdown file"
|
||||
" will not be generated. The default value is an empty string."
|
||||
),
|
||||
)
|
||||
|
||||
no_html: Optional[bool] = pydantic.Field(
|
||||
default=False,
|
||||
title="Generate HTML Flag",
|
||||
description=(
|
||||
"A boolean value to determine whether the HTML file will be generated. The"
|
||||
" default value is False."
|
||||
),
|
||||
)
|
||||
|
||||
no_markdown: Optional[bool] = pydantic.Field(
|
||||
default=False,
|
||||
title="Generate Markdown Flag",
|
||||
description=(
|
||||
"A boolean value to determine whether the Markdown file will be generated."
|
||||
" The default value is False."
|
||||
),
|
||||
)
|
||||
|
||||
no_png: Optional[bool] = pydantic.Field(
|
||||
default=False,
|
||||
title="Generate PNG Flag",
|
||||
description=(
|
||||
"A boolean value to determine whether the PNG file will be generated. The"
|
||||
" default value is False."
|
||||
),
|
||||
)
|
||||
|
||||
@pydantic.field_validator(
|
||||
"output_folder_name",
|
||||
"pdf_path",
|
||||
"latex_path",
|
||||
"html_path",
|
||||
"png_path",
|
||||
"no_html",
|
||||
"no_markdown",
|
||||
"no_png",
|
||||
)
|
||||
@classmethod
|
||||
def update_settings(
|
||||
cls, value: Optional[str], info: pydantic.ValidationInfo
|
||||
) -> Optional[str]:
|
||||
"""Update the `rendercv_settings` dictionary with the provided values."""
|
||||
if value:
|
||||
rendercv_settings[info.field_name] = value # type: ignore
|
||||
|
||||
return value
|
||||
|
||||
|
||||
# Initialize the rendercv settings with the default values
|
||||
rendercv_settings: dict[str, str] = {}
|
||||
RenderCVSettings() # Initialize the rendercv settings with the default values
|
||||
@@ -12,7 +12,6 @@ import sys
|
||||
from typing import Optional
|
||||
|
||||
import fitz
|
||||
|
||||
import markdown
|
||||
|
||||
from .. import data
|
||||
|
||||
129
schema.json
129
schema.json
@@ -1687,6 +1687,114 @@
|
||||
"title": "PublicationEntry",
|
||||
"type": "object"
|
||||
},
|
||||
"RenderCVSettings": {
|
||||
"additionalProperties": false,
|
||||
"description": "This class is the data model of the rendercv settings. The values of each field\nupdates the `rendercv_settings` dictionary.",
|
||||
"properties": {
|
||||
"output_folder_name": {
|
||||
"default": "rendercv_output",
|
||||
"description": "The name of the folder where the output files will be saved. The default value is \"rendercv_output\".",
|
||||
"title": "Output Folder Name",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"use_local_latex_command": {
|
||||
"default": null,
|
||||
"description": "The command to compile the LaTeX file to a PDF file. The default value is \"pdflatex\".",
|
||||
"title": "Local LaTeX Command",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"pdf_path": {
|
||||
"default": null,
|
||||
"description": "The path of the PDF file. If it is not provided, the PDF file will not be generated. The default value is an empty string.",
|
||||
"title": "PDF Path",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"latex_path": {
|
||||
"default": null,
|
||||
"description": "The path of the LaTeX file. If it is not provided, the LaTeX file will not be generated. The default value is an empty string.",
|
||||
"title": "LaTeX Path",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"html_path": {
|
||||
"default": null,
|
||||
"description": "The path of the HTML file. If it is not provided, the HTML file will not be generated. The default value is an empty string.",
|
||||
"title": "HTML Path",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"png_path": {
|
||||
"default": null,
|
||||
"description": "The path of the PNG file. If it is not provided, the PNG file will not be generated. The default value is an empty string.",
|
||||
"title": "PNG Path",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"markdown_path": {
|
||||
"default": null,
|
||||
"description": "The path of the Markdown file. If it is not provided, the Markdown file will not be generated. The default value is an empty string.",
|
||||
"title": "Markdown Path",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"no_html": {
|
||||
"default": false,
|
||||
"description": "A boolean value to determine whether the HTML file will be generated. The default value is False.",
|
||||
"title": "Generate HTML Flag",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "boolean"
|
||||
}
|
||||
]
|
||||
},
|
||||
"no_markdown": {
|
||||
"default": false,
|
||||
"description": "A boolean value to determine whether the Markdown file will be generated. The default value is False.",
|
||||
"title": "Generate Markdown Flag",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "boolean"
|
||||
}
|
||||
]
|
||||
},
|
||||
"no_png": {
|
||||
"default": false,
|
||||
"description": "A boolean value to determine whether the PNG file will be generated. The default value is False.",
|
||||
"title": "Generate PNG Flag",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "boolean"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"title": "RenderCVSettings",
|
||||
"type": "object"
|
||||
},
|
||||
"Sb2novThemeOptions": {
|
||||
"additionalProperties": false,
|
||||
"description": "This class is the data model of the theme options for the `sb2nov` theme.",
|
||||
@@ -2002,6 +2110,27 @@
|
||||
"default": null,
|
||||
"description": "The locale catalog of the CV to allow the support of multiple languages.",
|
||||
"title": "Locale Catalog"
|
||||
},
|
||||
"rendercv_settings": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/$defs/RenderCVSettings"
|
||||
}
|
||||
],
|
||||
"default": {
|
||||
"output_folder_name": "rendercv_output",
|
||||
"use_local_latex_command": null,
|
||||
"pdf_path": null,
|
||||
"latex_path": null,
|
||||
"html_path": null,
|
||||
"png_path": null,
|
||||
"markdown_path": null,
|
||||
"no_html": false,
|
||||
"no_markdown": false,
|
||||
"no_png": false
|
||||
},
|
||||
"description": "The settings of the RenderCV.",
|
||||
"title": "RenderCV Settings"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
||||
Reference in New Issue
Block a user