Swift Markdown

repository·main·Indexed 25 days ago

https://github.com/swiftlang/swift-markdown

A Swift package for parsing, building, editing, and analyzing Markdown documents using a parser powered by GitHub-flavored Markdown's cmark-gfm implementation. It supports block directive syntax, Doxygen command parsing, and provides tools for traversing and modifying markup trees via MarkupVisitor, MarkupWalker, and MarkupRewriter. The library includes HTMLFormatter for generating HTML and MarkupFormatter for string representations.

Tokens
4.6K
Snippets
12
Records
42
Agent score
85%

What's inside swift-markdown

  1. Use Block Directives in Markdown

    main

    Block directives are syntax extensions that create attributed containers to hold other block elements (like paragraphs or lists) or other block directives.

    A block directive consists of three parts:

    1. Name: An at-symbol @ followed by a non-empty name (e.g., @Directive).
    2. Argument Text: Optional text inside parentheses () following the name.
    3. Content: The body of the directive wrapped in curly brackets {}.

    Syntax Examples

    With arguments and content:

    @Directive(x: 1, y: 2, z: 3) {
        - A
        - B
    }

    Without arguments:

    @Directive {
        - A
        - B
    }

    Without content (omitting curly brackets):

    @TOC
    
    # Title
    @Directive(x: 1, y: 2
               z: 3)
    {
        - A
        - B
        - C
    }
  2. Nesting and Indentation in Block Directives

    main

    Block directives support nesting and flexible indentation.

    • Indentation: You can indent the name, arguments, and contents any amount.
    • Content Indentation: For the directive's content, indentation is established by the first non-blank line. Subsequent lines follow this indentation level.
    • Parsing: Lines that do not form part of the block directive definition are handed off to the cmark parser. Swift Markdown automatically adjusts source locations reported by cmark to account for the directive syntax.
    @Outer {
            @Inner {
              - A
                - B
            }
    }
  3. Modify elements directly in a Markup tree

    main

    Swift Markdown uses a persistent tree structure with copy-on-write value types. When you modify an element, Swift Markdown creates copies of the necessary substructure to create a unique root, leaving the original tree unchanged.

    To modify an element, traverse the tree using child(through:) to locate the specific node, cast it to the appropriate type (e.g., Text), and update its properties.

    import Markdown
    
    let source = "This is *emphasized.*
    let document = Document(parsing: source)
    
    // Traverse to the Text element inside Emphasis inside Paragraph
    var text = document.child(through:
        0, // Paragraph
        1, // Emphasis
        0) as! Text // Text
    
    // Modifying the property creates a new version of the tree via the .root property
    text.string = "really emphasized!"
    print(text.root.debugDescription())
    
    // The original document remains unchanged
    print(document.debugDescription())
  4. Enable Doxygen command parsing

    main

    To facilitate transitioning from other Markdown parsers, Swift Markdown can parse a limited set of Doxygen commands (using \ or @ prefixes). When enabled, these commands appear as regular Markup types in the resulting document hierarchy.

    To enable this feature, include the following options when parsing a Document:

    • ParseOptions/parseBlockDirectives
    • ParseOptions/parseMinimalDoxygen
  5. Build Markup Trees programmatically

    main

    Instead of parsing text, you can build trees of Markup elements declaratively using the initializers provided for various element types. This is useful for programmatically inserting content from other data sources into specific elements.

    import Markdown
    
    let document = Document(
        Paragraph(
            Text("This is a "),
            Emphasis(
                Text("paragraph.")))
    )
  6. Add Swift Markdown as a dependency

    main

    To use Swift Markdown in your project, add it to your Package.swift manifest. First, add the repository URL to your dependencies array, then add the Markdown product to your specific target's dependencies.

    // In Package.swift
    .package(url: "https://github.com/swiftlang/swift-markdown.git", branch: "main"),
    
    // In your target declaration
    .target(
        name: "MyTarget", 
        dependencies: [
            .product(name: "Markdown", package: "swift-markdown"),
        ]
    ),