% Author..........: C. Pierquet % licence.........: Released under the LaTeX Project Public License v1.3c or later, see http://www.latex-project.org/lppl.txt \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{customenvs-exams}[2025/08/04 0.1.1 customenvs for exam documents] %====HISTORY % v 0.1.1 Bugfix + BlocExo % v 0.1.0 Initial version subpackage (exam) of customenvs %====OPTION \newif\if@pictos\@pictosfalse% \DeclareOption{pictos}{\@pictostrue}% \DeclareOption*{} \ProcessOptions\relax %====PACKAGES \RequirePackage{tcolorbox} \RequirePackage{varwidth} \RequirePackage{xintexpr} \RequirePackage{tabularray} \RequirePackage{calc} \RequirePackage{pgf} \RequirePackage{simplekv} \RequirePackage{xstring} \RequirePackage{listofitems} \RequirePackage{randomlist} \if@pictos \RequirePackage{customenvs-tikzpictos} \fi \tcbuselibrary{skins,breakable} %====INT MACRO \newlength\cetmpheigheststring \newlength\cetmpheigheststringelt \newsavebox{\my@cetmp@height@box} \NewDocumentCommand\cegetheigheststring{ s O{\cetmpheigheststring} m }{% \ifdeflength{#2}{}{\newlength#2}% \setlength#2{0pt}% \IfBooleanTF{#1}% {% \xintFor* ##1 in {\xintCSVtoList{#3}}\do{% \savebox{\my@cetmp@height@box}{##1}% \settoheight{\cetmpheigheststringelt}{\usebox{\my@cetmp@height@box}}% \pgfmathsetlength{\global#2}{max(#2,\cetmpheigheststringelt)}% }% }% {% \xintFor* ##1 in {\xintCSVtoList{#3}}\do{% \savebox{\my@cetmp@height@box}{##1}% \settototalheight{\cetmpheigheststringelt}{\usebox{\my@cetmp@height@box}}% \pgfmathsetlength{\global#2}{max(#2,\cetmpheigheststringelt)}% }% }% } %====EXAM QCM \NewList{TmpListereponsesexamqcm} \def\ReponsesExamQCMbox{\raisebox{-0.2ex}{\faSquare[regular]}} %avec fontawesome567, à charger... \defKV[reponsesexamqcm]{% NbCols=\def\RepExamQCMNbCol{#1},% PoliceLabels=\def\RepExamQCMFonte{#1},% EspacesCL=\def\RepExamQCMOffset{#1},% Labels=\def\RepExamQCMTypeLabel{#1},% EspaceLabels=\def\RepExamQCMSpace{#1},% Largeur=\def\RepExamQCMLarg{#1} } \setKVdefault[reponsesexamqcm]{% EspacesCL={6pt/2pt},% NbCols=4,% Filets=false,% PoliceLabels={\bfseries},% Labels={a.},% EspaceLabels=\kern5pt,% Swap=false,% Largeur=0.99\linewidth,% Melange=false,% HtAuto=false } \NewDocumentCommand\QCMExamFormatteLabel{ m m }{%1=typelabel,%3=caractère \IfSubStr{#1}{a}% {% {\RepExamQCMFonte\StrSubstitute{#1}{a}{#2}}% }% {}% \IfSubStr{#1}{A}% {% {\RepExamQCMFonte\StrSubstitute{#1}{A}{#2}}% }% {}% \IfSubStr{#1}{1}% {% {\RepExamQCMFonte\StrSubstitute{#1}{1}{#2}}% }% {}% } \NewDocumentCommand\ExamReponsesQCM{ O{} m D<>{} }{%1=nbcol,2=listeréponses,3=options tblr \restoreKV[reponsesexamqcm]% \setKV[reponsesexamqcm]{#1}% \IfSubStr{\RepExamQCMOffset}{/}% {\StrCut{\RepExamQCMOffset}{/}{\RepExamQCMOffsetCol}{\RepExamQCMOffsetLgn}}% {\def\RepExamQCMOffsetCol{\RepExamQCMOffset}\def\RepExamQCMOffsetLgn{\RepExamQCMOffset}}% \setsepchar{,}% \readlist*\ExamQCMListereponses{#2}% \def\ExamQCMNbRep{\ExamQCMListereponseslen}% %les items créés \IfStrEq{\RepExamQCMTypeLabel}{box}% {% \def\RepExamQCMLabelA{\ReponsesExamQCMbox\RepExamQCMSpace}% \def\RepExamQCMLabelB{\ReponsesExamQCMbox\RepExamQCMSpace}% \def\RepExamQCMLabelC{\ReponsesExamQCMbox\RepExamQCMSpace}% \def\RepExamQCMLabelD{\ReponsesExamQCMbox\RepExamQCMSpace}% }% {% \IfSubStr{\RepExamQCMTypeLabel}{a}% {% \def\RepExamQCMLabelA{\QCMExamFormatteLabel{\RepExamQCMTypeLabel}{a}\RepExamQCMSpace}% \def\RepExamQCMLabelB{\QCMExamFormatteLabel{\RepExamQCMTypeLabel}{b}\RepExamQCMSpace}% \def\RepExamQCMLabelC{\QCMExamFormatteLabel{\RepExamQCMTypeLabel}{c}\RepExamQCMSpace}% \def\RepExamQCMLabelD{\QCMExamFormatteLabel{\RepExamQCMTypeLabel}{d}\RepExamQCMSpace}% }{}% \IfSubStr{\RepExamQCMTypeLabel}{A}% {% \def\RepExamQCMLabelA{\QCMExamFormatteLabel{\RepExamQCMTypeLabel}{A}\RepExamQCMSpace}% \def\RepExamQCMLabelB{\QCMExamFormatteLabel{\RepExamQCMTypeLabel}{B}\RepExamQCMSpace}% \def\RepExamQCMLabelC{\QCMExamFormatteLabel{\RepExamQCMTypeLabel}{C}\RepExamQCMSpace}% \def\RepExamQCMLabelD{\QCMExamFormatteLabel{\RepExamQCMTypeLabel}{D}\RepExamQCMSpace}% }{}% \IfSubStr{\RepExamQCMTypeLabel}{1}% {% \def\RepExamQCMLabelA{\QCMExamFormatteLabel{\RepExamQCMTypeLabel}{1}\RepExamQCMSpace}% \def\RepExamQCMLabelB{\QCMExamFormatteLabel{\RepExamQCMTypeLabel}{2}\RepExamQCMSpace}% \def\RepExamQCMLabelC{\QCMExamFormatteLabel{\RepExamQCMTypeLabel}{3}\RepExamQCMSpace}% \def\RepExamQCMLabelD{\QCMExamFormatteLabel{\RepExamQCMTypeLabel}{4}\RepExamQCMSpace}% }{}% \IfStrEq{\RepExamQCMTypeLabel}{null}% {% \def\RepExamQCMLabelA{}% \def\RepExamQCMLabelB{}% \def\RepExamQCMLabelC{}% \def\RepExamQCMLabelD{}% }% {}% }% %en fonction du nb de colonnes et du shuffle \ifboolKV[reponsesexamqcm]{Melange}% {% \ClearList{TmpListereponsesexamqcm}% \IfEq{\ExamQCMNbRep}{2}%2réponses {% \InsertRandomItem{TmpListereponsesexamqcm}{\ExamQCMListereponses[1]}% \InsertRandomItem{TmpListereponsesexamqcm}{\ExamQCMListereponses[2]}% \ifboolKV[reponsesexamqcm]{Filets}% {\begin{tblr}{rowsep=\RepExamQCMOffsetLgn,colsep=\RepExamQCMOffsetCol,hlines,vlines,width=\RepExamQCMLarg,colspec={*{2}{X[b,l]}},#3}}% {\begin{tblr}{rowsep=\RepExamQCMOffsetLgn,colsep=\RepExamQCMOffsetCol,width=\RepExamQCMLarg,colspec={*{2}{X[b,l]}},#3}}% \RepExamQCMLabelA\TmpListereponsesexamqcm[0] & \RepExamQCMLabelB\TmpListereponsesexamqcm[1] \\ \end{tblr}% }% {}% \IfEq{\ExamQCMNbRep}{3}%3réponses {% \InsertRandomItem{TmpListereponsesexamqcm}{\ExamQCMListereponses[1]}% \InsertRandomItem{TmpListereponsesexamqcm}{\ExamQCMListereponses[2]}% \InsertRandomItem{TmpListereponsesexamqcm}{\ExamQCMListereponses[3]}% \ifboolKV[reponsesexamqcm]{Filets}% {\begin{tblr}{rowsep=\RepExamQCMOffsetLgn,colsep=\RepExamQCMOffsetCol,hlines,vlines,width=\RepExamQCMLarg,colspec={*{3}{X[b,l]}},#3}}% {\begin{tblr}{rowsep=\RepExamQCMOffsetLgn,colsep=\RepExamQCMOffsetCol,width=\RepExamQCMLarg,colspec={*{3}{X[b,l]}},#3}}% \RepExamQCMLabelA\TmpListereponsesexamqcm[0] & \RepExamQCMLabelB\TmpListereponsesexamqcm[1] & \RepExamQCMLabelC\TmpListereponsesexamqcm[2] \\ \end{tblr}% }% {}% \IfEq{\ExamQCMNbRep}{4}%4réponses {% \InsertRandomItem{TmpListereponsesexamqcm}{\ExamQCMListereponses[1]}% \InsertRandomItem{TmpListereponsesexamqcm}{\ExamQCMListereponses[2]}% \InsertRandomItem{TmpListereponsesexamqcm}{\ExamQCMListereponses[3]}% \InsertRandomItem{TmpListereponsesexamqcm}{\ExamQCMListereponses[4]}% \IfEq{\RepExamQCMNbCol}{4}%4colonnes {% \ifboolKV[reponsesexamqcm]{Filets}% {\begin{tblr}{rowsep=\RepExamQCMOffsetLgn,colsep=\RepExamQCMOffsetCol,hlines,vlines,width=\RepExamQCMLarg,colspec={*{4}{X[b,l]}},#3}}% {\begin{tblr}{rowsep=\RepExamQCMOffsetLgn,colsep=\RepExamQCMOffsetCol,width=\RepExamQCMLarg,colspec={*{4}{X[b,l]}},#3}}% \RepExamQCMLabelA\TmpListereponsesexamqcm[0] & \RepExamQCMLabelB\TmpListereponsesexamqcm[1] & \RepExamQCMLabelC\TmpListereponsesexamqcm[2] & \RepExamQCMLabelD\TmpListereponsesexamqcm[3] \\ \end{tblr}% }% {} \IfEq{\RepExamQCMNbCol}{2}%2colonnes% {% \ifboolKV[reponsesexamqcm]{HtAuto}% {% \cegetheigheststring{#2}% \ifboolKV[reponsesexamqcm]{Filets}% {\begin{tblr}{rowsep=\RepExamQCMOffsetLgn,colsep=\RepExamQCMOffsetCol,hlines,vlines,width=\RepExamQCMLarg,colspec={*{2}{X[b,l]}},rows={ht=\cetmpheigheststring},#3}}% {\begin{tblr}{rowsep=\RepExamQCMOffsetLgn,colsep=\RepExamQCMOffsetCol,width=\RepExamQCMLarg,colspec={*{2}{X[b,l]}},rows={ht=\cetmpheigheststring},#3}}% \RepExamQCMLabelA\TmpListereponsesexamqcm[0] & \ifboolKV[reponsesexamqcm]{Swap}{\RepExamQCMLabelB\TmpListereponsesexamqcm[1]}{\RepExamQCMLabelC\TmpListereponsesexamqcm[1]} \\ \ifboolKV[reponsesexamqcm]{Swap}{\RepExamQCMLabelC\TmpListereponsesexamqcm[2]}{\RepExamQCMLabelB\TmpListereponsesexamqcm[2]} & \RepExamQCMLabelD\TmpListereponsesexamqcm[3] \\ \end{tblr}% }% {% \ifboolKV[reponsesexamqcm]{Filets}% {\begin{tblr}{rowsep=\RepExamQCMOffsetLgn,colsep=\RepExamQCMOffsetCol,hlines,vlines,width=\RepExamQCMLarg,colspec={*{2}{X[b,l]}},#3}}% {\begin{tblr}{rowsep=\RepExamQCMOffsetLgn,colsep=\RepExamQCMOffsetCol,width=\RepExamQCMLarg,colspec={*{2}{X[b,l]}},#3}}% \RepExamQCMLabelA\TmpListereponsesexamqcm[0] & \ifboolKV[reponsesexamqcm]{Swap}{\RepExamQCMLabelB\TmpListereponsesexamqcm[1]}{\RepExamQCMLabelC\TmpListereponsesexamqcm[1]} \\ \ifboolKV[reponsesexamqcm]{Swap}{\RepExamQCMLabelC\TmpListereponsesexamqcm[2]}{\RepExamQCMLabelB\TmpListereponsesexamqcm[2]} & \RepExamQCMLabelD\TmpListereponsesexamqcm[3] \\ \end{tblr}% }% }% {}% \IfEq{\RepExamQCMNbCol}{1}%1colonne% {% %test hauteur \ifboolKV[reponsesexamqcm]{HtAuto}% {% \cegetheigheststring{#2}% \ifboolKV[reponsesexamqcm]{Filets}% {\begin{tblr}{rowsep=\RepExamQCMOffsetLgn,colsep=\RepExamQCMOffsetCol,hlines,vlines,width=\RepExamQCMLarg,colspec={*{1}{X[b,l]}},rows={ht=\cetmpheigheststring},#3}}% {\begin{tblr}{rowsep=\RepExamQCMOffsetLgn,colsep=\RepExamQCMOffsetCol,width=\RepExamQCMLarg,colspec={*{1}{X[b,l]}},rows={ht=\cetmpheigheststring},#3}}% \RepExamQCMLabelA\TmpListereponsesexamqcm[0] \\ \ifboolKV[reponsesexamqcm]{Swap}{\RepExamQCMLabelB\TmpListereponsesexamqcm[1]}{\RepExamQCMLabelC\TmpListereponsesexamqcm[1]} \\ \ifboolKV[reponsesexamqcm]{Swap}{\RepExamQCMLabelC\TmpListereponsesexamqcm[2]}{\RepExamQCMLabelB\TmpListereponsesexamqcm[2]} \\ \RepExamQCMLabelD\TmpListereponsesexamqcm[3] \\ \end{tblr}% }% {% \ifboolKV[reponsesexamqcm]{Filets}% {\begin{tblr}{rowsep=\RepExamQCMOffsetLgn,colsep=\RepExamQCMOffsetCol,hlines,vlines,width=\RepExamQCMLarg,colspec={*{1}{X[b,l]}},#3}}% {\begin{tblr}{rowsep=\RepExamQCMOffsetLgn,colsep=\RepExamQCMOffsetCol,width=\RepExamQCMLarg,colspec={*{1}{X[b,l]}},#3}}% \RepExamQCMLabelA\TmpListereponsesexamqcm[0] \\ \ifboolKV[reponsesexamqcm]{Swap}{\RepExamQCMLabelB\TmpListereponsesexamqcm[1]}{\RepExamQCMLabelC\TmpListereponsesexamqcm[1]} \\ \ifboolKV[reponsesexamqcm]{Swap}{\RepExamQCMLabelC\TmpListereponsesexamqcm[2]}{\RepExamQCMLabelB\TmpListereponsesexamqcm[2]} \\ \RepExamQCMLabelD\TmpListereponsesexamqcm[3] \\ \end{tblr}% }% %fin test hauteur }% {}% }% {}% }% {% \IfEq{\ExamQCMNbRep}{2}%2réponses {% \ifboolKV[reponsesexamqcm]{Filets}% {\begin{tblr}{rowsep=\RepExamQCMOffsetLgn,colsep=\RepExamQCMOffsetCol,hlines,vlines,width=\RepExamQCMLarg,colspec={*{2}{X[b,l]}},#3}}% {\begin{tblr}{rowsep=\RepExamQCMOffsetLgn,colsep=\RepExamQCMOffsetCol,width=\RepExamQCMLarg,colspec={*{2}{X[b,l]}},#3}}% \RepExamQCMLabelA\ExamQCMListereponses[1] & \RepExamQCMLabelB\ExamQCMListereponses[2] \\ \end{tblr}% }% {}% \IfEq{\ExamQCMNbRep}{3}%3réponses {% \ifboolKV[reponsesexamqcm]{Filets}% {\begin{tblr}{rowsep=\RepExamQCMOffsetLgn,colsep=\RepExamQCMOffsetCol,hlines,vlines,width=\RepExamQCMLarg,colspec={*{3}{X[b,l]}},#3}}% {\begin{tblr}{rowsep=\RepExamQCMOffsetLgn,colsep=\RepExamQCMOffsetCol,width=\RepExamQCMLarg,colspec={*{3}{X[b,l]}},#3}}% \RepExamQCMLabelA\ExamQCMListereponses[1] & \RepExamQCMLabelB\ExamQCMListereponses[2] & \RepExamQCMLabelC\ExamQCMListereponses[3] \\ \end{tblr}% }% {}% \IfEq{\ExamQCMNbRep}{4}%4réponses {% \IfEq{\RepExamQCMNbCol}{4}%4colonnes {% \ifboolKV[reponsesexamqcm]{Filets}% {\begin{tblr}{rowsep=\RepExamQCMOffsetLgn,colsep=\RepExamQCMOffsetCol,hlines,vlines,width=\RepExamQCMLarg,colspec={*{4}{X[b,l]}},#3}}% {\begin{tblr}{rowsep=\RepExamQCMOffsetLgn,colsep=\RepExamQCMOffsetCol,width=\RepExamQCMLarg,colspec={*{4}{X[b,l]}},#3}}% \RepExamQCMLabelA\ExamQCMListereponses[1] & \RepExamQCMLabelB\ExamQCMListereponses[2] & \RepExamQCMLabelC\ExamQCMListereponses[3] & \RepExamQCMLabelD\ExamQCMListereponses[4] \\ \end{tblr}% }% {}% \IfEq{\RepExamQCMNbCol}{2}%2colonnes {% \ifboolKV[reponsesexamqcm]{HtAuto}% {% \cegetheigheststring{#2}% \ifboolKV[reponsesexamqcm]{Filets}% {\begin{tblr}{rowsep=\RepExamQCMOffsetLgn,colsep=\RepExamQCMOffsetCol,hlines,vlines,width=\RepExamQCMLarg,colspec={*{2}{X[b,l]}},rows={ht=\cetmpheigheststring},#3}}% {\begin{tblr}{rowsep=\RepExamQCMOffsetLgn,colsep=\RepExamQCMOffsetCol,width=\RepExamQCMLarg,colspec={*{2}{X[b,l]}},rows={ht=\cetmpheigheststring},#3}}% \RepExamQCMLabelA\ExamQCMListereponses[1] & \ifboolKV[reponsesexamqcm]{Swap}{\RepExamQCMLabelB\ExamQCMListereponses[2]}{\RepExamQCMLabelC\ExamQCMListereponses[3]} \\ \ifboolKV[reponsesexamqcm]{Swap}{\RepExamQCMLabelC\ExamQCMListereponses[3]}{\RepExamQCMLabelB\ExamQCMListereponses[2]} & \RepExamQCMLabelD\ExamQCMListereponses[4] \\ \end{tblr}% }% {% \ifboolKV[reponsesexamqcm]{Filets}% {\begin{tblr}{rowsep=\RepExamQCMOffsetLgn,colsep=\RepExamQCMOffsetCol,hlines,vlines,width=\RepExamQCMLarg,colspec={*{2}{X[b,l]}},#3}}% {\begin{tblr}{rowsep=\RepExamQCMOffsetLgn,colsep=\RepExamQCMOffsetCol,width=\RepExamQCMLarg,colspec={*{2}{X[b,l]}},#3}}% \RepExamQCMLabelA\ExamQCMListereponses[1] & \ifboolKV[reponsesexamqcm]{Swap}{\RepExamQCMLabelB\ExamQCMListereponses[2]}{\RepExamQCMLabelC\ExamQCMListereponses[3]} \\ \ifboolKV[reponsesexamqcm]{Swap}{\RepExamQCMLabelC\ExamQCMListereponses[3]}{\RepExamQCMLabelB\ExamQCMListereponses[2]} & \RepExamQCMLabelD\ExamQCMListereponses[4] \\ \end{tblr}% }% }% {}% \IfEq{\RepExamQCMNbCol}{1}%1colonne {% %test hauteur \ifboolKV[reponsesexamqcm]{HtAuto}% {% \cegetheigheststring{#2}% \ifboolKV[reponsesexamqcm]{Filets}% {\begin{tblr}{rowsep=\RepExamQCMOffsetLgn,colsep=\RepExamQCMOffsetCol,hlines,vlines,width=\RepExamQCMLarg,colspec={*{1}{X[b,l]}},rows={ht=\cetmpheigheststring},#3}}% {\begin{tblr}{rowsep=\RepExamQCMOffsetLgn,colsep=\RepExamQCMOffsetCol,width=\RepExamQCMLarg,colspec={*{1}{X[b,l]}},rows={ht=\cetmpheigheststring},#3}}% \RepExamQCMLabelA\ExamQCMListereponses[1] \\ \ifboolKV[reponsesexamqcm]{Swap}{\RepExamQCMLabelB\ExamQCMListereponses[2]}{\RepExamQCMLabelC\ExamQCMListereponses[3]} \\ \ifboolKV[reponsesexamqcm]{Swap}{\RepExamQCMLabelC\ExamQCMListereponses[3]}{\RepExamQCMLabelB\ExamQCMListereponses[2]} \\ \RepExamQCMLabelD\ExamQCMListereponses[4] \\ \end{tblr}% }% {% \ifboolKV[reponsesexamqcm]{Filets}% {\begin{tblr}{rowsep=\RepExamQCMOffsetLgn,colsep=\RepExamQCMOffsetCol,hlines,vlines,width=\RepExamQCMLarg,colspec={*{1}{X[b,l]}},#3}}% {\begin{tblr}{rowsep=\RepExamQCMOffsetLgn,colsep=\RepExamQCMOffsetCol,width=\RepExamQCMLarg,colspec={*{1}{X[b,l]}},#3}}% \RepExamQCMLabelA\ExamQCMListereponses[1] \\ \ifboolKV[reponsesexamqcm]{Swap}{\RepExamQCMLabelB\ExamQCMListereponses[2]}{\RepExamQCMLabelC\ExamQCMListereponses[3]} \\ \ifboolKV[reponsesexamqcm]{Swap}{\RepExamQCMLabelC\ExamQCMListereponses[3]}{\RepExamQCMLabelB\ExamQCMListereponses[2]} \\ \RepExamQCMLabelD\ExamQCMListereponses[4] \\ \end{tblr}% }% %fin test hauteur }% {}% }% {}% }% } %====EXAM CONFIG \@ifpackageloaded{amssymb}% {% \newcommand\examdecoexo{\scalebox{0.66}[1]{$\blacktriangleright$}\space}% \newcommand\examdecoquest{\scalebox{0.66}[1]{$\blacktriangleright$}\space}% }% {% \newcommand\examdecoexo{\textbullet\space}% \newcommand\examdecoquest{\textbullet\space}% }% \newcommand\ExamTitreExo[2]{% \textbf{\large\examdecoexo\underline{Exercice #1}\space(#2 points)}% } \newcommand\ExamLabelAutomat[1]{% \textbf{\examdecoquest\underline{Question #1}}% } %====EXAM EXO \NewDocumentEnvironment{ExamAutomatQuest}{ O{} m }% {% \tcolorbox[boxrule=1pt,left=2.5mm,right=2.5mm,colframe=darkgray,colback=white,sharp corners=downhill,#1] \ExamLabelAutomat{#2} \smallskip }% {% \endtcolorbox% } \NewDocumentEnvironment{ExamExercice}{ O{} m m }% {% \tcolorbox[boxrule=1pt,left=2.5mm,right=2.5mm,colframe=darkgray,colback=white,sharp corners=downhill,#1] \ExamTitreExo{#2}{#3} \medskip }% {% \endtcolorbox% } %====EAM \NewDocumentCommand\QuestionAutomatismesFichier{ m O{} O{} m D<>{} }{% \input{#4.tex} %1=nb %2=options env %3=options réponses %4=fichier \begin{ExamAutomatQuest}[#2]{#1} \AutomatEnonce \ExamReponsesQCM[#3]% {% \AutomatReponses }% <#5>% \end{ExamAutomatQuest}% } \NewDocumentCommand\QuestionAutomatismes{ m O{} m O{} m D<>{}}{% %1=nb %2=options env %3=énoncé %4=clés réponses %5=options tblr réponses %6=réponses \begin{ExamAutomatQuest}[#2]{#1} #3 \medskip \ExamReponsesQCM[#4] {% #5 }% <#6>% \end{ExamAutomatQuest}% } %====EXAM BOX TITLE(s) \NewDocumentCommand\LetPhantomBox{}{% \vphantom{(ÉAZERTYUIOPQSDFGHJKLMWXCVBN,éàço)}% } \tcbset{StyleTitreSujet/.style={% enhanced,size=small, colback=white!5,boxrule=1.25pt, attach boxed title to top left={xshift=0.5cm,yshift=1mm-\tcboxedtitleheight}, varwidth boxed title*=-3cm, boxed title style={frame code={ \path[fill=tcbcolframe!50!black] ([yshift=-1mm,xshift=-1mm]frame.north west) arc[start angle=0,end angle=180,radius=1mm] ([yshift=-1mm,xshift=1mm]frame.north east) arc[start angle=180,end angle=0,radius=1mm]; \path[fill=tcbcolframe] ([xshift=-2mm]frame.north west) -- ([xshift=2mm]frame.north east) [rounded corners=1mm]-- ([xshift=1mm,yshift=-1mm]frame.north east) -- (frame.south east) -- (frame.south west) -- ([xshift=-1mm,yshift=-1mm]frame.north west) [sharp corners]-- cycle; },interior engine=empty,size=fbox, }, fonttitle=\bfseries\sffamily, fontupper=\huge\bfseries\sffamily, } } \defKV[tcbtitresujet]{% AlignH=\def\tcbtitresujethalign{#1} } \setKVdefault[tcbtitresujet]{% Couleur=black, AlignH=center } \NewDocumentEnvironment{TitreSujet}{ O{} D<>{} m }% {% \restoreKV[tcbtitresujet]% \setKV[tcbtitresujet]{#1}% \IfStrEqCase{\tcbtitresujethalign}{% {right}{\tcbset{StyleTitreSujetAlign/.style={halign=flush right}}}% {left}{\tcbset{StyleTitreSujetAlign/.style={halign=flush left}}}% }[\tcbset{StyleTitreSujetAlign/.style={halign=flush center}}]% \tcolorbox[colupper={\useKV[tcbtitresujet]{Couleur}},colframe={\useKV[tcbtitresujet]{Couleur}},StyleTitreSujet,StyleTitreSujetAlign,title={\vphantom{QJ}#3},before upper=\LetPhantomBox,after upper=\LetPhantomBox,#2]% }% {% \endtcolorbox% } \tcbset{StyleTitreSujetSousEpreuve/.style={% center,after skip=1pt,size=small,boxsep=3pt,boxrule=1pt,colback=white,left=2pt,right=2pt,% sharp corners,rounded corners=downhill,arc=8pt, fontupper={\sffamily\bfseries\large} } } \NewDocumentCommand\SousTitreSujetEpreuve{ O{black} m }{% \tcbset{StyleTitreSujetSousEpreuveCouleur/.style={colframe=#1,colupper=#1}} \IfStrEqCase{#2}{% {U21}{\tcbox[StyleTitreSujetSousEpreuve,StyleTitreSujetSousEpreuveCouleur,before upper=\faArrDownNb\space\space,after upper=\space\space\faProjDiag]{Épreuve E2 - Mathématiques pour l'Informatique}}% {U2}{\tcbox[StyleTitreSujetSousEpreuve,StyleTitreSujetSousEpreuveCouleur,before upper=\faArrDownNb\space\space,after upper=\space\space\faProjDiag]{Épreuve E2 - Mathématiques pour l'Informatique}}% {U2CG}{\tcbox[StyleTitreSujetSousEpreuve,StyleTitreSujetSousEpreuveCouleur,before upper=\faArrDownNb\space\space,after upper=\space\space\faProjDiag]{Épreuve E2 - Mathématiques appliquées}}% {U3}{\tcbox[StyleTitreSujetSousEpreuve,StyleTitreSujetSousEpreuveCouleur,before upper=\faArrDownNb\space\space,after upper=\space\space\faProjDiag]{Épreuve E3 - Mathématiques pour l'Informatique}}% {UF2}{\tcbox[StyleTitreSujetSousEpreuve,StyleTitreSujetSousEpreuveCouleur,before upper=\faDice\space\space,after upper=\space\space\faChartLine]{Épreuve EF2 - Mathématiques Approfondies}}% {U41OL}{\tcbox[StyleTitreSujetSousEpreuve,StyleTitreSujetSousEpreuveCouleur,before upper=\faDice\space\space,after upper=\space\space\faBezierCurve]{Épreuve U41 - Mathématiques}}}% [{\tcbox[StyleTitreSujetSousEpreuve,StyleTitreSujetSousEpreuveCouleur]{#2}}]% } \NewDocumentCommand\SujetTitreExo{ O{black} m }{% \begingroup% \tcolorbox[enhanced,width=\linewidth,size=small,colback=white,colframe=#1,boxrule=0.75pt,fontupper={\color{#1}\Large\sffamily\bfseries},sharp corners,rounded corners=south,arc=4pt,before upper=\LetPhantomBox] #2 \endtcolorbox% \endgroup% } %====BLOC EXO NEW V3 \newcounter{numeroblocexo} \setcounter{numeroblocexo}{0} \newlength{\eptraitblocexo} \setlength{\eptraitblocexo}{1.1pt} \newlength{\eptraitblocexospace} \setlength{\eptraitblocexospace}{1.5\eptraitblocexo} \colorlet{macouleurblocexo}{black} \colorlet{macouleurblocexodeco}{black} \colorlet{macouleurblocexodecofond}{black!50} \newcommand\tmpstyleblocexo{\bfseries\sffamily\large}% \newcommand\tmplabelblocexo{Exercice\space}% \tcbset{monstyleblocexo/.style={% enhanced,% opacityfill=0,% size=small,% boxrule=0.25mm,% titlerule=0.25mm,% arc=2mm,% sharp corners=uphill,% nobeforeafter,% before skip=0.5\baselineskip,% after skip=0.5\baselineskip,% colback=white,% colbacktitle=white,% coltitle=macouleurblocexo,% colframe=macouleurblocexo,% left=1.5mm,% right=1.5mm,% top=1mm,% bottom=1mm,% fonttitle=\tmpstyleblocexo }% } \tikzset{ligne bloc exo/.style={line width=0.3mm,macouleurblocexo}} \defKV[StyleBlocExo]{% Libelle=\renewcommand\tmplabelblocexo{#1},% Couleur=\colorlet{macouleurblocexo}{#1},% CouleurDeco=\colorlet{macouleurblocexodeco}{#1},% CouleurFondDeco=\colorlet{macouleurblocexodecofond}{#1},% Police=\renewcommand\tmpstyleblocexo{#1},% EpTrait=\setlength{\eptraitblocexo}{#1} } \setKVdefault[StyleBlocExo]{% Libelle={Exercice\space},% Couleur={black},% CouleurDeco=black, CouleurFondDeco={black!33},% Police={\bfseries\sffamily\large},% EpTrait={1.1pt} } \defKV[BlocExo]{% Type=\def\EnvtExoAltType{#1},% ComplementTitre=\def\EnvtExoAltCpltTitre{#1},% CodeDebut=\def\EnvtExoAltCodeAvant{#1},% Etoiles=\def\EnvtExoAltEtoiles{#1},% Trait=\def\EnvtExoAltTrait{#1},% Bordures=\def\EnvtExoAltBordures{#1},% Strut=\def\blocexostrut{#1} } \setKVdefault[BlocExo]{ Type=Classique,% ComplementTitre={},% CodeDebut={},% Compteur=true,% Etoiles={},% Breakable=false,% Trait=non,% Bordures=alt,% Strut=() } \tcbuselibrary{breakable}%à voir... \NewDocumentEnvironment{BlocExo}{ O{} m }% {% \useKVdefault[BlocExo]% \setKV[BlocExo]{#1}% \addtocounter{numeroblocexo}{1}% \ifboolKV[BlocExo]{Compteur}{}{\addtocounter{numeroblocexo}{-1}}% %styles \tcbset{reset}% \ifboolKV[BlocExo]{Breakable}% {% \tcbset{monstyleblocexobreakable/.style={breakable}}% }% {% \tcbset{monstyleblocexobreakable/.style={}}% }% \IfStrEqCase{\EnvtExoAltBordures}{% {normal}{\tcbset{monstylebloexobordures/.style={}}}% {aucune}{\tcbset{monstylebloexobordures/.style={frame empty,left=0mm,right=0mm,boxsep=0mm,boxrule=0mm,top=2mm,before upper={\EnvtExoAltCodeAvant}}}}% {alt}{\tcbset{monstylebloexobordures/.style={frame empty,top=0mm,finish={\draw[ligne bloc exo,|-|] ([xshift=0.5em-0.1mm]title.west) --++ (-0.5em-0.1mm,0) {[rounded corners=2mm]|- (frame.south east)} |- ([xshift=-0.5em+0.1mm]title.east) ;}}}}% {fleche}{\tcbset{monstylebloexobordures/.style={frame empty,top=0mm,righttitle=0mm,finish={\draw[ligne bloc exo,->,>=latex] ([xshift=0.5em-0.1mm]title.west) --++ (-0.5em-0.1mm,0) {[rounded corners=2mm]|- (frame.south east)} -- ($(frame.south east)!0.5!(frame.north east)$) ;}}}}% }% \tcbset{monstyleblocexotitre/.style={ title={% \vphantom{\blocexostrut}% \IfStrEq{\EnvtExoAltType}{Classique}% {% \tmplabelblocexo% }% {% \StrBehind{\EnvtExoAltType}{/}[\EnvtExoLabel]% \EnvtExoLabel% }% \ifboolKV[BlocExo]{Compteur}{\thenumeroblocexo}{}\EnvtExoAltCpltTitre% \IfStrEq{\EnvtExoAltEtoiles}{}{}%les étoiles au début... {% \space(% \IfSubStr{\EnvtExoAltEtoiles}{§}% {% \StrCut{\EnvtExoAltEtoiles}{§}{\EnvtExoStarNb}{\EnvtExoStarTot}% \pictostars[colors=macouleurblocexodeco/macouleurblocexodecofond,dstrut=()]{\EnvtExoStarNb/\EnvtExoStarTot}% }% {% \pictostars[colors=macouleurblocexodeco/macouleurblocexodecofond,dstrut=()]{\EnvtExoStarNb}% }% )% }% %trait éventuel \IfStrEqCase{\EnvtExoAltTrait}{% {plein}% {% \def\hrulefill{\leavevmode\leaders\hrule height \eptraitblocexo\hfill\kern\z@}%épaisseur \,\hrulefill\null% \def\hrulefill{\leavevmode\leaders\hrule height 0.4pt\hfill\kern\z@}% }% {pointilles}{\,\dotfill\null}% {dashilles}{\,\hdashrule{\fill}{\eptraitblocexo}{\eptraitblocexospace}\null}% {non}{\hfill\null}% {aucun}{}% }% %la décoration, manuelle {#2} } } }% \noindent\tcolorbox[monstyleblocexo,monstyleblocexotitre,monstyleblocexobreakable,monstylebloexobordures] }% {% \endtcolorbox% } \endinput