Noweb does not cross-reference Perl identifiers delimited on the left by @

58 views Asked by At

Consider this Noweb source file named quux.nw:

\documentclass{article}
\usepackage{noweb}
\usepackage[colorlinks]{hyperref}
\begin{document}
<<quux.pl>>=
my @foo ;
my $bar ;
my %baz ;
@ %def foo bar baz
\end{document}

and compiled using the commands:

$ noweb quux.nw
$ latexmk -pdf quux.tex

The identifiers bar and baz are properly highlighted as identifiers and cross referenced in the PDF output. The identifier foo is not.

It's my understanding that Noweb has a very simple heuristic for recognizing identifiers. foo should be recognizable as an identifier because, like bar and baz, it begins with an alphanumeric, is delimited on the left by a symbol (at-sign), and is delimited on the right by a delimiter (whitespace).

I considered the possibility that the at-sign was being interpreted by Noweb as an escape and tried doubling it, but that (i) did not solve the problem, and (ii) introduced the syntax error my @@foo into quux.pl. This makes sense because according to the fine manual, a double at-sign is only treated specially in columns 1–2.

1

There are 1 answers

0
MetaEd On

Noweb treats @ as alphanumeric, with the rationale that it “helps LaTeX”. I did not find anything about this in the Noweb manual. This is documented only in the Noweb source file finduses.nw, line 24, in Noweb version 2.12.

Apparently, when writing your own LaTeX package, any macro you define has public scope. To write “private” macros, the trick is to temporarily reclass the @ as a letter at the top of the package, incorporate an @ into the name of each “private” macro, and restore the class of @ at the bottom of the package. The macro remains public, but is impossible to call because the name gets broken up into multiple lexemes. (A user can still call such a macro by reclassing @ as a letter before the call, but if they do that, they assume the risk.)

So yes, @ should be included as an alphanumeric character when the code block contains a LaTeX package.

The full list of symbols treated as alphanumeric by Noweb is:

_ ' @ #
  • The _ is treated as an identifier character in many programming languages, so Noweb is right to treat it as alphanumeric.

  • The # is treated as alphanumeric to “avoid false hits on C preprocessor directives”.

  • No explanation is given for treating the ' as alphanumeric.

Ideally, Noweb would support separate character class schemes for each source language. But as I understand it, Noweb has only the one global character class scheme, and no support for changing it (other than modifying the source).

Fortunately, Perl has alternate syntaxes for array identifiers that work around this limitation. Instead of @foo you can write @{foo} or even @ foo and it will work.