How do I include the EBNF square brackets on a new line and set the font to typewriter throughout my grammar in the syntax package?

You can exploit \new@ifnextchar from amsmath:

\documentclass[]{article}

\usepackage{amsmath}
\usepackage{newtxtext,newtxmath}

\usepackage{syntax}
\usepackage{xpatch}

\makeatletter
\pretocmd{\grammar}{\let\@ifnextchar\new@ifnextchar}{}{}
\makeatother
\renewcommand{\syntleft}{$\langle$\normalfont\ttfamily}

\begin{document}

\begin{grammar}

<a> ::= "a" [<b>]

<b> ::= "b" \\ <c>

<c> ::= "c" \\ [<d>]

\end{grammar}

\end{document}

With this trick, \\ will consider a following [ to introduce the optional argument only if no space intervenes.

I've used cfr's code for changing the font. The packages newtxtext and newtxmath are recommended for Times with math fonts support. If you don't like the typewriter font they provide, it's easy to change it.

enter image description here


The first part of your question is not specific to the syntax package. The problem is that in environments such as array and tabular and grammar, \\ directly followed by an opening square bracket is assumed to introduce an adjustment to vertical spacing. And a space beforehand doesn't prevent the next relevant token counting as the [. You don't want an adjustment, but that's just like an adjustment of zero, I think, so you can say \\[0pt] [<d>] and everything should work OK. Alternatively, you could define a special command to create the square brackets or write \\{} in place of \\[0pt] if that's better.

Note that times is long deprecated and ought not be used. I've used tgtermes here, but there are other options if you don't like this particular choice.

\documentclass{article}
\usepackage{tgtermes}
\usepackage{syntax}
\begin{document}
\begin{grammar}

  <a> ::= "a" [<b>]

  <b> ::= "b" \\ <c>

  % this works
  <c> ::= "c" \\[0pt] [<d>]
  % or this
%  <c> ::= "c" \\{} [<d>]

\end{grammar}
\end{document}

square brackets

The documentation does say something about changing the fonts (page 10) but it rather assumes that you know how to do this in the general case.

The commands it lists as affecting the appearance of different typeset elements are

\syntleft
\syntright
\ulitleft
\ulitright
\litleft
\litright

So, to change these, we need the origiinal definitions. The manual provides this for the first two:

\newcommand{\syntleft}{$\langle$\normalfont\itshape}
\newcommand{\syntright}{$\rangle$}

The \normalfont is setting the font to the default family for the document (usually serif). The \itshape sets the italic. If we want to use the typewriter family instead of serif, we can say

\renewcommand{\syntleft}{$\langle$\normalfont\ttfamily\itshape}

If we wanted the upright shape, we could say

\renewcommand{\syntleft}{$\langle$\normalfont\ttfamily}

We don't need to change the right one because it doesn't affect the font. The default definitions for the remaining 4 commands are as follows:

\newcommand{\ulitleft}{\normalfont\ttfamily\syn@ttspace\frenchspacing}

This changes the font but it already changes it to typewriter, so nothing to worry about here.

\newcommand{\ulitright}{}
\newcommand{\litleft}{`\bgroup\ulitleft}
\newcommand{\litright}{\ulitright\egroup'}

These don't affect the font, so nothing to do here either.

So, the one change of command yields this result in place of the original above:

all typewriter

Complete code:

\documentclass{article}
\usepackage{tgtermes}
\usepackage{syntax}
\renewcommand{\syntleft}{$\langle$\normalfont\ttfamily\itshape}
% \newcommand{\syntright}{$\rangle$}
% \newcommand{\ulitleft}{\normalfont\ttfamily\syn@ttspace\frenchspacing}
% \newcommand{\ulitright}{}
% \newcommand{\litleft}{`\bgroup\ulitleft}
% \newcommand{\litright}{\ulitright\egroup'}
\begin{document}
\begin{grammar}

  <a> ::= "a" [<b>]

  <b> ::= "b" \\ <c>

  % this works
  <c> ::= "c" \\[0pt] [<d>]
  % or this
%  <c> ::= "c" \\{} [<d>]

\end{grammar}
\end{document}