Skip to content
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

Custom matcher #292

Open
kakone opened this issue Oct 4, 2019 · 4 comments
Open

Custom matcher #292

kakone opened this issue Oct 4, 2019 · 4 comments

Comments

@kakone
Copy link

kakone commented Oct 4, 2019

Hello,

Thanks for this great library, it's very useful. I wanted to add my own custom matcher to the matchers list. I tried this code and it works great :

let autolinker = new Autolinker();
let tagBuilder = (<any>autolinker).getTagBuilder();
(<any>autolinker).getMatchers().push(new CustomMatcher({ tagBuilder }));

So, could you make the getTagBuilder and getMatchers methods public? With these two public methods, it will be easy to add a custom matcher. Or is there another easy way to add a custom matcher ?

Cordially,
Stephane.

@domjancik
Copy link

domjancik commented Mar 21, 2021

Thanks Stephane, your snippet helped me register a custom matcher for Amazon's ARNs, based on the Mention matcher and match source

It'd be great to see this extension use case supported without hacks like this :)
Especially considering how readable and well documented the current matchers are.

Maybe it could be an extra argument passed into the Autolinker constructor even.

@kakone
Copy link
Author

kakone commented Oct 14, 2022

Unfortunately, @gregjacobs broke everything in version 4 😃. It's seems to be hard to add a custom matcher now.
I will try to propose a PR when I have time but for the moment, I stay in version 3.6.12.

@gregjacobs
Copy link
Owner

Hey @kakone, apologies! Can you tell me more about your custom matcher use case? What are you matching exactly?

I'm trying to figure out how to best allow for this custom matchers scenario. In v4.0, I changed how matching worked to combine all of the previous "matchers" into one single non-deterministic finite state machine for performance reasons. (Autolinker previously walked through the input string one time for each matcher, and now only walks through the input string exactly once.)

Are you looking to match on a regular expression? Curious as to what your current CustomMatcher class looks like.

Best,
Greg

@kakone
Copy link
Author

kakone commented Oct 14, 2022

I use autolink to handle the URLs and email adresses but I add a custom matcher for my business app : I detect the orders numbers (some purchase orders, repair orders, ...) to create a link to my web app. This is the source code of my custom matcher :

export class OrderNumberMatcher extends Matcher {
    private ordersUrls;

    constructor(cfg: MatcherConfig, ordersUrls) {
        super(cfg);
        this.ordersUrls = ordersUrls;
    }    
    
    parseMatches(text: string) {
        let matches: Match[] = [],
            match: RegExpExecArray | null;

        for (let regExp in this.ordersUrls) {
            let regularExpression = new RegExp(regExp, "g");
            while ((match = regularExpression.exec(text)) !== null) {
                matches.push(new OrderNumberMatch({
                    tagBuilder: this.tagBuilder,
                    matchedText: match[0],
                    offset: match.index
                }, this.ordersUrls[regExp]));
            }
        }

        return matches;
    }
}

ordersUrls is a dictionary where the key is a regex and the value an URL with {0} that will be replaced by the order number.

So, my OrderNumberMatch is like this :

export class OrderNumberMatch extends Match {	
    private url: string;

    constructor(cfg: MatchConfig, url: string) {
        super(cfg);
        this.url = url;
    }
	
    getType() {
        return 'orderNumber';
    }
	
    getAnchorHref() {
        return this.url.replace("{0}", this.matchedText);
    }

    getAnchorText() {
        return this.matchedText;
    }
}

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

No branches or pull requests

3 participants