Skip to content

✨ NEW: Add linkify #78

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Dec 13, 2020
Merged

Conversation

tsutsu3
Copy link
Contributor

@tsutsu3 tsutsu3 commented Nov 15, 2020

close #5

Implement linkify with linkify-it-py

Implementation memo

  • If likify-it-py is not installed, import dummy LinkifyIt
  • Throw an exception only when linkify rule enabled, linkify option is True and likify-it-py is not installed
  • The exceptions raise at parse time, not at initialization time
  • Avoided including likify-it-py in dependency package

@codecov
Copy link

codecov bot commented Nov 15, 2020

Codecov Report

Merging #78 (994c0ad) into master (aa54b8b) will increase coverage by 0.02%.
The diff coverage is 95.78%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master      #78      +/-   ##
==========================================
+ Coverage   95.64%   95.67%   +0.02%     
==========================================
  Files          76       77       +1     
  Lines        3813     3907      +94     
==========================================
+ Hits         3647     3738      +91     
- Misses        166      169       +3     
Flag Coverage Δ
pytests 95.67% <95.78%> (+0.02%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
markdown_it/main.py 90.98% <60.00%> (-1.33%) ⬇️
markdown_it/rules_core/linkify.py 97.72% <97.72%> (ø)
markdown_it/parser_core.py 100.00% <100.00%> (ø)
markdown_it/rules_core/__init__.py 100.00% <100.00%> (ø)
markdown_it/common/utils.py 71.60% <0.00%> (+1.23%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update aa54b8b...994c0ad. Read the comment docs.

@chrisjsewell
Copy link
Member

The final piece of the puzzle!
Thanks 🙏 I should be able to have a look later today

@tsutsu3
Copy link
Contributor Author

tsutsu3 commented Nov 15, 2020

Is this implementation good?

If it's OK, increase coverage

@chrisjsewell
Copy link
Member

Well it passes all the markdown-it fixture tests. So that's always a good start 😀

@hukkinj1 might also want to have a look?

@tsutsu3 tsutsu3 marked this pull request as ready for review November 15, 2020 14:49
Copy link
Contributor

@hukkin hukkin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! I would suggest a change in how the "linkify enabled but not installed" case is handled, that should result in overall a bit less code, and avoids giving LinkifyIt.pretest a secondary task.

@@ -0,0 +1 @@
from .linkify_it import LinkifyIt # noqa: F401
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
from .linkify_it import LinkifyIt # noqa: F401

Comment on lines 1 to 43
class NotImportedError(Exception):
"""Not imported ``linkify-it-py`` package error"""

def __init__(self):
message = (
"If you want to use the 'linkify', "
+ "you must pre-install the 'linkify-it-py' package. "
+ "Please try 'pip install linkify-it-py'."
)
super().__init__(message)


class LinkifyIt:
"""linkify-it-py dummy class.

If ``linkify-it-py`` is not installed, this dummy class will be called. And
raise :class:`markdown_it.extra.linkify_it.NotImportedError` when input data
is parsed via core.rules (linkify).
"""

def __init__(self, schemas=None, options=None):
pass

# def add(self, schema, definition):
# raise NotImportedError

# def match(self, text):
# raise NotImportedError

def pretest(self, text):
raise NotImportedError

# def set(self, options):
# raise NotImportedError

# def test(self, text):
# raise NotImportedError

# def test_schema_at(self, text, name, position):
# raise NotImportedError

# def tlds(self, list_tlds, keep_old=False):
# raise NotImportedError
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
class NotImportedError(Exception):
"""Not imported ``linkify-it-py`` package error"""
def __init__(self):
message = (
"If you want to use the 'linkify', "
+ "you must pre-install the 'linkify-it-py' package. "
+ "Please try 'pip install linkify-it-py'."
)
super().__init__(message)
class LinkifyIt:
"""linkify-it-py dummy class.
If ``linkify-it-py`` is not installed, this dummy class will be called. And
raise :class:`markdown_it.extra.linkify_it.NotImportedError` when input data
is parsed via core.rules (linkify).
"""
def __init__(self, schemas=None, options=None):
pass
# def add(self, schema, definition):
# raise NotImportedError
# def match(self, text):
# raise NotImportedError
def pretest(self, text):
raise NotImportedError
# def set(self, options):
# raise NotImportedError
# def test(self, text):
# raise NotImportedError
# def test_schema_at(self, text, name, position):
# raise NotImportedError
# def tlds(self, list_tlds, keep_old=False):
# raise NotImportedError

Comment on lines 14 to 17
try:
from linkify_it import LinkifyIt
except (ImportError, ModuleNotFoundError):
from markdown_it.extra import LinkifyIt
Copy link
Contributor

@hukkin hukkin Nov 15, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
try:
from linkify_it import LinkifyIt
except (ImportError, ModuleNotFoundError):
from markdown_it.extra import LinkifyIt
try:
import linkify_it
except ModuleNotFoundError:
linkify_it = None

@@ -41,8 +46,7 @@ def __init__(
self.options = {}
self.configure(config)

# var LinkifyIt = require('linkify-it')
# self.linkify = LinkifyIt() # TODO maybe see https://github.com/Suor/autolink
self.linkify = LinkifyIt()
Copy link
Contributor

@hukkin hukkin Nov 15, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self.linkify = LinkifyIt()
self.linkify = linkify_it.LinkifyIt() if linkify_it else None

@tsutsu3
Copy link
Contributor Author

tsutsu3 commented Nov 16, 2020

Nice! I would suggest a change in how the "linkify enabled but not installed" case is handled, that should result in overall a bit less code, and avoids giving LinkifyIt.pretest a secondary task.

Oh, thanks. 😄

@tsutsu3 tsutsu3 marked this pull request as draft November 17, 2020 15:22
# We scan from the end, to keep position when new tags added.
# Use reversed logic in links start/end match
assert tokens is not None
for i in range(len(tokens))[::-1]:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just a preference thing but I personally always found reversed(iterable) more readable than iterable[::-1]

Copy link
Contributor Author

@tsutsu3 tsutsu3 Nov 18, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for statement did not calculate the index i correctly.

So I changed to a while statement.

4a97b09

return

if not state.md.linkify:
raise Exception("Linkify enabed but not installed.")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
raise Exception("Linkify enabed but not installed.")
raise Exception("Linkify enabled but not installed.")

There's a typo here which originates from my suggestion. Sorry! Btw, the text was just something I just quickly made up, dont know, maybe we want it to be more elaborate somehow @chrisjsewell ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, maybe it could be justified to make the exception type ModuleNotFoundError ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or ImportError?

I'm worried about exception type. 🤔

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'd vote for ModuleNotFoundError (a subclass of ImportError, a bit more precise) as it's equivalent to the root cause of the issue here (the exception we suppress inmarkdown_it/main.py line 16, and never need to raise unless this line runs).

@tsutsu3 tsutsu3 marked this pull request as ready for review November 18, 2020 11:30
Comment on lines 48 to 51
while i >= 0:
i -= 1
if i < 0:
break
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
while i >= 0:
i -= 1
if i < 0:
break
while i >= 1:
i -= 1

Wouldn't this do the same thing?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, same 😲

@chrisjsewell chrisjsewell requested a review from hukkin December 13, 2020 13:42
@chrisjsewell
Copy link
Member

@hukkinj1 have you got any more notes on this?

hukkin
hukkin previously approved these changes Dec 13, 2020
Copy link
Contributor

@hukkin hukkin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks very good to me!

Copy link
Member

@chrisjsewell chrisjsewell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks @tsutsu3 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Finalise port of non-standard rules to python
3 participants