Coverage for rendercv/themes/common_options.py: 100%
48 statements
« prev ^ index » next coverage.py v7.6.1, created at 2024-10-07 17:51 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2024-10-07 17:51 +0000
1"""
2The `rendercv.themes.common_options` module contains the standard data models for the
3design options. To avoid code duplication, the themes are encouraged to inherit from
4these data models.
5"""
7from typing import Annotated, Literal
9import pydantic
10import pydantic_extra_types.color as pydantic_color
12from ..data.models.base import RenderCVBaseModelWithoutExtraKeys
14# Create a custom type called LaTeXDimension that accepts only strings in a specified
15# format.
16# This type is used to validate the dimension fields in the design data.
17# See https://docs.pydantic.dev/2.5/concepts/types/#custom-types for more information
18# about custom types.
19LaTeXDimension = Annotated[
20 str,
21 pydantic.Field(
22 pattern=r"\d+\.?\d* *(cm|in|pt|mm|ex|em)",
23 ),
24]
27class PageMargins(RenderCVBaseModelWithoutExtraKeys):
28 """This class is a data model for the page margins."""
30 top: LaTeXDimension = pydantic.Field(
31 default="2 cm",
32 title="Top Margin",
33 description="The top margin of the page with units. The default value is 2 cm.",
34 )
35 bottom: LaTeXDimension = pydantic.Field(
36 default="2 cm",
37 title="Bottom Margin",
38 description=(
39 "The bottom margin of the page with units. The default value is 2 cm."
40 ),
41 )
42 left: LaTeXDimension = pydantic.Field(
43 default="2 cm",
44 title="Left Margin",
45 description=(
46 "The left margin of the page with units. The default value is 2 cm."
47 ),
48 )
49 right: LaTeXDimension = pydantic.Field(
50 default="2 cm",
51 title="Right Margin",
52 description=(
53 "The right margin of the page with units. The default value is 2 cm."
54 ),
55 )
58class SectionTitleMargins(RenderCVBaseModelWithoutExtraKeys):
59 """This class is a data model for the section title margins."""
61 top: LaTeXDimension = pydantic.Field(
62 default="0.3 cm",
63 title="Top Margin",
64 description="The top margin of section titles. The default value is 0.3 cm.",
65 )
66 bottom: LaTeXDimension = pydantic.Field(
67 default="0.2 cm",
68 title="Bottom Margin",
69 description="The bottom margin of section titles. The default value is 0.3 cm.",
70 )
73class EntryAreaMargins(RenderCVBaseModelWithoutExtraKeys):
74 """This class is a data model for the entry area margins."""
76 left_and_right: LaTeXDimension = pydantic.Field(
77 default="0.2 cm",
78 title="Left Margin",
79 description="The left margin of entry areas. The default value is 0.2 cm.",
80 )
82 vertical_between: LaTeXDimension = pydantic.Field(
83 default="0.2 cm",
84 title="Vertical Margin Between Entry Areas",
85 description=(
86 "The vertical margin between entry areas. The default value is 0.2 cm."
87 ),
88 )
90 date_and_location_width: LaTeXDimension = pydantic.Field(
91 default="4.5 cm",
92 title="Date and Location Column Width",
93 description=(
94 "The width of the date and location column. The default value is 4.5 cm."
95 ),
96 )
99class HighlightsAreaMargins(RenderCVBaseModelWithoutExtraKeys):
100 """This class is a data model for the highlights area margins."""
102 top: LaTeXDimension = pydantic.Field(
103 default="0.10 cm",
104 title="Top Margin",
105 description="The top margin of highlights areas. The default value is 0.10 cm.",
106 )
107 left: LaTeXDimension = pydantic.Field(
108 default="0.4 cm",
109 title="Left Margin",
110 description="The left margin of highlights areas. The default value is 0.4 cm.",
111 )
112 vertical_between_bullet_points: LaTeXDimension = pydantic.Field(
113 default="0.10 cm",
114 title="Vertical Margin Between Bullet Points",
115 description=(
116 "The vertical margin between bullet points. The default value is 0.10 cm."
117 ),
118 )
121class HeaderMargins(RenderCVBaseModelWithoutExtraKeys):
122 """This class is a data model for the header margins."""
124 vertical_between_name_and_connections: LaTeXDimension = pydantic.Field(
125 default="0.3 cm",
126 title="Vertical Margin Between the Name and Connections",
127 description=(
128 "The vertical margin between the name of the person and the connections."
129 " The default value is 0.3 cm."
130 ),
131 )
132 bottom: LaTeXDimension = pydantic.Field(
133 default="0.3 cm",
134 title="Bottom Margin",
135 description=(
136 "The bottom margin of the header, i.e., the vertical margin between the"
137 " connections and the first section title. The default value is 0.3 cm."
138 ),
139 )
140 horizontal_between_connections: LaTeXDimension = pydantic.Field(
141 default="0.5 cm",
142 title="Space Between Connections",
143 description=(
144 "The space between the connections (like phone, email, and website). The"
145 " default value is 0.5 cm."
146 ),
147 )
150class Margins(RenderCVBaseModelWithoutExtraKeys):
151 """This class is a data model for the margins."""
153 page: PageMargins = pydantic.Field(
154 default=PageMargins(),
155 title="Page Margins",
156 description="Page margins.",
157 )
158 section_title: SectionTitleMargins = pydantic.Field(
159 default=SectionTitleMargins(),
160 title="Section Title Margins",
161 description="Section title margins.",
162 )
163 entry_area: EntryAreaMargins = pydantic.Field(
164 default=EntryAreaMargins(),
165 title="Entry Area Margins",
166 description="Entry area margins.",
167 )
168 highlights_area: HighlightsAreaMargins = pydantic.Field(
169 default=HighlightsAreaMargins(),
170 title="Highlights Area Margins",
171 description="Highlights area margins.",
172 )
173 header: HeaderMargins = pydantic.Field(
174 default=HeaderMargins(),
175 title="Header Margins",
176 description="Header margins.",
177 )
180class ThemeOptions(RenderCVBaseModelWithoutExtraKeys):
181 """This class is a generic data model for the theme options. The themes are
182 encouraged to inherit from this data model and add their own options, to avoid code
183 duplication.
184 """
186 model_config = pydantic.ConfigDict(extra="forbid")
188 theme: Literal["tobeoverwritten"]
190 font: Literal[
191 "Latin Modern Serif",
192 "Latin Modern Sans Serif",
193 "Latin Modern Mono",
194 "Source Sans 3",
195 "Charter",
196 ] = pydantic.Field(
197 default="Latin Modern Serif",
198 title="Font",
199 description=(
200 "The font family of the CV. The default value is Latin Modern Serif."
201 ),
202 )
203 font_size: Literal["10pt", "11pt", "12pt"] = pydantic.Field(
204 default="10pt",
205 title="Font Size",
206 description="The font size of the CV. The default value is 10pt.",
207 )
208 page_size: Literal["a4paper", "letterpaper"] = pydantic.Field(
209 default="letterpaper",
210 title="Page Size",
211 description=(
212 "The page size of the CV. It can be a4paper or letterpaper. The default"
213 " value is letterpaper."
214 ),
215 )
216 color: pydantic_color.Color = pydantic.Field(
217 default="rgb(0,79,144)",
218 validate_default=True,
219 title="Primary Color",
220 description=(
221 "The primary color of the theme. \nThe color can be specified either with"
222 " their name (https://www.w3.org/TR/SVG11/types.html#ColorKeywords),"
223 " hexadecimal value, RGB value, or HSL value. The default value is"
224 " rgb(0,79,144)."
225 ),
226 examples=["Black", "7fffd4", "rgb(0,79,144)", "hsl(270, 60%, 70%)"],
227 )
228 disable_external_link_icons: bool = pydantic.Field(
229 default=False,
230 title="Disable External Link Icons",
231 description=(
232 "If this option is set to true, then the external link icons will not be"
233 " shown next to the links. The default value is false."
234 ),
235 )
236 disable_page_numbering: bool = pydantic.Field(
237 default=False,
238 title="Disable Page Numbering",
239 description=(
240 "If this option is set to true, then the page numbering will not be shown."
241 " The default value is false."
242 ),
243 )
244 page_numbering_style: str = pydantic.Field(
245 default="NAME - Page PAGE_NUMBER of TOTAL_PAGES",
246 title="Page Numbering Style",
247 description=(
248 "The style of the page numbering. The following placeholders can be"
249 " used:\n- NAME: The name of the person\n- PAGE_NUMBER: The current page"
250 " number\n- TOTAL_PAGES: The total number of pages\n- TODAY: Today's month"
251 " and year (April 2024)\nThe default value is NAME - Page PAGE_NUMBER of"
252 " TOTAL_PAGES."
253 ),
254 )
255 disable_last_updated_date: bool = pydantic.Field(
256 default=False,
257 title="Disable Last Updated Date",
258 description=(
259 "If this option is set to true, then the last updated date will not be"
260 " shown in the header. The default value is false."
261 ),
262 )
263 last_updated_date_style: str = pydantic.Field(
264 default="Last updated in TODAY",
265 title="Last Updated Date Style",
266 description=(
267 "The style of the last updated date. The following placeholders can be"
268 " used:\n- TODAY: Today's month and year (April 2024)\nThe default value is"
269 " Last updated in TODAY."
270 ),
271 )
272 header_font_size: LaTeXDimension = pydantic.Field(
273 default="30 pt",
274 title="Header Font Size",
275 description=(
276 "The font size of the header (the name of the person). The default value is"
277 " 30 pt."
278 ),
279 )
280 text_alignment: Literal[
281 "left-aligned", "justified", "justified-with-no-hyphenation"
282 ] = pydantic.Field(
283 default="justified",
284 title="Text Alignment",
285 description="The alignment of the text. The default value is justified.",
286 )
287 seperator_between_connections: str = pydantic.Field(
288 default="",
289 title="Seperator Between Connections",
290 description=(
291 "The separator between the connections in the header. The default value is"
292 " empty string."
293 ),
294 )
295 use_icons_for_connections: bool = pydantic.Field(
296 default=True,
297 title="Use Icons for Connections",
298 description=(
299 "If this option is set to true, then icons will be used for the connections"
300 " in the header. The default value is true."
301 ),
302 )
303 margins: Margins = pydantic.Field(
304 default=Margins(),
305 title="Margins",
306 description="Page, section title, entry field, and highlights field margins.",
307 )