<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Markdown Editor</title>

    <style>

        body {

            font-family: Arial, sans-serif;

            margin: 0;

            padding: 0;

            display: flex;

            justify-content: space-between;

            border-left: 100px solid #1e1e1e;

            border-right: 100px solid #1e1e1e;

        }


        #editor, #preview {

            width: 50%;

            height: 100vh;

            padding: 20px;

            background-color: #1e1e1e;

            color: #fff;

            overflow: auto;

        }


        #editor textarea {

            width: 100%;

            height: 100%;

            border: none;

            background-color: #1e1e1e;

            color: #fff;

            resize: none;

        }


        #output {

            color: #3498db;

        }

    </style>

</head>

<body>

    <div id="editor">

        <textarea id="markdown-input" placeholder="Enter Markdown here..."></textarea>

    </div>

    <div id="preview">

        <div id="output"></div>

    </div>


    <script>

        const markdownInput = document.getElementById("markdown-input");

        const output = document.getElementById("output");


        function updatePreview() {

            const markdownText = markdownInput.value;

            const htmlText = convertMarkdownToHTML(markdownText);

            output.innerHTML = htmlText;

        }


        markdownInput.addEventListener("input", updatePreview);


        function convertMarkdownToHTML(markdownText) {

            // Define a map of Markdown features to their corresponding HTML tags

            const featureMap = {

                '^# (.+?)\\n': '<h1>$1</h1>',

                '^## (.+?)\\n': '<h2>$1</h2>',

                '^### (.+?)\\n': '<h3>$1</h3>',

                '\\*\\*(.+?)\\*\\*': '<strong>$1</strong>',

                '\\*(.+?)\\*': '<em>$1</em>',

                '~~(.+?)~~': '<s>$1</s>',

                '==(.+?)==': '<mark>$1</mark>',

                '-> (.+?) <-': '<div style="text-align: center;">$1</div>',

                '-> (.+?)': '<div style="text-align: right;">$1</div>',

                '\\[TOC\\]': generateTableOfContents(markdownText),

                '- \\[ \\] (.+?)': '<input type="checkbox" disabled> $1',

                '- \\[x\\] (.+?)': '<input type="checkbox" checked disabled> $1',

                '> (.+?)\\n': '<blockquote>$1</blockquote>',

                '```\\s*(\\w+)?\\n([\\s\\S]*?)\\n```': '<pre><code class="$1">$2</code></pre>',

                '`(.+?)`': '<code>$1</code>',

                '\\*\\*\\*(.*)\\*\\*\\*': '<hr>',

                '\\\\(.+)': '$1',

                '\\|(.+?)\\|\\n(\\|?[-:]+\\|?\\n((\\|.+?\\|\\n)+))?': createTable,

                '!!! (info|note|warning|danger)\\n([^!]+)?': createAdmonition,

                '(https?://\\S+|www\\.\\S+)': createAutoLink,

                '\\[([^\\]]+)\\]\\((https?://\\S+|www\\.\\S+)\\)': createLink,

                '!\\[([^\\]]+)\\]\\((https?://\\S+|www\\.\\S+)\\)': createImage,

            };


            // Replace Markdown features with their HTML counterparts

            let htmlText = markdownText;

            for (const pattern in featureMap) {

                const regex = new RegExp(pattern, 'gm');

                htmlText = htmlText.replace(regex, featureMap[pattern]);

            }


            return htmlText;

        }


        function generateTableOfContents(markdownText) {

            // Generate a Table of Contents based on headers in the Markdown text

            const headers = markdownText.match(new RegExp(`^#{1,3} (.+?)\\n`, 'gm'));

            if (!headers) return '';


            const toc = ['<ul>'];

            for (const header of headers) {

                const text = header.replace(new RegExp(`^#{1,3} (.+?)\\n`), '$1');

                const id = text.replace(/\s+/g, '-').toLowerCase();

                toc.push(`<li><a href="#${id}">${text}</a></li>`);

            }

            toc.push('</ul>');


            return toc.join('');

        }


        function createTable(match, content) {

            const rows = content.split('\n');

            const tableHtml = ['<table>'];


            rows.forEach((row, index) => {

                if (row) {

                    const cells = row.split('|').map(cell => cell.trim());

                    if (index === 1) {

                        tableHtml.push('<thead>');

                    } else if (index === 2) {

                        tableHtml.push('<tbody>');

                    }


                    const rowHtml = cells.map((cell, cellIndex) => {

                        if (index === 1) {

                            return `<th>${cell}</th>`;

                        } else {

                            return `<td>${cell}</td>`;

                        }

                    }).join('');


                    tableHtml.push(`<tr>${rowHtml}</tr>`);

                }

            });


            tableHtml.push('</tbody></table>');

            return tableHtml.join('');

        }


        function createAdmonition(match, type, content) {

            const types = {

                info: '#3498db',

                note: '#27ae60',

                warning: '#e67e22',

                danger: '#e74c3c',

            };

            const backgroundColor = types[type] || '#e74c3c';

            const title = content ? `<strong>${content}</strong>` : '';

            return `<div style="background-color: ${backgroundColor}; padding: 10px; color: #fff; border-radius: 5px">${title}</div>`;

        }


        function createAutoLink(match, url) {

            return `<a href="${url}" target="_blank">${url}</a>`;

        }


        function createLink(match, text, url) {

            return `<a href="${url}" target="_blank">${text}</a>`;

        }


        function createImage(match, altText, imageUrl) {

            return `<img src="${imageUrl}" alt="${altText}">`;

        }


        updatePreview(); // Initially update the preview

    </script>

</body>

</html>