% Author.............: C. Pierquet % licence............: Released under the LaTeX Project Public License v1.3c or later, see http://www.latex-project.org/lppl.txt % help...............: Anthropic Claude AI, corrections manuelles \ProvidesExplPackage{ProfLycee-Arbres}{2026/10/23}{0.1.0} {Arbres de probabilites avec moteur TikZ (syntaxe recursive)} \RequirePackage{tikz} %%-------------------------------------------------------------------- %% Styles TikZ publics (modifiables par l'utilisateur avec \tikzset) %%-------------------------------------------------------------------- \tikzset { %% styles francais : portent les valeurs par defaut tkzArbreProbas~noeud/.style = { } , tkzArbreProbas~feuille/.style = { } , tkzArbreProbas~vide/.style = { inner~sep = 0pt , outer~sep = 0pt , minimum~size = 0pt } , tkzArbreProbas~arete/.style = { semithick } , tkzArbreProbas~proba/.style = { font = \small , inner~sep = 2pt } , tkzArbreProbas~proba~dessus/.style = { above = 1pt } , tkzArbreProbas~proba~dessous/.style = { below = 1pt } , tkzArbreProbas~proba~sur/.style = { fill = white } , tkzArbreProbas~surbrillance~arete/.style = { red , thick } , tkzArbreProbas~surbrillance~noeud/.style = { text = red } , tkzArbreProbas~resultat/.style = { } , %% alias anglais : vides, appliques apres les styles francais tkzProbaTree~node/.style = { } , tkzProbaTree~leaf/.style = { } , tkzProbaTree~empty/.style = { } , tkzProbaTree~edge/.style = { } , tkzProbaTree~prob/.style = { } , tkzProbaTree~prob~above/.style = { } , tkzProbaTree~prob~below/.style = { } , tkzProbaTree~prob~on/.style = { } , tkzProbaTree~hl~edge/.style = { } , tkzProbaTree~hl~node/.style = { } , tkzProbaTree~result/.style = { } , } %%-------------------------------------------------------------------- %% Variables %%-------------------------------------------------------------------- \int_new:N \g__tkzpt_n_int % nombre de noeuds (hors racine) \int_new:N \g__tkzpt_leaf_int % compteur de feuilles \int_new:N \g__tkzpt_maxdep_int % profondeur maximale d'une feuille \int_new:N \g__tkzpt_ref_int % une feuille de profondeur maximale \int_new:N \l__tkzpt_cur_int % parent courant pendant le parsing \int_new:N \l__tkzpt_id_int % identifiant du noeud en cours de creation \int_new:N \l__tkzpt_walk_int \int_new:N \l__tkzpt_dir_int % 1 = horizontal, 2 = vertical \int_new:N \l__tkzpt_res_int % 1 = rien, 2 = num, 3 = prod \int_new:N \l__tkzpt_digits_int \box_new:N \l__tkzpt_box \fp_new:N \l__tkzpt_acc_fp \bool_new:N \l__tkzpt_known_bool \bool_new:N \l__tkzpt_paren_bool \bool_new:N \l__tkzpt_sloped_bool \bool_new:N \l__tkzpt_arrows_bool \bool_new:N \l__tkzpt_inline_bool \bool_new:N \l__tkzpt_align_bool \bool_new:N \l__tkzpt_k_hl_bool \dim_new:N \l__tkzpt_ls_dim \dim_new:N \l__tkzpt_cs_dim \dim_new:N \l__tkzpt_rsep_dim \str_new:N \l__tkzpt_tmp_str \cs_generate_variant:Nn \str_remove_all:Nn { NV } \tl_new:N \l__tkzpt_coord_tl \tl_new:N \l__tkzpt_tmp_tl \tl_new:N \l__tkzpt_sty_tl \tl_new:N \l__tkzpt_pos_tl \tl_new:N \l__tkzpt_sym_tl \tl_new:N \l__tkzpt_v_tl \tl_new:N \l__tkzpt_p_tl \tl_new:N \l__tkzpt_times_tl \tl_new:N \l__tkzpt_restext_tl \tl_set:Nn \l__tkzpt_times_tl { \times } \clist_new:N \l__tkzpt_lvlsty_clist \clist_new:N \l__tkzpt_elvlsty_clist %% champs temporaires pour les cles de branche \tl_new:N \l__tkzpt_k_p_tl \tl_new:N \l__tkzpt_k_v_tl \tl_new:N \l__tkzpt_k_name_tl \tl_new:N \l__tkzpt_k_style_tl \tl_new:N \l__tkzpt_k_edge_tl \tl_new:N \l__tkzpt_k_pos_tl %%-------------------------------------------------------------------- %% Stockage des donnees : g__tkzpt___tl %%-------------------------------------------------------------------- \cs_new_protected:Npn \__tkzpt_gset:nnn #1#2#3 { \tl_gclear_new:c { g__tkzpt_ #1 _ #2 _tl } \tl_gset:cn { g__tkzpt_ #1 _ #2 _tl } {#3} } \cs_generate_variant:Nn \__tkzpt_gset:nnn { nVn , nVx , nnx , nnV , nVV } \cs_new:Npn \__tkzpt_get:nn #1#2 { \tl_use:c { g__tkzpt_ #1 _ #2 _tl } } \cs_generate_variant:Nn \__tkzpt_get:nn { nV } \cs_new:Npn \__tkzpt_nch:n #1 { \clist_count:c { g__tkzpt_ch_ #1 _clist } } %% nom TikZ du noeud : - \cs_new:Npn \__tkzpt_name:n #1 { \l__tkzpt_prefix_tl - \__tkzpt_get:nn { path } {#1} } \tl_new:N \l__tkzpt_prefix_tl %%-------------------------------------------------------------------- %% Cles de l'arbre %%-------------------------------------------------------------------- \tl_new:N \l__tkzpt_root_tl \tl_new:N \l__tkzpt_nstyle_tl \tl_new:N \l__tkzpt_lstyle_tl \tl_new:N \l__tkzpt_estyle_tl \tl_new:N \l__tkzpt_probstyle_tl \tl_new:N \l__tkzpt_probpos_tl \tl_new:N \l__tkzpt_probbg_tl \tl_new:N \l__tkzpt_hlstyle_tl \tl_new:N \l__tkzpt_hlnodestyle_tl \tl_new:N \l__tkzpt_resstyle_tl \tl_new:N \l__tkzpt_dec_tl \tl_new:N \l__tkzpt_tikz_tl \cs_new_protected:Npn \__tkzpt_resfmt:n #1 { \ensuremath {#1} } \keys_define:nn { tkzProbaTree } { level~sep .dim_set:N = \l__tkzpt_ls_dim , level~sep .initial:n = { 3cm } , leaf~sep .dim_set:N = \l__tkzpt_cs_dim , leaf~sep .initial:n = { 1cm } , direction .choices:nn = { right , down , droite , bas } { \int_set:Nn \l__tkzpt_dir_int { \int_mod:nn { \l_keys_choice_int + 1 } { 2 } + 1 } } , direction .initial:n = { right } , root .tl_set:N = \l__tkzpt_root_tl , node~style .tl_set:N = \l__tkzpt_nstyle_tl , leaf~style .tl_set:N = \l__tkzpt_lstyle_tl , edge~style .tl_set:N = \l__tkzpt_estyle_tl , prob~style .tl_set:N = \l__tkzpt_probstyle_tl , prob~pos .tl_set:N = \l__tkzpt_probpos_tl , prob~pos .initial:n = { auto } , sloped .bool_set:N = \l__tkzpt_sloped_bool , sloped .initial:n = { true } , arrows .bool_set:N = \l__tkzpt_arrows_bool , level~styles .clist_set:N = \l__tkzpt_lvlsty_clist , edge~level~styles .clist_set:N = \l__tkzpt_elvlsty_clist , hl~style .tl_set:N = \l__tkzpt_hlstyle_tl , hl~node~style .tl_set:N = \l__tkzpt_hlnodestyle_tl , results .choices:nn = { false , num , prod } { \int_set_eq:NN \l__tkzpt_res_int \l_keys_choice_int } , results .default:n = { num } , results .initial:n = { false } , result~style .tl_set:N = \l__tkzpt_resstyle_tl , result~sep .dim_set:N = \l__tkzpt_rsep_dim , result~sep .initial:n = { 4mm } , result~format .code:n = { \cs_set:Npn \__tkzpt_resfmt:n ##1 {#1} } , align~results .bool_set:N = \l__tkzpt_align_bool , align~results .initial:n = { true } , digits .int_set:N = \l__tkzpt_digits_int , digits .initial:n = { 3 } , decimal~sep .tl_set:N = \l__tkzpt_dec_tl , decimal~sep .initial:n = { {,} } , name~prefix .tl_set:N = \l__tkzpt_prefix_tl , name~prefix .initial:n = { tkzPT } , tikz .tl_set:N = \l__tkzpt_tikz_tl , inline .bool_set:N = \l__tkzpt_inline_bool , %% alias francais espace~niveaux .meta:n = { level~sep = {#1} } , espace~feuilles .meta:n = { leaf~sep = {#1} } , racine .meta:n = { root = {#1} } , style~noeuds .meta:n = { node~style = {#1} } , style~feuilles .meta:n = { leaf~style = {#1} } , style~aretes .meta:n = { edge~style = {#1} } , style~probas .meta:n = { prob~style = {#1} } , position~probas .meta:n = { prob~pos = {#1} } , incline .meta:n = { sloped = {#1} } , fleches .meta:n = { arrows = {#1} } , style~surbrillance .meta:n = { hl~style = {#1} } , resultats .meta:n = { results = {#1} } , resultats .default:n = { num } , style~resultats .meta:n = { result~style = {#1} } , format~resultats .meta:n = { result~format = {#1} } , chiffres .meta:n = { digits = {#1} } , separateur~decimal .meta:n = { decimal~sep = {#1} } , prefixe .meta:n = { name~prefix = {#1} } , styles~niveaux .meta:n = { level~styles = {#1} } , styles~aretes~niveaux .meta:n = { edge~level~styles = {#1} } , style~surbrillance~noeud .meta:n = { hl~node~style = {#1} } , alignement~resultats .meta:n = { align~results = {#1} } , separateur~resultats .meta:n = { result~sep = {#1} } , sans~environnement .meta:n = { inline = {#1} } , incline .default:n = { true } , fleches .default:n = { true } , sans~environnement .default:n = { true } , } %% cles d'une branche \keys_define:nn { tkzProbaTree / branch } { p .tl_set:N = \l__tkzpt_k_p_tl , v .tl_set:N = \l__tkzpt_k_v_tl , name .tl_set:N = \l__tkzpt_k_name_tl , style .tl_set:N = \l__tkzpt_k_style_tl , edge .tl_set:N = \l__tkzpt_k_edge_tl , pos .tl_set:N = \l__tkzpt_k_pos_tl , hl .bool_set:N = \l__tkzpt_k_hl_bool , hl .default:n = { true } , proba .meta:n = { p = {#1} } , valeur .meta:n = { v = {#1} } , nom .meta:n = { name = {#1} } , arete .meta:n = { edge = {#1} } , position .meta:n = { pos = {#1} } , surbrillance .meta:n = { hl = {#1} } , surbrillance .default:n = { true } , } %%-------------------------------------------------------------------- %% Valeur numerique deduite de la proba affichee (0{,}3 ; 0.3 ; 1/3) %%-------------------------------------------------------------------- \cs_new_protected:Npn \__tkzpt_derive_v: { \tl_if_empty:NT \l__tkzpt_k_v_tl { \tl_if_empty:NF \l__tkzpt_k_p_tl { \tl_set_eq:NN \l__tkzpt_tmp_tl \l__tkzpt_k_p_tl %% on nettoie l'etiquette saisie par l'utilisateur : $ , \num, \frac, {,} \regex_replace_all:nnN { \cM\$ } { } \l__tkzpt_tmp_tl \regex_replace_all:nnN { \c{[dt]?frac} \cB\{ (.*?) \cE\} \cB\{ (.*?) \cE\} } { (\1)/(\2) } \l__tkzpt_tmp_tl \regex_replace_all:nnN { \c{num} } { } \l__tkzpt_tmp_tl \str_set:Nx \l__tkzpt_tmp_str { \tl_to_str:N \l__tkzpt_tmp_tl } \str_remove_all:NV \l__tkzpt_tmp_str \c_left_brace_str \str_remove_all:NV \l__tkzpt_tmp_str \c_right_brace_str \str_replace_all:Nnn \l__tkzpt_tmp_str { , } { . } \regex_match:nVT { \A [ 0-9 . / * + ( ) \- \ ]+ \Z } \l__tkzpt_tmp_str { \tl_set_eq:NN \l__tkzpt_k_v_tl \l__tkzpt_tmp_str } } } } %%-------------------------------------------------------------------- %% Parsing : \tkzProbaTreeBranch(*)[opts]{label}{enfants} %%-------------------------------------------------------------------- \NewDocumentCommand \tkzProbaTreeBranch { s O{} m } { \IfBooleanTF {#1} { \__tkzpt_peek_children:nnn { 1 } {#2} {#3} } { \__tkzpt_peek_children:nnn { 0 } {#2} {#3} } } \cs_new_protected:Npn \__tkzpt_peek_children:nnn #1#2#3 { \peek_charcode_ignore_spaces:NTF \c_group_begin_token { \__tkzpt_branch:nnnn {#1} {#2} {#3} } { \__tkzpt_branch:nnnn {#1} {#2} {#3} { } } } \cs_new_protected:Npn \__tkzpt_branch:nnnn #1#2#3#4 { \group_begin: \int_gincr:N \g__tkzpt_n_int \int_set_eq:NN \l__tkzpt_id_int \g__tkzpt_n_int \tl_clear:N \l__tkzpt_k_p_tl \tl_clear:N \l__tkzpt_k_v_tl \tl_clear:N \l__tkzpt_k_name_tl \tl_clear:N \l__tkzpt_k_style_tl \tl_clear:N \l__tkzpt_k_edge_tl \tl_clear:N \l__tkzpt_k_pos_tl \bool_set_false:N \l__tkzpt_k_hl_bool \tl_if_in:nnTF {#2} { = } { \keys_set:nn { tkzProbaTree / branch } {#2} } { \tl_set:Nn \l__tkzpt_k_p_tl {#2} } \__tkzpt_derive_v: \int_compare:nNnT {#1} = { 1 } { \bool_set_true:N \l__tkzpt_k_hl_bool } %% enregistrement \__tkzpt_gset:nVx { par } \l__tkzpt_id_int { \int_use:N \l__tkzpt_cur_int } \__tkzpt_gset:nVx { dep } \l__tkzpt_id_int { \int_eval:n { \__tkzpt_get:nV { dep } \l__tkzpt_cur_int + 1 } } \__tkzpt_gset:nVx { path } \l__tkzpt_id_int { \int_compare:nNnF { \l__tkzpt_cur_int } = { 0 } { \__tkzpt_get:nV { path } \l__tkzpt_cur_int - } \int_eval:n { \__tkzpt_nch:n { \int_use:N \l__tkzpt_cur_int } + 1 } } \__tkzpt_gset:nVn { lab } \l__tkzpt_id_int {#3} \__tkzpt_gset:nVn { alias } \l__tkzpt_id_int { } \__tkzpt_gset:nVV { p } \l__tkzpt_id_int \l__tkzpt_k_p_tl \tl_set_eq:NN \l__tkzpt_tmp_tl \l__tkzpt_k_p_tl \regex_replace_all:nnN { \cM\$ } { } \l__tkzpt_tmp_tl \__tkzpt_gset:nVV { psym } \l__tkzpt_id_int \l__tkzpt_tmp_tl \__tkzpt_gset:nVV { v } \l__tkzpt_id_int \l__tkzpt_k_v_tl \__tkzpt_gset:nVV { sty } \l__tkzpt_id_int \l__tkzpt_k_style_tl \__tkzpt_gset:nVV { esty } \l__tkzpt_id_int \l__tkzpt_k_edge_tl \__tkzpt_gset:nVV { pos } \l__tkzpt_id_int \l__tkzpt_k_pos_tl \bool_if:NTF \l__tkzpt_k_hl_bool { \__tkzpt_gset:nVn { hl } \l__tkzpt_id_int { 1 } \__tkzpt_gset:nVn { hn } \l__tkzpt_id_int { 1 } } { \__tkzpt_gset:nVn { hl } \l__tkzpt_id_int { 0 } \__tkzpt_gset:nVn { hn } \l__tkzpt_id_int { 0 } } \clist_gclear_new:c { g__tkzpt_ch_ \int_use:N \l__tkzpt_id_int _clist } \clist_gput_right:cx { g__tkzpt_ch_ \int_use:N \l__tkzpt_cur_int _clist } { \int_use:N \l__tkzpt_id_int } %% nom personnalise (alias TikZ) : enregistre pour plus tard \tl_if_empty:NF \l__tkzpt_k_name_tl { \__tkzpt_gset:nVV { alias } \l__tkzpt_id_int \l__tkzpt_k_name_tl } %% enfants \int_set_eq:NN \l__tkzpt_cur_int \l__tkzpt_id_int #4 \group_end: } %%-------------------------------------------------------------------- %% Placement : feuilles equi-reparties, parents centrés sur les enfants %%-------------------------------------------------------------------- \cs_new_protected:Npn \__tkzpt_layout_leaf:n #1 { \int_compare:nNnT { \__tkzpt_nch:n {#1} } = { 0 } { \__tkzpt_gset:nnx { q } {#1} { \int_use:N \g__tkzpt_leaf_int } \int_gincr:N \g__tkzpt_leaf_int \int_compare:nNnT { \__tkzpt_get:nn { dep } {#1} } > { \g__tkzpt_maxdep_int } { \int_gset:Nn \g__tkzpt_maxdep_int { \__tkzpt_get:nn { dep } {#1} } \int_gset:Nn \g__tkzpt_ref_int {#1} } } } \cs_new_protected:Npn \__tkzpt_layout_inner:n #1 { \int_compare:nNnF { \__tkzpt_nch:n {#1} } = { 0 } { \__tkzpt_gset:nnx { q } {#1} { \fp_eval:n { ( \__tkzpt_get:nn { q } { \clist_item:cn { g__tkzpt_ch_ #1 _clist } { 1 } } + \__tkzpt_get:nn { q } { \clist_item:cn { g__tkzpt_ch_ #1 _clist } { -1 } } ) / 2 } } } } %% propagation de la surbrillance vers la racine \cs_new_protected:Npn \__tkzpt_hl_prop:n #1 { \str_if_eq:eeT { \__tkzpt_get:nn { hl } {#1} } { 1 } { \__tkzpt_gset:nxn { hl } { \__tkzpt_get:nn { par } {#1} } { 1 } } } \cs_generate_variant:Nn \__tkzpt_gset:nnn { nxn } \cs_new_protected:Npn \__tkzpt_layout: { \int_gzero:N \g__tkzpt_leaf_int \int_gzero:N \g__tkzpt_maxdep_int \int_gzero:N \g__tkzpt_ref_int \int_step_function:nnnN { 1 } { 1 } { \g__tkzpt_n_int } \__tkzpt_layout_leaf:n \int_step_function:nnnN { \g__tkzpt_n_int } { -1 } { 0 } \__tkzpt_layout_inner:n \int_step_function:nnnN { \g__tkzpt_n_int } { -1 } { 1 } \__tkzpt_hl_prop:n } %%-------------------------------------------------------------------- %% Dessin %%-------------------------------------------------------------------- \cs_new_protected:Npn \__tkzpt_node_coord:n #1 { \int_compare:nNnTF { \l__tkzpt_dir_int } = { 1 } { \tl_set:Nx \l__tkzpt_coord_tl { \fp_to_dim:n { \__tkzpt_get:nn { dep } {#1} * \dim_to_fp:n { \l__tkzpt_ls_dim } } , \fp_to_dim:n { - \__tkzpt_get:nn { q } {#1} * \dim_to_fp:n { \l__tkzpt_cs_dim } } } } { \tl_set:Nx \l__tkzpt_coord_tl { \fp_to_dim:n { \__tkzpt_get:nn { q } {#1} * \dim_to_fp:n { \l__tkzpt_cs_dim } } , \fp_to_dim:n { - \__tkzpt_get:nn { dep } {#1} * \dim_to_fp:n { \l__tkzpt_ls_dim } } } } } %% style de niveau (item de la clist selon la profondeur) \cs_new_protected:Npn \__tkzpt_level_style:Nn #1#2 { \tl_clear:N \l__tkzpt_sty_tl \int_compare:nNnT { \clist_count:N #1 } > { 0 } { \tl_set:Nf \l__tkzpt_sty_tl { \clist_item:Nn #1 { \__tkzpt_get:nn { dep } {#2} } } } } \tl_new:N \l__tkzpt_opts_tl \tl_new:N \l__tkzpt_lopts_tl \tl_new:N \l__tkzpt_nm_tl \tl_new:N \l__tkzpt_pnm_tl \tl_new:N \l__tkzpt_rnm_tl %% commandes TikZ : les listes d'options sont passees par expansion (V) \cs_new_protected:Npn \__tkzpt_node_cmd:nn #1#2 { \node [#1] ( \l__tkzpt_nm_tl ) at ( \l__tkzpt_coord_tl ) {#2} ; } \cs_generate_variant:Nn \__tkzpt_node_cmd:nn { Vv } \cs_new_protected:Npn \__tkzpt_edge_cmd:n #1 { \draw [#1] ( \l__tkzpt_pnm_tl ) -- ( \l__tkzpt_nm_tl ) ; } \cs_generate_variant:Nn \__tkzpt_edge_cmd:n { V } \cs_new_protected:Npn \__tkzpt_edge_cmd:nnn #1#2#3 { \draw [#1] ( \l__tkzpt_pnm_tl ) -- ( \l__tkzpt_nm_tl ) node [#2] {#3} ; } \cs_generate_variant:Nn \__tkzpt_edge_cmd:nnn { VVv } \cs_new_protected:Npn \__tkzpt_draw_node:n #1 { \__tkzpt_node_coord:n {#1} \tl_set:Nx \l__tkzpt_nm_tl { \__tkzpt_name:n {#1} } \tl_if_empty:cTF { g__tkzpt_lab_ #1 _tl } { \tl_set:Nn \l__tkzpt_opts_tl { tkzArbreProbas~vide , tkzProbaTree~empty } } { \__tkzpt_level_style:Nn \l__tkzpt_lvlsty_clist {#1} \tl_set:Nn \l__tkzpt_opts_tl { tkzArbreProbas~noeud , tkzProbaTree~node , } \tl_put_right:NV \l__tkzpt_opts_tl \l__tkzpt_nstyle_tl \tl_put_right:Nn \l__tkzpt_opts_tl { , } \int_compare:nNnT { \__tkzpt_nch:n {#1} } = { 0 } { \tl_put_right:Nn \l__tkzpt_opts_tl { tkzArbreProbas~feuille , tkzProbaTree~leaf , } \tl_put_right:NV \l__tkzpt_opts_tl \l__tkzpt_lstyle_tl \tl_put_right:Nn \l__tkzpt_opts_tl { , } } \tl_put_right:NV \l__tkzpt_opts_tl \l__tkzpt_sty_tl \tl_put_right:Nn \l__tkzpt_opts_tl { , } \tl_put_right:Nv \l__tkzpt_opts_tl { g__tkzpt_sty_ #1 _tl } \str_if_eq:eeT { \__tkzpt_get:nn { hn } {#1} } { 1 } { \tl_put_right:Nn \l__tkzpt_opts_tl { , tkzArbreProbas~surbrillance~noeud , tkzProbaTree~hl~node , } \tl_put_right:NV \l__tkzpt_opts_tl \l__tkzpt_hlnodestyle_tl } } \__tkzpt_node_cmd:Vv \l__tkzpt_opts_tl { g__tkzpt_lab_ #1 _tl } \tl_if_empty:cF { g__tkzpt_alias_ #1 _tl } { \pgfnodealias { \tl_use:c { g__tkzpt_alias_ #1 _tl } } { \l__tkzpt_nm_tl } } } %% position de l'etiquette d'une branche \cs_new_protected:Npn \__tkzpt_edge_pos:n #1 { \tl_set_eq:Nc \l__tkzpt_pos_tl { g__tkzpt_pos_ #1 _tl } \tl_if_empty:NT \l__tkzpt_pos_tl { \tl_set_eq:NN \l__tkzpt_pos_tl \l__tkzpt_probpos_tl } \str_case:Vn \l__tkzpt_pos_tl { { dessus } { \tl_set:Nn \l__tkzpt_pos_tl { above } } { dessous } { \tl_set:Nn \l__tkzpt_pos_tl { below } } { sur } { \tl_set:Nn \l__tkzpt_pos_tl { on } } } \str_if_eq:VnT \l__tkzpt_pos_tl { auto } { \fp_compare:nNnTF { \__tkzpt_get:nn { q } {#1} } < { \__tkzpt_get:nn { q } { \__tkzpt_get:nn { par } {#1} } } { \tl_set:Nn \l__tkzpt_pos_tl { above } } { \fp_compare:nNnTF { \__tkzpt_get:nn { q } {#1} } > { \__tkzpt_get:nn { q } { \__tkzpt_get:nn { par } {#1} } } { \tl_set:Nn \l__tkzpt_pos_tl { below } } { \tl_set:Nn \l__tkzpt_pos_tl { on } } } } \str_case:Vn \l__tkzpt_pos_tl { { above } { \tl_set:Nn \l__tkzpt_pos_tl { tkzArbreProbas~proba~dessus , tkzProbaTree~prob~above } } { below } { \tl_set:Nn \l__tkzpt_pos_tl { tkzArbreProbas~proba~dessous , tkzProbaTree~prob~below } } { on } { \tl_set:Nn \l__tkzpt_pos_tl { tkzArbreProbas~proba~sur , tkzProbaTree~prob~on } } } } \cs_new_protected:Npn \__tkzpt_draw_edge:n #1 { \tl_set:Nx \l__tkzpt_nm_tl { \__tkzpt_name:n {#1} } \tl_set:Nx \l__tkzpt_pnm_tl { \__tkzpt_name:n { \__tkzpt_get:nn { par } {#1} } } \__tkzpt_level_style:Nn \l__tkzpt_elvlsty_clist {#1} \tl_set:Nn \l__tkzpt_opts_tl { tkzArbreProbas~arete , tkzProbaTree~edge , } \tl_put_right:NV \l__tkzpt_opts_tl \l__tkzpt_estyle_tl \bool_if:NT \l__tkzpt_arrows_bool { \tl_put_right:Nn \l__tkzpt_opts_tl { , -> , >=latex } } \tl_put_right:Nn \l__tkzpt_opts_tl { , } \tl_put_right:NV \l__tkzpt_opts_tl \l__tkzpt_sty_tl \tl_put_right:Nn \l__tkzpt_opts_tl { , } \tl_put_right:Nv \l__tkzpt_opts_tl { g__tkzpt_esty_ #1 _tl } \str_if_eq:eeT { \__tkzpt_get:nn { hl } {#1} } { 1 } { \tl_put_right:Nn \l__tkzpt_opts_tl { , tkzArbreProbas~surbrillance~arete , tkzProbaTree~hl~edge , } \tl_put_right:NV \l__tkzpt_opts_tl \l__tkzpt_hlstyle_tl } \tl_if_empty:cTF { g__tkzpt_p_ #1 _tl } { \__tkzpt_edge_cmd:V \l__tkzpt_opts_tl } { \__tkzpt_edge_pos:n {#1} \tl_set:Nn \l__tkzpt_lopts_tl { midway , tkzArbreProbas~proba , tkzProbaTree~prob , } \bool_if:NT \l__tkzpt_sloped_bool { \tl_put_right:Nn \l__tkzpt_lopts_tl { sloped , } } \tl_put_right:NV \l__tkzpt_lopts_tl \l__tkzpt_pos_tl \tl_put_right:Nn \l__tkzpt_lopts_tl { , } \tl_put_right:NV \l__tkzpt_lopts_tl \l__tkzpt_probstyle_tl \__tkzpt_edge_cmd:VVv \l__tkzpt_opts_tl \l__tkzpt_lopts_tl { g__tkzpt_p_ #1 _tl } } } %%-------------------------------------------------------------------- %% Resultats : produit des probas le long du chemin %%-------------------------------------------------------------------- \cs_new_protected:Npn \__tkzpt_path_info:n #1 { \fp_set:Nn \l__tkzpt_acc_fp { 1 } \tl_clear:N \l__tkzpt_sym_tl \bool_set_true:N \l__tkzpt_known_bool \int_set:Nn \l__tkzpt_walk_int {#1} \int_while_do:nNnn { \l__tkzpt_walk_int } > { 0 } { \tl_set_eq:Nc \l__tkzpt_v_tl { g__tkzpt_v_ \int_use:N \l__tkzpt_walk_int _tl } \tl_set_eq:Nc \l__tkzpt_p_tl { g__tkzpt_psym_ \int_use:N \l__tkzpt_walk_int _tl } \tl_if_empty:NTF \l__tkzpt_v_tl { \bool_set_false:N \l__tkzpt_known_bool } { \fp_set:Nn \l__tkzpt_acc_fp { \l__tkzpt_acc_fp * ( \l__tkzpt_v_tl ) } } \tl_if_empty:NF \l__tkzpt_p_tl { \tl_if_empty:NF \l__tkzpt_sym_tl { \tl_put_left:NV \l__tkzpt_sym_tl \l__tkzpt_times_tl } %% parentheses autour d'une proba composee (1-p, a+b...) \bool_set_false:N \l__tkzpt_paren_bool \tl_if_in:NnT \l__tkzpt_p_tl { - } { \bool_set_true:N \l__tkzpt_paren_bool } \tl_if_in:NnT \l__tkzpt_p_tl { + } { \bool_set_true:N \l__tkzpt_paren_bool } \bool_if:NT \l__tkzpt_paren_bool { \tl_put_left:Nn \l__tkzpt_p_tl { ( } \tl_put_right:Nn \l__tkzpt_p_tl { ) } } \tl_put_left:NV \l__tkzpt_sym_tl \l__tkzpt_p_tl } \int_set:Nn \l__tkzpt_walk_int { \__tkzpt_get:nV { par } \l__tkzpt_walk_int } } } \cs_new_protected:Npn \__tkzpt_result_node:nn #1#2 { \node [#1] at ( #2 ) { \exp_args:NV \__tkzpt_resfmt:n \l__tkzpt_restext_tl } ; } \cs_generate_variant:Nn \__tkzpt_result_node:nn { Vx } \cs_new_protected:Npn \__tkzpt_draw_result:n #1 { \int_compare:nNnT { \__tkzpt_nch:n {#1} } = { 0 } { \__tkzpt_path_info:n {#1} \int_compare:nNnTF { \l__tkzpt_res_int } = { 2 } { \bool_if:NTF \l__tkzpt_known_bool { \tl_set:Nx \l__tkzpt_restext_tl { \fp_to_decimal:n { round ( \l__tkzpt_acc_fp , \l__tkzpt_digits_int ) } } \tl_replace_once:NnV \l__tkzpt_restext_tl { . } \l__tkzpt_dec_tl } { \tl_set_eq:NN \l__tkzpt_restext_tl \l__tkzpt_sym_tl } } { \tl_set_eq:NN \l__tkzpt_restext_tl \l__tkzpt_sym_tl } \tl_set:Nx \l__tkzpt_nm_tl { \__tkzpt_name:n {#1} } \tl_set:Nx \l__tkzpt_rnm_tl { \__tkzpt_name:n { \int_use:N \g__tkzpt_ref_int } } \int_compare:nNnTF { \l__tkzpt_dir_int } = { 1 } { \tl_set:Nn \l__tkzpt_opts_tl { anchor = west , xshift = \l__tkzpt_rsep_dim , tkzArbreProbas~resultat , tkzProbaTree~result , } \tl_put_right:NV \l__tkzpt_opts_tl \l__tkzpt_resstyle_tl \bool_if:NTF \l__tkzpt_align_bool { \__tkzpt_result_node:Vx \l__tkzpt_opts_tl { \l__tkzpt_rnm_tl .east ~ |- ~ \l__tkzpt_nm_tl .center } } { \__tkzpt_result_node:Vx \l__tkzpt_opts_tl { \l__tkzpt_nm_tl .east } } } { \tl_set:Nn \l__tkzpt_opts_tl { anchor = north , yshift = - \l__tkzpt_rsep_dim , tkzArbreProbas~resultat , tkzProbaTree~result , } \tl_put_right:NV \l__tkzpt_opts_tl \l__tkzpt_resstyle_tl \bool_if:NTF \l__tkzpt_align_bool { \__tkzpt_result_node:Vx \l__tkzpt_opts_tl { \l__tkzpt_nm_tl .center ~ |- ~ \l__tkzpt_rnm_tl .south } } { \__tkzpt_result_node:Vx \l__tkzpt_opts_tl { \l__tkzpt_nm_tl .south } } } } } \cs_new_protected:Npn \__tkzpt_draw_body: { \int_step_function:nnnN { 0 } { 1 } { \g__tkzpt_n_int } \__tkzpt_draw_node:n \int_step_function:nnnN { 1 } { 1 } { \g__tkzpt_n_int } \__tkzpt_draw_edge:n \int_compare:nNnF { \l__tkzpt_res_int } = { 1 } { \int_step_function:nnnN { 1 } { 1 } { \g__tkzpt_n_int } \__tkzpt_draw_result:n } } \cs_new_protected:Npn \__tkzpt_draw: { \bool_if:NTF \l__tkzpt_inline_bool { \begin{scope} [ \l__tkzpt_tikz_tl ] \__tkzpt_draw_body: \end{scope} } { \begin{tikzpicture} [ \l__tkzpt_tikz_tl ] \__tkzpt_draw_body: \end{tikzpicture} } } %%-------------------------------------------------------------------- %% Interface %% \begin{tkzProbaTree}[opts] ... \end{tkzProbaTree} %% \tkzProbaTree[opts]{ ... } %% \tkzProbaTreeSetup{opts} (reglages par defaut, locaux au gpe) %%-------------------------------------------------------------------- \cs_new_protected:Npn \__tkzpt_run:nn #1#2 { \group_begin: \keys_set:nn { tkzProbaTree } {#1} \int_gzero:N \g__tkzpt_n_int \int_set:Nn \l__tkzpt_cur_int { 0 } %% racine \__tkzpt_gset:nnn { par } { 0 } { 0 } \__tkzpt_gset:nnn { dep } { 0 } { 0 } \__tkzpt_gset:nnn { path } { 0 } { 0 } \__tkzpt_gset:nnV { lab } { 0 } \l__tkzpt_root_tl \__tkzpt_gset:nnn { p } { 0 } { } \__tkzpt_gset:nnn { psym } { 0 } { } \__tkzpt_gset:nnn { v } { 0 } { } \__tkzpt_gset:nnn { sty } { 0 } { } \__tkzpt_gset:nnn { esty } { 0 } { } \__tkzpt_gset:nnn { pos } { 0 } { } \__tkzpt_gset:nnn { hl } { 0 } { 0 } \__tkzpt_gset:nnn { hn } { 0 } { 0 } \__tkzpt_gset:nnn { alias } { 0 } { } \clist_gclear_new:c { g__tkzpt_ch_0_clist } %% lecture du corps (dans une boite pour neutraliser les espaces) \hbox_set:Nn \l__tkzpt_box {#2} \__tkzpt_layout: \__tkzpt_draw: \group_end: } %% \tkzProbaTree sert a la fois de macro (corps entre accolades) %% et de debut d'environnement (corps lu jusqu'a \end{tkzProbaTree}) \NewDocumentCommand \tkzProbaTree { O{} } { \peek_charcode_ignore_spaces:NTF \c_group_begin_token { \__tkzpt_cmd:nn {#1} } { \__tkzpt_env:nnw {#1} { } } } \cs_new_protected:Npn \__tkzpt_cmd:nn #1#2 { \__tkzpt_run:nn {#1} {#2} } \clist_new:N \g__tkzpt_envnames_clist \clist_gput_right:Nn \g__tkzpt_envnames_clist { tkzProbaTree } \cs_new_protected:Npn \__tkzpt_env:nnw #1#2#3 \end #4 { \clist_if_in:NnTF \g__tkzpt_envnames_clist {#4} { \__tkzpt_run:nn {#1} { #2 #3 } \end {#4} } { \__tkzpt_env:nnw {#1} { #2 #3 \end {#4} } } } \cs_new_protected:Npn \endtkzProbaTree { } \NewDocumentCommand \tkzProbaTreeSetup { m } { \keys_set:nn { tkzProbaTree } {#1} } %%-------------------------------------------------------------------- %% Alias (macros ET environnements) %%-------------------------------------------------------------------- \cs_new_protected:Npn \__tkzpt_alias_env:n #1 { \clist_gput_right:Nn \g__tkzpt_envnames_clist {#1} \cs_new_protected:cpn { end #1 } { } \exp_args:Nc \NewCommandCopy {#1} \tkzProbaTree } \__tkzpt_alias_env:n { tkzptree } \__tkzpt_alias_env:n { tkzArbre } \NewCommandCopy \tkzptreebranch \tkzProbaTreeBranch \NewCommandCopy \tkzptreesetup \tkzProbaTreeSetup \NewCommandCopy \tkzArbreArete \tkzProbaTreeBranch \NewCommandCopy \tkzArbreArc \tkzProbaTreeBranch \NewCommandCopy \tkzArbreConfig \tkzProbaTreeSetup \endinput