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  * &lt;h1 id="heading"&gt;Heading&lt;/h1&gt;
25  * &lt;h1 id="heading-1"&gt;Heading&lt;/h1&gt;
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 }