/* * Copyright (C) 2023-2024 Yomitan Authors * Copyright (C) 2020-2022 Yomichan Authors * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ /** * TODO : This function is not very type safe at the moment, could be improved. * @template {import('translation').FindTermsOptions|import('translation').FindKanjiOptions} T * @param {string} dictionaryName * @param {import('test/translator').OptionsPresetObject} optionsPresets * @param {import('test/translator').OptionsList} optionsArray * @returns {T} * @throws {Error} */ export function createFindOptions(dictionaryName, optionsPresets, optionsArray) { /** @type {import('core').UnknownObject} */ const options = {}; if (!Array.isArray(optionsArray)) { optionsArray = [optionsArray]; } for (const entry of optionsArray) { switch (typeof entry) { case 'string': if (!Object.prototype.hasOwnProperty.call(optionsPresets, entry)) { throw new Error('Invalid options preset'); } Object.assign(options, structuredClone(optionsPresets[entry])); break; case 'object': Object.assign(options, structuredClone(entry)); break; default: throw new Error('Invalid options type'); } } // Construct regex if (Array.isArray(options.textReplacements)) { options.textReplacements = options.textReplacements.map((value) => { if (Array.isArray(value)) { value = value.map(({pattern, flags, replacement}) => ({pattern: new RegExp(pattern, flags), replacement})); } return value; }); } // Update structure const placeholder = '${title}'; if (options.mainDictionary === placeholder) { options.mainDictionary = dictionaryName; } let {enabledDictionaryMap} = options; if (Array.isArray(enabledDictionaryMap)) { for (const entry of enabledDictionaryMap) { if (entry[0] === placeholder) { entry[0] = dictionaryName; } } enabledDictionaryMap = new Map(enabledDictionaryMap); options.enabledDictionaryMap = enabledDictionaryMap; } const {excludeDictionaryDefinitions} = options; options.excludeDictionaryDefinitions = ( Array.isArray(excludeDictionaryDefinitions) ? new Set(excludeDictionaryDefinitions) : null ); return /** @type {T} */ (options); }