···177 switch a.rctx.RendererType {
178 case RendererTypeRepoMarkdown:
179 switch n := n.(type) {
00180 case *ast.Link:
181 a.rctx.relativeLinkTransformer(n)
182 case *ast.Image:
···185 }
186 case RendererTypeDefault:
187 switch n := n.(type) {
00188 case *ast.Image:
189 a.rctx.imageFromKnotAstTransformer(n)
190 a.rctx.camoImageLinkAstTransformer(n)
···199200 dst := string(link.Destination)
201202- if isAbsoluteUrl(dst) {
203 return
204 }
205···240 img.Destination = []byte(rctx.imageFromKnotTransformer(dst))
241}
24200000000000000000000000000243// actualPath decides when to join the file path with the
244// current repository directory (essentially only when the link
245// destination is relative. if it's absolute then we assume the
···259 }
260 return parsed.IsAbs()
261}
00000000
···177 switch a.rctx.RendererType {
178 case RendererTypeRepoMarkdown:
179 switch n := n.(type) {
180+ case *ast.Heading:
181+ a.rctx.anchorHeadingTransformer(n)
182 case *ast.Link:
183 a.rctx.relativeLinkTransformer(n)
184 case *ast.Image:
···187 }
188 case RendererTypeDefault:
189 switch n := n.(type) {
190+ case *ast.Heading:
191+ a.rctx.anchorHeadingTransformer(n)
192 case *ast.Image:
193 a.rctx.imageFromKnotAstTransformer(n)
194 a.rctx.camoImageLinkAstTransformer(n)
···203204 dst := string(link.Destination)
205206+ if isAbsoluteUrl(dst) || isFragment(dst) || isMail(dst) {
207 return
208 }
209···244 img.Destination = []byte(rctx.imageFromKnotTransformer(dst))
245}
246247+func (rctx *RenderContext) anchorHeadingTransformer(h *ast.Heading) {
248+ idGeneric, exists := h.AttributeString("id")
249+ if !exists {
250+ return // no id, nothing to do
251+ }
252+ id, ok := idGeneric.([]byte)
253+ if !ok {
254+ return
255+ }
256+257+ // create anchor link
258+ anchor := ast.NewLink()
259+ anchor.Destination = fmt.Appendf(nil, "#%s", string(id))
260+ anchor.SetAttribute([]byte("class"), []byte("anchor"))
261+262+ // create icon text
263+ iconText := ast.NewString([]byte("#"))
264+ anchor.AppendChild(anchor, iconText)
265+266+ // set class on heading
267+ h.SetAttribute([]byte("class"), []byte("heading"))
268+269+ // append anchor to heading
270+ h.AppendChild(h, anchor)
271+}
272+273// actualPath decides when to join the file path with the
274// current repository directory (essentially only when the link
275// destination is relative. if it's absolute then we assume the
···289 }
290 return parsed.IsAbs()
291}
292+293+func isFragment(link string) bool {
294+ return strings.HasPrefix(link, "#")
295+}
296+297+func isMail(link string) bool {
298+ return strings.HasPrefix(link, "mailto:")
299+}