willoblog

Aller au contenu | Aller au menu | Aller à la recherche

Tag - geekeries

Fil des billets

vendredi 26 août 2011

Gedit, spell check and PHP syntax

I've been using for a few years Gedit as editor of all my scripts, including bash scripts and PHP scripts. So I use it a lot...

For a while, it seems that spell check is broken. I noticed that when I upgraded to Ubuntu Natty. Here is the issue : When you are editing a PHP script (and PHP syntax highlight is chosen), the only words that are underlined if mispelled are in single-quoted or double-quoted strings. All other words, especially those which are outside php code, aren't checked (nor in heredoc text).

A few bugs are open : on Ubuntu Launchpad, Redhat Bugzilla and Debian bugreport, but I found no ready-to-use solution after googling a moment.

The syntax files of Gedit are in /usr/share/gtksourceview-2.0/language-specs/ (at least for me). Each one defines what is every portion of code (type like string, attribute, keyword, number...) and its properties. "no-spell-check" is one of the properties.

The problem in php.lang is at the last lines : all is defined as "no-spell-check" class (line 321, id "php"), that is all the script, including what is outside php code. The solution is pretty simple : define as "no-spell-check" only what is actually php code, line 291, id "php-block" and erase the "no-spell-check" class on line 321.

As I prefer to check heredoc texts, I had to proceed :

sudo sed -i -e '/id="here-doc-string"/s/>/ class-disabled="no-spell-check">/' -e '/id="php-block"/s/>/ class="no-spell-check">/' -e '/id="php"/s/ class="no-spell-check"//' /usr/share/gtksourceview-2.0/language-specs/php.lang

Bonus : in HTML highlighting, values of attributes are checked. I don't think it's relevant, so I changed that :

sudo sed -i '/attrib-value/s/ class-disabled="no-spell-check"//' /usr/share/gtksourceview-2.0/language-specs/html.lang

This is not perfect yet, as we would like to see the HTML outside php code like in HTML syntax highlight.

jeudi 6 août 2009

Ma discothèque

Le résumé

http://musique.cyril-ravat.fr

La préhistoire

Depuis plus d'un an cela me trottait dans la tête. Alors je me suis pris par la main, j'ai un peu réfléchi, et je l'ai fait. C'est pas encore tout à fait comme je l'imagine au final, mais on s'en approche.

Depuis plus de 13 ans maintenant, depuis le printemps ou l'été 1996, j'achète de albums en cd. Avant, j'avais quelques cassette audio, mais rien de bien important, un pirate de Smash d'Offspring, premier album que j'ai pu écouter en entier, des enregistrements de Skyrock qui ne passait pas la même chose que désormais, des broutilles. Depuis ces temps reculés donc, des albums, beaucoup, maintenant près de 240. Presque tous choisis volontairement.

Depuis 13 ans donc, je note. Enfin au début pas tout à fait, mais en 1998 j'ai commencé à noter avec davantage d'assiduité dans mon agenda titres, artistes, dates d'achat, lieux d'achat et prix. Et je n'ai plus jamais arrêté, à de rares exceptions près. Et maintenant, avec mes capacités à organiser une base de données de façon pérenne, je me disais qu'il fallait vraiment que je stocke ça quelque part, dans des endroits plus sûrs qu'un simple carnet vieilli.

Depuis 3 semaines environ, je m'y suis mis. Entre 8 et 10 heures de code par jour, souvent la nuit, parce que malgré moi c'est comme cela que je préfère bosser. Mais j'ai procédé d'une façon complètement différente à d'habitude. Contrairement à d'habitude, j'ai l'impression de ne pas avoir perdu trop mon temps en pinaillages et fioritures.

L'histoire

Contrairement à d'habitude, j'ai commencé par fabriquer une interface d'administration solide et pratique, à base de contrôles en JavaScript et en Ajax, de validation à la volée, de pseudo-web2.0, de messages d'alertes ou de confirmation qui s'affichent sans recharger la page, dont je suis assez content. Plus je code en utilisant la formidable bibliothèque JQuery, plus je trouve qu'elle est géniale et facilite énormément les chose. Quand je pense que j'avais implémenté dans la GaleriePhotos, en octobre 2006, une connexion de type Ajax (en fait, une simple utilisation de la vieille fonction XMLHttpRequest)... C'est quand même autrement plus élégant de coder cela maintenant en trois ligne parce qu'une API complète se charge de tout.

Et puis, contrairement à d'habitude, j'ai entré quelques albums fictifs en bidouillant partout pour être sûr que la machinerie était robuste. Pas mal de bugs sont apparus, et rapidement, à peu près une semaine après avoir démarré, j'ai commencé à entrer mes albums. Contrairement à d'habitude, je n'ai pas attendu d'avoir tout entré pour avancer, et arrivé à un tiers environ, j'ai codé l'interface publique. Rapidement. J'ai ensuite repris la saisie des données, laborieuse et ennuyeuse. Avec en parallèle quelques moments de réflexions pour implémenter telle ou telle fonction pour l'affichage.

L'épilogue

De fil en aiguille, tout est maintenant enfin prêt. Depuis 2 jours, le site hébergeant la liste de mes albums acquis au fil des ans, de tout mon univers musical, existe. Depuis 4 jours en fait mais les deux derniers jours ont permis d'ajouter des fonctions de recherche et de classement que j'apprécie pas mal, surtout pour les techniques que j'ai employées (ce n'est rien d'autre que du narcissisme, rassurez-vous).

Le site en question, histoire de faire simple, s'appelle

http://musique.cyril-ravat.fr

Je vous invite à y venir faire un tour.

J'allais oublier de parler de ce qu'il manque. Le site contient des données, mais pas encore assez. J'ai prévu d'ajouter :

  • les pistes des albums, éventuellement, si je trouve un moyen simple et pratique de le faire. J'avoue ne pas avoir encore beaucoup cherché.
  • des liens entre artistes et entre albums, du genre « si vous aimez cela, alors vous aimerez... ». C'est assez complexe, en particulier en terme d'interface d'administration. J'ai déjà quelque chose de fonctionnel mais très lent à l'affichage, et mal pratique au final. Il faudrait surement effectuer une présélection grâce aux tags...
  • une description un peu plus complète des artistes, une photo, un lien wikipedia, des trucs.
  • un système de commentaires et la possibilité pour les visiteurs de mettre aussi des notes. En fait, c'est quasiment déjà en place, mais je pense que ce n'est pas le plus pressé et donc je ne le ferai pas très vite.

Et bien sûr, j'ai prévu, quand je serai assez sûr de moi, de publier sous licence libre le logiciel dans son ensemble, au cas où ça pourrait servir à certains. Mais il va falloir attendre une petite année environ avant cela...

SyntaxHighlighter, php et scripts Bash

SyntaxHighlighter : présentation

J'ai découvert il y a quelques semaines un (gros) bout de code génial. Comme le dit le site dédié, il s'agit d'un code de surlignage syntaxique, ou comment rendre des bouts de codes déjà lisibles encore plus lisibles.

L'utiliser n'est pas très compliqué, puisqu'il suffit de télécharger le dernier .zip, de le dézipper et de regarder ce qu'on trouve. Un répertoire scripts contenant en particulier shCore.js qui est le cœur de la machinerie, ainsi que plein de shBrush*.js, qui contiennent les définitions des syntaxes pour différents langages. Personnellement, je n'ai pas besoin de tout, donc je n'ai choisi de garder que ce qui m'intéresse : Bash, Php, Plain que j'utiliserai souvent, Css, JScript et Sql un peu moins, et puis aussi au cas où Diff, Perl, Python, Xml. Un dossier styles contient lui les fichiers de mise en page css, parmis lesquels shCore.css est obligatoire et ensuite shThemeDefault.css correspond au seul thème écrit en noir sur blanc (les autres font du blanc sur noir, je déteste ça). Sans oublier les trois icônes qui seront affichées dans la toolbar et l'icône de retour à la ligne.

Donc on prend tous ces fichiers, on met tout ça dans un répertoire, appelé par exemple syntaxhighlighter, à la racine du site. Il ne reste plus qu'à modifier les pages web en ayant besoin. Il faut rajouter dans l'entête html :

[html]
  <script type="text/javascript" src="/syntaxhighlighter/shCore.js"></script>
  <link type="text/css" rel="stylesheet" href="/syntaxhighlighter/shCore.css"/>
  <link type="text/css" rel="stylesheet" href="/syntaxhighlighter/shThemeDefault.css"/>
  <script type="text/javascript" src="/syntaxhighlighter/shBrushPlain.js"></script>
  <script type="text/javascript" src="/syntaxhighlighter/shBrushBash.js"></script>
  <script type="text/javascript">
    SyntaxHighlighter.all();
  </script>

Ensuite, tous les paragraphes de type <pre> seront analysés, pour peu qu'on dise à quel langage ils correspondent, en ajustant la classe :

[html]
<pre class="brush: bash">

par exemple. J'ajoute aussi, pour éviter la numérotation des lignes quand il s'agit d'une simple ligne de commande :

[html]
<pre class="brush: plain; gutter: false">

Mais il y a encore deux trois détails à gérer. Petits trucs et astuces pour pouvoir afficher des scripts bash comme cela est réalisé sur mon site.

Pour le transcript, deux problèmes

Balises malgré elles

SyntaxHighlighter transforme tous les chevrons « < » et « > » en entités html correspondantes, respectivement « &lt; » (less than) et « &gt; » (greater than). Ce ne serait pas grave s'il ne le faisait pas seulement pour presque tous les chevrons... Or il cherche à détecter automatiquement les balises (ce qui n'est pas très malin dans du code bash d'ailleurs, ce qui fait que mon adresse mail par exemple était comprise comme une balise, dégradant quelque peu la suite de l'affichage. Total : il faut le faire pour lui.
Au départ, j'avais choisi d'utiliser readline en php, à savoir

[php]
<pre class="brush: bash">
<?PHP  @readline('compil'); ?>
</pre>

Mais transformer les chevrons à l'avance n'est pas beaucoup plus compliqué :

[php]
<pre class="brush: bash">
<?PHP  echo str_replace('<','&lt;',str_replace('>','&gt;',file_get_contents('compil'))); ?>
</pre>

Vous aurez remarqué que du coup, dès que le fichier est modifié, c'est le code de la dernière version qui s'affiche. Zéro maintenance (le fichier compil est un lien symbolique vers /usr/local/bin/compil sur mon serveur).

Décidément, ces chevrons...

Et c'est à ce moment que l'on relit un peu ce qui s'affiche à l'écran, et qu'on se rend compte que plein de chevrons (mais pas tous) sont restés à l'état d'entités html. Alors qu'en enlevant l'influence de SyntaxHighlighter, on obtient bien le résultat attendu. Il m'aura fallu quelques minutes pour me souvenir que lt et gt, sont des mots-clés en bash, justement pour des tests numériques plus grand/plus petit (ouais, tout est lié). Un grand dilemme se pose alors. Soit on laisse comme ça, et le code affiché est faux. Soit on s'arrange pour ne jamais avoir de chevrons (ce qui est impossible quand on a besoin de redirections). Soit on commente les mots-clés gt et lt dans le fichier de définition shBrushBash.js, et tant pis pour leurs rares apparences en tant que tests, où ils ne seront pas colorés comme il faut. J'ai choisi cette dernière solution.

Pour l'aide

Ah, là ça se corse. Au départ j'avais recopié telle quelle la réponse de compil -h. Je me suis dit alors « mais si t'as une coquille dans l'aide ou que tu la modifies, il faudra revenir ici... au secours ». Alors j'ai trouvé un moyen. Après plusieurs tâtonnements et hésitations sur la meilleure fonction php entre exec, system et passthru, j'ai opté pour

[php]
<pre class="aide">
$ compil -h

<?PHP 
exec('[ ! -e compil.help -o compil -nt compil.help ] && compil -h | tr -d "\033" | sed -e "s/\[1m/<b>/g" -e "s/\[0m/<\/b>/g" > compil.help');
@readfile('compil.help'); ?>
</pre>

Explication : la dernière commande lit et affiche un fichier compil.help. On va donc y mettre l'aide. Problème, j'utilise un formatage à base de caractères bizarres qui permettent de mettre en gras du texte en console. On prend donc le résultat de compil -h, on en vire donc le caractère bizarre (grâce à la commande tr -d), puis on identifie le début et la fin des mises en gras, que l'on remplace de façon moche mais fonctionnelle par des balises de formatage html.
Le début est un test, qui permet d'exécuter la commande seulement si compil.help n'existe pas ou est plus ancien que compil. Cela semble fonctionner à peu près correctement.