|
| 1 | +# -*- coding: utf-8 -*- |
1 | 2 | import re |
2 | 3 | from typing import Optional |
3 | 4 |
|
|
6 | 7 | from .csl import GetCSLJsonHook, add_get_csl_json_hook |
7 | 8 | from .error import HookNotRegisteredError, ParamsError |
8 | 9 | from .hook import ExtensionHookBase, HOOKTYPE, HookBase |
9 | | -from .utils import logger |
| 10 | +from .utils import logger, find_urls |
10 | 11 | from .word import Word |
11 | 12 | from .zotero import zotero_check_initialized, zotero_query_pages |
12 | 13 |
|
@@ -620,5 +621,87 @@ def add_format_title_hook(word: Word, upper_first_char=False, upper_all_words=Fa |
620 | 621 | return bib_format_title_hook |
621 | 622 |
|
622 | 623 |
|
623 | | -__all__ = ["BibLoopHook", "BibBookmarkHook", "BibUpdateDashSymbolHook", "BibFormatTitleHook", "add_bib_loop_hook", "add_bib_bookmark_hook", "add_update_dash_symbol_hook", |
624 | | - "add_format_title_hook"] |
| 624 | +class BibURLHyperlinkHook(ExtensionHookBase): |
| 625 | + """ |
| 626 | + This extension hook adds hyperlinks to URLs in your bibliography. |
| 627 | + """ |
| 628 | + |
| 629 | + def __init__(self, color: int = None, no_under_line=False): |
| 630 | + """ |
| 631 | + Initialize the URL hyperlink hook. |
| 632 | +
|
| 633 | + :param color: Set font color for URLs. Defaults to None (keep original color). |
| 634 | + :type color: int |
| 635 | + :param no_under_line: If remove the underline of hyperlinks. Defaults to False. |
| 636 | + :type no_under_line: bool |
| 637 | + """ |
| 638 | + super().__init__(name="BibURLHyperlinkHook") |
| 639 | + self.color = color |
| 640 | + self.no_under_line = no_under_line |
| 641 | + |
| 642 | + def on_iterate(self, word: Word, word_range): |
| 643 | + """ |
| 644 | + Process each bibliography entry to find and hyperlink URLs. |
| 645 | +
|
| 646 | + :param word: Word object. |
| 647 | + :type word: Word |
| 648 | + :param word_range: Range object of the bibliography entry. |
| 649 | + :type word_range: object |
| 650 | + """ |
| 651 | + bib_text = word_range.Text |
| 652 | + |
| 653 | + # Find URLs in the bibliography text |
| 654 | + url_positions = find_urls(bib_text) |
| 655 | + |
| 656 | + if not url_positions: |
| 657 | + return |
| 658 | + |
| 659 | + logger.debug(f"Found {len(url_positions)} URLs in bibliography entry") |
| 660 | + |
| 661 | + # Process URLs in reverse order to maintain position integrity |
| 662 | + for start_pos, end_pos, url in reversed(url_positions): |
| 663 | + # Create a duplicate range for the URL |
| 664 | + url_range = word_range.Duplicate |
| 665 | + |
| 666 | + # Move start and end positions to isolate just the URL text |
| 667 | + url_range.MoveStart(Unit=1, Count=start_pos) |
| 668 | + url_range.MoveEnd(Unit=1, Count=-(len(bib_text) - end_pos)) |
| 669 | + |
| 670 | + try: |
| 671 | + # Add hyperlink to the URL |
| 672 | + word.add_hyperlink(url, url_range, no_under_line=self.no_under_line) |
| 673 | + |
| 674 | + # Set color if specified (after adding hyperlink) |
| 675 | + if self.color is not None: |
| 676 | + url_range.Font.Color = self.color |
| 677 | + |
| 678 | + logger.debug(f"Added hyperlink for URL: {url}") |
| 679 | + |
| 680 | + except AddHyperlinkError: |
| 681 | + logger.warning(f"Failed to add hyperlink for URL: {url}") |
| 682 | + |
| 683 | + |
| 684 | +def add_url_hyperlink_hook(word: Word, color: int = None, no_under_line=False) -> BibURLHyperlinkHook: |
| 685 | + """ |
| 686 | + Register ``BibURLHyperlinkHook`` to add hyperlinks to URLs in bibliography. |
| 687 | +
|
| 688 | + :param word: ``noterools.word.Word`` object. |
| 689 | + :type word: Word |
| 690 | + :param color: Set font color for URLs. Defaults to None (keep original color). |
| 691 | + :type color: int |
| 692 | + :param no_under_line: If remove the underline of hyperlinks. Defaults to False. |
| 693 | + :type no_under_line: bool |
| 694 | + :return: ``BibURLHyperlinkHook`` instance. |
| 695 | + :rtype: BibURLHyperlinkHook |
| 696 | + """ |
| 697 | + add_get_csl_json_hook(word) # In case it's needed for future functionality |
| 698 | + url_hyperlink_hook = BibURLHyperlinkHook(color, no_under_line) |
| 699 | + bib_loop_hook = add_bib_loop_hook(word) |
| 700 | + bib_loop_hook.set_hook(url_hyperlink_hook) |
| 701 | + |
| 702 | + return url_hyperlink_hook |
| 703 | + |
| 704 | + |
| 705 | +__all__ = ["BibLoopHook", "BibBookmarkHook", "BibUpdateDashSymbolHook", "BibFormatTitleHook", |
| 706 | + "BibURLHyperlinkHook", "add_bib_loop_hook", "add_bib_bookmark_hook", |
| 707 | + "add_update_dash_symbol_hook", "add_format_title_hook", "add_url_hyperlink_hook"] |
0 commit comments