Created
October 18, 2023 15:03
-
-
Save RyushiAok/dc3ace1a2d603c79758f86579e6954df to your computer and use it in GitHub Desktop.
F# Markdown Builder
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type Block = | |
| H1 of string | |
| H2 of string | |
| P of string | |
type Markdown = { | |
title: string | |
author: string | |
blocks: Block list | |
} with | |
static member Empty = { title = ""; author = ""; blocks = [] } | |
override this.ToString() = | |
let meta = $"---\ntitle: {this.title}\nauthor: {this.author}\n---\n" | |
let md = | |
this.blocks | |
|> List.map (fun b -> | |
match b with | |
| H1 s -> sprintf "# %s" s | |
| H2 s -> sprintf "## %s" s | |
| P s -> sprintf "%s" s) | |
|> String.concat "\n" | |
meta + md | |
type MarkdownBuilder() = | |
member _.Yield(_) = Markdown.Empty | |
[<CustomOperation("title")>] | |
member _.Title(md: Markdown, s: string) = { md with title = s } | |
[<CustomOperation("author")>] | |
member _.Author(md: Markdown, s: string) = { md with author = s } | |
[<CustomOperation("h1")>] | |
member _.H1(md: Markdown, s: string) = { | |
md with | |
blocks = md.blocks @ [ H1 s ] | |
} | |
[<CustomOperation("h2")>] | |
member _.H2(md: Markdown, s: string) = { | |
md with | |
blocks = md.blocks @ [ H2 s ] | |
} | |
[<CustomOperation("p")>] | |
member _.P(md: Markdown, s: string) = { md with blocks = md.blocks @ [ P s ] } | |
let markdown = MarkdownBuilder() | |
markdown { | |
title "Markdown DSL" | |
author "Aoki" | |
h1 "Custom Operator" | |
h2 "サイコーーー!!!" | |
p "F# |> I 💛" | |
} | |
|> fun md -> md.ToString() | |
|> printfn "%s" | |
(* | |
--- | |
title: Markdown DSL | |
author: Aoki | |
--- | |
# Custom Operator | |
## サイコーーー!!! | |
F# |> I 💛 | |
*) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment