diff --git a/src/components/FileExplorer.tsx b/src/components/FileExplorer.tsx
index 2e8185316..17d926b44 100644
--- a/src/components/FileExplorer.tsx
+++ b/src/components/FileExplorer.tsx
@@ -6,6 +6,7 @@ import htmlIconUrl from '~/images/file-icons/html.svg?url'
import jsonIconUrl from '~/images/file-icons/json.svg?url'
import svelteIconUrl from '~/images/file-icons/svelte.svg?url'
import vueIconUrl from '~/images/file-icons/vue.svg?url'
+import markoIconUrl from '~/images/file-icons/marko.svg?url'
import textIconUrl from '~/images/file-icons/txt.svg?url'
import type { GitHubFileNode } from '~/utils/documents.server'
import { twMerge } from 'tailwind-merge'
@@ -30,6 +31,8 @@ const getFileIconPath = (filename: string) => {
return svelteIconUrl
case 'vue':
return vueIconUrl
+ case 'marko':
+ return markoIconUrl
default:
return textIconUrl
}
diff --git a/src/components/markdown/codeBlock.shared.tsx b/src/components/markdown/codeBlock.shared.tsx
index 6b4562824..2befa457e 100644
--- a/src/components/markdown/codeBlock.shared.tsx
+++ b/src/components/markdown/codeBlock.shared.tsx
@@ -86,6 +86,10 @@ export function getCodeBlockLanguageFromFilePath(filePath: string) {
if (['prettierrc', 'babelrc', 'webmanifest'].includes(ext)) return 'json'
if (['env', 'example'].includes(ext)) return 'sh'
+ // Marko is HTML-based; @tanstack/highlight has no Marko grammar, so fall
+ // back to html for reasonable tag/attribute/string coloring.
+ if (ext === 'marko') return 'html'
+
if (
[
'gitignore',
diff --git a/src/images/file-icons/marko.svg b/src/images/file-icons/marko.svg
new file mode 100644
index 000000000..9af592b8d
--- /dev/null
+++ b/src/images/file-icons/marko.svg
@@ -0,0 +1,54 @@
+
diff --git a/src/images/marko-logo.svg b/src/images/marko-logo.svg
new file mode 100644
index 000000000..6da554b72
--- /dev/null
+++ b/src/images/marko-logo.svg
@@ -0,0 +1,54 @@
+
diff --git a/src/libraries/frameworks.tsx b/src/libraries/frameworks.tsx
index 38605e842..683a864e6 100644
--- a/src/libraries/frameworks.tsx
+++ b/src/libraries/frameworks.tsx
@@ -2,6 +2,7 @@ import alpineLogo from '../images/alpine-logo.svg'
import angularLogo from '../images/angular-logo.svg'
import jsLogo from '../images/js-logo.svg'
import litLogo from '../images/lit-logo.svg'
+import markoLogo from '../images/marko-logo.svg'
import qwikLogo from '../images/qwik-logo.svg'
import preactLogo from '../images/preact-logo.svg'
import reactLogo from '../images/react-logo.svg'
@@ -53,6 +54,13 @@ export const frameworkOptions = [
color: 'bg-orange-600',
fontColor: 'text-orange-600',
},
+ {
+ label: 'Marko',
+ value: 'marko',
+ logo: markoLogo,
+ color: 'bg-cyan-500',
+ fontColor: 'text-cyan-500',
+ },
{
label: 'Qwik',
value: 'qwik',
diff --git a/src/libraries/libraries.ts b/src/libraries/libraries.ts
index 057853816..4e2f763e3 100644
--- a/src/libraries/libraries.ts
+++ b/src/libraries/libraries.ts
@@ -428,7 +428,7 @@ export const virtual: LibrarySlim = {
to: '/virtual',
tagline: 'Headless UI for Virtualizing Large Element Lists',
description:
- 'Virtualize only the visible content for massive scrollable DOM nodes at 60FPS in TS/JS, React, Vue, Solid, Svelte, Lit & Angular while retaining 100% control over markup and styles.',
+ 'Virtualize only the visible content for massive scrollable DOM nodes at 60FPS in TS/JS, React, Vue, Solid, Svelte, Lit, Angular & Marko while retaining 100% control over markup and styles.',
bgStyle: 'bg-purple-500',
borderStyle: 'border-purple-500/50',
textStyle: 'text-purple-500',
@@ -438,7 +438,7 @@ export const virtual: LibrarySlim = {
bgRadial: 'from-purple-500 via-violet-600/50 to-transparent',
badge: undefined,
repo: 'tanstack/virtual',
- frameworks: ['react', 'solid', 'vue', 'svelte', 'lit', 'angular'],
+ frameworks: ['react', 'solid', 'vue', 'svelte', 'lit', 'angular', 'marko'],
corePackageName: '@tanstack/virtual-core',
npmPackageNames: ['@tanstack/virtual-core', 'react-virtual'],
latestVersion: 'v3',
diff --git a/src/libraries/types.ts b/src/libraries/types.ts
index 43f1108d6..8f452652c 100644
--- a/src/libraries/types.ts
+++ b/src/libraries/types.ts
@@ -7,6 +7,7 @@ export type Framework =
| 'angular'
| 'alpine'
| 'lit'
+ | 'marko'
| 'preact'
| 'qwik'
| 'react'
diff --git a/src/libraries/virtual.tsx b/src/libraries/virtual.tsx
index 57a47c64c..b99b27b28 100644
--- a/src/libraries/virtual.tsx
+++ b/src/libraries/virtual.tsx
@@ -7,7 +7,7 @@ const textStyles = 'text-violet-700 dark:text-violet-400'
export const virtualProject = {
...virtual,
- description: `Virtualize only the visible content for massive scrollable DOM nodes at 60FPS in TS/JS, React, Vue, Solid, Svelte, Lit & Angular while retaining 100% control over markup and styles.`,
+ description: `Virtualize only the visible content for massive scrollable DOM nodes at 60FPS in TS/JS, React, Vue, Solid, Svelte, Lit, Angular & Marko while retaining 100% control over markup and styles.`,
latestBranch: 'main',
bgRadial: 'from-purple-500 via-violet-600/50 to-transparent',
textColor: 'text-purple-600',
diff --git a/src/utils/llms.ts b/src/utils/llms.ts
index 6fec22395..987f9cc0a 100644
--- a/src/utils/llms.ts
+++ b/src/utils/llms.ts
@@ -42,6 +42,7 @@ const frameworkLabels: Record = {
angular: 'Angular',
alpine: 'Alpine',
lit: 'Lit',
+ marko: 'Marko',
preact: 'Preact',
qwik: 'Qwik',
react: 'React',
diff --git a/src/utils/npm-packages.ts b/src/utils/npm-packages.ts
index a30c48950..f37c4e023 100644
--- a/src/utils/npm-packages.ts
+++ b/src/utils/npm-packages.ts
@@ -26,6 +26,7 @@ export const frameworkMeta: Record =
solid: { name: 'Solid', color: '#2C4F7C' },
vue: { name: 'Vue', color: '#42B883' },
svelte: { name: 'Svelte', color: '#FF3E00' },
+ marko: { name: 'Marko', color: '#44bfef' },
angular: { name: 'Angular', color: '#DD0031' },
alpine: { name: 'Alpine', color: '#77C1D2' },
lit: { name: 'Lit', color: '#325CFF' },
diff --git a/src/utils/repo-path.ts b/src/utils/repo-path.ts
index facefd778..22330d275 100644
--- a/src/utils/repo-path.ts
+++ b/src/utils/repo-path.ts
@@ -1,6 +1,6 @@
export const MAX_REPO_PATH_LENGTH = 512
-const REPO_PATH_SEGMENT_PATTERN = /^[a-zA-Z0-9._$-]+$/
+const REPO_PATH_SEGMENT_PATTERN = /^[a-zA-Z0-9._$+-]+$/
export function isValidRepoPath(path: string) {
if (path === '') {