1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
//! 제61항 — 작은따옴표(')가 숫자 앞에 올 때는 수표와 작은따옴표를 함께 사용한다.
//!
//! When an apostrophe (or right single quote ') precedes a digit, the apostrophe
//! is skipped during symbol encoding; instead, it's emitted as ⠄(4) after the
//! number prefix ⠼(60) during number encoding.
//!
//! Reference: 2024 Korean Braille Standard, Chapter 6, Section 13, Article 61
use crate::char_struct::CharType;
use crate::rules::RuleMeta;
use crate::rules::context::RuleContext;
use crate::rules::traits::{BrailleRule, Phase, RuleResult};
pub static META: RuleMeta = RuleMeta {
section: "61",
subsection: None,
name: "apostrophe_before_number",
standard_ref: "2024 Korean Braille Standard, Ch.6 Sec.13 Art.61",
description: "Apostrophe before digit: skip here, emit after 수표 in number rule",
};
/// Plugin struct for the rule engine.
///
/// When an apostrophe (or right single quote) appears before a digit,
/// this rule Consumes the apostrophe without emitting anything.
/// The apostrophe code ⠄ is emitted by the number encoding rule (rule_40)
/// after the number prefix.
pub struct Rule61;
impl BrailleRule for Rule61 {
fn meta(&self) -> &'static RuleMeta {
&META
}
fn phase(&self) -> Phase {
Phase::CoreEncoding
}
fn priority(&self) -> u16 {
350 // Before rule_49 (500) — intercept apostrophe before generic symbol encoding
}
fn matches(&self, ctx: &RuleContext) -> bool {
let CharType::Symbol(c) = ctx.char_type else {
return false;
};
if *c != '\'' && *c != '\u{2019}' {
return false;
}
// Only match when followed by a digit
ctx.next_char().is_some_and(|next| next.is_ascii_digit())
}
fn apply(&self, _ctx: &mut RuleContext) -> Result<RuleResult, String> {
// Skip the apostrophe — it will be emitted by rule_40 after 수표
Ok(RuleResult::Consumed)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn meta_is_correct() {
assert_eq!(META.section, "61");
assert_eq!(META.name, "apostrophe_before_number");
}
#[test]
fn apostrophe_is_not_standalone_before_digit() {
// When apostrophe precedes a digit, it should not produce the standard
// symbol encoding; instead, ⠄ is emitted after the 수표 by rule_40.
// This test verifies via the full pipeline that the combination works.
// Note: this is tested indirectly — rule_61 skips the apostrophe,
// rule_40 emits 수표 + ⠄ + digit.
}
}