-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmarkdown-parser.php
More file actions
122 lines (96 loc) · 4.48 KB
/
markdown-parser.php
File metadata and controls
122 lines (96 loc) · 4.48 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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
<?php
/**
* Simple Markdown to HTML Converter
* Handles basic markdown syntax for documentation pages
*/
function parseMarkdown($markdown) {
// Escape HTML first
$markdown = htmlspecialchars($markdown, ENT_NOQUOTES);
// Headers
$markdown = preg_replace('/^##### (.*?)$/m', '<h5>$1</h5>', $markdown);
$markdown = preg_replace('/^#### (.*?)$/m', '<h4>$1</h4>', $markdown);
$markdown = preg_replace('/^### (.*?)$/m', '<h3>$1</h3>', $markdown);
$markdown = preg_replace('/^## (.*?)$/m', '<h2>$1</h2>', $markdown);
$markdown = preg_replace('/^# (.*?)$/m', '<h1>$1</h1>', $markdown);
// Code blocks (```language ... ```)
$markdown = preg_replace_callback('/```(.*?)\n(.*?)```/s', function($matches) {
$language = $matches[1];
$code = $matches[2];
return '<pre><code class="language-' . htmlspecialchars($language) . '">' . $code . '</code></pre>';
}, $markdown);
// Inline code (`code`)
$markdown = preg_replace('/`([^`]+)`/', '<code>$1</code>', $markdown);
// Bold (**text** or __text__)
$markdown = preg_replace('/\*\*(.+?)\*\*/', '<strong>$1</strong>', $markdown);
$markdown = preg_replace('/__(.+?)__/', '<strong>$1</strong>', $markdown);
// Italic (*text* or _text_)
$markdown = preg_replace('/\*(.+?)\*/', '<em>$1</em>', $markdown);
$markdown = preg_replace('/_(.+?)_/', '<em>$1</em>', $markdown);
// Links [text](url)
$markdown = preg_replace('/\[([^\]]+)\]\(([^)]+)\)/', '<a href="$2" target="_blank">$1</a>', $markdown);
// Images 
$markdown = preg_replace('/!\[([^\]]*)\]\(([^)]+)\)/', '<img src="$2" alt="$1" class="img-fluid" />', $markdown);
// Horizontal rules (--- or ***)
$markdown = preg_replace('/^---$/m', '<hr>', $markdown);
$markdown = preg_replace('/^\*\*\*$/m', '<hr>', $markdown);
// Blockquotes (> text)
$markdown = preg_replace('/^> (.*)$/m', '<blockquote>$1</blockquote>', $markdown);
// Unordered lists (- item or * item)
$markdown = preg_replace_callback('/(?:^[-*] .+$\n?)+/m', function($matches) {
$items = preg_replace('/^[-*] (.+)$/m', '<li>$1</li>', $matches[0]);
return '<ul>' . $items . '</ul>';
}, $markdown);
// Ordered lists (1. item)
$markdown = preg_replace_callback('/(?:^\d+\. .+$\n?)+/m', function($matches) {
$items = preg_replace('/^\d+\. (.+)$/m', '<li>$1</li>', $matches[0]);
return '<ol>' . $items . '</ol>';
}, $markdown);
// Tables
$markdown = preg_replace_callback('/(?:^\|.+\|$\n?)+/m', function($matches) {
$lines = explode("\n", trim($matches[0]));
$html = '<table class="table table-bordered">';
foreach ($lines as $i => $line) {
if (preg_match('/^\|[-: |]+\|$/', $line)) {
continue; // Skip separator line
}
$cells = array_map('trim', explode('|', trim($line, '|')));
$tag = ($i === 0) ? 'th' : 'td';
$html .= '<tr>';
foreach ($cells as $cell) {
$html .= "<$tag>$cell</$tag>";
}
$html .= '</tr>';
}
$html .= '</table>';
return $html;
}, $markdown);
// Checkboxes
$markdown = preg_replace('/\[x\]/i', '<i class="bi bi-check-square-fill text-success"></i>', $markdown);
$markdown = preg_replace('/\[ \]/', '<i class="bi bi-square"></i>', $markdown);
// Paragraphs
$markdown = preg_replace('/\n\n/', '</p><p>', $markdown);
$markdown = '<p>' . $markdown . '</p>';
// Clean up empty paragraphs
$markdown = preg_replace('/<p>\s*<\/p>/', '', $markdown);
$markdown = preg_replace('/<p>(\s*<(?:h[1-6]|ul|ol|table|pre|hr|blockquote))/i', '$1', $markdown);
$markdown = preg_replace('/(<\/(?:h[1-6]|ul|ol|table|pre|hr|blockquote)>)\s*<\/p>/i', '$1', $markdown);
// Line breaks
$markdown = str_replace("\n", '<br>', $markdown);
return $markdown;
}
function loadMarkdownFile($filename, $title) {
$filepath = __DIR__ . '/../' . $filename;
if (!file_exists($filepath)) {
http_response_code(404);
return [
'title' => '404 - Not Found',
'content' => '<h1>Document Not Found</h1><p>The requested documentation file could not be found.</p>'
];
}
$markdown = file_get_contents($filepath);
$html = parseMarkdown($markdown);
return [
'title' => $title,
'content' => $html
];
}