Archives par mot-clé : cal

Programme cal « vertical » optimisé

Dans un précédent article traitant de calendriers pèles-mêles, j’avais proposé l’écriture d’un programme cal permettant l’affichage vertical d’un mois.

Dans un souci d’apporter des solutions toujours meilleures, voici une nouvelle version de ce programme, qui apporte son lot d’améliorations :

  • plus robuste
  • plus performant
  • plus pérenne et évolutif

Bref, que du bonheur pour un gourou linuxien !

Ici, il n’est plus question d’utiliser la commande cal… Le texte parsé : aux oubliettes ! A la place, nous allons utiliser la commande date. Cette dernière va avoir plusieurs rôles, à savoir le nom des jours à afficher dans notre calendrier vertical, et la détection de la fin du mois via son code d’erreur en sortie (récupéré grâce au « $? »).

Commençons par définir des variables simples, que nous pourrons remplacer par des paramètres « dynamiques » ultérieurement : nous fixons une année et un mois comme ceci :

Y=’2010′
m=’07’

Le reste du programme consiste ensuite en une boucle for, prenant comme paramètres les numéros de jours allant de 01 à 31. Une autre possibilité serait d’utiliser une boucle while en incrémentant une variable de 1 à 31, mais voilà, j’ai pas envie… C’est donc dans la boucle ci-dessous que nous allons mettre « tout » notre code ; autant dire pas grand chose, vous allez voir…

for d in 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
do

[…]

done

A ce stade, nous connaissons l’année « $Y », le numéro de mois « $m » et le numéro de jour « $d ». Il nous faut connaître le nom du jour. La commande date permet d’afficher le nom du jour de deux façons :

  • avec « %A » pour l’affichage du nom complet (par exemple « lundi »)
  • avec « %a » pour l’affichage du nom abrégé (par exemple « lun »)

A l’aide du paramètre « -d », nous allons pouvoir soumettre nos 31 dates à la-dite commande, qui va donc gentiment nous retourner les jours correspondant… lorsque ces dates existent, ou bien nous gueuler dessus dans le cas contraire. Cette faculté à rejeter une date non valide va justement nous intéresser dans la suite.

date +’%a’ -d "$Y-$m-$d"

L’exécution de la commande ci-dessus retourne :

  • soit le nom abrégé du jour à la date précisée, ainsi que le code retour « 0 » pour « succès »
  • soit un message d’erreur car la date est non valide, et le code retour « 1 » pour « échec »

Nous devons stocker dans une variable le nom du jour obtenu, et empêcher l’affichage d’un éventuel message d’erreur en le redirigeant vers « /dev/null ». Il ne nous reste plus qu’à tester le résultat du code retour ainsi :

  • si c’est « 0 » (la date existe bien), on affiche le jour et son numéro dans le terminal
  • si c’est « 1 » (la date est non valide), on sort de la boucle for, le programme s’arrête normalement

Voici le programme (presque !) complet :

function cal2 ()
{
	Y='2010'
	m='07'
	
	for d in 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
	do
		j=`date +'%a' -d "$Y-$m-$d" 2>> /dev/null`
		
		if test "$?" = 0
		then
			printf "%3s %2s\n" "$j" "$d"
		else
			break
		fi
	done
}

Le résultat est déjà pas mal, mais on peut faire plus pratique en retirant désormais les limitations de développement sur l’année et le numéro de mois. Si ces données sont passées en arguments, alors nous nous en servons. Dans le cas contraire, nous utiliserons la date actuelle.

test "$1" != "" && Y=$1 || Y=`date +’%Y’`
test "$2" != "" && m=$2 || m=`date +’%m’`

Pour s’assurer de la pertinence des arguments passés à notre fonction, nous allons les contrôler à l’aide des expressions régulières. Ainsi, en cas de valeur non valide, le programme est stoppé et retourne la valeur « 1 » sans rien écrire dans le terminal.

case $Y in [1-2][09][0-9][0-9]) ;; *) return 1 ; esac
case $m in [01][0-9]) ;; *) return 1 ; esac

Il ne nous reste qu’à ajouter ces quatre petites lignes dans notre fonction, et le tour est joué.

function cal2 ()
{
	test "$1" != "" && Y=$1 || Y=`date +'%Y'`
	test "$2" != "" && m=$2 || m=`date +'%m'`
	
	case $Y in [1-2][09][0-9][0-9]) ;; *) return 1 ; esac
	case $m in [01][0-9]) ;; *) return 1 ; esac
	
	for d in 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
	do
		j=`date +'%a' -d "$Y-$m-$d" 2>> /dev/null`
		
		if test "$?" = 0
		then
			printf "%3s %2s\n" "$j" "$d"
		else
			break
		fi
	done
}

Après exécution de notre nouvelle commande, voici le résultat dans le terminal :

[benoit:~]$ cal2 2010 07
jeu 01
ven 02
sam 03
dim 04
lun 05
mar 06
mer 07
jeu 08
ven 09
sam 10
dim 11
lun 12
mar 13
mer 14
jeu 15
ven 16
sam 17
dim 18
lun 19
mar 20
mer 21
jeu 22
ven 23
sam 24
dim 25
lun 26
mar 27
mer 28
jeu 29
ven 30
sam 31

Je vous épargnerai davantage de code, mais, pour une utilisation exclusivement en ligne de commande, on pourrait aussi ajouter quelques améliorations visuelles, comme par exemple afficher en rouge les dimanches, ou bien souligner la date du jour… Bref, de quoi jouer encore quelques heures sur un programme finalement peu utile ! :mrgreen:

Le retour du calendrier pèle-mêle

Suite au précédent article sur la réalisation de calendriers avec l’aide de Fotowall, voici une alternative au calendrier mensuel « rectangulaire ». En effet, le calendrier affiché par la commande cal a l’avantage d’être compact. Cependant, on peut très bien préférer un affichage des mois sous forme « verticale », notamment pour avoir la possibilité d’annoter de petites choses en face d’une date.

Ce calendrier « vertical » m’a posé deux difficultés :

  • La commande cal ne permet pas un affichage autre qu’une semaine par ligne… Il a donc fallu que je fasse un peu de programmation…
  • Dans le cas du calendrier « rectangulaire », Scribus remplissait parfaitement son rôle pour faciliter la mise en forme à l’aide des styles. Malheureusement ce n’est plus du tout le cas avec le calendrier « vertical », qui oblige à séparer chaque ligne, soit par un trait, soit par un fond coloré alternatif, afin de faciliter la lecture. Je me suis donc tourné vers OpenOffice, mais vous verrez que tout n’est pas simple… Dans le cas du calendrier « vertical », j’ai d’abord pensé que Scribus ne permettrait tout simplement pas d’obtenir des résultats satisfaisants. Après une longue réflexion, j’ai finalement conclu que le format du calendrier ne changeait rien au problème, et que Scribus est donc tout à fait adapté ! Ce constat ayant été fait après la réalisation du présent article, la solution avec Scribus ne sera pas abordée ici. Les personnes intéressées par une utilisation de Scribus, qui apporte notamment le format vectoriel SVG et la transparence, pourront toujours se tourner vers le précédent article pour s’en inspirer : Réaliser un calendrier pèle-mêle. L’exemple ci-dessous avec l’utilisation d’OpenOffice permet en outre de bien comprendre que pour parvenir à un résultat, il existe plusieurs solutions, chacune avec ses avantages et ses inconvénients.

La commande cal revisitée

Comme expliqué un peu plus haut, la commande cal n’affiche le calendrier que d’une seule façon : un jour par colonne et une semaine par ligne. Pour continuer à profiter de la simplicité de la ligne de commande (je dois dire que j’aime bien le Bash !), j’ai décidé de développer un bout de code permettant de modifier l’affichage de cal. Ce script Bash est largement perfectible et nécessitera sans doute quelques petits arrangements pour coller à l’utilisation de certains.

#!/bin/bash

mois=$1
annee=$2

i=0

cal -m $mois $annee | while read ligne
do
    i=`echo $i + 1 | bc`

    if test $i -lt 3
    then
        continue
    fi

    if test "$ligne" != ""
    then
        j=1

        if test $i -eq 3
        then
            j=8

            for nombre in $ligne
            do
                j=`echo $j - 1 | bc`
            done
        fi

        for nombre in $ligne
        do
            case $j in
                1)
                    printf 'lun %2.0f\n' $nombre
                    ;;
                2)
                    printf 'mar %2.0f\n' $nombre
                    ;;
                3)
                    printf 'mer %2.0f\n' $nombre
                    ;;
                4)
                    printf 'jeu %2.0f\n' $nombre
                    ;;
                5)
                    printf 'ven %2.0f\n' $nombre
                    ;;
                6)
                    printf 'sam %2.0f\n' $nombre
                    ;;
                7)
                    printf 'dim %2.0f\n' $nombre
                    ;;
            esac

            j=`echo $j + 1 | bc`
        done
    fi
done
exit 0

C’est moche et obscur, pas vrai ? 8) Vous pourrez retrouver ce script au sein de l’archive zip présente un peu plus bas dans l’article. Celui-ci s’utilise exactement de la même façon que la commande cal, et prend en conséquence, un paramètre mois compris entre 1 et 12, et un paramètre année.

Mise en forme avec OpenOffice

Qu’on se le dise, aucune solution ne m’a réellement satisfait pour réaliser la mise en forme de ce calendrier. La seule solution trouvée, et ne consistant pas à concevoir un énième bout de code en Bash ou en PHP pour produire du SVG… Euh, bref, la seule possibilité trouvée pour profiter autant que possible des outils courants*, et par là même, de la gestion des styles de ces outils, a consisté à copier-coller la sortie de ma commande « cal2 » dans le tableur d’OpenOffice. Calc permet de gérer les styles sur les cellules, ce qui permet de retomber dans la même configuration que Scribus avec les paragraphes, à peu de choses près. Le fichier calendrier_modele.ots présent dans l’archive zip est un modèle de tableur avec quelques styles pré-définis pour faciliter la mise en forme des calendriers mensuels.

Malheureusement, Calc ne permet pas l’export sous forme d’image. Pour pouvoir faire cet export, j’ai été obligé de faire appel à Draw, lui aussi faisant partie de la suite OpenOffice. Pour insérer un tableur dans une page de Draw, il faut cliquer sur Insertion > Objet > Objet OLE, puis cliquer sur l’onglet « Créer à partir d’un fichier« . Le fichier calendrier_convertisseur.odg présent dans l’archive zip, est là à titre d’exemple. Pour fonctionner, il requiert les 12 fichiers *.ods représentant chacun des mois, qui pourront être remplacés par de nouveaux calendriers. Pour ce faire, la démarche est simple : utilisez le modèle en copiant-collant un premier calendrier, adaptez l’apparence des cellules à l’aide des styles, modifiez les styles selon vos goûts, et enregistrez votre mois en écrasant le fichier .ods correspondant. Votre calendrier apparaîtra automatiquement à la prochaine ouverture du fichier calendrier_convertisseur.odg !

La production des images me laisse encore une fois sur ma faim. Avec cette méthode, impossible d’obtenir un résultat satisfaisant en SVG (image vectorielle). Il faut donc se contenter d’un format d’image PNG ou JPG (image matricielle), intrinsèquement limité par sa résolution en pixels. Quoi qu’il en soit, pour produire une image de chaque page dans Draw, il vous suffira de cliquer sur Fichier >Exporter, et sélectionner le format de fichier approprié, PNG ou JPG, selon votre préférance. Le format PNG ne permettra même pas d’obtenir un fond transparent, ce qui est une autre mini-déception… 🙁

Une fois vos images créées… si toutefois vous avez eu le courage de suivre toutes ces instructions… si toutefois vous avez eu le courage de me lire… il ne vous reste plus qu’à les ajouter à vos pèle-mêles dans Fotowall. Voici un résultat de ce que cela a donné avec les fichiers de l’archive zip.

Exemple de calendrier vertical
Exemple de calendrier vertical

Pour disposer de tous les fichiers nécessaires à la réalisation d’un calendrier, je vous invite à télécharger l’archive zip et à décompresser son contenu. Bien évidemment, les utilisateurs sous Windows, donc pratiquement tout le monde, ne seront pas en mesure de lancer le script cal2… Ne désespérez pas ! Vous pouvez toujours taper les dates à la main…

Comme précisé en début d’article, Scribus permet bel et bien de réaliser des calendriers sous forme verticale. L’exemple ci-dessous a donc directement pu profiter du format SVG et de la transparence du fond, même si une conversion intermédiaire en PNG a été requise en raison d’un mauvais affichage des caractères.

Calendrier vertical grâce à Scribus
Calendrier vertical avec l'aide de Scribus

* Pour les linuxiens, la commande cal fait bel et bien partie des outils courants…

Réaliser un calendrier pêle-mêle

Les sites de développement photo sont monnaie courante, et tous proposent des calendriers. Ces calendriers, généralement basés sur des modèles pré-définis, peuvent être personnalisés avec les photos d’anniversaire de la petite dernière, ou bien avec les photos de vos dernières vacances à la neige (avant que vous ne les finissiez plâtré).

Pour les plus créatifs d’entre nous, il existe diverses façons de réaliser des calendriers. Je vous propose d’en découvrir une un peu originale. Ceux qui me connaissent se douteront que les outils utilisés seront exclusivement des logiciels libres, qui plus est multi-plateformes… à une toute petite exception près… Voici les logiciels dont nous aurons besoin :

  • La commande cal pour la génération de données calendaires. Bon, oui, je sais, il faut être linuxien pour aimer les lignes de commandes obscures… Mais essayez seulement d’obtenir un calendrier au format texte avec ouin-ouin ! Vous ne pouvez pas ? Dommage…
  • Scribus pour la personnalisation des mois. Cet excellent logiciel de PAO va nous permettre d’avoir des mois facilement mis en page grâce à la gestion des styles, et d’exporter les pages au format SVG pour une qualité irréprochable.
  • Fotowall pour la réalisation d’un pêle-mêle intégrant un mois du calendrier, ou pourquoi pas un calendrier complet. Un exemple sera donné pour chacun de ces cas.

Données calendaires au format texte

La chose essentielle pour réaliser un calendrier, ce sont les dates : mois, semaines, jours, numéro des jours dans le mois, etc. Pour pouvoir personnaliser entièrement un calendrier, il est hors de question de faire une copie d’écran du calendrier de votre environnement (KDE, Gnome, ouin-ouin…) ou de Sunbird ;  d’autant que cela ajouterait la nécessité de retoucher ces copies d’écran à l’aide de Gimp ou de Photoshop, donc non merci. Il faut impérativement disposer de ces données sous forme textuelle, et là je maîtrise personnellement deux façons de faire : soit je « m’amuse » à écrire les dates une à une 365 ou 366 fois, soit j’utilise la commande cal et là tout est largement plus simple. Voici ce que va nous donner cette commande magique sous GNU/Linux :

[benoit@localhost:~]$ cal -m 1 2010
janvier 2010
lu ma me je ve sa di
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31

[benoit@localhost:~]$ cal -m 2 2010
février 2010
lu ma me je ve sa di
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28

# puis 3, 4, 5, etc…
# le paramètre « -m » permettant d’avoir le lundi en premier et non le dimanche

Pour toute explication supplémentaire sur l’utilisation ô combien ésotérique de cal, RTFM :

[benoit@localhost:~]$ man cal

Si vous constatez que les mois sont en anglais, pas de panique, tapez ceci dans le terminal, puis exécutez de nouveau la commande cal :

[benoit@localhost:~]$ LANG=fr_FR

Personnalisation du calendrier avec Scribus

Nous ne prendrons pas le temps d’expliquer ce que permet de faire Scribus et comment il s’utilise. Les didacticiels sont très nombreux sur Internet, et plusieurs ouvrages sont également disponibles en librairie. Nous nous contenterons donc de préciser les paramètres les plus importants pour une bonne mise en page de nos mois.

Afin de conserver l’alignement vertical des jours, vous devrez obligatoirement utiliser une police de caractères à pas fixe. « A pas fixe » veut dire que la largeur des caractères, aussi bien lettres, chiffres, espace ou autres, sera toujours identique, ce qui n’est par exemple pas le cas de Times New Roman. Puisque le Libre est mon credo, je ne peux que vous inviter à utiliser la famille de polices de caractères DejaVu, également disponibles pour Windows. Dans notre cas, nous ferons donc appel à la fonte DejaVu Sans Mono. Tout le reste dans Scribus consistera à habiller nos différents mois. Pour vous embêter le moins possible, il est recommandé d’user et d’abuser des styles de paragraphes, notamment accessibles par la touche F3. De la même façon, utilisez les gabarits pour vous assurer d’avoir toujours le même rendu avec vos décorations, quel que soit le nombre de pages. Vous pouvez télécharger le fichier Scribus (compressé) de l’exemple ci-dessous : calendrier_2010.zip

Exemple de calendrier
Exemple de calendrier
Une fois que vos mois sont prêts, il ne vous reste plus qu’à les convertir en images SVG. Pour ce faire, dans Scribus c’est très facile : rendez-vous dans le menu Fichier > Exporter > Enregistrer en SVG pour enregistrer une à une vos pages, et c’est tout ! Si vous souhaitez éditer vos images, vous pourrez par exemple le faire à l’aide du génialissime Inkscape, qui est encore une fois un logiciel libre et multi-plateforme.

Réalisation du ou des pêle-mêles avec Fotowall

A ce stade, le plus gros du travail a été fait. Il ne vous reste plus qu’à réaliser vos pêle-mêles avec le très intuitif Fotowall, directement en y ajoutant vos fichiers SVG comme vous feriez avec vos photos. Voici trois exemples réalisés avec le calendrier ci-dessus.

Pêle-mêle mensuel avec des photos
Pêle-mêle mensuel avec des photos
Un premier calendrier annuel
Un premier calendrier annuel

Un second calendrier annuel
Un second calendrier annuel
Il ne vous reste plus qu’à faire preuve de créativité et d’expérimenter toutes les possibilités offertes par ces fabuleux logiciels qui, rappelons-le encore une fois, sont libres et multi-plateformes. Pour une excellente qualité d’image, n’oubliez pas d’exporter vos pêle-mêles dans des dimensions très importantes, par exemple en 8000 * 6000 pixels ! C’est mieux pour être développé sur du papier photo… 😉