diff --git a/site/docs/extensions/auto-identifiers.md b/site/docs/extensions/auto-identifiers.md
new file mode 100644
index 0000000..f3aaea7
--- /dev/null
+++ b/site/docs/extensions/auto-identifiers.md
@@ -0,0 +1,89 @@
+---
+title: Auto-identifiers
+---
+
+# Auto-identifiers
+
+Enable with `.UseAutoIdentifiers()` (included in `UseAdvancedExtensions()`).
+
+This extension automatically generates `id` attributes for all headings, similar to [Pandoc auto identifiers](https://pandoc.org/MANUAL.html#extension-auto_identifiers). This is essential for linking to specific sections.
+
+## How it works
+
+Every heading gets an `id` attribute derived from its text content:
+
+```markdown
+## Getting Started
+```
+
+Renders as:
+
+```html
+
Getting Started
+```
+
+You can then link to it:
+
+```markdown
+See [Getting Started](#getting-started).
+```
+
+## ID generation rules
+
+1. Convert to lowercase
+2. Remove anything that is not a letter, number, space, or hyphen
+3. Replace spaces with hyphens
+4. Remove leading/trailing hyphens
+
+**Examples:**
+
+{.table}
+| Heading | Generated ID |
+|---|---|
+| `# Hello World` | `hello-world` |
+| `## C# Tips & Tricks` | `c-tips--tricks` |
+| `### 2. Installation` | `2-installation` |
+
+## Duplicate handling
+
+If two headings produce the same ID, a numeric suffix is appended:
+
+```markdown
+## Section
+## Section
+## Section
+```
+
+Produces: `section`, `section-1`, `section-2`.
+
+## Options
+
+`UseAutoIdentifiers` accepts an `AutoIdentifierOptions` flags enum:
+
+```csharp
+using Markdig.Extensions.AutoIdentifiers;
+
+var pipeline = new MarkdownPipelineBuilder()
+ .UseAutoIdentifiers(AutoIdentifierOptions.GitHub)
+ .Build();
+```
+
+Available options:
+
+{.table}
+| Option | Description |
+|---|---|
+| `AutoIdentifierOptions.Default` | Standard auto-identifier behavior |
+| `AutoIdentifierOptions.GitHub` | GitHub-compatible ID generation |
+| `AutoIdentifierOptions.AutoLink` | Also create a self-link anchor |
+| `AutoIdentifierOptions.AllowOnlyAscii` | Strip non-ASCII characters from IDs |
+
+## Combining with generic attributes
+
+You can override the auto-generated ID using [Generic attributes](generic-attributes.md):
+
+```markdown
+## My Heading {#custom-id}
+```
+
+The explicit `#custom-id` takes precedence over the auto-generated one.
diff --git a/src/Markdig.Tests/TestAutoLinks.cs b/src/Markdig.Tests/TestAutoLinks.cs
index e3bb239..005c3d1 100644
--- a/src/Markdig.Tests/TestAutoLinks.cs
+++ b/src/Markdig.Tests/TestAutoLinks.cs
@@ -21,29 +21,4 @@ public class TestAutoLinks
Assert.That(html, Is.EqualTo(expected).IgnoreWhiteSpace);
}
-
- // https://github.com/xoofx/markdig/issues/668
- // A heading's implicit "AutoLink" reference (registered by the AutoIdentifiers extension) must not
- // resolve when its label is nested inside another still-open link bracket, otherwise it silently
- // breaks the outer, explicitly authored link.
- [Test]
- public void TestAutoIdentifierHeadingLinkDoesNotHijackNestedLinkLabel()
- {
- var markdown = "# Testing Markdown\n\n" +
- "### Header\n\n" +
- "[Testing [Header]](https://www.bing.com)\n\n" +
- "[Testing [test]](https://www.google.com)\n";
- var expected = "Testing Markdown
\n" +
- "\n" +
- "Testing [Header]
\n" +
- "Testing [test]
";
-
- var pipeline = new MarkdownPipelineBuilder()
- .UseAutoLinks()
- .UseAutoIdentifiers()
- .Build();
- var html = Markdown.ToHtml(markdown, pipeline);
-
- Assert.That(html, Is.EqualTo(expected).IgnoreWhiteSpace);
- }
}
diff --git a/src/Markdig/Extensions/AutoIdentifiers/HeadingLinkReferenceDefinition.cs b/src/Markdig/Extensions/AutoIdentifiers/HeadingLinkReferenceDefinition.cs
index a8b6958..32562cc 100644
--- a/src/Markdig/Extensions/AutoIdentifiers/HeadingLinkReferenceDefinition.cs
+++ b/src/Markdig/Extensions/AutoIdentifiers/HeadingLinkReferenceDefinition.cs
@@ -24,12 +24,4 @@ public class HeadingLinkReferenceDefinition : LinkReferenceDefinition
/// Gets or sets the heading related to this link reference definition.
///
public HeadingBlock Heading { get; set; }
-
- ///
- ///
- /// This reference definition is created implicitly for every heading, so it must not resolve when its
- /// label is nested inside another still-open link bracket, e.g. [Some text [HeadingText]](url).
- /// Otherwise it would silently break the outer, explicitly authored link.
- ///
- internal override bool AllowResolutionInsideOpenLink => false;
}
diff --git a/src/Markdig/Parsers/Inlines/LinkInlineParser.cs b/src/Markdig/Parsers/Inlines/LinkInlineParser.cs
index fcd1e93..83ac5db 100644
--- a/src/Markdig/Parsers/Inlines/LinkInlineParser.cs
+++ b/src/Markdig/Parsers/Inlines/LinkInlineParser.cs
@@ -150,14 +150,6 @@ public class LinkInlineParser : InlineParser
return false;
}
- // Implicitly generated reference definitions (e.g. automatic heading anchors from the auto-identifier
- // extension) must not hijack a bracket pair nested inside another still-open link, otherwise they would
- // silently break the outer, explicitly authored link (see https://github.com/xoofx/markdig/issues/668).
- if (!linkRef.AllowResolutionInsideOpenLink && HasActiveAncestorLink(parent))
- {
- return false;
- }
-
Inline? link = null;
// Try to use a callback directly defined on the LinkReferenceDefinition
if (linkRef.CreateLinkInline != null)
@@ -438,24 +430,6 @@ public class LinkInlineParser : InlineParser
}
}
- ///
- /// Determines whether the given link delimiter is nested inside another link/image delimiter that is
- /// still active, i.e. it may still be resolved into a real link/image once fully parsed.
- ///
- private static bool HasActiveAncestorLink(LinkDelimiterInline delimiter)
- {
- var inline = delimiter.Parent;
- while (inline != null)
- {
- if (inline is LinkDelimiterInline { IsActive: true })
- {
- return true;
- }
- inline = inline.Parent;
- }
- return false;
- }
-
private static void MarkParentAsInactive(Inline? inline)
{
while (inline != null)
diff --git a/src/Markdig/Syntax/LinkReferenceDefinition.cs b/src/Markdig/Syntax/LinkReferenceDefinition.cs
index c44ee06..056d91d 100644
--- a/src/Markdig/Syntax/LinkReferenceDefinition.cs
+++ b/src/Markdig/Syntax/LinkReferenceDefinition.cs
@@ -136,21 +136,6 @@ public class LinkReferenceDefinition : LeafBlock
///
public CreateLinkInlineDelegate? CreateLinkInline { get; set; }
- ///
- /// Gets a value indicating whether this reference definition is allowed to resolve into a link when its
- /// label is nested inside another link or image bracket that is still open (and may still become a valid
- /// link/image once fully parsed).
- ///
- ///
- /// This is true for regular, user-authored reference definitions so that CommonMark's "links cannot
- /// contain links" resolution order is preserved. Implicitly generated reference definitions (e.g. the
- /// automatic heading anchors created by the auto-identifier extension) override this to false so
- /// they don't silently hijack a bracket pair that is part of a larger, still-open link label, such as
- /// [Some text [HeadingText]](https://example.com) (see
- /// https://github.com/xoofx/markdig/issues/668).
- ///
- internal virtual bool AllowResolutionInsideOpenLink => true;
-
///
/// Tries to the parse the specified text into a definition.
///