codeurcv 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
codeurcv/__init__.py ADDED
File without changes
codeurcv/__main__.py ADDED
@@ -0,0 +1,4 @@
1
+ from codeurcv.cli import app
2
+
3
+ if __name__ == "__main__":
4
+ app()
codeurcv/cli.py ADDED
@@ -0,0 +1,69 @@
1
+ import typer
2
+ from pathlib import Path
3
+ from rich.console import Console
4
+ from importlib.metadata import version
5
+
6
+ from .core.renderer import ResumeRenderer
7
+ from .core.constants import DEFAULT_CONFIG_FILE, DEFAULT_OUT_DIR
8
+
9
+ app = typer.Typer(help="Generate LaTeX resumes from YAML configs.")
10
+ console = Console()
11
+
12
+
13
+ def get_version() -> str:
14
+ try:
15
+ return version("codeurcv")
16
+ except Exception:
17
+ return "0.0.0-dev"
18
+
19
+
20
+ def version_callback(value: bool):
21
+ if value:
22
+ console.print(f"[bold cyan]codeurcv version:[/bold cyan] {get_version()}")
23
+ raise typer.Exit()
24
+
25
+
26
+ @app.callback()
27
+ def main(
28
+ version: bool = typer.Option(
29
+ False,
30
+ "-v",
31
+ "--version",
32
+ help="Show version and exit",
33
+ is_eager=True,
34
+ callback=version_callback,
35
+ ),
36
+ ):
37
+ pass
38
+
39
+
40
+ @app.command()
41
+ def run(
42
+ filename: Path = typer.Option(
43
+ DEFAULT_CONFIG_FILE, "--file", "-f", help="Path to resume YAML config"
44
+ ),
45
+ out_dir: Path = typer.Option(
46
+ DEFAULT_OUT_DIR, "--out-dir", "-o", help="Directory to save generated resume"
47
+ ),
48
+ ):
49
+ """Render resume."""
50
+ console.print("[bold cyan]Starting resume generation...[/bold cyan]")
51
+
52
+ renderer = ResumeRenderer()
53
+
54
+ renderer.render(filename, out_dir)
55
+
56
+ console.print("[bold green]Done![/bold green]")
57
+
58
+
59
+ @app.command()
60
+ def templates():
61
+ """List available resume templates."""
62
+ from .core.plugin_loader import load_builtin_plugins
63
+
64
+ plugins = load_builtin_plugins()
65
+
66
+ console.print("\n[bold]Available Templates:[/bold]\n")
67
+
68
+ for name, plugin in plugins.items():
69
+ console.print(f"• [cyan]{name}[/cyan] — {plugin.description}")
@@ -0,0 +1,3 @@
1
+ DEFAULT_CONFIG_FILE = "config.yml"
2
+ DEFAULT_TEMPLATE = "minimalist"
3
+ DEFAULT_OUT_DIR = "output"
@@ -0,0 +1,16 @@
1
+ import logging
2
+ from pathlib import Path
3
+
4
+
5
+ def setup_logger(
6
+ debug: bool = False, log_file: Path = Path("app.log")
7
+ ) -> logging.Logger:
8
+ level = logging.DEBUG if debug else logging.INFO
9
+
10
+ logging.basicConfig(
11
+ level=level,
12
+ format="%(asctime)s | %(levelname)s | %(message)s",
13
+ handlers=[logging.FileHandler(log_file, encoding="utf-8")],
14
+ )
15
+
16
+ return logging.getLogger("codeurcv")
@@ -0,0 +1,13 @@
1
+ class MarkdownConverter:
2
+ @staticmethod
3
+ def convert(text: str) -> str:
4
+ import subprocess
5
+
6
+ result = subprocess.run(
7
+ ["pandoc", "-f", "markdown", "-t", "latex"],
8
+ input=text,
9
+ text=True,
10
+ capture_output=True,
11
+ check=True,
12
+ )
13
+ return result.stdout.strip()
@@ -0,0 +1,39 @@
1
+ import pkgutil
2
+ import importlib
3
+ from typing import Dict
4
+
5
+ from codeurcv.plugins.base import TemplatePlugin
6
+
7
+
8
+ def load_builtin_plugins() -> Dict[str, TemplatePlugin]:
9
+ """
10
+ Dynamically discover built-in template plugins.
11
+ """
12
+ plugins = {}
13
+
14
+ package = "codeurcv.plugins"
15
+
16
+ for _, module_name, is_pkg in pkgutil.iter_modules(
17
+ importlib.import_module(package).__path__
18
+ ):
19
+ if not is_pkg:
20
+ continue
21
+
22
+ try:
23
+ module = importlib.import_module(f"{package}.{module_name}.plugin")
24
+
25
+ for attr in dir(module):
26
+ obj = getattr(module, attr)
27
+
28
+ if (
29
+ isinstance(obj, type)
30
+ and issubclass(obj, TemplatePlugin)
31
+ and obj is not TemplatePlugin
32
+ ):
33
+ instance = obj()
34
+ plugins[instance.name] = instance
35
+
36
+ except ModuleNotFoundError:
37
+ continue
38
+
39
+ return plugins
@@ -0,0 +1,140 @@
1
+ import yaml
2
+ import shutil
3
+ import logging
4
+ import subprocess
5
+ from pathlib import Path
6
+ from datetime import datetime
7
+ from rich.console import Console
8
+
9
+ from codeurcv.core.template_loader import TemplateEngine
10
+ from codeurcv.core.logger import setup_logger
11
+ from codeurcv.core.plugin_loader import load_builtin_plugins
12
+ from codeurcv.core.schema import ResumeConfig
13
+
14
+ console = Console()
15
+
16
+
17
+ class ResumeRenderer:
18
+ def __init__(self):
19
+ self.plugins = load_builtin_plugins()
20
+ self._check_dependencies()
21
+ log_dir = Path("logs")
22
+ log_dir.mkdir(exist_ok=True)
23
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
24
+ self.log_file = log_dir / f"codeurcv_{timestamp}.log"
25
+ self.logger = setup_logger(debug=False, log_file=self.log_file)
26
+
27
+ @staticmethod
28
+ def _check_dependencies():
29
+ for tool in ("pandoc", "pdflatex"):
30
+ if shutil.which(tool) is None:
31
+ raise RuntimeError(f"{tool} is not installed or not in PATH.")
32
+
33
+ def render(self, config_path: Path, output_dir: Path):
34
+ console.print("\n[bold green]🚀 Building your resume...[/bold green]\n")
35
+
36
+ try:
37
+ # STEP 1
38
+ raw_data = self._step(
39
+ "Configuration loaded",
40
+ lambda: yaml.safe_load(config_path.read_text()),
41
+ )
42
+
43
+ # STEP 2
44
+ config = self._step(
45
+ "Data validated",
46
+ lambda: ResumeConfig(**raw_data),
47
+ )
48
+
49
+ # STEP 3
50
+ plugin = self._step(
51
+ f"Template applied: {config.template}",
52
+ lambda: self._get_plugin(config.template),
53
+ )
54
+
55
+ # STEP 4
56
+ data = plugin.preprocess(config)
57
+
58
+ template_path = plugin.template_path()
59
+ template_engine = TemplateEngine(template_path.parent)
60
+
61
+ rendered_tex = self._step(
62
+ "LaTeX rendered",
63
+ lambda: template_engine.render(
64
+ template_path.name,
65
+ data.model_dump(),
66
+ ),
67
+ )
68
+
69
+ output_dir.mkdir(parents=True, exist_ok=True)
70
+ tex_file = output_dir / f"{config.filename}.tex"
71
+ tex_file.write_text(plugin.postprocess(rendered_tex))
72
+
73
+ # STEP 5
74
+ console.print("\n📄 Generating PDF...\n")
75
+ self._generate_pdf(tex_file, output_dir)
76
+
77
+ console.print("\n[bold green]✔ PDF generated[/bold green]\n")
78
+ console.print("[bold green]🎉 Done![/bold green]")
79
+ console.print(
80
+ f"[cyan]📁 {output_dir.resolve() / f'{config.filename}.pdf'}[/cyan]\n"
81
+ )
82
+
83
+ except Exception:
84
+ console.print("\n[bold red]❌ Resume generation failed.[/bold red]")
85
+ console.print(f"[yellow]See full logs at:[/yellow] {self.log_file}\n")
86
+ raise
87
+
88
+ def _step(self, message: str, func):
89
+ try:
90
+ result = func()
91
+ console.print(f"[green]✔[/green] {message}")
92
+ logging.info("SUCCESS: %s", message)
93
+ return result
94
+ except Exception as e:
95
+ logging.exception("FAILED: %s", message)
96
+ raise RuntimeError(f"{message} failed.") from e
97
+
98
+ def _get_plugin(self, template_name: str):
99
+ if template_name not in self.plugins:
100
+ available = ", ".join(self.plugins.keys())
101
+ raise RuntimeError(
102
+ f"Template '{template_name}' not found.\n"
103
+ f"Available templates: {available}"
104
+ )
105
+ return self.plugins[template_name]
106
+
107
+ def _generate_pdf(self, tex_file: Path, output_dir: Path):
108
+ """
109
+ Runs pdflatex to generate PDF from the .tex file.
110
+ - Uses subprocess to call pdflatex with appropriate arguments.
111
+ - Captures and logs output in real-time.
112
+ - Raises an error if PDF generation fails.
113
+ """
114
+ command = [
115
+ "pdflatex",
116
+ "-interaction=nonstopmode",
117
+ "-output-directory",
118
+ str(output_dir),
119
+ str(tex_file),
120
+ ]
121
+
122
+ console.print(f"[bold] > Running:[/bold] {' '.join(command)}")
123
+ logging.info("Running command: %s", " ".join(command))
124
+
125
+ process = subprocess.Popen(
126
+ command,
127
+ stdout=subprocess.PIPE,
128
+ stderr=subprocess.STDOUT,
129
+ text=True,
130
+ bufsize=1,
131
+ )
132
+
133
+ with console.status("[green]Generating PDF...[/green]", spinner="dots"):
134
+ stdout, _ = process.communicate()
135
+
136
+ for line in stdout.splitlines():
137
+ logging.info(line)
138
+
139
+ if process.returncode != 0:
140
+ raise RuntimeError("PDF generation failed.")
@@ -0,0 +1,53 @@
1
+ from typing import List, Optional
2
+ from pydantic import BaseModel, Field
3
+
4
+ from codeurcv.core.constants import DEFAULT_TEMPLATE
5
+
6
+ class ResumeSection(BaseModel):
7
+ """Base model for resume sections with optional ordering."""
8
+ priority: Optional[int] = None
9
+
10
+ class BasicDetails(BaseModel):
11
+ name: str
12
+ email: str
13
+ phone: Optional[str] = None
14
+ website: Optional[str] = None
15
+ github: Optional[str] = None
16
+ linkedin: Optional[str] = None
17
+ location: Optional[str] = None
18
+
19
+ class Education(ResumeSection):
20
+ institution: str
21
+ location: str
22
+ degree: str
23
+ duration: str
24
+ gpa: Optional[str] = None
25
+ additional_information: List[str] = Field(default_factory=list)
26
+
27
+ class Job(ResumeSection):
28
+ company: str
29
+ role: str
30
+ duration: str
31
+ achievements: List[str] = Field(default_factory=list)
32
+ technologies: List[str] = Field(default_factory=list)
33
+
34
+ class Project(ResumeSection):
35
+ name: str
36
+ description: List[str] = Field(default_factory=list)
37
+ technologies: List[str] = Field(default_factory=list)
38
+ link: Optional[str] = None
39
+ date: Optional[str] = None
40
+
41
+ class Skill(ResumeSection):
42
+ name: str
43
+ featured_skills: List[str] = Field(default_factory=list)
44
+
45
+ class ResumeConfig(BaseModel):
46
+ template: str = DEFAULT_TEMPLATE
47
+ filename: str = "resume"
48
+ basic_details: BasicDetails
49
+ summary: Optional[str] = None
50
+ education: List[Education] = Field(default_factory=list)
51
+ work: List[Job] = Field(default_factory=list)
52
+ projects: List[Project] = Field(default_factory=list)
53
+ skills: List[Skill] = Field(default_factory=list)
@@ -0,0 +1,19 @@
1
+ from jinja2 import Environment, FileSystemLoader
2
+ from pathlib import Path
3
+
4
+
5
+ class TemplateEngine:
6
+ def __init__(self, template_dir: Path):
7
+ self.env = Environment(
8
+ loader=FileSystemLoader(template_dir),
9
+ block_start_string="((*",
10
+ block_end_string="*))",
11
+ variable_start_string="(((",
12
+ variable_end_string=")))",
13
+ comment_start_string="((#",
14
+ comment_end_string="#))",
15
+ )
16
+
17
+ def render(self, template_name: str, context: dict) -> str:
18
+ template = self.env.get_template(template_name)
19
+ return template.render(**context)
File without changes
@@ -0,0 +1,30 @@
1
+ from abc import ABC, abstractmethod
2
+ from pathlib import Path
3
+ from typing import Dict, Any
4
+ from codeurcv.core.schema import ResumeConfig
5
+
6
+
7
+ class TemplatePlugin(ABC):
8
+ """
9
+ Base class for resume template plugins.
10
+ """
11
+
12
+ name: str
13
+ description: str
14
+
15
+ @abstractmethod
16
+ def template_path(self) -> Path:
17
+ """Return path to LaTeX template file."""
18
+
19
+ def preprocess(self, data: ResumeConfig) -> ResumeConfig:
20
+ """
21
+ Optional hook to modify validated config
22
+ before rendering.
23
+ """
24
+ return data
25
+
26
+ def postprocess(self, tex_content: str) -> str:
27
+ """
28
+ Optional hook to modify final rendered LaTeX.
29
+ """
30
+ return tex_content
File without changes
@@ -0,0 +1,23 @@
1
+ from pathlib import Path
2
+
3
+ from codeurcv.core.schema import ResumeConfig
4
+ from codeurcv.plugins.base import TemplatePlugin
5
+ from codeurcv.core.markdown_converter import MarkdownConverter
6
+
7
+
8
+ class MinimalistTemplate(TemplatePlugin):
9
+ name = "minimalist"
10
+ description = "Clean minimalist resume style"
11
+
12
+ def template_path(self) -> Path:
13
+ return Path(__file__).parent / "template.tex"
14
+
15
+ def preprocess(self, data: ResumeConfig) -> ResumeConfig:
16
+ converter = MarkdownConverter()
17
+ if data.summary:
18
+ data.summary = converter.convert(data.summary)
19
+ for job in data.work:
20
+ job.achievements = [converter.convert(achievement) for achievement in job.achievements]
21
+ for proj in data.projects:
22
+ proj.description = [converter.convert(desc) for desc in proj.description]
23
+ return data
@@ -0,0 +1,178 @@
1
+ %-------------------------
2
+ % Resume in LateX
3
+ % Author : Subhomoy Roy Choudhury
4
+ % License : MIT
5
+ %------------------------
6
+
7
+ \documentclass[letterpaper,11pt]{article}
8
+
9
+ \usepackage{latexsym}
10
+ \usepackage[empty]{fullpage}
11
+ \usepackage{titlesec}
12
+ \usepackage{marvosym}
13
+ \usepackage[usenames,dvipsnames]{color}
14
+ \usepackage{verbatim}
15
+ \usepackage{enumitem}
16
+ \usepackage[hidelinks]{hyperref}
17
+ \usepackage{fancyhdr}
18
+ \usepackage[english]{babel}
19
+ \usepackage{tabularx}
20
+ \input{glyphtounicode}
21
+
22
+ \pagestyle{fancy}
23
+ \fancyhf{} % Clear all header and footer fields
24
+ \fancyfoot{}
25
+ \renewcommand{\headrulewidth}{0pt}
26
+ \renewcommand{\footrulewidth}{0pt}
27
+
28
+ % Adjust margins
29
+ \addtolength{\oddsidemargin}{-0.5in}
30
+ \addtolength{\evensidemargin}{-0.5in}
31
+ \addtolength{\textwidth}{1in}
32
+ \addtolength{\topmargin}{-.5in}
33
+ \addtolength{\textheight}{1.0in}
34
+ \setlength{\footskip}{12pt}
35
+
36
+ \urlstyle{same}
37
+
38
+ \raggedbottom
39
+ \raggedright
40
+ \setlength{\tabcolsep}{0in}
41
+
42
+ % Sections formatting
43
+ \titleformat{\section}{
44
+ \vspace{-4pt}\scshape\raggedright\large
45
+ }{}{0em}{}[\color{black}\titlerule \vspace{-5pt}]
46
+
47
+ % Ensure that generate PDF is machine readable/ATS parsable
48
+ \pdfgentounicode=1
49
+
50
+ %-------------------------
51
+ % Custom commands
52
+ % \newcommand{\resumeItem}[2]{
53
+ % \item\small{
54
+ % \textbf{#1}{: #2 \vspace{-2pt}}
55
+ % }
56
+ % }
57
+ \newcommand{\resumeItem}[1]{
58
+ \item\small{
59
+ {#1 \vspace{-2pt}}
60
+ }
61
+ }
62
+
63
+ % Just in case someone needs a heading that does not need to be in a list
64
+ \newcommand{\resumeHeading}[4]{
65
+ \begin{tabular*}{0.99\textwidth}[t]{l@{\extracolsep{\fill}}r}
66
+ \textbf{#1} & #2 \\
67
+ \textit{\small#3} & \textit{\small #4} \\
68
+ \end{tabular*}\vspace{-5pt}
69
+ }
70
+
71
+ \newcommand{\resumeSubheading}[4]{
72
+ \vspace{-2pt}\item
73
+ \begin{tabular*}{0.97\textwidth}[t]{l@{\extracolsep{\fill}}r}
74
+ \textbf{#1} & #2 \\
75
+ \textit{\small#3} & \textit{\small #4} \\
76
+ \end{tabular*}\vspace{-7pt}
77
+ }
78
+
79
+ \newcommand{\resumeSubSubheading}[2]{
80
+ \begin{tabular*}{0.97\textwidth}{l@{\extracolsep{\fill}}r}
81
+ \textit{\small#1} & \textit{\small #2} \\
82
+ \end{tabular*}\vspace{-7pt}
83
+ }
84
+
85
+ \newcommand{\resumeSubItem}[1]{\resumeItem{#1}\vspace{-4pt}}
86
+
87
+ \renewcommand{\labelitemii}{$\circ$}
88
+
89
+ \newcommand{\resumeSubHeadingListStart}{\begin{itemize}[leftmargin=0.15in, label={}]}
90
+ \newcommand{\resumeSubHeadingListEnd}{\end{itemize}}
91
+ \newcommand{\resumeItemListStart}{\begin{itemize}}
92
+ \newcommand{\resumeItemListEnd}{\end{itemize}\vspace{-5pt}}
93
+
94
+ \newcommand{\technologies}[1]{
95
+ \noindent\textbf{Technologies:} #1
96
+ }
97
+
98
+ \newcommand{\resumeProjectHeading}[2]{
99
+ \item
100
+ \begin{tabular*}{0.97\textwidth}{l@{\extracolsep{\fill}}r}
101
+ \small#1 & #2 \\
102
+ \end{tabular*}\vspace{-7pt}
103
+ }
104
+
105
+ \begin{document}
106
+
107
+ %----------HEADING-----------------
108
+ \begin{center}
109
+ {\LARGE \textbf{((( basic_details.name )))}} \\[4pt]
110
+ \normalsize
111
+ \href{mailto:((( basic_details.email )))}{((( basic_details.email )))} $|$
112
+ \href{tel:((( basic_details.phone )))}{((( basic_details.phone )))} $|$
113
+ \href{((( "https://www." + basic_details.github )))}{((( basic_details.github )))} $|$
114
+ \href{((( "https://www." + basic_details.linkedin )))}{((( basic_details.linkedin )))}
115
+
116
+ \end{center}
117
+
118
+ %----------SUMMARY-----------------
119
+ \section{Summary}
120
+ \resumeSubHeadingListStart
121
+ \item\small
122
+ ((( summary | safe ))) \\
123
+ \resumeSubHeadingListEnd
124
+
125
+ %-----------EDUCATION-----------------
126
+ \section{Education}
127
+ \resumeSubHeadingListStart
128
+ ((* for school in education *))
129
+ \resumeSubheading
130
+ { ((( school.institution ))) }{ ((( school.location ))) }
131
+ { ((( school.degree ))); GPA: ((( school.gpa ))) }{ ((( school.duration ))) }
132
+ ((* endfor *))
133
+ \resumeSubHeadingListEnd
134
+
135
+ %-----------EXPERIENCE-----------------
136
+ \section{Experience}
137
+ \resumeSubHeadingListStart
138
+ ((* for job in work *))
139
+ \resumeSubheading
140
+ { ((( job.company ))) }{ ((( job.location ))) }
141
+ { ((( job.role ))) }{ ((( job.duration ))) }
142
+ \resumeItemListStart
143
+ ((* for item in job.achievements *))
144
+ \resumeItem{ ((( item | safe ))) }
145
+ ((* endfor *))
146
+ \resumeItem{ \technologies{((( job.technologies | join(", ") ))) } }
147
+ \resumeItemListEnd
148
+ ((* endfor *))
149
+ \resumeSubHeadingListEnd
150
+
151
+
152
+ %-----------PROJECTS-----------------
153
+ \section{Projects}
154
+ \resumeSubHeadingListStart
155
+ ((* for proj in projects *))
156
+ \resumeProjectHeading
157
+ {\href{ ((( proj.link ))) }{ \textbf{((( proj.name )))}}((* if proj.technologies *)) $|$ \emph{((( proj.technologies | join(', ') )))}((* endif *))}
158
+ {((( proj.duration )))}
159
+ \resumeItemListStart
160
+ ((* for item in proj.description *))
161
+ \resumeItem{((( item | safe )))}
162
+ ((* endfor *))
163
+ \resumeItemListEnd
164
+ ((* endfor *))
165
+ \resumeSubHeadingListEnd
166
+
167
+ %-----------TECHNICAL SKILLS-----------------
168
+ \section{Technical Skills}
169
+ \resumeSubHeadingListStart
170
+ ((* for category in skills *))
171
+ \item\small
172
+ \begin{tabular*}{0.97\textwidth}{l@{\extracolsep{\fill}}r}
173
+ \textbf{ ((( category.name|capitalize )))}: {((( category.featured_skills | join(", ") )))} \\
174
+ \end{tabular*}\vspace{-7pt}
175
+ ((* endfor *))
176
+ \resumeSubHeadingListEnd
177
+
178
+ \end{document}
@@ -0,0 +1,44 @@
1
+ Metadata-Version: 2.4
2
+ Name: codeurcv
3
+ Version: 0.1.0
4
+ Summary: A Python library to generate LaTeX resumes from YAML configuration files using Jinja2 templates.
5
+ License: MIT
6
+ Keywords: python,digipin,coordinates
7
+ Author: crackedngineer
8
+ Author-email: subhomoyrchoudhury@gmail.com
9
+ Requires-Python: >=3.12
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3.12
12
+ Classifier: Operating System :: OS Independent
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
15
+ Classifier: Topic :: Security
16
+ Requires-Dist: jinja2 (>=3.1.6)
17
+ Requires-Dist: pydantic (>=2.12.5)
18
+ Requires-Dist: pyyaml (>=6.0.3)
19
+ Requires-Dist: rich (>=14.3.3)
20
+ Requires-Dist: typer (>=0.24.1)
21
+ Project-URL: Documentation, https://github.com/crackedngineer/code-ur-cv/
22
+ Project-URL: Homepage, https://github.com/crackedngineer/code-ur-cv
23
+ Project-URL: Repository, https://github.com/crackedngineer/code-ur-cv
24
+ Description-Content-Type: text/markdown
25
+
26
+ # Subhomoy Roy Choudhury Resume
27
+
28
+ ## Local Setup
29
+
30
+ To build and compile the resume locally using Docker:
31
+
32
+ 1. **Build the Docker image:**
33
+ ```bash
34
+ make docker-build
35
+ ```
36
+
37
+ 2. **Compile the LaTeX resume inside the container:**
38
+ ```bash
39
+ docker run --rm -v $(pwd):/workspace ghcr.io/youruser/latex-ci:latest make compile
40
+ ```
41
+
42
+ > Ensure you have [Docker](https://www.docker.com/) and [Make](https://www.gnu.org/software/make/) installed on your system.
43
+
44
+ The compiled PDF will be available in your project directory.
@@ -0,0 +1,19 @@
1
+ codeurcv/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ codeurcv/__main__.py,sha256=DK2zjOWykPtZIvszMtx2GBYbnuIq98qpYt8I1p0BBig,66
3
+ codeurcv/cli.py,sha256=2sdOHQJsfGE40PObtg19QfyJRC0z_YHl6qR_VbGo3i8,1667
4
+ codeurcv/core/constants.py,sha256=UQSPmRP9efKYB5dq--KIxatGrsTG9BIfJzQ1aJUTFb0,93
5
+ codeurcv/core/logger.py,sha256=x9_K9UwzZc7ygXqEBRwfj5Ze6OOn447eyWdJ51GH7Cc,415
6
+ codeurcv/core/markdown_converter.py,sha256=sNHIcHRM2wdIMfczO2ATwREnBGLiVdk2kVxhUhNyazc,345
7
+ codeurcv/core/plugin_loader.py,sha256=0TNullA-4FFKLbK9ANzt_8HpczzMZqmWPNmwBzl3GoQ,976
8
+ codeurcv/core/renderer.py,sha256=l7NvcBSL323ZqjzIbpOoF14WgEg0Tp7UCKwWHaWQqA4,4706
9
+ codeurcv/core/schema.py,sha256=7lEW5Fx4VC56eqR0gidv44sZQfCS_Tq4Flhru5cNP6s,1598
10
+ codeurcv/core/template_loader.py,sha256=zJytY-S8dn9WuMRl1-4XACsVdQ5cHVp1fauMfhRGQu0,630
11
+ codeurcv/plugins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
+ codeurcv/plugins/base.py,sha256=allYvP1gGXanGwo9ndLZrFb6MIfoROFsUAITGLx1kp8,708
13
+ codeurcv/plugins/minimalist/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
+ codeurcv/plugins/minimalist/plugin.py,sha256=Pzf6t0ca41xNiAr8qvoqHBiF7bKN_nd6OQZOpr1ouiM,855
15
+ codeurcv/plugins/minimalist/template.tex,sha256=hKNBWdjgWXP6CX3eusr56MTI8UBCROiRVAosGKCDipA,5036
16
+ codeurcv-0.1.0.dist-info/METADATA,sha256=OyYjzJJhYfYlgzkMAD7bG5MaxeURmWRraPuylBB-DVo,1537
17
+ codeurcv-0.1.0.dist-info/WHEEL,sha256=kJCRJT_g0adfAJzTx2GUMmS80rTJIVHRCfG0DQgLq3o,88
18
+ codeurcv-0.1.0.dist-info/entry_points.txt,sha256=aKyQXg_Xg0fHPN8T6N0wFrRzbSxc1JS2WBexEZL-NJU,55
19
+ codeurcv-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: poetry-core 2.3.1
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ codeurcv=src.codeurcv.__main__:main
3
+