diff --git a/doc/conf/LSformat.docbook b/doc/conf/LSformat.docbook index a7887994..85e4eea6 100644 --- a/doc/conf/LSformat.docbook +++ b/doc/conf/LSformat.docbook @@ -2,7 +2,7 @@ Format paramétrable Un format paramétrable est une chaîne de caractères contenant des mots clés formés comme dans l'exemple suivant : -%{[nom du mot clé][:A][:B][! ou _][~]} +%{[nom du mot clé][:A][:B][! ou _][~][%]} Le nom du mot clé peut contenir des lettres de "a" à "z", de "A" à "Z" et des chiffres de 0 à 9. Ces mots clés seront remplacés par les valeurs passées en paramètres et liées au contexte d'utilisation. Les paramètres :A et @@ -32,9 +32,24 @@ dans le premier cas. Si B vaut zéro, la totalité de la long de la chaîne sera retournée en tenant compte de A pour le rang du premier caractère. -Les paramètres ! ou _ permettre respectivement de forcer la mise en majuscule ou en minuscule de la valeur de substitution. +Il existe par ailleurs des paramètres permettant de modifier la valeur de +substitution avant son utilisation : + + + Les paramètres ! ou _ permettre + respectivement de forcer la mise en majuscule ou en minuscule ; + -Le paramètre ~ permet qu'en a lui de forcer la suppression des accents dans la valeur de substitution. + + Le paramètre ~ permet de forcer la suppression des + accents ; + + + Le paramètre % permet de protéger les + caractères éligibles en entités HTML. + + + Lorsque qu'une seule valeur clé est disponible pour la substitution, le nom du mot clé n'importe pas. Tous les mots clés trouvés dans diff --git a/public_html/includes/functions.php b/public_html/includes/functions.php index 270c4dd6..c150480f 100644 --- a/public_html/includes/functions.php +++ b/public_html/includes/functions.php @@ -40,19 +40,18 @@ function getFData($format,$data,$meth=NULL) { $unique=false; /* - * Format : %{[key name][:A][:B][! ou _][~]} + * Format : %{[key name][:A][:B][! ou _][~][%}} * * Extracted fields + * - 0 : full string '%{...}' * - 1 : key name * - 2 : :A * - 3 : A * - 4 : :B * - 5 : B - * - 6 : "-" - * - 7 : ! or _ - * - 8 : ~ + * - 6 : "!" / "_" / "~" / "%" */ - $expr="/%[{(]([A-Za-z0-9]+)(\:(-?[0-9])+)?(\:(-?[0-9]+))?(-)?(\!|\_)?(~)?[})]/"; + $expr="/%[{(]([A-Za-z0-9]+)(\:(-?[0-9])+)?(\:(-?[0-9]+))?([\!\_~%]*)[})]/"; if(!is_array($format)) { $format=array($format); $unique=true; @@ -130,42 +129,73 @@ function getFData($format,$data,$meth=NULL) { } function _getFData_extractAndModify($data,$ch) { - if($ch[3]) { - if ($ch[5]) { - if ($ch[6]) { - if ($ch[3]<0) { - $s=strlen((string)$data)-(-1*$ch[3])-$ch[5]; - $l=$ch[5]; + /* + * Format : %{[key name][:A][:B][-][! ou _][~][%}} + * + * Extracted fields + * - 0 : full string '%{...}' + * - 1 : key name + * - 2 : :A + * - 3 : A + * - 4 : :B + * - 5 : B + * - 6 : "!" / "_" / "~" / "%" + */ + // If A + if($ch[3]!="") { + // If A and B + if ($ch[5]!="") { + // If A and B=0 + if ($ch[5]==0) { + // If A<0 and B=0 + if ($ch[3]<0) { + $s=strlen((string)$data)-(-1*$ch[3]); + $l=strlen((string)$data); } + // If A >= 0 and B else { - $s=$ch[3]-$ch[5]; - $l=$ch[5]; - if ($s<0) { - $l=$l-(-1*$s); - $s=0; - } + $s=$ch[3]; + $l=strlen((string)$data); } } - else { + // If A and B > 0 + elseif ($ch[5]>0) { + // If A < 0 and B > 0 or A >= 0 and B > 0 $s=$ch[3]; $l=$ch[5]; } + // If A and B < 0 + else { + // If A < 0 and B < 0 + if ($ch[3]<0) { + $s=$ch[5]; + $l=false; + } + // If A >= 0 and B < 0 + else { + $s=$ch[3]+$ch[5]; + $l=abs($ch[5]); + } + } } - else if ($ch[5]==0) { + // If only A + else { if ($ch[3]<0) { - $s=strlen((string)$data)-(-1*$ch[3]); - $l=strlen((string)$data); + $s=$ch[3]; + $l=false; } else { - $s=$ch[3]; - $l=strlen((string)$data); + $s=0; + $l=$ch[3]; } } - else { - $s=0; - $l=$ch[3]; + + if ($l==false) { + $val=mb_substr((string)$data,$s); + } + else { + $val=mb_substr((string)$data,$s, abs($l)); } - $val=substr((string)$data,$s,$l); } else { try { @@ -176,17 +206,24 @@ function _getFData_extractAndModify($data,$ch) { } } - # Without Accent - if ($ch[8]) { - $val = withoutAccents($val); - } + if ($ch[6]) { + # Without Accent + if (strpos($ch[6], '~')!==false) { + $val = withoutAccents($val); + } - # Upper / Lower case - if ($ch[7]=="!") { - $val=strtoupper($val); - } - elseif ($ch[7]=='_') { - $val=strtolower($val); + # Upper / Lower case + if (strpos($ch[6], '!')!==false) { + $val=mb_strtoupper($val); + } + elseif (strpos($ch[6], '_')!==false) { + $val=mb_strtolower($val); + } + + # Escape HTML entities + if (strpos($ch[6], '%')!==false) { + $val = htmlentities($val); + } } return $val; @@ -194,7 +231,7 @@ function _getFData_extractAndModify($data,$ch) { function getFieldInFormat($format) { $fields=array(); - $expr='/%[{(]([A-Za-z0-9]+)(\:(-?[0-9])+)?(\:(-?[0-9]+))?(-)?(\!|\_)?(~)?[})]/'; + $expr='/%[{(]([A-Za-z0-9]+)(\:(-?[0-9])+)?(\:(-?[0-9]+))?(-)?(\!|\_)?(~)?(%)?[})]/'; while (preg_match($expr,$format,$ch)) { $fields[]=$ch[1]; $format=str_replace($ch[0],'',$format); diff --git a/public_html/includes/js/functions.js b/public_html/includes/js/functions.js index 923056cf..9dc1714f 100644 --- a/public_html/includes/js/functions.js +++ b/public_html/includes/js/functions.js @@ -44,7 +44,7 @@ function LSdebug(arguments) { */ function getFData(format,data,meth) { /* - * Format : %{[key name][:A][:B][! ou _][~]} + * Format : %{[key name][:A][:B][! ou _][~][%]} * * Extracted fields * - 1 : full string in %{} @@ -53,11 +53,9 @@ function getFData(format,data,meth) { * - 4 : A * - 5 : :B * - 6 : B - * - 7 : "-" - * - 8 : ! or _ - * - 9 : ~ + * - 7 : "!" / "_" / "~" / "%" */ - var getMotif = new RegExp('%\{(([A-Za-z0-9]+)(\:(-?[0-9])+)?(\:(-?[0-9])+)?)(-)?(\!|\_)?(~)?\}'); + var getMotif = new RegExp('%\{(([A-Za-z0-9]+)(\:(-?[0-9])+)?(\:(-?[0-9])+)?)([\!\_\~\%]*)?\}'); var find=1; var val=""; if(($type(data)=='object') || ($type(data)=='array')) { @@ -95,7 +93,7 @@ function getFData(format,data,meth) { val=_getFData_extractAndModify(val,ch); - format=format.replace(new RegExp('%\{'+ch[1]+'[\:0-9\!\_\~\-]*\}'),val); + format=format.replace(new RegExp('%\{'+ch[1]+'[\:0-9\!\_\%\~]*\}'),val); } else { find=0; @@ -108,7 +106,7 @@ function getFData(format,data,meth) { var ch = getMotif.exec(format); if ($type(ch)) { val=_getFData_extractAndModify(data,ch) - format=format.replace(new RegExp('%\{'+ch[1]+'[\:0-9\!\_\~\-]*\}'),val); + format=format.replace(new RegExp('%\{'+ch[1]+'[\:0-9\!\_\%\~]*\}'),val); } else { find=0; @@ -119,64 +117,94 @@ function getFData(format,data,meth) { } function _getFData_extractAndModify(data,ch) { - console.log(ch); - var val=data; + /* + * Extracted fields + * - 1 : full string in %{} + * - 2 : key name + * - 3 : :A + * - 4 : A + * - 5 : :B + * - 6 : B + * - 7 : "!" / "_" / "~" / "%" + */ + var val=(' ' + data).slice(1); // If A if($type(ch[4])) { ch[4]=parseInt(ch[4]); - var s=0; - var l=data.length; + // If A and B if ($type(ch[6])) { ch[6]=parseInt(ch[6]); - // With A and B + // If A and B=0 if (ch[6]==0) { - // If B == 0 - ch[6]=data.length; + // If A<0 and B=0 + if (ch[4]<0) { + s=val.length-(-1*ch[4]); + l=val.length; + } + // If A >= 0 and B + else { + s=ch[4]; + l=val.length; + } } - if (ch[4]>0) { - // A > 0 + // If A and B > 0 + else if (ch[6]>0) { + // If A < 0 and B > 0 or A >= 0 and B > 0 s=ch[4]; l=ch[6]; } + // If A and B < 0 else { - // A < 0 - s=data.length+ch[4]; - if (ch[6]<0) { - // B < 0 - l=data.length-s+ch[6]; + // If A < 0 and B < 0 + if (ch[4]<0) { + s=ch[6]; + l=false; } + // If A >= 0 and B < 0 else { - // B > 0 - l=ch[6]; + s=ch[4]+ch[6]; + l=Math.abs(ch[6]); } } } + // If only A else { - // Only A - if (ch[4]>0) { - // A > 0 + if (ch[4]<0) { + s=ch[4]; + l=false; + } + else { s=0; l=ch[4]; } - else { - // A < 0 - s=data.length+ch[4]; - l=data.length; - } } - console.log("s = " + s + " / l = " + l); - val=data.substr(s,l); + + if (l==false) { + val=val.substr(s); + } + else { + val=val.substr(s, Math.abs(l)); + } } - // Upper or Lower case - if (ch[8]=='!') { - val=val.toUpperCase(); - } - else if (ch[8]=='_') { - val=val.toLowerCase(); - } - // Strip accents - if (ch[9]=='~') { - val=replaceAccents(val); + + if (ch[7] != undefined) { + // Upper or Lower case + if (ch[7].indexOf('!')>=0) { + val=val.toUpperCase(); + } + else if (ch[7].indexOf('_')>=0) { + val=val.toLowerCase(); + } + // Strip accents + if (ch[7].indexOf('~')>=0) { + val=new String(replaceAccents(val)); + } + // Escape HTML entities + if (ch[7].indexOf('%')>=0) { + val=val.replace(/[\u00A0-\u9999<>\&]/gim, function(i) { + return '&#'+i.charCodeAt(0)+';'; + }); + } } return val; } @@ -189,18 +217,17 @@ function _getFData_extractAndModify(data,ch) { * @retval string de-accentuated string */ function replaceAccents(str) { - var new_str = String(str); - var accent = - new Array("à","á","â","ã","ä","ç","è","é","ê","ë","ì","í","î","ï","ñ","ò","ó","ô","õ","ö","ù","ú","û","ü","ý","ÿ","À","Á","Â","Ã","Ä","Ç","È","É","Ê","Ë","Ì","Í","Î","Ï","Ñ","Ò","Ó","Ô","Õ","Ö","Ù","Ú","Û","Ü","Ý"); - var sans_accent = - new Array("a","a","a","a","a","c","e","e","e","e","i","i","i","i","n","o","o","o","o","o","u","u","u","u","y","y","A","A","A","A","A","C","E","E","E","E","I","I","I","I","N","O","O","O","O","O","U","U","U","U","Y"); - if (str && str!= "") { - for (i=0; i { + let i = accent.indexOf(letter); + if (i != -1) { + str[index] = sans_accent[i]; } - } - return new_str; + }) + return str.join(''); } /** diff --git a/tests/test-getFData.js b/tests/test-getFData.js new file mode 100644 index 00000000..08ed22ee --- /dev/null +++ b/tests/test-getFData.js @@ -0,0 +1,30 @@ +var tests=[ +// array(format, test val, test good result) +['%{toto:2}', 'abcdef', 'ab'], +['%{toto:3:-2}', 'abcdef', 'bc'], +['%{toto:1:0}', 'abcdef', 'bcdef'], +['%{toto:-2}', 'abcdef', 'ef'], +['%{toto:-3:2}', 'abcdef', 'de'], +['%{toto:-1}', 'abcdef', 'f'], +['%{toto!}', 'tiTé', 'TITÉ'], +['%{toto_}', 'tiTé', 'tité'], +['%{toto~}', 'tiTé', 'tiTe'], +['%{toto%}', 'tiTé', '<a>tiTé'], +['%{toto!%}', 'tiTé', '<A>TITÉ'], +['%{toto!~}', 'tiTé', 'TITE'], +['%{toto!~%}', 'tiTé', '<A>TITE'], +['%{toto:1!%}', 'tiTé', '<'], +['%{toto:1:0!~}', 'tiTé', 'A>TITE'], +['%{toto:-3!~%}', 'tiTé', 'ITE'], +['%{toto:-3:2!~%}', 'tiTé', 'IT'], +]; + +var nb_tests = tests.length; +for (i = 0; i < nb_tests; i++) { + var result = getFData(tests[i][0], tests[i][1]); + var ok = 'OK'; + if (result != tests[i][2]) { + ok = "\n\t!!!! NOK !!!!"; + } + console.log('Test ('+i+') : "'+tests[i][0]+'" ('+tests[i][2]+') : "'+tests[i][1]+'" -> "'+result+'" => '+ok); +} diff --git a/tests/test-getFData.php b/tests/test-getFData.php new file mode 100644 index 00000000..8843f1d9 --- /dev/null +++ b/tests/test-getFData.php @@ -0,0 +1,30 @@ +tiTé', 'TITÉ'), +array('%{toto_}', 'tiTé', 'tité'), +array('%{toto~}', 'tiTé', 'tiTe'), +array('%{toto%}', 'tiTé', '<a>tiTé'), +array('%{toto!%}', 'tiTé', '<A>TITÉ'), +array('%{toto!~}', 'tiTé', 'TITE'), +array('%{toto!~%}', 'tiTé', '<A>TITE'), +array('%{toto:1!%}', 'tiTé', '<'), +array('%{toto:1:0!~}', 'tiTé', 'A>TITE'), +array('%{toto:-3!~%}', 'tiTé', 'ITE'), +array('%{toto:-3:2!~%}', 'tiTé', 'IT'), +); + +foreach ($tests as $test) { + $result = getFData($test[0], $test[1]); + $ok = (($result == $test[2])?'OK':"\n\t!!!! NOK !!!!"); + echo "Test : \"$test[0]\" ($test[2]) : \"$test[1]\" -> \"$result\" => $ok\n"; +}