%!TEX pdflatex
\documentclass[a4paper]{article}
\usepackage[margin=1cm]{geometry}
\usepackage{tikz}
\setlength\parindent{0pt}

\definecolor{llsnivbleu}{HTML}{b9d4ef}
\definecolor{llsnivvert}{HTML}{68b652}
\definecolor{llsnivorange}{HTML}{f29228}
\definecolor{llsnivrouge}{HTML}{da360a}

\ExplSyntaxOn
% variables et clés
\int_new:N   \l_llsniv_niveau_int
\fp_new:N    \l_llsniv_rescale_fp
\fp_const:Nn \c_llsniv_compensation_fp { 1 / 1.05 }
\tl_new:N    \l_llsniv_hauteur_tl
\tl_new:N    \l_llsniv_couleur_tl
\tl_new:N    \l_llsniv_strut_tl
\tl_new:N    \l_llsniv_dstrut_tl
\dim_new:N   \l_llsniv_profondeur_dim
\dim_new:N   \l_llsniv_baseline_dim
\dim_new:N   \l_llsniv_height_dim

\tikzset{llsnivdiff~bordure/.style={line~width=0.05\l_llsniv_height_dim}}
\tikzset{llsnivdiff~barre/.style={line~width=0.1\l_llsniv_height_dim,llsnivbleu}}

\keys_define:nn { llsniv }
{
  niveau  .int_set:N = \l_llsniv_niveau_int,
  niveau  .initial:n = 1,
  strut   .tl_set:N = \l_llsniv_strut_tl,
  strut   .initial:n = M,
  dstrut  .tl_set:N = \l_llsniv_dstrut_tl,
  dstrut  .initial:n = (qM),
  hauteur .tl_set:N  = \l_llsniv_hauteur_tl,
  hauteur .initial:n = dauto,
  rescale .fp_set:N  = \l_llsniv_rescale_fp,
  rescale .initial:n = 1,
}

% couleur associée à un niveau : 1 = vert, 2 = orange, 3 = rouge
\cs_new_protected:Nn \llsniv_couleur:n
{
  \tl_set:Nx \l_llsniv_couleur_tl
  {
    \int_case:nn { #1 }
    {
      { 1 } { llsnivvert   }
      { 2 } { llsnivorange }
      { 3 } { llsnivrouge  }
    }
  }
}

% calcule hauteur/profondeur
\cs_new_protected:Nn \llsniv_mesures:
{
  \tl_if_eq:NnTF \l_llsniv_hauteur_tl { auto }
  {
    \hbox_set:Nn \l_tmpa_box { \l_llsniv_strut_tl }
    \dim_set:Nn \l_llsniv_profondeur_dim { 0pt }
    \dim_set:Nn \l_llsniv_height_dim { \box_ht:N \l_tmpa_box }
  }
  {
    \tl_if_eq:NnTF \l_llsniv_hauteur_tl { dauto }
      {
        \hbox_set:Nn \l_tmpa_box { \l_llsniv_dstrut_tl }
        \dim_set:Nn \l_llsniv_profondeur_dim { \box_dp:N \l_tmpa_box }
        \dim_set:Nn \l_llsniv_height_dim
          { \box_ht:N \l_tmpa_box + \box_dp:N \l_tmpa_box }
      }
      {
        \dim_set:Nn \l_llsniv_height_dim { \l_llsniv_hauteur_tl }
        \dim_set:Nn \l_llsniv_profondeur_dim { 0pt }
      }
  }
  \dim_set:Nn \l_llsniv_baseline_dim
    { \l_llsniv_profondeur_dim - 0.5\l_llsniv_height_dim }
  \dim_set:Nn \l_llsniv_height_dim
    {
      \fp_to_decimal:n { \l_llsniv_rescale_fp * \c_llsniv_compensation_fp }
      \l_llsniv_height_dim
    }
}

% dessine le disque "niveau atteint" n°i (i = 1, 2, 3 -> x = 0, 2.75, 5.5)
\cs_new_protected:Nn \llsniv_cercle:n
{
  \draw[llsnivdiff~bordure, draw=\l_llsniv_couleur_tl, fill=white]
    ( { (#1-1)*2.5 } , 0 ) circle[radius=1] ;
  \fill[\l_llsniv_couleur_tl]
    ( { (#1-1)*2.5 } , 0 ) circle[radius=0.85] ;
}

% \llsniveaux[hauteur=auto|<dim>]<tikz keys>{niveau}
\NewDocumentCommand \llsniveaux { O { } D < > { } m }
{
  \group_begin:
  \keys_set:nn { llsniv } { niveau = #3, #1 }
  \llsniv_mesures:
  \llsniv_couleur:n { \l_llsniv_niveau_int }
  \begin{tikzpicture}[x=0.5\l_llsniv_height_dim, y=0.5\l_llsniv_height_dim, baseline={(0,\dim_use:N \l_llsniv_baseline_dim)}, #2]
    \useasboundingbox (-1.05,-1) rectangle (6.05,1);
    \draw[llsnivdiff~barre] (0,0)--(5,0);
    \fill[lightgray] (0,0)    circle[radius=0.85]
                     (2.5,0) circle[radius=0.85]
                     (5,0)  circle[radius=0.85] ;
    \int_step_function:nnN { 1 } { \l_llsniv_niveau_int } \llsniv_cercle:n
  \end{tikzpicture}
  \group_end:
}
\ExplSyntaxOff

\begin{document}

Hauteur dauto (avec jambage), dans le texte courant : (q\llsniveaux{1}M) -- (q\llsniveaux{2}M) -- (q\llsniveaux{3}M).

Hauteur auto (sans jambage), dans le texte courant : (q\llsniveaux[hauteur=auto]{1}M) -- (q\llsniveaux[hauteur=auto]{2}M) -- (q\llsniveaux[hauteur=auto]{3}M).

\bigskip
{\Huge Dans une grande police : (q\llsniveaux{2}M)}

\bigskip

{\Huge Dans une grande police : (q\llsniveaux[rescale=0.75]{3}M)}

\bigskip
\textsf{Exercice n°1 {\footnotesize [RAISONNER] \llsniveaux[hauteur=dauto,dstrut={[]}]{2}} }

\bigskip
Hauteur fixée \llsniveaux[hauteur=2cm]<rotate=30>{2}

\end{document}