# 3 surprises when using Markdown in SwiftUI

In [WWDC 2021](https://developer.apple.com/videos/play/wwdc2021/10018/) Apple announced to add [Markdown](https://en.wikipedia.org/wiki/Markdown) support to the Foundation (hello `AttributedString`) and SwiftUI frameworks (hello `Text`) starting with iOS 15.

Here I share three little surprises with you. Those are not obvious as they are not part of the documentation.

# 1. The supported specification

A nice surprise is that SwiftUI supports [GitHub Flavored Markdown](https://github.github.com/gfm/) (GFM). This becomes obvious when trying 

```Swift
Text("Hello ~~World~~")
```

Because strikethrough, any text wrapped in two tildes ( ~ ), is not supported in [CommonMark](https://spec.commonmark.org/).

An Apple engineer confirmed the use of GFM in the [Apple Developer forum](https://developer.apple.com/forums/thread/682711).

> Yes, it is GitHub flavored markdown. AttributedString converts both inline and block styles. SwiftUI renders inline styles (but not images at this time). We use the fantastic cmark-gfm library to parse the markdown string.

The last statement about using cmark-gfm library might or might not be true anymore considering Apple's investment in [swift-markdown](https://github.com/apple/swift-markdown). `swift-markdown` is a Swift package for parsing, building, editing, and analyzing Markdown documents.

# 2. Using String variables is NOT straightforward

Using a string literal in `Text` works.

```Swift
Text("**Hello** *World*") // :)
```

Fine, but using a string variable does not!

```Swift
struct MarkdownTest: View {
  var markdown = "**Hello** *World*"
  var body: some View {
    VStack {
      Text(markdown) // shows **Hello *World* :(
    }
  }
}
```

String interpolation does not help.

```
Text("\(markdown)") // shows **Hello *World* :(
```

The trick is to use [init(_:)](https://developer.apple.com/documentation/swiftui/localizedstringkey/init(_:)) of `LocalizedStringKey`.

```Swift
Text(.init(markdown)) // :)
```

`Text` implicitly looks up a localized string when you provide a string literal. When you use the initializer `Text("Hello")`, SwiftUI creates a `LocalizedStringKey` for you and uses that to look up a localization of the Hello string. This works because `LocalizedStringKey` conforms to `ExpressibleByStringLiteral`.

You must use the same initializer to mimic the behavior and ensure that markdown formatting is displayed correctly.

# 3. Line Breaks require use of `MarkdownParsingOptions` in `AttributedString`

You might run into the situation that you have an `AttributedString` with line breaks (`\n`), but those line breaks are not displayed.

The trick is to add the `.inlineOnlyPreservingWhitespace` option when initializing the `AttributedString`.

Example:

```Swift
struct MarkdownTest: View {
    let attributedString = try! AttributedString(markdown: "**Hello** ~~*World*~~\n!", options: .init(interpretedSyntax: .inlineOnlyPreservingWhitespace))

    var body: some View {
        Text(attributedString)
    }
} 
```

Using line breaks in a regular string is no problem.

# Summary

![Summary](https://cdn.hashnode.com/res/hashnode/image/upload/v1644379264130/3kSdZ09rR.png)

