SuperAPI AI Directory

markdown-spec-to-page

Frontend & websites

View repository

Updated 10-15 20:11

About this skill

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 component
  • assets/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

1. **Parse** — Read the markdown spec from a file path or inline text.
2. **Extract** — Build a section list with all key-value pairs per section.
3. **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.
4. **Handle Items** — For sections with `- items:`, build an array and apply grid layout.
5. **Generate Page** — Produce `pages/<page-name>.vue` with all sections.
6. **Generate Content** — Produce `assets/content/<page-name>.json` from the spec content.
7. **Report** — Summarize: N sections, components used, any unmatched sections.

## 5. Output Format

### Page File: `pages/<page-name>.vue`

```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