diff --git a/cli/utils/keyword_density.py b/cli/utils/keyword_density.py index 7a0df7b..c0f9b7c 100644 --- a/cli/utils/keyword_density.py +++ b/cli/utils/keyword_density.py @@ -13,6 +13,56 @@ from ..utils.config import Config from ..utils.yaml_parser import ResumeYAML +_TITLE_PATTERNS = [ + re.compile(r"(?:job title|position|title):\s*([^\n]+)", re.IGNORECASE | re.MULTILINE), + re.compile(r"^([^\n]+)\s*[-|]\s*[^|]+$", re.IGNORECASE | re.MULTILINE), + re.compile(r"#\s*([^\n]+)", re.IGNORECASE | re.MULTILINE), +] + +_COMPANY_PATTERNS = [ + re.compile(r"(?:company|organization):\s*([^\n]+)", re.IGNORECASE), + re.compile(r"(?:at|from)\s+([A-Z][^\n]+?)(?:\s+[-\u2014]|\s+$)", re.IGNORECASE), +] + +_TECH_KEYWORDS = { + "python", + "javascript", + "typescript", + "react", + "vue", + "angular", + "node.js", + "django", + "flask", + "fastapi", + "kubernetes", + "docker", + "aws", + "gcp", + "azure", + "sql", + "mongodb", + "postgresql", + "redis", + "ci/cd", + "devops", + "machine learning", + "ai", + "llm", + "pytorch", + "tensorflow", + "graphql", + "rest api", + "microservices", + "java", + "go", + "rust", + "c++", + "c#", + ".net", + "spring", +} + # Load environment variables from .env file if present try: from dotenv import load_dotenv @@ -208,26 +258,15 @@ def _extract_job_details(self, job_description: str) -> Tuple[str, str]: company = "" # Try to extract job title (common patterns) - title_patterns = [ - r"(?:job title|position|title):\s*([^\n]+)", - r"^([^\n]+)\s*[-|]\s*[^|]+$", - r"#\s*([^\n]+)", # Markdown headers often have job title - ] - - for pattern in title_patterns: - match = re.search(pattern, job_description, re.IGNORECASE | re.MULTILINE) + for pattern in _TITLE_PATTERNS: + match = pattern.search(job_description) if match: job_title = match.group(1).strip() break # Try to extract company name - company_patterns = [ - r"(?:company|organization):\s*([^\n]+)", - r"(?:at|from)\s+([A-Z][^\n]+?)(?:\s+[-\u2014]|\s+$)", - ] - - for pattern in company_patterns: - match = re.search(pattern, job_description, re.IGNORECASE) + for pattern in _COMPANY_PATTERNS: + match = pattern.search(job_description) if match: company = match.group(1).strip() break @@ -398,46 +437,7 @@ def _suggest_sections_for_keyword( suggestions = [] # Check if keyword is tech-related - tech_keywords = [ - "python", - "javascript", - "typescript", - "react", - "vue", - "angular", - "node.js", - "django", - "flask", - "fastapi", - "kubernetes", - "docker", - "aws", - "gcp", - "azure", - "sql", - "mongodb", - "postgresql", - "redis", - "ci/cd", - "devops", - "machine learning", - "ai", - "llm", - "pytorch", - "tensorflow", - "graphql", - "rest api", - "microservices", - "java", - "go", - "rust", - "c++", - "c#", - ".net", - "spring", - ] - - if keyword.lower() in tech_keywords: + if keyword.lower() in _TECH_KEYWORDS: suggestions.append("Skills section") # Check experience bullets