This Swift Package implements a Markdown DSL in Swift, using Result Builders and Callable Types.
let markdown = document {
section("Section") {
paragraph {
"This is a sentence."
"And this is another sentence."
}
}
section("Another Section") {
section("Subsection") {
quote {
"This is a quote in italic."
.textStyle(.italic)
}
paragraph {
"While the example below is a code block:"
}
code("swift") {
#"""
print("hello world!")
"""#
}
}
}
}
Sections are one of the most important features in a Markdown file. When writing a Markdown file it's quite easy to misuse #
, ##
, etc... without thinking of the document hierarchy. This DSL simplifies it by removing from the syntax the section level. Sections are automatically set based on the level they are in the document. Nesting sections creates subsections.
The example below
section("Title") {
// ...
}
results in
# Title
while nested sections
section("Title") {
section("Subtitle") {
// ...
}
}
result in
# Title
## Subtitle
Paragraphs are sequences of sentences. The example below
paragraph {
"This is a sentence."
"This is another sentence."
}
results in
This is a sentence. This is another sentence.
Another important element in a Markdown is a list. The example below shows a simple list
list {
"This is an item"
"This is another item"
}
which, when rendered, results in
* This is an item
* This is another item
quote {
"This is something someone said."
}
results in
> This is something someone said.
Code blocks take an additional parameter used to specify the programming language used in the block
code("swift") {
#"""
func yTown() -> String { "Berlin" }
"""#
}
results in
```swift
func yTown() -> String { "Berlin" }
```
Markdown supports bold and italic texts. These can be set using the textStyle(:)
modifier.
"bold text"
.textStyle(.bold)
results in
**bold text**
while
"italic text"
.textStyle(.italic)
results in
*italic text*
Links are also set via text modifier:
"this link"
.link("https://github.com")
results in
[this link]("https://github.com")
Modifiers can be combined to achieve the desired behavior
"this is a bold link"
.textStyle(.bold)
.link("https://github.com")
results in
[**this is a bold link**]("https://github.com")
Conditionals can be used to decide which Markdown element to display.
document {
if showShowCode {
code("swift") {
#"""
func yTown() -> String { "Berlin" }
"""#
}
} else {
paragraph {
"let's omit the code example instead"
}
}
}
For loops can be used to set a sequence of strings or Markdown elements:
document {
for value in (0..<5) {
paragraph {
"Paragraph \(value)."
}
}
paragraph {
for value in (0..<5) {
"Sentence \(value)."
}
}
}
The implementation is covered by Unit Tests, which provide additional examples on how to use and what to expect from this Swift Package.
This Package isn't supposed to be used in production. This is a simple experiment on how to use Result Builders and Callable Types. I don't have plans to maintain it, but contributions are welcomed.