| 156 | } |
| 157 | |
| 158 | override code({ lang: info, text }: Marked.Tokens.Code): string { |
| 159 | // format: tsx |
| 160 | // format: tsx my/file.ts |
| 161 | // format: tsx "This is my title" |
| 162 | let lang = ""; |
| 163 | let title = ""; |
| 164 | const match = info?.match(/^([\w_-]+)\s*(.*)?$/); |
| 165 | if (match) { |
| 166 | lang = match[1].toLocaleLowerCase(); |
| 167 | title = match[2] ?? ""; |
| 168 | } |
| 169 | |
| 170 | // Find icon by filename first, then by markdown block language. |
| 171 | const icon = LOGOS.find((l) => l.file.test(title)) ?? |
| 172 | LOGOS.find((l) => l.lang.test(lang)); |
| 173 | |
| 174 | let out = `<div class="fenced-code">`; |
| 175 | |
| 176 | if (title || icon) { |
| 177 | const image = icon |
| 178 | ? `<img src="${icon.src}" alt="${icon.text}" title="${icon.text}" width="20" height="20">` |
| 179 | : ""; |
| 180 | |
| 181 | out += `<div class="fenced-code-header"> |
| 182 | <span class="fenced-code-title lang-${lang} w-full"> |
| 183 | <span class="flex items-center gap-2"> |
| 184 | ${image} |
| 185 | ${title ? escapeHtml(String(title)) : " "} |
| 186 | </span> |
| 187 | </span> |
| 188 | ${ |
| 189 | icon && icon.text !== "Text" |
| 190 | ? `<button |
| 191 | type="button" |
| 192 | data-code="${escapeHtml(text)}" |
| 193 | aria-label="Copy to Clipboard" |
| 194 | class="rounded-sm flex items-center justify-center border border-foreground-secondary/30 hover:bg-foreground-secondary/20 dark:hover:bg-foreground-secondary/70 data-copied:text-green-700 dark:data-copied:text-green-300 relative group cursor-pointer w-7 h-7 dark:text-white" |
| 195 | > |
| 196 | <span class="group-copied"> |
| 197 | <svg |
| 198 | xmlns="http://www.w3.org/2000/svg" |
| 199 | class="h-4 w-4" |
| 200 | fill="none" |
| 201 | viewBox="0 0 24 24" |
| 202 | stroke="currentColor" |
| 203 | aria-hidden="true" |
| 204 | > |
| 205 | <path |
| 206 | stroke-width={3} |
| 207 | strokeLinecap="round" |
| 208 | strokeLinejoin="round" |
| 209 | d="M5 13l4 4L19 7" |
| 210 | /> |
| 211 | </svg> |
| 212 | </span> |
| 213 | <span class="group-not-copied"> |
| 214 | <svg |
| 215 | class="h-4 w-4" |