Let the human comment on each decision in the ready-for-merge card

This commit is contained in:
Ian Gulliver
2026-10-21 16:05:26 -07:00
parent 8202e9fc9f
commit ccb08ab6ec
7 changed files with 166 additions and 45 deletions
+46 -2
View File
@@ -27,8 +27,10 @@ private let leadToken = Re(#"^\s*(\S*)([\s\S]*)$"#)
struct MDItem: Sendable {
var choice: String?
var choiceIndex = 0
var discuss = false
var index = 0
var raw = ""
var quote = ""
var inline: [MDInline] = []
var blocks: [MDBlock] = []
}
@@ -74,6 +76,7 @@ struct Re: Sendable {
}
private let choiceMarker = Re(#"^(\([ *]\)|\[[ xX]\])\s+(\S.*?)\s*$"#)
private let discussMarker = Re(#"^\(\?\)\s+(.*)$"#)
private let detailsOpen = Re(#"^\s*<details>\s*(?:<summary>(.*?)</summary>)?\s*$"#, caseless: true)
private let summaryLine = Re(#"^\s*<summary>(.*?)</summary>\s*$"#, caseless: true)
private let detailsClose = Re(#"^\s*</details>\s*$"#, caseless: true)
@@ -92,6 +95,42 @@ func parseMarkdown(_ src: String, choices: Bool = false) -> [MDBlock] {
return blocks(text.components(separatedBy: "\n"), choices)
}
func numberMarked(_ blocks: [MDBlock], _ next: inout Int) -> [MDBlock] {
blocks.map { block in
switch block {
case .list(let ordered, let start, let items, let grid):
return .list(ordered: ordered, start: start, items: items.map { item in
var out = item
if item.choice != nil || item.discuss {
out.index = next
next += 1
}
out.blocks = numberMarked(item.blocks, &next)
return out
}, grid: grid)
case .quote(let inner):
return .quote(numberMarked(inner, &next))
case .details(let summary, let body):
return .details(summary: summary, body: numberMarked(body, &next))
default:
return block
}
}
}
func discussItems(_ blocks: [MDBlock]) -> [MDItem] {
blocks.flatMap { block -> [MDItem] in
switch block {
case .list(_, _, let items, _):
items.flatMap { ($0.discuss ? [$0] : []) + discussItems($0.blocks) }
case .quote(let inner), .details(_, let inner):
discussItems(inner)
default:
[]
}
}
}
func parseInline(_ src: String) -> [MDInline] {
inline(src)
}
@@ -282,10 +321,15 @@ private func parseList(_ lines: [String], _ start: Int, _ choices: Bool) -> (MDB
return (.list(ordered: isOrdered, start: startNumber, items: items, grid: imageChoices), i)
}
private func item(_ body: [String], _ choices: Bool) -> MDItem {
private func item(_ lines: [String], _ choices: Bool) -> MDItem {
var body = lines
var out = MDItem(raw: body[0])
if choices, let m = choiceMarker.exec(body[0]) {
out.choice = m[2]
} else if let m = discussMarker.exec(body[0]) {
body[0] = m[1]!
out.discuss = true
out.quote = trimmed(body.joined(separator: "\n"))
}
let first = out.choice != nil ? [] : [body[0]]
let rest = Array(body.dropFirst())