mirror of https://github.com/eyhc1/rendercv.git
add Publications section
This commit is contained in:
parent
cdcd418301
commit
920cf379cf
|
@ -492,12 +492,6 @@ class Event(BaseModel):
|
||||||
)
|
)
|
||||||
model.end_date = "present"
|
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
|
return model
|
||||||
|
|
||||||
@computed_field
|
@computed_field
|
||||||
|
@ -678,6 +672,50 @@ class EducationEntry(Event):
|
||||||
return highlight_strings
|
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):
|
class SocialNetwork(BaseModel):
|
||||||
"""This class stores a social network information.
|
"""This class stores a social network information.
|
||||||
|
|
||||||
|
@ -719,10 +757,14 @@ class Connection(BaseModel):
|
||||||
elif self.name == "email":
|
elif self.name == "email":
|
||||||
url = f"mailto:{self.value}"
|
url = f"mailto:{self.value}"
|
||||||
elif self.name == "website":
|
elif self.name == "website":
|
||||||
url = self.value
|
url = f"{self.value}"
|
||||||
|
elif self.name == "phone":
|
||||||
|
url = f"{self.value}"
|
||||||
else:
|
else:
|
||||||
raise RuntimeError(f'"{self.name}" is not a valid connection!"')
|
raise RuntimeError(f'"{self.name}" is not a valid connection!"')
|
||||||
|
|
||||||
|
return url
|
||||||
|
|
||||||
|
|
||||||
class Section(BaseModel):
|
class Section(BaseModel):
|
||||||
"""This class stores a section information."""
|
"""This class stores a section information."""
|
||||||
|
@ -733,15 +775,14 @@ class Section(BaseModel):
|
||||||
examples=["Awards", "My Custom Section", "Languages"],
|
examples=["Awards", "My Custom Section", "Languages"],
|
||||||
)
|
)
|
||||||
entry_type: Literal[
|
entry_type: Literal[
|
||||||
"OneLineEntry", "NormalEntry", "ExperienceEntry", "EducationEntry"
|
"OneLineEntry",
|
||||||
|
"NormalEntry",
|
||||||
|
"ExperienceEntry",
|
||||||
|
"EducationEntry",
|
||||||
|
"PublicationEntry",
|
||||||
] = Field(
|
] = Field(
|
||||||
title="Entry Type",
|
title="Entry Type",
|
||||||
description=(
|
description="The type of the entries in the section.",
|
||||||
"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"],
|
|
||||||
)
|
)
|
||||||
link_text: Optional[str] = Field(
|
link_text: Optional[str] = Field(
|
||||||
default=None,
|
default=None,
|
||||||
|
@ -753,7 +794,7 @@ class Section(BaseModel):
|
||||||
),
|
),
|
||||||
examples=["view on GitHub", "view on LinkedIn"],
|
examples=["view on GitHub", "view on LinkedIn"],
|
||||||
)
|
)
|
||||||
entries: list[NormalEntry | OneLineEntry | ExperienceEntry | EducationEntry] = (
|
entries: list[NormalEntry | OneLineEntry | ExperienceEntry | EducationEntry | PublicationEntry] = (
|
||||||
Field(
|
Field(
|
||||||
title="Entries",
|
title="Entries",
|
||||||
description=(
|
description=(
|
||||||
|
@ -827,6 +868,11 @@ class CurriculumVitae(BaseModel):
|
||||||
title="Personal Projects",
|
title="Personal Projects",
|
||||||
description="The personal project entries of the person.",
|
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(
|
certificates: Optional[list[NormalEntry]] = Field(
|
||||||
default=None,
|
default=None,
|
||||||
title="Certificates",
|
title="Certificates",
|
||||||
|
@ -890,6 +936,7 @@ class CurriculumVitae(BaseModel):
|
||||||
"Extracurricular Activities": self.extracurricular_activities,
|
"Extracurricular Activities": self.extracurricular_activities,
|
||||||
"Test Scores": self.test_scores,
|
"Test Scores": self.test_scores,
|
||||||
"Skills": self.skills,
|
"Skills": self.skills,
|
||||||
|
"Publications": self.publications,
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.section_order is None:
|
if self.section_order is None:
|
||||||
|
@ -903,6 +950,7 @@ class CurriculumVitae(BaseModel):
|
||||||
"Test Scores",
|
"Test Scores",
|
||||||
"Certificates",
|
"Certificates",
|
||||||
"Extracurricular Activities",
|
"Extracurricular Activities",
|
||||||
|
"Publications"
|
||||||
]
|
]
|
||||||
if self.custom_sections is not None:
|
if self.custom_sections is not None:
|
||||||
# If the user specified custom sections, then add them to the end of the
|
# If the user specified custom sections, then add them to the end of the
|
||||||
|
|
|
@ -16,6 +16,8 @@ import rendercv.templates
|
||||||
def markdown_to_latex(markdown_string: str) -> str:
|
def markdown_to_latex(markdown_string: str) -> str:
|
||||||
"""Convert a markdown string to LaTeX.
|
"""Convert a markdown string to LaTeX.
|
||||||
|
|
||||||
|
This function is used as a Jinja2 filter.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
```python
|
```python
|
||||||
markdown_to_latex("This is a **bold** text with an [*italic link*](https://google.com).")
|
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:
|
def markdown_url_to_url(value: str) -> bool:
|
||||||
"""Convert a markdown link to a normal string URL.
|
"""Convert a markdown link to a normal string URL.
|
||||||
|
|
||||||
|
This function is used as a Jinja2 filter.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
```python
|
```python
|
||||||
markdown_url_to_url("[Google](https://google.com)")
|
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!")
|
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):
|
def render_template(data):
|
||||||
"""Render the template using the given data.
|
"""Render the template using the given data.
|
||||||
|
|
||||||
|
@ -134,6 +169,7 @@ def render_template(data):
|
||||||
# add custom filters:
|
# add custom filters:
|
||||||
environment.filters["markdown_to_latex"] = markdown_to_latex
|
environment.filters["markdown_to_latex"] = markdown_to_latex
|
||||||
environment.filters["markdown_url_to_url"] = markdown_url_to_url
|
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)
|
output_latex_file = template.render(design=data.design.options, cv=data.cv)
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,25 @@
|
||||||
\end{tabularx}
|
\end{tabularx}
|
||||||
((* endmacro *))
|
((* 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)*))
|
((* macro one_line(name, details, markdown_url=none, link_text=none)*))
|
||||||
\setlength{\leftskip}{0.2cm}
|
\setlength{\leftskip}{0.2cm}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
((* macro LinkedIn(username, url) *))\href{<<url>>}{{\small\faLinkedinIn}\hspace{0.13cm}<<username>>}((* endmacro *))
|
((* 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 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 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 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 *))
|
((* macro website(url, dummy) *))\href{<<url>>}{{\small\faLink}\hspace{0.13cm}<<url|replace("https://","")|replace("/","")>>}((* endmacro *))
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,15 @@
|
||||||
details=value.details,
|
details=value.details,
|
||||||
markdown_url=value.markdown_url,
|
markdown_url=value.markdown_url,
|
||||||
link_text=link_text,
|
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)>>
|
)|indent(4)>>
|
||||||
((* endif *))
|
((* endif *))
|
||||||
((* if not loop.last *))
|
((* if not loop.last *))
|
||||||
|
|
Loading…
Reference in New Issue