@@ -6,7 +6,7 @@ use trie::Trie;
66use crate :: parser:: { AnchoredRule , Attribute , Braille , Direction , Rule , dots_to_unicode, fallback} ;
77
88use self :: trie:: Boundary ;
9- use indication:: { Indication , NumericIndicator } ;
9+ use indication:: { Indication , NumericIndicator , NumericIndicatorBuilder } ;
1010
1111mod boundaries;
1212mod indication;
@@ -181,7 +181,7 @@ pub struct TranslationTable {
181181 character_attributes : CharacterAttributes ,
182182 translations : Trie ,
183183 match_patterns : MatchPatterns ,
184- indicator_signs : IndicatorSigns ,
184+ numeric_indicator : NumericIndicator ,
185185 direction : Direction ,
186186}
187187
@@ -195,17 +195,20 @@ impl TranslationTable {
195195 let mut character_attributes = CharacterAttributes :: new ( ) ;
196196 let mut translations = Trie :: new ( ) ;
197197 let mut match_patterns = MatchPatterns :: new ( ) ;
198- let mut indicator_signs = IndicatorSigns :: new ( ) ;
198+ let mut numeric_indicator_builder = NumericIndicatorBuilder :: new ( ) ;
199199
200200 let rules: Vec < AnchoredRule > = rules
201201 . into_iter ( )
202202 . filter ( |r| r. rule . is_direction ( direction) )
203203 . collect ( ) ;
204204
205- // FIXME: For some unknown reason the litdigit rule seems to have precedence over the digit
206- // rule. Since they both want to define digits in the same character_definitions slot we
207- // need to make sure litdigits rules are handled before digit rules
208- for rule in rules. iter ( ) . filter ( |r| matches ! ( r. rule, Rule :: Litdigit { .. } ) ) {
205+ // FIXME: For some unknown reason the litdigit rule seems to have precedence over the digit
206+ // rule. Since they both want to define digits in the same character_definitions slot we
207+ // need to make sure litdigits rules are handled before digit rules
208+ for rule in rules
209+ . iter ( )
210+ . filter ( |r| matches ! ( r. rule, Rule :: Litdigit { .. } ) )
211+ {
209212 match & rule. rule {
210213 Rule :: Litdigit {
211214 character, dots, ..
@@ -215,9 +218,9 @@ impl TranslationTable {
215218 character_definitions. insert ( * character, translation) ;
216219 character_attributes. insert ( Attribute :: Digit , * character) ;
217220 }
218- _ => ( ) ,
219- }
220- }
221+ _ => ( ) ,
222+ }
223+ }
221224
222225 // The compilation is done in two passes: The first pass simply collects all character
223226 // definitions and character attributes, so that they are then known in a second pass, e.g.
@@ -296,10 +299,19 @@ impl TranslationTable {
296299 // TODO: should the math opcode not also define a CharacterAttribute?
297300 }
298301 Rule :: Numsign { dots } => {
299- indicator_signs. insert ( Indication :: NumericStart , dots_to_unicode ( dots) ) ;
302+ numeric_indicator_builder =
303+ numeric_indicator_builder. numsign ( & dots_to_unicode ( dots) ) ;
300304 }
301305 Rule :: Nonumsign { dots } => {
302- indicator_signs. insert ( Indication :: NumericEnd , dots_to_unicode ( dots) ) ;
306+ numeric_indicator_builder =
307+ numeric_indicator_builder. nonumsign ( & dots_to_unicode ( dots) ) ;
308+ }
309+ Rule :: Numericnocontchars { chars } => {
310+ numeric_indicator_builder =
311+ numeric_indicator_builder. numericnocontchars ( & chars) ;
312+ }
313+ Rule :: Numericmodechars { chars } => {
314+ numeric_indicator_builder = numeric_indicator_builder. numericmodechars ( & chars) ;
303315 }
304316 // display rules are ignored for translation tables
305317 Rule :: Display { .. } => ( ) ,
@@ -414,14 +426,19 @@ impl TranslationTable {
414426 }
415427 }
416428
429+ numeric_indicator_builder = numeric_indicator_builder. numeric_characters (
430+ character_attributes
431+ . get ( Attribute :: Digit )
432+ . unwrap_or ( HashSet :: default ( ) ) ,
433+ ) ;
417434 Ok ( TranslationTable {
418435 undefined,
419436 direction,
420437 character_definitions,
421438 character_attributes,
422439 translations,
423440 match_patterns,
424- indicator_signs ,
441+ numeric_indicator : numeric_indicator_builder . build ( ) ,
425442 } )
426443 }
427444
@@ -437,32 +454,23 @@ impl TranslationTable {
437454 let mut delayed_translations: Vec < Translation > = Vec :: new ( ) ;
438455 let mut chars = input. chars ( ) ;
439456 let mut prev: Option < char > = None ;
440- let mut indicator = NumericIndicator :: new (
441- self . character_attributes
442- . get ( Attribute :: Digit )
443- . unwrap_or ( HashSet :: default ( ) ) ,
444- self . indicator_signs . get ( Indication :: NumericStart ) . cloned ( ) ,
445- self . indicator_signs . get ( Indication :: NumericEnd ) . cloned ( ) ,
446- ) ;
457+ // FIXME: the following seems weird, but the indicator is a mutable state machine. Since
458+ // self (the translation table) is immutable we build a mutable copy of the indicator for
459+ // each translation
460+ let mut numeric_indicator = self . numeric_indicator . clone ( ) ;
447461
448462 loop {
449463 // Check if there is a need for an indication
450- if let Some ( indication) = indicator . next ( chars. as_str ( ) ) {
464+ if let Some ( indication) = numeric_indicator . next ( chars. as_str ( ) ) {
451465 match indication {
452466 Indication :: NumericStart => translations. push ( Translation :: new (
453467 "" . to_string ( ) ,
454- self . indicator_signs
455- . get ( Indication :: NumericStart )
456- . cloned ( )
457- . unwrap ( ) ,
468+ numeric_indicator. start_indicator ( ) . unwrap ( ) ,
458469 1 ,
459470 ) ) ,
460471 Indication :: NumericEnd => translations. push ( Translation :: new (
461472 "" . to_string ( ) ,
462- self . indicator_signs
463- . get ( Indication :: NumericEnd )
464- . cloned ( )
465- . unwrap ( ) ,
473+ numeric_indicator. end_indicator ( ) . unwrap ( ) ,
466474 1 ,
467475 ) ) ,
468476 _ => ( ) ,
0 commit comments