2121 < link rel ="alternate " hreflang ="ar " href ="https://subs.js.org/ass-subset/?lang=ar ">
2222 < link rel ="alternate " hreflang ="x-default " href ="https://subs.js.org/ass-subset/ ">
2323 < link rel ="icon " type ="image/jpeg " href ="icons/icon-256.png ">
24- < meta name ="version " content ="2.8.14 ">
24+ < meta name ="version " content ="2.8.15 ">
2525 < meta property ="og:type " content ="website ">
2626 < meta property ="og:title " content ="ASS Subsetter · Font Embedding for Subtitles ">
2727 < meta property ="og:description " content ="Font embedding tool for ASS/SSA subtitles. Subset fonts to compress file size, or embed them fully. Perfect for complex subtitle typesetting with multiple font files. ">
@@ -5650,37 +5650,19 @@ <h3 id="preview-title" data-i18n="preview.title">Font Preview / Download</h3>
56505650 if ( p . embeddedFonts ) totalEmbeddedCount += Object . keys ( p . embeddedFonts ) . length ;
56515651 }
56525652
5653- const SENTINEL_PREFIX = 'Comment: @@FSEP_' ;
5654- const SECTION_HDR_RE = / \r ? \n (? = \[ (?: S c r i p t I n f o | V ? \d + (?: \. \d + ) * \+ ? \s + S t y l e s | S t y l e s | E v e n t s | F o n t s | G r a p h i c s | A e g i s u b \s + (?: E x t r a d a t a | P r o j e c t \s + G a r b a g e ) ) \] ) / i;
5655- const SCRIPT_INFO_RE = / \[ S c r i p t I n f o \] [ \t ] * \r ? \n [ \s \S ] * ?(? = \r ? \n \[ (?: S c r i p t I n f o | V ? \d + (?: \. \d + ) * \+ ? \s + S t y l e s | S t y l e s | E v e n t s | F o n t s | G r a p h i c s | A e g i s u b ) | $ ) / i;
5656- const STYLES_BLOCK_RE = / \[ (?: V ? \d + (?: \. \d + ) * \+ ? \s + S t y l e s | S t y l e s ) \] [ \t ] * \r ? \n [ \s \S ] * ?(? = \r ? \n \[ (?: S c r i p t I n f o | V ? \d + (?: \. \d + ) * \+ ? \s + S t y l e s | S t y l e s | E v e n t s | F o n t s | G r a p h i c s | A e g i s u b ) | $ ) / i;
5657- const EVENTS_HDR_RE = / \[ E v e n t s \] [ \t ] * \r ? \n (?: F o r m a t : [ ^ \r \n ] * \r ? \n ) ? / i;
5658- const DEFAULT_SCRIPT_INFO = '[Script Info]\nScriptType: v4.00+' ;
5659- const DEFAULT_STYLES_BLOCK = '[V4+ Styles]\nFormat: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding\nStyle: Default,Arial,40,&H00FFFFFF,&H000000FF,&H00000000,&H00000000,0,0,0,0,100,100,0,0,1,2,2,2,10,10,10,1' ;
56605653 let combinedText = '' ;
56615654 let sortedFiles = null ;
56625655 let hostSortedIdx = 0 ;
5656+ let sepToken = '' ;
56635657 if ( isMulti ) {
56645658 sortedFiles = group . files . map ( ( f , idx ) => ( { ...f , _origIndex : idx } ) )
56655659 . sort ( ( a , b ) => a . file . name . toLowerCase ( ) . localeCompare ( b . file . name . toLowerCase ( ) , undefined , { numeric : true } ) ) ;
56665660 const hostOrigIdx = ( group . userSetEmbedTarget && group . embedTargetIndex >= 0 && group . embedTargetIndex < group . files . length )
56675661 ? group . embedTargetIndex : sortedFiles [ 0 ] . _origIndex ;
56685662 hostSortedIdx = sortedFiles . findIndex ( sf => sf . _origIndex === hostOrigIdx ) ;
5669- for ( let j = 0 ; j < sortedFiles . length ; j ++ ) {
5670- const f = sortedFiles [ j ] ;
5671- const siM = f . content . match ( SCRIPT_INFO_RE ) ;
5672- const siBlock = siM ? siM [ 0 ] . trimEnd ( ) : DEFAULT_SCRIPT_INFO ;
5673- const sm = f . content . match ( STYLES_BLOCK_RE ) ;
5674- const stylesBlock = sm ? sm [ 0 ] . trimEnd ( ) : DEFAULT_STYLES_BLOCK ;
5675- const em = f . content . match ( EVENTS_HDR_RE ) ;
5676- const evtHdrLine = em ? em [ 0 ] . trimEnd ( ) : '[Events]\nFormat: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text' ;
5677- if ( j > 0 ) combinedText += SENTINEL_PREFIX + j + '@@\n' ;
5678- combinedText += siBlock + '\n\n' + stylesBlock + '\n\n' + evtHdrLine + '\n' ;
5679- if ( em ) {
5680- const dlgLines = f . content . slice ( em . index + em [ 0 ] . length ) . split ( / \r ? \n / ) . filter ( l => / ^ ( D i a l o g u e | C o m m e n t ) \s * : / i. test ( l ) && ! l . includes ( '@@FSEP_' ) ) ;
5681- if ( dlgLines . length ) combinedText += dlgLines . join ( '\n' ) + '\n' ;
5682- }
5683- }
5663+ do { sepToken = 'FSEP_' + Math . random ( ) . toString ( 36 ) . slice ( 2 ) + Date . now ( ) . toString ( 36 ) ; }
5664+ while ( sortedFiles . some ( f => f . content . includes ( sepToken ) ) ) ;
5665+ combinedText = sortedFiles . map ( ( f , j ) => j === 0 ? f . content : f . content . replace ( / \[ S c r i p t I n f o \] [ \t ] * \r ? \n / i, m => m + '; @@' + sepToken + '\n' ) ) . join ( '\n' ) ;
56845666 } else {
56855667 combinedText = group . files [ 0 ] . content ;
56865668 }
@@ -5723,8 +5705,10 @@ <h3 id="preview-title" data-i18n="preview.title">Font Preview / Download</h3>
57235705 if ( isMulti ) {
57245706 const outText = result . finalText || combinedText ;
57255707 const detNl = outText . includes ( '\r\n' ) ? '\r\n' : '\n' ;
5726- const SENTINEL_ESC = SENTINEL_PREFIX . replace ( / [ . * + ? ^ $ { } ( ) | [ \] \\ ] / g, '\\$&' ) ;
5727- const chunks = outText . split ( new RegExp ( '\\r?\\n(?=' + SENTINEL_ESC + '\\d+@@)' ) ) ;
5708+ const sepEsc = sepToken . replace ( / [ . * + ? ^ $ { } ( ) | [ \] \\ ] / g, '\\$&' ) ;
5709+ const markerRe = new RegExp ( '(\\[Script Info\\][ \\t]*\\r?\\n(?:;\\s*Font Subset:[^\\r\\n]*\\r?\\n)*);\\s*@@' + sepEsc + '\\r?\\n' , 'i' ) ;
5710+ const cutRe = new RegExp ( '\\r?\\n(?=\\[Script Info\\][ \\t]*\\r?\\n(?:;\\s*Font Subset:[^\\r\\n]*\\r?\\n)*;\\s*@@' + sepEsc + '\\r?\\n)' , 'i' ) ;
5711+ const chunks = outText . split ( cutRe ) . map ( c => c . replace ( markerRe , '$1' ) ) ;
57285712 const fontsM = chunks [ 0 ] . match ( / \r ? \n \[ F o n t s \] [ \t ] * \r ? \n [ \s \S ] * ?(? = \r ? \n \[ | $ ) / i) ;
57295713 const fontsSection = fontsM ? fontsM [ 0 ] . replace ( / ^ \r ? \n / , '' ) . trimEnd ( ) : '' ;
57305714 const insertFontsBeforeEvents = ( text , sec ) => {
@@ -5737,7 +5721,7 @@ <h3 id="preview-title" data-i18n="preview.title">Font Preview / Download</h3>
57375721 const isHost = ! wantSeparate && j === hostSortedIdx ;
57385722 let body = j === 0
57395723 ? ( fontsM ? chunks [ 0 ] . slice ( 0 , fontsM . index ) + chunks [ 0 ] . slice ( fontsM . index + fontsM [ 0 ] . length ) : chunks [ 0 ] )
5740- : chunks [ j ] . replace ( new RegExp ( '^' + SENTINEL_ESC + '\\d+@@\\r?\\n' ) , '' ) ;
5724+ : chunks [ j ] ;
57415725 if ( isHost ) body = insertFontsBeforeEvents ( body , fontsSection ) ;
57425726 const myBlob = result . isDirect ? new Blob ( [ f . rawBuffer ] ) : new Blob ( [ body ] , { type : 'text/plain;charset=utf-8' } ) ;
57435727 const fileIndex = S . outputBlobs . length ;
0 commit comments