% !TeX encoding = UTF-8 % Ce fichier contient le code de l'extension "chemfig" % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % \def\CFname {chemfig} % \def\CFver {1.71} % % % \def\CFdate {2025/10/30} % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % %____________________________________________________________________ % Author : Christian Tellechea | % Status : Maintained | % Email : unbonpetit@netc.fr | % Package URL: https://www.ctan.org/pkg/chemfig | % Copyright : Christian Tellechea 2010-2025 | % Licence : Released under the LaTeX Project Public License v1.3c | % or later, see http://www.latex-project.org/lppl.txt | % Files : 1) chemfig.tex | % 2) chemfig.sty | % 3) README | % 4) chemfig_doc_fr.tex | % 5) chemfig_doc_fr.pdf | % 6) chemfig_doc_en.tex | % 7) chemfig_doc_fr.pdf | % 8) chemfig-lewis.tex | % 9) changelog.tex | %-------------------------------------------------------------------- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% P R É A L A B L E %%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \csname CFloadonce\endcsname \let\CFloadonce\endinput %-------------------------- Annonce package -------------------------- \ifdefined\CFfromsty\else \immediate\write -1 {% Package: \CFname\space\CFdate\space\space v\CFver\space\space Draw molecule with an easy syntax (CT)}% \fi %-------------------------- Régime catcodes -------------------------- \begingroup \def\X#1{\catcode\number`#1=\number\catcode`#1\relax} \xdef\CFrestorecatcode{\X\[\X\]\X\:\X\(\X\)\X\,\X\-\X\=\X\~\X\!\X\?\X\<\X\>\X\;\X\*\X\|\X\@\X\ \X\_}% \endgroup \catcode`\[12 \catcode`\]12 \catcode`\:12 \catcode`\(12 \catcode`\)12 \catcode`\,12 \catcode`\-12 \catcode`\=12 \catcode`\~12 \catcode`\!12 \catcode`\?12 \catcode`\<12 \catcode`\>12 \catcode`\;12 \catcode`\*12 \catcode`\|12 \catcode`\@12 \catcode`\#6 \catcode`\ 10 \catcode`\_11 %-------------------- Vérification des prérequis --------------------- \def\CF_error#1{\errmessage{Package \CFname\space Error: #1.}} \def\CF_warning#1{\immediate\write-1{Package \CFname\space Warning: #1^^J}} \def\CF_checkprimitive#1#2{% Vérifie que #1 est une primitive et sinon, émet le message #2 et exécute \endinput \begingroup \edef\__tempa{\meaning#1}% \edef\__tempb{\string#1}% \expandafter \endgroup \ifx\__tempa\__tempb\else \CF_error{#2}% \def\CF_temp{\CFrestorecatcode\endinput}% \expandafter\CF_temp \fi } \CF_checkprimitive\eTeXversion{You are not using an eTeX engine, \CFname\space cannot work.} \CF_checkprimitive\expanded{the \string\expanded\space primitive is not provided by your TeX engine, \CFname\space cannot work.} %------------------------ Chargement simplekv ------------------------ \input simplekv.tex %-------------------------- Chargement tikz -------------------------- \unless\ifdefined\tikzpicture \begingroup\def\CF_temp{\endgroup\input tikz.tex\relax}% \expandafter\CF_temp \fi \usetikzlibrary{arrows.meta} %--------------------------- Allocations ----------------------------- \newcount\CF_cnt_atomgroup \newcount\CF_cnt_group \newcount\CF_cnt_atom \newcount\CF_cnt_cycle \newcount\CF_cnt_cyclebonds \newcount\CF_cnt_compound \newif\ifCF_in_cycle \newif\ifCF_cycle_arc \newif\ifCF_define_submol \newif\ifCF_adjust_name_dp \newif\ifCF_macro_fixed_bond_length \newif\ifCF_compound_is_chemfig \newdimen\CF_dim \newdimen\CF_turnangle \newdimen\CF_arrowsize \newdimen\CF_zero \CF_zero=0pt \newbox\CF_box \newbox\CF_boxstuff \newbox\CF_testbox \newbox\CF_chargebox \newtoks\CF_substtoks %-------------------------- Petites macros --------------------------- \let\CF_begintikzpicture\tikzpicture \let\CF_endtikzpicture \endtikzpicture \def\CF_quark{\CF_quark} \def\CF_execfirst#1#2{#1} \def\CF_execsecond#1#2{#2} \def\CF_id#1{#1} \def\CF_gobarg#1{} \def\CF_gobtwoargs#1#2{} \def\CF_firsttonil#1#2\_nil{#1} \def\CF_sanitizelastitem#1,\empty#2\_nil{#1} \def\CF_gobtikzinstruction#1;{} \def\CF_makeother#1{\catcode`#1=12\relax} \def\CF_lettoken#1#2{\let#1= #2} \CF_lettoken\CF_sptoken{ } \def\CF_ifx#1#2{\ifx#1#2\expandafter\CF_execfirst\else\expandafter\CF_execsecond\fi} \def\CF_ifempty#1{\ifx\empty#1\empty\expandafter\CF_execfirst\else\expandafter\CF_execsecond\fi} \def\CF_ifnum#1{\ifnum#1\expandafter\CF_execfirst\else\expandafter\CF_execsecond\fi} \def\CF_ifinsidetikz{\ifdefined\pgfpictureid\expandafter\CF_execfirst\else\expandafter\CF_execsecond\fi} \def\CF_ifzerodim#1{%r bugfix 1.71 : rollback à v1.66 ! \setbox\CF_testbox\hbox{\pgfinterruptpicture\printatom{#1}\endpgfinterruptpicture}% bugfix 1.53 \CF_ifnum{1\ifdim\wd\CF_testbox=\CF_zero0\fi\ifdim\ht\CF_testbox=\CF_zero0\fi\ifdim\dp\CF_testbox=\CF_zero0\fi=1000 } } \def\CF_doifempty#1{\ifx\empty#1\empty\expandafter\CF_id\else\expandafter\CF_gobarg\fi} \def\CF_doifnotempty#1{\ifx\empty#1\empty\expandafter\CF_gobarg\else\expandafter\CF_id\fi} \def\CF_gobtonil#1\_nil{} \def\CF_striplastsp#1{% \long\def\CF_stripsp##1##2{\expanded{\CF_stripsp_i\_marksp##1\__nil\_marksp#1\_marksp\_nil{##2}}}% \long\def\CF_stripsp_i##1\_marksp#1##2\_marksp##3\_nil{\CF_stripsp_ii##3##1##2\__nil#1\__nil\_nil}% \long\def\CF_stripsp_ii##1#1\__nil##2\_nil{\CF_stripsp_iii##1##2\_nil}% \long\def\CF_stripsp_iii##1##2\__nil##3\_nil##4{\unexpanded{##4{##2}}}% \long\def\CF_striplastsp##1##2{\expanded{\CF_striplastsp_i\_marksp##1\__nil#1\__nil\_nil{##2}}}% \long\def\CF_striplastsp_i##1#1\__nil##2\_nil{\CF_stripsp_iii##1\__nil\_nil}% }\CF_striplastsp{ } \edef\CFhash{\string#} \begingroup \catcode`\_8 \expandafter\gdef\csname CF\string_underscore\endcsname{_} \endgroup \def\CF_threeea{\expandafter\expandafter\expandafter} \def\CF_exptwomacroargs#1#2#3{\CF_expsecond{\CF_expsecond#1{#2}}{#3}} \def\CF_expthreemacroargs#1#2#3#4{\CF_expsecond{\CF_exptwomacroargs#1{#2}{#3}}{#4}} \def\CF_swaparg#1#2{#2{#1}} \def\CF_expsecond#1#2{\expandafter\CF_swaparg\expandafter{#2}{#1}}% \CF_expsecond<{arg1>}{} donne "{*}" \def\CF_eexpsecond#1#2{\expandafter\expandafter\expandafter\CF_swaparg\expandafter\expandafter\expandafter{#2}{#1}}% \CF_eexpsecond{}{} donne "{**}" \def\CF_swapunbrace#1#2{#2#1} \def\CF_expafter#1#2{\expandafter\CF_swapunbrace\expandafter{#2}{#1}}% \CF_expafter{}{} donne "*" \def\CF_eexpafter#1#2{\expandafter\expandafter\expandafter\CF_swapunbrace\expandafter\expandafter\expandafter{#2}{#1}}% \CF_eexpafter{}{} donne "**" \def\CF_addtomacro#1#2{\CF_expsecond{\def#1}{#1#2}} \def\CF_eaddtomacro#1#2{\CF_expsecond{\CF_addtomacro#1}{#2}} \def\CF_preaddtomacro#1#2{\CF_expsecond{\CF_preaddtomacroa#1{#2}}#1} \def\CF_preaddtomacroa#1#2#3{\def#1{#2#3}} \def\CF_addtotoks#1#2{#1\expandafter{\the#1#2}} \def\CF_eaddtotoks#1#2{\expandafter\CF_addtotoks\expandafter#1\expandafter{#2}} \def\CF_assigntonil#1#2\_nil{\def#1{#2}} \def\CF_edefaddtomacro#1#2{\CF_expsecond{\CF_addtomacro#1}{\expanded{#2}}} \def\CF_ifnextchar#1#2#3{% \let\CF_ifnextchartok=#1% <- espace indésirable, bugfix v1.31 \def\CF_ifnextcharcodetrue{#2}% \def\CF_ifnextcharcodefalse{#3}% \futurelet\CF_temptok\CF_ifnextchara } \def\CF_ifnextchara{% \CF_ifx\CF_temptok\CF_sptoken {% \CF_ifnextcharb } {% \CF_ifx\CF_temptok\CF_ifnextchartok \CF_ifnextcharcodetrue \CF_ifnextcharcodefalse }% } \expandafter\def\expandafter\CF_ifnextcharb\space{\futurelet\CF_temptok\CF_ifnextchara} \def\CF_ifstar#1{\CF_ifnextchar*{\CF_execfirst{#1}}} \def\CF_testopt#1#2{\CF_ifnextchar[{#1}{#1[{#2}]}} \def\CF_ifinteger#1{% \begingroup \afterassignment\CF_afterinteger \CF_cnt_cyclebonds0#1\relax } \def\CF_afterinteger#1\relax{% \endgroup \CF_ifempty{#1}% } \def\CF_iffirsttokmatch#1#2{% est ce que #1 et #2 commencent par les mêmes tokens ? \futurelet\CF_toksa\CF_gobtonil#1\relax\_nil \futurelet\CF_toksb\CF_gobtonil#2\relax\_nil \CF_ifx\CF_toksa\CF_toksb } \def\CF_iffirsttokin#1{% teste si le token qui commence #1 appartient aux tokens mis dans #2 \futurelet\CF_toksa\CF_gobtonil#1\relax\_nil \CF_iffirsttokina } \def\CF_iffirsttokina#1{% \CF_ifempty{#1} {% \CF_execsecond } {% \futurelet\CF_toksb\CF_gobtonil#1\relax\_nil \CF_ifx\CF_toksa\CF_toksb {% \CF_execfirst } {% \CF_expsecond\CF_iffirsttokina{\CF_gobarg#1}% }% }% } \def\CF_ifinstr#1#2{% \def\CF_ifinstra##1#2##2\_nil{% \ifx\empty##2\empty \expandafter\CF_execsecond \else \expandafter\CF_execfirst \fi}% \CF_ifinstra#1\__nil#2\_nil } \def\CF_afterspace#1 #2\_nil{#2} \def\CF_ifxcase_endif{\CF_ifxcase_endif} \def\CF_ifxcase_elseif{\CF_ifxcase_elseif} \def\CF_idto_endif#1\CF_ifxcase_endif{#1} \def\CF_firstto_endif#1#2\CF_ifxcase_endif{#1} \def\CF_ifxcase#1#2{% #1=token à tester #2=token courant auquel #1 est comparé \CF_ifx\CF_ifxcase_elseif#2% {% \CF_idto_endif } {% \CF_ifx\CF_ifxcase_endif#2% {} {% \CF_ifx#1#2 {\CF_firstto_endif} {\CF_ifxcase_a#1}% }% }% } \def\CF_ifxcase_a#1#2{\CF_ifxcase{#1}} %--------------------------- Substitution ---------------------------- \def\CF_ifstartwith#1#2{% #1= #2= \CF_ifempty{#1}% {% \CF_execsecond } {% \def\CF_startwithcode{#1}% \def\CF_startwithpattern{#2}% \CF_ifstartwitha }% } \def\CF_ifstartwitha{% \CF_grabfirstarg\CF_startwithcode\CF_firstargcode \CF_grabfirstarg\CF_startwithpattern\CF_firstargpattern \CF_ifx\CF_firstargcode\CF_firstargpattern {% \CF_expsecond\CF_ifempty\CF_startwithpattern {% \CF_execfirst } {% \CF_expsecond\CF_ifempty\CF_startwithcode \CF_execsecond \CF_ifstartwitha }% } {% \CF_execsecond }% } \def\CF_grabfirstarg#1#2{% \CF_ifx#1\empty {% \let#2\empty } {% \def\CF_grabmacro{#2}% \CF_expsecond\CF_ifbracefirst#1% {% \expandafter\CF_grabbracearg#1\_nil#1% } {% \CF_expafter{\futurelet\CF_nexttok\CF_grabfirstarga}#1\_nil#1% }% }% } \def\CF_grabfirstarga{% \CF_ifx\CF_nexttok\CF_sptoken \CF_grabspacearg \CF_grabnormalarg } \def\CF_grabbracearg#1{% \expandafter\def\CF_grabmacro{{#1}}% \CF_grabargassigntonil\relax } \expandafter\def\expandafter\CF_grabspacearg\space{% \expandafter\def\CF_grabmacro{ }% \CF_grabargassigntonil\relax } \def\CF_grabnormalarg#1{% \expandafter\def\CF_grabmacro{#1}% \CF_grabargassigntonil\relax } \def\CF_grabargassigntonil#1\_nil#2{\CF_expsecond{\def#2}{\CF_gobarg#1}} \def\CF_ifbracefirst#1{\CF_ifnum{\catcode\CF_threeea`\expandafter\CF_firsttonil\detokenize{#1.}\_nil=1 }} \def\CF_substonly#1#2{% #1=entier maxi>0 #2=macro : dans la sc#1, remplace tous les par sauf lorsque le motif est suivi d'un caractère >#1 \def\CF_atendsubstitute{\edef#2{\the\CF_substtoks}}% macro exécutée à la fin \let\CF_substnogroups\CF_substnogrouponly \CF_ifnum{#1>0 } {% \let\CF_testifx\empty \foreach\CF_x in {1,...,#1} {% \xdef\CF_testifx{\unexpanded\expandafter{\CF_testifx}\unexpanded\expandafter{\expandafter\ifx\CF_x\CF_nexttok1\fi}}% }% \let\CF_testif\empty \foreach\CF_x in {1,...,#1} {% \xdef\CF_testif{\unexpanded\expandafter{\CF_testif}\unexpanded\expandafter{\expandafter\if\CF_x\CF_nexttok1\fi}}% }% \CF_expsecond\CF_substi#2% } {% \CF_substall#2% }% } \def\CF_substnogrouponly{% \CF_exptwomacroargs\CF_ifstartwith\CF_substcode\CF_substsubst {% \CF_grabfirstarg\CF_substcode\CF_temp \CF_expafter{\futurelet\CF_nexttok\CF_gobtonil}\CF_substcode\relax\_nil \CF_ifnum{0\CF_testifx=1 }% si le prochain token est \let-égal à 1...#1 {% \edef\CF_nexttok{\CF_threeea\CF_firsttonil\expandafter\string\CF_substcode\_nil}% le détokéniser \CF_ifnum{0\CF_testif=1 } {% \CF_eaddtotoks\CF_substtoks\CF_temp \CF_grabfirstarg\CF_substcode\CF_temp \CF_eaddtotoks\CF_substtoks\CF_temp } {% \CF_eaddtotoks\CF_substtoks\CF_substpattern }% } {% \CF_eaddtotoks\CF_substtoks\CF_substpattern }% \CF_substgroups } {% \CF_expsecond\CF_ifempty\CF_substcode {% \CF_atendsubstitute } {% \CF_grabfirstarg\CF_substcode\CF_substauxarg \CF_eaddtotoks\CF_substtoks\CF_substauxarg \CF_substgroups }% }% } \def\CF_substall#1{% #1=macro \def\CF_atendsubstitute{\edef#1{\the\CF_substtoks}}% macro exécutée à la fin \let\CF_substnogroups\CF_substnogroupall \CF_expsecond\CF_substi#1% } \def\CF_substnogroupall{% \CF_exptwomacroargs\CF_ifstartwith\CF_substcode\CF_substsubst {% \CF_eaddtotoks\CF_substtoks\CF_substpattern \CF_grabfirstarg\CF_substcode\CF_temp \CF_substgroups } {% \CF_expsecond\CF_ifempty\CF_substcode {% \CF_atendsubstitute } {% \CF_grabfirstarg\CF_substcode\CF_substauxarg \CF_eaddtotoks\CF_substtoks\CF_substauxarg \CF_substgroups }% }% } \def\CF_substi#1#2#3{% #1= #2= #3= \def\CF_substcode{#1}\def\CF_substsubst{#2}\def\CF_substpattern{#3}% \CF_substtoks={}% \CF_substgroups } \def\CF_substgroups{% \CF_expsecond\CF_ifbracefirst\CF_substcode {% \CF_grabfirstarg\CF_substcode\CF_substauxarg \begingroup \def\CF_atendsubstitute{% \expandafter\endgroup\expandafter\CF_addtotoks\expandafter\CF_substtoks\expandafter{\expandafter{\the\CF_substtoks}}% \CF_substgroups }% \CF_substtoks{}% initialiser à vide \expandafter\def\expandafter\CF_substcode\CF_substauxarg \CF_substgroups }% {% \CF_substnogroups }% } %---------------------------- Paramètres ----------------------------- \def\CF_defifempty#1#2#3{\CF_ifempty{#2}{\def#1{#3}}{\def#1{#2}}} \defKV[chemfig]{% atom style = \def\CF_atomstyle {#1}, baseline = \CF_defifempty\CF_baseline {#1}{0pt},% nouveau v 1.6e chemfig style = \def\CF_chemfigstyle {#1}, cram width = \CF_defifempty\CF_crambasewidth {#1}{1.5ex}, cram dash width = \CF_defifempty\CF_cramdashlength {#1}{1pt}, cram dash sep = \CF_defifempty\CF_cramdashsep {#1}{2pt}, atom sep = \CF_defifempty\CF_atomsep {#1}{3em}, bond offset = \CF_defifempty\CF_bondoffset {#1}{2pt}, double bond sep = \CF_defifempty\CF_doublesep {#1}{2pt}, angle increment = \CF_defifempty\CF_angleincrement {#1}{45}, node style = \def\CF_nodestyle {#1}, bond style = \def\CF_bondstyle {#1}, cycle radius coeff = \CF_defifempty\CF_cycleradiuscoeff {#1}{0.75}, stack sep = \CF_defifempty\CF_stacksep {#1}{1.5pt}, compound style = \def\CF_defaultcompoundstyle {#1}, compound sep = \CF_defifempty\CF_compoundsep {#1}{5em}, arrow offset = \CF_defifempty\CF_arrowoffset {#1}{1em}, arrow angle = \CF_defifempty\CF_arrowangle {#1}{0}, arrow coeff = \CF_defifempty\CF_arrowlength {#1}{1}, arrow style = \def\CF_defaultarrowstyle {#1}, arrow double sep = \CF_defifempty\CF_arrowdoublesep {#1}{2pt}, arrow double coeff = \CF_defifempty\CF_arrowdoubleposstart{#1}{0.6}, arrow label sep = \CF_defifempty\CF_arrowlabelsep {#1}{3pt}, arrow head = \CF_defifempty\CF_arrowhead {#1}{-CF}, init anchor = \CF_defifempty\CF_nextnodeanchor {#1}{text},% new v1.71 + sep left = \CF_defifempty\CF_signspaceante {#1}{0.5em}, + sep right = \CF_defifempty\CF_signspacepost {#1}{0.5em}, + vshift = \CF_defifempty\CF_signvshift {#1}{0pt}, harrow minwidth = \CF_defifempty\CF_harrow_min_width {#1}{3em}, label xsep = \CF_defifempty\CF_harrow_label_xsep {#1}{3pt}, label align = \CF_set_label_align {#1}, name sep = \CF_defifempty\CF_hreac_name_sep {#1}{1.5ex}, hreac anchor = \def\CF_hreac_init_anchor {#1}, hreac sep = \CF_defifempty\CF_hreac_sep {#1}{0.5em}, } \def\CF_set_label_align#1{% \let\CF_harrow_label_align_right\hss \let\CF_harrow_label_align_left \hss \expandafter\CF_ifxcase\CF_firsttonil#1c\_nil c {} l {\let\CF_harrow_label_align_left\empty} r {\let\CF_harrow_label_align_right\empty} \CF_ifxcase_elseif \CF_error{Illegal alignment directive '#1'}% \CF_ifxcase_endif } \def\setchemfig{\setKV[chemfig]} \def\resetchemfig{\restoreKV[chemfig]} \setKVdefault[chemfig]{% atom style = {},% code tikz mis à la fin de every node/.style use atom strut = false,% met à chaque atome le strut de l'atome précédent nouveau 1.7 baseline = {0pt},% nouveau v 1.6e chemfig style = {},% code tikz mis à la fin de l'arugment optionnel de \tikzpicture bond join = false, fixed length = false, cram rectangle = false, cram width = 1.5ex, cram dash width = 1pt, cram dash sep = 2pt, atom sep = 3em, bond offset = 2pt, double bond sep = 2pt, angle increment = 45, node style = {}, bond style = {}, cycle radius coeff = 0.75, stack sep = 1.5pt, autoreset cntcycle = true, show cntcycle = false, debug = false, scheme debug = false, compound style = {}, compound sep = 5em, arrow offset = 1em, arrow angle = 0, arrow coeff = 1, arrow style = {}, arrow double sep = 2pt, arrow double coeff = 0.6, arrow double harpoon= true, arrow label sep = 3pt, arrow head = -CF, init anchor = text, % new v1.71 + sep left = 0.5em, + sep right = 0.5em, + vshift = 0pt, gchemname = true, % ajout de cette clé v1.6c schemestart code = {}, % ajout de cette clé v1.6c schemestop code = {}, % ajout de cette clé v1.6c harrow minwidth = 3em, % dimension minimale de la flèche hreac debug = false, label xsep = 3pt, % dist H supplémentaire label align = c, % vaut c, l ou r name sep = 1.5ex, % distance v entre composé et nom hreac anchor = text, % ancre de la ligne de base du 1er composé hreac sep = 0.5em % espace horizontal entre composés }% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% D E S S I N M O L É C U L E S %%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \def\CF_sanitizecatcode{% \CF_makeother\[% \CF_makeother\]% \CF_makeother\:% \CF_makeother\(% \CF_makeother\)% \CF_makeother\,% \CF_makeother\-% \CF_makeother\=% \CF_makeother\~% \CF_makeother\!% \CF_makeother\?% \CF_makeother\<% \CF_makeother\>% \CF_makeother\;% \CF_makeother\*% \CF_makeother\|% \CF_makeother\#% \CF_makeother\@% } \def\printatom#1{\ifmmode\rm#1\else$\rm#1$\fi} \def\CF_nodecontent{% \CF_nodestrut = \empty si "use atom strut=true" \CF_eexpsecond\printatom{\csname atom_\number\CF_cnt_atom\expandafter\endcsname\CF_nodestrut}% } \def\chemskipalign{% \CF_doifempty\CF_bondoutcontentsaved% sauf si un \chemskipalign a été fait à l'atome précédent {% \global\let\CF_bondoutcontentsaved\CF_bondoutcontent% sauvegarder l'atome d'où vient la liaison }% \let\CF_nodestrut\empty } \def\definesubmol{\CF_define_submoltrue\CF_defsubmol} \def\redefinesubmol{\CF_define_submolfalse\CF_defsubmol} \def\CF_defsubmol#1{% \CF_cnt_atomgroup=0 % nombre d'arguments supposé \def\CF_temp{#1}% nom \futurelet\CF_toksa\CF_submoltestnxttok } \def\CF_submoltestnxttok{% \if[\noexpand\CF_toksa\expandafter\CF_execfirst\else\expandafter\CF_execsecond\fi {% \begingroup\CF_sanitizecatcode\CF_expsecond\CF_submolgrabopt{\CF_temp}% } {% \afterassignment\CF_submoltestnxttoka% pas d'argument entre crochet \CF_cnt_atomgroup=0% cherche le nombre d'arguments éventuels }% } \def\CF_submoltestnxttoka{\futurelet\CF_toksa\CF_submoltestnxttokb} \def\CF_submoltestnxttokb{% \if[\noexpand\CF_toksa\expandafter\CF_execfirst\else\expandafter\CF_execsecond\fi {% \begingroup\CF_sanitizecatcode\CF_expsecond\CF_submolgrabopt{\CF_temp}% } {% \CF_expsecond{\CF_defsubmola}\CF_temp{}% }% } \def\CF_submolgrabopt#1[#2]#{\endgroup\CF_defsubmola{#1}{#2}} \def\CF_defsubmola#1{% #1 nom \CF_ifnum{0\CF_ifnum{\CF_cnt_atomgroup<0 }1{\CF_ifnum{\CF_cnt_atomgroup>9 }10}>0 } {% \CF_error{Invalid number of arguments in submol \detokenize\expandafter{\string#1}. Defining it with 0 argument}% \CF_cnt_atomgroup=0 } {}% \ifcat\relax\expandafter\noexpand\CF_firsttonil#1\_nil\expandafter\CF_execfirst\else\expandafter\CF_execsecond\fi% si #1 est une séquence de contrôle {% \expandafter\ifdefined\CF_firsttonil#1\_nil \ifCF_define_submol \CF_warning{the submol \expandafter\string\CF_firsttonil#1\_nil\space is already defined, the previous definition is lost}% \fi \fi \begingroup \CF_sanitizecatcode \CF_defsubmolb{#1}% } {% \ifcsname CF__#1\endcsname \ifCF_define_submol \CF_warning{the submol "#1" is already defined, the previous definition is lost}% \fi \fi \begingroup \CF_sanitizecatcode \expandafter\CF_defsubmolb\csname CF__#1\endcsname }% } \def\CF_defsubmolb#1#2#3{% #1 nom sous forme de macro, #2 = code si liaison arrive de droite , #3 = code si liaison arrive de gauche, \CF_cnt_atomgroup = nombre d'arguments \def\CF_tempa{#2}% \CF_doifnotempty{#2} {% \CF_expsecond{\CF_expsecond\CF_substonly{\number\CF_cnt_atomgroup}\CF_tempa}{\CFhash}{\CFhash}% }% \def\CF_tempb{#3}% \CF_expsecond{\CF_expsecond\CF_substonly{\number\CF_cnt_atomgroup}\CF_tempb}{\CFhash}{\CFhash}% \CF_expsecond{\CF_expsecond{\CF_defsubmolc{#1}}\CF_tempa}\CF_tempb } \def\CF_defsubmolc#1#2#3{% #1 nom sous forme de macro, #2 = code si liaison arrive de droite , #3 = code si liaison arrive de gauche, \CF_cnt_atomgroup = nombre d'arguments \endgroup \begingroup \global\toks0{\gdef\CFthesubmol}% \CF_ifnum{\CF_cnt_atomgroup>0 } {% \foreach\CF_x in {1,...,\CF_cnt_atomgroup}% {% \global\toks0\expandafter{\expanded{\the\toks0\CFhash\CF_x}}% }% } {}% \CF_sanitizecatcode \catcode`\#6 \endlinechar-1 \everyeof{\noexpand}% \CF_ifempty{#2}% {% \scantokens\expandafter{\the\toks0{\empty#3}}% }% {% \scantokens\expandafter {% \the\toks0 {% \expanded {% bugfix 1.52 \csname CF_exec% \ifdim\csname CF_currentangle\endcsname pt>90pt \ifdim\csname CF_currentangle\endcsname pt<270pt first% \else second% \fi \else second% \fi \endcsname {\unexpanded{#2}}{\unexpanded{#3}}% }% }% }% }% \endgroup \let#1\CFthesubmol } \def\CF_searchnode#1#2#3{% cherche un noeud au début de #1 l'assigne dans la sc #2 et met le reste dans #3 \let#2\empty \def#3{#1}% \CF_iffirsttokmatch{#1}{ }% {% \CF_expsecond\CF_searchnodea{\romannumeral-`\.\noexpand#1}#2#3% ignore les espaces au début du groupe d'atome }% {% \CF_searchnodea{#1}#2#3% }% } \def\CF_searchnodea#1#2#3{% \CF_ifempty{#1}% {% \let#3\empty } {% \futurelet\CF_toksa\CF_gobtonil#1\relax\_nil \CF_ifx\CF_toksa\CF_sptoken {% \CF_addtomacro#2{ }% \CF_expsecond\CF_searchnodea{\CF_afterspace#1\_nil}#2#3% }% {% \CF_ifx\CF_toksa\bgroup {% \CF_eaddtomacro#2{\expandafter{\CF_firsttonil#1\_nil}}% \CF_expsecond\CF_searchnodea{\CF_gobarg#1}#2#3% }% {% \CF_ifx!\CF_toksa% Bugfix v1.5 {% \def\CF_seeksubmloltemp{#1}% \CF_searchsubmola \CF_expsecond\CF_searchnodea\CF_seeksubmloltemp#2#3% } {% \CF_iffirsttokina{-=(*<>~}% {% \def#3{#1}% }% {% \CF_eaddtomacro#2{\CF_firsttonil#1\_nil}% \CF_expsecond\CF_searchnodea{\CF_gobarg#1}#2#3% }% } }% }% }% } % on sait que #1 commence par -,=,~,<,>. On analyse cette liaison % #2 reçoit le type de liaisons (1 pour -, 2 pour =, 3 pour ~) \def\CF_assignbondcode#1#2{% \futurelet\CF_toksa\CF_gobtonil#1\_nil \edef#2{% \ifx-\CF_toksa1\else \ifx=\CF_toksa2\else \ifx~\CF_toksa3\else \ifx>\CF_toksa4\else \ifx<\CF_toksa5\else0% si 0 --> il y a une erreur non due à l'utilisateur \fi\fi\fi\fi\fi }% \ifnum#2>3 % si c'est une liaison de Cram \CF_expafter{\futurelet\CF_toksa\CF_gobtonil}{\CF_gobarg#1\_nil}% chope le caractère suivant \CF_ifx:\CF_toksa {% \edef#2{\number\numexpr#2+2}% si c 'est un ":", signe du pointillé, ajoute 2 }% {% \CF_ifx|\CF_toksa% si c 'est un "|", signe du triangle évidé, ajouter 4 {% \edef#2{\number\numexpr#2+4}% } {}% }% \fi } \def\CF_grabbondoffseta#1,#2\_nil{% \def\CF_startoffset{#1}\def\CF_endoffset{#2}% } \def\CF_grabbondoffset#1(#2)#3\_nil{% \CF_doifnotempty{#2}% {% \CF_ifinstr{#2},% {% \CF_grabbondoffseta#2\_nil }% {% \def\CF_startoffset{#2}% }% }% \def\CF_remainafterbond{#3}% } \def\CF_analysebond#1#2{% \CF_assignbondcode{#1}#2% \CF_expsecond{\def\CF_remainafterbond}{\CF_gobarg#1}%mange le premier signe de la liaison \let\CF_doublebondtype\CF_zero \ifnum#2=2 % si c'est une double liaison, regarde s'il y a un + ou - derrière \CF_expafter{\futurelet\CF_toksa\CF_gobtonil}{\CF_gobarg#1\_nil}% \CF_ifx^\CF_toksa {% \def\CF_doublebondtype{1}% \CF_expsecond{\def\CF_remainafterbond}{\CF_gobtwoargs#1}% mange le "^" } {% \expandafter\ifx\CF_underscore\CF_toksa \def\CF_doublebondtype{2}% \CF_expsecond{\def\CF_remainafterbond}{\CF_gobtwoargs#1}% mange le "_" \fi }% \else \ifnum#2>5 % si c'est une laision de Cram pointillée ou triangle évidé \CF_expsecond{\def\CF_remainafterbond}{\CF_gobtwoargs#1}% mange un caractère de plus \fi \fi \CF_expsecond\CF_iffirsttokmatch\CF_remainafterbond\CFhash {% \CF_eexpsecond\CF_iffirsttokmatch{\expandafter\CF_gobarg\CF_remainafterbond.}(%si parenthèse juste après {% \expandafter\CF_grabbondoffset\CF_remainafterbond\_nil } {}% }% {}% \CF_expsecond\CF_iffirsttokmatch\CF_remainafterbond @% {% \expandafter\CF_grabmovearg\CF_remainafterbond\_nil }% {}% \CF_expsecond\CF_iffirsttokmatch{\CF_remainafterbond}[% {% \expandafter\CF_analyseoptarg\CF_remainafterbond\_nil\CF_remainafterbond }% {% \let\CF_currentstringangle\CF_defaultstringangle \let\CF_currentlength\CF_defaultlength \let\CF_currentfromatom\CF_defaultfromatom \let\CF_currenttoatom\CF_defaulttoatom \let\CF_currenttikz\CF_defaulttikz \let\CF_movebondname\empty }% \ifCF_in_cycle \pgfmathsetmacro\CF_cycleincrementangle{360/\CF_cyclenum+\CF_initcycleangle}% \edef\CF_currentstringangle{::+\CF_cycleincrementangle}% \def\CF_initcycleangle{0}% \let\CF_currentlength\CF_defaultlength% et on ignore la longueur de liaison spécifiée \fi \CF_expsecond\CF_setbondangle{\CF_currentstringangle}\CF_currentangle } \def\CF_setbondangle#1#2{% le code de la direction est contenu dans #1, en sortie, #2 contient l'angle \CF_ifempty{#1}% {% \let#2\CF_defaultangle } {% \if:\expandafter\noexpand\CF_firsttonil#1\_nil \if:\CF_threeea\noexpand\expandafter\CF_firsttonil\CF_gobarg#1\_nil \pgfmathsetmacro#2{\CF_previousangle+\expandafter\CF_gobarg\CF_gobarg#1}% \else \pgfmathsetmacro#2{\CF_gobarg#1}% \fi \else \pgfmathsetmacro#2{#1*\CF_angleincrement}% \fi% puis normalise l'angle entre 0 et 360 \ifdim\ifdim#2pt<0pt -\fi#2pt>360pt \pgfmathsetmacro#2{#2-360*floor(#2/360)}% \fi% si |#2|>360 \ifdim#2pt<0pt \pgfmathsetmacro#2{#2+360}% \fi }% } \def\CF_analysemovearg#1,#2\_nil#3{% \def#3{#1}% \def\CF_movebondcoeff{#2}% } % Argument limités légitimes ici car #2 (qui est ce qui suit "@{}" dans l'argument optionnel) ne DOIT PAS commencer par une accolade. \def\CF_grabmovearg @#1#2\_nil{% \CF_ifinstr{#1},% {% \CF_analysemovearg#1\_nil\CF_movebondname }% {% \def\CF_movebondname{#1}% \def\CF_movebondcoeff{0.5}% }% \def\CF_remainoptarg{#2}% } \def\CF_testemptyandassign#1#2#3{% \CF_ifempty{#2} {% \let#1#3% } {% \def#1{#2}% }% } \def\CF_parseoptlist#1,#2,#3,#4,#5\_nil{% \CF_testemptyandassign\CF_currentstringangle{#1}\CF_defaultstringangle \CF_testemptyandassign\CF_currentlength {#2}\CF_defaultlength \CF_testemptyandassign\CF_currentfromatom {#3}\CF_defaultfromatom \CF_testemptyandassign\CF_currenttoatom {#4}\CF_defaulttoatom \CF_expsecond{\CF_testemptyandassign\CF_currenttikz}{\CF_sanitizelastitem#5,\empty\_nil}\CF_defaulttikz }% \def\CF_analyseoptarg[#1]{% \CF_doifnotempty{#1}% {% \CF_iffirsttokmatch{#1}{@}% {% \CF_grabmovearg#1\_nil } {% \let\CF_movebondname\empty \def\CF_remainoptarg{#1}% }% \expandafter\CF_parseoptlist\CF_remainoptarg,\empty,\empty,\empty,\empty\_nil }% \CF_analyseoptarga\relax } \def\CF_analyseoptarga#1\_nil#2{% \CF_expsecond{\def#2}{\CF_gobarg#1}% } \def\CF_searchsubmol#1#2{% cherche et remplace ! au début de #1. #1=code #2=macro recevant le résultat \def\CF_seeksubmloltemp{#1}% \CF_searchsubmola \let#2\CF_seeksubmloltemp } \def\CF_searchsubmola{% \CF_expsecond{\def\CF_seeksubmloltemp}{\romannumeral-`\.\expandafter\noexpand\CF_seeksubmloltemp}% \CF_expsecond\CF_iffirsttokmatch{\CF_seeksubmloltemp}!% {% \CF_eexpsecond{\def\CF_seeksubmloltemp}{\expandafter\CF_gobarg\CF_seeksubmloltemp}% enlève le "!" \CF_ifx\empty\CF_seeksubmloltemp {% \CF_error{no submol name found after "!"}% } {}% \ifcat\relax\CF_threeea\noexpand\expandafter\CF_firsttonil\CF_seeksubmloltemp*\_nil \expandafter\CF_searchsubmolb\CF_seeksubmloltemp\_nil \else \expandafter\CF_searchsubmolc\CF_seeksubmloltemp\_nil \fi \CF_searchsubmola }% {}% } \def\CF_searchsubmolb#1{\CF_searchsubmold#1\relax} \def\CF_searchsubmolc#1{\expandafter\CF_searchsubmold\csname CF__#1\endcsname\relax}% nom de la sous molécule \def\CF_searchsubmold#1#2\_nil{% #1=macro de la sous molécule #2=reste du code commençant par \relax \CF_expsecond{\CF_eexpsecond{\def\CF_seeksubmloltemp}}{\expandafter#1\CF_gobarg#2}% supprime le \relax puis ajoute la macro au début et la 2-développe } \def\CF_insertemptygroup#1{% insère {} au début de la sc #1 \CF_expsecond{\def#1}{\expandafter{\expandafter}#1}% } \def\chemfig{\CF_testopt\CF_chemfiga{}} \def\CF_chemfiga[#1]{% \begingroup \CF_sanitizecatcode \CF_exptwomacroargs\CF_chemfigb\CF_begintikzpicture\CF_endtikzpicture[#1]% } \def\CF_chemfigb#1#2[#3]#4{% \endgroup \begingroup \setchemfig{#3}% \CF_ifinsidetikz {% \pgfinterruptpicture \let\CF_atendofchemfig\endpgfinterruptpicture } {% \let\CF_atendofchemfig\relax }% \expanded {% début du tikzpicture \unexpanded{#1}[% remember picture,% every node/.style={% anchor=base,% inner sep=0pt,% outer sep=0pt,% minimum size=0pt,% \unexpanded\expandafter{\CF_atomstyle}% },% baseline=\CF_baseline,% \unexpanded\expandafter{\CF_chemfigstyle}% ]% }% \begingroup% \endgroup rajouté en sortie de tracé par \CF_chemfigd \let\CF_hooklist\empty \ifboolKV[chemfig]{fixed length} {% \CF_macro_fixed_bond_lengthtrue } {% \CF_macro_fixed_bond_lengthfalse }% \ifboolKV[chemfig]{bond join} {% \let\CF_drawaxisbond\CF_drawaxisbondjoin } {% \let\CF_drawaxisbond\CF_drawaxisbondnojoin }% \ifboolKV[chemfig]{cram rectangle} {% \let\CF_clipcramornot\CF_gobtikzinstruction } {% \let\CF_clipcramornot\clip }% \CF_in_cyclefalse \CF_cnt_group0 \ifboolKV[chemfig]{autoreset cntcycle} {% \global\CF_cnt_cycle0 } {}% \let\CF_lastaction\CF_zero% 0=début du dessin 1=tracé d'un noeud 2=tracé d'une liaison \let\CF_startoffset\empty \let\CF_endoffset\empty \let\CF_bondoutcontentsaved\empty \def\CF_cycleanglecorrection{180/\CF_cyclenum}% \def\CF_defaultangle{0}% \def\CF_defaultstringangle{:0}% angle pris par défaut si le champ est vide \def\CF_defaultlength{1}% \let\CF_defaultfromatom\empty% numero de l'atome d'où partent les liaisons par défaut \let\CF_defaulttoatom\empty% numéro de l'atome où arrivent les laisons par défaut \let\CF_defaulttikz\empty \let\CF_previousbondangle\empty \def\CF_previousbondtype{0}% \def\CF_previousnode{}% \def\CF_previous_offset{0pt}% \let\CF_joinbond\CF_zero \let\CF_previoustikz\empty \everyeof{\_nil}\endlinechar-1 \CF_sanitizecatcode \expandafter\CF_assigntonil\expandafter\CF_molecule\scantokens{#4}% \CF_expsecond{\CF_substall\CF_molecule}\CFhash\CFhash \CF_expsecond\CF_chemfigc{\CF_molecule}% %\endgroup <-- rajouté par \CF_chemfigd #2% fin du tikzpicture \CF_atendofchemfig \endgroup \let\CF_flipstate\CF_zero } \def\CF_chemfigc#1{% #1 est le code de la molécule \ifnum\CF_lastaction=3 \ifCF_in_cycle \def\CF_defaultangle{0}% \else \ifnum\CF_cnt_cyclebonds=0 % si c'est le début d'un cycle \pgfmathsetmacro\CF_defaultangle{\CF_previousangle+180+\CF_cycleanglecorrection}% on met la liaison à +180° + correction \else \pgfmathsetmacro\CF_defaultangle{\CF_previousangle-90+180/\CF_cyclenum}% sinon à la bissectrice du sommet du cycle \fi \fi \let\CF_defaultstringangle\empty \fi \let\CF_currentangle\CF_defaultangle \def\CF_molecule{#1}% \CF_expsecond\CF_searchsubmol\CF_molecule\CF_molecule% alias en premier ? \if[\CF_threeea\noexpand\expandafter\CF_firsttonil\CF_molecule\_nil \expandafter\CF_analyseoptarg\CF_molecule\_nil\CF_molecule \CF_expsecond\CF_setbondangle{\CF_currentstringangle}\CF_currentangle \let\CF_defaultangle\CF_currentangle \let\CF_previousangle\CF_currentangle \CF_doifnotempty\CF_currentstringangle{\let\CF_defaultangle\CF_currentangle}% \CF_doifnotempty\CF_currentlength {\let\CF_defaultlength\CF_currentlength}% \CF_doifnotempty\CF_currentfromatom {\let\CF_defaultfromatom\CF_currentfromatom}% \CF_doifnotempty\CF_currenttoatom {\let\CF_defaulttoatom\CF_currenttoatom}% \CF_doifnotempty\CF_currenttikz {\let\CF_defaulttikz\CF_currenttikz}% \CF_expsecond\CF_searchsubmol\CF_molecule\CF_molecule \fi \edef\CF_defaultstringangle{:\CF_defaultangle}% \let\CF_currentlength\CF_defaultlength \let\CF_currentfromatom\CF_defaultfromatom \let\CF_currenttoatom\CF_defaulttoatom \let\CF_currenttikz\CF_defaulttikz \ifCF_in_cycle% si on commence un cycle \let\CF_currentangle\CF_previousangle \pgfmathsetmacro\CF_cycle_arcinitangle{\CF_currentangle+\CF_initcycleangle+180/\CF_cyclenum+90}% \pgfmathsetmacro\CF_centeroffset{\CF_currentlength*\CF_atomsep/(2*sin(180/\CF_cyclenum))}% \node[at=(\CF_bondoutnode),shift=(\CF_cycle_arcinitangle:\CF_centeroffset pt),anchor=center](cyclecenter\number\CF_cnt_cycle){};% le centre du cycle \ifboolKV[chemfig]{show cntcycle} {% \node[at=(cyclecenter\number\CF_cnt_cycle),anchor=center,overlay]{\tiny\number\CF_cnt_cycle};% } {}% \ifCF_cycle_arc% on doit tracer l'arc de cercle dans le cycle ? \pgfmathsetmacro\CF_cycle_arcradius{\CF_cycleradiuscoeff*\CF_currentlength*\CF_atomsep/(2*tan(180/\CF_cyclenum))}% \node[at=(cyclecenter\number\CF_cnt_cycle),shift=(\CF_cycle_arcstartangle:\CF_cycle_arcradius pt)](initarc){};% le début de l'arc \CF_expafter{\draw[}\CF_cycle_arcdirecttikz](initarc) arc (\CF_cycle_arcstartangle:\CF_cycle_arcendangle:\CF_cycle_arcradius pt);% \fi \else \let\CF_currentangle\CF_defaultangle \fi \ifnum\CF_lastaction=0 \let\CF_previousangle\CF_defaultangle \node(CF_node){}; \CF_expsecond\CF_iffirsttokin{\CF_molecule}{-=(*~?<>}% {% \CF_insertemptygroup\CF_molecule }% {}% \fi \CF_chemfigd } \def\CF_chemfigd{% \let\CF_nextaction\CF_chemfigd% à priori, on reboucle \CF_ifx\CF_molecule\empty {% \let\CF_nextaction\endgroup } {% \CF_expsecond\CF_searchnode{\CF_molecule}\CF_currentatomgroup\CF_molecule \CF_ifx\empty\CF_currentatomgroup% pas de noeud pour commencer ? {% \def\CF_bondoutnode{% n\CF_lastgroupnumber-% \ifx\CF_currentfromatom\empty \ifdim\CF_currentangle pt<90pt \number\CF_cnt_atomgroup \else \ifdim\CF_currentangle pt>270pt \number\CF_cnt_atomgroup \else 1% \fi \fi \else \CF_currentfromatom \fi }% \CF_expafter{\futurelet\CF_toksa\CF_gobtonil}{\CF_molecule\relax\_nil}% \CF_iffirsttokina{-=<>~}% la suite est une liaison {% \ifnum\CF_lastaction=2 % c'est la deuxième liaison consécutive ? \CF_insertemptygroup\CF_molecule% insère un groupe vide \edef\CF_bondoutnode{\CF_bondoutnode}% \else \ifCF_in_cycle \advance\CF_cnt_cyclebonds1 \fi \CF_expsecond\CF_analysebond{\CF_molecule}\CF_bondtype \edef\CF_bondoutnode{\CF_bondoutnode}% \let\CF_molecule\CF_remainafterbond \ifCF_in_cycle \ifnum\CF_cnt_cyclebonds=\CF_cyclenum\relax \CF_threeea\CF_execfirst \else \ifnum\CF_cnt_cyclebonds=1 \let\CF_cyclefirsttikz\CF_currenttikz \CF_doifnotempty\CF_startoffset{\let\CF_cyclejoinlast\CF_zero}% \fi \CF_threeea\CF_execsecond \fi \else \expandafter\CF_execsecond \fi {% \let\CF_nextaction\endgroup \CF_drawbond\CF_bondtype{\CF_bondoutnode}{\CF_hookcycle}\CF_previousatomgroup\CF_hookatomgroup }% {% \node[at=(\CF_bondoutnode\ifCF_in_cycle\else\ifCF_macro_fixed_bond_length.\CF_currentangle\fi\fi),shift=(\ifcase\CF_flipstate\or180-\or-\fi\CF_currentangle:\CF_currentlength*\CF_atomsep)](CF_node){}; \let\CF_previousangle\CF_currentangle \def\CF_lastaction{2}% on a tracé une liaison }% \fi \ifcat\relax\detokenize\expandafter{\romannumeral-`\.\expandafter\noexpand\CF_molecule}\relax % s'il ne reste plus rien après la liaison (sans tenir compte de l'espace devant)-> insère un groupe vide \CF_insertemptygroup\CF_molecule \fi }% {% \edef\CF_bondoutnode{\CF_bondoutnode}% évalue le l'atome de départ de liaison \CF_ifx(\CF_toksa% une parenthèse pour commencer ? {% \ifnum\CF_lastaction=2 % il y avait une liaison juste avant ? \CF_insertemptygroup\CF_molecule \else \CF_expsecond\CF_grabsubmol{\CF_molecule}% \begingroup \ifCF_in_cycle\def\CF_lastaction{3}\fi% on était dans un cycle \CF_in_cyclefalse \aftergroup\CF_chemfigd \def\CF_nextaction{\CF_expsecond\CF_chemfigc{\CF_molinparen}}% \fi }% {% \CF_ifx\CF_molecule\empty {% \let\CF_nextaction\endgroup } {% ce qui reste après le noeud courant n'est pas vide, ne commence pas par "-=~", ni par une parenthèse \CF_ifx*\CF_toksa% un cycle ? {% \ifnum\CF_lastaction=2 \def\CF_currentfromatom{1}% Bugfix 1.6d \CF_insertemptygroup\CF_molecule% insère un groupe vide \else \ifCF_in_cycle \def\CF_lastaction{3}% \fi% on était dans un cycle \ifnum\CF_lastaction=3 \let\CF_lastcyclenum\CF_cyclenum \fi \CF_eexpsecond\CF_iffirsttokmatch{\expandafter\CF_gobarg\CF_molecule}*% {% \CF_eexpsecond{\def\CF_molecule}{\expandafter\CF_gobarg\CF_molecule}% enlève la 1er étoile \CF_eexpsecond\CF_iffirsttokmatch{\expandafter\CF_gobarg\CF_molecule}[% un crochet ensuite ? {% \expandafter\CF_parsecyclepreamblewithoptarg\CF_molecule\_nil% \begingroup inclus }% {% \def\CF_cycle_arcstartangle{0}% \def\CF_cycle_arcendangle{360}% \let\CF_cycle_arcdirecttikz\empty \expandafter\CF_parsecyclepreamble\CF_molecule\_nil% \begingroup inclus }% \CF_cycle_arctrue }% {% \expandafter\CF_parsecyclepreamble\CF_molecule\_nil% \begingroup inclus \CF_cycle_arcfalse }% \CF_cnt_cyclebonds0 \edef\CF_hookcycle{\CF_bondoutnode}% \let\CF_hookatomgroup\CF_previousatomgroup \CF_ifnum{\CF_previousatomgroup_nodim=0 }% bugfix v1.71 {% \def\CF_cyclejoinlast{1}% joindre le dernier }% {% \def\CF_cyclejoinlast{0}% }% \CF_in_cycletrue \global\advance\CF_cnt_cycle1 \CF_ifnum{\CF_lastaction=3 } {% \pgfmathsetmacro\CF_initcycleangle{360/\CF_lastcyclenum-180}% c'est un cycle dans un cycle } {% \pgfmathsetmacro\CF_initcycleangle{-180/\CF_cyclenum-90+\CF_cycleanglecorrection}% } \aftergroup\CF_chemfigd \def\CF_nextaction{\CF_expsecond\CF_chemfigc{\CF_molinparen}}% \fi }% {% \CF_error{something went wrong here: \detokenize\expandafter{\CF_molecule}^^JIf you think it's a bug, please, send a Minimal Example to the author}% }% }% }% }% }% {% \CF_expthreemacroargs\CF_drawatomgroup\CF_currentangle\CF_currenttoatom\CF_currentatomgroup }% }% \CF_nextaction } \def\CF_parsecyclepreamble*#1#2\_nil{% \ifnum#1<3 \CF_error{a cycle must be at least a triangle.^^JThe number following "*" must be 3 or more}% \fi \def\CF_molecule{#2}% \CF_expsecond\CF_grabsubmol{\CF_molecule}% \begingroup \def\CF_cyclenum{#1}% } \def\CF_parsecyclepreamblewithoptarg*[#1]#2#3\_nil{% \CF_cycleparseoptarg#1,\empty,\empty,\empty\_nil \CF_parsecyclepreamble*#2#3\_nil } \def\CF_cycleparseoptarg#1,#2,#3\_nil{% \CF_ifempty{#1} {% \def\CF_cycle_arcstartangle{0}% } {% \def\CF_cycle_arcstartangle{#1}% }% \CF_ifempty{#2} {% \def\CF_cycle_arcendangle{360}% } {% \def\CF_cycle_arcendangle{#2}% }% \CF_expsecond{\def\CF_cycle_arcdirecttikz}{\CF_sanitizelastitem#3,\empty\_nil}% } \def\CF_grabsubmol#1{% \begingroup \catcode`(1 \catcode`)2 \CF_threeea \endgroup \expandafter\CF_grabsubmola\scantokens{\relax#1}% } \def\CF_grabsubmola#1\_nil{% \expandafter\CF_assigntonil\expandafter\CF_molecule\scantokens\CF_threeea{\expandafter\CF_gobarg \CF_gobarg#1}% \expandafter\CF_assigntonil\expandafter\CF_molinparen\scantokens\CF_threeea{\expandafter\CF_firsttonil\CF_gobarg#1\_nil}% } \def\CF_ifcarisupperletter#1{% \ifcat\relax\noexpand#1% \let\CF_next\CF_execsecond% faux si c'est une sc \else \ifnum`#1<`A \let\CF_next\CF_execsecond \else \ifnum`#1>`Z \let\CF_next\CF_execsecond \else \let\CF_next\CF_execfirst \fi \fi \fi \CF_next } % Créé 4 noeuds au dessus et au dessous des noeuds #1 et #2 % à une distance de #3 du noeud #1 et #4 du noeud #2 \def\CF_createnormnodes#1#2#3#4{% \CF_doifnotempty{#3} {% \node[shape=coordinate,at=(#1),xshift=#3*\CF_normx,yshift=#3*\CF_normy](#11){};% \node[shape=coordinate,at=(#1),xshift=-#3*\CF_normx,yshift=-#3*\CF_normy](#12){};% }% \CF_doifnotempty{#4} {% \node[shape=coordinate,at=(#2),xshift=#4*\CF_normx,yshift=#4*\CF_normy](#21){};% \node[shape=coordinate,at=(#2),xshift=-#4*\CF_normx,yshift=-#4*\CF_normy](#22){};% }% } \def\CF_distancebetweenpoints#1#2#3#4#5{% \pgfextractx\CF_dim{\pgfpointanchor{#1}{#2}}\edef\CF_dimax{\the\CF_dim}% \pgfextracty\CF_dim{\pgfpointanchor{#1}{#2}}\edef\CF_dimay{\the\CF_dim}% \pgfextractx\CF_dim{\pgfpointanchor{#3}{#4}}\edef\CF_dimbx{\the\CF_dim}% \pgfextracty\CF_dim{\pgfpointanchor{#3}{#4}}\edef\CF_dimby{\the\CF_dim}% \pgfmathsetmacro#5{veclen(\CF_dimbx-\CF_dimax,\CF_dimby-\CF_dimay)}% } \def\CF_computenodevect#1#2{% \CF_distancebetweenpoints{#1}{center}{#2}{center}\CF_vectorlen \pgfmathsetmacro\CF_normx{(\CF_dimay-\CF_dimby)/\CF_vectorlen}% \pgfmathsetmacro\CF_normy{(\CF_dimbx-\CF_dimax)/\CF_vectorlen}% } \def\CF_ifzerodistance#1#2#3#4{% #1=nom du noeud 1 #2=ancre du noeud 1 #3=nom noeud 2 #4=ancre noeud 2 T-> si distance nulle F->sinon \pgfextractx\CF_dim{\pgfpointanchor{#3}{#4}}\edef\CF_dimax{\the\CF_dim}% \pgfextracty\CF_dim{\pgfpointanchor{#3}{#4}}\edef\CF_dimay{\the\CF_dim}% \pgfextractx\CF_dim{\pgfpointanchor{#1}{#2}}\edef\CF_dimbx{\the\CF_dim}% \pgfextracty\CF_dim{\pgfpointanchor{#1}{#2}}\edef\CF_dimby{\the\CF_dim}% \CF_ifnum{0\ifdim\CF_dimax=\CF_dimbx\space1\fi\ifdim\CF_dimay=\CF_dimby\space1\fi=11 } } \def\CF_setoffset#1#2{% #1=macro recevant le résultat #2= nom du noeud bugfix 1.71 \CF_doifempty#1% {% \CF_ifzerodistance{#2}{south west}{#2}{north east}% si noeud de dimension nulle {% \def#1{0pt}% } {% \edef#1{\CF_bondoffset}% }% }% } \def\CF_drawbond#1#2#3#4#5{% #1=type de liaison #2 et #3:nom de noeuds de début et fin #4 et #5: sc contenant les atomes de débutet fin \CF_setoffset\CF_startoffset{#2}% \CF_setoffset\CF_endoffset{#3}% \let\CF_currentbondstyle\CF_bondstyle \CF_doifnotempty\CF_currenttikz {% \CF_eaddtomacro\CF_currentbondstyle{\expandafter,\CF_currenttikz}% }% \path(#2)--(#3)coordinate[pos=0](#2@)coordinate[pos=1](#3@);% \CF_computenodevect{#2@}{#3@}% \pgfmathsetmacro\CF_startcoeff{\CF_startoffset/\CF_vectorlen}% \pgfmathsetmacro\CF_endcoeff{1-\CF_endoffset/\CF_vectorlen}% \path(#2@)--(#3@)coordinate[pos=\CF_startcoeff](#2@@)coordinate[pos=\CF_endcoeff](#3@@);% \CF_doifnotempty\CF_movebondname% on doit poser un noeud sur la liaison {% \path(#2@@)--(#3@@)coordinate[overlay,pos=\CF_movebondcoeff](\CF_movebondname); \let\CF_movebondname\empty }% \ifcase#1\relax \CF_error{unknown bond type, this error should not occur^^JIf you think it's a bug, send a Minimal Example to the author}% \or% 1 = liaison simple \ifboolKV[chemfig]{bond join}% nouveau v1.66 {% \scope \expandafter\tikzset\expandafter{\CF_currentbondstyle}% \ifnum\CF_previousbondtype=5 \ifnum0\ifdim\CF_startoffset=0pt 1\fi\ifdim\CF_previous_offset=0pt 1\fi=11 \CF_ifnum{\CF_previousatomgroup_nodim=1 }% bugfix 1.71 {% \CF_turnangle=\CF_compute_turnangle{\CF_previousbondangle}{\CF_currentangle}% \pgfmathsetmacro\CF_cram_overlap{\CF_crambasewidth*cos(\CF_turnangle)-\pgflinewidth}% \ifdim\CF_cram_overlap pt>0pt \CF_warning{Cram base too wide to join}% \else \ifdim\CF_turnangle>0pt % si on tourne à gauche \fill(#2@@)--(\CF_previousnode@@2)--([shift=(\CF_currentangle-90:\pgflinewidth/2)]#2@@)--cycle; \else \fill(#2@@)--(\CF_previousnode@@1)--([shift=(\CF_currentangle+90:\pgflinewidth/2)]#2@@)--cycle; \fi \fi } {}% \fi \fi \expandafter \endscope \expanded{\def\noexpand\CF_simplebondwidth{\the\dimexpr\pgflinewidth}}% récupère l'épaisseur de ligne si une liaison ">" est à suivre } {}% \CF_drawaxisbond{#2}{#3}% trace la liaison simple dans l'axe \or% 2 = liaison double \ifCF_in_cycle \ifnum\CF_doublebondtype=0 \def\CF_doublebondtype{1}% \fi \ifnum\CF_flipstate>0 \def\CF_doublebondtype{2}% \fi \pgfmathsetmacro\CF_doublebondlengthcorrection{\CF_doublesep*tan(180/\CF_cyclenum)}% \fi \ifcase\CF_doublebondtype \CF_createnormnodes{#2@@}{#3@@}{\CF_doublesep/2}{\CF_doublesep/2}% \CF_drawbonda(#2@@1)--(#3@@1); \CF_drawbonda(#2@@2)--(#3@@2); \let\CF_joinbond\CF_zero \or \CF_createnormnodes{#2@@}{#3@@}\CF_doublesep\CF_doublesep \CF_drawaxisbond{#2}{#3}% trace la liaison simple dans l'axe\CF_drawbonda(#2@@)--(#3@@); \begingroup% ajuste éventuellement les longueurs des liaisons doubles \ifCF_in_cycle \ifdim\CF_startoffset=0pt \CF_edefaddtomacro\CF_currentbondstyle{,shorten <=\CF_doublebondlengthcorrection pt}% \fi \ifdim\CF_endoffset=0pt \CF_edefaddtomacro\CF_currentbondstyle{,shorten >=\CF_doublebondlengthcorrection pt}% \fi \fi \CF_drawbonda(#2@@1)--(#3@@1); \endgroup \or \CF_createnormnodes{#2@@}{#3@@}\CF_doublesep\CF_doublesep \CF_drawaxisbond{#2}{#3}% trace la liaison simple dans l'axe\CF_drawbonda(#2@@)--(#3@@); \begingroup% ajuste éventuellement les longueurs des liaisons doubles \ifCF_in_cycle \ifdim\CF_startoffset=0pt \CF_edefaddtomacro\CF_currentbondstyle{,shorten \ifnum\CF_flipstate=0 <=-\else>=\fi\CF_doublebondlengthcorrection pt}% \fi \ifdim\CF_endoffset=0pt \CF_edefaddtomacro\CF_currentbondstyle{,shorten \ifnum\CF_flipstate=0 >=-\else<=\fi\CF_doublebondlengthcorrection pt}% \fi \fi \CF_drawbonda(#2@@2)--(#3@@2); \endgroup \fi \or% 3 = liaison triple \CF_createnormnodes{#2@@}{#3@@}\CF_doublesep\CF_doublesep \CF_drawaxisbond{#2}{#3}% trace la liaison simple dans l'axe\CF_drawbonda(#2@@)--(#3@@); \CF_drawbonda(#2@@1)--(#3@@1); \CF_drawbonda(#2@@2)--(#3@@2); \or% 4 = liaison Cram pleine de #2 vers #3 : > \CF_createnormnodes{#2@@}{#3@@}{\CF_crambasewidth/2}{\pgflinewidth/2}% \CF_ifnum{\CF_previousatomgroup_nodim=1 }% bugfix 1.71 {% \ifnum\ifboolKV[chemfig]{bond join}10\ifdim\CF_startoffset=0pt 1\fi\ifdim\CF_previous_offset=0pt 1\fi=111 \ifnum\CF_previousbondtype=1 \CF_turnangle=\CF_compute_turnangle{\CF_previousbondangle}{\CF_currentangle}% \pgfmathsetmacro\CF_cram_overlap{\CF_crambasewidth*cos(\CF_turnangle)-\CF_simplebondwidth}% \ifdim\CF_cram_overlap pt>0pt \CF_warning{Cram base too wide to join}% \else \CF_expafter{\fill[}\CF_currentbondstyle](#2@@1)--([shift=(\CF_previousbondangle\ifdim\CF_turnangle>0pt -\else+\fi90:\CF_simplebondwidth/2)]\CF_previousnode@@)--(#2@@2)--cycle;% \fi \else \ifnum\CF_previousbondtype=5 \CF_turnangle=\CF_compute_turnangle{\CF_previousbondangle}{\CF_currentangle}% \CF_expafter{\fill[}\CF_currentbondstyle](#2@@1)--([shift=(\CF_previousbondangle\ifdim\CF_turnangle>0pt -\else+\fi90:\CF_crambasewidth/2)]\CF_previousnode@@)--(#2@@2)--cycle;% \fi \fi \fi } {}% \ifboolKV[chemfig]{bond join} {\CF_expafter{\fill[}}% pas de contour si liaisons jointes {\CF_expafter{\filldraw[}} \CF_currentbondstyle](#2@@1)--(#2@@2)--(#3@@2)--(#3@@1)--cycle; \let\CF_joinbond\CF_zero \or% 5 = liaison Cram pleine de #2 vers #3 : < \CF_createnormnodes{#3@@}{#2@@}{\CF_crambasewidth/2}{\pgflinewidth/2}% \ifboolKV[chemfig]{bond join} {\CF_expafter{\fill[}}% pas de contour si liaisons jointes {\CF_expafter{\filldraw[}} \CF_currentbondstyle](#2@@2)--(#2@@1)--(#3@@1)--(#3@@2)--cycle; \let\CF_joinbond\CF_zero \or% 6 = liaison Cram pointillée de #2 vers #3 \scope \CF_createnormnodes{#2@@}{#3@@}{\CF_crambasewidth/2}{}% \CF_clipcramornot(#2@@1)--(#2@@2)--(#3@@)--(#2@@1); \CF_expafter{\draw[}\CF_currentbondstyle,dash pattern=on \CF_cramdashlength off \CF_cramdashsep,line width=\CF_crambasewidth](#2@@)--(#3@@); \endscope \let\CF_joinbond\CF_zero \or% 7 = liaison Cram pointillée de #3 vers #2 \scope \CF_createnormnodes{#3@@}{#2@@}{\CF_crambasewidth/2}{}% \CF_clipcramornot(#3@@1)--(#3@@2)--(#2@@)--(#3@@1); \CF_expafter{\draw[}\CF_currentbondstyle,dash pattern=on \CF_cramdashlength off \CF_cramdashsep,line width=\CF_crambasewidth](#3@@)--(#2@@); \endscope \let\CF_joinbond\CF_zero \or% 8 = liaison cram rectangle évidé de #2 vers #3 \CF_createnormnodes{#2@@}{#3@@}{\CF_crambasewidth/2}{}% \CF_expafter{\draw[}\CF_currentbondstyle,line join=bevel](#2@@1)--(#2@@2)--(#3@@)--cycle; \let\CF_joinbond\CF_zero \or% 9 = liaison cram rectangle évidé de #3 vers #1 \CF_createnormnodes{#3@@}{#2@@}{\CF_crambasewidth/2}{}% \CF_expafter{\draw[}\CF_currentbondstyle,line join=bevel](#3@@1)--(#3@@2)--(#2@@)--cycle; \let\CF_joinbond\CF_zero \else \CF_error{unknown bond type, this error should not occur^^JIf you think it's a bug, send a Minimal Example to the author}% \fi \let\CF_startoffset\empty \let\CF_previous_offset\CF_endoffset \let\CF_endoffset\empty \let\CF_previoustikz\CF_currenttikz \let\CF_previousbondangle\CF_previousangle \edef\CF_previousnode{#3}% } \def\CF_compute_turnangle#1#2{% \expandafter\CF_compute_turnangle_a\the\dimexpr #2pt-#1pt\relax\_nil } \def\CF_compute_turnangle_a#1\_nil{% \dimexpr#1 \ifdim#1<-180pt +360pt\else \ifdim#1>180pt -360pt\fi\fi\relax } \def\CF_drawaxisbondnojoin#1#2{\CF_drawbonda(#1@@)--(#2@@);} \def\CF_drawaxisbondjoin#1#2{% dessine une liaison simple dans l'axe avec raccord rétrograde \ifCF_in_cycle\ifnum\CF_cnt_cyclebonds=\CF_cyclenum\relax \let\CF_nexttikz\CF_cyclefirsttikz \fi\fi \ifnum\CF_joinbond=0 \ifCF_in_cycle \ifnum\CF_cnt_cyclebonds=\CF_cyclenum\relax \ifnum\CF_cyclejoinlast=1 \CF_drawbonda(#1@@)--(#2@@)--% ([shift=(\CF_previousbondangle+2*\CF_cycleincrementangle:.5\pgflinewidth)]#2@@); \else \CF_drawbonda(#1@@)--(#2@@); \fi \else \CF_drawbonda(#1@@)--(#2@@); \fi \else \CF_drawbonda(#1@@)--(#2@@); \fi \def\CF_joinbond{1}% \else \CF_ifx\CF_previoustikz\CF_currenttikz {% \def\CF_joinbond{1}% \CF_ifnum{\CF_previousatomgroup_nodim=1 }% bugfix 1.71 {% \CF_ifx\CF_previousbondangle\empty% si début molécule {% \CF_drawbonda(#1@@)--(#2@@); } {% \ifdim\CF_startoffset=0pt \ifCF_in_cycle \ifnum\CF_cnt_cyclebonds=\CF_cyclenum\relax \ifnum\CF_cyclejoinlast=1 \CF_ifx\CF_cyclefirsttikz\CF_currenttikz {% \CF_drawbonda([shift=(\CF_previousbondangle:-.5\pgflinewidth)]#1@@)--(#1@@)--(#2@@)--([shift=(\CF_previousbondangle+2*\CF_cycleincrementangle:.5\pgflinewidth)]#2@@); } {% \CF_drawbonda([shift=(\CF_previousbondangle:-.5\pgflinewidth)]#1@@)--(#1@@)--(#2@@); }% \else \CF_drawbonda([shift=(\CF_previousbondangle:-.5\pgflinewidth)]#1@@)--(#1@@)--(#2@@); \fi \else \CF_drawbonda([shift=(\CF_previousbondangle:-.5\pgflinewidth)]#1@@)--(#1@@)--(#2@@); \fi \else \CF_drawbonda([shift=(\CF_previousbondangle:-.5\pgflinewidth)]#1@@)--(#1@@)--(#2@@); \fi \else \CF_drawbonda(#1@@)--(#2@@); \fi }% } {% \CF_drawbonda(#1@@)--(#2@@);% }% } {% \ifCF_in_cycle \ifnum\CF_cnt_cyclebonds=\CF_cyclenum\relax \ifnum\CF_cyclejoinlast=1 \CF_ifx\CF_nexttikz\CF_currenttikz {% \CF_drawbonda(#1@@)--(#2@@)--([shift=(\CF_previousbondangle+2*\CF_cycleincrementangle:.5\pgflinewidth)]#2@@);% }% {% \CF_drawbonda(#1@@)--(#2@@);% }% \else \CF_drawbonda(#1@@)--(#2@@); \fi \else \CF_drawbonda(#1@@)--(#2@@); \fi \else \CF_drawbonda(#1@@)--(#2@@);% \fi }% \fi \ifdim\CF_endoffset=0pt \else \let\CF_joinbond\CF_zero \fi } \def\CF_drawbonda{\CF_expafter{\draw[}\CF_currentbondstyle]} \def\CF_drawallhooks{% dessine tous les crochets contenus dans la sc \CF_hookdraw \CF_doifnotempty\CF_hookdrawlist {% \expandafter\CF_drawfirsthook\CF_hookdrawlist\_nil% trace un lien de crochet à crochet \CF_drawallhooks }% } \def\CF_drawfirsthook[#1,#2,#3]#4#5#6#7#8\_nil{% \def\CF_hookdrawlist{#8}% \begingroup \let\CF_joinbond\CF_zero \def\CF_currenttikz{#3}% \def\CF_hookstartcontent{#6}% \def\CF_hookendcontent{#7}% \CF_ifinteger{#2}% {% \CF_drawbond{#2}{#4}{#5}\CF_hookstartcontent\CF_hookendcontent }% {% \CF_assignbondcode{#2}\CF_bondcurrentnum \CF_drawbond\CF_bondcurrentnum{#4}{#5}\CF_hookstartcontent\CF_hookendcontent }% \endgroup } \def\CF_extractatom#1-#2\_nil{#2}% transforme le bound@outnode en n° de l'atome \def\CF_gobblemovearg @#1#2\_nil#3{% \expandafter\def\csname atom_\number\CF_cnt_atom\endcsname{#2}% \CF_ifinstr{#1},% {% \CF_analysemovearg#1\_nil#3\let\CF_movebondcoeff\empty }% {% \def#3{#1}% }% \CF_doifempty{#2} {% \let\CF_nodestrut\empty }% }% \def\hflipnext{\def\CF_flipstate{1}} \def\vflipnext{\def\CF_flipstate{2}} \let\CF_flipstate\CF_zero \def\CF_drawatomgroup#1#2#3{% #1=angle d'arrivée de la liaison #2=numero atome sur lequel arrive la liaison #3=groupe d'atomes \expandafter\let\expandafter\CF_bondoutcontent% assigne le contenu de l'atome d'où part la liaison \csname \ifdefined\CF_bondoutnode atom_\expandafter\CF_extractatom\CF_bondoutnode\_nil \else empty% \fi \endcsname \global\advance\CF_cnt_group1 \let\CF_currentatom\empty \global\let\CF_hookdrawlist\empty \CF_cnt_atomgroup0 % est le nombre d'atome dans le groupe que va calculer \CF_drawatomgroupa \CF_iffirsttokmatch{#3}?% {% \CF_drawatomgroupa{{}#3}% } {% \CF_drawatomgroupa{#3}% }% \def\CF_currentatomgroup{#3}% \CF_removemovearg\CF_currentatomgroup% enlève les "@{}" \CF_ifinstr{#3}?% {% \CF_removehook\CF_currentatomgroup \CF_expsecond\CF_stripsp\CF_currentatomgroup\CF_ifempty {% \let\CF_currentatomgroup\empty% rollback à 1.66 } {}% }% {}% \CF_doifnotempty{#2} {% \ifnum#2<1 \CF_warning{no atom found at position #2, pershaps you mispelled the optional argument of the bond.}% \else \ifnum#2>\CF_cnt_atomgroup \CF_error{no atom found at position #2, pershaps you mispelled the optional argument of the bond.}% \fi \fi }% \edef\CF_hookatomnumber{% \CF_ifempty{#2} {% \ifdim#1pt>90pt \ifdim#1pt<270pt \number\CF_cnt_atomgroup \else 1% \fi \else 1% \fi } {% #2% }% }% \CF_cnt_atom\CF_hookatomnumber \ifboolKV[chemfig]{use atom strut}% bugfix 1.71 {% branche inutile si use atom strut=false \CF_ifzerodim\CF_currentatomgroup {% \let\CF_nodestrut\empty } {% \CF_ifx\empty\CF_bondoutcontentsaved {% \def\CF_nodestrut{\vphantom\CF_bondoutcontent}% }% {% \def\CF_nodestrut{\vphantom\CF_bondoutcontentsaved}% }% }% } {% \let\CF_nodestrut\empty }% \edef\CF_optstring{anchor=\ifnum\CF_lastaction=0 base\else\ifCF_in_cycle center\else\ifCF_macro_fixed_bond_length 180+#1\else center\fi\fi\fi,at=(CF_node),\CF_nodestyle}% premier atome de la molécule affiché \loop \unless\ifnum\CF_cnt_atom>\CF_cnt_atomgroup \CF_eexpafter{\futurelet\CF_toksa}{\expandafter\expandafter\expandafter\CF_gobtonil\csname atom_\number\CF_cnt_atom\endcsname\_nil}% \CF_ifx @\CF_toksa% l'atome courant commence par un "@" {% \CF_threeea\CF_gobblemovearg\csname atom_\number\CF_cnt_atom\endcsname\_nil\CF_moveatomname \CF_expafter{\node[}\CF_optstring,overlay](\CF_moveatomname){\phantom{\CF_nodecontent}};% \let\CF_moveatomname\empty } {}% \ifboolKV[chemfig]{debug} {% \CF_expafter{\node[}\CF_optstring,draw=gray](n\number\CF_cnt_group-\number\CF_cnt_atom){\CF_nodecontent};% \CF_show_debug_atom } {% \CF_expafter{\node[}\CF_optstring](n\number\CF_cnt_group-\number\CF_cnt_atom){\CF_nodecontent};% }% \let\CF_nodestrut\empty \advance\CF_cnt_atom1 \edef\CF_optstring{anchor=base \ifnum\CF_flipstate=1 east\else west\fi,at=(n\number\CF_cnt_group-\number\numexpr\CF_cnt_atom-1.base \ifnum\CF_flipstate=1 west\else east\fi),\CF_nodestyle}% \repeat \CF_cnt_atom\CF_hookatomnumber \ifnum\CF_lastaction=2 % s'il faut tracer une liaison \gdef\CF_cycleanglecorrection{0}% alors c'est qu'un cycle ne peut pas commencer la molécule : annulation de la correction d'angle \CF_drawbond\CF_bondtype{\CF_bondoutnode}{n\number\CF_cnt_group-\number\CF_cnt_atom}\CF_previousatomgroup\CF_currentatomgroup \let\CF_previousbondtype\CF_bondtype \fi \def\CF_lastaction{1}% met la dernière action à 1 : affichage d'un noeud \loop \ifnum\CF_cnt_atom>1 \advance\CF_cnt_atom-1 \edef\CF_optstring{anchor=base \ifnum\CF_flipstate=1 west\else east\fi,at=(n\number\CF_cnt_group-\number\numexpr\CF_cnt_atom+1.base \ifnum\CF_flipstate=1 east\else west\fi),\CF_nodestyle}% \CF_eexpafter{\futurelet\CF_toksa}{\expandafter\expandafter\expandafter\CF_gobtonil\csname atom_\number\CF_cnt_atom\endcsname\_nil}% \CF_ifx @\CF_toksa% l'atome courant commence par un "@" {% \CF_threeea\CF_gobblemovearg\csname atom_\number\CF_cnt_atom\endcsname\_nil\CF_moveatomname \CF_expafter{\node[}\CF_optstring,overlay](\CF_moveatomname){\phantom{\CF_nodecontent}};% \let\CF_moveatomname\empty } {}% \ifboolKV[chemfig]{debug} {% \CF_expafter{\node[}\CF_optstring,draw=gray](n\number\CF_cnt_group-\number\CF_cnt_atom){\CF_nodecontent};% \CF_show_debug_atom } {% \CF_expafter{\node[}\CF_optstring](n\number\CF_cnt_group-\number\CF_cnt_atom){\CF_nodecontent};% }% \repeat \ifboolKV[chemfig]{debug} \CF_show_debug_atomgroup {}% \CF_drawallhooks \edef\CF_lastgroupnumber{\number\CF_cnt_group}% \let\CF_previousatomgroup\CF_currentatomgroup \CF_ifzerodistance{n\number\CF_cnt_group-1}{south west}{n\number\CF_cnt_group-\number\CF_cnt_atomgroup}{north west}% new v1.71 {\def\CF_previousatomgroup_nodim{1}} {\def\CF_previousatomgroup_nodim{0}}% } \def\CF_show_debug_atom{% \node[at=(n\number\CF_cnt_group-\number\CF_cnt_atom.south),anchor=north,outer sep=1pt,overlay]{$\scriptscriptstyle\color{gray}\number\CF_cnt_atom$};% } \def\CF_show_debug_atomgroup{% \draw[red,overlay] ([xshift=-.5pt,yshift=.5pt]n\number\CF_cnt_group-1.north west) rectangle ([xshift=.5pt,yshift=-.5pt]n\number\CF_cnt_group-\number\CF_cnt_atomgroup.south east);% \path (n\number\CF_cnt_group-1.north west) -- (n\number\CF_cnt_group-\number\CF_cnt_atomgroup.north east) node [midway,yshift=1pt,overlay] {$\scriptscriptstyle\color{red}\number\CF_cnt_group$};% TODO : supprimer ce noeud qui ne donne aucune information utile ? } \def\CF_savemovearg @#1#2\_nil{\def\CF_currentatom{@{#1}}} \def\CF_drawatomgroupa#1{% transforme #1 en un groupe d'atomes \CF_ifempty{#1} {% \expandafter\let\csname atom_\number\CF_cnt_atomgroup\endcsname\CF_currentatom } {% \advance\CF_cnt_atomgroup1 \futurelet\CF_toksa\CF_gobtonil#1\_nil \CF_ifx @\CF_toksa {% \CF_savemovearg#1\_nil \CF_removemovearga#1\_nil\CF_aftermovearg \CF_expsecond\CF_drawatomgroupb{\CF_aftermovearg}% }% {% \let\CF_currentatom\empty \CF_drawatomgroupb{#1}% }% }% } \def\CF_drawatomgroupb#1{% \CF_ifempty{#1} {% \expandafter\let\csname atom_\number\CF_cnt_atomgroup\endcsname\CF_currentatom } {% \futurelet\CF_toksa\CF_gobtonil#1\_nil \CF_ifxcase\CF_toksa \bgroup {% \CF_eaddtomacro\CF_currentatom{\expandafter{\CF_firsttonil#1\_nil}}% \CF_expsecond\CF_drawatomgroupc{\CF_gobarg#1}% }% \CF_sptoken {% \CF_addtomacro\CF_currentatom{ }% \CF_expsecond\CF_drawatomgroupc{\CF_afterspace#1\_nil}% }% \CF_ifxcase_elseif \CF_eaddtomacro\CF_currentatom{\CF_firsttonil#1\_nil}% \CF_expsecond\CF_drawatomgroupc{\CF_gobarg#1}% \CF_ifxcase_endif }% } % enlève tous les "@{nom}" de la sc #1 \def\CF_removemovearg#1{% \CF_expsecond\CF_ifinstr{#1}@% {% \expandafter\CF_removemovearga#1\_nil#1% \CF_removemovearg#1% }% {}% } % enlève le premier "@{}" de l'argument et l'assigne à #2 \def\CF_removemovearga#1\_nil#2{% \def\CF_removemoveargb##1@{% \CF_expsecond{\def#2}{\CF_gobarg##1}% mange le \relax \CF_removemoveargc\relax }% \def\CF_removemoveargc##1\_nil{\CF_eaddtomacro#2{\CF_gobtwoargs##1}}% mange le \relax et le \CF_removemoveargb\relax#1\_nil } \def\CF_drawatomgroupc#1{% transforme #1 en un groupe d'atomes \CF_ifempty{#1} {% \expandafter\let\csname atom_\number\CF_cnt_atomgroup\endcsname\CF_currentatom \let\CF_currentatom\empty } {% \futurelet\CF_toksa\CF_gobtonil#1\_nil \CF_ifx @\CF_toksa {% \expandafter\let\csname atom_\number\CF_cnt_atomgroup\endcsname\CF_currentatom \let\CF_currentatom\empty \CF_drawatomgroupa{#1}% }% {% \CF_ifx|\CF_toksa {% \expandafter\let\csname atom_\number\CF_cnt_atomgroup\endcsname\CF_currentatom \let\CF_currentatom\empty \CF_expsecond\CF_drawatomgroupa{\CF_gobarg#1}% }% {% \CF_ifx\CF_sptoken\CF_toksa {% \CF_addtomacro\CF_currentatom{ }% \CF_expsecond\CF_drawatomgroupc{\CF_afterspace#1\_nil}% }% {% \CF_ifx\bgroup\CF_toksa {% \CF_eaddtomacro\CF_currentatom{\expandafter{\CF_firsttonil#1\_nil}}% \CF_expsecond\CF_drawatomgroupc{\CF_gobarg#1}% }% {% \CF_expsecond\CF_ifcarisupperletter{\CF_firsttonil#1\_nil}% {% \expandafter\let\csname atom_\number\CF_cnt_atomgroup\endcsname\CF_currentatom \let\CF_currentatom\empty \CF_drawatomgroupa{#1}% }% {% \CF_ifx?\CF_toksa {% \CF_expsecond\CF_iffirsttokmatch{\CF_gobarg#1}[% un crochet après le "?" {% \expandafter\CF_graboptarg\CF_gobarg#1\_nil\CF_afterhook }% {% \CF_expafter{\CF_graboptarg[]}{\CF_gobarg#1}\_nil\CF_afterhook }% \CF_exptwomacroargs\CF_ifinstr{\CF_hooklist}{\expandafter(\CF_hookcurrentname)}% crochet déjà défini ? {% \CF_expsecond\CF_hookparselist{\CF_hookcurrentname}% chercher les caractéristiques du crochet sauvegardé \CF_edefaddtomacro\CF_hookdrawlist{% [\CF_hookcurrentname,\CF_hookcurrentlink,\CF_hookcurrenttikz]{\CF_hooksavedcoord}{n\number\CF_cnt_group-\number\CF_cnt_atomgroup}}% \CF_eaddtomacro\CF_hookdrawlist{\expandafter{\CF_hooksavedcontent}}% \CF_eaddtomacro\CF_hookdrawlist{\expandafter{\CF_currentatom}}% ajoute les 4 arguments à la liste des crochets à tracer \global\let\CF_hookdrawlist\CF_hookdrawlist }% {% \CF_edefaddtomacro\CF_hooklist{(\CF_hookcurrentname)|n\number\CF_cnt_group-\number\CF_cnt_atomgroup|}% \CF_eaddtomacro\CF_hooklist{\CF_currentatom|}% \global\let\CF_hooklist\CF_hooklist }% \CF_expsecond\CF_drawatomgroupc{\CF_afterhook}% }% {% \CF_eaddtomacro\CF_currentatom{\CF_firsttonil#1\_nil}% \CF_expsecond\CF_drawatomgroupc{\CF_gobarg#1}% }% }% }% }% }% }% }% } \def\CF_kookdefaultname{a} \def\CF_hookdefaultlink{-} \def\CF_hookdefaulttikz{} \def\CF_hookparseoptarg#1,#2,#3\_nil{% \CF_testemptyandassign\CF_hookcurrentname{#1}\CF_kookdefaultname \CF_testemptyandassign\CF_hookcurrentlink{#2}\CF_hookdefaultlink \CF_testemptyandassign\CF_hookcurrenttikz{#3}\CF_hookdefaulttikz } \def\CF_graboptarg[#1]#2\_nil#3{% \CF_hookparseoptarg#1,,\_nil \def#3{#2}% } \def\CF_hookparselist#1{% #1 est le nom du noeud à retrouver \def\CF_hookparselista##1(#1)|##2|##3|##4\_nil{% \def\CF_hooksavedcoord{##2}% \def\CF_hooksavedcontent{##3}% }% \expandafter\CF_hookparselista\CF_hooklist\_nil } \def\CF_removehook#1{% \CF_expsecond\CF_ifinstr{#1}?% {% \CF_expafter{\CF_removehooka\relax}#1\_nil#1% \CF_removehook#1% } {}% } \def\CF_removehooka#1?#2\_nil#3{% \CF_iffirsttokmatch{#2}[% {% \CF_removehookb#1?#2\_nil#3% } {% \CF_expsecond{\def#3}{\CF_gobarg#1#2}% }% } \def\CF_removehookb#1?[#2]#3\_nil#4{\CF_expsecond{\def#4}{\CF_gobarg#1#3}} \defKV[charge]{% .radius = \CF_defifempty\CF_dotradius {#1}{0.15ex}, :sep = \CF_defifempty\CF_dotsep {#1}{0.3em}, .style = \CF_defifempty\CF_dotstyle {#1}{fill=black}, "length = \CF_defifempty\CF_rectlength{#1}{1.5ex}, "width = \CF_defifempty\CF_rectwidth {#1}{.3ex} } \def\setcharge#{\setKV[charge]} \def\resetcharge{\restoreKV[charge]} \setKVdefault[charge]{% debug = false,% trace les contours des noeuds macro atom = \printatom,%macro qui prendra comme argument l'atome recevant la charge circle = false,% false => noeud atome = rectangle macro charge = ,% macro attendue (\printatom ou \ensuremath, par exemple) qui prendra comme argument la charge extra sep = 1.5pt,% séparation additionnelle entre le noeud (cercle ou rectangle) et la position des charges overlay = true,% charges en "surimpression" shortcuts = true,% raccourcis \. \: \| et \" actifs pour Lewis lewisautorot = true,% rotation auto charge Lewis .radius = 0.15ex,% rayon du point :sep = 0.3em,% séparation des deux points .style = {fill=black},% style des points "length = 1.5ex,% longueur rectangle "width = .3ex,% largeur rectangle "style = {black,line width=0.4pt},% style rectangle |style = {black,line width=0.4pt},% style ligne }% \def\chargedot{\CF_testopt\chargedot_a{}} \def\chargedot_a[#1]{% \begingroup \setKV[charge]{#1}% \CF_expafter{\tikz\draw[}{\CF_dotstyle}](0,0)circle(\CF_dotradius);% \endgroup } \def\chargeddot{\CF_testopt\chargeddot_a{}} \def\chargeddot_a[#1]{% \begingroup \setKV[charge]{#1}% \ifboolKV[charge]{lewisautorot} {% \pgfmathsetmacro\CF_lewisrot{90+\chargeangle}% } {% \def\CF_lewisrot{0}% }% \pgfmathsetmacro\CF_halfsep{\CF_dotsep/2}% \tikzpicture[anchor=center,rotate=\CF_lewisrot] \CF_expafter{\draw[}{\CF_dotstyle}](-\CF_halfsep pt,0)circle(\CF_dotradius)(\CF_halfsep pt,0)circle(\CF_dotradius);% \endtikzpicture \endgroup } \def\chargerect{\CF_testopt\chargerect_a{}} \def\chargerect_a[#1]{% \begingroup \setKV[charge]{#1}% \ifboolKV[charge]{lewisautorot} {% \pgfmathsetmacro\CF_lewisrot{90+\chargeangle}% } {% \def\CF_lewisrot{0}% }% \pgfmathsetmacro\CF_halfwidth{\CF_rectwidth/2}% \pgfmathsetmacro\CF_halflength{\CF_rectlength/2}% \tikzpicture[anchor=center,rotate=\CF_lewisrot]% \CF_eexpafter{\draw[}{\useKV[charge]{"style}}](-\CF_halflength pt,-\CF_halfwidth pt)rectangle(\CF_halflength pt,\CF_halfwidth pt);% bugfix 1.51 \endtikzpicture \endgroup } \def\chargeline{\CF_testopt\chargeline_a{}} \def\chargeline_a[#1]{% \begingroup \setKV[charge]{#1}% \ifboolKV[charge]{lewisautorot} {% \pgfmathsetmacro\CF_lewisrot{90+\chargeangle}% } {% \def\CF_lewisrot{0}% }% \pgfmathsetmacro\CF_halflength{\CF_rectlength/2}% \tikzpicture[anchor=center,rotate=\CF_lewisrot]% \CF_eexpafter{\draw[}{\useKV[charge]{|style}}](-\CF_halflength pt,0)--(\CF_halflength pt,0);% bugfix 1.51 \endtikzpicture \endgroup } \def\CF_enableshortcuts{% \let\CF_saveddot \.\let\.\chargedot \let\CF_savedddot\:\let\:\chargeddot \let\CF_savedrect\"\let\"\chargerect \let\CF_savedline\|\let\|\chargeline \let\enableshortcuts\relax \let\disableshortcuts\CF_disableshortcuts } \def\CF_disableshortcuts{% \let\.\CF_saveddot \let\:\CF_savedddot \let\"\CF_savedrect \let\|\CF_savedline \let\enableshortcuts\CF_enableshortcuts \let\disableshortcuts\relax } \def\charge{% \begingroup \catcode`\: 12 \charge_a{true}% } \def\Charge{% \begingroup \catcode`\: 12 \charge_a{false}% } \def\charge_a#1#2{% #1=TF #2=liste emplacements \CF_testopt{\charge_b{#1}}{}#2\_nil } \def\charge_b#1[#2]#3\_nil{% \charge_c{#1}[#2]{#3}% } \def\charge_c#1[#2]#3#4{% #1=TF pour overlay, #2= réglages, #3=liste d'emplacements, #4=atome \setcharge{overlay=#1,#2}% \setbox\CF_chargebox\hbox{\useKV[charge]{macro atom}{#4}}% \CF_ifinsidetikz {% \pgfinterruptpicture \let\CF_atendofcharge\endpgfinterruptpicture } {% \let\CF_atendofcharge\relax }% \expanded{\noexpand \tikzpicture[every node/.style={% \ifboolKV[charge]{debug}{draw=red,}{}% anchor=base,% inner sep=0pt,% outer sep=0pt,% minimum size=0pt},% baseline]}% \expanded{\noexpand \node[% \ifboolKV[charge]{circle}{circle,}{}% \ifboolKV[charge]{debug}{draw=green,}{}% anchor=base% ]}% (atombox)at(0,0)% {\copy\CF_chargebox};% noeud contenant l'atome \expanded{\noexpand \node[% \ifboolKV[charge]{circle}{circle,}{}% \ifboolKV[charge]{debug}{draw=blue,}{}% anchor=base,% inner sep=\useKV[charge]{extra sep},% overlay% ]}% (atom)at(0,0){% \vrule width0pt height\ht\CF_chargebox depth\dp\CF_chargebox \vrule width\wd\CF_chargebox height\CF_zero depth\CF_zero};% noeud pour placer les charges \let\enableshortcuts\relax \let\disableshortcuts\relax \ifboolKV[charge]{shortcuts} \CF_enableshortcuts {}% l'atome n'est _PAS_ concerné par les racourcis \charge_d#3,\CF_quark=% \endtikzpicture \CF_atendofcharge \endgroup } \def\charge_d#1={% \CF_ifx\CF_quark{#1}% {} {% \CF_striplastsp{#1}\charge_e=% bugfix 1.54 }% } \def\charge_e#1={% \CF_ifinstr{#1}[ {% \charge_f#1=% } {% \charge_f#1[]=% }% } \def\charge_f#1[#2]={% \CF_ifinstr{#1}: {% \charge_g#1[#2]=% } {% \charge_g#1:0pt[#2]=% }% } \def\charge_g#1:#2[#3]=#4,{% #1=angle, #2=offset, #3=code tikz charge, #4=charge \CF_stripsp{#1}\CF_ifinteger {% \pgfmathsetmacro\chargeangle{mod(#1,360)}% } {% \pgfmathanglebetweenpoints{\pgfpointanchor{atom}{center}}{\CF_stripsp{#1}{\pgfpointanchor{atom}}}% \let\chargeangle\pgfmathresult% incorrect si (atom.center==atom.#1) && (extra sep==0) TODO: mettre un warning ? }% \edef\CF_offset{\the\dimexpr#2+0pt}% \CF_stripsp{#1}{\CF_distancebetweenpoints{atom}{center}{atom}}\CF_chargedistance \CF_eexpafter{\node[anchor=center,}{\ifboolKV[charge]{overlay}{overlay,}{}}#3]% at([shift=(\chargeangle:\CF_chargedistance pt+\CF_offset)]atom.center){\useKV[charge]{macro charge}{#4}};% \charge_d } \def\Chembelow{% \begingroup \let\CF_temp\CF_gobarg \CF_chembelowa } \def\chembelow{% \begingroup \let\CF_temp\CF_id \CF_chembelowa } \def\CF_chembelowa{\CF_testopt\CF_chembelowb\CF_stacksep} \def\CF_chembelowb[#1]#2#3{% \setbox\CF_box\hbox{\printatom{#2}}% \expandafter\vtop\CF_temp{to\ht\CF_box}{% \offinterlineskip \hbox{\printatom{#2}}% \kern#1\relax \hbox to\wd\CF_box{\hss\printatom{#3}\hss}% \CF_temp\vss }% \endgroup } \def\Chemabove{% \begingroup \let\CF_temp\CF_gobarg \CF_chemabovea } \def\chemabove{% \begingroup \let\CF_temp\CF_id \CF_chemabovea } \def\CF_chemabovea{\CF_testopt\CF_chemaboveb\CF_stacksep} \def\CF_chemaboveb[#1]#2#3{% \setbox\CF_box\hbox{\printatom{#2}}% \expandafter\vbox\CF_temp{to\ht\CF_box}{% \offinterlineskip \CF_temp\vss \hbox to\wd\CF_box{\hss\printatom{#3}\hss}% \kern#1\relax \hbox{\printatom{#2}}% }% \endgroup } \def\chemmove{\CF_testopt\CF_chemmove{}} \def\CF_chemmove[#1]#2{% \CF_doifnotempty{#2}% {% \expandafter\tikzpicture\expanded{[overlay,remember picture,-CF\CF_ifempty{#1}{}{,\unexpanded{#1}}]}% #2% \endtikzpicture }% } \def\chemnameinit#1{% \setbox\CF_boxstuff\hbox{#1}% \ifboolKV[chemfig]{gchemname} \xdef \edef \CF_dpmax{\the\dp\CF_boxstuff}% } \chemnameinit{} \def\CF_parsemolname#1\\#2\_nil{% \hbox to\CF_wdstuffbox{\hss#1\hss}% \CF_doifnotempty{#2}{\CF_parsemolname#2\_nil}% } \def\chemname{% \CF_ifstar {% \CF_adjust_name_dpfalse \CF_chemnamea } {% \CF_adjust_name_dptrue \CF_chemnamea }% } \def\CF_chemnamea{\CF_testopt\CF_chemnameb{}} \def\CF_chemnameb[#1]#2#3{% \CF_stripsp{#1}\CF_ifempty% v1.71 : mise en cohérence avec \name[dimension]{nom} {% \def\CF_current_name_sep{\useKV[chemfig]{name sep}}% } {% \def\CF_current_name_sep{#1}% }% \setbox\CF_boxstuff\hbox{#2}% \edef\CF_wdstuffbox{\the\wd\CF_boxstuff}% \edef\CF_dpstuffbox{\the\dp\CF_boxstuff}% \leavevmode \ifdim\CF_dpmax<\CF_dpstuffbox \ifboolKV[chemfig]{gchemname}\global{}\let\CF_dpmax\CF_dpstuffbox \fi \vtop{% \box\CF_boxstuff \nointerlineskip \kern\dimexpr\CF_current_name_sep\ifCF_adjust_name_dp+\CF_dpmax-\CF_dpstuffbox\fi\relax \CF_parsemolname#3\\\_nil }% } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% R É A C T I O N S H O R I Z O N T A L E S %%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \newbox\CF_harrow_boxup \newbox\CF_harrow_boxdown \newcount\CF_hreact_cnt \def\CF_harrowdisplaylabel#1#2#3#4#5#6#7#8{} \def\hreac{% \begingroup \CF_testopt\CF_hreac_a{}% } \def\CF_hreac_a[#1]{% #1=arg optionnel \CF_doifnotempty{#1}{\setKV[chemfig]{#1}}% \CF_hreact_cnt0 % compteur de composé \pgfmathsetmacro\CF_arrowdoublesep{\CF_arrowdoublesep/2}% \pgfmathsetmacro\CF_arrowdoubleposstart{(1-\CF_arrowdoubleposstart)/2}% \pgfmathsetmacro\CF_arrowdoubleposend{1-\CF_arrowdoubleposstart}% \let\CF_arrowshiftnodes\CF_gobarg % neutralisation des macros \let\CF_arrowdisplaylabel\CF_harrowdisplaylabel% inutiles de \CF_arrow \let\CF_hreac_name_list\empty \let\CF_hreac_current_name\empty \def\CF_hreac_max_depth{0pt}% \def\CF_current_shiftup{0pt}% \def\CF_current_shiftup_back{0pt}% \def\CF_current_shiftleft{0pt}% \edef\CF_current_node_name{c\number\CF_hreact_cnt}% \let\CF_hreac_current_compound\empty \let\chemname\CF_hreac_chemname % reprogrammation de \chemname \let\name\CF_hreac_name \CF_compound_is_chemfigfalse \ifboolKV[chemfig]{hreac debug} {% \tikzpicture[every node/.style={draw,anchor=base,inner sep=0pt,outer sep=0pt,minimum size=1pt},baseline]% } {% \tikzpicture[every node/.style={anchor=base,inner sep=0pt,outer sep=0pt,minimum size=0pt},baseline]% }% \node[anchor=\CF_hreac_init_anchor](\CF_current_node_name){\vphantom{A}};% \pgfextracty\CF_dim{\pgfpointanchor{\CF_current_node_name}{base}}% \edef\CF_hreac_posy_initnode{\the\CF_dim}% \CF_hreac_b } \def\CF_hreac_b{% \futurelet\CF_toksa\CF_hreac_c } \def\CF_hreac_c{% \CF_ifxcase\CF_toksa \endhreac {}% exécuter \endhreac \bgroup {% \ifCF_compound_is_chemfig \edef\CF_restore_hashcatcode{\catcode\number`\# =\number\catcode`\# \relax}% \catcode`\# 12 \fi \CF_hreac_add_arg }% \CF_sptoken \CF_hreac_gob_space + \CF_hreac_next_plus > \CF_hreac_next_arrow \^ \CF_hreac_set_shiftup \> \CF_hreac_set_shiftleft \chemfig \CF_hreac_next_chemfig \chemname {}% exécuter \CF_hreac_name \name {}% exécuter \CF_hreac_name \hreac \CF_hreac_illegal_command \schemestart\CF_hreac_illegal_command \CF_ifxcase_elseif \CF_hreac_addtok \CF_ifxcase_endif } \def\CF_hreac_illegal_command#1{% \CF_error{Macro '\string#1' not allowed in \string\hreac...\string\endhreac}% } \def\CF_hreac_set_shiftup\^{% \CF_ifstar {% \CF_hreac_set_shiftup_a1% } {% \CF_hreac_set_shiftup_a0% }% } \def\CF_hreac_set_shiftup_a#1#2{% #1=1 ou 0 selon * #2=dimension \edef\CF_current_shiftup{\CF_current_shiftup+#2}% \edef\CF_current_shiftup_back{\ifnum#1=1 0pt\else-#2\fi}% \CF_hreac_b } \def\CF_hreac_set_shiftleft\>#1{% \def\CF_current_shiftleft{#1}% \CF_hreac_b } \def\CF_hreac_addtok#1{% \CF_addtomacro\CF_hreac_current_compound{#1}% \CF_hreac_b } \def\CF_hreac_add_arg#1{% \CF_addtomacro\CF_hreac_current_compound{{#1}}% \ifCF_compound_is_chemfig \CF_restore_hashcatcode \CF_compound_is_chemfigfalse \fi \CF_hreac_b } \def\endhreac{% \CF_expsecond\CF_hreac_compose\CF_hreac_current_compound \expandafter\CF_hreac_draw_names\CF_hreac_name_list[0={}{}{}]% placer les noms des composés \ifboolKV[chemfig]{hreac debug} {% \pgfextractx\CF_dim{\pgfpointanchor{\CF_current_node_name}{0}}% \edef\CF_current_width{\the\CF_dim}% \pgfextractx\CF_dim{\pgfpointanchor{c1}{180}}% \edef\CF_current_width{\the\dimexpr\CF_current_width-\CF_dim\relax}% largeur de la réaction \draw[dotted,red,line width=0.5pt](c1.west)--([xshift=\CF_current_width]c1.west);% } {}% \endtikzpicture \endgroup } \def\CF_hreac_draw_names[#1=#2#3#4]{% \CF_ifnum{#1=0 } {} {% \node[anchor=north,at=(c#1.south),yshift=-(\CF_hreac_max_depth-#3+\CF_hreac_name_sep)](name#1)% {\hbox to#2{\hss\vbox{\CF_compose_harrow_label#4\\\_nil}\hss}};% \ifboolKV[chemfig]{hreac debug} {% \node[anchor=north,at=(name#1.south),fill=purple!60,overlay,opacity=0.5]{\scriptsize\bfseries name#1}; }% {}% \CF_hreac_draw_names }% } \expandafter\def\expandafter\CF_hreac_gob_space\space{% \CF_hreac_b } \def\CF_hreac_next_plus#1{% \CF_expsecond\CF_hreac_compose\CF_hreac_current_compound \CF_hreac_compose{#1}% #1= '+' \CF_hreac_b } \def\CF_hreac_next_arrow>{% \CF_expsecond\CF_hreac_compose\CF_hreac_current_compound \CF_harrow } \def\CF_hreac_next_chemfig#1{% #1 est \chemfig \CF_testopt\CF_hreac_next_chemfig_a{}% bugfix v1.71 } \def\CF_hreac_next_chemfig_a[#1]{% \CF_addtomacro\CF_hreac_current_compound{\chemfig[#1]}% \CF_compound_is_chemfigtrue \CF_hreac_b } \def\CF_hreac_chemname{% \CF_testopt\CF_hreac_chemname_a{}% fixme v1.71 } \def\CF_hreac_chemname_a[#1]{% \CF_stripsp{#1}\CF_ifempty% v1.71 {% \edef\CF_hreac_chemname_current_sep{\useKV[chemfig]{name sep}}% } {% \def\CF_hreac_chemname_current_sep{#1}% }% \begingroup \catcode`\# 12 \CF_hreac_chemname_b } \def\CF_hreac_chemname_b#1{% #1=composé lu avec \catcode`\#=12 \endgroup \CF_hreac_chemname_c{#1}% } \def\CF_hreac_chemname_c#1#2{% #1=composé #2=nom \endgroup \def\CF_hreac_current_name{#2}% \CF_hreac_b#1% } \def\CF_hreac_name{% si \name{nom} est rencontré \CF_testopt\CF_hreac_name_a{}% fixme v1.71 } \def\CF_hreac_name_a[#1]#2{% \CF_stripsp{#1}\CF_ifempty% v1.71 {% \edef\CF_hreac_chemname_current_sep{\useKV[chemfig]{name sep}}% } {% \def\CF_hreac_chemname_current_sep{#1}% }% \def\CF_hreac_current_name{#2}% \CF_hreac_b } \def\CF_harrow{% \CF_ifnextchar\bgroup {\CF_harrow_a} {\CF_harrow_b{->}}% } \def\CF_harrow_a#1{% \CF_stripsp{#1}\CF_harrow_b } \def\CF_harrow_b#1{% \CF_ifinstr{\relax->\relax<-\relax<->\relax<=>\relax<<->\relax<->>\relax}{\relax#1\relax} {% \def\CF_harrow_type{#1}% } {% \CF_ifempty{#1} {% \def\CF_harrow_type{->}% } {% \CF_error{'\detokenize{#1}' is not a valid arrow type in hreac} \def\CF_harrow_type{->}% }% }% \CF_harrow_c } \def\CF_harrow_c{% \CF_testopt\CF_harrow_d{}% } \def\CF_harrow_d[#1]{% \CF_testopt{\CF_harrow_e[#1]}{}% } \def\CF_harrow_e[#1][#2]{% \let\CF_harrow_length\CF_harrow_min_width \CF_doifnotempty{#1} {% \setbox\CF_harrow_boxup\hbox {% \vbox{\pgfinterruptpicture\CF_compose_harrow_label#1\\\_nil\endpgfinterruptpicture}% }% \ifdim\dimexpr\wd\CF_harrow_boxup+\CF_harrow_label_xsep*2\relax>\CF_harrow_length\relax \edef\CF_harrow_length{\the\dimexpr\wd\CF_harrow_boxup+\CF_harrow_label_xsep*2\relax}% \fi }% \CF_doifnotempty{#2} {% \setbox\CF_harrow_boxdown\hbox {% \vtop{\pgfinterruptpicture\CF_compose_harrow_label#2\\\_nil\endpgfinterruptpicture}% }% \ifdim\dimexpr\wd\CF_harrow_boxdown+\CF_harrow_label_xsep*2\relax>\CF_harrow_length\relax \edef\CF_harrow_length{\the\dimexpr\wd\CF_harrow_boxdown+\CF_harrow_label_xsep*2\relax}% \fi }% \CF_hreac_compose{\kern\CF_harrow_length}% \node[at=(\CF_current_node_name.180)](harrowstart){};% \node[at=(\CF_current_node_name.0)](harrowend){};% \CF_eexpsecond{\def\CF_arrowtip}{\expandafter\CF_gobarg\CF_arrowhead}% \edef\CF_arrowstartnode{harrowstart}% \edef\CF_arrowendnode {harrowend}% \def\CF_arrowcurrentstyle{-CF,line width=0.5pt}% \csname CF_arrow(\CF_harrow_type)\endcsname[][][][][][][][]\_nil \CF_doifnotempty{#1} {% \node[anchor=south, at=(\CF_current_node_name.north), yshift=\CF_arrowlabelsep]% (labelup\the\CF_hreact_cnt)% {\hbox to\dimexpr\CF_harrow_length-\CF_harrow_label_xsep*2\relax {\CF_harrow_label_align_left\box\CF_harrow_boxup\CF_harrow_label_align_right}% };% \ifboolKV[chemfig]{hreac debug} {% \node[anchor=south, at=(labelup\the\CF_hreact_cnt.north), fill=blue!60, overlay, opacity=0.5]% {\scriptsize\bfseries l-sup\the\CF_hreact_cnt}; } {}% }% \CF_doifnotempty{#2} {% \node[% anchor=north, at=(\CF_current_node_name.south), yshift=-\CF_arrowlabelsep% ]% (labeldown\the\CF_hreact_cnt)% {% \hbox to\dimexpr\CF_harrow_length-\CF_harrow_label_xsep*2\relax {\CF_harrow_label_align_left\box\CF_harrow_boxdown\CF_harrow_label_align_right}% };% \ifboolKV[chemfig]{hreac debug} {% \node[% anchor=north, at=(labeldown\the\CF_hreact_cnt.south), fill=blue!60, overlay, opacity=0.5 ] {\scriptsize\bfseries l-inf\the\CF_hreact_cnt}; } {}% }% \CF_hreac_b } \def\CF_hreac_compose#1{% \advance\CF_hreact_cnt1 \let\CF_previousnodename\CF_current_node_name \edef\CF_current_node_name{c\number\CF_hreact_cnt}% \edef\CF_hreac_current_compound_sep{\CF_ifnum{\CF_hreact_cnt=1 }{0pt}{\CF_hreac_sep}}% \node[% anchor=180, at=(\CF_previousnodename.0), xshift=\CF_hreac_current_compound_sep+\CF_current_shiftleft, yshift=\CF_current_shiftup% ]% (\CF_current_node_name){#1};% \ifboolKV[chemfig]{hreac debug} {% \node[% anchor=south, at=(\CF_current_node_name.north), fill=green!60, overlay, opacity=0.5% ]% {\scriptsize\bfseries \CF_current_node_name};% \node[at=(\CF_current_node_name.west),fill,red]{}; } {}% \pgfextracty\CF_dim{\pgfpointanchor{\CF_current_node_name}{south}}% \edef\CF_current_depth{\the\dimexpr\CF_hreac_posy_initnode-\CF_dim\relax}% \CF_ifnum{0\ifx\CF_hreac_current_name\empty1\else\ifx\CF_hreac_chemname_current_sep\empty1\fi\fi>0 } {% si composé sans nom OU SINON [décalage] non précisé dans \chemname ou \name \ifdim\CF_current_depth>\CF_hreac_max_depth\relax \let\CF_hreac_max_depth\CF_current_depth \fi } {% \ifdim\dimexpr\CF_current_depth+\CF_hreac_chemname_current_sep\relax>\CF_hreac_max_depth\relax \edef\CF_hreac_max_depth{\the\dimexpr\CF_current_depth+\CF_hreac_chemname_current_sep-\CF_hreac_name_sep\relax}% \fi }% \CF_ifx\CF_hreac_current_name\empty {} {% \pgfextractx\CF_dim{\pgfpointanchor{\CF_current_node_name}{0}}% \edef\CF_current_width{\the\CF_dim}% \pgfextractx\CF_dim{\pgfpointanchor{\CF_current_node_name}{180}}% \edef\CF_current_width{\the\dimexpr\CF_current_width-\CF_dim\relax}% largeur du composé \CF_edefaddtomacro\CF_hreac_name_list{% [% \the\CF_hreact_cnt=% {\CF_current_width}% {\CF_current_depth}% {\unexpanded\expandafter{\CF_hreac_current_name}}% ]% }% \let\CF_hreac_current_name\empty }% \def\CF_hreac_current_compound{}% \def\CF_current_shiftleft{0pt}% \let\CF_current_shiftup\CF_current_shiftup_back \def\CF_current_shiftup_back{0pt}% } \def\CF_compose_harrow_label#1\\#2\_nil{% \hbox{#1}% \CF_doifnotempty{#2}{\CF_compose_harrow_label#2\_nil}% } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% S C H É M A S R É A C T I O N N E L S %%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \let\CF_schemenest\CF_zero \def\CF_subscheme{\CF_testopt\CF_subschemea{}} \def\CF_subschemea[#1]{\CF_testopt{\CF_subschemeb[#1]}{text}} \def\CF_subschemeb[#1][#2]#3{\schemestart[#1][#2]#3\schemestop} \def\chemleft#1#2\chemright#3{% \leavevmode \begingroup \setbox0\hbox{$\vcenter{\hbox{}}$}\edef\CF_delimmathht{\the\ht0}% \setbox0\hbox{#2}\edef\CF_delimdim{\the\dimexpr(\ht0+\dp0)/2}% \edef\CF_delimshift{\the\dimexpr(\ht0-\dp0)/2-\CF_delimmathht}% \raise\CF_delimshift\hbox{$\left#1\vrule height\CF_delimdim depth\CF_delimdim width0pt\right.$}\box0 \raise\CF_delimshift\hbox{$\left.\vrule height\CF_delimdim depth\CF_delimdim width0pt\right#3$}% \endgroup } \def\chemright#1{% \CF_warning{"\string\chemright\string#1" ignored! No \string\chemleft\space previously found.}% } \def\chemup#1#2\chemdown#3{% \begingroup \setbox0\hbox{\printatom{#2}}\edef\CF_delimdim{\the\dimexpr\wd0/2}% \tikzpicture[every node/.style={inner sep=0pt,outer sep=0pt,minimum size=0pt},baseline]% \node[anchor=base west](chem@stuff){\box0};% \node[at=(chem@stuff.north),anchor=east,rotate=-90]{$\left#1\vrule height\CF_delimdim depth\CF_delimdim width0pt\right.$};% \node[at=(chem@stuff.south),anchor=west,rotate=-90]{$\left.\vrule height\CF_delimdim depth\CF_delimdim width0pt\right#3$};% \endtikzpicture \endgroup } \def\chemdown#1{% \CF_warning{"\string\chemdown\string#1" ignored! No \string\chemup\space previously found.}% } \def\CF_setstyle#1,#2,#3\_nil#4#5#6{% \def#4{#1}% \let#5\empty \let#6\empty \CF_iffirsttokmatch\CF_quark{#2\relax} {}% {% \def#5{#2}% \CF_iffirsttokmatch\CF_quark{#3\relax} {}% {% \CF_setstylea#3\_nil#6% }% }% } \def\CF_setstylea#1,\CF_quark#2\_nil#3{\def#3{#1}} \def\CF_and{\futurelet\CF_toksa\CF_anda} \def\CF_anda{% \CF_ifx\CF_toksa\bgroup {% \CF_andb } {% \CF_andb{}% }% } \def\CF_andb#1{% \CF_setstyle#1,\CF_quark,\CF_quark\_nil\CF_signspaceante_\CF_signspacepost_\CF_signvshift_ \CF_doifnotempty\CF_signspaceante_ {% \let\CF_signspaceante\CF_signspaceante_ }% \CF_doifnotempty\CF_signspacepost_ {% \let\CF_signspacepost\CF_signspacepost_ }% \CF_doifnotempty\CF_signvshift_ {% \let\CF_signvshift\CF_signvshift_ }% \raise\CF_signvshift\hbox{\kern\CF_signspaceante$+$\kern\CF_signspacepost}% } \def\schemestart{% \begingroup \CF_ifnum{\CF_schemenest=0 } {% \useKV[chemfig]{schemestart code}% }% {}% \xdef\CF_schemenest{\number\numexpr\CF_schemenest+1}% \CF_testopt\CF_schemestarta{}% } \def\CF_schemestarta[#1]{% \CF_ifempty{#1} {} {% \CF_warning{In a very soon version, the optional argument of \string\schemestart\space must contain keys=values.^^JUse preferable keys 'arrow angle', 'arrow coeff' and 'arrow style'.}% avertissement à partir de la v1.71 }% \CF_setstyle#1,\CF_quark,\CF_quark\_nil\CF_arrowangle_\CF_arrowlength_\CF_arrowstyle_ \CF_doifnotempty\CF_arrowangle_ {% \let\CF_arrowangle\CF_arrowangle_ }% \CF_doifnotempty\CF_arrowlength_ {% \let\CF_arrowlength\CF_arrowlength_% }% \CF_eexpsecond{\def\CF_arrowtip}{\expandafter\CF_gobarg\CF_arrowhead}% \CF_expsecond{\CF_preaddtomacro\CF_defaultarrowstyle}{\CF_arrowhead,}% \let\CF_arrowstyle\CF_defaultarrowstyle \CF_doifnotempty\CF_arrowstyle_ {% \CF_eaddtomacro\CF_arrowstyle{\expandafter,\CF_arrowstyle_}% }% \pgfmathsetmacro\CF_arrowdoublesep{\CF_arrowdoublesep/2}% \pgfmathsetmacro\CF_arrowdoubleposstart{(1-\CF_arrowdoubleposstart)/2}% \pgfmathsetmacro\CF_arrowdoubleposend{1-\CF_arrowdoubleposstart}% \ifboolKV[chemfig]{scheme debug} {% \tikzpicture[every node/.style={draw,anchor=base,inner sep=0pt,outer sep=0pt,minimum size=1.5pt},baseline,remember picture]% } {% \tikzpicture[every node/.style={anchor=base,inner sep=0pt,outer sep=0pt,minimum size=0pt},baseline,remember picture]% }% \let\merge\CF_merge \expandafter\let\csname+\endcsname\CF_and \let\arrow\CF_arrow \let\schemestop\CF_schemestop \let\subscheme\CF_subscheme \CF_testopt{\CF_schemestartb}{}% } \def\CF_schemestartb[#1]{% \CF_ifempty{#1} {} {% \CF_warning{In a very soon version, the second optional argument of \string\schemestart\space will be removed.^^JUse the key 'init anchor' to set the starting anchor.}% avertissement à partir de la v1.71 }% \ifnum\CF_schemenest=1 % la commande n'est pas imbriquée ? \CF_cnt_compound0 \fi \edef\CF_currentnodename{c\number\CF_cnt_compound}% \let\CF_nextnodename\empty \let\CF_nextnodestyle\empty \let\CF_directarrowlist\empty \ifboolKV[chemfig]{scheme debug} {% \node[fill,green](\CF_currentnodename){};% } {% \node(\CF_currentnodename){};% }% \def\CF_nextnodeanchor{#1}% \CF_doifempty\CF_nextnodeanchor{\def\CF_nextnodeanchor{text}}% \let\CF_compound\empty \CF_schemestartc } \def\CF_schemestartc{% \futurelet\CF_toksa\CF_schemestarte } \expandafter\def\expandafter\CF_schemestartd\space{\futurelet\CF_toksa\CF_schemestarte} \def\CF_schemestarte{% ... et l'examine : \CF_iffirsttokina{\arrow\schemestop\merge}% {} {% \CF_ifx\CF_toksa\bgroup {% \ifCF_compound_is_chemfig% bugfix 1.6 \edef\CF_restore_hashcatcode{\catcode\number`\#=\number\catcode`\# \relax}% \catcode`\#12 \fi \CF_addnextarg } {% \CF_ifx\CF_toksa\CF_sptoken {% \CF_addtomacro\CF_compound{ }% \CF_schemestartd } {% \CF_ifx\CF_toksa\chemfig \CF_compound_is_chemfigtrue% mettre le flag à vrai {}% \afterassignment\CF_schemestartc \CF_addtomacro\CF_compound }% }% }% } \def\CF_addnextarg#1{% \CF_addtomacro\CF_compound{{#1}}% \ifCF_compound_is_chemfig% bugfix 1.6 \CF_restore_hashcatcode \CF_compound_is_chemfigfalse% mettre le flag à faux \fi \CF_schemestartc } \def\CF_displaycompound#1#2{% #1 = nom et #2 = style \CF_doifnotempty\CF_compound {% \global\advance\CF_cnt_compound1 \CF_ifx\CF_defaultcompoundstyle\empty {% \let\CF_currentnodestyle\empty } {% \CF_expsecond{\def\CF_currentnodestyle}{\CF_defaultcompoundstyle,}% }% \CF_addtomacro\CF_currentnodestyle{anchor=\CF_nextnodeanchor,at=(\CF_currentnodename)}% \CF_ifempty{#2}% {% \CF_doifnotempty\CF_nextnodestyle {% \CF_eaddtomacro\CF_currentnodestyle{\expandafter,\CF_nextnodestyle}% }% } {% \CF_doifnotempty\CF_nextnodestyle {% \CF_warning{two styles for the same node, first style "\CF_nextnodestyle" ignored}% }% \CF_addtomacro\CF_currentnodestyle{,#2}% }% \CF_ifempty{#1} {% \edef\CF_temp{% \CF_ifempty\CF_nextnodename {% c\number\CF_cnt_compound } {% \CF_nextnodename }% }% } {% \CF_doifnotempty\CF_nextnodename {% \CF_warning{two names for the same node, first name "\CF_nextnodename" ignored}% }% \edef\CF_temp{#1}% }% \CF_expafter{\node[}\CF_currentnodestyle](\CF_temp){\CF_compound};% \ifboolKV[chemfig]{scheme debug}% {% \node[draw=none,anchor=270,at=(\CF_temp.90),fill=green!60,overlay,opacity=0.5]{\scriptsize\bfseries\CF_temp};% } {}% \let\CF_currentnodename\CF_temp }% } \def\CF_schemestop{% \CF_displaycompound{}{}% \CF_directarrowlist \endtikzpicture \xdef\CF_schemenest{\number\numexpr\CF_schemenest-1}% \CF_ifnum{\CF_schemenest=0 } {% \useKV[chemfig]{schemestop code}% }% {}% \endgroup } \def\CF_analysearrowarg#1{\CF_analysearrowarga#1[]\_nil} \def\CF_analysearrowarga#1[#2]#3\_nil{% \CF_ifinstr{#1}. {% \CF_addtomacro\CF_temp{#1[#2]}% } {% \CF_addtomacro\CF_temp{#1.[#2]}% }% } \def\CF_arrow{% \CF_ifnextchar(% {% \CF_arrowa } {% \CF_ifnextchar\bgroup {% \CF_arrowb(.[]--.[])% } {% \CF_arrowb(.[]--.[]){}% }% }% } \def\CF_arrowa(#1--#2){% \def\CF_temp{(}% \CF_analysearrowarg{#1}% \CF_addtomacro\CF_temp{--}% \CF_analysearrowarg{#2}% \CF_addtomacro\CF_temp)% \CF_ifnextchar\bgroup {% \expandafter\CF_arrowb\CF_temp } {% \expandafter\CF_arrowb\CF_temp{}% }% } \def\CF_arrowb(#1.#2[#3]--#4.#5[#6])#7{% \def\CF_currentarrowtype{#7}% nom de la flèche \CF_doifempty\CF_currentarrowtype {% \def\CF_currentarrowtype{->}% }% \CF_testopt{\CF_arrowc(#1.#2[#3]--#4.#5[#6])}{}% } \def\CF_arrowc(#1.#2[#3]--#4.#5[#6])[#7]{% \def\CF_temp{\CF_arrowe(#1.#2[#3]--#4.#5[#6])}% \CF_arrowd#7,\empty,\empty\_nil } \def\CF_arrowd#1,#2,#3\_nil{% \CF_addtomacro\CF_temp{{#1}}% \CF_eaddtomacro\CF_temp{\expandafter{#2}}% \expandafter\CF_eaddtomacro\expandafter\CF_temp\expandafter{\expandafter\expandafter\expandafter{\expandafter\CF_sanitizelastitem#3,\empty\_nil}}% \CF_temp } % #1, #4 : nom des nodes #2, #5 : ancres des nodes #3, #6 : styles des nodes % #7 : angle flèche #8 : longueur flèche #9 : style tikz de la flèche \def\CF_arrowe(#1.#2[#3]--#4.#5[#6])#7#8#9{% \let\CF_arrowcurrentstyle\CF_arrowstyle \if @\expandafter\CF_firsttonil\detokenize{#1.}\_nil% si #1 commence par @ \if @\expandafter\CF_firsttonil\detokenize{#4.}\_nil \CF_eaddtomacro\CF_directarrowlist{\expandafter\CF_directarrow\expandafter{\CF_currentarrowtype}{#1}{#2}{#4}{#5}{#9}}% \let\CF_nextaction\CF_schemestartc \else \CF_doifnotempty\CF_arrowcurrentstyle {% \CF_addtomacro\CF_arrowcurrentstyle,% }% \CF_doifnotempty{#9} {% \CF_addtomacro\CF_arrowcurrentstyle{#9,}% }% \CF_displaycompound{}{#3}% \def\CF_nextnodename{#4}% \CF_expsecond{\def\CF_currentnodename}{\CF_gobarg#1}% \let\CF_arrowstartname\CF_currentnodename \let\CF_arrowendname\CF_nextnodename \CF_arrowf{#7}{#8}{#2}{#5}% \def\CF_nextnodestyle{#6}% \fi \else \CF_doifnotempty\CF_arrowcurrentstyle {% \CF_addtomacro\CF_arrowcurrentstyle,% }% \CF_doifnotempty{#9} {% \CF_addtomacro\CF_arrowcurrentstyle{#9,}% }% \if @\expandafter\CF_firsttonil\detokenize{#2.}\_nil \CF_error{syntax "(--@)" is not allowed}% \else \CF_displaycompound{#1}{#3}% \edef\CF_arrowstartname{% \CF_ifempty{#1} \CF_currentnodename {#1}% \CF_doifnotempty{#2}{.#2}% }% \CF_arrowf{#7}{#8}{#2}{#5}% \def\CF_nextnodename{#4}% \def\CF_nextnodestyle{#6}% \fi \fi \CF_arrowgobspaces% mange les espaces puis exécute \CF_nextaction } \def\CF_arrowgobspaces{\futurelet\CF_toksa\CF_arrowgobspacesa} \def\CF_arrowgobspacesa{% \CF_ifx\CF_sptoken\CF_toksa \CF_arrowgobspacesb \CF_nextaction } \expandafter\def\expandafter\CF_arrowgobspacesb\space{\futurelet\CF_toksa\CF_arrowgobspacesa} \def\CF_arrowf#1#2#3#4{% #1=angle #2=longueur #3=ancre départ #4=ancre arrivée \def\CF_nextaction{\let\CF_compound\empty\CF_schemestartc}% \def\CF_arrowcurrentangle{#1}\CF_doifempty\CF_arrowcurrentangle{\let\CF_arrowcurrentangle\CF_arrowangle}% \def\CF_currentarrowlength{#2}\CF_doifempty\CF_currentarrowlength{\let\CF_currentarrowlength\CF_arrowlength}% \node[at=(\CF_currentnodename.\CF_ifempty{#3}\CF_arrowcurrentangle{#3}),shift=(\CF_arrowcurrentangle:\CF_currentarrowlength*\CF_compoundsep),cyan,fill](end@arrow@i@\number\CF_schemenest){};% \edef\CF_arrowendname{end@arrow@i@\number\CF_schemenest\CF_doifnotempty{#4}{.#4}}% \ifboolKV[chemfig]{scheme debug} {% \node[at=(\CF_currentnodename.\CF_ifempty{#3}\CF_arrowcurrentangle{#3}),shift=(\CF_arrowcurrentangle:\CF_arrowoffset),red,fill](start@arrow){};% \node[at=(\CF_currentnodename.\CF_ifempty{#3}\CF_arrowcurrentangle{#3}),shift=(\CF_arrowcurrentangle:\CF_currentarrowlength*\CF_compoundsep-\CF_arrowoffset),red,fill](end@arrow){};% } {% \node[at=(\CF_currentnodename.\CF_ifempty{#3}\CF_arrowcurrentangle{#3}),shift=(\CF_arrowcurrentangle:\CF_arrowoffset)](start@arrow){};% \node[at=(\CF_currentnodename.\CF_ifempty{#3}\CF_arrowcurrentangle{#3}),shift=(\CF_arrowcurrentangle:\CF_currentarrowlength*\CF_compoundsep-\CF_arrowoffset)](end@arrow){};% }% \def\CF_arrowstartnode{start@arrow}\def\CF_arrowendnode{end@arrow}% \csname\expandafter\CF_grabarrowname\CF_currentarrowtype[\_nil\CF_threeea\endcsname \expandafter\CF_grabarrowargs\CF_currentarrowtype[]\_nil[][][][][][][][]\_nil \def\CF_currentnodename{end@arrow@i@\number\CF_schemenest}% \edef\CF_nextnodeanchor{\CF_ifempty{#4}{180+\CF_arrowcurrentangle}{#4}}% } % trace un flèche initiée par (@nom--@nom) % #1=type de flèche #2=nom depart #3=ancre départ #4=nom arrivée #5=ancre arrivée #6=style flèche \def\CF_directarrow#1#2#3#4#5#6{% \edef\CF_arrowstartname{\CF_gobarg#2\ifx\empty#3\empty\else.#3\fi}% BUGFIX 1.6d \edef\CF_arrowendname{\CF_gobarg#4\ifx\empty#5\empty\else.#5\fi}% BUGFIX 1.6d \path[sloped,allow upside down](\CF_gobarg#2\ifx\empty#3\empty\else.#3\fi)--(\CF_gobarg#4\ifx\empty#5\empty\else.#5\fi)% coordinate[pos=0,xshift=\CF_arrowoffset](start@direct@arrow)% coordinate[pos=1,xshift=-\CF_arrowoffset](end@direct@arrow);% \def\CF_arrowstartnode{start@direct@arrow}% \def\CF_arrowendnode{end@direct@arrow}% \pgfmathanglebetweenpoints {\pgfpointanchor{\CF_gobarg#2}{\ifx\empty#3\empty center\else#3\fi}}% Ne pas utiliser \CF_ifempty ici !!! {\pgfpointanchor{\CF_gobarg#4}{\ifx\empty#5\empty center\else#5\fi}}% \let\CF_arrowcurrentangle\pgfmathresult \CF_doifnotempty{#6}{\CF_addtomacro\CF_arrowcurrentstyle{#6,}}% \csname\CF_grabarrowname#1[]\_nil\expandafter\endcsname\CF_grabarrowargs#1[]\_nil[][][][][][][][]\_nil } \def\CF_mergegrabchardir#1[#2][#3]#4\_nil{% \CF_expafter{\futurelet\CF_toksa\CF_gobtonil}{\CF_firsttonil#1>\_nil}\_nil \ifx>\CF_toksa \def\CF_mergeangle{0}\def\CF_mergeextreme{xmax}\def\CF_mergesign{+}% \else \ifx<\CF_toksa \def\CF_mergeangle{180}\def\CF_mergeextreme{xmin}\def\CF_mergesign{-}% \else \ifx^\CF_toksa \def\CF_mergeangle{90}\def\CF_mergeextreme{ymax}\def\CF_mergesign{+}% \else \ifx v\CF_toksa \def\CF_mergeangle{-90}\def\CF_mergeextreme{ymin}\def\CF_mergesign{-}% \fi\fi\fi\fi \def\CF_mergelabelup{#2}\def\CF_mergelabeldo{#3}% } \def\CF_merge#1({% \CF_mergegrabchardir#1[][]\_nil \CF_mergea(% } \def\CF_mergea#1--(#2){\CF_testopt{\CF_mergeb#1--(#2)}{}} \def\CF_mergeb#1--(#2)[#3]{% \CF_displaycompound{}{}% \CF_parsemergeopt#3,\CF_quark,\CF_quark,\CF_quark\_nil \def\CF_mergexmax{-16383.99999pt}\let\CF_mergeymax\CF_mergexmax \def\CF_mergexmin{16383.99999pt}\let\CF_mergeymin\CF_mergexmin \CF_mergeparsenodelist#1(\relax)% calcule les maxi des positions \pgfmathsetmacro\CF_mergeextremeresult{\csname CF_merge\CF_mergeextreme\endcsname\CF_mergesign\CF_mergefromcoeff*\CF_compoundsep}% \CF_mergec#1(\relax)% trace les lignes entre les noeuds précédents et la ligne de jonction \CF_expsecond{\def\CF_temp}{\expandafter[\CF_mergestyle,shorten <=0,shorten >=0,-]}% \if x\expandafter\CF_firsttonil\CF_mergeextreme\_nil \CF_addtomacro\CF_temp{(\CF_mergeextremeresult pt,\CF_mergeymax)--(\CF_mergeextremeresult pt,\CF_mergeymin)}% \else \CF_addtomacro\CF_temp{(\CF_mergexmin,\CF_mergeextremeresult pt)--(\CF_mergexmax,\CF_mergeextremeresult pt)}% \fi \expandafter\draw\CF_temp node[pos=\CF_mergesplitcoeff](merge@point){}% trace la ligne de jonction node[at=(merge@point),shift=(\CF_mergeangle:\CF_compoundsep*\CF_mergetocoeff-\CF_arrowoffset)](end@merge){}% node[at=(merge@point),shift=(\CF_mergeangle:\CF_compoundsep*\CF_mergetocoeff)](end@merge@i){};% \let\CF_arrowcurrentangle\CF_mergeangle \CF_expafter{\draw[}\CF_mergestyle,shorten <=0](merge@point)--(end@merge)% \expandafter\CF_arrowdisplaylabela\expandafter{\CF_mergelabelup}{.5}+\expandafter\CF_arrowdisplaylabela\expandafter{\CF_mergelabeldo}{.5}-;% \def\CF_currentnodename{end@merge@i}% \let\CF_temp\empty \CF_analysearrowarg{#2}% \expandafter\CF_merged\CF_temp\_nil } \def\CF_mergec(#1){% \if\relax\expandafter\noexpand\CF_firsttonil#1\_nil \else \CF_ifdot{#1}% {% \edef\merge_currentnodename{\CF_beforedot#1\_nil}% \edef\merge_currentanchor{\CF_afterdot#1\_nil}% }% {% \def\merge_currentnodename{#1}% \let\merge_currentanchor\CF_mergeangle }% \if x\expandafter\CF_firsttonil\CF_mergeextreme\_nil \pgfextracty\CF_dim{\pgfpointanchor\merge_currentnodename\merge_currentanchor}% \CF_expafter{\draw[}\CF_mergestyle,shorten >=0,-]([shift=(\CF_mergeangle:\CF_arrowoffset)]\merge_currentnodename.\merge_currentanchor)--(\CF_mergeextremeresult pt,\CF_dim);% \else \pgfextractx\CF_dim{\pgfpointanchor\merge_currentnodename\merge_currentanchor}% \CF_expafter{\draw[}\CF_mergestyle,shorten >=0,-]([shift=(\CF_mergeangle:\CF_arrowoffset)]\merge_currentnodename.\merge_currentanchor)--(\CF_dim,\CF_mergeextremeresult pt);% \fi \expandafter\CF_mergec \fi } \def\CF_merged#1.#2[#3]\_nil{% \def\CF_nextnodename{#1}% \edef\CF_nextnodeanchor{% \CF_ifempty{#2} {% 180+\CF_mergeangle } {% #2% }% }% \def\CF_nextnodestyle{#3}% \let\CF_compound\empty \CF_schemestartc } \def\CF_parsemergeopt#1,#2,#3,#4\_nil{% \CF_ifempty{#1} {% \def\CF_mergefromcoeff{0.5}% } {% \def\CF_mergefromcoeff{#1}% }% \def\CF_mergetocoeff{0.5}% \def\CF_mergesplitcoeff{0.5}% \CF_expsecond{\def\CF_mergestyle}{\CF_arrowhead}% \CF_iffirsttokmatch\CF_quark{#2\relax} {} {% \CF_ifempty{#2} {% \def\CF_mergetocoeff{0.5}% } {% \def\CF_mergetocoeff{#2}% }% \CF_iffirsttokmatch\CF_quark{#3\relax} {} {% \CF_ifempty{#3} {% \def\CF_mergesplitcoeff{0.5}% } {% \def\CF_mergesplitcoeff{#3}% }% \CF_iffirsttokmatch\CF_quark{#4\relax} {} {% \CF_parsemergeopta#4\_nil }% }% }% } \def\CF_parsemergeopta#1,\CF_quark#2\_nil{% \CF_ifempty{#1} {} {% \CF_addtomacro\CF_mergestyle{,#1}% }% } \def\CF_mergeparsenodelist(#1){% \if\relax\expandafter\noexpand\CF_firsttonil#1\_nil \else \CF_ifdot{#1}% {% \edef\merge_currentnodename{\CF_beforedot#1\_nil}% \edef\merge_currentanchor{\CF_afterdot#1\_nil}% }% {% \def\merge_currentnodename{#1}% \let\merge_currentanchor\CF_mergeangle }% \pgfextractx\CF_dim{\pgfpointanchor\merge_currentnodename\merge_currentanchor}% \ifdim\CF_dim>\CF_mergexmax \edef\CF_mergexmax{\the\CF_dim}% \fi \ifdim\CF_dim<\CF_mergexmin \edef\CF_mergexmin{\the\CF_dim}% \fi \pgfextracty\CF_dim{\pgfpointanchor\merge_currentnodename\merge_currentanchor}% \ifdim\CF_dim>\CF_mergeymax \edef\CF_mergeymax{\the\CF_dim}% \fi \ifdim\CF_dim<\CF_mergeymin \edef\CF_mergeymin{\the\CF_dim}% \fi \expandafter\CF_mergeparsenodelist \fi } \def\CF_grabarrowname#1[#2\_nil{\detokenize{CF_arrow(#1)}} \def\CF_grabarrowargs#1[#2\_nil{[#2} \def\CF_makeparametertext#1{% \toks0{}% \CF_cnt_group#1\relax \CF_makeparametertexta1% } \def\CF_makeparametertexta#1{% \unless\ifnum#1>\CF_cnt_group \toks0\expandafter{\the\toks0[###1]}% \expandafter\CF_makeparametertexta\expandafter{\number\numexpr#1+1\expandafter}% \fi } % #1 est le nombre d'arguments optionnels, #2 est le nom et #3 le code \def\definearrow#1#2#3{% \begingroup \CF_makeparametertext{#1}% \expandafter\endgroup \expandafter\def\csname\detokenize{CF_arrow(#2)}\expandafter\endcsname\the\toks0{#3\CF_gobtonil}% } \def\CF_ifdot#1{\CF_ifdota#1.\_nil} \def\CF_ifdota#1.#2\_nil{\ifx\empty#2\empty\expandafter\CF_execsecond\else\expandafter\CF_execfirst\fi} \def\CF_beforedot#1.#2\_nil{#1} \def\CF_afterdot#1.#2\_nil{#2} \def\CF_rotatenode*#1#2\_nil{% \CF_ifdot{#1} {% \CF_beforedot#1\_nil } {% #1% }% } \def\CF_anchornode*#1#2\_nil#3{% \CF_ifdot{#1} {% \CF_afterdot#1\_nil } {% \CF_arrowcurrentangle-#390-#1% }% } % #1 = label #2 = position #3 = + ou - (au dessus ou au dessous) #4 : nom du noeud de départ % #5 = label #6 = position #7 = + ou - (au dessus ou au dessous) #8 : nom du noeud de fin \def\CF_arrowdisplaylabel#1#2#3#4#5#6#7#8{% \CF_doifnotempty{#1#5} {\path(#4)--(#8)\CF_arrowdisplaylabela{#1}{#2}{#3}\CF_arrowdisplaylabela{#5}{#6}{#7};}% } \def\CF_arrowdisplaylabela#1#2#3{% \CF_doifnotempty{#1} {% \if*\expandafter\CF_firsttonil\detokenize{#1}\_nil \ifboolKV[chemfig]{scheme debug} {% node[pos=#2,sloped,yshift=#3\CF_arrowlabelsep,draw,fill,cyan](shifted@node){}% node[draw,rotate=\CF_rotatenode#1\_nil,anchor=\CF_anchornode#1\_nil#3,at=(shifted@node)]{\expandafter\CF_gobarg\CF_gobarg#1}% } {% node[pos=#2,sloped,yshift=#3\CF_arrowlabelsep](shifted@node){}% node[rotate=\CF_rotatenode#1\_nil,anchor=\CF_anchornode#1\_nil#3,at=(shifted@node)]{\expandafter\CF_gobarg\CF_gobarg#1}% }% \else \ifboolKV[chemfig]{scheme debug} {% node[pos=#2,sloped,yshift=#3\CF_arrowlabelsep,draw,fill,cyan](shifted@node){}% node[draw,pos=#2,anchor=-#390,sloped,yshift=#3\CF_arrowlabelsep]{#1}% } {% node[pos=#2,anchor=-#390,sloped,yshift=#3\CF_arrowlabelsep]{#1}% }% \fi }% } % pose des noeuds décalés de la dimension #1 à (\CF_arrowstartnode) et (\CF_arrowendnode) \def\CF_arrowshiftnodes#1{% \unless\ifdim\CF_ifempty{#1}\CF_zero{#1}=0pt \expanded{% \noexpand\path(\CF_arrowstartnode)--(\CF_arrowendnode)% node[pos=0,sloped,yshift=#1](\CF_arrowstartnode1){}node[pos=1,sloped,yshift=#1](\CF_arrowendnode1){};}% \edef\CF_arrowstartnode{\CF_arrowstartnode1}\edef\CF_arrowendnode{\CF_arrowendnode1}% \fi } \definearrow3{->}{% \CF_arrowshiftnodes{#3}% \CF_expafter{\draw[}\CF_arrowcurrentstyle](\CF_arrowstartnode)--(\CF_arrowendnode);% \CF_arrowdisplaylabel{#1}{0.5}+\CF_arrowstartnode{#2}{0.5}-\CF_arrowendnode } \definearrow3{<-}{% \CF_arrowshiftnodes{#3}% \CF_expafter{\draw[}\CF_arrowcurrentstyle](\CF_arrowendnode)--(\CF_arrowstartnode);% \CF_arrowdisplaylabel{#1}{0.5}+\CF_arrowstartnode{#2}{0.5}-\CF_arrowendnode } \definearrow5{-/>}{% \CF_arrowshiftnodes{#3}% \CF_expafter{\draw[}\CF_arrowcurrentstyle](\CF_arrowstartnode)--(\CF_arrowendnode)% coordinate[midway,shift=(\CF_arrowcurrentangle:-1pt)](midway@i)% coordinate[midway,shift=(\CF_arrowcurrentangle:1pt)](midway@ii)% coordinate[at=(midway@i),shift=(\CF_ifempty{#4}{225}{#4+180}+\CF_arrowcurrentangle:\CF_ifempty{#5}{5pt}{#5})](line@start)% coordinate[at=(midway@i),shift=(\CF_ifempty{#4}{45}{#4}+\CF_arrowcurrentangle:\CF_ifempty{#5}{5pt}{#5})](line@end)% coordinate[at=(midway@ii),shift=(\CF_ifempty{#4}{225}{#4+180}+\CF_arrowcurrentangle:\CF_ifempty{#5}{5pt}{#5})](line@start@i)% coordinate[at=(midway@ii),shift=(\CF_ifempty{#4}{45}{#4}+\CF_arrowcurrentangle:\CF_ifempty{#5}{5pt}{#5})](line@end@i); \draw(line@start)--(line@end);% \draw(line@start@i)--(line@end@i);% \CF_arrowdisplaylabel{#1}{0.5}+\CF_arrowstartnode{#2}{0.5}-\CF_arrowendnode } \definearrow3{<->}{% \CF_arrowshiftnodes{#3}% \CF_expafter{\draw[}\CF_arrowcurrentstyle,\CF_arrowtip-\CF_arrowtip](\CF_arrowstartnode)--(\CF_arrowendnode);% \CF_arrowdisplaylabel{#1}{0.5}+\CF_arrowstartnode{#2}{0.5}-\CF_arrowendnode } \definearrow3{<=>}{% \CF_arrowshiftnodes{#3}% \path[allow upside down](\CF_arrowstartnode)--(\CF_arrowendnode)% node[pos=0,sloped,yshift=\CF_arrowdoublesep](\CF_arrowstartnode @u0){}% node[pos=0,sloped,yshift=-\CF_arrowdoublesep](\CF_arrowstartnode @d0){}% node[pos=1,sloped,yshift=\CF_arrowdoublesep](\CF_arrowstartnode @u1){}% node[pos=1,sloped,yshift=-\CF_arrowdoublesep](\CF_arrowstartnode @d1){};% \begingroup \ifboolKV[chemfig]{arrow double harpoon} \pgfarrowharpoontrue {}% \CF_expafter{\draw[}\CF_arrowcurrentstyle](\CF_arrowstartnode @u0)--(\CF_arrowstartnode @u1);% \CF_expafter{\draw[}\CF_arrowcurrentstyle](\CF_arrowstartnode @d1)--(\CF_arrowstartnode @d0);% \endgroup \CF_arrowdisplaylabel{#1}{0.5}+\CF_arrowstartnode{#2}{0.5}-\CF_arrowendnode% } \definearrow3{<->>}{% \CF_arrowshiftnodes{#3}% \path[allow upside down](\CF_arrowstartnode)--(\CF_arrowendnode)% node[pos=0,sloped,yshift=1pt](\CF_arrowstartnode @u0){}% node[pos=\CF_arrowdoubleposstart,sloped,yshift=-1pt](\CF_arrowstartnode @d0){}% node[pos=1,sloped,yshift=1pt](\CF_arrowstartnode @u1){}% node[pos=\CF_arrowdoubleposend,sloped,yshift=-1pt](\CF_arrowstartnode @d1){};% \begingroup \ifboolKV[chemfig]{arrow double harpoon} \pgfarrowharpoontrue {}% \CF_expafter{\draw[}\CF_arrowcurrentstyle](\CF_arrowstartnode @u0)--(\CF_arrowstartnode @u1);% \CF_expafter{\draw[}\CF_arrowcurrentstyle](\CF_arrowstartnode @d1)--(\CF_arrowstartnode @d0);% \endgroup \CF_arrowdisplaylabel{#1}{0.5}+\CF_arrowstartnode{#2}{0.5}-\CF_arrowendnode% } \definearrow3{<<->}{% \path[allow upside down](\CF_arrowstartnode)--(\CF_arrowendnode)% node[pos=\CF_arrowdoubleposstart,sloped,yshift=1pt](\CF_arrowstartnode @u0){}% node[pos=0,sloped,yshift=-1pt](\CF_arrowstartnode @d0){}% node[pos=\CF_arrowdoubleposend,sloped,yshift=1pt](\CF_arrowstartnode @u1){}% node[pos=1,sloped,yshift=-1pt](\CF_arrowstartnode @d1){};% \begingroup \ifboolKV[chemfig]{arrow double harpoon} \pgfarrowharpoontrue {}% \CF_expafter{\draw[}\CF_arrowcurrentstyle](\CF_arrowstartnode @u0)--(\CF_arrowstartnode @u1);% \CF_expafter{\draw[}\CF_arrowcurrentstyle](\CF_arrowstartnode @d1)--(\CF_arrowstartnode @d0);% \endgroup \CF_arrowdisplaylabel{#1}{0.5}+\CF_arrowstartnode{#2}{0.5}-\CF_arrowendnode } \definearrow30{% \CF_arrowshiftnodes{#3}% \CF_arrowdisplaylabel{#1}{0.5}+\CF_arrowstartnode{#2}{0.5}-\CF_arrowendnode } \definearrow5{-U>}{% \CF_arrowshiftnodes{#3}% \CF_expafter{\draw[}\CF_arrowcurrentstyle](\CF_arrowstartnode)--(\CF_arrowendnode)node[midway](Uarrow@arctangent){};% \CF_ifempty{#4} {% \def\CF_Uarrowradius{0.333}% } {% \def\CF_Uarrowradius{#4}% }% \CF_ifempty{#5}% {% \def\CF_Uarrowabsangle{60}% } {% \pgfmathsetmacro\CF_Uarrowabsangle{abs(#5)}% ne prendre en compte que la valeur absolue de l'angle }% \expandafter\draw\expanded{[\CF_ifempty{#1}{draw=none}{\unexpanded\expandafter{\CF_arrowcurrentstyle}},-]}(Uarrow@arctangent)% arc[radius=\CF_compoundsep*\CF_currentarrowlength*\CF_Uarrowradius,start angle=\CF_arrowcurrentangle-90,delta angle=-\CF_Uarrowabsangle]node(Uarrow@start){}; \expandafter\draw\expanded{[\CF_ifempty{#2}{draw=none}{\unexpanded\expandafter{\CF_arrowcurrentstyle}}]}(Uarrow@arctangent)% arc[radius=\CF_compoundsep*\CF_currentarrowlength*\CF_Uarrowradius,start angle=\CF_arrowcurrentangle-90,delta angle=\CF_Uarrowabsangle]node(Uarrow@end){}; \pgfmathsetmacro\CF_temp{\CF_Uarrowradius*cos(\CF_arrowcurrentangle)<0?"-":"+"}% \ifdim\CF_Uarrowradius pt>0pt \CF_arrowdisplaylabel{#1}{0}\CF_temp{Uarrow@start}{#2}{1}\CF_temp{Uarrow@end}% \else \CF_arrowdisplaylabel{#2}{0}\CF_temp{Uarrow@start}{#1}{1}\CF_temp{Uarrow@end}% \fi } \def\CF_grabdelim#1#2#3\_CFnil{\def\CF_leftdelim{#1}\def\CF_rightdelim{#2}} \defKV[CFdelimiters]{% delimiters = \CF_grabdelim#1()\_CFnil, height = \def\CF_delimheight{#1}, depth = \CF_expsecond{\CF_defifempty\CF_delimdepth{#1}}{\CF_delimheight}, open xshift = \edef\CF_leftdelimxshift{\the\dimexpr#1}, close xshift = \edef\CF_rightdelimxshift{\CF_ifempty{#1}{-\CF_leftdelimxshift}{-\the\dimexpr#1}} } \setKVdefault[CFdelimiters]{% delimiters = (), height = 10pt, depth = , open xshift = 0pt, close xshift = , h align = true, auto rotate = false, rotate = 0, indice = n }% \def\polymerdelim{\CF_ifnextchar[{\CF_polymerdelima}{\CF_polymerdelima[]}} \def\CF_polymerdelima[#1]#2#3{% \restoreKV[CFdelimiters]% \CF_doifnotempty{#1} {% \setKV[CFdelimiters]{#1}% }% \edef\CF_delimhalfdim{\the\dimexpr(\CF_delimheight+\CF_delimdepth)/2}% \edef\CF_delimvshift {\the\dimexpr(\CF_delimheight-\CF_delimdepth)/2}% \chemmove{% \nulldelimiterspace0pt \pgfextractx\CF_dim{\pgfpointanchor{#2}{center}}\edef\CF_leftdelimx{\the\CF_dim}% \pgfextracty\CF_dim{\pgfpointanchor{#2}{center}}\edef\CF_leftdelimy{\the\CF_dim}% \pgfextractx\CF_dim{\pgfpointanchor{#3}{center}}\edef\CF_rightdelimx{\the\CF_dim}% \pgfextracty\CF_dim{\pgfpointanchor{#3}{center}}\edef\CF_rightdelimy{\the\CF_dim}% \def\CF_autorotate{0}% \ifboolKV[CFdelimiters]{h align} {% \let\CF_rightdelimy\CF_leftdelimy } {% \ifboolKV[CFdelimiters]{auto rotate} {% \pgfmathatantwo{\CF_rightdelimy-\CF_leftdelimy}{\CF_rightdelimx-\CF_leftdelimx}% \let\CF_autorotate\pgfmathresult } {% \CF_eexpsecond\CF_ifempty{\useKV[CFdelimiters]{rotate}} {} {% \edef\CF_autorotate{\useKV[CFdelimiters]{rotate}}% }% }% }% \node[at={(\CF_leftdelimx+\CF_leftdelimxshift,\CF_leftdelimy+\CF_delimvshift)},rotate=\CF_autorotate] {$\left\CF_leftdelim\vrule height\CF_delimhalfdim depth\CF_delimhalfdim width0pt\right.$};% \node[at={(\CF_rightdelimx+\CF_rightdelimxshift,\CF_rightdelimy+\CF_delimvshift)},rotate=\CF_autorotate] {$\left.\vrule height\CF_delimhalfdim depth\CF_delimhalfdim width0pt\right\CF_rightdelim \CF_eexpsecond\CF_doifnotempty{\useKV[CFdelimiters]{indice}} {\CF_underscore{\rlap{$\scriptstyle\useKV[CFdelimiters]{indice}$}}} $}; }% } \catcode`\@11 \pgfdeclarearrow{% name = CF,% defaults = {% length = 3pt 5 1,% width' = 0pt .8,% inset' = 0pt .5,% line width = 0pt 1 1,% round% },% setup code = {% % Cap the line width at 1/4th distance from inset to tip \pgf@x\pgfarrowlength \advance\pgf@x by-\pgfarrowinset \pgf@x.25\pgf@x \ifdim\pgf@x<\pgfarrowlinewidth\pgfarrowlinewidth\pgf@x\fi % Compute front miter length: \pgfmathdivide@{\pgf@sys@tonumber\pgfarrowlength}{\pgf@sys@tonumber\pgfarrowwidth}% \let\pgf@temp@quot\pgfmathresult% \pgf@x\pgfmathresult pt% \pgf@x\pgfmathresult\pgf@x% \pgf@x4\pgf@x% \advance\pgf@x by1pt% \pgfmathsqrt@{\pgf@sys@tonumber\pgf@x}% \pgf@xc\pgfmathresult\pgfarrowlinewidth% xc is front miter \pgf@xc.5\pgf@xc \pgf@xa\pgf@temp@quot\pgfarrowlinewidth% xa is extra harpoon miter % Compute back miter length: \pgf@ya.5\pgfarrowwidth% \csname pgfmathatan2@\endcsname{\pgfmath@tonumber\pgfarrowlength}{\pgfmath@tonumber\pgf@ya}% \pgf@yb\pgfmathresult pt% \csname pgfmathatan2@\endcsname{\pgfmath@tonumber\pgfarrowinset}{\pgfmath@tonumber\pgf@ya}% \pgf@ya\pgfmathresult pt% \advance\pgf@yb by-\pgf@ya% \pgf@yb.5\pgf@yb% half angle in yb \pgfmathtan@{\pgf@sys@tonumber\pgf@yb}% \pgfmathreciprocal@{\pgfmathresult}% \pgf@yc\pgfmathresult\pgfarrowlinewidth% \pgf@yc.5\pgf@yc% \advance\pgf@ya by\pgf@yb% \pgfmathsincos@{\pgf@sys@tonumber\pgf@ya}% \pgf@ya\pgfmathresulty\pgf@yc% ya is the back miter \pgf@yb\pgfmathresultx\pgf@yc% yb is the top miter \ifdim\pgfarrowinset=0pt \pgf@ya.5\pgfarrowlinewidth% easy: back miter is half linewidth \fi % Compute inset miter length: \pgfmathdivide@{\pgf@sys@tonumber\pgfarrowinset}{\pgf@sys@tonumber\pgfarrowwidth}% \let\pgf@temp@quot\pgfmathresult% \pgf@x\pgfmathresult pt% \pgf@x\pgfmathresult\pgf@x% \pgf@x4\pgf@x%\pgf@ya \advance\pgf@x by1pt% \pgfmathsqrt@{\pgf@sys@tonumber\pgf@x}% \pgf@yc\pgfmathresult\pgfarrowlinewidth% yc is inset miter \pgf@yc.5\pgf@yc% % Inner length (pgfutil@tempdima) is now arrowlength - front miter - back miter \pgfutil@tempdima\pgfarrowlength% \advance\pgfutil@tempdima by-\pgf@xc% \advance\pgfutil@tempdima by-\pgf@ya% \pgfutil@tempdimb.5\pgfarrowwidth% \advance\pgfutil@tempdimb by-\pgf@yb% % harpoon miter correction \ifpgfarrowroundjoin \pgfarrowssetbackend{\pgf@ya\advance\pgf@x by-.5\pgfarrowlinewidth}% \else \pgfarrowssetbackend{0pt} \fi \ifpgfarrowharpoon \pgfarrowssetlineend{\pgfarrowinset\advance\pgf@x by\pgf@yc\advance\pgf@x by.5\pgfarrowlinewidth}% \else \pgfarrowssetlineend{\pgfarrowinset\advance\pgf@x by\pgf@yc\advance\pgf@x by-.25\pgfarrowlinewidth}% \ifpgfarrowreversed \ifdim\pgfinnerlinewidth>0pt \pgfarrowssetlineend{\pgfarrowinset}% \else \pgfarrowssetlineend{\pgfutil@tempdima\advance\pgf@x by\pgf@ya\advance\pgf@x by-.25\pgfarrowlinewidth}% \fi \fi \fi \ifpgfarrowroundjoin \pgfarrowssettipend{\pgfutil@tempdima\advance\pgf@x by\pgf@ya\advance\pgf@x by.5\pgfarrowlinewidth}% \else \pgfarrowssettipend{\pgfarrowlength\ifpgfarrowharpoon\advance\pgf@x by\pgf@xa\fi}% \fi % The hull: \pgfarrowshullpoint{\pgfarrowlength\ifpgfarrowroundjoin\else\ifpgfarrowharpoon\advance\pgf@x by\pgf@xa\fi\fi}{\ifpgfarrowharpoon-.5\pgfarrowlinewidth\else0pt\fi}% \pgfarrowsupperhullpoint{0pt}{.5\pgfarrowwidth}% \pgfarrowshullpoint{\pgfarrowinset}{\ifpgfarrowharpoon-.5\pgfarrowlinewidth\else 0pt\fi}% % Adjust inset \pgfarrowssetvisualbackend{\pgfarrowinset}% \advance\pgfarrowinset by\pgf@yc% % The following are needed in the code: \pgfarrowssavethe\pgfutil@tempdima \pgfarrowssavethe\pgfutil@tempdimb \pgfarrowssavethe\pgfarrowlinewidth \pgfarrowssavethe\pgf@ya \pgfarrowssavethe\pgfarrowinset },% drawing code = {% \pgfsetdash{}{0pt}% \ifpgfarrowroundjoin\pgfsetroundjoin\else\pgfsetmiterjoin\fi \ifdim\pgfarrowlinewidth=\pgflinewidth\else\pgfsetlinewidth{\pgfarrowlinewidth}\fi \pgfpathmoveto{\pgfqpoint{\pgfutil@tempdima\advance\pgf@x by\pgf@ya}{0pt}}% \pgfpathlineto{\pgfqpoint{\pgf@ya}{\pgfutil@tempdimb}}% \pgfpathlineto{\pgfqpoint{\pgfarrowinset}{0pt}}% \ifpgfarrowharpoon \else \pgfpathlineto{\pgfqpoint{\pgf@ya}{-\pgfutil@tempdimb}}% \fi \pgfpathclose \ifpgfarrowopen\pgfusepathqstroke\else\ifdim\pgfarrowlinewidth>0pt \pgfusepathqfillstroke\else\pgfusepathqfill\fi\fi },% parameters = {% \the\pgfarrowlinewidth,% \the\pgfarrowlength,% \the\pgfarrowwidth,% \the\pgfarrowinset,% \ifpgfarrowharpoon h\fi% \ifpgfarrowopen o\fi% \ifpgfarrowroundjoin j\fi% }% } \CFrestorecatcode \endinput