4

I'm trying to hack a bibliography package (amsrefs), and fall into the following problem. I'm trying to convert the amsrefs format back to .bib files. This doesn't quite work, because strings get modified; i.e. a name such as Goode, Johnny~B. gets transformed to Goode, Johnny\nobreakspace {}B. and this is what appears in the output stream when I try to \immediate\write it.

How do I force the \nobreakspace and/or the more complicated \protect \unhbox \voidb@x \penalty \@M macros to evaluate to ~?

Here is a simplified version of what I'm trying to achieve, and the problem: saving this file into 'test.tex' and compiling it produces 'test.bib', which contains the lines

%Output bibliography test.tex to test.bib
@Book{
 title={Goode, Johhny\protect \unhbox \voidb@x \penalty \@M \ {}B.}
}

and not just "title={Goode, Johnny~B.}"

\documentclass{article}
\usepackage{amsrefs}

\makeatletter

\def\printtitle#1{\immediate\write\bibfile{ title={#1}}}

\BibSpec{book}{%
  +{}{\immediate\write\bibfile{@Book\@charlb}}{transition}
  +{}{\printtitle}{title}
  +{}{\immediate\write\bibfile{\@charrb}}{transition}
}

\begin{document}
\immediate\newwrite\bibfile
\immediate\openout\bibfile=\jobname.bib
\immediate\write\bibfile{\@percentchar Output bibliography \jobname.tex to \jobname.bib}

\begin{bibdiv}
\begin{biblist}
\bib{test}{book}{
  title={Goode, Johhny~B.}
}
\end{biblist}
\end{bibdiv}

\immediate\closeout\bibfile
\end{document}

1 Answers1

2

You need an \immediate version of \write (see Writing \\ to a File). The \protected@iwrite command has one argument more, where to give settings that are applied when writing. For writing a literal ~ you need to make it (temporarily) equivalent to \relax:

\documentclass{article}
\usepackage{amsrefs}
\usepackage{xpatch}

\makeatletter
% get a copy of `\protected@write
\let\protected@iwrite\protected@write
% patch the copy to add \immediate
\xpatchcmd{\protected@iwrite}{\write}{\immediate\write}{}{}

\newcommand{\bib@write}[1]{%
  \protected@iwrite\bibfile
   {\let~\relax}%
   {#1}%
}

\def\printtitle#1{\bib@write{ title={#1}}}

\BibSpec{book}{%
  +{}{\bib@write{@Book\@charlb}}{transition}
  +{}{\printtitle}{title}
  +{}{\bib@write{\@charrb}}{transition}
}
\newwrite\bibfile
\immediate\openout\bibfile=\jobname.bib
\bib@write{\@percentchar Output bibliography \jobname.tex to \jobname.bib}
\makeatother

\begin{document}

\begin{bibdiv}
\begin{biblist}
\bib{test}{book}{
  title={Goode, Johhny~B.}
}
\end{biblist}
\end{bibdiv}

\immediate\closeout\bibfile
\end{document}

Here's the contents of \jobname.bib:

%Output bibliography bartholdi.tex to bartholdi.bib
@Book{
 title={Goode, Johhny~B.}
}
egreg
  • 1,121,712