FA-80186 / Typography line breaking / Open access
Ties and discretionary hyphens: unbroken discretionary rendering · case 01
Hyphens show inside words that were not broken.
ROOT CAUSE
Discretionary opportunities render a hyphen even when the line continues.
THE FAILURE
Discretionary opportunities render a hyphen even when the line continues.
Unsuccessful approach: Treating discretionaries as spaces splits words visibly.
Case contract
Input [source, width]. Runs of spaces are one breakable space; "~" is an unbreakable space rendered " "; "\-" is a discretionary hyphen: invisible unless the line breaks there, then rendered "-"; "|" is an invisible break opportunity. Greedy: append the next chunk if the line (without a potential hyphen) fits, else break at that opportunity. Return rendered lines.
Why this case matters
Line breaking decides where paragraphs wrap on screen and in print; a wrong decision point shifts every following line.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
src, width = x
chunks = ['']
ops = []
i = 0
while i < len(src):
c = src[i]
if src.startswith('\\-', i):
ops.append('d')
chunks.append('')
i += 2
continue
if c == ' ':
j = i
while j < len(src) and src[j] == ' ':
j += 1
ops.append('s')
chunks.append('')
i = j
continue
if c == '|':
ops.append('z')
chunks.append('')
i += 1
continue
chunks[-1] += ' ' if c == '~' else c
i += 1
line = chunks[0]
lines = []
for op, ch in zip(ops, chunks[1:]):
sep = ' ' if op == 's' else ('-' if op == 'd' else '')
if len(line + sep + ch) <= width:
line = line + sep + ch
else:
lines.append(line + ('-' if op == 'd' else ''))
line = ch
lines.append(line)
return lines
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('discretionary taken', ['the com\\-po\\-si\\-tion', 9], ['the compo-', 'sition']), ('regression: unbroken discretionary rendering', ['ink a a ~hy\\-phen x com\\-po\\-si\\-tion x', 6], ['ink a', 'a hy-', 'phen x', 'compo-', 'sition', 'x']), ('regression: unbroken discretionary rendering', ['Dr.~Knuth url|path a Dr.~Knuth b|c b|c com\\-po\\-si\\-tion', 15], ['Dr. Knuth url', 'path a', 'Dr. Knuth bc bc', 'composition']), ('regression: unbroken discretionary rendering', ['b|c set type set Dr.~Knuth com\\-po\\-si\\-tion Dr.~Knuth x', 15], ['bc set type set', 'Dr. Knuth compo-', 'sition', 'Dr. Knuth x']), ('tie keeps title with name', ['see Dr.~Knuth now', 9], ['see', 'Dr. Knuth', 'now']), ('double space collapses', ['type set', 20], ['type set']), ('control layout', ['word 10~pt 10~pt 10~pt url|path ink', 13], ['word 10 pt', '10 pt 10 pt', 'urlpath ink']), ('control layout', ['type set Dr.~Knuth word word b|c', 12], ['type set', 'Dr. Knuth', 'word word bc'])], [('regression: unbroken discretionary rendering', ['com\\-po\\-si\\-tion ~com\\-po\\-si\\-tion hy\\-phen x url|path ~a a com\\-po\\-si\\-tion', 15], ['composition', ' composition hy-', 'phen x urlpath', ' a a composi-', 'tion']), ('regression: unbroken discretionary rendering', ['com\\-po\\-si\\-tion b|c b|c x x word x', 15], ['composition bc', 'bc x x word x']), ('regression: unbroken discretionary rendering', ['word url|path ~hy\\-phen set a', 14], ['word urlpath', ' hyphen set a']), ('regression: unbroken discretionary rendering', ['com\\-po\\-si\\-tion ~ink word url|path x set', 10], ['composi-', 'tion ink', 'word url', 'path x set']), ('invisible break', ['url|path|x', 5], ['url', 'pathx']), ('tie keeps title with name', ['see Dr.~Knuth now', 9], ['see', 'Dr. Knuth', 'now']), ('control layout', ['b|c b|c type ~hy\\-phen Dr.~Knuth ~ink x a', 15], ['bc bc type hy-', 'phen Dr. Knuth', ' ink x a']), ('control layout', ['Dr.~Knuth ~Dr.~Knuth ~b|c', 15], ['Dr. Knuth', ' Dr. Knuth bc'])], [('regression: unbroken discretionary rendering', ['hy\\-phen ~a 10~pt type type url|path 10~pt type', 9], ['hyphen a', '10 pt', 'type type', 'urlpath', '10 pt', 'type']), ('regression: unbroken discretionary rendering', ['ink x hy\\-phen ~x set type', 12], ['ink x hyphen', ' x set type']), ('regression: unbroken discretionary rendering', ['type 10~pt com\\-po\\-si\\-tion com\\-po\\-si\\-tion type type', 12], ['type 10 pt', 'composition', 'composition', 'type type']), ('regression: unbroken discretionary rendering', ['type x url|path 10~pt hy\\-phen', 14], ['type x urlpath', '10 pt hyphen']), ('double space collapses', ['type set', 20], ['type set']), ('tie keeps title with name', ['see Dr.~Knuth now', 9], ['see', 'Dr. Knuth', 'now']), ('control layout', ['Dr.~Knuth ~Dr.~Knuth ~b|c', 15], ['Dr. Knuth', ' Dr. Knuth bc']), ('control layout', ['a x set', 16], ['a x set'])], [('regression: unbroken discretionary rendering', ['com\\-po\\-si\\-tion x x hy\\-phen Dr.~Knuth Dr.~Knuth com\\-po\\-si\\-tion type set', 14], ['composition x', 'x hyphen', 'Dr. Knuth', 'Dr. Knuth com-', 'position type', 'set']), ('regression: unbroken discretionary rendering', ['a set word hy\\-phen hy\\-phen word url|path', 15], ['a set word hy-', 'phen hyphen', 'word urlpath']), ('regression: unbroken discretionary rendering', ['Dr.~Knuth hy\\-phen word 10~pt Dr.~Knuth word', 11], ['Dr. Knuth', 'hyphen word', '10 pt', 'Dr. Knuth', 'word']), ('regression: unbroken discretionary rendering', ['hy\\-phen ink Dr.~Knuth com\\-po\\-si\\-tion hy\\-phen', 9], ['hyphen', 'ink', 'Dr. Knuth', 'composi-', 'tion hy-', 'phen']), ('tie keeps title with name', ['see Dr.~Knuth now', 9], ['see', 'Dr. Knuth', 'now']), ('discretionary taken', ['the com\\-po\\-si\\-tion', 9], ['the compo-', 'sition']), ('control layout', ['a b|c set', 11], ['a bc set']), ('control layout', ['a ink x 10~pt b|c a', 16], ['a ink x 10 pt bc', 'a'])], [('regression: unbroken discretionary rendering', ['url|path x ~hy\\-phen word com\\-po\\-si\\-tion com\\-po\\-si\\-tion x', 14], ['urlpath x hy-', 'phen word com-', 'position compo-', 'sition x']), ('regression: unbroken discretionary rendering', ['com\\-po\\-si\\-tion ink ~Dr.~Knuth url|path url|path ink b|c word 10~pt', 5], ['compo-', 'si-', 'tion', 'ink', ' Dr. Knuth', 'url', 'path', 'url', 'path', 'ink b', 'c', 'word', '10 pt']), ('regression: unbroken discretionary rendering', ['ink hy\\-phen ~10~pt url|path word ink url|path ~type b|c', 15], ['ink hyphen', ' 10 pt urlpath', 'word ink url', 'path type bc']), ('regression: unbroken discretionary rendering', ['b|c Dr.~Knuth a hy\\-phen a type ~a Dr.~Knuth', 8], ['bc', 'Dr. Knuth', 'a hyphen', 'a type', ' a', 'Dr. Knuth']), ('discretionary taken', ['the com\\-po\\-si\\-tion', 9], ['the compo-', 'sition']), ('tie keeps title with name', ['see Dr.~Knuth now', 9], ['see', 'Dr. Knuth', 'now']), ('control layout', ['Dr.~Knuth ~Dr.~Knuth ~b|c', 15], ['Dr. Knuth', ' Dr. Knuth bc']), ('control layout', ['Dr.~Knuth ~a url|path', 11], ['Dr. Knuth', ' a urlpath'])]]
for label, args, expected in fixtures[N - 1]:
check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| discretionary taken | ['the com-', 'po-si-', 'tion'] | ['the compo-', 'sition'] | Failed |
| regression: unbroken discretionary rendering | ['ink a', 'a hy-', 'phen x', 'com-po-', 'si-', 'tion x'] | ['ink a', 'a hy-', 'phen x', 'compo-', 'sition', 'x'] | Failed |
| regression: unbroken discretionary rendering | ['Dr. Knuth url', 'path a', 'Dr. Knuth bc bc', 'com-po-si-tion'] | ['Dr. Knuth url', 'path a', 'Dr. Knuth bc bc', 'composition'] | Failed |
| regression: unbroken discretionary rendering | ['bc set type set', 'Dr. Knuth com-', 'po-si-tion', 'Dr. Knuth x'] | ['bc set type set', 'Dr. Knuth compo-', 'sition', 'Dr. Knuth x'] | Failed |
| tie keeps title with name | ['see', 'Dr. Knuth', 'now'] | ['see', 'Dr. Knuth', 'now'] | Passed |
| double space collapses | ['type set'] | ['type set'] | Passed |
| control layout | ['word 10 pt', '10 pt 10 pt', 'urlpath ink'] | ['word 10 pt', '10 pt 10 pt', 'urlpath ink'] | Passed |
| control layout | ['type set', 'Dr. Knuth', 'word word bc'] | ['type set', 'Dr. Knuth', 'word word bc'] | Passed |
SHA-256 / 3e31353ef924f22a665b14fabb2e6db7a1eaafdf229b05752f9ffb466bb24071
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
src, width = x
chunks = ['']
ops = []
i = 0
while i < len(src):
c = src[i]
if src.startswith('\\-', i):
ops.append('d')
chunks.append('')
i += 2
continue
if c == ' ':
j = i
while j < len(src) and src[j] == ' ':
j += 1
ops.append('s')
chunks.append('')
i = j
continue
if c == '|':
ops.append('z')
chunks.append('')
i += 1
continue
chunks[-1] += ' ' if c == '~' else c
i += 1
line = chunks[0]
lines = []
for op, ch in zip(ops, chunks[1:]):
sep = ' ' if op != 'z' else ''
if len(line + sep + ch) <= width:
line = line + sep + ch
else:
lines.append(line + ('-' if op == 'd' else ''))
line = ch
lines.append(line)
return lines
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('discretionary taken', ['the com\\-po\\-si\\-tion', 9], ['the compo-', 'sition']), ('regression: unbroken discretionary rendering', ['ink a a ~hy\\-phen x com\\-po\\-si\\-tion x', 6], ['ink a', 'a hy-', 'phen x', 'compo-', 'sition', 'x']), ('regression: unbroken discretionary rendering', ['Dr.~Knuth url|path a Dr.~Knuth b|c b|c com\\-po\\-si\\-tion', 15], ['Dr. Knuth url', 'path a', 'Dr. Knuth bc bc', 'composition']), ('regression: unbroken discretionary rendering', ['b|c set type set Dr.~Knuth com\\-po\\-si\\-tion Dr.~Knuth x', 15], ['bc set type set', 'Dr. Knuth compo-', 'sition', 'Dr. Knuth x']), ('tie keeps title with name', ['see Dr.~Knuth now', 9], ['see', 'Dr. Knuth', 'now']), ('double space collapses', ['type set', 20], ['type set']), ('control layout', ['word 10~pt 10~pt 10~pt url|path ink', 13], ['word 10 pt', '10 pt 10 pt', 'urlpath ink']), ('control layout', ['type set Dr.~Knuth word word b|c', 12], ['type set', 'Dr. Knuth', 'word word bc'])], [('regression: unbroken discretionary rendering', ['com\\-po\\-si\\-tion ~com\\-po\\-si\\-tion hy\\-phen x url|path ~a a com\\-po\\-si\\-tion', 15], ['composition', ' composition hy-', 'phen x urlpath', ' a a composi-', 'tion']), ('regression: unbroken discretionary rendering', ['com\\-po\\-si\\-tion b|c b|c x x word x', 15], ['composition bc', 'bc x x word x']), ('regression: unbroken discretionary rendering', ['word url|path ~hy\\-phen set a', 14], ['word urlpath', ' hyphen set a']), ('regression: unbroken discretionary rendering', ['com\\-po\\-si\\-tion ~ink word url|path x set', 10], ['composi-', 'tion ink', 'word url', 'path x set']), ('invisible break', ['url|path|x', 5], ['url', 'pathx']), ('tie keeps title with name', ['see Dr.~Knuth now', 9], ['see', 'Dr. Knuth', 'now']), ('control layout', ['b|c b|c type ~hy\\-phen Dr.~Knuth ~ink x a', 15], ['bc bc type hy-', 'phen Dr. Knuth', ' ink x a']), ('control layout', ['Dr.~Knuth ~Dr.~Knuth ~b|c', 15], ['Dr. Knuth', ' Dr. Knuth bc'])], [('regression: unbroken discretionary rendering', ['hy\\-phen ~a 10~pt type type url|path 10~pt type', 9], ['hyphen a', '10 pt', 'type type', 'urlpath', '10 pt', 'type']), ('regression: unbroken discretionary rendering', ['ink x hy\\-phen ~x set type', 12], ['ink x hyphen', ' x set type']), ('regression: unbroken discretionary rendering', ['type 10~pt com\\-po\\-si\\-tion com\\-po\\-si\\-tion type type', 12], ['type 10 pt', 'composition', 'composition', 'type type']), ('regression: unbroken discretionary rendering', ['type x url|path 10~pt hy\\-phen', 14], ['type x urlpath', '10 pt hyphen']), ('double space collapses', ['type set', 20], ['type set']), ('tie keeps title with name', ['see Dr.~Knuth now', 9], ['see', 'Dr. Knuth', 'now']), ('control layout', ['Dr.~Knuth ~Dr.~Knuth ~b|c', 15], ['Dr. Knuth', ' Dr. Knuth bc']), ('control layout', ['a x set', 16], ['a x set'])], [('regression: unbroken discretionary rendering', ['com\\-po\\-si\\-tion x x hy\\-phen Dr.~Knuth Dr.~Knuth com\\-po\\-si\\-tion type set', 14], ['composition x', 'x hyphen', 'Dr. Knuth', 'Dr. Knuth com-', 'position type', 'set']), ('regression: unbroken discretionary rendering', ['a set word hy\\-phen hy\\-phen word url|path', 15], ['a set word hy-', 'phen hyphen', 'word urlpath']), ('regression: unbroken discretionary rendering', ['Dr.~Knuth hy\\-phen word 10~pt Dr.~Knuth word', 11], ['Dr. Knuth', 'hyphen word', '10 pt', 'Dr. Knuth', 'word']), ('regression: unbroken discretionary rendering', ['hy\\-phen ink Dr.~Knuth com\\-po\\-si\\-tion hy\\-phen', 9], ['hyphen', 'ink', 'Dr. Knuth', 'composi-', 'tion hy-', 'phen']), ('tie keeps title with name', ['see Dr.~Knuth now', 9], ['see', 'Dr. Knuth', 'now']), ('discretionary taken', ['the com\\-po\\-si\\-tion', 9], ['the compo-', 'sition']), ('control layout', ['a b|c set', 11], ['a bc set']), ('control layout', ['a ink x 10~pt b|c a', 16], ['a ink x 10 pt bc', 'a'])], [('regression: unbroken discretionary rendering', ['url|path x ~hy\\-phen word com\\-po\\-si\\-tion com\\-po\\-si\\-tion x', 14], ['urlpath x hy-', 'phen word com-', 'position compo-', 'sition x']), ('regression: unbroken discretionary rendering', ['com\\-po\\-si\\-tion ink ~Dr.~Knuth url|path url|path ink b|c word 10~pt', 5], ['compo-', 'si-', 'tion', 'ink', ' Dr. Knuth', 'url', 'path', 'url', 'path', 'ink b', 'c', 'word', '10 pt']), ('regression: unbroken discretionary rendering', ['ink hy\\-phen ~10~pt url|path word ink url|path ~type b|c', 15], ['ink hyphen', ' 10 pt urlpath', 'word ink url', 'path type bc']), ('regression: unbroken discretionary rendering', ['b|c Dr.~Knuth a hy\\-phen a type ~a Dr.~Knuth', 8], ['bc', 'Dr. Knuth', 'a hyphen', 'a type', ' a', 'Dr. Knuth']), ('discretionary taken', ['the com\\-po\\-si\\-tion', 9], ['the compo-', 'sition']), ('tie keeps title with name', ['see Dr.~Knuth now', 9], ['see', 'Dr. Knuth', 'now']), ('control layout', ['Dr.~Knuth ~Dr.~Knuth ~b|c', 15], ['Dr. Knuth', ' Dr. Knuth bc']), ('control layout', ['Dr.~Knuth ~a url|path', 11], ['Dr. Knuth', ' a urlpath'])]]
for label, args, expected in fixtures[N - 1]:
check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| discretionary taken | ['the com-', 'po si-', 'tion'] | ['the compo-', 'sition'] | Failed |
| regression: unbroken discretionary rendering | ['ink a', 'a hy-', 'phen x', 'com po-', 'si-', 'tion x'] | ['ink a', 'a hy-', 'phen x', 'compo-', 'sition', 'x'] | Failed |
| regression: unbroken discretionary rendering | ['Dr. Knuth url', 'path a', 'Dr. Knuth bc bc', 'com po si tion'] | ['Dr. Knuth url', 'path a', 'Dr. Knuth bc bc', 'composition'] | Failed |
| regression: unbroken discretionary rendering | ['bc set type set', 'Dr. Knuth com-', 'po si tion', 'Dr. Knuth x'] | ['bc set type set', 'Dr. Knuth compo-', 'sition', 'Dr. Knuth x'] | Failed |
| tie keeps title with name | ['see', 'Dr. Knuth', 'now'] | ['see', 'Dr. Knuth', 'now'] | Passed |
| double space collapses | ['type set'] | ['type set'] | Passed |
| control layout | ['word 10 pt', '10 pt 10 pt', 'urlpath ink'] | ['word 10 pt', '10 pt 10 pt', 'urlpath ink'] | Passed |
| control layout | ['type set', 'Dr. Knuth', 'word word bc'] | ['type set', 'Dr. Knuth', 'word word bc'] | Passed |
SHA-256 / b209126e650abe0c289986df00fafd9a46dedde621629b056608ace2370b0dfb
HELD IN THE MEMBER ARCHIVE
The verified repair and its recorded checks are member-only.
This mechanism has 8 recorded checks per implementation. The open-access tier publishes the failure and the unsuccessful fix; the repaired source that passes every check, and the observations that prove it, are available to members.
Every case sharing this mechanism uses the same contract and the same repair, so this one record is held back for all of them.
Member access is invitation-based. Sign in with your invited account to inspect the repair.
Sign in to the archive ↗Verification & scope
A deterministic toy typesetting model with integer widths and a stipulated rule set; it does not claim conformance to any engine. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.
Observations recorded using Python 3.12.14 at 2026-09-29T14:49:51.559512+00:00.
Case digest / bf04d595ab17fa2c70fae715fdeb9c69f271dd7ec6d641757c0758008f48260a