# 'Missing \begin{document}' when using the \lowercase trick

Mostly for fun, I'm trying to make % comments manipulatable using the \lowercase trick. For some reason, I'm getting a strange (to me) error:

ERROR: LaTeX Error: Missing \begin{document}.

--- TeX said ---

See the LaTeX manual or LaTeX Companion for explanation.
Type  H <return>  for immediate help.
...



Generally when I get this kind of error, I have unbalanced brace groups somewhere. As far as I can tell, this is not the case here.

### MWE

\documentclass{article}

\usepackage{xparse}
\ExplSyntaxOn

\cs_new_protected:Nn \vc_make_comment:n
{ \textbf{Comment: #1'} }
{
\group_begin:
\char_set_lccode:nn {\~} {\%}
\tl_to_lowercase:n
{ \group_end: \cs_set_eq:NN ~ } \vc_make_comment:n
\char_set_catcode_active:N \%
}

\ExplSyntaxOff

\begin{document}

Hello, this is a % comment

\end{document}
Expecting: Hello, this is a \textbf{Comment: comment'}

• (With the understanding that I'll have to create \vc_make_comment:w to scan until the end of the line and feed that into \vc_make_comment:n for 'proper' behavior.) – Sean Allred Sep 7 '15 at 16:51
• The full code for proper behavior can be found on reddit. – Sean Allred Sep 7 '15 at 17:18

The '\lowercase trick' relies on you having a char that is already active. The usual one in a document is ~ as it is active in plain, LaTeX and ConTeXt for creating a non-breaking space. However, inside an expl3 code block it's a space, so you get the wrong outcome (you've effectively go \cs_set_eq:NN}...). You can fix this by making it active:

\documentclass{article}

\usepackage{xparse}
\ExplSyntaxOn

\cs_new_protected:Nn \vc_make_comment:n
{ \textbf{Comment: #1'} }
\group_begin:
\char_set_catcode_active:N \~
{
\group_begin:
\char_set_lccode:nn {\~} {\%}
\tl_to_lowercase:n
{ \group_end: \cs_set_eq:NN ~ } \vc_make_comment:n
\char_set_catcode_active:N \%
}
\group_end:

\ExplSyntaxOff

\begin{document}

Hello, this is a % comment

\end{document}


However, the team are working to provide better interfaces that the above (what's case changing got to do with making something active, really). The current (still experimental) interface is

\cs_new_protected:Nn \vc_visible_comments:
{
\char_set_active_eq:NN \% \vc_make_comment:n
\char_set_catcode_active:N \%
}


There's been a (very) recent change in the definition of \char_set_active_eq:NN: with the current release, it means 'set the behaviour of #1 to be equal to #2 if #1 is active'. As such, actually making the token active is a second step, as shown above.

• I don't think you quite realize how happy \char_set_active_eq:NN makes me. :) – Sean Allred Sep 7 '15 at 18:49

Your question, however doesn't “grab until the end of line”. Here's a suggestion coming from an old question I asked.

\documentclass{scrartcl}

\usepackage{xparse}
\ExplSyntaxOn

\group_begin:
\char_set_catcode_other:N \^^M %
\cs_new_protected:Npn \cs_new_delimited_by_newline:Nn #1 #2 %
{ %
\cs_new_protected:Npn #1 %
{ %
\group_begin: %
\char_set_catcode_other:N \^^M %
\use:c { __ \cs_to_str:N #1 } %
} %
\cs_new_protected:cpn { __ \cs_to_str:N #1 } ##1 ^^M %
{ %
#2 %
\group_end: %
} %
} %
\group_end:
\cs_new_delimited_by_newline:Nn \vc_make_comment:w
{ \vc_make_comment:n { \tl_trim_spaces:n {#1} } }
\cs_new_protected:Npn \vc_make_comment:n #1
{ \textbf{Comment: ~ #1'} }

{
\char_set_active_eq:NN \% \vc_make_comment:w
\char_set_catcode_active:N \%
}

\ExplSyntaxOff


• Should've taken a look at the comments on the question :) (on second thought, it should rather be an edit to the question or a comment on Joseph's answer) though \tl_trim_spaces:n is probably more appropriate than my \ignorespaces. – Sean Allred Sep 7 '15 at 18:37
• Ah, by the way, this would work only for “outer” comments, if a comment is inside an argument of a macro it wouldn't be shown correctly, in that case it's probably better the sed script you proposed. – Manuel Sep 7 '15 at 18:41