Watch: activity line on working cards, All threads browsing, a thread's subagents, Load earlier, and markdown messages

This commit is contained in:
gib committed 2026-11-02 13:10:02 -05:00
1 parent abd2fd0e13
commit d916bfbab5
21 files changed
+928 -46

No files matched your search

+50
View File
@@ -0,0 +1,50 @@
// Message text as styled text. Inline markdown (bold, italics, inline code, links) goes through
// `AttributedString(markdown:)`. Block syntax is rewritten line by line first, since SwiftUI's Text
// runs full-parsed paragraphs together: headings turn bold, list markers turn into bullets, quote
// markers go, and fenced code keeps its lines in monospace.
import Foundation
enum Markdown {
static func render(_ source: String) -> AttributedString {
var result = AttributedString()
var fenced = false
var first = true
for line in source.split(separator: "\n", omittingEmptySubsequences: false).map(String.init) {
if line.trimmingCharacters(in: .whitespaces).hasPrefix("```") {
fenced.toggle()
continue
}
if !first { result += AttributedString("\n") }
first = false
if fenced {
var code = AttributedString(line)
code.inlinePresentationIntent = .code
result += code
} else {
result += inline(block(line))
}
}
return result
}
/// One line with its block syntax rewritten as inline markdown or plain text.
static func block(_ line: String) -> String {
if let heading = line.wholeMatch(of: /\s{0,3}#{1,6}\s+(.+?)[\s#]*/) {
return "**\(heading.1)**"
}
if let item = line.wholeMatch(of: /(\s*)[-*+]\s+(.*)/) {
return "\(item.1)• \(item.2)"
}
if let quote = line.wholeMatch(of: /\s{0,3}>\s?(.*)/) {
return String(quote.1)
}
return line
}
/// Inline markdown, or the line as plain text when it does not parse.
private static func inline(_ line: String) -> AttributedString {
let options = AttributedString.MarkdownParsingOptions(interpretedSyntax: .inlineOnlyPreservingWhitespace)
return (try? AttributedString(markdown: line, options: options)) ?? AttributedString(line)
}
}