From 7f8fffa1c8b5b30f8e2a9fd4b76778147dbb9128 Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Tue, 28 Apr 2020 03:02:53 +0000 Subject: CTAN sync 202004280302 --- macros/generic/chemfig/README | 4 +- macros/generic/chemfig/chemfig-en.pdf | Bin 1087261 -> 1087404 bytes macros/generic/chemfig/chemfig-fr.pdf | Bin 1115526 -> 1115715 bytes macros/generic/chemfig/chemfig.tex | 317 +++++++++++++-------------- macros/generic/simplekv/README | 4 +- macros/generic/simplekv/simplekv-fr.pdf | Bin 329306 -> 326887 bytes macros/generic/simplekv/simplekv-fr.tex | 161 ++++++++++---- macros/generic/simplekv/simplekv.sty | 1 + macros/generic/simplekv/simplekv.tex | 374 +++++++++++--------------------- 9 files changed, 403 insertions(+), 458 deletions(-) (limited to 'macros/generic') diff --git a/macros/generic/chemfig/README b/macros/generic/chemfig/README index 145bdfed79..1068cd4dce 100644 --- a/macros/generic/chemfig/README +++ b/macros/generic/chemfig/README @@ -2,9 +2,9 @@ ___________________________________ The Chemfig package - v1.52 + v1.53 - 2020/04/14 + 2020/04/27 ___________________________________ Maintainer: Christian Tellechea diff --git a/macros/generic/chemfig/chemfig-en.pdf b/macros/generic/chemfig/chemfig-en.pdf index 250d8500c9..1e5152ae55 100644 Binary files a/macros/generic/chemfig/chemfig-en.pdf and b/macros/generic/chemfig/chemfig-en.pdf differ diff --git a/macros/generic/chemfig/chemfig-fr.pdf b/macros/generic/chemfig/chemfig-fr.pdf index 4e63fadd1d..fd399ee621 100644 Binary files a/macros/generic/chemfig/chemfig-fr.pdf and b/macros/generic/chemfig/chemfig-fr.pdf differ diff --git a/macros/generic/chemfig/chemfig.tex b/macros/generic/chemfig/chemfig.tex index bf66ce58d1..3764ace94d 100644 --- a/macros/generic/chemfig/chemfig.tex +++ b/macros/generic/chemfig/chemfig.tex @@ -4,9 +4,9 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % \def\CFname {chemfig} % -\def\CFver {1.52} % +\def\CFver {1.53} % % % -\def\CFdate {2020/04/14} % +\def\CFdate {2020/04/27} % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % @@ -72,10 +72,7 @@ {\input chemfigold.tex\relax\endinput}% %------------------------ Chargement simplekv ------------------------ -\unless\ifdefined\skvname - \begingroup\def\CFtemp{\endgroup\input simplekv.tex\relax}% - \expandafter\CFtemp -\fi +\input simplekv.tex %-------------------------- Chargement tikz -------------------------- \unless\ifdefined\tikzpicture @@ -129,12 +126,20 @@ \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{% - \setbox\CF_testbox\hbox{\printatom{#1}}% + \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 @@ -213,12 +218,6 @@ \CF_ifinstra#1\__nil#2\_nil } \def\CF_afterspace#1 #2\_nil{#2} -\def\CF_valuetomacro[#1]#2[#3]#4{% #1=trousseau #2= macro #3=valeur défaut #4=clé - \CF_eexpsecond{\def#2}{\useKV[#1]{#4}}% - \CF_ifx#2\empty - {\def#2{#3}} - {}% -} %--------------------------- Substitution ---------------------------- \def\CF_ifstartwith#1#2{% #1= #2= @@ -357,50 +356,84 @@ } %---------------------------- Paramètres ----------------------------- -\def\setchemfig{\setKV[chemfig]} -\def\resetchemfig{% - \setKVdefault[chemfig]{% - atom style ={},% code tikz mis à la fin de every node/.style - 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 ={}, - lewis | width =0.3ex, - lewis sep =0.4ex, - lewis length =1.5ex, - lewis style ={}, - lewis dist =0.3em, - lewis radius =0.15ex, - lewis diag coeff =1, - cycle radius coeff =0.75, - stack sep =1.5pt, - scheme debug =false, - compound style ={}, - compound sep =5em, - arrow offset =4pt, - 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, - + sep left =0.5em, - + sep right =0.5em, - + vshift =0pt, - }% +\def\CF_defifempty#1#2#3{\CF_ifempty{#2}{\def#1{#3}}{\def#1{#2}}} +\defKV[chemfig]{% + atom style = \def\CF_atomstyle {#1}, + 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}, + lewis | width = \CF_defifempty\CF_lewiswidthdouble {#1}{0.3ex}, + lewis sep = \CF_defifempty\CF_lewisoffset {#1}{0.4ex}, + lewis length = \CF_defifempty\CF_lewislength {#1}{1.5ex}, + lewis style = \def\CF_lewisstyle {#1}, + lewis dist = \CF_defifempty\CF_lewisdist {#1}{0.3em}, + lewis radius = \CF_defifempty\CF_lewisradius {#1}{0.15ex}, + lewis diag coeff = \CF_defifempty\CF_lewisdiagcoeff {#1}{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}, + + 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} } -\resetchemfig +\def\setchemfig{\setKV[chemfig]} +\def\resetchemfig{\restoreKV[chemfig]} +\setKVdefault[chemfig]{% + atom style = {},% code tikz mis à la fin de every node/.style + 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 = {}, + lewis | width = 0.3ex, + lewis sep = 0.4ex, + lewis length = 1.5ex, + lewis style = {}, + lewis dist = 0.3em, + lewis radius = 0.15ex, + lewis diag coeff = 1, + cycle radius coeff = 0.75, + stack sep = 1.5pt, + 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, + + sep left = 0.5em, + + sep right = 0.5em, + + vshift = 0pt +}% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% D E S S I N M O L É C U L E S %%% @@ -769,10 +802,10 @@ inner sep=0pt,% outer sep=0pt,% minimum size=0pt,% - \unexpanded\CF_threeea{\useKV[chemfig]{atom style}}% + \unexpanded\expandafter{\CF_atomstyle}% },% baseline,% - \unexpanded\CF_threeea{\useKV[chemfig]{chemfig style}}% + \unexpanded\expandafter{\CF_chemfigstyle}% ]% }% \begingroup% \endgroup rajouté en sortie de tracé par \CF_chemfigd @@ -786,17 +819,6 @@ \ifboolKV[chemfig]{cram rectangle} {\let\CF_clipcramornot\CF_gobtikzinstruction} {\let\CF_clipcramornot\clip}% - \CF_valuetomacro[chemfig]\CF_crambasewidth [1.5ex]{cram width}% - \CF_valuetomacro[chemfig]\CF_cramdashlength [1pt]{cram dash width}% - \CF_valuetomacro[chemfig]\CF_cramdashsep [2pt]{cram dash sep}% - \CF_valuetomacro[chemfig]\CF_atomsep [3em]{atom sep}% espacement des atomes liés - \CF_valuetomacro[chemfig]\CF_bondoffset [2pt]{bond offset}% - \CF_valuetomacro[chemfig]\CF_doublesep [2pt]{double bond sep}% - \CF_valuetomacro[chemfig]\CF_angleincrement [45]{angle increment}% - \CF_valuetomacro[chemfig]\CF_nodestyle []{node style}% - \CF_valuetomacro[chemfig]\CF_bondstyle []{bond style}% - \CF_valuetomacro[chemfig]\CF_stacksep [1.5pt]{stack sep}% - \CF_valuetomacro[chemfig]\CF_cycleradiuscoeff[0.75]{cycle radius coeff}% coeff multiplicateur du rayon des arcs dans les cycles \CF_incyclefalse \CF_cntgroup0 \let\CF_lastaction\CF_zero% 0=début du dessin 1=tracé d'un noeud 2=tracé d'une liaison @@ -1575,47 +1597,49 @@ \def\CF_removehookb#1?[#2]#3\_nil#4{\CF_expsecond{\def#4}{\CF_gobarg#1#3}} -\def\setcharge#{\setKV[charge]} -\def\resetcharge{% - \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 - }% +\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} } -\resetcharge +\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_valuetomacro[charge]\CF_dotradius[0.15ex]{.radius}% - \CF_eexpsecond{\tikz\draw[}{\useKV[charge]{.style}}](0,0)circle(\CF_dotradius);% + \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}% - \CF_valuetomacro[charge]\CF_dotsep [0.5ex] {:sep}% - \CF_valuetomacro[charge]\CF_dotradius[.15ex]{.radius}% \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_eexpsecond{\draw[}{\useKV[charge]{.style}}]% + \CF_expafter{\draw[}{\CF_dotstyle}]% (-\CF_halfsep pt,0)circle(\CF_dotradius)% (\CF_halfsep pt,0)circle(\CF_dotradius);% \endtikzpicture @@ -1625,8 +1649,6 @@ \def\chargerect_a[#1]{% \begingroup \setKV[charge]{#1}% - \CF_valuetomacro[charge]\CF_rectlength[1.5ex]{"length}% - \CF_valuetomacro[charge]\CF_rectwidth [0.3ex]{"width}% \ifboolKV[charge]{lewisautorot} {\pgfmathsetmacro\CF_lewisrot{90+\chargeangle}} {\def\CF_lewisrot{0}}% @@ -1641,11 +1663,10 @@ \def\chargeline_a[#1]{% \begingroup \setKV[charge]{#1}% - \CF_valuetomacro[charge]\CF_linelength[1.5ex]{"length}% \ifboolKV[charge]{lewisautorot} {\pgfmathsetmacro\CF_lewisrot{90+\chargeangle}} {\def\CF_lewisrot{0}}% - \pgfmathsetmacro\CF_halflength{\CF_linelength/2}% + \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 @@ -1730,7 +1751,7 @@ \def\charge_d#1={% \CF_ifx\CF_quark{#1}% {} - {\expandafter\charge_e\expanded{\skv_removelastspaces{#1}}=}% + {\CF_striplastsp{#1}\charge_e}=% } \def\charge_e#1={% \CF_ifinstr{#1}[ @@ -1743,14 +1764,14 @@ {\charge_g#1:0pt[#2]=}% } \def\charge_g#1:#2[#3]=#4,{% #1=angle, #2=offset, #3=code tikz charge, #4=charge - \CF_eexpsecond\CF_ifinteger{\skv_removeextremespaces{#1}} + \CF_stripsp{#1}\CF_ifinteger {\pgfmathsetmacro\chargeangle{mod(#1,360)}% } - {\pgfmathanglebetweenpoints{\pgfpointanchor{atom}{center}}{\pgfpointanchor{atom}{\skv_removeextremespaces{#1}}}% + {\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_distancebetweenpoints{atom}{center}{atom}{\skv_removeextremespaces{#1}}\CF_chargedistance + \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 @@ -1771,13 +1792,6 @@ \def\CF_lewisa[#1]{% \begingroup \CF_doifnotempty{#1}{\setchemfig{#1}}% - \CF_valuetomacro[chemfig]\CF_lewiswidthdouble[0.3ex]{lewis | width}% - \CF_valuetomacro[chemfig]\CF_lewisoffset [0.4ex]{lewis sep}% - \CF_valuetomacro[chemfig]\CF_lewislength [1.5ex]{lewis length}% - \CF_valuetomacro[chemfig]\CF_lewisstyle []{lewis style}% - \CF_valuetomacro[chemfig]\CF_lewisdist [0.3em]{lewis dist}% - \CF_valuetomacro[chemfig]\CF_lewisradius [0.15ex]{lewis radius}% - \CF_valuetomacro[chemfig]\CF_lewisdiagcoeff [1]{lewis diag coeff}% \ifCF_lewisoverlay \CF_addtomacro\CF_lewisstyle{,overlay}% \fi @@ -1990,10 +2004,10 @@ } \def\CF_andb#1{% - \CF_setstyle#1,\CF_quark,\CF_quark\_nil\CF_signspaceante\CF_signspacepost\CF_signvshift - \CF_doifempty\CF_signspaceante{\CF_valuetomacro[chemfig]\CF_signspaceante[0.5em]{+ sep left}}% - \CF_doifempty\CF_signspacepost{\CF_valuetomacro[chemfig]\CF_signspacepost[0.5em]{+ sep right}}% - \CF_doifempty\CF_signvshift{\CF_valuetomacro[chemfig]\CF_signvshift[0pt]{+ vshift}}% + \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}% } @@ -2004,23 +2018,14 @@ } \def\CF_schemestarta[#1]{% - \CF_valuetomacro[chemfig]\CF_defaultcompoundstyle[]{compound style}% - \CF_setstyle#1,\CF_quark,\CF_quark\_nil\CF_arrowangle\CF_arrowlength\CF_arrowstyle - \CF_doifempty\CF_arrowangle{\CF_valuetomacro[chemfig]\CF_arrowangle[0]{arrow angle}}% - \CF_doifempty\CF_arrowlength{\CF_valuetomacro[chemfig]\CF_arrowlength[1]{arrow coeff}}% - \CF_valuetomacro[chemfig]\CF_defaultarrowstyle[]{arrow style}% - \CF_valuetomacro[chemfig]\CF_arrowoffset[1em]{arrow offset}% - \CF_valuetomacro[chemfig]\CF_compoundsep[5em]{compound sep}% - \CF_valuetomacro[chemfig]\CF_arrowlabelsep[3pt]{arrow label sep}% - \CF_valuetomacro[chemfig]\CF_arrowhead[-CF]{arrow head}% + \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_eexpsecond{\CF_preaddtomacro\CF_defaultarrowstyle}{\useKV[chemfig]{arrow head},}% - \CF_ifx\empty\CF_arrowstyle - {\let\CF_arrowstyle\CF_defaultarrowstyle} - {\CF_expsecond{\CF_preaddtomacro\CF_arrowstyle}{\CF_defaultarrowstyle,}}% se rajoute après le style par défaut - \CF_valuetomacro[chemfig]\CF_arrowdoublesep[2pt]{arrow double sep}% + \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}% - \CF_valuetomacro[chemfig]\CF_arrowdoubleposstart[0.6]{arrow double coeff}% \pgfmathsetmacro\CF_arrowdoubleposstart{(1-\CF_arrowdoubleposstart)/2}% \pgfmathsetmacro\CF_arrowdoubleposend{1-\CF_arrowdoubleposstart}% \ifboolKV[chemfig]{scheme debug} @@ -2345,7 +2350,7 @@ {\def\CF_mergefromcoeff{#1}}% \def\CF_mergetocoeff{0.5}% \def\CF_mergesplitcoeff{0.5}% - \CF_eexpsecond{\def\CF_mergestyle}{\useKV[chemfig]{arrow head}}% + \CF_expsecond{\def\CF_mergestyle}{\CF_arrowhead}% \CF_iffirsttokmatch\CF_quark{#2\relax} {} {\CF_ifempty{#2} @@ -2579,38 +2584,31 @@ \fi } -\def\CF_grabdelim#1#2#3\_nil{\def\CF_leftdelim{#1}\def\CF_rightdelim{#2}} -\def\CF_resetdelim{% - \setKVdefault[CFdelimiters]{ - delimiters = (), - height = 10pt, - depth = , - open xshift = 0pt, - close xshift = , - h align = true, - auto rotate = false, - rotate = 0, - indice = n - }% -} - -\CF_resetdelim - +\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{% - \CF_resetdelim + \restoreKV[CFdelimiters]% \CF_doifnotempty{#1}{\setKV[CFdelimiters]{#1}}% - \expandafter\expandafter\expandafter\CF_grabdelim\useKV[CFdelimiters]{delimiters}()\_nil - \edef\CF_delimheight{\the\dimexpr\useKV[CFdelimiters]{height}}% - \CF_eexpsecond\CF_ifempty{\useKV[CFdelimiters]{depth}} - {\let\CF_delimdepth\CF_delimheight} - {\edef\CF_delimdepth{\the\dimexpr\useKV[CFdelimiters]{depth}}}% \edef\CF_delimhalfdim{\the\dimexpr(\CF_delimheight+\CF_delimdepth)/2}% \edef\CF_delimvshift {\the\dimexpr(\CF_delimheight-\CF_delimdepth)/2}% - \edef\CF_leftdelimxshift{\the\dimexpr\useKV[CFdelimiters]{open xshift}}% - \CF_eexpsecond\CF_ifempty{\useKV[CFdelimiters]{close xshift}} - {\edef\CF_rightdelimxshift{\the\dimexpr-\useKV[CFdelimiters]{open xshift}}} - {\edef\CF_rightdelimxshift{\the\dimexpr-\useKV[CFdelimiters]{close xshift}}}% \chemmove{% \nulldelimiterspace0pt \pgfextractx\CF_dim{\pgfpointanchor{#2}{center}}\edef\CF_leftdelimx{\the\CF_dim}% @@ -3072,4 +3070,9 @@ v1.51 2020/04/06 ---------------------------------------------------------------------- v1.52 2020/04/14 - bug : définition corrigée de \CFthesubmol dans \def_submolc pour - qu'elle se développe en 1 coup seulement \ No newline at end of file + qu'elle se développe en 1 coup seulement +---------------------------------------------------------------------- +v1.53 2020/04/27 + - mise à jour en fonction des nouvelles fonctionnalités de + l'extension simplekv + - bug : \CF_ifzerodim interrompt maintenant le tracé dans la \hbox \ No newline at end of file diff --git a/macros/generic/simplekv/README b/macros/generic/simplekv/README index d612d38b6b..1172bd96a6 100644 --- a/macros/generic/simplekv/README +++ b/macros/generic/simplekv/README @@ -3,9 +3,9 @@ ___________________________________ L'extension simplekv - v0.1 + v0.2 - 8 aout 2017 + 27 avril 2020 ___________________________________ Authors : Christian Tellechea diff --git a/macros/generic/simplekv/simplekv-fr.pdf b/macros/generic/simplekv/simplekv-fr.pdf index 797171dd55..950d64baa1 100644 Binary files a/macros/generic/simplekv/simplekv-fr.pdf and b/macros/generic/simplekv/simplekv-fr.pdf differ diff --git a/macros/generic/simplekv/simplekv-fr.tex b/macros/generic/simplekv/simplekv-fr.tex index c899feeb73..e23a0ae078 100644 --- a/macros/generic/simplekv/simplekv-fr.tex +++ b/macros/generic/simplekv/simplekv-fr.tex @@ -22,7 +22,7 @@ \let\do\@makeother \dospecials \ttfamily\small\@noligs \make@car@active\<{\begingroup$\langle$\itshape}% - \make@car@active\>{$\rangle$\endgroup}% + \make@car@active\>{\/$\rangle$\endgroup}% \obeylines\obeyspaces \def\code@ii##1#1{##1\par\medbreak\endgroup}% \code@ii @@ -126,25 +126,23 @@ \endgroup \vskip2cm \leftskip=.2\linewidth \rightskip=.2\linewidth \small - Cette petite extension est une implémentation d'un système dit à «clé/valeurs» pour \TeX{} ou \LaTeX. Aucune fioriture inutile n'a été codée, elle comporte juste l'essentiel. + Cette petite extension est une implémentation d'un système dit à «\/\» pour \TeX{} ou \LaTeX. Elle comporte juste l'essentiel, aucune fioriture inutile n'a été codée et aucune extension tierce n'est nécessaire à son fonctionnement. \end{titlepage} \section{Clés, valeurs} -Lorsqu'une macro doit recevoir des paramètres dont le nombre n'est pas fixe ou connu, il est commode de procéder par \ et \. Beaucoup d'extensions allant en ce sens existent déjà. - -Le but de celle-ci n'est pas de grossir le nombre déjà trop grand de ces extensions, c'est simplement un morceau de l'extension \texttt{hlist} qui a été converti en extension car ce système \/\ est également utilisé par l'extension \texttt{scratch}.\medskip - +Lorsqu'une macro doit recevoir des paramètres dont le nombre n'est pas fixe ou connu, il est commode de procéder par \ et \. +\medskip Voici brièvement les définitions et les limitations des structures mises à disposition : \begin{itemize} - \item une \ est un mot désignant un paramètre; il est formé de préférence avec des caractères de code de catégorie 11 (lettres), 12 (autres caractères sauf la virgule) et 10 (l'espace). On peut cependant y mettre des caractères ayant d'autres codes de catégorie, dans la limitation de ce qui est admis dans la primitive \verb|\detokenize|; + \item une \ est un mot désignant un paramètre; il est formé de préférence avec des caractères de code de catégorie 11 (lettres), 12 (autres caractères sauf la virgule et le signe \verb|=|) et 10 (l'espace). On peut cependant y mettre des caractères ayant d'autres codes de catégorie, dans la limitation de ce qui est admis dans la primitive \verb|\detokenize|; une \, même si cela revêt peu de signification, peut être vide; \item la syntaxe pour assigner une \ à une \ est : \hbox{\=\}; \item les espaces qui précèdent et qui suivent la \ et la \ sont ignorés, mais \emph{pas ceux} qui se trouvent à l'intérieur de la \ ou de la \; \item une \ est un \ arbitraire; \item si une \ est entourée d'accolades, ces dernières seront retirées : \verb|=| est donc équivalent à \verb|={}|; + \item lorsqu'une valeur est entourée de \emph{plusieurs} imbrications d'accolades, seul le niveau externe est retiré et donc \verb|={{}}| est compris comme \verb|={}|; \item lorsque plusieurs couples de \/\ doivent être spécifiés, ils sont séparés les uns des autres par des virgules; \item une virgule ne peut figurer dans une \ que si la virgule est dans un niveau d'accolades; par exemple, \verb|foo=1,5| n'est pas valide car la \ s'étend jusqu'au 1. Il faudrait écrire \verb|foo={1,5}| pour spécifier une valeur de \verb|1,5|; - \item lorsqu'une valeur est entourée de \emph{plusieurs} d'accolades, seul le niveau externe est retiré; \item les \ sont stockées \emph{telles qu'elles sont lues} ; en particulier, aucun développement n'est effectué; \item les définitions sont \emph{locales} : par conséquent, toute \ définie ou modifiée dans un groupe est restaurée à son état antérieur à la sortie du groupe; \item des \/\ destinées à une même macro ou à un même usage doivent être regroupées dans un ensemble dont on choisit le nom. Un tel ensemble est appelé \. @@ -152,87 +150,154 @@ Voici bri \section{Commandes mises à disposition} -\paragraph{La macro \texttt{\char`\\setKVdefault}} -Cette commande est un préalable à toute utilisation de \ puisqu'elle définit un \ contenant des \ et leurs \ par défaut. +\paragraph{Les macro \texttt{\char`\\setKV} et \texttt{\char`\\setKVdefault}} +Ces commandes définissent des \ et leur assignent des \ dans un \. La seule différence entre les deux macros est que \verb|\setKVdefault|, en plus d'assigner les \ aux \, les sauvegarde en vue d'une restauration ultérieure avec \verb|\restoreKV|. On écrit -\begin{center} \verb|\setKVdefault[]{=,=,...,=}| -\end{center} +\code|\setKV[]{=,=,...,=}| Il faut noter que \begin{itemize} - \item l'argument entre accolades contenant les \ et les \ ne peut pas être vide; + \item l'argument entre accolades contenant les \ et les \ ne devrait pas être vide, sauf à vouloir définir une \ booléenne vide égale à \texttt{true}; + \item lors de la lecture des \/\, la virgule et le signe égal ont leurs catcodes rendus égaux à 12; \item le nom du \, bien qu'entre crochet, est \emph{obligatoire}, mais il peut être vide bien que cela ne soit pas conseillé; - \item si plusieurs \ sont identiques, seule la dernière \ sera prise en compte; - \item les \ peuvent être booléennes, auquel cas, elles \emph{doivent} être «\texttt{true}» ou «\texttt{false}» en caractères de catcode 11; + \item si une même \ figure plusieurs fois, la \ retenue sera celle de la dernière assignation; + \item les \ peuvent être booléennes auquel cas, elles \emph{doivent} être «\texttt{true}» ou «\texttt{false}» en caractères de catcode 11; \item si une \ est omise, elle est comprise comme étant «\texttt{true}». Ainsi, écrire - \code|\setKVdefault[foo]{mon bool}| + \code|\setKV[foo]{mon bool}| est équivalent à - \code|\setKVdefault[foo]{mon bool = true}| - \item il est \emph{déconseillé} d'exécuter plusieurs fois \verb|\setKVdefault| pour le même \. Si cela est indispensable, il convient de redéfinir \emph{toutes} les \ qui figuraient dans les précédents appels de \verb|\setKVdefault|. + \code|\setKV[foo]{mon bool = true}| \end{itemize} -\paragraph{La macro \texttt{\char`\\setKV}} -Cette macro fonctionne selon les mêmes principes et limitations que \verb|\setKVdefault|, sauf qu'elle redéfinit une ou plusieurs \ dont les \ ont précédemment été définies par \verb|\setKVdefault|. - -Si une \ n'a pas été prédéfinie par \verb|\setKVdefault|, une erreur sera émise. - \paragraph{La macro \texttt{\char`\\useKV}} Cette macro purement développable renvoie la \ préalablement associée à une \ dans un \: -\code|\useKV[]{}| + \code|\useKV[]{}| Il faut noter que \begin{itemize} - \item si la \ n'a pas été prédéfinie par \verb|\setKVdefault|, une erreur sera émise; + \item si la \ n'a pas été définie, une erreur sera émise; \item si la \ est booléenne, le texte «\texttt{true}» ou «\texttt{false}» sera renvoyé; \item il faut 2 développements à \verb|\useKV[]{}| pour donner la \ associée à la \. \end{itemize} -\exemple|\setKVdefault[foo]{nombre = 5 , lettres= AB \textit{CD} , mon bool} -a) \useKV[foo]{nombre}.\qquad b) \useKV[foo]{lettres}.\qquad c) \useKV[foo]{mon bool}.\par +\exemple|\setKV[foo]{nombre = 5 , lettres= AB \textit{CD} , mon bool} +a) \useKV[foo]{nombre}.\qquad b) \useKV[foo]{lettres}.\qquad c) \useKV[foo]{mon bool}. + \setKV[foo]{lettres = X Y Z \textbf{123} } a) \useKV[foo]{nombre}.\qquad b) \useKV[foo]{lettres}.\qquad c) \useKV[foo]{mon bool}.| -\paragraph{La macro \texttt{\char`\\useKVdefault}} -L'exécution de cette macro par \verb|\useKVdefault[]| réinitialise toutes les \ du \ aux \ qui ont été définies lors de l'exécution \verb|\setKVdefault|. +\paragraph{La macro \texttt{\char`\\restoreKV}} +La macro \verb|\restoreKV[]| réinitialise toutes les \ du \ aux \ qui ont été définies lors de l'exécution \verb|\setKVdefault|. La macro \verb|\useKVdefault[]| lui est équivalente. \paragraph{La macro \texttt{\char`\\ifboolKV}} Cette macro permet, selon la valeur d'une \, d'exécuter un des deux \ donnés. La syntaxe est -\code|\ifboolKV[]{}{}{}| + \code|\ifboolKV[]{}{}{}| La macro est purement développable, elle nécessite 2 développements pour donner l'un des deux codes, et exige que la \ soit booléenne sans quoi un message d'erreur est émis. \paragraph{La macro \texttt{\char`\\showKV}} Cette commande écrit dans le fichier \texttt{log} la \ assignée à une \ d'un \: -\code|\showKV[]{}| + \code|\showKV[]{}| Si la \ n'est pas définie, «\texttt{not defined}» est affiché dans le fichier log. +\section{Code} +En plus d'une \, un \ arbitraire peut être assigné à n'importe quelle \. Pour ce faire, on écrit +\begin{center} \verb|\defKV[]{=,=,...,=}| +\end{center} +Chaque \ peut contenir \verb|#1| qui représente la \ de la \. Ce \ est exécuté lorsque une \ est assignée à la \ avec \verb|\setKV|, \verb|\setKVdefault| ou \verb|\restoreKV|. +\bigbreak + +Ainsi déclarer + \code|\defKV[x]{ mykey = \def\foo{\textbf{#1}}| +va définir une macro \verb|\foo| dès que la \ «\texttt{mykey}» va être définie (ou redéfinie) et donc, si l'on écrit + \code|\setKV[x]{ mykey = bonjour }| +le code qui est exécuté en coulisses est + \code|\long\def\foo{\textbf{bonjour}}| + +\exemple|\defKV[x]{ mykey = \def\foo{\textbf{#1}} } +\setKV[x]{ mykey = bonjour }% définition +1) \meaning\foo\par +2) \useKV[x]{ mykey } + +\setKV[x]{ mykey = hello }% redéfinition +3) \meaning\foo\par +4) \useKV[x]{ mykey }| + +La macro \verb|\testboolKV| permet de tester, par exemple dans un \, si son argument est «true» ou «false» + \code|\testboolKV{}{}{}| + +La macro est purement développable, elle nécessite 2 développements pour donner l'un des deux codes, et exige que l'\ soit booléen sans quoi un message d'erreur est émis. + +\exemple|\defKV[x]{ x = \def\test{\testboolKV{#1}{test positif}{test négatif}}} +\setKV[x]{ x = true} +1) \test + +\setKV[x]{ x= false} +2) \test| +Toute autre valeur que «\verb|true|» ou «\verb|false|» génèrera un message d'erreur. + \section{Un exemple d'utilisation} -Voici comment on pourrait programmer une macro qui affiche un cadre sur une ligne. Pour cela les \ suivantes seront utilisées: +Voici comment on pourrait programmer une macro qui affiche un cadre sur une ligne, grâce à la macro \verb|\fbox| et l'environnement \verb|center| de \LaTeX. Pour cela les \ suivantes seront utilisées: \begin{itemize} \item le booléen \texttt{inline} qui affichera le cadre dans le texte s'il est vrai et sur une ligne dédié s'il est faux; - \item \texttt{left code} et \texttt{right code} qui sont deux codes exécutés avant et après le cadre si le booléen est faux (par défaut : \verb|\hfill| et \verb|\hfill| pour un centrage sur la ligne); \item \texttt{sep} qui est une dimension mesurant la distance entre le texte et le cadre (par défaut \texttt{3pt}); - \item \texttt{width} qui est la largeur des traits du cadre (par défaut \texttt{0.5pt}). + \item \texttt{width} qui est la largeur des traits du cadre (par défaut \texttt{0.5pt}); + \item \texttt{style} qui contient le code exécuté avant le texte. \end{itemize} -\exemple|\setKVdefault[frame]{inline , left code = \hfill, right code = \hfill, sep = 3pt, width=0.5pt } +Une première façon de faire, sans recours à \verb|\defKV|; +\exemple|\setKVdefault[frame]{ + sep = 3pt, + line width = 0.5pt, + style = \bfseries, + inline + } +\newcommand\frametxt[2][]{% + \restoreKV[frame]% revenir au valeurs par défaut + \setKV[frame]{#1}% lit les arguments optionnels + \fboxsep = \useKV[frame]{sep} + \fboxrule= \useKV[frame]{line width} + \ifboolKV[frame]{inline} + {} + {\begin{center}}% + \fbox{\useKV[frame]{style}#2}% + \ifboolKV[frame]{inline} + {} + {\end{center}}% +} +Un essai en ligne par défaut \frametxt{essai} puis un autre \frametxt[sep=5pt,line width=2pt]{essai} +et un dernier \frametxt[sep=1pt,style=\itshape]{essai}. + +Un essai hors ligne : \frametxt[inline = false, style=\bfseries\color{red}]{essai centré}| + +Dans l'exemple repris ci-dessous et grâce à \verb|\defKV|, on stocke tous les paramètres lors de leur assignation. Il y a bien moins de verbosité dans le code de \verb|frametxt| ce qui le rend plus léger et plus lisible. + +\exemple|\defKV[frame]{% + sep = {\fboxsep = #1 }, + line width = {\fboxrule= #1 }, + inline = \testboolKV{#1} + {\def\hookpre{}\def\hookpost{}} + {\def\hookpre{\begin{center}}\def\hookpost{\end{center}}}, + style = \def\fstyle{#1} +} +\setKVdefault[frame]{ + sep = 3pt, + line width = 0.5pt, + style = \bfseries, + inline + } \newcommand\frametxt[2][]{% + \restoreKV[frame]% revenir au valeurs par défaut \setKV[frame]{#1}% lit les arguments optionnels - \ifboolKV[frame]{inline}{}{\par\noindent\useKV[frame]{left code}}% - \fboxsep=\useKV[frame]{sep}\relax - \fboxrule=\useKV[frame]{width}\relax - \fbox{#2}% - \ifboolKV[frame]{inline}{}{\useKV[frame]{right code}\null\par}% + \hookpre + \fbox{\fstyle #2}% + \hookpost } -Un essai en ligne par défaut \frametxt{essai} puis un autre \frametxt[sep=5pt,width=2pt]{essai} -et un dernier \frametxt[sep=0.5pt]{essai}. +Un essai en ligne par défaut \frametxt{essai} puis un autre \frametxt[sep=5pt,line width=2pt]{essai} +et un dernier \frametxt[sep=1pt,style=\itshape]{essai}. -\useKVdefault[frame]% revenir au valeurs par défaut -Un essai centré \frametxt[inline = false]{essai centré} -un autre fer à gauche \frametxt[left code={}]{essai à gauche} -un dernier indenté \frametxt[left code=\hskip 5em, right code={}, sep=1pt, width=2pt]{essai indenté}| +Un essai hors ligne : \frametxt[inline = false, style=\bfseries\color{red}]{essai centré}| \section{Le code} @@ -240,7 +305,7 @@ Le code ci-dessous est l'exact verbatim du fichier \verb|simplekv.tex| : \lstinputlisting[ language=TeX, - moretexcs={unless,ifcsname,ifdefined,detokenize,numexpr,dimexpr,glueexpr,unexpanded}, + moretexcs={unless,ifcsname,ifdefined,detokenize,numexpr,dimexpr,glueexpr,unexpanded,expanded}, basicstyle=\small\ttfamily\color{black!25}, identifierstyle=\bfseries\color{white},% backgroundcolor=\color{black!85}, @@ -264,7 +329,7 @@ Le code ci-dessous est l'exact verbatim du fichier \verb|simplekv.tex| : numbersep=1em, classoffset=1, alsoletter={\_}, - morekeywords={setKVdefault,setKV,useKVdefault,useKV,ifboolKV,}, + morekeywords={setKVdefault,setKV,useKVdefault,useKV,ifboolKV,defKV,testboolKV,showKV}, keywordstyle=\bfseries\color{red!85!black}, classoffset=0, ]{simplekv.tex} diff --git a/macros/generic/simplekv/simplekv.sty b/macros/generic/simplekv/simplekv.sty index 979276c0a6..957f9ea0b4 100644 --- a/macros/generic/simplekv/simplekv.sty +++ b/macros/generic/simplekv/simplekv.sty @@ -1,4 +1,5 @@ % !TeX encoding = ISO-8859-1 +\def\skvfromSTY{} \input simplekv.tex \ProvidesPackage{simplekv}[\skvdate\space v\skvver\space Simple keyval package (CT)] \endinput \ No newline at end of file diff --git a/macros/generic/simplekv/simplekv.tex b/macros/generic/simplekv/simplekv.tex index d4ca63d9eb..b1e2d3b59b 100644 --- a/macros/generic/simplekv/simplekv.tex +++ b/macros/generic/simplekv/simplekv.tex @@ -7,9 +7,9 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % \def\skvname {simplekv} % -\def\skvver {0.1} % +\def\skvver {0.2} % % % -\def\skvdate {2017/08/08} % +\def\skvdate {2020/04/27} % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % @@ -27,11 +27,10 @@ % This work has the LPPL maintenance status `maintained'. % % The Current Maintainer of this work is Christian Tellechea -% Copyright : Christian Tellechea 2017 % email: unbonpetit@netc.fr % Commentaires, suggestions et signalement de bugs bienvenus ! % Comments, bug reports and suggestions are welcome. -% Copyright: Christian Tellechea 2017 +% Copyright: Christian Tellechea 2017-2020 % -------------------------------------------------------------------- % L'extension simplekv est composée des 5 fichiers suivants : % - code : simplekv (.tex et .sty) @@ -39,284 +38,157 @@ % - fichier lisezmoi : README % -------------------------------------------------------------------- -\expandafter\edef\csname skv_restorecatcode\endcsname{\catcode`\noexpand\_=\the\catcode`\_\relax} +%########################################## +%################ Préalable ############### +%########################################## +\csname skvloadonce\endcsname +\let\skvloadonce\endinput +\ifdefined\skvfromSTY\else + \immediate\write -1 {% + Package: \skvname\space\skvdate\space v\skvver\space Simple keyval package (CT)% + }% +\fi +%########################################## +%############ Gestion catcodes ############ +%########################################## +\begingroup + \def\X#1{\catcode\number`#1=\number\catcode`#1\relax} + \expandafter\xdef\csname skv_restorecatcode\endcsname{\X\,\X\=\X\_} +\endgroup \catcode`\_11 - -%################################################ -%################################################ -% Cette macro est équivalente à 0 et sert notamment à stopper le développement -% de \romannumeral +\chardef\skv_other12 +\catcode`\,\skv_other\catcode`\=\skv_other +%########################################## +%############ Macros auxilaires ########### +%########################################## \chardef\skv_stop 0 - -% Définition du quark, notamment inséré à la fin d'une liste pour en reconnaitre -% la fin et stopper la récursivité -\def\skv_quark{\skv_quark} - -% Voici les macros habituelles de sélection d'arguments \long\def\skv_first#1#2{#1} \long\def\skv_second#1#2{#2} - -% Voici la macro pour 1-développer ou 2-développer le 2e argument (le 1er étant -% dépouillé des accolades) -% \skv_exparg{}{} devient {} -% \skv_eearg{}{} devient {**} -\long\def\skv_exparg#1#2{\expandafter\skv_exparg_i\expandafter{#2}{#1}}% -\long\def\skv_eearg#1#2{\expandafter\expandafter\expandafter\skv_exparg_i\expandafter\expandafter\expandafter{#2}{#1}}% -\long\def\skv_exparg_i#1#2{#2{#1}} - -% Et la macro pour 1-développer le 2e argument (le 1er et le 2e argument sont -% dépouillés des accolades)% -% \skv_expafter{}{} devient <*b> -\long\def\skv_expafter#1#2{\expandafter\skv_expafter_i\expandafter{#2}{#1}} +\long\def\skv_gob#1{} +\long\def\skv_exe#1{#1} +\expandafter\def\expandafter\skv_gobspace\space{}% pour garder la compatibilité +\long\def\skv_earg#1#2{\expandafter\skv_earg_i\expandafter{#2}{#1}}\let\skv_exparg\skv_earg +\long\def\skv_eearg#1#2{\expandafter\expandafter\expandafter\skv_earg_i\expandafter\expandafter\expandafter{#2}{#1}} +\long\def\skv_earg_i#1#2{#2{#1}} +\long\def\skv_expafter#1#2{\expandafter\skv_expafter_i\expandafter{#2}{#1}}% {}{} devient <*b> \long\def\skv_expafter_i#1#2{#2#1} - -% Enfin, la macro pour former le nom du 2e argument (le 1er est dépouillé des -% accolades) -% \skv_argcsname{}{} devient \ -\def\skv_argcsname#1#{\skv_argcsname_i{#1}} -\def\skv_argcsname_i#1#2{\skv_expafter{#1}{\csname#2\endcsname}} - -\def\skv_eaddtomacro#1#2{\skv_exparg{\skv_exparg{\def#1}}{\expandafter#1#2}} - -%################################################ -%################ macros de test ################ -%################################################ -% Voici quelques macros à sélection d'arguments pour les tests \def\skv_ifcsname#1{\ifcsname#1\endcsname\expandafter\skv_first\else\expandafter\skv_second\fi} \long\def\skv_ifx#1{\ifx#1\expandafter\skv_first\else\expandafter\skv_second\fi} -\long\def\skv_ifempty#1{\skv_exparg\skv_ifx{\expandafter\relax\detokenize{#1}\relax}} - -% Ces macros sont utiles pour \skv_removeextremespaces, qui retire les -% espaces extrêmes de son argument -% Voir codes 320-324 (http://progtex.fr/wp-content/uploads/2014/09/code.txt) -% et pages 339-343 de "Apprendre à programmer en TeX" -\long\def\skv_ifspacefirst#1{\expandafter\skv_ifspacefirst_i\detokenize{#10} \_nil} -\long\def\skv_ifspacefirst_i#1 #2\_nil{\skv_ifempty{#1}} -\expandafter\def\expandafter\skv_gobspace\space{} -\def\skv_removefirstspaces{\romannumeral\skv_removefirstspaces_i} -\long\def\skv_removefirstspaces_i#1{\skv_ifspacefirst{#1}{\expandafter\skv_removefirstspaces_i\expandafter{\skv_gobspace#1}}{\skv_stop#1}} -\begingroup - \catcode0 12 - \long\gdef\skv_removelastspaces#1{\romannumeral\skv_removelastspaces_i#1^^00 ^^00\_nil} - \long\gdef\skv_removelastspaces_i#1 ^^00{\skv_removelastspaces_ii#1^^00} - \long\gdef\skv_removelastspaces_ii#1^^00#2\_nil{\skv_ifspacefirst{#2}{\skv_removelastspaces_i#1^^00 ^^00\_nil}{\skv_stop#1}} -\endgroup -\long\def\skv_removeextremespaces#1{% - \romannumeral\expandafter\expandafter\expandafter\skv_removelastspaces\expandafter\expandafter\expandafter - {\expandafter\expandafter\expandafter\skv_stop\skv_removefirstspaces{#1}}% +\long\def\skv_ifempty#1{\skv_ifempty_i#1\_nil\_nil\skv_second\skv_first\__nil}% +\long\def\skv_ifempty_i#1#2\_nil#3#4#5\__nil{#4} +\def\skv_stripsp#1{% +\long\def\skv_stripsp##1##2{\expanded{\skv_stripsp_i\_marksp##2\__nil\_marksp#1\_marksp\_nil{##1}}}% +\long\def\skv_stripsp_i##1\_marksp#1##2\_marksp##3\_nil{\skv_stripsp_ii##3##1##2\__nil#1\__nil\_nil}% +\long\def\skv_stripsp_ii##1#1\__nil##2\_nil{\skv_stripsp_iii##1##2\_nil}% +\long\def\skv_stripsp_iii##1##2\__nil##3\_nil##4{\unexpanded{##4{##2}}}% +}\skv_stripsp{ } +%########################################## +%########## Macros de définition ########## +%########################################## +\def\setKVdefault{\let\skv_find_kv_i\skv_find_kv_nocode\skv_readKV\skv_exe} +\def\setKV {\let\skv_find_kv_i\skv_find_kv_nocode\skv_readKV\skv_gob} +\def\defKV {\let\skv_find_kv_i\skv_find_kv_code \skv_readKV\skv_gob} +\def\skv_readKV{% + \edef\skv_restorecatcode{\catcode44=\the\catcode44 \relax\catcode61=\the\catcode61 \relax}% + \catcode44\skv_other\catcode61\skv_other + \skv_readKV_i } - -%################################################ -%############## système clé/valeur ############## -%################################################ -% Ceci est le booléen indiquant si la lecture de = définit les -% _par défaut_ ou qu'il s'agit d'une _redéfinition_ des déjà -% existantes -\newif\ifskv_default - -% macros chapeau appelant la même macro avec le booléen préalablement défini -\def\setKVdefault{\skv_defaulttrue\skv_readKV} -\def\setKV{\skv_defaultfalse\skv_readKV} - -% L'argument obligatoire #1 est le nom du et #2 est l'ensemble -% des = -\def\skv_readKV[#1]#2{% - \skv_ifempty{#2} -% Si aucune = alors qu'on définit les par défaut, -% message d'erreur et on s'arrête là - {\ifskv_default\errmessage{No key/val found, no default key/val defined}\fi} -% Sinon, initialiser à la macro \skv_[] uniquement si on -% créé les par défaut - {\ifskv_default\skv_argcsname\let{skv_[#1]}\empty\fi -% Puis on passe aux choses sérieuses, on va lire un par un tous les éléments -% = (contenus dans #2) en mettant le quark comme dernier couple -% pour montrer la fin de la liste - \skv_readKV_i[#1]#2,\skv_quark,% - }% +\long\def\skv_readKV_i#1[#2]#3{% + #1{\expandafter\def\csname skv_[#2]\endcsname{#3}}% exécute (si \defKV) ou pas + \def\skv_setname{#2}% + \skv_readKV_ii#3,\__,% + \skv_restorecatcode } +\long\def\skv_readKV_ii#1,{\skv_readKV_iii\skv_find_kv#1=true=\_nil\skv_find_kv\__\__nil}% si #1=\__ ne rien faire sinon \skv_find_kv#1=true=\_nil +\long\def\skv_readKV_iii#1\skv_find_kv\__#2\__nil{#1} -\def\skv_readKV_i[#1]#2,{% -% #2 est le premier couple "=" de la liste qui reste à traiter : -% tout d'abord, on se débarrasse des espaces extrêmes - \skv_eearg{\def\__temp}{\skv_removeextremespaces{#2}}% -% Si ce qui en résulte est égal au , - \skv_ifx{\__temp\skv_quark} -% alors, on a fini et on ne fait rien (fin du processus) - {} -% Sinon, si ce qui en résulte est vide (le couple "=" était donc -% vide ou composé d'un espace) - {\skv_ifx{\__temp\empty} -% On a fini et on ne fait rien (fin du processus) - {} -% dans le cas contraire, on va isoler la et la du couple lu en -% prenant soin de mettre à la fin "=" pour se prémunir du cas où -% "=" ne contient que la "" et pas de signe "=", ce qui -% ferait planter la macro à arguments délimités - {\expandafter\skv_find_kv\__temp=\skv_quark\_nil[#1]% - }% -% Lorsque la et la est trouvée et stockée, recommencer et aller -% lire le prochain couple "=" - \skv_readKV_i[#1]% - }% +\long\def\skv_find_kv#1=#2=#3\_nil{% + \edef\__key{_[\skv_setname]_\skv_stripsp\detokenize{#1}}% + \skv_stripsp\skv_find_kv_i{#2}% + \skv_readKV_ii } - -% Voici la macro à arguments délimités à qui on a transmis -% == (si = est l'élément lu) -% ou -% = (si est seule) -% et qui va isoler la de la . -\def\skv_find_kv#1=#2\_nil[#3]{% -% #1 est ce qui se trouve avant le _premier_ signe "=" et -% #2 est ce qui se trouve entre le premier signe "=" et le \_nil -% Pour la , pas de problème, c'est _obligatoirement_ ce qui est avant le -% signe "=", que ce signe soit présent dans le couple lu ou pas puisqu'on y a -% rajouté "=". -% On élimine les espaces extrêmes pour obtenir la définitive stockée dans -% \__key (il faut 2-développer \skv_removeextremespaces pour qu'elle donne son -% argument sans espace extrême) - \edef\__key{\detokenize\expandafter\expandafter\expandafter{\skv_removeextremespaces{#1}}}% -% Pour la , on lui ôte d'abord les espaces extrêmes - \skv_eearg{\def\__val}{\skv_removeextremespaces{#2}}% - \skv_ifx{\__val\skv_quark} -% Si elle est égale au , alors la vaut "true" - {\def\__val{true}}% -% Sinon, ôter "=" de la fin de l'argument #2, éliminer les espaces -% extrêmes de ce qui en résulte et stocker le tout dans \__val (tout ceci est -% effectué par la macro \skv_find_val =) - {\skv_find_val#2}% -% Si on lit les = par défaut, - \ifskv_default -% assigner à la macro "\skv_[]_" la trouvée - \skv_argcsname\let{skv_[#3]_\detokenize\expandafter{\__key}}\__val -% Puis ajouter à la macro "\skv_[]", qui a été préalablement -% initialisée à : -% \def\skv_[]_{} - \skv_argcsname\skv_eaddtomacro{skv_[#3]}% - {\expandafter\def\csname skv_[#3]_\detokenize\expandafter{\__key}\expandafter\endcsname\expandafter{\__val}}% -% C'est selon ce hashage que sont enregistrés les couples / : les -% sont contenues dans les noms des macros tandis que les sont -% les textes de remplacement de ces macros. -% C'est rapide et simple : -% a) pour trouver une d'après sa , il suffit de développer la -% macro \skv_[]_ -% b) pour redéfinir une , il suffit de redéfinir cette macro avec la -% nouvelle -% c) il est facile de vérifier qu'une existe en vérifiant que la macro -% associée est définie, la primitive \ifcsname le fait très bien -% d) en revanche, on ne peut pas faire de recherche _inverse_ de façon -% pratique : il est en effet plus difficile de trouver la (ou les) -% contenant une donnée, mais cette limitation n'a pas grande -% importance ici (je ne sais pas si les autres systèmes de / -% sont programmés de telle sorte que cela soit simple...) -% Bref, la macro "\skv_[]" contient donc _toutes_ les définitions -% des macros définissant les / _par défaut_ et exécuter -% "\skv_[]" remet donc toutes les à leur par défaut. - \else -% Dans le cas où on _lit_ des nouvelles pour des - \skv_ifcsname{skv_[#3]_\__key} -% Si la existe (ssi la macro "\skv_[]_" est définie), -% alors assigner la à cette macro - {\skv_argcsname\let{skv_[#3]_\__key}\__val}% -% Sinon, émettre un message d'erreur et ne rien faire de plus - {\errmessage{Key "\__key" is not defined: nothing is modified}}% +\long\def\skv_find_kv_nocode#1{% + \expandafter\def\csname skv\__key\endcsname{#1}%\__val% stocker la clé + \ifcsname skvcode\__key\endcsname% si le code correspondant existe + \csname skvcode\__key\endcsname{#1}% exécute le code \fi } +\long\def\skv_find_kv_code#1{% + \expandafter\def\csname skvcode\__key\endcsname##1{#1}% +} -% Cette macro à qui on a transmis "=" ne garde que , en -% ôte les espaces extrêmes et stocke le résultat dans \__val -\def\skv_find_val#1=\skv_quark{\skv_eearg{\def\__val}{\skv_removeextremespaces{#1}}} - -% Cette macro remet toutes les à leur par défaut en exécutant -% la macro "\skv_[]" -\def\useKVdefault[#1]{% +\def\restoreKV[#1]{% \skv_ifcsname{skv_[#1]} - {\csname skv_[#1]\endcsname} -% Si la macro "\skv_[]" n'existe pas, message d'erreur - {\errmessage{Undefined set of keys "#1"}}% + {\skv_eearg{\setKV[#1]}{\csname skv_[#1]\endcsname}} + {\errmessage{Undefined or not saved set of keys "#1"}}% } - -% Cette macro donne la correspondant à la contenue dans #2 -\def\useKV[#1]#2{% -% Avec \romannumeral, la sera obtenue après _2_ développements de -% \useKV[]{} - \romannumeral\skv_ifempty{#2} -% Si la est vide, message d'erreur (il ne peut y avoir de -% associée à une vide) - {\skv_stop\errmessage{Key name missing}} - {\skv_ifcsname{skv_[#1]_\skv_removeextremespaces{#2}} -% Si la macro "\skv_[]_" existe, 2-développer le \csname pour -% avoir la - {\expandafter\expandafter\expandafter\skv_stop\csname skv_[#1]_\skv_removeextremespaces{#2}\endcsname} -% Sinon, message d'erreur - {\skv_stop\errmessage{Key "\skv_removeextremespaces{#2}" not defined}}% - }% +\let\useKVdefault\restoreKV +%########################################## +%############## Macro \useKV ############## +%########################################## +\def\useKV[#1]#2{\expanded{\skv_stripsp{\useKV_i[#1]}{#2}}} +\def\useKV_i[#1]#2{\expandafter\useKV_ii\csname skv_[#1]_#2\endcsname{#2}} +\def\useKV_ii#1#2{% + \ifdefined#1\unexpanded\expandafter{#1}% + \else \errmessage{Key "#2" not defined}% + \fi } - -% Voici une macro purement développable qui teste si #2 (la du -% #1) est égale à "true" ou à "false" et selon l'issue, exécute le 1er ou 2e -% argument qui suit (arguments appelés et ) -\def\ifboolKV[#1]#2{% -% Cette macro donnera un des 2 arguments ou en _2_ développements -% grâce au \romannumeral - \romannumeral\skv_ifempty{#2} -% Si la est vide, message d'erreur - {\skv_stop\errmessage{Key name missing}\skv_second} - {\skv_ifcsname{skv_[#1]_\skv_removeextremespaces{#2}} -% Si la débarrassée de ses espaces extrêmes existe, tester son contenu - {\skv_eearg\ifboolKV_i{\csname skv_[#1]_\skv_removeextremespaces{#2}\endcsname}} -% Sinon, message d'erreur - {\skv_stop\errmessage{Key "\skv_removeextremespaces{#2}" not defined}\skv_second}% +%########################################## +%############# Macros de test ############# +%########################################## +\def\ifboolKV[#1]#2{\romannumeral\skv_stripsp{\ifboolKV_i[#1]}{#2}} +\def\ifboolKV_i[#1]#2{% + \skv_ifempty{#2} + {\skv_stop\errmessage{Empty argument is not a valid boolean}\skv_second + } + {\skv_ifcsname{skv_[#1]_#2} + {\skv_eearg\ifboolKV_ii{\csname skv_[#1]_#2\endcsname}} + {\skv_stop\errmessage{Key "#2" not defined}\skv_second}% }% } - -% Cette macro teste si #1, qui est une , vaut "true" ou "false" -\def\ifboolKV_i#1{% -% Tester d'abord si elle vaut "true" +\def\ifboolKV_ii#1{%% Cette macro teste si #1, qui est une , vaut "true" ou "false" \skv_ifargtrue{#1} - {\expandafter\skv_stop\skv_first} + {\expandafter\skv_stop\skv_first + } {\skv_ifargfalse{#1} -% Puis si elle vaut "false" {\expandafter\skv_stop\skv_second} -% Si ni l'un ni l'autre, la n'est pas un booléen acceptable {\skv_stop\errmessage{Value "#1" is not a valid boolean}\skv_second}% }% } -% La macro \skv_ifargtrue{} teste de façon purement développable si -% vaut "true" ou "false". -% Pour cela, on transmet à \skv_ifargtrue_i l'argument "true" qui est -% délimité par \_nil +\def\testboolKV#1{\romannumeral\skv_stripsp{\testboolKV_i}{#1}}% macro publique qui teste si #1 est ou , erreur sinon +\def\testboolKV_i#1{% + \skv_ifempty{#1} + {\skv_stop\errmessage{Empty argument is not a valid boolean}\skv_second} + {\skv_stripsp{\ifboolKV_ii}{#1}}% +} + \def\skv_ifargtrue#1{\skv_ifargtrue_i#1true\_nil} -% Dans la macro \skv_ifargtrue_i, l'argument #1 est ce qui se trouve avant -% "true" dans "true" : -% - s'il n'est pas vide, sélectionner l'argument -% - s'il est vide, cela signifie que commence par "true" ; il est -% donc de la forme "true" -% L'argument #2 est ce qui se trouve après "true" dans "truetrue", -% c'est donc "true". -% Pour être sûr que est , on transmet "true" à -% \skv_ifargtrue_ii qui teste si la réunion de ce qui est avant le -% premier "true" et ce qui est après est \def\skv_ifargtrue_i#1true#2\_nil{\skv_ifempty{#1}{\skv_ifargtrue_ii#2\_nil}\skv_second} \def\skv_ifargtrue_ii#1true#2\_nil{\skv_ifempty{#1#2}} - -% On procède de même pour tester "false" \def\skv_ifargfalse#1{\skv_ifargfalse_i#1false\_nil} \def\skv_ifargfalse_i#1false#2\_nil{\skv_ifempty{#1}{\skv_ifargfalse_ii#2\_nil}\skv_second} \def\skv_ifargfalse_ii#1false#2\_nil{\skv_ifempty{#1#2}} - -\def\showKV[#1]#2{% -% Ecrire dans le fichier log "Key []=" - \immediate\write-1 {Key [#1]\skv_removeextremespaces{#2}=% - \skv_ifcsname{skv_[#1]_\skv_removeextremespaces{#2}} -% si la est définie, prendre le \meaning de la macro correspondante - {\expandafter\expandafter\expandafter\skv_show\expandafter - \meaning\csname skv_[#1]_\skv_removeextremespaces{#2}\endcsname} -% Sinon, afficher - {not defined}% - }% +%########################################## +%############# Macro \showKV ############## +%########################################## +\def\showKV[#1]#2{\expanded{\skv_stripsp{\showKV_i[#1]}{#2}}} +\def\showKV_i[#1]#2{% + \immediate\write-1 {% + ^^JKey\space\space[#1]#2=% + \skv_ifcsname{skv_[#1]_#2} + {\expandafter\expandafter\expandafter\skv_show\expandafter + \meaning\csname skv_[#1]_#2\endcsname + \skv_ifcsname{skvcode_[#1]_#2} + {^^JCode [#1]#2=\expandafter\expandafter\expandafter\skv_show\expandafter + \meaning\csname skvcode_[#1]_#2\endcsname + } + {}% + } + {not defined% + }% + ^^J\relax}% } -% Mange ce qui se trouve jusqu'à "->" dans le développement de \meaning \def\skv_show#1->{} \skv_restorecatcode \endinput @@ -327,3 +199,7 @@ Versions : |-----------------------------------------------------------------------------| | 0.1 | 08/08/2017 | Première version | |-----------------------------------------------------------------------------| +| 0.2 | 27/04/2020 | - Un peut être assigné à une | +| | | - Correction de bugs | +| | | - Optimisations | +|-----------------------------------------------------------------------------| \ No newline at end of file -- cgit v1.2.3