参数直到非字母数字字符

参数直到非字母数字字符

不确定这是否可能...

我想将(比如说)转换+为一个不带括号的参数的命令。此参数应为以下所有内容:+ 直到第一个非字母数字字符。 一个例子:

\documentclass{article}

\catcode`+\active

\def+{%
  %do some magic tricks
}

\begin{document}

+ % + with an empty argument
+hello527world % + with the argument hello527world
+cool. This is nice. % + with the argument cool followed by ". This is nice."
+cool is nice. % + with the argument cool followed by a space and "is nice"

\end{document}

换句话说,+应该有点像\,只是支持字母数字字符。此外,以下空格也需要输入。

我到底为什么要这样做?我正在尝试创建一个更简单的 LaTeX 前端,并且我想使用符号+blahblah进行引用。

我尝试过xparse,但没有找到任何方法来实现这一点。

答案1

引用其中一条评论:“欢迎使用非字母字符的解决方案”。因此,我提出了一个解决方案,提取完全由字母(\catcode= 11)字符组成的参数,直到但不包括第一个非字母。原则上,代码可以调整为包括十个数字 0...9。

这个解决方案只需要 Knuth 的原始 TeX。

\documentclass[a4paper]{article}
\usepackage[T1]{fontenc}

\makeatletter

% Avoid using a critical character like +
\catcode`\! = \active
\def!{%
  \toks@{}%
  \@AN@scan@forward
}
\@ifdefinable\@AN@scan@forward{\def\@AN@scan@forward{%
  \futurelet\next \@AN@test@next
}}
\@ifdefinable\@AN@test@next{\def\@AN@test@next{%
  \ifcat A\noexpand\next
    \expandafter\@AN@add@token
  \else
    \expandafter\@AN@call@payload
  \fi
}}
\@ifdefinable\@AN@add@token{\def\@AN@add@token#1{%
  \toks@ \expandafter{\the\toks@ #1}%
  \@AN@scan@forward
}}
\@ifdefinable\@AN@call@payload{\def\@AN@call@payload{%
  \ANPayload{\the\toks@}%
  % (Or
  % \expandafter\ANPayload \expandafter{\the\toks@}%
  % if needed).
}}

\makeatother

\newcommand{\ANPayload}[1]{%
  % Substitute the operations you want to perform on the argument:
  \typeout{#1}%
  \textbf{#1}%
}



\begin{document}

Reference text.
! % + with an empty argument
!hello527world % + with the argument hello followed by "527world"
!helloworld % + with the argument helloworld
!cool. This is nice. % + with the argument cool followed by ". This is nice."
!cool is nice. % + with the argument cool followed by a space and "is nice"

\end{document}

在此处输入图片描述

我必须警告,可能,解析提供了更好的解决方案,我根本不知道:在看到大约两天没有提供其他答案后,我决定发布这个临时答案。

答案2

我建了一个图书馆...

%! TEX program = lualatex
\documentclass{article}
\usepackage{pythonimmediate}

\begin{pycode}
from pythonimmediate import newcommand, peek_next_char, get_next_char
from pythonimmediate import print as print_to_TeX
from string import ascii_letters, digits
@newcommand
def plussign():
    s=""
    while True:
        ch=peek_next_char()
        if ch!="" and (ch in ascii_letters or ch in digits):
            get_next_char()
            s+=ch
        else:
            break
    print_to_TeX(r'(' + s + ')', end="")  # need end="" to suppress the new line character being interpreted as a space, see documentation for details (did I remember to include it in the documentation?)
\end{pycode}

% currently there's no function to define active character yet...
\catcode `+\active
\let+\plussign

\begin{document}


+ % + with an empty argument

+hello527world % + with the argument hello527world

+cool. This is nice. % + with the argument cool followed by ". This is nice."

+cool is nice. % + with the argument cool followed by a space and "is nice"

\end{document}

输出正如你所期望的:

输出


话虽如此,这是一个“正常”的实现:

%! TEX program = lualatex
\documentclass{article}

\ExplSyntaxOn
\cs_new_protected:Npn \__gaussler_plus_sign:n #1 {
    (#1)
}
\cs_new_protected:Npn \__gaussler_plus_sign:w {
    \peek_regex_replace_once:nn {[A-Za-z0-9]*} {\c{__gaussler_plus_sign:n}{\0}}
}
\char_set_active_eq:NN + \__gaussler_plus_sign:w
\char_set_catcode_active:N +
\ExplSyntaxOff


\begin{document}


+ % + with an empty argument

+hello527world % + with the argument hello527world

+cool. This is nice. % + with the argument cool followed by ". This is nice."

+cool is nice. % + with the argument cool followed by a space and "is nice"

\end{document}

所有的魔法都隐藏在函数后面。基本上,它 用\peek_regex_replace_once:nn替换标记列表,然后函数本身完成工作。(在这个例子中,它用一对括号括起来)cool. This is nice\__gaussler_plus_sign:n {cool}. This is nice.

答案3

这是一份工作\peek_regex_replace_once:nn

\documentclass{article}
\usepackage[T1]{fontenc}

\ExplSyntaxOn

\NewDocumentCommand{\+}{}
 {
  \gaussler_plus:
 }
\cs_new_protected:Nn \gaussler_plus:
 {
  \peek_regex_replace_once:nn { ([[:alnum:]]*) } { \c{gaussler_plus_do:n}\cB\{\1\cE\} }
 }
\cs_new:Nn \gaussler_plus_do:n
 {
  --Argument~was~|#1|--
 }

% if you want to live dangerously
\char_gset_active_eq:NN + \gaussler_plus:
\char_set_catcode_active:N +

\ExplSyntaxOff

\begin{document}

\+ % + with an empty argument

\+Hello527World % + with the argument hello527world

\+cool. This is nice. % + with the argument cool followed by ". This is nice."

\+cool is nice. % + with the argument cool followed by a space and "is nice"

+ % + with an empty argument

+Hello527World % + with the argument hello527world

+cool. This is nice. % + with the argument cool followed by ". This is nice."

+cool is nice. % + with the argument cool followed by a space and "is nice"

\end{document}

与搜索正则表达式(第一个参数)匹配的标记将按照替换正则表达式(第二个参数)的指示进行替换。在这里,它们作为参数输入\gaussler_plus:n

我还展示了如何激活+。这不是一个好主意,因为+catcode 12 的标准是 TeX 数字语法的一部分。

在此处输入图片描述

您可以制作一种变体,其中没有字母数字后续字符会触发其他操作。

\documentclass{article}
\usepackage[T1]{fontenc}

\ExplSyntaxOn

\NewDocumentCommand{\+}{}
 {
  \gaussler_plus:
 }
\cs_new_protected:Nn \gaussler_plus:
 {
  \peek_regex_replace_once:nnF 
   { ([[:alnum:]]+) } % search
   { \c{gaussler_plus_do:n}\cB\{\1\cE\} } % replace
   { Hey! } % no match
 }
\cs_new:Nn \gaussler_plus_do:n
 {
  --Argument~was~|#1|--
 }

\ExplSyntaxOff

\begin{document}

\+ % + with an empty argument

\+Hello527World % + with the argument hello527world

\+cool. This is nice. % + with the argument cool followed by ". This is nice."

\+cool is nice. % + with the argument cool followed by a space and "is nice"

\end{document}

在此处输入图片描述

另一种变体是,只要后面跟着字母数字,就会忽略初始空格。

\documentclass{article}
\usepackage[T1]{fontenc}

\ExplSyntaxOn

\NewDocumentCommand{\+}{}
 {
  \gaussler_plus:
 }
\cs_new_protected:Nn \gaussler_plus:
 {
  \peek_regex_replace_once:nnF 
   { \s*([[:alnum:]]+) } % search
   { \c{gaussler_plus_do:n}\cB\{\1\cE\} } % replace
   { Hey! } % no match
 }
\cs_new:Nn \gaussler_plus_do:n
 {
  --Argument~was~|#1|--
 }

\ExplSyntaxOff

\begin{document}

\+ % + with an empty argument

\+ Hello527World % + with the argument hello527world

\+cool. This is nice. % + with the argument cool followed by ". This is nice."

\+ cool is nice. % + with the argument cool followed by a space and "is nice"

\end{document}

与之前相同的输出。

相关内容