6

I have a chemfig command which involves the use of #. It compiles properly on itself.

\chemfig{**[135,405,dash pattern=on 2pt off 2pt]6(----#(,0pt)\chembelow[2.5em]{}{+}(-#(0pt)[3]H)(-#(0pt)[1]NO_3)-#(0pt)-)}

But when I put it into the align block, pdfLaTeX gives error.

\begin{align*}
\chemfig{**[135,405,dash pattern=on 2pt off 2pt]6(----#(,0pt)\chembelow[2.5em]{}{+}(-#(0pt)[3]H)(-#(0pt)[1]NO_3)-#(0pt)-)}
\end{align*}

The error message is here: http://pastebin.com/3FLzX4RP

MWE:

\documentclass[10pt]{article}
\usepackage[usenames]{color} %used for font color
\usepackage{amssymb} %maths
\usepackage{amsmath} %maths
\usepackage[utf8]{inputenc} %useful to type directly diacritic characters
\usepackage{chemfig}

\pagestyle{empty} 
\begin{document}

\begin{align*}
\chemfig{**[135,405,dash pattern=on 2pt off 2pt]6(----#(,0pt)\chembelow[2.5em]{}{+}(-#(0pt)[3]H)(-#(0pt)[1]NO_3)-#(0pt)-)}
\end{align*}

\end{document}

In chemfig, # is used to adjust the bond shortening. The following example is from the chemfig documentation, pg. 6 Example from chemfig doc

I've tried using \#(0pt), but instead of adjusting the bond, it outputs the string directly.

2 Answers2

6

The \chemfig command relies on category code changes, in particular it changes # to an “other character” (category code 12). Such commands cannot appear in the argument to another command.

While equation and equation* are safe on this respect, align* isn't: the multiline alignment environments of amsmath absorb their content as the argument to a command. You'd have the same problem trying \fbox{\chemfig{...}}.

Using align* as a substitute for equation* is not recommended, so in the example case equation* would do. But if you really need a multiline environment, here's a trick:

\documentclass{article}
\usepackage{amsmath,chemfig}

\makeatletter
\newcommand{\chemfigon}{\begingroup\@makeother\#}
\let\chemfigoff\endgroup
\makeatother

\begin{document}

\chemfig{**[135,405,dash pattern=on 2pt off 2pt]6(----#(,0pt)\chembelow[2.5em]{}{+}(-#(0pt)[3]H)(-#(0pt)[1]NO_3)-#(0pt)-)}

\chemfigon
\begin{align*}
\chemfig{**[135,405,dash pattern=on 2pt off 2pt]6(----#(,0pt)\chembelow[2.5em]{}{+}(-#(0pt)[3]H)(-#(0pt)[1]NO_3)-#(0pt)-)}
\end{align*}
\chemfigoff

\end{document}

This makes # an “other character” before the input is grabbed as an argument.

enter image description here

egreg
  • 1,121,712
  • \chemfig{**[150,390,dash pattern=on 2pt off 2pt,late options={name=arccenter,label=center:+}]6(----#(,0pt)(-#(0pt)[3]H)(-#(0pt)[1]NO_3)-#(0pt)-)} this is more elegant in my opinion. – Manuel Feb 22 '15 at 12:20
  • 1
    And this one, without #, should be prefered: \chemfig{**[135,405,dash pattern=on 2pt off 2pt]6(----(-[3]H)(-[1]NO_3)(-[6,,,,draw=none]+)--)} – unbonpetit Feb 22 '15 at 15:34
3

In theory, \chemfig{<code>} can be written in the argument of a macro since \CF@chemfig@iv does a \scantokens of the <code>. Unfortunately, there is a bug because via \scantokens, # becomes ## in the argument of a macro and this behaviour is not taken into account by \chemfig.

For example, if you write \fbox{\chemfig{A-#(0pt)B}}, the code of the molecule becomes A-##(0pt)B, where # is catcode 12. The bug is in \CF@grab@bondoffset: this macro expects a ( juste after the first #. And this is not the case when \chemfig is in the argument of a macro.

Here is a fix:

\documentclass{article}
\usepackage{chemfig}
\makeatletter
\def\CF@grab@bondoffset#1(#2)#3\@nil{%
    \ifx\@empty#2\@empty
    \else
        \CF@if@instr{#2},%
            {\CF@analyse@bondoffset#2\@nil}%
            {\def\CF@start@offset{#2}}%
    \fi
    \def\CF@remain@afterbond{#3}%
}
\makeatother
\begin{document}
\fbox{\chemfig{A-#(0pt)B}}

\chemfig{A-#(0pt)B}
\end{document}

enter image description here

unbonpetit
  • 6,190
  • 1
  • 20
  • 26