import { j3pAddElt, j3pChaine, j3pElement, j3pEnsureHtmlElement } from 'src/legacy/core/functions'
import { j3pAffiche } from 'src/lib/mathquill/functions'
/**
* Ajoute une phrase dans un nouveau bloc. Cette phrase peut contenir des variables de la forme £a où la valeur sera précisée
* @param {string|HTMLElement} container
* @param {string} phrase
* @param {Object} [options={}] Objet contenant les variables à remplacer dans la phrase et leurs valeurs
* @param {string|number} [options.x] pour le remplacement d’un £x ou £{x} qui serait dans contenu
* @return {HTMLElement} l’élément Html construit
* @throws {Error} si le conteneur n’existe pas
*/
export function phraseBloc (container, phrase, options) {
try {
container = j3pEnsureHtmlElement(container)
if (typeof phrase !== 'string') return console.error(Error('paramètre phrase invalide'), phrase)
// Utilisation ci-dessous d’une RegExp avec groupe de capture nommé :
// https://delicious-insights.com/fr/articles/js-captures-nommees/
if (/(?<delimiteur>[&#@])[1-9]\d*\k<delimiteur>/.test(phrase)) return console.error('Pour mettre un input ou une liste, il faut utiliser afficheBloc ou j3pAffiche')
// Cela revient à ce qui suit :
/* for (const car of '&#@') {
if (RegExp(car + '[1-9][\\d]*' + car).test(phrase)) return console.error('Pour mettre un input ou une liste, il faut utiliser afficheBloc ou j3pAffiche')
} */
if (options && typeof options === 'object') phrase = j3pChaine(phrase, options)
return j3pAddElt(container, 'p', phrase)
} catch (error) {
console.error(error)
console.error('phraseBloc plante avec le conteneur', container, 'la phrase', phrase, 'et les options', options)
// on veut pas planter, on retourne le conteneur,
// c’est encore le "moins pire" (si l’appelant utilise le résultat pour ajouter qqchose dedans)
return container
}
}
/**
* Affiche contenu dans conteneur en créant un nouveau bloc. C’est j3pAffiche sans la création d’un div auparavant
* contenu est en effet traitée pour
* - substituer les £x ou £{x}
* - gérer du $code LaTeX$
* - gérer du contenu mathquill substituable
* - gérer des input mathquill
* - gérer de la substitution dynamique (les valeurs à substituer peuvent contenir des opérations comme calcule[…], signe[…], pgcd[…]
* Voir le détail sur {@tutorial paramContent}
* Si vous voulez simplement afficher une chaîne sans avoir besoin de traitement particulier, utiliser j3pAddElt(conteneur, options)
* @param {HTMLElement|string} container
* @param {string} contenu Le texte à afficher (les caractères spéciaux $@&# seront interprétés à la mode j3p :
* $\\frac{3}{2}$ : affiché comme du LaTeX
* @N@ : input mathquill n°N, à documenter (options.inputN a bcp de propriétés possibles)
* &N& : zone d’édition mathquill n°N
* #???# : pour insérer un <select> @todo à documenter
* Si contenu contient ou < ou > c’est géré
* mais ça ne tolèrera pas d’autres htmlEntities de cette forme)
* @param {Object} [options={}]
* @param {Object} [options.style] Objet style qui sera passé au span, pour ceux qui préfèrent style.fontSize (en string avec unité px ou autre) plutôt que styletexte.taillepolice (number sans unité)
* @param {Object} [options.styletexte] des infos pour le style à mettre sur le span qu’on va créer autour du contenu
* @param {string} [options.styletexte.couleur]
* @param {number} [options.styletexte.taillepolice]
* @param {string|number} [options.x] pour le remplacement d’un £x ou £{x} qui serait dans contenu
* @param {object} [options.inputN] pour les @N@ @todo à documenter
* @param {object} [options.inputmqN] pour les &N& (édition mathquill) @todo à documenter
* @param {object} [options.listeN] pour les #N# (le <select>) @todo à documenter
* @param {string[]} [options.listeN].texte les <option> mises dans le <select> précédent
* @param {Object} [position] Si fourni, doit avoir les propriétés top & left en number (sinon ce sera ignoré)
* @param {number} [position.top]
* @param {number} [position.left]
* @return {ResultatAffichage} Les éléments créés dans le DOM, parent est le span englobant, les autres propriétés sont toutes des array d’éléments (ces listes sont donc souvent vides), mqList pour les span créés par $text$, inputList pour les input créés par @N@, selectList pour les listes créées par #N# (parcourir sa propriété childNodes pour avoir les options), inputmqList pour les input mathquill créés avec &N& et inputmqefList pour les champs éditables créés par mathquill si y’a du \editable{} dans le latex fourni
*/
export function afficheBloc (container, contenu, options, position) {
if (typeof container === 'string') container = j3pElement(container)
if (!container) return console.error(Error('cet élément n’est pas dans un conteneur'), container)
// cette RegExp permet de trouver tous les dollars non précédés de \, (?<!y)x veux dire x non précédé de y
// const tabDollar = contenu.match(/(?<!\\)\$/g)
// le pb est que seuls les navigateurs récent le comprenne, sauf safari qui bug dessus…
const tabDollar = contenu.match(/[$]/g)
const tabDollarEscaped = contenu.match(/\\[$]/g)
const nbDollar = (tabDollar?.length ?? 0) - (tabDollarEscaped?.length ?? 0)
if (nbDollar % 2 !== 0) return console.error('Il y a un problème avec le code latex de cette chaine, car il devrait y avoir un nombre pair de $ et là j’en ai', nbDollar)
if (contenu.includes('\\$')) return console.error('Pour afficher un $, il faut utiliser $ ou utiliser la fonction phraseBloc')
const elt = j3pAddElt(container, 'div')
return j3pAffiche(elt, '', contenu, options, position)
}