Skip to content

BREAKING CHANGE: Don't allow dots (.) in slug #1093

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

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions src/Elastic.Markdown/Helpers/SlugExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,14 @@ namespace Elastic.Markdown.Helpers;

public static class SlugExtensions
{
private static readonly SlugHelper Instance = new();
private static readonly SlugHelper Instance = InitSlugHelper();

public static string Slugify(this string? text) => Instance.GenerateSlug(text);
private static SlugHelper InitSlugHelper()
{
var config = new SlugHelperConfiguration();
_ = config.AllowedChars.Remove('.');
return new SlugHelper(config);
}

public static string Slugify(this string? text) => Instance.GenerateSlug(text);
}
8 changes: 3 additions & 5 deletions src/Elastic.Markdown/Myst/SectionedHeadingRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,9 @@ protected override void Write(HtmlRenderer renderer, HeadingBlock obj)
var header = obj.GetData("header") as string;
var anchor = obj.GetData("anchor") as string;

var slugTarget = (anchor ?? header) ?? string.Empty;
if (slugTarget.Contains('$'))
slugTarget = HeadingAnchorParser.InlineAnchors().Replace(slugTarget, "");

var slug = slugTarget.Slugify();
var slug = anchor ?? header.Slugify();
if (slug.Contains('$'))
slug = HeadingAnchorParser.InlineAnchors().Replace(slug, "");
Copy link
Member

Choose a reason for hiding this comment

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

I do think we want to always sanitize anchor or header through Slugify().

What was the usecase for removing it from anchor?

Copy link
Member Author

@reakaleek reakaleek Apr 11, 2025

Choose a reason for hiding this comment

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

Sorry, currently working on this. Switched back to draft.

But I was thinking of limiting the blast radius.

If someone creates a custom anchor, we might want to maintain the dot.

Copy link
Member

Choose a reason for hiding this comment

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

I think having uniformity in our slugging beats allowing dots in custom anchors.

The main reason might be version numbers but they look okay without dots too e.g

#whats-new-in-8.18

vs

#whats-new-in-8-18

I actually prefer the latter visually too.

Copy link
Member Author

@reakaleek reakaleek Apr 11, 2025

Choose a reason for hiding this comment

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

The slight problem here is that it seems like the default markdown behaviour is to strip the . and not replace it with -.

Screenshot 2025-04-11 at 11 52 55

Hence, it would become #whats-new-in-818

Copy link
Member

Choose a reason for hiding this comment

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

ahh but that discrepancy exists today already no?

If someone writes

## Whats new in 8.18

We slug to: whats-new-in-8-18 today?

## Whats new in 8.18 [whats-new-in-8.18]

I do think that should also be sanitized the same way to whats-new-in-8-18.

We shouldn't take anchors verbatim and having two sanitation rules is a bit suprising to writers IMO.

Copy link
Member

Choose a reason for hiding this comment

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

  • The numbering gets removed (maybe this is intended?)
  • As a consequence, the anchor is generated differently which breaks the navigation functionality (clicking on the navbar link does nothing)

Copy link
Member Author

Choose a reason for hiding this comment

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

💩

Copy link
Member Author

Choose a reason for hiding this comment

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

One problem I just thought of is the authoring experience.

It will be confusing if you set a custom anchor and then it's sanitized.

E.g.

If I add the custom anchor #whats-new-in-8.0 I would expect it to stay like that.

It could be confusing to see that it changed to #whats-new-in-8-0.

Maybe the best way is to actually to discourage dots (.) in anchors and make it error?

Copy link
Member

Choose a reason for hiding this comment

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

We need to sanitize custom anchors anyhoo e.g #What's-new-in-8.0 we can not take it verbatim. The sanitization is not surprising to me but thats subjective :)

We could hint if custom anchors end up different after sanitization?

Copy link
Member Author

Choose a reason for hiding this comment

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

@flobernd #1094 should fix the bug you reported.


_ = renderer.Write(@"<div class=""heading-wrapper"" id=""")
.Write(slug)
Expand Down
Loading