From d39570760243435ff2cd4ac49aed5fb6fd43646a Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Sun, 21 Nov 2010 23:54:10 +0000 Subject: chemfig 0.3 (22nov10) git-svn-id: svn://tug.org/texlive/trunk@20523 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/tex/latex/chemfig/chemfig.sty | 701 +++++++++++++++++------- 1 file changed, 506 insertions(+), 195 deletions(-) (limited to 'Master/texmf-dist/tex/latex') diff --git a/Master/texmf-dist/tex/latex/chemfig/chemfig.sty b/Master/texmf-dist/tex/latex/chemfig/chemfig.sty index 4931fe7f2cc..97aedb5067a 100644 --- a/Master/texmf-dist/tex/latex/chemfig/chemfig.sty +++ b/Master/texmf-dist/tex/latex/chemfig/chemfig.sty @@ -1,9 +1,9 @@ % __________________________________________________________________ % | | % | | -% | chemfig v0.2 | +% | chemfig v0.3 | % | | -% | August 31, 2010 | +% | November 21, 2010 | % | | % |__________________________________________________________________| % @@ -28,7 +28,7 @@ % of this license or (at your option) any later version. % The latest version of this license is in % -% http://www.latex-project.org/lppl.txt +% % http://www.latex-project.org/lppl.txt % % and version 1.3 or later is part of all distributions of LaTeX % version 2005/12/01 or later. @@ -37,10 +37,10 @@ % % The Current Maintainer of this work is Christian Tellechea % -------------------------------------------------------------------- -\newcommand*\CF@ver {0.2} -\newcommand*\CF@date {2010/08/31} -\newcommand*\CF@fr@date {31 ao\^ut 2010} -\newcommand*\CF@en@date {August 31, 2010} +\newcommand*\CF@ver {0.3} +\newcommand*\CF@date {2010/11/21} +\newcommand*\CF@fr@date {21 novembre 2010} +\newcommand*\CF@en@date {November 21, 2010} \newcommand*\CF@package@name{chemfig} \ProvidesPackage\CF@package@name[\CF@date\space v\CF@ver\space Draw molecule with an easy syntax] @@ -54,6 +54,7 @@ \newif\ifCF@incycle \newif\ifCF@cyclearc +\newif\if@CF@definesubmol \newdimen\CF@dimax \newdimen\CF@dimbx @@ -63,12 +64,20 @@ \newbox\CF@lewis@box \newbox\CF@box@boxa \newbox\CF@box@boxb +\newbox\CF@stuff@box \newcommand*\printatom[1]{\ensuremath{\mathrm{#1}}} -\def\CF@empty@node{{}} +\newcommand\CF@node@content{\expandafter\printatom\expandafter{\csname atom@\number\CF@cnt@atomnumber\endcsname\CF@node@strut}} -\newcommand*\CF@global@let{\global\let} +\newcommand\chemskipalign{% + \ifx\CF@bond@outcontentsaved\@empty% sauf si un \chemskipalign a été fait à l'atome précédent + \global\let\CF@bond@outcontentsaved\CF@bond@outcontent% sauvegarder l'atome d'où vient la liaison + \fi + \let\CF@node@strut\@empty +} + +\def\CF@empty@node{{}} \expandafter\let\expandafter\CF@char@triplebond\string~ @@ -80,29 +89,65 @@ \ifx\@empty#3\@empty\def\CF@cram@dashsep{2pt}\else\def\CF@cram@dashsep{#3}\fi} \setcrambond{}{}{} -\newcommand*\setatomsep[1]{\def\CF@atom@sep{#1}}% espacement des atomes liés +\newcommand*\setatomsep{\def\CF@atom@sep}% espacement des atomes liés \setatomsep{} -\newcommand*\setbondoffset[1]{\def\CF@bond@offset{#1}}% offset des liaisons +\newcommand*\setbondoffset{\def\CF@bond@offset}% offset des liaisons \setbondoffset{2pt} -\newcommand*\setdoublesep[1]{\def\CF@double@sep{#1}} +\newcommand*\setdoublesep{\def\CF@double@sep} \setdoublesep{2pt} \newcommand*\CF@read@manual{Please, read the manual.} -\newcommand*\definesubmol[2]{% #1 est le nom, #2 est le code - \ifcsname CF@@#1\endcsname - \PackageWarning\CF@package@name{The submol "#1" already defined\MessageBreak I redefined it instead.}% - \fi - \expandafter\def\csname CF@@#1\endcsname{#2}% -} +\newcommand*\definesubmol{\@CF@definesubmoltrue\CF@def@submol} +\newcommand*\redefinesubmol{\@CF@definesubmolfalse\CF@def@submol} -\newcommand*\redefinesubmol[2]{% - \unless\ifcsname CF@@#1\endcsname - \PackageWarning\CF@package@name{The submol "#1" cannot be redefined\MessageBreak I defined it instead.}% +\newcommand*\CF@def@submol[1]{\@ifnextchar[{\CF@def@submol@i{#1}}{\CF@def@submol@i{#1}[]}} + +\def\CF@def@submol@i#1[#2]#3% +{% #1 nom, #2 = code si liaison arrive de droite , #3 = code si liaison arrive de gauche + \ifcat\relax\expandafter\noexpand\@car#1\@nil% si #1 est une séquence de contrôle + \expandafter\ifdefined\@car#1\@nil + \if@CF@definesubmol\PackageWarning\CF@package@name{The macro \expandafter\string\@car#1\@nil\space is already defined, the previous definition is lost.}\fi + \fi + \ifx\@empty#2\@empty + \expandafter\def\@car#1\@nil{\@empty#3}% + \else + \expandafter\def\@car#1\@nil{% + \romannumeral + \ifdim\CF@current@angle pt>90pt + \ifdim\CF@current@angle pt<270pt + \expandafter\expandafter\expandafter\@firstoftwo + \else + \expandafter\expandafter\expandafter\@secondoftwo + \fi + \else + \expandafter\@secondoftwo + \fi + {\z@#2}{\z@#3}}% + \fi + \else + \ifcsname CF@@#1\endcsname + \if@CF@definesubmol\PackageWarning\CF@package@name{The submol "#1" is already defined, the previous definition is lost.}\fi + \fi + \ifx\@empty#2\@empty + \expandafter\def\csname CF@@#1\endcsname{\@empty#3}%\@empty car sera 1-développé lorsque rencontrée + \else + \expandafter\def\csname CF@@#1\endcsname{% + \romannumeral% donnera le développement souhaité en 1 coup + \ifdim\CF@current@angle pt>90pt + \ifdim\CF@current@angle pt<270pt + \expandafter\expandafter\expandafter\@firstoftwo + \else + \expandafter\expandafter\expandafter\@secondoftwo + \fi + \else + \expandafter\@secondoftwo + \fi + {\z@#2}{\z@#3}}% + \fi \fi - \expandafter\def\csname CF@@#1\endcsname{#2}% } \newcommand*\CF@if@integer[1]{% @@ -120,6 +165,20 @@ \def\CF@gobble@tonil#1\@nil{} +\newcommand*\CF@expafterarg@ntimes[3][1]{% + \CF@expafterarg@ntimes@i{#1}{#3}% + \expandafter\CF@swap@arg\expandafter{\CF@tmp@str}{#2}% +} + +\newcommand*\CF@expafterarg@ntimes@i[2]{% + \ifnum#1=\z@ + \def\CF@tmp@str{#2}% + \else + \CF@swap@fi + \expandafter\CF@expafterarg@ntimes@i\expandafter{\number\numexpr#1-1\expandafter}\expandafter{#2}% + \fi +} + \newcommand*\CF@swap@arg[2]{#2{#1}} \newcommand*\CF@expand@second[2]{\expandafter\CF@swap@arg\expandafter{#2}{#1}} @@ -129,7 +188,7 @@ \newcommand*\CF@expand@afterfirst[2]{\expandafter\CF@swap@two\expandafter{#2}{#1}} \newcommand*\CF@edef@second[2]{% - \begingroup\edef\CF@tmp@str{#2}\expandafter\endgroup + \edef\CF@tmp@str{#2}% \expandafter\CF@swap@two\expandafter{\CF@tmp@str}{#1}% } @@ -138,14 +197,14 @@ \newcommand*\CF@expadd@tocs[2]{\expandafter\CF@add@tocs\expandafter#1\expandafter{#2}} \newcommand*\CF@edefadd@tocs[2]{% - \begingroup\edef\CF@tmp@str{#2}\expandafter\endgroup + \edef\CF@tmp@str{#2}% \expandafter\CF@add@tocs\expandafter#1\expandafter{\CF@tmp@str}% } \newcommand*\CF@if@firsttokmatch[2]{% est ce que #1 et #2 commencent par les mêmes tokens ? \futurelet\CF@toks@a\CF@gobble@tonil#1\relax\@nil \futurelet\CF@toks@b\CF@gobble@tonil#2\relax\@nil - \csname @\ifx\CF@toks@a\CF@toks@b first\else second\fi oftwo\endcsname + \ifx\CF@toks@a\CF@toks@b\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi } \newcommand*\CF@if@firsttokin[1]{% teste si le token qui commence #1 appartient aux tokens mis dans #2 @@ -174,16 +233,11 @@ \def\CF@after@space#1 #2\@nil{#2} -\newcommand\CF@if@spacefirst[1]{% - \futurelet\CF@toks@a\CF@gobble@tonil#1\relax\@nil - \csname @\ifx\CF@toks@a\@sptoken first\else second\fi oftwo\endcsname -} - \newcommand*\CF@seek@node[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}% \futurelet\CF@toks@a\CF@gobble@tonil#1\relax\@nil - \csname @\ifx\CF@toks@a\@sptoken first\else second\fi oftwo\endcsname + \ifx\CF@toks@a\@sptoken\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi {\expandafter\CF@seek@node@i\expandafter{\CF@after@space#1\@nil}#2#3}% ignore l'espace qui commence un groupe d'atome {\CF@seek@node@i{#1}#2#3}% } @@ -193,18 +247,18 @@ \let#3\@empty \else \futurelet\CF@toks@a\CF@gobble@tonil#1\relax\@nil - \csname @\ifx\CF@toks@a\@sptoken first\else second\fi oftwo\endcsname + \ifx\CF@toks@a\@sptoken\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi {\CF@add@tocs#2{ }% - \CF@swap@fi\CF@expand@second\CF@seek@node@i{\CF@after@space#1\@nil}#2#3% + \CF@swap@fi\expandafter\CF@seek@node@i\expandafter{\CF@after@space#1\@nil}#2#3% }% - {\csname @\ifx\CF@toks@a\bgroup first\else second\fi oftwo\endcsname + {\ifx\CF@toks@a\bgroup\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi {\CF@expadd@tocs#2{\expandafter{\@car#1\@nil}}% - \CF@swap@fi\CF@expand@second\CF@seek@node@i{\@gobble#1}#2#3% + \CF@swap@fi\expandafter\CF@seek@node@i\expandafter{\@gobble#1}#2#3% }% {\CF@if@firsttokin@i{-=(*<>!\CF@char@triplebond}% {\def#3{#1}}% {\CF@expadd@tocs#2{\@car#1\@nil}% - \CF@swap@fi\CF@expand@second\CF@seek@node@i{\@gobble#1}#2#3% + \CF@swap@fi\expandafter\CF@seek@node@i\expandafter{\@gobble#1}#2#3% }% }% }% @@ -234,15 +288,29 @@ \ifnum#2>\thr@@% si c'est une liaison de Cram \expandafter\futurelet\expandafter\CF@toks@a\expandafter\CF@gobble@tonil\@gobble#1\@nil% chope le caractère suivant \ifx:\CF@toks@a - \edef#2{\number\numexpr#2+2}% si c 'est un :, signe du pointillé, ajoute 2 + \edef#2{\number\numexpr#2+2}% si c 'est un ":", signe du pointillé, ajoute 2 \else \ifx|\CF@toks@a - \edef#2{\number\numexpr#2+4}% si c 'est un "|", signe du triangle évide, ajouter 4 + \edef#2{\number\numexpr#2+4}% si c 'est un "|", signe du triangle évidé, ajouter 4 \fi \fi \fi } +\def\CF@analyse@bondoffset#1,#2\@nil{% + \def\CF@start@offset{#1}\def\CF@end@offset{#2}% +} + +\expandafter\def\expandafter\CF@grab@bondoffset\string#(#1)#2\@nil{% + \ifx\@empty#1\@empty + \else + \CF@if@instr{#1},% + {\CF@analyse@bondoffset#1\@nil}% + {\def\CF@start@offset{#1}}% + \fi + \def\CF@remain@afterbond{#2}% +} + \newcommand*\CF@analyse@bond[2]{% \CF@bond@findnum{#1}#2% \expandafter\def\expandafter\CF@remain@afterbond\expandafter{\@gobble#1}%mange le premier signe de la liaison @@ -263,16 +331,28 @@ \expandafter\def\expandafter\CF@remain@afterbond\expandafter{\@gobbletwo#1}% mange un caractère de plus \fi \fi + \expandafter\expandafter\expandafter\CF@if@firsttokmatch\expandafter\expandafter\expandafter{\expandafter\CF@remain@afterbond\expandafter}\string##% + {\expandafter\CF@grab@bondoffset\CF@remain@afterbond\@nil}% + \relax + \expandafter\expandafter\expandafter\CF@if@firsttokmatch\expandafter\expandafter\expandafter{\expandafter\CF@remain@afterbond\expandafter}\string @% + {\expandafter\CF@grab@movearg\CF@remain@afterbond\@nil}% + \relax \expandafter\CF@if@firsttokmatch\expandafter{\CF@remain@afterbond}[% - {\expandafter\CF@seekbond@optarg\CF@remain@afterbond\@nil\CF@remain@afterbond}% - {\expandafter\CF@seekbond@optarg\expandafter[\expandafter]\CF@remain@afterbond\@nil\CF@remain@afterbond}% + {\expandafter\CF@analyse@optarg\CF@remain@afterbond\@nil\CF@remain@afterbond}% + {\let\CF@current@stringangle\CF@default@stringangle + \let\CF@current@length\CF@default@length + \let\CF@current@fromatom\CF@default@fromatom + \let\CF@current@toatom\CF@default@toatom + \let\CF@current@tikz\CF@default@tikz + \let\CF@movebond@name\@empty + }% \ifCF@incycle \pgfmathparse{360/\CF@cycle@num+\CF@initcycle@angle}% \edef\CF@current@stringangle{::+\pgfmathresult}% \def\CF@initcycle@angle{0}% \let\CF@current@length\CF@default@length% et on ignore la longueur de liaison spécifiée \fi - \CF@expand@second\CF@set@bondangle{\CF@current@stringangle}\CF@current@angle + \expandafter\CF@set@bondangle\expandafter{\CF@current@stringangle}\CF@current@angle } \newcommand*\CF@set@bondangle[2]{% le code de la direction est contenu dans #1, en sortie, #2 contient l'angle @@ -284,51 +364,80 @@ \pgfmathparse{\CF@previous@angle+\expandafter\@gobble\@gobble#1}% \let#2\pgfmathresult \else - \CF@expand@second{\def#2}{\@gobble#1} + \expandafter\def\expandafter#2\expandafter{\@gobble#1} \fi% puis normalise l'angle entre 0 et 360 - \pgfmathparse{#2-360*floor(#2/360)}% - \ifdim\pgfmathresult pt<\z@\pgfmathparse{\pgfmathresult+360}\fi - \let#2\pgfmathresult + \ifdim\ifdim#2pt<\z@-\fi#2pt>360pt % si |#2|>360 + \pgfmathparse{#2-360*floor(#2/360)}% + \ifdim\pgfmathresult pt<\z@\pgfmathparse{\pgfmathresult+360}\fi + \let#2\pgfmathresult + \else + \ifdim\pgfmathresult pt<\z@ + \pgfmathparse{#2+360}% + \let#2\pgfmathresult + \fi + \fi \else - \pgfmathparse{#1-floor(#1/8)*8}% - \ifdim\pgfmathresult pt<\z@\pgfmathparse{\pgfmathresult+8}\fi - \edef#2{\ifcase\expandafter\CF@int@part\pgfmathresult\@nil0\or45\or90\or135\or180\or225\or270\or315\else-1\fi}% angle =-1 --> erreur + \ifnum#1>7 + \pgfmathparse{#1-floor(#1/8)*8}% + \ifdim\pgfmathresult pt<\z@\pgfmathparse{\pgfmathresult+8}\fi + \edef#2{\ifcase\expandafter\CF@int@part\pgfmathresult\@nil0\or45\or90\or135\or180\or225\or270\or315\else-1\fi}% angle =-1 --> erreur + \else + \edef#2{\ifcase#1 0\or45\or90\or135\or180\or225\or270\or315\else-1\fi}% + \fi \fi \fi } \def\CF@int@part#1.#2\@nil{#1 } -\newcommand*\CF@test@assign[3]{\ifx\@empty#2\@empty\let#1#3\else\def#1{#2}\fi} - -% #1 est une liste de 4 éléments a,b,c,d chacun assignés aux sc #2,#3,#4,#5 -\newcommand*\CF@parse@list[6]{% - \def\CF@parse@list@i##1,##2,##3,##4,##5\@nil{% - \CF@test@assign#2{##1}\CF@default@stringangle - \CF@test@assign#3{##2}\CF@default@length - \CF@test@assign#4{##3}\CF@default@fromatom - \CF@test@assign#5{##4}\CF@default@toatom - \CF@test@assign#6{##5}\CF@default@tikz}% - \CF@parse@list@i#1,,,,\@nil +\def\CF@analyse@movearg#1,#2\@nil#3{% + \def#3{#1}\def\CF@movebond@coeff{#2}% } -\def\CF@seekbond@optarg[#1]{% - \CF@parse@list{#1}\CF@current@stringangle\CF@current@length\CF@current@fromatom\CF@current@toatom\CF@current@tikz - \CF@seekbond@optarg@i\relax +% Argument limités légitimes ici car #2 (qui est ce qui suit "@{}" dans l'argument optionnel) ne DOIT +% pas commencer par une accolade. +\expandafter\def\expandafter\CF@grab@movearg\string @#1#2\@nil{% + \CF@if@instr{#1},% + {\CF@analyse@movearg#1\@nil\CF@movebond@name}% + {\def\CF@movebond@name{#1}\def\CF@movebond@coeff{0.5}}% + \def\CF@remain@optarg{#2}% } -\def\CF@seekbond@optarg@i#1\@nil#2{% - \CF@expand@second{\def#2}{\@gobble#1}% le \@gobble bouffe le \relax et laisse intact le reste +\newcommand*\CF@testempty@andassign[3]{\ifx\@empty#2\@empty\let#1#3\else\def#1{#2}\fi} + +\def\CF@sanitize@lastitem#1,\@empty#2\@nil{#1} + +\def\CF@parse@optlist#1,#2,#3,#4,#5\@nil{% + \CF@testempty@andassign\CF@current@stringangle{#1}\CF@default@stringangle + \CF@testempty@andassign\CF@current@length{#2}\CF@default@length + \CF@testempty@andassign\CF@current@fromatom{#3}\CF@default@fromatom + \CF@testempty@andassign\CF@current@toatom{#4}\CF@default@toatom + \expandafter\CF@testempty@andassign\expandafter\CF@current@tikz\expandafter{\CF@sanitize@lastitem#5,\@empty\@nil}\CF@default@tikz +}% + +\def\CF@analyse@optarg[#1]#2\@nil#3{% + \ifx\@empty#1\@empty + \else + \CF@expand@afterfirst{\CF@if@firsttokmatch{#1}}{\string @}% + {\CF@grab@movearg#1\@nil}% + {\let\CF@movebond@name\@empty + \def\CF@remain@optarg{#1}}% + \expandafter\CF@parse@optlist\CF@remain@optarg,\@empty,\@empty,\@empty,\@empty\@nil + \def#3{#2}% + \fi } \newcommand*\CF@seek@submol{% - \CF@expand@second\CF@if@firsttokmatch\CF@remain@molecule!% - {\expandafter\expandafter\expandafter\def - \expandafter\expandafter\expandafter\CF@remain@molecule - \expandafter\expandafter\expandafter - {\csname CF@@\expandafter\expandafter\expandafter\@car\expandafter\@gobble\CF@remain@molecule\@nil - \expandafter\expandafter\expandafter\endcsname\csname @gobble\expandafter\expandafter\expandafter\endcsname - \csname @gobble\expandafter\endcsname\CF@remain@molecule}% + \expandafter\CF@if@firsttokmatch\expandafter{\CF@remain@molecule}!% + {\expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter + \CF@remain@molecule\expandafter\expandafter\expandafter{\expandafter\@gobble\CF@remain@molecule}% enlève le ``!'' + \ifcat\relax\expandafter\expandafter\expandafter\noexpand\expandafter\@car\CF@remain@molecule\@nil + \CF@expafterarg@ntimes[5]{\def\CF@insert@submol}{\expandafter\@car\CF@remain@molecule\@nil}% + \else + \CF@expafterarg@ntimes[3]{\def\CF@insert@submol}{\csname CF@@\expandafter\@car\CF@remain@molecule\@nil\endcsname}% + \fi + \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\CF@remain@molecule\expandafter\expandafter\expandafter + {\csname CF@insert@submol\expandafter\expandafter\expandafter\endcsname\csname @gobble\expandafter\endcsname\CF@remain@molecule}% \CF@seek@submol }% \relax @@ -343,28 +452,34 @@ \else \expandafter\@makeother\@car#1\@nil \CF@swap@fi - \CF@expand@second\CF@make@other{\@gobble#1}% + \expandafter\CF@make@other\expandafter{\@gobble#1}% \fi } -\newcommand*\chemfig{% - \begin{tikzpicture}[every node/.style={anchor=base,inner sep=0pt,outer sep=0pt,minimum size=0pt},baseline] +\newcommand*\chemfig[1][]{\def\CF@tmp@str{#1}\chemfig@optarg} + +\newcommand*\chemfig@optarg[1][]{% + \edef\CF@tmp@str{[remember picture,every node/.style={anchor=base,inner sep=0pt,outer sep=0pt,minimum size=0pt\ifx\@empty#1\@empty\else,#1\fi},baseline\unless\ifx\CF@tmp@str\@empty,\CF@tmp@str\fi]}% + \expandafter\tikzpicture\CF@tmp@str \begingroup - \CF@global@let\CF@hook@list\@empty + \let\CF@hook@list\@empty \ifx\CF@atom@sep\@empty\def\CF@atom@sep{3em}\fi \ifx\CF@cram@basewidth\@empty\def\CF@cram@basewidth{1.5ex}\fi \CF@incyclefalse - \global\CF@cnt@groupnumber\z@ + \CF@cnt@groupnumber\z@ \let\CF@last@action\z@% 0=début du dessin 1=tracé d'un noeud 2=tracé d'une liaison - \gdef\CF@cycle@anglecorrection{180/\CF@cycle@num}% + \let\CF@start@offset\@empty + \let\CF@end@offset\@empty + \let\CF@bond@outcontentsaved\@empty + \def\CF@cycle@anglecorrection{180/\CF@cycle@num}% \everyeof{\@nil}\endlinechar\m@ne - \CF@make@other{[]:(),-=~!?<>;*|}% + \CF@make@other{[]:(),-=~!?<>;*|##@}% \CF@chemfig@i } \newcommand*\CF@chemfig@i[1]{% \CF@chemfig@ii{#1}% - \end{tikzpicture}% + \endtikzpicture } \newcommand*\CF@chemfig@ii[1]{% #1 est le code de la molécule @@ -383,14 +498,14 @@ \else \def\CF@default@angle{0}% \def\CF@default@stringangle{:0}% angle pris par défaut si le champ est vide - \fi% angle par défaut + \fi \let\CF@current@angle\CF@default@angle \ifCF@incycle\else\def\CF@default@length{1}\fi% longueur de la liaison par défaut sauf pour un cycle où on prend celle en cours \let\CF@default@fromatom\@empty% numero de l'atome d'où partent les liaisons par défaut \let\CF@default@toatom\@empty% numéro de l'atome où arrivent les laisons par défaut \let\CF@default@tikz\@empty \if[\expandafter\noexpand\@car#1\@nil - \CF@seekbond@optarg#1\@nil\CF@remain@molecule + \CF@analyse@optarg#1\@nil\CF@remain@molecule \expandafter\CF@set@bondangle\expandafter{\CF@current@stringangle}\CF@current@angle \let\CF@default@angle\CF@current@angle \let\CF@previous@angle\CF@current@angle @@ -415,7 +530,7 @@ \ifnum\CF@last@action=\z@ \let\CF@previous@angle\CF@default@angle \node(CF@node){}; - \CF@expand@second\CF@if@firsttokin{\CF@remain@molecule}{-=(*\CF@char@triplebond?<>}% + \expandafter\CF@if@firsttokin\expandafter{\CF@remain@molecule}{-=(*\CF@char@triplebond?<>}% {\CF@insert@emptygroup\CF@remain@molecule}% \relax \fi @@ -423,12 +538,12 @@ } \newcommand*\CF@chemfig@iii{% - \let\CF@next@scan\CF@chemfig@iii% à prioi, on reboucle + \let\CF@next@action\CF@chemfig@iii% à prioi, on reboucle \ifx\CF@remain@molecule\@empty - \let\CF@next@scan\endgroup + \let\CF@next@action\endgroup \else \CF@seek@submol - \CF@expand@second\CF@seek@node{\CF@remain@molecule}\CF@current@atomgroup\CF@remain@molecule + \expandafter\CF@seek@node\expandafter{\CF@remain@molecule}\CF@current@atomgroup\CF@remain@molecule \ifx\@empty\CF@current@atomgroup% pas de noeud pour commencer ? \def\CF@bond@outnode{n\CF@last@groupnumber-% \ifx\CF@current@fromatom\@empty @@ -444,16 +559,19 @@ \edef\CF@bond@outnode{\CF@bond@outnode}% \else \ifCF@incycle\advance\CF@cnt@cycle\@ne\fi - \CF@expand@second\CF@analyse@bond{\CF@remain@molecule}\CF@bond@type + \expandafter\CF@analyse@bond\expandafter{\CF@remain@molecule}\CF@bond@type \edef\CF@bond@outnode{\CF@bond@outnode}% \let\CF@remain@molecule\CF@remain@afterbond - \csname @% il y a plus de liaisons que de sommet dans le cycle ? - \ifCF@incycle - \ifnum\CF@cnt@cycle=\CF@cycle@num first\else second\fi - \else second\fi - oftwo% - \endcsname - {\let\CF@next@scan\endgroup + \ifCF@incycle + \ifnum\CF@cnt@cycle=\CF@cycle@num\relax + \expandafter\expandafter\expandafter\@firstoftwo + \else + \expandafter\expandafter\expandafter\@secondoftwo + \fi + \else + \expandafter\@secondoftwo + \fi + {\let\CF@next@action\endgroup \CF@draw@bond\CF@bond@type{\CF@bond@outnode}{\CF@hook@cycle}\CF@previous@atomgroup\CF@hook@atomgroup }% {\node[at=(\CF@bond@outnode),shift=(\CF@current@angle:\CF@current@length*\CF@atom@sep)](CF@node){}; @@ -466,30 +584,30 @@ \fi }% {\edef\CF@bond@outnode{\CF@bond@outnode}% évalue le l'atome de départ de liaison - \csname @\ifx(\CF@toks@a first\else second\fi oftwo\endcsname% une parenthèse pour commencer ? + \ifx(\CF@toks@a\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi% une parenthèse pour commencer ? {\ifnum\CF@last@action=\tw@% il y avait une liaison juste avant ? \CF@insert@emptygroup\CF@remain@molecule \else - \CF@expand@second\CF@grab@submol\CF@remain@molecule + \expandafter\CF@grab@submol\expandafter{\CF@remain@molecule}% \begingroup \ifCF@incycle\let\CF@last@action\thr@@\fi% on était dans un cycle \CF@incyclefalse \aftergroup\CF@chemfig@iii - \def\CF@next@scan{\CF@expand@second\CF@chemfig@ii\CF@sub@mol}% + \def\CF@next@action{\expandafter\CF@chemfig@ii\expandafter{\CF@sub@mol}}% \fi }% {\ifx\CF@remain@molecule\@empty - \let\CF@next@scan\endgroup + \let\CF@next@action\endgroup \else% ce qui reste après le noeud courant n'est pas vide, ne commence pas par "-=~", ni par une parenthèse - \csname @\ifx*\CF@toks@a first\else second\fi oftwo\endcsname% un cycle ? + \ifx*\CF@toks@a\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi% un cycle ? {\ifnum\CF@last@action=\tw@ \CF@insert@emptygroup\CF@remain@molecule% insère un groupe vide \else \ifCF@incycle\let\CF@last@action\thr@@\fi% on était dans un cycle \ifnum\CF@last@action=\thr@@\let\CF@lastcycle@num\CF@cycle@num\fi - \CF@expand@second{\CF@expand@second\CF@if@firsttokmatch}{\expandafter\@gobble\CF@remain@molecule}*% un 2è "*" ? - {\CF@expand@second{\CF@expand@second{\def\CF@remain@molecule}}{\expandafter\@gobble\CF@remain@molecule}% enlève la 1er étoile - \CF@expand@second{\CF@expand@second\CF@if@firsttokmatch}{\expandafter\@gobble\CF@remain@molecule}[% un crochet ensuite ? + \CF@expafterarg@ntimes[2]\CF@if@firsttokmatch{\expandafter\@gobble\CF@remain@molecule}*% un 2è "*" ? + {\CF@expafterarg@ntimes[2]{\def\CF@remain@molecule}{\expandafter\@gobble\CF@remain@molecule}% enlève la 1er étoile + \CF@expafterarg@ntimes[2]\CF@if@firsttokmatch{\expandafter\@gobble\CF@remain@molecule}[% un crochet ensuite ? {\expandafter\CF@cycle@parsepreamblewithoptarg\CF@remain@molecule\@nil% \begingroup inclus }% {\def\CF@cyclearc@startangle{0}\def\CF@cyclearc@endangle{360}% @@ -522,7 +640,7 @@ \expandafter\draw\expandafter[\CF@cyclearc@directtikz](initarc) arc (\CF@cyclearc@startangle:\CF@cyclearc@endangle:\CF@cyclearc@radius pt); \fi \aftergroup\CF@chemfig@iii - \def\CF@next@scan{\CF@expand@second\CF@chemfig@ii\CF@sub@mol}% + \def\CF@next@action{\expandafter\CF@chemfig@ii\expandafter{\CF@sub@mol}}% \fi }% {\PackageError\CF@package@name{Something went wrong at this point: \detokenize\expandafter{\CF@remain@molecule}}{If you think it's a bug, please, send a Minimal Example to the author.}}% @@ -532,7 +650,7 @@ \CF@expand@second{\CF@expand@second{\CF@expand@second\CF@draw@atomgroup\CF@current@angle}\CF@current@toatom}\CF@current@atomgroup \fi \fi - \CF@next@scan + \CF@next@action } \def\CF@cycle@parsepreamble*#1#2\@nil{% @@ -540,20 +658,20 @@ \PackageError\CF@package@name{A cycle must be at least a triangle.}{} \fi \def\CF@remain@molecule{#2}% - \CF@expand@second\CF@grab@submol\CF@remain@molecule + \expandafter\CF@grab@submol\expandafter{\CF@remain@molecule}% \begingroup \def\CF@cycle@num{#1}% } \def\CF@cycle@parsepreamblewithoptarg*[#1]#2#3\@nil{% - \CF@cycle@parseoptarg#1,,,\@nil + \CF@cycle@parseoptarg#1,\@empty,\@empty,\@empty\@nil \CF@cycle@parsepreamble*#2#3\@nil } -\def\CF@cycle@parseoptarg#1,#2,#3,#4\@nil{% +\def\CF@cycle@parseoptarg#1,#2,#3\@nil{% \ifx\@empty#1\@empty\def\CF@cyclearc@startangle{0}\else\def\CF@cyclearc@startangle{#1}\fi \ifx\@empty#2\@empty\def\CF@cyclearc@endangle{360}\else\def\CF@cyclearc@endangle{#2}\fi - \def\CF@cyclearc@directtikz{#3}% + \expandafter\def\expandafter\CF@cyclearc@directtikz\expandafter{\CF@sanitize@lastitem#3,\@empty\@nil}% } \newcommand*\CF@grab@submol[1]{% @@ -572,12 +690,20 @@ \def\assign@tonil#1#2\@nil{\def#1{#2}} \newcommand*\CF@ifcar@isupperletter[1]{% - \csname @% - \ifcat\relax\noexpand#1second% faux si c'est une sc + \ifcat\relax\noexpand#1% + \let\CF@next\@secondoftwo% faux si c'est une sc + \else + \ifnum`#1<`A + \let\CF@next\@secondoftwo \else - \ifnum`#1<`Asecond\else\ifnum`#1>`Zsecond\else first\fi\fi + \ifnum`#1>`Z + \let\CF@next\@secondoftwo + \else + \let\CF@next\@firstoftwo + \fi \fi - oftwo\endcsname + \fi + \CF@next } % Créé 4 noeuds au dessus et au dessous des noeuds #1 et #2 @@ -604,13 +730,29 @@ } \newcommand*\CF@draw@bond[5]{% #1=type de liaison #2 et #3:nom de noeuds de début et fin #4 et #5: contenu des atomes de début et fin - \edef\CF@start@offset{\ifx#4\CF@empty@node0pt\else\ifx#4\@empty0pt\else\CF@bond@offset\fi\fi}% - \edef\CF@end@offset{\ifx#5\CF@empty@node0pt\else\ifx#5\@empty0pt\else\CF@bond@offset\fi\fi}% + \edef\CF@start@offset{% + \ifx\CF@start@offset\@empty + \ifx#4\CF@empty@node0pt\else\ifx#4\@empty0pt\else\CF@bond@offset\fi\fi + \else + \CF@start@offset + \fi + }% + \edef\CF@end@offset{% + \ifx\CF@end@offset\@empty + \ifx#5\CF@empty@node0pt\else\ifx#5\@empty0pt\else\CF@bond@offset\fi\fi + \else + \CF@end@offset + \fi + }% \path(#2)--(#3)coordinate[pos=0](#2@)coordinate[pos=1](#3@);% \CF@compute@nodevect{#2@}{#3@}% \pgfmathparse{\CF@start@offset/\CF@len@vector}\let\CF@start@coeff\pgfmathresult \pgfmathparse{1-\CF@end@offset/\CF@len@vector}\let\CF@end@coeff\pgfmathresult \path(#2@)--(#3@)coordinate[pos=\CF@start@coeff](#2@@)coordinate[pos=\CF@end@coeff](#3@@);% + \unless\ifx\CF@movebond@name\@empty% on doit poser un nœud sur la liaison + \path(#2@@)--(#3@@)coordinate[overlay,pos=\CF@movebond@coeff](\CF@movebond@name); + \let\CF@movebond@name\@empty + \fi \ifcase#1\relax \PackageError\CF@package@name{Unknown bond type, this error should not occur}{If you think it's a bug, send a Minimal Example to the author.}% \or% 1 = liaison simple @@ -668,17 +810,17 @@ \CF@create@normnodes{#3@@}{#2@@}{\CF@cram@basewidth/2}{}% \expandafter\filldraw\expandafter[\CF@current@tikz,line join=bevel](#3@@1)--(#3@@2)--(#2@@)--(#3@@1); \or% 6 = liaison Cram pointillée de #2 vers #3 - \begin{scope} + \scope \CF@create@normnodes{#2@@}{#3@@}{\CF@cram@basewidth/2}{}% \clip(#2@@1)--(#2@@2)--(#3@@)--(#2@@1); \expandafter\draw\expandafter[\CF@current@tikz,dash pattern=on \CF@cram@dashlength off \CF@cram@dashsep,line width=\CF@cram@basewidth](#2@@)--(#3@@); - \end{scope} + \endscope \or% 7 = liaison Cram pointillée de #3 vers #2 - \begin{scope} + \scope \CF@create@normnodes{#3@@}{#2@@}{\CF@cram@basewidth/2}{}% \clip(#3@@1)--(#3@@2)--(#2@@)--(#3@@1); \expandafter\draw\expandafter[\CF@current@tikz,dash pattern=on \CF@cram@dashlength off \CF@cram@dashsep,line width=\CF@cram@basewidth](#3@@)--(#2@@); - \end{scope} + \endscope \or% 8 = liaison Cram triangle évidé de #2 vers #3 \CF@create@normnodes{#2@@}{#3@@}{\CF@cram@basewidth/2}{}% \expandafter\draw\expandafter[\CF@current@tikz,line join=bevel](#2@@1)--(#2@@2)--(#3@@)--(#2@@1); @@ -688,13 +830,14 @@ \else \PackageError\CF@package@name{Unknown bond type, this error should not occur}{If you think it's a bug, send a Minimal Example to the author.}% \fi + \let\CF@start@offset\@empty + \let\CF@end@offset\@empty } \newcommand*\CF@draw@bond@i{\expandafter\draw\expandafter[\CF@current@tikz]} \newcommand*\CF@hook@drawall{% dessine tous les crochets contenus dansla sc \CF@hook@draw - \ifx\CF@hook@drawlist\@empty - \else + \unless\ifx\CF@hook@drawlist\@empty \expandafter\CF@hook@drawfirst\CF@hook@drawlist\@nil% trace un lien de crochet à crochet \expandafter\CF@hook@drawall \fi @@ -716,18 +859,34 @@ \def\CF@extract@atom#1-#2\@nil{#2}% transforme le bound@outnode en n° de l'atome -\newcommand\setnodestyle{\def\CF@node@style} +\newcommand*\setnodestyle{\def\CF@node@style} \setnodestyle{} +\expandafter\def\expandafter\CF@gobble@movearg\string @#1#2\@nil#3% +{% + \expandafter\def\csname atom@\number\CF@cnt@atomnumber\endcsname{#2}% + \CF@if@instr{#1},% + {\CF@analyse@movearg#1\@nil#3\let\CF@movebond@coeff\@empty}% + {\def#3{#1}}% + \ifx\@empty#2\@empty\let\CF@node@strut\@empty\fi +}% + \newcommand*\CF@draw@atomgroup[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@bond@outcontent% assigne le contenu de l'atome d'où part la liaison - \csname\ifdefined\CF@bond@outnode atom@\expandafter\CF@extract@atom\CF@bond@outnode\@nil\else @empty\fi\endcsname + \csname + \ifdefined\CF@bond@outnode + atom@\expandafter\CF@extract@atom\CF@bond@outnode\@nil + \else + @empty% + \fi + \endcsname \global\advance\CF@cnt@groupnumber\@ne \let\CF@current@atom\@empty - \CF@global@let\CF@hook@drawlist\@empty + \global\let\CF@hook@drawlist\@empty \CF@cnt@atomingroup\z@ \CF@if@firsttokmatch{#3}?{\CF@draw@atomgroup@i{{}#3}}{\CF@draw@atomgroup@i{#3}}% \def\CF@current@atomgroup{#3}% + \CF@remove@movearg\CF@current@atomgroup% enlève les "@{}" \CF@if@instr{#3}?% {\CF@remove@hook\CF@current@atomgroup \ifx\@empty\CF@current@atomgroup\let\CF@current@atomgroup\CF@empty@node\fi}% @@ -743,7 +902,7 @@ \fi \fi \edef\CF@hook@atomnumber{% - \ifx\@empty#2\@empty% + \ifx\@empty#2\@empty%\relax \ifdim#1pt>90pt \ifdim#1pt<270pt \number\CF@cnt@atomingroup\else1\fi \else1% @@ -754,12 +913,22 @@ \ifx\CF@current@atomgroup\CF@empty@node \let\CF@node@strut\@empty \else - \def\CF@node@strut{\vphantom\CF@bond@outcontent}% + \ifx\@empty\CF@bond@outcontentsaved + \def\CF@node@strut{\vphantom\CF@bond@outcontent}% + \else + \def\CF@node@strut{\vphantom\CF@bond@outcontentsaved}% + \fi \fi - \def\CF@node@content{\expandafter\printatom\expandafter{\csname atom@\number\CF@cnt@atomnumber\endcsname\CF@node@strut}}% \edef\CF@opt@string{anchor=\ifnum\CF@last@action=\z@ base\else center\fi,at=(CF@node),\CF@node@style}% premier atome de la molécule affiché \loop \unless\ifnum\CF@cnt@atomnumber>\CF@cnt@atomingroup + \expandafter\expandafter\expandafter\futurelet\expandafter\expandafter\expandafter\CF@toks@a\expandafter\expandafter\expandafter + \CF@gobble@tonil\csname atom@\number\CF@cnt@atomnumber\endcsname\@nil + \expandafter\ifx\string @\CF@toks@a% l'atome courant commence par un "@" + \expandafter\expandafter\expandafter\CF@gobble@movearg\csname atom@\number\CF@cnt@atomnumber\endcsname\@nil\CF@moveatom@name + \expandafter\node\expandafter[\CF@opt@string,overlay](\CF@moveatom@name){\phantom{\CF@node@content}};% + \let\CF@moveatom@name\@empty + \fi \expandafter\node\expandafter[\CF@opt@string](n\number\CF@cnt@groupnumber-\number\CF@cnt@atomnumber){\CF@node@content};% \let\CF@node@strut\@empty \advance\CF@cnt@atomnumber\@ne @@ -775,6 +944,13 @@ \ifnum\CF@cnt@atomnumber>\@ne \advance\CF@cnt@atomnumber\m@ne \edef\CF@opt@string{anchor=base east,at=(n\number\CF@cnt@groupnumber-\number\numexpr\CF@cnt@atomnumber+1.base west),\CF@node@style}% + \expandafter\expandafter\expandafter\futurelet\expandafter\expandafter\expandafter\CF@toks@a\expandafter\expandafter\expandafter + \CF@gobble@tonil\csname atom@\number\CF@cnt@atomnumber\endcsname\@nil + \expandafter\ifx\string @\CF@toks@a% l'atome courant commence par un "@" + \expandafter\expandafter\expandafter\CF@gobble@movearg\csname atom@\number\CF@cnt@atomnumber\endcsname\@nil\CF@moveatom@name + \expandafter\node\expandafter[\CF@opt@string,overlay](\CF@moveatom@name){\phantom{\CF@node@content}};% + \let\CF@moveatom@name\@empty + \fi \expandafter\node\expandafter[\CF@opt@string](n\number\CF@cnt@groupnumber-\number\CF@cnt@atomnumber){\CF@node@content};% \repeat \CF@hook@drawall @@ -782,63 +958,117 @@ \let\CF@previous@atomgroup\CF@current@atomgroup } +\expandafter\def\expandafter\CF@keep@movearg\string @#1#2\@nil{\expandafter\def\expandafter\CF@current@atom\expandafter{\string @{#1}}} + \newcommand*\CF@draw@atomgroup@i[1]{% transforme #1 en un groupe d'atomes - \ifx\@empty#1\@empty% + \ifx\@empty#1\@empty + \expandafter\let\csname atom@\number\CF@cnt@atomingroup\endcsname\CF@current@atom \else \advance\CF@cnt@atomingroup\@ne - \CF@if@firsttokmatch{#1}\egroup - {\CF@expand@second{\def\CF@current@atom}{\expandafter{\@car#1\@nil}}% - \CF@swap@fi\CF@expand@second\CF@draw@atomgroup@ii{\@gobble#1}% + \futurelet\CF@toks@a\CF@gobble@tonil#1\@nil + \expandafter\ifx\string @\CF@toks@a\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi + {\CF@keep@movearg#1\@nil + \CF@swap@fi + \CF@remove@movearg@i#1\@nil\CF@after@movearg + \expandafter\CF@draw@atomgroup@ii\expandafter{\CF@after@movearg}% }% - {\CF@if@spacefirst{#1}% - {\def\CF@current@atom{ }% - \CF@swap@fi\CF@expand@second\CF@draw@atomgroup@ii{\CF@after@space#1\@nil}% - }% - {\CF@expand@second{\def\CF@current@atom}{\@car#1\@nil}% - \CF@swap@fi\CF@expand@second\CF@draw@atomgroup@ii{\@gobble#1}% - }% + {\CF@swap@fi + \let\CF@current@atom\@empty + \CF@draw@atomgroup@ii{#1}% }% \fi } -\newcommand*\CF@draw@atomgroup@ii[1]{% transforme #1 en un groupe d'atomes +\newcommand*\CF@draw@atomgroup@ii[1]{% + \ifx\@empty#1\@empty + \expandafter\let\csname atom@\number\CF@cnt@atomingroup\endcsname\CF@current@atom + \else + \futurelet\CF@toks@a\CF@gobble@tonil#1\@nil + \ifx\bgroup\CF@toks@a\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi + {\CF@expadd@tocs\CF@current@atom{\expandafter{\@car#1\@nil}}% + \expandafter\CF@draw@atomgroup@iii\expandafter{\@gobble#1}% + }% + {\ifx\@sptoken\CF@toks@a\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi + {\CF@add@tocs\CF@current@atom{ }% + \expandafter\CF@draw@atomgroup@iii\expandafter{\CF@after@space#1\@nil}% + }% + {\CF@expadd@tocs\CF@current@atom{\@car#1\@nil}% + \expandafter\CF@draw@atomgroup@iii\expandafter{\@gobble#1}% + }% + }% + \fi +} + +% enlève tous les "@{nom}" de la sc #1 +\def\CF@remove@movearg#1% +{% + \CF@expand@afterfirst{\expandafter\CF@if@instr\expandafter{#1}}{\string @}% + {\expandafter\CF@remove@movearg@i#1\@nil#1% + \CF@remove@movearg#1}% + \relax +} + +% enlève le premier "@{}" de l'argument et l'assigne à #2 +\def\CF@remove@movearg@i#1\@nil#2% +{% + \expandafter\def\expandafter\CF@remove@movearg@ii\expandafter##\expandafter1\string @{% + \expandafter\def\expandafter#2\expandafter{\@gobble##1}% mange le \relax + \CF@remove@movearg@iii\relax + }% + \def\CF@remove@movearg@iii##1\@nil{\CF@expadd@tocs#2{\@gobbletwo##1}}% mange le \relax et le + \CF@remove@movearg@ii\relax#1\@nil +} + +\newcommand*\CF@draw@atomgroup@iii[1]{% transforme #1 en un groupe d'atomes \ifx\@empty#1\@empty% \expandafter\let\csname atom@\number\CF@cnt@atomingroup\endcsname\CF@current@atom \let\CF@current@atom\@empty \else - \CF@if@spacefirst{#1}% - {\CF@expadd@tocs\CF@current@atom{ }% - \CF@swap@fi\CF@expand@second\CF@draw@atomgroup@ii{\CF@after@space#1\@nil}% - } - {\CF@if@firsttokmatch{#1}\bgroup - {\CF@expadd@tocs\CF@current@atom{\expandafter{\@car#1\@nil}}% - \CF@swap@fi\CF@expand@second\CF@draw@atomgroup@ii{\@gobble#1}% - }% - {\CF@expand@second\CF@ifcar@isupperletter{\@car#1\@nil}% - {\expandafter\let\csname atom@\number\CF@cnt@atomingroup\endcsname\CF@current@atom - \let\CF@current@atom\@empty - \CF@swap@fi\CF@draw@atomgroup@i{#1} - }% - {\CF@if@firsttokmatch{#1}?% - {\expandafter\CF@if@firsttokmatch\expandafter{\@gobble#1}[% un crochet après le "?" - {\expandafter\CF@grab@optarg\@gobble#1\@nil\CF@after@hook}% - {\expandafter\CF@grab@optarg\expandafter[\expandafter]\@gobble#1\@nil\CF@after@hook}% - \CF@expand@second{\CF@expand@second\CF@if@instr\CF@hook@list}{\expandafter(\CF@hook@currentname)}% crochet déjà défini ? - {\expandafter\CF@hook@parselist\expandafter{\CF@hook@currentname}% va chercher les caractéristiques du crochet sauvegardé - \CF@edefadd@tocs\CF@hook@drawlist{% - [\CF@hook@currentname,\CF@hook@currentlink,\CF@hook@currenttikz]{\CF@hook@savedcoord}{n\number\CF@cnt@groupnumber-\number\CF@cnt@atomingroup}}% - \CF@expadd@tocs\CF@hook@drawlist{\expandafter{\CF@hook@savedcontent}}% - \CF@expadd@tocs\CF@hook@drawlist{\expandafter{\CF@current@atom}}% ajoute les 4 arguments à la liste des crochets à tracer - \CF@global@let\CF@hook@drawlist\CF@hook@drawlist + \futurelet\CF@toks@a\CF@gobble@tonil#1\@nil + \expandafter\ifx\string @\CF@toks@a\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi + {\expandafter\let\csname atom@\number\CF@cnt@atomingroup\endcsname\CF@current@atom + \let\CF@current@atom\@empty + \CF@swap@fi\CF@draw@atomgroup@i{#1}% + }% + {\ifx|\CF@toks@a\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi + {\expandafter\let\csname atom@\number\CF@cnt@atomingroup\endcsname\CF@current@atom + \let\CF@current@atom\@empty + \CF@swap@fi\expandafter\CF@draw@atomgroup@i\expandafter{\@gobble#1}}% + {\ifx\@sptoken\CF@toks@a\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi + {\CF@add@tocs\CF@current@atom{ }% + \CF@swap@fi\expandafter\CF@draw@atomgroup@iii\expandafter{\CF@after@space#1\@nil}% + }% + {\ifx\bgroup\CF@toks@a\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi + {\CF@expadd@tocs\CF@current@atom{\expandafter{\@car#1\@nil}}% + \CF@swap@fi\expandafter\CF@draw@atomgroup@iii\expandafter{\@gobble#1}% + }% + {\expandafter\CF@ifcar@isupperletter\expandafter{\@car#1\@nil}% + {\expandafter\let\csname atom@\number\CF@cnt@atomingroup\endcsname\CF@current@atom + \let\CF@current@atom\@empty + \CF@swap@fi\CF@draw@atomgroup@i{#1}% }% - {\CF@edefadd@tocs\CF@hook@list{(\CF@hook@currentname)|n\number\CF@cnt@groupnumber-\number\CF@cnt@atomingroup|}% - \CF@expadd@tocs\CF@hook@list{\CF@current@atom|}% - \CF@global@let\CF@hook@list\CF@hook@list + {\ifx?\CF@toks@a\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi + {\expandafter\CF@if@firsttokmatch\expandafter{\@gobble#1}[% un crochet après le "?" + {\expandafter\CF@grab@optarg\@gobble#1\@nil\CF@after@hook}% + {\expandafter\CF@grab@optarg\expandafter[\expandafter]\@gobble#1\@nil\CF@after@hook}% + \CF@expand@second{\CF@expand@second\CF@if@instr\CF@hook@list}{\expandafter(\CF@hook@currentname)}% crochet déjà défini ? + {\expandafter\CF@hook@parselist\expandafter{\CF@hook@currentname}% va chercher les caractéristiques du crochet sauvegardé + \CF@edefadd@tocs\CF@hook@drawlist{% + [\CF@hook@currentname,\CF@hook@currentlink,\CF@hook@currenttikz]{\CF@hook@savedcoord}{n\number\CF@cnt@groupnumber-\number\CF@cnt@atomingroup}}% + \CF@expadd@tocs\CF@hook@drawlist{\expandafter{\CF@hook@savedcontent}}% + \CF@expadd@tocs\CF@hook@drawlist{\expandafter{\CF@current@atom}}% ajoute les 4 arguments à la liste des crochets à tracer + \global\let\CF@hook@drawlist\CF@hook@drawlist + }% + {\CF@edefadd@tocs\CF@hook@list{(\CF@hook@currentname)|n\number\CF@cnt@groupnumber-\number\CF@cnt@atomingroup|}% + \CF@expadd@tocs\CF@hook@list{\CF@current@atom|}% + \global\let\CF@hook@list\CF@hook@list + }% + \CF@swap@fi\expandafter\CF@draw@atomgroup@iii\expandafter{\CF@after@hook}% + }% + {\CF@expadd@tocs\CF@current@atom{\@car#1\@nil}% + \CF@swap@fi\expandafter\CF@draw@atomgroup@iii\expandafter{\@gobble#1}% + }% }% - \CF@swap@fi\CF@expand@second\CF@draw@atomgroup@ii\CF@after@hook - }% - {\CF@expadd@tocs\CF@current@atom{\@car#1\@nil}% - \CF@swap@fi\CF@expand@second\CF@draw@atomgroup@ii{\@gobble#1}% }% }% }% @@ -851,9 +1081,9 @@ \def\CF@hook@defaulttikz{} \def\CF@hook@parseoptarg#1,#2,#3\@nil{% - \CF@test@assign\CF@hook@currentname{#1}\CF@kook@defaultname - \CF@test@assign\CF@hook@currentlink{#2}\CF@hook@defaultlink - \CF@test@assign\CF@hook@currenttikz{#3}\CF@hook@defaulttikz + \CF@testempty@andassign\CF@hook@currentname{#1}\CF@kook@defaultname + \CF@testempty@andassign\CF@hook@currentlink{#2}\CF@hook@defaultlink + \CF@testempty@andassign\CF@hook@currenttikz{#3}\CF@hook@defaulttikz } \def\CF@grab@optarg[#1]#2\@nil#3{% @@ -890,17 +1120,20 @@ \def\CF@remove@singlehook#1?#2\@nil{#1#2} -\newcommand*\setlewis[3]{% - \ifx\@empty#1\@empty\def\CF@lewis@offset{1.5pt}\else\def\CF@lewis@offset{#1}\fi - \ifx\@empty#2\@empty\def\CF@lewis@length{1.5ex}\else\def\CF@lewis@length{#2}\fi - \ifx\@empty#3\@empty\def\CF@lewis@style{}\else\def\CF@lewis@style{#3}\fi +\newcommand*\setlewis[4][0.3ex]{% + \def\CF@lewis@widthdouble{#1}% TODO à renseigner dans la doc (oublié dans la version 0.3) + \ifx\@empty#2\@empty\def\CF@lewis@offset{0.4ex}\else\def\CF@lewis@offset{#2}\fi + \ifx\@empty#3\@empty\def\CF@lewis@length{1.5ex}\else\def\CF@lewis@length{#3}\fi + \ifx\@empty#4\@empty\def\CF@lewis@style{}\else\def\CF@lewis@style{#4}\fi } \setlewis{}{}{} -\newcommand*\lewis[1]{\begingroup\@makeother;\CF@lewis@i#1\@nil} +\newcommand*\lewis{\begingroup\@makeother;\@makeother:\CF@lewis@i} -\def\CF@lewis@i#1,#2\@nil% +\newcommand\CF@lewis@i[1]{\CF@lewis@ii#1\@nil} + +\def\CF@lewis@ii#1,#2\@nil% {% \setbox\CF@lewis@box\hbox{\printatom{#2}}% \def\CF@lewis@remainpos{#1}% @@ -913,25 +1146,31 @@ \let\CF@lewis@x\pgfmathresult \pgfmathparse{\ht\CF@lewis@box/2+\ifcase\CF@lewis@currentpos\space0\or1\or1\or1\or0\or-1\or-1\or-1\fi*(\ht\CF@lewis@box/2\ifnum\CF@lewis@currentpos>4 +\dp\CF@lewis@box\fi+\CF@lewis@offset)}% \let\CF@lewis@y\pgfmathresult - \edef\CF@lewis@xoffset{\ifcase\CF@lewis@currentpos\space0\or0.7071\or1\or0.7071\or0\or-0.7071\or-1\or-0.7071\fi}% - \edef\CF@lewis@yoffset{\ifcase\CF@lewis@currentpos\space-1\or-0.7071\or0\or0.7071\or1\or0.7071\or0\or-0.7071\fi}% + \edef\CF@lewis@xoffset{\ifcase\CF@lewis@currentpos\space + 0\or0.70711\or1\or0.70711\or0\or-0.70711\or-1\or-0.70711\fi}% + \edef\CF@lewis@yoffset{\ifcase\CF@lewis@currentpos\space + -1\or-0.70711\or0\or0.70711\or1\or0.70711\or0\or-0.70711\fi}% + \pgfmathparse{veclen(\CF@lewis@xoffset,\CF@lewis@yoffset)}\let\CF@len@normvec\pgfmathresult + \edef\CF@lewis@diagmul{\ifcase\CF@lewis@currentpos\space1\or0\or1\or0\or1\or0\or1\or0\fi}% annule l'offset pour les diagonales \if.\expandafter\@car\CF@lewis@remainpos\relax\@nil \edef\CF@lewis@remainpos{\expandafter\@gobble\CF@lewis@remainpos}% - \tikz \draw[overlay,fill,black] ([xshift=-\CF@lewis@yoffset*0.8,yshift=\CF@lewis@xoffset*0.8]\CF@lewis@x pt,\CF@lewis@y pt)circle(0.8pt);% + \tikz \draw[overlay,fill,black] + (\CF@lewis@x pt-\CF@lewis@yoffset*\CF@lewis@diagmul*0.1ex, + \CF@lewis@y pt+\CF@lewis@xoffset*\CF@lewis@diagmul*0.1ex)circle(0.15ex);% \else \if|\expandafter\@car\CF@lewis@remainpos\relax\@nil \edef\CF@lewis@remainpos{\expandafter\@gobble\CF@lewis@remainpos}% \expandafter\tikz\expandafter\draw\expandafter[\CF@lewis@style,overlay]% (\CF@lewis@x-\CF@lewis@length*\CF@lewis@xoffset/2 pt,\CF@lewis@y-\CF@lewis@length*\CF@lewis@yoffset/2 pt)-- - ([xshift=-\CF@lewis@yoffset*2,yshift=\CF@lewis@xoffset*2]\CF@lewis@x-\CF@lewis@xoffset*\CF@lewis@length/2 pt,\CF@lewis@y-\CF@lewis@yoffset*\CF@lewis@length/2 pt)-- - ([xshift=-\CF@lewis@yoffset*2,yshift=\CF@lewis@xoffset*2]\CF@lewis@x+\CF@lewis@length*\CF@lewis@xoffset/2 pt,\CF@lewis@y+\CF@lewis@length*\CF@lewis@yoffset/2 pt)-- + ([xshift=-\CF@lewis@yoffset*\CF@lewis@widthdouble,yshift=\CF@lewis@xoffset*\CF@lewis@widthdouble]\CF@lewis@x-\CF@lewis@xoffset*\CF@lewis@length/2 pt,\CF@lewis@y-\CF@lewis@yoffset*\CF@lewis@length/2 pt)-- + ([xshift=-\CF@lewis@yoffset*\CF@lewis@widthdouble,yshift=\CF@lewis@xoffset*\CF@lewis@widthdouble]\CF@lewis@x+\CF@lewis@length*\CF@lewis@xoffset/2 pt,\CF@lewis@y+\CF@lewis@length*\CF@lewis@yoffset/2 pt)-- (\CF@lewis@x+\CF@lewis@length*\CF@lewis@xoffset/2 pt,\CF@lewis@y+\CF@lewis@length*\CF@lewis@yoffset/2 pt)--cycle;% \else \if:\expandafter\@car\CF@lewis@remainpos\relax\@nil \edef\CF@lewis@remainpos{\expandafter\@gobble\CF@lewis@remainpos}% \tikz \draw[overlay,fill,black] - ([xshift=-2*\CF@lewis@xoffset,yshift=-2*\CF@lewis@yoffset]\CF@lewis@x pt,\CF@lewis@y pt)circle(0.8pt)% - ([xshift=2*\CF@lewis@xoffset,yshift=2*\CF@lewis@yoffset]\CF@lewis@x pt,\CF@lewis@y pt)circle(0.8pt);% + (\CF@lewis@x pt-\CF@lewis@yoffset*\CF@lewis@diagmul*0.2ex-.2em*\CF@lewis@xoffset/\CF@len@normvec,\CF@lewis@y pt+\CF@lewis@xoffset*\CF@lewis@diagmul*0.2ex-.2em*\CF@lewis@yoffset/\CF@len@normvec)circle(0.15ex)% + (\CF@lewis@x pt-\CF@lewis@yoffset*\CF@lewis@diagmul*0.2ex+.2em*\CF@lewis@xoffset/\CF@len@normvec,\CF@lewis@y pt+\CF@lewis@xoffset*\CF@lewis@diagmul*0.2ex+.2em*\CF@lewis@yoffset/\CF@len@normvec)circle(0.15ex);% \else \expandafter\tikz\expandafter\draw\expandafter[\CF@lewis@style,overlay]% (\CF@lewis@x-\CF@lewis@length*\CF@lewis@xoffset/2 pt,\CF@lewis@y-\CF@lewis@length*\CF@lewis@yoffset/2 pt)--% @@ -950,9 +1189,9 @@ \hbox{\printatom{#2}}% \hrule width0pt depth0pt height#1\relax \hbox{% - \hskip\dimexpr(\wd\CF@box@boxa-\wd\CF@box@boxb)/2\relax + \hskip\dimexpr(\wd\CF@box@boxa-\wd\CF@box@boxb)/\tw@ \printatom{#3}% - \hskip\dimexpr(\wd\CF@box@boxa-\wd\CF@box@boxb)/2\relax + \hskip\dimexpr(\wd\CF@box@boxa-\wd\CF@box@boxb)/\tw@ }% \vskip-\dimexpr\ht\CF@box@boxb+\dp\CF@box@boxb+#1\relax }% @@ -964,9 +1203,9 @@ \hbox{\printatom{#2}}% \hrule width0pt depth0pt height-\dimexpr#1+\ht\CF@box@boxa+\ht\CF@box@boxb+\dp\CF@box@boxb\relax \hbox{% - \hskip\dimexpr(\wd\CF@box@boxa-\wd\CF@box@boxb)/2\relax + \hskip\dimexpr(\wd\CF@box@boxa-\wd\CF@box@boxb)/\tw@ \printatom{#3}% - \hskip\dimexpr(\wd\CF@box@boxa-\wd\CF@box@boxb)/2\relax + \hskip\dimexpr(\wd\CF@box@boxa-\wd\CF@box@boxb)/\tw@ }% }% } @@ -988,17 +1227,17 @@ \def\CF@equi@chars{<>}\def\CF@chemrel@chars{#3}% \def\CF@chemrel@stuff {\leavevmode\kern\CF@chemrel@hsep - \begin{tikzpicture}[every node/.style={anchor=base,inner sep=0pt,outer sep=0pt,minimum size=0pt},baseline]% + \tikzpicture[every node/.style={anchor=base,inner sep=0pt,outer sep=0pt,minimum size=0pt},baseline]% \CF@if@instr{#3}{<>}% - {\node[yshift=-2pt] at(0,0)(chemrel@start){\vphantom I};\node[yshift=-2pt] at(\CF@chemrel@length,0)(chemrel@end){\vphantom I};% - \expandafter\draw\expandafter[\CF@remove@equichars#3,\@nil->](chemrel@start)--(chemrel@end);% - \node[yshift=2pt] at(0,0)(chemrel@start){\vphantom I};\node[yshift=2pt] at(\CF@chemrel@length,0)(chemrel@end){\vphantom I};% - \expandafter\draw\expandafter[\CF@remove@equichars#3,\@nil<-](chemrel@start)--(chemrel@end); + {\node[yshift=-1pt] at(0,0)(chemrel@start){\vphantom I};\node[yshift=-1pt] at(\CF@chemrel@length,0)(chemrel@end){\vphantom I};% + \expandafter\draw\expandafter[\CF@remove@equichars#3,\@nil-](chemrel@end)--(chemrel@start);\fill (chemrel@start)--++(4pt,-1.75pt)--+(-1.5pt,1.75pt)--cycle;% + \node[yshift=1pt] at(0,0)(chemrel@start){\vphantom I};\node[yshift=1pt] at(\CF@chemrel@length,0)(chemrel@end){\vphantom I};% + \expandafter\draw\expandafter[\CF@remove@equichars#3,\@nil-](chemrel@start)--(chemrel@end);\fill(chemrel@end)--++(-4pt,1.75pt)--+(1.5pt,-1.75pt)--cycle; }% {\node at(0,0)(chemrel@start){\vphantom I};\node at(\CF@chemrel@length,0)(chemrel@end){\vphantom I};% \draw[#3](chemrel@start)--(chemrel@end);% }% - \end{tikzpicture}% + \endtikzpicture \kern\CF@chemrel@hsep }% \ifx#1\@empty @@ -1013,6 +1252,47 @@ } \def\CF@remove@equichars#1<>#2\@nil{#1#2} + +\newcommand\chemmove[2][]{% + \ifx\@empty#2\@empty + \expandafter\@gobble + \else + \expandafter\@firstofone + \fi + {\expandafter\tikzpicture\romannumeral\ifx\@empty#1\@empty\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi + {\z@[remember picture,overlay]}{\z@[remember picture,overlay,#1]}#2 + \endtikzpicture + }% +} + +\newcommand*\chemnameinit[1]{% + \setbox\CF@stuff@box\hbox{#1}% + \edef\CF@dp@max{\the\dp\CF@stuff@box}% +} +\chemnameinit{} + +\def\CF@parse@molname#1\\#2\@nil{% + \hbox to\CF@wd@stuffbox{\hss#1\hss}% + \ifx\@empty#2\@empty + \else + \CF@swap@fi + \CF@parse@molname#2\@nil + \fi +} + +\newcommand*\chemname[3][1.5ex]{% + \setbox\CF@stuff@box\hbox{#2}% + \edef\CF@wd@stuffbox{\the\wd\CF@stuff@box}\edef\CF@dp@stuffbox{\the\dp\CF@stuff@box}% + \leavevmode + \ifdim\CF@dp@max<\CF@dp@stuffbox\let\CF@dp@max\CF@dp@stuffbox\fi + \vtop{% + \box\CF@stuff@box + \nointerlineskip + \kern\dimexpr#1+\CF@dp@max-\CF@dp@stuffbox\relax + \CF@parse@molname#3\\\@nil + }% +} + \endinput ###################################################################### @@ -1035,4 +1315,35 @@ v0.2 2010/08/31 l'on écrit \chemfig{*5(=====)}, on obtient deux polygones réguliers concentriques. - La séquence de contrôle \setnodestyle permet de spécifier le - style des nœuds dessinés par tikz. \ No newline at end of file + style des nœuds dessinés par tikz. +---------------------------------------------------------------------- +v0.3 2010/11/21 + - Amélioration de \definesubmol qui accepte les séquences de + contrôle. On peut aussi choisir un alias dont la substitution + est différente selon l'orientation de la liaison qui lui arrive + dessus. + - Le caractère "|" force la fin d'un atome. Si on écrit "D|ef" + alors, chemfig verra deux atomes "D" et "ef". + - Le caractère "#" est reconnu lorsqu'il suit un caractère de + liaison. Il doit être suivi d'un argument entre parenthèses qui + contient l'offset de début et de fin qui s'appliqueront à cette + liaison. + - La macro \chemfig admet un argument optionnel qui sera passé à + l'environnement tikzpicture dans lequel elle est dessinée. + - Mise en place de la représentation des mécanismes réactionnels + avec la synatxe "@{}" devant un atome ou + "@{,}" au tout début de l'argument d'une liaison. + Cette syntaxe permet de placer un nœud (au sens de tikz) qui + deviendra l'extrémité des flèches des mécanismes. + Le tracé des flèches est faite par la macro \chemmove dont + l'argument optionnel devient celui de l'environnement + tikspicture dans lequel sont faites les flèches. + - Pour le mécanisme d'alignement vertical via le \vphantom, la + commande \chemskipalign permet d'ignorer le groupe d'atomes + dans lequel elle est écrite. + - La commande \chemname permet d'afficher un nom sous une + molécule. la commande \chemnameinit initialise la plus grande + profondeur rencontrée. + - La commande \lewis a été modifiée de telle sorte que les + dessins des décorations soient proportionnels à la taille de la + police. \ No newline at end of file -- cgit v1.2.3