From 9ddbb5306fa7df4b427fcab3ab29361ebd370ec0 Mon Sep 17 00:00:00 2001 From: Sina Atalay Date: Fri, 1 Sep 2023 21:56:05 +0200 Subject: [PATCH] upload TinyTeX binaries --- .gitignore | 321 ++++++++++---------- LICENSE | 402 ++++++++++++------------- README.md | 4 +- rendercv/data/content.py | 200 ++++++------- rendercv/rendercv.py | 53 ++-- rendercv/templates/template1.tex.j2 | 164 +++++----- rendercv/tinytex/__init__.py | 0 rendercv/tinytex/command.txt | 1 + rendercv/tinytex/preamble.tex | 99 +++++++ rendercv/tinytex/test.pdf | Bin 0 -> 14097 bytes rendercv/tinytex/test.tex | 39 +++ rendercv/tinytex/vendor/README.md | 40 +++ tests/inputs/test.json | 444 ++++++++++++++-------------- tests/outputs/preamble.tex | 99 +++++++ tests/outputs/test.tex | 39 +++ 15 files changed, 1115 insertions(+), 790 deletions(-) create mode 100644 rendercv/tinytex/__init__.py create mode 100644 rendercv/tinytex/command.txt create mode 100644 rendercv/tinytex/preamble.tex create mode 100644 rendercv/tinytex/test.pdf create mode 100644 rendercv/tinytex/test.tex create mode 100644 rendercv/tinytex/vendor/README.md create mode 100644 tests/outputs/preamble.tex create mode 100644 tests/outputs/test.tex diff --git a/.gitignore b/.gitignore index 68bc17f..c74c4de 100644 --- a/.gitignore +++ b/.gitignore @@ -1,160 +1,161 @@ -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] -*$py.class - -# C extensions -*.so - -# Distribution / packaging -.Python -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -share/python-wheels/ -*.egg-info/ -.installed.cfg -*.egg -MANIFEST - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.nox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*.cover -*.py,cover -.hypothesis/ -.pytest_cache/ -cover/ - -# Translations -*.mo -*.pot - -# Django stuff: -*.log -local_settings.py -db.sqlite3 -db.sqlite3-journal - -# Flask stuff: -instance/ -.webassets-cache - -# Scrapy stuff: -.scrapy - -# Sphinx documentation -docs/_build/ - -# PyBuilder -.pybuilder/ -target/ - -# Jupyter Notebook -.ipynb_checkpoints - -# IPython -profile_default/ -ipython_config.py - -# pyenv -# For a library or package, you might want to ignore these files since the code is -# intended to run in multiple environments; otherwise, check them in: -# .python-version - -# pipenv -# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. -# However, in case of collaboration, if having platform-specific dependencies or dependencies -# having no cross-platform support, pipenv may install dependencies that don't work, or not -# install all needed dependencies. -#Pipfile.lock - -# poetry -# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. -# This is especially recommended for binary packages to ensure reproducibility, and is more -# commonly ignored for libraries. -# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control -#poetry.lock - -# pdm -# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. -#pdm.lock -# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it -# in version control. -# https://pdm.fming.dev/#use-with-ide -.pdm.toml - -# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm -__pypackages__/ - -# Celery stuff -celerybeat-schedule -celerybeat.pid - -# SageMath parsed files -*.sage.py - -# Environments -.env -.venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ - -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# mkdocs documentation -/site - -# mypy -.mypy_cache/ -.dmypy.json -dmypy.json - -# Pyre type checker -.pyre/ - -# pytype static type analyzer -.pytype/ - -# Cython debug symbols -cython_debug/ - -# PyCharm -# JetBrains specific template is maintained in a separate JetBrains.gitignore that can -# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore -# and can be added to the global gitignore or merged into this file. For a more nuclear -# option (not recommended) you can uncomment the following to ignore the entire idea folder. -#.idea/ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +.venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ diff --git a/LICENSE b/LICENSE index 261eeb9..29f81d8 100644 --- a/LICENSE +++ b/LICENSE @@ -1,201 +1,201 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md index 79de034..59ebc97 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,2 @@ -# RenderCV -A Python application that creates CVs in PDF, HTML, LaTeX, etc., from a JSON/YAML input file. +# RenderCV +A Python application that creates CVs in PDF, HTML, LaTeX, etc., from a JSON/YAML input file. diff --git a/rendercv/data/content.py b/rendercv/data/content.py index 3f54c01..28fdfc0 100644 --- a/rendercv/data/content.py +++ b/rendercv/data/content.py @@ -1,100 +1,100 @@ -from pydantic import BaseModel, HttpUrl -from pydantic_extra_types.phone_numbers import PhoneNumber -from typing import Literal -from datetime import date as Date - - -class Location(BaseModel): - # 1) Mandotory user inputs: - city: str - country: str - # 2) Optional user inputs: - state: str = None - - -class Skill(BaseModel): - # 1) Mandotory user inputs: - name: str - # 2) Optional user inputs: - details: str = None - - -class Activity(BaseModel): - # 1) Mandotory user inputs: - organization: str - position: str - location: Location - # 2) Optional user inputs: - start_date: Date = None - end_date: Date = None - company_url: HttpUrl = None - highlights: list[str] = None - - -class TestScore(BaseModel): - # 1) Mandotory user inputs: - name: str - score: str - # 2) Optional user inputs: - url: HttpUrl = None - date: Date = None - - -class Project(BaseModel): - # 1) Mandotory user inputs: - name: str - location: Location - # 2) Optional user inputs: - start_date: Date= None - end_date: Date = None - url: HttpUrl = None - highlights: list[str] = None - - -class WorkExperience(BaseModel): - # 1) Mandotory user inputs: - company: str - position: str - start_date: Date - location: Location - # 2) Optional user inputs: - end_date: Date = None - highlights: list[str] = None - - -class Education(BaseModel): - # 1) Mandotory user inputs: - institution: str - area: str - location: Location - start_date: Date - # 2) Optional user inputs: - end_date: Date = None - study_type: str = None - gpa: str = None - transcript_url: HttpUrl = None - highlights: list[str] = None - - -class SocialNetwork(BaseModel): - # 1) Mandotory user inputs: - network: Literal["LinkedIn", "GitHub", "Twitter", "Facebook", "Instagram"] - username: str - url: HttpUrl - - -class CurriculumVitae(BaseModel): - # 1) Mandotory user inputs: - name: str - # 2) Optional user inputs: - email: str = None - phone: PhoneNumber = None - website: HttpUrl = None - location: Location = None - social_networks: list[SocialNetwork] = None - education: list[Education] = None - work_experience: list[WorkExperience] = None - academic_projects: list[Project] = None - extracurricular_activities: list[Activity] = None - test_scores: list[TestScore] = None - skills: list[Skill] = None +from pydantic import BaseModel, HttpUrl +from pydantic_extra_types.phone_numbers import PhoneNumber +from typing import Literal +from datetime import date as Date + + +class Location(BaseModel): + # 1) Mandotory user inputs: + city: str + country: str + # 2) Optional user inputs: + state: str = None + + +class Skill(BaseModel): + # 1) Mandotory user inputs: + name: str + # 2) Optional user inputs: + details: str = None + + +class Activity(BaseModel): + # 1) Mandotory user inputs: + organization: str + position: str + location: Location + # 2) Optional user inputs: + start_date: Date = None + end_date: Date = None + company_url: HttpUrl = None + highlights: list[str] = None + + +class TestScore(BaseModel): + # 1) Mandotory user inputs: + name: str + score: str + # 2) Optional user inputs: + url: HttpUrl = None + date: Date = None + + +class Project(BaseModel): + # 1) Mandotory user inputs: + name: str + location: Location + # 2) Optional user inputs: + start_date: Date= None + end_date: Date = None + url: HttpUrl = None + highlights: list[str] = None + + +class WorkExperience(BaseModel): + # 1) Mandotory user inputs: + company: str + position: str + start_date: Date + location: Location + # 2) Optional user inputs: + end_date: Date = None + highlights: list[str] = None + + +class Education(BaseModel): + # 1) Mandotory user inputs: + institution: str + area: str + location: Location + start_date: Date + # 2) Optional user inputs: + end_date: Date = None + study_type: str = None + gpa: str = None + transcript_url: HttpUrl = None + highlights: list[str] = None + + +class SocialNetwork(BaseModel): + # 1) Mandotory user inputs: + network: Literal["LinkedIn", "GitHub", "Twitter", "Facebook", "Instagram"] + username: str + url: HttpUrl + + +class CurriculumVitae(BaseModel): + # 1) Mandotory user inputs: + name: str + # 2) Optional user inputs: + email: str = None + phone: PhoneNumber = None + website: HttpUrl = None + location: Location = None + social_networks: list[SocialNetwork] = None + education: list[Education] = None + work_experience: list[WorkExperience] = None + academic_projects: list[Project] = None + extracurricular_activities: list[Activity] = None + test_scores: list[TestScore] = None + skills: list[Skill] = None diff --git a/rendercv/rendercv.py b/rendercv/rendercv.py index c810c64..2198cb8 100644 --- a/rendercv/rendercv.py +++ b/rendercv/rendercv.py @@ -1,23 +1,30 @@ -from jinja2 import Environment, FileSystemLoader -from data.content import CurriculumVitae -import os -import json - -workspace = os.path.dirname(os.path.dirname(__file__)) -environment = Environment(loader=FileSystemLoader(os.path.join(workspace, "rendercv", "templates"))) -environment.block_start_string = "((*" -environment.block_end_string = "*))" -environment.variable_start_string = "(((" -environment.variable_end_string = ")))" -environment.comment_start_string = "((=" -environment.comment_end_string = "=))" - -template = environment.get_template("template1.tex.j2") - -input_file_path = os.path.join(workspace, "tests", "inputs", "test.json") -with open(input_file_path) as file: - raw_json = json.load(file) - -data = CurriculumVitae(**raw_json) - -output_latex_file = template.render(data=data) +from jinja2 import Environment, FileSystemLoader +from data.content import CurriculumVitae +import os +import json + +workspace = os.path.dirname(os.path.dirname(__file__)) +environment = Environment(loader=FileSystemLoader(os.path.join(workspace, "rendercv", "templates"))) +environment.block_start_string = "((*" +environment.block_end_string = "*))" +environment.variable_start_string = "(((" +environment.variable_end_string = ")))" +environment.comment_start_string = "((=" +environment.comment_end_string = "=))" + +template = environment.get_template("template1.tex.j2") + +input_file_path = os.path.join(workspace, "tests", "inputs", "test.json") +with open(input_file_path) as file: + raw_json = json.load(file) + +data = CurriculumVitae(**raw_json) + +output_latex_file = template.render(data=data) + +# Create an output file and write the rendered LaTeX code to it: +output_file_path = os.path.join(workspace, "tests", "outputs", "test.tex") +with open(output_file_path, "w") as file: + file.write(output_latex_file) + + \ No newline at end of file diff --git a/rendercv/templates/template1.tex.j2 b/rendercv/templates/template1.tex.j2 index 76158c5..9d16b64 100644 --- a/rendercv/templates/template1.tex.j2 +++ b/rendercv/templates/template1.tex.j2 @@ -1,83 +1,83 @@ -\documentclass[10pt, a4paper]{memoir} - -% =========== -% =========== -% USER INPUTS: -\newcommand{\AUTHOR}{Sina Atalay} - -\newcommand{\PRIMARYCOLOR}{0,79,144} % In RGB out of 255 - -\newcommand{\PageXMargin}{0.53in} -\newcommand{\PageYMargin}{0.53in} - -\newcommand{\TopMarginOfSections}{0.13cm} -\newcommand{\BottomMarginOfSections}{0.13cm} - -\newcommand{\YMarginBetweenEntries}{0.12cm} -\newcommand{\YMarginBetweenBullets}{0.07cm} -\newcommand{\LeftMarginOfBullets}{0.7cm} - -\newcommand{\DateandLocationWidth}{3.7cm} -% =========== -% =========== - -\input{preamble} - -\begin{document} - % Test out the 4 main entry types with the commands below: - % \Header{a}{b}{c}{d}{e}{f} - % \section{EducationEntry} - % \EducationEntry{a}{b}{c}{d}{e}{f}{g}{j} - % \section{ExperienceEntry} - % \ExperienceEntry{a}{b}{c}{d}{e}{f}{g}{j} - % \section{NormalEntry} - % \NormalEntry{a}{b}{c}{d}{e}{f} - % \section{OneLineEntry} - % \OneLineEntry{a}{b} - - % To create the header manually (insted of \Header command), use the code below: - % \begin{header}[0pt] - % \Huge - % \textbf{\directlua{tex.print(json.basics.name)}} - - % \normalsize - % \faPhone\hspace{0.13cm}\directlua{tex.print(json.basics.phone)} \hspace{0.5cm} - % \href{mailto:\directlua{tex.print(json.basics.email)}}{\faEnvelopeO\hspace{0.13cm}\directlua{tex.print(json.basics.email)}} \hspace{0.5cm} - % \href{https://\directlua{tex.print(json.basics.url)}}{\faLaptop\hspace{0.13cm}\directlua{tex.print(json.basics.url)}} \hspace{0.5cm} - % \href{https://www.linkedin.com/in/williamhgates}{\faLinkedin\hspace{0.13cm}williamhgates} \hspace{0.5cm} - % \href{https://www.github.com/sinaatalay}{\faGithub\hspace{0.13cm}sinaatalay} - % \end{header} - - \directlua{require("parser.lua")} - - \makeoddhead{headings}{}{}{\small\color{gray}\linespread{0}\emph{Last updated on {\printdayon\today}}\hspace*{0.2cm}} - \directlua{printHeader()} - - \section{Education} - ((* for education in data.education *)) - \EducationEntry{(((education.institution)))}{(((education.area)))}{(((education.studyType)))}{(((education.startDate)))}{(((education.endDate)))}{(((education.gpa)))}{(((education.courses)))}{(((education.location)))} - ((* endfor *)) - - \section{Work Experience} - \directlua{printExperience()} - - - \section{Academic Projects} - \directlua{printAcademicProjects()} - - \section{Certificates} - \directlua{printCertificates()} - - \section{Skills} - \directlua{printSkills()} - - \section{Test Scores} - \directlua{printTestScores()} - - \section{Personal Projects (test)} - \directlua{printPersonalProjects()} - - \section{Extracurricular Activities} - \directlua{printExtracurricularActivities()} - +\documentclass[10pt, a4paper]{memoir} + +% =========== +% =========== +% USER INPUTS: +\newcommand{\AUTHOR}{Sina Atalay} + +\newcommand{\PRIMARYCOLOR}{0,79,144} % In RGB out of 255 + +\newcommand{\PageXMargin}{0.53in} +\newcommand{\PageYMargin}{0.53in} + +\newcommand{\TopMarginOfSections}{0.13cm} +\newcommand{\BottomMarginOfSections}{0.13cm} + +\newcommand{\YMarginBetweenEntries}{0.12cm} +\newcommand{\YMarginBetweenBullets}{0.07cm} +\newcommand{\LeftMarginOfBullets}{0.7cm} + +\newcommand{\DateandLocationWidth}{3.7cm} +% =========== +% =========== + +\input{preamble} + +\begin{document} + % Test out the 4 main entry types with the commands below: + % \Header{a}{b}{c}{d}{e}{f} + % \section{EducationEntry} + % \EducationEntry{a}{b}{c}{d}{e}{f}{g}{j} + % \section{ExperienceEntry} + % \ExperienceEntry{a}{b}{c}{d}{e}{f}{g}{j} + % \section{NormalEntry} + % \NormalEntry{a}{b}{c}{d}{e}{f} + % \section{OneLineEntry} + % \OneLineEntry{a}{b} + + % To create the header manually (insted of \Header command), use the code below: + % \begin{header}[0pt] + % \Huge + % \textbf{\directlua{tex.print(json.basics.name)}} + + % \normalsize + % \faPhone\hspace{0.13cm}\directlua{tex.print(json.basics.phone)} \hspace{0.5cm} + % \href{mailto:\directlua{tex.print(json.basics.email)}}{\faEnvelopeO\hspace{0.13cm}\directlua{tex.print(json.basics.email)}} \hspace{0.5cm} + % \href{https://\directlua{tex.print(json.basics.url)}}{\faLaptop\hspace{0.13cm}\directlua{tex.print(json.basics.url)}} \hspace{0.5cm} + % \href{https://www.linkedin.com/in/williamhgates}{\faLinkedin\hspace{0.13cm}williamhgates} \hspace{0.5cm} + % \href{https://www.github.com/sinaatalay}{\faGithub\hspace{0.13cm}sinaatalay} + % \end{header} + + \directlua{require("parser.lua")} + + \makeoddhead{headings}{}{}{\small\color{gray}\linespread{0}\emph{Last updated on {\printdayon\today}}\hspace*{0.2cm}} + \directlua{printHeader()} + + \section{Education} + ((* for education in data.education *)) + \EducationEntry{(((education.institution)))}{(((education.area)))}{(((education.studyType)))}{(((education.startDate)))}{(((education.endDate)))}{(((education.gpa)))}{(((education.courses)))}{(((education.location)))} + ((* endfor *)) + + \section{Work Experience} + \directlua{printExperience()} + + + \section{Academic Projects} + \directlua{printAcademicProjects()} + + \section{Certificates} + \directlua{printCertificates()} + + \section{Skills} + \directlua{printSkills()} + + \section{Test Scores} + \directlua{printTestScores()} + + \section{Personal Projects (test)} + \directlua{printPersonalProjects()} + + \section{Extracurricular Activities} + \directlua{printExtracurricularActivities()} + \end{document} \ No newline at end of file diff --git a/rendercv/tinytex/__init__.py b/rendercv/tinytex/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/rendercv/tinytex/command.txt b/rendercv/tinytex/command.txt new file mode 100644 index 0000000..507b65d --- /dev/null +++ b/rendercv/tinytex/command.txt @@ -0,0 +1 @@ +C:\GIT\rendercv\rendercv\tinytex\vendor\TinyTeX\bin\windows\latexmk.exe -lualatex -c test.tex \ No newline at end of file diff --git a/rendercv/tinytex/preamble.tex b/rendercv/tinytex/preamble.tex new file mode 100644 index 0000000..7466a8c --- /dev/null +++ b/rendercv/tinytex/preamble.tex @@ -0,0 +1,99 @@ +\usepackage[ignoreheadfoot, top=\PageYMargin, bottom=\PageYMargin, left=\PageXMargin, right=\PageXMargin, headsep=0.3cm]{geometry} +\usepackage{fontspec} +\usepackage[explicit]{titlesec} +\usepackage{tabularx} +\usepackage{array} +\usepackage{xifthen} +\usepackage[dvipsnames]{xcolor} +\definecolor{primaryColor}{RGB}{\PRIMARYCOLOR} +\usepackage{enumitem} +\usepackage{fontawesome} +\usepackage[pdftitle={\AUTHOR's CV}, pdfauthor={\AUTHOR}, colorlinks=true, urlcolor=primaryColor]{hyperref} % Linking + +% \setmainfont{SourceSansPro}[ +% Path= fonts/, +% Extension = .ttf, +% UprightFont = *-Regular, +% ItalicFont = *-Italic, +% BoldFont = *-Bold, +% BoldItalicFont = *-BoldItalic] + +% Calculate last update top margin: +\newlength\A +\newlength\B +\setlength\A{\PageYMargin} +\setlength\B{\dimexpr \numexpr \A / 1 \relax sp\relax} + +\setcounter{secnumdepth}{0} % No section numbering +\setlength{\parindent}{0pt} % No indentation +\setlength{\topskip}{0pt} % No top skip +\pagenumbering{gobble} % No page numbering + +\titleformat{\section}{\LARGE\color{primaryColor}}{}{}{\textbf{#1}\hspace{0.15cm}\titlerule[0.8pt]}[] % New section title format +\titlespacing{\section}{0pt}{\TopMarginOfSections}{\BottomMarginOfSections} % New section title spacing + +% Date format (from: https://web.library.yale.edu/cataloging/months): +% \makeatletter +% \def\month@english{\ifcase\month\or +% Jan.\or Feb.\or Mar.\or Apr.\or May\or June\or +% July\or Aug.\or Sept.\or Oct.\or Nov.\or Dec.\fi} +% \makeatother +% \origdate + +% New column types: +\newcolumntype{L}[1]{>{\raggedright\let\newline\\\arraybackslash\hspace{0pt}}p{#1}} +\newcolumntype{R}[1]{>{\raggedleft\let\newline\\\arraybackslash\hspace{0pt}}p{#1}} + +% New commands/environments: +\newenvironment{highlights}{\begin{itemize}[topsep=0pt, parsep=\YMarginBetweenBullets, partopsep=0pt, itemsep=0pt, after=\vspace*{-\baselineskip}, leftmargin=\LeftMarginOfBullets]}{\end{itemize}} % New environment for highlights + +\newenvironment{header}[1][\topsep]{\setlength{\topsep}{#1}\par\kern\topsep\centering\color{primaryColor}\linespread{1.5}}{\par\kern\topsep} % New environment for the header + +% New commands: +\newcommand{\hrefExternal}[2]{\href{#1}{#2\, \faExternalLink}} + +\newcommand{\Header}[6]{ + \begin{header}[0pt] + \Huge + \textbf{#1} + + \normalsize + \faPhone\hspace{0.13cm}#2 \hspace{0.5cm} + \href{mailto:#3}{\faEnvelopeO\hspace{0.13cm}#3} \hspace{0.5cm} + \href{https://#4}{\faLaptop\hspace{0.13cm}#4} \hspace{0.5cm} + \href{https://www.linkedin.com/in/#5}{\faLinkedin\hspace{0.13cm}#5} \hspace{0.5cm} + \href{https://www.github.com/#6}{\faGithub\hspace{0.13cm}#6} + \end{header} +} + +\newcommand{\EducationEntry}[8]{ + \begin{tabularx}{\textwidth}{p{0.55cm} >{\raggedright}X R{\DateandLocationWidth}} + \textbf{#1} & \textbf{#2}, #3 \ifthenelse{\isempty{#6}}{}{\vspace{\YMarginBetweenBullets}\begin{highlights} \item #6 \ifthenelse{\isempty{#7}}{\end{highlights}}{\item #7 \ifthenelse{\isempty{#8}}{\end{highlights}}{\item #8 \end{highlights}}}} & \ifthenelse{\isempty{#4}}{#5}{#4\newline #5} \\ + \end{tabularx} + + \vspace{\YMarginBetweenEntries} +} + +\newcommand{\ExperienceEntry}[8]{ + \begin{tabularx}{\textwidth}{X R{\DateandLocationWidth}} + \textbf{#1}, #2 \ifthenelse{\isempty{#6}}{}{\vspace{\YMarginBetweenBullets}\begin{highlights} \item #6 \ifthenelse{\isempty{#7}}{\end{highlights}}{\item #7 \ifthenelse{\isempty{#8}}{\end{highlights}}{\item #8 \end{highlights}}}} & \ifthenelse{\isempty{#3}}{#4\newline #5}{#3\newline #4\newline #5} \\ + \end{tabularx} + + \vspace{\YMarginBetweenEntries} +} + +\newcommand{\NormalEntry}[6]{ + \begin{tabularx}{\textwidth}{X R{\DateandLocationWidth}} + \textbf{#1} \ifthenelse{\isempty{#4}}{}{\vspace{\YMarginBetweenBullets}\begin{highlights} \item #4 \ifthenelse{\isempty{#5}}{\end{highlights}}{\item #5 \ifthenelse{\isempty{#6}}{\end{highlights}}{\item #6 \end{highlights}}}} & \ifthenelse{\isempty{#2}}{#3}{#2\newline #3} \\ + \end{tabularx} + + \vspace{\YMarginBetweenEntries} +} + +\newcommand{\OneLineEntry}[2]{ + \setlength{\leftskip}{0.2cm} + \textbf{#1:} #2 + + \vspace{\YMarginBetweenEntries} + \setlength{\leftskip}{0cm} +} \ No newline at end of file diff --git a/rendercv/tinytex/test.pdf b/rendercv/tinytex/test.pdf new file mode 100644 index 0000000000000000000000000000000000000000..11c51d25acd68aeb66b87868d2f7a269d4b198fb GIT binary patch literal 14097 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\raggedright\let\newline\\\arraybackslash\hspace{0pt}}p{#1}} +\newcolumntype{R}[1]{>{\raggedleft\let\newline\\\arraybackslash\hspace{0pt}}p{#1}} + +% New commands/environments: +\newenvironment{highlights}{\begin{itemize}[topsep=0pt, parsep=\YMarginBetweenBullets, partopsep=0pt, itemsep=0pt, after=\vspace*{-\baselineskip}, leftmargin=\LeftMarginOfBullets]}{\end{itemize}} % New environment for highlights + +\newenvironment{header}[1][\topsep]{\setlength{\topsep}{#1}\par\kern\topsep\centering\color{primaryColor}\linespread{1.5}}{\par\kern\topsep} % New environment for the header + +% New commands: +\newcommand{\hrefExternal}[2]{\href{#1}{#2\, \faExternalLink}} + +\newcommand{\Header}[6]{ + \begin{header}[0pt] + \Huge + \textbf{#1} + + \normalsize + \faPhone\hspace{0.13cm}#2 \hspace{0.5cm} + \href{mailto:#3}{\faEnvelopeO\hspace{0.13cm}#3} \hspace{0.5cm} + \href{https://#4}{\faLaptop\hspace{0.13cm}#4} \hspace{0.5cm} + \href{https://www.linkedin.com/in/#5}{\faLinkedin\hspace{0.13cm}#5} \hspace{0.5cm} + \href{https://www.github.com/#6}{\faGithub\hspace{0.13cm}#6} + \end{header} +} + +\newcommand{\EducationEntry}[8]{ + \begin{tabularx}{\textwidth}{p{0.55cm} >{\raggedright}X R{\DateandLocationWidth}} + \textbf{#1} & \textbf{#2}, #3 \ifthenelse{\isempty{#6}}{}{\vspace{\YMarginBetweenBullets}\begin{highlights} \item #6 \ifthenelse{\isempty{#7}}{\end{highlights}}{\item #7 \ifthenelse{\isempty{#8}}{\end{highlights}}{\item #8 \end{highlights}}}} & \ifthenelse{\isempty{#4}}{#5}{#4\newline #5} \\ + \end{tabularx} + + \vspace{\YMarginBetweenEntries} +} + +\newcommand{\ExperienceEntry}[8]{ + \begin{tabularx}{\textwidth}{X R{\DateandLocationWidth}} + \textbf{#1}, #2 \ifthenelse{\isempty{#6}}{}{\vspace{\YMarginBetweenBullets}\begin{highlights} \item #6 \ifthenelse{\isempty{#7}}{\end{highlights}}{\item #7 \ifthenelse{\isempty{#8}}{\end{highlights}}{\item #8 \end{highlights}}}} & \ifthenelse{\isempty{#3}}{#4\newline #5}{#3\newline #4\newline #5} \\ + \end{tabularx} + + \vspace{\YMarginBetweenEntries} +} + +\newcommand{\NormalEntry}[6]{ + \begin{tabularx}{\textwidth}{X R{\DateandLocationWidth}} + \textbf{#1} \ifthenelse{\isempty{#4}}{}{\vspace{\YMarginBetweenBullets}\begin{highlights} \item #4 \ifthenelse{\isempty{#5}}{\end{highlights}}{\item #5 \ifthenelse{\isempty{#6}}{\end{highlights}}{\item #6 \end{highlights}}}} & \ifthenelse{\isempty{#2}}{#3}{#2\newline #3} \\ + \end{tabularx} + + \vspace{\YMarginBetweenEntries} +} + +\newcommand{\OneLineEntry}[2]{ + \setlength{\leftskip}{0.2cm} + \textbf{#1:} #2 + + \vspace{\YMarginBetweenEntries} + \setlength{\leftskip}{0cm} +} \ No newline at end of file diff --git a/tests/outputs/test.tex b/tests/outputs/test.tex new file mode 100644 index 0000000..8161429 --- /dev/null +++ b/tests/outputs/test.tex @@ -0,0 +1,39 @@ +\documentclass[10pt, a4paper]{memoir} + +% =========== +% =========== +% USER INPUTS: +\newcommand{\AUTHOR}{Sina Atalay} + +\newcommand{\PRIMARYCOLOR}{0,79,144} % In RGB out of 255 + +\newcommand{\PageXMargin}{0.53in} +\newcommand{\PageYMargin}{0.53in} + +\newcommand{\TopMarginOfSections}{0.13cm} +\newcommand{\BottomMarginOfSections}{0.13cm} + +\newcommand{\YMarginBetweenEntries}{0.12cm} +\newcommand{\YMarginBetweenBullets}{0.07cm} +\newcommand{\LeftMarginOfBullets}{0.7cm} + +\newcommand{\DateandLocationWidth}{3.7cm} +% =========== +% =========== + +\input{preamble} + +\begin{document} + % Test out the 4 main entry types with the commands below: + \Header{a}{b}{c}{d}{e}{f} + \section{EducationEntry} + \EducationEntry{a}{b}{c}{d}{e}{f}{g}{j} + \section{ExperienceEntry} + \ExperienceEntry{a}{b}{c}{d}{e}{f}{g}{j} + \section{NormalEntry} + \NormalEntry{a}{b}{c}{d}{e}{f} + \section{OneLineEntry} + \OneLineEntry{a}{b} + + +\end{document} \ No newline at end of file