![具有字符识别功能的高级宏](https://linux22.com/image/374141/%E5%85%B7%E6%9C%89%E5%AD%97%E7%AC%A6%E8%AF%86%E5%88%AB%E5%8A%9F%E8%83%BD%E7%9A%84%E9%AB%98%E7%BA%A7%E5%AE%8F.png)
我想编写一个高级宏,如下所示
\begin{exercise}[....]
bla bla bla
\end{exercise}
在括号中[....]
,我会输入如下字符串:
- 氟化氢
- F
- 高频高频振荡
- 中枢神经系统
- ?
- ETC。
这个想法是计算 和 的数量F
,H
并C
根据结果采取不同的行动。在我看来,FFF
将在练习旁边打印三个“闪电”符号,H
将打印一颗星、HH
两颗星、CC
两个计算机符号,?
将打印一个问号等。
(F
代表“闪存”、H
“硬盘”、C
“计算机”、?
“未知”等)
我应该采取什么方向?您有什么提示吗(比如我可以在哪里复制一些代码)?有什么软件包可以帮助我吗?
我希望有一个LaTeX
唯一的解决方案,但我也想知道是否LuaLaTeX
可以使这类事情变得更容易。
答案1
\documentclass{article}
\newenvironment{zzz}[1][]{%
\quote\strut\marginpar{\zzzz#1!}\ignorespaces}
{\endquote}
\def\zzzz#1{\csname zzz#1\endcsname\zzzz}
\def\zzzH{$\ast$}
\def\zzzF{$|$}
\def\zzzC{$\,\rule{4pt}{5pt}\,$}
\expandafter\def\csname zzz?\endcsname{?}
\expandafter\def\csname zzz!\endcsname#1{}
\begin{document}
\begin{zzz}
one two three
\end{zzz}
\begin{zzz}[CCCH]
one two three
\end{zzz}
\begin{zzz}[FF]
one two three
\end{zzz}
\begin{zzz}[CF?]
one two three
\end{zzz}
\end{document}
这会直接打印符号,但您当然可以让宏增加一些计数器,并推迟所有打印,直到知道整个集合之后。
\documentclass{article}
\newenvironment{zzz}[1][]{%
\quote\strut\marginpar{%
\Hc=0
\Fc=0
\Cc=0
\Qc=0
\zzzz#1!%
There are \the\Cc\ C and \the\Fc\ F}\ignorespaces}
{\endquote}
\def\zzzz#1{\csname zzz#1\endcsname\zzzz}
\newcount\Hc
\newcount\Fc
\newcount\Cc
\newcount\Qc
\def\zzzH{\advance\Hc1 }
\def\zzzF{\advance\Fc1 }
\def\zzzC{\advance\Cc1 }
\expandafter\def\csname zzz?\endcsname{\advance\Qc1 }
\expandafter\def\csname zzz!\endcsname#1{}
\begin{document}
\begin{zzz}
one two three
\end{zzz}
\begin{zzz}[CCCH]
one two three
\end{zzz}
\begin{zzz}[FF]
one two three
\end{zzz}
\begin{zzz}[CF?]
one two three
\end{zzz}
\end{document}
答案2
这是一个expl3
实现:\regex_count:nnN
我们可以将一个整数变量设置为字母出现的次数,并用所需重复的次数填充一个标记列表变量。
在这个实现中,我将符号设置在“锻炼”左边的空白处。
\documentclass{article}
\usepackage{xparse,marvosym,amsthm}
\ExplSyntaxOn
\theoremstyle{definition}
\newtheorem{innerexercise}
{
\makebox[0pt][r]{\l__colas_symbols_tl\enspace}Exercise
}
\tl_new:N \l__colas_symbols_tl
\prop_new:N \g_colas_symbols_prop
\clist_new:N \g_colas_symbols_clist
\prop_gset_from_keyval:Nn \g_colas_symbols_prop % the equivalents
{
F=\Lightning,
H=\textasteriskcentered,
C=\Keyboard,
?=?,
}
\clist_gset:Nn \g_colas_symbols_clist { F, H, C, ? } % the final order
\NewDocumentEnvironment{exercise}{o}
{
\IfValueT{#1} { \colas_symbols_add:n { #1 } }
\begin{innerexercise}
}
{
\end{innerexercise}
}
\cs_new_protected:Nn \colas_symbols_add:n
{
\tl_clear:N \l__colas_symbols_tl
\clist_map_inline:Nn \g_colas_symbols_clist
{
\regex_count:nnN { ##1 } { #1 } \l_tmpa_int
\tl_put_right:Nx \l__colas_symbols_tl
{
\prg_replicate:nn { \l_tmpa_int } { \prop_item:Nn \g_colas_symbols_prop { ##1 } }
}
}
}
\ExplSyntaxOff
\begin{document}
\begin{exercise}
Simple one
\end{exercise}
\begin{exercise}[FFFHHC]
Harder one
\end{exercise}
\begin{exercise}[F]
Harder one
\end{exercise}
\begin{exercise}[HHF]
Harder one
\end{exercise}
\begin{exercise}[CHC]
Harder one
\end{exercise}
\begin{exercise}[?]
Harder one
\end{exercise}
\end{document}
答案3
这是一个使用 LuaTeX 的解决方案。
\documentclass{article}
\usepackage{amsthm,marvosym,luacode}
\begin{luacode*}
function convert(str)
local symbols = {
F = "\\Lightning",
H = "\\textasteriskcentered",
C = "\\Keyboard",
["?"] = "?",
}
local order = { "F", "H", "C", "?" }
local count = {}
for c in str:gmatch"." do
count[c] = (count[c] or 0) + 1
end
for _,s in ipairs(order) do
tex.sprint(string.rep(symbols[s],count[s] or 0))
end
end
\end{luacode*}
\newtheoremstyle{exercise}%
{}% space above
{}% space below
{}% body font
{}% indent
{\bfseries}% head font
{.}% punctuation after head
{ }% space around head
{\makebox[0pt][r]{\directlua{convert([[#3]])}\enspace}%
\thmname{#1}\thmnumber{ #2}}% head spec
\theoremstyle{exercise}
\newtheorem{exercise}{Exercise}
\begin{document}
\begin{exercise}
Simple one
\end{exercise}
\begin{exercise}[FFFHHC]
Harder one
\end{exercise}
\begin{exercise}[F]
Harder one
\end{exercise}
\begin{exercise}[HHF]
Harder one
\end{exercise}
\begin{exercise}[CHC]
Harder one
\end{exercise}
\begin{exercise}[?]
Harder one
\end{exercise}
\end{document}