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

How to implement a custom MdSpan #196

Open
ChristopherHaws opened this issue Jan 7, 2023 · 2 comments
Open

How to implement a custom MdSpan #196

ChristopherHaws opened this issue Jan 7, 2023 · 2 comments

Comments

@ChristopherHaws
Copy link

Hi there! I would like to implement a custom MdSpan but there are internal abstract methods on it so I am not able to and the implemented types are all sealed. How would I go about creating a custom span. The type of span I am trying to make is a MdShieldSpan which would be based on https://shields.io/

Thanks!

@ChristopherHaws
Copy link
Author

FYI, I found a way to do this using the implicit operator, but would like to hear if there is a better way or not. Thanks!

public abstract class CustomMdSpan {
    public abstract MdSpan AsMdSpan();
    public static implicit operator MdSpan(CustomMdSpan x) => x.AsMdSpan();
}

public class MdShieldSpan : CustomMdSpan {
    private static readonly string baseUrl = "https://img.shields.io/";

    public MdShieldSpan(string label, string message, string color) {
        this.Label = label;
        this.Message = message;
        this.Color = color;
    }
    
    public string Label { get; set; }
    public string Message { get; set; }
    public string Color { get; set; }

    public override MdSpan AsMdSpan() {
        var url = new Url(baseUrl);
        url.AppendPathSegments("static", "v1");
        url.SetQueryParams(new {
            label = this.Label,
            message = this.Message,
            color = this.Color
        });

        return new MdImageSpan(
            description: this.Label,
            uri: url
        );
    }
}

public class MdShieldLinkSpan : MdShieldSpan {
    public MdShieldLinkSpan(
        string label,
        string message,
        string color,
        string linkUrl
    ) : base(label, message, color) {
        this.LinkUrl = linkUrl;
    }

    public string LinkUrl { get; set; }

    public override MdSpan AsMdSpan() {
        var imageSpan = base.AsMdSpan();
        
        return new MdLinkSpan(
            text: imageSpan,
            uri: this.LinkUrl
        );
    }
}

@ap0llo
Copy link
Owner

ap0llo commented Jan 9, 2023

Implementing a custom MdSpan outside the MarkdownGenerator assembly is not possible at the moment.

The core issue is that MdSpan uses the Visitor pattern which requires all possible types of MdSpan implementations to be handled in ISpanVisitor.

I'd generally be open to making this less restrictive, but it requires more changes than only making the internal abstract members accessible.

I think in the current state, your solution using implicit conversions is the best way to achieve your goal (other than including MdShieldSpan in MarkdownGenerator itself)

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

2 participants