@@ -38,7 +38,7 @@ export interface TypedConfig extends TypingCallbacks<TypeWriter> {
3838export interface ParsedAction {
3939 action : string ;
4040 n ?: string ;
41- options ?: Record < string , string > ;
41+ options ?: Record < string , string > | string [ ] ;
4242 text ?: string ;
4343 id ?: string ;
4444}
@@ -71,7 +71,7 @@ export interface TypeWriterState extends Properties {
7171// Pre-compiled regex patterns for better performance
7272// ============================================================================
7373
74- export const QUOTED_VALUE_PATTERN = / = [ " ' ] ( .* ?) \1/ g;
74+ export const QUOTED_VALUE_PATTERN = / = ( [ " ' ] ) ( .* ?) \1/ g;
7575export const CSS_VALUE_PATTERN = / ( : [ ] ? ) ( .* ?) ; / g;
7676export const QUOTE_CONTENT_PATTERN = / ( [ " ' ] ) ( .* ?) \1/ g;
7777
@@ -416,8 +416,8 @@ class TypeWriter extends Component<TypeWriterProps, TypeWriterState> {
416416 // Matches {action:N} or {action N}
417417 result = result . replace ( new RegExp ( `\\{${ actionName } [:\\s]\\d+\\}` , 'g' ) , '' ) ;
418418 } else if ( action . type === 'enclosed' ) {
419- // Matches {/action} or {/action options}
420- result = result . replace ( new RegExp ( `\\{\\/ ${ actionName } (?:\\s[^}]*)?\\}` , 'g' ) , '' ) ;
419+ // Matches {action} or {action options} or { /action} or {/action options}
420+ result = result . replace ( new RegExp ( `\\{/? ${ actionName } (?:\\s[^}]*)?\\}` , 'g' ) , '' ) ;
421421 } else if ( action . type === 'instance' ) {
422422 // Matches {action/}
423423 result = result . replace ( new RegExp ( `\\{${ actionName } \\/\\}` , 'g' ) , '' ) ;
@@ -505,7 +505,7 @@ class TypeWriter extends Component<TypeWriterProps, TypeWriterState> {
505505 patterns . push ( `\\{(?:${ this . _numberActionsCache } )[:\\s]\\d+\\}` ) ;
506506 }
507507 if ( this . _enclosedActionsCache ) {
508- patterns . push ( `\\{\\/ (?:${ this . _enclosedActionsCache } ).*?\\}` ) ;
508+ patterns . push ( `\\{/? (?:${ this . _enclosedActionsCache } ).*?\\}` ) ;
509509 }
510510 if ( this . _instanceActionsCache ) {
511511 patterns . push ( `\\{(?:${ this . _instanceActionsCache } )\\/\\}` ) ;
@@ -921,20 +921,27 @@ class TypeWriter extends Component<TypeWriterProps, TypeWriterState> {
921921 // Try enclosed action
922922 if ( ! match && this . _enclosedActionsCache ) {
923923 type = 'enclosed' ;
924- match = section . match ( new RegExp ( `^\\{\\/ (?<action>${ this . _enclosedActionsCache } )(?<options>.*)\\}$` ) ) ;
924+ match = section . match ( new RegExp ( `^\\{/? (?<action>${ this . _enclosedActionsCache } )(?<options>.*)\\}$` ) ) ;
925925
926926 if ( match ?. groups ) {
927- if ( this . enclosedID . length ) {
928- // Extract action name from enclosedID (format: "actionName-parseIndex")
929- // Action names can contain hyphens (e.g., "shake-hard"), so we find the last hyphen
930- const lastId = this . enclosedID [ this . enclosedID . length - 1 ] ;
931- const lastDashIndex = lastId . lastIndexOf ( '-' ) ;
932- const idAction = lastDashIndex > 0 ? lastId . substring ( 0 , lastDashIndex ) : lastId ;
933- if ( idAction === match . groups . action ) {
934- this . enclosedID . pop ( ) ;
935- return undefined ;
927+ const isClosing = section . startsWith ( '{/' ) ;
928+ if ( isClosing ) {
929+ if ( this . enclosedID . length ) {
930+ // Extract action name from enclosedID (format: "actionName-parseIndex")
931+ // Action names can contain hyphens (e.g., "shake-hard"), so we find the last hyphen
932+ const lastId = this . enclosedID [ this . enclosedID . length - 1 ] ;
933+ const lastDashIndex = lastId . lastIndexOf ( '-' ) ;
934+ const idAction = lastDashIndex > 0 ? lastId . substring ( 0 , lastDashIndex ) : lastId ;
935+ if ( idAction === match . groups . action ) {
936+ this . enclosedID . pop ( ) ;
937+ return undefined ;
938+ } else {
939+ this . engine . debug . error ( 'Mismatched closing action:' , match . groups . action ) ;
940+ return undefined ;
941+ }
936942 } else {
937- this . enclosedID . push ( `${ match . groups . action } -${ this . parseIndex } ` ) ;
943+ this . engine . debug . error ( 'Closing action without opening:' , match . groups . action ) ;
944+ return undefined ;
938945 }
939946 } else {
940947 this . enclosedID . push ( `${ match . groups . action } -${ this . parseIndex } ` ) ;
@@ -953,7 +960,7 @@ class TypeWriter extends Component<TypeWriterProps, TypeWriterState> {
953960 return undefined ;
954961 }
955962
956- let options : Record < string , string > | undefined ;
963+ let options : Record < string , string > | string [ ] | undefined ;
957964
958965 if ( type === 'enclosed' && match . groups . options ) {
959966 options = this . _parseOptions ( match . groups . options ) ;
@@ -982,8 +989,8 @@ class TypeWriter extends Component<TypeWriterProps, TypeWriterState> {
982989 /**
983990 * Parse options from an enclosed action.
984991 */
985- private _parseOptions ( optionsStr : string ) : Record < string , string > {
986- const options : Record < string , string > = { } ;
992+ private _parseOptions ( optionsStr : string ) : Record < string , string > | string [ ] {
993+ const options : Record < string , string > | string [ ] = { } ;
987994 let opts : string | string [ ] = optionsStr . trim ( ) ;
988995
989996 if ( QUOTED_VALUE_PATTERN . test ( opts ) ) {
@@ -1002,6 +1009,10 @@ class TypeWriter extends Component<TypeWriterProps, TypeWriterState> {
10021009 . replace ( / \s / g, ':' )
10031010 . replace ( / \[ ~ \] / g, ' ' )
10041011 . split ( / : / g) ;
1012+ } else {
1013+ // If no special patterns, split by whitespace and return as an array of strings.
1014+ opts = opts . split ( / \s + / g) ;
1015+ return opts ;
10051016 }
10061017
10071018 if ( Array . isArray ( opts ) ) {
0 commit comments