51 lines
1.9 KiB
Swift
51 lines
1.9 KiB
Swift
import Foundation
|
|
|
|
/// What a block *is* at the line/merge level. Advisory metadata captured
|
|
/// during parsing — used by the recompose engine (e.g. restyling every list
|
|
/// block when the document's indent unit changes) and available to future
|
|
/// outline/folding features. Styling itself still derives from the block's
|
|
/// content, not from this tag.
|
|
public enum BlockKind: Equatable, Sendable {
|
|
case paragraph
|
|
case heading(level: Int)
|
|
case quoteRun(isCallout: Bool)
|
|
case fence
|
|
case indentedCode
|
|
case mathDisplay
|
|
case table
|
|
case listItem
|
|
case thematicBreak
|
|
case htmlBlock
|
|
case blank
|
|
}
|
|
|
|
/// A Block is one paragraph of markdown — the unit of rendering.
|
|
///
|
|
/// Blocks are separated by newlines (`\n`). Each block carries:
|
|
/// - `id`: stable UUID so we can track which block the cursor is in
|
|
/// - `content`: the raw markdown text of this paragraph
|
|
/// - `range`: the character range within the full document string
|
|
/// - `kind`: advisory classification (see `BlockKind`)
|
|
///
|
|
/// The editor renders every block as rich text *except* the one containing
|
|
/// the cursor, which stays as raw markdown so the user can edit it.
|
|
public struct Block: Identifiable, Sendable {
|
|
public var id: UUID
|
|
public var content: String
|
|
public var range: NSRange
|
|
public var kind: BlockKind
|
|
/// Whether the text storage currently holds this block's full styling.
|
|
/// False = the block is pending lazy styling (base attributes, or stale
|
|
/// styling scheduled for the drain). Maintained by the recompose engine.
|
|
public var isStyled: Bool
|
|
|
|
public init(id: UUID = UUID(), content: String, range: NSRange,
|
|
kind: BlockKind = .paragraph, isStyled: Bool = false) {
|
|
self.id = id
|
|
self.content = content
|
|
self.range = range
|
|
self.kind = kind
|
|
self.isStyled = isStyled
|
|
}
|
|
}
|