Handling Multi-Level Lists in Markdown Using NextJS or NuxtJS

Azzam Jihad Ulhaq
4 min readDec 28, 2024

--

Learn how to create your own markdown parser in JavaScript that handles multi-level lists without relying on third-party libraries. Discover the power of customizing markdown handling to fit your unique use case.

Introduction

Markdown is a widely used markup language prized for its simplicity and flexibility. It’s particularly effective for content creation in blogs, documentation, and notes. However, handling multi-level lists (nested lists) can sometimes be challenging, especially when using JavaScript without the help of third-party libraries. In this article, we will focus on creating a custom function that effectively parses markdown into HTML, with a particular emphasis on supporting multi-level lists.

Understanding Markdown Syntax for Lists

Before diving into the implementation, let’s clarify how markdown handles lists. A typical markdown unordered list looks like this:

- Item 1
- Subitem 1.1
- Subitem 1.1.1
- Item 2

In this example:

  • The first level consists of items prefixed by a -.
  • Sub-items are indented and also prefixed with - but are nested beneath their parent items.

The goal is to convert this markdown structure into properly formatted HTML while preserving the nested structure.

Why Create Your Own Markdown Parser for Multi-Level Lists?

While there are various third-party libraries available for parsing markdown, they may not adequately support your specific use case or performance requirements. Building your own parser allows you to:

  • Customize Behavior: Tailor the parsing logic to fit your unique needs, especially for nested lists.
  • Control Output: Ensure that the HTML output adheres to the exact styling conventions and formats you require, such as utilizing Tailwind CSS.
  • Optimize Performance: Avoid the overhead of unnecessary dependencies that can bloat the application.

The Custom convertMarkdownToHtml Function

Here is a function that effectively converts markdown into HTML while specifically handling multi-level unordered lists:

function convertMarkdownToHtml(markdown) {
let html = markdown;

// Convert headers
html = html.replace(/###### (.*?)$/gm, '<h6 class="text-lg font-semibold my-3">$1</h6>');
html = html.replace(/##### (.*?)$/gm, '<h5 class="text-lg font-semibold my-3">$1</h5>');
html = html.replace(/#### (.*?)$/gm, '<h4 class="text-xl font-semibold my-3">$1</h4>');
html = html.replace(/### (.*?)$/gm, '<h3 class="text-xl font-bold my-5">$1</h3>');
html = html.replace(/## (.*?)$/gm, '<h2 class="text-2xl font-bold my-5">$1</h2>');
html = html.replace(/# (.*?)$/gm, '<h1 class="text-3xl font-bold my-5">$1</h1>');

// Convert bold text
html = html.replace(/\*\*(.*?)\*\*/g, '<strong class="font-bold">$1</strong>');

// Handle nested unordered lists
html = html.replace(
/^(\s*-\s+.*?)(?=\n\s*-\s+|\n*$)/gm,
(match) => {
const indentLevel = match.match(/^\s*/)[0].length / 2; // Assuming 2 spaces per indent
const marginLeft = indentLevel * 20;
return `<li style="margin-left: ${marginLeft}px;">${match.trim().replace(/^\s*-\s+/, '')}</li>`;
}
);

return html;
}

Explanation of the Function:

Header Conversion

This section converts markdown headers into HTML header tags with appropriate Tailwind CSS classes for styling.

Bold Text:

The function identifies and converts bold markdown syntax into strong HTML tags.

Multi-Level Lists:

  • The nested list detection is achieved using regular expressions. The function looks for leading whitespace to determine the indentation level.
  • For each level of indentation, a corresponding pixel margin is calculated and applied as an inline style to ensure proper visual hierarchy.

Example Usage

Here’s how you would use this function with sample markdown input:

const markdownInput = `
#### Grammatical Range and Accuracy Errors:
- **Error**: "plastics, due to their non-biodegradable nature, contribute extensively to land and marine pollution."
- **Improved**: "Plastics, due to their non-biodegradable nature, extensively contribute to land and marine pollution."
- **Explanation**: The placement of "extensively" can be improved for clarity and emphasis.
- **Examples**:
- Correct: "The team, due to their hard work, extensively contributed to the project’s success."
- Correct: "Students, due to their dedication, significantly improve academic results."
- Correct: "Weather, due to its unpredictability, greatly affects travel plans."
`;

const htmlOutput = convertMarkdownToHtml(markdownInput);
console.log(htmlOutput);

Expected HTML Output

When the provided markdown is processed, the function will generate HTML similar to this:

<h4 class="text-xl font-semibold my-3">Grammatical Range and Accuracy Errors:</h4>
<ul class="mb-2">
<li style="margin-left: 0px;"><strong>Error</strong>: "plastics, due to their non-biodegradable nature, contribute extensively to land and marine pollution."</li>
<ul class="mb-2">
<li style="margin-left: 20px;"><strong>Improved</strong>: "Plastics, due to their non-biodegradable nature, extensively contribute to land and marine pollution."</li>
<li style="margin-left: 20px;"><strong>Explanation</strong>: The placement of "extensively" can be improved for clarity and emphasis.</li>
<ul class="mb-2">
<li style="margin-left: 40px;"><strong>Examples</strong>:</li>
<li style="margin-left: 60px;">Correct: "The team, due to their hard work, extensively contributed to the project’s success."</li>
<li style="margin-left: 60px;">Correct: "Students, due to their dedication, significantly improve academic results."</li>
<li style="margin-left: 60px;">Correct: "Weather, due to its unpredictability, greatly affects travel plans."</li>
</ul>
</ul>
</ul>

Handling multi-level lists in markdown using JavaScript doesn’t have to be daunting. By creating your own parser, you have full control over how markdown is converted to HTML, ensuring it meets your project’s needs perfectly. The code provided here serves as a solid foundation for managing markdown processing without relying on third-party libraries.

If you found this guide helpful, consider applying these techniques in your next project! I’m eager to hear your thoughts. Have you faced challenges with markdown processing? Share your experiences in the comments below!

--

--

No responses yet