| name | bookforge |
| description | Generate commercial-book-quality Korean ebook PDFs from a topic or a finished manuscript. Six design styles (practical, insight, academic, essay, business, magazine) with real book anatomy โ cover, TOC with page numbers, chapter openers, running heads, QC gates. Use when the user wants an ebook, a PDF book or report, book typesetting, or mentions ์ ์์ฑ
, PDF ์ฑ
, ์ฑ
์กฐํ, ๋ถํฌ์ง, bookforge. |
bookforge โ ์์
๋์๊ธ ์ ์์ฑ
PDF ๊ณต์ฅ
์ฃผ์ ํ ์ค ๋๋ ์์ฑ ์๊ณ ๋ฅผ ๋ฐ์, ์ค์ ๋จํ๋ณธ ํด๋ถ ๊ตฌ์กฐ(ํ์งยท์ฐจ๋กยท์ฅ ๋๋น๋ผยท๋ฌ๋ ์์คํ
ยทํ๊ถ๋ฉด)๋ฅผ ๊ฐ์ถ PDF๋ฅผ ๋ง๋ ๋ค. ์ฝํ
์ธ ๋ ๋งํฌ๋ค์ด์ผ๋ก๋ง ์ฐ๊ณ , ์กฐํ์ ์คํ์ผ ํฉ๊ณผ ์คํฌ๋ฆฝํธ๊ฐ ์ ๋ดํ๋ค. ํ์ง์ QC ๊ฒ์ดํธ๊ฐ ๋ฌผ๋ฆฌ์ ์ผ๋ก ๊ฐ์ ํ๋ค โ ๊ฒ์ดํธ๋ฅผ ํต๊ณผํ์ง ๋ชปํ PDF๋ final/์ ์กด์ฌํ ์ ์๋ค.
์ด ํ์ผ์ ๊ฒฝ๋ก๊ฐ <SKILL>์ด๋ค. ๋ชจ๋ ๋ช
๋ น์ <SKILL>์ ์ด ์คํฌ ํด๋์ ์ ๋ ๊ฒฝ๋ก๋ก ์นํํด ์คํํ๋ค.
์คํ ์ ์ ๊ฒ
typst --version
python3 -c "import pymupdf, markdown_it"
npm root -g >/dev/null
node -e "require(require('child_process').execSync('npm root -g').toString().trim()+'/playwright')" \
|| npm i -g playwright
npx playwright install chromium
ls <SKILL>/vendor/antv-ssr.bundle.mjs \
|| (cd <SKILL> && npm ci && node vendor/build-bundle.mjs)
์๋ ๊ฒ์ด ์์ผ๋ฉด ์ฌ์ฉ์์๊ฒ ์ค์น๋ฅผ ์์ฒญํ๊ณ ์ค๋จํ๋ค. HTML ํธ๋ยท๋ํด ์์ด Typst 4์คํ์ผ๋ง ์ธ ๊ฑฐ๋ผ๋ฉด playwrightยทChromiumยทnpm ci๋ ์๋ต ๊ฐ๋ฅ.
ํ์ดํ๋ผ์ธ (์ฒดํฌ๋ฆฌ์คํธ๋ฅผ ๋ณต์ฌํด ์งํํ๋ฉฐ ์ฒดํฌ)
[ ] P0 ๊ณ์ฝ: ๋ชจ๋ยท์คํ์ผยท๋ถ๋ ํ์ โ ์ฑ
ํ๋ก์ ํธ ์ค์บํด๋
[ ] P1 ์ฝํ
์ธ : outline.json + chapters/ch-NN.md ์์ฑ
[ ] P1.5 ๋ํด(์ ํ): diagrams/fig-NN.json ์์ฑ โ build.py๊ฐ ์๋ ํ๋ฆฌ๋ ๋ (๊ณ์ฝ: references/diagrams.md)
[ ] P2-3 ๋น๋: build.py โ draft/book.pdf
[ ] P4 ๊ฒ์ดํธ: qc_gate.py PASS โ final/ ์์ฑ ํ์ธ
[ ] P5 ์๊ฐ ๊ฒ์: contact_sheet.py โ ํ์งยท์ฐจ๋กยท๋๋น๋ผยท๋ณธ๋ฌธ 4๋ฉด ์ด์ ๋์ผ๋ก ํ์ธ
P0 โ ๊ณ์ฝ
- ๋ชจ๋ ๊ฐ์ง: ์ฌ์ฉ์๊ฐ ์๊ณ ํ์ผ(md/txt/docx)์ ์คฌ์ผ๋ฉด manuscript ๋ชจ๋ โ modes/manuscript.md๋ฅผ ์ฝ๊ณ ๋ฐ๋ฅธ๋ค. ์ฃผ์ ยท์์ด๋์ด๋ง ์คฌ์ผ๋ฉด topic ๋ชจ๋ โ modes/topic.md๋ฅผ ์ฝ๊ณ ๋ฐ๋ฅธ๋ค.
- ์คํ์ผ ์ ํ: ์ฌ์ฉ์๊ฐ ์ง์ ํ์ง ์์์ผ๋ฉด ์๋ ํ์์ ๋ด์ฉ ์ฑ๊ฒฉ์ ๋ง๋ ๊ฒ์ ๊ณจ๋ผ ์งํํ๋ค(์ง๋ฌธํ์ง ์๋๋ค).
| ์คํ์ผ | ์ฑ๊ฒฉ | ํํ | ์์ง |
|---|
practical | ITยท์ค์ฉ ํ์ฉ์, ๋จ๊ณ๋ณ ๊ฐ์ด๋, ์ฉ์ด์ง | 153ร225 | typst |
insight | ๊ธฐ์ ๋ํฅยท์ธ์ฌ์ดํธ ๋ฆฌํฌํธ, ๋ฐ์ดํฐ ๋ธ๋ฆฌํ | 182ร257 | html |
academic | ํ์ ๋จํ๋ณธ, ์ฐ๊ตฌ ๊ฐ๋ก , ์ด๋ก ์ | 153ร225 | typst |
essay | ์ฐ๋ฌธ์ง, ํ๊ณ , ๋ฌธํ์ ๊ธ | 128ร188 | typst |
business | ์ปจ์คํ
๋ฆฌํฌํธ, ์์ฅ ๋ถ์, ์ ๋ต ๋ฐฑ์ | 200ร280 | typst |
magazine | ํธ๋ ๋๋ถ, ํ๋ ์ด์
, ๋ฃฉ๋ถ | 200ร265 | html |
- ์ค์บํด๋ (์ฑ
ํ๋ก์ ํธ๋ ์คํฌ ํด๋ ๋ฐ ์์
๋๋ ํ ๋ฆฌ์ ๋ง๋ ๋ค):
python3 <SKILL>/scripts/scaffold.py <book_dir> --style practical \
--title "์ ๋ชฉ" --subtitle "๋ถ์ " --length short --author "์ ์" --date "2026-08"
--length: short/standard/long โ ์ชฝ์ ๋ฒ์์ ์ ๋ณธ์ ๊ฐ ์คํ์ผ tokens.json์ length_pages(short๋ ์คํ์ผ๋ณ 22~70์ชฝ ๋์ญ, INV-1์ ๋ฐ๋ผ ์ฐ์ถ๋ฌผ ์ชฝ์๋ WARN๋ง). --brand "#hex"๋ก ๋ธ๋๋์ ๊ต์ฒด, --images vector|generated|none์ผ๋ก ์ด๋ฏธ์ง ์ ์ฑ
(๋ฒกํฐ๋งยท์์ฑ ์ํธ ํฌํจยท์์) ์ง์ .
P1 โ ์ฝํ
์ธ ๊ณ์ฝ
outline.json์ ๊ฐ ์ฅ์ fileยทtitleยทsummary(๋๋น๋ผ์ ์ค๋ฆฌ๋ 1~2๋ฌธ์ฅ)๋ฅผ ์ฑ์ฐ๊ณ , chapters/ch-NN.md๋ฅผ ์๋ ๋ฌธ๋ฒ๋ง์ผ๋ก ์ด๋ค:
# ์ฅ์ ๋ชฉ(ํ์ผ๋น 1๊ฐ, outline์ title๊ณผ ์ผ์น) / ## ์ / ### ์์ ๋ชฉ
- ๋ฌธ๋จ,
**๋ณผ๋**, ๋ฆฌ์คํธ, > ์ธ์ฉ, GFM ํ, ``` ์ฝ๋๋ธ๋ก
- ์ด๋ฏธ์ง:
 โ ํ์ผ์ <book_dir>/assets/์ ๋จผ์ ๋ฃ๊ณ , ๋ฐ๋์ ../assets/ ๊ฒฝ๋ก + ์ด๋ฏธ์ง ๋จ๋
๋ฌธ๋จ์ผ๋ก ์ด๋ค(ํ
์คํธ๊ฐ ์์ด๋ฉด ์กฐํ์์ ์กฐ์ฉํ ์ฆ๋ฐ)
- ๋ฒกํฐ ๋ํด 2ํธ๋: โ ์์ ์๊ฐํ๋
diagrams/fig-NN.json(AntV DSL ์ฌ์ด๋์นด) โก ๊ธฐ์ ๋ํด(์ํ์คยท์ํ๋จธ์ ยทERยท์ค์๋ฐ๋ ์ธยท๊ฐํธ ๋ฑ)๋ SVG๋ฅผ ์ง์ ๊ทธ๋ ค diagrams/fig-NN.svg + ์ฌ์ด๋์นด {"kind":"authored"}. ๋น๋๊ฐ ์ ๊ทํํด assets/fig-NN.svg๋ก ์ฐ์ถ. ๋ณธ๋ฌธ ์ฐธ์กฐ๋ . ์์ฑ ๊ณ์ฝยทํ์
๋ผ์ฐํ
ยท์ปค๋ฅํฐ ๊ท์นยท๋ณต์ก๋ ์์ฐ์ references/diagrams.md๊ฐ ์ ๋ณธ
- ์ฝ์์(์ค ๋จ์ ๋๋ ํฐ๋ธ):
::: tip ์ ๋ชฉ
๋ด์ฉ (stat์ ์ฒซ ์ค=์์น, ๋์งธ ์ค=์ค๋ช
)
:::
์ข
๋ฅ info|tip|warn|quote|stat|pull(pull์ magazine ํํํธ โ ๋ณธ๋ฌธ์ ์ค์ฌํ๋ ๋ฌธ์ฅ๋ง, ์๋ ์ธ์ฉ์ G10 ํ๋ ์คํจ).
- ํ ์บก์
: ํ ๋ฐ๋ก ์ ๋ฌธ๋จ์
[ํ] ์ ๋ชฉ | ์๋ฃ: ์ถ์ฒ ํ ์ค โ ์ด ์ค์ ์ค ํ๋ง ๋ฒํธ ๋ผ๋ฒจ์ด ๋ถ๋๋ค. ์บก์
์๋ ํ๋ ๋ผ๋ฒจ ์์ด ๋ ๋๋๋ค(์๋ ํ๋ฌ ์บก์
์ ์กด์ฌํ์ง ์๋๋ค).
stat์ ์์น๋ ๊ฐ์ ์ฅ ๋ณธ๋ฌธ์ ์ค์ฌํด์ผ ํ๋ค(G10) โ ๋ฐ์ค์๋ง ์๋ ์ซ์๋ ๋ ์กฐ๋ก ํ์ ๋๋ค.
ํ์งยท๋๋น๋ผ์ฉ ์์ฑ ์ํธ๋ฅผ ์ธ ๊ฒฝ์ฐ references/art-policy.md๋ฅผ ์ฝ๊ณ ๋ฐ๋ฅธ๋ค(๋ฌดํ
์คํธ ์์น).
์๋ฃ ๊ธฐ์ค: outline์ ๋ชจ๋ ์ฅ ํ์ผ์ด ์กด์ฌํ๊ณ , ๊ฐ ํ์ผ ์ฒซ ์ค์ด # {title}์ด๋ฉฐ, ๋ถ๋ ํ๋ฆฌ์
์ ๋ง๋ ์ด ๊ธ์์(short ๊ธฐ์ค ๋ณธ๋ฌธ 1.0๋ง2.1๋ง ์ = ์ฅ 57๊ฐ ร 2,000~3,000์ โ modes/topic.md์ ๋์ผ ๊ธฐ์ค)๋ฅผ ๊ฐ์ถ๋ค. ๊ฐ ์ฅ์ toc_line(๋ชฉ์ฐจ ์ ์ฉ ์๊ฒฐ ์นดํผ ํ ์ค)์ ์ฑ์ด๋ค โ ์์ผ๋ฉด summary ์ 40์๊ฐ ์๋ ค ์ค๋ฆฐ๋ค.
P2-4 โ ๋น๋์ ๊ฒ์ดํธ
python3 <SKILL>/scripts/build.py <book_dir>
python3 <SKILL>/scripts/qc_gate.py <book_dir>
๊ฒ์ดํธ: G10 ์ธ์ฉยท์์น ์ค์ฌ(๋ ๋ ์ ) / G0 ๋ํด SVG ์์ค(๋ ๋ ์ โ foreignObjectยท์ธ๋ถ์ฐธ์กฐยท๋จ๋
๋ฌธ๋จยท์์ด์ฝ ํ๋ฝ) / G1 ๋ ๋ยทํํ(tokens trim_mm ๋์กฐ)ยท๋ณธ๋ฌธ ๊ธ์(tokens body_pt ยฑ0.3pt โ ์ ์ญ ์ถ์ ์ฐจ๋จ)ยท๋ถ๋๋ฒ์(WARN โ --strict-pages๋ง HARD) / G2 ํฐํธ ์๋ฒ ๋+Type3 0 / G3 ๋ฉด ๊ธฐํ 3์ถ(OVERFLOW ์ฌ๋จ ๋ฐ bbox 0 ยท COLLIDE ํ
์คํธ ๋ผ์ธ ๊ต์ฐจ 0 ยท FIT ์๋ถ์ ํ
์คํธ๊ฐ tokens front_frame_mm ์) / G4 ๋ชฉ์ฐจยท๋ถ๋งํฌ ์ ํฉ / G7 ๋ฐ๋(๋ฐฑ๋ฉดยท๊ผฌ๋ฆฌ ์ฑ์ยทํ๋ฉด ๋๋ฆฌํํธ) / G8 ๊ณต๊ธฐ ์ฑ์ / G9 ์ ๋ชฉ ๊ณ ๋ฆฝยทwidow / G11 ์ฌ์ ์ฝ๋ ๋ฌด๊ฒฐ์ฑ / G12 ํ๋ฌ ๋ฐฑ๋ฉด / G13 ๋ํด ๋ผ๋ฒจ PDF ์ค์ฌ / G17 ๋ํด ๋ฉด ์ ํฉ(figure๊ฐ ํ ๋ฉด ์ โ ๋ฉด ๋ถ๋จยทํ๋ฉด ์ด๊ณผยทdiagram.maxHeightMm ๋์กฐ) / G14 ๋ชฉ์ฐจยท๋์์ธ ์ ํฉ(์ธ์ ๋ชฉ์ฐจ ์ชฝ๋ฒํธโํด๋ฆฌ์คยท๋ชฉ์ฐจโ๋๋น๋ผ ์ ๊ณ์ดยทํ
์คํธ ๋๋น ํํ) / G16-TOKENS ์คํ์ผ ํฉ ํ ํฐ ๊ณ์ฝ 3์ถ(SYNC ์ยท์์น ๊ณ์ฝ ์ ํฉ โ palette_rolesยทfront_frame_mm ์ ์ธ๊ฐ ํ๋น์ฑ ํฌํจ / CONTRAST ์ ์ธ ํ์ด์ WCAG ๋๋น / BRAND ๋ธ๋๋ ์
๋ ฅ ์ฌ์ ๊ฒ์ฆ) / G16-LINT contrast_contract โ theme.cssยท๋ ๋ DOM ์ค๋ฌผ ๋์กฐ(html ์์ง ํ์ โ pt ์ ํฉยท๊ฐ ์ปค๋ฒ๋ฆฌ์ง๋ HARD, ์์ ์ฑ์ WARN). ๊ธฐ์ค ์์น์ ๋์๋ฒ์ references/pagination.md๊ฐ ์ ๋ณธ์ด๋ค.
์คํจ ์ gate-report.json์ ์์ธ ํญ๋ชฉ๋ง ๊ณ ์น๊ณ ์ฌ์คํํ๋ค. ์์ธ โ G16-TOKENS: ์ด ์ถ๋ง build.py๊ฐ ๋ ๋ ์ ์ ๊ทธ ์๋ฆฌ์์ ์ค๋จ์ํค๋ฏ๋ก ๊ทธ ์์ ์ gate-report.json์ด ์์ง ์๋ค(์๋ค๋ฉด ์ด์ ์คํ์ ๋ก์ ํ์ผ์ด๋ค). stderr์ ์ฐํ ์ถยท์ฌ์ ๋ฅผ ์ฝ๊ณ styles/<style>/tokens.json์ ๊ณ ์น ๊ฒ โ ๊ฒ์ดํธ ๋ฆฌํฌํธ๋ฅผ ์ฐพ์ง ๋ง ๊ฒ. ๊ธ์ง ๋์: ๋ถ๋ ๋ฏธ๋ฌ์ ๋ถ๋กยท์ฉ์ด์ง ์ถ๊ฐ๋ก ๋ฉ์ฐ๊ธฐ, ์ ๋ณ ๊ฐ์ ๊ฐ๋ฉด, ๋น ์คยทํ๊ฐ ํ๋๋ก ๋ฉด ์ฑ์ฐ๊ธฐ โ ์ ๋ถ ๊ฒ์ดํธ๊ฐ ๋ค์ ์ก๋๋ค. ์ฌ๋ฐ๋ฅธ ๋์: G7 ๊ผฌ๋ฆฌ ๋ฏธ๋ฌ์ python3 <SKILL>/scripts/refit.py <book_dir>(์๊ฐ ๋ฏธ์ธ์กฐ์ ์๋ ํ์) โ ํด ์์ผ๋ฉด ๋ฌธ๋จ 1~2๊ฐ ๊ตญ์ ์ฆ๊ฐ ๋๋ pageroles.json ์ฌ์ ์ฝ๋(์๋๋ ์ฌ๋ฐฑ ์ ์ธ, G11์ด ์ง์ ๊ฒ์ฆ). ๊ฐ์ ๊ฒ์ดํธ 3ํ ์ฐ์ ์คํจ๋ฉด ์์ธ์ ์ฌ์ฉ์์๊ฒ ๋ณด๊ณ ํ๋ค.
P5 โ ์๊ฐ ๊ฒ์ (ํ์, ์๋ต ๊ธ์ง)
python3 <SKILL>/scripts/contact_sheet.py <book_dir>/final/*.pdf <book_dir>/qc --dpi 90 --pages 1,2,3,4,5
ํ์งยท์ฐจ๋กยท๋๋น๋ผยท๋ณธ๋ฌธ ํผ์นจ๋ฉด PNG๋ฅผ ์ง์ ์ด์ด ๋ณด๊ณ ํ๋จํ๋ค: ๊ธ์ ๊ฒน์นจ ์์, ๋ชฉ์ฐจ ์ชฝ๋ฒํธ=์ค์ ์ชฝ, ๋๋น๋ผ ์คํ์ผ ์ฑ๋ฆฝ, ๋ณธ๋ฌธ ์ฌ๋ฐฑ ๋ฆฌ๋ฌ ์ ์. ์ด์์ด ์์ผ๋ฉด ์ฝํ
์ธ (md)๋ book.json์ ๊ณ ์ณ P2-4๋ฅผ ์ฌ์คํํ๋ค. ํ์ผ์ด ์์ฑ๋์๋ค๋ ๊ฒ์ ์๋ฃ๊ฐ ์๋๋ค โ ๋์ผ๋ก ๋ณธ ๊ฒ๋ง ์๋ฃ๋ค.
๋ ์ฝ์ ๊ฒ (ํ์ํ ๋๋ง)
- modes/topic.md โ ์ฃผ์ ๋ง ๋ฐ์์ ๋: ์กฐ์ฌโ๋ชฉ์ฐจโ์งํ ์ ์ฐจ
- modes/manuscript.md โ ์๊ณ ๋ฅผ ๋ฐ์์ ๋: ์ธ์ ์คํธยท์ฅ ๋ถํ ์ ์ฐจ
- references/pagination.md โ ๋ฐฐ์น ๊ท์น์(์ ๋ณธ): ์ฑ์/๋น์์ ์ฌ์ , ๋ ๋ฒ ์ฌ๋ค๋ฆฌ, ๋ฐ๋ ๊ฒ์ดํธ ์์น, ์ฌ์ ์ฝ๋
- references/art-policy.md โ ์์ฑ ์ํธ(ํ์งยท๋๋น๋ผ) ๊ท์น: ๋ฌดํ
์คํธ ์์น, ์คํ์ผ๋ณ ์ฌ์ฉ์ฒ
- references/orchestration.md โ (Claude Code ์ ์ฉ, ์ ํ) ์ฅ๋ณ ์งํ์ codex ์ค์ยท์๋ธ์์ด์ ํธ๋ก ๋ณ๋ ฌํํ๋ ๋ฒ
- references/extending.md โ ์ ์คํ์ผ ํฉ ์ถ๊ฐยทํ
๋ง ์์ ๊ฐ์ด๋
styles/<์ด๋ฆ>/STYLE.md โ ๊ฐ ์คํ์ผ์ ์ ์ฒด ๋์์ธ ๊ท์น์(์งํ ์ ํคยท๊ตฌ์ฑ ์ฐธ๊ณ )