Repository: tsutsu3/linkify-it-py

Issue:
Support for linkify-it update (Add matchAtStart method)
https://github.com/markdown-it/linkify-it/commit/945df9f192ac091482c8c89896a4a48f4e8b76a9

Discussion:
codecov-commenter: # [Codecov](https://codecov.io/gh/tsutsu3/linkify-it-py/pull/31?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) Report
> Merging [#31](https://codecov.io/gh/tsutsu3/linkify-it-py/pull/31?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) (03b8ff0) into [main](https://codecov.io/gh/tsutsu3/linkify-it-py/commit/06839ccea16f611dae13ad52dd8a8e011a03abcb?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) (06839cc) will **decrease** coverage by `0.50%`.
> The diff coverage is `88.23%`.

```diff
@@            Coverage Diff             @@
##             main      #31      +/-   ##
==========================================
- Coverage   97.66%   97.16%   -0.51%     
==========================================
  Files           4        4              
  Lines         300      317      +17     
  Branches       54       57       +3     
==========================================
+ Hits          293      308      +15     
- Misses          4        5       +1     
- Partials        3        4       +1     
```

| Flag | Coverage Δ | |
|---|---|---|
| pytests | `97.16% <88.23%> (-0.51%)` | :arrow_down: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Impacted Files](https://codecov.io/gh/tsutsu3/linkify-it-py/pull/31?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) | Coverage Δ | |
|---|---|---|
| [linkify\_it/main.py](https://codecov.io/gh/tsutsu3/linkify-it-py/pull/31/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-bGlua2lmeV9pdC9tYWluLnB5) | `96.66% <88.23%> (-0.57%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/tsutsu3/linkify-it-py/pull/31?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/tsutsu3/linkify-it-py/pull/31?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None). Last update [06839cc...03b8ff0](https://codecov.io/gh/tsutsu3/linkify-it-py/pull/31?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None).


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c4e0d49..2cb51fd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
 # Change Log
 
+## vx.x.x (2022-xx-xx) / Draft
+
+- Add `matchAtStart` method to match full URLs at the start of the string.
+
 ## v1.0.3 (2021-12-18)
 
 - Fixed [#98](https://github.com/markdown-it/linkify-it/issues/98). Don't count `;` at the end of link (when followed with space).
diff --git a/README.md b/README.md
index bd45d54..439c647 100644
--- a/README.md
+++ b/README.md
@@ -185,6 +185,11 @@ Each match has:
 - __text__ - normalized text
 - __url__ - link, generated from matched text
 
+### .matchAtStart(text)
+
+Checks if a match exists at the start of the string. Returns `Match`
+(see docs for `match(text)`) or null if no URL is at the start.
+Doesn't work with fuzzy links.
 
 ### .tlds(list_tlds, keep_old=False)
 
diff --git a/linkify_it/main.py b/linkify_it/main.py
index 8d9254b..6aa8903 100644
--- a/linkify_it/main.py
+++ b/linkify_it/main.py
@@ -361,6 +361,7 @@ class LinkifyIt:
         # (?!_) cause 1.5x slowdown
         self.re["schema_test"] = re_schema_test
         self.re["schema_search"] = re_schema_test
+        self.re["schema_at_start"] = "^" + self.re["schema_search"]
 
         self.re["pretest"] = (
             "(" + re_schema_test + ")|(" + self.re["host_fuzzy_test"] + ")|@"
@@ -559,6 +560,38 @@ class LinkifyIt:
 
         return None
 
+    def match_at_start(self, text):
+        """Returns fully-formed (not fuzzy) link if it starts at the beginning
+        of the string, and null otherwise.
+
+        Args:
+            text (str): text to search
+
+        Retuns:
+            ``Match`` or ``None``
+        """
+        # Reset scan cache
+        self._text_cache = text
+        self._index = -1
+
+        if not len(text):
+            return None
+
+        founds = re.search(self.re["schema_at_start"], text, flags=re.IGNORECASE)
+        if not founds:
+            return None
+
+        m = (founds.group(), founds.groups()[0], founds.groups()[1])
+        length = self.test_schema_at(text, m[2], len(m[0]))
+        if not length:
+            return None
+
+        self._schema = m[2]
+        self._index = founds.start(0) + len(m[1])
+        self._last_index = founds.start(0) + len(m[0]) + length
+
+        return self._create_match(0)
+
     def tlds(self, list_tlds, keep_old=False):
         """Load (or merge) new tlds list. (chainable)
 


Test patch:
diff --git a/test/test_apis.py b/test/test_apis.py
index 093f293..20c71db 100644
--- a/test/test_apis.py
+++ b/test/test_apis.py
@@ -280,3 +280,40 @@ def test_api_add_alias_rule_with_excape_re_string(escape_str):
 
     linkifyit.add("foo{}bar:".format(escape_str), "http:")
     assert linkifyit.test("Check foo{}bar://test".format(escape_str)) is True
+
+
+def test_api_blank_test_match_at_the_start():
+    linkifyit = LinkifyIt()
+
+    assert not linkifyit.match_at_start("")
+
+
+def test_api_should_find_a_match_at_the_start():
+    linkifyit = LinkifyIt()
+
+    linkifyit = LinkifyIt(options={"fuzzy_link": True})
+    linkifyit.set({"fuzzy_link": True})
+
+    assert not linkifyit.test("@@invalid")
+    assert not linkifyit.match_at_start("google.com 123")
+    assert not linkifyit.match_at_start("  http://google.com 123")
+
+
+def test_api_match_a_start_should_not_interfere_with_normal_match():
+    linkifyit = LinkifyIt()
+
+    str = "http://google.com http://google.com"
+    assert linkifyit.match_at_start(str)
+    assert len(linkifyit.match(str)) == 2
+
+    str = "aaa http://google.com http://google.com"
+    assert not linkifyit.match_at_start(str)
+    assert len(linkifyit.match(str)) == 2
+
+
+def test_api_should_not_match_incomplete_links():
+    # regression test for https://github.com/markdown-it/markdown-it/issues/868
+    linkifyit = LinkifyIt()
+
+    assert not linkifyit.match_at_start("http://")
+    assert not linkifyit.match_at_start("https://")