Valentin Jacquemin

From my Strava activites into one sparkline

With sal it’s now possible to fetch on demand all my personal Strava activities from the past year. The next step is to transform this raw dataset into a sparkline. But before diving into this, let’s see concretly how to install and start using sal.

Setup walkthrough

sal’s README explains it all, let’s go through this step by step.

  1. On Strava, create an API Application.

  2. Fetch sal from the GitHub repository’s release section or build it on your machine.

  3. Launch sal. You’ll need a browser to complete the first launch as it has to fetch an authentication token and ask for your approval in doing so.

    You’ll need the client_id and the client_secret that got generated on step 1 as well. They are available anytime on the settings page of your Strava profile.

    SAL_CLIENT_ID=<your_client_id> SAL_CLIENT_SECRET_ID=<your_client_secret_id> sal

  4. Under the default root directory for user-specific configuration, you’ll find the authentication details that sal will use on further launches. Those are stored under sal/state.json. That will come handy later.

If everything is alright, that should be it, the past year of Strava activities are dumped in your terminal!

Raw data into a sparkline

That dataset is an array of activities. To transform that into a sparkline, that needs to go through a few steps of transformations.

The idea is to get the total distance per week and then to plot those 52 points on a line. Besides that, one or two other stats are computed so that we can generate the accompanying text.

The whole pipeline uses jq and m4. The bulk of the process is the following:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
SL_DATAPOINTS=$(jq -c '.| map(select(.sport_type == "Run" or .sport_type == "TrailRun"))
    | map({distance: .distance, start_date: (.start_date | fromdate | strftime("%g%V"))})
    | group_by(.start_date)
    | map({start_date: (first.start_date), distance: (map(.distance) | add | floor | . / 1000)})

    +
    [(range(52) | {start_date: (now - (60 * 60 * 24 * 7 * .) | strftime("%g%V")), distance: 0})]
    | group_by(.start_date)
    | map({(first.start_date): (map(.distance) | add)})
    | reduce .[] as $week ({max: 0}; . as $acc | . + $week + ($week | keys | $week[.[0]] as $d | if $d > $acc.max then {max: $d} else {} end))
    | .max as $max | map_values(. / $max * 24 | round) | del(.max)

    | to_entries
    | . as $payload | reduce .[] as $week (""; . + ($payload | index($week) | . * 3 | tostring) + "," + ($week.value | tostring) + " ")
    ' activities.json)

A whole bunch of things are taking place 🤠:

  1. map and select filters the dataset to retain only running and trailrunning activities
  2. another map transforms each entries to pick only the distance and the date of the activity; the %g%V date format creates a key we’ll use to group activities of the same week. For example for today 2608 is %g%V
  3. group_by prepares the dataset so that we can make a total per week, it produces an array of activites per week, or more precisely per %g%V
  4. the next map sums all the activites of each week
  5. to ensure there’s no hole in the series, another array is created. It contains the 52 past weeks and an initial distance to zero
  6. next, it groups the 2 arrays in one, with the week as key
  7. for each week, it sums the .distance key, from each array; if I don’t run on a given week, this would ensure that I still have a datapoint for that week. At that stage, the dataset is made up of week keys and _distance values, as in [{"2607": 42}, ...].
  8. lines 10-11 normalize the .distance values
  9. lines 13-14 are the final touches to generate the 52 datapoints that we are going to draw with svg. The . * 3 is for the width of a given week. So the whole sparkline would be approximately 160px wide. There was definitely a bit of playing around before I’d end up with a pleasing rendering
  10. activities.json contains the output of sal, the past 52 weeks of Strava activities

So SL_DATAPOINTS contains the datapoints, something like 0,6 3,3 6,5..., and are included in a m4 template that I prepared.

More on this next step, in yet another upcoming and final post about this fun little side project.

Visualizing my year of running with one sparkline

Around 2010, I started running. Regularly. I was going through a very tough time – betrayal, abuse and loss of trust. That was my darkest period. It took me years to recover some self-esteem and my usual cheerfulness. Although I’ve never lost hope, I often felt powerless and stuck.

Running became an outlet that helped me greatly rebuild myself, to this day it helps me to balance my emotions, to process my life and expand my gratitude.

Thanks to running, I know that I may show a good dose of grit. I know that I can be disciplined enough to follow a training program to be fit to run a marathon at a given pace.

Thanks to running I’ve had unforgettable experiences. I’ve seen places, I’ve strengthened friendships. I’ve marveled at what our body is capable of achieving.

I’ll always be thankful that running is there.

Early came technology to the mix, I’ve used initially Runkeeper as a platform to track my runs. I think I purchased my first training programs there too. It started with half-marathon goals. Later came Strava, that’s where I post my runs until this date.

I used to have a subscription on Strava and that meant having access to a whole bunch of different tracking data. I would from time to time check my yearly progress in elevation, distance, etc.

But I dropped that subscription a couple of years ago as my running volume decreased drastically. New (happy) life priorities.

With no subscription comes less statistics, that’s part of the deal. But Strava provides an API you can use to fetch all your personal activities.

I’m using this API to generate a sparkline on my running blog. That one gives me the one statistic that I still like to look at: yearly distance.

Sparkline illustrating my running distance over 52 weeks. I amounts to 1006.9km.
The sparkline, how it looks like today on runboyrun.

To generate and publish it automatically I’m using sal a command-line tool I’ve created to first fetch the data needed.

I chose Go to build sal because I’ve been reading a couple of Go codebases over the past 2 years1, found nice what I read and thought this command line utility would be a perfect side project to get some practice. I liked especially how easy it’s been to generate cross-platform binaries. Knowing that I’m developing on a MacBook and that my goal was to run this little thing on my tiny home server running a Linux distro, that cross-compiling feature has been a decisive factor!

Every day, sal downloads all my Strava activities from the past year, 52 weeks and stores them in a JSON file. I get all the details I need in there, specifically distance, the type of the activity and its datetime.

That’s the foundation.

Then how do you transform this raw dataset into a sparkline? I’ll describe that second part in another post.


  1. I’ve been diving into CKAD in 2023, LFS261 and LFS241 in 2024 and Terraform in 2025 all of which are codebases written in Go ↩︎

I migrated all my tweets, here's how

On how I reclaimed my tweets and imported them into my personal website

About a year ago, I closed my twitter account. Before pulling the trigger though, I’ve exported my personal content as I knew that I did not want to loose all that history of my online presence.

Funnily, that export feature still matches the Twitter branding, the guys from X did not bother taking care of that.

My personal twitter archive homepage
My twitter archive as static website. X did not bother rebrading this feature.

I got in my mailbox a fully functioning static website. Where I could browse my own feed as if Twitter still existed. You can search, filter and sort the feed as you please, all locally. The web as I like it.

I did not know what I would do with that archive a year ago. I just wanted to close my account without loosing my content. As I decided to resume my personal website, I knew that my tweets would get a new home in there.

Here’s how I migrated that content.

When you browse the archive you quickly find where to go. And as it’s a static website anyway, you can figure out how the whole thing works by looking to the sources.

twitter-archive> tree -P '*.html' -L2
.
├── assets
│   ├── fonts
│   ├── images
│   └── js
├── data
│   ├── community_tweet_media
│   ├── deleted_tweets_media
│   ├── direct_messages_group_media
│   ├── direct_messages_media
│   ├── moments_media
│   ├── moments_tweets_media
│   ├── profile_media
│   ├── tweets_media
│   └── tweets.js
└── Your archive.html

The entire collection of tweets is in app/tweets.js. From there to my own website, it’s a matter of using a few tools to filter and re-shape that array of microblog entries.

First, I simply kept the json compatible part of app/tweets.js, i.e. I dropped the javascript variable declaration. I saved that into preprocess1.json.

Second, I decided to filter out any replies as I just wanted to keep my own posts. That would be too much of work to bring replies into their context, not even sure that it would be feasible at all.

jq '[.[] | .tweet.id as $id 
  | ( .tweet.entities.media | length > 0 ) as $hasMedia 
  | select(IN(paths; ["tweet", "in_reply_to_user_id"])==false) 
  | del(
    .tweet.extended_entities, 
    .tweet.favorite_count, 
    .tweet.id_str, 
    .tweet.truncated, 
    .tweet.retweet_count, 
    .tweet.id, 
    .tweet.possibly_sensitive, 
    .tweet.favorited, 
    .tweet.entities.user_mentions, 
    .tweet.entities.symbols, 
    .tweet.entities.hashtags, 
    .tweet.retweeted, 
    .tweet.edit_info, 
    .tweet.source, 
    .tweet.display_text_range) 
   | .tweet.entities.media 
   |= if $hasMedia then $id end]' preprocess.1.json > preprocess.2.json

That filtered out about a third of my tweets.

Then I re-shaped the tweets. For example, the json payload gives the expanded URLs of any shortened link present in a tweet:

{
    "tweet" : {
      "entities" : {
        "urls" : [
          {
            "url" : "https://t.co/FhmBWq39rL",
            "expanded_url" : "https://activitypub.rocks/",
            "indices" : [
              "178",
              "201"
            ]
          }
        ]
      },
      "created_at" : "Fri Nov 01 11:54:07 +0000 2024",
      "full_text" : "\"Don't you miss the days when the web really was the world's greatest  decentralized network?  Before everything got locked down into a handful  of walled gardens?  So do we.\" – https://t.co/FhmBWq39rL",
      "lang" : "en"
    }
  },

I definitely don’t want to use the twitter URL shortener anymore. Thanks to that thorough payload, it was easy for me to translate them.

A multipass of the following jq script would convert all the shortened URLs into their expanded version.

cat preprocess.2.json | jq '[.[] 
  | .tweet.entities.urls[0]?.url as $url 
  | .tweet.entities.urls[0]?.expanded_url as $expanded_url 
  | (if $url then .tweet.full_text 
  | sub($url; "<a href=" + $expanded_url + ">" + $expanded_url + "</a>") 
    else .tweet.full_text end) as $text 
  | { tweet: { 
      full_text: $text, 
      lang: .tweet.lang, 
      created_at: .tweet.created_at, 
      entities: { 
        urls: .tweet.entities.urls[1:], 
        media: .tweet.entities.media 
      } 
    }}]' > preprocess.3.json

Once the content reshaped, I created one file per tweet under the notes section of my hugo website. I’ve used a bash script for that:

#!/usr/bin/env sh

file='preprocess.5.json'
length=$(cat "$file" | jq '. | length')
i_tweet=1

for (( i=0; i<length; i++ ))
do
    created_at=$( jq -r ".[$i] | .date | todate" "$file")
    output_folder="output/tweets/$(( i_tweet++ ))"
    out="$output_folder/index.md"
    hasMedia=$( jq ".[$i] | if .tweet.media then true else false end" "$file" )
    lang=$( jq -r ".[$i] | .tweet.lang" "$file")
    content=$( jq -r ".[$i] | .tweet.full_text" "$file")
    template='tweet.pre'

    if $hasMedia = "true" ; then
            template='tweet-with-media.pre'
            filename=$( jq -r ".[$i] | .tweet.media" $file)
            media=$(basename $(ls tweets_media/"$filename"*))
            if [[ "$media" == *.mp4 ]]; then
     	       mediaHtml="<video autoplay loop src='/notes/$media' class='u-video'></video>"
            else
     	       mediaHtml="<img src='/notes/$media' class='u-photo' />"
            fi
    fi
    data=$( m4 -D__CREATED_AT__="${created_at}" \
            -D__LANG__="$lang" \
            -D__CONTENT__="$content" \
            -D__MEDIA__="$mediaHtml" \
            $template)
    mkdir -p "$output_folder"
    echo "$data" > $out
done

That uses m4 too, simply to keep the templating outside, just a bit easier to manage.

Here’s for example how I prepared tweet.pre. The bash script would either use this one or tweet-with-media.pre depending on the presence or not of a media in the tweet.

changequote(<!, !>)
---
date: __CREATED_AT__
lang: __LANG__
params:
  kind: tweet
---
<p>__CONTENT__</p>
<p class="meta original-link">
First published on <a href="https://twitter.com">twitter</a> 
(<a href="/articles/1/">?</a>)
</p>

That’s it! 3143 tweets kept intact, now persisted on my own website.

I migrated all my instagram photos, here's how

On how I reclaimed my instagram posts and imported them to my personal website

Instagram provides an export feature, not easy to find but the help section provided me with the right sequence of clicks. I did that in September this year. You can choose between json and html exports, I chose json and received shortly after a zip file in my mailbox. Once deflated that amounts to 85 megabytes.

➜  instagram-jacqueminv-2025-09-04-83XcnSA4-json tree -d -L2
.
├── ads_information
├── apps_and_websites_off_of_instagram
├── connections
├── media
│   └── posts
├── personal_information
├── preferences
├── security_and_login_information
└── your_instagram_activity
    └── media
The listing of the instagram export. In the end, I'm interested in ./media/posts and ./your_instagram_activity/media.

There was no description of the archive’s content so I browse and quickly found that all my posts were under your_instagram_activity/media/posts_1.json. I decided to ignore everything else. That means my stories, comments or likes are not migrated. What I want is all the photos and their metadata so that I can keep them on my website.

That json file contains a list of entries and each has one to many media linked to it. It’s straightforward to find the link to the media file, each one is referenced via a uri property. That’s the link to the file within the very same archive, under /media/posts.

Having sorted out the structure and what I wanted, I could start playing around on the command line. For that kind of task, jq is a good candidate.

Here’s how I proceeded to only keep the attributes I needed and prepare the payload for the next step:

jq -c '[ .[] | {title: .media[0].title, date: first(.media[].creation_timestamp), pictures: .media | del(.[].creation_timestamp, .[].title, .[].media_metadata, .[].cross_post_source), location: first(.media[].media_metadata?.photo_metadata?.exif_data[0]?)} ]' posts_1.json > preprocess.json

One unpleasant surprise was that special characters were badly encoded. As I sometimes wrote my descriptions in french, that ended in the json like “matinée” for “matinée”. I did not see customization options on the export page so what I did was going through all my entries and fix them manually. Annoying. But my export is made of less than 400 entries and not that many in french so in the end, not a huge deal either. Still surprising for a service coming from a mammoth like Meta! I did that on that preprocess.json as I had not noticed that at first.

Equipped now with that filtered json I simply needed to generate the html hugo files for each entry. To achieve that part I’ve used a bash script and m4 .

#!/usr/bin/env sh

file='preprocess.json'
length=$(cat "$file" | jq '. | length')
i_insta=1

for (( i=0; i<length; i++ ))
do
	created_at=$( jq -r ".[$i] | .date | todate" "$file")
	output_folder="output/photos/$(( i_insta++ ))"
	out="$output_folder/index.md"
	content=$( jq -r ".[$i] | .title | sub(\"\n\"; \"<br/>\")" "$file" )
	latitude=$( jq -r ".[$i] | .location?.latitude" "$file" )
	longitude=$( jq -r ".[$i] | .location?.longitude" "$file" )
	location=""
	if [ "$latitude" != "null" -a "$longitude" != "null" ]; then
		location="<p class='h-geo meta'><a href='https://www.openstreetmap.org/#map=15/$latitude/$longitude'>"
		location+="<data class='p-longitude' value='$longitude'>$longitude</data>, "
		location+="<data class='p-latitude' value='$latitude'>$latitude</data></a></p>"
	fi

	mediaHtml='<ul>'
	lengthMedia=$( jq -r ".[$i] | .pictures | length" "$file")
	for (( m=0; m<lengthMedia; m++ ))
	do
		media=$(jq -r ".[$i].pictures[$m].uri" "$file")
		mediaHtml+="<li><figure><a href='/photos/$media'>"
		if [[ "$media" == *.mp4 ]]; then
			mediaHtml+="<video autoplay loop src='/photos/$media' class='u-video'></video>"
		else
			mediaHtml+="<img src='/photos/$media' class='u-photo' />"
		fi
		mediaHtml+="</a></figure></li>"
		
	done
	mediaHtml+='</ul>'
	data=$( m4 -D__CREATED_AT__="${created_at}" \
		-D__CONTENT__="$content" \
		-D__MEDIA__="$mediaHtml" \
		-D__LOCATION__="$location" \
		insta.pre)

	mkdir -p "$output_folder"
	echo "$data" > $out
done

With the accompanying insta.pre given to m4:

---
date: __CREATED_AT__
params:
  kind: insta
---
__MEDIA__
<p>__CONTENT__</p>
__LOCATION__
<p class="meta original-link">First published on <a href="https://www.instagram.com/jacqueminv/">instagram</a> (<a href="/articles/1/">?</a>)</p>

After execution, my 359 insta posts found a new home. I just had to copy the posts folder that actually contains the photos and one video.

Hiatus terminus

On why I stopped updating my personal website and social media took over. Interested to know how to reclaim your own twitter and instagram content? That’s for a future article.

I closed my twitter account about a year ago. We have to agree that social media in general got ever more toxic over the years. The promises of connection failed short. Instead, that’s a feeling of exhaustion and sadness that predominate if I spend time there.

I was using twitter mainly to stay up to date around information technology at large. I started to use twitter in October 2007. I’m not and I’ve never been an hardcore user, that was a tool to an end. Still, over the years I amassed some content that I was for some reasons attached to. Same for instagram, I posted quite a few photos there but using the platform today, with its mix of ads and unsolicited content? Not for me.

The closure of my twitter account acted as a trigger.

I used to have my own website back then but over time, when my personal life took tough turns, I took a bit of distance from all this. Actually, I lost the motivation to stay connected, to code, to write (online), to explore programming languages, technologies. Instead I did more and more running, spent time with other (new) friends and kept up with other healthy routines. Programming has been purely to get a paycheck, which is sort of sad considering how I did enjoy it before. Moving on takes time and for me it meant putting programming as a hobby on the side.

Fast-forward to years later, I moved to another place, continued to “rebuild” myself. The pinacle of that phase is when we decided to envision a life together, my now wife and I. Around that time I was even more disconnected, I was off, in heaven. That kept rebuilding me, for good and I could see that slowly my willingness to grow again in my programming, in setting a plan to give an answer to my thirst of knowledge made sense again. I started to regularly set time for my learning journey, not a huge amount as I have dear responsibilities I always strive to keep my best attention to. But learning was again in my routine, especially early mornings.

That led me to dig deeper into different areas over last years: kubernetes, css (boy how that part evolved), SRE topics, Terraform, and on and on. Learning, spending time to grow is again appealing and satisfying.

Writing always got its spot in my life. I’m excited to reclaim my own online space to keep track of my learnings and other wanderings. Social media may be tiring that’s a lesson. Producing my own content though is loaded with benefits: I know I can experiment if I have my own website, I know I can focus more on my own journey rather than looking what’s going on elsewhere passively. I mean that as a balance, staying up to date is still a goal and social media might be one way to do that. Reducing my time in staying connected to get more into producing, tracking my learnings is one clear goal of putting an end to my hiatus.

I’ll report about those learnings and lessons reaped along my way.

To start, I had in mind to reclaim my own content. Mainly the one spread on twitter and instagram. At least to start with. It’s now in good shape, there’s still a few fixes to apply but it got good enough for me to hit publish. All my tweets are in the notes section and all my insta snaps are in the photos section. The migration itself has been rewarding in terms of learnings, I’ll share about that next.

To me, I wish Happy Learning, Happy Hacking and long live to my own digital space.

Les particularités de Javascript

Ça m’a fait plaisir de lire l’article Ten Oddities And Secrets About Javascript parce que je cherche un peu de motivation actuellement pour écrire sur ce blog et j’ai ici un prétexte pour ajouter une onzième particularité de Javascript fort troublante lorsqu’on ne la connait pas. Elle s’appelle hoisting feature, on pourrait traduire ça par fonctionalité de de levage

Voici un morceau de code pour nous aider:

var score = 42;
function computeScore () {
    if ( score ) {
        alert(score);
    }
    var score = 0;
    return score + 42;
}

computeScore();

Selon vous l’alert va apparaître? Si oui quelle valeur sera affichée?

Eh bien non, l’alert ne s’affichera pas. Si ça vous paraît surprenant je le comprends, mais cela signifie aussi que cet article pourrait vous apprendre quelque chose…

La portée des variables en Javascript

En Javascript il faut savoir qu’il n’y a que les fonctions qui définissent un nouveau bloc de portée pour les variables, déclarer une variable dans une boucle ou un if ne restreindra pas sa portée à ce simple bloc mais bien à la fonction l’englobant ou la portée globale dans le cas où cette dernière n’existe pas.

Sachant cela, vous comprendrez alors pourquoi ici l’alert va bien nous afficher true:

function test () {
    if ( true ) {
        var isDefined = true;
    }
    alert( isDefined );
}

Deuxième point important concernant la hoisting feature, c’est que toute variable est déclarée en début de portée et ce même dans le cas où le développeur décide de ne pas le faire en début de portée. Si l’on reprend par exemple le code d’introduction, voici comment le comment il est interprété:

var score = 42;
function computeScore () {
    var score; //"cache" (shadow) la variable globale du même nom sans l'initialiser, sa valeur est donc `undefined`
    if ( score ) {
        alert(score);
    }
    score = 0;
    return score + 42;
}

computeScore();

Bonne pratique de déclaration de variable

Afin de s’éviter toutes surprises la bonne pratique recommandée est de déclarer toutes ses variables en début de bloc et en utilisant le mot-clé var. Omettre le var enverrait directement la variable dans la portée globale ce qui n’est pas ce qui est recherché en général.

Le jour des triffides

Si Will Smith et son cleps seuls contre des zombies dans “Je suis une legende” ou encore Tom Cruise face aux Tripods de “La guerre des mondes” vous ont plu, en voilà un autre du genre: le jour des Triffides.

Ce livre a d’ailleurs lui aussi son adaptation cinématographique; qui date un peu par contre.

En ce qui concerne le bouquin, on se retrouve de facon similaire dans la peau d’un gars qui par (mal)chance doit affronter un monde empli de bestioles qu’il connait ma fois assez bien pour les avoir étudiées en labo: les Triffides.

Ces Triffides ce sont des arbres. Pas forcément les gentils Ents que vous connaissez. Les Triffides ne voient ni ne parlent eux, et sont exploités par les humains pour leur sève aux propriétés énergétiques très profitables.

Mais voilà, un accident et hop leur cécité n’est plus un si terrible désavantage puisqu’en face les humains ne voient plus rien non plus! La menace est sérieuse. Les Triffides sont nombreux et, bien qu’aveugles, semblent communiquer entre eux. Leur but parait loin d’être pacifique… Envie de vengence? Peut-etre. Assez pour se debarasser de leurs récents exploiteurs? A découvrir.

Je me suis laissé embarquer par ce bouquin meme si c’est le genre de scenario que l’ont retrouve dans plusieurs bouquins de science fiction. Je n’ai pas lu Je suis une légende mais Le jour des Triffides vaut largement La guerre des mondes.

Mon père m’avait un jour raconté qu’avant la guerre contre Hitler, il avait pris l’habitude de faire le tour de Londres, les yeux grands ouverts plus que jamais, pour admirer des bâtiments qu’il n’avait jamais remarqués auparavant et leur dire adieu. J’éprouvais en cet instant un sentiment similaire, mais notre situation avait quelque chose de plus tragique. La plupart des gens pouvaient avoir un certain espoir de survivre à la guerre. Là, nous avions affaire à un ennemi qui ne les laisserait pas survire.

[…]

L’esprit humain est incapable de demeurer trop longtemps dans une humeur tragique – tel un phénix, il renaît de ses cendres. Cela peut s’avérer utile ou nuisible – c’est juste une manifestation de notre volonté de vivre.

Jonathan Livingston le Goéland

Richard Bach, pilote de l’US Air Force à ses heures a été rendu célèbre par ce livre, Jonathan Livingston le goéland.

Célèbre grâce à un message de liberté rendu ici par un goéland différend des autres. Voulant en apprendre toujours plus sur le vol de haute voltige alors que ses camarades eux se préoccupent surtout de remplir leur panse… Malheureusement être différend pour un goéland signifie à peu près la même chose que pour un humain: le rejet, l’incompréhension.

Heureusement Jonathan ne désarme pas et poursuit sa course du savoir et par la même occasion conforte le lecteur qu’un engagement vers la connaissance mène à la liberté.

Chacun de nous, en vérité, est une idée du Grand Goéland, une image illimitée de la liberté […]. Le vol de précision n’est qu’un de plus franchi dans l’expression de notre vraie nature. Tout ce qui nous limite nous devons l’éliminer.

Ce livre doit être le plus court de la liste des 110 meilleurs livres à lire. A ne pas manquer, poétique avec un message simple et marquant.

Critique de livre: Si c'est un homme par Primo Levi

Primo Levi fait partie des juifs ayant survécu aux camps de concentration. Ce livre fort, fait office de témoignage. Un témoignage frappant de part bien sûr ce qu’il évoque mais aussi par la distance que Levi démontre face aux événements.

Mais pourquoi se remémorer de tels épisodes si terribles ? On pourrait se le demander et j’ai mon opinion toute personnelle mais l’auteur donne la sienne, profitons donc d’une citation pour la découvrir:

Nous sommes persuadés en effet qu’aucune expérience humaine n’est dénuée de sens ni indigne d’analyse, et que bien au contraire, l’univers particulier que nous décrivons ici peut servir à mettre en évidence des valeurs fondamentales, sinon toujours positives. Nous voudrions faire observer à quel point le Lager a été, aussi et à bien des égards, une gigantesque expérience biologique et sociale.

Sortie de son contexte on pourrait croire à un manque de sentiment, une distance froide par rapport au sujet si remuant mais ici c’est bien un acteur direct de cet épisode terrible qui parle. Gardons-nous donc de tout jugement. Cette distance ressort d’ailleurs beaucoup durant tout le récit. La haine, le ressentiment ou tout autre négativisme a peu de place au contraire de l’analyse et du simple témoignage des faits donné par Levi. Analyse qui ressort par exemple ici:

La mémoire est une bien curieuse mécanique: durant tout mon séjour au camp, ces deux vers qu’un de mes amis a écrits il y a bien longtemps me sont régulièrement revenus à l’esprit:

jusqu’à ce qu’un jour dire “demain” n’ait plus de sens

Ici, c’est exactement comme ça. Savez-vous comment on dit “jamais” dans le langage du camp? “Morgen früh”, demain matin.

Bon, même si il y a de la distance par rapport aux “méchants” de l’histoire, on ressent par contre bien le mal que cette tragédie a pu avoir sur lui. Après une année de captivité dans des conditions insoutenables, Levi exprime à quel point sa vie a pu changer:

j’avais un nom de famille, un esprit curieux et inquiet, un corps agile et sain. Je pensais à toutes sortes de choses très lointaines: à mon travail, à la fin de la guerre, au bien et au mal, à la nature des choses et aux lois qui gouvernent les actions des hommes; et aussi aux montages, aux chansons, à l’amour, à la musique, à la poésie. J’avais un confiance énorme, inébranlable et stupide dans la bienveillance du destin, et les mots “tuer” et “mourir” avaient pour moi un sens tout extérieur et littéraire. Mes journées étaient tristes et gaies. Mais je les regrettais toutes, toutes étaient pleines et positives; l’avenir s’ouvrait devant moi comme une grande richesse. De ma vie d’alors il ne me reste aujourd’hui que la force d’endurer la faim et le froid; je ne suis plus assez vivant pour être capable de me supprimer.

Quoiqu’il en soit, le témoignage de Levi fait partie des livres que j’ai le plus aimé cette année.

J’ai le sentiment là tout de suite que cette critique n’en est pas vraiment une, que ce que j’ai écrit est de piètre qualité. C’est comme ça parfois, mais bon ou pas, je tiens à publier ce billet. Je voudrais bien sûr écrire que des choses de qualité mais il faut beaucoup se planter pour réussir à ce qu’il paraît.

Livre vs livre électronique: chacun sa place

Printemps 2009, je rejoins le département R&D de Merck Serono au 1er étage des magnifiques locaux genevois. J’allume mon outil de travail et me coule un doux nespresso-lait pour bien démarrer ma journée. Je reviens à mon écran, pose mon café, tape au clavier mon identifiant et retourne à mon café lorsque ma main gauche – elle porte bien son nom celle-là – prend l’envie soudaine de 1) ruiner mon café et de 2) inonder mon bouquin du moment, l’excellent The Pragmatic Programmer: From Journeyman to Master

Bilan des courses, mon bouquin a pris des couleurs mais je peux heureusement toujours le lire dans son intégralité et mon pc n’a subi aucun dommage. Plus de peur que de mal…

Certains pensent que les livres au format électronique vont supplanter à terme les livres au format papier. J’espère au fond de moi que ce ne sera jamais le cas ou du moins pas de mon vivant et je compte profiter de ce billet pour expliquer pourquoi.

Chaque format ayant ses avantages laissez-moi commencer par mon préféré, le livre, le vrai. Les avantages du livre sont multiples et on peut les aborder au travers de certains de nos sens.

La vue. Aujourd’hui mon livre brunit par le café occupe une place de choix aux côtés d’autres livres techniques et lorsque je le prends, que je l’ouvre, de revoir les ondulations et la couleur des pages me rappellent automatiquement cet épisode burlesque. D’autres livres me renvoient d’autres souvenirs. Pour l’un ce sera au travers d’une cornure, pour l’autre une déchirure, etc. Ces éléments qui font qu’un livre vit, qu’il est unique me font préférer le livre papier. La vue entre en jeu également lorsqu’on est face non plus à un seul livre mais à une bibliothèque entièrement couverte de bouquins. Chez moi, je passe tous les jours devant la mienne et j’adore ça. J’adore pouvoir me poser devant elle et me rappeler ce que m’a apporté telle ou telle lecture. J’adore sortir un de mes livres et le feuilleter quelques minutes… Impossible de retrouver la même expérience devant un iPad ou autre Kindle.

L’odorat. Une de mes manies consiste à ouvrir chaque nouveau livre, d’y plonger mon nez et d’inspirer cette odeur d’encre et de papier imprimé. J’adore. C’est quelque chose qui me manque clairement devant mon iphone ou tout autre lecteur électronique.

Le toucher. Ce grain sous le doigt ou au contraire cette douceur des livres grand format. Le contact est plus direct, le lien entre le livre et le lecteur est plus proche du fait qu’il n’y ait pas d’intermédiaire forcément.

L’expérience et la culture du livre font pencher la balance pour ma part mais je suis un geek et un geek ça aime tous ces engins électronique, non? C’est sûr que même si je ne veux pas voir le livre papier disparaître, le livre électronique vient aussi avec ses avantages.

Le premier ebook que j’ai pu lire – en entier – a été la biographie de Richard Stallman. J’avais commencé par plusieurs fois cette biographie directement sur mon laptop mais à chaque fois j’ai abandonné. Je crois qu’il y a trop de distractions sur un ordinateur pour pouvoir y lire correctement; entre les développements que je pourrais faire, défiler mes abonnements dans google reader, aller sur twitter, chatter, etc. Impossible pour moi, c’est pas l’outil qu’il me faut. J’ai donc transféré l’ebook sur mon iphone et malgrés la petite taille de son écran j’ai trouvé l’expérience agréable et j’ai lu tout le bouquin. Un lecteur électronique nous permet de faire des annotations, mémoriser des passages, lancer une recherche, modifier l’apparence à souhait, etc. Les fonctionalités sont nombreuses et bienvenues. Bien sûr on a l’avantage également de pouvoir se trimbaler un nombre indécent de livres avec soi tout en les ayant dans la poche, là ça commence à devenir un sacré plus! Economiquement évidemment les avantages sont aussi là, les coûts baissant drastiquement à (quasi) tous les niveaux de l’échelle de production. On en profite nous lecteurs sur le prix d’achat.

Ce format permet également de soutenir d’une manière incroyable les pays en voie de développement.

nearly two billion children of the developing world with little or no access to education – OLPC,vision

Vous avez peut-être en effet déjà entendu parler du projet OLPC? Ce projet a pour but de fournir un ordinateur portable à tout enfant en âge de scolarisation dans les pays en voie de développement. Ces enfants peuvent alors avoir accès à une mine d’information qui ne profitait jusqu’à aujourd’hui qu’à une poignée de privilégiés. Le livre électronique est un précieux levier à la mise en route de ce genre de projet de part son faible coût d’acquisition, de transport et de stockage.

Tout ça mis dans la balance me pousse à croire que les livres quel que soit leur support ont leur place. Je ne me passerai personnellement jamais de l’expérience que procure un vrai livre quitte à payer plus cher. Cela dit je ne crache pas sur les avantages du livre électronique et me réjouis déjà de goûter l’expérience que procure un Kindle dernière génération…