"use strict"; import {Check} from "../../Utils/Check.ecma.js"; import {FormatModule} from "../FormatModule.ecma.js"; /** * @typedef {import("../FormatModule.ecma.js").FormatModule} FormatModule */ /** * @class AlternativesFormat * @constructor * @param {!FormatModule} format * @returns {void} * @access public * @static */ export const AlternativesFormat = (function(){ /** * @constructs AlternativesFormat * @param {!FormatModule} format * @returns {void} * @access private * @static */ const AlternativesFormat = function(format){ /** @type {AlternativesFormat} */ const self = this; /** * @returns {void} * @access private */ const constructor = () => { ["alt", "alts", "alternative", "alternatives"].forEach(name => { format.modes[name] = self.get; format.checks[name] = self.check; }); ["Alt", "Alts", "Alternative", "Alternatives"].forEach(name => { format.modes[name] = self.get; format.checks[name] = self.check; }); }; /** * @param {[number, number]} coordenates * @param {!(string|Array.)} inputs * @param {!Object.} [shared = {}] * @param {!Array.} [fragments = []] * @returns {string} * @access public */ this.get = ([i, j], inputs, shared = {}, fragments = []) => { /** @type {[string, boolean, string|Array.]} */ const [language, mutable, content_base] = ( Check.is_string(inputs) ? ((_, language, mutable, options) => [ language, mutable == "1", options ])(...inputs.match(/^([^,]+),([01]),(.*)$/)) : Check.is_array(inputs) ? inputs : []), /** @type {string} */ content = Check.is_array(content_base) ? content_base.join("\n") : content_base; /** @type {string|null} */ let block = null; if(mutable){ if(shared && shared.uniques_cache){ for(let _ = 0; _ < 100; _ ++){ /** @type {string} */ const temporary = format.execute([i, j], content, shared, fragments); if(!shared.uniques_cache.includes(temporary)){ block = temporary; shared.uniques_cache.push(temporary); break; }; }; }else block = format.execute([i, j], content, shared, fragments); }; return "```" + language + "`" + ( block === null ? format.restore_fragments(content, fragments) : block) + "```"; }; /** * @param {[number, number]} coordenates * @param {!string} string * @param {!(string|Array.)} inputs * @param {!Object.} [shared = {}] * @param {!Array.} [fragments = []] * @returns {number} * @access public */ this.check = ([i, j], string, inputs, shared = {}, fragments = []) => { /** @type {[string, boolean, string|Array.]} */ const [language, mutable, content_base] = ( Check.is_string(inputs) ? ((_, language, mutable, options) => [ language, mutable == "1", options ])(...inputs.match(/^([^,]+),([01]),(.*)$/)) : Check.is_array(inputs) ? inputs : []), /** @type {string} */ content = Check.is_array(content_base) ? content_base.join("\n") : content_base; /** @type {number} */ let k = -1, /** @type {string} */ clone = "" + string; if(clone.startsWith("```" + language + "`")){ /** @type {number} */ const end = (clone = clone.substring(6 + language.length)).indexOf("```"); end != -1 && (k = ( mutable ? format.get_check_length([i, j], clone.substring(0, end), [content], shared, fragments) : clone.startsWith(content + "```") ? content.length : -1)) != -1 && (k += 7 + language.length); }; return k; }; constructor(); }; return AlternativesFormat; })();