mirror of
https://github.com/sbrow/thor.git
synced 2026-08-26 11:23:32 -04:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0dc6cc117f |
@@ -3,14 +3,15 @@
|
|||||||
- Look at the source for 3 template languages that support mustache syntax,
|
- Look at the source for 3 template languages that support mustache syntax,
|
||||||
and see how they implement the tempaltes, then pick the best one. One of them
|
and see how they implement the tempaltes, then pick the best one. One of them
|
||||||
should be Hugo / go.
|
should be Hugo / go.
|
||||||
|
- [ ] robots.txt?
|
||||||
- [ ] Evaluate Tufte CSS — borrow sidenote CSS or replace TailwindCSS entirely
|
- [ ] Evaluate Tufte CSS — borrow sidenote CSS or replace TailwindCSS entirely
|
||||||
- Option B: Steal Tufte's sidenote/margin-note CSS (adapt for dark theme), keep TailwindCSS
|
- Option B: Steal Tufte's sidenote/margin-note CSS (adapt for dark theme), keep TailwindCSS
|
||||||
- Option C: Full Tufte CSS — drop TailwindCSS, no build step, semantic HTML, customize for dark theme + Roboto
|
- Option C: Full Tufte CSS — drop TailwindCSS, no build step, semantic HTML, customize for dark theme + Roboto
|
||||||
- Our sidenote HTML pattern already matches Tufte's exactly
|
- Our sidenote HTML pattern already matches Tufte's exactly
|
||||||
|
- [ ] GitHub alerts (`> [!CAUTION]` → styled blockquote) — 2 posts
|
||||||
- [ ] Block attributes on code fences (`{ #ex-1 }`) — hello-world.md
|
- [ ] Block attributes on code fences (`{ #ex-1 }`) — hello-world.md
|
||||||
- [x] Emoji shortcodes (`:shrug:` etc.) — 2 instances
|
- [ ] Emoji shortcodes (`:shrug:` etc.) — 2 instances
|
||||||
- [ ] Backslash in shrug not visible.
|
|
||||||
- [ ] include-code shortcode (`{{< include-code ... >}}`) — i-ported-fd-to-odin
|
- [ ] include-code shortcode (`{{< include-code ... >}}`) — i-ported-fd-to-odin
|
||||||
- [x] Nix build integration — main flake runs thor + tailwindcss instead of Hugo
|
- [ ] Nix build integration — main flake runs thor + tailwindcss instead of Hugo
|
||||||
- [ ] Copy-to-clipboard button on code blocks (was in Hugo's custom-head.html)
|
- [ ] Copy-to-clipboard button on code blocks (was in Hugo's custom-head.html)
|
||||||
- [ ] OpenGraph meta tags
|
- [ ] OpenGraph meta tags
|
||||||
|
|||||||
-108
@@ -1,108 +0,0 @@
|
|||||||
#+feature dynamic-literals
|
|
||||||
package main
|
|
||||||
|
|
||||||
import "core:fmt"
|
|
||||||
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 = {
|
|
||||||
"note" = "\xe2\x84\xb9\xef\xb8\x8f",
|
|
||||||
"tip" = "\xf0\x9f\x92\xa1",
|
|
||||||
"important" = "\xe2\x9d\x97",
|
|
||||||
"warning" = "\xe2\x9a\xa0\xef\xb8\x8f",
|
|
||||||
"caution" = "\xe2\x9d\x97",
|
|
||||||
}
|
|
||||||
|
|
||||||
inject_alerts :: proc(html: string) -> string {
|
|
||||||
parts: [dynamic]string
|
|
||||||
defer delete(parts)
|
|
||||||
|
|
||||||
remaining := html
|
|
||||||
|
|
||||||
for {
|
|
||||||
bq_start := strings.index(remaining, "<blockquote>")
|
|
||||||
if bq_start < 0 {
|
|
||||||
append(&parts, remaining)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
bq_close := strings.index(remaining, "</blockquote>")
|
|
||||||
if bq_close < 0 {
|
|
||||||
append(&parts, remaining)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
bq_end := bq_close + len("</blockquote>")
|
|
||||||
bq := remaining[bq_start:bq_end]
|
|
||||||
|
|
||||||
// Append text before this blockquote
|
|
||||||
append(&parts, remaining[:bq_start])
|
|
||||||
|
|
||||||
// Transform if it's an alert, otherwise keep as-is
|
|
||||||
append(&parts, transform_alert(bq))
|
|
||||||
|
|
||||||
remaining = remaining[bq_end:]
|
|
||||||
}
|
|
||||||
|
|
||||||
return strings.join(parts[:], "")
|
|
||||||
}
|
|
||||||
|
|
||||||
transform_alert :: proc(bq: string) -> string {
|
|
||||||
// Skip <blockquote> tag and whitespace
|
|
||||||
pos := len("<blockquote>")
|
|
||||||
for pos < len(bq) && (bq[pos] == '\n' || bq[pos] == '\r' || bq[pos] == ' ' || bq[pos] == '\t') {
|
|
||||||
pos += 1
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for <p>[!
|
|
||||||
if pos + 4 >= len(bq) || bq[pos] != '<' || bq[pos + 1] != 'p' || bq[pos + 2] != '>' ||
|
|
||||||
bq[pos + 3] != '[' || bq[pos + 4] != '!' {
|
|
||||||
return bq
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract alert type until ]
|
|
||||||
close := strings.index(bq[pos + 5:], "]")
|
|
||||||
if close < 0 {
|
|
||||||
return bq
|
|
||||||
}
|
|
||||||
|
|
||||||
type_raw := bq[pos + 5 : pos + 5 + close]
|
|
||||||
type_lower := strings.to_lower(type_raw)
|
|
||||||
|
|
||||||
style, has_style := ALERT_STYLES[type_lower]
|
|
||||||
emoji, has_emoji := ALERT_EMOJIS[type_lower]
|
|
||||||
if !has_style || !has_emoji {
|
|
||||||
return bq
|
|
||||||
}
|
|
||||||
|
|
||||||
// Position after ]
|
|
||||||
after_type := pos + 5 + close + 1
|
|
||||||
|
|
||||||
// Skip optional + or -
|
|
||||||
content_start := after_type
|
|
||||||
if content_start < len(bq) && (bq[content_start] == '+' || bq[content_start] == '-') {
|
|
||||||
content_start += 1
|
|
||||||
}
|
|
||||||
// Skip space after marker
|
|
||||||
if content_start < len(bq) && bq[content_start] == ' ' {
|
|
||||||
content_start += 1
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rebuild: styled blockquote + bold title paragraph + rest
|
|
||||||
rest := bq[content_start:]
|
|
||||||
|
|
||||||
return fmt.aprintf(
|
|
||||||
`<blockquote class="alert %s rounded-r py-2">
|
|
||||||
<p class="font-bold mb-1">%s %s`,
|
|
||||||
style,
|
|
||||||
emoji,
|
|
||||||
rest,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
+2
-3
@@ -173,10 +173,9 @@ load_page :: proc(
|
|||||||
if strings.has_suffix(file_path, ".html") {
|
if strings.has_suffix(file_path, ".html") {
|
||||||
page.body_html = strings.clone(body)
|
page.body_html = strings.clone(body)
|
||||||
} else {
|
} else {
|
||||||
expanded := expand_emoji(body)
|
clean_body, defs := strip_definitions(body)
|
||||||
clean_body, defs := strip_definitions(expanded)
|
|
||||||
html := cm.markdown_to_html_from_string(clean_body, {.Unsafe})
|
html := cm.markdown_to_html_from_string(clean_body, {.Unsafe})
|
||||||
page.body_html = inject_alerts(inject_sidenotes(html, defs))
|
page.body_html = inject_sidenotes(html, defs)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch page_type {
|
switch page_type {
|
||||||
|
|||||||
-438
@@ -1,438 +0,0 @@
|
|||||||
#+feature dynamic-literals
|
|
||||||
package main
|
|
||||||
|
|
||||||
import "core:strings"
|
|
||||||
|
|
||||||
EMOJIS: map[string]string = {
|
|
||||||
// People
|
|
||||||
"smile" = "\xf0\x9f\x98\x84",
|
|
||||||
"laughing" = "\xf0\x9f\x98\x86",
|
|
||||||
"blush" = "\xf0\x9f\x98\x8a",
|
|
||||||
"smiley" = "\xf0\x9f\x98\x83",
|
|
||||||
"wink" = "\xf0\x9f\x98\x89",
|
|
||||||
"joy" = "\xf0\x9f\xa4\xa3",
|
|
||||||
"rofl" = "\xf0\x9f\xa4\xa3",
|
|
||||||
"relaxed" = "\xe2\x98\xba\xef\xb8\x8f",
|
|
||||||
"thinking" = "\xf0\x9f\xa4\x94",
|
|
||||||
"neutral_face" = "\xf0\x9f\x98\x90",
|
|
||||||
"expressionless" = "\xf0\x9f\x98\x91",
|
|
||||||
"no_mouth" = "\xf0\x9f\x98\xb6",
|
|
||||||
"rolling_eyes" = "\xf0\x9f\x99\x84",
|
|
||||||
"smirk" = "\xf0\x9f\x98\x8f",
|
|
||||||
"persevere" = "\xf0\x9f\x98\xa3",
|
|
||||||
"disappointed_relieved" = "\xf0\x9f\x98\xa5",
|
|
||||||
"open_mouth" = "\xf0\x9f\x98\xae",
|
|
||||||
"zipper_mouth_face" = "\xf0\x9f\xa4\x90",
|
|
||||||
"hushed" = "\xf0\x9f\x98\xaf",
|
|
||||||
"sleepy" = "\xf0\x9f\x98\xaa",
|
|
||||||
"tired_face" = "\xf0\x9f\x98\xab",
|
|
||||||
"sleeping" = "\xf0\x9f\x98\xb4",
|
|
||||||
"relieved" = "\xf0\x9f\x98\x8c",
|
|
||||||
"stuck_out_tongue" = "\xf0\x9f\x98\x9b",
|
|
||||||
"stuck_out_tongue_winking_eye" = "\xf0\x9f\x98\x9c",
|
|
||||||
"stuck_out_tongue_closed_eyes" = "\xf0\x9f\x98\x9d",
|
|
||||||
"drooling_face" = "\xf0\x9f\xa4\xa4",
|
|
||||||
"unamused" = "\xf0\x9f\x98\x92",
|
|
||||||
"sweat" = "\xf0\x9f\x98\x85",
|
|
||||||
"pensive" = "\xf0\x9f\x98\x94",
|
|
||||||
"confused" = "\xf0\x9f\x98\x95",
|
|
||||||
"upside_down_face" = "\xf0\x9f\x99\x83",
|
|
||||||
"money_mouth_face" = "\xf0\x9f\xa4\x91",
|
|
||||||
"astonished" = "\xf0\x9f\x98\xb2",
|
|
||||||
"white_frowning_face" = "\xe2\x98\xb9\xef\xb8\x8f",
|
|
||||||
"slightly_sad_face" = "\xe2\x98\xb9\xef\xb8\x8f",
|
|
||||||
"confounded" = "\xf0\x9f\x98\x96",
|
|
||||||
"disappointed" = "\xf0\x9f\x98\x9e",
|
|
||||||
"worried" = "\xf0\x9f\x98\x9f",
|
|
||||||
"triumph" = "\xf0\x9f\x98\xa4",
|
|
||||||
"cry" = "\xf0\x9f\x98\xa2",
|
|
||||||
"sob" = "\xf0\x9f\x98\xad",
|
|
||||||
"frowning" = "\xf0\x9f\x98\xa6",
|
|
||||||
"frowning_face" = "\xf0\x9f\x99\x81",
|
|
||||||
"anguished" = "\xf0\x9f\x98\xa7",
|
|
||||||
"fearful" = "\xf0\x9f\x98\xa8",
|
|
||||||
"weary" = "\xf0\x9f\x98\xa9",
|
|
||||||
"grimacing" = "\xf0\x9f\x98\xac",
|
|
||||||
"cold_sweat" = "\xf0\x9f\x98\xb0",
|
|
||||||
"scream" = "\xf0\x9f\x98\xb1",
|
|
||||||
"flushed" = "\xf0\x9f\x98\xb3",
|
|
||||||
"dizzy_face" = "\xf0\x9f\x98\xb5",
|
|
||||||
"rage" = "\xf0\x9f\x98\xa1",
|
|
||||||
"angry" = "\xf0\x9f\x98\xa0",
|
|
||||||
"innocent" = "\xf0\x9f\x98\x87",
|
|
||||||
"cowboy_hat_face" = "\xf0\x9f\xa4\xa0",
|
|
||||||
"clown_face" = "\xf0\x9f\xa4\xa1",
|
|
||||||
"mask" = "\xf0\x9f\x98\xb7",
|
|
||||||
"thermometer_face" = "\xf0\x9f\xa4\x92",
|
|
||||||
"head_bandage" = "\xf0\x9f\xa4\x95",
|
|
||||||
"nauseated_face" = "\xf0\x9f\xa4\xa2",
|
|
||||||
"sneezing_face" = "\xf0\x9f\xa4\xa7",
|
|
||||||
"smiling_imp" = "\xf0\x9f\x98\x88",
|
|
||||||
"imp" = "\xf0\x9f\x91\xbf",
|
|
||||||
"shrug" = "\xc2\xaf\\_(\xe3\x83\x84)_/\xc2\xaf",
|
|
||||||
"facepalm" = "\xf0\x9f\xa4\xa6",
|
|
||||||
"facepunch" = "\xf0\x9f\x91\x8a",
|
|
||||||
"wave" = "\xf0\x9f\x91\x8b",
|
|
||||||
"ok_hand" = "\xf0\x9f\x91\x8c",
|
|
||||||
"thumbsup" = "\xf0\x9f\x91\x8d",
|
|
||||||
"thumbsdown" = "\xf0\x9f\x91\x8e",
|
|
||||||
"clap" = "\xf0\x9f\x91\x8f",
|
|
||||||
"pray" = "\xf0\x9f\x99\x8f",
|
|
||||||
"point_up" = "\xe2\x98\x9d\xef\xb8\x8f",
|
|
||||||
"point_down" = "\xf0\x9f\x91\x87",
|
|
||||||
"point_left" = "\xf0\x9f\x91\x88",
|
|
||||||
"point_right" = "\xf0\x9f\x89\x89",
|
|
||||||
"v" = "\xe2\x9c\x8c\xef\xb8\x8f",
|
|
||||||
"raised_hands" = "\xf0\x9f\x99\x8c",
|
|
||||||
"muscle" = "\xf0\x9f\x92\xaa",
|
|
||||||
"fist" = "\xe2\x9c\x8a",
|
|
||||||
"hand" = "\xe2\x9c\x8b",
|
|
||||||
|
|
||||||
// Hearts & symbols
|
|
||||||
"heart" = "\xe2\x9d\xa4\xef\xb8\x8f",
|
|
||||||
"orange_heart" = "\xf0\x9f\xa7\xa1",
|
|
||||||
"yellow_heart" = "\xf0\x9f\x92\x9b",
|
|
||||||
"green_heart" = "\xf0\x9f\x92\x9a",
|
|
||||||
"blue_heart" = "\xf0\x9f\x92\x99",
|
|
||||||
"purple_heart" = "\xf0\x9f\x92\x9c",
|
|
||||||
"broken_heart" = "\xf0\x9f\x92\x94",
|
|
||||||
"sparkling_heart" = "\xf0\x9f\x92\x96",
|
|
||||||
"100" = "\xf0\x9f\x92\xaf",
|
|
||||||
"anger" = "\xf0\x9f\x92\xa2",
|
|
||||||
"checkered_flag" = "\xf0\x9f\x8f\x81",
|
|
||||||
"crossed_flags" = "\xf0\x9f\x9a\xa9",
|
|
||||||
"rocket" = "\xf0\x9f\x9a\x80",
|
|
||||||
"star" = "\xe2\xad\x90",
|
|
||||||
"star2" = "\xf0\x9f\x8c\x9f",
|
|
||||||
"sparkles" = "\xe2\x9c\xa8",
|
|
||||||
"boom" = "\xf0\x9f\x92\xa5",
|
|
||||||
"exclamation" = "\xe2\x9d\x97",
|
|
||||||
"question" = "\xe2\x9d\x93",
|
|
||||||
"grey_exclamation" = "\xe2\x9d\x95",
|
|
||||||
"grey_question" = "\xe2\x9d\x94",
|
|
||||||
"zzz" = "\xf0\x9f\x92\xa4",
|
|
||||||
"warning" = "\xe2\x9a\xa0\xef\xb8\x8f",
|
|
||||||
"no_entry_sign" = "\xf0\x9f\x9a\xab",
|
|
||||||
"no_entry" = "\xe2\x9b\x94",
|
|
||||||
"white_check_mark" = "\xe2\x9c\x85",
|
|
||||||
"negative_squared_cross_mark" = "\xe2\x9d\x8e",
|
|
||||||
"x" = "\xe2\x9d\x8c",
|
|
||||||
"o" = "\xe2\xad\x95",
|
|
||||||
"heavy_plus_sign" = "\xe2\x9e\x95",
|
|
||||||
"heavy_minus_sign" = "\xe2\x9e\x96",
|
|
||||||
"heavy_division_sign" = "\xe2\x9e\x97",
|
|
||||||
"copyright" = "\xc2\xa9\xef\xb8\x8f",
|
|
||||||
"registered" = "\xc2\xae\xef\xb8\x8f",
|
|
||||||
"tm" = "\xe2\x84\xa2\xef\xb8\x8f",
|
|
||||||
|
|
||||||
// Nature & weather
|
|
||||||
"fire" = "\xf0\x9f\x94\xa5",
|
|
||||||
"zap" = "\xe2\x9a\xa1",
|
|
||||||
"sunny" = "\xe2\x98\x80\xef\xb8\x8f",
|
|
||||||
"cloud" = "\xe2\x98\x81\xef\xb8\x8f",
|
|
||||||
"rainbow" = "\xf0\x9f\x8c\x88",
|
|
||||||
"snowflake" = "\xe2\x9d\x84\xef\xb8\x8f",
|
|
||||||
"dash" = "\xf0\x9f\x92\xa8",
|
|
||||||
"tornado" = "\xf0\x9f\x8c\xaa\xef\xb8\x8f",
|
|
||||||
"deciduous_tree" = "\xf0\x9f\x8c\xb3",
|
|
||||||
"evergreen_tree" = "\xf0\x9f\x8c\xb2",
|
|
||||||
"palm_tree" = "\xf0\x9f\x8c\xb4",
|
|
||||||
"cactus" = "\xf0\x9f\x8c\xb5",
|
|
||||||
"tulip" = "\xf0\x9f\x8c\xb7",
|
|
||||||
"rose" = "\xf0\x9f\x8c\xb9",
|
|
||||||
"sunflower" = "\xf0\x9f\x8c\xbb",
|
|
||||||
"hibiscus" = "\xf0\x9f\x8c\xba",
|
|
||||||
"earth_africa" = "\xf0\x9f\x8c\x8d",
|
|
||||||
"earth_americas" = "\xf0\x9f\x8c\x8e",
|
|
||||||
"earth_asia" = "\xf0\x9f\x8c\x8f",
|
|
||||||
"new_moon" = "\xf0\x9f\x8c\x9a",
|
|
||||||
"full_moon" = "\xf0\x9f\x8c\x95",
|
|
||||||
|
|
||||||
// Food & drink
|
|
||||||
"coffee" = "\xe2\x98\x95",
|
|
||||||
"tea" = "\xf0\x9f\x8d\xb5",
|
|
||||||
"beer" = "\xf0\x9f\x8d\xba",
|
|
||||||
"beers" = "\xf0\x9f\x8d\xbb",
|
|
||||||
"wine_glass" = "\xf0\x9f\x8d\xb7",
|
|
||||||
"tropical_drink" = "\xf0\x9f\x8d\xb9",
|
|
||||||
"apple" = "\xf0\x9f\x8d\x8e",
|
|
||||||
"green_apple" = "\xf0\x9f\x8d\x8f",
|
|
||||||
"orange" = "\xf0\x9f\x8d\x8a",
|
|
||||||
"lemon" = "\xf0\x9f\x8d\x8b",
|
|
||||||
"banana" = "\xf0\x9f\x8d\x8c",
|
|
||||||
"watermelon" = "\xf0\x9f\x8d\x89",
|
|
||||||
"grapes" = "\xf0\x9f\x8d\x87",
|
|
||||||
"strawberry" = "\xf0\x9f\x8d\x93",
|
|
||||||
"melon" = "\xf0\x9f\x8d\x88",
|
|
||||||
"cherries" = "\xf0\x9f\x8d\x92",
|
|
||||||
"peach" = "\xf0\x9f\x8d\x91",
|
|
||||||
"pineapple" = "\xf0\x9f\x8d\x8d",
|
|
||||||
"pizza" = "\xf0\x9f\x8d\x95",
|
|
||||||
"hamburger" = "\xf0\x9f\x8d\x94",
|
|
||||||
"hotdog" = "\xf0\x9f\x8c\xad",
|
|
||||||
"taco" = "\xf0\x9f\x8c\xae",
|
|
||||||
"burrito" = "\xf0\x9f\x8c\xaf",
|
|
||||||
"cake" = "\xf0\x9f\x8d\xb0",
|
|
||||||
"cookie" = "\xf0\x9f\x8d\xaa",
|
|
||||||
"chocolate_bar" = "\xf0\x9f\x8d\xab",
|
|
||||||
"candy" = "\xf0\x9f\x8d\xac",
|
|
||||||
"popcorn" = "\xf0\x9f\x8d\xbf",
|
|
||||||
|
|
||||||
// Animals
|
|
||||||
"dog" = "\xf0\x9f\x90\xb6",
|
|
||||||
"cat" = "\xf0\x9f\x90\xb1",
|
|
||||||
"mouse" = "\xf0\x9f\x90\xad",
|
|
||||||
"hamster" = "\xf0\x9f\x90\xb9",
|
|
||||||
"rabbit" = "\xf0\x9f\x90\xb0",
|
|
||||||
"bear" = "\xf0\x9f\x90\xbb",
|
|
||||||
"panda_face" = "\xf0\x9f\x90\xbc",
|
|
||||||
"koala" = "\xf0\x9f\x90\xa8",
|
|
||||||
"tiger" = "\xf0\x9f\x90\xaf",
|
|
||||||
"lion_face" = "\xf0\x9f\xa6\x81",
|
|
||||||
"cow" = "\xf0\x9f\x90\xae",
|
|
||||||
"pig" = "\xf0\x9f\x90\xb7",
|
|
||||||
"frog" = "\xf0\x9f\x90\xb8",
|
|
||||||
"monkey_face" = "\xf0\x9f\x90\xb5",
|
|
||||||
"see_no_evil" = "\xf0\x9f\x99\x88",
|
|
||||||
"hear_no_evil" = "\xf0\x9f\x99\x89",
|
|
||||||
"speak_no_evil" = "\xf0\x9f\x99\x8a",
|
|
||||||
"owl" = "\xf0\x9f\xa6\x89",
|
|
||||||
"bat" = "\xf0\x9f\xa6\x87",
|
|
||||||
"wolf" = "\xf0\x9f\x90\xba",
|
|
||||||
"boar" = "\xf0\x9f\x90\x97",
|
|
||||||
"horse" = "\xf0\x9f\x90\x8e",
|
|
||||||
"unicorn" = "\xf0\x9f\xa6\x84",
|
|
||||||
"honeybee" = "\xf0\x9f\x90\x9d",
|
|
||||||
"bug" = "\xf0\x9f\x90\x9b",
|
|
||||||
"snail" = "\xf0\x9f\x90\x8c",
|
|
||||||
"beetle" = "\xf0\x9f\x90\x9e",
|
|
||||||
"ant" = "\xf0\x9f\x90\x9c",
|
|
||||||
"spider" = "\xf0\x9f\x95\xb7",
|
|
||||||
"scorpion" = "\xf0\x9f\xa6\x82",
|
|
||||||
"turtle" = "\xf0\x9f\x90\xa2",
|
|
||||||
"snake" = "\xf0\x9f\x90\x8d",
|
|
||||||
"octopus" = "\xf0\x9f\x90\x99",
|
|
||||||
"shell" = "\xf0\x9f\x90\x9a",
|
|
||||||
"whale" = "\xf0\x9f\x90\xb3",
|
|
||||||
"dolphin" = "\xf0\x9f\x90\xac",
|
|
||||||
"fish" = "\xf0\x9f\x90\x9f",
|
|
||||||
"tropical_fish" = "\xf0\x9f\x90\xa0",
|
|
||||||
"blowfish" = "\xf0\x9f\x90\xa1",
|
|
||||||
"penguin" = "\xf0\x9f\x90\xa7",
|
|
||||||
"chicken" = "\xf0\x9f\x90\x94",
|
|
||||||
"bird" = "\xf0\x9f\x90\xa6",
|
|
||||||
"eagle" = "\xf0\x9f\xa6\x85",
|
|
||||||
|
|
||||||
// Objects
|
|
||||||
"computer" = "\xf0\x9f\x92\xbb",
|
|
||||||
"iphone" = "\xf0\x9f\x93\xb1",
|
|
||||||
"keyboard" = "\xe2\x8c\xa8\xef\xb8\x8f",
|
|
||||||
"desktop_computer" = "\xf0\x9f\x96\xa5",
|
|
||||||
"printer" = "\xf0\x9f\x96\xa8",
|
|
||||||
"mouse_three_button" = "\xf0\x9f\x96\xb1",
|
|
||||||
"joystick" = "\xf0\x9f\x95\xb9",
|
|
||||||
"stash" = "\xf0\x9f\x92\xbe",
|
|
||||||
"floppy_disk" = "\xf0\x9f\x92\xbe",
|
|
||||||
"cd" = "\xf0\x9f\x92\xbf",
|
|
||||||
"dvd" = "\xf0\x9f\x93\x80",
|
|
||||||
"vhs" = "\xf0\x9f\x93\xbc",
|
|
||||||
"camera" = "\xf0\x9f\x93\xb7",
|
|
||||||
"video_camera" = "\xf0\x9f\x93\xb9",
|
|
||||||
"tv" = "\xf0\x9f\x93\xba",
|
|
||||||
"radio" = "\xf0\x9f\x93\xbb",
|
|
||||||
"pager" = "\xf0\x9f\x93\x9f",
|
|
||||||
"telephone" = "\xe2\x98\x8e\xef\xb8\x8f",
|
|
||||||
"fax" = "\xf0\x9f\x93\xa0",
|
|
||||||
"bulb" = "\xf0\x9f\x92\xa1",
|
|
||||||
"candle" = "\xf0\x9f\x95\xaf",
|
|
||||||
"bathtub" = "\xf0\x9f\x9b\x81",
|
|
||||||
"shower" = "\xf0\x9f\x9a\xbf",
|
|
||||||
"toilet" = "\xf0\x9f\x9a\xbd",
|
|
||||||
"wrench" = "\xf0\x9f\x94\xa7",
|
|
||||||
"hammer" = "\xf0\x9f\x94\xa8",
|
|
||||||
"nut_and_bolt" = "\xf0\x9f\x94\xa9",
|
|
||||||
"gear" = "\xe2\x9a\x99\xef\xb8\x8f",
|
|
||||||
"link" = "\xf0\x9f\x94\x97",
|
|
||||||
"lock" = "\xf0\x9f\x94\x92",
|
|
||||||
"unlock" = "\xf0\x9f\x94\x93",
|
|
||||||
"key" = "\xf0\x9f\x94\x91",
|
|
||||||
"bell" = "\xf0\x9f\x94\x94",
|
|
||||||
"bookmark" = "\xf0\x9f\x94\x96",
|
|
||||||
"pushpin" = "\xf0\x9f\x93\x8c",
|
|
||||||
"paperclip" = "\xf0\x9f\x93\x8e",
|
|
||||||
"memo" = "\xf0\x9f\x93\x9d",
|
|
||||||
"pencil2" = "\xe2\x9c\x8f\xef\xb8\x8f",
|
|
||||||
"black_nib" = "\xe2\x9c\x92\xef\xb8\x8f",
|
|
||||||
"pen" = "\xf0\x9f\x96\x8a",
|
|
||||||
"paintbrush" = "\xf0\x9f\x96\x8c",
|
|
||||||
"crayon" = "\xf0\x9f\x96\x8d",
|
|
||||||
"book" = "\xf0\x9f\x93\x97",
|
|
||||||
"books" = "\xf0\x9f\x93\x9a",
|
|
||||||
"ledger" = "\xf0\x9f\x93\x92",
|
|
||||||
"notebook" = "\xf0\x9f\x93\x93",
|
|
||||||
"scroll" = "\xf0\x9f\x93\x9c",
|
|
||||||
"page_with_curl" = "\xf0\x9f\x93\x84",
|
|
||||||
"newspaper" = "\xf0\x9f\x93\xb0",
|
|
||||||
"chart_with_upwards_trend" = "\xf0\x9f\x93\x88",
|
|
||||||
"chart_with_downwards_trend" = "\xf0\x9f\x93\x89",
|
|
||||||
"bar_chart" = "\xf0\x9f\x93\x8a",
|
|
||||||
"calendar" = "\xf0\x9f\x93\x85",
|
|
||||||
"date" = "\xf0\x9f\x93\x85",
|
|
||||||
"hourglass" = "\xe2\x8f\xb3",
|
|
||||||
"hourglass_flowing_sand" = "\xe2\x8f\xb3",
|
|
||||||
"clock" = "\xf0\x9f\x95\x90",
|
|
||||||
"alarm_clock" = "\xe2\x8f\xb0",
|
|
||||||
"stopwatch" = "\xe2\x8f\xb1",
|
|
||||||
"watch" = "\xe2\x8c\x9a",
|
|
||||||
"moneybag" = "\xf0\x9f\x92\xb0",
|
|
||||||
"yen" = "\xf0\x9f\x92\xb4",
|
|
||||||
"dollar" = "\xf0\x9f\x92\xb5",
|
|
||||||
"euro" = "\xf0\x9f\x92\xb6",
|
|
||||||
"pound" = "\xf0\x9f\x92\xb7",
|
|
||||||
"money_with_wings" = "\xf0\x9f\x92\xb8",
|
|
||||||
"credit_card" = "\xf0\x9f\x92\xb3",
|
|
||||||
"gem" = "\xf0\x9f\x92\x8e",
|
|
||||||
"bomb" = "\xf0\x9f\x92\xa3",
|
|
||||||
"gift" = "\xf0\x9f\x8e\x81",
|
|
||||||
"balloon" = "\xf0\x9f\x8e\x88",
|
|
||||||
"tada" = "\xf0\x9f\x8e\x89",
|
|
||||||
"confetti_ball" = "\xf0\x9f\x8e\x8a",
|
|
||||||
"package" = "\xf0\x9f\x93\xa6",
|
|
||||||
"mailbox" = "\xf0\x9f\x93\xab",
|
|
||||||
"inbox_tray" = "\xf0\x9f\x93\xa5",
|
|
||||||
"outbox_tray" = "\xf0\x9f\x93\xa4",
|
|
||||||
"email" = "\xe2\x9c\x89\xef\xb8\x8f",
|
|
||||||
"envelope" = "\xe2\x9c\x89\xef\xb8\x8f",
|
|
||||||
"incoming_envelope" = "\xf0\x9f\x93\xa8",
|
|
||||||
|
|
||||||
// Activities
|
|
||||||
"soccer" = "\xe2\x9a\xbd",
|
|
||||||
"basketball" = "\xf0\x9f\x8f\x80",
|
|
||||||
"football" = "\xf0\x9f\x8f\x88",
|
|
||||||
"baseball" = "\xe2\x9a\xbe",
|
|
||||||
"tennis" = "\xf0\x9f\x8e\xbe",
|
|
||||||
"8ball" = "\xf0\x9f\x8e\xb1",
|
|
||||||
"bowling" = "\xf0\x9f\x8e\xb3",
|
|
||||||
"video_game" = "\xf0\x9f\x8e\xae",
|
|
||||||
"dart" = "\xf0\x9f\x8e\xaf",
|
|
||||||
"game_die" = "\xf0\x9f\x8e\xb2",
|
|
||||||
"slot_machine" = "\xf0\x9f\x8e\xb0",
|
|
||||||
"cards" = "\xf0\x9f\x83\x8f",
|
|
||||||
"black_joker" = "\xf0\x9f\x83\x9f",
|
|
||||||
"mahjong" = "\xf0\x9f\x80\x84",
|
|
||||||
"musical_note" = "\xf0\x9f\x8e\xb5",
|
|
||||||
"notes" = "\xf0\x9f\x8e\xb6",
|
|
||||||
"saxophone" = "\xf0\x9f\x8e\xb7",
|
|
||||||
"guitar" = "\xf0\x9f\x8e\xb8",
|
|
||||||
"musical_keyboard" = "\xf0\x9f\x8e\xb9",
|
|
||||||
"trumpet" = "\xf0\x9f\x8e\xba",
|
|
||||||
"violin" = "\xf0\x9f\x8e\xbb",
|
|
||||||
"drum" = "\xf0\x9f\xa5\x81",
|
|
||||||
"headphones" = "\xf0\x9f\x8e\xa7",
|
|
||||||
"microphone" = "\xf0\x9f\x8e\xa4",
|
|
||||||
"level_slider" = "\xf0\x9f\x8e\x9a",
|
|
||||||
"control_knobs" = "\xf0\x9f\x8e\x9b",
|
|
||||||
"ticket" = "\xf0\x9f\x8e\xab",
|
|
||||||
"art" = "\xf0\x9f\x8e\xa8",
|
|
||||||
"circus_tent" = "\xf0\x9f\x8e\xaa",
|
|
||||||
"theater_masks" = "\xf0\x9f\x8e\xad",
|
|
||||||
"clapper" = "\xf0\x9f\x8e\xac",
|
|
||||||
|
|
||||||
// Travel
|
|
||||||
"car" = "\xf0\x9f\x9a\x97",
|
|
||||||
"taxi" = "\xf0\x9f\x9a\x95",
|
|
||||||
"bus" = "\xf0\x9f\x9a\x8d",
|
|
||||||
"train" = "\xf0\x9f\x9a\x86",
|
|
||||||
"metro" = "\xf0\x9f\x9a\x87",
|
|
||||||
"light_rail" = "\xf0\x9f\x9a\x88",
|
|
||||||
"tram" = "\xf0\x9f\x9a\x8a",
|
|
||||||
"bike" = "\xf0\x9f\x9a\xb2",
|
|
||||||
"motorcycle" = "\xf0\x9f\x8f\x8d",
|
|
||||||
"airplane" = "\xe2\x9c\x88\xef\xb8\x8f",
|
|
||||||
"helicopter" = "\xf0\x9f\x9a\x81",
|
|
||||||
"boat" = "\xe2\x9b\xb5",
|
|
||||||
"sailboat" = "\xe2\x9b\xb5",
|
|
||||||
"ship" = "\xf0\x9f\x9a\xa2",
|
|
||||||
"fuelpump" = "\xe2\x9b\xbd",
|
|
||||||
"construction" = "\xf0\x9f\x9a\xa7",
|
|
||||||
"house" = "\xf0\x9f\x8f\xa0",
|
|
||||||
"house_with_garden" = "\xf0\x9f\x8f\xa1",
|
|
||||||
"office" = "\xf0\x9f\x8f\xa2",
|
|
||||||
"post_office" = "\xf0\x9f\x8f\xa3",
|
|
||||||
"hospital" = "\xf0\x9f\x8f\xa5",
|
|
||||||
"bank" = "\xf0\x9f\x8f\xa6",
|
|
||||||
"hotel" = "\xf0\x9f\x8f\xa8",
|
|
||||||
"school" = "\xf0\x9f\x8f\xab",
|
|
||||||
"department_store" = "\xf0\x9f\x8f\xac",
|
|
||||||
"church" = "\xe2\x9b\xaa",
|
|
||||||
"castle" = "\xf0\x9f\x8f\xb0",
|
|
||||||
"factory" = "\xf0\x9f\x8f\xad",
|
|
||||||
"tokyo_tower" = "\xf0\x9f\x97\xbc",
|
|
||||||
"statue_of_liberty" = "\xf0\x9f\x97\xbd",
|
|
||||||
"fountain" = "\xe2\x9b\xb2",
|
|
||||||
"tent" = "\xe2\x9b\xba",
|
|
||||||
"mountain" = "\xf0\x9f\x8f\x94",
|
|
||||||
"snow_capped_mountain" = "\xf0\x9f\x8f\x94",
|
|
||||||
"beach" = "\xf0\x9f\x8f\x96",
|
|
||||||
"camping" = "\xf0\x9f\x8f\x95",
|
|
||||||
"world_map" = "\xf0\x9f\x97\xba",
|
|
||||||
"japan" = "\xf0\x9f\x97\xbe",
|
|
||||||
};
|
|
||||||
|
|
||||||
expand_emoji :: proc(text: string) -> string {
|
|
||||||
if len(EMOJIS) == 0 {
|
|
||||||
return text
|
|
||||||
}
|
|
||||||
|
|
||||||
parts: [dynamic]string
|
|
||||||
defer delete(parts)
|
|
||||||
|
|
||||||
remaining := text
|
|
||||||
|
|
||||||
for {
|
|
||||||
colon := strings.index(remaining, ":")
|
|
||||||
if colon < 0 {
|
|
||||||
append(&parts, remaining)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the closing colon
|
|
||||||
after := remaining[colon + 1:]
|
|
||||||
end := strings.index(after, ":")
|
|
||||||
if end < 0 {
|
|
||||||
append(&parts, remaining)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
shortcode := remaining[colon + 1 : colon + 1 + end]
|
|
||||||
|
|
||||||
// Validate: shortcode must be all lowercase letters, digits, or underscores
|
|
||||||
// and must not contain whitespace
|
|
||||||
valid := true
|
|
||||||
for c in shortcode {
|
|
||||||
if !(c >= 'a' && c <= 'z') && !(c >= '0' && c <= '9') && c != '_' && c != '+' && c != '-' {
|
|
||||||
valid = false
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !valid || len(shortcode) == 0 {
|
|
||||||
append(&parts, remaining[:colon + 1])
|
|
||||||
remaining = remaining[colon + 1:]
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
emoji, found := EMOJIS[shortcode]
|
|
||||||
if !found {
|
|
||||||
append(&parts, remaining[:colon + 1])
|
|
||||||
remaining = remaining[colon + 1:]
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Replace :shortcode: with emoji
|
|
||||||
append(&parts, remaining[:colon])
|
|
||||||
append(&parts, emoji)
|
|
||||||
remaining = remaining[colon + 1 + end + 1:]
|
|
||||||
}
|
|
||||||
|
|
||||||
return strings.join(parts[:], "")
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user