Skip to content

shiki代码高亮 #23

@leno23

Description

@leno23
<title>Shiki 代码高亮演示</title> <style> body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); min-height: 100vh; padding: 40px 20px; margin: 0; }
    .container {
        max-width: 1200px;
        margin: 0 auto;
    }
    
    h1 {
        color: white;
        text-align: center;
        font-size: 2.5em;
        margin-bottom: 10px;
    }
    
    .subtitle {
        color: rgba(255,255,255,0.9);
        text-align: center;
        margin-bottom: 30px;
    }
    
    .theme-selector {
        background: white;
        border-radius: 12px;
        padding: 20px;
        margin-bottom: 20px;
        box-shadow: 0 10px 40px rgba(0,0,0,0.2);
    }
    
    .theme-buttons {
        display: flex;
        flex-wrap: wrap;
        gap: 10px;
    }
    
    .theme-btn {
        padding: 8px 16px;
        border: 2px solid #667eea;
        background: white;
        color: #667eea;
        border-radius: 6px;
        cursor: pointer;
        font-weight: 600;
        transition: all 0.3s ease;
    }
    
    .theme-btn:hover {
        background: #667eea;
        color: white;
    }
    
    .theme-btn.active {
        background: #667eea;
        color: white;
    }
    
    .demo-card {
        background: white;
        border-radius: 12px;
        margin-bottom: 20px;
        overflow: hidden;
        box-shadow: 0 10px 40px rgba(0,0,0,0.2);
    }
    
    .demo-header {
        background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        color: white;
        padding: 15px 20px;
        font-size: 1.2em;
        font-weight: 600;
    }
    
    .code-container {
        padding: 20px;
    }
    
    .shiki {
        border-radius: 8px;
        padding: 16px !important;
        overflow-x: auto;
    }
    
    .loading {
        text-align: center;
        color: white;
        padding: 40px;
        font-size: 1.3em;
    }
</style>

🎨 Shiki 代码高亮演示

基于 VSCode 的精美代码语法高亮

    <div class="loading" id="loading">正在加载 Shiki...</div>
    
    <div id="content" style="display: none;">
        <div class="theme-selector">
            <strong>选择主题:</strong>
            <div class="theme-buttons">
                <button class="theme-btn active" data-theme="github-dark">GitHub Dark</button>
                <button class="theme-btn" data-theme="github-light">GitHub Light</button>
                <button class="theme-btn" data-theme="monokai">Monokai</button>
                <button class="theme-btn" data-theme="nord">Nord</button>
                <button class="theme-btn" data-theme="one-dark-pro">One Dark Pro</button>
                <button class="theme-btn" data-theme="dracula">Dracula</button>
            </div>
        </div>
        
        <div class="demo-card">
            <div class="demo-header">📜 JavaScript</div>
            <div class="code-container" id="js-code"></div>
        </div>
        
        <div class="demo-card">
            <div class="demo-header">🐍 Python</div>
            <div class="code-container" id="python-code"></div>
        </div>
        
        <div class="demo-card">
            <div class="demo-header">🎨 CSS</div>
            <div class="code-container" id="css-code"></div>
        </div>
    </div>
</div>

<script type="module">
    import { getHighlighter } from 'https://esm.sh/shiki@1.18.0';
    
    const CODE_SAMPLES = {
        javascript: [
            'const greeting = (name) => {',
            '  return `Hello, ${name}!`;',
            '};',
            '',
            'class User {',
            '  constructor(name, email) {',
            '    this.name = name;',
            '    this.email = email;',
            '  }',
            '',
            '  async fetchData() {',
            '    const response = await fetch("/api/user");',
            '    return await response.json();',
            '  }',
            '}',
            '',
            'const user = new User("Alice", "alice@example.com");',
        ].join('\n'),
        
        python: [
            'from typing import List',
            'import asyncio',
            '',
            'class DataProcessor:',
            '    def __init__(self, data: List[str]):',
            '        self.data = data',
            '    ',
            '    async def process(self):',
            '        """Process data asynchronously"""',
            '        results = []',
            '        for item in self.data:',
            '            result = await self._process_item(item)',
            '            results.append(result)',
            '        return results',
            '',
            'processor = DataProcessor(["a", "b", "c"])',
        ].join('\n'),
        
        css: [
            ':root {',
            '  --primary: #667eea;',
            '  --secondary: #764ba2;',
            '}',
            '',
            '.container {',
            '  display: flex;',
            '  justify-content: center;',
            '  align-items: center;',
            '  background: linear-gradient(135deg, var(--primary), var(--secondary));',
            '}',
            '',
            '.card {',
            '  border-radius: 12px;',
            '  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);',
            '  transition: transform 0.3s ease;',
            '}',
            '',
            '.card:hover {',
            '  transform: translateY(-5px);',
            '}',
        ].join('\n')
    };
    
    let highlighter = null;
    let currentTheme = 'github-dark';
    
    async function init() {
        try {
            highlighter = await getHighlighter({
                themes: ['github-dark', 'github-light', 'monokai', 'nord', 'one-dark-pro', 'dracula'],
                langs: ['javascript', 'python', 'css']
            });
            
            renderAll();
            
            document.getElementById('loading').style.display = 'none';
            document.getElementById('content').style.display = 'block';
            
            setupThemeButtons();
            
            console.log('✅ Shiki loaded successfully!');
        } catch (error) {
            document.getElementById('loading').textContent = 'Error: ' + error.message;
        }
    }
    
    function renderAll() {
        document.getElementById('js-code').innerHTML = 
            highlighter.codeToHtml(CODE_SAMPLES.javascript, { 
                lang: 'javascript', 
                theme: currentTheme 
            });
        
        document.getElementById('python-code').innerHTML = 
            highlighter.codeToHtml(CODE_SAMPLES.python, { 
                lang: 'python', 
                theme: currentTheme 
            });
        
        document.getElementById('css-code').innerHTML = 
            highlighter.codeToHtml(CODE_SAMPLES.css, { 
                lang: 'css', 
                theme: currentTheme 
            });
    }
    
    function setupThemeButtons() {
        document.querySelectorAll('.theme-btn').forEach(btn => {
            btn.addEventListener('click', () => {
                document.querySelectorAll('.theme-btn').forEach(b => 
                    b.classList.remove('active')
                );
                btn.classList.add('active');
                currentTheme = btn.dataset.theme;
                renderAll();
            });
        });
    }
    
    init();
</script>

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions