%%%============================================================================== %% Copyright 2022-present by Alceu Frigeri %% %% This work may be distributed and/or modified under the conditions of %% %% * The [LaTeX Project Public License](http://www.latex-project.org/lppl.txt), %% version 1.3c (or later), and/or %% * The [GNU Affero General Public License](https://www.gnu.org/licenses/agpl-3.0.html), %% version 3 (or later) %% %% This work has the LPPL maintenance status *maintained*. %% %% The Current Maintainer of this work is Alceu Frigeri %% %% This is version {2.10} {2024/04/20} %% %% The list of files that compose this work can be found in the README.md file at %% https://ctan.org/pkg/ufrgscca %% %%%============================================================================== %% UFRGS stands for "Federal University of Rio Grande do Sul" in south Brazil %% EE stands for "Engineering School" %% CCA stands for "Control and Automation Engineering Course" (Portuguese acronym) %%%============================================================================== \NeedsTeXFormat{LaTeX2e}[2023/11/01] \ProvidesExplPackage {ufrgscca-curr} {2024/04/20} {2.10} {UFRGS/CCA curricula commands} %%%%%%% %%% %%% Just an attempt of having my packages info in a regular way %%% Idea being: { / pkg info } for each and all. %%% %%%%%%% \keys_define:nn { ufrgscca-curr / pkg info} { name .code:n = {ufrgscca-curr} , prefix .code:n = {ufrgscca} , date .code:n = {2024/04/20}, version .code:n = {2.10} , description .code:n = {UFRGS/CCA~ curricula~ commands} } \cs_if_exist:NF \PkgInfo { \NewDocumentCommand \PkgInfo {mm} { \keys_set:nn {#1 / pkg info}{#2} } \NewDocumentCommand \PkgDescription {m} { \noindent Package~ \textbf{\PkgInfo{#1}{name}}~Version:~\PkgInfo{#1}{version}~ -~ \PkgInfo{#1}{date}\par \emph{\PkgInfo{#1}{description}}~\par } } %%%%%%% %%% End of cut-n-paste %%%%%%% %%%%%%% %%% %%% V-less nightmare TO BE DONE! %%% => convert all V referenced sequences into 'starray sub structures' %%% less efficient, but 'portable' and V-safe. %%% %%% => Alternative approach: convert a _seq into a clist then store it into starray (argh! double damm) %%% => or just use ..._clist instead of _seq (replacing all _seq that are stored in starrays by a _clist) %%% %%%%%%% \starray_new:n {topics} \starray_new:n {classes} \starray_new:n {curricula} \starray_def_from_keyval:nn {topics} { self = , name = , color = , uniqueID = , % to replace class list (V-less) } \starray_def_from_keyval:nn {classes} { cred = , self = , name = , summary = , topic = , remark = , uniqueID = , % to replace the many V sequences (bib) ref . struct = { curr = , sem = , kind = , } , } \starray_def_from_keyval:nn {curricula} { self = , name = , text = , sem.struct = { pos = , self = , name = , class . struct = { name = , kind = , obs = , pos = , color = , prereqset . struct = { prereq . struct = { starred = , name = , ang = , } } , } , } , } \NewDocumentCommand{\currdef}{mmm} { \starray_new_term:nn {curricula}{#1} \starray_set_from_keyval:nn {curricula} { self = {#1} , name = {#2} , text = {#3} , } } \NewDocumentCommand{\semdef}{mmm} { \starray_new_term:nn {curricula.sem}{#1} \starray_set_from_keyval:nn {curricula.sem} { self = {#1} , name = {#2} , pos = {#3} , } } \NewDocumentCommand{\addclass}{O{}D<>{}mmO{}} { \starray_new_term:nn {curricula.sem.class}{#3} \starray_set_from_keyval:nn {curricula.sem.class} { color = {#1} , pos = {#2} , name = {#3} , kind = {#4} , obs = {#5} , } \starray_new_term:nn {curricula.sem.class.prereqset}{} \starray_set_iter_from_hash:nn {classes}{#3} \starray_new_term:nn {classes.ref}{} \starray_get_prop:nnN {curricula}{self} \l_tmpa_tl \starray_set_prop:nnV {classes.ref}{curr} \l_tmpa_tl \starray_get_prop:nnN {curricula.sem}{self} \l_tmpa_tl \starray_set_prop:nnV {classes.ref}{sem} \l_tmpa_tl \starray_set_prop:nnn {classes.ref}{kind}{#4} } \NewDocumentCommand{\depdef}{sD<>{}m} { \starray_new_term:nn {curricula.sem.class.prereqset.prereq}{#3} \starray_set_from_keyval:nn {curricula.sem.class.prereqset.prereq} { starred = {#1} , name = {#3} , ang = {#2} } } \NewDocumentCommand{\altdep}{} { \starray_new_term:nn {curricula.sem.class.prereqset}{} } \NewDocumentCommand\topicdef{O{}mm} { \starray_new_term:nn {topics}{#2} \starray_set_from_keyval:nn {topics} { self = {#2} , name = {#3} , color = {#1} , } %% V-less : replacing / new seq \starray_get_unique_id:nNTF {topics}\l__ufrgscca_uniqueID_tmpa_tl {} {\tl_set:Nn \l__ufrgscca_uniqueID_tmpa_tl {}} \starray_set_prop:nnV {topics}{uniqueID} \l__ufrgscca_uniqueID_tmpa_tl \seq_new:c {l__ufrgscca_curr_ \l__ufrgscca_uniqueID_tmpa_tl _seq} } \tl_new:N \l__ufrgscca_default_topic_tl \NewDocumentCommand\defaulttopic{m} { \tl_set:Ne \l__ufrgscca_default_topic_tl{#1} } \NewDocumentCommand{\classdef}{O{\l__ufrgscca_default_topic_tl}mmm} { \starray_new_term:nn {classes}{#2} \starray_set_from_keyval:nn {classes} { self = {#2} , cred = {#3} , name = {#4} , topic = {#1} , } %% V-less : new \starray_get_unique_id:nNTF {classes}\l__ufrgscca_uniqueID_tmpb_tl {} {\tl_set:Nn \l__ufrgscca_uniqueID_tmpb_tl {}} \starray_set_prop:nnV {classes}{uniqueID} \l__ufrgscca_uniqueID_tmpb_tl \seq_new:c {l__ufrgscca_curr_ \l__ufrgscca_uniqueID_tmpb_tl _bib _seq} \seq_new:c {l__ufrgscca_curr_ \l__ufrgscca_uniqueID_tmpb_tl _bib basic _seq} \seq_new:c {l__ufrgscca_curr_ \l__ufrgscca_uniqueID_tmpb_tl _bib compl _seq} \starray_set_iter_from_hash:nn {topics}{#1} %% V-less : new seq \starray_get_prop:nnN {topics}{uniqueID} \l__ufrgscca_uniqueID_tmpa_tl \seq_put_right:cn {l__ufrgscca_curr_ \l__ufrgscca_uniqueID_tmpa_tl _seq} {#2} } \NewDocumentCommand{\csummary}{m} { \starray_set_prop:nnn {classes}{summary}{#1} } \NewDocumentCommand{\classremark}{m} { \starray_set_prop:nnn {classes}{remark}{#1} } \NewDocumentCommand{\bibdef}{O{main}m} { %% V-less \starray_get_prop:nnN {classes}{uniqueID} \l__ufrgscca_uniqueID_tmpb_tl \str_case:nnF {#1} { {main} { %% V-less \seq_gput_right:cn {l__ufrgscca_curr_ \l__ufrgscca_uniqueID_tmpb_tl _bib _seq} {#2} } {basic}%{ \starray_get_prop:nnN {classes}{bib basic seq} \l_tmpa_seq } { %% V-less \seq_gput_right:cn {l__ufrgscca_curr_ \l__ufrgscca_uniqueID_tmpb_tl _bib basic _seq} {#2} } {compl}%{ \starray_get_prop:nnN {classes}{bib compl seq} \l_tmpa_seq } { %% V-less \seq_gput_right:cn {l__ufrgscca_curr_ \l__ufrgscca_uniqueID_tmpb_tl _bib compl _seq} {#2} } } { %% V-less \seq_put_right:cn {l__ufrgscca_curr_ \l__ufrgscca_uniqueID_tmpb_tl _bib _seq} {#2} } } \NewDocumentCommand{\classset}{m} { \starray_set_iter_from_hash:nn {classes}{#1} } \let\setclass\classset %\NewDocumentCommand\xTabEtp{O{\notoc\section}m}{% \cs_generate_variant:Nn \starray_set_iter_from_hash:nn {ne} %%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%% %%% %%% %%% %%% %%% %%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%% \tl_new:N \l__ufrgscca_tmp_class_tl \tl_new:N \l__ufrgscca_tmp_name_tl \tl_new:N \l__ufrgscca_tmp_obs_tl \tl_new:N \l__ufrgscca_tmp_kind_tl \tl_new:N \l__ufrgscca_tmp_cred_tl \tl_new:N \l__ufrgscca_tmp_topic_tl \tl_new:N \l__ufrgscca_tmp_color_tl \tl_new:N \l__ufrgscca_tmp_summary_tl \tl_new:N \l__ufrgscca_tmp_OR_tl \seq_new:N \l__ufrgscca_tmp_bib_seq \seq_new:N \l__ufrgscca_tmp_bibB_seq \seq_new:N \l__ufrgscca_tmp_prereq_seq \bool_new:N \l__ufrgscca_tmp_second_bool \NewDocumentCommand\TabEtp{sO{\notoc\section}mO{\footnotesize}}{% \starray_set_iter_from_hash:nn {curricula.sem}{#3} \bool_if:nTF {#1} { #4 \begin{tabular}{l@{\,}l@{\ }c@{\ }c@{\ }J{5mm}@{}J{10.2cm}}% \starray_get_prop:nnN {curricula.sem}{name} \l__ufrgscca_tmp_name_tl \use:e { & \exp_not:N \multicolumn{5}{J{11cm}}{\exp_not:N \textbf{\l__ufrgscca_tmp_name_tl}}}\\* } { \starray_term_syntax:n {curricula.sem} #2{\starray_parsed_get_prop:n {name}} #4 \begin{longtable}{l@{\,}l@{\ }c@{\ }c@{\ }J{5mm}@{}J{10.2cm}}% } \starray_iterate_over:nn {curricula.sem.class} { \starray_get_prop:nnN {curricula.sem.class}{name} \l__ufrgscca_tmp_class_tl \starray_get_prop:nnN {curricula.sem.class}{kind} \l__ufrgscca_tmp_kind_tl \starray_get_prop:nnN {curricula.sem.class}{color} \l__ufrgscca_tmp_color_tl \starray_set_iter_from_hash:ne {classes}{\l__ufrgscca_tmp_class_tl} \starray_get_prop:nnN {classes}{name} \l__ufrgscca_tmp_name_tl \starray_get_prop:nnN {classes}{cred} \l__ufrgscca_tmp_cred_tl \tl_if_empty:NT \l__ufrgscca_tmp_color_tl { \tl_set:Nn \l__ufrgscca_tmp_color_tl {black} } %% class identification \bool_if:NTF \l__ufrgscca_showind_bool { \use:e { & \l__ufrgscca_tmp_class_tl & \l__ufrgscca_tmp_cred_tl & \l__ufrgscca_tmp_kind_tl & \exp_not:N \multicolumn{2}{J{10.5cm}}{\exp_not:N \textcolor{\l__ufrgscca_tmp_color_tl}{\l__ufrgscca_tmp_name_tl}}\\* } } { \use:e { & \l__ufrgscca_tmp_class_tl & \l__ufrgscca_tmp_cred_tl & \l__ufrgscca_tmp_kind_tl & \exp_not:N \multicolumn{2}{J{10.5cm}}{\l__ufrgscca_tmp_name_tl}\\* } } %% Pre-reqs \bool_gset_false:N \l__ufrgscca_tmp_second_bool \starray_iterate_over:nnTF {curricula.sem.class.prereqset} { \seq_gclear:N \l__ufrgscca_tmp_prereq_seq \starray_iterate_over:nnTF {curricula.sem.class.prereqset.prereq} { \starray_get_prop:nnN {curricula.sem.class.prereqset.prereq}{name} \l_tmpa_tl \seq_gput_right:Ne \l__ufrgscca_tmp_prereq_seq {\l_tmpa_tl} } {} {} \seq_if_empty:NF \l__ufrgscca_tmp_prereq_seq { \bool_if:NTF \l__ufrgscca_tmp_second_bool { & & & & \multicolumn{2}{J{11cm}}{\smaller\makebox[10mm][l]{~\ ~OU}\seq_use:Nn \l__ufrgscca_tmp_prereq_seq {~E~} }\\* } { & & & & \multicolumn{2}{J{11cm}}{\smaller\makebox[10mm][l]{}\seq_use:Nn \l__ufrgscca_tmp_prereq_seq {~E~} }\\* \bool_gset_true:N \l__ufrgscca_tmp_second_bool } } } {} {} \starray_get_prop:nnN {curricula.sem.class}{obs} \l__ufrgscca_tmp_obs_tl \tl_if_empty:NF \l__ufrgscca_tmp_obs_tl { \use:e { & & & & & {\exp_not:N \scriptsize{\exp_not:N \emph{\l__ufrgscca_tmp_obs_tl}}}\\* } } \bool_if:nF {#1} { %% Topic \starray_get_prop:nnN {classes}{topic} \l__ufrgscca_tmp_topic_tl \starray_set_iter_from_hash:ne {topics}{\l__ufrgscca_tmp_topic_tl} \starray_get_prop:nnN {topics}{name} \l__ufrgscca_tmp_topic_tl \starray_get_prop:nnN {topics}{color} \l__ufrgscca_tmp_color_tl \tl_if_empty:NT \l__ufrgscca_tmp_color_tl { \tl_set:Nn \l__ufrgscca_tmp_color_tl {black} } \use:e { & & & & \exp_not:N \multicolumn{2}{J{11cm}}{\exp_not:N \smaller \exp_not:N \scshape\exp_not:N \textcolor{\l__ufrgscca_tmp_color_tl}{\l__ufrgscca_tmp_topic_tl}}\\* } %% class summary & & & & \multicolumn{2}{J{11cm}}{\smaller\scshape Súmula}\\* \starray_get_prop:nnN {classes}{summary} \l__ufrgscca_tmp_summary_tl \use:e { & & & & & \exp_not:N \smaller \l__ufrgscca_tmp_summary_tl\\*} %% V-less \starray_get_prop:nnN {classes}{uniqueID} \l_tmpa_tl \tl_gset:Ne \l__ufrgscca_uniqueID_tmpb_tl {\l_tmpa_tl} %% bibliography I \seq_if_empty:cF {l__ufrgscca_curr_ \l__ufrgscca_uniqueID_tmpb_tl _bib _seq} { & & & & \multicolumn{2}{J{11cm}}{\smaller\scshape Bibliografia~ Básica~ Essencial}\\* \seq_map_inline:cn {l__ufrgscca_curr_ \l__ufrgscca_uniqueID_tmpb_tl _bib _seq} { & & & & & \smaller\textopenbullet ~\ ~ ##1\\ } } %% bibliography II \seq_if_empty:cF {l__ufrgscca_curr_ \l__ufrgscca_uniqueID_tmpb_tl _bib basic _seq} { & & & & \multicolumn{2}{J{11cm}}{\smaller\scshape Bibliografia~ Básica}\\* \seq_map_inline:cn {l__ufrgscca_curr_ \l__ufrgscca_uniqueID_tmpb_tl _bib basic _seq} { & & & & & \smaller\textopenbullet ~\ ~ ##1\\ } } %% bibliography III \seq_if_empty:cF {l__ufrgscca_curr_ \l__ufrgscca_uniqueID_tmpb_tl _bib compl _seq} { & & & & \multicolumn{2}{J{11cm}}{\smaller\scshape Bibliografia~ Complementar}\\* \seq_map_inline:cn {l__ufrgscca_curr_ \l__ufrgscca_uniqueID_tmpb_tl _bib compl _seq} { & & & & & \smaller\textopenbullet ~\ ~ ##1\\ } } \\[-1.5mm] } } \bool_if:nTF {#1} { \end{tabular} } { \end{longtable} } } \seq_new:N \l__ufrgscca_tmp_classlst_seq \NewDocumentCommand{\TabTopic}{m} { \starray_set_iter_from_hash:nnTF {topics}{#1} { \begin{tabular}{l@{\,}l@{\ -\ }J{11.5cm}} \starray_get_prop:nnN {topics}{name} \l__ufrgscca_tmp_name_tl \starray_get_prop:nnN {topics}{color} \l__ufrgscca_tmp_color_tl \tl_if_empty:NF \l__ufrgscca_tmp_color_tl { \tl_set:Nn \l__ufrgscca_tmp_color_tl {black} } \use:e { & \exp_not:N \multicolumn{2}{J{11cm}}{\exp_not:N \textcolor{\l__ufrgscca_tmp_color_tl}{\exp_not:N \textbf{\l__ufrgscca_tmp_name_tl} }}}\\\hline %% V-less : to be replaced \starray_get_prop:nnN {topics}{uniqueID} \l__ufrgscca_uniqueID_tmpa_tl \seq_map_inline:cn {l__ufrgscca_curr_ \l__ufrgscca_uniqueID_tmpa_tl _seq} { \starray_set_iter_from_hash:nn {classes}{##1} \starray_get_prop:nnN {classes}{name} \l__ufrgscca_tmp_name_tl \use:e { & ##1 & \l__ufrgscca_tmp_name_tl\\} } \end{tabular} } { \textbf{--Topic #1 non existant--} } } %%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%% %%% %%% %%% %%% %%% %%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%% \bool_new:N \l__ufrgscca_colors_topic_bool \bool_new:N \l__ufrgscca_colors_class_bool \keys_define:nn { ufrgscca / curr graph} { deltaX .usage:n = general, deltaX .fp_set:N = \l__ufrgscca_graph_deltaX_fp, deltaX .value_required:n = true, deltaX .initial:n = {4.2}, deltaY .usage:n = general, deltaY .fp_set:N = \l__ufrgscca_graph_deltaY_fp, deltaY .value_required:n = true, deltaY .initial:n = {2.1}, clipminX .usage:n = general, clipminX .fp_set:N = \l__ufrgscca_graph_clip_minX_fp, clipminX .value_required:n = true, clipminX .initial:n = {0}, maxX .usage:n = general, maxX .fp_set:N = \l__ufrgscca_graph_maxX_fp, maxX .value_required:n = true, maxX .initial:n = {11.5}, clipminY .usage:n = general, clipminY .fp_set:N = \l__ufrgscca_graph_clip_minY_fp, clipminY .value_required:n = true, clipminY .initial:n = {0}, maxY .usage:n = general, maxY .fp_set:N = \l__ufrgscca_graph_maxY_fp, maxY .value_required:n = true, maxY .initial:n = {-18.5}, graph~ title .usage:n = general, graph~ title .tl_set:N = \l__ufrgscca_graph_title_tl, graph~ title .value_required:n = true, graph~ title .initial:n = {Graph Title}, default~ color .usage:n = general, default~ color .tl_set:N = \l__ufrgscca_graph_default_color_tl, default~ color .value_required:n = true, default~ color .initial:n = {black}, colors .usage:n = general, colors .choice: , colors / none .code:n = { \bool_set_false:N \l__ufrgscca_colors_topic_bool \bool_set_false:N \l__ufrgscca_colors_class_bool } , colors / topic .code:n = { \bool_set_true:N \l__ufrgscca_colors_topic_bool \bool_set_false:N \l__ufrgscca_colors_class_bool } , colors / class .code:n = { \bool_set_false:N \l__ufrgscca_colors_topic_bool \bool_set_true:N \l__ufrgscca_colors_class_bool } , colors / both .code:n = { \bool_set_true:N \l__ufrgscca_colors_topic_bool \bool_set_true:N \l__ufrgscca_colors_class_bool } , colors / unknown .code:n = { \bool_set_false:N \l__ufrgscca_colors_topic_bool \bool_set_false:N \l__ufrgscca_colors_class_bool } , } \keys_define:nn { ufrgscca / graph angles} { } \NewDocumentEnvironment{tikzGraphSem}{O{}}{% \bool_set_false:N \l__ufrgscca_colors_topic_bool \bool_set_false:N \l__ufrgscca_colors_class_bool \keys_set:nn {ufrgscca / curr graph}{#1} \fp_set:Nn \l__ufrgscca_graph_clip_maxX_fp {\l__ufrgscca_graph_maxX_fp * \l__ufrgscca_graph_deltaX_fp } \fp_set:Nn \l__ufrgscca_graph_clip_maxY_fp {\l__ufrgscca_graph_maxY_fp * \l__ufrgscca_graph_deltaY_fp } \begin{tikzpicture}[% disc/.style={% ellipse~ split, double, draw, line~ width=2pt,% every~ text~ node part/.style={font=\small\bfseries},% every~ lower~ node part/.style={font=\large\bfseries,color=blue}},% dep/.style={->,dotted,line~ width=3pt}]% \begin{scope} \clip ( \fp_use:N \l__ufrgscca_graph_clip_minX_fp , \fp_use:N \l__ufrgscca_graph_clip_minY_fp ) -- ( \fp_use:N \l__ufrgscca_graph_clip_minX_fp , \fp_use:N \l__ufrgscca_graph_clip_maxY_fp ) -- ( \fp_use:N \l__ufrgscca_graph_clip_maxX_fp , \fp_use:N \l__ufrgscca_graph_clip_maxY_fp ) -- ( \fp_use:N \l__ufrgscca_graph_clip_maxX_fp , \fp_use:N \l__ufrgscca_graph_clip_minY_fp ); \filldraw[color=red] ( \fp_eval:n {0.5*\l__ufrgscca_graph_clip_maxX_fp} , \fp_eval:n {-0.25*\l__ufrgscca_graph_deltaY_fp} ) node{\Huge\textbf{\l__ufrgscca_graph_title_tl}};% }{% \end{scope}% \end{tikzpicture}% } \fp_new:N \l__ufrgscca_tmp_posX_fp \bool_new:N \l__ufrgscca_tmp_starred_bool \tl_new:N \l__ufrgscca_tmp_prereq_name_tl \tl_new:N \l__ufrgscca_graph_color_tl \NewDocumentCommand{\GraphEtp}{m} { \starray_set_iter_from_hash:nn {curricula.sem}{#1} \starray_get_prop:nnN {curricula.sem}{pos} \l__ufrgscca_tmp_pos_tl \starray_get_prop:nnN {curricula.sem}{name} \l__ufrgscca_tmp_name_tl \fp_set:Nn \l__ufrgscca_tmp_posX_fp {\l__ufrgscca_tmp_pos_tl * \l__ufrgscca_graph_deltaX_fp - 0.5*\l__ufrgscca_graph_deltaX_fp} \draw ( \fp_use:N \l__ufrgscca_tmp_posX_fp , \fp_eval:n {-\l__ufrgscca_graph_deltaY_fp} ) node[disc](#1) {\l__ufrgscca_tmp_name_tl }; \starray_iterate_over:nn {curricula.sem.class} { \starray_get_prop:nnN {curricula.sem.class}{pos} \l__ufrgscca_tmp_pos_tl \starray_get_prop:nnN {curricula.sem.class}{name} \l__ufrgscca_tmp_name_tl \starray_set_iter_from_hash:ne {classes}{\l__ufrgscca_tmp_name_tl} \starray_get_prop:nnN {classes}{cred} \l__ufrgscca_tmp_cred_tl \starray_get_prop:nnN {classes}{topic} \l__ufrgscca_tmp_topic_tl \tl_set:Ne \l__ufrgscca_graph_color_tl {\l__ufrgscca_graph_default_color_tl} \bool_if:NT \l__ufrgscca_colors_topic_bool { \starray_set_iter_from_hash:ne {topics}{\l__ufrgscca_tmp_topic_tl} \starray_get_prop:nnN {topics}{color} \l__ufrgscca_tmp_color_tl \tl_if_empty:NF \l__ufrgscca_tmp_color_tl { \tl_set:Ne \l__ufrgscca_graph_color_tl {\l__ufrgscca_tmp_color_tl} } } \bool_if:NT \l__ufrgscca_colors_class_bool { \starray_get_prop:nnN {curricula.sem.class}{color} \l__ufrgscca_tmp_color_tl \tl_if_empty:NF \l__ufrgscca_tmp_color_tl { \tl_set:Ne \l__ufrgscca_graph_color_tl {\l__ufrgscca_tmp_color_tl} } } \draw ( \fp_use:N \l__ufrgscca_tmp_posX_fp , \fp_eval:n {\l__ufrgscca_tmp_pos_tl * \l__ufrgscca_graph_deltaY_fp - 1.25 * \l__ufrgscca_graph_deltaY_fp} ) node[disc,\l__ufrgscca_graph_color_tl](\l__ufrgscca_tmp_name_tl) {\l__ufrgscca_tmp_name_tl \nodepart{lower} \l__ufrgscca_tmp_cred_tl ~\ ~créd.};% \starray_iterate_over:nnTF {curricula.sem.class.prereqset} { \starray_iterate_over:nnTF {curricula.sem.class.prereqset.prereq} { \starray_get_prop:nnN {curricula.sem.class.prereqset.prereq}{starred} \l__ufrgscca_tmp_starred_bool \bool_if:NF \l__ufrgscca_tmp_starred_bool { \starray_get_prop:nnN {curricula.sem.class.prereqset.prereq}{name} \l__ufrgscca_tmp_prereq_name_tl \starray_get_prop:nnN {curricula.sem.class.prereqset.prereq}{ang} \l__ufrgscca_tmp_ang_tl \StrCut{\l__ufrgscca_tmp_ang_tl}{:}{\l__ufrgscca_partA_tl}{\l__ufrgscca_partB_tl} \tl_if_empty:NTF \l__ufrgscca_partB_tl { \str_case:NnF \l__ufrgscca_partA_tl { {A} { \tl_set:Nn \l__ufrgscca_angOUT_tl {30} \tl_set:Nn \l__ufrgscca_angIN_tl {180-30} } {B} { \tl_set:Nn \l__ufrgscca_angOUT_tl {60} \tl_set:Nn \l__ufrgscca_angIN_tl {180-60} } {C} { \tl_set:Nn \l__ufrgscca_angOUT_tl {80} \tl_set:Nn \l__ufrgscca_angIN_tl {180-80} } {-A} { \tl_set:Nn \l__ufrgscca_angOUT_tl {-30} \tl_set:Nn \l__ufrgscca_angIN_tl {180+30} } {-B} { \tl_set:Nn \l__ufrgscca_angOUT_tl {-60} \tl_set:Nn \l__ufrgscca_angIN_tl {180+60} } {-C} { \tl_set:Nn \l__ufrgscca_angOUT_tl {-80} \tl_set:Nn \l__ufrgscca_angIN_tl {180+80} } {A*} { \tl_set:Nn \l__ufrgscca_angOUT_tl {30} \tl_set:Nn \l__ufrgscca_angIN_tl {180+30} } {B*} { \tl_set:Nn \l__ufrgscca_angOUT_tl {60} \tl_set:Nn \l__ufrgscca_angIN_tl {180+60} } {C*} { \tl_set:Nn \l__ufrgscca_angOUT_tl {80} \tl_set:Nn \l__ufrgscca_angIN_tl {180+80} } {-A*} { \tl_set:Nn \l__ufrgscca_angOUT_tl {-30} \tl_set:Nn \l__ufrgscca_angIN_tl {180-30} } {-B*} { \tl_set:Nn \l__ufrgscca_angOUT_tl {60} \tl_set:Nn \l__ufrgscca_angIN_tl {180-60} } {-C*} { \tl_set:Nn \l__ufrgscca_angOUT_tl {80} \tl_set:Nn \l__ufrgscca_angIN_tl {180-80} } } { \tl_set:Nn \l__ufrgscca_angOUT_tl {0} \tl_set:Nn \l__ufrgscca_angIN_tl {180} }%didn't match } { \tl_set:Nn \l__ufrgscca_angOUT_tl {\l__ufrgscca_partA_tl} \tl_set:Nn \l__ufrgscca_angIN_tl {180-\l__ufrgscca_partB_tl} } \path[dep,\l__ufrgscca_graph_color_tl] (\l__ufrgscca_tmp_prereq_name_tl)edge[out=\l__ufrgscca_angOUT_tl,in=\l__ufrgscca_angIN_tl] (\l__ufrgscca_tmp_name_tl); } }{}{} %iterate over:TF prereq }{}{} %iterate over:TF prereqset } }