Compare commits

...
10 Commits
Author SHA1 Message Date
scambier 819d9cb77d Deps update and added a copy button 2025-08-27 18:22:15 +02:00
scambier 5b685e251b "Fixed" trailing slash bug
The goto() function does not respect no trailing slashes, so the app breaks
2025-08-27 18:21:52 +02:00
scambier 0d61c7662a Fixed raw text and lisp 2024-06-22 10:13:19 +02:00
scambier ed2fd9f45e Fixed deprecations and removed taggerscript 2024-04-12 16:29:29 +02:00
scambier 7f8091120c Added a comment in the about text 2024-02-22 21:26:21 +01:00
scambier 05adc4574a Fixed custom font loading 2024-02-22 21:26:09 +01:00
scambier 0d14e6a6d8 Load codemirror stuff only in editor 2024-02-22 21:19:46 +01:00
scambier b4ae405876 Updated about 2024-02-22 21:03:10 +01:00
scambier 1c174a3b1c Fixed hljs langs mapping 2024-02-22 11:55:41 +01:00
scambier c3e2bbe4c0 Fixed deprecation 2024-02-22 11:37:48 +01:00
10 changed files with 3035 additions and 2228 deletions
+31 -31
View File
@@ -12,44 +12,44 @@
"format": "prettier --plugin-search-dir . --write ." "format": "prettier --plugin-search-dir . --write ."
}, },
"devDependencies": { "devDependencies": {
"@sveltejs/adapter-auto": "^2.0.0", "@sveltejs/adapter-auto": "^2.1.1",
"@sveltejs/kit": "^1.20.4", "@sveltejs/kit": "^1.30.4",
"@tailwindcss/typography": "^0.5.10", "@tailwindcss/typography": "^0.5.16",
"@types/codemirror": "^5.60.12", "@types/codemirror": "^5.60.16",
"@types/lodash-es": "^4.17.10", "@types/lodash-es": "^4.17.12",
"@typescript-eslint/eslint-plugin": "^6.0.0", "@typescript-eslint/eslint-plugin": "^6.21.0",
"@typescript-eslint/parser": "^6.0.0", "@typescript-eslint/parser": "^6.21.0",
"autoprefixer": "^10.4.16", "autoprefixer": "^10.4.21",
"eslint": "^8.28.0", "eslint": "^8.57.1",
"eslint-config-prettier": "^8.5.0", "eslint-config-prettier": "^8.10.2",
"eslint-plugin-svelte": "^2.30.0", "eslint-plugin-svelte": "^2.46.1",
"postcss": "^8.4.31", "postcss": "^8.5.6",
"prettier": "^2.8.0", "prettier": "^2.8.8",
"prettier-plugin-svelte": "^2.10.1", "prettier-plugin-svelte": "^2.10.1",
"svelte": "^4.0.5", "svelte": "^4.2.20",
"svelte-check": "^3.4.3", "svelte-check": "^3.8.6",
"tailwindcss": "^3.3.5", "tailwindcss": "^3.4.17",
"tslib": "^2.4.1", "tslib": "^2.8.1",
"typescript": "^5.0.0", "typescript": "^5.9.2",
"vite": "^4.4.2" "vite": "^4.5.14"
}, },
"type": "module", "type": "module",
"dependencies": { "dependencies": {
"@iconify/svelte": "^3.1.4", "@iconify/svelte": "^3.1.6",
"@svelte-put/clickoutside": "^3.0.0", "@svelte-put/clickoutside": "^3.0.2",
"@sveltejs/adapter-static": "^2.0.3", "@sveltejs/adapter-static": "^2.0.3",
"brotli-compress": "^1.3.3", "brotli-compress": "^1.3.3",
"highlight.js": "^11.9.0", "highlight.js": "^11.11.1",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"rehype-highlight": "^7.0.0", "rehype-highlight": "^7.0.2",
"rehype-stringify": "^10.0.0", "rehype-stringify": "^10.0.1",
"remark-gfm": "^4.0.0", "remark-gfm": "^4.0.1",
"remark-parse": "^11.0.0", "remark-parse": "^11.0.0",
"remark-rehype": "^11.0.0", "remark-rehype": "^11.1.2",
"sass": "^1.69.5", "sass": "^1.91.0",
"slim-select": "^2.6.0", "slim-select": "^2.12.1",
"svelte-select": "^5.7.0", "svelte-select": "^5.8.3",
"tw-elements": "^1.0.0", "tw-elements": "^1.1.0",
"unified": "^11.0.4" "unified": "^11.0.5"
} }
} }
+2893 -2124
View File
File diff suppressed because it is too large Load Diff
+1 -7
View File
@@ -4,13 +4,7 @@
<title>Paste</title> <title>Paste</title>
<meta charset="utf-8" /> <meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.svg" /> <link rel="icon" href="%sveltekit.assets%/favicon.svg" />
<link rel="preload" as="font" type="text/css" href="%sveltekit.assets%/hack-subset.css" /> <link rel="stylesheet" href="%sveltekit.assets%/hack-subset.css" />
<link
rel="stylesheet"
type="text/css"
href="https://cdn.jsdelivr.net/combine/
npm/codemirror@5.65.16/lib/codemirror.min.css,
npm/codemirror@5.65.16/theme/nord.min.css" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<meta property="og:title" content="Paste - No-database paste service" /> <meta property="og:title" content="Paste - No-database paste service" />
<meta property="og:url" content="https://paste.scambier.xyz" /> <meta property="og:url" content="https://paste.scambier.xyz" />
+22 -4
View File
@@ -1,22 +1,40 @@
<script lang="ts"> <script lang="ts">
import Icon from '@iconify/svelte'
import { fade } from 'svelte/transition'
export let isMarkdown: boolean export let isMarkdown: boolean
export let isPlainText: boolean export let isPlainText: boolean
export let decompressed: string export let decompressed: string
export let htmlContent: string export let htmlContent: string
let cssClass = '' let cssClass = ''
export { cssClass as class } export { cssClass as class }
let copied = false
function copyCode() {
navigator.clipboard.writeText(decompressed)
copied = true
setTimeout(() => (copied = false), 500)
}
</script> </script>
<div class={cssClass}> <div class={cssClass + ' relative'}>
{#if isMarkdown} {#if isMarkdown}
<div class="h-full p-2"> <div class="h-full p-2">
{@html htmlContent} {@html htmlContent}
</div> </div>
{:else if isPlainText} {:else if isPlainText}
<div class="whitespace-pre-line h-full"> <pre class="h-full">{decompressed}</pre>
{decompressed}
</div>
{:else} {:else}
<button
class="z-40 right-4 top-[5.25rem] absolute inline"
on:click={copyCode}
title="Copy code">
<Icon class="text-xl" icon="fluent:copy-24-regular" />
</button>
{#if copied}
<span class="absolute right-4 top-24" out:fade={{ duration: 500 }}>Copied!</span>
{/if}
<!-- code block -->
<pre class="h-full"><code>{@html htmlContent}</code></pre> <pre class="h-full"><code>{@html htmlContent}</code></pre>
{/if} {/if}
</div> </div>
+11 -6
View File
@@ -6,6 +6,7 @@
import ComboBox from './ComboBox.svelte' import ComboBox from './ComboBox.svelte'
import Icon from '@iconify/svelte' import Icon from '@iconify/svelte'
import { goto } from '$app/navigation' import { goto } from '$app/navigation'
import hljs from 'highlight.js'
type Language = { type Language = {
text: string text: string
@@ -31,7 +32,7 @@
}) })
selectedLang.subscribe((lang) => { selectedLang.subscribe((lang) => {
textWrap = lang === 'plt' || lang === 'md' textWrap = lang === 'plaintext' || lang === 'markdown'
}) })
$: { $: {
@@ -43,12 +44,16 @@
$: { $: {
if (editor) { if (editor) {
languages = CodeMirror.modeInfo languages = (CodeMirror.modeInfo as unknown[])
.map((e: any) => ({ .map((e: any) => {
text: e.name, let name = e.name
value: shorten(e.name), if (name === 'Common Lisp') name = 'Lisp'
return {
text: name,
value: shorten(name),
data: { mime: e.mime, mode: e.mode }, data: { mime: e.mime, mode: e.mode },
})) }
})
.filter((l: any) => l.value !== 'gflm') // Remove github flavored markdown, redundant with markdown .filter((l: any) => l.value !== 'gflm') // Remove github flavored markdown, redundant with markdown
selectedLanguage = selectedLanguage =
+14 -4
View File
@@ -1,3 +1,5 @@
import hljs from 'highlight.js'
export const slugify = (str: string) => export const slugify = (str: string) =>
str str
.trim() .trim()
@@ -10,22 +12,22 @@ export const slugify = (str: string) =>
export const shorten = (name: string) => { export const shorten = (name: string) => {
let n = slugify(name).replace('script', '-s').replace('python', 'py').replace('markdown', 'md') let n = slugify(name).replace('script', '-s').replace('python', 'py').replace('markdown', 'md')
const nov = (s: string) => s[0] + s.substr(1).replace(/[aeiouy-]/g, '') const nov = (s: string) => s[0] + s.substring(1).replace(/[aeiouy-]/g, '')
if (n.replace(/-/g, '').length <= 4) { if (n.replace(/-/g, '').length <= 4) {
return n.replace(/-/g, '') return n.replace(/-/g, '')
} }
if (n.split('-').length >= 2) { if (n.split('-').length >= 2) {
return n return n
.split('-') .split('-')
.map((x) => nov(x.substr(0, 2))) .map((x) => nov(x.substring(0, 2)))
.join('') .join('')
.substr(0, 4) .substring(0, 4)
} }
n = nov(n) n = nov(n)
if (n.length <= 4) { if (n.length <= 4) {
return n return n
} }
return n.substr(0, 2) + n.substr(n.length - 2, 2) return n.substring(0, 2) + n.substring(n.length - 2, 2)
} }
export function getLangFromUrl() { export function getLangFromUrl() {
@@ -37,3 +39,11 @@ export const byId = (id: string) => document.getElementById(id)
export function isInIframe(): boolean { export function isInIframe(): boolean {
return window !== window.parent return window !== window.parent
} }
export function getHljsLangFromShort(short: string): string {
const langs = hljs
.listLanguages()
.filter((l) => l !== 'taggerscript') // seriously? This overrides typescript.
.map((lang) => ({ lang, short: shorten(lang) }))
return langs.find((l) => l.short === short)?.lang ?? 'plaintext'
}
+1
View File
@@ -1,2 +1,3 @@
export const prerender = true export const prerender = true
export const ssr = false export const ssr = false
export const trailingSlash = 'always'
+8 -4
View File
@@ -8,7 +8,7 @@
import rehypeStringify from 'rehype-stringify' import rehypeStringify from 'rehype-stringify'
import hljs from 'highlight.js' import hljs from 'highlight.js'
import 'highlight.js/styles/nord.min.css' import 'highlight.js/styles/nord.min.css'
import { getLangFromUrl, isInIframe } from '$lib/utils' import { getHljsLangFromShort, getLangFromUrl, isInIframe } from '$lib/utils'
import TopBar from '../components/TopBar.svelte' import TopBar from '../components/TopBar.svelte'
import Icon from '@iconify/svelte' import Icon from '@iconify/svelte'
import CodeView from '../components/CodeView.svelte' import CodeView from '../components/CodeView.svelte'
@@ -26,12 +26,16 @@
let lang = getLangFromUrl() let lang = getLangFromUrl()
// Remove github flavored markdown, redundant with markdown // Remove github flavored markdown, redundant with markdown
lang = lang === 'gflm' ? 'md' : lang lang = lang === 'gflm' ? 'md' : lang
// Get the correct language name for hljs
lang = getHljsLangFromShort(lang)
// decompress the data // decompress the data
const { decompress } = await import('$lib/brotli') const { decompress } = await import('$lib/brotli')
decompressed = await decompress(hash) decompressed = await decompress(hash)
// Markdown // Markdown
if (lang === 'md') { if (lang === 'markdown') {
const html = await unified() const html = await unified()
.use(remarkParse) .use(remarkParse)
.use(remarkGfm) .use(remarkGfm)
@@ -43,12 +47,12 @@
htmlContent = html.toString() htmlContent = html.toString()
} }
// Plain text // Plain text
else if (lang === 'plt' || !lang) { else if (lang === 'plaintext' || !lang) {
isPlainText = true isPlainText = true
} }
// Code // Code
else { else {
htmlContent = hljs.highlight(lang, decompressed).value htmlContent = hljs.highlight(decompressed, { language: lang }).value
} }
} else { } else {
// Redirect to editor page // Redirect to editor page
+1 -1
View File
@@ -2,6 +2,6 @@
import { goto } from '$app/navigation' import { goto } from '$app/navigation'
goto( goto(
'/?l=md#G6QLACwPuFPLgyKzJ/S8nBADxa9HABs9NUhg5Lt6/ARlnACvViO43Pfd7/Ux6n6C/jFY5gfdlkHyTtNxhVMTaqnQwqc3vN71Lw1i7Guvm1i6R6IZj7FIldl9ez+ldGTprl4OusV1YePAIzzC6W8kEiGxMZgtP0uwgDNeXAYvx9ue9PsvR8GGTPBnORfQ6Vm/nvPPuzkLiBF3gpmtTL4xUQKcvL2nOutBVybQ69ps4X6/D9AcNySMMJIM1dekVmWXI7Y1MxBFzti1I4o0TpyX8sYOSYVlhpuffAReh7WIbOSHz63ygBBw6YrU8p8ta6IZgBryTI2My/gOEr9fJA7/66PakXtkJ6xaec4JeGKgp/1hUnixWPLvKki4dvy08SPpJWVat6uhONaKV5UBxx45WJGahp6pwje7mRT+jL3TDZ40ofBg8+51pR5EAE5djuV6KZkTjMPculABx4yxxTTYa8+/7umnEMvlWNz3SEhJ8GjKNxp/jE34W60/R5xz5G6O11aG4CfyTItQbVejJOEQDAzIoH8zgzJ3ZRz1dxrIh+hVKF/csLImtT2Wx/p52r4lZl9cQH7p+whWeWLC1Qq0cq3+RRV8jOwDqc6I8hDO55l50PjKTaQIwdzrYovt7cudjR4zqchTODncNgpdi0xt6+jDf7vitwaEcJ3Uz1SrcWrvtunHoNX3XAe2cn15moyJVtmofK83Go7ZTTGZ9HM584Is77LBlZKUQiBLBlAZ5XQqbWgjjHnJBpCDWDIwUNdWVlVWBNKJB21EEjbORwEASHFVwC4SOm5j82E90XBFfKv7WJ3IsbOTGb7KSpJWxa9Z+opYeoda8eO0sOOGQ1+WHAGDBuIYpw86auJi4t+dpmwcMkeNlUUkjzE+cl78pqHUD6psu5JVVz53J2HzLx1OoXAEIHlofSGiwaydOgeHGA5I/OVJbqbv5CbH12/g+Gs1PuBq8v4CAEkPniT4tybOtyDI74YE0ZW1s5mfPwQSup8sPaaKd4/uW1b0xGyQcGYUhfci90VEgVK1xEqkLnzspWWA1a1l4XTeXtFGA2QYk7MSftmNMG6ZGjRKM5N/TNuO9kuQuqC0T+HzzjO/gHjPPsoessA4YvDxbs9ZsCz53vMWZVMTCdDoMIxC08ciEpIlHjJQ6bfPLCczAQ==' '/?l=md#GysKICwPbMcLBD17GY3E2G8DSmoFwEZPDRIY+a4eP0EZJ8Cr1Qgu96X91MeoV4Jrh2wLgNl2heQ+bCycmlBrhRYqvgnDYuNne1vO0j0STTxGIh3Mm7dzpRVJqa7urrpgiUfYC+o8dGHVNxKJkFgsmxK110tv7u4wBMKS9h1GxeLkihii/V9yCyIib9H/WZByLMTCbTooCZTn58WCN8VUWVlKEiXp8UMkCs3aireAUbeJzahqKj8YsACPq+roiSpZbKr/1uuOZWV3SJ7ACiLF83VcZWYk5teMZLP3Eb+qIAHyJklcCeJLMN7dW1qhZ0xX0LTZQr7QBcRi7WgxlLRIicVpJJ5ls4Dee5JlIMgaNP4Z7X1VCpiwzVAUeQ4P5TnJvalhWe/GEcE5m5/W5SPQp8zhcU3DgKOvTD1RViuRxWakddH4v4R3AUdIi5Ov+vH1K2Lwvz4ECp5bCagC46ldwAI7T/vXdMUSBBJvq6K79b1OaYmIyzTrpdXPjZ3VTmVow4xrUj7W1V/nVvzybSGFP/PdoZ6HE5J3UprPpfEMKSNyZwmWz0RkRfE37lkPKrQfAdaARtsj8Oa+fohb+VSm+7oWQPHNSWp9w7OyewEqz0uIMYbMBLjmcxelEBzqVQ0RxZ4EN4IuPoCeXc2IUeROMJA2xSqlZVz4g+LRoXX99bwZfEm4+LQrIBO0OgFPpoFYN7YulcYvcT6HoWXfpW6B0n2OsC1c+hrubOXPuNlcmjUdlYeVx4xfrPxd6TTLAaUzXSPbbr3zoy0uDQkxVgJrUB8OZqWbebFZe1uie3up259eURT0mOyNWEzlvEIuhF9hoEVQByqiHCaG6TGESuutg+pRUEBbHss2OG/+VVUqk7OFc0H6E+tfCQrkF4/O4ZJ9QGmvh1+skE7Msns6TAmP+JmoBR52K4uAN+YkRtvC9xq9EoYUAiQ+n64Cs6fJ67UNAaU89DBZFxh2yEz9uye5uMAh26qErePAJNigv/9+f22Pe7DBbGvZRIFZV2i/Use/IBuRqkZs3CSw3FywVBvNUU5Sf/moD6N3/cmGuy/A/FonF4csOS5ctRQ70WerDvqKdq080+cCI4BpNvK4aX7f8mV7HI+afPdQIV+ifUwBLA=='
) )
</script> </script>
+7 -1
View File
@@ -80,6 +80,12 @@ npm/codemirror@5.65.16/addon/mode/simple.min.js,
npm/codemirror@5.65.16/addon/scroll/simplescrollbars.js, npm/codemirror@5.65.16/addon/scroll/simplescrollbars.js,
npm/codemirror@5.65.16/mode/meta.min.js" npm/codemirror@5.65.16/mode/meta.min.js"
on:load={initCodeEditor}></script> on:load={initCodeEditor}></script>
<link
rel="stylesheet"
type="text/css"
href="https://cdn.jsdelivr.net/combine/
npm/codemirror@5.65.16/lib/codemirror.min.css,
npm/codemirror@5.65.16/theme/nord.min.css" />
</svelte:head> </svelte:head>
<div class="flex flex-col font-mono h-screen bg-gray-700"> <div class="flex flex-col font-mono h-screen bg-gray-700">
@@ -103,7 +109,7 @@ npm/codemirror@5.65.16/mode/meta.min.js"
<style> <style>
:global(div.CodeMirror) { :global(div.CodeMirror) {
height: 100%; height: 100%;
font-size: 15px; font-size: 14px;
font-family: 'Hack', monospace; font-family: 'Hack', monospace;
} }
#footer { #footer {