| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>MarkView - Markdown Preview</title> |
| <style> |
| |
| body { |
| font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; |
| margin: 0; |
| padding: 0; |
| background-color: #000; |
| color: #eaeaea; |
| } |
| |
| |
| .container { |
| max-width: 800px; |
| margin: 0 auto; |
| padding: 20px; |
| } |
| |
| |
| .header { |
| display: flex; |
| align-items: center; |
| margin-bottom: 20px; |
| } |
| |
| .logo { |
| font-size: 24px; |
| font-weight: bold; |
| color: #fff; |
| margin-right: 10px; |
| } |
| |
| .logo span { |
| color: #0070f3; |
| } |
| |
| |
| .command-dropdown { |
| margin-bottom: 20px; |
| } |
| |
| .command-dropdown select { |
| width: 100%; |
| padding: 10px; |
| border: 1px solid #333; |
| border-radius: 4px; |
| background-color: #000; |
| color: #eaeaea; |
| font-family: 'Inter', sans-serif; |
| font-size: 14px; |
| outline: none; |
| cursor: pointer; |
| } |
| |
| .command-dropdown select:focus { |
| border-color: #0070f3; |
| box-shadow: 0 0 0 2px rgba(0, 112, 243, 0.1); |
| } |
| |
| |
| .modal { |
| display: none; |
| position: fixed; |
| top: 0; |
| left: 0; |
| width: 100%; |
| height: 100%; |
| background-color: rgba(0, 0, 0, 0.8); |
| justify-content: center; |
| align-items: center; |
| z-index: 1000; |
| } |
| |
| .modal-content { |
| background-color: #111; |
| padding: 20px; |
| border-radius: 8px; |
| width: 400px; |
| max-width: 90%; |
| } |
| |
| .modal-content h2 { |
| margin-top: 0; |
| color: #fff; |
| } |
| |
| .modal-content label { |
| display: block; |
| margin-bottom: 10px; |
| color: #eaeaea; |
| } |
| |
| .modal-content input, |
| .modal-content select, |
| .modal-content textarea { |
| width: 100%; |
| padding: 10px; |
| border: 1px solid #333; |
| border-radius: 4px; |
| background-color: #000; |
| color: #eaeaea; |
| font-family: 'Inter', sans-serif; |
| font-size: 14px; |
| outline: none; |
| margin-bottom: 20px; |
| } |
| |
| .modal-content button { |
| padding: 10px 20px; |
| border: none; |
| border-radius: 4px; |
| background-color: #0070f3; |
| color: #fff; |
| font-family: 'Inter', sans-serif; |
| font-size: 14px; |
| cursor: pointer; |
| } |
| |
| .modal-content button:hover { |
| background-color: #005bb5; |
| } |
| |
| |
| .editor, .preview { |
| background-color: #111; |
| border-radius: 8px; |
| padding: 20px; |
| margin-bottom: 20px; |
| } |
| |
| textarea { |
| width: 100%; |
| height: 200px; |
| padding: 10px; |
| border: 1px solid #333; |
| border-radius: 4px; |
| font-family: 'JetBrains Mono', monospace; |
| font-size: 14px; |
| background-color: #000; |
| color: #eaeaea; |
| resize: vertical; |
| outline: none; |
| } |
| |
| textarea:focus { |
| border-color: #0070f3; |
| box-shadow: 0 0 0 2px rgba(0, 112, 243, 0.1); |
| } |
| |
| |
| .preview { |
| color: #eaeaea; |
| } |
| |
| .preview h1, .preview h2, .preview h3 { |
| margin-top: 0; |
| color: #fff; |
| } |
| |
| .preview code { |
| background-color: #333; |
| padding: 2px 4px; |
| border-radius: 4px; |
| font-family: 'JetBrains Mono', monospace; |
| color: #eaeaea; |
| } |
| |
| .preview pre { |
| background-color: #333; |
| padding: 10px; |
| border-radius: 4px; |
| overflow-x: auto; |
| } |
| |
| .preview blockquote { |
| border-left: 4px solid #0070f3; |
| padding-left: 10px; |
| color: #999; |
| margin: 0; |
| } |
| |
| .preview a { |
| color: #0070f3; |
| text-decoration: none; |
| } |
| |
| .preview a:hover { |
| text-decoration: underline; |
| } |
| |
| |
| .preview img { |
| margin: 5px; |
| } |
| </style> |
| |
| <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&display=swap" rel="stylesheet"> |
| |
| <link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet"> |
| </head> |
| <body> |
|
|
| <div class="container"> |
| |
| <div class="header"> |
| <div class="logo"> |
| Mark<span>View</span> |
| </div> |
| </div> |
|
|
| |
| <div class="command-dropdown"> |
| <select id="command-select"> |
| <option value="">Select a command...</option> |
| <option value="/badge">Create a Badge</option> |
| <option value="/links">Links and Media</option> |
| <option value="/blocks">Blocks</option> |
| <option value="/lists">Lists</option> |
| <option value="/headings">Headings</option> |
| <option value="/text">Text Formatting</option> |
| <option value="/tables">Tables</option> |
| <option value="/tasks">Task Lists</option> |
| <option value="/hr">Horizontal Rule</option> |
| <option value="/emoji">Emojis</option> |
| <option value="/mention">Mentions</option> |
| </select> |
| </div> |
|
|
| |
| <div class="editor"> |
| <textarea id="markdown-input" placeholder="Write your Markdown here..."># Welcome to MarkView |
| **Markdown Preview** with a *dark theme*. |
|
|
| - List item 1 |
| - List item 2 |
|
|
| `Inline code` |
|
|
| ```javascript |
| function hello() { |
| console.log('Hello, MarkView!'); |
| } |
| ```</textarea> |
| </div> |
|
|
| |
| <div class="preview" id="markdown-preview"> |
| |
| </div> |
| </div> |
|
|
| |
| |
| <div class="modal" id="badge-modal"> |
| <div class="modal-content"> |
| <h2>Create a Badge</h2> |
| <label for="badge-label">Label:</label> |
| <input type="text" id="badge-label" placeholder="e.g., version"> |
| <label for="badge-message">Message:</label> |
| <input type="text" id="badge-message" placeholder="e.g., v1.0"> |
| <label for="badge-color">Color:</label> |
| <input type="text" id="badge-color" placeholder="e.g., blue"> |
| <label for="badge-icon">Icon:</label> |
| <select id="badge-icon"> |
| <option value="">No Icon</option> |
| <option value="github">GitHub</option> |
| <option value="npm">npm</option> |
| <option value="docker">Docker</option> |
| <option value="python">Python</option> |
| <option value="javascript">JavaScript</option> |
| <option value="react">React</option> |
| <option value="vue">Vue</option> |
| <option value="angular">Angular</option> |
| <option value="apple">Apple</option> |
| <option value="windows">Windows</option> |
| <option value="v0">v0</option> |
| <option value="huggingface">huggingface</option> |
| <option value="replicate">replicate</option> |
| <option value="vercel">vercel</option> |
| <option value="fal">fal</option> |
| <option value="google">google</option> |
| <option value="claude">claude</option> |
| <option value="gemini">gemini</option> |
| <option value="qwen">qwen</option> |
| <option value="deepseek">deepseek</option> |
| </select> |
| |
| <label for="badge-url">Link URL (optional):</label> |
| <input type="text" id="badge-url" placeholder="e.g., https://example.com"> |
| <button id="insert-badge">Insert Badge</button> |
| </div> |
| </div> |
|
|
| |
| <div class="modal" id="links-modal"> |
| <div class="modal-content"> |
| <h2>Links and Media</h2> |
| <label for="link-text">Link Text:</label> |
| <input type="text" id="link-text" placeholder="e.g., Google"> |
| <label for="link-url">URL:</label> |
| <input type="text" id="link-url" placeholder="e.g., https://google.com"> |
| <label for="image-url">Image URL:</label> |
| <input type="text" id="image-url" placeholder="e.g., https://example.com/image.png"> |
| <button id="insert-link">Insert Link</button> |
| <button id="insert-image">Insert Image</button> |
| </div> |
| </div> |
|
|
| |
| <div class="modal" id="blocks-modal"> |
| <div class="modal-content"> |
| <h2>Blocks</h2> |
| <label for="block-type">Block Type:</label> |
| <select id="block-type"> |
| <option value="code">Code Block</option> |
| <option value="quote">Blockquote</option> |
| </select> |
| <label for="block-content">Content:</label> |
| <textarea id="block-content" placeholder="Enter your content..."></textarea> |
| <button id="insert-block">Insert Block</button> |
| </div> |
| </div> |
|
|
| |
| <div class="modal" id="lists-modal"> |
| <div class="modal-content"> |
| <h2>Lists</h2> |
| <label for="list-type">List Type:</label> |
| <select id="list-type"> |
| <option value="unordered">Unordered List</option> |
| <option value="ordered">Ordered List</option> |
| </select> |
| <label for="list-items">Items (one per line):</label> |
| <textarea id="list-items" placeholder="Enter items..."></textarea> |
| <button id="insert-list">Insert List</button> |
| </div> |
| </div> |
|
|
| |
| <div class="modal" id="headings-modal"> |
| <div class="modal-content"> |
| <h2>Headings</h2> |
| <label for="heading-level">Heading Level:</label> |
| <select id="heading-level"> |
| <option value="1">Heading 1 (#)</option> |
| <option value="2">Heading 2 (##)</option> |
| <option value="3">Heading 3 (###)</option> |
| <option value="4">Heading 4 (####)</option> |
| <option value="5">Heading 5 (#####)</option> |
| <option value="6">Heading 6 (######)</option> |
| </select> |
| <label for="heading-text">Text:</label> |
| <input type="text" id="heading-text" placeholder="e.g., My Heading"> |
| <button id="insert-heading">Insert Heading</button> |
| </div> |
| </div> |
|
|
| |
| <div class="modal" id="text-modal"> |
| <div class="modal-content"> |
| <h2>Text Formatting</h2> |
| <label for="text-content">Text:</label> |
| <input type="text" id="text-content" placeholder="e.g., Hello, World!"> |
| <label for="text-format">Format:</label> |
| <select id="text-format"> |
| <option value="bold">Bold (**)</option> |
| <option value="italic">Italic (*)</option> |
| <option value="strikethrough">Strikethrough (~~)</option> |
| <option value="inline-code">Inline Code (`)</option> |
| </select> |
| <button id="insert-text">Insert Text</button> |
| </div> |
| </div> |
|
|
| |
| <div class="modal" id="tables-modal"> |
| <div class="modal-content"> |
| <h2>Tables</h2> |
| <label for="table-headers">Headers (comma-separated):</label> |
| <input type="text" id="table-headers" placeholder="e.g., Name, Age, City"> |
| <label for="table-rows">Rows (one per line, comma-separated):</label> |
| <textarea id="table-rows" placeholder="e.g., John, 25, New York"></textarea> |
| <button id="insert-table">Insert Table</button> |
| </div> |
| </div> |
|
|
| |
| <div class="modal" id="tasks-modal"> |
| <div class="modal-content"> |
| <h2>Task Lists</h2> |
| <label for="task-items">Tasks (one per line):</label> |
| <textarea id="task-items" placeholder="e.g., [x] Task 1"></textarea> |
| <button id="insert-tasks">Insert Tasks</button> |
| </div> |
| </div> |
|
|
| |
| <div class="modal" id="hr-modal"> |
| <div class="modal-content"> |
| <h2>Horizontal Rule</h2> |
| <p>Insert a horizontal rule:</p> |
| <button id="insert-hr">Insert Horizontal Rule</button> |
| </div> |
| </div> |
|
|
| |
| <div class="modal" id="emoji-modal"> |
| <div class="modal-content"> |
| <h2>Emojis</h2> |
| <label for="emoji">Select an Emoji:</label> |
| <select id="emoji"> |
| <option value="😀">😀 Grinning Face</option> |
| <option value="🚀">🚀 Rocket</option> |
| <option value="❤️">❤️ Heart</option> |
| <option value="🌟">🌟 Star</option> |
| <option value="🔥">🔥 Fire</option> |
| </select> |
| <button id="insert-emoji">Insert Emoji</button> |
| </div> |
| </div> |
|
|
| |
| <div class="modal" id="mention-modal"> |
| <div class="modal-content"> |
| <h2>Mentions</h2> |
| <label for="mention-username">Username:</label> |
| <input type="text" id="mention-username" placeholder="e.g., octocat"> |
| <button id="insert-mention">Insert Mention</button> |
| </div> |
| </div> |
|
|
| |
| <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script> |
| <script> |
| const input = document.getElementById('markdown-input'); |
| const preview = document.getElementById('markdown-preview'); |
| const commandSelect = document.getElementById('command-select'); |
| |
| |
| function updatePreview() { |
| const markdownText = input.value; |
| preview.innerHTML = marked.parse(markdownText); |
| } |
| |
| |
| function showModal(modalId) { |
| const modal = document.getElementById(modalId); |
| modal.style.display = 'flex'; |
| } |
| |
| |
| function hideModal(modalId) { |
| const modal = document.getElementById(modalId); |
| modal.style.display = 'none'; |
| } |
| |
| |
| function insertBadge() { |
| const label = document.getElementById('badge-label').value || 'label'; |
| const message = document.getElementById('badge-message').value || 'message'; |
| const color = document.getElementById('badge-color').value || 'blue'; |
| const icon = document.getElementById('badge-icon').value; |
| const url = document.getElementById('badge-url').value; |
| |
| let badgeUrl = `https://img.shields.io/badge/${encodeURIComponent(label)}-${encodeURIComponent(message)}-${color}`; |
| if (icon) { |
| badgeUrl += `?logo=${icon}`; |
| } |
| |
| |
| let badgeMarkdown = ``; |
| |
| |
| if (url) { |
| badgeMarkdown = `[${badgeMarkdown}](${url})`; |
| } |
| |
| |
| input.value += `\n${badgeMarkdown}`; |
| updatePreview(); |
| hideModal('badge-modal'); |
| } |
| |
| |
| function insertLink() { |
| const text = document.getElementById('link-text').value || 'Link'; |
| const url = document.getElementById('link-url').value || '#'; |
| const linkMarkdown = `[${text}](${url})`; |
| |
| input.value += `\n${linkMarkdown}`; |
| updatePreview(); |
| hideModal('links-modal'); |
| } |
| |
| |
| function insertImage() { |
| const url = document.getElementById('image-url').value || '#'; |
| const imageMarkdown = ``; |
| |
| input.value += `\n${imageMarkdown}`; |
| updatePreview(); |
| hideModal('links-modal'); |
| } |
| |
| |
| function insertBlock() { |
| const type = document.getElementById('block-type').value; |
| const content = document.getElementById('block-content').value; |
| |
| let blockMarkdown = ''; |
| if (type === 'code') { |
| blockMarkdown = `\`\`\`\n${content}\n\`\`\``; |
| } else if (type === 'quote') { |
| blockMarkdown = `> ${content}`; |
| } |
| |
| input.value += `\n${blockMarkdown}`; |
| updatePreview(); |
| hideModal('blocks-modal'); |
| } |
| |
| |
| function insertList() { |
| const type = document.getElementById('list-type').value; |
| const items = document.getElementById('list-items').value.split('\n').filter(item => item.trim() !== ''); |
| |
| let listMarkdown = ''; |
| if (type === 'unordered') { |
| listMarkdown = items.map(item => `- ${item}`).join('\n'); |
| } else if (type === 'ordered') { |
| listMarkdown = items.map((item, index) => `${index + 1}. ${item}`).join('\n'); |
| } |
| |
| input.value += `\n${listMarkdown}`; |
| updatePreview(); |
| hideModal('lists-modal'); |
| } |
| |
| |
| function insertHeading() { |
| const level = document.getElementById('heading-level').value; |
| const text = document.getElementById('heading-text').value || 'Heading'; |
| |
| const headingMarkdown = `${'#'.repeat(level)} ${text}`; |
| |
| input.value += `\n${headingMarkdown}`; |
| updatePreview(); |
| hideModal('headings-modal'); |
| } |
| |
| |
| function insertText() { |
| const content = document.getElementById('text-content').value || 'Text'; |
| const format = document.getElementById('text-format').value; |
| |
| let formattedText = ''; |
| if (format === 'bold') { |
| formattedText = `**${content}**`; |
| } else if (format === 'italic') { |
| formattedText = `*${content}*`; |
| } else if (format === 'strikethrough') { |
| formattedText = `~~${content}~~`; |
| } else if (format === 'inline-code') { |
| formattedText = `\`${content}\``; |
| } |
| |
| input.value += `\n${formattedText}`; |
| updatePreview(); |
| hideModal('text-modal'); |
| } |
| |
| |
| function insertTable() { |
| const headers = document.getElementById('table-headers').value.split(',').map(header => header.trim()); |
| const rows = document.getElementById('table-rows').value.split('\n').map(row => row.split(',').map(cell => cell.trim())); |
| |
| let tableMarkdown = `| ${headers.join(' | ')} |\n`; |
| tableMarkdown += `| ${headers.map(() => '---').join(' | ')} |\n`; |
| rows.forEach(row => { |
| tableMarkdown += `| ${row.join(' | ')} |\n`; |
| }); |
| |
| input.value += `\n${tableMarkdown}`; |
| updatePreview(); |
| hideModal('tables-modal'); |
| } |
| |
| |
| function insertTasks() { |
| const tasks = document.getElementById('task-items').value.split('\n').filter(task => task.trim() !== ''); |
| |
| const tasksMarkdown = tasks.map(task => `- ${task}`).join('\n'); |
| |
| input.value += `\n${tasksMarkdown}`; |
| updatePreview(); |
| hideModal('tasks-modal'); |
| } |
| |
| |
| function insertHR() { |
| input.value += `\n---\n`; |
| updatePreview(); |
| hideModal('hr-modal'); |
| } |
| |
| |
| function insertEmoji() { |
| const emoji = document.getElementById('emoji').value; |
| input.value += `\n${emoji}`; |
| updatePreview(); |
| hideModal('emoji-modal'); |
| } |
| |
| |
| function insertMention() { |
| const username = document.getElementById('mention-username').value || 'username'; |
| input.value += `\n@${username}`; |
| updatePreview(); |
| hideModal('mention-modal'); |
| } |
| |
| |
| input.addEventListener('input', updatePreview); |
| commandSelect.addEventListener('change', (e) => { |
| const command = e.target.value; |
| if (command === '/badge') { |
| showModal('badge-modal'); |
| } else if (command === '/links') { |
| showModal('links-modal'); |
| } else if (command === '/blocks') { |
| showModal('blocks-modal'); |
| } else if (command === '/lists') { |
| showModal('lists-modal'); |
| } else if (command === '/headings') { |
| showModal('headings-modal'); |
| } else if (command === '/text') { |
| showModal('text-modal'); |
| } else if (command === '/tables') { |
| showModal('tables-modal'); |
| } else if (command === '/tasks') { |
| showModal('tasks-modal'); |
| } else if (command === '/hr') { |
| showModal('hr-modal'); |
| } else if (command === '/emoji') { |
| showModal('emoji-modal'); |
| } else if (command === '/mention') { |
| showModal('mention-modal'); |
| } |
| }); |
| |
| |
| document.getElementById('insert-badge').addEventListener('click', insertBadge); |
| document.getElementById('insert-link').addEventListener('click', insertLink); |
| document.getElementById('insert-image').addEventListener('click', insertImage); |
| document.getElementById('insert-block').addEventListener('click', insertBlock); |
| document.getElementById('insert-list').addEventListener('click', insertList); |
| document.getElementById('insert-heading').addEventListener('click', insertHeading); |
| document.getElementById('insert-text').addEventListener('click', insertText); |
| document.getElementById('insert-table').addEventListener('click', insertTable); |
| document.getElementById('insert-tasks').addEventListener('click', insertTasks); |
| document.getElementById('insert-hr').addEventListener('click', insertHR); |
| document.getElementById('insert-emoji').addEventListener('click', insertEmoji); |
| document.getElementById('insert-mention').addEventListener('click', insertMention); |
| |
| |
| window.addEventListener('click', (e) => { |
| if (e.target.classList.contains('modal')) { |
| e.target.style.display = 'none'; |
| } |
| }); |
| |
| |
| updatePreview(); |
| </script> |
|
|
| </body> |
| </html> |