-
Notifications
You must be signed in to change notification settings - Fork 99
/
update-toc.fsx
63 lines (51 loc) · 1.66 KB
/
update-toc.fsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#r "nuget: Markdig, 0.38.0"
open System
open Markdig
open System.IO
open Markdig.Renderers.Roundtrip
open Markdig.Syntax
let readmeFilePath = Path.Combine(__SOURCE_DIRECTORY__, "README.md")
let markdown = File.ReadAllText(readmeFilePath)
let document = Markdown.Parse(markdown, trackTrivia = true)
let headers =
document.Descendants<HeadingBlock>()
|> Seq.skip 2 // The document header and the Table of Contents
let getLink(header: string) =
let characters =
header
|> Seq.choose(function
| c when Char.IsLetterOrDigit c -> Some(Char.ToLowerInvariant c)
| ' ' -> Some '-'
| _ -> None
)
|> Seq.toArray
"#" + String characters
let tocText =
(
headers
|> Seq.map(fun h ->
let text = h.Inline.FirstChild.ToString()
let indent = String(' ', (h.Level - 2) * 2)
$"{indent}- [{text}]({getLink text})"
)
|> String.concat "\n"
) + "\n\n"
let updateHeader (header: HeadingBlock) (newContent: string) =
let parent = header.Parent
let index = parent.IndexOf header
while not (parent[index + 1] :? HeadingBlock) do
parent.RemoveAt(index + 1)
let newMd = Markdown.Parse(newContent, trackTrivia = true)
for block in newMd do
block.Parent.Remove block |> ignore
parent.Insert(index + 1, block)
let firstHeader =
document.Descendants<HeadingBlock>()
|> Seq.find (fun h -> h.Level = 2)
updateHeader firstHeader tocText
File.WriteAllText(readmeFilePath,
use sw = new StringWriter()
let renderer = RoundtripRenderer sw
renderer.Write document
sw.ToString()
)