add Publications section

This commit is contained in:
Sina Atalay 2023-09-18 20:22:44 +02:00
parent cdcd418301
commit 920cf379cf
5 changed files with 129 additions and 17 deletions

View File

@ -492,12 +492,6 @@ class Event(BaseModel):
)
model.end_date = "present"
elif not start_date_is_provided and not date_is_provided:
raise ValueError(
'Either "date" or "start_date" and "end_date" should be provided in'
" each entry."
)
return model
@computed_field
@ -678,6 +672,50 @@ class EducationEntry(Event):
return highlight_strings
class PublicationEntry(Event):
"""This class stores [PublicationEntry](../index.md#publicationentry) information."""
title: str = Field(
title="Title of the Publication",
description="The title of the publication. It will be shown as bold text.",
examples=["My Awesome Paper", "My Awesome Book"],
)
authors: list[str] = Field(
title="Authors",
description="The authors of the publication in order as a list of strings.",
examples=["John Doe", "Jane Doe"],
)
journal: str = Field(
title="Journal",
description="The journal or the conference name.",
examples=[
"Physical Review B",
"ASME International Mechanical Engineering Congress and Exposition",
],
)
doi: str = Field(
title="DOI",
description="The DOI of the publication.",
examples=["10.1103/PhysRevB.76.054309"],
)
date: str = Field(
title="Publication Date",
description="The date of the publication.",
examples=[2021, 2022],
)
cited_by: Optional[int] = Field(
default=None,
title="Cited By",
description="The number of citations of the publication.",
examples=[10, 100],
)
@computed_field
@cached_property
def doi_url(self) -> str:
return f"https://doi.org/{self.doi}"
class SocialNetwork(BaseModel):
"""This class stores a social network information.
@ -719,10 +757,14 @@ class Connection(BaseModel):
elif self.name == "email":
url = f"mailto:{self.value}"
elif self.name == "website":
url = self.value
url = f"{self.value}"
elif self.name == "phone":
url = f"{self.value}"
else:
raise RuntimeError(f'"{self.name}" is not a valid connection!"')
return url
class Section(BaseModel):
"""This class stores a section information."""
@ -733,15 +775,14 @@ class Section(BaseModel):
examples=["Awards", "My Custom Section", "Languages"],
)
entry_type: Literal[
"OneLineEntry", "NormalEntry", "ExperienceEntry", "EducationEntry"
"OneLineEntry",
"NormalEntry",
"ExperienceEntry",
"EducationEntry",
"PublicationEntry",
] = Field(
title="Entry Type",
description=(
"The type of the entries in the section. Classic theme supports"
" four types of entries: OneLineEntry, NormalEntry, ExperienceEntry, and"
" EducationEntry."
),
examples=["OneLineEntry", "NormalEntry", "ExperienceEntry", "EducationEntry"],
description="The type of the entries in the section.",
)
link_text: Optional[str] = Field(
default=None,
@ -753,7 +794,7 @@ class Section(BaseModel):
),
examples=["view on GitHub", "view on LinkedIn"],
)
entries: list[NormalEntry | OneLineEntry | ExperienceEntry | EducationEntry] = (
entries: list[NormalEntry | OneLineEntry | ExperienceEntry | EducationEntry | PublicationEntry] = (
Field(
title="Entries",
description=(
@ -827,6 +868,11 @@ class CurriculumVitae(BaseModel):
title="Personal Projects",
description="The personal project entries of the person.",
)
publications: Optional[list[PublicationEntry]] = Field(
default=None,
title="Publications",
description="The publication entries of the person.",
)
certificates: Optional[list[NormalEntry]] = Field(
default=None,
title="Certificates",
@ -890,6 +936,7 @@ class CurriculumVitae(BaseModel):
"Extracurricular Activities": self.extracurricular_activities,
"Test Scores": self.test_scores,
"Skills": self.skills,
"Publications": self.publications,
}
if self.section_order is None:
@ -903,6 +950,7 @@ class CurriculumVitae(BaseModel):
"Test Scores",
"Certificates",
"Extracurricular Activities",
"Publications"
]
if self.custom_sections is not None:
# If the user specified custom sections, then add them to the end of the

View File

@ -16,6 +16,8 @@ import rendercv.templates
def markdown_to_latex(markdown_string: str) -> str:
"""Convert a markdown string to LaTeX.
This function is used as a Jinja2 filter.
Example:
```python
markdown_to_latex("This is a **bold** text with an [*italic link*](https://google.com).")
@ -72,6 +74,8 @@ def markdown_to_latex(markdown_string: str) -> str:
def markdown_url_to_url(value: str) -> bool:
"""Convert a markdown link to a normal string URL.
This function is used as a Jinja2 filter.
Example:
```python
markdown_url_to_url("[Google](https://google.com)")
@ -98,6 +102,37 @@ def markdown_url_to_url(value: str) -> bool:
raise ValueError("markdown_url_to_url should only be used on markdown links!")
def make_it_bold(value: str, match_str: str) -> str:
"""Make the matched parts of the string bold.
This function is used as a Jinja2 filter.
Example:
```python
make_it_bold_if("Hello World!", "Hello")
```
will return:
`#!python "\\textbf{Hello} World!"`
Args:
value (str): The string to make bold.
match_str (str): The string to match.
"""
if not isinstance(value, str):
raise ValueError("make_it_bold_if should only be used on strings!")
if not isinstance(match_str, str):
raise ValueError("The string to match should be a string!")
if match_str in value:
value.replace(match_str, "\\textbf{" + match_str + "}")
return value
else:
return value
def render_template(data):
"""Render the template using the given data.
@ -134,6 +169,7 @@ def render_template(data):
# add custom filters:
environment.filters["markdown_to_latex"] = markdown_to_latex
environment.filters["markdown_url_to_url"] = markdown_url_to_url
environment.filters["make_it_bold"] = make_it_bold
output_latex_file = template.render(design=data.design.options, cv=data.cv)

View File

@ -55,6 +55,25 @@
\end{tabularx}
((* endmacro *))
((* macro publication(title, authors, journal, year, doi, doi_url)*))
((# \begin{tabularx}{⟨width⟩}[⟨pos⟩]{⟨preamble⟩} #))
((# width: \textwidth #))
((# preamble: first column, second column #))
((# first column:: K{<<design.margins.entry_area.left>>}; variable width, ragged left column #))
((# second column: R{<<design.date_and_location_width>>}; constant width ragged right column #))
\begin{tabularx}{\textwidth}{K{<<design.margins.entry_area.left>>} R{2 cm}}
\textbf{<<title>>}
<<authors|join(", ")|make_it_bold("Cetin Yilmaz")>>
DOI: \hrefExternal{<<doi_url>>}{<<doi>>}
<<journal>>
&
<<year>>
\end{tabularx}
((* endmacro *))
((* macro one_line(name, details, markdown_url=none, link_text=none)*))
\setlength{\leftskip}{0.2cm}

View File

@ -2,7 +2,7 @@
((* macro LinkedIn(username, url) *))\href{<<url>>}{{\small\faLinkedinIn}\hspace{0.13cm}<<username>>}((* endmacro *))
((* macro GitHub(username, url) *))\href{<<url>>}{{\small\faGithub}\hspace{0.13cm}<<username>>}((* endmacro *))
((* macro Instagram(username, url) *))\href{}{{\small\faInstagram}\hspace{0.13cm}<<username>>}((* endmacro *))
((* macro phone(number, url) *)){\footnotesize\faPhone*}\hspace{0.13cm}<<number|replace("tel:", "")|replace("-"," ")>>((* endmacro *))
((* macro phone(number, url) *))\href{<<url>>}{{\footnotesize\faPhone*}\hspace{0.13cm}<<number|replace("tel:", "")|replace("-"," ")>>}((* endmacro *))
((* macro email(email, url) *))\href{<<url>>}{{\small\faEnvelope[regular]}\hspace{0.13cm}<<email>>}((* endmacro *))
((* macro website(url, dummy) *))\href{<<url>>}{{\small\faLink}\hspace{0.13cm}<<url|replace("https://","")|replace("/","")>>}((* endmacro *))

View File

@ -36,6 +36,15 @@
details=value.details,
markdown_url=value.markdown_url,
link_text=link_text,
)|indent(4)>>
((* elif entry_type == "PublicationEntry" *))
<<entry["publication"](
title=value.title,
authors=value.authors,
journal=value.journal,
year=value.date,
doi=value.doi,
doi_url=value.doi_url,
)|indent(4)>>
((* endif *))
((* if not loop.last *))