All posts
Engineering

Markdown Import — Full Feature Test

A single-file fixture that exercises every markdown construct the importer supports — use it to sanity-check rendering after parser changes.

4 min read
Markdown Import — Full Feature Test

This post is generated from a single .md file by the vlozi blog importer. Every section below targets a specific construct so you can spot regressions visually after parser changes. The frontmatter status above is intentionally published — the importer should downgrade it to draft and surface a warning.

1. Headings

Heading 1 — primary title

Heading 2 — section

Heading 3 — subsection

Heading 4 — nested

Heading 5 — minor
Heading 6 — micro

A paragraph after the heading run to confirm spacing.

2. Paragraph + inline marks

This paragraph mixes bold, italic, bold-italic, strikethrough, and inline code. It also has a regular link, a link with a title attribute, a bare URL https://example.com inside text, and an email link [email protected]. Unsafe protocols like #alert(1) should drop their link mark entirely — only the visible text should remain: click me.

A second paragraph with a hard break
forced by two trailing spaces above this line — the break should split the paragraph at that point.

3. Lists

3.1 Bullet list

  • First bullet item

  • Second bullet item

    • Nested bullet (level 2)

    • Another nested bullet

      • Deeply nested (level 3)

  • Third bullet with bold and code

3.2 Numbered list

  1. Step one — set up the project

  2. Step two — install dependencies

  3. Step three — start the dev server

    1. Sub-step a

    2. Sub-step b

  4. Step four — ship it

3.3 Task list (GFM)

  • Wire up the parser

  • Add a paste dialog

  • Cover image upload from .zip

  • Round-trip support (probably never)

3.4 Mixed list with paragraphs

  • A list item that contains a full paragraph of text. This should still render inside the list item's body without breaking the bullet flow above.

    Even with a second paragraph nested inside the same list item.

  • Next item resumes normally.

4. Blockquote

A regular blockquote. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Multiple lines and even inline formatting are supported here.

5. Callouts (GFM admonitions)

This is a NOTE admonition. The importer maps it to your info callout type.

A TIP — maps to the tip callout. Often used for "did you know?"-style asides.

Same family as NOTE — also maps to info. Use for emphasis without alarming the reader.

Maps to the warning callout. Heads-up but not destructive.

Maps to the danger callout. Reserve this for irreversible operations.

6. Code blocks

6.1 TypeScript

interface User {
    id: string
    name: string
}

function greet(user: User): string {
    return `Hello, ${user.name}!`
}

console.log(greet({ id: "u1", name: "Dipanshu" }))

6.2 Python

def fizzbuzz(n: int) -> None:
    for i in range(1, n + 1):
        if i % 15 == 0:
            print("FizzBuzz")
        elif i % 3 == 0:
            print("Fizz")
        elif i % 5 == 0:
            print("Buzz")
        else:
            print(i)

6.3 Bash

pnpm add unified remark-parse remark-gfm gray-matter
git commit -m "feat(blog): markdown import"

6.4 Code without a language tag

Plain text code — no syntax highlighting expected.
Useful for log dumps and ASCII diagrams.

6.5 Mermaid diagram

flowchart LR
    A([User pastes .md]) --> B[Frontmatter parser]
    B --> C{Has title?}
    C -- yes --> D[Convert body]
    C -- no --> E[Use first H1]
    E --> D
    D --> F[Resolve category]
    F --> G[(createPost)]
    G --> H{{Editor opens}}

    style A fill:#0a0a0a,stroke:#fafafa,color:#fafafa
    style H fill:#fafafa,stroke:#0a0a0a,color:#0a0a0a

6.6 Mermaid sequence (second flavor)

sequenceDiagram
    participant U as User
    participant E as Editor
    participant P as Parser
    participant API as createPost
    U->>E: Drops .md file
    E->>P: parseImport(text)
    P-->>E: { title, body, tags }
    E->>API: POST /api/blog/admin/posts
    API-->>E: { id }
    E->>U: Navigate to /dashboard/blog/{id}

7. Tables (GFM)

Feature

Status

Notes

Headings 1–6

Levels clamped to [1, 6]

Bold / italic

Combined marks supported

Tables

First row treated as header

Mermaid

Renders live in the editor

Round-trip export

One-way import only

A second smaller table for spacing checks:

Key

Value

id

post_…

slug

markdown-import-…

8. Images

A standalone image:

Mountain landscape

An inline image inside a paragraph:

tiny avatar
An avatar
followed by more text — confirms the inline: true config on the Image extension.

A relative-path image that should be dropped with a warning, leaving the alt text behind: local-only.

9. Horizontal rule

Above the rule.


Below the rule.

10. YouTube embed (standalone link)

A bare YouTube URL on its own line should be promoted to an embed:

A YouTube link inside a paragraph stays as a regular link: visit https://www.youtube.com/watch?v=dQw4w9WgXcQ for the classic.

11. HTML — should be dropped

The importer drops raw HTML for security. The <details> block below should not render, and neither should the inline <span>:

A paragraph containing an inline styled span should keep only the surrounding text.

12. Edge cases

12.1 Empty heading

Below this line is an empty heading (no text) — the editor should still emit a heading node:

12.2 Long line wrapping

This paragraph is one very long line of text intended to test soft-wrap behaviour, narrow viewport rendering, and the table-of-contents truncation logic that lives in the right rail of the editor; it should wrap naturally and not introduce horizontal scrolling on a 1280px viewport.

12.3 Special characters

Em-dashes — like this — and en-dashes – like this – should survive intact. So should curly quotes "smart quotes" and apostrophes don't break.

Code with angle brackets: <Component prop="value" /> and an inline backtick literal `nested`.

12.4 List immediately after heading

Sub-heading

  • Item right after a heading

  • Should render without a blank paragraph in between

12.5 Code block right before EOF

// This is the very last block in the file.
export const ok = true


TAGS
#test#markdown#import#fixture
KEEP READING

Related posts

Engineering

Hello from MCP — a test post

A quick test post created and published through the Vlozi MCP to confirm the blog pipeline works end to end.

1 min read
Engineering

MCP Test Draft — Gateway Permission Fix Verification

A throwaway draft created via MCP to confirm blog_create_draft works after the gateway fix.

1 min read