MCPcopy Create free account
hub / github.com/HzaCode/OneCite / _detect_thesis

Method _detect_thesis

onecite/pipeline/identifier.py:414–513  ·  view source on GitHub ↗

Detect and search for thesis/dissertation

(self, text: str)

Source from the content-addressed store, hash-verified

412 return None
413
414 def _detect_thesis(self, text: str) -> Optional[Dict]:
415 """Detect and search for thesis/dissertation"""
416 try:
417 text_lower = text.lower()
418
419 thesis_keywords = [
420 'phd thesis', 'ph.d. thesis', 'doctoral thesis', 'dissertation',
421 'master thesis', "master's thesis", 'msc thesis', 'm.s. thesis'
422 ]
423
424 is_thesis = any(keyword in text_lower for keyword in thesis_keywords)
425
426 if not is_thesis:
427 return None
428
429 # Determine thesis type
430 is_phd = any(kw in text_lower for kw in ['phd', 'ph.d.', 'doctoral', 'dissertation'])
431 thesis_type = 'phdthesis' if is_phd else 'mastersthesis'
432
433 # Pattern: Author (Year). Title. Type. University.
434 author_match = re.match(r'^([^(]+?)\s*\(', text)
435 author = author_match.group(1).strip() if author_match else None
436
437 year_match = re.search(r'\((\d{4})\)', text)
438 year = int(year_match.group(1)) if year_match else None
439
440 title = None
441 title_pattern = r'\(\d{4}\)\.\s*(.+?)\.\s*(?:PhD|Ph\.D\.|Master|Doctoral|Dissertation)'
442 title_match = re.search(title_pattern, text, re.IGNORECASE)
443 if title_match:
444 title = title_match.group(1).strip()
445 else:
446 # Fallback: extract text after year
447 parts = text.split(')')
448 if len(parts) > 1:
449 rest = parts[1].strip().lstrip('.')
450 # Take text before thesis keyword
451 for keyword in thesis_keywords:
452 if keyword in rest.lower():
453 title = rest.split(keyword)[0].strip().rstrip('.')
454 break
455 if not title:
456 title = rest.split('.')[0].strip()
457
458 # Try to extract university/school
459 university_patterns = [
460 r'(?:PhD|Ph\.D\.|Master|Doctoral|Dissertation).*?([A-Z][^.]*?University[^.]*?)\.?\s*$',
461 r'([A-Z][^.]*?University[^.]*?)\.?\s*$',
462 ]
463
464 school = None
465 for pattern in university_patterns:
466 match = re.search(pattern, text, re.IGNORECASE)
467 if match:
468 school = match.group(1).strip().rstrip('.')
469 break
470
471 if title and len(title) > 10:

Calls 2