SwiftyMarkdown

repository·master·Indexed 23 days ago

https://github.com/simonfairbairn/swiftymarkdown

A Swift library that converts Markdown strings or files into NSAttributedString objects. It supports standard Markdown features including headers, lists, blockquotes, and images from app bundles. The library features a rules-based engine for custom syntax, respects iOS Dynamic Type, and supports Dark Mode via system colors. Users can customize visual properties such as fontName, fontSize, color, and alignment for various Markdown elements.

Tokens
2.6K
Snippets
9
Records
18
Agent score
83%

What's inside SwiftyMarkdown

  1. What is SwiftyMarkdown?

    master

    SwiftyMarkdown is a library that converts Markdown files and strings into NSAttributedStrings. It uses sensible defaults and a Swift-style syntax. It leverages dynamic type to ensure font sizes are set correctly based on the font you choose.

    Key features include:

    • Support for Dark Mode out of the box (uses system color .label on iOS 13+).
    • Support for images stored in the app bundle using the syntax ![Image](<Name In bundle>).
    • Support for codeblocks, blockquotes, and unordered lists.
    • Paragraph alignment for line-level attributes (e.g., h2.alignment = .center).
    • Option to underline links by setting underlineLinks = true.
  2. Access YAML front matter attributes

    master
    SwiftyMarkdown recognizes YAML front matter at the beginning of a document. The key-value pairs found in the front matter are populated into the frontMatterAttributes property.
  3. Supported Markdown Features

    master

    SwiftyMarkdown supports a wide range of standard Markdown syntax, including:

    • Emphasis: *italics* or _italics_, **bold** or __bold__, and ~~strikethrough~~.
    • Code: Inline `code` and indented code blocks.
    • Headers: # Header 1 (or using underlines like ====) through ###### Header 6.
    • Links & Images: [Links](url) and bundle images ![Images](<Name of asset in bundle>).
    • Blockquotes: > Blockquotes.
    • Lists:
      • Unordered (bulleted) lists with up to three levels of indentation.
      • Ordered (numbered) lists with up to three levels of indentation.
  4. How SwiftyMarkdown's rules-based engine works

    master

    SwiftyMarkdown uses a two-step processing engine that is not limited to Markdown; you can use it to define custom syntax for any text-based styling.

    1. Line Processing: Rules are processed from top to bottom. Line tags (like headings or code blocks) are identified first.
    2. Character Styling: After lines are processed, character rules are applied to the text to handle inline styles (like bold or italic).

    To implement custom logic, you define a LineStyling enum for line-level rules and a CharacterStyling enum for character-level rules, then provide them to a SwiftyLineProcessor or SwiftyTokeniser.

  5. Install SwiftyMarkdown via CocoaPods or SPM

    master

    You can integrate SwiftyMarkdown into your Xcode project using either CocoaPods or Swift Package Manager (SPM).

    CocoaPods Add the following to your Podfile: pod 'SwiftyMarkdown'

    Swift Package Manager (SPM) In Xcode, navigate to File -> Swift Packages -> Add Package Dependency and provide the GitHub URL for the repository.

    pod 'SwiftyMarkdown'
  6. Create custom character styles with SwiftyTokeniser

    master

    You can use SwiftyTokeniser to parse custom syntax. For example, to apply a custom .elf style to text wrapped in % characters:

    1. Define a CharacterStyling enum.
    2. Create a CharacterRule with the % tag set to .repeating.
    3. Process the string using SwiftyTokeniser.
    enum Characters : CharacterStyling {
    	case elf
    
    	func isEqualTo( _ other : CharacterStyling) -> Bool {
    		if let other = other as? Characters {
    			return other == self
    		}
    		return false
    	}
    }
    
    let characterRules = [
    	CharacterRule(primaryTag: CharacterRuleTag(tag: "%", type: .repeating), otherTags: [], styles: [1 : CharacterStyle.elf])
    ]
    
    let processor = SwiftyTokeniser( with : characterRules )
    let string = "The elf will speak now: %Here is my elf speaking%"
    let tokens = processor.process(string)
  7. Use SwiftyMarkdown with SpriteKit SKLabelNode

    master

    Since SKLabelNode supports attributed text, you can render Markdown directly into a label by converting the parsed Markdown into an NSAttributedString.

    let smd = SwiftyMarkdown(string: "My Character's **Dialogue**")
    
    let label = SKLabelNode()
    label.preferredMaxLayoutWidth = 500
    label.numberOfLines = 0
    label.attributedText = smd.attributedString()
  8. Customise fonts and colors in SwiftyMarkdown

    master

    You can customize the appearance of specific Markdown elements (like code blocks or headers) by setting properties on the Markdown instance. Supported properties include fontName, color, and alignment for various element types.

    md.code.fontName = "CourierNewPSMT"
    
    md.h2.fontName = "AvenirNextCondensed-Medium"
    md.h2.color = UIColor.redColor()
    md.h2.alignment = .center
  9. Convert Markdown strings or URLs to NSAttributedString

    master
    SwiftyMarkdown provides initializers to parse Markdown from either a raw string or a file URL. The resulting object can then be used to generate an NSAttributedString for display in UI components like UILabel or UITextView.
  10. Customize Markdown styles and attributes

    master

    SwiftyMarkdown allows you to customize the appearance of different Markdown elements (headers, body, italics, etc.) using dot syntax. You can modify font names, colors, font sizes, and alignments.

    Note: On iOS, specified font sizes are adjusted relative to the user's dynamic type settings. Line-level attributes like headers support paragraph alignment (e.g., .center).

    md.body.fontName = "AvenirNextCondensed-Medium"
    
    md.h1.color = UIColor.redColor()
    md.h1.fontName = "AvenirNextCondensed-Bold"
    md.h1.fontSize = 16
    md.h1.alignmnent = .center
    
    md.italic.color = UIColor.blueColor()
    
    md.underlineLinks = true
    
    md.bullet = "🍏"
  11. Parse a different string from an existing SwiftyMarkdown instance

    master
    If you have already initialized a SwiftyMarkdown instance, you can use the attributedString(from:) method to parse a new Markdown string using the same configuration.