# Defining a macro whose syntax includes another macro's syntax

I've defined the following macro:

\begingroup
\lccode\~=\#%
\lowercase{\endgroup%
\def~ #1\par}{%
\begingroup\def\par{\endgroup\par}%
\section*{#1}\par}%
\catcode\#=13


But if I go on to define a command such as

\begingroup
\lccode\~=\#%
\lowercase{\endgroup%
\def~~ #1\par}{%
\begingroup\def\par{\endgroup\par}%
\subsection*{#1}\par}%
\catcode\#=13


while ## Test now works as expected, any usages of # Test no longer function, and the console returns an error stating that Use of # doesn't match its definition..

How can I configure a macro of this variety so that both macros work as expected?

-

When \def is followed by an active character, that is defined and all that follows up to the open brace is the macro's parameter text.

With the first part of the code you're giving a meaning to the active # and \show# prints

> #=macro:
#1\par ->\begingroup \def \par {\endgroup \par }\section *{#1}\par .


The parameter text is

#1\par


which means that everything up to the first following \par token is to be the argument.

When you execute the second code (that of course requires to delay \catcode#=13), you're overriding the meaning of the active#; indeed,\show# now prints

> #=macro:
# #1\par ->\begingroup \def \par {\endgroup \par }\subsection *{#1}\par .


Now # is a macro (active character) that expects to be followed by another active #. Therefore # Text will raise the error

Use of # doesn't match its definition.


You need to define the active # to look whether the following token is another # and, in this case take the appropriate action.

Here's a possible definition

\documentclass{article}

\makeatletter
\begingroup\lccode~=#
\lowercase{\endgroup
\def~{\@ifnextchar~\markdown@subsec\markdown@sec}
}

\def\markdown@sec#1\par{\section*{#1}}
\def\markdown@subsec#1{\@ifnextchar\valign\relax\markdown@subsec@aux}
\def\markdown@subsec@aux#1\par{\subsection*{#1}}
\makeatother

\AtBeginDocument{\catcode\#=\active}

\begin{document}
# Section Title

Some text

## Subsection Title

Some other text

\end{document}


The mysterious definition of \markdown@subsec is explained by the need of eating up spaces: \@ifnextchar does just this, because it's quite difficult that you write ##\valign; and if you do, the macro would fail.

The extension for subsubsections is straightforward:

\documentclass{article}

\makeatletter
\begingroup\lccode~=#
\lowercase{\endgroup
\def~{\@ifnextchar~\markdown@subsec\markdown@sec}
\def\markdown@subsec#1{\@ifnextchar~\markdown@subsubsec\markdown@subsec@aux}
}
\def\markdown@sec#1\par{\section*{#1}}
\def\markdown@subsubsec#1{\@ifnextchar\valign\relax\markdown@subsubsec@aux}
\def\markdown@subsec@aux#1\par{\subsection*{#1}}
\def\markdown@subsubsec@aux#1\par{\subsubsection*{#1}}
\makeatother

\AtBeginDocument{\catcode\#=\active}

\begin{document}
# Section Title

Some text

## Subsection Title

Some other text

### Subsubsection Title

Oh, well!

\end{document}
`

-