12

Is there a way to convert a plain text string containing Markdown text (i.e., # heading, * list item, [a link](http://example.com), etc.) to an NSAttributedString in Swift? I suppose I could perform some kind of regex search for the indices of certain MD patterns and create the attributed string from that, but that seems clunky and feels wrong to me.

Is there an easier method?

coder
  • 8,346
  • 16
  • 39
  • 53
Matt
  • 2,576
  • 6
  • 34
  • 52
  • 2
    Yes there is a way (various) to do so. There are some third party lib that do it (Pods, GitHub, etc.). You might want to try them, and if you want to rewrite your own check how they did. Because your question is quite broad and maybe primarily opinion based, I think that's why it has been downvoted (I didn't downvote it). – Larme Jun 15 '18 at 07:36

3 Answers3

16

iOS 15 now supports Markdown parsing directly by NSAttributedString/AttributedString class.

let markdownString = "..."
let attrString = try AttributedString(markdown: markdownString)

See details here: https://developer.apple.com/documentation/foundation/attributedstring

Skie
  • 1,942
  • 16
  • 27
  • 3
    Beware! This markdown parser is not usable for display on screen. It seems to be a semantic parsing only, meaning it's up to you to convert attributes like paragraph intent (which Apple could not be bothered to document) into visible attributes. For example, lists are not formatted as lists. – George Apr 17 '22 at 23:44
  • To add to what @George stated. If you create an `NSAttributedString` with markdown, and then try to use that attributed string with the `attributedText` property of `UITextView`, `UILabel`, etc., only some basic markdown is honored. Markdown for bold, italic, strikethrough, and code will work. But titles and tables, for example, do not work at all. – HangarRash Jun 29 '23 at 00:07
13

You can try using a third party library like Down. It's a lot simpler than creating your own parsing engine.

After installing this library, you can use the following code to parse markdown strings to NSAttributedStrings:

let downMdStr = Down(markdownString: yourMarkdownString)
let attributedStr = try? down.toAttributedString()

attributedStr is an NSAttributedString. However, it may be nil if any error occurs, so remember to perform checking.

Papershine
  • 4,995
  • 2
  • 24
  • 48
  • 5
    Warning: Converting to NSAttributedString this way is extremely slow and can only be done on the main thread. Not suitable for tableviews or anything like that. Even Down converts to HTML first and then uses NSAttributedString's init that takes HTML. Painfully slow. – TylerJames Mar 24 '19 at 17:33
9

As there is no accepted answer and I had some issues with Down myself, I used SwiftMarkdown to create an attributed string from markdown. I'm happy with the result and the styling can be easily adjusted. The code basically looks like this:

let down = SwiftyMarkdown(string: markdownString)
let attributedString = down.attributedString()
1024kilobyte
  • 413
  • 4
  • 10