©
. Document créé le 16 juillet 2010 , mis à jour le 16 juillet 2010.Quand on a dix pas à faire, neuf font la moitié du chemin. Proverbe chinois
Accueil du site > Astuces > MacOSX > Compter les caractères d’un fichier RTF
Script PHP à lancer en ligne de commande (Terminal.app), rtf_txtlen tente de convertir proprement le ou les fichiers donnés en paramètres en fichier ascii et en déduit la longueur du texte.
Par défaut, rtf_txtlen nettoie le texte avant de donner son résultat : il supprime les espaces en doubles et les lignes vides.
Le résultat est transmis sur la sortie standard. rtf_txtlen ne fait que lire les fichiers passés en paramètre. rtf_txtlen n’écrit ni ne modifie aucun fichier.
La fonction de conversion rtf2text inspirée du script de DonRamon, a été adaptée et corrigée pour certains caractères. Probablement à compléter d’ailleurs.
#!/usr/bin/php
<?php
// rtf_txtlen
// CP: Fri Jul 16 10:29:47 CEST 2010
// A utiliser en ligne de commande !
// Convertit le texte d'un fichier RTF
// et en donne la longueur
// ex:
// monfichier.rtf 123456
// @see: http://habrahabr.ru/blogs/php/70119/
// @todo: tester un très gros fichier
$strip = $print = true;
$output = $help = false;
$usage = "Usage: {$argv[0]} [-h] [-s] [-o] [-n] [-?] file [file ...]";
$files = array();
if($argc > 1) {
// Le premier arg est le nom de ce script
// Ergo, passer à l'argument suivant
while ($arg = next($argv)) {
if ($arg[0] === '-') {
// option commence par '-'
switch ($arg) {
case '-h':
case '--help':
case '-help':
case '-?':
$help = true;
break;
case '-s':
$strip = true;
break;
case '-o':
$output = true;
break;
case '-n':
$strip = false;
break;
}
}
else {
$files[] = $arg;
}
}
}
else {
fwrite(STDERR, $usage . PHP_EOL);
exit(1);
}
if ($help) {
fwrite(STDOUT, "
rtf_txtlen: Returns text len of RTF file.
{$usage}
Options:
-h print this help and quit
-n don't strip whitespaces and blank lines
-s strip whitespaces and blank lines
-o output file convertion to stdout
file RTF filename
");
exit();
}
// Certains éléments précisent la forme
// de la page (couleur, fonte)
// ne sont pas du vrai contenu.
/*
* rtf_isPlainText()
* @param: $s string
* @return: true si c'est du vrai contenu
*/
function rtf_isPlainText($s) {
static $n_eviter;
$eviter = array(
'*'
, 'author'
, 'info'
, 'fonttbl'
// Color Table
, 'colortbl'
// Custom XML Data Properties
, 'datastore'
, 'themedata'
// oOo use stylesheet
, 'stylesheet'
);
if(!$n_eviter) {
$n_eviter = count($eviter);
}
for ($i = 0; $i < $n_eviter; $i++) {
if (!empty($s[$eviter[$i]])) return(false);
}
return(true);
}
/*
* Lire le fichier demandé
* et le convertir en texte.
* $param: $filename string
* @return: le texte converti
*/
function rtf2text($filename) {
// Lire le fichier complet indiqué.
// Attention aux très gros fichiers.
$text = file_get_contents($filename);
$text = trim($text);
if (!strlen($text)) {
return '';
}
$document = '';
$stack = array();
$j = -1;
$chr_39 = chr(39);
$chr_45 = chr(45);
$chr_46 = chr(46);
$chr_tab = "\t";
// caractère par caractère
for ($i = 0, $len = strlen($text);
$i < $len;
$i++
) {
$c = $text[$i];
switch ($c) {
// si backslash, key word
case '\\':
// lire ce qu'il y a après
$nc = $text[$i + 1];
$rtf_isPlainText = rtf_isPlainText($stack[$j]);
if ($nc == '\\' && $rtf_isPlainText) {
$document .= $nc;
}
elseif ($nc == '~' && $rtf_isPlainText) {
$document .= ' ';
}
elseif ($nc == '_' && $rtf_isPlainText) {
$document .= '-';
}
elseif ($nc == '*') {
$stack[$j][$nc] = true;
}
elseif ($nc == "'") {
$hex = substr($text, $i + 2, 2);
if (rtf_isPlainText($stack[$j])) {
$document .= chr(hexdec($hex));
}
$i += 2;
} elseif (
($nc >= 'a' && $nc <= 'z')
|| ($nc >= 'A' && $nc <= 'Z')
) {
$word = '';
$param = null;
for ($k = $i + 1, $m = 0;
$k < strlen($text);
$k++, $m++
) {
$nc = $text[$k];
if (
($nc >= 'a' && $nc <= 'z')
|| ($nc >= 'A' && $nc <= 'Z')
) {
if (empty($param)) {
$word .= $nc;
}
else {
break;
}
} elseif ($nc >= '0' && $nc <= '9')
$param .= $nc;
elseif ($nc == '-') {
if (empty($param)) {
$param .= $nc;
}
else {
break;
}
} else {
break;
}
}
$i += $m - 1;
$toText = '';
switch (strtolower($word)) {
// 'u' est suivi d'un paramètre
// en notation décimale d'un char unicode
case 'u':
// skip utf8
$toText .= (($param < 256)
? chr($param) : ' ');
$ucDelta = @$stack[$j]['uc'];
if ($ucDelta > 0) {
$i += $ucDelta;
}
break;
case 'par':
case 'page':
case 'column':
case 'line':
case 'lbr':
$toText .= PHP_EOL;
break;
case 'emspace':
case 'enspace':
case 'qmspace':
$toText .= ' ';
break;
case 'tab':
$toText .= $chr_tab;
break;
case 'chdate':
$toText .= date("m.d.Y");
break;
case 'chdpl':
$toText .= date("l, j F Y");
break;
case 'chdpa':
$toText .= date("D, j M Y");
break;
case 'chtime':
$toText .= date("H:i:s");
break;
case 'emdash':
case 'endash':
$toText .= $chr_45;
break;
case 'bullet':
$toText .= $chr_46;
break;
case 'lquote':
case 'rquote':
$toText .= $chr_39;
break;
default:
$stack[$j][strtolower($word)] =
empty($param)
? true
: $param
;
break;
}
if (rtf_isPlainText($stack[$j])) {
$document .= $toText;
}
}
$i++;
break;
case '{':
array_push($stack, $stack[$j++]);
break;
case '}':
array_pop($stack);
$j--;
break;
case '\0':
case '\r':
case '\f':
case '\n':
break;
default:
if (rtf_isPlainText($stack[$j])) {
$document .= $c;
}
break;
}
}
return($document);
}
// traiter les fichiers donnés en paramètre
foreach($files as $file) {
$len = null;
if(is_readable($file)) {
$result = rtf2text($file);
if($result && $strip) {
// supprimer les espaces en trop
// et les lignes vides
$replace = array(
'@[[:space:]]+@' => ' '
, '@[\r\n]+@' => "\n"
);
$result = preg_replace(array_keys($replace)
, $replace, $result);
}
if($output) {
echo($result . PHP_EOL);
}
if($print) {
echo($file . "\t" . strlen($result) . PHP_EOL);
}
}
else {
fwrite(STDERR, 'Error: '.$file . ' unreadable' . PHP_EOL);
}
}
Pour une utilisation plus souple, donnez les droits d’exécution (755) à ce script.
Problème de copier/coller ? Voici le script :
P.S. : unrtf, disponible sur le site gnu.org permet également de traduire un fichier RTF. Mais il ignore les accents (mode —text) et nécessite l’écriture dans un fichier.
A découvrir :
Les forums sont fermés.