fix post generate
This commit is contained in:
71
src/lib/markdown.ts
Normal file
71
src/lib/markdown.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
import { marked, Renderer } from 'marked'
|
||||
import hljs from 'highlight.js/lib/core'
|
||||
|
||||
// Import only common languages
|
||||
import javascript from 'highlight.js/lib/languages/javascript'
|
||||
import typescript from 'highlight.js/lib/languages/typescript'
|
||||
import bash from 'highlight.js/lib/languages/bash'
|
||||
import json from 'highlight.js/lib/languages/json'
|
||||
import yaml from 'highlight.js/lib/languages/yaml'
|
||||
import markdown from 'highlight.js/lib/languages/markdown'
|
||||
import css from 'highlight.js/lib/languages/css'
|
||||
import xml from 'highlight.js/lib/languages/xml'
|
||||
import python from 'highlight.js/lib/languages/python'
|
||||
import rust from 'highlight.js/lib/languages/rust'
|
||||
import go from 'highlight.js/lib/languages/go'
|
||||
|
||||
hljs.registerLanguage('javascript', javascript)
|
||||
hljs.registerLanguage('js', javascript)
|
||||
hljs.registerLanguage('typescript', typescript)
|
||||
hljs.registerLanguage('ts', typescript)
|
||||
hljs.registerLanguage('bash', bash)
|
||||
hljs.registerLanguage('sh', bash)
|
||||
hljs.registerLanguage('shell', bash)
|
||||
hljs.registerLanguage('json', json)
|
||||
hljs.registerLanguage('yaml', yaml)
|
||||
hljs.registerLanguage('yml', yaml)
|
||||
hljs.registerLanguage('markdown', markdown)
|
||||
hljs.registerLanguage('md', markdown)
|
||||
hljs.registerLanguage('css', css)
|
||||
hljs.registerLanguage('html', xml)
|
||||
hljs.registerLanguage('xml', xml)
|
||||
hljs.registerLanguage('python', python)
|
||||
hljs.registerLanguage('py', python)
|
||||
hljs.registerLanguage('rust', rust)
|
||||
hljs.registerLanguage('rs', rust)
|
||||
hljs.registerLanguage('go', go)
|
||||
|
||||
// Custom renderer with syntax highlighting
|
||||
const renderer = new Renderer()
|
||||
|
||||
renderer.code = function({ text, lang }: { text: string; lang?: string }) {
|
||||
let highlighted: string
|
||||
if (lang && hljs.getLanguage(lang)) {
|
||||
try {
|
||||
highlighted = hljs.highlight(text, { language: lang }).value
|
||||
} catch {
|
||||
highlighted = escapeHtml(text)
|
||||
}
|
||||
} else {
|
||||
// No auto-detect, just escape
|
||||
highlighted = escapeHtml(text)
|
||||
}
|
||||
return `<pre><code class="hljs">${highlighted}</code></pre>`
|
||||
}
|
||||
|
||||
function escapeHtml(str: string): string {
|
||||
return str
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
}
|
||||
|
||||
marked.setOptions({
|
||||
breaks: true,
|
||||
gfm: true,
|
||||
renderer,
|
||||
})
|
||||
|
||||
export function renderMarkdown(content: string): string {
|
||||
return marked.parse(content) as string
|
||||
}
|
||||
95
src/lib/router.ts
Normal file
95
src/lib/router.ts
Normal file
@@ -0,0 +1,95 @@
|
||||
export interface Route {
|
||||
type: 'blog' | 'post' | 'browser-services' | 'browser-collections' | 'browser-record' | 'new'
|
||||
handle?: string
|
||||
collection?: string
|
||||
rkey?: string
|
||||
service?: string
|
||||
}
|
||||
|
||||
export function parseRoute(pathname: string): Route {
|
||||
const parts = pathname.split('/').filter(Boolean)
|
||||
|
||||
// / - Blog top
|
||||
if (parts.length === 0) {
|
||||
return { type: 'blog' }
|
||||
}
|
||||
|
||||
// /new - New post form
|
||||
if (parts[0] === 'new') {
|
||||
return { type: 'new' }
|
||||
}
|
||||
|
||||
// /app - SPA entry point (same as blog)
|
||||
if (parts[0] === 'app') {
|
||||
return { type: 'blog' }
|
||||
}
|
||||
|
||||
// /post - New post form (no rkey)
|
||||
// /post/${rkey} - Post detail
|
||||
if (parts[0] === 'post') {
|
||||
if (parts[1]) {
|
||||
return { type: 'post', rkey: parts[1] }
|
||||
}
|
||||
return { type: 'new' }
|
||||
}
|
||||
|
||||
// /at/${handle} - Browser services
|
||||
// /at/${handle}/${service-or-collection} - Browser collections or records
|
||||
// /at/${handle}/${collection}/${rkey} - Browser record detail
|
||||
if (parts[0] === 'at' && parts[1]) {
|
||||
const handle = parts[1]
|
||||
|
||||
if (!parts[2]) {
|
||||
// /at/${handle}
|
||||
return { type: 'browser-services', handle }
|
||||
}
|
||||
|
||||
if (!parts[3]) {
|
||||
// /at/${handle}/${service-or-collection}
|
||||
// If it looks like a domain (2 parts), treat as service
|
||||
// Otherwise treat as collection NSID (3+ parts)
|
||||
const segment = parts[2]
|
||||
if (segment.split('.').length <= 2) {
|
||||
// Likely a service domain like "bsky.app"
|
||||
return { type: 'browser-collections', handle, service: segment }
|
||||
} else {
|
||||
// Likely a collection NSID like "app.bsky.feed.post"
|
||||
// Show record list for this collection
|
||||
return { type: 'browser-record', handle, collection: segment }
|
||||
}
|
||||
}
|
||||
|
||||
// /at/${handle}/${collection}/${rkey}
|
||||
return { type: 'browser-record', handle, collection: parts[2], rkey: parts[3] }
|
||||
}
|
||||
|
||||
// Fallback to blog
|
||||
return { type: 'blog' }
|
||||
}
|
||||
|
||||
export function buildPath(route: Route): string {
|
||||
switch (route.type) {
|
||||
case 'blog':
|
||||
return '/'
|
||||
case 'new':
|
||||
return '/new'
|
||||
case 'post':
|
||||
return `/post/${route.rkey}`
|
||||
case 'browser-services':
|
||||
return `/at/${route.handle}`
|
||||
case 'browser-collections':
|
||||
return `/at/${route.handle}/${route.service}`
|
||||
case 'browser-record':
|
||||
if (route.rkey) {
|
||||
return `/at/${route.handle}/${route.collection}/${route.rkey}`
|
||||
}
|
||||
return `/at/${route.handle}/${route.collection}`
|
||||
default:
|
||||
return '/'
|
||||
}
|
||||
}
|
||||
|
||||
export function navigate(path: string): void {
|
||||
window.history.pushState({}, '', path)
|
||||
window.dispatchEvent(new PopStateEvent('popstate'))
|
||||
}
|
||||
Reference in New Issue
Block a user