Repository navigation
Expand file tree
/
Copy pathscript.js
More file actions
89 lines (76 loc) · 2.76 KB
/
Copy pathscript.js
File metadata and controls
89 lines (76 loc) · 2.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
const editor = document.getElementById('editor');
const preview = document.getElementById('preview');
const defaultText = `# Welcome to Markdown Preview!
## Features
- **Bold** text and *italic* text
- [Links](https://example.com)
- \`inline code\`
### Code Block
\`\`\`
function greet(name) {
return \`Hello, \${name}!\`;
}
\`\`\`
### Blockquote
> This is a blockquote example.
### Table
| Name | Role |
|------|------|
| Jane | Developer |
| John | Designer |
---
Type your own markdown on the left!`;
function escapeHtml(text) {
return text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
}
function parseMarkdown(md) {
let html = escapeHtml(md);
// Code blocks
html = html.replace(/```([\s\S]*?)```/g, (_, code) => `<pre><code>${code.trim()}</code></pre>`);
// Inline code
html = html.replace(/`([^`]+)`/g, '<code>$1</code>');
// Headers
html = html.replace(/^### (.+)$/gm, '<h3>$1</h3>');
html = html.replace(/^## (.+)$/gm, '<h2>$1</h2>');
html = html.replace(/^# (.+)$/gm, '<h1>$1</h1>');
// Bold and italic
html = html.replace(/\*\*([^*]+)\*\*/g, '<strong>$1</strong>');
html = html.replace(/\*([^*]+)\*/g, '<em>$1</em>');
// Links
html = html.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2" target="_blank" rel="noopener">$1</a>');
// Blockquotes
html = html.replace(/^> (.+)$/gm, '<blockquote>$1</blockquote>');
// Horizontal rule
html = html.replace(/^---$/gm, '<hr>');
// Unordered lists
html = html.replace(/(?:^- (.+)$\n?)+/gm, (match) => {
const items = match.trim().split('\n').map(l => `<li>${l.replace(/^- /, '')}</li>`).join('');
return `<ul>${items}</ul>`;
});
// Ordered lists
html = html.replace(/(?:^\d+\. (.+)$\n?)+/gm, (match) => {
const items = match.trim().split('\n').map(l => `<li>${l.replace(/^\d+\. /, '')}</li>`).join('');
return `<ol>${items}</ol>`;
});
// Tables
html = html.replace(/^\|(.+)\|\n\|[-| :]+\|\n((?:\|.*\|\n?)+)/gm, (_, header, rows) => {
const ths = header.split('|').filter(c => c.trim()).map(c => `<th>${c.trim()}</th>`).join('');
const trs = rows.trim().split('\n').map(row => {
const tds = row.split('|').filter(c => c.trim()).map(c => `<td>${c.trim()}</td>`).join('');
return `<tr>${tds}</tr>`;
}).join('');
return `<table><thead><tr>${ths}</tr></thead><tbody>${trs}</tbody></table>`;
});
// Paragraphs
html = html.split(/\n\n+/).map(block => {
block = block.trim();
if (!block) return '';
if (/^<(h[1-3]|ul|ol|pre|blockquote|hr|table)/.test(block)) return block;
return `<p>${block.replace(/\n/g, '<br>')}</p>`;
}).join('\n');
return html;
}
function updatePreview() { preview.innerHTML = parseMarkdown(editor.value); }
editor.addEventListener('input', updatePreview);
editor.value = defaultText;
updatePreview();