wip
This commit is contained in:
@@ -95,7 +95,7 @@ func TestFuzzyBlockMatchSalad(t *testing.T) {
|
|||||||
}
|
}
|
||||||
blocks, err := template.CompileTemplate(schemaMd)
|
blocks, err := template.CompileTemplate(schemaMd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Failed to compile template: %s", err.Error())
|
t.Errorf("failed to compile template: %s", err.Error())
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -40,19 +40,9 @@ func DetectType(markdownContent string) (string, error) {
|
|||||||
return "", fmt.Errorf("could not parse frontmatter")
|
return "", fmt.Errorf("could not parse frontmatter")
|
||||||
}
|
}
|
||||||
|
|
||||||
func MatchBlocks(markdownContent string) ([]matcher.Block, error) {
|
func MatchBlocks(markdownContent, templateContent string) ([]matcher.Block, error) {
|
||||||
markdownContent = strings.TrimSuffix(markdownContent, "\n")
|
markdownContent = strings.TrimSuffix(markdownContent, "\n")
|
||||||
|
|
||||||
contentType, err := DetectType(markdownContent)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("could not detect type: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
templateContent, err := registry.GetTemplate(contentType)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("could not get schema: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
tpl, err := template.CompileTemplate(templateContent)
|
tpl, err := template.CompileTemplate(templateContent)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to compile template: %w", err)
|
return nil, fmt.Errorf("failed to compile template: %w", err)
|
||||||
|
@@ -39,5 +39,15 @@
|
|||||||
"onlyBuiltDependencies": [
|
"onlyBuiltDependencies": [
|
||||||
"esbuild"
|
"esbuild"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@codemirror/lang-javascript": "^6.2.4",
|
||||||
|
"@codemirror/lang-json": "^6.0.2",
|
||||||
|
"@codemirror/lang-markdown": "^6.3.4",
|
||||||
|
"@codemirror/state": "^6.5.2",
|
||||||
|
"@codemirror/view": "^6.38.3",
|
||||||
|
"codemirror": "^6.0.2",
|
||||||
|
"lucide-svelte": "^0.544.0",
|
||||||
|
"svelte-codemirror-editor": "^2.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
268
playground/pnpm-lock.yaml
generated
268
playground/pnpm-lock.yaml
generated
@@ -7,6 +7,31 @@ settings:
|
|||||||
importers:
|
importers:
|
||||||
|
|
||||||
.:
|
.:
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/lang-javascript':
|
||||||
|
specifier: ^6.2.4
|
||||||
|
version: 6.2.4
|
||||||
|
'@codemirror/lang-json':
|
||||||
|
specifier: ^6.0.2
|
||||||
|
version: 6.0.2
|
||||||
|
'@codemirror/lang-markdown':
|
||||||
|
specifier: ^6.3.4
|
||||||
|
version: 6.3.4
|
||||||
|
'@codemirror/state':
|
||||||
|
specifier: ^6.5.2
|
||||||
|
version: 6.5.2
|
||||||
|
'@codemirror/view':
|
||||||
|
specifier: ^6.38.3
|
||||||
|
version: 6.38.3
|
||||||
|
codemirror:
|
||||||
|
specifier: ^6.0.2
|
||||||
|
version: 6.0.2
|
||||||
|
lucide-svelte:
|
||||||
|
specifier: ^0.544.0
|
||||||
|
version: 0.544.0(svelte@5.39.6)
|
||||||
|
svelte-codemirror-editor:
|
||||||
|
specifier: ^2.0.0
|
||||||
|
version: 2.0.0(codemirror@6.0.2)(svelte@5.39.6)
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@eslint/compat':
|
'@eslint/compat':
|
||||||
specifier: ^1.2.5
|
specifier: ^1.2.5
|
||||||
@@ -71,6 +96,42 @@ importers:
|
|||||||
|
|
||||||
packages:
|
packages:
|
||||||
|
|
||||||
|
'@codemirror/autocomplete@6.18.7':
|
||||||
|
resolution: {integrity: sha512-8EzdeIoWPJDsMBwz3zdzwXnUpCzMiCyz5/A3FIPpriaclFCGDkAzK13sMcnsu5rowqiyeQN2Vs2TsOcoDPZirQ==}
|
||||||
|
|
||||||
|
'@codemirror/commands@6.8.1':
|
||||||
|
resolution: {integrity: sha512-KlGVYufHMQzxbdQONiLyGQDUW0itrLZwq3CcY7xpv9ZLRHqzkBSoteocBHtMCoY7/Ci4xhzSrToIeLg7FxHuaw==}
|
||||||
|
|
||||||
|
'@codemirror/lang-css@6.3.1':
|
||||||
|
resolution: {integrity: sha512-kr5fwBGiGtmz6l0LSJIbno9QrifNMUusivHbnA1H6Dmqy4HZFte3UAICix1VuKo0lMPKQr2rqB+0BkKi/S3Ejg==}
|
||||||
|
|
||||||
|
'@codemirror/lang-html@6.4.10':
|
||||||
|
resolution: {integrity: sha512-h/SceTVsN5r+WE+TVP2g3KDvNoSzbSrtZXCKo4vkKdbfT5t4otuVgngGdFukOO/rwRD2++pCxoh6xD4TEVMkQA==}
|
||||||
|
|
||||||
|
'@codemirror/lang-javascript@6.2.4':
|
||||||
|
resolution: {integrity: sha512-0WVmhp1QOqZ4Rt6GlVGwKJN3KW7Xh4H2q8ZZNGZaP6lRdxXJzmjm4FqvmOojVj6khWJHIb9sp7U/72W7xQgqAA==}
|
||||||
|
|
||||||
|
'@codemirror/lang-json@6.0.2':
|
||||||
|
resolution: {integrity: sha512-x2OtO+AvwEHrEwR0FyyPtfDUiloG3rnVTSZV1W8UteaLL8/MajQd8DpvUb2YVzC+/T18aSDv0H9mu+xw0EStoQ==}
|
||||||
|
|
||||||
|
'@codemirror/lang-markdown@6.3.4':
|
||||||
|
resolution: {integrity: sha512-fBm0BO03azXnTAsxhONDYHi/qWSI+uSEIpzKM7h/bkIc9fHnFp9y7KTMXKON0teNT97pFhc1a9DQTtWBYEZ7ug==}
|
||||||
|
|
||||||
|
'@codemirror/language@6.11.3':
|
||||||
|
resolution: {integrity: sha512-9HBM2XnwDj7fnu0551HkGdrUrrqmYq/WC5iv6nbY2WdicXdGbhR/gfbZOH73Aqj4351alY1+aoG9rCNfiwS1RA==}
|
||||||
|
|
||||||
|
'@codemirror/lint@6.8.5':
|
||||||
|
resolution: {integrity: sha512-s3n3KisH7dx3vsoeGMxsbRAgKe4O1vbrnKBClm99PU0fWxmxsx5rR2PfqQgIt+2MMJBHbiJ5rfIdLYfB9NNvsA==}
|
||||||
|
|
||||||
|
'@codemirror/search@6.5.11':
|
||||||
|
resolution: {integrity: sha512-KmWepDE6jUdL6n8cAAqIpRmLPBZ5ZKnicE8oGU/s3QrAVID+0VhLFrzUucVKHG5035/BSykhExDL/Xm7dHthiA==}
|
||||||
|
|
||||||
|
'@codemirror/state@6.5.2':
|
||||||
|
resolution: {integrity: sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA==}
|
||||||
|
|
||||||
|
'@codemirror/view@6.38.3':
|
||||||
|
resolution: {integrity: sha512-x2t87+oqwB1mduiQZ6huIghjMt4uZKFEdj66IcXw7+a5iBEvv9lh7EWDRHI7crnD4BMGpnyq/RzmCGbiEZLcvQ==}
|
||||||
|
|
||||||
'@esbuild/aix-ppc64@0.25.10':
|
'@esbuild/aix-ppc64@0.25.10':
|
||||||
resolution: {integrity: sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==}
|
resolution: {integrity: sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
@@ -314,6 +375,33 @@ packages:
|
|||||||
'@jridgewell/trace-mapping@0.3.31':
|
'@jridgewell/trace-mapping@0.3.31':
|
||||||
resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
|
resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
|
||||||
|
|
||||||
|
'@lezer/common@1.2.3':
|
||||||
|
resolution: {integrity: sha512-w7ojc8ejBqr2REPsWxJjrMFsA/ysDCFICn8zEOR9mrqzOu2amhITYuLD8ag6XZf0CFXDrhKqw7+tW8cX66NaDA==}
|
||||||
|
|
||||||
|
'@lezer/css@1.3.0':
|
||||||
|
resolution: {integrity: sha512-pBL7hup88KbI7hXnZV3PQsn43DHy6TWyzuyk2AO9UyoXcDltvIdqWKE1dLL/45JVZ+YZkHe1WVHqO6wugZZWcw==}
|
||||||
|
|
||||||
|
'@lezer/highlight@1.2.1':
|
||||||
|
resolution: {integrity: sha512-Z5duk4RN/3zuVO7Jq0pGLJ3qynpxUVsh7IbUbGj88+uV2ApSAn6kWg2au3iJb+0Zi7kKtqffIESgNcRXWZWmSA==}
|
||||||
|
|
||||||
|
'@lezer/html@1.3.11':
|
||||||
|
resolution: {integrity: sha512-SV04kK5EHDPPecMCiFNZAnQhUIxktP04yHxgOKK7TZ3+KUAlK9f4dcYbjAWwDx2C2pJmiOeSV05QEbHeQo5JqA==}
|
||||||
|
|
||||||
|
'@lezer/javascript@1.5.4':
|
||||||
|
resolution: {integrity: sha512-vvYx3MhWqeZtGPwDStM2dwgljd5smolYD2lR2UyFcHfxbBQebqx8yjmFmxtJ/E6nN6u1D9srOiVWm3Rb4tmcUA==}
|
||||||
|
|
||||||
|
'@lezer/json@1.0.3':
|
||||||
|
resolution: {integrity: sha512-BP9KzdF9Y35PDpv04r0VeSTKDeox5vVr3efE7eBbx3r4s3oNLfunchejZhjArmeieBH+nVOpgIiBJpEAv8ilqQ==}
|
||||||
|
|
||||||
|
'@lezer/lr@1.4.2':
|
||||||
|
resolution: {integrity: sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA==}
|
||||||
|
|
||||||
|
'@lezer/markdown@1.4.3':
|
||||||
|
resolution: {integrity: sha512-kfw+2uMrQ/wy/+ONfrH83OkdFNM0ye5Xq96cLlaCy7h5UT9FO54DU4oRoIc0CSBh5NWmWuiIJA7NGLMJbQ+Oxg==}
|
||||||
|
|
||||||
|
'@marijn/find-cluster-break@1.0.2':
|
||||||
|
resolution: {integrity: sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==}
|
||||||
|
|
||||||
'@nodelib/fs.scandir@2.1.5':
|
'@nodelib/fs.scandir@2.1.5':
|
||||||
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
|
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
|
||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
@@ -702,6 +790,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
|
resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
|
codemirror@6.0.2:
|
||||||
|
resolution: {integrity: sha512-VhydHotNW5w1UGK0Qj96BwSk/Zqbp9WbnyK2W/eVMv4QyF41INRGpjUhFJY7/uDNuudSc33a/PKr4iDqRduvHw==}
|
||||||
|
|
||||||
color-convert@2.0.1:
|
color-convert@2.0.1:
|
||||||
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
|
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
|
||||||
engines: {node: '>=7.0.0'}
|
engines: {node: '>=7.0.0'}
|
||||||
@@ -716,6 +807,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==}
|
resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==}
|
||||||
engines: {node: '>= 0.6'}
|
engines: {node: '>= 0.6'}
|
||||||
|
|
||||||
|
crelt@1.0.6:
|
||||||
|
resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==}
|
||||||
|
|
||||||
cross-spawn@7.0.6:
|
cross-spawn@7.0.6:
|
||||||
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
|
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
|
||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
@@ -1043,6 +1137,11 @@ packages:
|
|||||||
lodash.merge@4.6.2:
|
lodash.merge@4.6.2:
|
||||||
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
|
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
|
||||||
|
|
||||||
|
lucide-svelte@0.544.0:
|
||||||
|
resolution: {integrity: sha512-8kBxSivf8SJdEUJRHBpu9bRw0S/qfVK+Yfb92KQnRRBdP425RzT6aQfrIfZctG1oucPVTBQe1ZXgmth/3qVICg==}
|
||||||
|
peerDependencies:
|
||||||
|
svelte: ^3 || ^4 || ^5.0.0-next.42
|
||||||
|
|
||||||
magic-string@0.30.19:
|
magic-string@0.30.19:
|
||||||
resolution: {integrity: sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==}
|
resolution: {integrity: sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==}
|
||||||
|
|
||||||
@@ -1290,6 +1389,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
|
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
|
style-mod@4.1.2:
|
||||||
|
resolution: {integrity: sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==}
|
||||||
|
|
||||||
supports-color@7.2.0:
|
supports-color@7.2.0:
|
||||||
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
|
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@@ -1302,6 +1404,12 @@ packages:
|
|||||||
svelte: ^4.0.0 || ^5.0.0-next.0
|
svelte: ^4.0.0 || ^5.0.0-next.0
|
||||||
typescript: '>=5.0.0'
|
typescript: '>=5.0.0'
|
||||||
|
|
||||||
|
svelte-codemirror-editor@2.0.0:
|
||||||
|
resolution: {integrity: sha512-LJyCPGzOHL290ec4dLBsVyu6e5dsk2pLKUBfU8wA5/EN7Zgc0UXxjNeEsDHGLZhZr2RYMiYwa7tLRZCHOtsxCg==}
|
||||||
|
peerDependencies:
|
||||||
|
codemirror: ^6.0.0
|
||||||
|
svelte: ^5.0.0
|
||||||
|
|
||||||
svelte-eslint-parser@1.3.3:
|
svelte-eslint-parser@1.3.3:
|
||||||
resolution: {integrity: sha512-oTrDR8Z7Wnguut7QH3YKh7JR19xv1seB/bz4dxU5J/86eJtZOU4eh0/jZq4dy6tAlz/KROxnkRQspv5ZEt7t+Q==}
|
resolution: {integrity: sha512-oTrDR8Z7Wnguut7QH3YKh7JR19xv1seB/bz4dxU5J/86eJtZOU4eh0/jZq4dy6tAlz/KROxnkRQspv5ZEt7t+Q==}
|
||||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||||
@@ -1417,6 +1525,9 @@ packages:
|
|||||||
vite:
|
vite:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
w3c-keyname@2.2.8:
|
||||||
|
resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==}
|
||||||
|
|
||||||
which@2.0.2:
|
which@2.0.2:
|
||||||
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
|
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
|
||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
@@ -1443,6 +1554,97 @@ packages:
|
|||||||
|
|
||||||
snapshots:
|
snapshots:
|
||||||
|
|
||||||
|
'@codemirror/autocomplete@6.18.7':
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/language': 6.11.3
|
||||||
|
'@codemirror/state': 6.5.2
|
||||||
|
'@codemirror/view': 6.38.3
|
||||||
|
'@lezer/common': 1.2.3
|
||||||
|
|
||||||
|
'@codemirror/commands@6.8.1':
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/language': 6.11.3
|
||||||
|
'@codemirror/state': 6.5.2
|
||||||
|
'@codemirror/view': 6.38.3
|
||||||
|
'@lezer/common': 1.2.3
|
||||||
|
|
||||||
|
'@codemirror/lang-css@6.3.1':
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/autocomplete': 6.18.7
|
||||||
|
'@codemirror/language': 6.11.3
|
||||||
|
'@codemirror/state': 6.5.2
|
||||||
|
'@lezer/common': 1.2.3
|
||||||
|
'@lezer/css': 1.3.0
|
||||||
|
|
||||||
|
'@codemirror/lang-html@6.4.10':
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/autocomplete': 6.18.7
|
||||||
|
'@codemirror/lang-css': 6.3.1
|
||||||
|
'@codemirror/lang-javascript': 6.2.4
|
||||||
|
'@codemirror/language': 6.11.3
|
||||||
|
'@codemirror/state': 6.5.2
|
||||||
|
'@codemirror/view': 6.38.3
|
||||||
|
'@lezer/common': 1.2.3
|
||||||
|
'@lezer/css': 1.3.0
|
||||||
|
'@lezer/html': 1.3.11
|
||||||
|
|
||||||
|
'@codemirror/lang-javascript@6.2.4':
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/autocomplete': 6.18.7
|
||||||
|
'@codemirror/language': 6.11.3
|
||||||
|
'@codemirror/lint': 6.8.5
|
||||||
|
'@codemirror/state': 6.5.2
|
||||||
|
'@codemirror/view': 6.38.3
|
||||||
|
'@lezer/common': 1.2.3
|
||||||
|
'@lezer/javascript': 1.5.4
|
||||||
|
|
||||||
|
'@codemirror/lang-json@6.0.2':
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/language': 6.11.3
|
||||||
|
'@lezer/json': 1.0.3
|
||||||
|
|
||||||
|
'@codemirror/lang-markdown@6.3.4':
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/autocomplete': 6.18.7
|
||||||
|
'@codemirror/lang-html': 6.4.10
|
||||||
|
'@codemirror/language': 6.11.3
|
||||||
|
'@codemirror/state': 6.5.2
|
||||||
|
'@codemirror/view': 6.38.3
|
||||||
|
'@lezer/common': 1.2.3
|
||||||
|
'@lezer/markdown': 1.4.3
|
||||||
|
|
||||||
|
'@codemirror/language@6.11.3':
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/state': 6.5.2
|
||||||
|
'@codemirror/view': 6.38.3
|
||||||
|
'@lezer/common': 1.2.3
|
||||||
|
'@lezer/highlight': 1.2.1
|
||||||
|
'@lezer/lr': 1.4.2
|
||||||
|
style-mod: 4.1.2
|
||||||
|
|
||||||
|
'@codemirror/lint@6.8.5':
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/state': 6.5.2
|
||||||
|
'@codemirror/view': 6.38.3
|
||||||
|
crelt: 1.0.6
|
||||||
|
|
||||||
|
'@codemirror/search@6.5.11':
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/state': 6.5.2
|
||||||
|
'@codemirror/view': 6.38.3
|
||||||
|
crelt: 1.0.6
|
||||||
|
|
||||||
|
'@codemirror/state@6.5.2':
|
||||||
|
dependencies:
|
||||||
|
'@marijn/find-cluster-break': 1.0.2
|
||||||
|
|
||||||
|
'@codemirror/view@6.38.3':
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/state': 6.5.2
|
||||||
|
crelt: 1.0.6
|
||||||
|
style-mod: 4.1.2
|
||||||
|
w3c-keyname: 2.2.8
|
||||||
|
|
||||||
'@esbuild/aix-ppc64@0.25.10':
|
'@esbuild/aix-ppc64@0.25.10':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@@ -1609,6 +1811,47 @@ snapshots:
|
|||||||
'@jridgewell/resolve-uri': 3.1.2
|
'@jridgewell/resolve-uri': 3.1.2
|
||||||
'@jridgewell/sourcemap-codec': 1.5.5
|
'@jridgewell/sourcemap-codec': 1.5.5
|
||||||
|
|
||||||
|
'@lezer/common@1.2.3': {}
|
||||||
|
|
||||||
|
'@lezer/css@1.3.0':
|
||||||
|
dependencies:
|
||||||
|
'@lezer/common': 1.2.3
|
||||||
|
'@lezer/highlight': 1.2.1
|
||||||
|
'@lezer/lr': 1.4.2
|
||||||
|
|
||||||
|
'@lezer/highlight@1.2.1':
|
||||||
|
dependencies:
|
||||||
|
'@lezer/common': 1.2.3
|
||||||
|
|
||||||
|
'@lezer/html@1.3.11':
|
||||||
|
dependencies:
|
||||||
|
'@lezer/common': 1.2.3
|
||||||
|
'@lezer/highlight': 1.2.1
|
||||||
|
'@lezer/lr': 1.4.2
|
||||||
|
|
||||||
|
'@lezer/javascript@1.5.4':
|
||||||
|
dependencies:
|
||||||
|
'@lezer/common': 1.2.3
|
||||||
|
'@lezer/highlight': 1.2.1
|
||||||
|
'@lezer/lr': 1.4.2
|
||||||
|
|
||||||
|
'@lezer/json@1.0.3':
|
||||||
|
dependencies:
|
||||||
|
'@lezer/common': 1.2.3
|
||||||
|
'@lezer/highlight': 1.2.1
|
||||||
|
'@lezer/lr': 1.4.2
|
||||||
|
|
||||||
|
'@lezer/lr@1.4.2':
|
||||||
|
dependencies:
|
||||||
|
'@lezer/common': 1.2.3
|
||||||
|
|
||||||
|
'@lezer/markdown@1.4.3':
|
||||||
|
dependencies:
|
||||||
|
'@lezer/common': 1.2.3
|
||||||
|
'@lezer/highlight': 1.2.1
|
||||||
|
|
||||||
|
'@marijn/find-cluster-break@1.0.2': {}
|
||||||
|
|
||||||
'@nodelib/fs.scandir@2.1.5':
|
'@nodelib/fs.scandir@2.1.5':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@nodelib/fs.stat': 2.0.5
|
'@nodelib/fs.stat': 2.0.5
|
||||||
@@ -1966,6 +2209,16 @@ snapshots:
|
|||||||
|
|
||||||
clsx@2.1.1: {}
|
clsx@2.1.1: {}
|
||||||
|
|
||||||
|
codemirror@6.0.2:
|
||||||
|
dependencies:
|
||||||
|
'@codemirror/autocomplete': 6.18.7
|
||||||
|
'@codemirror/commands': 6.8.1
|
||||||
|
'@codemirror/language': 6.11.3
|
||||||
|
'@codemirror/lint': 6.8.5
|
||||||
|
'@codemirror/search': 6.5.11
|
||||||
|
'@codemirror/state': 6.5.2
|
||||||
|
'@codemirror/view': 6.38.3
|
||||||
|
|
||||||
color-convert@2.0.1:
|
color-convert@2.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
color-name: 1.1.4
|
color-name: 1.1.4
|
||||||
@@ -1976,6 +2229,8 @@ snapshots:
|
|||||||
|
|
||||||
cookie@0.6.0: {}
|
cookie@0.6.0: {}
|
||||||
|
|
||||||
|
crelt@1.0.6: {}
|
||||||
|
|
||||||
cross-spawn@7.0.6:
|
cross-spawn@7.0.6:
|
||||||
dependencies:
|
dependencies:
|
||||||
path-key: 3.1.1
|
path-key: 3.1.1
|
||||||
@@ -2297,6 +2552,10 @@ snapshots:
|
|||||||
|
|
||||||
lodash.merge@4.6.2: {}
|
lodash.merge@4.6.2: {}
|
||||||
|
|
||||||
|
lucide-svelte@0.544.0(svelte@5.39.6):
|
||||||
|
dependencies:
|
||||||
|
svelte: 5.39.6
|
||||||
|
|
||||||
magic-string@0.30.19:
|
magic-string@0.30.19:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@jridgewell/sourcemap-codec': 1.5.5
|
'@jridgewell/sourcemap-codec': 1.5.5
|
||||||
@@ -2470,6 +2729,8 @@ snapshots:
|
|||||||
|
|
||||||
strip-json-comments@3.1.1: {}
|
strip-json-comments@3.1.1: {}
|
||||||
|
|
||||||
|
style-mod@4.1.2: {}
|
||||||
|
|
||||||
supports-color@7.2.0:
|
supports-color@7.2.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
has-flag: 4.0.0
|
has-flag: 4.0.0
|
||||||
@@ -2486,6 +2747,11 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- picomatch
|
- picomatch
|
||||||
|
|
||||||
|
svelte-codemirror-editor@2.0.0(codemirror@6.0.2)(svelte@5.39.6):
|
||||||
|
dependencies:
|
||||||
|
codemirror: 6.0.2
|
||||||
|
svelte: 5.39.6
|
||||||
|
|
||||||
svelte-eslint-parser@1.3.3(svelte@5.39.6):
|
svelte-eslint-parser@1.3.3(svelte@5.39.6):
|
||||||
dependencies:
|
dependencies:
|
||||||
eslint-scope: 8.4.0
|
eslint-scope: 8.4.0
|
||||||
@@ -2584,6 +2850,8 @@ snapshots:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
vite: 7.1.7(@types/node@22.18.6)(jiti@2.6.0)(lightningcss@1.30.1)
|
vite: 7.1.7(@types/node@22.18.6)(jiti@2.6.0)(lightningcss@1.30.1)
|
||||||
|
|
||||||
|
w3c-keyname@2.2.8: {}
|
||||||
|
|
||||||
which@2.0.2:
|
which@2.0.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
isexe: 2.0.0
|
isexe: 2.0.0
|
||||||
|
@@ -1,5 +1,11 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import CheckCircleIcon from '$lib/icons/CheckCircleIcon.svelte';
|
||||||
|
import MinusCircleIcon from '$lib/icons/MinusCircleIcon.svelte';
|
||||||
|
import XCircleIcon from '$lib/icons/XCircleIcon.svelte';
|
||||||
|
import type { Extension } from '@codemirror/state';
|
||||||
|
import { basicSetup } from 'codemirror';
|
||||||
import type { Snippet } from 'svelte';
|
import type { Snippet } from 'svelte';
|
||||||
|
import CodeMirror from 'svelte-codemirror-editor';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
title: string;
|
title: string;
|
||||||
@@ -9,9 +15,10 @@
|
|||||||
children?: Snippet;
|
children?: Snippet;
|
||||||
headerActions?: Snippet;
|
headerActions?: Snippet;
|
||||||
subtitle?: string;
|
subtitle?: string;
|
||||||
status?: 'success' | 'error';
|
status?: 'success' | 'error' | 'indeterminate';
|
||||||
timing?: number;
|
timing?: number;
|
||||||
pillText?: string;
|
pillText?: string;
|
||||||
|
langExtension?: Extension;
|
||||||
}
|
}
|
||||||
|
|
||||||
let {
|
let {
|
||||||
@@ -24,48 +31,27 @@
|
|||||||
subtitle,
|
subtitle,
|
||||||
status,
|
status,
|
||||||
timing,
|
timing,
|
||||||
pillText
|
pillText,
|
||||||
|
langExtension
|
||||||
}: Props = $props();
|
}: Props = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex h-full flex-col border-r border-gray-200 last:border-r-0">
|
<div class="flex flex-1 flex-col overflow-hidden border-r border-gray-200 last:border-r-0">
|
||||||
<div class="flex items-center border-b border-gray-200 bg-gray-50/50 px-4 py-3">
|
<div class="flex items-center border-b border-gray-200 bg-gray-50/50 px-4 py-3">
|
||||||
{#if status === 'success'}
|
{#if status === 'success'}
|
||||||
<svg
|
<CheckCircleIcon class="mr-2 h-5 w-5 text-green-500" />
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
stroke-width="1.5"
|
|
||||||
stroke="currentColor"
|
|
||||||
class="mr-2 h-5 w-5 text-green-500"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
{:else if status === 'error'}
|
{:else if status === 'error'}
|
||||||
<svg
|
<XCircleIcon class="mr-2 h-5 w-5 text-red-500" />
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
{:else if status === 'indeterminate'}
|
||||||
fill="none"
|
<MinusCircleIcon class="mr-2 h-5 w-5 text-gray-400" />
|
||||||
viewBox="0 0 24 24"
|
|
||||||
stroke-width="1.5"
|
|
||||||
stroke="currentColor"
|
|
||||||
class="mr-2 h-5 w-5 text-red-500"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
d="M9.75 9.75l4.5 4.5m0-4.5l-4.5 4.5M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
{/if}
|
{/if}
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<h2 class="text-sm font-semibold tracking-wide text-gray-900 uppercase flex items-center">
|
<h2 class="flex items-center text-sm font-semibold uppercase tracking-wide text-gray-900">
|
||||||
{title}
|
{title}
|
||||||
{#if pillText}
|
{#if pillText}
|
||||||
<span class="ml-2 inline-flex items-center rounded-full bg-blue-100 px-2 py-0.5 text-xs font-medium text-blue-800">
|
<span
|
||||||
|
class="ml-2 inline-flex items-center rounded-full bg-blue-100 px-2 py-0.5 text-xs font-medium text-blue-800"
|
||||||
|
>
|
||||||
{pillText}
|
{pillText}
|
||||||
</span>
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
@@ -83,22 +69,17 @@
|
|||||||
<div class="ml-4 text-xs text-gray-500">{timing}ms</div>
|
<div class="ml-4 text-xs text-gray-500">{timing}ms</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<div class="group relative flex-1">
|
<div class="group relative flex flex-1 flex-col overflow-hidden">
|
||||||
{#if readonly}
|
<div class="flex-1 overflow-auto">
|
||||||
<div class="absolute inset-0 overflow-auto p-4">
|
<CodeMirror
|
||||||
<pre
|
|
||||||
class="font-mono text-sm leading-relaxed whitespace-pre-wrap text-gray-800">{value}</pre>
|
|
||||||
</div>
|
|
||||||
{:else}
|
|
||||||
<textarea
|
|
||||||
bind:value
|
bind:value
|
||||||
|
extensions={[basicSetup, langExtension].filter(Boolean) as Extension[]}
|
||||||
{placeholder}
|
{placeholder}
|
||||||
class="absolute inset-0 h-full w-full resize-none border-0 bg-transparent p-4 font-mono text-sm leading-relaxed text-gray-800 transition-colors outline-none placeholder:text-gray-400 focus:bg-gray-50/30"
|
{readonly}
|
||||||
spellcheck="false"
|
class="text-sm"
|
||||||
></textarea>
|
/>
|
||||||
{/if}
|
</div>
|
||||||
|
|
||||||
<!-- Subtle hover effect -->
|
|
||||||
<div
|
<div
|
||||||
class="pointer-events-none absolute inset-0 bg-black opacity-0 transition-opacity duration-200 group-hover:opacity-5"
|
class="pointer-events-none absolute inset-0 bg-black opacity-0 transition-opacity duration-200 group-hover:opacity-5"
|
||||||
></div>
|
></div>
|
||||||
|
@@ -1,26 +1,21 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
// import { CodeIcon, ArrowRightIcon } from "lucide-svelte";
|
import Logo from '$lib/icons/Logo.svelte';
|
||||||
|
import { GithubIcon } from 'lucide-svelte';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<header class="sticky top-0 z-10 border-b border-gray-200 bg-white/80 backdrop-blur-sm">
|
<header class="sticky top-0 z-10 border-b border-gray-200 bg-white/80 backdrop-blur-sm">
|
||||||
<div class="container mx-auto px-6 py-4">
|
<div class="container px-6 py-4">
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex w-full items-center justify-between">
|
||||||
<div class="flex items-center gap-3">
|
<div class="flex items-center gap-3">
|
||||||
<div class="rounded-lg bg-black p-2">
|
<Logo />
|
||||||
<!-- <CodeIcon class="h-5 w-5 text-white" /> -->
|
|
||||||
</div>
|
|
||||||
<div>
|
<div>
|
||||||
<h1 class="text-2xl font-bold text-black">Marka</h1>
|
<h1 class="text-2xl font-bold text-black">Marka</h1>
|
||||||
<p class="text-sm text-gray-600">Bidirectional Markdown ↔ JSON Parser</p>
|
<p class="text-sm text-gray-600">Bidirectional Markdown ↔ JSON Parser</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="hidden items-center gap-2 text-sm text-gray-500 md:flex">
|
<a href="https://github.com/jim-fx/marka" target="_blank" rel="noopener noreferrer">
|
||||||
<span>Template</span>
|
<GithubIcon class="h-6 w-6 text-gray-600 transition-colors duration-200 hover:text-black" />
|
||||||
<!-- <ArrowRightIcon class="w-4 h-4" /> -->
|
</a>
|
||||||
<span>Markdown</span>
|
|
||||||
<!-- <ArrowRightIcon class="w-4 h-4" /> -->
|
|
||||||
<span>JSON</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
@@ -1,18 +1,20 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { ParseResult } from '../wasm';
|
import { json } from '@codemirror/lang-json';
|
||||||
|
import { markdown } from '@codemirror/lang-markdown';
|
||||||
import {
|
import {
|
||||||
getTemplate,
|
getTemplate,
|
||||||
listTemplates,
|
listTemplates,
|
||||||
|
matchBlocks,
|
||||||
parseMarkdown,
|
parseMarkdown,
|
||||||
parseMarkdownWithTemplate,
|
parseMarkdownWithTemplate,
|
||||||
wasmReady
|
wasmReady,
|
||||||
|
type ParseResultSuccess
|
||||||
} from '../wasm';
|
} from '../wasm';
|
||||||
import EditorPanel from './EditorPanel.svelte';
|
import EditorPanel from './EditorPanel.svelte';
|
||||||
|
|
||||||
let templates = $state([] as string[]);
|
let templates = $state([] as string[]);
|
||||||
|
|
||||||
let templateValue = $state('');
|
const DEFAULT_MARKDOWN_VALUE = `---
|
||||||
let markdownValue = $state(`---
|
|
||||||
_type: Recipe
|
_type: Recipe
|
||||||
author.name: Max Richter
|
author.name: Max Richter
|
||||||
---
|
---
|
||||||
@@ -28,20 +30,45 @@ My favourite baguette recipe
|
|||||||
|
|
||||||
## Steps
|
## Steps
|
||||||
1. Mix Flour Water and Salt
|
1. Mix Flour Water and Salt
|
||||||
2. Bake the bread`);
|
2. Bake the bread`;
|
||||||
|
|
||||||
|
const DEFAULT_TEMPLATE_VALUE = '';
|
||||||
|
|
||||||
|
let templateValue = $state(
|
||||||
|
typeof window !== 'undefined'
|
||||||
|
? localStorage.getItem('templateValue') || DEFAULT_TEMPLATE_VALUE
|
||||||
|
: DEFAULT_TEMPLATE_VALUE
|
||||||
|
);
|
||||||
|
let markdownValue = $state(
|
||||||
|
typeof window !== 'undefined'
|
||||||
|
? localStorage.getItem('markdownValue') || DEFAULT_MARKDOWN_VALUE
|
||||||
|
: DEFAULT_MARKDOWN_VALUE
|
||||||
|
);
|
||||||
|
|
||||||
let jsonOutput = $state('');
|
let jsonOutput = $state('');
|
||||||
let detectedSchemaName = $derived.by(() => {
|
let detectedSchemaName = $derived.by(() => {
|
||||||
try {
|
try {
|
||||||
const parsed = JSON.parse(jsonOutput);
|
return JSON.parse(jsonOutput)['_schema'];
|
||||||
return parsed['_schema'];
|
} catch {
|
||||||
} catch (err) {
|
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let timings = $state<ParseResult['timings'] | null>(null);
|
let timings = $state<ParseResultSuccess['timings'] | null>(null);
|
||||||
let status = $state<'success' | 'error' | undefined>(undefined);
|
let templateStatus = $state<'success' | 'error' | 'indeterminate' | undefined>(undefined);
|
||||||
|
let dataStatus = $state<'success' | 'error' | 'indeterminate' | undefined>(undefined);
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
if (typeof window !== 'undefined') {
|
||||||
|
localStorage.setItem('templateValue', templateValue);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
if (typeof window !== 'undefined') {
|
||||||
|
localStorage.setItem('markdownValue', markdownValue);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
if ($wasmReady) {
|
if ($wasmReady) {
|
||||||
@@ -54,20 +81,40 @@ My favourite baguette recipe
|
|||||||
if (!$wasmReady) {
|
if (!$wasmReady) {
|
||||||
jsonOutput = 'Loading wasm...';
|
jsonOutput = 'Loading wasm...';
|
||||||
timings = null;
|
timings = null;
|
||||||
status = undefined;
|
templateStatus = undefined;
|
||||||
|
dataStatus = undefined;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const result = templateValue
|
const result = templateValue
|
||||||
? parseMarkdownWithTemplate(markdownValue, templateValue)
|
? parseMarkdownWithTemplate(markdownValue, templateValue)
|
||||||
: parseMarkdown(markdownValue);
|
: parseMarkdown(markdownValue);
|
||||||
|
|
||||||
|
if ('error' in result) {
|
||||||
|
jsonOutput = result.error;
|
||||||
|
if (result.error.startsWith('failed to compile template')) {
|
||||||
|
templateStatus = 'error';
|
||||||
|
dataStatus = 'indeterminate';
|
||||||
|
} else {
|
||||||
|
templateStatus = undefined;
|
||||||
|
dataStatus = 'error';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
jsonOutput = JSON.stringify(result.data, null, 2);
|
jsonOutput = JSON.stringify(result.data, null, 2);
|
||||||
timings = result.timings;
|
timings = result.timings;
|
||||||
status = 'success';
|
templateStatus = 'success';
|
||||||
|
dataStatus = 'success';
|
||||||
|
}
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
jsonOutput = (e as Error).message;
|
jsonOutput = (e as Error).message;
|
||||||
timings = null;
|
timings = null;
|
||||||
status = 'error';
|
if (jsonOutput.startsWith('failed to compile template')) {
|
||||||
|
templateStatus = 'error';
|
||||||
|
dataStatus = 'indeterminate';
|
||||||
|
} else {
|
||||||
|
templateStatus = undefined;
|
||||||
|
dataStatus = 'error';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -79,16 +126,22 @@ My favourite baguette recipe
|
|||||||
console.error(e);
|
console.error(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function resetMarkdown() {
|
||||||
|
markdownValue = DEFAULT_MARKDOWN_VALUE;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="grid min-h-0 flex-1 grid-cols-1 lg:grid-cols-3">
|
<div class="flex flex-1 overflow-hidden">
|
||||||
|
<div class="grid flex-1 grid-cols-1 overflow-hidden lg:grid-cols-3">
|
||||||
<EditorPanel
|
<EditorPanel
|
||||||
title="Template"
|
title="Template"
|
||||||
bind:value={templateValue}
|
bind:value={templateValue}
|
||||||
placeholder="Enter your Marka template here..."
|
placeholder="Enter your Marka template here..."
|
||||||
{status}
|
status={templateStatus}
|
||||||
timing={timings?.template_compilation}
|
timing={timings?.template_compilation}
|
||||||
subtitle="Define your mapping schema"
|
subtitle="Define your mapping schema"
|
||||||
|
langExtension={markdown()}
|
||||||
>
|
>
|
||||||
{#snippet headerActions()}
|
{#snippet headerActions()}
|
||||||
<select
|
<select
|
||||||
@@ -107,19 +160,30 @@ My favourite baguette recipe
|
|||||||
title="Markdown"
|
title="Markdown"
|
||||||
bind:value={markdownValue}
|
bind:value={markdownValue}
|
||||||
placeholder="Enter your markdown content here..."
|
placeholder="Enter your markdown content here..."
|
||||||
{status}
|
|
||||||
timing={timings?.markdown_parsing}
|
timing={timings?.markdown_parsing}
|
||||||
subtitle="Your source content"
|
subtitle="Your source content"
|
||||||
/>
|
langExtension={markdown()}
|
||||||
|
>
|
||||||
|
{#snippet headerActions()}
|
||||||
|
<button
|
||||||
|
onclick={resetMarkdown}
|
||||||
|
class="rounded border border-gray-300 bg-white px-2 py-1 text-xs text-gray-700 shadow-sm focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500"
|
||||||
|
>
|
||||||
|
Reset
|
||||||
|
</button>
|
||||||
|
{/snippet}
|
||||||
|
</EditorPanel>
|
||||||
|
|
||||||
<EditorPanel
|
<EditorPanel
|
||||||
title="Data"
|
title="Data"
|
||||||
value={jsonOutput}
|
value={jsonOutput}
|
||||||
readonly={true}
|
readonly={true}
|
||||||
{status}
|
status={dataStatus}
|
||||||
subtitle="Parsed JSON output"
|
subtitle="Parsed JSON output"
|
||||||
pillText={!templateValue && detectedSchemaName
|
pillText={!templateValue && detectedSchemaName
|
||||||
? `Detected Template: ${detectedSchemaName}`
|
? `Detected Template: ${detectedSchemaName}`
|
||||||
: undefined}
|
: undefined}
|
||||||
|
langExtension={json()}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
18
playground/src/lib/icons/CheckCircleIcon.svelte
Normal file
18
playground/src/lib/icons/CheckCircleIcon.svelte
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
let { class: className = '' } = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width="1.5"
|
||||||
|
stroke="currentColor"
|
||||||
|
class={className}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||||
|
/>
|
||||||
|
</svg>
|
10
playground/src/lib/icons/Logo.svelte
Normal file
10
playground/src/lib/icons/Logo.svelte
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<img src="/logo.svg" alt="logo" width="100%" />
|
||||||
|
|
||||||
|
<style>
|
||||||
|
img {
|
||||||
|
height: 64px;
|
||||||
|
width: 64px;
|
||||||
|
aspect-ratio: 1;
|
||||||
|
filter: drop-shadow(0px 0px 8px #0002);
|
||||||
|
}
|
||||||
|
</style>
|
14
playground/src/lib/icons/MinusCircleIcon.svelte
Normal file
14
playground/src/lib/icons/MinusCircleIcon.svelte
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
let { class: className = '' } = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width="1.5"
|
||||||
|
stroke="currentColor"
|
||||||
|
class={className}
|
||||||
|
>
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M18 12H6" />
|
||||||
|
</svg>
|
18
playground/src/lib/icons/XCircleIcon.svelte
Normal file
18
playground/src/lib/icons/XCircleIcon.svelte
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
let { class: className = '' } = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width="1.5"
|
||||||
|
stroke="currentColor"
|
||||||
|
class={className}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
d="M9.75 9.75l4.5 4.5m0-4.5l-4.5 4.5M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||||
|
/>
|
||||||
|
</svg>
|
@@ -1,13 +1,14 @@
|
|||||||
import { readable } from 'svelte/store';
|
import { readable } from "svelte/store";
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
Go: {
|
Go: {
|
||||||
new (): {
|
new(): {
|
||||||
run: (inst: WebAssembly.Instance) => Promise<void>;
|
run: (inst: WebAssembly.Instance) => Promise<void>;
|
||||||
importObject: WebAssembly.Imports;
|
importObject: WebAssembly.Imports;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
markaMatchBlocks: (input: string) => unknown;
|
||||||
markaParseFile: (input: string) => string;
|
markaParseFile: (input: string) => string;
|
||||||
markaParseFileWithTemplate: (markdown: string, template: string) => string;
|
markaParseFileWithTemplate: (markdown: string, template: string) => string;
|
||||||
markaListTemplates: () => string;
|
markaListTemplates: () => string;
|
||||||
@@ -16,59 +17,83 @@ declare global {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const wasmReady = readable(false, (set) => {
|
export const wasmReady = readable(false, (set) => {
|
||||||
if (typeof window === 'undefined') {
|
if (typeof window === "undefined") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const loadWasm = async () => {
|
const loadWasm = async () => {
|
||||||
const go = new window.Go();
|
const go = new window.Go();
|
||||||
try {
|
try {
|
||||||
const result = await WebAssembly.instantiateStreaming(fetch('/main.wasm'), go.importObject);
|
const result = await WebAssembly.instantiateStreaming(
|
||||||
|
fetch("/main.wasm"),
|
||||||
|
go.importObject,
|
||||||
|
);
|
||||||
go.run(result.instance);
|
go.run(result.instance);
|
||||||
set(true);
|
set(true);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error loading wasm module:', error);
|
console.error("Error loading wasm module:", error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (document.readyState === 'complete') {
|
if (document.readyState === "complete") {
|
||||||
loadWasm();
|
loadWasm();
|
||||||
} else {
|
} else {
|
||||||
window.addEventListener('load', loadWasm);
|
window.addEventListener("load", loadWasm);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export interface ParseResult {
|
export type ParseResultSuccess = {
|
||||||
data: unknown;
|
data: unknown;
|
||||||
timings: { [key: string]: number };
|
timings: { [key: string]: number };
|
||||||
}
|
};
|
||||||
|
|
||||||
|
export type ParseResultError = {
|
||||||
|
error: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ParseResult = ParseResultSuccess | ParseResultError;
|
||||||
|
|
||||||
export function parseMarkdown(markdown: string): ParseResult {
|
export function parseMarkdown(markdown: string): ParseResult {
|
||||||
if (typeof window.markaParseFile !== 'function') {
|
if (typeof window.markaParseFile !== "function") {
|
||||||
throw new Error('Wasm module not ready');
|
throw new Error("Wasm module not ready");
|
||||||
}
|
}
|
||||||
const result = window.markaParseFile(markdown);
|
const result = window.markaParseFile(markdown);
|
||||||
|
if (result.error) return result;
|
||||||
return JSON.parse(result);
|
return JSON.parse(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function parseMarkdownWithTemplate(markdown: string, template: string): ParseResult {
|
export function matchBlocks(markdown: string): ParseResult {
|
||||||
if (typeof window.markaParseFileWithTemplate !== 'function') {
|
if (typeof window.markaMatchBlocks !== "function") {
|
||||||
throw new Error('Wasm module not ready');
|
throw new Error("Wasm module not ready");
|
||||||
|
}
|
||||||
|
const result = window.markaMatchBlocks(markdown) as ParseResult;
|
||||||
|
if (result.error) return result;
|
||||||
|
return JSON.parse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function parseMarkdownWithTemplate(
|
||||||
|
markdown: string,
|
||||||
|
template: string,
|
||||||
|
): ParseResult {
|
||||||
|
if (typeof window.markaParseFileWithTemplate !== "function") {
|
||||||
|
throw new Error("Wasm module not ready");
|
||||||
}
|
}
|
||||||
const result = window.markaParseFileWithTemplate(markdown, template);
|
const result = window.markaParseFileWithTemplate(markdown, template);
|
||||||
|
if (result.error) return result;
|
||||||
return JSON.parse(result);
|
return JSON.parse(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function listTemplates(): string[] {
|
export function listTemplates(): string[] {
|
||||||
if (typeof window.markaListTemplates !== 'function') {
|
if (typeof window.markaListTemplates !== "function") {
|
||||||
throw new Error('Wasm module not ready');
|
throw new Error("Wasm module not ready");
|
||||||
}
|
}
|
||||||
const result = window.markaListTemplates();
|
const result = window.markaListTemplates();
|
||||||
return JSON.parse(result);
|
return JSON.parse(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getTemplate(name: string): string {
|
export function getTemplate(name: string): string {
|
||||||
if (typeof window.markaGetTemplate !== 'function') {
|
if (typeof window.markaGetTemplate !== "function") {
|
||||||
throw new Error('Wasm module not ready');
|
throw new Error("Wasm module not ready");
|
||||||
}
|
}
|
||||||
return window.markaGetTemplate(name);
|
return window.markaGetTemplate(name);
|
||||||
}
|
}
|
||||||
|
@@ -1,12 +1,13 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import '../app.css';
|
|
||||||
import favicon from '$lib/assets/favicon.svg';
|
import favicon from '$lib/assets/favicon.svg';
|
||||||
|
import '../app.css';
|
||||||
|
|
||||||
let { children } = $props();
|
let { children } = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
<link rel="icon" href={favicon} />
|
<link rel="icon" href={favicon} />
|
||||||
|
<title>Marka Playground</title>
|
||||||
<script src="/wasm_exec.js"></script>
|
<script src="/wasm_exec.js"></script>
|
||||||
</svelte:head>
|
</svelte:head>
|
||||||
|
|
||||||
|
@@ -5,7 +5,9 @@
|
|||||||
|
|
||||||
<div class="bg-background text-foreground flex min-h-screen flex-col">
|
<div class="bg-background text-foreground flex min-h-screen flex-col">
|
||||||
<Header />
|
<Header />
|
||||||
|
<div class="flex flex-1 overflow-hidden">
|
||||||
<Playground />
|
<Playground />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
15
playground/static/logo.svg
Normal file
15
playground/static/logo.svg
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<svg viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 50.0001C0 28.9476 19.9406 13.3665 43.3168 13.3665C52.852 13.3665 71.2871 17.0793 79.703 30.1981C79.703 30.1981 75.9901 41.3368 62.8713 43.5645C49.7525 45.7922 40.5941 30.4457 30.9406 30.4457C21.2871 30.4457 13.3663 38.7833 13.3663 51.9283C13.3663 59.1669 15.6639 65.9462 19.6134 71.7442C27.299 83.0278 41.2416 90.5942 56.6832 90.5942C80.0594 90.5942 100 71.3259 100 50.0001C100 77.6145 77.6144 100 50 100C22.3856 100 0 77.6145 0 50.0001Z" fill="url(#paint0_linear_12_27)"/>
|
||||||
|
<path d="M86.6337 51.9282C86.6337 60.2351 82.1782 70.1022 72.7723 74.505C63.3663 78.9077 57.4257 68.0693 43.3168 64.1089C29.2079 60.1485 19.6134 71.7441 19.6134 71.7441C27.299 83.0277 41.2416 90.5941 56.6832 90.5941C80.0594 90.5941 100 71.3257 100 50C100 22.3856 77.6144 0 50 0C22.3856 0 0 22.3856 0 50C0 28.9475 19.9406 13.3663 43.3168 13.3663C52.852 13.3663 61.9391 16.0842 69.3069 20.8153C80.0015 27.6822 87.0733 38.7896 86.6337 51.9802" fill="url(#paint1_linear_12_27)"/>
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="paint0_linear_12_27" x1="75.1033" y1="92.9796" x2="22.9842" y2="7.71589" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="white"/>
|
||||||
|
<stop offset="1" stop-color="#545454"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="paint1_linear_12_27" x1="23.9405" y1="7.17252" x2="75.3423" y2="92.0288" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="white"/>
|
||||||
|
<stop offset="1" stop-color="#545454"/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
|
After Width: | Height: | Size: 1.5 KiB |
@@ -1,7 +1,14 @@
|
|||||||
import tailwindcss from '@tailwindcss/vite';
|
import tailwindcss from "@tailwindcss/vite";
|
||||||
import { sveltekit } from '@sveltejs/kit/vite';
|
import { sveltekit } from "@sveltejs/kit/vite";
|
||||||
import { defineConfig } from 'vite';
|
import { defineConfig } from "vite";
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [tailwindcss(), sveltekit()]
|
plugins: [tailwindcss(), sveltekit()],
|
||||||
|
optimizeDeps: {
|
||||||
|
exclude: [
|
||||||
|
"svelte-codemirror-editor",
|
||||||
|
"codemirror",
|
||||||
|
"@codemirror/language-javascript", /* ... */
|
||||||
|
],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
@@ -14,13 +14,12 @@ func matchBlocks(_ js.Value, args []js.Value) any {
|
|||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
return js.ValueOf(map[string]any{"error": "missing markdown"})
|
return js.ValueOf(map[string]any{"error": "missing markdown"})
|
||||||
}
|
}
|
||||||
t, err := p.MatchBlocks(args[0].String())
|
t, err := p.MatchBlocks(args[0].String(), args[1].String())
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return js.ValueOf(map[string]any{"error": err.Error()})
|
return js.ValueOf(map[string]any{"error": err.Error()})
|
||||||
}
|
}
|
||||||
|
|
||||||
jsonString,_ := json.Marshal(t)
|
jsonString, _ := json.Marshal(t)
|
||||||
|
|
||||||
return js.ValueOf(string(jsonString)) // plain string
|
return js.ValueOf(string(jsonString)) // plain string
|
||||||
}
|
}
|
||||||
@@ -44,7 +43,7 @@ func parseFile(_ js.Value, args []js.Value) any {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return js.ValueOf(map[string]any{"error": err.Error()})
|
return js.ValueOf(map[string]any{"error": err.Error()})
|
||||||
}
|
}
|
||||||
b, err := json.Marshal(res) // return JSON string to avoid reflect-heavy bridging
|
b, err := json.Marshal(res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return js.ValueOf(map[string]any{"error": err.Error()})
|
return js.ValueOf(map[string]any{"error": err.Error()})
|
||||||
}
|
}
|
||||||
@@ -59,7 +58,7 @@ func parseFileWithTemplate(_ js.Value, args []js.Value) any {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return js.ValueOf(map[string]any{"error": err.Error()})
|
return js.ValueOf(map[string]any{"error": err.Error()})
|
||||||
}
|
}
|
||||||
b, err := json.Marshal(res) // return JSON string to avoid reflect-heavy bridging
|
b, err := json.Marshal(res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return js.ValueOf(map[string]any{"error": err.Error()})
|
return js.ValueOf(map[string]any{"error": err.Error()})
|
||||||
}
|
}
|
||||||
@@ -98,4 +97,3 @@ func main() {
|
|||||||
js.Global().Set("markaGetTemplate", js.FuncOf(getTemplate))
|
js.Global().Set("markaGetTemplate", js.FuncOf(getTemplate))
|
||||||
select {}
|
select {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user