Refine presentation slides created by translating English source text into Korean into natural Korean, and fix CJK line-breaking issues with CSS.
Resolve bundled scripts relative to this skill directory:
verify.shpolish-loop.sh
Source: https://github.com/hackertaco/skill-forge/tree/main/slide-ko-polish
License: MIT License, Copyright (c) 2026 hackertaco. The full upstream license text is included in LICENSE.
When to Use
- When the Korean on the slides is awkward due to "translationese"
- When line breaks that cut Korean word units in the middle are bothersome
- When you want to keep English abbreviations/predicates (verifier, AC, replay) but make the sentences sound like natural Korean
Don't use for:
- Materials originally written in Korean (a different kind of problem)
- Technical documentation/API reference (accuracy takes priority over sentence flow)
Core Diagnosis — The 3 Major Causes of Awkwardness
- Noun-predicate overuse — Repetition of the "X는 Y입니다" structure → Korean is a verb-centered language
- "~의 / ~을" chains — Sino-Korean nouns strung together with particles → heavy and choppy
- CJK line-breaking default —
word-break: normalBreaks this Hangul at the character level
The 12 Major Signals of Translationese — Suspect Immediately When You See Them
Sources: Hanbit+ "Top 12 Common Translationese", National Institute of Korean Language "English-Korean Translation Translationese Sentences", Woorimal reporter Park Ye-jin.
| Signal | English/Japanese original form | Natural language |
|---|---|---|
| ① Pronoun overuse ("그것", "그", "그 말") | it, this, that | Omission or noun repetition |
| ② Passive overuse ("~되어지다", "위치한다") | passive | Active |
| ③ "~의" overuse | of, の | Spacing or omission |
| ④ "~의 경우" | in case of | Omission |
| ⑤ "~에 대하여" | about | Omit or paraphrase |
| ⑥ "~하고 있는 중" | be -ing | Simple present tense |
| ⑦ "~을 가지다" | have | "있다" |
| ⑧ "~로부터" | from | "에게서", "에서" |
| ⑨ "~을 통해" | through | "써서", "이용해" |
| ⑩ "~에 있어" | in / for | Omission |
| ⑪ "~기 전에" | before -ing | "~지 말고" / "~이 아니라" |
| ⑫ Inanimate subject ("시스템은 ~한다") | inanimate subject | Human subject or imperative |
Additional principles
- Unpack nouns into predicates — End with a verb instead of a Sino-Korean noun + 합니다
- Break "~의 / ~을" chains — If a sentence has 3 or more adverbial phrases, always split it
- Keep English predicates (verifier, AC, replay) as they are — Koreanize them with particles and word order
- Slides are spoken language — If it sounds natural when read aloud, it's OK
- No abstract metaphors — English idioms (
close,ship,land,kill) translated literally becomes ambiguous in Korean as to what it does. Replace it with a concrete verb.- ❌
Phase 1을 **닫는다**(English close translated literally → what are you closing?) - ✅
Phase 1을 **완성한다**(concrete) - ❌
이번 분기에 기능을 **태운다**(ship translated literally) - ✅
이번 분기에 기능을 **출시한다** / **내보낸다** - ❌
버그를 **죽인다**(kill translated literally) - ✅
버그를 **잡는다** / **고친다**
- ❌
Single criterion for judgment
If it sounds awkward when read aloud, it's translationese. + If even one of the above 12 signals appears, awkwardness is confirmed.
CSS is only a safety net — manual control is the right answer for line breaks
Key realization: CSS only guarantees that "it won't break within a word." The browser doesn't know where to break. Korean slides should be broken by semantic units using <br />must be inserted directly.
CSS safety net (essential, apply by default)
body, .slide * {
word-break: keep-all; /* 어절 단위 — 자동 wrap 안전망 */
overflow-wrap: break-word;
line-break: strict;
}
/* 제목·짧은 본문은 balance — 마지막 줄에 단어 하나만 남는 것 방지 */
h1, .lede, .subtitle, .note { text-wrap: balance; }
/* 끊기면 안 되는 표현은 명시적으로 보호 */
.nb { white-space: nowrap; }
3 types of manual control tools
<br />— semantic-unit line break (used most often)<span class="nb">…</span>— expressions that must never be broken (quotations, proper nouns, English predicates that disrupt flow, etc.)max-widthGenerously (52chabout) — minimize automatic wrap triggers. Line breaks should happen only with<br />.
⛔ <br /> Forbidden break points — semantic units broken
Do not insert <br /> right after a particle. In Korean, particle + predicate form one unit (grammatical unit).
| Forbidden pattern | Severity | Why it doesn't work |
|---|---|---|
~을/를<br /> |
FAIL | Object ↔ predicate separation (in Korean they are always a unit) |
~하는/한/할/된/될<br />명사 |
FAIL | Modifier (relative clause) ↔ head noun separation. E.g.: Phase 1을 완성하는<br />세 트랙 |
~이/가<br /> |
WARN | Subject ↔ predicate separation |
~과/와<br /> |
WARN | Noun list broken |
~에<br /> |
WARN | Adverbial phrase ↔ predicate separation |
Caution — ~은/는<br />is not automatically detected. Reason: in Korean, 는/은can be a subject particle or verb conjugation ending, so regex cannot distinguish them. E.g.:
- ❌
말은<br />증거가 아니다(mal + eun = subject particle → awkward) - ✅
Phase 1을 닫는<br />세 트랙(dat + neun = verb ending → natural)
Manual check: 은/는<br /> If found, awkward if the preceding word is a noun, OK if it is a verb stem.
Example:
- ❌
AgentOS는 실행 증거와 verifier 판정, replay 기록을 <br />따로따로 다룹니다. - ✅
AgentOS는 셋을 따로 다룹니다 — <br />실행 증거, verifier 판정, replay 기록. - ❌
AgentOS의 첫 단계가 <br />자리를 잡았습니다. - ✅
AgentOS의 첫 단계가 자리를 잡았습니다.(on one line)
✅ <br /> OK points
- After sentence end (
. <br />,! <br />,? <br />) - After comma (
, <br />) - Use of dash (—) —
X — <br />YNatural break in the form of - Before conjunction (
<br />하지만,<br />그래서)
Automatic detection: verify.sh Stage 1.5 catches the particle +<br /> pattern.
Example of bad automatic wrap
Original: "하지만 시스템은 그 말을 믿기 전에, 증거부터 따로 들여다봐야 합니다."
❌ max-width: 38chIf left as is, the browser will:
하지만 시스템은 그 말을
믿기 전에, 증거부터 따로
들여다봐야 합니다.
"믿기 전에" is separated from "그 말을", breaking the meaning.
✅ Manual <br /> If inserted:
하지만 시스템은 그 말을 믿기 전에,
증거부터 따로 들여다봐야 합니다.
Semantic unit (clause) preserved.
Mandatory Workflow — 4 steps (including verification gate)
Important: Do not separate polishing and verification. polish → verify is one action.
Step 1 — Extraction
WebFetch or read directly and organize the per-slide source text (title/body/bullets) as text
Step 2 — Proofreading
Apply the 11 translationese signal table. Per-slide Before/After.
Step 3 — CSS Patch (if HTML)
word-break: keep-all + text-wrap: balance + <br /> manual line breaks + <span class="nb"> protection
Step 4 — Automated Verification (MANDATORY)
verify.sh <slide-file.html|.md>
Checks the script runs automatically:
- Stage 1 — translationese 11-signal regex scan (outputs line numbers)
- Stage 1.5 — HTML structure (CSS, max-width, particle +
<br />, modifier +<br />+noun, heavy quotation marks, abstract metaphor verbs) - Stage 2 — visual verification command output (manual check)
- Stage 3 — spoken-language test guidance (manual check)
- Stage 4 — LLM Fresh Review (Claude CLI call) — reviews English literal-translation metaphors, awkward expressions, and title-body correspondence with fresh context. Catches awkwardness that regex can't.
Exit code:
0PASS — 0 Stage 1/1.5 signals + Stage 4 PASS1WARN — Stage 1.5 recommendations present or Stage 4 found review items2FAIL — 4 or more signals in Stage 1, Stage 1.5 FAIL pattern found, or missing word-break
If FAIL, always rework. Even with PASS/WARN, Stage 2/3 must be checked manually by a person.
Stage 4 Prompt (Reference)
Stage 4 of verify.sh evaluates with an LLM on the following 5 items:
- Heavy quotation marks + noun phrase fragments
- Abstract metaphor literal translation (literal translations of English close/ship/kill like 닫는다/태우다/죽이다/살아있다)
- English word-order literal translation
- Title-body message mismatch
- Expressions clearly awkward to a Korean speaker
English abbreviations (verifier, AC, replay, etc.) are protected as intentional terminology. Noun phrase enumeration is accepted as a normal slide pattern.
Quick Reference — Frequently Appearing Patterns
| Translationese (Before) | Naturalness (After) |
|---|---|
| "X는 Y입니다" | "X는 Y" (noun ending) or "X가 Y한다" (verbalization) |
| "~을 분리합니다" | "~을 따로따로 다룹니다" |
| "기준선을 만들었습니다" | "자리를 잡았습니다" / "토대를 다졌습니다" |
| "방식의 한계" | "이렇게 해서는 안 되는 이유" |
| "내부 상태입니다" | "안에서만 살아있는 상태입니다" |
| "타입화된 증거" | "타입이 박힌 증거" / "구조화된 증거" |
| "재시작 시 의도 손실" | "재시작하면 사라지는 의도" |
Common Mistakes
word-break: keep-alltrusting only and leaving it to automatic wrap → words are preserved but meaning units aren't, so it's still awkward. Manual<br />must be insertedtext-wrap: prettytrust → prevents "only one word going to the next line" but can't catch meaning-unit breaks. On slides,balanceis safer- Translating even English predicates →
verifier,replay,ACFixed terms like this stay as is - 4 or more bullets on one slide → can't catch your breath. Cut to 3 or fewer or split the slide
- Fix only CSS and leave the text as is → line breaks improve, but translationese remains unchanged
- Fix only the text and leave line breaking to automatic → good sentences get cut off in the wrong place and don't come alive
- You need to nail all three (CSS safety net + natural sentences + manual
<br />) for it to work
Real-World Pattern
Recommended work order for presenters:
- Don't write in English first; say the key point of each slide out loud in Korean, then transcribe it
- If it still doesn't work, use this skill for post-editing
The best is when no trace of translation arises in the first place; this skill is the second best.