Skip to content

Commit 0aa4b04

Browse files
authored
update: 2.8.15
1 parent d3dcf37 commit 0aa4b04

1 file changed

Lines changed: 10 additions & 26 deletions

File tree

app/index.html

Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
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(?=\[(?:Script Info|V?\d+(?:\.\d+)*\+?\s+Styles|Styles|Events|Fonts|Graphics|Aegisub\s+(?:Extradata|Project\s+Garbage))\])/i;
5655-
const SCRIPT_INFO_RE = /\[Script Info\][ \t]*\r?\n[\s\S]*?(?=\r?\n\[(?:Script Info|V?\d+(?:\.\d+)*\+?\s+Styles|Styles|Events|Fonts|Graphics|Aegisub)|$)/i;
5656-
const STYLES_BLOCK_RE = /\[(?:V?\d+(?:\.\d+)*\+?\s+Styles|Styles)\][ \t]*\r?\n[\s\S]*?(?=\r?\n\[(?:Script Info|V?\d+(?:\.\d+)*\+?\s+Styles|Styles|Events|Fonts|Graphics|Aegisub)|$)/i;
5657-
const EVENTS_HDR_RE = /\[Events\][ \t]*\r?\n(?:Format:[^\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 => /^(Dialogue|Comment)\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(/\[Script Info\][ \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\[Fonts\][ \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

Comments
 (0)