This is not a minimal example, there are ten different questions here! The code given below works. Following the request in your comment, I have made more changes than strictly necessary in order to better adhere to LaTeX3 coding conventions (to the best of my knowledge).
Note that the _private_ naming scheme in \keys_define:nn { tikzmkpd/_private_/config-#1 } is an invention of mine; I don't know if there is a standard naming scheme for such situations. I did this way because I believe the keys defined under this hierarchy are an implementation detail of your macros and shouldn't be used directly by “users”.
LaTeX3 coding conventions are presented in expl3.pdf, l3styleguide.pdf and at the beginning of interface3.pdf. The indentation style suggested there is a bit different from yours (in particular, it uses a basic offset of two spaces). But the code below is already fairly readable, so I let you decide for yourself whether you want to strictly follow the indentation guidelines too.
For functions, I used:
a \__tikzmkpd_ prefix for private ones;
a \tikzmkpd_ prefix for public ones (only \tikzmkpd:nnn, which I added as the programming-layer backend function corresponding to the user-layer \tikzmkpd command you had already defined).
This way, it is very easy to turn all this code into a package that will play well with the rest of the LaTeX ecosystem. Your \_case_one:n and \_case_two:n functions had an incorrect name for two reasons:
- the prefix;
- the
:n suffix which indicated they were supposed to take an argument, whereas they actually don't.
I renamed these two functions to \__tikzmkpd_case_one: and \__tikzmkpd_case_two:, respectively.
\documentclass{article}
\usepackage{xparse}
\usepackage{tikz}
\usetikzlibrary{arrows.meta, bending, calc, tikzmark}
\ExplSyntaxOn
\cs_new_protected:Npn \__tikzmkpd_define_numeric_keys:nnnnnnnnn
#1#2#3#4#5#6#7#8#9
{
\keys_define:nn { tikzmkpd/_private_/config-#1 }
{
yshift-#1C .tl_set:c = { l_yshift_#1C_tl }, yshift-#1C .initial:n = {#2},
yshift-#1D .tl_set:c = { l_yshift_#1D_tl }, yshift-#1D .initial:n = {#3},
yshift-#1E .tl_set:c = { l_yshift_#1E_tl }, yshift-#1E .initial:n = {#4},
distan-#1C .tl_set:c = { l_distan_#1C_tl }, distan-#1C .initial:n = {#5},
distan-#1D .tl_set:c = { l_distan_#1D_tl }, distan-#1D .initial:n = {#6},
distan-#1E .tl_set:c = { l_distan_#1E_tl }, distan-#1E .initial:n = {#7},
angles-#1C .tl_set:c = { l_angles_#1C_tl }, angles-#1C .initial:n = {#8},
angles-#1D .tl_set:c = { l_angles_#1D_tl }, angles-#1D .initial:n = {#8},
angles-#1E .tl_set:c = { l_angles_#1E_tl }, angles-#1E .initial:n = {#8},
anglee-#1C .tl_set:c = { l_anglee_#1C_tl }, anglee-#1C .initial:n = {#9},
anglee-#1D .tl_set:c = { l_anglee_#1D_tl }, anglee-#1D .initial:n = {#9},
anglee-#1E .tl_set:c = { l_anglee_#1E_tl }, anglee-#1E .initial:n = {#9},
}
}
\__tikzmkpd_define_numeric_keys:nnnnnnnnn
{ A } { 1.7ex } { 1.7ex } { 1.7ex } { 1ex } { 2ex } { 3ex } { 60 } { 120 }
\__tikzmkpd_define_numeric_keys:nnnnnnnnn
{ B }{ -0.5ex }{ -0.5ex }{ -0.5ex } { 1ex } { 2ex } { 3ex } {-60 } {-120 }
\cs_new_protected:Npn \__tikzmkpd_define_colour_keys:nnnn #1#2#3#4
{
\keys_define:nn { tikzmkpd/_private_/config-#1 }
{
colour-#1C .tl_set:c = { l_colour_#1C_tl }, colour-#1C .initial:n = {#2},
colour-#1D .tl_set:c = { l_colour_#1D_tl }, colour-#1D .initial:n = {#3},
colour-#1E .tl_set:c = { l_colour_#1E_tl }, colour-#1E .initial:n = {#4},
}
}
\__tikzmkpd_define_colour_keys:nnnn { A } { red } { green } { blue }
\__tikzmkpd_define_colour_keys:nnnn { B } { red } { green } { blue }
\keys_define:nn { tikzmkpd / config-A }
{
yshift-A .tl_set:c = { l_yshift_A_tl },
yshift-A .initial:n = { 1.7ex },
end-yshift .code:n = { \__tikzmkpd_set_subkeys:nnn { A } { yshift } {#1} },
angle-star .code:n = { \__tikzmkpd_set_subkeys:nnn { A } { angles } {#1} },
angle-end .code:n = { \__tikzmkpd_set_subkeys:nnn { A } { anglee } {#1} },
distance .code:n = { \__tikzmkpd_set_subkeys:nnn { A } { distan } {#1} },
color .code:n = { \__tikzmkpd_set_subkeys:nnn { A } { colour } {#1} },
raise .meta:n = { yshift-A = {#1}, end-yshift = {#1,#1,#1} },
}
\keys_define:nn { tikzmkpd / config-B }
{
yshift-B .tl_set:c = { l_yshift_B_tl },
yshift-B .initial:n = { -0.5ex },
end-yshift .code:n = { \__tikzmkpd_set_subkeys:nnn { B } { yshift } {#1} },
angle-star .code:n = { \__tikzmkpd_set_subkeys:nnn { B } { angles } {#1} },
angle-end .code:n = { \__tikzmkpd_set_subkeys:nnn { B } { anglee } {#1} },
distance .code:n = { \__tikzmkpd_set_subkeys:nnn { B } { distan } {#1} },
color .code:n = { \__tikzmkpd_set_subkeys:nnn { B } { colour } {#1} },
raise .meta:n = { yshift-B = {#1}, end-yshift = {#1,#1,#1} },
}
\cs_new:Npn \__tikzmkpd_subs_i:nnn #1#2#3
{ \exp_not:n { #1-#2C = {#3} } }
\cs_new:Npn \__tikzmkpd_subs_ii:nnnn #1#2#3#4
{ \exp_not:n { #1-#2C= {#3}, #1-#2D= {#4} } }
\cs_new:Npn \__tikzmkpd_subs_iii:nnnnn #1#2#3#4#5
{ \exp_not:n { #1-#2C= {#3}, #1-#2D= {#4}, #1-#2E= {#5} } }
\cs_generate_variant:Nn \__tikzmkpd_subs_i:nnn { nnV }
\cs_generate_variant:Nn \__tikzmkpd_subs_ii:nnnn { nnVV }
\cs_generate_variant:Nn \__tikzmkpd_subs_iii:nnnnn { nnVVV }
\cs_generate_variant:Nn \keys_set:nn { nx }
\tl_new:N \l__tikzmkpd_tmp_tl
\cs_new_protected:Npn \__tikzmkpd_set_subkeys:nnn #1#2#3
{
\clist_set:Nn \l_tmpa_clist {#3}
\bool_if:nT { \int_compare_p:n { \clist_count:n {#3} = 1 } }
{
\tl_set:Nx \l_tmpa_tl { \clist_item:Nn \l_tmpa_clist {1} }
\keys_set:nx
{ tikzmkpd/_private_/config-#1 }
{ \__tikzmkpd_subs_i:nnV {#2} {#1} \l_tmpa_tl }
}
\bool_if:nT { \int_compare_p:n { \clist_count:n {#3} = 2 } }
{
\tl_set:Nx \l_tmpa_tl { \clist_item:Nn \l_tmpa_clist {1} }
\tl_set:Nx \l_tmpb_tl { \clist_item:Nn \l_tmpa_clist {2} }
\keys_set:nx
{ tikzmkpd/_private_/config-#1 }
{ \__tikzmkpd_subs_ii:nnVV {#2} {#1} \l_tmpa_tl \l_tmpb_tl }
}
\bool_if:nT { \int_compare_p:n { \clist_count:n {#3} = 3 } }
{
\tl_set:Nx \l_tmpa_tl { \clist_item:Nn \l_tmpa_clist {1} }
\tl_set:Nx \l_tmpb_tl { \clist_item:Nn \l_tmpa_clist {2} }
\tl_set:Nx \l__tikzmkpd_tmp_tl { \clist_item:Nn \l_tmpa_clist {3} }
\keys_set:nx
{ tikzmkpd/_private_/config-#1 }
{ \__tikzmkpd_subs_iii:nnVVV {#2} {#1} \l_tmpa_tl \l_tmpb_tl
\l__tikzmkpd_tmp_tl }
}
}
\seq_new:N \l__tikzmkpd_mycmd_seq
\cs_new_protected:Npn \__tikzmkpd_store_node_names:nn #1#2
{
\seq_set_from_clist:Nn \l__tikzmkpd_mycmd_seq {#2}
\seq_indexed_map_inline:Nn \l__tikzmkpd_mycmd_seq
{
\tl_clear_new:c { l__tikzmkpd_nodename_#1##1_tl }
\tl_set:cn { l__tikzmkpd_nodename_#1##1_tl } {##2}
}
}
% case 1: a(c+d) A1(B1+B2)
\cs_new_protected:Npn \__tikzmkpd_case_one:
{
\draw[->, \use:c{l_colour_AC_tl}]
($(\tl_use:c { l__tikzmkpd_nodename_A1_tl }) + (0, \use:c{l_yshift_A_tl})$)
to[out=\use:c{l_angles_AC_tl}, in=\use:c{l_anglee_AC_tl},
distance=\use:c{l_distan_AC_tl}]
([yshift=\use:c{l_yshift_AC_tl}] \tl_use:c { l__tikzmkpd_nodename_B1_tl });
\draw[->,\use:c{l_colour_AD_tl}]
($(\tl_use:c { l__tikzmkpd_nodename_A1_tl }) + (0, \use:c{l_yshift_A_tl})$)
to[out=\use:c{l_angles_AD_tl}, in=\use:c{l_anglee_AD_tl},
distance=\use:c{l_distan_AD_tl}]
([yshift=\use:c{l_yshift_AD_tl}] \tl_use:c { l__tikzmkpd_nodename_B2_tl });
}
% case 2: a(c+d+e) A1(B1+B2+B3)
\cs_new_protected:Npn \__tikzmkpd_case_two:
{
\__tikzmkpd_case_one:
\draw[->, \use:c{l_colour_AE_tl}]
($(\tl_use:c { l__tikzmkpd_nodename_A1_tl }) + (0, \use:c{l_yshift_A_tl})$)
to[out=\use:c{l_angles_AE_tl}, in=\use:c{l_anglee_AE_tl},
distance=\use:c{l_distan_AE_tl}]
([yshift=\use:c{l_yshift_AE_tl}] \tl_use:c { l__tikzmkpd_nodename_B3_tl });
}
\keys_define:nn { tikzmkpd }
{
config-A .code:n = { \keys_set:nn { tikzmkpd / config-A } {#1} },
config-B .code:n = { \keys_set:nn { tikzmkpd / config-B } {#1} },
}
\cs_new_protected:Npn \tikzmkpd:nnn #1#2#3
{
\group_begin:
\keys_set:nn { tikzmkpd } {#1}
\__tikzmkpd_store_node_names:nn {A} {#2}
\__tikzmkpd_store_node_names:nn {B} {#3}
\tikzset{>={Straight ~ Barb[length=1.5pt,round,bend]}}
\begin{tikzpicture}[overlay, remember ~ picture]
\bool_if:nT
{
\int_compare_p:n { \clist_count:n {#2} = 1 } &&
\int_compare_p:n { \clist_count:n {#3} = 2 }
}
{ \__tikzmkpd_case_one: }
\bool_if:nT
{
\int_compare_p:n { \clist_count:n {#2} = 1 } &&
\int_compare_p:n { \clist_count:n {#3} = 3 }
}
{ \__tikzmkpd_case_two: }
\end{tikzpicture}
\group_end:
}
\NewDocumentCommand \tikzmkpd { O{} m m }
{
\tikzmkpd:nnn {#1} {#2} {#3}
}
\ExplSyntaxOff
\newcommand*{\TkM}[2]{\tikzmarknode{#1}{#2}} % short :)
\setlength{\parindent}{0pt} % just for the example
\pagestyle{empty}
\begin{document}
\section{case 1}
$\TkM{A}{2a^2}(\TkM{B}{b}+\TkM{D}{3q})$%
\tikzmkpd[config-A={end-yshift={8pt,9pt}, yshift-A=8pt, color={gray,red}}]%
{A}{B, D}
\section{case 2}
$\TkM{a1}{2p}\left(\TkM{b1}{3q}+\TkM{c1}{4r}+\TkM{d1}{1}\right)$%
\tikzmkpd[config-A={color={gray,gray,gray}, end-yshift={5pt,5pt,5pt}}]%
{a1}{b1, c1, d1}
\end{document}
I tested the preceding code, it gives the screenshot below. At the end of the post, you'll find a variant with improvements from Pablo that deals with more cases of the distributive property of multiplication (cases “one” to “four” instead of just “one” and “two”). However, I can't completely validate that version myself, as it apparently relies on recent bug fixes or features of PGF/TikZ—too recent for the version I have here, which is 2019/02/02 v3.1.1.

I believe you can make progress regarding your debugging methodology: had you tested the output of every single function of yours, you'd have done:
\tl_show:N \l_yshift_AC_tl
\tl_show:N \l_yshift_AD_tl
\tl_show:N \l_colour_AC_tl
\tl_show:N \l_colour_AD_tl
right after the \keys_set:nn { tikzmkpd } {#1} call, which would have shown that your \__testkeys:nnn (now called \__tikzmkpd_set_subkeys:nnn) was not working properly. The main problem there was that you were passing single tokens such as \l_tmpa_tl in arguments where you actually wanted their value (something equivalent to the result of expanding \l_tmpa_tl or \tl_use:N \l_tmpa_tl; see how I did). Also, more bracing was desirable in some places in case some parameter values were to contain commas. For instance, this:
\cs_new:Npn \__tikzmkpd_subs_i:nnn #1#2#3
{ #1-#2C = {#3}, }
is preferable to this:
\cs_new:Npn \__tikzmkpd_subs_i:nnn #1#2#3
{ #1-#2C= #3, }
in case #3 were to contain commas. In fact, unless you plan to use macros in #1, #2 or #3, the following is maybe preferable in order to avoid unwanted expansions (since we later use it inside an x argument), which is what I did above:
\cs_new:Npn \__tikzmkpd_subs_i:nnn #1#2#3
{ \exp_not:n { #1-#2C = {#3} } }
The other problem that prevented the code from working is that for nodes created with \tikzmarknode, the pic cs syntax you used doesn't work—at least in my setup. The good news is, this can be simplified a lot (see my changes to \_case_one:n and \_case_two:n [now renamed to \__tikzmkpd_case_one: and \__tikzmkpd_case_two:]).
Your question is so complex with all the parameters, the TikZ code mixed up with the l3keys code, that I fear no one is going to reuse my answer. :-( I don't criticize the use of l3keys for TikZ work (for one, I'm much more comfortable myself with l3keys than with pgfkeys), but in the interest of other users of this site, I think you should have isolated the parsing problem from the TikZ issue—as people already told you.
Your LaTeX coding skills seem good; my main advice would be:
Read a bit more documentation, in particular on the LaTeX3 naming conventions, expansion and variants (see the first chapters of interface3.pdf).
Whenever you face again a problem like that, use \tracingmacros=1 \tracingonline=1\relax, and if this isn't enough to understand what is happening, print the value of every “thing” that your functions prepare1 (for each of your functions). For example, before even trying to typeset the tikzpicture, print all options and all parameters that you are going to use therein. This method would have helped you find the errors in your \__testkeys:nnn (now renamed to \__tikzmkpd_set_subkeys:nnn).
As promised, here is the expanded code with additions from Pablo:
\documentclass{article}
\usepackage{xparse}
\usepackage{tikz}
\usetikzlibrary{arrows.meta, bending, calc, tikzmark}
\ExplSyntaxOn
\cs_new_protected:Npn \__tikzmkpd_define_numeric_keys:nnnnnnnnn
#1#2#3#4#5#6#7#8#9
{
\keys_define:nn { tikzmkpd/_private_/config-#1 }
{
yshift-#1C .tl_set:c = { l_yshift_#1C_tl }, yshift-#1C .initial:n = {#2},
yshift-#1D .tl_set:c = { l_yshift_#1D_tl }, yshift-#1D .initial:n = {#3},
yshift-#1E .tl_set:c = { l_yshift_#1E_tl }, yshift-#1E .initial:n = {#4},
distan-#1C .tl_set:c = { l_distan_#1C_tl }, distan-#1C .initial:n = {#5},
distan-#1D .tl_set:c = { l_distan_#1D_tl }, distan-#1D .initial:n = {#6},
distan-#1E .tl_set:c = { l_distan_#1E_tl }, distan-#1E .initial:n = {#7},
angles-#1C .tl_set:c = { l_angles_#1C_tl }, angles-#1C .initial:n = {#8},
angles-#1D .tl_set:c = { l_angles_#1D_tl }, angles-#1D .initial:n = {#8},
angles-#1E .tl_set:c = { l_angles_#1E_tl }, angles-#1E .initial:n = {#8},
anglee-#1C .tl_set:c = { l_anglee_#1C_tl }, anglee-#1C .initial:n = {#9},
anglee-#1D .tl_set:c = { l_anglee_#1D_tl }, anglee-#1D .initial:n = {#9},
anglee-#1E .tl_set:c = { l_anglee_#1E_tl }, anglee-#1E .initial:n = {#9},
}
}
\__tikzmkpd_define_numeric_keys:nnnnnnnnn
{ A } { 1.7ex } { 1.7ex } { 1.7ex } { 1ex } { 2ex } { 3ex } { 60 } { 120 }
\__tikzmkpd_define_numeric_keys:nnnnnnnnn
{ B }{ -0.5ex }{ -0.5ex }{ -0.5ex } { 1ex } { 2ex } { 3ex } {-60 } {-120 }
\cs_new_protected:Npn \__tikzmkpd_define_colour_keys:nnnn #1#2#3#4
{
\keys_define:nn { tikzmkpd/_private_/config-#1 }
{
colour-#1C .tl_set:c = { l_colour_#1C_tl }, colour-#1C .initial:n = {#2},
colour-#1D .tl_set:c = { l_colour_#1D_tl }, colour-#1D .initial:n = {#3},
colour-#1E .tl_set:c = { l_colour_#1E_tl }, colour-#1E .initial:n = {#4},
}
}
\__tikzmkpd_define_colour_keys:nnnn { A } { red } { green } { blue }
\__tikzmkpd_define_colour_keys:nnnn { B } { red } { green } { blue }
\keys_define:nn { tikzmkpd / config-A }
{
yshift-A .tl_set:c = { l_yshift_A_tl },
yshift-A .initial:n = { 1.7ex },
end-yshift .code:n = { \__tikzmkpd_set_subkeys:nnn { A } { yshift } {#1} },
angle-star .code:n = { \__tikzmkpd_set_subkeys:nnn { A } { angles } {#1} },
angle-end .code:n = { \__tikzmkpd_set_subkeys:nnn { A } { anglee } {#1} },
distance .code:n = { \__tikzmkpd_set_subkeys:nnn { A } { distan } {#1} },
color .code:n = { \__tikzmkpd_set_subkeys:nnn { A } { colour } {#1} },
raise .meta:n = { yshift-A = {#1}, end-yshift = {#1,#1,#1} },
}
\keys_define:nn { tikzmkpd / config-B }
{
yshift-B .tl_set:c = { l_yshift_B_tl },
yshift-B .initial:n = { -0.5ex },
end-yshift .code:n = { \__tikzmkpd_set_subkeys:nnn { B } { yshift } {#1} },
angle-star .code:n = { \__tikzmkpd_set_subkeys:nnn { B } { angles } {#1} },
angle-end .code:n = { \__tikzmkpd_set_subkeys:nnn { B } { anglee } {#1} },
distance .code:n = { \__tikzmkpd_set_subkeys:nnn { B } { distan } {#1} },
color .code:n = { \__tikzmkpd_set_subkeys:nnn { B } { colour } {#1} },
raise .meta:n = { yshift-B = {#1}, end-yshift = {#1,#1,#1} },
}
\cs_new:Npn \__tikzmkpd_subs_i:nnn #1#2#3
{ \exp_not:n { #1-#2C = {#3} } }
\cs_new:Npn \__tikzmkpd_subs_ii:nnnn #1#2#3#4
{ \exp_not:n { #1-#2C= {#3}, #1-#2D= {#4} } }
\cs_new:Npn \__tikzmkpd_subs_iii:nnnnn #1#2#3#4#5
{ \exp_not:n { #1-#2C= {#3}, #1-#2D= {#4}, #1-#2E= {#5} } }
\cs_generate_variant:Nn \__tikzmkpd_subs_i:nnn { nnV }
\cs_generate_variant:Nn \__tikzmkpd_subs_ii:nnnn { nnVV }
\cs_generate_variant:Nn \__tikzmkpd_subs_iii:nnnnn { nnVVV }
\cs_generate_variant:Nn \keys_set:nn { nx }
\tl_new:N \l__tikzmkpd_tmp_tl
\cs_new_protected:Npn \__tikzmkpd_set_subkeys:nnn #1#2#3
{
\clist_set:Nn \l_tmpa_clist {#3}
\bool_if:nT { \int_compare_p:n { \clist_count:n {#3} = 1 } }
{
\tl_set:Nx \l_tmpa_tl { \clist_item:Nn \l_tmpa_clist {1} }
\keys_set:nx
{ tikzmkpd/_private_/config-#1 }
{ \__tikzmkpd_subs_i:nnV {#2} {#1} \l_tmpa_tl }
}
\bool_if:nT { \int_compare_p:n { \clist_count:n {#3} = 2 } }
{
\tl_set:Nx \l_tmpa_tl { \clist_item:Nn \l_tmpa_clist {1} }
\tl_set:Nx \l_tmpb_tl { \clist_item:Nn \l_tmpa_clist {2} }
\keys_set:nx
{ tikzmkpd/_private_/config-#1 }
{ \__tikzmkpd_subs_ii:nnVV {#2} {#1} \l_tmpa_tl \l_tmpb_tl }
}
\bool_if:nT { \int_compare_p:n { \clist_count:n {#3} = 3 } }
{
\tl_set:Nx \l_tmpa_tl { \clist_item:Nn \l_tmpa_clist {1} }
\tl_set:Nx \l_tmpb_tl { \clist_item:Nn \l_tmpa_clist {2} }
\tl_set:Nx \l__tikzmkpd_tmp_tl { \clist_item:Nn \l_tmpa_clist {3} }
\keys_set:nx
{ tikzmkpd/_private_/config-#1 }
{ \__tikzmkpd_subs_iii:nnVVV {#2} {#1} \l_tmpa_tl \l_tmpb_tl
\l__tikzmkpd_tmp_tl }
}
}
\seq_new:N \l__tikzmkpd_mycmd_seq
\cs_new_protected:Npn \__tikzmkpd_store_node_names:nn #1#2
{
\seq_set_from_clist:Nn \l__tikzmkpd_mycmd_seq {#2}
\seq_indexed_map_inline:Nn \l__tikzmkpd_mycmd_seq
{
\tl_clear_new:c { l__tikzmkpd_nodename_#1##1_tl }
\tl_set:cn { l__tikzmkpd_nodename_#1##1_tl } {##2}
}
}
% case 1: a(c+d) A1(B1+B2)
\cs_new_protected:Npn \__tikzmkpd_case_one:
{
\draw[->, \tl_use:c{l_colour_AC_tl}]
([yshift=\tl_use:c{l_yshift_A_tl}]$(pic ~ cs \tl_to_str:n { : } \tl_use:c { l__tikzmkpd_nodename_A1_tl})$)
to[out=\tl_use:c{l_angles_AC_tl}, in=\tl_use:c{l_anglee_AC_tl},
distance=\tl_use:c{l_distan_AC_tl}]
([yshift=\tl_use:c{l_yshift_AC_tl}]$(pic ~ cs \tl_to_str:n { : } \tl_use:c { l__tikzmkpd_nodename_B1_tl})$);
\draw[->,\tl_use:c{l_colour_AD_tl}]
([yshift=\tl_use:c{l_yshift_A_tl}]$(pic ~ cs \tl_to_str:n { : } \tl_use:c { l__tikzmkpd_nodename_A1_tl})$)
to[out=\tl_use:c{l_angles_AD_tl}, in=\tl_use:c{l_anglee_AD_tl},
distance=\tl_use:c{l_distan_AD_tl}]
([yshift=\tl_use:c{l_yshift_AD_tl}]$(pic ~ cs \tl_to_str:n { : } \tl_use:c { l__tikzmkpd_nodename_B2_tl})$);
}
% case 2: a(c+d+e) A1(B1+B2+B3)
\cs_new_protected:Npn \__tikzmkpd_case_two:
{
\__tikzmkpd_case_one:
\draw[->, \tl_use:c{l_colour_AE_tl}]
([yshift=\tl_use:c{l_yshift_A_tl}]$(pic ~ cs \tl_to_str:n { : } \tl_use:c { l__tikzmkpd_nodename_A1_tl})$)
to[out=\tl_use:c{l_angles_AE_tl}, in=\tl_use:c{l_anglee_AE_tl},
distance=\tl_use:c{l_distan_AE_tl}]
([yshift=\tl_use:c{l_yshift_AE_tl}]$(pic ~ cs \tl_to_str:n { : } \tl_use:c { l__tikzmkpd_nodename_B3_tl})$);
}
% case 3: (a+b)(c+d) (A1+A2)(B1+B2)
\cs_new_protected:Npn \__tikzmkpd_case_three:
{
\__tikzmkpd_case_one:
\draw[->,\tl_use:c{l_colour_BC_tl}]
([yshift=\tl_use:c{l_yshift_B_tl}]$(pic ~ cs \tl_to_str:n { : } \tl_use:c { l__tikzmkpd_nodename_A2_tl})$)
to[out=\tl_use:c{l_angles_BC_tl},in=\tl_use:c{l_anglee_BC_tl},
distance=\tl_use:c{l_distan_BC_tl}]
([yshift=\tl_use:c{l_yshift_BC_tl}]$(pic ~ cs \tl_to_str:n { : } \tl_use:c { l__tikzmkpd_nodename_B1_tl})$);
\draw[->,\tl_use:c{l_colour_BD_tl}]
([yshift=\tl_use:c{l_yshift_B_tl}]$(pic ~ cs \tl_to_str:n { : } \tl_use:c { l__tikzmkpd_nodename_A2_tl})$)
to[out=\tl_use:c{l_angles_BD_tl},in=\tl_use:c{l_anglee_BD_tl},
distance=\tl_use:c{l_distan_BD_tl}]
([yshift=\tl_use:c{l_yshift_BD_tl}]$(pic ~ cs \tl_to_str:n { : } \tl_use:c { l__tikzmkpd_nodename_B2_tl})$);
}
% case 4: (a+b)(c+d+e) (A1+A2)(B1+B2+B3)
\cs_new_protected:Npn \__tikzmkpd_case_four:
{
\__tikzmkpd_case_three:
\draw[->,\tl_use:c{l_colour_AE_tl}]
([yshift=\tl_use:c{l_yshift_A_tl}]$(pic ~ cs \tl_to_str:n { : } \tl_use:c { l__tikzmkpd_nodename_A1_tl})$)
to[out=\tl_use:c{l_angles_AE_tl},in=\tl_use:c{l_anglee_AE_tl},
distance=\tl_use:c{l_distan_AE_tl}]
([yshift=\tl_use:c{l_yshift_AE_tl}]$(pic ~ cs \tl_to_str:n { : } \tl_use:c { l__tikzmkpd_nodename_B3_tl})$);
\draw[->,\tl_use:c{l_colour_BE_tl}]
([yshift=\tl_use:c{l_yshift_B_tl}]$(pic ~ cs \tl_to_str:n { : } \tl_use:c { l__tikzmkpd_nodename_A2_tl})$)
to[out=\tl_use:c{l_angles_BE_tl},in=\tl_use:c{l_anglee_BE_tl},
distance=\tl_use:c{l_distan_BE_tl}]
([yshift=\tl_use:c{l_yshift_BE_tl}]$(pic ~ cs \tl_to_str:n { : } \tl_use:c { l__tikzmkpd_nodename_B3_tl})$);
}
\keys_define:nn { tikzmkpd }
{
config-A .code:n = { \keys_set:nn { tikzmkpd / config-A } {#1} },
config-B .code:n = { \keys_set:nn { tikzmkpd / config-B } {#1} },
}
\cs_new_protected:Npn \tikzmkpd:nnn #1#2#3
{
\group_begin:
\keys_set:nn { tikzmkpd } {#1}
\__tikzmkpd_store_node_names:nn {A} {#2}
\__tikzmkpd_store_node_names:nn {B} {#3}
\tikzset{>={Straight ~ Barb[length=1.5pt,round,bend]}}
\begin{tikzpicture}[overlay, remember ~ picture]
\bool_if:nT
{
\int_compare_p:n { \clist_count:n {#2} = 1 } &&
\int_compare_p:n { \clist_count:n {#3} = 2 }
}
{ \__tikzmkpd_case_one: }
\bool_if:nT
{
\int_compare_p:n { \clist_count:n {#2} = 1 } &&
\int_compare_p:n { \clist_count:n {#3} = 3 }
}
{ \__tikzmkpd_case_two: }
\bool_if:nT
{
\int_compare_p:n { \clist_count:n {#2} = 2 } &&
\int_compare_p:n { \clist_count:n {#3} = 2 }
}
{ \__tikzmkpd_case_three: }
\bool_if:nT
{
\int_compare_p:n { \clist_count:n {#2} = 2 } &&
\int_compare_p:n { \clist_count:n {#3} = 3 }
}
{ \__tikzmkpd_case_four: }
\end{tikzpicture}
\group_end:
}
\NewDocumentCommand \tikzmkpd { O{} m m }
{
\tikzmkpd:nnn {#1} {#2} {#3}
}
\ExplSyntaxOff
\newcommand*{\TkM}[2]{\tikzmarknode{#1}{#2}} % short :)
\setlength{\parindent}{0pt} % just for the example
\pagestyle{empty}
\begin{document}
\section{case 1}
$\TkM{A}{2a^2}(\TkM{B}{b}+\TkM{D}{3q})$%
\tikzmkpd[config-A={raise=12pt}]%
{A}{B, D}
\section{case 2}
$\TkM{a1}{2p}\left(\TkM{b1}{3q}+\TkM{c1}{4r}+\TkM{d1}{1}\right)$%
\tikzmkpd[config-A={color={gray,gray,gray}, end-yshift={5pt,5pt,5pt}}]%
{a1}{b1, c1, d1}
\section{case 3}
$(\TkM{X1}{2a^2}+\TkM{X2}{n})(\TkM{Y1}{b}+\TkM{Y2}{3q})$%
\tikzmkpd{X1,X2}{Y1,Y2}
\section{case 4}
$(\TkM{a}{x}-\TkM{b}{2})(\TkM{c}{x^2}+\TkM{d}{2x}+\TkM{e}{4})$
\tikzmkpd[config-B={end-yshift={-15pt,-15pt},color={gray,red}}]{a,b}{c, d, e}
\tikzmkpd[config-A={raise=4pt,color={gray,gray,gray}}]%
{A}{B, D}
\end{document}

Footnote
- For such temporary code, you can use TeX or LaTeX2e commands such as
\show or \typeout, as well as LaTeX3 ones such as \tl_show:N or \box_show:N.
config-B). Related to(pic cs), in my case it works well, the problem is intikzmark(https://github.com/loopspace/tikzmark/issues/9) in my case I have installed the version fromgit. And it's true, mixingpgfkeyswithl3keydoesn't seem like a good idea, but, I just want to modify those parameters and not the rest of thetikzoptions, so from my point of view it's fine. I must study more about the use of variants and expansion inexpl3. Gracias Totales :) – Pablo González L Jun 10 '19 at 12:51l3keysfor TikZ work; what I'm saying is that you could have completely separated the parsing issue from the TikZ one as part of reducing your example to something minimal. And probably you would have found the problem yourself while doing so, because you would likely have seen then what was happening when preparing the options destined to TikZ. – frougon Jun 10 '19 at 16:20\debug_on:n { check-declarations , deprecation }and\tl_show:Nalong with a more accurate reading of theexpl3documentation should have been my starting point. Theyshift-Akey doesn't work, I'll add the use of(pic cs)and this solves my problem. Thanks again. – Pablo González L Jun 10 '19 at 16:52yshift-Atoo. It was a TikZ parsing (syntax) problem—don't ask me why the other quite similar cases work. As can be seen with\tl_show:N,\l_yshift_A_tlwas quite fine in\__tikzmkpd_case_one:and\__tikzmkpd_case_two:even before this edit (i.e., all the LaTeX3 option parsing code was working as designed). – frougon Jun 10 '19 at 18:59yshift-Ainside\__tikzmkpd_define_numericand also failed,TikZis a bit dark and difficult to understand in certain points. Until next time and thank you for the programming lesson and debug inLaTeX|expl3. – Pablo González L Jun 10 '19 at 19:43etoolboxpackage for the use of\seq_indexed_map_inline:Nnfrom the response given by @egreg at (https://tex.stackexchange.com/a/496604/7832), just with the idea of having one more code in theexpl3line. Saludos – Pablo González L Jun 23 '19 at 16:49\seq_indexed_map_inline:Nnin principle, but I don't remember introducing the dependency onetoolboxmyself here. I see it's used for\csxdef(which could be replaced byexpl3stuff but not by\seq_indexed_map_inline:Nn), however this command was in your original code, it's not from me either. What else is there that you'd like to convert? Can you post the new file somewhere, or a diff for instance on https://pastebin.com (or an additional answer you'll cancel, I don't know...)? Thanks. – frougon Jun 23 '19 at 17:21\csxdef(sorry, there was some disturbance around...). It seems okay to me in principle. – frougon Jun 23 '19 at 17:28:nvalues in the key definitions. 2) Private function names (\__tikzmkpd_pass_comma_args:nn) start with two underscores after the backslash. 3)\l__tikzmkpd_mycmd_seqwasn't declared. I'll fix these and see the rest, no need to fix them on your side. – frougon Jun 23 '19 at 18:28l_tikzmkpd_#1##1_tlmeans the variable is public (and local), is it what you intended? Otherwise, usel__tikzmkpd_#1##1_tl. And I would add something else (fixed string) to the name to avoid any clash with the other cs names in case of particular user input. – frougon Jun 23 '19 at 18:35_and__. – Pablo González L Jun 23 '19 at 18:37l_tikzmkpd_#1##1_tl, search&replace onl_tikzmkpd_seems safe. To avoid clashes (as said) and declare it as private, I propose the namel__tikzmkpd_nodename_#1##1_tl. What do you think? – frougon Jun 23 '19 at 18:46l__tikzmkpd_nodename_#1##1_tlis much more natural for me :) – Pablo González L Jun 23 '19 at 18:48pic csproblem, but since you say it is fixed in PGF/TikZ Git, I have included yours at the end of the post, with my fixes applied. You can retest it and add a screenshot if you want (at the end, right after the code). I can compile your version but the rendering is not correct, so no screenshot. I included as much as I could in my version, though, so the only differences are in the TikZ code and the new cases, “three” and “four” (+ settings in the first tests that would... – frougon Jun 23 '19 at 19:43tikzmark). Grateful for your time :) – Pablo González L Jun 23 '19 at 19:57{ #2 }→{#2}and\cs_new_protected:Npn \__tikzmkpd_store_node_names:nn #1 #2→\cs_new_protected:Npn \__tikzmkpd_store_node_names:nn #1#2(spaces removed). These are from the recommendations in l3styleguide.pdf. – frougon Jun 23 '19 at 20:03l3keys:key1 = {subkey1=value1, subkey2=value2, ...}, ...” (note: backquotes don't “work” in titles, AFAIK). BTW, I suppose that renaming the question would break the link one can find on your board (I know one can have a permalink for the question, though...). – frougon Jun 23 '19 at 20:45