SwiftMarkdownBuilder

develop

`resultBuilder` support for `swift-markdown`
DoccZz/SwiftMarkdownBuilder

SwiftMarkdownBuilder

resultBuilder support for swift-markdown.

The default way to build Markdown in swift-markdown is to use varargs initializers, e.g. as in the example from the README.md:

let document = Document(
    Paragraph(
        Text("This is a "),
        Emphasis(
            Text("paragraph."))))

Wouldn't it be nice to be able to use a SwiftUI like "resultBuilder" syntax, like:

let document = Document {
  Paragraph {
    "This is a "
    "paragraph"
      .emphasis()
  }
}

And maybe even control structures like:

let document = Document {
  "Our Tasks:"
    .font(.largeTitle)
  
  List {
    ForEach(todos) { todo in
      Text(todo.title)
    }
  }
}

Or custom Markdown "views":

struct TOC: DynamicMarkdownBlock {
  let pages : [ Page ]
  
  var body: [ MarkdownBlock ] {
    "Table of Contents"
      .font(.title)
    
    ForEach(pages) { page in
      Paragraph {
        Text(page.title)
          .font(.title2)
        
        Text(page.abstract)
      }
    }
  }
}

That's what we play with here.

Maybe we can get it to a state suitable for a PR on swift-markdown itself.

Status

An experiment for curious people. Work in progress.

It is not entirely clear how useful this thing is. Is there really a usecase for building Markdown in Swift? 😃

A goal is/was to not come up with protocols/structures specific to the resultBuilders, but to directly attach to the ones provided by swift-markdown already.

If that would be internal to the Markdown module, a few hacky things could be dropped (i.e. because the API could be accessed).

The implementation also doesn't have to resort to the type-safyness attached to SwiftUI style setups, because the swift-markdown protocols do not use associated types. Also, it doesn't need two-way setups like Binding.

Things missing:

  • table stuff (needs an own builder for scoping the contents), but could be similar to the macOS SwiftUI table
  • List
  • conditionals
  • finish the ForEach
  • an Environment maybe
  • also add an HTML resultBuilder?
  • many more things?

Maybe more things from SwiftBlocksUI could be used (it generates Slack JSON block structures, but those are essentially just fancy markdown).

Usage in a Swift Package

Example Package.swift:

// swift-tools-version:5.3

import PackageDescription

let package = Package(
  name         : "MyWebsite",
  products     : [ .executable(name: "MyWebsite", targets: [ "MyWebsite" ]) ],
  dependencies : [
    .package(url: "https://github.com/DoccZz/SwiftMarkdownBuilder.git", from: "0.1.0")
  ],
  targets: [ 
    .target(name: "MyWebsite", dependencies: [ 
      .product(name: "MarkdownBuilder", package: "SwiftMarkdownBuilder") 
    ])
  ]
)

Who

SwiftMarkdownBuilder is brought to you by the Always Right Institute and ZeeZide. We like feedback, GitHub stars, cool contract work, presumably any form of praise you can think of.

Description

  • Swift Tools 5.3.0
View More Packages from this Author

Dependencies

Last updated: Tue Mar 19 2024 05:53:23 GMT-0900 (Hawaii-Aleutian Daylight Time)