Skip to content

Add callouts, %%comments%%, and front-matter hiding#95

Open
ChristineTham wants to merge 2 commits into
nodes-app:mainfrom
ChristineTham:pr/callouts-comments-frontmatter
Open

Add callouts, %%comments%%, and front-matter hiding#95
ChristineTham wants to merge 2 commits into
nodes-app:mainfrom
ChristineTham:pr/callouts-comments-frontmatter

Conversation

@ChristineTham

Copy link
Copy Markdown

Three editor-styling passes (the styling context now also carries the caret location):

  • Callouts — a > [!type] blockquote renders as a tinted band + accent bar (new .calloutTint fragment attribute) with a bold accent title, a type SF Symbol in the gutter, and hidden [! ] punctuation. [!type]- / [!type]+ callouts are collapsible: - renders collapsed (chevron.right, body hidden), + expanded (chevron.down); clicking the header's gutter chevron toggles the marker in the source (mirrors the task-checkbox click handling). A common Obsidian type→colour/icon map is included.
  • Comments%%…%% (inline or multi-line) are dimmed; code/LaTeX spans are skipped.
  • Front matter — a leading ------ block collapses to nothing (its fence thematic-break rules suppressed), revealing the raw YAML only when the caret is inside it. Pairs well with a host-side properties panel.

All additive; no behaviour change for documents without these constructs.

Context: extracted from the ChristineTham/swift-markdown-engine fork used by HelloNotes. Rebased onto current main.

ChristineTham and others added 2 commits July 11, 2026 19:05
Three editor-styling passes (all keyed off the styling context, which now
carries the caret location):

- Callouts: a `> [!type]` blockquote gets a tinted band + accent bar (new
  `.calloutTint` attribute drawn by MarkdownTextLayoutFragment), a bold
  accent-colored title, and hidden `[!` `]` punctuation. Type→color mapping
  covers the common Obsidian set.
- Comments: `%%…%%` (inline or multi-line) are dimmed; code/LaTeX spans are
  skipped.
- Front matter: a leading `---`…`---` block collapses to nothing (its fence
  thematic-break rules suppressed), revealing the raw YAML only when the caret
  is inside it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Each callout header now paints an SF Symbol in the gutter (type-specific, in
the accent color). Callouts written `[!type]-` / `[!type]+` are collapsible:
`-` renders collapsed (body hidden, chevron.right), `+` expanded
(chevron.down); clicking the header's gutter chevron toggles the marker in the
source (mirrors the task-checkbox click handling) and restyles. The caret
inside a collapsed callout reveals its body for editing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 11, 2026 09:07

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Obsidian-style editor affordances (callouts, %%…%% comments, and YAML front matter hiding) to the MarkdownEngine styling pipeline, plus renderer and editor interactions needed to support collapsible callouts.

Changes:

  • Introduces three new styling passes: callouts (with folding), %%…%% comments dimming, and caret-sensitive front matter hiding.
  • Adds callout background/icon rendering support to MarkdownTextLayoutFragment via new attributed-string keys.
  • Adds NativeTextView hit-testing to toggle collapsible callout markers ([!type]-[!type]+) on gutter clicks.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
Sources/MarkdownEngine/TextView/NativeTextView/NativeTextView+DragSelectBoost.swift Adds callout-fold hit-test before drag-select logic proceeds.
Sources/MarkdownEngine/TextView/NativeTextView/NativeTextView+CalloutFold.swift Implements gutter hit-testing and source marker toggling for collapsible callouts.
Sources/MarkdownEngine/Styling/MarkdownStyler+FrontMatter.swift Adds caret-sensitive hiding of leading YAML front matter and suppresses thematic-break rendering for its fences.
Sources/MarkdownEngine/Styling/MarkdownStyler+Comments.swift Adds dimming for %%…%% comments while skipping code/LaTeX spans.
Sources/MarkdownEngine/Styling/MarkdownStyler+Callouts.swift Detects/styles callouts, sets attributes for tint/icon, and collapses body when folded.
Sources/MarkdownEngine/Styling/MarkdownStyler.swift Extends StylingContext with caret location and wires the three new styling passes into the pipeline.
Sources/MarkdownEngine/Renderer/MarkdownTextLayoutFragment.swift Adds .calloutTint/.calloutIcon/.calloutFold keys and renders callout backgrounds + gutter icons.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +25 to +27
storage.enumerateAttribute(.calloutFold, in: fullRange, options: []) { value, attrRange, stop in
guard value is Bool else { return }
let rect = bridge.boundingRect(forCharacterRange: attrRange, in: textContainer)
Comment on lines +38 to +50
// Re-parse the header line to locate the `]±` marker and toggle it.
let nsText = storage.string as NSString
let lineRange = nsText.lineRange(for: NSRange(location: headerRange.location, length: 0))
let line = nsText.substring(with: lineRange)
guard let bracket = line.range(of: #"\]([+-]?)"#, options: .regularExpression) else { return false }
let markerStart = lineRange.location + line.distance(from: line.startIndex, to: bracket.lowerBound) + 1
let existing = nsText.substring(with: NSRange(location: markerStart, length: min(1, NSMaxRange(lineRange) - markerStart)))
let (oldMarkerRange, replacement): (NSRange, String)
switch existing {
case "-": (oldMarkerRange, replacement) = (NSRange(location: markerStart, length: 1), "+") // expand
case "+": (oldMarkerRange, replacement) = (NSRange(location: markerStart, length: 1), "-") // collapse
default: return false // not a foldable header
}
Comment on lines +55 to +58
if let coord = delegate as? NativeTextViewCoordinator {
let fullRange = NSRange(location: 0, length: storage.length)
coord.restyleParagraphs([fullRange], in: self)
}
Comment on lines 90 to 96
// NSImage rendering reuses the existing, proven machinery.
result += styleBlockLatex(ctx)
result += styleInlineLatex(ctx)
result += styleFrontMatter(ctx)
result += styleComments(ctx)
result += styleCallouts(ctx)
result += styleImageEmbeds(ctx)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants