Skip to content

Conversation

@sunjay
Copy link
Contributor

@sunjay sunjay commented Feb 12, 2019

Wow! This implementation is so much simpler than #98. I totally get why pulldown-cmark went with this.


This PR adds a new method parse_document_with_broken_link_callback which allows you to pass in a function/closure which will be used to resolve broken reference links. This is similar in spirit (but quite different in reality) than the method that pulldown-cmark has for this.

I think the approach I've taken here is even more flexible than pulldown-cmark. Our closure is FnMut instead of Fn which means that the user can do whatever they want in the closure to resolve the broken reference. We also use byte slices instead of string slices since that is conventionally what is used throughout the rest of this library.

The change has been tested locally and I added a doctest that both documents how to use this and to show that it really works.

I copied the additional comments I added in my previous PR to this PR so the codebase still improves even though we went with a different approach. :)

If these changes work and they get merged, feel free to close my other PR. 😄 🎉

Documentation Screenshot

image

Compatibility

Unlike my previous PR (#98), this PR is actually completely backwards compatible. By adding a new function and implementing the old one in terms of that, none of my changes can break anyone's code. Feel free to just bump the patch version and release this when it is ready. 🎉

@sunjay sunjay mentioned this pull request Feb 12, 2019
Copy link
Owner

@kivikakk kivikakk left a comment

Choose a reason for hiding this comment

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

I love this! Thank you for bringing the comments across from #98 too, this is great!

One query: do you think it'd be possible to roll the callback into ComrakOptions? The lifetimes on that thing make me think it might be tricky, but it could be cleaner.

I'm going to merge this right away and leave that in your hands. Thank you so much!

// Need to borrow the callback from the parser only for the lifetime of the Subject, 'subj, and
// then give it back when the Subject goes out of scope. Needs to be a mutable reference so we
// can call the FnMut and let it mutate its captured variables.
callback: Option<&'subj mut &'c mut dyn FnMut(&[u8]) -> Option<(Vec<u8>, Vec<u8>)>>,
Copy link
Owner

Choose a reason for hiding this comment

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

jaw drop

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Heh. I totally agree that this super ugly! I spent a long time staring at it trying to figure out if it could be made nicer. Unfortunately, it can't because of two things:

  1. we need a reference to the closure because you can only have one instance of a mutable reference at any given time. You can futher borrow that reference (as we have done here), and the only other alternative is moving the reference around everywhere which is far more ugly!
  2. you can only use a mutable reference through another mutable reference. You can't use it through an immutable reference. So &'a &'b mut would not work.

It's ugly, but it gives us memory safety so I guess it's okay! 😭 😆

@kivikakk kivikakk merged commit 040ef72 into kivikakk:master Feb 12, 2019
@sunjay
Copy link
Contributor Author

sunjay commented Feb 12, 2019

Thank you! ❤️ I'm really excited to see these changes get released! 🎉

I thought about adding this to the options struct, but I feel like that would only pass on the ugliness to the user (if they store the options) instead of making it any easier to us. This way, the user doesn't need to worry about any of the lifetime madness, we take care of it all internally and they just have to pass a simple callback to our function. :)

@sunjay sunjay deleted the broken-refs-v2 branch February 12, 2019 01:01
@kivikakk
Copy link
Owner

Your reasoning is super solid -- thank you!

I'll make the point release now 👍

@kivikakk
Copy link
Owner

Done! https://crates.io/crates/comrak/0.4.2

Thank you so much for helping out. 🙏

@sunjay
Copy link
Contributor Author

sunjay commented Feb 12, 2019

Thank you for being so responsive and helping me when I needed it! 😄 🎉

@sunjay sunjay restored the broken-refs-v2 branch February 12, 2019 02:49
@brson
Copy link
Collaborator

brson commented Feb 13, 2019

Amazing work you've been doing @sunjay ! Kudos.

@sunjay sunjay deleted the broken-refs-v2 branch February 13, 2019 00:44
@sunjay
Copy link
Contributor Author

sunjay commented Feb 13, 2019

Thank you @brson! Happy to help out! 😄

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.

3 participants