@app.command(
name="render",
help=(
"Render a YAML input file. Example: [yellow]rendercv render"
" John_Doe_CV.yaml[/yellow]. Details: [cyan]rendercv render --help[/cyan]"
),
# allow extra arguments for updating the data model (for overriding the values of
# the input file):
context_settings={"allow_extra_args": True, "ignore_unknown_options": True},
)
@printer.handle_and_print_raised_exceptions
def cli_command_render(
input_file_name: Annotated[
str, typer.Argument(help="Name of the YAML input file.")
],
use_local_latex_command: Annotated[
Optional[str],
typer.Option(
"--use-local-latex-command",
"-use",
help=(
"Use the local LaTeX installation with the given command instead of the"
" RenderCV's TinyTeX."
),
),
] = None,
output_folder_name: Annotated[
str,
typer.Option(
"--output-folder-name",
"-o",
help="Name of the output folder.",
),
] = "rendercv_output",
latex_path: Annotated[
Optional[str],
typer.Option(
"--latex-path",
"-latex",
help="Copy the LaTeX file to the given path.",
),
] = None,
pdf_path: Annotated[
Optional[str],
typer.Option(
"--pdf-path",
"-pdf",
help="Copy the PDF file to the given path.",
),
] = None,
markdown_path: Annotated[
Optional[str],
typer.Option(
"--markdown-path",
"-md",
help="Copy the Markdown file to the given path.",
),
] = None,
html_path: Annotated[
Optional[str],
typer.Option(
"--html-path",
"-html",
help="Copy the HTML file to the given path.",
),
] = None,
png_path: Annotated[
Optional[str],
typer.Option(
"--png-path",
"-png",
help="Copy the PNG file to the given path.",
),
] = None,
dont_generate_markdown: Annotated[
bool,
typer.Option(
"--dont-generate-markdown",
"-nomd",
help="Don't generate the Markdown and HTML file.",
),
] = False,
dont_generate_html: Annotated[
bool,
typer.Option(
"--dont-generate-html",
"-nohtml",
help="Don't generate the HTML file.",
),
] = False,
dont_generate_png: Annotated[
bool,
typer.Option(
"--dont-generate-png",
"-nopng",
help="Don't generate the PNG file.",
),
] = False,
# This is a dummy argument for the help message for
# extra_data_model_override_argumets:
_: Annotated[
Optional[str],
typer.Option(
"--YAMLLOCATION",
help="Overrides the value of YAMLLOCATION. For example,"
' [cyan bold]--cv.phone "123-456-7890"[/cyan bold].',
),
] = None,
extra_data_model_override_argumets: typer.Context = None, # type: ignore
):
"""Render a CV from a YAML input file."""
printer.welcome()
input_file_path: pathlib.Path = pathlib.Path(input_file_name).absolute()
original_working_directory = pathlib.Path.cwd()
input_file_as_a_dict = data.read_a_yaml_file(input_file_path)
# Update the input file if there are extra override arguments (for example,
# --cv.phone "123-456-7890"):
if extra_data_model_override_argumets:
key_and_values = utilities.parse_render_command_override_arguments(
extra_data_model_override_argumets
)
input_file_as_a_dict = utilities.set_or_update_values(
input_file_as_a_dict, key_and_values
)
# If non-default CLI arguments are provided, override the `rendercv_settings.render_command`:
cli_render_arguments = {
"use_local_latex_command": use_local_latex_command,
"output_folder_name": output_folder_name,
"latex_path": latex_path,
"pdf_path": pdf_path,
"markdown_path": markdown_path,
"html_path": html_path,
"png_path": png_path,
"dont_generate_png": dont_generate_png,
"dont_generate_markdown": dont_generate_markdown,
"dont_generate_html": dont_generate_html,
}
input_file_as_a_dict = utilities.update_render_command_settings_of_the_input_file(
input_file_as_a_dict, cli_render_arguments
)
render_command_settings_dict = input_file_as_a_dict["rendercv_settings"][
"render_command"
]
# Compute the number of steps
# 1. Validate the input file.
# 2. Create the LaTeX file.
# 3. Render PDF from LaTeX.
# 4. Render PNGs from PDF.
# 5. Create the Markdown file.
# 6. Render HTML from Markdown.
number_of_steps = 6
if render_command_settings_dict["dont_generate_png"]:
number_of_steps -= 1
if render_command_settings_dict["dont_generate_markdown"]:
number_of_steps -= 2
else:
if render_command_settings_dict["dont_generate_html"]:
number_of_steps -= 1
with printer.LiveProgressReporter(number_of_steps=number_of_steps) as progress:
progress.start_a_step("Validating the input file")
data_model = data.validate_input_dictionary_and_return_the_data_model(
input_file_as_a_dict
)
render_command_settings: data.models.RenderCommandSettings = (
data_model.rendercv_settings.render_command # type: ignore
) # type: ignore
output_directory = (
original_working_directory / render_command_settings.output_folder_name # type: ignore
)
progress.finish_the_current_step()
# Change the current working directory to the input file's directory (because
# the template overrides are looked up in the current working directory). The
# output files will be in the original working directory.
os.chdir(input_file_path.parent)
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 render_command_settings.latex_path:
utilities.copy_files(
latex_file_path_in_output_folder,
render_command_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,
render_command_settings.use_local_latex_command,
)
if render_command_settings.pdf_path:
utilities.copy_files(
pdf_file_path_in_output_folder,
render_command_settings.pdf_path,
)
progress.finish_the_current_step()
if not render_command_settings.dont_generate_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 render_command_settings.png_path:
utilities.copy_files(
png_file_paths_in_output_folder,
render_command_settings.png_path,
)
progress.finish_the_current_step()
if not render_command_settings.dont_generate_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 render_command_settings.markdown_path:
utilities.copy_files(
markdown_file_path_in_output_folder,
render_command_settings.markdown_path,
)
progress.finish_the_current_step()
if not render_command_settings.dont_generate_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 render_command_settings.html_path:
utilities.copy_files(
html_file_path_in_output_folder,
render_command_settings.html_path,
)
progress.finish_the_current_step()