Repository with sources and generator of https://larlet.fr/david/ https://larlet.fr/david/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

пре 11 месеци
пре 11 месеци
пре 11 месеци
пре 11 месеци
пре 11 месеци
пре 11 месеци
пре 11 месеци
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. <!DOCTYPE html><!-- This is a valid HTML5 document. -->
  2. <!-- Screen readers, SEO, extensions and so on. -->
  3. <html lang="fr">
  4. <!-- Has to be within the first 1024 bytes, hence before the `title` element
  5. See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset -->
  6. <meta charset="utf-8">
  7. <!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 -->
  8. <!-- The viewport meta is quite crowded and we are responsible for that.
  9. See: https://codepen.io/tigt/post/meta-viewport-for-2015 -->
  10. <meta name="viewport" content="width=device-width,initial-scale=1">
  11. <!-- Required to make a valid HTML5 document. -->
  12. <title>
  13. Développement(s)
  14. — David Larlet</title>
  15. <meta name="description" content="J’ai un peu de mal ces temps-ci à dire que je suis un développeur car j’ai l’impression de passer énormément d’énergie à faire d’autres choses. Lorsqu’on me demande ce que je fais, je dis « des trucs, de-ci de-là… », rien de bien grandiloquent. Une bonne partie de mes journées est passée dans la gestion de Scopyleft (au sens très large), une autre à interagir avec les équipes avec lesquelles je travaille. Et puis parfois, l’après-midi ou le soir, lorsqu’il n’y a ni grève, ni neige, ni journée pédagogique, ni covid, ni flemme, il m’arrive de coder des trucs.">
  16. <!-- That good ol' feed, subscribe :). -->
  17. <link rel="alternate"
  18. type="application/atom+xml"
  19. title="Feed"
  20. href="/david/log/">
  21. <!-- Generated from https://realfavicongenerator.net/ such a mess. -->
  22. <link rel="apple-touch-icon"
  23. sizes="180x180"
  24. href="/static/david/icons2/apple-touch-icon.png">
  25. <link rel="icon"
  26. type="image/png"
  27. sizes="32x32"
  28. href="/static/david/icons2/favicon-32x32.png">
  29. <link rel="icon"
  30. type="image/png"
  31. sizes="16x16"
  32. href="/static/david/icons2/favicon-16x16.png">
  33. <link rel="manifest" href="/static/david/icons2/site.webmanifest">
  34. <link rel="mask-icon"
  35. href="/static/david/icons2/safari-pinned-tab.svg"
  36. color="#07486c">
  37. <link rel="shortcut icon" href="/static/david/icons2/favicon.ico">
  38. <meta name="msapplication-TileColor" content="#f7f7f7">
  39. <meta name="msapplication-config"
  40. content="/static/david/icons2/browserconfig.xml">
  41. <meta name="theme-color"
  42. content="#f7f7f7"
  43. media="(prefers-color-scheme: light)">
  44. <meta name="theme-color"
  45. content="#272727"
  46. media="(prefers-color-scheme: dark)">
  47. <!-- Is that even respected? Retrospectively? What a shAItshow…
  48. https://neil-clarke.com/block-the-bots-that-feed-ai-models-by-scraping-your-website/ -->
  49. <meta name="robots" content="noai, noimageai">
  50. <!-- Documented, feel free to shoot an email. -->
  51. <link rel="stylesheet" href="/static/david/css/style_2021-01-20.css">
  52. <!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. -->
  53. <link rel="preload"
  54. href="/static/david/css/fonts/triplicate_t4_poly_regular.woff2"
  55. as="font"
  56. type="font/woff2"
  57. media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)"
  58. crossorigin>
  59. <link rel="preload"
  60. href="/static/david/css/fonts/triplicate_t4_poly_bold.woff2"
  61. as="font"
  62. type="font/woff2"
  63. media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)"
  64. crossorigin>
  65. <link rel="preload"
  66. href="/static/david/css/fonts/triplicate_t4_poly_italic.woff2"
  67. as="font"
  68. type="font/woff2"
  69. media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)"
  70. crossorigin>
  71. <link rel="preload"
  72. href="/static/david/css/fonts/triplicate_t3_regular.woff2"
  73. as="font"
  74. type="font/woff2"
  75. media="(prefers-color-scheme: dark)"
  76. crossorigin>
  77. <link rel="preload"
  78. href="/static/david/css/fonts/triplicate_t3_bold.woff2"
  79. as="font"
  80. type="font/woff2"
  81. media="(prefers-color-scheme: dark)"
  82. crossorigin>
  83. <link rel="preload"
  84. href="/static/david/css/fonts/triplicate_t3_italic.woff2"
  85. as="font"
  86. type="font/woff2"
  87. media="(prefers-color-scheme: dark)"
  88. crossorigin>
  89. <script>
  90. function toggleTheme(themeName) {
  91. document.documentElement.classList.toggle(
  92. 'forced-dark',
  93. themeName === 'dark'
  94. )
  95. document.documentElement.classList.toggle(
  96. 'forced-light',
  97. themeName === 'light'
  98. )
  99. }
  100. const selectedTheme = localStorage.getItem('theme')
  101. if (selectedTheme !== 'undefined') {
  102. toggleTheme(selectedTheme)
  103. }
  104. </script>
  105. <body class="remarkdown h1-underline h2-underline h3-underline em-underscore hr-center ul-star pre-tick"
  106. data-instant-intensity="viewport-all">
  107. <article>
  108. <header>
  109. <h1>Développement(s)</h1>
  110. </header>
  111. <nav>
  112. <p class="center">
  113. <a rel="prev"
  114. href="/david/2023/12/06/"
  115. title="Publication précédente : Équivalent">← Précédent</a> •
  116. <nobr>
  117. <a href="/david/" title="Aller à l’accueil" rel="up">
  118. <svg class="icon icon-home">
  119. <use xlink:href="/static/david/icons2/symbol-defs-2022-03.svg#icon-home"></use>
  120. </svg>
  121. Accueil</a>
  122. </nobr>
  123. <nobr>
  124. <a href="/david/recherche/"
  125. title="Aller à la page de recherche"
  126. rel="search">
  127. <svg class="icon icon-search">
  128. <use xlink:href="/static/david/icons2/symbol-defs-2022-03.svg#icon-search"></use>
  129. </svg>
  130. Recherche</a>
  131. </nobr>
  132. • <a rel="next"
  133. href="/david/2023/12/12/"
  134. title="Publication suivante : Abonnement">Suivant →</a>
  135. </p>
  136. </nav>
  137. <hr>
  138. <p>J’ai un peu de mal ces temps-ci à dire que je suis un développeur car j’ai l’impression de passer énormément d’énergie à faire d’autres choses. Lorsqu’on me demande ce que je fais, je dis «&nbsp;des trucs, de-ci de-là…&nbsp;», rien de bien grandiloquent. Une bonne partie de mes journées est passée dans la gestion de Scopyleft (au sens très large), une autre à interagir avec les équipes avec lesquelles je travaille. Et puis parfois, l’après-midi ou le soir, lorsqu’il n’y a ni grève, ni neige, ni journée pédagogique, ni covid, ni flemme, il m’arrive de coder des&nbsp;trucs.</p>
  139. <h2 id="anthologie-palatine">Anthologie Palatine <a href="#anthologie-palatine" title="Ancre vers cette partie">#</a></h2><figure>
  140. <a href="/static/david/2023/2023-12-08-anthologie-palatine.jpg"
  141. title="Cliquer pour une version haute résolution">
  142. <img
  143. src="/static/david/2023/2023-12-08-anthologie-palatine.jpg"
  144. width="2862" height="2124"
  145. srcset="/static/david/2023/2023-12-08-anthologie-palatine.jpg 2862w, /static/david/2023/2023-12-08-anthologie-palatine_660x440.jpg 660w, /static/david/2023/2023-12-08-anthologie-palatine_990x660.jpg 990w, /static/david/2023/2023-12-08-anthologie-palatine_1320x880.jpg 1320w"
  146. sizes="min(100vw, calc(100vh * 2862 / 2124))"
  147. loading="lazy"
  148. decoding="async"
  149. alt="Capture d’écran du produit">
  150. </a>
  151. <figcaption>Capture d’écran du&nbsp;produit.</figcaption>
  152. </figure>
  153. <p>Projet de longue date avec la <a href="https://www.ecrituresnumeriques.ca/">Chaire du Canada sur les écritures numériques</a> qui consiste à rendre possible le parcours et l’analyse de <a href="https://anthologiagraeca.org/">textes en Grec ancien</a>. C’est un peu en pause depuis le début de l’année mais j’ai pris beaucoup de plaisir à échanger / pairer techniquement avec Sarah (de Scopyleft) sur ces&nbsp;évolutions.</p>
  154. <p>Participer à de la recherche par l’angle du développement est <del>un des moyens d’être bien payé</del> une façon de garder un pied dans un domaine qui me fait mouliner le cerveau pour autre chose que le profit des&nbsp;autres.</p>
  155. <h2 id="pressoir">Pressoir <a href="#pressoir" title="Ancre vers cette partie">#</a></h2><figure>
  156. <a href="/static/david/2023/2023-12-08-ateliers-sens-public.jpg"
  157. title="Cliquer pour une version haute résolution">
  158. <img
  159. src="/static/david/2023/2023-12-08-ateliers-sens-public.jpg"
  160. width="2288" height="2122"
  161. srcset="/static/david/2023/2023-12-08-ateliers-sens-public.jpg 2288w, /static/david/2023/2023-12-08-ateliers-sens-public_660x440.jpg 660w, /static/david/2023/2023-12-08-ateliers-sens-public_990x660.jpg 990w, /static/david/2023/2023-12-08-ateliers-sens-public_1320x880.jpg 1320w"
  162. sizes="min(100vw, calc(100vh * 2288 / 2122))"
  163. loading="lazy"
  164. decoding="async"
  165. alt="Capture d’écran du produit">
  166. </a>
  167. <figcaption>Capture d’écran du&nbsp;produit.</figcaption>
  168. </figure>
  169. <p>Toujours avec la <a href="https://www.ecrituresnumeriques.ca/">Chaire du Canada sur les écritures numériques</a>, parce qu’on apprécie bien de travailler ensemble, on a fait il y a quelques années un outil permettant de générer des livres numériques à partir de sources en <em>markdown</em>.</p>
  170. <p>Cela a donné lieu à <a href="https://ateliers.sens-public.org/">deux</a> <a href="http://parcoursnumeriques-pum.ca/">collections</a> enrichies de contenus numériques (vidéos, etc).</p>
  171. <figure>
  172. <a href="/static/david/2023/2023-12-08-presses-universitaires-montreal.jpg"
  173. title="Cliquer pour une version haute résolution">
  174. <img
  175. src="/static/david/2023/2023-12-08-presses-universitaires-montreal.jpg"
  176. width="2310" height="2108"
  177. srcset="/static/david/2023/2023-12-08-presses-universitaires-montreal.jpg 2310w, /static/david/2023/2023-12-08-presses-universitaires-montreal_660x440.jpg 660w, /static/david/2023/2023-12-08-presses-universitaires-montreal_990x660.jpg 990w, /static/david/2023/2023-12-08-presses-universitaires-montreal_1320x880.jpg 1320w"
  178. sizes="min(100vw, calc(100vh * 2310 / 2108))"
  179. loading="lazy"
  180. decoding="async"
  181. alt="Capture d’écran du produit">
  182. </a>
  183. <figcaption>Capture d’écran du&nbsp;produit.</figcaption>
  184. </figure>
  185. <p>Depuis l’automne, on assume d’avoir fait un <a href="https://gitlab.huma-num.fr/ecrinum/pressoir-cli/">Générateur de Livres Statiques</a> et on essaye de le rendre plus polyvalent / autonome. C’est un exercice de recherche qui va vers une dé-GAFAM-isation et qui m’intéresse <a href="/david/biologeek/archives/20060119-open-articles-liberez-votre-savoir/">depuis un bout de&nbsp;temps…</a></p>
  186. <h2 id="stylo">Stylo <a href="#stylo" title="Ancre vers cette partie">#</a></h2><figure>
  187. <a href="/static/david/2023/2023-12-08-stylo-export.jpg"
  188. title="Cliquer pour une version haute résolution">
  189. <img
  190. src="/static/david/2023/2023-12-08-stylo-export.jpg"
  191. width="2302" height="1770"
  192. srcset="/static/david/2023/2023-12-08-stylo-export.jpg 2302w, /static/david/2023/2023-12-08-stylo-export_660x440.jpg 660w, /static/david/2023/2023-12-08-stylo-export_990x660.jpg 990w, /static/david/2023/2023-12-08-stylo-export_1320x880.jpg 1320w"
  193. sizes="min(100vw, calc(100vh * 2302 / 1770))"
  194. loading="lazy"
  195. decoding="async"
  196. alt="Capture d’écran du produit">
  197. </a>
  198. <figcaption>Capture d’écran du&nbsp;produit.</figcaption>
  199. </figure>
  200. <p>Puisque j’en suis sur la recherche, j’ai aussi contribué modestement à l’éditeur de texte <a href="https://stylo.huma-num.fr/">Stylo</a> pour la partie export. Cela m’a fait plonger dans l’univers de <a href="https://gitlab.huma-num.fr/ecrinum/stylo/pandoc-api">Pandoc</a> (et Docker), de la bibliographie académique et puis j’ai refait des API et j’aime bien&nbsp;ça.</p>
  201. <h2 id="labrri">LABRRI <a href="#labrri" title="Ancre vers cette partie">#</a></h2><figure>
  202. <a href="/static/david/2023/2023-12-08-labrri.jpg"
  203. title="Cliquer pour une version haute résolution">
  204. <img
  205. src="/static/david/2023/2023-12-08-labrri.jpg"
  206. width="2446" height="2028"
  207. srcset="/static/david/2023/2023-12-08-labrri.jpg 2446w, /static/david/2023/2023-12-08-labrri_660x440.jpg 660w, /static/david/2023/2023-12-08-labrri_990x660.jpg 990w, /static/david/2023/2023-12-08-labrri_1320x880.jpg 1320w"
  208. sizes="min(100vw, calc(100vh * 2446 / 2028))"
  209. loading="lazy"
  210. decoding="async"
  211. alt="Capture d’écran du produit">
  212. </a>
  213. <figcaption>Capture d’écran du&nbsp;produit.</figcaption>
  214. </figure>
  215. <p>Pour finir côté recherche, j’ai accompagné le <a href="https://labrri.net/">LABRRI</a> dans l’analyse et la mise en forme de leurs données autour de situations interculturelles au Québec. C’est en interagissant avec des personnes peu/pas techniques que j’ai l’impression de progresser aujourd’hui. Cela permet de revoir les contraintes, l’autonomie, la consommation des ressources, les outils déjà en place. Cette prise de recul est nécessaire pour un avenir&nbsp;frugal.</p>
  216. <p>Le sujet en lui-même est une façon de m’intégrer au Québec en analysant le prisme des incompréhensions culturelles qu’il peut parfois y&nbsp;avoir.</p>
  217. <h2 id="croix-rouge">Croix-Rouge <a href="#croix-rouge" title="Ancre vers cette partie">#</a></h2><figure>
  218. <a href="/static/david/2023/2023-12-08-croix-rouge-aime.jpg"
  219. title="Cliquer pour une version haute résolution">
  220. <img
  221. src="/static/david/2023/2023-12-08-croix-rouge-aime.jpg"
  222. width="2340" height="2124"
  223. srcset="/static/david/2023/2023-12-08-croix-rouge-aime.jpg 2340w, /static/david/2023/2023-12-08-croix-rouge-aime_660x440.jpg 660w, /static/david/2023/2023-12-08-croix-rouge-aime_990x660.jpg 990w, /static/david/2023/2023-12-08-croix-rouge-aime_1320x880.jpg 1320w"
  224. sizes="min(100vw, calc(100vh * 2340 / 2124))"
  225. loading="lazy"
  226. decoding="async"
  227. alt="Capture d’écran du produit">
  228. </a>
  229. <figcaption>Capture d’écran du&nbsp;produit.</figcaption>
  230. </figure>
  231. <p>On a mis en place un outil pour qu’un lieu d’accueil et d’orientation puisse donner des formations à des mineurs étrangers avec <a href="https://www.maiwann.net/">Maïtané</a> et c’était émotionnellement intense. Beaucoup de <a href="/david/2023/02/18/" title="Quiz">remises en questions techniques</a> personnelles mais surtout de réflexions sur quelles sont les véritables héroïnes de ce&nbsp;monde…</p>
  232. <p>Un des enjeux était de voir ce que l’on arrivait à produire avec un budget très restreint (pour le domaine). Il y aurait de la matière pour un article&nbsp;dédié.</p>
  233. <h2 id="outils-scopyleft">Outils scopyleft <a href="#outils-scopyleft" title="Ancre vers cette partie">#</a></h2><figure>
  234. <a href="/static/david/2023/2023-12-08-outils-scopyleft.jpg"
  235. title="Cliquer pour une version haute résolution">
  236. <img
  237. src="/static/david/2023/2023-12-08-outils-scopyleft.jpg"
  238. width="2430" height="2124"
  239. srcset="/static/david/2023/2023-12-08-outils-scopyleft.jpg 2430w, /static/david/2023/2023-12-08-outils-scopyleft_660x440.jpg 660w, /static/david/2023/2023-12-08-outils-scopyleft_990x660.jpg 990w, /static/david/2023/2023-12-08-outils-scopyleft_1320x880.jpg 1320w"
  240. sizes="min(100vw, calc(100vh * 2430 / 2124))"
  241. loading="lazy"
  242. decoding="async"
  243. alt="Capture d’écran du produit">
  244. </a>
  245. <figcaption>Capture d’écran du&nbsp;produit.</figcaption>
  246. </figure>
  247. <p>J’ai produit et maintenu une quinzaine d’outils pour <a href="http://scopyleft.fr/">Scopyleft</a> au cours de l’année. C’est beaucoup et je m’en suis rendu compte au moment où j’ai dû faire une page pour en faire la liste car on avait du mal à nous y retrouver&#8239;! Plus que les outils en eux-mêmes, c’est la structuration et l’aide qu’ils ont pu apporter à des moments critiques qui me&nbsp;réjouit.</p>
  248. <p>J’ai aussi développé pas mal de bouts de code relatifs à l’automatisation / vérification des sous-traitant·es qui sont de plus en plus nombreuses avec le <a href="https://www.data.gouv.fr/fr/datasets/realisation-de-services-publics-numeriques-en-mode-produit-coordonnes-par-le-programme-interministeriel-beta-gouv/">marché public</a> que l’on a remporté il y a quelques années. Extraire et vérifier des données issues de PDF provenant de l’administration ou d’outils de comptabilité n’est pas une mince&nbsp;affaire…</p>
  249. <h2 id="umap">uMap <a href="#umap" title="Ancre vers cette partie">#</a></h2><figure>
  250. <a href="/static/david/2023/2023-12-08-umap-anct.jpg"
  251. title="Cliquer pour une version haute résolution">
  252. <img
  253. src="/static/david/2023/2023-12-08-umap-anct.jpg"
  254. width="2472" height="2124"
  255. srcset="/static/david/2023/2023-12-08-umap-anct.jpg 2472w, /static/david/2023/2023-12-08-umap-anct_660x440.jpg 660w, /static/david/2023/2023-12-08-umap-anct_990x660.jpg 990w, /static/david/2023/2023-12-08-umap-anct_1320x880.jpg 1320w"
  256. sizes="min(100vw, calc(100vh * 2472 / 2124))"
  257. loading="lazy"
  258. decoding="async"
  259. alt="Capture d’écran du produit">
  260. </a>
  261. <figcaption>Capture d’écran du&nbsp;produit.</figcaption>
  262. </figure>
  263. <p>Au printemps dernier, Yohan m’a motivé pour que l’on transforme un logiciel open-source en commun tout en se faisant financer par l’État. Je dois avouer que j’étais un peu dubitatif mais j’ai tenté le coup. Quelques mois après, on a une <a href="https://umap.incubateur.anct.gouv.fr/">instance souveraine</a> en production, des centaines d’<em>issues</em> traitées, un <a href="https://umap-project.org/">site dédié</a> avec une possibilité de financement participatif, des mises à jour régulières, des réflexions de fond avec la communauté, un financement par <a href="https://nlnet.nl/">NLnet</a>, etc.</p>
  264. <p>Pari tellement réussi qu’on a décidé de me passer en mécénat de compétences avec Scopyleft pour les derniers mois de l’année. Il faudra que je fasse un billet&nbsp;dédié.</p>
  265. <figure>
  266. <a href="/static/david/2023/2023-12-08-umap-project.jpg"
  267. title="Cliquer pour une version haute résolution">
  268. <img
  269. src="/static/david/2023/2023-12-08-umap-project.jpg"
  270. width="2462" height="2108"
  271. srcset="/static/david/2023/2023-12-08-umap-project.jpg 2462w, /static/david/2023/2023-12-08-umap-project_660x440.jpg 660w, /static/david/2023/2023-12-08-umap-project_990x660.jpg 990w, /static/david/2023/2023-12-08-umap-project_1320x880.jpg 1320w"
  272. sizes="min(100vw, calc(100vh * 2462 / 2108))"
  273. loading="lazy"
  274. decoding="async"
  275. alt="Capture d’écran du produit">
  276. </a>
  277. <figcaption>Capture d’écran du&nbsp;produit.</figcaption>
  278. </figure>
  279. <hr />
  280. <p>La plupart de ces sites sont statiques ou <a href="/david/2023/09/13/" title="Documentation">semynamiques</a>, sans faire appel à NPM.&nbsp;Vous n’avez pas idée d’à quel point cela me tranquillise et augmente mon efficacité en terme de maintenance sur le long&nbsp;terme.</p>
  281. <nav>
  282. <p>
  283. <a href="/david/2023/complexite/"
  284. title="Liste de tous les articles 2023 associés à cette étiquette"
  285. rel="tag">#complexité</a>
  286. <a href="/david/2023/recherche/"
  287. title="Liste de tous les articles 2023 associés à cette étiquette"
  288. rel="tag">#recherche</a>
  289. <a href="/david/2023/web/"
  290. title="Liste de tous les articles 2023 associés à cette étiquette"
  291. rel="tag">#web</a>
  292. <a href="/david/#tags-2023" title="Liste de toutes les étiquettes 2023">
  293. <svg class="icon icon-tags">
  294. <use xlink:href="/static/david/icons2/symbol-defs-2022-03.svg#icon-tags"></use>
  295. </svg>
  296. tous ?</a>
  297. </p>
  298. </nav>
  299. <nav>
  300. <p class="center">
  301. <a rel="prev"
  302. href="/david/2023/12/06/"
  303. title="Publication précédente : Équivalent">← Précédent</a> •
  304. <a href="/david/2023/" title="Liste des publications récentes">↑ En 2023</a>
  305. • <a rel="next"
  306. href="/david/2023/12/12/"
  307. title="Publication suivante : Abonnement">Suivant →</a>
  308. </p>
  309. </nav>
  310. </article>
  311. <hr>
  312. <footer>
  313. <p>
  314. <nobr>
  315. <a href="/david/" title="Aller à l’accueil">
  316. <svg class="icon icon-home">
  317. <use xlink:href="/static/david/icons2/symbol-defs-2022-03.svg#icon-home"></use>
  318. </svg>
  319. Accueil</a>
  320. </nobr>
  321. <nobr>
  322. <a href="/david/log/" title="Accès au flux RSS">
  323. <svg class="icon icon-rss2">
  324. <use xlink:href="/static/david/icons2/symbol-defs-2022-03.svg#icon-rss2"></use>
  325. </svg>
  326. Suivre</a>
  327. </nobr>
  328. <nobr>
  329. <a href="http://larlet.com"
  330. title="Go to my English profile"
  331. data-instant>
  332. <svg class="icon icon-user-tie">
  333. <use xlink:href="/static/david/icons2/symbol-defs-2022-03.svg#icon-user-tie"></use>
  334. </svg>
  335. Pro</a>
  336. </nobr>
  337. <nobr>
  338. <a href="mailto:david%40larlet.fr" title="Envoyer un courriel">
  339. <svg class="icon icon-mail">
  340. <use xlink:href="/static/david/icons2/symbol-defs-2022-03.svg#icon-mail"></use>
  341. </svg>
  342. Email</a>
  343. </nobr>
  344. <nobr>
  345. <abbr class="nowrap"
  346. title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340">
  347. <svg class="icon icon-hammer2">
  348. <use xlink:href="/static/david/icons2/symbol-defs-2022-03.svg#icon-hammer2"></use>
  349. </svg>
  350. Légal</abbr>
  351. </nobr>
  352. </p>
  353. <template id="theme-selector">
  354. <form>
  355. <fieldset>
  356. <legend>
  357. <svg class="icon icon-brightness-contrast">
  358. <use xlink:href="/static/david/icons2/symbol-defs-2022-03.svg#icon-brightness-contrast"></use>
  359. </svg>
  360. Thème
  361. </legend>
  362. <label>
  363. <input type="radio" value="auto" name="chosen-color-scheme" checked>
  364. Auto
  365. </label>
  366. <label>
  367. <input type="radio" value="dark" name="chosen-color-scheme">
  368. Foncé
  369. </label>
  370. <label>
  371. <input type="radio" value="light" name="chosen-color-scheme">
  372. Clair
  373. </label>
  374. </fieldset>
  375. </form>
  376. </template>
  377. </footer>
  378. <script src="/static/david/js/instantpage-5.1.0.min.js" type="module"></script>
  379. <script>
  380. function loadThemeForm(templateName) {
  381. const themeSelectorTemplate = document.querySelector(templateName)
  382. const form = themeSelectorTemplate.content.firstElementChild
  383. themeSelectorTemplate.replaceWith(form)
  384. form.addEventListener('change', (e) => {
  385. const chosenColorScheme = e.target.value
  386. localStorage.setItem('theme', chosenColorScheme)
  387. toggleTheme(chosenColorScheme)
  388. })
  389. const selectedTheme = localStorage.getItem('theme')
  390. if (selectedTheme && selectedTheme !== 'undefined') {
  391. form.querySelector(`[value="${selectedTheme}"]`).checked = true
  392. }
  393. }
  394. const prefersColorSchemeDark = '(prefers-color-scheme: dark)'
  395. window.addEventListener('load', () => {
  396. let hasDarkRules = false
  397. for (const styleSheet of Array.from(document.styleSheets)) {
  398. let mediaRules = []
  399. for (const cssRule of styleSheet.cssRules) {
  400. if (cssRule.type !== CSSRule.MEDIA_RULE) {
  401. continue
  402. }
  403. // WARNING: Safari does not have/supports `conditionText`.
  404. if (cssRule.conditionText) {
  405. if (cssRule.conditionText !== prefersColorSchemeDark) {
  406. continue
  407. }
  408. } else {
  409. if (cssRule.cssText.startsWith(prefersColorSchemeDark)) {
  410. continue
  411. }
  412. }
  413. mediaRules = mediaRules.concat(Array.from(cssRule.cssRules))
  414. }
  415. // WARNING: do not try to insert a Rule to a styleSheet you are
  416. // currently iterating on, otherwise the browser will be stuck
  417. // in a infinite loop…
  418. for (const mediaRule of mediaRules) {
  419. styleSheet.insertRule(mediaRule.cssText)
  420. hasDarkRules = true
  421. }
  422. }
  423. if (hasDarkRules) {
  424. loadThemeForm('#theme-selector')
  425. }
  426. })
  427. </script>
  428. </body>
  429. </html>