我需要一个可以识别以下语法的 Latex makro:
!!! note
Custom text: This is a Admonition note in Markdown.
是否有可能有一个同名的宏!!!
?或者还有其他解决方法吗?
当我尝试时,makro 没有起作用:
\newcommand{!!!}{Latex Makro Text}
% my document text
!!!
感叹号尚未被“Latex Makro Text”替换
感谢您的帮助!
法比奥
上下文:
我想用 pandoc 将 Markdown 文件解析为 PDF。
我创建了一个 Latex 模板,并使用 Admonition 插件来突出显示警告或注释。我希望我的 Latex 模板能够识别 Admonition 语法并适当地设置其样式。我对 Latex 不是很熟悉。
答案1
(一定有一种方法来实现您的目标,即通过创建!
一个“活动”字符并检查它后面是否正好有两个!
字符;如果是的话,让 LaTeX 打印出一条警告消息;如果不是,只需将感叹号标记放回流中。)
这是一个 LuaLaTeX 解决方案,它扫描输入流以查找实例!!!
并用适当选择的警告消息替换它们。
关于Lua函数内部使用的语法string.gsub
:因为Lua使用\
转义字符,所以需要输入\\
来生成(单个)反斜杠。
\documentclass{article}
\usepackage{luacode,xcolor}
\begin{luacode}
function triplebang ( s )
return ( string.gsub ( s , '!!!',
'\\par\\bigskip\\noindent\\textcolor{red}{!!! ' ..
'This is an admonition note. !!!}\\par\\bigskip ' ) )
end
\end{luacode}
\AtBeginDocument{\directlua{luatexbase.add_to_callback (
"process_input_buffer", triplebang, "triplebang" ) }}
\begin{document}
hello world!!!hello world!!hello world!hello world!!!hello world
\end{document}
答案2
无论如何,我认为这不会有什么用处。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\tl_new:N \l_fabio_three_exclam_note_tl
\cs_new_protected:Npn \fabio_three_exclam:w
{
\peek_charcode_remove:NTF { ! }
{ \__fabio_three_exclam_aux:w }
{ ! }
}
\cs_new_protected:Npn \__fabio_three_exclam_aux:w
{
\peek_charcode_remove:NTF { ! }
{ \tl_use:N \l_fabio_three_exclam_note_tl }
{ !! }
}
\char_set_active_eq:NN ! \fabio_three_exclam:w
\char_set_catcode_active:N !
\NewDocumentCommand{\setnotetext}{m}
{
\tl_set:Nn \l_fabio_three_exclam_note_tl { #1 }
}
\ExplSyntaxOff
\setnotetext{This is a Admonition note in Markdown.}
\begin{document}
This is silly! Really!! Well, it works.
!!!
Some text.
\end{document}
答案3
(请将此答案视为一个没有实际意义/相当“学术”的事情。)
如果您需要在没有 Lua 扩展的情况下执行操作,您可以创建!
一个活动字符,使 TeX 通过\futurelet
(或通过\let
,\afterassignment
这将要求您以一种获取所有可选空格的方式写下来,\let
根据 TeXbook,它会丢弃这些空格)“查看”下一个标记的含义。
如果下一个标记的含义等于活动字符的含义,则可以(不丢失括号)让 TeX 将下一个标记捕获为未分隔的参数,然后通过内部使用 active!
作为参数分隔符的宏让 TeX 检查该标记是否真的是活动字符!
,而不是某些控制序列或等于 active 的活动非!
字符。\let
!
\documentclass{article}
\usepackage{color}%
\makeatletter
\newcommand\UD@firstoftwo[2]{#1}%
\newcommand\UD@secondoftwo[2]{#2}%
\newcommand\UD@Exchange[2]{#2#1}%
%%----------------------------------------------------------------------
%% Check whether argument is empty:
%%......................................................................
%% \UD@CheckWhetherNull{<Argument which is to be checked>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is empty>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is not empty>}%
%%
%% The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
%% <https://groups.google.com/forum/#!original/comp.text.tex/kuOEIQIrElc/lUg37FmhA74J>
%%
%% (\romannumeral expansion was introduced by me in order to overcome the
%% concerns and worries about improperly balanced \if..\else..\fi constructs.)
\newcommand\UD@CheckWhetherNull[1]{%
\romannumeral0\expandafter\UD@secondoftwo\string{\expandafter
\UD@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
\UD@secondoftwo\string}\expandafter\UD@firstoftwo\expandafter{\expandafter
\UD@secondoftwo\string}\expandafter\expandafter\UD@firstoftwo{ }{}%
\UD@secondoftwo}{\expandafter\expandafter\UD@firstoftwo{ }{}\UD@firstoftwo}%
}%
\newcommand\UDtempa{}
\begingroup
\renewcommand\UDtempa[1]{%
\endgroup
%%-----------------------------------------------------------------------------
%% Check whether brace-balanced argument starts with an active !
%%.............................................................................
%% \UD@CheckWhetherLeadingExclam{<Argument which is to be checked>}%
%% {<Tokens to be delivered in case <argument
%% which is to be checked>'s 1st token is an
%% active exclamation mark>}%
%% {<Tokens to be delivered in case <argument
%% which is to be checked>'s 1st token is not
%% an active exclamation mark>}%
\newcommand\UD@CheckWhetherLeadingExclam[1]{%
\romannumeral0\UD@CheckWhetherNull{##1}%
{\expandafter\expandafter\UD@firstoftwo{ }{}\UD@secondoftwo}%
{\expandafter\UD@secondoftwo\string{\UD@CheckWhetherLeadingExclamB.##1#1}{}}%
}%
\newcommand\UD@CheckWhetherLeadingExclamB{}%
\long\def\UD@CheckWhetherLeadingExclamB##1#1{%
\expandafter\UD@CheckWhetherNull\expandafter{\UD@secondoftwo##1{}}%
{\UD@Exchange{\UD@firstoftwo}}{\UD@Exchange{\UD@secondoftwo}}%
{\UD@Exchange{ }{\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter}\expandafter\expandafter
\expandafter}\expandafter\UD@secondoftwo\expandafter{\string}%
}%
\newcommand#1{\futurelet\UDtempa\@ChkSecondExclam}%
\newcommand\@ChkSecondExclam{%
\ifx\UDtempa#1\expandafter\UD@firstoftwo\else\expandafter\UD@secondoftwo\fi
{\@ChkThirdExclam}%
{!}%
}%
\newcommand\@ChkThirdExclam[1]{%
\UD@CheckWhetherLeadingExclam{##1}{\futurelet\UDtempa\@FinishChkThirdExclam}{!!}%
}%
\newcommand\@FinishChkThirdExclam{%
\ifx\UDtempa#1\expandafter\UD@firstoftwo\else\expandafter\UD@secondoftwo\fi
{\@gobbleactiveexclam}{!!}%
}%
\newcommand\@gobbleactiveexclam[1]{%
\UD@CheckWhetherLeadingExclam{##1}{%
\par\bigskip
\noindent\textcolor{red}{\mbox{!!! This is an admonition note. !!!}}%
\par\bigskip
}{!!!}%
}%
}%
\catcode`\!=13
\UDtempa{!}%<-this does the \endgroup
\makeatother
\begin{document}
\catcode`\!=13
hello world!!!hello world!!hello world!hello world!!!hello world
\bigskip
\let\misleading=!
hello world!\misleading!hello world!!hello world!hello world\misleading!\misleading hello world
\bigskip
But there is the edge case of a token \verb|\let| equal to active \verb|!| being trailed by two active \verb|!| :
hello world \misleading!!
\end{document}