1 module hunt.markdown.ext.heading.anchor.HeadingAnchorExtension; 2 3 import hunt.markdown.Extension; 4 import hunt.markdown.ext.heading.anchor.internal.HeadingIdAttributeProvider; 5 import hunt.markdown.renderer.html.AttributeProvider; 6 import hunt.markdown.renderer.html.AttributeProviderContext; 7 import hunt.markdown.renderer.html.AttributeProviderFactory; 8 import hunt.markdown.renderer.html.HtmlRenderer; 9 10 /** 11 * Extension for adding auto generated IDs to headings. 12 * <p> 13 * Create it with {@link #create()} or {@link #builder()} and then configure it on the 14 * renderer builder ({@link HtmlRenderer.Builder#extensions(Iterable)}). 15 * <p> 16 * The heading text will be used to create the id. Multiple headings with the 17 * same text will result in appending a hyphen and number. For example: 18 * <pre><code> 19 * # Heading 20 * # Heading 21 * </code></pre> 22 * will result in 23 * <pre><code> 24 * <h1 id="heading">Heading</h1> 25 * <h1 id="heading-1">Heading</h1> 26 * </code></pre> 27 * 28 * @see IdGenerator the IdGenerator class if just the ID generation part is needed 29 */ 30 class HeadingAnchorExtension : HtmlRenderer.HtmlRendererExtension { 31 32 private string defaultId; 33 private string idPrefix; 34 private string idSuffix; 35 36 private this(Builder builder) { 37 this.defaultId = builder._defaultId; 38 this.idPrefix = builder._idPrefix; 39 this.idSuffix = builder._idSuffix; 40 } 41 42 /** 43 * @return the extension built with default settings 44 */ 45 public static Extension create() { 46 return new HeadingAnchorExtension(builder()); 47 } 48 49 /** 50 * @return a builder to configure the extension settings 51 */ 52 public static Builder builder() { 53 return new Builder(); 54 } 55 56 override public void extend(HtmlRenderer.Builder rendererBuilder) { 57 rendererBuilder.attributeProviderFactory(new class AttributeProviderFactory { 58 override public AttributeProvider create(AttributeProviderContext context) { 59 return HeadingIdAttributeProvider.create(defaultId, idPrefix, idSuffix); 60 } 61 }); 62 } 63 64 public static class Builder { 65 private string _defaultId = "id"; 66 private string _idPrefix = ""; 67 private string _idSuffix = ""; 68 69 /** 70 * @param value Default value for the id to take if no generated id can be extracted. Default "id" 71 * @return {@code this} 72 */ 73 public Builder defaultId(string value) { 74 this._defaultId = value; 75 return this; 76 } 77 78 /** 79 * @param value Set the value to be prepended to every id generated. Default "" 80 * @return {@code this} 81 */ 82 public Builder idPrefix(string value) { 83 this._idPrefix = value; 84 return this; 85 } 86 87 /** 88 * @param value Set the value to be appended to every id generated. Default "" 89 * @return {@code this} 90 */ 91 public Builder idSuffix(string value) { 92 this._idSuffix = value; 93 return this; 94 } 95 96 /** 97 * @return a configured extension 98 */ 99 public Extension build() { 100 return new HeadingAnchorExtension(this); 101 } 102 } 103 }