diff --git a/config/index.d.ts b/config/index.d.ts index 8e386c79..e78e2ba8 100644 --- a/config/index.d.ts +++ b/config/index.d.ts @@ -92,6 +92,7 @@ export type AudioConfig = { }; export type WritingSystemConfig = { + type: string; displayNames: { [key: string]: string; }; @@ -100,12 +101,7 @@ export type WritingSystemConfig = { }; export type DictionaryWritingSystemConfig = WritingSystemConfig & { - code: string; - type: string; - trait?: { - [key: string]: string; - }; - sortingMethod: { + sortMethod: { type: string; ignoreChars?: string[]; }; diff --git a/convert/convertConfig.ts b/convert/convertConfig.ts index 22330ed0..3f5bf2bc 100644 --- a/convert/convertConfig.ts +++ b/convert/convertConfig.ts @@ -9,7 +9,10 @@ import type { BookCollectionConfig, BookCollectionAudioConfig, StyleConfig, - DictionaryConfig + DictionaryConfig, + AppConfig, + WritingSystemConfig, + DictionaryWritingSystemConfig } from '$config'; const fontFamilies: string[] = []; @@ -255,6 +258,18 @@ function convertConfig(dataDir: string, verbose: number) { (bc) => bc.books.filter((b) => b.type === 'glossary').length > 0 ).length > 0; } + if (isDictionaryConfig(data)) { + const writingSystems: { [key: string]: DictionaryWritingSystemConfig } = {}; + const writingSystemsTag = document.getElementsByTagName('writing-systems')[0]; + const writingSystemTags = writingSystemsTag.getElementsByTagName('writing-system'); + for (const tag of writingSystemTags) { + const writingSystem = parseDictionaryWritingSystem(tag, verbose); + const code: string = tag.attributes.getNamedItem('code')!.value; + writingSystems[code] = writingSystem; + } + + data.writingSystems = writingSystems; + } data.interfaceLanguages = parseInterfaceLanguages(document, data, verbose); @@ -649,16 +664,12 @@ function parseBookCollections(document: Document, verbose: number) { return bookCollections; } -function parseInterfaceLanguages( - document: Document, - data: ScriptureConfig | DictionaryConfig, - verbose: number -) { +function parseInterfaceLanguages(document: Document, data: AppConfig, verbose: number) { const interfaceLanguagesTag = document.getElementsByTagName('interface-languages')[0]; const useSystemLanguage = parseTrait(interfaceLanguagesTag, 'use-system-language') === 'true'; const interfaceLanguages: { useSystemLanguage: boolean; - writingSystems: { [key: string]: any }; + writingSystems: { [key: string]: WritingSystemConfig }; } = { useSystemLanguage, writingSystems: {} }; const writingSystemsTags = interfaceLanguagesTag @@ -667,54 +678,8 @@ function parseInterfaceLanguages( for (const tag of writingSystemsTags) { const code: string = tag.attributes.getNamedItem('code')!.value; - const fontFamily = tag.getElementsByTagName('font-family')[0].innerHTML; - const textDirection = parseTrait(tag, 'text-direction'); - const displaynamesTag = tag.getElementsByTagName('display-names')[0]; - const displayNames: Record = {}; - - for (const form of displaynamesTag.getElementsByTagName('form')) { - displayNames[form.attributes.getNamedItem('lang')!.value] = form.innerHTML; - } - - const writingSystemConfig: any = { - fontFamily, - textDirection, - displayNames - }; - - if (isDictionaryConfig(data)) { - const sortMethodTag = tag.getElementsByTagName('sort-method')[0]; - const sortMethod = { - ignoreChars: Array.from(sortMethodTag?.getElementsByTagName('ignore') || []).map( - (ignore) => ignore.innerHTML - ) - }; - - const alphabetTag = tag.getElementsByTagName('alphabet')[0]; - const alphabet = Array.from(alphabetTag?.getElementsByTagName('letter') || []).map( - (letter) => letter.innerHTML - ); - - const inputButtonsTag = tag.getElementsByTagName('input-buttons')[0]; - const inputButtons = Array.from( - inputButtonsTag?.getElementsByTagName('button') || [] - ).map((button) => button.innerHTML); - // Optional features - const featuresTag = tag.getElementsByTagName('features')[0]; - const features: Record = {}; - if (featuresTag) { - for (const feature of featuresTag.getElementsByTagName('feature')) { - features[feature.getAttribute('name')!] = feature.getAttribute('value')!; - } - } - - // Add DAB-specific fields to the writing system config - writingSystemConfig.sortMethod = sortMethod; - writingSystemConfig.alphabet = alphabet; - writingSystemConfig.inputButtons = inputButtons; - writingSystemConfig.features = features; - } - interfaceLanguages.writingSystems[code] = writingSystemConfig; + const writingSystem = parseWritingSystem(tag, verbose); + interfaceLanguages.writingSystems[code] = writingSystem; if (verbose >= 2) { console.log(`.. writing system ${code}`); @@ -727,6 +692,76 @@ function parseInterfaceLanguages( return interfaceLanguages; } +function parseWritingSystem(element: Element, verbose: number): WritingSystemConfig { + const type = element.attributes.getNamedItem('type')!.value; + const fontFamily = element.getElementsByTagName('font-family')[0].innerHTML; + const textDirection = parseTrait(element, 'text-direction'); + const displaynamesTag = element.getElementsByTagName('display-names')[0]; + const displayNames: Record = {}; + for (const form of displaynamesTag.getElementsByTagName('form')) { + displayNames[form.attributes.getNamedItem('lang')!.value] = form.innerHTML; + } + const writingSystem: WritingSystemConfig = { + type, + fontFamily, + textDirection, + displayNames + }; + + return writingSystem; +} +function parseDictionaryWritingSystem( + element: Element, + verbose: number +): DictionaryWritingSystemConfig { + const writingSystemConfig = parseWritingSystem(element, verbose); + + let sortMethod: { type: string; ignoreChars?: string[] }; + const sortMethodTag = element.getElementsByTagName('sort-method')[0]; + if (sortMethodTag) { + const type = sortMethodTag.attributes.getNamedItem('type')?.value; + const ignoreCharsTag = sortMethodTag.getElementsByTagName('ignore-chars')[0]; + const ignoreChars = ignoreCharsTag ? ignoreCharsTag.innerHTML.split(/\s+/) : undefined; + sortMethod = { type: type || 'default', ignoreChars }; + } else { + sortMethod = { type: 'default' }; + } + + const alphabetTag = element.getElementsByTagName('alphabet')[0]; + const alphabet = alphabetTag ? alphabetTag.innerHTML.split(/\s+/) : undefined; + + const inputButtonsTag = element.getElementsByTagName('input-buttons')[0]; + const inputButtons = inputButtonsTag ? inputButtonsTag.innerHTML.split(/\s+/) : undefined; + + // Parse the features + let features: Record | undefined; + const featuresTag = element.getElementsByTagName('features')[0]; + if (featuresTag) { + features = {}; + for (const feature of featuresTag.getElementsByTagName('e')) { + const name = feature.getAttribute('name'); + const value = feature.getAttribute('value'); + if (name && value) { + features[name] = value === 'true'; + } + } + } + let reversalFilename: string | undefined; + const reversalFilenameTag = element.getElementsByTagName('reversal-filename')[0]; + if (reversalFilenameTag) { + reversalFilename = reversalFilenameTag.textContent?.trim(); + } + + return { + ...writingSystemConfig, + sortMethod, + alphabet, + inputButtons, + features, + reversalFilename + }; +} + function parseMenuLocalizations(document: Document, verbose: number) { const translationMappingsTags = document.getElementsByTagName('translation-mappings'); let translationMappings: {