Infer title and author byline from the first page text.
(lines: List[str])
| 389 | |
| 390 | |
| 391 | def extract_title_and_authors(lines: List[str]) -> Dict[str, Any]: |
| 392 | """Infer title and author byline from the first page text.""" |
| 393 | metadata: Dict[str, Any] = {"title": "", "authors": []} |
| 394 | if not lines: |
| 395 | return metadata |
| 396 | |
| 397 | title_lines: List[str] = [] |
| 398 | title_end_idx = -1 |
| 399 | for index, raw_line in enumerate(lines[:25]): |
| 400 | line = raw_line.strip() |
| 401 | if not line: |
| 402 | continue |
| 403 | if line.startswith("http"): |
| 404 | continue |
| 405 | if is_section_heading(line): |
| 406 | continue |
| 407 | if len(line) < 6: |
| 408 | continue |
| 409 | title_lines.append(line) |
| 410 | title_end_idx = index |
| 411 | for follow_idx in range(index + 1, min(index + 4, len(lines))): |
| 412 | follow_line = lines[follow_idx].strip() |
| 413 | if not follow_line: |
| 414 | break |
| 415 | if is_section_heading(follow_line) or split_author_names(follow_line): |
| 416 | break |
| 417 | if follow_line.startswith("http") or re.match(r"^\d+[\.\)]", follow_line): |
| 418 | break |
| 419 | if len(" ".join(title_lines + [follow_line])) > 180: |
| 420 | break |
| 421 | title_lines.append(follow_line) |
| 422 | title_end_idx = follow_idx |
| 423 | break |
| 424 | |
| 425 | if title_lines: |
| 426 | metadata["title"] = " ".join(title_lines) |
| 427 | |
| 428 | for line in lines[title_end_idx + 1:title_end_idx + 6]: |
| 429 | authors = split_author_names(line) |
| 430 | if authors: |
| 431 | metadata["authors"] = authors |
| 432 | break |
| 433 | if line.strip() and (is_section_heading(line) or re.match(r"^\d+[\.\)]", line.strip())): |
| 434 | break |
| 435 | |
| 436 | return metadata |
| 437 | |
| 438 | |
| 439 | def extract_abstract(text: str) -> str: |
no test coverage detected