Astuces

Des astuces divers et variées…

Déverrouiller un document Microsoft Office sans connaître le mot de passe

Afficher les extentions

Il faut que les extensions soient visibles. Sur Windows 10 :

Changer l'extension

Un document Microsoft Office est une archive compressée de fichier .xml.
Pour accéder aux fichiers internes, il faut changer l'extension du document (.docx, .xlsx, etc) par .zip.

Décompresser le fichier .zip

Clic droit Extraire tout….
Bouton Extraire.

Modifier le fichier .xml

[…]<w:documentProtection />[…]

Reconstruire le document Microsoft Office

Ajouter du texte Lorem ipsum sous Microsoft Office

Il suffit de taper :

La syntaxe complète est du type :

=lorem(paragraphes,phrases)

Par exemple, pour avoir 6 paragraphes de 20 phrases :

=lorem(6,20)

Insérer des caractères d'après le code Unicode dans LibreOffice ou Microsoft Office

Et voilà.

Du coup : Symboles et codes clavier.

Masquer les éléments « Premium » dans Canva.com

Pourquoi faire ?

Le but est simplement de masquer les éléments qui demande de payer un abonnement (ceux avec la petite couronne).

Image avant

Image après

Installation de Tapermonkey

Se rendre sur le site officiel du projet www.tampermonkey.net pour télécharger le plugin en fonction de son navigateur :

Le script

Un fois l'installation (très rapide) terminée, cliquer sur l'icône de l'extension dans le navigateur et choisir Ajouter un nouveau script….

Coller tout le script suivant :

// ==UserScript==
// @name         Canva - Hide Premium Content
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  Hide premimum content on Canva.com
// @author       MickGe
// @match        https://www.canva.com/design/*
// @icon         https://icons.duckduckgo.com/ip2/canva.com.ico
// @grant        none
// ==/UserScript==

(function() {
    const clearPremium = () => {
    const classesPremium = "MSQthA";
    const classesPicPremium = "A0JANA ADVZ4g";
    const picPremium = [...document.getElementsByClassName(classesPicPremium)];
    picPremium.forEach(el => {
        const premimum = [...el.getElementsByClassName(classesPremium)].length;
        if (premimum) el.style.display = 'none';
    });
}
setInterval(clearPremium, 2000);
})();

Résultat

Lorsque le navigateur sera sur une page commençant par www.canva.com/design/, il lancera le script toutes les 2 secondes pour masquer les éléments « Premium ».

Pour désactiver le script, il suffit de cliquer sur l'icône de l'extension dans le navigateur puis sur Canva - Hide Premium Content.

Table de remplacement intégrée à LibreOffice

Divers
(c)©
(r)®
(tm)
//-
/no
/No
/No-
Lettres grecques
__aα
__AΑ
__bβ
__BΒ
__dδ
__eε
__EΕ
__fφ
__FΦ
__gγ
__GΓ
__hη
__HΗ
__iι
__IΙ
__jθ
__JΘ
__kκ
__KΚ
__lλ
__LΛ
__mμ
__MΜ
__nν
__NΝ
__oο
__OΟ
__pπ
__PΠ
__qχ
__QΧ
__rρ
__RΡ
__sσ
__SΣ
__tτ
__TΤ
__DΔ
__uυ
__UΥ
__wω
__WΩ
__xξ
__XΞ
__yψ
__YΨ
__zζ
__ZΖ
//d
//D
//i
//l
//oØ
//OΩ
//P
//r
//S
Flèches, ponctuations et arithmétique
_>
--
---
-->
:---:
:--:
:-:
:-+:
:.:
:':
:/:
:\\:
:+-:±
:<<:
:<=:
:>=:
:>>:
:~:
.*<-.*
//_
//^
//<
//>
^>
<-->
<->
<--
<==
==>
<<
>>
./.÷
%o
+/-±
<=
=/=
===
><×
>=
~~
1//2½
1//3
1//4¼
1//8
2//3
3//4¾
3//8
5//8
7//8
Exposants
:^-:
:^(:
:^):
:^+:
:^=:
:^0:
:^1:¹
:^2:²
:^3:³
:^4:
:^5:
:^6:
:^7:
:^8:
:^9:
:^a:
:^A:
:^alpha:
:^b:
:^B:
:^bêta:
:^c:
:^d:
:^D:
:^delta:
:^e:
:^E:
:^epsilon:
:^f:
:^g:
:^G:
:^gamma:
:^h:ʰ
:^H:
:^i:
:^I:
:^iota:
:^j:ʲ
:^J:
:^k:
:^K:
:^khi:
:^l:ˡ
:^L:
:^m:
:^M:
:^n:
:^N:
:^o:
:^O:
:^p:
:^P:
:^phi:
:^Phi:
:^r:ʳ
:^R:ᴿ
:^s:ˢ
:^t:
:^T:
:^thêta:ᶿ
:^u:
:^U:
:^v:
:^V:
:^w:ʷ
:^W:
:^x:ˣ
:^y:ʸ
:^z:
Émojis
:!:
:!!:
:!?:
:!2:
:?:
:?2:
:1 h:🕐
:1/2:½
:1/3:
:1/4:¼
:1/8:
:10 h:🕙
:100:💯
:11 h:🕚
:12 h:🕛
:2 h:🕑
:2/3:
:3 h:🕒
:3/4:¾
:3/8:
:4 h:🕓
:5 h:🕔
:5/8:
:6 h:🕕
:7 h:🕖
:7/8:
:8 h:🕗
:9 h:🕘
:abc:🔤
:abeille:🐝
:Adi Shakti:
:adulte:🧑
:agrafe:🗜
:agrandir:🗖
:aigle:🦅
:alambic:
:alpha:α
:Alpha:Α
:ambulance:🚑
:amour:💘
:amour2:🤟
:amphore:🏺
:ampoule électrique:💡
:ananas:🍍
:ancre:
:ange:👼
:angle:
:angle2:
:angoissé:😧
:anneau:💍
:anniversaire:🎂
:annuler:🗙
:antenne:📡
:appareil photo:📷
:appel:📲
:applaudissements:👏
:aquaplaning:
:araignée:🕷
:arbre:🌳
:arc-en-ciel:🌈
:arc:🏹
:argent:💸
:argent2:💰
:argent3:🤑
:armoire:🗄
:arrêt de bus:🚏
:arrivée:🛬
:as:🂡
:assiette:🍽
:atome:
:attention:
:aubergine:🍆
:autoroute:🛣
:avertissement:
:avion:
:avion2:🛩
:avion3:🛧
:avion4:🛨
:avion5:🛦
:avion6:🛪
:avocat:🥑
:bacon:🥓
:badge:📛
:badminton:🏸
:bagages:🛄
:baguettes:🥢
:baht:฿
:baignoire:🛁
:bain:🛀
:balance:
:balance2:
:baleine:🐳
:baleine2:🐋
:balle:
:ballon de rugby:🏉
:ballon:🎈
:bambou:🎍
:banane:🍌
:banque:🏦
:banquet:🕃
:banquet2:🕄
:barbe:🧔
:bas:
:bas2:👇
:bas3:🖟
:bas4:🖗
:bas5:🖣
:bas6:🖡
:baseball:
:basket-ball:🏀
:bateau à moteur:🛥
:bâton d'Asclépios:
:bâton d'Hermès:
:batterie:🔋
:baver:🤤
:bébé:👶
:bébé2:🚼
:bébé3:🤱
:bécarre:
:bélier:🐏
:bélier2:
:bémol:
:bento:🍱
:bêta:β
:Bêta:Β
:biberon:🍼
:bicyclette:🚲
:bidon:🥫
:bière:🍺
:bière2:🍻
:bikini:👙
:billard:🎱
:biorisque:
:bisou:💏
:bisou2:😘
:bisou3:😙
:bisou4:😚
:bisou5:😗
:bitcoin:
:blanche:𝅗𝅥
:blason:🛡
:blason2:
:bloc-note vide:🗇
:bloc-note:🗊
:bloc-notes:🗒
:bœuf:🐂
:boisson:🥤
:boisson2:🍹
:boîte aux lettres:📪
:boîte aux lettres2:📫
:boîte aux lettres3:📬
:boîte aux lettres4:📭
:boîte entrée:📥
:boîte envoi:📤
:boîte postale:📮
:boîte:🗃
:bol:🍜
:bombe:💣
:bonbons:🍬
:bonheur:🙋
:bonhomme de neige:
:bonhomme de neige2:
:bonne chance:🤞
:boom:💥
:bottes:👢
:bouche ouverte:😮
:bouche:👄
:boucle:
:boucle2:
:boudeur:🙎
:bougie:🕯
:boule de cristal:🔮
:boule de riz:🍙
:boulette:🥟
:bouquet:💐
:bouquet2:🎕
:boutique:🛍
:bouton-radio:🔘
:bouton:🔳
:bouton2:🔲
:bowling:🎳
:boxe:🥊
:bretzel:🥨
:brocoli:🥦
:bronze:🥉
:brouillard:🌫
:brumeux:🌁
:buffles d'eau:🐃
:bulle:💬
:bulle10:🗩
:bulle2:💭
:bulle3:🗫
:bulle4:🗯
:bulle5:🗭
:bulle6:🗱
:bulle7:🗬
:bulle8:🗮
:bulle9:🗰
:bureau de poste:🏤
:bureau de poste2:🏣
:burrito:🌯
:bus:🚌
:bus2:🚍
:buste:👤
:bustes:👥
:caca:💩
:cacahuètes:🥜
:cactus:🌵
:cadeau:🎁
:cadre:🖾
:cadre2:🖽
:caducée:
:café:
:calamar:🦑
:calculatrice:🖩
:calendrier:📅
:calendrier2:📆
:calendrier3:🗓
:caméra cinéma:🎥
:caméra vidéo:📹
:camion d'incendie2:🛱
:camion pompier:🚒
:camion:
:camion2:🚚
:camping:🏕
:canapé:🛋
:canard:🦆
:cancer:
:caniche:🐩
:canoé:🛶
:capricorne:
:carillon:🎐
:carotte:🥕
:carré blanc:
:carré moyen noir:
:carré moyen:
:carré noir:
:carreau:
:carreau2:
:cartable:🎒
:carte de crédit:💳
:carte:🗺
:cartes:🎴
:cartouche:🖭
:Case à cocher cochée:
:case à cocher croix:
:Case à cocher:
:case à cocher4:🗷
:case à cocher5:🗹
:case à cocher6:🗵
:casque audio:🎧
:casque:
:casquette:🧢
:cavalier blanc:
:cavalier noir:
:cdrom:💿
:cent:¢
:cercle blanc moyen:
:cercle noir moyen:
:cercle noir:
:cercle:
:cercle3:🔾
:cercle4:🔿
:cercueil:
:cerise:🍒
:cerveau:🧠
:chaînes:
:chaloupe:🚣
:chameau:🐫
:champignon:🍄
:chapeau:👒
:chapeau2:👲
:chariot:🛒
:chat bisou:😽
:chat boudeur:😾
:chat joyeux:😹
:chat narquois:😼
:chat pleurant:😿
:chat souriant:😸
:chat souriant2:😺
:chat triste:🙀
:chat:🐈
:chat2:🐱
:châtaigne:🌰
:château:🏰
:château2:🏯
:chaussettes:🧦
:chaussure:👞
:chaussure2:👟
:chaussure3:👠
:chauve-souris:🦇
:chenille:🐛
:cheval:🐎
:cheval2:🐴
:chevaucher:🗗
:chevaux3:🏇
:cheveux blonds:👱
:chèvre:🐐
:chevreuil:🦌
:chien:🐕
:chien2:🐶
:chocolat:🍫
:choqué:🤯
:chouette:🦉
:chronomètre:
:cible:🎯
:cierge magique:🎇
:cinéma:🎦
:cirque:🎪
:ciseaux:
:ciseaux2:
:ciseaux3:
:ciseaux4:
:citron:🍋
:clap:🎬
:clavier:
:clavier2:🖮
:clavier3:🖦
:clé anglaise:🔧
:clé:🔑
:clé2:🗝
:clef:𝄞
:clignoter:📸
:clin d’œil:😉
:cloche3:🕭
:clou:🖈
:clown:🤡
:coccinelle:🐞
:coche:
:coche2:
:coche3:
:coche4:🗴
:coche5:🗸
:cocktail:🍸
:cœur animé:💖
:cœur battant:💓
:cœur brisé:💔
:cœur chat:😻
:cœur croissant:💗
:cœur décoration:💟
:coeur noir:🖤
:coeur orange:🧡
:cœur ruban:💝
:cœur yeux:😍
:cœur:
:coeur2:🎔
:cœur2:
:cœurs cercle:💞
:cœurs:
:coiffeur:💈
:colère:💢
:colliers:📿
:colombe:🕊
:combiné téléphonique:📞
:combiné téléphonique2:🕻
:combiné téléphonique3:🕽
:combiné téléphonique4:🕼
:comète:
:concombre:🥒
:confondu:😖
:confus:😕
:consigne:🛅
:contient:
:contrôle:🎛
:cookie:🍪
:cookie2:🥠
:copyright:©
:coq:🐓
:coquille:🐚
:cor de poste:📯
:corbeille:🗑
:cornet de glace:🍦
:cors:🤘
:coucher du soleil:🌆
:couleur:🕴
:coupe de cheveux:💇
:couple:👫
:couple2:👬
:couple3:👭
:couple4:💑
:coureur:🏃
:couronne:👑
:course:🏁
:couteau:🔪
:couteau2:🗡
:cowboy:🤠
:CQFD:
:crabe:🦀
:cracker de riz:🍘
:craintif:😨
:crâne:💀
:cravate:👔
:crayon:
:crayon2:
:crayon3:
:crème:🍮
:crevette:🍤
:cricket:🏏
:cricket2:🦗
:crier:😱
:croche:𝅘𝅥𝅮
:crocodile:🐊
:croissant de lune:🌙
:croissant:🥐
:croix ancée:
:croix celtique:🕈
:croix de Jérusalem:
:croix de Lorraine:
:croix de Malte:
:Croix de saint André:
:croix grecque:
:croix grecque2:
:croix latine:
:croix latine2:🕆
:croix latine3:🕇
:croix orthodoxe:
:cuiller:🥄
:cuisine:🍳
:cuisse de volaille:🍗
:curling:🥌
:curry:🍛
:cycliste:🚴
:cyclone:🌀
:DAB:🏧
:dague:
:dague2:
:dame blanche:
:dame:🂭
:dango:🍡
:danseur:💃
:danseur2:🕺
:dauphin:🐬
:débutant:🔰
:déçu soulagé:😥
:degré:°
:delta:δ
:Delta:Δ
:demi-pause:𝄼
:demi-soupir:𝄾
:départ:🛫
:déplaisir:😒
:dernier croissant:🌘
:dernier quartier:🌗
:dés:🎲
:dés1:
:dés2:
:dés3:
:dés4:
:dés5:
:dés6:
:désappointé:😞
:désert:🏜
:détective:🕵
:deux cœurs:💕
:déverrouillé:🔓
:diablotin:👿
:diagramme:📈
:diagramme4:💹
:diagramme5:🗠
:dièse:
:différent:
:dinde:🦃
:dinosaure:🦕
:dinosaure2:🦖
:disque dur:🖴
:disque optique:🖸
:disquette:💾
:disquette2:🖬
:disquette3:🖫
:disquette4:🖪
:diviseur:
:divorce:
:document vide:🗋
:document:🗎
:document2:🖹
:document3:🖻
:document4:🖺
:doigt:🖕
:dollar:💲
:dollar2:💵
:domino:🁠
:donut:🍩
:dossier:📁
:dossier2:📂
:dossier3:🗀
:dossier4:🗁
:dossier5:🖿
:douane:🛃
:double-bémol:𝄫
:double-croche:𝅘𝅥𝅯
:double-dièse:𝄪
:douche:🚿
:dragon:🐉
:dragon2:🐲
:drapeau triangulaire:🚩
:drapeau:
:drapeau2:🏳
:drapeau4:
:drapeaux:🎌
:drapeaux2:🎏
:droit:
:droit2:👉
:droit3:
:droit4:🖛
:droit5:🖙
:droit6:🖝
:dromadaire:🐪
:dvd:📀
:e-mail:📧
:E:
:E2:
:eau non potable:🚱
:eau potable:🚰
:échange:💱
:écharpe:🧕
:éclair2:🗲
:école:🏫
:écran:🖵
:écriture:
:écriture2:🖎
:église:
:éléphant:🐘
:elfe:🧝
:ellipse:
:emcodeintes:👣
:en colère:😠
:enceinte:🤰
:endormi:😴
:enfant:🧒
:engrenage:
:enregistrement:
:ensemble vide:
:ensoleillé:
:enveloppe:
:enveloppe2:🖃
:enveloppe3:🖂
:enveloppe5:🖄
:enveloppe6:🖅
:enveloppe7:📨
:enveloppe8:📩
:EO:
:EO2:
:épées:
:epsilon:ε
:Epsilon:Ε
:épuisé:😫
:escargot:🐌
:escrimeur:🤺
:est élément de:
:et:
:êta:η
:Êta:Η
:éternuer:🤧
:étincelle:
:étincelles:
:étiquette:🏷
:étoile blanche:
:étoile de David:
:étoile et croissant:
:étoile moyenne:
:étoile:
:étoile3:🌟
:étoile4:🌠
:étonné:😲
:étourdi:💫
:étreinte:🤗
:euro:
:euro2:💶
:eveloppe4:🖆
:excité:🤩
:extraterrestre:👽
:extraterrestre2:👾
:famille:👪
:fanion:🏲
:fanion2:🏱
:fantôme:👻
:Farsi:
:fatigué:😩
:faucille et marteau:
:fauteuil roulant:
:fax:📠
:fax2:🖷
:fée:🧚
:femelle:
:femme:👩
:femmes:🚺
:fenêtre:🗔
:fermeture éclair:🤐
:ferry:
:fête:🎉
:fête2:🎊
:fête3:🥂
:fête4:🍾
:feu d'artifice:🎆
:feu:🔥
:feuille:🍁
:feuille2:🍂
:feuille3:🍃
:feutré:😯
:feux de signalisation:🚥
:feux de signalisation2:🚦
:feux tournant:🚨
:ff:
:ffi:
:ffl:
:fi:
:fille:👧
:filles:🛊
:film:🎞
:fish-cake:🍥
:fl:
:flèches:🗘
:fleur blanche:💮
:fleur de lys:
:fleur:
:fleur2:🌼
:fleur3:🌸
:flocon de neige:
:foire:🎡
:foire2:🎠
:fontaine:
:football américain:🏈
:football:
:football2:🥅
:fou blanc:
:fou noir:
:foudre:🌩
:foudre3:
:foulard:🧣
:fourmi:🐜
:fraise:🍓
:frites:🍟
:fromage:🧀
:Fuji:🗻
:fumeur:🚬
:funiculaire:🚞
:fusée:🚀
:galette:🥙
:gamma:γ
:Gamma:Γ
:gants:🧤
:garçon:👦
:garçons:🛉
:garde:💂
:gare:🚉
:gâteau:🍰
:gauche:
:gauche2:👈
:gauche3:
:gauche4:🖚
:gauche5:🖜
:gauche6:🖘
:gémeaux:
:génie:🧞
:girafe:🦒
:glace pilée:🍧
:glace:🍨
:glissière:🎚
:globe:🌍
:globe2:🌎
:globe3:🌏
:globe4:🌐
:golf:🏌
:golf2:
:gorille:🦍
:gouttelette:💧
:gouttelette2:🌢
:gouttes de sueur:💦
:grand carré noir:
:grand carré:
:grand cercle noir:
:grand cercle:
:graphique2:📉
:graphique3:📊
:grenouille:🐸
:grimaçant:😀
:grimaçant2:😬
:grimace:😁
:grimpeur:🧗
:groin:🐽
:groom:🤵
:guitare:🎸
:gymnaste:🤸
:halloween:🎃
:haltérophile:🏋
:hamburger:🍔
:hamster:🐹
:handball:🤾
:haussement d'épaule:🤷
:haut-de-forme:🎩
:haut-parleur:📢
:haut-parleur2:🔈
:haut-parleur3:🕨
:haut-parleur4:🕪
:haut:
:haut2:👆
:haut3:🖞
:haut4:🖠
:haut5:🖢
:haute tension:
:hélicoptère:🚁
:herbe:🌿
:hérisson:🦔
:hexagone noir:
:hexagone:
:hibiscus:🌺
:hockey:🏒
:hockey2:🏑
:homme:👨
:hommes:🚹
:hôpital:🏥
:horloge:
:hot-dog:🌭
:hôtel:🏨
:hôtel2:🏩
:hourra:🙌
:hryvnia:
:il existe:
:il n'existe pas:
:île:🏝
:image:🖼
:immeuble de bureaux:🏢
:imprimante:🖨
:imprimante2:🖶
:indice:🗂
:infini:
:information:
:information2:💁
:information3:🛈
:innocent:😇
:inquiet:😟
:intégrale contour:
:intégrale double:
:intégrale triple:
:intégrale volume:
:intégrale:
:inter:
:interdit:🛇
:inversé:🙃
:iota:ι
:Iota:Ι
:Japon:🗾
:jeans:👖
:jeu vidéo:🎮
:jeune mariée:👰
:joie:😂
:joker:🃏
:jongler:🤹
:journal:📰
:journal2:🗞
:judo:🥋
:jupiter:
:kaaba:🕋
:kappa:κ
:Kappa:Κ
:khi rhô:
:khi:χ
:Khi:Χ
:kimono:👘
:kiwi:🥝
:koala:🐨
:lait:🥛
:lambda:λ
:Lambda:Λ
:lampe torche:🔦
:langue:👅
:langue2:😛
:langue3:😜
:langue4:😝
:lanterne:🏮
:lapin:🐇
:lapin2:🐰
:leopard:🐆
:lettre d'amour:💌
:lever du soleil:🌅
:lever du soleil2:🌄
:lever du soleil3:🌇
:lèvres:🗢
:lézard:🦎
:liberté:🗽
:licorne:🦄
:lien:🔗
:lion:
:lire turque:
:lire:
:lit:🛏
:livre de compte:📒
:livre sterling:£
:livre:📕
:livre2:💷
:livre3:📖
:livre4:🕮
:livres:📚
:locomotive:🚂
:locomotive2:🛲
:losange:
:loufoque:🤪
:loup:🐺
:loupe:🔍
:loupe2:🔎
:luge:🛷
:luminosité:🔅
:luminosité2:🔆
:lune gibbeuse croissante:🌔
:lune gibbeuse décroissante:🌖
:lune:🌛
:Lune:
:lune2:🌜
:Lune2:
:lunettes de soleil:🕶
:lunettes de soleil2:😎
:lunettes:👓
:lutin souriant:😈
:lutin:👺
:lutte:🤼
:machine à sous:🎰
:magasin:🏪
:magasin2:🏬
:mage:🧙
:mahjong:🀄
:maillot:🎽
:main:
:main2:🖐
:main3:🖑
:main4:🤚
:mains ouvertes:👐
:maïs:🌽
:maison:🏠
:maison2:🏡
:maison3:🏚
:maisons:🏘
:mâle:
:malette:💼
:manchot:🐧
:mandarine:🍊
:manette de jeu:🕹
:maniaque:🤓
:manteau:🧥
:mariage:
:marque de baiser:💋
:marque déposée:®
:marque page:🕅
:marque-page:📑
:marque-pages2:🔖
:marteau et clé:🛠
:marteau et pic:
:marteau:🔨
:masque:😷
:massage:💆
:maudire:🤬
:mauvais:🙅
:mdr:🤣
:médaille:🏅
:médaille2:🎖
:megaphone:📣
:melon:🍈
:mémo:📝
:menorah:🕎
:menteur:🤥
:mercure:
:merperson:🧜
:métro léger:🚈
:metro:🚇
:miam:😋
:microphone:🎤
:microphone2:🎙
:microscope:🔬
:miel:🍯
:mineur:🔞
:mini carré noir:
:minibus:🚐
:minidisc:💽
:minuterie:
:modem:🖀
:monocle:🧐
:monorail:🚝
:montagne:
:montagne2:🏔
:montagnes russes:🎢
:mosquée:🕌
:moto:🏍
:mouton:🐑
:mrs. claus:🤶
:mu:μ
:Mu:Μ
:muet:🔇
:multiplication2:
:muscle:💪
:musée:🏛
:musique:🎶
:musique2:🎵
:N:
:n'est pas élément de:
:n'inclut pas:
:N2:
:nageur:🏊
:narquois:😏
:nausée:🤢
:navire:🚢
:navire2:🛳
:ne contient pas:
:ne divise pas:
:ne pas jeter:🚯
:NE:
:NE2:
:neige:🌨
:neptune:
:neutre:😐
:nez:👃
:NO:
:NO2:
:noces:💒
:noël:🎄
:noire:𝅘𝅥
:noix de coco:🥥
:non fumeur:🚭
:non inclus:
:non parallèle:
:non:👎
:NON:¬
:non2:🖓
:note vide:🗅
:note:
:note2:
:note3:🗈
:notebook:📓
:notebook2:📔
:notes:
:notes2:
:notes3:🎝
:notes4:🎜
:nourriture:🥘
:nouvelle lune:🌑
:nouvelle lune2:🌚
:NS:
:NS2:
:nu:ν
:Nu:Ν
:nuage:
:nuage2:
:nuage3:
:nuageux:🌤
:nuageux2:🌥
:nuit:🌃
:O:
:O2:
:océan:🌊
:oden:🍢
:oeil:👁
:œuf:🥚
:ogre:👹
:oiseau:🐦
:ok:👌
:ok2:🖏
:ok3:🙆
:om:🕉
:oméga:ω
:Oméga:Ω
:omicron:ο
:Omicron:Ο
:ondulation:👋
:ongles:💅
:or:🥇
:orage2:
:ordinateur:💻
:ordinateur2:🖥
:oreille:👂
:oreilles de lapin:👯
:ou:
:oui:👍
:oui2:🖒
:ours:🐻
:ouvrier:👷
:ovni:🛸
:page de note vide:🗆
:page de note:🗉
:page vide:🗌
:page:📄
:page2:🗏
:page3:📃
:page4:🗟
:pager:📟
:pages vides:🗍
:pages:🗐
:pain:🍞
:pain2:🥖
:paix:
:palette de peintre:🎨
:palmier:🌴
:pancakes:🥞
:panda:🐼
:pansement:🤕
:papier non-acide:
:papier recyclé:
:papillon:🦋
:paquet:📦
:parallèle:
:parallélogramme blanc:
:parallélogramme noir:
:parapluie:
:parapluie2:🌂
:parasol:
:parc:🏞
:partiel:
:partition musicale:🎼
:pas de piratage:🕲
:passage piéton:🚸
:passeport:🛂
:pastèque:🍉
:patate douce:🍠
:patate:🥔
:patin:
:paume:🤦
:paume2:🤲
:pause:𝄻
:pc:🖳
:peau1:🏻
:peau2:🏼
:peau3:🏽
:peau4:🏾
:peau5:🏿
:pêche :🍑
:pêche à la ligne:🎣
:pensif:😔
:pentagone noir:
:pentagone:
:pentagramme:
:père-noël:🎅
:persévère:😣
:peso:
:petit carré blanc:
:petit carré noir:
:petit carré:
:petite étoile noire:
:petite étoile:
:phi:φ
:Phi:Φ
:pi:π
:Pi:Π
:piano:🎹
:pic:
:pierre précieuse:💎
:piéton interdit:🚷
:piéton:🚶
:pilule:💊
:pin:🌲
:pinceau:🖌
:ping pong:🏓
:pion blanc:
:pion noir:
:pique:
:pique2:
:pirate:🕱
:piste:🛤
:pistolet:🔫
:pizza:🍕
:plantule:🌱
:plat à emporter:🥡
:pleine lune:🌕
:pleine lune2:🌝
:pleurer:😢
:pluie:
:pluie2:
:plume:
:plume2:
:pluton:
:pluvieux:🌦
:poche:👝
:poignée de main:🤝
:poing:
:poing2:👊
:poing3:🤛
:poing4:🤜
:point central:·
:point de base:
:poire:🍐
:poison:
:poisson:🐟
:poisson2:🐠
:poisson3:🐡
:poissons:
:poivre:🌶
:police:🗛
:police2:🗚
:policier:👮
:pomme verte:🍏
:pomme:🍎
:pompe à essence:
:pont:🌉
:popcorn:🍿
:porc:🐖
:porc2:🐷
:portable éteint:📴
:portable interdit:📵
:portable:📱
:portable2:🖁
:porte-monnaie:👛
:porte-voix:🕫
:porte-voix2:🕬
:porte:🚪
:poubelle:🚮
:pouce:
:poulet:🐔
:poulpe:🐙
:poupées:🎎
:pour mille:
:poussin:🐣
:poussin2:🐤
:poussin3:🐥
:codemier croissant:🌒
:codemier quartier:🌓
:codesse-papiers:📋
:priant:🙏
:prime:
:prince:🤴
:princesse:👸
:prise électrique:🔌
:produit:
:projecteur:📽
:prosternation:🙇
:psi:ψ
:Psi:Ψ
:puce blanche:
:puce:
:puce2:
:puissance signal:📶
:punaise ronde:📍
:punaise:📌
:quel que soit:
:racine 4e:
:racine cubique:
:racine:
:radio:📻
:radioactif:
:rage:😡
:ragout:🍲
:raisin:🍇
:rat:🐀
:rayons:🗦
:rayons2:🗥
:rayons3:🗤
:rayons4:🗧
:rectangle blanc:
:rectangle noir:
:recyclage:
:recyclage2:
:réduire:🗕
:règle:📏
:règle2:📐
:reine noire:
:remise diplôme:🎓
:renard:🦊
:renfrogné:😦
:renfrogné2:🙁
:renfrogné3:
:répertoire:📇
:requin:🦈
:réseau:🖧
:restaurant:🍴
:réveil:
:rhinocéros:🦏
:rhô:ρ
:Rhô:Ρ
:rire:😆
:riz épi:🌾
:riz:🍚
:robe:👗
:robot:🤖
:roi blanc:
:roi noir:
:roi:🂮
:ronde:𝅝
:rosace:🏵
:rosace2:🏶
:rose:🌹
:rouge-à-lèvres:💄
:rougir:😊
:rougissant:😳
:rouleau:📜
:roulement d'yeux:🙄
:roupie:
:ruban:🎗
:ruban2:🎀
:S:
:S2:
:sablier:
:sablier2:
:sac-à-main:👜
:sagittaire:
:saké:🍶
:salade:🥗
:sandale:👡
:sandwich:🥪
:sanglot:😭
:sans bouche:😶
:sans excodession:😑
:satellite:🛰
:saturne:
:sauna:🧖
:saxophone:🎷
:scooter:🛴
:scooter2:🛵
:scorpion:
:scrutin:🗳
:SE:
:SE2:
:section:§
:séduction:💠
:selfie:🤳
:semi-remorque:🚛
:sens interdit:
:seringue:💉
:serpent:🐍
:serpentaire:
:shekel:
:siège:💺
:sigma:σ
:Sigma:Σ
:sigma2:ς
:signal:🔔
:signal2:🛎
:silence:🔕
:singe aveugle:🙈
:singe muet:🙊
:singe sourd:🙉
:singe:🐒
:singe2:🐵
:ski:🎿
:skieur:
:small in:
:small ni:
:snowboarder:🏂
:SO:
:SO2:
:soleil visage:🌞
:Soleil:
:soleil2:🌣
:Soleil2:
:somme:
:sommeil:🛌
:somnolent:😪
:son fort:🔊
:son:🔉
:soulagé:😌
:soupir:𝄽
:source chaude:
:sourcil:🤨
:souriant:😃
:sourire sueur:😅
:sourire:
:sourire2:
:sourire3:😄
:sourire4:🤭
:souris:🐁
:souris2:🐭
:souris3:🖱
:souris4:🖰
:souris5:🖯
:sous-ensemble:
:spaghetti:🍝
:spock:🖖
:stade:🏟
:statue:🗿
:steak:🥩
:stéréo:📾
:stop:🛑
:stop2:
:stylo:🖊
:stylo2:🖋
:stylo4:🖉
:sucette:🍭
:sueur froide:😰
:sur-ensemble:
:surfeur:🏄
:sushi:🍣
:synagogue:🕍
:synthétiseur:🎘
:t-shirt:👕
:taco:🌮
:tambour:🛢
:tambour2:🥁
:tamia:🐿
:tanabata:🎋
:tarte:🥧
:tau:τ
:Tau:Τ
:taureau:
:taxi:🚕
:taxi2:🚖
:téléphérique:🚡
:téléphérique2:🚠
:téléphone blanc:
:téléphone noir:
:téléphone:
:téléphone3:🕾
:téléphone4:🕿
:télescope:🔭
:tempête:🌧
:tennis:🎾
:tente:
:terre:
:tête:🗣
:tgv:🚄
:tgv2:🚅
:thé:🍵
:théatre:🎭
:thermomètre:🌡
:thermomètre2:🤒
:thêta:θ
:Thêta:Θ
:ticket:🎫
:ticket2:🎟
:tigre:🐅
:tigre2:🐯
:tiret:💨
:tm:
:toilettes:🚻
:tomate:🍅
:tornade:🌪
:tortue:🐢
:tour blanche:
:tour noire:
:tour:🗼
:tournesol:🌻
:traces de pas:🐾
:trackball:🖲
:tracteur:🚜
:train suspendu:🚟
:train:🚆
:tram:🚊
:tram2:🚋
:transpiration:😓
:trapèze:
:travaux:🚧
:trèfle:
:trèfle2:
:trèfle4:🍀
:triangle rectangle:
:triangle:
:triangle2:
:triangle3:🛆
:trident:🔱
:triomphe:😤
:trolley:🚎
:trombone:📎
:trombone2:🖇
:trompette:🎺
:trophée:🏆
:trou:🕳
:tsukimi:🎑
:tulipe:🌷
:turban:👳
:tv:📺
:union:
:upsilon:υ
:Upsilon:Υ
:uranus:
:urne:
:usine:🏭
:vache:🐄
:vache2:🐮
:valet:🂫
:vampire:🧛
:vedette:🚤
:vélo interdit:🚳
:vénération:🛐
:vent:🌬
:verrat:🐗
:verre:🍷
:verre3:🥃
:verrouillé:🔒
:verrouillé2:🔏
:verrouillé3:🔐
:verseau:
:vertige:😵
:vêtements de femme:👚
:vhs:📼
:viande:🍖
:vibreur:📳
:victoire:
:victoire2:🖔
:vieil homme:👴
:vieille femme:👵
:vierge:
:vieux:🧓
:ville:🏙
:violon:🎻
:vis et écrou:🔩
:voie lactée:🌌
:voilier:
:voiture police:🚓
:voiture police2:🚔
:voiture:🚗
:voiture2:🚘
:voiture3:🚙
:voiture4:🏎
:volcan:🌋
:voleyball:🏐
:vomir:🤮
:vtt:🚵
:wagon:🚃
:water polo:🤽
:wc:🚾
:wc2:🚽
:web:🕸
:won:
:x:×
:x2:
:x3:
:x4:🗶
:xi:ξ
:Xi:Ξ
:yen:¥
:yen2:💴
:yeux:👀
:yin yang:
:yoga:🧘
:zèbre:🦓
:zêta:ζ
:Zêta:Ζ
:zombie:🧟
:zzz:💤
Indices
:_-:
:_(:
:_):
:_+:
:_=:
:_0:
:_1:
:_2:
:_3:
:_4:
:_5:
:_6:
:_7:
:_8:
:_9:
:_a:
:_bêta:
:_e:
:_gamma:
:_h:
:_i:
:_j:
:_k:
:_khi:
:_l:
:_m:
:_n:
:_o:
:_p:
:_phi:
:_r:
:_rhô:
:_s:
:_t:
:_u:
:_v:
:_x:
.*_-
.*_(
.*_)
.*_+
.*_=
.*_0
.*_1
.*_2
.*_3
.*_4
.*_5
.*_6
.*_7
.*_8
.*_9
.*->.*
.*...
.*//.·
.*/cm2/cm²
.*/dm2/dm²
.*/km2/km²
.*/m2/m²
.*/m3/m³
.*/mm2/mm²
.*/µm2/µm²
.*^-
.*^(
.*^)
.*^+
.*^=
.*^0
.*^1¹
.*^2²
.*^3³
.*^4
.*^5
.*^6
.*^7
.*^8
.*^9
Corrections
.*soeursœur
.*soeurssœurs
*coeurcœur
*coeurscœurs
a t'ellea-t-elle
a t'ila-t-il
a t'ona-t-on
a-t'ellea-t-elle
a-t'ila-t-il
a-t'ona-t-on
abcisseabscisse
accompteacompte
acroîtreaccroître
afairesaffaires
afirmeraffirmer
aggioagio
aggiosagios
agrèeragréer
aleraller
alleursailleurs
allieursailleurs
am2am²
am3am³
ambigueambiguë
anéeannée
anéesannées
annullerannuler
anotationannotation
anotationsannotations
anullerannuler
aparaîtreapparaître
apelappel
apelsappels
apparaitapparaît
apparaitreapparaître
appellerappeler
appercevoirapercevoir
acodendreapcodendre
après JCaprès J.-C.
aritmétiquearithmétique
atrapperattrapper
au delaau-delà
au delàau-delà
aujourd’hiuaujourd’hui
aujourdhiuaujourd’hui
ausiaussi
aussitotaussitôt
autentiqueauthentique
autentiquesauthentiques
authorisationautorisation
avant JCavant J.-C.
baragebarrage
baucoupbeaucoup
bibliotèquebibliothèque
bientotbientôt
boeufbœuf
boeufsbœufs
buletinbulletin
càdc’est-à-dire
cealcela
celàcela
celullecellule
cetraincertain
chaqunchacun
charettecharrette
charriotchariot
chateauchâteau
circonstantielcirconstanciel
clientéleclientèle
cm2cm²
cm3cm³
cnetcent
cometrecommettre
concesionconcession
concesionsconcessions
concluseconclue
confidencielconfidentiel
connaitconnaît
connaitreconnaître
contencieuxcontentieux
controlecontrôle
coulerucouleur
courierscourriers
courrircourir
créeecréée
creercréer
crêmecrème
curiculumcurriculum
d'Etatd’État
d’Etatd’État
dégrévementdégrèvement
dejadéjà
dejàdéjà
déjadéjà
dépotdépôt
désoeuvrementdésœuvrement
déveloperdévelopper
dexudeux
dictionairedictionnaire
dilemnedilemme
dilemnesdilemmes
diplomediplôme
disparaitdisparaît
disparaitredisparaître
dnasdans
dnotdont
dsedes
dûedue
dûesdues
dûsdus
E-UE.-U.
efetseffets
emmissionémission
entr’acteentracte
envelopeenveloppe
enveloperenvelopper
etc...etc.
etc…etc.
excelentexcellent
excelentsexcellents
exelentexcellent
exelentsexcellents
exigeanceexigence
falangephalange
faloirfalloir
ficheirfichier
ficheirsfichiers
filiallefiliale
fillialefiliale
financiairefinancière
fiosfois
flêcheflèche
foetusfœtus
francofonefrancophone
fuirefuir
gèrergérer
gestionairegestionnaire
goufregouffre
goutgoût
grand chosegrand-chose
grand mèregrand-mère
grand pèregrand-père
griffonergriffonner
hatuhaut
iconeicône
imbécilitéimbécillité
incluinclus
inclueincluse
indémniserindemniser
indépendentindépendant
inovationinnovation
intéretintérêt
intérresserintéresser
intervaleintervalle
jamiasjamais
jusqu'ajusqu’à
jusquaujusqu’au
jutsejuste
l'Eglisel’Église
L'EgliseL’Église
l'Etatl’État
L'EtatL’État
l’Eglisel’Église
L’EgliseL’Église
l’Etatl’État
L’EtatL’État
languagelangage
languageslangages
leruleur
licenselicence
licenseslicences
lseles
manoeuvremanœuvre
manoeuvresmanœuvres
MéditerannéeMéditerranée
mémotechniquemnémotechnique
miomoi
mionsmoins
modélemodèle
moeursmœurs
mourrirmourir
NoelNoël
noeudnœud
noeudsnœuds
nosunous
occupperoccuper
occurenceoccurrence
occurencesoccurrences
ocuperoccuper
ocurrenceoccurrence
ocurrencesoccurrences
odfODF
oecuménismeœcuménisme
oeilœil
oenologieœnologie
oenologueœnologue
oenologuesœnologues
oesophageœsophage
oeufœuf
oeufsœufs
oeuvreœuvre
oeuvresœuvres
oo
paquepâque
PaquesPâques
paraitparaît
paraitreparaître
paralèlleparallèle
paralèllesparallèles
paranoyaqueparanoïaque
parce-queparce que
parcequeparce que
pélerinpèlerin
périfériquepériphérique
personalitépersonnalité
personelpersonnel
plein-piedplain-pied
codetprêt
problemmeproblème
problemmesproblèmes
professionelprofessionnel
professionelleprofessionnelle
professionellesprofessionnelles
professionelsprofessionnels
proffessionelprofessionnel
proffessionelleprofessionnelle
proffessionellesprofessionnelles
proffessionelsprofessionnels
quelq'unquelqu'un
quelqunquelqu'un
racourciraccourci
rapelrappel
rapellerappelle
rapellerrappeller
rapelsrappels
recepissérécépissé
reconnaitreconnaît
reconnaitrereconnaître
réflectionréflexion
réglementrèglement
règlementationréglementation
règlerrégler
réhausserrehausser
remèdierremédier
réouvrirrouvrir
resentirressentir
rhytmerythme
rhytmesrythmes
rintroduireréintroduire
rolerôle
sera t'ellesera-t-elle
sera t'ilsera-t-il
sera t'onsera-t-il
sera-t'ellesera-t-elle
sera-t'ilsera-t-il
sera-t'onsera-t-il
serat-ellesera-t-elle
serat-ilsera-t-il
serat-onsera-t-on
soutraitantsous-traitant
tepmstemps
toujorustoujours
traffictrafic
tréstrès
valeruvaleur
vérouillerverrouiller
veulliezveuillez
voeuvœu
voeuxvœux
VoilaVoilà
volontiervolontiers
vosuvous
vouliorvouloir
Unités
.*g.m2g·m²
.*m2.sm²·s
.*m3/sm³/s
dam2dam²
dam3dam³
dm2dm²
dm3dm³
Em2Em²
Em3Em³
fm2fm²
fm3fm³
Gm2Gm²
Gm3Gm³
hm2hm²
hm3hm³
km2km²
km3km³
m2
m3
mm2mm²
Mm2Mm²
mm3mm³
Mm3Mm³
nm2nm²
nm3nm³
pm2pm²
Pm2Pm²
pm3pm³
Pm3Pm³
Tm2Tm²
Tm3Tm³
ym2ym²
Ym2Ym²
ym3ym³
Ym3Ym³
zm2zm²
Zm2Zm²
zm3zm³
Zm3Zm³
µm2µm²
µm3µm³

Source : https://wiki.documentfoundation.org/UserProfile#User_profile_content.


Par défaut, il est difficile d'obtenir certains caractères sous Windows (contrairement à MacOS ou GNU/Linux), par exemple À, É, œ, une espace insécable, …

eric.bugnet.fr

En utilisant Microsoft Keyboard Layout Creator, il a créé un layout basé sur le clavier fr-oss présent dans les distributions GNU/Linux.

Clavier fr-oss.png

Tous les détails sur la page : Un clavier pour écrire en français sous Windows É Ç Œ et trucs dans le genre... - Mon coin du web...

Il y partage notamment son fichier source. Pour ma part je m'en suis servi pour ajouter l'espace fine insécable avec Shift+Espace avant de reconstruire les fichiers d'installation (voir pièces-jointes).

Obtenir des infos sur une image docker

Commande

Attention, les actions se lisent de bas en haut.

docker history --format "{{.CreatedBy}}" --no-trunc <image>

Exemple

docker history --format "{{.CreatedBy}}" --no-trunc cthulhoo/ttrss-web-nginx 
COPY nginx.conf /etc/nginx/nginx.conf # buildkit
HEALTHCHECK &{["CMD-SHELL" "curl --fail http://localhost/tt-rss/index.php || exit 1"] "0s" "0s" "0s" '\x00'}
/bin/sh -c #(nop)  CMD ["nginx" "-g" "daemon off;"]
/bin/sh -c #(nop)  STOPSIGNAL SIGQUIT
/bin/sh -c #(nop)  EXPOSE 80
/bin/sh -c #(nop)  ENTRYPOINT ["/docker-entrypoint.sh"]
/bin/sh -c #(nop) COPY file:09a214a3e07c919af2fb2d7c749ccbc446b8c10eb217366e5a65640ee9edcc25 in /docker-entrypoint.d
/bin/sh -c #(nop) COPY file:0fd5fca330dcd6a7de297435e32af634f29f7132ed0550d342cad9fd20158258 in /docker-entrypoint.d
/bin/sh -c #(nop) COPY file:0b866ff3fc1ef5b03c4e6c8c513ae014f691fb05d530257dfffd07035c1b75da in /docker-entrypoint.d
/bin/sh -c #(nop) COPY file:65504f71f5855ca017fb64d502ce873a31b2e0decd75297a8fb0a287f97acf92 in /
/bin/sh -c set -x     && addgroup -g 101 -S nginx     && adduser -S -D -H -u 101 -h /var/cache/nginx -s /sbin/nologin -G nginx -g nginx nginx     && apkArch="$(cat /etc/apk/arch)"     && nginxPackages="         nginx=${NGINX_VERSION}-r${PKG_RELEASE}         nginx-module-xslt=${NGINX_VERSION}-r${PKG_RELEASE}         nginx-module-geoip=${NGINX_VERSION}-r${PKG_RELEASE}         nginx-module-image-filter=${NGINX_VERSION}-r${PKG_RELEASE}         nginx-module-njs=${NGINX_VERSION}.${NJS_VERSION}-r${PKG_RELEASE}     "     && apk add --no-cache --virtual .checksum-deps         openssl     && case "$apkArch" in         x86_64|aarch64)             set -x             && KEY_SHA512="e7fa8303923d9b95db37a77ad46c68fd4755ff935d0a534d26eba83de193c76166c68bfe7f65471bf8881004ef4aa6df3e34689c305662750c0172fca5d8552a *stdin"             && wget -O /tmp/nginx_signing.rsa.pub https://nginx.org/keys/nginx_signing.rsa.pub             && if [ "$(openssl rsa -pubin -in /tmp/nginx_signing.rsa.pub -text -noout | openssl sha512 -r)" = "$KEY_SHA512" ]; then                 echo "key verification succeeded!";                 mv /tmp/nginx_signing.rsa.pub /etc/apk/keys/;             else                 echo "key verification failed!";                 exit 1;             fi             && apk add -X "https://nginx.org/packages/mainline/alpine/v$(egrep -o '^[0-9]+\.[0-9]+' /etc/alpine-release)/main" --no-cache $nginxPackages             ;;         *)
set -x             && tempDir="$(mktemp -d)"             && chown nobody:nobody $tempDir             && apk add --no-cache --virtual .build-deps                 gcc                 libc-dev                 make                 openssl-dev                 pcre2-dev                 zlib-dev                 linux-headers                 libxslt-dev                 gd-dev                 geoip-dev                 perl-dev                 libedit-dev                 bash
   alpine-sdk                 findutils             && su nobody -s /bin/sh -c "                 export HOME=${tempDir}                 && cd ${tempDir}                 && curl -f -O https://hg.nginx.org/pkg-oss/archive/${NGINX_VERSION}-${PKG_RELEASE}.tar.gz                 && PKGOSSCHECKSUM=\"513952f1e0432e667a8e3afef791a2daa036911f35573c849712747f10418f3f5b8712faf75fcb87f91bfaf593622b1e1c4f38ad9fef830f4cae141357206ecd *${NGINX_VERSION}-${PKG_RELEASE}.tar.gz\"                 && if [ \"\$(openssl sha512 -r ${NGINX_VERSION}-${PKG_RELEASE}.tar.gz)\" = \"\$PKGOSSCHECKSUM\" ]; then                     echo \"pkg-oss tarball checksum verification succeeded!\";                 else                     echo \"pkg-oss tarball checksum verification failed!\";                     exit 1;                 fi                 && tar xzvf ${NGINX_VERSION}-${PKG_RELEASE}.tar.gz                 && cd pkg-oss-${NGINX_VERSION}-${PKG_RELEASE}                 && cd alpine                 && make all                 && apk index -o ${tempDir}/packages/alpine/${apkArch}/APKINDEX.tar.gz ${tempDir}/packages/alpine/${apkArch}/*.apk                 && abuild-sign -k ${tempDir}/.abuild/abuild-key.rsa ${tempDir}/packages/alpine/${apkArch}/APKINDEX.tar.gz                 "             && cp ${tempDir}/.abuild/abuild-key.rsa.pub /etc/apk/keys/             && apk del .build-deps             && apk add -X ${tempDir}/packages/alpine/ --no-cache $nginxPackages             ;;     esac     && apk del .checksum-deps     && if [ -n "$tempDir" ]; then rm -rf "$tempDir"; fi     && if [ -n "/etc/apk/keys/abuild-key.rsa.pub" ]; then rm -f /etc/apk/keys/abuild-key.rsa.pub; fi     && if [ -n "/etc/apk/keys/nginx_signing.rsa.pub" ]; then rm -f /etc/apk/keys/nginx_signing.rsa.pub; fi     && apk add --no-cache --virtual .gettext gettext     && mv /usr/bin/envsubst /tmp/         && runDeps="$(         scanelf --needed --nobanner /tmp/envsubst             | awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }'             | sort -u             | xargs -r apk info --installed             | sort -u     )"     && apk add --no-cache $runDeps     && apk del .gettext     && mv /tmp/envsubst /usr/local/bin/     && apk add --no-cache tzdata     && apk add --no-cache curl ca-certificates     && ln -sf /dev/stdout /var/log/nginx/access.log     && ln -sf /dev/stderr /var/log/nginx/error.log     && mkdir /docker-entrypoint.d
/bin/sh -c #(nop)  ENV PKG_RELEASE=1
/bin/sh -c #(nop)  ENV NJS_VERSION=0.7.6
/bin/sh -c #(nop)  ENV NGINX_VERSION=1.23.1
/bin/sh -c #(nop)  LABEL maintainer=NGINX Docker Maintainers <docker-maint@nginx.com>
/bin/sh -c #(nop)  CMD ["/bin/sh"]
/bin/sh -c #(nop) ADD file:2a949686d9886ac7c10582a6c29116fd29d3077d02755e87e111870d63607725 in /

Et pour obtenir une mise en page qui va bien, c'est à dire avec des retours à la ligne :

$ docker history --format "{{.CreatedBy}}" --no-trunc collabora/code:latest | perl -p -e 's/(?=[ ]{2,})(?<![ ])/\n/g'
CMD ["/start-collabora-online.sh"]
USER 100
EXPOSE map[9980/tcp:{}]
COPY /scripts/start-collabora-online.pl / # buildkit
COPY /scripts/start-collabora-online.sh / # buildkit
RUN |4 repo= type= nobrand= noinotifywait= /bin/sh -c apt-get update &&
     apt-get -y install cpio tzdata libcap2-bin apt-transport-https gnupg2 ca-certificates curl &&
     repourl="https://collaboraoffice.com/${repo:-repos}/CollaboraOnline/";
     secret_key=$(cat /run/secrets/secret_key);
     if [ "$type" = "cool" ] && [ -n ${secret_key+set} ]; then
         echo "Based on the provided build arguments Collabora Online from customer repo will be used.";
         repourl="${repourl}23.05/customer-deb-${secret_key}/";
     elif [ "$type" = "key" ]; then
         echo "Based on the provided build arguments license key enabled Collabora Online will be used.";
         repourl="${repourl}23.05-key/";
     else
         echo "Based on the provided build arguments Collabora Online Development Edition will be used.";
         repourl="${repourl}23.05-CODE/CODE-deb/";
     fi &&
     echo "deb [signed-by=/usr/share/keyrings/collaboraonline-release-keyring.gpg] ${repourl} /" > /etc/apt/sources.list.d/collabora.list &&
     if [ "$repo" = "repos-snapshot" ]; then
         curl https://www.collaboraoffice.com/downloads/gpg/collaboraonline-snapshot-keyring.gpg --output /usr/share/keyrings/collaboraonline-snapshot-keyring.gpg;
         sed -i "s/collaboraonline-release-keyring/collaboraonline-snapshot-keyring/" /etc/apt/sources.list.d/collabora.list;
     else
         curl https://www.collaboraoffice.com/downloads/gpg/collaboraonline-release-keyring.gpg --output /usr/share/keyrings/collaboraonline-release-keyring.gpg;
     fi &&
     apt-get update &&
     apt-get -y install coolwsd
                        collaboraoffice-dict-*
                        collaboraofficebasis-ar
                        collaboraofficebasis-bg
                        collaboraofficebasis-ca
                        collaboraofficebasis-cs
                        collaboraofficebasis-da
                        collaboraofficebasis-de
                        collaboraofficebasis-el
                        collaboraofficebasis-en-gb
                        collaboraofficebasis-en-us
                        collaboraofficebasis-eo
                        collaboraofficebasis-es
                        collaboraofficebasis-eu
                        collaboraofficebasis-fi
                        collaboraofficebasis-fr
                        collaboraofficebasis-gl
                        collaboraofficebasis-he
                        collaboraofficebasis-hr
                        collaboraofficebasis-hu
                        collaboraofficebasis-id
                        collaboraofficebasis-is
                        collaboraofficebasis-it
                        collaboraofficebasis-ja
                        collaboraofficebasis-ko
                        collaboraofficebasis-lo
                        collaboraofficebasis-nb
                        collaboraofficebasis-nl
                        collaboraofficebasis-oc
                        collaboraofficebasis-pl
                        collaboraofficebasis-pt
                        collaboraofficebasis-pt-br
                        collaboraofficebasis-ru
                        collaboraofficebasis-sk
                        collaboraofficebasis-sl
                        collaboraofficebasis-sq
                        collaboraofficebasis-sv
                        collaboraofficebasis-tr
                        collaboraofficebasis-uk
                        collaboraofficebasis-vi
                        collaboraofficebasis-zh-cn
                        collaboraofficebasis-zh-tw &&
     if [ -z "$nobrand" ]; then
         if [ "$type" = "cool" ] || [ "$type" = "key" ]; then
             apt-get -y install collabora-online-brand;
         else
             apt-get -y install code-brand;
         fi;
     fi &&
     if [ -z "$noinotifywait" ]; then
         apt-get -y install inotify-tools psmisc;
     fi &&
     chown cool:cool /etc/coolwsd &&
     rm -rf /var/lib/apt/* &&
     rm -rf /etc/coolwsd/proof_key* # buildkit
ENV LC_CTYPE=C.UTF-8
ARG noinotifywait
ARG nobrand
ARG type
ARG repo
MAINTAINER Andras Timar <andras.timar@collabora.com>
/bin/sh -c #(nop)
  CMD ["bash"]
/bin/sh -c #(nop) ADD file:95a4ddc3a846636c52c273cac4e2e0d75225cde59612235c1480201b14581d9a in / 

Command Line Interface - Tips en vrac

Chercher les fichiers qui contiennent un (des) . dans leur nom et le(s) supprimer

Toute la difficulté est de ne pas supprimer le point de l'extension…

"find -iname '*.avi' -exec rename -v 's/(?!^)\.(?!avi$)/ /g' {} \;"

Chercher les fichiers dans les sous-dossiers et le remonter dans le dossier

find . -maxdepth 2 -mindepth 2 -exec mv '{}' ./ \;

Connaître la date d'expiration d'un certificat TLS

read DOMAIN"?Domain to check:" ; echo | openssl s_client -connect "$DOMAIN":443 2>/dev/null | openssl x509 -noout -enddate ; unset DOMAIN

Poster en multilignes sur Mastodon avec cURL

curl https://<domain>/api/v1/statuses \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  -d '{"status":"Première ligne.\nSeconde ligne…",
  "in_reply_to_id":null,"media_ids":[],"sensitive":false,
  "spoiler_text":"","visibility":"direct",
  "poll":null,"language":"fr"}' \
| jq '.id'

Note…

Ce qui renvoie l'id du post.

Documentation : statuses API methods - Mastodon documentation.

Pour ajouter un émoji, on peut le copier depuis le navigateur puis le coller. Il y a sans doute une autre façon, mais je n'ai pas trop cherché et ça fonctionne comme ça !

Récupérer les réponses de ChatGPT en markdown

Le script est « en partie » écrit par ChatGPT lui-même…

Importer le fichier lib/turndown.browser.umd.js de la bibliothèque mixmark-ioturndown 🛏 An HTML to Markdown converter written in JavaScript depuis le site https://unpkg.com/browse/turndown/ (actuellement ce lien) dans la console JavaScript du navigateur.

Version minifiée par JavaScript Minifier & Compressor Toptal®
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(e="undefined"!=typeof globalThis?globalThis:e||self).TurndownService=n()}(this,function(){"use strict";function e(e,n){return Array(n+1).join(e)}var n,t=["ADDRESS","ARTICLE","ASIDE","AUDIO","BLOCKQUOTE","BODY","CANVAS","CENTER","DD","DIR","DIV","DL","DT","FIELDSET","FIGCAPTION","FIGURE","FOOTER","FORM","FRAMESET","H1","H2","H3","H4","H5","H6","HEADER","HGROUP","HR","HTML","ISINDEX","LI","MAIN","MENU","NAV","NOFRAMES","NOSCRIPT","OL","OUTPUT","P","PRE","SECTION","TABLE","TBODY","TD","TFOOT","TH","THEAD","TR","UL"];function r(e){return l(e,t)}var i=["AREA","BASE","BR","COL","COMMAND","EMBED","HR","IMG","INPUT","KEYGEN","LINK","META","PARAM","SOURCE","TRACK","WBR"];function o(e){return l(e,i)}var a=["A","TABLE","THEAD","TBODY","TFOOT","TH","TD","IFRAME","SCRIPT","AUDIO","VIDEO"];function l(e,n){return n.indexOf(e.nodeName)>=0}function u(e,n){return e.getElementsByTagName&&n.some(function(n){return e.getElementsByTagName(n).length})}var c={};function s(e){return e?e.replace(/(\n+\s*)+/g,"\n"):""}function f(e){for(var n in this.options=e,this._keep=[],this._remove=[],this.blankRule={replacement:e.blankReplacement},this.keepReplacement=e.keepReplacement,this.defaultRule={replacement:e.defaultReplacement},this.array=[],e.rules)this.array.push(e.rules[n])}function d(e,n,t){for(var r=0;r<e.length;r++){var i=e[r];if(p(i,n,t))return i}}function p(e,n,t){var r=e.filter;if("string"==typeof r){if(r===n.nodeName.toLowerCase())return!0}else if(Array.isArray(r)){if(r.indexOf(n.nodeName.toLowerCase())>-1)return!0}else if("function"==typeof r){if(r.call(e,n,t))return!0}else throw TypeError("`filter` needs to be a string, array, or function")}function h(e){var n=e.nextSibling||e.parentNode;return e.parentNode.removeChild(e),n}function g(e,n,t){return e&&e.parentNode===n||t(n)?n.nextSibling||n.parentNode:n.firstChild||n.nextSibling||n.parentNode}c.paragraph={filter:"p",replacement:function(e){return"\n\n"+e+"\n\n"}},c.lineBreak={filter:"br",replacement:function(e,n,t){return t.br+"\n"}},c.heading={filter:["h1","h2","h3","h4","h5","h6"],replacement:function(n,t,r){var i=Number(t.nodeName.charAt(1));if("setext"!==r.headingStyle||!(i<3))return"\n\n"+e("#",i)+" "+n+"\n\n";var o=e(1===i?"=":"-",n.length);return"\n\n"+n+"\n"+o+"\n\n"}},c.blockquote={filter:"blockquote",replacement:function(e){return"\n\n"+(e=(e=e.replace(/^\n+|\n+$/g,"")).replace(/^/gm,"> "))+"\n\n"}},c.list={filter:["ul","ol"],replacement:function(e,n){var t=n.parentNode;return"LI"===t.nodeName&&t.lastElementChild===n?"\n"+e:"\n\n"+e+"\n\n"}},c.listItem={filter:"li",replacement:function(e,n,t){e=e.replace(/^\n+/,"").replace(/\n+$/,"\n").replace(/\n/gm,"\n    ");var r=t.bulletListMarker+"   ",i=n.parentNode;if("OL"===i.nodeName){var o=i.getAttribute("start"),a=Array.prototype.indexOf.call(i.children,n);r=(o?Number(o)+a:a+1)+".  "}return r+e+(n.nextSibling&&!/\n$/.test(e)?"\n":"")}},c.indentedCodeBlock={filter:function(e,n){return"indented"===n.codeBlockStyle&&"PRE"===e.nodeName&&e.firstChild&&"CODE"===e.firstChild.nodeName},replacement:function(e,n,t){return"\n\n    "+n.firstChild.textContent.replace(/\n/g,"\n    ")+"\n\n"}},c.fencedCodeBlock={filter:function(e,n){return"fenced"===n.codeBlockStyle&&"PRE"===e.nodeName&&e.firstChild&&"CODE"===e.firstChild.nodeName},replacement:function(n,t,r){for(var i,o=((t.firstChild.getAttribute("class")||"").match(/language-(\S+)/)||[null,""])[1],a=t.firstChild.textContent,l=r.fence.charAt(0),u=3,c=RegExp("^"+l+"{3,}","gm");i=c.exec(a);)i[0].length>=u&&(u=i[0].length+1);var s=e(l,u);return"\n\n"+s+o+"\n"+a.replace(/\n$/,"")+"\n"+s+"\n\n"}},c.horizontalRule={filter:"hr",replacement:function(e,n,t){return"\n\n"+t.hr+"\n\n"}},c.inlineLink={filter:function(e,n){return"inlined"===n.linkStyle&&"A"===e.nodeName&&e.getAttribute("href")},replacement:function(e,n){var t=n.getAttribute("href"),r=s(n.getAttribute("title"));return r&&(r=' "'+r+'"'),"["+e+"]("+t+r+")"}},c.referenceLink={filter:function(e,n){return"referenced"===n.linkStyle&&"A"===e.nodeName&&e.getAttribute("href")},replacement:function(e,n,t){var r,i,o=n.getAttribute("href"),a=s(n.getAttribute("title"));switch(a&&(a=' "'+a+'"'),t.linkReferenceStyle){case"collapsed":r="["+e+"][]",i="["+e+"]: "+o+a;break;case"shortcut":r="["+e+"]",i="["+e+"]: "+o+a;break;default:var l=this.references.length+1;r="["+e+"]["+l+"]",i="["+l+"]: "+o+a}return this.references.push(i),r},references:[],append:function(e){var n="";return this.references.length&&(n="\n\n"+this.references.join("\n")+"\n\n",this.references=[]),n}},c.emphasis={filter:["em","i"],replacement:function(e,n,t){return e.trim()?t.emDelimiter+e+t.emDelimiter:""}},c.strong={filter:["strong","b"],replacement:function(e,n,t){return e.trim()?t.strongDelimiter+e+t.strongDelimiter:""}},c.code={filter:function(e){var n=e.previousSibling||e.nextSibling,t="PRE"===e.parentNode.nodeName&&!n;return"CODE"===e.nodeName&&!t},replacement:function(e){if(!e)return"";e=e.replace(/\r?\n|\r/g," ");for(var n=/^`|^ .*?[^ ].* $|`$/.test(e)?" ":"",t="`",r=e.match(/`+/gm)||[];-1!==r.indexOf(t);)t+="`";return t+n+e+n+t}},c.image={filter:"img",replacement:function(e,n){var t=s(n.getAttribute("alt")),r=n.getAttribute("src")||"",i=s(n.getAttribute("title"));return r?"!["+t+"]("+r+(i?' "'+i+'"':"")+")":""}},f.prototype={add:function(e,n){this.array.unshift(n)},keep:function(e){this._keep.unshift({filter:e,replacement:this.keepReplacement})},remove:function(e){this._remove.unshift({filter:e,replacement:function(){return""}})},forNode:function(e){var n;return e.isBlank?this.blankRule:(n=d(this.array,e,this.options))||(n=d(this._keep,e,this.options))||(n=d(this._remove,e,this.options))?n:this.defaultRule},forEach:function(e){for(var n=0;n<this.array.length;n++)e(this.array[n],n)}};var m,v="undefined"!=typeof window?window:{},A=!function e(){var n=v.DOMParser,t=!1;try{new n().parseFromString("","text/html")&&(t=!0)}catch(r){}return t}()?(m=function(){},!function e(){var n=!1;try{document.implementation.createHTMLDocument("").open()}catch(t){window.ActiveXObject&&(n=!0)}return n}()?m.prototype.parseFromString=function(e){var n=document.implementation.createHTMLDocument("");return n.open(),n.write(e),n.close(),n}:m.prototype.parseFromString=function(e){var n=new window.ActiveXObject("htmlfile");return n.designMode="on",n.open(),n.write(e),n.close(),n},m):v.DOMParser;function y(e,t){var i;return!function e(n){var t=n.element,r=n.isBlock,i=n.isVoid,o=n.isPre||function(e){return"PRE"===e.nodeName};if(!(!t.firstChild||o(t))){for(var a=null,l=!1,u=null,c=g(u,t,o);c!==t;){if(3===c.nodeType||4===c.nodeType){var s=c.data.replace(/[ \r\n\t]+/g," ");if((!a||/ $/.test(a.data))&&!l&&" "===s[0]&&(s=s.substr(1)),!s){c=h(c);continue}c.data=s,a=c}else if(1===c.nodeType)r(c)||"BR"===c.nodeName?(a&&(a.data=a.data.replace(/ $/,"")),a=null,l=!1):i(c)||o(c)?(a=null,l=!0):a&&(l=!1);else{c=h(c);continue}var f=g(u,c,o);u=c,c=f}a&&(a.data=a.data.replace(/ $/,""),a.data||h(a))}}({element:i="string"==typeof e?(n=n||new A).parseFromString('<x-turndown id="turndown-root">'+e+"</x-turndown>","text/html").getElementById("turndown-root"):e.cloneNode(!0),isBlock:r,isVoid:o,isPre:t.preformattedCode?N:null}),i}function N(e){return"PRE"===e.nodeName||"CODE"===e.nodeName}function E(e,n){var t,c,s,f;return e.isBlock=r(e),e.isCode="CODE"===e.nodeName||e.parentNode.isCode,e.isBlank=(t=e,!o(t)&&!l(c=t,a)&&/^\s*$/i.test(t.textContent)&&!u(s=t,i)&&!u(f=t,a)),e.flankingWhitespace=function e(n,t){if(n.isBlock||t.preformattedCode&&n.isCode)return{leading:"",trailing:""};var r,i,o=(r=n.textContent,i=r.match(/^(([ \t\r\n]*)(\s*))[\s\S]*?((\s*?)([ \t\r\n]*))$/),{leading:i[1],leadingAscii:i[2],leadingNonAscii:i[3],trailing:i[4],trailingNonAscii:i[5],trailingAscii:i[6]});return o.leadingAscii&&T("left",n,t)&&(o.leading=o.leadingNonAscii),o.trailingAscii&&T("right",n,t)&&(o.trailing=o.trailingNonAscii),{leading:o.leading,trailing:o.trailing}}(e,n),e}function T(e,n,t){var i,o,a;return"left"===e?(i=n.previousSibling,o=/ $/):(i=n.nextSibling,o=/^ /),i&&(3===i.nodeType?a=o.test(i.nodeValue):t.preformattedCode&&"CODE"===i.nodeName?a=!1:1!==i.nodeType||r(i)||(a=o.test(i.textContent))),a}var C=Array.prototype.reduce,R=[[/\\/g,"\\\\"],[/\*/g,"\\*"],[/^-/g,"\\-"],[/^\+ /g,"\\+ "],[/^(=+)/g,"\\$1"],[/^(#{1,6}) /g,"\\$1 "],[/`/g,"\\`"],[/^~~~/g,"\\~~~"],[/\[/g,"\\["],[/\]/g,"\\]"],[/^>/g,"\\>"],[/_/g,"\\_"],[/^(\d+)\. /g,"$1\\. "]];function k(e){if(!(this instanceof k))return new k(e);this.options=function e(n){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var i in r)r.hasOwnProperty(i)&&(n[i]=r[i])}return n}({},{rules:c,headingStyle:"setext",hr:"* * *",bulletListMarker:"*",codeBlockStyle:"indented",fence:"```",emDelimiter:"_",strongDelimiter:"**",linkStyle:"inlined",linkReferenceStyle:"full",br:"  ",preformattedCode:!1,blankReplacement:function(e,n){return n.isBlock?"\n\n":""},keepReplacement:function(e,n){return n.isBlock?"\n\n"+n.outerHTML+"\n\n":n.outerHTML},defaultReplacement:function(e,n){return n.isBlock?"\n\n"+e+"\n\n":e}},e),this.rules=new f(this.options)}function b(e){var n=this;return C.call(e.childNodes,function(e,t){t=new E(t,n.options);var r="";return 3===t.nodeType?r=t.isCode?t.nodeValue:n.escape(t.nodeValue):1===t.nodeType&&(r=D.call(n,t)),S(e,r)},"")}function O(e){var n=this;return this.rules.forEach(function(t){"function"==typeof t.append&&(e=S(e,t.append(n.options)))}),e.replace(/^[\t\r\n]+/,"").replace(/[\t\r\n\s]+$/,"")}function D(e){var n=this.rules.forNode(e),t=b.call(this,e),r=e.flankingWhitespace;return(r.leading||r.trailing)&&(t=t.trim()),r.leading+n.replacement(t,e,this.options)+r.trailing}function S(e,n){var t,r=function e(n){for(var t=n.length;t>0&&"\n"===n[t-1];)t--;return n.substring(0,t)}(e),i=(t=n).replace(/^\n*/,""),o=Math.max(e.length-r.length,n.length-i.length);return r+"\n\n".substring(0,o)+i}return k.prototype={turndown:function(e){if(n=e,null==n||"string"!=typeof n&&(!n.nodeType||1!==n.nodeType&&9!==n.nodeType&&11!==n.nodeType))throw TypeError(e+" is not a string, or an element/document/fragment node.");if(""===e)return"";var n,t=b.call(this,new y(e,this.options));return O.call(this,t)},use:function(e){if(Array.isArray(e))for(var n=0;n<e.length;n++)this.use(e[n]);else if("function"==typeof e)e(this);else throw TypeError("plugin must be a Function or an Array of Functions");return this},addRule:function(e,n){return this.rules.add(e,n),this},keep:function(e){return this.rules.keep(e),this},remove:function(e){return this.rules.remove(e),this},escape:function(e){return R.reduce(function(e,n){return e.replace(n[0],n[1])},e)}},k});

Puis coller ce code :

{
const answerClass = 'prose';
// Crée une instance de TurndownService
const turndownService = new TurndownService({codeBlockStyle: 'fenced', strongDelimiter: '__'});

// Ajoute une règle pour les blocs de code
turndownService.addRule('codeBlock', {
  filter: 'pre',
  replacement: function (content) {
    const regexTick = /^`|`\n+/gm;
    const _content = content.replace('\n\n','').replace('Copy code\n','').replace(regexTick,'');
    console.log('***', _content);
    return '\n```' + _content + '\n```\n';
  }
});

// Sélectionne toutes les balises <div> qui contiennent la classe
const answerElements = document.querySelectorAll('div.' + answerClass);

// Initialise une chaîne de caractères vide pour stocker les réponses en markdown
let markdown = '';

// Boucle à travers chaque élément de réponse
answerElements.forEach((answerElement) => {
  // Convertit le contenu HTML de l'élément réponse en markdown
  const answerHtml = answerElement.innerHTML.trim();
  const answerMarkdown = turndownService.turndown(answerHtml);
  
  // Ajoute le texte en markdown de l'élément réponse à la chaîne markdown
  markdown += answerMarkdown + '\n\n';
});

// Affiche la chaîne markdown dans la console
console.log(markdown);
}

Il est possible que la classe de la réponse ait changé, il faudra l'adapter.

Version minifiée tout compris
{const answerClass='prose';!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(e="undefined"!=typeof globalThis?globalThis:e||self).TurndownService=n()}(this,function(){"use strict";function e(e,n){return Array(n+1).join(e)}var n,t=["ADDRESS","ARTICLE","ASIDE","AUDIO","BLOCKQUOTE","BODY","CANVAS","CENTER","DD","DIR","DIV","DL","DT","FIELDSET","FIGCAPTION","FIGURE","FOOTER","FORM","FRAMESET","H1","H2","H3","H4","H5","H6","HEADER","HGROUP","HR","HTML","ISINDEX","LI","MAIN","MENU","NAV","NOFRAMES","NOSCRIPT","OL","OUTPUT","P","PRE","SECTION","TABLE","TBODY","TD","TFOOT","TH","THEAD","TR","UL"];function r(e){return a(e,t)}var i=["AREA","BASE","BR","COL","COMMAND","EMBED","HR","IMG","INPUT","KEYGEN","LINK","META","PARAM","SOURCE","TRACK","WBR"];function o(e){return a(e,i)}var l=["A","TABLE","THEAD","TBODY","TFOOT","TH","TD","IFRAME","SCRIPT","AUDIO","VIDEO"];function a(e,n){return n.indexOf(e.nodeName)>=0}function u(e,n){return e.getElementsByTagName&&n.some(function(n){return e.getElementsByTagName(n).length})}var c={};function s(e){return e?e.replace(/(\n+\s*)+/g,"\n"):""}function f(e){for(var n in this.options=e,this._keep=[],this._remove=[],this.blankRule={replacement:e.blankReplacement},this.keepReplacement=e.keepReplacement,this.defaultRule={replacement:e.defaultReplacement},this.array=[],e.rules)this.array.push(e.rules[n])}function d(e,n,t){for(var r=0;r<e.length;r++){var i=e[r];if(p(i,n,t))return i}}function p(e,n,t){var r=e.filter;if("string"==typeof r){if(r===n.nodeName.toLowerCase())return!0}else if(Array.isArray(r)){if(r.indexOf(n.nodeName.toLowerCase())>-1)return!0}else if("function"==typeof r){if(r.call(e,n,t))return!0}else throw TypeError("`filter` needs to be a string, array, or function")}function h(e){var n=e.nextSibling||e.parentNode;return e.parentNode.removeChild(e),n}function g(e,n,t){return e&&e.parentNode===n||t(n)?n.nextSibling||n.parentNode:n.firstChild||n.nextSibling||n.parentNode}c.paragraph={filter:"p",replacement:function(e){return"\n\n"+e+"\n\n"}},c.lineBreak={filter:"br",replacement:function(e,n,t){return t.br+"\n"}},c.heading={filter:["h1","h2","h3","h4","h5","h6"],replacement:function(n,t,r){var i=Number(t.nodeName.charAt(1));if("setext"!==r.headingStyle||!(i<3))return"\n\n"+e("#",i)+" "+n+"\n\n";var o=e(1===i?"=":"-",n.length);return"\n\n"+n+"\n"+o+"\n\n"}},c.blockquote={filter:"blockquote",replacement:function(e){return"\n\n"+(e=(e=e.replace(/^\n+|\n+$/g,"")).replace(/^/gm,"> "))+"\n\n"}},c.list={filter:["ul","ol"],replacement:function(e,n){var t=n.parentNode;return"LI"===t.nodeName&&t.lastElementChild===n?"\n"+e:"\n\n"+e+"\n\n"}},c.listItem={filter:"li",replacement:function(e,n,t){e=e.replace(/^\n+/,"").replace(/\n+$/,"\n").replace(/\n/gm,"\n    ");var r=t.bulletListMarker+"   ",i=n.parentNode;if("OL"===i.nodeName){var o=i.getAttribute("start"),l=Array.prototype.indexOf.call(i.children,n);r=(o?Number(o)+l:l+1)+".  "}return r+e+(n.nextSibling&&!/\n$/.test(e)?"\n":"")}},c.indentedCodeBlock={filter:function(e,n){return"indented"===n.codeBlockStyle&&"PRE"===e.nodeName&&e.firstChild&&"CODE"===e.firstChild.nodeName},replacement:function(e,n,t){return"\n\n    "+n.firstChild.textContent.replace(/\n/g,"\n    ")+"\n\n"}},c.fencedCodeBlock={filter:function(e,n){return"fenced"===n.codeBlockStyle&&"PRE"===e.nodeName&&e.firstChild&&"CODE"===e.firstChild.nodeName},replacement:function(n,t,r){for(var i,o=((t.firstChild.getAttribute("class")||"").match(/language-(\S+)/)||[null,""])[1],l=t.firstChild.textContent,a=r.fence.charAt(0),u=3,c=RegExp("^"+a+"{3,}","gm");i=c.exec(l);)i[0].length>=u&&(u=i[0].length+1);var s=e(a,u);return"\n\n"+s+o+"\n"+l.replace(/\n$/,"")+"\n"+s+"\n\n"}},c.horizontalRule={filter:"hr",replacement:function(e,n,t){return"\n\n"+t.hr+"\n\n"}},c.inlineLink={filter:function(e,n){return"inlined"===n.linkStyle&&"A"===e.nodeName&&e.getAttribute("href")},replacement:function(e,n){var t=n.getAttribute("href"),r=s(n.getAttribute("title"));return r&&(r=' "'+r+'"'),"["+e+"]("+t+r+")"}},c.referenceLink={filter:function(e,n){return"referenced"===n.linkStyle&&"A"===e.nodeName&&e.getAttribute("href")},replacement:function(e,n,t){var r,i,o=n.getAttribute("href"),l=s(n.getAttribute("title"));switch(l&&(l=' "'+l+'"'),t.linkReferenceStyle){case"collapsed":r="["+e+"][]",i="["+e+"]: "+o+l;break;case"shortcut":r="["+e+"]",i="["+e+"]: "+o+l;break;default:var a=this.references.length+1;r="["+e+"]["+a+"]",i="["+a+"]: "+o+l}return this.references.push(i),r},references:[],append:function(e){var n="";return this.references.length&&(n="\n\n"+this.references.join("\n")+"\n\n",this.references=[]),n}},c.emphasis={filter:["em","i"],replacement:function(e,n,t){return e.trim()?t.emDelimiter+e+t.emDelimiter:""}},c.strong={filter:["strong","b"],replacement:function(e,n,t){return e.trim()?t.strongDelimiter+e+t.strongDelimiter:""}},c.code={filter:function(e){var n=e.previousSibling||e.nextSibling,t="PRE"===e.parentNode.nodeName&&!n;return"CODE"===e.nodeName&&!t},replacement:function(e){if(!e)return"";e=e.replace(/\r?\n|\r/g," ");for(var n=/^`|^ .*?[^ ].* $|`$/.test(e)?" ":"",t="`",r=e.match(/`+/gm)||[];-1!==r.indexOf(t);)t+="`";return t+n+e+n+t}},c.image={filter:"img",replacement:function(e,n){var t=s(n.getAttribute("alt")),r=n.getAttribute("src")||"",i=s(n.getAttribute("title"));return r?"!["+t+"]("+r+(i?' "'+i+'"':"")+")":""}},f.prototype={add:function(e,n){this.array.unshift(n)},keep:function(e){this._keep.unshift({filter:e,replacement:this.keepReplacement})},remove:function(e){this._remove.unshift({filter:e,replacement:function(){return""}})},forNode:function(e){var n;return e.isBlank?this.blankRule:(n=d(this.array,e,this.options))||(n=d(this._keep,e,this.options))||(n=d(this._remove,e,this.options))?n:this.defaultRule},forEach:function(e){for(var n=0;n<this.array.length;n++)e(this.array[n],n)}};var m,v="undefined"!=typeof window?window:{},y=!function e(){var n=v.DOMParser,t=!1;try{new n().parseFromString("","text/html")&&(t=!0)}catch(r){}return t}()?(m=function(){},!function e(){var n=!1;try{document.implementation.createHTMLDocument("").open()}catch(t){window.ActiveXObject&&(n=!0)}return n}()?m.prototype.parseFromString=function(e){var n=document.implementation.createHTMLDocument("");return n.open(),n.write(e),n.close(),n}:m.prototype.parseFromString=function(e){var n=new window.ActiveXObject("htmlfile");return n.designMode="on",n.open(),n.write(e),n.close(),n},m):v.DOMParser;function A(e,t){var i;return!function e(n){var t=n.element,r=n.isBlock,i=n.isVoid,o=n.isPre||function(e){return"PRE"===e.nodeName};if(!(!t.firstChild||o(t))){for(var l=null,a=!1,u=null,c=g(u,t,o);c!==t;){if(3===c.nodeType||4===c.nodeType){var s=c.data.replace(/[ \r\n\t]+/g," ");if((!l||/ $/.test(l.data))&&!a&&" "===s[0]&&(s=s.substr(1)),!s){c=h(c);continue}c.data=s,l=c}else if(1===c.nodeType)r(c)||"BR"===c.nodeName?(l&&(l.data=l.data.replace(/ $/,"")),l=null,a=!1):i(c)||o(c)?(l=null,a=!0):l&&(a=!1);else{c=h(c);continue}var f=g(u,c,o);u=c,c=f}l&&(l.data=l.data.replace(/ $/,""),l.data||h(l))}}({element:i="string"==typeof e?(n=n||new y).parseFromString('<x-turndown id="turndown-root">'+e+"</x-turndown>","text/html").getElementById("turndown-root"):e.cloneNode(!0),isBlock:r,isVoid:o,isPre:t.preformattedCode?N:null}),i}function N(e){return"PRE"===e.nodeName||"CODE"===e.nodeName}function E(e,n){var t,c,s,f;return e.isBlock=r(e),e.isCode="CODE"===e.nodeName||e.parentNode.isCode,e.isBlank=!o(t=e)&&!a(c=t,l)&&/^\s*$/i.test(t.textContent)&&!u(s=t,i)&&!u(f=t,l),e.flankingWhitespace=function e(n,t){if(n.isBlock||t.preformattedCode&&n.isCode)return{leading:"",trailing:""};var r,i,o={leading:(i=(r=n.textContent).match(/^(([ \t\r\n]*)(\s*))[\s\S]*?((\s*?)([ \t\r\n]*))$/))[1],leadingAscii:i[2],leadingNonAscii:i[3],trailing:i[4],trailingNonAscii:i[5],trailingAscii:i[6]};return o.leadingAscii&&T("left",n,t)&&(o.leading=o.leadingNonAscii),o.trailingAscii&&T("right",n,t)&&(o.trailing=o.trailingNonAscii),{leading:o.leading,trailing:o.trailing}}(e,n),e}function T(e,n,t){var i,o,l;return"left"===e?(i=n.previousSibling,o=/ $/):(i=n.nextSibling,o=/^ /),i&&(3===i.nodeType?l=o.test(i.nodeValue):t.preformattedCode&&"CODE"===i.nodeName?l=!1:1!==i.nodeType||r(i)||(l=o.test(i.textContent))),l}var C=Array.prototype.reduce,R=[[/\\/g,"\\\\"],[/\*/g,"\\*"],[/^-/g,"\\-"],[/^\+ /g,"\\+ "],[/^(=+)/g,"\\$1"],[/^(#{1,6}) /g,"\\$1 "],[/`/g,"\\`"],[/^~~~/g,"\\~~~"],[/\[/g,"\\["],[/\]/g,"\\]"],[/^>/g,"\\>"],[/_/g,"\\_"],[/^(\d+)\. /g,"$1\\. "]];function k(e){if(!(this instanceof k))return new k(e);this.options=function e(n){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var i in r)r.hasOwnProperty(i)&&(n[i]=r[i])}return n}({},{rules:c,headingStyle:"setext",hr:"* * *",bulletListMarker:"*",codeBlockStyle:"indented",fence:"```",emDelimiter:"_",strongDelimiter:"**",linkStyle:"inlined",linkReferenceStyle:"full",br:"  ",preformattedCode:!1,blankReplacement:function(e,n){return n.isBlock?"\n\n":""},keepReplacement:function(e,n){return n.isBlock?"\n\n"+n.outerHTML+"\n\n":n.outerHTML},defaultReplacement:function(e,n){return n.isBlock?"\n\n"+e+"\n\n":e}},e),this.rules=new f(this.options)}function b(e){var n=this;return C.call(e.childNodes,function(e,t){t=new E(t,n.options);var r="";return 3===t.nodeType?r=t.isCode?t.nodeValue:n.escape(t.nodeValue):1===t.nodeType&&(r=O.call(n,t)),S(e,r)},"")}function D(e){var n=this;return this.rules.forEach(function(t){"function"==typeof t.append&&(e=S(e,t.append(n.options)))}),e.replace(/^[\t\r\n]+/,"").replace(/[\t\r\n\s]+$/,"")}function O(e){var n=this.rules.forNode(e),t=b.call(this,e),r=e.flankingWhitespace;return(r.leading||r.trailing)&&(t=t.trim()),r.leading+n.replacement(t,e,this.options)+r.trailing}function S(e,n){var t,r=function e(n){for(var t=n.length;t>0&&"\n"===n[t-1];)t--;return n.substring(0,t)}(e),i=(t=n).replace(/^\n*/,""),o=Math.max(e.length-r.length,n.length-i.length);return r+"\n\n".substring(0,o)+i}return k.prototype={turndown:function(e){if(null==(n=e)||"string"!=typeof n&&(!n.nodeType||1!==n.nodeType&&9!==n.nodeType&&11!==n.nodeType))throw TypeError(e+" is not a string, or an element/document/fragment node.");if(""===e)return"";var n,t=b.call(this,new A(e,this.options));return D.call(this,t)},use:function(e){if(Array.isArray(e))for(var n=0;n<e.length;n++)this.use(e[n]);else if("function"==typeof e)e(this);else throw TypeError("plugin must be a Function or an Array of Functions");return this},addRule:function(e,n){return this.rules.add(e,n),this},keep:function(e){return this.rules.keep(e),this},remove:function(e){return this.rules.remove(e),this},escape:function(e){return R.reduce(function(e,n){return e.replace(n[0],n[1])},e)}},k});let e=new TurndownService({codeBlockStyle:"fenced",strongDelimiter:"__"});e.addRule("codeBlock",{filter:"pre",replacement:function(e){let n=e.replace("\n\n","").replace("Copy code\n","").replace(/^`|`\n+/gm,"");return console.log("***",n),"\n```"+n+"\n```\n"}});let n=document.querySelectorAll("div."+answerClass),t="";n.forEach(n=>{let r=n.innerHTML.trim(),i=e.turndown(r);t+=i+"\n\n"}),console.log(t)}

Obtenir les request headers avec curl

curl -s -D - -o /dev/null <url>

Source : How to display request headers with command line curl - Stack Overflow

Astuces dans la console de navigateur

Astuces dans la console de navigateur

Lister les aliases dans Mailo

{
  const aliases = Array.from(document.querySelectorAll(".cl_lst_td_elt")).map(el => el.textContent).join('\n');
  console.log(aliases);
}
Astuces dans la console de navigateur

Lister les nouveautés de GitLab-CE

Entrer les lignes suivantes dans la console Javascript du navigateur

{
	const version = document.querySelector("h1").textContent;
	const wishesSections = [
		"top-feature",
		"primary-features",
		"secondary-features",
	];
	const availableData =
		'[data-original-title="Available in GitLab self-managed Free"]';
	const notAvailable =
		'[data-original-title="Not available in GitLab self-managed Free"]';
	const [topFeatures, primaryFeatures, secondaryFeatures] = Array.from(
		document.querySelectorAll(".content > section")
	).filter((el) => wishesSections.includes(el.id));

	const nestedElement = (el, overload, linkEl = "previousElementSibling") => {
		const paths = overload.split(".");
		let result = el.parentNode.parentNode.parentNode;
		const doc =
			result.parentNode.lastElementChild.firstElementChild.firstElementChild
				.href;
		const docLink = doc ? `[_(doc)_](${doc})` : "";
		for (path of paths) {
			result = result[path];
		}
		const link = result[linkEl];
		return [`- [${result.textContent}](${link.href}) ${docLink}`];
	};

	const hideElements = (el, overload, linkEl = false) => {
		const paths = overload.split(".");
		let result = el.parentNode.parentNode.parentNode;
		for (path of paths) {
			result = result[path];
		}
		linkEl && result.previousElementSibling.style.display = "none";
		result.style.display = "none";
	};

	Array.from(topFeatures.querySelectorAll(notAvailable)).forEach((el) =>
		hideElements(el, "parentNode")
	);

	Array.from(primaryFeatures.querySelectorAll(notAvailable)).forEach((el) =>
		hideElements(el, "parentNode.parentNode", true)
	);

	Array.from(secondaryFeatures.querySelectorAll(notAvailable)).forEach((el) =>
		hideElements(el, "parentNode")
	);

	const primaryAvailable = Array.from(
		primaryFeatures.querySelectorAll(availableData)
	).map((el) =>
		nestedElement(
			el,
			"parentNode.parentNode.previousElementSibling.firstElementChild.lastElementChild"
		)
	);

	const secondaryAvailable = Array.from(
		secondaryFeatures.querySelectorAll(availableData)
	).map((el) => nestedElement(el, "previousElementSibling.lastElementChild"));

	const finalResult = []
		.concat(version, primaryAvailable, secondaryAvailable)
		.join("\n");

	console.log(finalResult);

	const copyButton = document.createElement("button");
	const defaultOpacity = "0.4";
	copyButton.style.position = "fixed";
	copyButton.style.margin = "20px";
	copyButton.style.bottom = "0";
	copyButton.style.zIndex = "10";
	copyButton.style.backgroundColor = "teal";
	copyButton.style.color = "wheat";
	copyButton.style.fontSize = "1.5em";
	copyButton.style.fontWeight = "bold";
	copyButton.style.borderRadius = "10px";
	copyButton.style.transition = "all 0.4s 0.1s ease-in";
	copyButton.style.opacity = defaultOpacity;
	copyButton.onmouseover = function () {
		this.style.opacity = "1";
		this.style.boxShadow = "black -3px 2px 6px";
		this.style.transform = "translate(3px, -2px)";
	};
	copyButton.onmouseleave = function () {
		this.style.opacity = defaultOpacity;
		this.style.boxShadow = "unset";
		this.style.transform = "translate(-3px, 2px)";
	};
	copyButton.innerHTML = "Copier la liste<br><em>Community Edition</em>";
	document.body.insertBefore(copyButton, document.body.firstChild);
	const copyFunction = () => {
		navigator.clipboard.writeText(finalResult).then(
			() => {
				console.log("Données copiées dans le presse-papier.");
			},
			(e) => {
				console.error("Les données ne sont pas copiées…", e);
			}
		);
		document.execCommand("copy");
	};
	copyButton.addEventListener("click", copyFunction);
}

Version Bookmarklet

Pour une utilisation régulière, il faut ajouter un marque-page, puis remplacer l'URL par le code suivant :

javascript: const version = document.querySelector("h1").textContent; const wishesSections = [ "top-feature", "primary-features", "secondary-features", ]; const availableData = '[data-original-title="Available in GitLab self-managed Free"]'; const notAvailable = '[data-original-title="Not available in GitLab self-managed Free"]'; const [topFeatures, primaryFeatures, secondaryFeatures] = Array.from( document.querySelectorAll(".content > section") ).filter((el) => wishesSections.includes(el.id)); const nestedElement = (el, overload, linkEl = "previousElementSibling") => { const paths = overload.split("."); let result = el.parentNode.parentNode.parentNode; const doc = result.parentNode.lastElementChild.firstElementChild.firstElementChild.href; const docLink = doc ? `[_(doc)_](${doc})` : ""; for (path of paths) { result = result[path]; } const link = result[linkEl]; return [`- [${result.textContent}](${link.href}) ${docLink}`]; }; const hideElements = (el, overload, linkEl = false) => { const paths = overload.split("."); let result = el.parentNode.parentNode.parentNode; for (path of paths) { result = result[path]; } if (linkEl) {result.previousElementSibling.style.display = "none"}; result.style.display = "none"; }; Array.from(topFeatures.querySelectorAll(notAvailable)).forEach((el) => hideElements(el, "parentNode") ); Array.from(primaryFeatures.querySelectorAll(notAvailable)).forEach((el) => hideElements(el, "parentNode.parentNode", true) ); Array.from(secondaryFeatures.querySelectorAll(notAvailable)).forEach((el) => hideElements(el, "parentNode") ); const primaryAvailable = Array.from( primaryFeatures.querySelectorAll(availableData) ).map((el) => nestedElement( el, "parentNode.parentNode.previousElementSibling.firstElementChild.lastElementChild" ) ); const secondaryAvailable = Array.from( secondaryFeatures.querySelectorAll(availableData) ).map((el) => nestedElement(el, "previousElementSibling.lastElementChild")); const finalResult = [] .concat(version, primaryAvailable, secondaryAvailable) .join("\n"); console.log(finalResult); const copyButton = document.createElement("button"); const defaultOpacity = "0.4"; copyButton.style.position = "fixed"; copyButton.style.margin = "20px"; copyButton.style.bottom = "0"; copyButton.style.zIndex = "10"; copyButton.style.backgroundColor = "teal"; copyButton.style.color = "wheat"; copyButton.style.fontSize = "1.5em"; copyButton.style.fontWeight = "bold"; copyButton.style.borderRadius = "10px"; copyButton.style.transition = "all 0.4s 0.1s ease-in"; copyButton.style.opacity = defaultOpacity; copyButton.onmouseover = function () { this.style.opacity = "1"; this.style.boxShadow = "black -3px 2px 6px"; this.style.transform = "translate(3px, -2px)"; }; copyButton.onmouseleave = function () { this.style.opacity = defaultOpacity; this.style.boxShadow = "unset"; this.style.transform = "translate(-3px, 2px)"; }; copyButton.innerHTML = "Copier la liste<br><em>Community Edition</em>"; document.body.insertBefore(copyButton, document.body.firstChild); const copyFunction = () => { navigator.clipboard.writeText(finalResult).then( () => { console.log("Donn%C3%A9es copi%C3%A9es dans le presse-papier."); }, (e) => { console.error("Les donn%C3%A9es ne sont pas copi%C3%A9es%E2%80%A6", e); } ); document.execCommand("copy"); }; copyButton.addEventListener("click", copyFunction);

Ensuite, le fait de cliquer sur le marque-page activera le script.
En ajoutant comme seul mot-clé : bm_gitlab, cela me permet d'entrer ce mot-clé lorsque je suis sur la page de release de GitLab pour lancer directement le script.

Résultat

Exemple avec la page GitLab 16.0 released.

Les éléments ne correspondant pas à Self-Managed Free sont masqués sur la page.

Un bouton apparaît permettant de copier la liste suivante dans le presse-papier :

GitLab 16.0 Release

Astuces dans la console de navigateur

Lister les mises à jour de WordPress

Entrer les lignes suivantes dans la console Javascript du navigateur

{
  const names={plugins: "Extensions", themes: "Thèmes", translations: "Traductions"};
  let result="";
  
  const getUpgrades = (name) => {
    const elements = Array.from(document.querySelectorAll(`[name=\"upgrade-${name}\"] .plugin-title > p > strong`));
    if (!elements.length) {
    return "";
    };
    const textContent = elements.map(el => `- ${el.textContent}`).join('\n');
    return `${names[name]} :\n${textContent}\n`;
  };
  
  for (name in names) {
    result = result.concat(getUpgrades(name));
  };
  console.log(result);
  
  const copyButton = document.createElement("button");
	const defaultOpacity = "0.4";
	copyButton.style.position = "fixed";
	copyButton.style.margin = "20px";
	copyButton.style.bottom = "0";
	copyButton.style.zIndex = "10";
	copyButton.style.backgroundColor = "teal";
	copyButton.style.color = "wheat";
	copyButton.style.fontSize = "1.5em";
	copyButton.style.fontWeight = "bold";
	copyButton.style.borderRadius = "10px";
	copyButton.style.transition = "all 0.4s 0.1s ease-in";
	copyButton.style.opacity = defaultOpacity;
	copyButton.onmouseover = function () {
		this.style.opacity = "1";
		this.style.boxShadow = "black -3px 2px 6px";
		this.style.transform = "translate(3px, -2px)";
	};
	copyButton.onmouseleave = function () {
		this.style.opacity = defaultOpacity;
		this.style.boxShadow = "unset";
		this.style.transform = "translate(-3px, 2px)";
	};
	copyButton.innerHTML = "Copier la liste";
	document.body.insertBefore(copyButton, document.body.firstChild);
	const copyFunction = () => {
		navigator.clipboard.writeText(result).then(
			() => {
				console.log("Données copiées dans le presse-papier.");
			},
			(e) => {
				console.error("Les données ne sont pas copiées…", e);
			}
		);
	};
	copyButton.addEventListener("click", copyFunction);
}

Version Bookmarklet

Pour une utilisation régulière, il faut ajouter un marque-page, puis remplacer l'URL par le code suivant :

javascript: const names={plugins: "Extensions", themes: "Thèmes", translations: "Traductions"}; let result=""; const getUpgrades = (name) => { const elements = Array.from(document.querySelectorAll(`[name=\"upgrade-${name}\"] .plugin-title > p > strong`));if (!elements.length) {return "";};const textContent = elements.map(el => `- ${el.textContent}`).join('\n');return `${names[name]} :\n${textContent}\n`;};for (name in names) {result = result.concat(getUpgrades(name));};console.log(result);const copyButton = document.createElement("button");const defaultOpacity = "0.4";copyButton.style.position = "fixed";copyButton.style.margin = "20px";copyButton.style.bottom = "0";copyButton.style.zIndex = "10";copyButton.style.backgroundColor = "teal";copyButton.style.color = "wheat";copyButton.style.fontSize = "1.5em";copyButton.style.fontWeight = "bold";copyButton.style.borderRadius = "10px";copyButton.style.transition = "all 0.4s 0.1s ease-in";copyButton.style.opacity = defaultOpacity;copyButton.onmouseover = function () {this.style.opacity = "1";this.style.boxShadow = "black -3px 2px 6px";this.style.transform = "translate(3px, -2px)";};copyButton.onmouseleave = function () {this.style.opacity = defaultOpacity;this.style.boxShadow = "unset";this.style.transform = "translate(-3px, 2px)";};copyButton.innerHTML = "Copier la liste";document.body.insertBefore(copyButton, document.body.firstChild);const copyFunction = () => {navigator.clipboard.writeText(result).then(() => {console.log("Données copiées dans le presse-papier.");},(e) => {console.error("Les données ne sont pas copiées…", e);});};copyButton.addEventListener("click", copyFunction);

Ensuite, le fait de cliquer sur le marque-page activera le script.
En ajoutant comme seul mot-clé : bm_wp, cela me permet d'entrer ce mot-clé lorsque je suis sur la page de mise à jour de WordPress pour lancer directement le script.

Astuces dans la console de navigateur

Exporter des données du DOM dans un fichier .csv

{
  let type = "text/csv;charset=utf-8"
  const rows = Array.from(document.getElementsByTagName('tr')).map(el => `${el.children[0].textContent},${el.children[1].textContent}`).join('\n');

  const blob = new Blob([rows], {type: type});
  const blobUrl = URL.createObjectURL(blob);

  window.open(blobUrl);
}

À adapter évidemment suivant les éléments à sélectionner dans la variable rows.

Astuces dans la console de navigateur

Yt-dlp dans France.tv

En construction.png

{
  const maxWidth = 1000;
  const shebang = "#!/bin/sh\n";
  const createTmpFile = "tempFile=$(mktemp)\n";
  const autoClean = '\n\nwhile read line; do\nsed -i '' -e "${line}s/^/#/" script.sh\ndone < "${tempFile}"';
  class Video {
    constructor(video) {
      const getElContent = (parent, selector) => parent.querySelector(selector).textContent.trim()
      const title = getElContent(video, '.c-card-16x9__title');
      const subtitle = getElContent(video, '.c-card-16x9__subtitle');
      this.title = `${title} - ${subtitle}`;
      this.link = video.firstChild.href;
    }
    dlp() {
      const cli = `[ ! -e "${this.title}" ] && yt-dlp -w -f "b[width<${maxWidth}]/bv[width<${maxWidth}]+ba" -o "${this.title}.%(ext)s" ${this.link}  && grep -nF "${this.title}" script.sh | awk -F ':' '{print $1;}' >> "$tempFile"`
      return cli;
    }
  }
  const videos = Array.from(document.querySelectorAll(".c-wall__item")).map((video) => (new Video(video)).dlp()).sort().filter((el,i,a) => i===a.indexOf(el)).join('\n');
  const result = shebang.concat(createTmpFile, videos, autoClean);
  
  console.log(result);
}
Astuces dans la console de navigateur

Supprimer plusieurs tickets d'un coup sur GitLab

But

Avoir des cases à cocher pour sélectionner les tickets que l'on souhaite supprimer.

À ce jour il n'est pas possible de les supprimer en série avec le Bulk edit.

Script

Entrer dans la console des outils de développement le script suivant :

{
	const deleteIssue = async (projectId, issueId) => {
		fetch(
			`https://<GITLAB_URL>/api/v4/projects/${projectId}/issues/${issueId}`,
			{
				method: "DELETE",
				headers: {
					"PRIVATE-TOKEN": "<PRIVATE_TOKEN>",
				},
			}
		);
	};
	const issuesLi = Array.from(document.querySelectorAll("ul.issues-list > li"));
	const issuesNb = Array.from(
		document.getElementsByClassName("issuable-reference")
	).map((el) => parseInt(el.innerText.trim().slice(1)));
	const projectId = document.body.dataset.projectId;

	console.log("Project ID:", projectId);

	issuesLi.forEach((li, id) => {
		const checkbox = document.createElement("input");
		checkbox.type = "checkbox";
		checkbox.className = "delete";
		checkbox.style.marginRight = "1em";
		checkbox.value = issuesNb[id];
		li.insertBefore(checkbox, li.firstChild);
	});

	const deleteButton = document.createElement("button");
	deleteButton.style.position = "fixed";
	deleteButton.style.margin = "20px";
	deleteButton.style.bottom = "20px";
	deleteButton.style.zIndex = "1000";
	deleteButton.style.backgroundColor = "darkred";
	deleteButton.style.color = "wheat";
	deleteButton.style.fontSize = "1.5em";
	deleteButton.style.fontWeight = "bold";
	deleteButton.style.borderRadius = "10px";
	deleteButton.style.transition = "all 0.4s 0.1s ease-in";
	deleteButton.onmouseover = function () {
		this.style.boxShadow = "black -3px 2px 6px";
		this.style.transform = "translate(3px, -2px)";
	};
	deleteButton.onmouseleave = function () {
		this.style.boxShadow = "unset";
		this.style.transform = "translate(-3px, 2px)";
	};
	deleteButton.innerHTML = "Supprimer les tickets";
	document.body.insertBefore(deleteButton, document.body.firstChild);

	const deleteFunction = () => {
		const selectedCheckboxes = document.querySelectorAll(
			"input:checked.delete"
		);
		selectedCheckboxes.forEach((el) => deleteIssue(projectId, el.value));
	};

	deleteButton.addEventListener("click", deleteFunction);
}

TODO

Ajouter le rechargement automatique à la fin de la suppression…

Adapter les valeurs :

Utilisation

Attention : Il n'y a pas de confirmation avant la suppression.

Il est possible d'en faire un bookmarklet en supprimant tous les retours à la ligne, ajouter javascript: au départ puis coller tout ça dans un lien de marque-page du navigateur.

Obtenir l'URL pour l'abonnement d'agendas et de contacts iCloud

En gros, il faut aller sur icloud.com, se connecter à son compte, obtenir l'URL appelé quand on clique sur un nom d'agenda ou lorsqu'on rafraîchit la page de contacts. Il faut copier l'URL de la requête XHR.

Ensuite, utliser les scripts suivants (zsh sur MacOS)…

Agendas

read URL"?XHR URL ? " ; \
iCloud_SER=$(echo "$URL" | ggrep -Po '(?<=https:\/\/).*(?=-calendarws\.icloud\.com)') ; \
iCloud_CAL=$(echo "$URL" | ggrep -Po '(?<=ca\/collections\/).*(?=\?)') ; \
iCloud_ID=$(echo "$URL" | ggrep -Po '(?<=&dsid\=)\d*(?=&?)') ; \
echo "\n\nhttps://$iCloud_SER-caldav.icloud.com/$iCloud_ID/calendars/$iCloud_CAL/" ; \
unset URL iCloud_SER iCloud_CAL iCloud_ID

Source : Thunderbird iCloud calendar sync • my2cents

Contacts

read URL"?XHR URL ? " ; \
iCloud_SER=$(echo "$URL" | ggrep -Po '(?<=https:\/\/).*(?=-contactsws\.icloud\.com)') ; \
iCloud_ID=$(echo "$URL" | ggrep -Po '(?<=&dsid\=)\d*(?=&?)') ; \
echo "\n\nhttps://$iCloud_SER-contacts.icloud.com/$iCloud_ID/carddavhome/card/" ; \
unset URL iCloud_SER iCloud_ID

Claviers US

Source : British and American keyboards - Wikipedia.

United States keyboard layout

KB_United_States.png

US keyboard layout (Linux)

LinuxUSKeyboard.png

United States version of Apple keyboard

KB_United_States_Mac_-Apple_Keyboard(MC184LL).png