88import { fileURLToPath } from 'node:url' ;
99import { byCode , byName , fetchLanguages , parseArgs , replaceBlock } from './lib.mjs' ;
1010
11- // The matrix folds target-only variants into their base language's row.
12- const MATRIX_NAME_OVERRIDES = {
13- en : 'English (American/British)' ,
14- fr : 'French (France/Canada <Badge color="blue">beta</Badge>)' ,
15- pt : 'Portuguese (Brazil/Portugal)' ,
16- zh : 'Chinese (Simplified/Traditional)' ,
17- } ;
18-
1911// feature values are objects like { status, external? }; presence means the
2012// capability exists, external: true means an external partner provides it
2113export const mark = ( feature ) => ( feature ? ( feature . external ? '⎋' : '✓' ) : '—' ) ;
@@ -25,19 +17,28 @@ export async function update({ authKey, dryRun = false }) {
2517 const sources = languages . filter ( ( l ) => l . usable_as_source ) ;
2618 const targets = languages . filter ( ( l ) => l . usable_as_target ) ;
2719
28- // The matrix only shows source languages (variants fold into the base row),
29- // so a target-only language without a source base would silently vanish.
30- const sourceBases = new Set ( sources . map ( ( l ) => l . lang . split ( '-' ) [ 0 ] ) ) ;
31- for ( const t of targets . filter ( ( t ) => ! sourceBases . has ( t . lang . split ( '-' ) [ 0 ] ) ) ) {
32- console . warn ( `voice target ${ t . lang } has no source base language and is missing from the matrix` ) ;
33- }
20+ const languagesByCode = new Map ( languages . map ( ( language ) => [ language . lang , language ] ) ) ;
3421
35- const rows = sources
36- . map ( ( l ) => ( { ...l , name : MATRIX_NAME_OVERRIDES [ l . lang ] ?? l . name } ) )
22+ const rows = languages
23+ // Skip the row for a base language if variants are available
24+ . filter ( ( l ) => l . lang . includes ( '-' ) || ! languages . some ( ( f ) => f . lang . startsWith ( `${ l . lang } -` ) ) )
3725 . sort ( byName )
3826 . map ( ( l ) => {
27+ const isVariant = l . lang . includes ( '-' ) ;
28+ const baseCode = l . lang . split ( '-' ) [ 0 ] ;
29+ const base = languagesByCode . get ( baseCode ) ;
30+
31+ if ( isVariant && ! base ) {
32+ console . warn ( `voice variant ${ l . lang } has no base language (${ baseCode } )` ) ;
33+ }
34+
35+ // Transcription for variants is determined by base language, if it exists
36+ const transcription = isVariant
37+ ? ( base ?. features ?. transcription ?? l . features . transcription )
38+ : l . features . transcription ;
3939 const name = l . status !== 'stable' ? `${ l . name } <Badge color="blue">beta</Badge>` : l . name ;
40- return `| ${ name } | ${ mark ( l . features . transcription ) } | ✓ | ${ mark ( l . features . translated_speech ) } |` ;
40+
41+ return `| ${ name } | ${ mark ( transcription ) } | ✓ | ${ mark ( l . features . translated_speech ) } |` ;
4142 } ) ;
4243 const matrix = [
4344 '| **Language** | **Transcription** | **Translation** | **Translated Speech** |' ,
0 commit comments