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";
+}