markdown-spec-to-page
Markdown Spec to Page
1. Overview
Parses a structured markdown document and generates a complete Nuxt 3 landing page. The markdown spec defines page sections, content, and optionally which RDS Vue UI components to use. When no component is specified, the skill infers the best match using the rds-component-mapper decision tree based on the section name and content.
This skill converts a single markdown specification into two output files:
pages/<page-name>.vue— the Nuxt 3 page componentassets/content/<page-name>.json— the structured content data
2. Markdown Spec Format
The specification follows a simple, human-readable markdown structure:
# Page Title
## Hero
- component: hero-standard-apollo (optional — will be inferred if omitted)
- title: "Welcome to Our Program"
- subtitle: "Discover opportunities"
- backgroundImage: /images/hero.jpg
## About Section
- component: section-apollo
- title: "About Us"
- body: "We are a leading institution..."
## Programs
- layout: 3-column grid
- component: card-image-article
- items:
- title: "Program A"
image: /images/prog-a.jpg
link: /programs/a
- title: "Program B"
image: /images/prog-b.jpg
link: /programs/b
## Testimonials
- component: section-testimonial-falcon
- quote: "This program changed my life"
- author: "Jane Doe"
- role: "Class of 2025"
## Footer
- component: footer-standard
3. Parsing Rules
| Element | Syntax | Behavior |
|---|---|---|
| Page title | # Page Title |
Sets the <title> tag and page meta |
| Section | ## Section Name |
Each H2 heading becomes a page section |
| Component (explicit) | - component: xxx |
Use the named RDS component (kebab-case) |
| Component (inferred) | (no component line) | Infer via rds-component-mapper from section name + content |
| Repeated items | - items: |
Indicates a list of repeated components (cards, accordion, etc.) |
| Grid layout | - layout: N-column grid |
Wraps items in Bootstrap row/col-md-* grid |
| Props/content | - key: value |
All other key-value pairs become component props or content JSON fields |
| Nested items | Indented - key: value under items: |
Each indented block is one item in the array |
Component Name Resolution
When a - component: line is present, convert from kebab-case to the PascalCase Vue component:
| Spec Value | Vue Component |
|---|---|
hero-standard-apollo |
HeroStandardApollo |
section-apollo |
SectionApollo |
card-image-article |
CardImageArticle |
overlap-accordion-atlas |
OverlapAccordionAtlas |
section-testimonial-falcon |
SectionTestimonialFalcon |
section-stat-apollo |
SectionStatApollo |
carousel-image-apollo |
CarouselImageApollo |
footer-standard |
FooterStandard |
video-apollo |
VideoApollo |
navbar-standard |
NavbarStandard |
Component Inference (when no component specified)
When the - component: line is omitted, infer from the section name and content:
| Section Name Pattern | Inferred Component | Condition |
|---|---|---|
| Hero, Banner | HeroStandardApollo |
Default hero |
| About, Overview, Introduction | SectionApollo |
General content section |
| Programs, Courses, Services | CardImageArticle (grid) |
Has items: with images |
| Testimonial(s), Quote(s) | SectionTestimonialFalcon |
Single testimonial |
| Testimonial(s), Quote(s) | CarouselTestimonialApollo |
Multiple items |
| FAQ, Questions | OverlapAccordionAtlas |
Has question/answer items |
| Stats, Numbers, Metrics | SectionStatApollo |
Has numeric values |
| Gallery, Images, Photos | CarouselImageApollo |
Image collection |
| Video, Media | VideoApollo |
Video content |
| Footer | FooterStandard |
Page footer |
| Contact, Form | FormApollo |
Has form fields |
| Navigation, Navbar | NavbarStandard |
Top navigation |
If no pattern matches, default to SectionApollo as a generic content block.
4. Workflow
- Parse — Read the markdown spec from a file path or inline text.
- Extract — Build a section list with all key-value pairs per section.
- Resolve Components — For each section:
- If
- component:is specified → use it (convert kebab to PascalCase). - If not → infer from section name + content via the inference table above.
- Map remaining key-value pairs to component props.
- If
- Handle Items — For sections with
- items:, build an array and apply grid layout. - Generate Page — Produce
pages/<page-name>.vuewith all sections. - Generate Content — Produce
assets/content/<page-name>.jsonfrom the spec content. - Report — Summarize: N sections, components used, any unmatched sections.
5. Output Format
Page File: pages/<page-name>.vue
<template>
<div>
<!-- Section: Hero -->
<HeroStandardApollo
:title="content.hero.title"
:subtitle="content.hero.subtitle"
:backgroundImage="content.hero.backgroundImage"
/>
<!-- Section: About -->
<SectionApollo
:title="content.about.title"
:body="content.about.body"
/>
<!-- Section: Programs -->
<div class="container py-5">
<div class="row">
<div
v-for="(card, index) in content.programs.items"
:key="index"
class="col-md-4 mb-4"
>
<CardImageArticle
:title="card.title"
:image="card.image"
:link="card.link"
/>
</div>
</div>
</div>
<!-- Section: Testimonials -->
<SectionTestimonialFalcon
:quote="content.testimonials.quote"
:author="content.testimonials.author"
:role="content.testimonials.role"
/>
<!-- Section: Footer -->
<FooterStandard />
</div>
</template>
<script setup>
useHead({ title: 'Welcome to Our Program' })
const { data: content } = await useAsyncData('content', () =>
import('~/assets/content/welcome.json').then(m => m.default)
)
</script>
Content File: assets/content/<page-name>.json
{
"hero": {
"title": "Welcome to Our Program",
"subtitle": "Discover opportunities",
"backgroundImage": "/images/hero.jpg"
},
"about": {
"title": "About Us",
"body": "We are a leading institution..."
},
"programs": {
"items": [
{ "title": "Program A", "image": "/images/prog-a.jpg", "link": "/programs/a" },
{ "title": "Program B", "image": "/images/prog-b.jpg", "link": "/programs/b" }
]
},
"testimonials": {
"quote": "This program changed my life",
"author": "Jane Doe",
"role": "Class of 2025"
}
}
6. Grid Layout Calculation
When - layout: N-column grid is specified, calculate Bootstrap column classes:
| Columns | Class | Items per Row |
|---|---|---|
| 1 | col-12 |
1 |
| 2 | col-md-6 |
2 |
| 3 | col-md-4 |
3 |
| 4 | col-md-3 |
4 |
| 6 | col-md-2 |
6 |
If no layout is specified but items: is present, default to 3-column grid (col-md-4).
7. Section Key to JSON Key Mapping
Section names from H2 headings are converted to JSON keys:
| H2 Heading | JSON Key |
|---|---|
## Hero |
hero |
## About Section |
about |
## Our Programs |
programs |
## Student Testimonials |
testimonials |
## FAQ |
faq |
Rules: lowercase, remove articles (a, an, the, our), take the primary noun, use camelCase for multi-word keys that remain after stripping.
8. Error Handling
| Condition | Behavior |
|---|---|
No # Page Title found |
Use the file name as page title |
No ## sections found |
Report error: spec contains no sections |
| Unknown component name | Report warning, skip section, continue |
| Missing required props | Report warning, generate with placeholder values |
Empty items: array |
Report warning, generate section with empty array |
| Duplicate section names | Append numeric suffix to JSON key (programs, programs2) |
9. Generation Report
After generating, output a summary:
Markdown Spec → Page Generation Report
───────────────────────────────────────
Page title: Welcome to Our Program
Sections: 5
# │ Section │ Component │ Source
──┼────────────────┼─────────────────────────────┼─────────
1 │ Hero │ HeroStandardApollo │ explicit
2 │ About │ SectionApollo │ explicit
3 │ Programs │ CardImageArticle × 2 │ explicit
4 │ Testimonials │ SectionTestimonialFalcon │ explicit
5 │ Footer │ FooterStandard │ explicit
Output:
→ pages/welcome.vue
→ assets/content/welcome.json
Warnings: none
10. Complete Example
Input Spec (spec/engineering.md)
# Engineering Program
## Hero
- title: "Bachelor of Engineering"
- subtitle: "Build the future with us"
- backgroundImage: /images/engineering-hero.jpg
## Program Tracks
- layout: 3-column grid
- items:
- title: "Computer Science"
image: /images/cs.jpg
link: /tracks/cs
body: "Learn algorithms, AI, and systems design."
- title: "Electrical Engineering"
image: /images/ee.jpg
link: /tracks/ee
body: "Power systems, circuits, and signal processing."
- title: "Mechanical Engineering"
image: /images/me.jpg
link: /tracks/me
body: "Thermodynamics, robotics, and manufacturing."
## Stats
- items:
- label: "Graduates"
value: "10,000+"
- label: "Industry Partners"
value: "200+"
- label: "Research Labs"
value: "45"
## Testimonials
- quote: "The hands-on labs prepared me for my career from day one."
- author: "Alex Rivera"
- role: "BS Computer Science, 2024"
## FAQ
- items:
- question: "What are the admission requirements?"
answer: "A strong foundation in math and science with a minimum GPA of 3.0."
- question: "Are internships included?"
answer: "Yes, all programs include a required industry internship in year 3."
- question: "Is financial aid available?"
answer: "Multiple scholarship and aid options are available for qualified students."
## Footer
Generated Output
Report:
Page title: Engineering Program
Sections: 6
# │ Section │ Component │ Source
──┼────────────────┼─────────────────────────────┼─────────
1 │ Hero │ HeroStandardApollo │ inferred
2 │ Program Tracks │ CardImageArticle × 3 │ inferred
3 │ Stats │ SectionStatApollo │ inferred
4 │ Testimonials │ SectionTestimonialFalcon │ inferred
5 │ FAQ │ OverlapAccordionAtlas │ inferred
6 │ Footer │ FooterStandard │ inferred
Output:
→ pages/engineering.vue
→ assets/content/engineering.json
Warnings: none
More from chandima/rds-lp-factory
rds-component-mapper
Maps visual descriptions, design context, or screenshots to the closest @rds-vue-ui/* design system components. Use when you need to select RDS components for a landing page section based on visual intent, Figma data, or natural-language descriptions.
2figma-to-landing-page
Translates Figma design URLs into complete Nuxt 3 landing pages using RDS Vue UI components. Supports both Dev+ accounts (rich design context) and Basic accounts (screenshot-based). Use when user provides a Figma URL or screenshot of a design to implement.
1iterative-build-page
Builds a Nuxt 3 landing page section-by-section from natural language descriptions using RDS Vue UI components. Use when user describes page sections incrementally (e.g., "Add a hero with video background", "Now add a 3-column card grid").
1reference-to-landing-page
Creates a new Nuxt 3 landing page inspired by a reference website URL, adapted with user-specified modifications, using RDS Vue UI components. Use when user provides an existing page URL and describes how they want the new page to differ.
1