Build a Markdown to HTML Converter Lab

HTML:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Markdown to HTML Converter</title>
    <link rel="stylesheet" href="styles.css">
</head>

<body>
    <h1>Markdown to HTML Converter</h1>
    <div id="container">
        <div class="container">
            <h2>Markdown Input:</h2>
            <textarea id="markdown-input" placeholder="Enter your markdown here..."></textarea>
        </div>
        <div class="container">
            <h2>Raw HTML Output:</h2>
            <div id="html-output"></div>
        </div>
        <div class="container">
            <h2>HTML Preview:</h2>
            <div id="preview"></div>
        </div>
    </div>
    <script src="./script.js"></script>
</body>

</html>

CSS:

* {
     box-sizing: border-box;
}
 body {
     font-family: Arial, sans-serif;
     padding: 20px;
}
 #markdown-input {
     width: 100%;
     height: 100px;
}
 #html-output, #preview {
     height: 100px;
     display: inline-block;
     width: 100%;
     border: 1px solid #ccc;
     padding: 10px;
     margin: auto;
     white-space: pre-wrap;
     background-color: #f9f9f9;
}
 @media (min-width: 600px) {
     #markdown-input, #html-output, #preview {
         height: 200px;
         margin: 0;
    }
     #container {
         display: flex;
         justify-content: space-evenly;
         gap: 10px;
    }
}

JS:

const mdInput = document.getElementById("markdown-input");
const rawOutput = document.getElementById("html-output");
const preview = document.getElementById("preview");
const headingsRegx = /^#{1,6}\s+/;
const boldRegx = /\*\*(.+?)\*\*|__(.+?)__/g;
const italicRegx = /\*(.+?)\*|_(.+?)_/g;
const imgRgex = /!\[(.*?)\]\((.*?)\)/;
const linkRegex = /\[(.*?)\]\((.*?)\)/;
const quoteRegx = /^>{1}\s+(.*)/;

function parseInline(text) {
  return text
    .replace(boldRegx, "<strong>$1$2</strong>") // 粗体 优先处理
    .replace(italicRegx, "<em>$1$2</em>") // 斜体
    .replace(imgRgex, '<img alt="$1" src="$2">') // 图片
    .replace(linkRegex, '<a href="$2">$1</a>'); // 链接
}

function convertMarkdown() {
  const lines = mdInput.value.split("\n");
  const html = [];

  for (let raw of lines) {
    const line = raw.trimEnd(); // 保留行内空格,去掉末尾换行

    /* 1. 标题 */
    if (headingsRegx.test(line)) {
      const level = line.match(headingsRegx)[0].length;
      const txt = line.replace(headingsRegx, "");
      html.push(`<h${level}>${parseInline(txt)}</h${level}>`);
      continue;
    }

    /* 2. 引用 */
    if (quoteRegx.test(line)) {
      const txt = line.replace(quoteRegx, "");
      html.push(`<blockquote>${parseInline(txt)}</blockquote>`);
      continue;
    }

    /*3. 文本本身包含可转换格式 (不生成<p>标签)*/
    if (parseInline(line) !== line) html.push(`${parseInline(line)}`);

    /* 4. 空行 → 直接跳过(不生成<p>标签) */
    if (line === "") continue;

    /* 5. 普通段落 → 包裹 <p> 并解析内联 */
    html.push(`<p>${parseInline(line)}</p>`);
  }

  return html.join("\n");
}

/* ---------- 实时更新 ---------- */
mdInput.addEventListener("input", () => {
  const result = convertMarkdown();
  rawOutput.textContent = result;
  preview.innerHTML = result;
});

Is there a better way to realize the function?:thinking: Can anybody give me some advice?I am still learning JS for interest.This is all I can thought of depending on what I have been taught so far(Courses before this Lab).

I suggest testing your regular expressions at regex101: build, test, and debug regex.

Start with the first test that isn’t passing for the header. Note that currently when you enter “# title1” in the preview window, convertMarkup() wraps the text with the h2 element rather than the h1 element. You will see why when you test.

html.push(<p>${parseInline(line)}</p>);

Also, what user story is this line of code addressing?

2 Likes

I`ve found my mistake.It is caused by this piece.

Changed:

Forget to trim the end of my match…

I just add it myself to handle random text input.(For Fun)

The Note of this Lab said:

Note: The final result won’t be a comprehensive Markdown to HTML converter, but you can add extra functionalities to it if you would like.

1 Like