mirror of
https://github.com/sbrow/thor.git
synced 2026-08-26 11:23:32 -04:00
feat(alerts): Fixed alert class names + css.
This commit is contained in:
@@ -56,7 +56,8 @@
|
|||||||
- [ ] Review main.odin
|
- [ ] Review main.odin
|
||||||
- [ ] Review minify.odin
|
- [ ] Review minify.odin
|
||||||
- [ ] Review `markdown/`
|
- [ ] Review `markdown/`
|
||||||
- [ ] Review alerts.odin
|
- [x] Review alerts.odin
|
||||||
|
- [x] Review alerts_test.odin
|
||||||
- [x] Review emoji.odin
|
- [x] Review emoji.odin
|
||||||
- [x] Review emoji_test.odin
|
- [x] Review emoji_test.odin
|
||||||
- [ ] Review footnotes.odin
|
- [ ] Review footnotes.odin
|
||||||
@@ -69,3 +70,5 @@
|
|||||||
- [x] Review site.odin
|
- [x] Review site.odin
|
||||||
- [ ] Review treesitter/treesitter.odin
|
- [ ] Review treesitter/treesitter.odin
|
||||||
- [ ] Review vfs.odin
|
- [ ] Review vfs.odin
|
||||||
|
- [ ] Review procs
|
||||||
|
- [ ] markdown.transform_alert
|
||||||
|
|||||||
+19
-29
@@ -4,20 +4,12 @@ package markdown
|
|||||||
import "core:fmt"
|
import "core:fmt"
|
||||||
import "core:strings"
|
import "core:strings"
|
||||||
|
|
||||||
ALERT_STYLES: map[string]string = {
|
|
||||||
"note" = "border-l-blue-500 bg-blue-950/30 text-slate-300",
|
|
||||||
"tip" = "border-l-green-500 bg-green-950/30 text-slate-300",
|
|
||||||
"important" = "border-l-purple-500 bg-purple-950/30 text-slate-300",
|
|
||||||
"warning" = "border-l-yellow-500 bg-yellow-950/30 text-slate-300",
|
|
||||||
"caution" = "border-l-red-500 bg-red-950/30 text-slate-300",
|
|
||||||
}
|
|
||||||
|
|
||||||
ALERT_EMOJIS: map[string]string = {
|
ALERT_EMOJIS: map[string]string = {
|
||||||
"note" = "\xe2\x84\xb9\xef\xb8\x8f",
|
"note" = "ℹ️",
|
||||||
"tip" = "\xf0\x9f\x92\xa1",
|
"tip" = "💡",
|
||||||
"important" = "\xe2\x9d\x97",
|
"important" = "❗",
|
||||||
"warning" = "\xe2\x9a\xa0\xef\xb8\x8f",
|
"warning" = "⚠️",
|
||||||
"caution" = "\xe2\x9d\x97",
|
"caution" = "❗",
|
||||||
}
|
}
|
||||||
|
|
||||||
inject_alerts :: proc(html: string) -> string {
|
inject_alerts :: proc(html: string) -> string {
|
||||||
@@ -52,19 +44,21 @@ inject_alerts :: proc(html: string) -> string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
transform_alert :: proc(bq: string) -> string {
|
transform_alert :: proc(bq: string) -> string {
|
||||||
// Skip <blockquote> tag and whitespace
|
|
||||||
pos := len("<blockquote>")
|
pos := len("<blockquote>")
|
||||||
for pos < len(bq) && (bq[pos] == '\n' || bq[pos] == '\r' || bq[pos] == ' ' || bq[pos] == '\t') {
|
for pos < len(bq) &&
|
||||||
|
(bq[pos] == '\n' || bq[pos] == '\r' || bq[pos] == ' ' || bq[pos] == '\t') {
|
||||||
pos += 1
|
pos += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for <p>[!
|
if pos + 4 >= len(bq) ||
|
||||||
if pos + 4 >= len(bq) || bq[pos] != '<' || bq[pos + 1] != 'p' || bq[pos + 2] != '>' ||
|
bq[pos] != '<' ||
|
||||||
bq[pos + 3] != '[' || bq[pos + 4] != '!' {
|
bq[pos + 1] != 'p' ||
|
||||||
|
bq[pos + 2] != '>' ||
|
||||||
|
bq[pos + 3] != '[' ||
|
||||||
|
bq[pos + 4] != '!' {
|
||||||
return bq
|
return bq
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract alert type until ]
|
|
||||||
close := strings.index(bq[pos + 5:], "]")
|
close := strings.index(bq[pos + 5:], "]")
|
||||||
if close < 0 {
|
if close < 0 {
|
||||||
return bq
|
return bq
|
||||||
@@ -73,33 +67,29 @@ transform_alert :: proc(bq: string) -> string {
|
|||||||
type_raw := bq[pos + 5:pos + 5 + close]
|
type_raw := bq[pos + 5:pos + 5 + close]
|
||||||
type_lower := strings.to_lower(type_raw)
|
type_lower := strings.to_lower(type_raw)
|
||||||
|
|
||||||
style, has_style := ALERT_STYLES[type_lower]
|
emoji, found := ALERT_EMOJIS[type_lower]
|
||||||
emoji, has_emoji := ALERT_EMOJIS[type_lower]
|
if !found {
|
||||||
if !has_style || !has_emoji {
|
|
||||||
return bq
|
return bq
|
||||||
}
|
}
|
||||||
|
|
||||||
// Position after ]
|
|
||||||
after_type := pos + 5 + close + 1
|
after_type := pos + 5 + close + 1
|
||||||
|
|
||||||
// Skip optional + or -
|
|
||||||
content_start := after_type
|
content_start := after_type
|
||||||
if content_start < len(bq) && (bq[content_start] == '+' || bq[content_start] == '-') {
|
if content_start < len(bq) && (bq[content_start] == '+' || bq[content_start] == '-') {
|
||||||
content_start += 1
|
content_start += 1
|
||||||
}
|
}
|
||||||
// Skip space after marker
|
|
||||||
if content_start < len(bq) && bq[content_start] == ' ' {
|
if content_start < len(bq) && bq[content_start] == ' ' {
|
||||||
content_start += 1
|
content_start += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rebuild: styled blockquote + bold title paragraph + rest
|
|
||||||
rest := bq[content_start:]
|
rest := bq[content_start:]
|
||||||
|
|
||||||
return fmt.aprintf(
|
return fmt.aprintf(
|
||||||
`<blockquote class="alert %s rounded-r py-2">
|
`<blockquote class="alert alert-%s">
|
||||||
<p class="font-bold mb-1">%s %s`,
|
<p class="alert-title">%s %s`,
|
||||||
style,
|
type_lower,
|
||||||
emoji,
|
emoji,
|
||||||
rest,
|
rest,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,104 @@
|
|||||||
|
#+feature dynamic-literals
|
||||||
|
#+test
|
||||||
|
package markdown
|
||||||
|
|
||||||
|
import "core:testing"
|
||||||
|
|
||||||
|
@(test)
|
||||||
|
test_alerts_render_properly :: proc(t: ^testing.T) {
|
||||||
|
testing.expect_value(
|
||||||
|
t,
|
||||||
|
inject_alerts("<blockquote>\n<p>[!NOTE] Hello.</p>\n</blockquote>"),
|
||||||
|
`<blockquote class="alert alert-note">
|
||||||
|
<p class="alert-title">ℹ️ Hello.</p>
|
||||||
|
</blockquote>`,
|
||||||
|
)
|
||||||
|
|
||||||
|
testing.expect_value(
|
||||||
|
t,
|
||||||
|
inject_alerts("<blockquote>\n<p>[!TIP] Be smart.</p>\n</blockquote>"),
|
||||||
|
`<blockquote class="alert alert-tip">
|
||||||
|
<p class="alert-title">💡 Be smart.</p>
|
||||||
|
</blockquote>`,
|
||||||
|
)
|
||||||
|
|
||||||
|
testing.expect_value(
|
||||||
|
t,
|
||||||
|
inject_alerts("<blockquote>\n<p>[!CAUTION] Danger!</p>\n</blockquote>"),
|
||||||
|
`<blockquote class="alert alert-caution">
|
||||||
|
<p class="alert-title">❗ Danger!</p>
|
||||||
|
</blockquote>`,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@(test)
|
||||||
|
test_non_alerts_pass_through_inject_alerts :: proc(t: ^testing.T) {
|
||||||
|
testing.expect_value(
|
||||||
|
t,
|
||||||
|
inject_alerts("<blockquote>\n<p>Just a quote.</p>\n</blockquote>"),
|
||||||
|
"<blockquote>\n<p>Just a quote.</p>\n</blockquote>",
|
||||||
|
)
|
||||||
|
|
||||||
|
testing.expect_value(
|
||||||
|
t,
|
||||||
|
inject_alerts("<blockquote>\n<p>[!UNKNOWN] Nope.</p>\n</blockquote>"),
|
||||||
|
"<blockquote>\n<p>[!UNKNOWN] Nope.</p>\n</blockquote>",
|
||||||
|
)
|
||||||
|
|
||||||
|
testing.expect_value(
|
||||||
|
t,
|
||||||
|
inject_alerts("<p>No blockquote here.</p>"),
|
||||||
|
"<p>No blockquote here.</p>",
|
||||||
|
)
|
||||||
|
|
||||||
|
testing.expect_value(t, inject_alerts(""), "")
|
||||||
|
}
|
||||||
|
|
||||||
|
@(test)
|
||||||
|
test_case_insensitive_alerts_render :: proc(t: ^testing.T) {
|
||||||
|
testing.expect_value(
|
||||||
|
t,
|
||||||
|
inject_alerts("<blockquote>\n<p>[!Note] Mixed case.</p>\n</blockquote>"),
|
||||||
|
`<blockquote class="alert alert-note">
|
||||||
|
<p class="alert-title">ℹ️ Mixed case.</p>
|
||||||
|
</blockquote>`,
|
||||||
|
)
|
||||||
|
|
||||||
|
testing.expect_value(
|
||||||
|
t,
|
||||||
|
inject_alerts("<blockquote>\n<p>[!NOTE] Upper case.</p>\n</blockquote>"),
|
||||||
|
`<blockquote class="alert alert-note">
|
||||||
|
<p class="alert-title">ℹ️ Upper case.</p>
|
||||||
|
</blockquote>`,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@(test)
|
||||||
|
test_multiple_alerts_render_together :: proc(t: ^testing.T) {
|
||||||
|
testing.expect_value(
|
||||||
|
t,
|
||||||
|
inject_alerts(
|
||||||
|
"<blockquote>\n<p>[!NOTE] First.</p>\n</blockquote>\n<blockquote>\n<p>[!TIP] Second.</p>\n</blockquote>",
|
||||||
|
),
|
||||||
|
`<blockquote class="alert alert-note">
|
||||||
|
<p class="alert-title">ℹ️ First.</p>
|
||||||
|
</blockquote>
|
||||||
|
<blockquote class="alert alert-tip">
|
||||||
|
<p class="alert-title">💡 Second.</p>
|
||||||
|
</blockquote>`,
|
||||||
|
)
|
||||||
|
|
||||||
|
testing.expect_value(
|
||||||
|
t,
|
||||||
|
inject_alerts(
|
||||||
|
"<blockquote>\n<p>Regular.</p>\n</blockquote>\n<blockquote>\n<p>[!WARNING] Alert!</p>\n</blockquote>",
|
||||||
|
),
|
||||||
|
`<blockquote>
|
||||||
|
<p>Regular.</p>
|
||||||
|
</blockquote>
|
||||||
|
<blockquote class="alert alert-warning">
|
||||||
|
<p class="alert-title">⚠️ Alert!</p>
|
||||||
|
</blockquote>`,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user