Markdown Unordered List Parser - FreeCodeCamp #150 Daily Challenge
Introduction
In this post, we solve the “Markdown Unordered List Parser” challenge from FreeCodeCamp’s #150 Daily Challenge. The problem requires converting a string representing a valid unordered list in Markdown to its HTML equivalent. We’ll explore the analysis, JavaScript implementation, and reflections on the process.
Problem Statement
Given a string of a valid unordered list in Markdown, return the equivalent HTML string.
An unordered list consists of one or more list items. Each valid item:
- Appears on its own line.
- Starts with a dash (”-”).
- Followed by at least one space.
- Then the item text.
The list is provided as a single string, with items separated by “\n”. Do not include newline characters in the item text.
Wrap each item in <li> and the entire list in <ul>.
Example: For "- Item A\n- Item B", return "<ul><li>Item A</li><li>Item B</li></ul>".
Initial Analysis
Understanding the Problem
The challenge involves simple parsing: identify items starting with ”- ” (or more spaces), extract the text, and generate HTML. The input guarantees validity, so we don’t need complex validations.
Test Cases
- Basic case:
"- Item A\n- Item B"→"<ul><li>Item A</li><li>Item B</li></ul>" - Extra spaces:
"- JavaScript\n- Python"→"<ul><li>JavaScript</li><li>Python</li></ul>" - Longer list:
"- 2 C Flour\n- 1/2 C Sugar\n- 1 Tsp Vanilla"→"<ul><li>2 C Flour</li><li>1/2 C Sugar</li><li>1 Tsp Vanilla</li></ul>" - Dashes in text:
"- A-1\n- A-2\n- B-1"→"<ul><li>A-1</li><li>A-2</li><li>B-1</li></ul>"
Solution Development
We chose a string manipulation approach: split into lines, extract text, and build HTML. It’s efficient and straightforward.
flowchart TD
A["Input: Markdown string"] --> B["Split into lines with split('\n')"]
B --> C["For each line: extract text removing '- '"]
C --> D["Wrap text in <li>"]
D --> E["Join <li> in <ul>"]
E --> F["Output: HTML string"]
Implementation
function parseUnorderedList(markdown) {
// Split the string into lines
const lines = markdown.split('\n')
// Process each line: remove prefix and wrap in <li>
const listItems = lines.map((line) => {
// Use regex to remove one or more dashes followed by spaces
const text = line.replace(/^-+\s+/, '')
return `<li>${text}</li>`
})
// Join the items in a <ul> list
return `<ul>${listItems.join('')}</ul>`
}The code is simple: split separates lines, map transforms each by removing the prefix with regex, and join builds the HTML.
Complexity Analysis
- Time: O(n), where n is the string length. Linear operations on the input.
- Space: O(n), due to created arrays. Suitable for typical lists.
Edge Cases
- Handles extra spaces correctly (flexible regex).
- Dashes in text don’t interfere, as only the initial prefix is removed.
- Assumes valid input, no empty items or malformed lines.
Reflections and Learnings
We applied basic string manipulation and regex. This pattern is useful for simple parsing. Possible optimizations: use substring instead of regex for more control, but the current code is readable and efficient.