A compound separator pairs the two sides too

"Do's, and Don'ts" and "Do and/or Don't" put a comma and a conjunction, or
a conjunction and a slash, between the two halves, and a joiner that
accepted exactly one token read those headings as negative and dropped the
classes their "Do" sections sanction. One joiner or several, up to four.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LQBUunp8QttxZqihybNmtL
This commit is contained in:
Paul Bakaus
2026-09-20 19:51:21 -07:00
co-authored by Claude Fable 5.1
parent 6233ba2e89
commit c97ed90df0
+10 -1
View File
@@ -83,7 +83,10 @@ re!(
// we don't do" also put a `do` beside a `don't`, and they mean only the one
// thing.
re!(DESIGN_BOTH_SIDES_HEADING, {
let joiner = format!(r"{WS}*(?:and|or|&|/|\||\+|,|vs\.?|versus){WS}*", WS = WS);
// One joiner or several: "Do's, and Don'ts" and "Do and/or Don't" pair
// the two sides with a comma plus a conjunction and with a conjunction
// plus a slash.
let joiner = format!(r"(?:{WS}*(?:and|or|&|/|\||\+|,|vs\.?|versus)){{1,4}}{WS}*", WS = WS);
let affirmative = r"\bdo'?s?\b";
let negative = r"\b(?:do ?n[o']?ts?|do not)\b";
format!("(?i)(?:{affirmative}{joiner}{negative}|{negative}{joiner}{affirmative})")
@@ -2166,6 +2169,12 @@ mod tests {
### Don't\n\n- Reach for `.eyebrow`.\n";
assert_eq!(declared_component_selectors(md), vec![".kicker"]);
// Compound separators pair the two sides just as well.
for heading in ["Do's, and Don'ts", "Do and/or Don't", "Don'ts / Dos"] {
let md = format!("## {heading}\n\n### Do\n\n- Use `.kicker`.\n");
assert_eq!(declared_component_selectors(&md), vec![".kicker"], "{heading}");
}
// A heading that only puts a `do` beside a `don't` is not a section
// of both, and still condemns what it names.
let md = "## Don't do this\n\n- `.eyebrow` above a heading.\n\n\