Skip to content

Commit b6e69a1

Browse files
committed
using my fork with improved neomd features
1 parent 248876c commit b6e69a1

7 files changed

Lines changed: 104 additions & 74 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ Or in Gmail:
142142
- **Link opener** — links in emails are numbered `[1]`-`[0]` in the reader header; press `space+digit` to open in `$BROWSER`
143143
- **CC, BCC, Reply-all** — optional Cc/Bcc fields (toggle with `ctrl+b`); `R` in the reader replies to sender + all CC recipients
144144
- **Emoji reactions** — press `ctrl+e` from inbox or reader to react with emoji (👍 ❤️ 😂 🎉 🙏 💯 👀 ✅); instant send with proper threading and quoted message history, no editor needed; reactions appear in conversation threads with neomd branding
145+
- **GitHub/Obsidian-style callouts in emails** — compose emails with callout syntax `> [!note]`, `> [!tip]`, `> [!warning]` for styled alert boxes in HTML emails; rendered with colored left borders, subtle backgrounds, and emoji icons
145146
- **Drafts**`d` in pre-send saves to Drafts (IMAP APPEND); `E` in the reader re-opens a draft as an editable compose; compose sessions are auto-backed up to `~/.cache/neomd/drafts/` so you never lose an unsent email (`:recover` to reopen)
146147
- **HTML signatures** — configure separate text and HTML signatures; text signature appears in editor and plain text part, HTML signature in HTML part only; use `[html-signature]` placeholder to control inclusion per-email
147148
- **Multiple From addresses** — define SMTP-only `[[senders]]` aliases (e.g. `s@ssp.sh` through an existing account); cycle with `ctrl+f` in compose and pre-send; sent copies always land in the Sent folder

docs/content/docs/_index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ Or in Gmail:
149149
- **Link opener** — links in emails are numbered `[1]`-`[0]` in the reader header; press `space+digit` to open in `$BROWSER`
150150
- **CC, BCC, Reply-all** — optional Cc/Bcc fields (toggle with `ctrl+b`); `R` in the reader replies to sender + all CC recipients
151151
- **Emoji reactions** — press `ctrl+e` from inbox or reader to react with emoji (👍 ❤️ 😂 🎉 🙏 💯 👀 ✅); instant send with proper threading and quoted message history, no editor needed; reactions appear in conversation threads with neomd branding
152+
- **GitHub/Obsidian-style callouts in emails** — compose emails with callout syntax `> [!note]`, `> [!tip]`, `> [!warning]` for styled alert boxes in HTML emails; rendered with colored left borders, subtle backgrounds, and emoji icons
152153
- **Drafts**`d` in pre-send saves to Drafts (IMAP APPEND); `E` in the reader re-opens a draft as an editable compose; compose sessions are auto-backed up to `~/.cache/neomd/drafts/` so you never lose an unsent email (`:recover` to reopen)
153154
- **HTML signatures** — configure separate text and HTML signatures; text signature appears in editor and plain text part, HTML signature in HTML part only; use `[html-signature]` placeholder to control inclusion per-email
154155
- **Multiple From addresses** — define SMTP-only `[[senders]]` aliases (e.g. `s@ssp.sh` through an existing account); cycle with `ctrl+f` in compose and pre-send; sent copies always land in the Sent folder

docs/content/docs/sending.md

Lines changed: 63 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -14,73 +14,6 @@ When attachments are present the MIME structure is upgraded automatically:
1414
- **Images**`multipart/related` with `Content-ID` — displayed inline in the email body
1515
- **Other files** (PDF, zip, …) → `multipart/mixed` — shown as downloadable attachments
1616

17-
## Callouts (Admonition)
18-
19-
neomd supports GitHub/Obsidian-style [callouts](https://www.ssp.sh/brain/admonition-call-outs) through the [this extension (with my fork)](https://github.com/sspaeti/goldmark-obsidian-callout-for-neomd) for highlighted information boxes in your emails. Use the `> [!TYPE]` syntax to create styled alert boxes:
20-
21-
This is how it looks at the recievers end:
22-
![neomd](images/callouts.png)
23-
24-
```markdown
25-
> [!note]
26-
> This is a note callout with default styling
27-
28-
> [!tip] Pro Tip
29-
> Use custom titles by adding text after the type
30-
31-
> [!warning] Important
32-
> Callouts can have multiple paragraphs
33-
>
34-
> Just add blank blockquote lines between them
35-
36-
> [!important]
37-
> Recipients see colored boxes with icons in HTML email clients
38-
> while plain text clients show it as a blockquote
39-
```
40-
41-
**Available callout types:**
42-
- `[!note]` — Blue info box
43-
- `[!tip]` — Green success/tip box
44-
- `[!important]` — Purple important box
45-
- `[!warning]` — Yellow warning box
46-
- `[!caution]` — Red caution/danger box
47-
48-
**Features:**
49-
- Custom titles — add text after the type: `> [!warning] Security Alert`
50-
- Multiple paragraphs — use `> ` (blockquote with space) for blank lines
51-
- Works in both syntaxes: `> [!note]` (with space) or `>[!note]` (without space)
52-
53-
**What recipients see:**
54-
55-
HTML email clients (Gmail, Outlook, Apple Mail) display callouts as colored boxes with:
56-
- Colored left border (4px solid)
57-
- Colored background
58-
- Bold title with icon
59-
- Proper spacing and padding
60-
61-
>[!NOTE]
62-
> Plain text email clients show callouts as regular blockquotes (graceful degradation).
63-
64-
**Example in composed email:**
65-
66-
```markdown
67-
Hi team,
68-
69-
Here's the update on the project:
70-
71-
> [!tip] Good News
72-
> We're ahead of schedule! The new feature shipped yesterday.
73-
74-
> [!warning] Action Required
75-
> Please review the security audit by Friday.
76-
>
77-
> Contact @security if you have questions.
78-
79-
Thanks,
80-
Simon
81-
```
82-
83-
8417
## Multiple From Addresses
8518

8619
Add `[[senders]]` blocks to config to define extra identities that share an existing account's SMTP credentials:
@@ -252,3 +185,66 @@ This gives you full control: professional HTML signatures by default, plain sign
252185
For full HTML signature configuration examples, see [Configuration Reference](configuration#html-signatures).
253186

254187
For reading emails — images, links, attachments, and navigation — see [Reading Emails](reading).
188+
189+
## Callouts (Admonition)
190+
191+
neomd supports GitHub/Obsidian-style [callouts](https://www.ssp.sh/brain/admonition-call-outs) through the [this extension (with my fork)](https://github.com/sspaeti/goldmark-obsidian-callout-for-neomd) for highlighted information boxes in your emails. Use the `> [!TYPE]` syntax to create styled alert boxes:
192+
193+
This is how it looks at the recievers end:
194+
![neomd](/images/callouts.png)
195+
196+
```markdown
197+
> [!note]
198+
> This is a note callout with default styling
199+
200+
> [!tip] Pro Tip
201+
> Use custom titles by adding text after the type
202+
203+
> [!warning] Important
204+
> Callouts can have multiple paragraphs
205+
>
206+
> Just add blank blockquote lines between them
207+
208+
```
209+
210+
**Available callout types:**
211+
- `[!note]` — Blue info box
212+
- `[!tip]` — Green success/tip box
213+
- `[!warning]` — Yellow warning box
214+
215+
**Features:**
216+
- Custom titles — add text after the type: `> [!warning] Security Alert`
217+
- Multiple paragraphs — use `> ` (blockquote with space) for blank lines
218+
- Works in both syntaxes: `> [!note]` (with space) or `>[!note]` (without space)
219+
220+
**What recipients see:**
221+
222+
HTML email clients (Gmail, Outlook, Apple Mail) display callouts as colored boxes with:
223+
- Colored left border (4px solid)
224+
- Colored background
225+
- Bold title with icon
226+
- Proper spacing and padding
227+
228+
>[!NOTE]
229+
> Plain text email clients show callouts as regular blockquotes (graceful degradation).
230+
231+
**Example in composed email:**
232+
233+
```markdown
234+
Hi team,
235+
236+
Here's the update on the project:
237+
238+
> [!tip] Good News
239+
> We're ahead of schedule! The new feature shipped yesterday.
240+
241+
> [!warning] Action Required
242+
> Please review the security audit by Friday.
243+
>
244+
> Contact @security if you have questions.
245+
246+
Thanks,
247+
Simon
248+
```
249+
250+

go.mod

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ go 1.24.2
55
require (
66
github.com/BurntSushi/toml v1.6.0
77
github.com/JohannesKaufmann/html-to-markdown v1.6.0
8-
github.com/VojtaStruhar/goldmark-obsidian-callout v0.1.0
98
github.com/charmbracelet/bubbles v1.0.0
109
github.com/charmbracelet/bubbletea v1.3.10
1110
github.com/charmbracelet/glamour v0.9.1
1211
github.com/charmbracelet/lipgloss v1.1.0
1312
github.com/emersion/go-imap/v2 v2.0.0-beta.8
1413
github.com/emersion/go-message v0.18.2
1514
github.com/emersion/go-sasl v0.0.0-20241020182733-b788ff22d5a6
15+
github.com/sspaeti/goldmark-obsidian-callout-for-neomd v0.1.1
1616
github.com/yuin/goldmark v1.7.8
1717
golang.org/x/oauth2 v0.35.0
1818
)
@@ -52,5 +52,3 @@ require (
5252
golang.org/x/term v0.30.0 // indirect
5353
golang.org/x/text v0.23.0 // indirect
5454
)
55-
56-
replace github.com/VojtaStruhar/goldmark-obsidian-callout => /home/sspaeti/git/email/goldmark-obsidian-callout-for-neomd

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ github.com/sebdah/goldie/v2 v2.5.3/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvK
9898
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
9999
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
100100
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
101+
github.com/sspaeti/goldmark-obsidian-callout-for-neomd v0.1.1 h1:obWsWMJZGW4w9Qj1/WKLDweR+olq23r24UPS86XTbQU=
102+
github.com/sspaeti/goldmark-obsidian-callout-for-neomd v0.1.1/go.mod h1:p/gHio8liSHKd6Zcig2LFSU8Ym1yV9L+Dt1eYP9F6+I=
101103
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
102104
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
103105
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=

internal/integration_test.go

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -462,8 +462,17 @@ func TestIntegration_SignatureRenderedInHTML(t *testing.T) {
462462
defer cli.Close()
463463

464464
subject := uniqueSubject("signature")
465-
// Simulate a compose with signature (same format as editor.Prelude adds)
466-
body := "Hi there,\n\nThis is the email body.\n\n" +
465+
// Simulate a compose with signature and callouts (same format as editor.Prelude adds)
466+
body := "Hi team,\n\n" +
467+
"Here's the update on the project:\n\n" +
468+
"> [!tip] Good News\n" +
469+
"> We're ahead of schedule! The new feature shipped yesterday.\n\n" +
470+
"> [!warning] Action Required\n" +
471+
"> Please review the security audit by Friday.\n\n" +
472+
"> [!note] note\n" +
473+
"> Please read\n\n" +
474+
"Thanks,\n" +
475+
"Simon\n\n" +
467476
"-- \n" +
468477
"**Simon Späti**\n" +
469478
"Data Engineer, [SSP Data](https://ssp.sh/)\n"
@@ -495,9 +504,32 @@ func TestIntegration_SignatureRenderedInHTML(t *testing.T) {
495504
}
496505

497506
// Body content before signature should also be rendered
498-
if !strings.Contains(rawHTML, "email body") {
507+
if !strings.Contains(rawHTML, "update on the project") {
499508
t.Errorf("HTML missing email body text, got: %s", truncate(rawHTML, 500))
500509
}
510+
511+
// Callout rendering verification
512+
if !strings.Contains(rawHTML, "callout callout-tip") {
513+
t.Errorf("HTML missing tip callout class, got: %s", truncate(rawHTML, 800))
514+
}
515+
if !strings.Contains(rawHTML, "callout callout-warning") {
516+
t.Errorf("HTML missing warning callout class, got: %s", truncate(rawHTML, 800))
517+
}
518+
if !strings.Contains(rawHTML, "callout callout-note") {
519+
t.Errorf("HTML missing note callout class, got: %s", truncate(rawHTML, 800))
520+
}
521+
if !strings.Contains(rawHTML, "💡") { // Light bulb emoji for tip
522+
t.Errorf("HTML missing tip callout icon, got: %s", truncate(rawHTML, 800))
523+
}
524+
if !strings.Contains(rawHTML, "⚠️") { // Warning sign emoji
525+
t.Errorf("HTML missing warning callout icon, got: %s", truncate(rawHTML, 800))
526+
}
527+
if !strings.Contains(rawHTML, "Good News") {
528+
t.Errorf("HTML missing custom callout title, got: %s", truncate(rawHTML, 800))
529+
}
530+
if !strings.Contains(rawHTML, "ahead of schedule") {
531+
t.Errorf("HTML missing callout content, got: %s", truncate(rawHTML, 800))
532+
}
501533
}
502534

503535
func TestIntegration_SaveSent(t *testing.T) {

internal/render/html.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import (
44
"bytes"
55
"fmt"
66

7-
callout "github.com/VojtaStruhar/goldmark-obsidian-callout"
7+
callout "github.com/sspaeti/goldmark-obsidian-callout-for-neomd"
88
"github.com/yuin/goldmark"
99
"github.com/yuin/goldmark/extension"
1010
"github.com/yuin/goldmark/renderer/html"

0 commit comments

Comments
 (0)