A simple and customizable Markdown Parser for Swift

Related tags

Text MarkdownKit
Overview

Logo

MarkdownKit

Version Carthage compatible License Platform CI

MarkdownKit is a customizable and extensible Markdown parser for iOS and macOS. It supports many of the standard Markdown elements through the use of Regular Expressions. It also allows customization of font and color attributes for all the Markdown elements.

Screenshot

Example

Installation

Installation via CocoaPods

MarkdownKit is available through CocoaPods. CocoaPods is a dependency manager that automates and simplifies the process of using 3rd-party libraries like MarkdownKit in your projects. You can install CocoaPods with the following command:

gem install cocoapods

To integrate MarkdownKit into your Xcode project using CocoaPods, simply add the following line to your Podfile:

pod "MarkdownKit"

Afterwards, run the following command:

pod install

Installation via Carthage

MarkdownKit is available through Carthage. Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks.

You can install Carthage via Homebrew with the following command:

brew update
brew install carthage

To integrate MarkdownKit into your Xcode project using Carthage, simply add the following line to your Cartfile:

github "ivanbruel/MarkdownKit"

Afterwards, run the following command:

carthage update --use-xcframeworks

Installation via Swift Package Manager

MarkdownKit is available through Swift Package Manager.

To add MarkdownKit as a dependency of your Swift package, simply add the following line to your Package.swift file:

.package(url: "https://github.com/bmoliveira/MarkdownKit.git", from: "1.7.0")

Supported Elements

*italic* or _italics_
**bold** or __bold__
~~strikethrough~~

# Header 1
## Header 2
### Header 3
#### Header 4
##### Header 5
###### Header 6

> Quote

* List
- List
+ List

`code` or ```code```
[Links](http://github.com/ivanbruel/MarkdownKit/)

Usage

In order to use MarkdownKit to transform Markdown into NSAttributedString, all you have to do is create an instance of MarkdownParser and call the parse(_) function.

let markdownParser = MarkdownParser()
let markdown = "I support a *lot* of custom Markdown **Elements**, even `code`!"
label.attributedText = markdownParser.parse(markdown)

Customization

let markdownParser = MarkdownParser(font: UIFont.systemFont(ofSize: 18))
markdownParser.enabledElements = .disabledAutomaticLink
markdownParser.bold.color = UIColor.red
markdownParser.italic.font = UIFont.italicSystemFont(ofSize: 300)
markdownParser.header.fontIncrease = 4

Extensibility

To add new Markdown elements all you have to do is implement the MarkdownElement protocol (or descendants) and add it to the MarkdownParser.

import MarkdownKit

class MarkdownSubreddit: MarkdownLink {

  private static let regex = "(^|\\s|\\W)(/?r/(\\w+)/?)"

  override var regex: String {
    return MarkdownSubreddit.regex
  }

  override func match(match: NSTextCheckingResult,
                             attributedString: NSMutableAttributedString) {
    let subredditName = attributedString.attributedSubstringFromRange(match.rangeAtIndex(3)).string
    let linkURLString = "http://reddit.com/r/\(subredditName)"
    formatText(attributedString, range: match.range, link: linkURLString)
    addAttributes(attributedString, range: match.range, link: linkURLString)
  }

}
let markdownParser = MarkdownParser(customElements: [MarkdownSubreddit()])
let markdown = "**/r/iosprogramming** can be *markdown* as well!"
label.attributedText = markdownParser.parse(markdown)

Example

To run the example project, clone the repo, and run pod install from the Example directory first.

Acknowledgements

This library is heavily inspired in TSMarkdownParser and also SwiftyMarkdown.

Special thanks to Michael Brown for helping out with the UTF-16 Escaping/Unescaping.

License

MarkdownKit is available under the MIT license. See the LICENSE file for more info.

Comments
  • Color of

    Color of "regular" text

    In my case I have this string that is displayed as a button label. "Already registered? **Login**"

           let parser = MarkdownParser(font: UIFont.systemFont(ofSize: 17))
            parser.automaticLinkDetectionEnabled = false
            parser.bold.color = UIColor.white
            parser.header.color = UIColor.white
    

    My problem is that "Already registered?" is displayed in blue and "Login" is white as set by bold-attribute. How can the color for regular text be set? Why is it set to blue?

    opened by ogezue 7
  • Combined bold and italic formatting doesn't work as expected.

    Combined bold and italic formatting doesn't work as expected.

    First of all: Awesome framework, thank you for open-sourcing it! 👍


    When nesting emphasis and strong delimiters (i.e. bold and italic delimiters) as follows:

    _**word**_
    

    I would expect word to be formatted both bold and italic:

    word

    This is specified in the CommonMark Spec and as you can see above, it's also the default behavior on GitHub.

    The MarkdownKit parser currently formats the Markdown input above as only italic:

    word

    I would suggest to change the parser's behavior according to the specification.

    opened by mischa-hildebrand 5
  • Fix parsing of markdown code element

    Fix parsing of markdown code element

    This solves issue #8 whereby 2 anomalies occurred constantly when parsing grave accent to represent markdown element code. For example, let c1 = this is code, c2 = this is code too

    1. When either c1 or c2 occurs at the the beginning of a file, it will cause a runtime error.

    2. When either c1 or c2 occurs somewhere within the file, it doesn't cause a runtime error but as explained in #8, it outputs a random string of numbers.

    After further investigation, the culprit is in the regex string: "(?<!\\\\)(?:\\\\\\\\)*+(+)(._?[^]._?)(\1)(?!)"`. I am not good at regex yet but that's where the issue is. So, in my implementation, I modified the regex string and no anomaly occurs and thus no runtime error.

    opened by yohannes 5
  • Example does not compile

    Example does not compile

    Hello,

    I'm just trying to use your code. I download Example project but I have a compilation Error

    ld: warning: directory not found for option '-F/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator9.3.sdk/Developer/Library/Frameworks'

    Can you please help

    opened by ghost 5
  • App crash on link markdown

    App crash on link markdown

    The app is crashing on this format of link: [(William) Davenport Griffen](/artists/(william)-davenport-griffen)

    The issue is with the name William in brackets. It seems that the framework treats (William) as a separate link.. instead of just a plain text. The app is crashing in the MarkdownLink.swift file on formatText function.

    @bmoliveira

    opened by victormihaita 3
  • Fix build for macCatalyst

    Fix build for macCatalyst

    Currently library fails to build when targeting Mac Catalyst platform. It happens due to canImport(AppKit) pre-compile check which is true on Mac Catalyst, but many APIs like NSFont still are not available. This PR adds targetEnvironment checks.

    opened by ky1vstar 2
  • Carthage Install Failing

    Carthage Install Failing

    I'm trying to install via Carthage on Xcode 12.2 and keep getting this error:

    *** Building scheme "MarkdownKit-AppKit" in MarkdownKit.xcworkspace
    *** Building scheme "MarkdownKit" in MarkdownKit.xcworkspace
    Build Failed
    	Task failed with exit code 1:
    	/usr/bin/xcrun lipo -create /Users/tj/Library/Caches/org.carthage.CarthageKit/DerivedData/12.2_12B45b/MarkdownKit/1.7.0/Build/Intermediates.noindex/ArchiveIntermediates/MarkdownKit/IntermediateBuildFilesPath/UninstalledProducts/iphoneos/MarkdownKit.framework/MarkdownKit /Users/tj/Library/Caches/org.carthage.CarthageKit/DerivedData/12.2_12B45b/MarkdownKit/1.7.0/Build/Products/Release-iphonesimulator/MarkdownKit.framework/MarkdownKit -output /Volumes/VNStorage/Repos/iosSwitchbacks/switchbacks-ios/Carthage/Build/iOS/MarkdownKit.framework/MarkdownKit
    
    This usually indicates that project itself failed to compile. Please check the xcodebuild log for more details: /var/folders/yt/zk5_9dxd08b_4gpddjpl6qx00000gn/T/carthage-xcodebuild.RtHQE3.log
    

    Is this because Xcode 12.2 (Swift 5.3.1) is not supported? Or maybe arm64 architecture needs to be excluded?

    opened by tjolsen-vn 2
  • Errors occur when installing via Swift Package Manager

    Errors occur when installing via Swift Package Manager

    If you go to File > Swift Packages > Add Package Dependency, paste in https://github.com/bmoliveira/MarkdownKit.git, click Next, leave it at the default up to 1.4.1 rule, click Next, you'll get an error stating:

    https://github.com/bmoliveira/MarkdownKit.git has no Package.swift manifest for version 1.4.1 in https://github.com/bmoliveira/MarkdownKit.git

    If you instead put in 1.7.0 as is implied in the Readme, you'll get an error stating:

    Dependencies could not be resolved because no versions of 'MarkdownKit' match the requirement 1.7.0..<2.0.0 and root depends on 'MarkdownKit' 1.7.0..<2.0.0.

    Screen Shot 2021-03-22 at 1 33 50 PM
    opened by jordanhbuiltbyhq 2
  • Links without explicit schemes formatted but not working

    Links without explicit schemes formatted but not working

    Steps to reproduce

    1. Parse a markdown text containing links without explicit schemes:
    let markdownParser = MarkdownParser()
    let markdown = """
        Link with implicit scheme: old.reddit.com
        Link with explicit scheme: https://old.reddit.com/
        """
    textView.attributedText = markdownParser.parse(markdown)
    
    1. Observe that the link with the implicit scheme is formatted as a link
    2. Select the link

    Expected behaviour Either the link is opened in Safari, or the text is not formatted as a link at all

    Actual behaviour

    • The link is formatted as a link
    • Selecting the link does nothing
    • Printed to console: Could not find any actions for URL old.reddit.com without any result.

    My suggestion would be to have an option for a default scheme for links that is added if the scheme is nil.

    opened by rberggreen 2
  • Crash in `String+UTF16.swift` - `unescapeUTF16()`

    Crash in `String+UTF16.swift` - `unescapeUTF16()`

    I have experienced a crash in the unescapeUTF16 method in String+UTF16.swift. The markdown that led to the crash can be found here: https://github.com/apple/swift-evolution/blob/master/proposals/0240-ordered-collection-diffing.md

    The crash was found on the line let endIndex = index(self.startIndex, offsetBy: $0 + 4) in the following code snippet:

    stride(from: 0, to: count, by: 4).forEach {
        let startIndex = index(self.startIndex, offsetBy: $0)
        let endIndex = index(self.startIndex, offsetBy: $0 + 4)
        let hex4 = String(self[startIndex..<endIndex])
        if let utf16 = UInt16(hex4, radix: 16) {
            utf16Array.append(utf16)
        }
    }
    
    opened by Frederiks96 2
  • Abandoned????

    Abandoned????

    Since the maintainer appears to have abandoned this, I have cloned and renamed this project, and merged most of the outstanding PRs manually. I also support Swift 4. New PRs are welcomed as well. https://github.com/davidlari/Haring

    opened by DavidLari 2
  • Fails to parse markdown starting or ending with a whitespace

    Fails to parse markdown starting or ending with a whitespace

    The parser fails to parse this string:**Kids ** has arrived at **UAT Test**

    Expected result: Kids has arrived at Test

    Actual result: Kids ** has arrived at ** UAT Test

    Version 1.7.1 used

    opened by theedov 0
  • Three ticks and new lines

    Three ticks and new lines

    Parsing new lines inside 3 ticks ( ``` ) is returning with a weird format. It'll show a tick at the beginning and the end, and the content will format as if I had only used one tick.

    opened by mathist 0
  • Bad parsing result

    Bad parsing result

    If I try to parse: "``Why did the scarecrow win an award? Because he was outstanding in his field.``" The resulted string value is "뻊"

    If I add a space at the beginning and pass in: " ``Why did the scarecrow win an award? Because he was outstanding in his field.``"

    Then it parses properly.

    opened by mathist 0
  • Combination of italic with custom markdown element not working

    Combination of italic with custom markdown element not working

    Reproducible for the case when text has mixed text-decoration style with custom markdown element. In my case. I have the custom element that not supports by markdown be default - underline(++). I implement the custom markdown element for parsing (like MarkdownStrikethrough).

    class MarkdownUnderline: MarkdownCommonElement {
    	
    	var font: MarkdownFont?
    	var color: MarkdownColor?
    	
    	private static let regex = "(.?|^)(\\+\\+)(?=\\S)(.+?)(?<=\\S)(\\2)"
    
    	var regex: String {
    		return MarkdownUnderline.regex
    	}
    	
    	public init(font: MarkdownFont?, color: MarkdownColor? = nil) {
    		self.font = font
    		self.color = color
    	}
    	
    	public func match(_ match: NSTextCheckingResult, attributedString: NSMutableAttributedString) {
    		attributedString.deleteCharacters(in: match.range(at: 4))
    
    		var attributes = attributedString.attributes(
    			at: match.range(at: 3).location,
    			longestEffectiveRange: nil,
    			in: match.range(at: 3)
    		)
    
    		attributes[.underlineStyle] = NSNumber.init(value: NSUnderlineStyle.single.rawValue)
    
    		attributedString.addAttributes(attributes, range: match.range(at: 3))
    
    		attributedString.deleteCharacters(in: match.range(at: 2))
    	}
    }
    

    But parsing result is not correct, for example for text **_++Lorem ipsum++_** will be produced the attributed text: image

    _++Lorem ipsum++_ image

    If I change the regex to (.?|^)(\\*|_)(?=\\S)(.+?)(?<=\\S)(\\2) ,that was implemented for fix, the parsing result is correct.

    opened by S2V 4
Releases(1.7.1)
Owner
Bruno Oliveira
Mobile developer @Doist and a Kotlin and FRP lover
Bruno Oliveira
Leverages Apple's Swift-based Markdown parser to output NSAttributedString.

Markdownosaur ?? Markdownosaur uses Apple's excellent and relatively new Swift Markdown library to analyze a Markdown source, and then takes that anal

Christian Selig 232 Dec 20, 2022
Markdown parser for iOS

Marky Mark Marky Mark is a parser written in Swift that converts markdown into native views. The way it looks it highly customizable and the supported

M2mobi 254 Jun 11, 2021
Markdown parser for iOS

Marky Mark Marky Mark is a parser written in Swift that converts markdown into native views. The way it looks it highly customizable and the supported

M2mobi 262 Nov 23, 2021
Simple, keyboard-first, markdown note-taking for MacOS

QuickDown Simple, keyboard-first, markdown note-taking for MacOS Main Features Global Hotkey: ⌘-⌥-N Save Note: ⌘-S Launch on Login (Optional) Addition

Alexis Rondeau 50 Nov 29, 2022
A simple Cron Parser with Swift

A simplified cron parser Requirements Swift 5.5 Command line tools How to Run Cr

null 0 Dec 21, 2021
Markdown parsing and rendering for iOS and OS X

CocoaMarkdown Markdown parsing and rendering for iOS and macOS CocoaMarkdown is a cross-platform framework for parsing and rendering Markdown, built o

Indragie Karunaratne 1.2k Dec 12, 2022
MarkdownView is a WKWebView based UI element, and internally use bootstrap, highlight.js, markdown-it.

MarkdownView is a WKWebView based UI element, and internally use bootstrap, highlight.js, markdown-it.

Keita Oouchi 1.8k Dec 21, 2022
Markdown in SwiftUI, and some other interesting components.

RoomTime RoomTime is a bundle of tools developed in my app RoomTime Lite. ( ?? RoomTime Lite is still in development) Features TextArea AutoWrap Markd

Chen SiWei 56 Dec 20, 2022
Converts Markdown files and strings into NSAttributedStrings with lots of customisation options.

SwiftyMarkdown 1.0 SwiftyMarkdown converts Markdown files and strings into NSAttributedStrings using sensible defaults and a Swift-style syntax. It us

Simon Fairbairn 1.5k Dec 22, 2022
Swift markdown library

Markdown ![Swift version](https://img.shields.io/badge/Swift-2.1 | 2.2-blue.svg) ![GitHub license](https://img.shields.io/badge/license-LGPL v3-green.

Crossroad Labs 79 Oct 9, 2022
A Pure Swift implementation of the markdown mark-up language

SmarkDown A pure Swift markdown implementation consistent with Gruber's 1.0.1 version. It is released under the BSD license so please feel free to use

Swift Studies 67 Jan 24, 2022
`resultBuilder` support for `swift-markdown`

SwiftMarkdownBuilder resultBuilder support for swift-markdown. The default way to build Markdown in swift-markdown is to use varargs initializers, e.g

DocZ 9 May 31, 2022
Blazing fast Markdown / CommonMark rendering in Swift, built upon cmark.

Down Blazing fast Markdown (CommonMark) rendering in Swift, built upon cmark v0.29.0. Is your app using it? Let us know! If you're looking for iwasrob

John Nguyen 2k Dec 19, 2022
Notepad - A fully themeable iOS markdown editor with live syntax highlighting.

Notepad is just like any other UITextView, but you need to use the convenience initializer in order to use the themes. To create a new theme, copy one of the existing themes and edit the JSON.

Rudd Fawcett 802 Dec 31, 2022
AttributedString Markdown initializer with custom styling

AttributedString Markdown initializer with custom styling AttributedString in iOS 15 and macOS 12 comes with a Markdown initializer. But: There is no

Frank Rausch 41 Dec 19, 2022
An Objective-C framework for converting Markdown to HTML.

MMMarkdown MMMarkdown is an Objective-C framework for converting Markdown to HTML. It is compatible with OS X 10.7+, iOS 8.0+, tvOS, and watchOS. Unli

Matt Diephouse 1.2k Dec 14, 2022
Markdown syntax highlighter for iOS

Marklight Markdown syntax highlighter for iOS and macOS. Description Marklight is a drop in component to easily add realtime Markdown syntax highlight

Matteo Gavagnin 539 Dec 29, 2022
Rich Markdown editing control for iOS

MarkdownTextView Rich Markdown Editing for iOS MarkdownTextView is an iOS framework for adding rich Markdown editing capabilities. Support for Markdow

Indragie Karunaratne 676 Dec 7, 2022
A Github action for creating generic run report using Markdown

create-report A Github action for creating generic run report (using Markdown!) - uses: michaelhenry/[email protected] with: report-title: "

Michael Henry 4 Apr 19, 2022