diff --git a/rendercv/data_models.py b/rendercv/data_models.py index 4b63b32..f45a687 100644 --- a/rendercv/data_models.py +++ b/rendercv/data_models.py @@ -26,7 +26,6 @@ import pydantic import pydantic_extra_types.phone_numbers as pydantic_phone_numbers import strictyaml -from . import utilities from .terminal_reporter import warning from .themes.classic import ClassicThemeOptions from .terminal_reporter import time_the_event_below @@ -72,6 +71,51 @@ def get_date_object(date: str | int) -> Date: return date_object +def format_date(date: Date) -> str: + """Formats a `Date` object to a string in the following format: "Jan. 2021". + + It uses month abbreviations, taken from + [Yale University Library](https://web.library.yale.edu/cataloging/months). + + Example: + ```python + format_date(Date(2024, 5, 1)) + ``` + will return + + `#!python "May 2024"` + + Args: + date (Date): The date to format. + + Returns: + str: The formatted date. + """ + # Month abbreviations, + # taken from: https://web.library.yale.edu/cataloging/months + abbreviations_of_months = [ + "Jan.", + "Feb.", + "Mar.", + "Apr.", + "May", + "June", + "July", + "Aug.", + "Sept.", + "Oct.", + "Nov.", + "Dec.", + ] + + month = int(date.strftime("%m")) + month_abbreviation = abbreviations_of_months[month - 1] + year = date.strftime(format="%Y") + date_string = f"{month_abbreviation} {year}" + + return date_string + + class RenderCVBaseModel(pydantic.BaseModel): """This class is the parent class of all the data models in RenderCV. It has only one difference from the default `pydantic.BaseModel`: It raises an error if an @@ -223,7 +267,7 @@ class EntryBase(RenderCVBaseModel): if self.date is not None: try: date_object = get_date_object(self.date) - date_string = utilities.format_date(date_object) + date_string = format_date(date_object) except ValueError: # Then it is a custom date string (e.g., "My Custom Date") date_string = str(self.date) @@ -235,7 +279,7 @@ class EntryBase(RenderCVBaseModel): else: # Then it means start_date is either in YYYY-MM-DD or YYYY-MM format date_object = get_date_object(self.start_date) - start_date = utilities.format_date(date_object) + start_date = format_date(date_object) if self.end_date == "present": end_date = "present" @@ -245,7 +289,7 @@ class EntryBase(RenderCVBaseModel): else: # Then it means end_date is either in YYYY-MM-DD or YYYY-MM format date_object = get_date_object(self.end_date) - end_date = utilities.format_date(date_object) + end_date = format_date(date_object) date_string = f"{start_date} to {end_date}" @@ -480,7 +524,7 @@ class PublicationEntry(RenderCVBaseModel): date_string = str(self.date) elif isinstance(self.date, str): date_object = get_date_object(self.date) - date_string = utilities.format_date(date_object) + date_string = format_date(date_object) else: date_string = "" diff --git a/rendercv/utilities.py b/rendercv/utilities.py deleted file mode 100644 index 6652f49..0000000 --- a/rendercv/utilities.py +++ /dev/null @@ -1,133 +0,0 @@ -import re -from datetime import date as Date -import time -import os - -from ruamel.yaml import YAML - -from .terminal_reporter import warning, error, information - - -def escape_latex_characters(sentence: str) -> str: - """Escape some of the speacial LaTeX characters (e.g. #, %, &, ~) in a string. - - Example: - ```python - escape_latex_characters("This is a # sentence.") - ``` - will return: - `#!python "This is a \\# sentence."` - """ - - # Dictionary of escape characters: - escape_characters = { - "#": r"\#", - # "$": r"\$", # Don't escape $ as it is used for math mode - "%": r"\%", - "&": r"\&", - "~": r"\textasciitilde{}", - # "_": r"\_", # Don't escape _ as it is used for math mode - # "^": r"\textasciicircum{}", # Don't escape ^ as it is used for math mode - } - - # Don't escape links as hyperref will do it automatically: - - # Find all the links in the sentence: - links = re.findall(r"\[.*?\]\(.*?\)", sentence) - - # Replace the links with a placeholder: - for link in links: - sentence = sentence.replace(link, "!!-link-!!") - - # Handle backslash and curly braces separately because the other characters are - # escaped with backslash and curly braces: - # --don't escape curly braces as they are used heavily in LaTeX--: - # sentence = sentence.replace("{", ">>{") - # sentence = sentence.replace("}", ">>}") - # --don't escape backslash as it is used heavily in LaTeX--: - # sentence = sentence.replace("\\", "\\textbackslash{}") - # sentence = sentence.replace(">>{", "\\{") - # sentence = sentence.replace(">>}", "\\}") - - # Loop through the letters of the sentence and if you find an escape character, - # replace it with its LaTeX equivalent: - copy_of_the_sentence = sentence - for character in copy_of_the_sentence: - if character in escape_characters: - sentence = sentence.replace(character, escape_characters[character]) - - # Replace the links with the original links: - for link in links: - sentence = sentence.replace("!!-link-!!", link) - - return sentence - - -def parse_date_string(date_string: str) -> Date: - """Parse a date string in YYYY-MM-DD, YYYY-MM, or YYYY format and return a - datetime.date object. - - Args: - date_string (str): The date string to parse. - Returns: - datetime.date: The parsed date. - """ - if re.match(r"\d{4}-\d{2}-\d{2}", date_string): - # Then it is in YYYY-MM-DD format - date = Date.fromisoformat(date_string) - elif re.match(r"\d{4}-\d{2}", date_string): - # Then it is in YYYY-MM format - # Assign a random day since days are not rendered in the CV - date = Date.fromisoformat(f"{date_string}-01") - else: - raise ValueError( - f'The date string "{date_string}" is not in YYYY-MM-DD, YYYY-MM, or YYYY' - " format." - ) - - return date - - -def format_date(date: Date) -> str: - """Formats a `Date` object to a string in the following format: "Jan. 2021". - - It uses month abbreviations, taken from - [Yale University Library](https://web.library.yale.edu/cataloging/months). - - Example: - ```python - format_date(Date(2024, 5, 1)) - ``` - will return - - `#!python "May 2024"` - - Args: - date (Date): The date to format. - - Returns: - str: The formatted date. - """ - # Month abbreviations, - # taken from: https://web.library.yale.edu/cataloging/months - abbreviations_of_months = [ - "Jan.", - "Feb.", - "Mar.", - "Apr.", - "May", - "June", - "July", - "Aug.", - "Sept.", - "Oct.", - "Nov.", - "Dec.", - ] - - month = int(date.strftime("%m")) - month_abbreviation = abbreviations_of_months[month - 1] - year = date.strftime(format="%Y") - date_string = f"{month_abbreviation} {year}" - - return date_string