[
  {
    "path": ".gitignore",
    "content": ".DS_Store\n/.build\n/Packages\n/*.xcodeproj\nxcuserdata/\nDerivedData/\n.swiftpm/config/registries.json\n.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata\n.netrc\n"
  },
  {
    "path": "LICENSE.md",
    "content": "MIT License\n\nCopyright (c) 2021 Shaps Benkau\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
  },
  {
    "path": "Package.resolved",
    "content": "{\n  \"pins\" : [\n    {\n      \"identity\" : \"swift-cmark\",\n      \"kind\" : \"remoteSourceControl\",\n      \"location\" : \"https://github.com/shaps80/swift-cmark.git\",\n      \"state\" : {\n        \"revision\" : \"476f7b4fcf12eba381b4aaed8987006fd8fcec9c\",\n        \"version\" : \"0.2.0\"\n      }\n    },\n    {\n      \"identity\" : \"swift-markdown\",\n      \"kind\" : \"remoteSourceControl\",\n      \"location\" : \"https://github.com/shaps80/swift-markdown\",\n      \"state\" : {\n        \"revision\" : \"83188dee2dbccfa70124c56055dd0b759d3e4ec3\",\n        \"version\" : \"0.3.0\"\n      }\n    },\n    {\n      \"identity\" : \"swiftuibackports\",\n      \"kind\" : \"remoteSourceControl\",\n      \"location\" : \"https://github.com/shaps80/SwiftUIBackports\",\n      \"state\" : {\n        \"revision\" : \"252d01385a0730cc604310373ac934a64f1d4b1a\",\n        \"version\" : \"1.8.2\"\n      }\n    }\n  ],\n  \"version\" : 2\n}\n"
  },
  {
    "path": "Package.swift",
    "content": "// swift-tools-version: 5.6\n// The swift-tools-version declares the minimum version of Swift required to build this package.\n\nimport PackageDescription\n\nlet package = Package(\n    name: \"MarkdownText\",\n    platforms: [\n        .iOS(.v13),\n        .macOS(.v11),\n    ],\n    products: [\n        .library(\n            name: \"MarkdownText\",\n            targets: [\"MarkdownText\"]\n        ),\n    ],\n    dependencies: [\n        .package(url: \"https://github.com/shaps80/swift-markdown\", .upToNextMinor(from: \"0.3.0\")),\n        .package(url: \"https://github.com/shaps80/SwiftUIBackports\", .upToNextMajor(from: \"2.0.0\")),\n    ],\n    targets: [\n        .target(\n            name: \"MarkdownText\",\n            dependencies: [\n                .product(name: \"Markdown\", package: \"swift-markdown\"),\n                .byName(name: \"SwiftUIBackports\"),\n            ]\n        ),\n    ]\n)\n\n"
  },
  {
    "path": "README.md",
    "content": "![macOS](https://img.shields.io/badge/macOS-EE751F)\n![ios](https://img.shields.io/badge/iOS-0C62C7)\n[![swift](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fshaps80%2FMarkdownText%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/shaps80/MarkdownText)\n\n# MarkdownText\n\nA native SwiftUI view for rendering Markdown text in an iOS or macOS app.\n\n## Preview\n\n![Markdown Text Screenshot](Resources/screenshot.jpg)\n\n## Sponsor\n\nBuilding useful libraries like these, takes time away from my family. I build these tools in my spare time because I feel its important to give back to the community. Please consider [Sponsoring](https://github.com/sponsors/shaps80) me as it helps keep me working on useful libraries like these 😬\n\nYou can also give me a follow and a 'thanks' anytime.\n\n[![Twitter](https://img.shields.io/badge/Twitter-@shaps-4AC71B)](http://twitter.com/shaps)\n\n## Supported Markdown\n\n- Headings\n- Paragraphs\n- Quotes\n- Inline formatting\n    - Strong/Bold\n    - Emphasis/Italic\n    - Strikethrough\n    - Code\n    - Links (non interactive only)\n- Lists\n    - Ordered\n    - Unordered\n    - Checklist (GitHub style)\n- Thematic Breaks\n- Code Blocks\n- Images\n    - A full backport of `AsyncImage` is included\n    \n## Features\n\n**Style APIs**\n\nAdopting the familiar SwiftUI style-based APIs, you can customize the appearance of almost all markdown elements either individually or composed.\n\n```swift\nstruct CustomUnorderedBullets: UnorderedListBulletMarkdownStyle {\n    func makeBody(configuration: Configuration) -> some View {\n        // you can also provide a completely new View if preferred 👍\n        configuration.label\n            .foregroundColor(.blue)\n    }\n}\n```\n\nYou can even customize animations since the library is composed of 100% SwiftUI elements only.\n\n```swift\nstruct ScaledImageStyle: ImageMarkdownStyle {\n    // image will scale up as its loaded, moving content out of the way\n    func makeBody(configuration: Configuration) -> some View {\n        configuration.label\n            .transition(.scale)\n    }\n}\n```\n\nModifiers for styling and visibility can also be placed anywhere in your SwiftUI hierarchy, just as you'd expect:\n\n```\nNavigationView {\n    MarkdownText(markdown)\n}\n// Styling\n.markdownQuoteStyle(.inset)\n.markdownOrderedListBulletStyle(.tinted)\n.markdownImageStyle(.animated)\n\n// Visibility\n.markdownCode(.visible)\n.markdownThematicBreak(.hidden)\n```\n\n## Demo App\n\nA [MarkdownText Demo](https://github.com/shaps80/MarkdownTextDemo) is also available to better showcase the libraries capabilities.\n\n## Usage\n\nUsing the view couldn't be easier:\n\n```swift\nMarkdownText(\"Some **markdown** text\")\nLazyMarkdownText(someMassiveMarkdownText)\n```\n\nThere's even a `LazyMarkdownText` view that loads its view's lazily for those cases where you need improved scrolling and loading performance.\n\n## Installation\n\nYou can install manually (by copying the files in the `Sources` directory) or using Swift Package Manager (**preferred**)\n\nTo install using Swift Package Manager, add this to the `dependencies` section of your `Package.swift` file:\n\n`.package(url: \"https://github.com/shaps80/MarkdownText.git\", .upToNextMinor(from: \"1.0.0\"))`\n"
  },
  {
    "path": "Sources/MarkdownText/Helpers/InlineStyle.swift",
    "content": "import SwiftUI\n\nstruct InlineMarkdownConfiguration {\n    struct Label: View {\n        @Environment(\\.font) private var font\n        @Environment(\\.markdownStrongStyle) private var strong\n        @Environment(\\.markdownEmphasisStyle) private var emphasis\n        @Environment(\\.markdownStrikethroughStyle) private var strikethrough\n        @Environment(\\.markdownInlineCodeStyle) private var code\n        @Environment(\\.markdownInlineLinkStyle) private var link\n\n        let elements: [MarkdownInlineElement]\n\n        var body: some View {\n            elements.reduce(into: Text(\"\")) { result, component in\n                if component.attributes.contains(.code) {\n                    return result = result + code.makeBody(\n                        configuration: .init(code: component.content, font: font)\n                    )\n                } else {\n                    return result = result + Text(component.content).apply(\n                        strong: strong,\n                        emphasis: emphasis,\n                        strikethrough: strikethrough,\n                        link: link,\n                        attributes: component.attributes\n                    )\n                }\n            }\n        }\n    }\n\n    public let elements: [MarkdownInlineElement]\n\n    public var label: some View {\n        Label(elements: elements)\n            .fixedSize(horizontal: false, vertical: true)\n    }\n}\n\nstruct InlineMarkdownStyle {\n    func makeBody(configuration: InlineMarkdownConfiguration) -> some View {\n        configuration.label\n    }\n}\n"
  },
  {
    "path": "Sources/MarkdownText/Helpers/ListLabelStyle.swift",
    "content": "import SwiftUI\nimport SwiftUIBackports\n\nstruct ListLabelStyle: LabelStyle {\n    struct Content: View {\n        let configuration: Configuration\n\n        var body: some View {\n            HStack(alignment: .firstTextBaseline, spacing: 0) {\n                configuration.icon\n                Text(Array(repeating: \" \", count: 1).joined())\n                configuration.title\n            }\n        }\n    }\n\n    init() { }\n    func makeBody(configuration: Configuration) -> some View {\n        Content(configuration: configuration)\n    }\n}\n\nextension LabelStyle where Self == ListLabelStyle {\n    static var list: Self { .init() }\n}\n"
  },
  {
    "path": "Sources/MarkdownText/Helpers/Platform.swift",
    "content": "import SwiftUI\nimport SwiftUIBackports\n\n#if os(macOS)\ntypealias ScaledMetric = SwiftUI.ScaledMetric\ntypealias LabelStyle = SwiftUI.LabelStyle\ntypealias Label = SwiftUI.Label\ntypealias ProgressView = SwiftUI.ProgressView\n#else\ntypealias ScaledMetric = Backport<Any>.ScaledMetric\ntypealias LabelStyle = SwiftUIBackports.BackportLabelStyle\ntypealias Label = Backport<Any>.Label\ntypealias ProgressView = Backport<Any>.ProgressView\n\nextension View {\n    func labelStyle<S: BackportLabelStyle>(_ style: S) -> some View {\n        backport.labelStyle(style)\n    }\n}\n#endif\n"
  },
  {
    "path": "Sources/MarkdownText/MarkdownBlockElement.swift",
    "content": "import Foundation\n\n// Used during parsing to store all discovered block elements\nenum MarkdownBlockElement {\n    case heading(HeadingMarkdownConfiguration)\n    case paragraph(ParagraphMarkdownConfiguration)\n    case quote(QuoteMarkdownConfiguration)\n    case list(ListStyleMarkdownConfiguration)\n    case code(CodeMarkdownConfiguration)\n    case image(ImageMarkdownConfiguration)\n    case thematicBreak(ThematicMarkdownConfiguration)\n    case inline(InlineMarkdownConfiguration)\n}\n"
  },
  {
    "path": "Sources/MarkdownText/MarkdownInlineElement.swift",
    "content": "import SwiftUI\n\n/// Represents a single inline element, including any applied attributes (e.g. strong, italic, etc)\npublic struct MarkdownInlineElement {\n    /// The string content for this inline element\n    public var content: String\n    /// The attributes to apply to this content\n    public var attributes: InlineAttributes = []\n}\n\n/// Represents the supported attributes for an inline element\npublic struct InlineAttributes: OptionSet, CustomStringConvertible {\n    public let rawValue: Int\n    public init(rawValue: Int) {\n        self.rawValue = rawValue\n    }\n\n    /// A `bold` representation should be applied\n    public static let bold = InlineAttributes(rawValue: 1 << 0)\n    /// An `italic` representation should be applied\n    public static let italic = InlineAttributes(rawValue: 1 << 1)\n    /// A `strikethrough` representation should be applied\n    public static let strikethrough = InlineAttributes(rawValue: 1 << 2)\n    /// A `monospaced` representation should be applied\n    public static let code = InlineAttributes(rawValue: 1 << 3)\n    /// A link representation should be applied\n    public static let link = InlineAttributes(rawValue: 1 << 4)\n\n    public var description: String {\n        var elements: [String] = []\n        if contains(.bold) { elements.append(\"bold\") }\n        if contains(.italic) { elements.append(\"italic\") }\n        if contains(.strikethrough) { elements.append(\"strikethrough\") }\n        if contains(.code) { elements.append(\"code\") }\n        return elements.joined(separator: \", \")\n    }\n}\n\ninternal extension Text {\n    func apply(\n        strong: StrongMarkdownStyle,\n        emphasis: EmphasisMarkdownStyle,\n        strikethrough: StrikethroughMarkdownStyle,\n        link: InlineLinkMarkdownStyle,\n        attributes: InlineAttributes\n    ) -> Self {\n        var text = self\n\n        if attributes.contains(.bold) {\n            text = strong.makeBody(configuration: .init(content: text))\n        }\n\n        if attributes.contains(.italic) {\n            text = emphasis.makeBody(configuration: .init(content: text))\n        }\n\n        if attributes.contains(.strikethrough) {\n            text = strikethrough.makeBody(configuration: .init(content: text))\n        }\n\n        if attributes.contains(.link) {\n            text = link.makeBody(configuration: .init(content: text))\n        }\n\n        return text\n    }\n}\n"
  },
  {
    "path": "Sources/MarkdownText/MarkdownListElement.swift",
    "content": "import Foundation\n\n/// Represents a list markdown element\npublic struct MarkdownList {\n    /// Represents the types of lists\n    public enum ListType {\n        /// An unordered list\n        case unordered\n        /// An ordered list\n        case ordered\n    }\n\n    /// The type of list this represents\n    public let type: ListType\n    /// The elements contained in this list. This could be single elements, or even another nested list\n    public var elements: [MarkdownListElement] = []\n\n    internal mutating func append(ordered item: OrderedListItemMarkdownConfiguration) {\n        elements.append(.ordered(item))\n    }\n\n    internal mutating func append(unordered item: UnorderedListItemMarkdownConfiguration) {\n        elements.append(.unordered(item))\n    }\n\n    internal mutating func append(checklist item: CheckListItemMarkdownConfiguration) {\n        elements.append(.checklist(item))\n    }\n\n    internal mutating func append(nested list: Self) {\n        elements.append(.list(list))\n    }\n}\n\n/// Represents a list, including any nested list elements\npublic enum MarkdownListElement {\n    /// A nested list\n    case list(MarkdownList)\n    /// An ordered list\n    case ordered(OrderedListItemMarkdownConfiguration)\n    /// An unordered list\n    case unordered(UnorderedListItemMarkdownConfiguration)\n    /// A checked list\n    case checklist(CheckListItemMarkdownConfiguration)\n}\n"
  },
  {
    "path": "Sources/MarkdownText/MarkdownText.swift",
    "content": "import SwiftUI\nimport Markdown\n\n/// A view that renders Markdown text, but only creates elements as they are needed.\n///\n/// The stack is \"lazy,\" in that the stack view doesn't create items until\n/// it needs to render them onscreen.\n@available(iOS 14, *)\npublic struct LazyMarkdownText: View, MarkupWalker {\n    private let content: MarkdownContent\n    public var body: some View { content }\n\n    /// Creates a new Markdown view\n    /// - Parameters:\n    ///   - markdown: The markdown text to render\n    ///   - source: An explicit source URL from which the input string came for marking source locations. This need not be a file URL.\n    ///   - paragraphSpacing: The spacing to apply between all block elements\n    public init(_ markdown: String, source: URL? = nil, paragraphSpacing: CGFloat? = 20) {\n        let elements = MarkdownTextBuilder(\n            document: Document(parsing: markdown, source: source)\n        ).blockElements\n\n        content = .init(elements: elements, paragraphSpacing: paragraphSpacing, isLazy: true)\n    }\n}\n\n/// A view that rendered Markdown text.\npublic struct MarkdownText: View, MarkupWalker {\n    private let content: MarkdownContent\n    public var body: some View { content }\n\n    /// Creates a new Markdown view\n    /// - Parameters:\n    ///   - markdown: The markdown text to render\n    ///   - source: An explicit source URL from which the input string came for marking source locations. This need not be a file URL.\n    ///   - paragraphSpacing: The spacing to apply between all block elements\n    public init(_ markdown: String, source: URL? = nil, paragraphSpacing: CGFloat? = 20) {\n        let elements = MarkdownTextBuilder(\n            document: Document(parsing: markdown, source: source)\n        ).blockElements\n\n        content = .init(elements: elements, paragraphSpacing: paragraphSpacing, isLazy: false)\n    }\n}\n\nprivate struct MarkdownContent: View {\n    @Environment(\\.multilineTextAlignment) private var alignment\n\n    @Environment(\\.markdownHeadingStyle) private var headerStyle\n    @Environment(\\.markdownParagraphStyle) private var paragraphStyle\n    @Environment(\\.markdownQuoteStyle) private var quoteStyle\n    @Environment(\\.markdownCodeStyle) private var codeStyle\n    @Environment(\\.markdownThematicBreakStyle) private var thematicBreak\n    @Environment(\\.markdownListStyle) private var listStyle\n    @Environment(\\.markdownImageStyle) private var imageStyle\n\n    @Environment(\\.markdownCodeVisibility) private var codeVisibility\n    @Environment(\\.markdownImageVisibility) private var imageVisibility\n    @Environment(\\.markdownHeadingVisibility) private var headingVisibility\n    @Environment(\\.markdownQuoteListVisibility) private var quoteVisibility\n    @Environment(\\.markdownThematicBreakVisibility) private var thematicBreakVisibility\n    @Environment(\\.markdownListVisibility) private var listVisibility\n\n    private var inlineStyle = InlineMarkdownStyle()\n\n    private var content: some View {\n        ForEach(elements.indices, id: \\.self) { index in\n            switch elements[index] {\n            case let .heading(config):\n                if headingVisibility != .hidden {\n                    AnyView(headerStyle.makeBody(configuration: config))\n                }\n            case let .quote(config):\n                if quoteVisibility != .hidden {\n                    AnyView(quoteStyle.makeBody(configuration: config))\n                }\n            case let .code(config):\n                if codeVisibility != .hidden {\n                    AnyView(codeStyle.makeBody(configuration: config))\n                }\n            case let .thematicBreak(config):\n                if thematicBreakVisibility != .hidden {\n                    AnyView(thematicBreak.makeBody(configuration: config))\n                }\n            case let .image(config):\n                if imageVisibility != .hidden {\n                    AnyView(imageStyle.makeBody(configuration: config))\n                }\n            case let .list(config):\n                if listVisibility != .hidden {\n                    AnyView(listStyle.makeBody(configuration: config))\n                }\n            case let .paragraph(config):\n                AnyView(paragraphStyle.makeBody(configuration: config))\n            case let .inline(config):\n                AnyView(inlineStyle.makeBody(configuration: config))\n            }\n        }\n    }\n\n    let elements: [MarkdownBlockElement]\n    let paragraphSpacing: CGFloat?\n    let isLazy: Bool\n\n    private var stackAlignment: HorizontalAlignment {\n        alignment == .leading\n            ? .leading\n            : alignment == .trailing\n            ? .trailing\n            : .center\n    }\n\n    init(elements: [MarkdownBlockElement], paragraphSpacing: CGFloat?, isLazy: Bool) {\n        self.elements = elements\n        self.paragraphSpacing = paragraphSpacing\n        self.isLazy = isLazy\n    }\n\n    public var body: some View {\n        if isLazy {\n            if #available(iOS 14.0, *) {\n                LazyVStack(alignment: stackAlignment, spacing: paragraphSpacing) { content }\n            } else {\n                VStack(alignment: stackAlignment, spacing: paragraphSpacing) { content }\n            }\n        } else {\n            VStack(alignment: stackAlignment, spacing: paragraphSpacing) { content }\n        }\n    }\n}\n"
  },
  {
    "path": "Sources/MarkdownText/MarkdownTextBuilder.swift",
    "content": "import SwiftUI\nimport Markdown\n\nstruct MarkdownTextBuilder: MarkupWalker {\n    var isNested: Bool = false\n    var nestedBlockElements: [MarkdownBlockElement] = []\n    var inlineElements: [MarkdownInlineElement] = []\n    var blockElements: [MarkdownBlockElement] = []\n    var lists: [MarkdownList] = []\n\n    init(document: Document) {\n        visit(document)\n    }\n\n    mutating func visitHeading(_ markdown: Heading) {\n        descendInto(markdown)\n        blockElements.append(.heading(.init(level: markdown.level, content: .init(elements: inlineElements))))\n        inlineElements = []\n    }\n\n    mutating func visitText(_ markdown: Markdown.Text) {\n        var attributes: InlineAttributes = []\n        var parent = markdown.parent\n        var text = markdown.string\n\n        while parent != nil {\n            defer { parent = parent?.parent }\n\n            if parent is Strong {\n                attributes.insert(.bold)\n            }\n\n            if parent is Emphasis {\n                attributes.insert(.italic)\n            }\n\n            if parent is Strikethrough {\n                attributes.insert(.strikethrough)\n            }\n\n            if parent is InlineCode {\n                attributes.insert(.code)\n            }\n\n            if let link = parent as? Markdown.Link {\n                /*\n                 One idea here could be to collect links like footnotes, reference them in the rendered result as such (at least by default) and then add actual buttons to the bottom of the rendered output?\n                 */\n                attributes.insert(.link)\n                text = link.plainText // + (link.destination.flatMap { \" [\\($0)]\" } ?? \"\")\n            }\n        }\n\n        inlineElements.append(.init(content: .init(text), attributes: attributes))\n    }\n\n    mutating func visitOrderedList(_ markdown: OrderedList) {\n        lists.append(.init(type: .ordered))\n        descendInto(markdown)\n\n        if let list = lists.last {\n            if lists.count == 1 {\n                // if we're at the root element, add the the tree to the block elements\n                blockElements.append(.list(.init(list: list, level: lists.count - 1)))\n            } else {\n                // otherwise, append nested lists to the last list\n                let index = lists.index(before: lists.index(before: lists.endIndex))\n                lists[index].append(nested: list)\n            }\n        }\n\n        lists.removeLast()\n    }\n\n    mutating func visitUnorderedList(_ markdown: UnorderedList) {\n        lists.append(.init(type: .unordered))\n        descendInto(markdown)\n\n        if let list = lists.last {\n            if lists.count == 1 {\n                // if we're at the root element, add the the tree to the block elements\n                blockElements.append(.list(.init(list: list, level: lists.count - 1)))\n            } else {\n                // otherwise, append nested lists to the last list\n                let index = lists.index(before: lists.index(before: lists.endIndex))\n                lists[index].append(nested: list)\n            }\n        }\n\n        lists.removeLast()\n    }\n\n    mutating func visitListItem(_ markdown: Markdown.ListItem) {\n        descendInto(markdown)\n    }\n\n    mutating func visitParagraph(_ markdown: Paragraph) {\n        descendInto(markdown)\n\n        if let listItem = markdown.parent as? ListItem {\n            let index = lists.index(before: lists.endIndex)\n\n            switch lists[index].type {\n            case .ordered:\n                lists[index].append(ordered: .init(\n                    level: lists.count - 1,\n                    bullet: .init(order: listItem.indexInParent + 1),\n                    content: .init(content: .init(elements: inlineElements))\n                )\n                )\n            default:\n                if let checkbox = listItem.checkbox {\n                    lists[index].append(checklist: .init(\n                        level: lists.count - 1,\n                        bullet: .init(isChecked: checkbox == .checked),\n                        content: .init(content: .init(elements: inlineElements))\n                    )\n                    )\n                } else {\n                    lists[index].append(unordered: .init(\n                        level: lists.count - 1,\n                        bullet: .init(level: lists.count - 1),\n                        content: .init(content: .init(elements: inlineElements))\n                    )\n                    )\n                }\n            }\n        } else {\n            if isNested {\n                nestedBlockElements.append(.paragraph(.init(content: .init(elements: inlineElements))))\n            } else {\n                blockElements.append(.paragraph(.init(content: .init(elements: inlineElements))))\n            }\n        }\n\n        inlineElements = []\n    }\n\n    mutating func visitImage(_ markdown: Markdown.Image) {\n        let title = markdown.title ?? \"\"\n        blockElements.append(.image(.init(source: markdown.source, title: title.isEmpty ? nil : title)))\n    }\n\n    mutating func visitLink(_ markdown: Markdown.Link) {\n        descendInto(markdown)\n    }\n\n    mutating func visitStrong(_ markdown: Strong) {\n        descendInto(markdown)\n    }\n\n    mutating func visitEmphasis(_ markdown: Emphasis) {\n        descendInto(markdown)\n    }\n\n    mutating func visitInlineCode(_ markdown: InlineCode) {\n        inlineElements.append(.init(content: .init(markdown.code), attributes: .code))\n    }\n\n    mutating func visitStrikethrough(_ markdown: Strikethrough) {\n        descendInto(markdown)\n    }\n\n    mutating func visitCodeBlock(_ markdown: CodeBlock) {\n        blockElements.append(.code(.init(code: markdown.code, language: markdown.language)))\n        inlineElements = []\n    }\n\n    mutating func visitThematicBreak(_ markdown: ThematicBreak) {\n        blockElements.append(.thematicBreak(.init()))\n        descendInto(markdown)\n    }\n\n    mutating func visitBlockQuote(_ markdown: BlockQuote) {\n        isNested = true\n        descendInto(markdown)\n\n        for element in nestedBlockElements {\n            if case let .paragraph(config) = element {\n                blockElements.append(.quote(.init(content: config)))\n            }\n        }\n\n        inlineElements = []\n        nestedBlockElements = []\n        isNested = false\n    }\n\n    mutating func visitSoftBreak(_ markdown: SoftBreak) {\n        visitText(.init(markdown.plainText))\n    }\n\n    mutating func visitTable(_: Markdown.Table) { }\n    mutating func visitTableRow(_: Markdown.Table.Row) { }\n    mutating func visitTableBody(_: Markdown.Table.Body) { }\n    mutating func visitTableCell(_: Markdown.Table.Cell) { }\n    mutating func visitTableHead(_: Markdown.Table.Head) { }\n\n    mutating func visitSymbolLink(_: SymbolLink) { }\n    mutating func visitBlockDirective(_: BlockDirective) { }\n    mutating func visitCustomInline(_: CustomInline) { }\n    mutating func visitHTMLBlock(_: HTMLBlock) { }\n    mutating func visitInlineHTML(_: InlineHTML) { }\n}\n"
  },
  {
    "path": "Sources/MarkdownText/Styles/Block Elements/CodeStyle.swift",
    "content": "import SwiftUI\n\n/// A type that applies a custom appearance to code block markdown elements\npublic protocol CodeMarkdownStyle {\n    associatedtype Body: View\n    /// The properties of an code block markdown element\n    typealias Configuration = CodeMarkdownConfiguration\n    /// Creates a view that represents the body of a label\n    @ViewBuilder func makeBody(configuration: Configuration) -> Body\n}\n\n/// The properties of a code block markdown element\npublic struct CodeMarkdownConfiguration {\n    /// The raw code for this element\n    public let code: String\n    /// The code language for this element\n    public let language: String?\n\n    struct Label: View {\n        @Environment(\\.font) private var font\n\n        let code: String\n        let language: String?\n\n        var body: some View {\n            #if os(macOS)\n            if #available(macOS 12, *) {\n                Text(code.trimmingCharacters(in: .newlines))\n                    .font(\n                        font?.monospaced()\n                        ?? .system(.body, design: .monospaced)\n                    )\n            } else {\n                Text(code.trimmingCharacters(in: .newlines))\n                    .font(.system(.body, design: .monospaced))\n            }\n            #elseif os(iOS)\n            if #available(iOS 15, *) {\n                Text(code.trimmingCharacters(in: .newlines))\n                    .font(\n                        font?.monospaced()\n                            ?? .system(.body, design: .monospaced)\n                    )\n            } else {\n                Text(code.trimmingCharacters(in: .newlines))\n                    .font(.system(.body, design: .monospaced))\n            }\n            #else\n            Text(code.trimmingCharacters(in: .newlines))\n                .font(.system(.body, design: .monospaced))\n            #endif\n        }\n    }\n\n    /// Returns a default code block markdown representation\n    public var label: some View {\n        Label(code: code, language: language)\n            .font(.callout)\n            .lineSpacing(5)\n            .environment(\\.layoutDirection, .leftToRight)\n    }\n}\n\n/// A code block style that applies a monospaced representation to its content and wraps it in a horizontal `ScrollView`\npublic struct DefaultCodeMarkdownStyle: CodeMarkdownStyle {\n    var axes: Axis.Set\n    var showsIndicators: Bool\n\n    /// Creates a new instance of this style\n    /// - Parameters:\n    ///   - axes: The scrollable axes\n    ///   - showsIndicators: If `true`, scroll indicators will be visible when required\n    public init(_ axes: Axis.Set = .horizontal, showsIndicators: Bool = false) {\n        self.axes = axes\n        self.showsIndicators = showsIndicators\n    }\n\n    public func makeBody(configuration: Configuration) -> some View {\n        ScrollView(axes, showsIndicators: showsIndicators) {\n            configuration.label\n        }\n    }\n}\n\npublic extension CodeMarkdownStyle where Self == DefaultCodeMarkdownStyle {\n    /// A code block style that applies a monospaced representation to its content and wraps it in a horizontal `ScrollView`\n    static var `default`: Self { .init() }\n\n    /// A code block style that applies a monospaced representation to its content and wraps it in a horizontal `ScrollView`\n    /// - Parameters:\n    ///   - axes: The scrollable axes\n    ///   - showsIndicators: If `true`, scroll indicators will be visible when required\n    static func `default`(_ axes: Axis.Set, showsIndicators: Bool = false) -> Self {\n        .init(axes, showsIndicators: showsIndicators)\n    }\n}\n\nprivate struct CodeMarkdownEnvironmentKey: EnvironmentKey {\n    static let defaultValue: any CodeMarkdownStyle = DefaultCodeMarkdownStyle()\n}\n\npublic extension EnvironmentValues {\n    /// The current code block markdown style\n    var markdownCodeStyle: any CodeMarkdownStyle {\n        get { self[CodeMarkdownEnvironmentKey.self] }\n        set { self[CodeMarkdownEnvironmentKey.self] = newValue }\n    }\n}\n\npublic extension View {\n    /// Sets the style for code block markdown elements\n    func markdownCodeStyle(_ style: some CodeMarkdownStyle) -> some View {\n        environment(\\.markdownCodeStyle, style)\n    }\n}\n"
  },
  {
    "path": "Sources/MarkdownText/Styles/Block Elements/HeadingStyle.swift",
    "content": "import SwiftUI\n\n/// A type that applies a custom appearance to heading markdown elements\npublic protocol HeadingMarkdownStyle {\n    associatedtype Body: View\n    /// The properties of a heading markdown element\n    typealias Configuration = HeadingMarkdownConfiguration\n    /// Creates a view that represents the body of a label\n    @ViewBuilder func makeBody(configuration: Configuration) -> Body\n}\n\n/// The properties of a heading markdown element\npublic struct HeadingMarkdownConfiguration {\n    /// The header level (e.g. `H2` would have a level of `2`)\n    public let level: Int\n    /// The content for this element\n    ///\n    /// You can use this to maintain the existing heading style:\n    ///\n    ///     content.label // maintains its font style\n    ///         .foregroundColor(.accentColor)\n    let content: InlineMarkdownConfiguration\n\n    /// The preferred text tyle for this heading.\n    public var preferredStyle: Font.TextStyle {\n        switch level {\n        case 1: return .title\n        case 2:\n            if #available(iOS 14.0, *) {\n                return .title2\n            } else {\n                return .title\n            }\n        case 3:\n            if #available(iOS 14.0, *) {\n                return .title3\n            } else {\n                return .title\n            }\n        case 4: return .headline\n        default: return .subheadline\n        }\n    }\n\n    private struct Label: View {\n        public let level: Int\n        let content: InlineMarkdownConfiguration\n\n        var body: some View {\n            content.label\n        }\n    }\n\n    /// Returns a default heading markdown representation\n    public var label: some View {\n        Label(level: level, content: content)\n            .font(.system(preferredStyle).weight(.bold))\n    }\n}\n\n/// A heading style that applies a preferred font style based on the heading level\npublic struct DefaultHeadingMarkdownStyle: HeadingMarkdownStyle {\n    public init() { }\n    public func makeBody(configuration: Configuration) -> some View {\n        configuration.label\n    }\n}\n\npublic extension HeadingMarkdownStyle where Self == DefaultHeadingMarkdownStyle {\n    /// A heading style that applies a preferred font style based on the heading level\n    static var `default`: Self { .init() }\n}\n\nprivate struct HeadingMarkdownEnvironmentKey: EnvironmentKey {\n    static let defaultValue: any HeadingMarkdownStyle = DefaultHeadingMarkdownStyle()\n}\n\npublic extension EnvironmentValues {\n    /// The current heading markdown style\n    var markdownHeadingStyle: any HeadingMarkdownStyle {\n        get { self[HeadingMarkdownEnvironmentKey.self] }\n        set { self[HeadingMarkdownEnvironmentKey.self] = newValue }\n    }\n}\n\npublic extension View {\n    /// Sets the style for heading markdown elements\n    func markdownHeadingStyle(_ style: some HeadingMarkdownStyle) -> some View {\n        environment(\\.markdownHeadingStyle, style)\n    }\n}\n"
  },
  {
    "path": "Sources/MarkdownText/Styles/Block Elements/Image Styles/DefaultImageStyle.swift",
    "content": "import SwiftUI\n\n/// An image style that loads content asynchronously if a valid URL is supplied, otherwise tries to load an SFSymbol\npublic struct DefaultImageMarkdownStyle: ImageMarkdownStyle {\n    public func makeBody(configuration: Configuration) -> some View {\n        if let source = configuration.source, let url = URL(string: source), url.scheme != nil {\n            RemoteImageMarkdownStyle()\n                .makeBody(configuration: configuration)\n        } else {\n            SFSymbolImageMarkdownStyle()\n                .makeBody(configuration: configuration)\n        }\n    }\n}\n\npublic extension ImageMarkdownStyle where Self == DefaultImageMarkdownStyle {\n    /// A default image style that loads content asynchronously if a valid URL is supplied, otherwise tries to load an SFSymbol\n    ///\n    /// The following example will load the `star` SF Symbol\n    ///\n    ///     ![][star]\n    ///\n    /// To render a remote image:\n    ///\n    ///     ![Lorem Image](https://picsum.photos/500)\n    ///\n    static var automatic: Self { .init() }\n}\n"
  },
  {
    "path": "Sources/MarkdownText/Styles/Block Elements/Image Styles/RemoteImageStyle.swift",
    "content": "import SwiftUI\n\n/// An image style that loads content asynchronously if a valid URL is supplied\npublic struct RemoteImageMarkdownStyle: ImageMarkdownStyle {\n    public func makeBody(configuration: Configuration) -> some View {\n        configuration.label\n    }\n}\n\npublic extension ImageMarkdownStyle where Self == RemoteImageMarkdownStyle {\n    /// An image style that loads content asynchronously if a valid URL is supplied\n    ///\n    /// Example:\n    ///\n    ///     ![Lorem Image](https://picsum.photos/500)\n    ///\n    static var remote: Self { .init() }\n}\n"
  },
  {
    "path": "Sources/MarkdownText/Styles/Block Elements/Image Styles/SymbolImageStyle.swift",
    "content": "import SwiftUI\n\n/// An image style that renders an SFSymbol (if possible)\npublic struct SFSymbolImageMarkdownStyle: ImageMarkdownStyle {\n    public func makeBody(configuration: Configuration) -> some View {\n        if let source = configuration.source {\n            Image(systemName: source)\n        }\n    }\n}\n\npublic extension ImageMarkdownStyle where Self == SFSymbolImageMarkdownStyle {\n    /// An image style that renders an SFSymbol (if possible)\n    ///\n    /// Example:\n    ///\n    ///     ![](star)\n    ///\n    static var symbol: Self { .init() }\n}\n"
  },
  {
    "path": "Sources/MarkdownText/Styles/Block Elements/ImageStyle.swift",
    "content": "import SwiftUI\nimport SwiftUIBackports\n\n/// A type that applies a custom appearance to image markdown elements\npublic protocol ImageMarkdownStyle {\n    associatedtype Body: View\n    /// The properties of an image markdown element\n    typealias Configuration = ImageMarkdownConfiguration\n    /// Creates a view that represents the body of a label\n    @ViewBuilder func makeBody(configuration: Configuration) -> Body\n}\n\n/// The properties of an image markdown element\npublic struct ImageMarkdownConfiguration {\n    /// The source of the image. Generally either a URL\n    public let source: String?\n    /// The title of the image\n    public let title: String?\n\n    private struct Label: View {\n        private var inlineStyle = InlineMarkdownStyle()\n\n        let source: String?\n        let title: String?\n\n        init(source: String?, title: String?) {\n            self.source = source\n            self.title = title\n        }\n\n        var body: some View {\n            if let source = source, let url = URL(string: source), url.scheme != nil {\n                if source.localizedCaseInsensitiveContains(\"img.shields.io\")\n                    || source.localizedCaseInsensitiveContains(\".svg\")\n                {\n                    inlineStyle.makeBody(configuration: .init(elements: [\n                        .init(content: .init(title ?? source)),\n                    ]))\n                } else {\n                    Backport.AsyncImage(url: url) { phase in\n                        switch phase {\n                        case let .success(image):\n                            image\n                                .resizable()\n                                .scaledToFit()\n                        case .empty:\n                            ProgressView()\n                        default:\n                            EmptyView()\n                        }\n                    }\n                    .scaledToFit()\n                    .animation(.default)\n                }\n            }\n        }\n    }\n\n    /// Returns a default image markdown representation\n    public var label: some View {\n        Label(source: source, title: title)\n    }\n}\n\nprivate struct ImageMarkdownEnvironmentKey: EnvironmentKey {\n    static let defaultValue: any ImageMarkdownStyle = DefaultImageMarkdownStyle()\n}\n\npublic extension EnvironmentValues {\n    /// The current image markdown style\n    var markdownImageStyle: any ImageMarkdownStyle {\n        get { self[ImageMarkdownEnvironmentKey.self] }\n        set { self[ImageMarkdownEnvironmentKey.self] = newValue }\n    }\n}\n\npublic extension View {\n    /// Sets the style for image markdown elements\n    func markdownImageStyle(_ style: some ImageMarkdownStyle) -> some View {\n        environment(\\.markdownImageStyle, style)\n    }\n}\n"
  },
  {
    "path": "Sources/MarkdownText/Styles/Block Elements/ListStyle.swift",
    "content": "import SwiftUI\nimport SwiftUIBackports\n\n/// A type that applies a custom appearance to list markdown elements\npublic protocol ListMarkdownStyle {\n    associatedtype Body: View\n    /// The properties of a list markdown element\n    typealias Configuration = ListStyleMarkdownConfiguration\n    /// Creates a view that represents the body of a label\n    @ViewBuilder func makeBody(configuration: Configuration) -> Body\n}\n\npublic struct AnyListMarkdownStyle: ListMarkdownStyle {\n    var label: (Configuration) -> AnyView\n    init<S: ListMarkdownStyle>(_ style: S) {\n        label = { AnyView(style.makeBody(configuration: $0)) }\n    }\n\n    public func makeBody(configuration: Configuration) -> some View {\n        label(configuration)\n    }\n}\n\n/// The properties of a list markdown element\npublic struct ListStyleMarkdownConfiguration {\n    private struct Label: View {\n        @Environment(\\.markdownListStyle) private var list\n        @Environment(\\.markdownUnorderedListItemStyle) private var unordered\n        @Environment(\\.markdownOrderedListItemStyle) private var ordered\n        @Environment(\\.markdownCheckListItemStyle) private var checklist\n\n        @Environment(\\.markdownCheckListItemVisibility) private var checkListItemVisibility\n        @Environment(\\.markdownUnorderedListItemVisibility) private var unorderedListItemVisibility\n        @Environment(\\.markdownOrderedListItemVisibility) private var orderedListItemVisibility\n\n        @ScaledMetric private var spacing: CGFloat = 8\n\n        let markdownList: MarkdownList\n        let level: Int\n\n        var body: some View {\n            VStack(alignment: .leading, spacing: spacing) {\n                ForEach(markdownList.elements.indices, id: \\.self) { index in\n                    switch markdownList.elements[index] {\n                    case let .ordered(config):\n                        if orderedListItemVisibility != .hidden {\n                            AnyView(ordered.makeBody(configuration: config))\n                        }\n                    case let .unordered(config):\n                        if unorderedListItemVisibility != .hidden {\n                            AnyView(unordered.makeBody(configuration: config))\n                        }\n                    case let .checklist(config):\n                        if checkListItemVisibility != .hidden {\n                            AnyView(checklist.makeBody(configuration: config))\n                        }\n                    case let .list(nested):\n                        AnyView(list.makeBody(configuration: .init(list: nested, level: level + 1)))\n                    }\n                }\n            }\n        }\n    }\n\n    /// A model representing the elements of this list, including any nested lists\n    public let list: MarkdownList\n    /// The indentation level of the list\n    public let level: Int\n\n    /// Returns a default list markdown representation\n    public var label: some View {\n        Label(markdownList: list, level: level)\n    }\n}\n\n/// The default list style\npublic struct DefaultListMarkdownStyle: ListMarkdownStyle {\n    public init() { }\n    public func makeBody(configuration: Configuration) -> some View {\n        configuration.label\n    }\n}\n\npublic extension ListMarkdownStyle where Self == DefaultListMarkdownStyle {\n    /// The default list style\n    static var `default`: Self { .init() }\n}\n\nprivate struct ListMarkdownEnvironmentKey: EnvironmentKey {\n    static let defaultValue = AnyListMarkdownStyle(.default)\n}\n\npublic extension EnvironmentValues {\n    /// The current list markdown style\n    var markdownListStyle: AnyListMarkdownStyle {\n        get { self[ListMarkdownEnvironmentKey.self] }\n        set { self[ListMarkdownEnvironmentKey.self] = newValue }\n    }\n}\n\npublic extension View {\n    /// Sets the style for list markdown elements\n    func markdownListStyle<S>(_ style: S) -> some View where S: ListMarkdownStyle {\n        environment(\\.markdownListStyle, .init(style))\n    }\n}\n"
  },
  {
    "path": "Sources/MarkdownText/Styles/Block Elements/ParagraphStyle.swift",
    "content": "import SwiftUI\n\n/// A type that applies a custom appearance to paragraph markdown elements\npublic protocol ParagraphMarkdownStyle {\n    associatedtype Body: View\n    /// The properties of a paragraph markdown element\n    typealias Configuration = ParagraphMarkdownConfiguration\n    /// Creates a view that represents the body of a label\n    @ViewBuilder func makeBody(configuration: Configuration) -> Body\n}\n\npublic struct AnyParagraphMarkdownStyle: ParagraphMarkdownStyle {\n    var label: (Configuration) -> AnyView\n    init<S: ParagraphMarkdownStyle>(_ style: S) {\n        label = { AnyView(style.makeBody(configuration: $0)) }\n    }\n\n    public func makeBody(configuration: Configuration) -> some View {\n        label(configuration)\n    }\n}\n\n/// The properties of a paragraph markdown element\npublic struct ParagraphMarkdownConfiguration {\n    /// The content for this element\n    ///\n    /// You can use this to maintain the existing paragraph style:\n    ///\n    ///     content.label // maintains the default style\n    ///         .lineSpacing(20)\n    let content: InlineMarkdownConfiguration\n\n    private struct Label: View {\n        let content: InlineMarkdownConfiguration\n\n        var body: some View {\n            content.label\n        }\n    }\n\n    /// Returns a default heading markdown representation\n    public var label: some View {\n        Label(content: content)\n    }\n}\n\n/// The default paragraph style\npublic struct DefaultParagraphMarkdownStyle: ParagraphMarkdownStyle {\n    public init() { }\n    public func makeBody(configuration: Configuration) -> some View {\n        configuration.label\n    }\n}\n\npublic extension ParagraphMarkdownStyle where Self == DefaultParagraphMarkdownStyle {\n    /// The default paragraph style\n    static var `default`: Self { .init() }\n}\n\nprivate struct ParagraphMarkdownEnvironmentKey: EnvironmentKey {\n    static let defaultValue = AnyParagraphMarkdownStyle(.default)\n}\n\npublic extension EnvironmentValues {\n    /// The current paragraph markdown style\n    var markdownParagraphStyle: AnyParagraphMarkdownStyle {\n        get { self[ParagraphMarkdownEnvironmentKey.self] }\n        set { self[ParagraphMarkdownEnvironmentKey.self] = newValue }\n    }\n}\n\npublic extension View {\n    /// Sets the style for paragraph markdown elements\n    func markdownParagraphStyle<S>(_ style: S) -> some View where S: ParagraphMarkdownStyle {\n        environment(\\.markdownParagraphStyle, AnyParagraphMarkdownStyle(style))\n    }\n}\n"
  },
  {
    "path": "Sources/MarkdownText/Styles/Block Elements/QuoteStyle.swift",
    "content": "import SwiftUI\n\n/// A type that applies a custom appearance to quote markdown elements\npublic protocol QuoteMarkdownStyle {\n    associatedtype Body: View\n    /// The properties of a quote markdown element\n    typealias Configuration = QuoteMarkdownConfiguration\n    /// Creates a view that represents the body of a label\n    @ViewBuilder func makeBody(configuration: Configuration) -> Body\n}\n\npublic struct AnyQuoteMarkdownStyle: QuoteMarkdownStyle {\n    var label: (Configuration) -> AnyView\n    init<S: QuoteMarkdownStyle>(_ style: S) {\n        label = { AnyView(style.makeBody(configuration: $0)) }\n    }\n\n    public func makeBody(configuration: Configuration) -> some View {\n        label(configuration)\n    }\n}\n\n/// The properties of a quote markdown element\npublic struct QuoteMarkdownConfiguration {\n    /// The content for this element\n    ///\n    /// You can use this to maintain the existing heading style:\n    ///\n    ///     content.label // maintains its font style\n    ///         .padding()\n    ///         .background {\n    ///             Color.primary\n    ///                 .opacity(0.05)\n    ///                 .cornerRadius(13)\n    ///         }\n    public let content: ParagraphMarkdownConfiguration\n\n    private struct Label: View {\n        let paragraph: ParagraphMarkdownConfiguration\n\n        var body: some View {\n            paragraph.label\n        }\n    }\n\n    /// Returns a default quote markdown representation\n    public var label: some View {\n        Label(paragraph: content)\n    }\n}\n\npublic struct DefaultQuoteMarkdownStyle: QuoteMarkdownStyle {\n    public init() { }\n    public func makeBody(configuration: Configuration) -> some View {\n        configuration.label\n    }\n}\n\npublic extension QuoteMarkdownStyle where Self == DefaultQuoteMarkdownStyle {\n    /// The default quote style\n    static var `default`: Self { .init() }\n}\n\nprivate struct QuoteMarkdownEnvironmentKey: EnvironmentKey {\n    static let defaultValue = AnyQuoteMarkdownStyle(.default)\n}\n\npublic extension EnvironmentValues {\n    /// The current quote markdown style\n    var markdownQuoteStyle: AnyQuoteMarkdownStyle {\n        get { self[QuoteMarkdownEnvironmentKey.self] }\n        set { self[QuoteMarkdownEnvironmentKey.self] = newValue }\n    }\n}\n\npublic extension View {\n    /// Sets the style for quote markdown elements\n    func markdownQuoteStyle<S>(_ style: S) -> some View where S: QuoteMarkdownStyle {\n        environment(\\.markdownQuoteStyle, AnyQuoteMarkdownStyle(style))\n    }\n}\n"
  },
  {
    "path": "Sources/MarkdownText/Styles/Block Elements/ThematicStyle.swift",
    "content": "import SwiftUI\n\n/// A type that applies a custom appearance to thematic break markdown elements\npublic protocol ThematicBreakMarkdownStyle {\n    associatedtype Body: View\n    /// The properties of a thematic break markdown element\n    typealias Configuration = ThematicMarkdownConfiguration\n    /// Creates a view that represents the body of a label\n    @ViewBuilder func makeBody(configuration: Configuration) -> Body\n}\n\n/// The properties of a thematic break markdown element\npublic struct AnyThematicMarkdownStyle: ThematicBreakMarkdownStyle {\n    var label: (Configuration) -> AnyView\n\n    init<S: ThematicBreakMarkdownStyle>(_ style: S) {\n        label = { AnyView(style.makeBody(configuration: $0)) }\n    }\n\n    public func makeBody(configuration: Configuration) -> some View {\n        label(configuration)\n    }\n}\n\npublic struct ThematicMarkdownConfiguration {\n    /// Returns a default thematic break markdown representation\n    public let label = Divider()\n}\n\n/// A thematic break style represented by a SwiftUI  `Divider`\npublic struct DefaultThematicMarkdownStyle: ThematicBreakMarkdownStyle {\n    public init() { }\n    public func makeBody(configuration: Configuration) -> some View {\n        configuration.label\n    }\n}\n\npublic extension ThematicBreakMarkdownStyle where Self == DefaultThematicMarkdownStyle {\n    /// A thematic break style represented by a SwiftUI  `Divider`\n    static var `default`: Self { .init() }\n}\n\nprivate struct MarkdownEnvironmentKey: EnvironmentKey {\n    static let defaultValue = AnyThematicMarkdownStyle(.default)\n}\n\npublic extension EnvironmentValues {\n    /// The current thematic break markdown style\n    var markdownThematicBreakStyle: AnyThematicMarkdownStyle {\n        get { self[MarkdownEnvironmentKey.self] }\n        set { self[MarkdownEnvironmentKey.self] = newValue }\n    }\n}\n\npublic extension View {\n    /// Sets the style for thematic break markdown elements\n    func markdownThematicBreakStyle<S>(_ style: S) -> some View where S: ThematicBreakMarkdownStyle {\n        environment(\\.markdownThematicBreakStyle, AnyThematicMarkdownStyle(style))\n    }\n}\n"
  },
  {
    "path": "Sources/MarkdownText/Styles/Inline Elements/EmphasisStyle.swift",
    "content": "import SwiftUI\n\n/// A type that applies a custom appearance to italic (emphasis) markdown elements\npublic protocol EmphasisMarkdownStyle {\n    /// The properties of an emphasis markdown element\n    typealias Configuration = EmphasisMarkdownConfiguration\n    /// Creates a view that represents the body of a label\n    func makeBody(configuration: Configuration) -> Text\n}\n\n/// The properties of an italic (emphasis) markdown element\npublic struct EmphasisMarkdownConfiguration {\n    /// The textual content for this element\n    public let content: Text\n    /// Returns a default italic (emphasis) markdown representation\n    public var label: Text { content.italic() }\n}\n\n/// An italic (emphasis) style that applies the `italic` modifier to its textual content\npublic struct DefaultEmphasisMarkdownStyle: EmphasisMarkdownStyle {\n    public init() { }\n    public func makeBody(configuration: Configuration) -> Text {\n        configuration.label\n    }\n}\n\npublic extension EmphasisMarkdownStyle where Self == DefaultEmphasisMarkdownStyle {\n    /// An italic (emphasis) style that applies the `italic` modifier to its textual content\n    static var `default`: Self { .init() }\n}\n\nprivate struct EmphasisMarkdownEnvironmentKey: EnvironmentKey {\n    static let defaultValue: EmphasisMarkdownStyle = DefaultEmphasisMarkdownStyle()\n}\n\npublic extension EnvironmentValues {\n    /// The current italic (amphasis) markdown style\n    var markdownEmphasisStyle: EmphasisMarkdownStyle {\n        get { self[EmphasisMarkdownEnvironmentKey.self] }\n        set { self[EmphasisMarkdownEnvironmentKey.self] = newValue }\n    }\n}\n\npublic extension View {\n    /// Sets the style for italic (emphasis) markdown elements\n    func markdownEmphasisStyle<S>(_ style: S) -> some View where S: EmphasisMarkdownStyle {\n        environment(\\.markdownEmphasisStyle, style)\n    }\n}\n"
  },
  {
    "path": "Sources/MarkdownText/Styles/Inline Elements/InlineCodeStyle.swift",
    "content": "import SwiftUI\n\n/// A type that applies a custom appearance to inline code markdown elements\npublic protocol InlineCodeMarkdownStyle {\n    /// The properties of an inline code markdown element\n    typealias Configuration = InlineCodeMarkdownConfiguration\n    /// Creates a view that represents the body of a label\n    func makeBody(configuration: Configuration) -> Text\n}\n\n/// The properties of an inline code markdown element\npublic struct InlineCodeMarkdownConfiguration {\n    /// The code for this element\n    public let code: String\n    internal let font: Font?\n\n    /// Returns a default inline code markdown representation\n    public var label: Text {\n        #if os(macOS)\n        if #available(macOS 12, *) {\n            return Text(code)\n                .font(font?.monospaced() ?? .system(.body, design: .monospaced))\n        } else {\n            return Text(code)\n                .font(.system(.body, design: .monospaced))\n        }\n        #elseif os(iOS)\n        if #available(iOS 15, *) {\n            return Text(code)\n                .font(font?.monospaced() ?? .system(.body, design: .monospaced))\n        } else {\n            return Text(code)\n                .font(.system(.body, design: .monospaced))\n        }\n        #else\n        return Text(code)\n            .font(.system(.body, design: .monospaced))\n        #endif\n    }\n}\n\n/// An inline code style that applies the `monospaced` modifier to its textual content\npublic struct DefaultInlineCodeMarkdownStyle: InlineCodeMarkdownStyle {\n    public init() { }\n    public func makeBody(configuration: Configuration) -> Text {\n        configuration.label\n    }\n}\n\npublic extension InlineCodeMarkdownStyle where Self == DefaultInlineCodeMarkdownStyle {\n    /// An inline code style that applies the `monospaced` modifier to its textual content\n    static var `default`: Self { .init() }\n}\n\nprivate struct InlineCodeMarkdownEnvironmentKey: EnvironmentKey {\n    static let defaultValue: InlineCodeMarkdownStyle = DefaultInlineCodeMarkdownStyle()\n}\n\npublic extension EnvironmentValues {\n    /// The current inline code markdown style\n    var markdownInlineCodeStyle: InlineCodeMarkdownStyle {\n        get { self[InlineCodeMarkdownEnvironmentKey.self] }\n        set { self[InlineCodeMarkdownEnvironmentKey.self] = newValue }\n    }\n}\n\npublic extension View {\n    /// Sets the style for inline code markdown elements\n    func markdownInlineCodeStyle<S>(_ style: S) -> some View where S: InlineCodeMarkdownStyle {\n        environment(\\.markdownInlineCodeStyle, style)\n    }\n}\n"
  },
  {
    "path": "Sources/MarkdownText/Styles/Inline Elements/InlineLinkStyle.swift",
    "content": "import SwiftUI\n\n/// A type that applies a custom appearance to inline link markdown elements\npublic protocol InlineLinkMarkdownStyle {\n    /// The properties of an inline link markdown element\n    typealias Configuration = InlineLinkMarkdownConfiguration\n    /// Creates a view that represents the body of a label\n    func makeBody(configuration: Configuration) -> Text\n}\n\n/// The properties of an inline link markdown element\npublic struct InlineLinkMarkdownConfiguration {\n    /// The textual content for this element\n    public let content: Text\n    /// Returns a default inline link markdown representation\n    public var label: Text { content }\n}\n\n/// An inline link style that sets the `foregroundColor` to the view's current `accentColor`\npublic struct DefaultInlineLinkMarkdownStyle: InlineLinkMarkdownStyle {\n    public init() { }\n    public func makeBody(configuration: Configuration) -> Text {\n        configuration.label\n            .foregroundColor(.accentColor)\n    }\n}\n\npublic extension InlineLinkMarkdownStyle where Self == DefaultInlineLinkMarkdownStyle {\n    /// An inline link style that sets the `foregroundColor` to the view's current `accentColor`\n    ///\n    /// - note: Inline links are always **non-interactive**.\n    static var nonInteractiveInline: Self { .init() }\n}\n\nprivate struct InlineLinkMarkdownEnvironmentKey: EnvironmentKey {\n    static let defaultValue: InlineLinkMarkdownStyle = DefaultInlineLinkMarkdownStyle.nonInteractiveInline\n}\n\npublic extension EnvironmentValues {\n    /// The current inline link markdown style\n    var markdownInlineLinkStyle: InlineLinkMarkdownStyle {\n        get { self[InlineLinkMarkdownEnvironmentKey.self] }\n        set { self[InlineLinkMarkdownEnvironmentKey.self] = newValue }\n    }\n}\n\npublic extension View {\n    /// Sets the style for inline link markdown elements\n    func markdownInlineLinkStyle<S>(_ style: S) -> some View where S: InlineLinkMarkdownStyle {\n        environment(\\.markdownInlineLinkStyle, style)\n    }\n}\n"
  },
  {
    "path": "Sources/MarkdownText/Styles/Inline Elements/StrikethroughStyle.swift",
    "content": "import SwiftUI\n\n/// A type that applies a custom appearance to strikethough markdown elements\npublic protocol StrikethroughMarkdownStyle {\n    /// The properties of a strikethough  markdown element\n    typealias Configuration = StrikethroughMarkdownConfiguration\n    /// Creates a view that represents the body of a label\n    func makeBody(configuration: Configuration) -> Text\n}\n\n/// The properties of a strikethrough markdown element\npublic struct StrikethroughMarkdownConfiguration {\n    /// The textual content for this element\n    public let content: Text\n    /// Returns a default strikethrough markdown representation\n    public var label: Text { content.strikethrough() }\n}\n\n/// An strikethrough style that applies the `strikethrough` modifier to its textual content\npublic struct DefaultStrikethroughMarkdownStyle: StrikethroughMarkdownStyle {\n    public init() { }\n    public func makeBody(configuration: Configuration) -> Text {\n        configuration.label\n    }\n}\n\npublic extension StrikethroughMarkdownStyle where Self == DefaultStrikethroughMarkdownStyle {\n    /// An strikethrough style that applies the `strikethrough` modifier to its textual content\n    static var `default`: Self { .init() }\n}\n\nprivate struct StrikethroughMarkdownEnvironmentKey: EnvironmentKey {\n    static let defaultValue: StrikethroughMarkdownStyle = DefaultStrikethroughMarkdownStyle()\n}\n\npublic extension EnvironmentValues {\n    /// The current strikethrough markdown style\n    var markdownStrikethroughStyle: StrikethroughMarkdownStyle {\n        get { self[StrikethroughMarkdownEnvironmentKey.self] }\n        set { self[StrikethroughMarkdownEnvironmentKey.self] = newValue }\n    }\n}\n\npublic extension View {\n    /// Sets the style for strikethrough markdown elements\n    func markdownStrikethroughStyle<S>(_ style: S) -> some View where S: StrikethroughMarkdownStyle {\n        environment(\\.markdownStrikethroughStyle, style)\n    }\n}\n"
  },
  {
    "path": "Sources/MarkdownText/Styles/Inline Elements/StrongStyle.swift",
    "content": "import SwiftUI\n\n/// A type that applies a custom appearance to bold (strong) markdown elements\npublic protocol StrongMarkdownStyle {\n    /// The properties of a bold (strong) markdown element\n    typealias Configuration = StrongMarkdownConfiguration\n    /// Creates a view that represents the body of a label\n    func makeBody(configuration: Configuration) -> Text\n}\n\n/// The properties of a bold (strong) markdown element\npublic struct StrongMarkdownConfiguration {\n    /// The textual content for this element\n    public let content: Text\n    /// Returns a default bold (strong) markdown representation\n    public var label: Text { content.bold() }\n}\n\n/// An bold (strong) style that applies the `bold` modifier to its textual content\npublic struct DefaultStrongMarkdownStyle: StrongMarkdownStyle {\n    public init() { }\n    public func makeBody(configuration: Configuration) -> Text {\n        configuration.label\n    }\n}\n\npublic extension StrongMarkdownStyle where Self == DefaultStrongMarkdownStyle {\n    /// An bold (strong) style that applies the `bold` modifier to its textual content\n    static var `default`: Self { .init() }\n}\n\nprivate struct StrongMarkdownEnvironmentKey: EnvironmentKey {\n    static let defaultValue: StrongMarkdownStyle = DefaultStrongMarkdownStyle()\n}\n\npublic extension EnvironmentValues {\n    /// The current bold (strong) markdown style\n    var markdownStrongStyle: StrongMarkdownStyle {\n        get { self[StrongMarkdownEnvironmentKey.self] }\n        set { self[StrongMarkdownEnvironmentKey.self] = newValue }\n    }\n}\n\npublic extension View {\n    /// Sets the style for bold (strong) markdown elements\n    func markdownStrongStyle<S>(_ style: S) -> some View where S: StrongMarkdownStyle {\n        environment(\\.markdownStrongStyle, style)\n    }\n}\n"
  },
  {
    "path": "Sources/MarkdownText/Styles/Lists/Bullets/ChecklistBulletStyle.swift",
    "content": "import SwiftUI\nimport SwiftUIBackports\n\n/// A type that applies a custom appearance to checklist bullet markdown elements\npublic protocol CheckListBulletMarkdownStyle {\n    associatedtype Body: View\n    /// The properties of a checklist bullet markdown element\n    typealias Configuration = CheckListBulletMarkdownConfiguration\n    /// Creates a view that represents the body of a label\n    func makeBody(configuration: Configuration) -> Body\n}\n\npublic struct AnyCheckListBulletMarkdownStyle: CheckListBulletMarkdownStyle {\n    var label: (Configuration) -> AnyView\n    init<S: CheckListBulletMarkdownStyle>(_ style: S) {\n        label = { AnyView(style.makeBody(configuration: $0)) }\n    }\n\n    public func makeBody(configuration: Configuration) -> some View {\n        label(configuration)\n    }\n}\n\n/// The properties of a checklist bullet markdown element\npublic struct CheckListBulletMarkdownConfiguration {\n    private struct Label: View {\n        @ScaledMetric private var reservedWidth: CGFloat = 25\n        public let isChecked: Bool\n\n        var body: some View {\n            Image(systemName: isChecked ? \"checkmark.circle.fill\" : \"circle\")\n                .frame(minWidth: reservedWidth)\n        }\n    }\n\n    /// A boolean that represents whether the checklist item is selected or not\n    public let isChecked: Bool\n    /// Returns a default checklist bullet markdown representation\n    public var label: some View {\n        Label(isChecked: isChecked)\n    }\n}\n\n/// The default checklist bullet style\npublic struct DefaultChecklistBulletMarkdownStyle: CheckListBulletMarkdownStyle {\n    public init() { }\n    public func makeBody(configuration: Configuration) -> some View {\n        configuration.label\n    }\n}\n\npublic extension CheckListBulletMarkdownStyle where Self == DefaultChecklistBulletMarkdownStyle {\n    /// The default checklist bullet style\n    static var `default`: Self { .init() }\n}\n\nprivate struct ChecklistBulletMarkdownEnvironmentKey: EnvironmentKey {\n    static let defaultValue: AnyCheckListBulletMarkdownStyle = .init(DefaultChecklistBulletMarkdownStyle())\n}\n\npublic extension EnvironmentValues {\n    /// The current checklist bullet markdown style\n    var markdownCheckListBulletStyle: AnyCheckListBulletMarkdownStyle {\n        get { self[ChecklistBulletMarkdownEnvironmentKey.self] }\n        set { self[ChecklistBulletMarkdownEnvironmentKey.self] = newValue }\n    }\n}\n\npublic extension View {\n    /// Sets the style for checklist bullet markdown elements\n    func markdownCheckListBulletStyle<S>(_ style: S) -> some View where S: CheckListBulletMarkdownStyle {\n        environment(\\.markdownCheckListBulletStyle, .init(style))\n    }\n}\n"
  },
  {
    "path": "Sources/MarkdownText/Styles/Lists/Bullets/OrderedBulletStyle.swift",
    "content": "import SwiftUI\nimport SwiftUIBackports\n\n/// A type that applies a custom appearance to ordered bullet markdown elements\npublic protocol OrderedListBulletMarkdownStyle {\n    associatedtype Body: View\n    /// The properties of a ordered bullet markdown element\n    typealias Configuration = OrderedListBulletMarkdownConfiguration\n    /// Creates a view that represents the body of a label\n    func makeBody(configuration: Configuration) -> Body\n}\n\npublic struct AnyOrderedListBulletMarkdownStyle: OrderedListBulletMarkdownStyle {\n    var label: (Configuration) -> AnyView\n    init<S: OrderedListBulletMarkdownStyle>(_ style: S) {\n        label = { AnyView(style.makeBody(configuration: $0)) }\n    }\n\n    public func makeBody(configuration: Configuration) -> some View {\n        label(configuration)\n    }\n}\n\n/// The properties of a ordered bullet markdown element\npublic struct OrderedListBulletMarkdownConfiguration {\n    struct Label: View {\n        @ScaledMetric private var reservedWidth: CGFloat = 25\n        let order: Int\n\n        var body: some View {\n            Text(\"\\(order).\")\n                .frame(minWidth: reservedWidth)\n        }\n    }\n\n    /// An integer value representing this element's order in the list\n    public let order: Int\n    /// Returns a default ordered bullet markdown representation\n    public var label: some View {\n        Label(order: order)\n    }\n}\n\n/// An ordered bullet style that presents its bullet as a numerical value (e.g. `1.`, `2.`)\npublic struct NumericallyOrderedListBulletMarkdownStyle: OrderedListBulletMarkdownStyle {\n    public init() { }\n    public func makeBody(configuration: Configuration) -> some View {\n        configuration.label\n    }\n}\n\npublic extension OrderedListBulletMarkdownStyle where Self == NumericallyOrderedListBulletMarkdownStyle {\n    /// An ordered bullet style that presents its bullet as a numerical value (e.g. `1.`, `2.`)\n    static var numerical: Self { .init() }\n}\n\nprivate struct OrderedBulletMarkdownEnvironmentKey: EnvironmentKey {\n    static let defaultValue: AnyOrderedListBulletMarkdownStyle = .init(.numerical)\n}\n\npublic extension EnvironmentValues {\n    /// The current ordered bullet markdown style\n    var markdownOrderedListBulletStyle: AnyOrderedListBulletMarkdownStyle {\n        get { self[OrderedBulletMarkdownEnvironmentKey.self] }\n        set { self[OrderedBulletMarkdownEnvironmentKey.self] = newValue }\n    }\n}\n\npublic extension View {\n    /// Sets the style for ordered bullet markdown elements\n    func markdownOrderedListBulletStyle<S>(_ style: S) -> some View where S: OrderedListBulletMarkdownStyle {\n        environment(\\.markdownOrderedListBulletStyle, .init(style))\n    }\n}\n"
  },
  {
    "path": "Sources/MarkdownText/Styles/Lists/Bullets/UnorderedBulletStyle.swift",
    "content": "import SwiftUI\nimport SwiftUIBackports\n\n/// Various styles for representing unordered list item bullet elements\n///\n///     ● Element one\n///     ● Element two\n///       ○ Element one\n///       ○ Element two\n///         ◼︎ Element one\n///         ◼︎ Element two\npublic enum UnorderedListBulletStyle: String {\n    /// Represents a filled circle bullet. By default this is used for all level-0 elements\n    ///\n    ///     ● Element one\n    ///     ● Element two\n    case filledCircle = \"●\"\n    /// Represents an outlined circle bullet. By default this is used for all level-1 elements\n    ///\n    ///     ○ Element one\n    ///     ○ Element two\n    case outlineCircle = \"○\"\n    /// Represents a filled square bullet. By default this is used for all elements greater than level 1\n    ///\n    ///     ◼︎ Element one\n    ///     ◼︎ Element two\n    case square = \"◼︎\"\n}\n\n/// A type that applies a custom appearance to unordered bullet markdown elements\npublic protocol UnorderedListBulletMarkdownStyle {\n    associatedtype Body: View\n    /// The properties of a unordered bullet markdown element\n    typealias Configuration = UnorderedListBulletMarkdownConfiguration\n    /// Creates a view that represents the body of a label\n    func makeBody(configuration: Configuration) -> Body\n}\n\npublic struct AnyUnorderedListBulletMarkdownStyle: UnorderedListBulletMarkdownStyle {\n    var label: (Configuration) -> AnyView\n    init<S: UnorderedListBulletMarkdownStyle>(_ style: S) {\n        label = { AnyView(style.makeBody(configuration: $0)) }\n    }\n\n    public func makeBody(configuration: Configuration) -> some View {\n        label(configuration)\n    }\n}\n\n/// The properties of a unordered bullet markdown element\npublic struct UnorderedListBulletMarkdownConfiguration {\n    struct Label: View {\n        @ScaledMetric private var reservedWidth: CGFloat = 25\n        let bulletStyle: UnorderedListBulletStyle\n        var body: some View {\n            Text(\"\\(bulletStyle.rawValue)\")\n                .frame(minWidth: reservedWidth)\n        }\n    }\n\n    /// An integer value representing this element's indentation level\n    public let level: Int\n    /// The preferred bullet style, based on the current indentation level\n    ///\n    ///     ● Element one\n    ///     ● Element two\n    ///       ○ Element one\n    ///       ○ Element two\n    ///         ◼︎ Element one\n    ///         ◼︎ Element two\n    public var preferredBulletStyle: UnorderedListBulletStyle {\n        switch level {\n        case 0: return .filledCircle\n        case 1: return .outlineCircle\n        default: return .square\n        }\n    }\n\n    /// Returns a default unordered bullet markdown representation\n    public var label: some View {\n        Label(bulletStyle: preferredBulletStyle)\n    }\n}\n\n/// An unordered bullet style that presents its bullets as `UnorderedListBulletStyle` elements, based on the elements indendation level\npublic struct DefaultUnorderedListBulletMarkdownStyle: UnorderedListBulletMarkdownStyle {\n    public init() { }\n    public func makeBody(configuration: Configuration) -> some View {\n        configuration.label\n    }\n}\n\npublic extension UnorderedListBulletMarkdownStyle where Self == DefaultUnorderedListBulletMarkdownStyle {\n    /// An unordered bullet style that presents its bullets as `UnorderedListBulletStyle` elements, based on the elements indendation level\n    static var automatic: Self { .init() }\n}\n\nprivate struct UnorderedListBulletMarkdownEnvironmentKey: EnvironmentKey {\n    static let defaultValue: AnyUnorderedListBulletMarkdownStyle = .init(.automatic)\n}\n\npublic extension EnvironmentValues {\n    /// The current unordered bullet markdown style\n    var markdownUnorderedListBulletStyle: AnyUnorderedListBulletMarkdownStyle {\n        get { self[UnorderedListBulletMarkdownEnvironmentKey.self] }\n        set { self[UnorderedListBulletMarkdownEnvironmentKey.self] = newValue }\n    }\n}\n\npublic extension View {\n    /// Sets the style for unordered bullet markdown elements\n    func markdownUnorderedListBulletStyle<S>(_ style: S) -> some View where S: UnorderedListBulletMarkdownStyle {\n        environment(\\.markdownUnorderedListBulletStyle, .init(style))\n    }\n}\n"
  },
  {
    "path": "Sources/MarkdownText/Styles/Lists/Items/CheckedListItemStyle.swift",
    "content": "import SwiftUI\nimport SwiftUIBackports\n\n/// A type that applies a custom appearance to checklist item markdown elements\npublic protocol CheckListItemMarkdownStyle {\n    associatedtype Body: View\n    /// The properties of a checklist item markdown element\n    typealias Configuration = CheckListItemMarkdownConfiguration\n    /// Creates a view that represents the body of a label\n    @ViewBuilder func makeBody(configuration: Configuration) -> Body\n}\n\npublic struct AnyCheckListItemMarkdownStyle: CheckListItemMarkdownStyle {\n    var label: (Configuration) -> AnyView\n    init<S: CheckListItemMarkdownStyle>(_ style: S) {\n        label = { AnyView(style.makeBody(configuration: $0)) }\n    }\n\n    public func makeBody(configuration: Configuration) -> some View {\n        label(configuration)\n    }\n}\n\n/// The properties of a checklist item markdown element\npublic struct CheckListItemMarkdownConfiguration {\n    private struct Item: View {\n        @ScaledMetric private var reservedWidth: CGFloat = 25\n        @Environment(\\.markdownParagraphStyle) private var paragraphStyle\n        @Environment(\\.markdownCheckListBulletStyle) private var bulletStyle\n        @Environment(\\.markdownCheckListItemBulletVisibility) private var bulletVisibility\n\n        let level: Int\n        let bullet: CheckListBulletMarkdownConfiguration\n        let paragraph: ParagraphMarkdownConfiguration\n\n        private var space: String {\n            Array(repeating: \"    \", count: level).joined()\n        }\n\n        var body: some View {\n            HStack(alignment: .firstTextBaseline, spacing: 0) {\n                Text(space)\n\n                Label {\n                    paragraphStyle.makeBody(configuration: paragraph)\n                } icon: {\n                    if bulletVisibility != .hidden {\n                        bulletStyle.makeBody(configuration: bullet)\n                            .frame(minWidth: reservedWidth)\n                    }\n                }\n                .labelStyle(.list)\n            }\n        }\n    }\n\n    /// An integer value representing this element's indentation level\n    public let level: Int\n    /// The bullet configuration for this element\n    public let bullet: CheckListBulletMarkdownConfiguration\n    /// The content configuration for this element\n    public let content: ParagraphMarkdownConfiguration\n    /// Returns a default checklist item markdown representation\n    public var label: some View {\n        Item(level: level, bullet: bullet, paragraph: content)\n    }\n}\n\n/// The default checklist item style\npublic struct DefaultCheckListItemMarkdownStyle: CheckListItemMarkdownStyle {\n    public init() { }\n    public func makeBody(configuration: Configuration) -> some View {\n        configuration.label\n    }\n}\n\npublic extension CheckListItemMarkdownStyle where Self == DefaultCheckListItemMarkdownStyle {\n    /// The default checklist item style\n    static var `default`: Self { .init() }\n}\n\nprivate struct CheckListItemMarkdownEnvironmentKey: EnvironmentKey {\n    static let defaultValue = AnyCheckListItemMarkdownStyle(.default)\n}\n\npublic extension EnvironmentValues {\n    /// The current checklist item markdown style\n    var markdownCheckListItemStyle: AnyCheckListItemMarkdownStyle {\n        get { self[CheckListItemMarkdownEnvironmentKey.self] }\n        set { self[CheckListItemMarkdownEnvironmentKey.self] = newValue }\n    }\n}\n\npublic extension View {\n    /// Sets the style for checklist item markdown elements\n    func markdownCheckListItemStyle<S>(_ style: S) -> some View where S: CheckListItemMarkdownStyle {\n        environment(\\.markdownCheckListItemStyle, AnyCheckListItemMarkdownStyle(style))\n    }\n}\n"
  },
  {
    "path": "Sources/MarkdownText/Styles/Lists/Items/OrderedListItemStyle.swift",
    "content": "import SwiftUI\nimport SwiftUIBackports\n\n/// A type that applies a custom appearance to ordered item markdown elements\npublic protocol OrderedListItemMarkdownStyle {\n    associatedtype Body: View\n    /// The properties of a ordered item markdown element\n    typealias Configuration = OrderedListItemMarkdownConfiguration\n    /// Creates a view that represents the body of a label\n    @ViewBuilder func makeBody(configuration: Configuration) -> Body\n}\n\npublic struct AnyOrderedListItemMarkdownStyle: OrderedListItemMarkdownStyle {\n    var label: (Configuration) -> AnyView\n    init<S: OrderedListItemMarkdownStyle>(_ style: S) {\n        label = { AnyView(style.makeBody(configuration: $0)) }\n    }\n\n    public func makeBody(configuration: Configuration) -> some View {\n        label(configuration)\n    }\n}\n\n/// The properties of a ordered item markdown element\npublic struct OrderedListItemMarkdownConfiguration {\n    private struct Item: View {\n        @ScaledMetric private var reservedWidth: CGFloat = 25\n        @Environment(\\.markdownParagraphStyle) private var paragraphStyle\n        @Environment(\\.markdownOrderedListBulletStyle) private var bulletStyle\n        @Environment(\\.markdownOrderedListItemBulletVisibility) private var bulletVisibility\n\n        public let level: Int\n        public let bullet: OrderedListBulletMarkdownConfiguration\n        public let paragraph: ParagraphMarkdownConfiguration\n\n        private var space: String {\n            Array(repeating: \"    \", count: level).joined()\n        }\n\n        var body: some View {\n            HStack(alignment: .firstTextBaseline, spacing: 0) {\n                Text(space)\n\n                Label {\n                    paragraphStyle.makeBody(configuration: paragraph)\n                } icon: {\n                    if bulletVisibility != .hidden {\n                        bulletStyle.makeBody(configuration: bullet)\n                            .frame(minWidth: reservedWidth)\n                    }\n                }\n                .labelStyle(.list)\n            }\n        }\n    }\n\n    /// An integer value representing this element's indentation level in the list\n    public let level: Int\n    /// The bullet configuration for this element\n    public let bullet: OrderedListBulletMarkdownConfiguration\n    /// The content configuration for this element\n    public let content: ParagraphMarkdownConfiguration\n    /// Returns a default ordered item markdown representation\n    public var label: some View {\n        Item(level: level, bullet: bullet, paragraph: content)\n    }\n}\n\n/// The default ordered item style\npublic struct DefaultOrderedListItemMarkdownStyle: OrderedListItemMarkdownStyle {\n    public init() { }\n    public func makeBody(configuration: Configuration) -> some View {\n        configuration.label\n    }\n}\n\npublic extension OrderedListItemMarkdownStyle where Self == DefaultOrderedListItemMarkdownStyle {\n    /// The default ordered item style\n    static var `default`: Self { .init() }\n}\n\nprivate struct OrderedListMarkdownEnvironmentKey: EnvironmentKey {\n    static let defaultValue = AnyOrderedListItemMarkdownStyle(.default)\n}\n\npublic extension EnvironmentValues {\n    /// The current ordered item markdown style\n    var markdownOrderedListItemStyle: AnyOrderedListItemMarkdownStyle {\n        get { self[OrderedListMarkdownEnvironmentKey.self] }\n        set { self[OrderedListMarkdownEnvironmentKey.self] = newValue }\n    }\n}\n\npublic extension View {\n    /// Sets the style for ordered item markdown elements\n    func markdownOrderedListItemStyle<S>(_ style: S) -> some View where S: OrderedListItemMarkdownStyle {\n        environment(\\.markdownOrderedListItemStyle, AnyOrderedListItemMarkdownStyle(style))\n    }\n}\n"
  },
  {
    "path": "Sources/MarkdownText/Styles/Lists/Items/UnorderedListItemStyle.swift",
    "content": "import SwiftUI\nimport SwiftUIBackports\n\n/// A type that applies a custom appearance to unordered item markdown elements\npublic protocol UnorderedListItemMarkdownStyle {\n    associatedtype Body: View\n    /// The properties of an unordered item markdown element\n    typealias Configuration = UnorderedListItemMarkdownConfiguration\n    /// Creates a view that represents the body of a label\n    @ViewBuilder func makeBody(configuration: Configuration) -> Body\n}\n\npublic struct AnyUnorderedListItemMarkdownStyle: UnorderedListItemMarkdownStyle {\n    var label: (Configuration) -> AnyView\n    init<S: UnorderedListItemMarkdownStyle>(_ style: S) {\n        label = { AnyView(style.makeBody(configuration: $0)) }\n    }\n\n    public func makeBody(configuration: Configuration) -> some View {\n        label(configuration)\n    }\n}\n\n/// The properties of an unordered item markdown element\npublic struct UnorderedListItemMarkdownConfiguration {\n    private struct Item: View {\n        @ScaledMetric private var reservedWidth: CGFloat = 25\n        @Environment(\\.markdownParagraphStyle) private var paragraphStyle\n        @Environment(\\.markdownUnorderedListBulletStyle) private var bulletStyle\n        @Environment(\\.markdownUnorderedListItemBulletVisibility) private var bulletVisibility\n\n        public let level: Int\n        public let bullet: UnorderedListBulletMarkdownConfiguration\n        public let paragraph: ParagraphMarkdownConfiguration\n\n        private var space: String {\n            Array(repeating: \"    \", count: level).joined()\n        }\n\n        var body: some View {\n            HStack(alignment: .firstTextBaseline, spacing: 0) {\n                Text(space)\n\n                Label {\n                    paragraphStyle.makeBody(configuration: paragraph)\n                } icon: {\n                    if bulletVisibility != .hidden {\n                        bulletStyle.makeBody(configuration: bullet)\n                            .frame(minWidth: reservedWidth)\n                    }\n                }\n                .labelStyle(.list)\n            }\n        }\n    }\n\n    /// An integer value representing this element's indentation level in the list\n    public let level: Int\n    /// The bullet configuration for this element\n    public let bullet: UnorderedListBulletMarkdownConfiguration\n    /// The content configuration for this element\n    public let content: ParagraphMarkdownConfiguration\n    /// Returns a default unordered item markdown representation\n    public var label: some View {\n        Item(level: level, bullet: bullet, paragraph: content)\n    }\n}\n\n/// The default unordered item style\npublic struct DefaultUnorderedListItemMarkdownStyle: UnorderedListItemMarkdownStyle {\n    public init() { }\n    public func makeBody(configuration: Configuration) -> some View {\n        configuration.label\n    }\n}\n\npublic extension UnorderedListItemMarkdownStyle where Self == DefaultUnorderedListItemMarkdownStyle {\n    /// The default unordered item style\n    static var `default`: Self { .init() }\n}\n\nprivate struct UnorderedListItemMarkdownEnvironmentKey: EnvironmentKey {\n    static let defaultValue = AnyUnorderedListItemMarkdownStyle(.default)\n}\n\npublic extension EnvironmentValues {\n    /// The current unordered item markdown style\n    var markdownUnorderedListItemStyle: AnyUnorderedListItemMarkdownStyle {\n        get { self[UnorderedListItemMarkdownEnvironmentKey.self] }\n        set { self[UnorderedListItemMarkdownEnvironmentKey.self] = newValue }\n    }\n}\n\npublic extension View {\n    /// Sets the style for unordered item markdown elements\n    func markdownUnorderedListItemStyle<S>(_ style: S) -> some View where S: UnorderedListItemMarkdownStyle {\n        environment(\\.markdownUnorderedListItemStyle, AnyUnorderedListItemMarkdownStyle(style))\n    }\n}\n"
  },
  {
    "path": "Sources/MarkdownText/Styles/Visibility/CheckListVisibility.swift",
    "content": "import SwiftUI\nimport SwiftUIBackports\n\nstruct CheckListItemMarkdownVisibility: EnvironmentKey {\n    static let defaultValue: Backport<Any>.Visibility = .automatic\n}\n\ninternal extension EnvironmentValues {\n    var markdownCheckListItemVisibility: CheckListItemMarkdownVisibility.Value {\n        get { self[CheckListItemMarkdownVisibility.self] }\n        set { self[CheckListItemMarkdownVisibility.self] = newValue }\n    }\n}\n\npublic extension View {\n    /// Sets the visibility for checklist item markdown elements\n    func markdownCheckListItem(_ visibility: Backport<Any>.Visibility) -> some View {\n        environment(\\.markdownCheckListItemVisibility, visibility)\n    }\n}\n\nstruct CheckListItemBulletMarkdownVisibility: EnvironmentKey {\n    static let defaultValue: Backport<Any>.Visibility = .automatic\n}\n\ninternal extension EnvironmentValues {\n    var markdownCheckListItemBulletVisibility: CheckListItemBulletMarkdownVisibility.Value {\n        get { self[CheckListItemBulletMarkdownVisibility.self] }\n        set { self[CheckListItemBulletMarkdownVisibility.self] = newValue }\n    }\n}\n\npublic extension View {\n    /// Sets the visibility for checklist bullet markdown elements\n    func markdownCheckListItemBullet(_ visibility: Backport<Any>.Visibility) -> some View {\n        environment(\\.markdownCheckListItemBulletVisibility, visibility)\n    }\n}\n"
  },
  {
    "path": "Sources/MarkdownText/Styles/Visibility/CodeVisibility.swift",
    "content": "import SwiftUI\nimport SwiftUIBackports\n\nstruct CodeMarkdownVisibility: EnvironmentKey {\n    static let defaultValue: Backport<Any>.Visibility = .automatic\n}\n\ninternal extension EnvironmentValues {\n    var markdownCodeVisibility: CodeMarkdownVisibility.Value {\n        get { self[CodeMarkdownVisibility.self] }\n        set { self[CodeMarkdownVisibility.self] = newValue }\n    }\n}\n\npublic extension View {\n    /// Sets the visibility for code block markdown elements\n    func markdownCode(_ visibility: Backport<Any>.Visibility) -> some View {\n        environment(\\.markdownCodeVisibility, visibility)\n    }\n}\n"
  },
  {
    "path": "Sources/MarkdownText/Styles/Visibility/HeadingVisibility.swift",
    "content": "import SwiftUI\nimport SwiftUIBackports\n\n#warning(\"Refactor to allow for range based API as well (inspo: DynamicType API)\")\n\nstruct HeadingMarkdownVisibility: EnvironmentKey {\n    static let defaultValue: Backport<Any>.Visibility = .automatic\n}\n\ninternal extension EnvironmentValues {\n    var markdownHeadingVisibility: HeadingMarkdownVisibility.Value {\n        get { self[HeadingMarkdownVisibility.self] }\n        set { self[HeadingMarkdownVisibility.self] = newValue }\n    }\n}\n\npublic extension View {\n    /// Sets the visibility for heading markdown elements\n    func markdownHeading(_ visibility: Backport<Any>.Visibility) -> some View {\n        environment(\\.markdownHeadingVisibility, visibility)\n    }\n}\n"
  },
  {
    "path": "Sources/MarkdownText/Styles/Visibility/ImageVisibility.swift",
    "content": "import SwiftUI\nimport SwiftUIBackports\n\nstruct ImageMarkdownVisibility: EnvironmentKey {\n    static let defaultValue: Backport<Any>.Visibility = .automatic\n}\n\ninternal extension EnvironmentValues {\n    var markdownImageVisibility: ImageMarkdownVisibility.Value {\n        get { self[ImageMarkdownVisibility.self] }\n        set { self[ImageMarkdownVisibility.self] = newValue }\n    }\n}\n\npublic extension View {\n    /// Sets the visibility for image markdown elements\n    func markdownImage(_ visibility: Backport<Any>.Visibility) -> some View {\n        environment(\\.markdownImageVisibility, visibility)\n    }\n}\n"
  },
  {
    "path": "Sources/MarkdownText/Styles/Visibility/ListItemVisibility.swift",
    "content": "import SwiftUI\nimport SwiftUIBackports\n\nstruct ListMarkdownVisibility: EnvironmentKey {\n    static let defaultValue: Backport<Any>.Visibility = .automatic\n}\n\ninternal extension EnvironmentValues {\n    var markdownListVisibility: ListMarkdownVisibility.Value {\n        get { self[ListMarkdownVisibility.self] }\n        set { self[ListMarkdownVisibility.self] = newValue }\n    }\n}\n\npublic extension View {\n    /// Sets the visibility for all list item markdown elements\n    func markdownList(_ visibility: Backport<Any>.Visibility) -> some View {\n        environment(\\.markdownListVisibility, visibility)\n    }\n}\n"
  },
  {
    "path": "Sources/MarkdownText/Styles/Visibility/OrderedListVisibility.swift",
    "content": "import SwiftUI\nimport SwiftUIBackports\n\nstruct OrderedListItemMarkdownVisibility: EnvironmentKey {\n    static let defaultValue: Backport<Any>.Visibility = .automatic\n}\n\ninternal extension EnvironmentValues {\n    var markdownOrderedListItemVisibility: OrderedListItemMarkdownVisibility.Value {\n        get { self[OrderedListItemMarkdownVisibility.self] }\n        set { self[OrderedListItemMarkdownVisibility.self] = newValue }\n    }\n}\n\npublic extension View {\n    /// Sets the visibility for ordered list markdown elements\n    func markdownOrderedListItem(_ visibility: Backport<Any>.Visibility) -> some View {\n        environment(\\.markdownOrderedListItemVisibility, visibility)\n    }\n}\n\nstruct OrderedListItemBulletMarkdownVisibility: EnvironmentKey {\n    static let defaultValue: Backport<Any>.Visibility = .automatic\n}\n\ninternal extension EnvironmentValues {\n    var markdownOrderedListItemBulletVisibility: OrderedListItemBulletMarkdownVisibility.Value {\n        get { self[OrderedListItemBulletMarkdownVisibility.self] }\n        set { self[OrderedListItemBulletMarkdownVisibility.self] = newValue }\n    }\n}\n\npublic extension View {\n    /// Sets the visibility for ordered bullet markdown elements\n    func markdownOrderedListItemBullet(_ visibility: Backport<Any>.Visibility) -> some View {\n        environment(\\.markdownOrderedListItemBulletVisibility, visibility)\n    }\n}\n"
  },
  {
    "path": "Sources/MarkdownText/Styles/Visibility/QuoteVisibility.swift",
    "content": "import SwiftUI\nimport SwiftUIBackports\n\nstruct QuoteMarkdownVisibility: EnvironmentKey {\n    static let defaultValue: Backport<Any>.Visibility = .automatic\n}\n\ninternal extension EnvironmentValues {\n    var markdownQuoteListVisibility: QuoteMarkdownVisibility.Value {\n        get { self[QuoteMarkdownVisibility.self] }\n        set { self[QuoteMarkdownVisibility.self] = newValue }\n    }\n}\n\npublic extension View {\n    /// Sets the visibility for quote markdown elements\n    func markdownQuote(_ visibility: Backport<Any>.Visibility) -> some View {\n        environment(\\.markdownQuoteListVisibility, visibility)\n    }\n}\n"
  },
  {
    "path": "Sources/MarkdownText/Styles/Visibility/ThematicVisibility.swift",
    "content": "import SwiftUI\nimport SwiftUIBackports\n\nstruct ThematicBreakMarkdownVisibility: EnvironmentKey {\n    static let defaultValue: Backport<Any>.Visibility = .automatic\n}\n\ninternal extension EnvironmentValues {\n    var markdownThematicBreakVisibility: ThematicBreakMarkdownVisibility.Value {\n        get { self[ThematicBreakMarkdownVisibility.self] }\n        set { self[ThematicBreakMarkdownVisibility.self] = newValue }\n    }\n}\n\npublic extension View {\n    /// Sets the visibility for thematic break markdown elements\n    func markdownThematicBreak(_ visibility: Backport<Any>.Visibility) -> some View {\n        environment(\\.markdownThematicBreakVisibility, visibility)\n    }\n}\n"
  },
  {
    "path": "Sources/MarkdownText/Styles/Visibility/UnorderedListVisibility.swift",
    "content": "import SwiftUI\nimport SwiftUIBackports\n\nstruct UnorderedListItemMarkdownVisibility: EnvironmentKey {\n    static let defaultValue: Backport<Any>.Visibility = .automatic\n}\n\ninternal extension EnvironmentValues {\n    var markdownUnorderedListItemVisibility: UnorderedListItemMarkdownVisibility.Value {\n        get { self[UnorderedListItemMarkdownVisibility.self] }\n        set { self[UnorderedListItemMarkdownVisibility.self] = newValue }\n    }\n}\n\npublic extension View {\n    /// Sets the visibility for unordered item markdown elements\n    func markdownUnorderedListItem(_ visibility: Backport<Any>.Visibility) -> some View {\n        environment(\\.markdownUnorderedListItemVisibility, visibility)\n    }\n}\n\nstruct UnorderedListItemBulletMarkdownVisibility: EnvironmentKey {\n    static let defaultValue: Backport<Any>.Visibility = .automatic\n}\n\ninternal extension EnvironmentValues {\n    var markdownUnorderedListItemBulletVisibility: UnorderedListItemBulletMarkdownVisibility.Value {\n        get { self[UnorderedListItemBulletMarkdownVisibility.self] }\n        set { self[UnorderedListItemBulletMarkdownVisibility.self] = newValue }\n    }\n}\n\npublic extension View {\n    /// Sets the visibility for unordered bullet markdown elements\n    func markdownUnorderedListItemBullet(_ visibility: Backport<Any>.Visibility) -> some View {\n        environment(\\.markdownUnorderedListItemBulletVisibility, visibility)\n    }\n}\n"
  },
  {
    "path": "generate-docs.sh",
    "content": "#!/bin/sh\n\nswift package \\\n    --allow-writing-to-directory ./docs \\\n    generate-documentation \\\n    --disable-indexing \\\n    --output-path ./docs \\\n    --transform-for-static-hosting \\\n    --hosting-base-path ./docs"
  }
]