Copy link to clipboard
Copied
Bonjour,
Ceci est mon premier post dans la communauté donc soyez indulgent avec moi hihi 🙂
Je souhaiterais me lancer dans des vidéos pédagogique dans le domaine de la programmation informatique, avec de l'animation graphique pour accentuer l'aspect pédagogique.
Voici un exemple de ce que je voudrais obtenir sur la chaîne Youtube CodeAesthetic.
Seulement voilà, je suis déjà bloqué par la coloration syntaxique des différents codes sources que je souhaite intégrer dans le montage. En plus de cela, je risque d'utiliser un langage très peu utilisé (Windev), mais même avec un langage natif tel que le C++ par exemple, cela semble très compliqué pour faire ce que je veux...
J'ai trouvé un module sympa => ASH Syntax Hightligher.
Le problème c'est qu'il est payant et cher, et aucune idée s'il est possible de paramétrer le tout pour faire un langage maison.
J'ai essayé de m'appuyer sur les expressions, mais impossible de formater une section de texte en une autre couleur et avec du gras par exemple. C'est plus ou moins tout le texte ou rien. Et la doc ne m'a pas vraiment aidé en ce sens...
Je me sens bloqué et ne sais plus vers quelle solutions me tourner.
Après de nombreuses recherches sur le net autour du sujet, les réponses sont du genre : No you can't do that with AE...
Si vous avez d'autres pistes à me suggérer ou souhaitez approfondir celles que j'ai déjà tentées, je suis preneur !
Bonne journée.
Cordialement,
Phendel.
Copy link to clipboard
Copied
Je pense avoir trouvé mon salut dans cette vidéo de Luis Martínez !
On crée un texte qui correspond au code source que l'on souhaite colorer syntaxtiquement.
Puis on lui crée une animation de type Color > RVB puis ajouter Sélecteur > Expression,
renomer le nom de l'animation par le token voulu puis indiquer dans Expression le code source suivant :
//Luigimx_textAnimator.expSelector_v01.29
var sourceTxt = text.sourceText;
var animator = thisProperty.propertyGroup(3);
var animatorName = animator.name;
var selector = thisProperty.propertyGroup(1);
var result = 0;
//[ 0, X, Y ] == All off
if (thisLayer.active && animator.active && selector.active) {
var valX = (value[0] >= 0) ? Math.round(value[0]) : 0;
var valY = (value[1] >= 0) ? Math.round(value[1]) : 0;
var valZ = (value[2] >= 0) ? Math.round(value[2]) : 0;
if (valX == 1) {
var basedOn = selector.basedOn;
//Selector is NOT based on Lines
if (basedOn.value != 4) {
var charactersRE = /\r?\n|\r/g;
var wordsRE = /\s/g;
var noSep = "";
var vSep = "\v";
var animatorRE = charactersRE;
var animatorSep = noSep;
var sourceRE, sourceSeparator;
switch (basedOn.value) {
case 1:
sourceRE = charactersRE;
sourceSeparator = noSep;
break;
case 2:
sourceRE = wordsRE;
sourceSeparator = noSep;
break;
case 3:
animatorRE = wordsRE;
animatorSep = vSep;
sourceRE = wordsRE;
sourceSeparator = vSep;
break;
default:
break;
}
var sourceTxtFixed = sourceTxt.replace(sourceRE, sourceSeparator);
var sourceArr = sourceTxtFixed.split(sourceSeparator);
var sourceLen = sourceArr.length;
var animatorNameFixed = animatorName.replace(animatorRE, animatorSep);
var animatorArr = (animatorNameFixed.length > 1) ? animatorNameFixed.split(animatorSep) : [animatorNameFixed];
var animatorLen = animatorArr.length;
function escapeRegExp(stringToGoIntoTheRegex) {
return stringToGoIntoTheRegex.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
var indicesArr = [];
//Find pattern occurrences in source text and store inside array
function findIndicesInSource(str) {
var patternIndices = [];
var patternRE = new RegExp(escapeRegExp(str), 'g');
var patternMatches;
while ((patternMatches = patternRE.exec(sourceTxtFixed))) {
patternIndices.push(patternMatches.index);
}
if (basedOn.value == 3 && patternIndices.length > 0) {
var sourceObj = {};
var p = 0;
while (p < sourceLen) {
sourceObj[sourceArr[p]] = (!(sourceArr[p] in sourceObj)) ? [] : sourceObj[sourceArr[p]];
sourceObj[sourceArr[p]].push(p);
p++
}
try {
patternIndices = sourceObj[str];
} catch (err) {
patternIndices = [sourceLen];
}
}
return patternIndices;
}
indicesArr = findIndicesInSource(animatorNameFixed);
var itemZ = animatorNameFixed;
if (valZ > 0) {
var arrZ = animatorArr;
// Z value will represent the index of a character or word item from the animator name
if (arrZ.length > 0) {
if ((valZ - 1) < arrZ.length) {
itemZ = arrZ[valZ - 1];
if (animatorLen > 1 && basedOn.value != 2) {
indicesArr = findIndicesInSource(itemZ);
}
// } else {
// itemZ = null;
}
}
}
var itemY = sourceLen;
if (valY > 0) {
var arrY = indicesArr;
// Y value will represent the index of the occurence
if ((arrY.length > 0) && ((valY - 1) < arrY.length)) {
itemY = arrY[valY - 1];
}
}
//Animator name has more than one character
if (animatorLen > 1) {
//Selector IS based on Characters Excluding Spaces
if (basedOn.value == 2) {
//Create object that contains pattern indexes
var patternObj = function () {
var indicesLen = indicesArr.length
var chars, h, m, n, idx, patternObj = {};
if (valZ > 0) {
chars = clamp(valZ, 1, animatorLen);
} else {
chars = animatorLen;
}
h = 0;
while (h < (indicesLen * chars)) {
n = 0;
while (n < indicesLen) {
m = 0;
while (m < chars) {
idx = indicesArr[n] + m;
patternObj[idx] = h;
m++;
h++;
}
n++;
}
}
return patternObj;
}();
//Change sourceArr so it will only match the entire pattern
var i = 0;
while (i < sourceLen) {
if (!(i in patternObj)) {
sourceArr[i] = vSep;
}
i++;
}
}
if (valY < 1) {
if (valZ < 1) {
//[ 1, 0, 0 ] == All items, all occurrences
var animatorObj = {};
for (var j = 0; j < animatorLen; j++) {
animatorObj[animatorArr[j]] = (!(animatorArr[j] in animatorObj)) ? [] : animatorObj[animatorArr[j]];
animatorObj[animatorArr[j]].push(j);
}
result = (sourceArr[textIndex - 1] in animatorObj) ? 100 : result;
} else {
if (basedOn.value != 2) {
//[ 1, 0, z ] == All occurrences, Z item
result = (itemZ == sourceArr[textIndex - 1]) ? 100 : result;
} else {
//[ 1, 0, z ] == All pattern occurrences, up to Z character
result = ((textIndex - 1) in patternObj) ? 100 : result;
}
}
} else {
if (valZ < 1) {
if (basedOn.value != 2) {
//[ 1, y, 0 ] == Y occurrence, all items
result = ((itemY <= (textIndex - 1)) && ((textIndex - 1) <= (itemY + animatorLen - 1))) ? 100 : result;
//[ 1, y, 0 ] == Y occurrence of the whole pattern
} else {
result = ((itemY <= (textIndex - 1)) && ((textIndex - 1) <= (itemY + animatorLen - 1))) ? 100 : result;
}
} else {
//[ 1, y, z ] == Y occurrence, Z item
if (basedOn.value != 2) {
result = (itemY == (textIndex - 1)) ? 100 : result;
//[ 1, y, z ] == Y occurrence of the pattern item, up to Z character
} else {
result = ((itemY <= (textIndex - 1)) && ((textIndex - 1) <= (itemY + valZ - 1)) && ((valZ - 1) < animatorLen)) ? 100 : result;
}
}
}
} else {
//Animator name has only one character
if (valZ < 1) {
if (valY < 1) {
//[ 1, 0, 0 ] == All occurrences of character
result = (itemZ == sourceArr[textIndex - 1]) ? 100 : result;
} else {
//[ 1, 1, 0 ] == Y occurrence of character
result = (itemY == (textIndex - 1)) ? 100 : result;
}
}
}
} else {
//Selector IS based on Lines
if (valY > 0) {
if (valY >= valZ) {
result = (valY == textIndex) ? 100 : result;
} else {
result = (valY <= textIndex) && (valZ >= textIndex) ? 100 : result;
}
}
}
}
}
result *= selectorValueLe code ci-dessus est open source je précise !
Voir la vidéo pour comprendre comment le script fonctionne, mais en gros il faut pour mon cas mettre la propriété <Basé sur> à "Mots" et <Valeur> à "1;0;0" (activation (1=activé) / index occurrence (0=tous) / index mot-clé (0=tous))
Maintenant il ne reste plus qu'à dupliquer autant d'animations que nécessaire pour notre langage, de les renommer avec tous les mots-clés réservés du langage, appliquer la coloration syntaxique souhaité, etc.
Il faudrait ensuite pouvoir "capitaliser" cette banque de mots-clés dans un composant que l'on peut affecter à n'importe quel code source automatiquement (on va pas le refaire à chaque fois).
Je vais voir comment cela peut s'implémenter.
Merci n'hésitez pas à compléter si besoin 🙂
Find more inspiration, events, and resources on the new Adobe Community
Explore Now