9

I have been using chemfig for a while and I like it very much. But some small things I still can't do. Check this example:

\schemestart
\chemname{\chemfig{[2]OH-[4]CH_2-CH(-[0]OH)-CH_2(-[0]OH)}}{Glycerol} 
\hspace{.3cm}
\arrow{-U>[\footnotesize ATP][\footnotesize ADP + H$^{+}$][][0.6][45]}
\hspace{.7cm}
\chemname{\chemfig{[2]O(-[0]\circleatom{P})-[4]CH_2-CH(-[0]OH)-CH_2(-[0]OH)}}{Glycerol 3-phosphate} 
\schemestop

I would like to write the enzyme's name (glycerol kinase) below the U-shaped arrow. Is there an easy way to do that?

2
  • Welcome to TeX.sx! Please add a minimal working example (MWE) that illustrates your problem. In particular, indicate what packages you're using for typesetting the chemical formulas.
    – egreg
    Sep 30, 2012 at 15:50
  • I think a MWE here would be something like \documentclass{article} \usepackage{chemfig} \begin{document} \schemestart A \arrow{-U>[X][Y]} B \schemestop \end{document}, where without the U the Y text would appear under the arrow.
    – Joseph Wright
    Sep 30, 2012 at 16:14

5 Answers 5

13

I'm guessing the \circleatom is a copy of what I used here. I vaguely remembered having defined something like it before.

The middle of an -U> arrow is a node named Uarrow@arctangent. If you have only one such arrow you can use that fact to write something beneath it with \chemmove:

\documentclass{article}
\usepackage{chemfig}
\newcommand*\circleatom[1]{\tikz\node[circle,draw]{\printatom{#1}};}

\begin{document}

\setarrowoffset{1cm}
\schemestart
  \chemname
    {\chemfig{[2]OH-[4]CH_2-CH(-[0]OH)-CH_2(-[0]OH)}}
    {Glycerol} 
  \arrow{-U>[\footnotesize ATP]%
            [\footnotesize ADP + H$^{+}$]%
            []%
            [.25]}[,3]
  \chemname
    {\chemfig{[2]O(-[0]\circleatom{P})-[4]CH_2-CH(-[0]OH)-CH_2(-[0]OH)}}
    {Glycerol 3-phosphate} 
\schemestop
\makeatletter
  \chemmove{\node[below] at (Uarrow@arctangent) {below}; }
\makeatother

\end{document}

enter image description here

If you need that more often you should consider usings chemfig's possibility to add new arrow types. You could for example adapt the definition of the -U> arrow to define a variant that takes a third argument:

\makeatletter
% define an arrow type `-y>' that takes 6 optional arguments
% \arrow{-y>[<label arc start>]%
%           [<label arc end>]%
%           [<label below>]%
%           [<arrow shift>]%
%           [<ratio arc radius/arrow length>]% default: 0.333
%           [<half of angle of arc>]% default: 60
\definearrow{6}{-y>}{%
    % shift the arrow:
    \CF@arrow@shift@nodes{#4}%
    % draw main arrow:
    \expandafter\draw\expandafter[\CF@arrow@current@style,-CF@full]
      (\CF@arrow@start@node)--(\CF@arrow@end@node)node[midway](yarrow@arctangent){};%
    % draw first half of arc if label #1 is given:
    \edef\CF@tmp@str{\ifx\@empty#1\@empty[draw=none]\fi}%
    \expandafter\draw\CF@tmp@str (yarrow@arctangent)%
        arc[
          radius=\CF@compound@sep*\CF@current@arrow@length*\ifx\@empty#5\@empty0.333\else#5\fi,
          start angle=\CF@arrow@current@angle-90,
          delta angle=-\ifx\@empty#6\@empty60\else#6\fi]
        node(yarrow@start){};
    % draw second half of arrow if label #2 is given:
    \edef\CF@tmp@str{[\ifx\@empty#2\@empty draw=none,\fi-CF@full]}%
    \expandafter\draw\CF@tmp@str (yarrow@arctangent)%
        arc[
          radius=\CF@compound@sep*\CF@current@arrow@length*\ifx\@empty#5\@empty0.333\else#5\fi,
          start angle=\CF@arrow@current@angle-90,%
          delta angle=\ifx\@empty#6\@empty60\else#6\fi]
        node(yarrow@end){};
    \edef\CF@tmp@str{\if\string-\expandafter\@car\detokenize{#4.}\@nil-\else+\fi}%
    % place labels #1 and #2:
    \CF@arrow@display@label{#1}{0}\CF@tmp@str{yarrow@start}{#2}{1}\CF@tmp@str{yarrow@end}%
    % place label #3:
    \CF@arrow@display@label{#3}{0.5}-\CF@arrow@start@node{}{}{}\CF@arrow@end@node
}
\makeatother

It can now be used as follows:

\schemestart
 A
 \arrow{-y>[a][b][below]}
 B
\schemestop

enter image description here

It has three further optional arguments which are the same as the ones of -U>.


The complete code:

\documentclass{article}
\usepackage{chemfig}
\newcommand*\circleatom[1]{\tikz\node[circle,draw]{\printatom{#1}};}


\makeatletter
% define an arrow type `-y>' that takes 6 optional arguments
% \arrow{-y>[<label arc start>]%
%           [<label arc end>]%
%           [<label below>]%
%           [<arrow shift>]%
%           [<ratio arc radius/arrow length>]% default: 0.333
%           [<half of angle of arc>]% default: 60
\definearrow{6}{-y>}{%
    % shift the arrow:
    \CF@arrow@shift@nodes{#4}%
    % draw main arrow:
    \expandafter\draw\expandafter[\CF@arrow@current@style,-CF@full]
      (\CF@arrow@start@node)--(\CF@arrow@end@node)node[midway](yarrow@arctangent){};%
    % draw first half of arc if label #1 is given:
    \edef\CF@tmp@str{\ifx\@empty#1\@empty[draw=none]\fi}%
    \expandafter\draw\CF@tmp@str (yarrow@arctangent)%
        arc[
          radius=\CF@compound@sep*\CF@current@arrow@length*\ifx\@empty#5\@empty0.333\else#5\fi,
          start angle=\CF@arrow@current@angle-90,
          delta angle=-\ifx\@empty#6\@empty60\else#6\fi]
        node(yarrow@start){};
    % draw second half of arrow if label #2 is given:
    \edef\CF@tmp@str{[\ifx\@empty#2\@empty draw=none,\fi-CF@full]}%
    \expandafter\draw\CF@tmp@str (yarrow@arctangent)%
        arc[
          radius=\CF@compound@sep*\CF@current@arrow@length*\ifx\@empty#5\@empty0.333\else#5\fi,
          start angle=\CF@arrow@current@angle-90,%
          delta angle=\ifx\@empty#6\@empty60\else#6\fi]
        node(yarrow@end){};
    \edef\CF@tmp@str{\if\string-\expandafter\@car\detokenize{#4.}\@nil-\else+\fi}%
    % place labels #1 and #2:
    \CF@arrow@display@label{#1}{0}\CF@tmp@str{yarrow@start}{#2}{1}\CF@tmp@str{yarrow@end}%
    % place label #3:
    \CF@arrow@display@label{#3}{0.5}-\CF@arrow@start@node{}{}{}\CF@arrow@end@node
}
\makeatother

\begin{document}

\setarrowoffset{1cm}
\schemestart
  \chemname
    {\chemfig{[2]OH-[4]CH_2-CH(-[0]OH)-CH_2(-[0]OH)}}
    {Glycerol} 
  \arrow{-y>[\footnotesize ATP]%
            [\footnotesize ADP + H$^{+}$]%
            [below]%
            []%
            [.25]}[,3]
  \chemname
    {\chemfig{[2]O(-[0]\circleatom{P})-[4]CH_2-CH(-[0]OH)-CH_2(-[0]OH)}}
    {Glycerol 3-phosphate} 
\schemestop

\end{document}
4
  • Hey cgnieder, ideed, I have "borrowed" your \circleatom and I appreciate very much your effort maintaining all these packages. Thank you for the answer!
    – bispo
    Sep 30, 2012 at 22:17
  • 1
    @bispo you're welcome! BTW: I don't maintain chemfig (nor could I). All credits go to Christian Tellechea (@unbonpetit).
    – cgnieder
    Sep 30, 2012 at 22:21
  • @clemens Used your code and got an error message: Package pgf Error: Unknown arrow tip kind 'CF@full'. [.25]}[,3]
    – Sam
    Dec 7, 2016 at 20:37
  • 1
    @Sam replace CF@full with CFchemfig changed its arrow tips some while ago…
    – cgnieder
    Dec 7, 2016 at 20:44
9

Here's an update on @runiq's extension to @clemens' code above (and partially an extension of my answer here), that is compatible with current versions of chemfig (as of 2017, v1.2e), for an all-powerful -X> arrow that can label above, below and midway along the arrow.

looks the same, i know..

The output looks the same, but there has been a few under the hood changes, described below.

But first...

Quick Intro on how to use

The syntax is similar to the original -U> arrow, and (obviously) identical to that of @runiq's -X> arrow.

\arrow{-X>[#1][#2][#3][#4][#5][#6][#7][#8][#9]}

where arguments are:

  • [#1]: Label to be placed at top arrow (start)
  • [#2]: Label to be placed at top arrow (end)
  • [#3]: Label to be placed at top arrow (midway)
  • [#4]: Label to be placed at bottom arrow (start)
  • [#5]: Label to be placed at bottom arrow (end)
  • [#6]: Label to be placed at bottom arrow (midway)
  • [#7]: Y-shift for the arrow, positive for upwards shift, vice versa
  • [#8]: Radius of arc (default 0.333)
  • [#9]: Angle for arc (default 60)

What has changed from @runiq's answer

  • Overall code structure is different. This is based on the -U> definition from the chemfig documentation.
  • The arrow head is given by -CF, no longer -CF@full, as pointed out in the comments.
  • Included CF@arrow@current@style as a style when drawing the arrows. In short, this means the default arrow settings will be passed on to the -X> arrow. Demonstrated below:

modified vs original


Code and result

\makeatletter
% Arguments:
% #1, #2, #3, #4, #5, #6: Labels as shown in the output figure
% #7: yshift for the arrow, positive for upwards shift, vice versa
% #8: radius of arc (default 0.333)
% #9: angle for arc (default 60)
\definearrow9{-X>}{%
    \CF@arrow@shift@nodes{#7}%
    \expandafter\draw\expandafter[\CF@arrow@current@style](\CF@arrow@start@node)--(\CF@arrow@end@node)node[midway](Xarrow@arctangent){};%
    \CF@ifempty{#8}
    {\def\CF@Xarrow@radius{0.333}}
    {\def\CF@Xarrow@radius{#8}}%
    \CF@ifempty{#9}%
    {\def\CF@Xarrow@absangle{60}}
    {\pgfmathsetmacro\CF@Xarrow@absangle{abs(#9)}}
    % Draw top arrow (start)
    \edef\CF@tmp@str{[\CF@ifempty{#1}{draw=none}{\unexpanded\expandafter{\CF@arrow@current@style}},-]}%
    \expandafter\draw\CF@tmp@str (Xarrow@arctangent)%
    arc[radius=\CF@compound@sep*\CF@current@arrow@length*\CF@Xarrow@radius,start angle=\CF@arrow@current@angle-90,delta angle=-\CF@Xarrow@absangle]node(Xarrow1@start){};
    % Draw bottom arrow (end)
    \edef\CF@tmp@str{[\CF@ifempty{#2}{draw=none}{\unexpanded\expandafter{\CF@arrow@current@style}},-CF]}%
    \expandafter\draw\CF@tmp@str (Xarrow@arctangent)%
    arc[radius=\CF@compound@sep*\CF@current@arrow@length*\CF@Xarrow@radius,%
    start angle=\CF@arrow@current@angle-90,%
    delta angle=\CF@Xarrow@absangle]%
    node(Xarrow1@end){};
    % Draw bottom arrow (start)
    \edef\CF@tmp@str{[\CF@ifempty{#4}{draw=none}{\unexpanded\expandafter{\CF@arrow@current@style}},-]}%
    \expandafter\draw\CF@tmp@str (Xarrow@arctangent)%
    arc[radius=\CF@compound@sep*\CF@current@arrow@length*\CF@Xarrow@radius,start angle=\CF@arrow@current@angle+90,delta angle=\CF@Xarrow@absangle]node(Xarrow2@start){};
    % Draw bottom arrow (end)
    \edef\CF@tmp@str{[\CF@ifempty{#5}{draw=none}{\unexpanded\expandafter{\CF@arrow@current@style}},-CF]}%
    \expandafter\draw\CF@tmp@str (Xarrow@arctangent)%
    arc[radius=\CF@compound@sep*\CF@current@arrow@length*\CF@Xarrow@radius,%
    start angle=\CF@arrow@current@angle+90,%
    delta angle=-\CF@Xarrow@absangle]%
    node(Xarrow2@end){};
    % Insert labels
    \pgfmathsetmacro\CF@tmp@stra{\CF@Xarrow@radius*cos(\CF@arrow@current@angle)<0?"-":"+"}%
    \pgfmathsetmacro\CF@tmp@strb{\CF@Xarrow@radius*cos(\CF@arrow@current@angle)<0?"+":"-"}%
    \ifdim\CF@Xarrow@radius pt>\z@
        \CF@arrow@display@label{#1}{0}\CF@tmp@stra{Xarrow1@start}{#2}{1}\CF@tmp@stra{Xarrow1@end}%
        \CF@arrow@display@label{#4}{0}\CF@tmp@strb{Xarrow2@start}{#5}{1}\CF@tmp@strb{Xarrow2@end}%
        \CF@arrow@display@label{#3}{0.5}\CF@tmp@stra\CF@arrow@start@node{}{}{}\CF@arrow@end@node%
        \CF@arrow@display@label{#6}{0.5}\CF@tmp@strb\CF@arrow@start@node{}{}{}\CF@arrow@end@node%
    \else
        \CF@arrow@display@label{#2}{0}\CF@tmp@stra{Xarrow1@start}{#1}{1}\CF@tmp@stra{Xarrow1@end}%
        \CF@arrow@display@label{#5}{0}\CF@tmp@strb{Xarrow2@start}{#4}{1}\CF@tmp@strb{Xarrow2@end}%
        \CF@arrow@display@label{#3}{0.5}\CF@tmp@stra\CF@arrow@start@node{}{}{}\CF@arrow@end@node%
        \CF@arrow@display@label{#6}{0.5}\CF@tmp@strb\CF@arrow@start@node{}{}{}\CF@arrow@end@node%
    \fi
}
\makeatother

With the above code placed in the preamble, the code below produces the following output:

\documentclass{article}
\usepackage{chemfig}
% <paste def. of -X> here>
\begin{document}
    \begin{center}
    \schemestart
    A
    \arrow{-X>[1][2][3][4][5][6][][0.333][60]}
    B
    \arrow{-X>[][2][][4][][][5pt][0.5][70]}% Note the yshift, radius and angle changes
    C
    \schemestop
    \end{center}
\end{document}

final


Bugs?

Unfortunately, setting the radius (argument #8) as negative would flip the two U arrows horizontally (i.e. they point from B to A), but the straight arrow will still point from A to B. As it stands, I don't see a way to fix this, barring a complete re-definition, or a definition of an alternate, reversed -X> arrow.

4
  • What if I need an equilibrium arrow plus curved arrows? Should be easy, but I'm getting nothing.
    – Viridjan
    Sep 2, 2017 at 13:36
  • @Viridjan Hi, please ask a new question and provide a clear description of what you would like there.
    – Troy
    Sep 2, 2017 at 13:38
  • Hey, thanks for updating my hacky arrow thing. That was the first time I've ever written LaTeX code (and it'll probably be the last time, too). :-)
    – runiq
    May 13, 2019 at 16:10
  • 1
    As of V. 1.4 of ChemFig, this solution does not work as the syntax for using internal ChemFig functions was changed. I have made a re-write of this code that you can see here Feb 21, 2020 at 20:27
8

Edit: Please see Troy's answer for an updated version of this command that works with more recent versions of chemfig.


I've recently had to use a similar kind of arrow and decided to expand on @cgnieder's -y> arrow:

\makeatletter
% Initial arguments:
% #1, #2: Same as for -U> (above arrow)
% #3: Additional label at midpoint (also above arrow)
% #4, #5, #6: Like #1, #2, and #3, but below arrow
\definearrow9{-X>}{%
    \CF@arrow@shift@nodes{#7}%
    \expandafter\draw\expandafter[\CF@arrow@current@style,-CF@full](\CF@arrow@start@node)--(\CF@arrow@end@node)node[midway](Xarrow@arctangent){};%
    \edef\CF@tmp@str{\ifx\@empty#1\@empty[draw=none]\fi}%
    \expandafter\draw\CF@tmp@str (Xarrow@arctangent)%
        arc[radius=\CF@compound@sep*\CF@current@arrow@length*\ifx\@empty#8\@empty0.333\else#8\fi,start angle=\CF@arrow@current@angle-90,%
        delta angle=-\ifx\@empty#9\@empty60\else#9\fi]node(Xarrow1@start){};
    \edef\CF@tmp@str{[\ifx\@empty#2\@empty draw=none,\fi-CF@full]}%
    \expandafter\draw\CF@tmp@str (Xarrow@arctangent)%
        arc[radius=\CF@compound@sep*\CF@current@arrow@length*\ifx\@empty#8\@empty0.333\else#8\fi,start angle=\CF@arrow@current@angle-90,%
        delta angle=\ifx\@empty#9\@empty60\else#9\fi]node(Xarrow1@end){};
    \edef\CF@tmp@str{\ifx\@empty#4\@empty[draw=none]\fi}%
    \expandafter\draw\CF@tmp@str (Xarrow@arctangent)%
        arc[radius=\CF@compound@sep*\CF@current@arrow@length*\ifx\@empty#8\@empty0.333\else#8\fi,start angle=\CF@arrow@current@angle+90,%
        delta angle=\ifx\@empty#9\@empty60\else#9\fi]node(Xarrow2@start){};
    \edef\CF@tmp@str{[\ifx\@empty#5\@empty draw=none,\fi-CF@full]}%
    \expandafter\draw\CF@tmp@str (Xarrow@arctangent)%
        arc[radius=\CF@compound@sep*\CF@current@arrow@length*\ifx\@empty#8\@empty0.333\else#8\fi,start angle=\CF@arrow@current@angle+90,%
        delta angle=-\ifx\@empty#9\@empty60\else#9\fi]node(Xarrow2@end){};
    \edef\CF@tmp@str{\if\string-\expandafter\@car\detokenize{#7.}\@nil-\else+\fi}%
    \CF@arrow@display@label{#1}{0}\CF@tmp@str{Xarrow1@start}{#2}{1}\CF@tmp@str{Xarrow1@end}%
    \CF@arrow@display@label{#3}{0.5}\CF@tmp@str\CF@arrow@start@node{}{}{}\CF@arrow@end@node%
    \edef\CF@tmp@str{\if\string-\expandafter\@car\detokenize{#7.}\@nil+\else-\fi}%
    \CF@arrow@display@label{#4}{0}\CF@tmp@str{Xarrow2@start}{#5}{1}\CF@tmp@str{Xarrow2@end}%
    \CF@arrow@display@label{#6}{0.5}\CF@tmp@str\CF@arrow@start@node{}{}{}\CF@arrow@end@node%
}
\makeatother

The -X> arrow has 9 optional arguments. The first three are similar to those for -y>, but all of them are above the arrow. The 4th to 6th are similar but below the arrow. The 7th to 9th are the usual vertical shift, length coefficient, and half-angle as per the -U> and -y> arrows.

The -X> arrow looks like this in action:

\schemestart
A
\arrow{-X>[1][2][3][4][5][6]}
B
\schemestop

enter image description here

7
  • 1
    Your code gives me ! Package pgf Error: No shape named e is known. when one of the optional arguments of the arrow is used.
    – cgnieder
    Jul 28, 2013 at 12:39
  • @cgnieder: How exactly did you invoke the arrow? I've tried it with an MWE and both pdflatex/lualatex, and everything seems to work. MWE: gist.github.com/runiq/6098546
    – runiq
    Jul 28, 2013 at 13:18
  • Just as I said: with the code you provided. I copy-pasted your code, added \begin{document} and \end{document} and copy-pasted the scheme in between.
    – cgnieder
    Jul 28, 2013 at 13:28
  • Ah, sorry, I made an error while copy-pasting. Should be fixed now…
    – runiq
    Jul 28, 2013 at 13:47
  • 2
    @ArchStanton I think the definition changed. Using CF instead of CF@full works for me
    – Troy
    May 31, 2017 at 13:57
5

Version with Equilibrium and Disequalibrium arrows

Inspired by Troy's answer and Jasper Habicht's answer to a similar question. Uses same I/O convention as Troy's answer and as the -U> arrow from the ChemFig Documentation.

Addent arrows in the -X> arrow defintion are customized according to the PGF arrows documentation. See the PGFManual section 16 for more info on how to customize these.

Compatable with ChemFig 1.41

\documentclass[border=1mm,tikz]{standalone}
\usepackage{chemfig}
\usepackage[version=4,arrows=pgf-filled]{mhchem}
\usetikzlibrary{arrows.meta}

\catcode`\_=11
% Initial arguments:
% #1, #2: Same as for -U> (above arrow)
% #3: Additional label at midpoint (also above arrow)
% #4, #5, #6: Like #1, #2, and #3, but below arrow
% #7: Optional shift, default 0
% #8: Optional arrow radius
% #9: Optional arrow angle
\definearrow9{-X>}{%
    % handle optional shift
    \CF_arrowshiftnodes{#7}%
    % handle optional arrow radius
    \CF_ifempty{#8}
        {\def\CF_Xarrowradius{0.333}}
        {\def\CF_Xarrowradius{abs{#8}}}%
    % handle optional arrow angle
    \CF_ifempty{#9}%
        {\def\CF_Xarrowabsangle{60}}
        {\pgfmathsetmacro\CF_Xarrowabsangle{abs(#9)}}
    % draw basic arrow
    \expandafter\draw\expandafter[\CF_arrowcurrentstyle](\CF_arrowstartnode)--(\CF_arrowendnode)node[midway](Xarrowarctangent){};%
    \begingroup
    \pgfarrowharpoontrue
    % Draw top arrow (start)
    \edef\CF_tmpstr{[\CF_ifempty{#1}{draw=none}{\unexpanded\expandafter{\CF_arrowcurrentstyle}},-]}%
    \expandafter\draw\CF_tmpstr (Xarrowarctangent)%
    arc[radius=\CF_compoundsep*\CF_currentarrowlength*\CF_Xarrowradius,start angle=\CF_arrowcurrentangle-90,delta angle=-\CF_Xarrowabsangle]node(Xarrow1start){};
    % Draw bottom arrow (end)
    \edef\CF_tmpstr{[\CF_ifempty{#2}{draw=none}{\unexpanded\expandafter{\CF_arrowcurrentstyle}},-{Stealth[left,round,scale=1.1,inset'=0pt 0.55]}]}%angle'=40
    \expandafter\draw\CF_tmpstr (Xarrowarctangent)%
    arc[radius=\CF_compoundsep*\CF_currentarrowlength*\CF_Xarrowradius,%
    start angle=\CF_arrowcurrentangle-90,%
    delta angle=\CF_Xarrowabsangle]%
    node(Xarrow1end){};
    % Draw bottom arrow (start)
    \edef\CF_tmpstr{[\CF_ifempty{#4}{draw=none}{\unexpanded\expandafter{\CF_arrowcurrentstyle}},-]}%
    \expandafter\draw\CF_tmpstr (Xarrowarctangent)%
    arc[radius=\CF_compoundsep*\CF_currentarrowlength*\CF_Xarrowradius,start angle=\CF_arrowcurrentangle+90,delta angle=\CF_Xarrowabsangle]node(Xarrow2start){};
    % Draw bottom arrow (end)
    \edef\CF_tmpstr{[\CF_ifempty{#5}{draw=none}{\unexpanded\expandafter{\CF_arrowcurrentstyle}},-{Stealth[right,round,scale=1.1,inset'=0pt 0.555]}]}%
    \expandafter\draw\CF_tmpstr (Xarrowarctangent)%
    arc[radius=\CF_compoundsep*\CF_currentarrowlength*\CF_Xarrowradius,%
    start angle=\CF_arrowcurrentangle+90,%
    delta angle=-\CF_Xarrowabsangle]%
    node(Xarrow2end){};
    \endgroup
    % Insert labels
    \pgfmathsetmacro\CF_tmpstra{\CF_Xarrowradius*cos(\CF_arrowcurrentangle)<0?"-":"+"}%
    \pgfmathsetmacro\CF_tmpstrb{\CF_Xarrowradius*cos(\CF_arrowcurrentangle)<0?"+":"-"}%
    \CF_arrowdisplaylabel{#1}{0}\CF_tmpstra{Xarrow1start}{#2}{1}\CF_tmpstra{Xarrow1end}%
    \CF_arrowdisplaylabel{#4}{0}\CF_tmpstrb{Xarrow2start}{#5}{1}\CF_tmpstrb{Xarrow2end}%
    \CF_arrowdisplaylabel{#3}{0.5}\CF_tmpstra\CF_arrowstartnode{}{}{}\CF_arrowendnode%
    \CF_arrowdisplaylabel{#6}{0.5}\CF_tmpstrb\CF_arrowstartnode{}{}{}\CF_arrowendnode%
}


% Initial arguments:
% #1, #2: Same as for -U> (above arrow)
% #3: Additional label at midpoint (also above arrow)
% #4, #5, #6: Like #1, #2, and #3, but below arrow
% #7: Optional shift, default 0
% #8: Optional arrow radius
% #9: Optional arrow angle
\definearrow9{<=X=>}{%
    % handle optional shift
    \CF_arrowshiftnodes{#7}%
    % handle optional arrow radius
    \CF_ifempty{#8}
        {\def\CF_Xarrowradius{0.333}}
        {\def\CF_Xarrowradius{abs{#8}}}%
    % handle optional arrow angle
    \CF_ifempty{#9}%
        {\def\CF_Xarrowabsangle{60}}
        {\pgfmathsetmacro\CF_Xarrowabsangle{abs(#9)}}
    % ensure harpoon style lines
    \begingroup
    \pgfarrowharpoontrue%
    % draw equilibrium lines
    \path[allow upside down](\CF_arrowstartnode)--(\CF_arrowendnode)%
            node[pos=0,yshift= 1pt](\CF_arrowstartnode u0){}%
            node[pos=0,yshift=-1pt](\CF_arrowstartnode d0){}%
            node[pos=1,yshift= 1pt](\CF_arrowstartnode u1){}%
            node[pos=1,yshift=-1pt](\CF_arrowstartnode d1){};%
    \expandafter\draw\expandafter[\CF_arrowcurrentstyle](\CF_arrowstartnode u0)--(\CF_arrowstartnode u1)node[midway](toparrowarctangent){};%
    \expandafter\draw\expandafter[\CF_arrowcurrentstyle](\CF_arrowstartnode d1)--(\CF_arrowstartnode d0)node[midway](bottomarrowarctangent){};%
    % Draw top arrow (start) (left hand side)
    \edef\CF_tmpstr{[\CF_ifempty{#1}{draw=none}{\unexpanded\expandafter{\CF_arrowcurrentstyle}},-]}%
    \expandafter\draw\CF_tmpstr (toparrowarctangent)%
    arc[radius=\CF_compoundsep*\CF_currentarrowlength*\CF_Xarrowradius,start angle=\CF_arrowcurrentangle-90,delta angle=-\CF_Xarrowabsangle]node(Xarrow1start){};
    % Draw top arrow (end) (right hand side)
    \edef\CF_tmpstr{[\CF_ifempty{#2}{draw=none}{\unexpanded\expandafter{\CF_arrowcurrentstyle}},-CF]}%
    \expandafter\draw\CF_tmpstr (toparrowarctangent)%
    arc[radius=\CF_compoundsep*\CF_currentarrowlength*\CF_Xarrowradius,%
    start angle=\CF_arrowcurrentangle-90,%
    delta angle=\CF_Xarrowabsangle]%
    node(Xarrow1end){};
    % Draw bottom arrow (end) (left hand side)
    \edef\CF_tmpstr{[\CF_ifempty{#4}{draw=none}{\unexpanded\expandafter{\CF_arrowcurrentstyle}},-CF]}%
    \expandafter\draw\CF_tmpstr (bottomarrowarctangent)%
    arc[radius=\CF_compoundsep*\CF_currentarrowlength*\CF_Xarrowradius,start angle=\CF_arrowcurrentangle+90,delta angle=\CF_Xarrowabsangle]node(Xarrow2start){};
    % Draw bottom arrow (start) (right hand side)
    \edef\CF_tmpstr{[\CF_ifempty{#5}{draw=none}{\unexpanded\expandafter{\CF_arrowcurrentstyle}},-]}%
    \expandafter\draw\CF_tmpstr (bottomarrowarctangent)%
    arc[radius=\CF_compoundsep*\CF_currentarrowlength*\CF_Xarrowradius,%
    start angle=\CF_arrowcurrentangle+90,%
    delta angle=-\CF_Xarrowabsangle]%
    node(Xarrow2end){};
    % Insert labels
    \pgfmathsetmacro\CF_tmpstra{\CF_Xarrowradius*cos(\CF_arrowcurrentangle)<0?"-":"+"}%
    \pgfmathsetmacro\CF_tmpstrb{\CF_Xarrowradius*cos(\CF_arrowcurrentangle)<0?"+":"-"}%
    \CF_arrowdisplaylabel{#1}{0}\CF_tmpstra{Xarrow1start}{#2}{1}\CF_tmpstra{Xarrow1end}%
    \CF_arrowdisplaylabel{#4}{0}\CF_tmpstrb{Xarrow2start}{#5}{1}\CF_tmpstrb{Xarrow2end}%
    \CF_arrowdisplaylabel{#3}{0.5}\CF_tmpstra\CF_arrowstartnode{}{}{}\CF_arrowendnode%
    \CF_arrowdisplaylabel{#6}{0.5}\CF_tmpstrb\CF_arrowstartnode{}{}{}\CF_arrowendnode%
    \endgroup
}


% Initial arguments:
% #1, #2: Same as for -U> (above arrow)
% #3: Additional label at midpoint (also above arrow)
% #4, #5, #6: Like #1, #2, and #3, but below arrow
% #7: Optional shift, default 0
% #8: Optional arrow radius
% #9: Optional arrow angle
\definearrow9{<=X=>>}{%
    % handle optional shift
    \CF_arrowshiftnodes{#7}%
    % handle optional arrow radius
    \CF_ifempty{#8}
        {\def\CF_Xarrowradius{0.333}}
        {\def\CF_Xarrowradius{abs{#8}}}%
    % handle optional arrow angle
    \CF_ifempty{#9}%
        {\def\CF_Xarrowabsangle{60}}
        {\pgfmathsetmacro\CF_Xarrowabsangle{abs(#9)}}
    % ensure harpoon style lines
    \begingroup
    \pgfarrowharpoontrue%
    % draw equilibrium lines
    \path[allow upside down](\CF_arrowstartnode)--(\CF_arrowendnode)%
            node[pos=0.000,yshift= 1pt](\CF_arrowstartnode f0){}%
            node[pos=0.155,yshift=-1pt](\CF_arrowstartnode r0){}%
            node[pos=1.000,yshift= 1pt](\CF_arrowstartnode f1){}%
            node[pos=0.845,yshift=-1pt](\CF_arrowstartnode r1){};%
    \expandafter\draw\expandafter[\CF_arrowcurrentstyle](\CF_arrowstartnode f0)--(\CF_arrowstartnode f1)node[midway](forarrowarctangent){};%
    \expandafter\draw\expandafter[\CF_arrowcurrentstyle](\CF_arrowstartnode r1)--(\CF_arrowstartnode r0)node[midway](revarrowarctangent){};%
    % Draw top arrow (start) (left hand side)
    \edef\CF_tmpstr{[\CF_ifempty{#1}{draw=none}{\unexpanded\expandafter{\CF_arrowcurrentstyle}},-]}%
    \expandafter\draw\CF_tmpstr (forarrowarctangent)%
    arc[radius=\CF_compoundsep*\CF_currentarrowlength*\CF_Xarrowradius,start angle=\CF_arrowcurrentangle-90,delta angle=-\CF_Xarrowabsangle]node(Xarrow1start){};
    % Draw top arrow (end) (right hand side)
    \edef\CF_tmpstr{[\CF_ifempty{#2}{draw=none}{\unexpanded\expandafter{\CF_arrowcurrentstyle}},-CF]}%
    \expandafter\draw\CF_tmpstr (forarrowarctangent)%
    arc[radius=\CF_compoundsep*\CF_currentarrowlength*\CF_Xarrowradius,%
    start angle=\CF_arrowcurrentangle-90,%
    delta angle=\CF_Xarrowabsangle]%
    node(Xarrow1end){};
    % Draw bottom arrow (end) (left hand side)
    \edef\CF_tmpstr{[\CF_ifempty{#4}{draw=none}{\unexpanded\expandafter{\CF_arrowcurrentstyle}},-CF]}%
    \expandafter\draw\CF_tmpstr (revarrowarctangent)%
    arc[radius=\CF_compoundsep*\CF_currentarrowlength*\CF_Xarrowradius,start angle=\CF_arrowcurrentangle+90,delta angle=\CF_Xarrowabsangle]node(Xarrow2start){};
    % Draw bottom arrow (start) (right hand side)
    \edef\CF_tmpstr{[\CF_ifempty{#5}{draw=none}{\unexpanded\expandafter{\CF_arrowcurrentstyle}},-]}%
    \expandafter\draw\CF_tmpstr (revarrowarctangent)%
    arc[radius=\CF_compoundsep*\CF_currentarrowlength*\CF_Xarrowradius,%
    start angle=\CF_arrowcurrentangle+90,%
    delta angle=-\CF_Xarrowabsangle]%
    node(Xarrow2end){};
    % Insert labels
    \pgfmathsetmacro\CF_tmpstra{\CF_Xarrowradius*cos(\CF_arrowcurrentangle)<0?"-":"+"}%
    \pgfmathsetmacro\CF_tmpstrb{\CF_Xarrowradius*cos(\CF_arrowcurrentangle)<0?"+":"-"}%
    \CF_arrowdisplaylabel{#1}{0}\CF_tmpstra{Xarrow1start}{#2}{1}\CF_tmpstra{Xarrow1end}%
    \CF_arrowdisplaylabel{#4}{0}\CF_tmpstrb{Xarrow2start}{#5}{1}\CF_tmpstrb{Xarrow2end}%
    \CF_arrowdisplaylabel{#3}{0.5}\CF_tmpstra\CF_arrowstartnode{}{}{}\CF_arrowendnode%
    \CF_arrowdisplaylabel{#6}{0.5}\CF_tmpstrb\CF_arrowstartnode{}{}{}\CF_arrowendnode%
    \endgroup
}
% Initial arguments:
% #1, #2: Same as for -U> (above arrow)
% #3: Additional label at midpoint (also above arrow)
% #4, #5, #6: Like #1, #2, and #3, but below arrow
% #7: Optional shift, default 0
% #8: Optional arrow radius
% #9: Optional arrow angle
\definearrow9{<<=X=>}{%
    % handle optional shift
    \CF_arrowshiftnodes{#7}%
    % handle optional arrow radius
    \CF_ifempty{#8}
        {\def\CF_Xarrowradius{0.333}}
        {\def\CF_Xarrowradius{abs{#8}}}%
    % handle optional arrow angle
    \CF_ifempty{#9}%
        {\def\CF_Xarrowabsangle{60}}
        {\pgfmathsetmacro\CF_Xarrowabsangle{abs(#9)}}
    % ensure harpoon style lines
    \begingroup
    \pgfarrowharpoontrue%
    % draw equilibrium lines
    \path[allow upside down](\CF_arrowstartnode)--(\CF_arrowendnode)%
            node[pos=0.155,yshift= 1pt](\CF_arrowstartnode f0){}%
            node[pos=0.000,yshift=-1pt](\CF_arrowstartnode r0){}%
            node[pos=0.845,yshift= 1pt](\CF_arrowstartnode f1){}%
            node[pos=1.000,yshift=-1pt](\CF_arrowstartnode r1){};%
    \expandafter\draw\expandafter[\CF_arrowcurrentstyle](\CF_arrowstartnode f0)--(\CF_arrowstartnode f1)node[midway](forarrowarctangent){};%
    \expandafter\draw\expandafter[\CF_arrowcurrentstyle](\CF_arrowstartnode r1)--(\CF_arrowstartnode r0)node[midway](revarrowarctangent){};%
    % Draw top arrow (start) (left hand side)
    \edef\CF_tmpstr{[\CF_ifempty{#1}{draw=none}{\unexpanded\expandafter{\CF_arrowcurrentstyle}},-]}%
    \expandafter\draw\CF_tmpstr (forarrowarctangent)%
    arc[radius=\CF_compoundsep*\CF_currentarrowlength*\CF_Xarrowradius,start angle=\CF_arrowcurrentangle-90,delta angle=-\CF_Xarrowabsangle]node(Xarrow1start){};
    % Draw top arrow (end) (right hand side)
    \edef\CF_tmpstr{[\CF_ifempty{#2}{draw=none}{\unexpanded\expandafter{\CF_arrowcurrentstyle}},-CF]}%
    \expandafter\draw\CF_tmpstr (forarrowarctangent)%
    arc[radius=\CF_compoundsep*\CF_currentarrowlength*\CF_Xarrowradius,%
    start angle=\CF_arrowcurrentangle-90,%
    delta angle=\CF_Xarrowabsangle]%
    node(Xarrow1end){};
    % Draw bottom arrow (end) (left hand side)
    \edef\CF_tmpstr{[\CF_ifempty{#4}{draw=none}{\unexpanded\expandafter{\CF_arrowcurrentstyle}},-CF]}%
    \expandafter\draw\CF_tmpstr (revarrowarctangent)%
    arc[radius=\CF_compoundsep*\CF_currentarrowlength*\CF_Xarrowradius,start angle=\CF_arrowcurrentangle+90,delta angle=\CF_Xarrowabsangle]node(Xarrow2start){};
    % Draw bottom arrow (start) (right hand side)
    \edef\CF_tmpstr{[\CF_ifempty{#5}{draw=none}{\unexpanded\expandafter{\CF_arrowcurrentstyle}},-]}%
    \expandafter\draw\CF_tmpstr (revarrowarctangent)%
    arc[radius=\CF_compoundsep*\CF_currentarrowlength*\CF_Xarrowradius,%
    start angle=\CF_arrowcurrentangle+90,%
    delta angle=-\CF_Xarrowabsangle]%
    node(Xarrow2end){};
    % Insert labels
    \pgfmathsetmacro\CF_tmpstra{\CF_Xarrowradius*cos(\CF_arrowcurrentangle)<0?"-":"+"}%
    \pgfmathsetmacro\CF_tmpstrb{\CF_Xarrowradius*cos(\CF_arrowcurrentangle)<0?"+":"-"}%
    \CF_arrowdisplaylabel{#1}{0}\CF_tmpstra{Xarrow1start}{#2}{1}\CF_tmpstra{Xarrow1end}%
    \CF_arrowdisplaylabel{#4}{0}\CF_tmpstrb{Xarrow2start}{#5}{1}\CF_tmpstrb{Xarrow2end}%
    \CF_arrowdisplaylabel{#3}{0.5}\CF_tmpstra\CF_arrowstartnode{}{}{}\CF_arrowendnode%
    \CF_arrowdisplaylabel{#6}{0.5}\CF_tmpstrb\CF_arrowstartnode{}{}{}\CF_arrowendnode%
    \endgroup
}

\catcode`\_=8


\begin{document}

\schemestart
A
\arrow{-X>[1][2][3][4][5][6]}
B
\schemestop
\schemestart
A
\arrow{<=X=>[1][2][3][4][5][6]}
B
\schemestop

\schemestart
Z
\arrow{-X>[1][2][3][4][5][6]}
Y
\arrow{<=X=>[1][2][3][4][5][6]}
X
\schemestop
\schemestart
A
\arrow{<=X=>>[1][2][3][4][5][6]}
B
\arrow{<<=X=>[1][2][3][4][5][6]}
C
\schemestop
\end{document}

Output

arrows example


Note

As of version 1.4 of ChemFig (c. May 2019), the previous answers, are no longer functional as a result of a change in the way that ChemFig handles internal calls. - I have posted un updated version of Troy's code as a comment on his answer

1

If you rotate the equilibrium arrow by 90°, the distance between the two opposing arrows disappears.

\schemestart
   Z
     \arrow{-X>[][2][3][4][][]}
   Y
     \arrow{<=X=>[1][2][3][4][5][6]}[-90,1]
   X
\schemestop

[enter image description here]

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .