mdparser/playground.js
Jörg Lohrer 9fe34cc743 docs: add interactive playground and quick start guide
- playground.js: Interaktives Script zum Ausprobieren aller Features
  - Forgejo API Client Demo
  - Post-Listing (53 Posts)
  - Vollständiges Parsing-Beispiel
  - AMB-Metadaten-Analyse mit Validierung
  - Content-Statistiken (Überschriften, Links, Bilder)
  - AST-Struktur-Visualisierung
  - JSON-Export-Vorschau
  - Farbige Console-Ausgabe

- QUICKSTART.md: Schnelleinstieg für Entwickler
  - Playground-Anleitung
  - Code-Beispiele für alle Use Cases
  - Alle verfügbaren Posts aufgelistet
  - Erweiterte Optionen
  - Links zur weiteren Dokumentation

Ready to use! 🚀
2025-10-01 15:53:36 +02:00

246 lines
7.9 KiB
JavaScript
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Interaktives Playground zum Ausprobieren des Parsers
*
* Verwendung:
* node playground.js
*/
import { createForgejoClient } from './src/forgejo-client.js'
import { parseMarkdownString, extractHeadings, extractLinks, extractImages } from './src/parser.js'
import { validateAMBMetadata } from './src/extractors/amb-extractor.js'
// Farben für Console-Output
const colors = {
reset: '\x1b[0m',
bright: '\x1b[1m',
green: '\x1b[32m',
yellow: '\x1b[33m',
blue: '\x1b[34m',
magenta: '\x1b[35m',
cyan: '\x1b[36m'
}
function print(text, color = 'reset') {
console.log(`${colors[color]}${text}${colors.reset}`)
}
function section(title) {
console.log('\n' + '='.repeat(70))
print(title, 'bright')
console.log('='.repeat(70) + '\n')
}
async function playground() {
section('🎮 MDParser Playground')
print('Dieses Script zeigt die verschiedenen Funktionen des Parsers.', 'cyan')
print('Du kannst den Code in playground.js anpassen, um zu experimentieren.\n', 'cyan')
// 1. Forgejo Client Setup
section('1⃣ Forgejo API Client')
const client = createForgejoClient()
print(`✓ Client erstellt`, 'green')
print(` Repository: ${client.owner}/${client.repo}`, 'blue')
print(` Branch: ${client.branch}`, 'blue')
// Repository-Info
const repo = await client.getRepository()
print(` Beschreibung: ${repo.description}`, 'blue')
// 2. Posts auflisten
section('2⃣ Posts auflisten')
const posts = await client.listPosts()
print(`${posts.length} Posts gefunden`, 'green')
// Die ersten 10 Posts anzeigen
print('\nErste 10 Posts:', 'yellow')
posts.slice(0, 10).forEach((post, i) => {
console.log(` ${i + 1}. ${post.name}`)
})
// 3. Einen Post parsen
section('3⃣ Post parsen')
// Du kannst hier einen anderen Post wählen!
const selectedPost = '2025-04-20-OER-und-Symbole'
print(`📄 Parse: ${selectedPost}`, 'yellow')
const markdown = await client.getPostContent(selectedPost)
print(`✓ Markdown geladen: ${markdown.length} Zeichen`, 'green')
const result = await parseMarkdownString(markdown)
print(`✓ Erfolgreich geparst`, 'green')
// 4. Metadaten analysieren
section('4⃣ AMB-Metadaten')
if (result.metadata) {
const meta = result.metadata
console.log('\n📋 Basis-Informationen:')
console.log(` Titel: ${meta.name || 'N/A'}`)
console.log(` Typ: ${meta.type}`)
console.log(` Lizenz: ${meta.license || 'N/A'}`)
console.log(` Datum: ${meta.datePublished || 'N/A'}`)
console.log(` ID: ${meta.id || 'N/A'}`)
console.log(` Sprache: ${meta.inLanguage ? meta.inLanguage.join(', ') : 'N/A'}`)
if (meta.creator && meta.creator.length > 0) {
console.log('\n👥 Autoren:')
meta.creator.forEach((creator, i) => {
const name = creator.name || `${creator.givenName} ${creator.familyName}`
console.log(` ${i + 1}. ${name}`)
if (creator.id) console.log(` └─ ID: ${creator.id}`)
if (creator.affiliation) {
console.log(` └─ Affiliation: ${creator.affiliation.name}`)
}
})
}
if (meta.about && meta.about.length > 0) {
console.log('\n🏷 Themen:')
meta.about.forEach(topic => console.log(` - ${topic}`))
}
if (meta.learningResourceType && meta.learningResourceType.length > 0) {
console.log('\n📚 Lernressourcen-Typen:')
meta.learningResourceType.forEach(type => console.log(` - ${type}`))
}
// Validierung
const validation = validateAMBMetadata(meta)
console.log('\n✓ Validierung:')
console.log(` Status: ${validation.valid ? '✅ Gültig' : '⚠️ Unvollständig'}`)
if (validation.errors.length > 0) {
console.log(` Fehler: ${validation.errors.length}`)
validation.errors.forEach(err => console.log(` - ${err}`))
}
if (validation.warnings.length > 0) {
console.log(` Warnings: ${validation.warnings.length}`)
validation.warnings.slice(0, 3).forEach(warn => console.log(` - ${warn}`))
if (validation.warnings.length > 3) {
console.log(` ... und ${validation.warnings.length - 3} weitere`)
}
}
if (meta._warnings && meta._warnings.length > 0) {
console.log('\n⚠ Parser-Warnings:')
meta._warnings.forEach(w => console.log(` - ${w}`))
}
} else {
print('⚠️ Keine Metadaten gefunden', 'yellow')
}
// 5. Content-Analyse
section('5⃣ Content-Analyse')
console.log('📝 Content-Statistik:')
console.log(` Länge: ${result.content.length} Zeichen`)
console.log(` Zeilen: ${result.content.split('\n').length}`)
console.log(` Wörter (ca.): ${result.content.split(/\s+/).length}`)
// Überschriften
const headings = extractHeadings(result.ast)
console.log(`\n📑 Überschriften: ${headings.length}`)
headings.forEach(h => {
const indent = ' ' + ' '.repeat(h.level - 2)
console.log(`${indent}H${h.level}: ${h.text}`)
})
// Links
const links = extractLinks(result.ast)
if (links.length > 0) {
console.log(`\n🔗 Links: ${links.length}`)
links.slice(0, 5).forEach(link => {
console.log(` - ${link.text || 'Kein Text'}`)
console.log(`${link.url}`)
})
if (links.length > 5) {
console.log(` ... und ${links.length - 5} weitere`)
}
}
// Bilder
const images = extractImages(result.ast)
if (images.length > 0) {
console.log(`\n🖼️ Bilder: ${images.length}`)
images.forEach(img => {
console.log(` - ${img.alt || 'Kein Alt-Text'}`)
console.log(`${img.url}`)
})
}
// 6. AST-Struktur
section('6⃣ AST-Struktur (Auszug)')
console.log('🌲 Root-Node:')
console.log(` Type: ${result.ast.type}`)
console.log(` Children: ${result.ast.children?.length || 0}`)
if (result.ast.children && result.ast.children.length > 0) {
console.log('\n Erste 5 Child-Nodes:')
result.ast.children.slice(0, 5).forEach((child, i) => {
console.log(` ${i + 1}. ${child.type}`)
if (child.depth) console.log(` └─ depth: ${child.depth}`)
if (child.value) {
const preview = child.value.substring(0, 50)
console.log(` └─ value: "${preview}${child.value.length > 50 ? '...' : ''}"`)
}
})
if (result.ast.children.length > 5) {
console.log(` ... und ${result.ast.children.length - 5} weitere`)
}
}
// 7. Rohdaten-Export
section('7⃣ JSON-Export')
const exportData = {
metadata: result.metadata,
content: result.content.substring(0, 500) + '...',
stats: {
chars: result.content.length,
lines: result.content.split('\n').length,
headings: headings.length,
links: links.length,
images: images.length
}
}
console.log('📦 Export-Vorschau (erste 500 Zeichen Content):')
console.log(JSON.stringify(exportData, null, 2))
// 8. Tipps
section('💡 Tipps zum Experimentieren')
print('Du kannst dieses Script anpassen:', 'cyan')
console.log('\n1. Anderen Post wählen:')
console.log(' const selectedPost = "2024-08-05-hello-world"')
console.log('\n2. Mehrere Posts analysieren:')
console.log(' for (const post of posts.slice(0, 5)) { ... }')
console.log('\n3. Parser-Optionen anpassen:')
console.log(' const result = await parseMarkdownString(markdown, {')
console.log(' extractYaml: true,')
console.log(' parseGfm: true,')
console.log(' extractAMB: true')
console.log(' })')
console.log('\n4. Weitere Funktionen ausprobieren:')
console.log(' import { extractYAML, hasYAML } from "./src/index.js"')
section('✅ Fertig!')
print('Viel Spaß beim Experimentieren! 🎉', 'green')
print('Für mehr Infos: README.md oder docs/ARCHITECTURE.md\n', 'cyan')
}
// Fehlerbehandlung
playground().catch(error => {
console.error('\n❌ Fehler:', error.message)
console.error(error.stack)
process.exit(1)
})