Skip to content

Repository files navigation

PosterScript

LLM이 포스터를 생성하고, 텍스트만 정확히 수정하고, PNG로 내보내는 오픈 텍스트 포맷


왜 PosterScript인가

AI로 포스터를 만들 때 기존 방식은 한계가 있습니다.

방법문제점
AI 이미지 생성글자 하나 바꾸면 전체 재생성, 디자인이 달라짐
HTML/CSS 생성AI가 레이아웃 계산 실수, 픽셀 단위 오류 잦음
PosterScript.poster 파일이 상태로 존재 → content만 수정, 디자인 100% 유지

PosterScript는 선언형 텍스트 포맷입니다. AI가 생성하기 쉽고, 사람이 읽기 쉽고, 렌더러가 결정론적으로 그립니다.

동작 방식

사용자: "콘서트 포스터 만들어줘"
→ LLM이 .poster 파일 생성
사용자: "날짜를 9월로 바꿔줘"
→ LLM이 해당 @text의 content 한 줄만 수정
→ 렌더러가 그 텍스트만 업데이트
→ 레이아웃, 색상, 폰트 등 나머지 디자인 그대로 유지
사용자: "PNG로 저장해줘"
→ exportPNG() → 2배 해상도로 다운로드

빠른 예시

@canvas
size: 800x1100
@bg
color: #070010
@image
id: hero
src: https://images.unsplash.com/photo-1493225457124?w=800
x: 0 y: 0 w: 100% h: 60%
fit: cover
opacity: 0.75
@shape
id: gradient-fade
x: 0 y: 45% w: 100% h: 55%
fill: linear-gradient(to bottom, transparent, #070010 60%)
@text
id: title
@editable
content: NOVA ECLIPSE
x: 40 y: 660
font: Bebas Neue
size: 80
color: #ffffff
tracking: 2
@text
id: date
@editable
content: 2025년 9월 20일
x: 40 y: 770
font: Noto Sans KR
size: 16
color: rgba(255,255,255,0.6)

@editable 플래그가 붙은 블록의 content만 수정하면 디자인이 유지됩니다.


패키지 구조

posterscript/
├── packages/
│ ├── parser/ # @posterscript/parser — .poster → AST (zero deps)
│ ├── renderer/ # @posterscript/renderer — AST → DOM + PNG 내보내기
│ ├── cli/ # posterscript CLI — 생성, 검증, 렌더, 내보내기
│ └── share-server/ # @posterscript/share-server — 공유 링크 API
├── playground/ # 웹 에디터 + 실시간 미리보기
├── examples/ # 예시 .poster 파일
│ ├── concert.poster
│ ├── product.poster
│ └── minimal.poster
├── docs/
│ ├── SPEC.md # 언어 스펙 (source of truth)
│ ├── LLM_SYSTEM_PROMPT.md # AI 앱 연동용 시스템 프롬프트
│ └── START_PROMPT.md # Claude Code 개발 시작 프롬프트
└── spec/
└── POSTERSCRIPT.md # 영문 스펙

시작하기

요구사항

  • Node.js 20+
  • pnpm 9+

설치 및 실행

git clone https://github.com/your-org/posterscript.git
cd posterscript
pnpm install
# 터미널 1: 공유 서버 (포트 4000)
pnpm --filter @posterscript/share-server dev
# 터미널 2: 플레이그라운드 (포트 5173)
pnpm dev

http://localhost:5173 에서 에디터 + 실시간 미리보기를 사용할 수 있습니다.

CLI로 포스터 생성

# ANTHROPIC_API_KEY 환경변수 필요export ANTHROPIC_API_KEY=sk-ant-...
npx posterscript generate "미니멀 재즈 콘서트 포스터"
Generating poster...
✓ poster.poster 생성됨
▶ playground에서 확인:
http://localhost:5173/playground?p=aB3xK9
(링크는 24시간 후 만료됩니다)

--out jazz.poster 로 출력 파일명을 지정하거나, --no-open 으로 브라우저 자동 열기를 끌 수 있습니다.


언어 스펙

전체 스펙은 docs/SPEC.md를 참조하세요.

블록 타입

블록설명필수 속성
@canvas캔버스 크기 (파일 맨 앞, 필수)size (WxH)
@bg배경색 또는 배경 이미지
@image이미지 요소id, src, x, y, w, h
@text텍스트 요소id, content, x, y
@shape도형 (사각형, 선, 오버레이 등)id, x, y, w, h

좌표 & 단위

  • 숫자만 쓰면 px: x: 40 → 40px
  • %를 붙이면 캔버스 기준: w: 100% → 캔버스 전체 너비
  • x, w → 캔버스 너비 기준 / y, h → 캔버스 높이 기준

주요 속성

@text 전체 속성 목록
속성타입기본값설명
idstring(필수)고유 식별자
contentstring(필수)텍스트 내용 (\n으로 줄바꿈)
x, ypx | %(필수)위치
w, hpx | %auto크기
fontstringsans-serifGoogle Fonts 이름
sizenumber16폰트 크기 (px)
weight100–900400굵기
colorhex | rgb() | rgba()#000000글자색
alignleft | center | rightleft가로 정렬
valigntop | middle | bottomtop세로 정렬
line-heightnumber1.35행간 배수
trackingnumber0자간 (px)
uppercasetrue | falsefalse대문자 변환
opacity0–11투명도
rotationnumber0회전 (도)
bghex | rgb()텍스트 배경색 (버튼 스타일)
radiusnumber0배경 모서리 둥글기

렌더링 순서

블록이 선언된 순서대로 그립니다. 나중에 선언된 블록이 위에 그려집니다.

@editable 플래그

@text
id: artist-name
@editable ← 이 플래그가 있으면
content: NOVA ECLIPSE ← LLM이 이 값만 수정 가능
x: 40 y: 660 ← 나머지 속성은 절대 건드리지 않음
size: 80
color: #ffffff

Playground 기능

Canva 스타일 비주얼 에디터

Playground는 코드 에디터와 캔버스가 양방향 동기화됩니다.

[코드 에디터] ←→ [비주얼 캔버스]
↕ ↕
코드 수정 → 캔버스 즉시 반영
캔버스 조작 → 코드 자동 업데이트

인터랙션

기능동작
선택요소 클릭. Shift+Click으로 다중 선택
이동선택 후 드래그. 다중 선택 시 그룹 이동
리사이즈8개 핸들 드래그. Shift로 비율 유지 (최소 20x20px)
회전상단 원형 핸들 드래그. Shift로 15도 단위 스냅
텍스트 편집@editable 텍스트 더블클릭 → 직접 편집
스냅다른 요소 가장자리, 캔버스 중앙에 자동 정렬
그리드16px 격자 표시 + 그리드 스냅 (토글)

키보드 단축키

단축키기능
Arrow선택 요소 1px 이동
Shift + Arrow10px 이동
Delete / Backspace선택 요소 삭제
Ctrl+D선택 요소 복제
Ctrl+A전체 선택
Ctrl+Z실행 취소
Ctrl+Shift+Z / Ctrl+Y다시 실행
[ / ]레이어 순서 변경 (앞으로/뒤로)
Ctrl+Enter즉시 렌더링

패널

  • Properties: 선택 요소의 X, Y, W, H, Rotation, Opacity 직접 입력
  • Layers: 모든 블록을 z-order 순으로 표시, 클릭으로 선택
  • Status Bar: 캔버스 크기, 블록 수, 경고 표시

내보내기 & 공유

  • PNG 저장: html2canvas로 2배 해상도 PNG 다운로드
  • 링크 공유: share-server에 업로드 → ?p=ID URL 클립보드 복사 (24시간 유효)

LLM 연동

docs/LLM_SYSTEM_PROMPT.md의 내용을 시스템 프롬프트에 넣으면 Claude, GPT 등 어떤 LLM이든 PosterScript 포맷으로 포스터를 생성/수정합니다.

생성 규칙

  • 모든 사용자 텍스트에 @editable 플래그 추가
  • Unsplash 실제 이미지 URL 사용
  • 레이어 순서: @bg@image@shape 오버레이 → @text
  • 캔버스 크기: 세로 420x600, 가로 600x420

수정 규칙

  • @editable 블록의 content 변경
  • x, y, size, color, font 등 다른 속성은 절대 변경하지 않음
  • @editable이 아닌 블록은 건드리지 않음
  • 수정된 전체 .poster 파일을 반환

CLI

posterscript <command> [options]
명령어설명상태
generate <prompt>Claude API로 포스터 생성구현됨
validate <file>.poster 파일 검증미구현
render <file>브라우저 실시간 미리보기미구현
export <file>PNG/PDF 내보내기미구현

generate 옵션

--out <file> 출력 파일명 (기본: poster.poster)
--no-open 브라우저 자동 열기 비활성화

생성된 포스터는 자동으로 share-server에 업로드되고, playground URL이 출력됩니다.


Share Server

.poster 파일을 공유할 수 있는 간단한 REST API 서버입니다.

API

엔드포인트설명
POST /share{ content: string }{ id, url } (6자 ID, 24시간 TTL)
GET /share/:id{ content: string } 또는 404
  • Hono + Node.js
  • 메모리 저장 (서버 재시작 시 초기화)
  • CORS 전체 허용

배포

share-server → Railway

pnpm --filter @posterscript/share-server build
cd packages/share-server
railway up

Railway 대시보드에서 환경변수 설정:

PORT=4000
PLAYGROUND_URL=https://your-playground.vercel.app

share-server → Docker

pnpm --filter @posterscript/share-server build
docker build -f packages/share-server/Dockerfile -t posterscript-share .
docker run -p 4000:4000 \
-e PLAYGROUND_URL=https://your-playground.vercel.app \
posterscript-share

playground → Vercel / Netlify

빌드 후 playground/dist/ 를 정적 호스팅합니다.

VITE_SHARE_SERVER_URL=https://your-server.railway.app pnpm build

환경변수

변수사용처기본값설명
PORTshare-server4000서버 포트
PLAYGROUND_URLshare-serverhttp://localhost:5173공유 링크에 포함될 playground URL
VITE_SHARE_SERVER_URLplaygroundhttp://localhost:4000playground → share-server 호출 URL
SHARE_SERVER_URLCLIhttp://localhost:4000CLI → share-server 호출 URL
ANTHROPIC_API_KEYCLIClaude API 키

.env.example 파일을 .env로 복사해서 사용하세요.


기술 스택

영역기술
패키지 매니저pnpm workspaces
언어TypeScript (strict)
파서Zero-dependency, never throws
렌더러Vanilla JS, position: absolute 기반
폰트Google Fonts 동적 로드
PNG 내보내기html2canvas
플레이그라운드Vite + Vanilla JS
CLICommander + Anthropic SDK
공유 서버Hono + nanoid
빌드tsup
테스트Vitest

개발 명령어

pnpm install # 의존성 설치
pnpm dev # playground 개발 서버
pnpm build # 전체 빌드
pnpm test# 전체 테스트
pnpm test:parser # parser만 테스트

라이선스

MIT

About

LLM이 포스터를 생성하고, 텍스트만 정확히 수정하고, PNG로 내보내는 오픈 포맷

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages