Back to skills
SkillHub ClubWrite Technical DocsFull StackTech Writer

lorem-ipsum

Generate lorem ipsum placeholder text. This skill should be used when users ask to generate lorem ipsum content, placeholder text, dummy text, or filler text. Supports various structures including plain paragraphs, headings with sections, lists, and continuous text. Output can be saved to a file or used directly as requested by the user.

Packaged view

This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.

Stars
224
Hot score
98
Updated
March 20, 2026
Overall rating
C3.6
Composite score
3.6
Best-practice grade
B70.4

Install command

npx @skill-hub/cli install intellectronica-agent-skills-lorem-ipsum

Repository

intellectronica/agent-skills

Skill path: skills/lorem-ipsum

Generate lorem ipsum placeholder text. This skill should be used when users ask to generate lorem ipsum content, placeholder text, dummy text, or filler text. Supports various structures including plain paragraphs, headings with sections, lists, and continuous text. Output can be saved to a file or used directly as requested by the user.

Open repository

Best for

Primary workflow: Write Technical Docs.

Technical facets: Full Stack, Tech Writer.

Target audience: everyone.

License: Unknown.

Original source

Catalog source: SkillHub Club.

Repository owner: intellectronica.

This is still a mirrored public skill entry. Review the repository before installing into production workflows.

What it helps with

  • Install lorem-ipsum into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
  • Review https://github.com/intellectronica/agent-skills before adding lorem-ipsum to shared team environments
  • Use lorem-ipsum for development workflows

Works across

Claude CodeCodex CLIGemini CLIOpenCode

Favorites: 0.

Sub-skills: 0.

Aggregator: No.

Original source / Raw SKILL.md

---
name: lorem-ipsum
description: Generate lorem ipsum placeholder text. This skill should be used when users ask to generate lorem ipsum content, placeholder text, dummy text, or filler text. Supports various structures including plain paragraphs, headings with sections, lists, and continuous text. Output can be saved to a file or used directly as requested by the user.
---

# Lorem Ipsum Generator

## Overview

Generate lorem ipsum placeholder text using the bundled generator script. **Always use the script** to generate content rather than writing lorem ipsum directly.

**Critical requirement**: ALL text in the generated output must be lorem ipsum, including headings, bullet points, list items, table cells, and any other textual elements.

## Generator Script

Use `scripts/generate.py` to produce lorem ipsum content. The script handles all text generation to ensure consistent, authentic lorem ipsum output.

### Basic Usage

```bash
# Generate 3 paragraphs (default)
uv run scripts/generate.py

# Generate 5 paragraphs with 4 sentences each
uv run scripts/generate.py --paragraphs 5 --sentences 4

# Generate approximately 500 words
uv run scripts/generate.py --words 500

# Generate exactly 1000 characters
uv run scripts/generate.py --characters 1000

# Generate approximately 200 LLM tokens (~800 characters)
uv run scripts/generate.py --tokens 200

# Continuous text without paragraph breaks
uv run scripts/generate.py --paragraphs 4 --continuous
```

### Structured Content

```bash
# 3 sections with headings and 2 paragraphs each
uv run scripts/generate.py --headings 3 --paragraphs 6

# 4 sections with bullet points (5 bullets each)
uv run scripts/generate.py --headings 4 --bullets 5

# Numbered lists instead of bullets
uv run scripts/generate.py --headings 3 --bullets 6 --numbered

# Realistic mixed document with 5 sections (varied content types)
uv run scripts/generate.py --mixed 5
```

The `--mixed` option generates realistic documents with varied structure per section:
- Some sections have paragraphs only
- Some have bullet or numbered lists
- Some have subheadings (h3) with nested content
- Some combine paragraphs with lists

### Output Options

```bash
# Write to file
uv run scripts/generate.py --paragraphs 3 --output ~/Desktop/placeholder.txt

# HTML format
uv run scripts/generate.py --headings 2 --format html --output page.html

# Plain text (no markdown formatting)
uv run scripts/generate.py --format text

# Copy to clipboard
uv run scripts/generate.py --words 200 | pbcopy
```

### All Options

| Option | Description |
|--------|-------------|
| `--paragraphs N` | Number of paragraphs (default: 3) |
| `--sentences N` | Sentences per paragraph (default: 5) |
| `--words N` | Approximate total word count |
| `--characters N` | Exact character count (truncates to match) |
| `--tokens N` | Estimated LLM token count (~4 chars/token) |
| `--continuous` | Output without paragraph breaks |
| `--headings N` | Number of sections with headings |
| `--bullets N` | Bullet points per section |
| `--numbered` | Use numbered lists instead of bullets |
| `--mixed N` | Realistic document with N sections, varied content types |
| `--output FILE` | Write to file instead of stdout |
| `--format FORMAT` | Output format: text, markdown, html (default: markdown) |

## Workflow

1. Interpret the user's request for length and structure
2. Run `scripts/generate.py` with appropriate options
3. If the user wants the output saved, use `--output` or redirect/pipe as needed
4. If the user wants it in clipboard, pipe to `pbcopy`
5. Display the result or confirm the file was written

## Examples

**"Generate 3 paragraphs of lorem ipsum"**
```bash
uv run scripts/generate.py --paragraphs 3
```

**"Create lorem ipsum with 3 headings and 2 paragraphs under each"**
```bash
uv run scripts/generate.py --headings 3 --paragraphs 6
```

**"Give me a document with bullet points"**
```bash
uv run scripts/generate.py --headings 3 --bullets 5
```

**"500 words of continuous lorem ipsum saved to ~/Desktop/placeholder.txt"**
```bash
uv run scripts/generate.py --words 500 --continuous --output ~/Desktop/placeholder.txt
```

**"Lorem ipsum with numbered lists in HTML format"**
```bash
uv run scripts/generate.py --headings 4 --bullets 5 --numbered --format html
```

**"Exactly 500 characters of lorem ipsum"**
```bash
uv run scripts/generate.py --characters 500
```

**"About 100 tokens worth of lorem ipsum with headings"**
```bash
uv run scripts/generate.py --tokens 100 --headings 2
```

**"A realistic document with mixed content"**
```bash
uv run scripts/generate.py --mixed 5
```


---

## Referenced Files

> The following files are referenced in this skill and included for context.

### scripts/generate.py

```python
#!/usr/bin/env python3
# /// script
# requires-python = ">=3.10"
# ///
"""
Lorem ipsum generator script.

Usage:
    uv run generate.py [options]

Options:
    --paragraphs N      Number of paragraphs (default: 3)
    --sentences N       Sentences per paragraph (default: 5)
    --words N           Approximate total word count
    --characters N      Exact number of characters (truncates to match)
    --tokens N          Estimated LLM token count (~4 chars/token)
    --continuous        Output as continuous text without paragraph breaks
    --headings N        Number of sections with headings (each gets paragraphs underneath)
    --bullets N         Number of bullet points per section (use with --headings)
    --numbered          Use numbered lists instead of bullets
    --mixed N           Generate realistic document with N sections, varied content types
    --output FILE       Write to file instead of stdout
    --format FORMAT     Output format: text, markdown, html (default: markdown)
"""

import argparse
import random
import sys

# Classic lorem ipsum vocabulary
WORDS = [
    "lorem", "ipsum", "dolor", "sit", "amet", "consectetur", "adipiscing", "elit",
    "sed", "do", "eiusmod", "tempor", "incididunt", "ut", "labore", "et", "dolore",
    "magna", "aliqua", "enim", "ad", "minim", "veniam", "quis", "nostrud",
    "exercitation", "ullamco", "laboris", "nisi", "aliquip", "ex", "ea", "commodo",
    "consequat", "duis", "aute", "irure", "in", "reprehenderit", "voluptate",
    "velit", "esse", "cillum", "fugiat", "nulla", "pariatur", "excepteur", "sint",
    "occaecat", "cupidatat", "non", "proident", "sunt", "culpa", "qui", "officia",
    "deserunt", "mollit", "anim", "id", "est", "laborum", "perspiciatis", "unde",
    "omnis", "iste", "natus", "error", "voluptatem", "accusantium", "doloremque",
    "laudantium", "totam", "rem", "aperiam", "eaque", "ipsa", "quae", "ab", "illo",
    "inventore", "veritatis", "quasi", "architecto", "beatae", "vitae", "dicta",
    "explicabo", "nemo", "ipsam", "quia", "voluptas", "aspernatur", "aut", "odit",
    "fugit", "consequuntur", "magni", "dolores", "eos", "ratione", "sequi",
    "nesciunt", "neque", "porro", "quisquam", "nihil", "numquam", "eius", "modi",
    "tempora", "corporis", "suscipit", "laboriosam", "aliquid", "commodi",
    "consequatur", "autem", "vel", "eum", "iure", "quam", "nihil", "molestiae",
    "illum", "quo", "maxime", "placeat", "facere", "possimus", "assumenda",
    "repellendus", "temporibus", "quibusdam", "officiis", "debitis", "rerum",
    "necessitatibus", "saepe", "eveniet", "voluptates", "repudiandae", "recusandae",
    "itaque", "earum", "hic", "tenetur", "sapiente", "delectus", "reiciendis",
    "voluptatibus", "maiores", "alias", "perferendis", "doloribus", "asperiores",
    "repellat"
]

# Canonical opening
OPENING = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."


def generate_word():
    return random.choice(WORDS)


def generate_words(count):
    return [generate_word() for _ in range(count)]


def generate_sentence(min_words=6, max_words=15):
    length = random.randint(min_words, max_words)
    words = generate_words(length)
    words[0] = words[0].capitalize()
    return " ".join(words) + "."


def generate_paragraph(sentences=5, use_opening=False):
    result = []
    for i in range(sentences):
        if i == 0 and use_opening:
            result.append(OPENING)
        else:
            result.append(generate_sentence())
    return " ".join(result)


def generate_heading():
    word_count = random.randint(2, 4)
    words = generate_words(word_count)
    return " ".join(w.capitalize() for w in words)


def generate_bullet_item():
    word_count = random.randint(4, 10)
    words = generate_words(word_count)
    words[0] = words[0].capitalize()
    return " ".join(words)


def format_output(content, fmt, is_heading=False, heading_level=2):
    if fmt == "html":
        if is_heading:
            return f"<h{heading_level}>{content}</h{heading_level}>"
        return f"<p>{content}</p>"
    elif fmt == "markdown":
        if is_heading:
            return "#" * heading_level + " " + content
        return content
    else:  # plain text
        return content


def format_list_item(content, fmt, numbered=False, index=1):
    if fmt == "html":
        return f"<li>{content}</li>"
    elif fmt == "markdown":
        if numbered:
            return f"{index}. {content}"
        return f"- {content}"
    else:
        if numbered:
            return f"{index}. {content}"
        return f"* {content}"


def generate_mixed_section(fmt, use_opening=False):
    """Generate a section with varied content types."""
    lines = []

    # Choose section structure randomly
    structure = random.choice([
        "paragraphs",           # Just paragraphs
        "bullets",              # Just bullet list
        "numbered",             # Just numbered list
        "para_then_bullets",    # Paragraph intro + bullets
        "para_then_numbered",   # Paragraph intro + numbered
        "subheadings",          # Subheadings with paragraphs
        "subheadings_mixed",    # Subheadings with mixed content
    ])

    if structure == "paragraphs":
        num_paras = random.randint(1, 3)
        for i in range(num_paras):
            para = generate_paragraph(random.randint(3, 6), use_opening=(i == 0 and use_opening))
            lines.append(format_output(para, fmt))
            lines.append("")

    elif structure == "bullets":
        num_bullets = random.randint(3, 7)
        if fmt == "html":
            lines.append("<ul>")
        for i in range(num_bullets):
            item = generate_bullet_item()
            lines.append(format_list_item(item, fmt, numbered=False, index=i+1))
        if fmt == "html":
            lines.append("</ul>")
        lines.append("")

    elif structure == "numbered":
        num_items = random.randint(3, 6)
        if fmt == "html":
            lines.append("<ol>")
        for i in range(num_items):
            item = generate_bullet_item()
            lines.append(format_list_item(item, fmt, numbered=True, index=i+1))
        if fmt == "html":
            lines.append("</ol>")
        lines.append("")

    elif structure == "para_then_bullets":
        para = generate_paragraph(random.randint(2, 4), use_opening=use_opening)
        lines.append(format_output(para, fmt))
        lines.append("")
        num_bullets = random.randint(3, 6)
        if fmt == "html":
            lines.append("<ul>")
        for i in range(num_bullets):
            item = generate_bullet_item()
            lines.append(format_list_item(item, fmt, numbered=False, index=i+1))
        if fmt == "html":
            lines.append("</ul>")
        lines.append("")

    elif structure == "para_then_numbered":
        para = generate_paragraph(random.randint(2, 4), use_opening=use_opening)
        lines.append(format_output(para, fmt))
        lines.append("")
        num_items = random.randint(3, 6)
        if fmt == "html":
            lines.append("<ol>")
        for i in range(num_items):
            item = generate_bullet_item()
            lines.append(format_list_item(item, fmt, numbered=True, index=i+1))
        if fmt == "html":
            lines.append("</ol>")
        lines.append("")

    elif structure == "subheadings":
        num_subs = random.randint(2, 4)
        for _ in range(num_subs):
            subheading = generate_heading()
            lines.append(format_output(subheading, fmt, is_heading=True, heading_level=3))
            lines.append("")
            para = generate_paragraph(random.randint(2, 4))
            lines.append(format_output(para, fmt))
            lines.append("")

    elif structure == "subheadings_mixed":
        # Intro paragraph
        para = generate_paragraph(random.randint(2, 3), use_opening=use_opening)
        lines.append(format_output(para, fmt))
        lines.append("")

        num_subs = random.randint(2, 3)
        for _ in range(num_subs):
            subheading = generate_heading()
            lines.append(format_output(subheading, fmt, is_heading=True, heading_level=3))
            lines.append("")

            # Random content under subheading
            if random.choice([True, False]):
                para = generate_paragraph(random.randint(2, 3))
                lines.append(format_output(para, fmt))
                lines.append("")
            else:
                num_bullets = random.randint(3, 5)
                if fmt == "html":
                    lines.append("<ul>")
                for i in range(num_bullets):
                    item = generate_bullet_item()
                    lines.append(format_list_item(item, fmt, numbered=False, index=i+1))
                if fmt == "html":
                    lines.append("</ul>")
                lines.append("")

    return lines


def main():
    parser = argparse.ArgumentParser(description="Generate lorem ipsum text")
    parser.add_argument("--paragraphs", type=int, default=3, help="Number of paragraphs")
    parser.add_argument("--sentences", type=int, default=5, help="Sentences per paragraph")
    parser.add_argument("--words", type=int, help="Approximate total word count")
    parser.add_argument("--characters", type=int, help="Exact character count (truncates to match)")
    parser.add_argument("--tokens", type=int, help="Estimated LLM token count (~4 chars/token)")
    parser.add_argument("--continuous", action="store_true", help="Continuous text without breaks")
    parser.add_argument("--headings", type=int, help="Number of sections with headings")
    parser.add_argument("--bullets", type=int, help="Bullet points per section")
    parser.add_argument("--numbered", action="store_true", help="Use numbered lists")
    parser.add_argument("--mixed", type=int, help="Generate realistic document with N sections")
    parser.add_argument("--output", "-o", help="Output file path")
    parser.add_argument("--format", "-f", choices=["text", "markdown", "html"], default="markdown")

    args = parser.parse_args()

    # Convert tokens/characters to word count estimate for generation
    # Then we'll truncate to exact character count if needed
    target_chars = None
    if args.characters:
        target_chars = args.characters
        # Estimate words needed: avg ~8 chars per word (including space)
        args.words = (args.characters // 6) + 10  # Generate extra, then truncate
    elif args.tokens:
        target_chars = args.tokens * 4  # ~4 chars per token
        args.words = (target_chars // 6) + 10

    output_lines = []
    use_opening = True

    # Mixed document mode - realistic varied structure
    if args.mixed:
        for section_idx in range(args.mixed):
            heading = generate_heading()
            output_lines.append(format_output(heading, args.format, is_heading=True))
            output_lines.append("")
            section_lines = generate_mixed_section(args.format, use_opening=(section_idx == 0))
            output_lines.extend(section_lines)

    # Structured mode (headings with optional word count target)
    elif args.headings:
        num_headings = args.headings

        # Calculate content per section based on word count or defaults
        if args.words:
            words_per_section = args.words // num_headings
        else:
            words_per_section = None

        for section_idx in range(num_headings):
            heading = generate_heading()
            output_lines.append(format_output(heading, args.format, is_heading=True))
            output_lines.append("")

            if args.bullets:
                # Bullet list mode
                if args.format == "html":
                    tag = "ol" if args.numbered else "ul"
                    output_lines.append(f"<{tag}>")

                num_bullets = args.bullets
                if words_per_section:
                    # Estimate bullets needed for word count
                    words_per_bullet = 7  # average
                    num_bullets = max(args.bullets, words_per_section // words_per_bullet)

                section_words = 0
                for i in range(num_bullets):
                    if words_per_section and section_words >= words_per_section:
                        break
                    item = generate_bullet_item()
                    section_words += len(item.split())
                    output_lines.append(format_list_item(item, args.format, args.numbered, i + 1))

                if args.format == "html":
                    output_lines.append(f"</{tag}>")
                output_lines.append("")
            else:
                # Paragraph mode under headings
                if words_per_section:
                    # Generate paragraphs until word count reached
                    section_words = 0
                    while section_words < words_per_section:
                        para = generate_paragraph(args.sentences, use_opening=use_opening)
                        use_opening = False
                        section_words += len(para.split())
                        output_lines.append(format_output(para, args.format))
                        output_lines.append("")
                else:
                    # Use paragraph count
                    paragraphs_per_section = max(1, args.paragraphs // num_headings)
                    for _ in range(paragraphs_per_section):
                        para = generate_paragraph(args.sentences, use_opening=use_opening)
                        use_opening = False
                        output_lines.append(format_output(para, args.format))
                        output_lines.append("")

    # Plain word count mode (no structure)
    elif args.words:
        words_generated = 0
        paragraphs = []
        while words_generated < args.words:
            para = generate_paragraph(args.sentences, use_opening=use_opening)
            use_opening = False
            paragraphs.append(para)
            words_generated += len(para.split())

        if args.continuous:
            output_lines.append(" ".join(paragraphs))
        else:
            for para in paragraphs:
                output_lines.append(format_output(para, args.format))
                if args.format != "html":
                    output_lines.append("")

    # Standard paragraph mode
    else:
        paragraphs = []
        for _ in range(args.paragraphs):
            para = generate_paragraph(args.sentences, use_opening=use_opening)
            use_opening = False
            paragraphs.append(para)

        if args.continuous:
            output_lines.append(" ".join(paragraphs))
        else:
            for para in paragraphs:
                output_lines.append(format_output(para, args.format))
                if args.format != "html":
                    output_lines.append("")

    # Join and output
    result = "\n".join(output_lines).strip()

    # Truncate to exact character count if specified
    if target_chars and len(result) > target_chars:
        result = result[:target_chars].rstrip()

    if args.output:
        with open(args.output, "w") as f:
            f.write(result)
        print(f"Written to {args.output}")
    else:
        print(result)


if __name__ == "__main__":
    main()

```

lorem-ipsum | SkillHub