@@ -177,17 +177,23 @@ fn to_line_input(b: &SessionOcrBlock) -> crate::line_merge::LineInput {
177177}
178178
179179/// 两块合并(① 产物):文本直拼(中文行内拼接)+ 得分均值 + bbox 并集。
180+ ///
181+ /// @ai-context: ASCII 词间空格保持(审查 M1)——英文/数字 OCR 块 trim 后直拼会
182+ /// 单词粘连("Hello " + "World" → "HelloWorld",空格信息已丢失
183+ /// 不可恢复);中文无词间空格不受影响。
180184fn merge_two ( a : & SessionOcrBlock , b : & SessionOcrBlock ) -> SessionOcrBlock {
181185 let ( ba, bb) = ( a. bbox . unwrap ( ) , b. bbox . unwrap ( ) ) ;
182186 let x = ba. x . min ( bb. x ) ;
183187 let y = ba. y . min ( bb. y ) ;
184188 let x2 = ( ba. x + ba. w ) . max ( bb. x + bb. w ) ;
185189 let y2 = ( ba. y + ba. h ) . max ( bb. y + bb. h ) ;
190+ let ( a_t, b_t) = ( a. text . trim ( ) , b. text . trim ( ) ) ;
191+ let gap = if ascii_gap ( a_t, b_t) { " " } else { "" } ;
186192 SessionOcrBlock {
187193 id : a. id ,
188194 session_id : a. session_id ,
189195 timestamp_ms : a. timestamp_ms ,
190- text : format ! ( "{}{}" , a . text . trim ( ) , b . text . trim ( ) ) ,
196+ text : format ! ( "{}{}{} " , a_t , gap , b_t ) ,
191197 score : ( a. score + b. score ) / 2.0 ,
192198 region : a. region . clone ( ) ,
193199 region_kind : a. region_kind . clone ( ) ,
@@ -196,6 +202,13 @@ fn merge_two(a: &SessionOcrBlock, b: &SessionOcrBlock) -> SessionOcrBlock {
196202 }
197203}
198204
205+ /// ASCII 词间空格判定(审查 M1):a 尾字符与 b 首字符均为 ASCII 字母/数字 →
206+ /// 需补空格(英文/数字行合并场景;中文首尾字符非 ASCII 不触发)。
207+ fn ascii_gap ( a : & str , b : & str ) -> bool {
208+ a. chars ( ) . last ( ) . is_some_and ( |c| c. is_ascii_alphanumeric ( ) )
209+ && b. chars ( ) . next ( ) . is_some_and ( |c| c. is_ascii_alphanumeric ( ) )
210+ }
211+
199212/// 块 → 净化行(trim 文本/bbox)。
200213fn to_purified ( b : & SessionOcrBlock ) -> PurifiedLine {
201214 PurifiedLine {
0 commit comments