Skip to content
Back to skills

003 Name Skill C35ba5c7

ASecurity

Converts a Markdown file to a styled PDF with DevExpert branding (logo in bottom-right corner). Use when asked to generate a PDF from a Markdown document, or when any DevExpert proposal/document needs to be exported as PDF.

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 11, 2026
developmentpythongobash

Security analysis

A96/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro shows the line behind each finding and how to fix it

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 003-name-skill_c35ba5c7 --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 003 Name Skill C35ba5c7?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 003 Name Skill C35ba5c7
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-003-name-skill-c35ba5c7/badge)](https://www.skillsdirectory.com/skills/tools-only-003-name-skill-c35ba5c7)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
---
name: gen-pdf
description: Converts a Markdown file to a styled PDF with DevExpert branding (logo in bottom-right corner). Use when asked to generate a PDF from a Markdown document, or when any DevExpert proposal/document needs to be exported as PDF.
---

# gen-pdf — Generador de PDFs con estilo DevExpert

Convierte cualquier fichero Markdown a PDF con la tipografía, colores y logo de DevExpert.

## Cuándo usar esta skill

- El usuario pide generar un PDF a partir de un fichero `.md`
- Se acaba de crear o actualizar un documento/propuesta y hay que exportarlo
- El usuario pide añadir el logo de DevExpert a un PDF existente

## Dependencias

```bash
pip install markdown-it-py[plugins] weasyprint reportlab PyPDF2
```

## Rutas clave

- **Logo DevExpert:** `assets/devexpert-logo.png` (relativo a la carpeta de esta skill, `~/.claude/skills/gen-pdf/assets/devexpert-logo.png`)
- **Output por defecto:** `~/Documents/aipal/40-archive/`

## Script de generación

Usa el siguiente script Python. Acepta `input_md` y `output_pdf` como variables:

```python
import os
from markdown_it import MarkdownIt
from weasyprint import HTML, CSS
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A4
from PyPDF2 import PdfReader, PdfWriter
import tempfile

md = MarkdownIt("commonmark", {"breaks": True, "html": True}).enable("table")

LOGO_PATH = os.path.expanduser("~/.claude/skills/gen-pdf/assets/devexpert-logo.png")

CSS_STYLES = """
@page { size: A4; margin: 2cm 2.5cm; }
body { font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 10pt; line-height: 1.5; color: #333; }
h1 { color: #1a56a0; font-size: 18pt; border-bottom: 2px solid #1a56a0; padding-bottom: 6px; margin-top: 40px; }
h2 { color: #1a56a0; font-size: 13pt; margin-top: 36px; border-bottom: 1px solid #ccc; padding-bottom: 4px; }
h3 { color: #2c7be5; font-size: 11pt; margin-top: 28px; }
ul { margin: 6px 0 6px 20px; padding: 0; }
li { margin-bottom: 3px; }
table { width: 100%; border-collapse: collapse; margin: 12px 0; font-size: 9.5pt; }
th { background-color: #1a56a0; color: white; padding: 6px 10px; text-align: left; }
td { padding: 5px 10px; border-bottom: 1px solid #ddd; }
tr:nth-child(even) td { background-color: #f5f8ff; }
strong { color: #1a56a0; }
hr { page-break-after: always; border: none; margin: 0; }
blockquote { border-left: 3px solid #2c7be5; padding-left: 12px; color: #555; margin: 8px 0; }
"""

def gen_pdf(input_md, output_pdf, add_logo=True):
    with open(input_md, 'r', encoding='utf-8') as f:
        content = f.read()

    html_content = md.render(content)
    full_html = f'<html><body>{html_content}</body></html>'
    os.makedirs(os.path.dirname(output_pdf), exist_ok=True)
    HTML(string=full_html).write_pdf(output_pdf, stylesheets=[CSS(string=CSS_STYLES)])

    if add_logo:
        reader = PdfReader(output_pdf)
        writer = PdfWriter()
        with tempfile.NamedTemporaryFile(suffix='.pdf', delete=False) as f:
            temp_logo_pdf = f.name

        page_width, page_height = A4
        c = canvas.Canvas(temp_logo_pdf, pagesize=A4)
        c.drawImage(LOGO_PATH, page_width - 120, 15, width=100, height=25,
                   mask='auto', preserveAspectRatio=True)
        c.showPage()
        c.save()

        logo_page = PdfReader(temp_logo_pdf).pages[0]
        for page in reader.pages:
            page.merge_page(logo_page)
            writer.add_page(page)

        with open(output_pdf, 'wb') as out:
            writer.write(out)
        os.unlink(temp_logo_pdf)
```

## Instrucciones de uso

1. Importa o copia la función `gen_pdf` en un script temporal en `/tmp/`
2. Llámala con `input_md` = ruta al fichero Markdown, `output_pdf` = ruta de salida
3. `add_logo=True` por defecto (siempre para documentos DevExpert)
4. Tras generar, copia al directorio temporal de Telegram (`$TMPDIR/aipal/documents/`) y responde con `[[document:/ruta]]`

## Notas

- Los `---` en el Markdown generan saltos de página en el PDF
- Los saltos de línea simples se respetan (comportamiento igual que Obsidian)
- Las tablas Markdown se renderizan correctamente

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.