我想用 latex 制作一个 hangman 命令,其用途是 \hangman[]{word to guess},其规格如下:
- 开关 \ifhide 允许显示刽子手或答案;
- 刽子手或答案都出现在相同大小的框中;
- 可选参数指定框的水平缩放比例;
- 在隐藏模式下,空格和连字符不应被隐藏。
第一个脚本满足 1、2 和 3,但不满足 4。另外,当命令不是行首时,会添加不必要的额外空格。
\documentclass[11pt]{article}
\usepackage{calc} % for \widthof{text}
\usepackage{graphicx}
\usepackage{xstring}
\usepackage{multido}
\setlength\parindent{0pt}
\newlength{\txtwidth}
\newlength{\txtheight}
\newif\ifhide
\newcommand{\hangman}[2][1.25]{
\settowidth{\txtwidth}{#2}
\settoheight{\txtheight}{#2}
\StrLen{#2}[\n]
\ifhide
\resizebox{#1\txtwidth}{!}{ \multido{\i=1+1}{\n}{\_\hspace{0.5ex}} }
\else
\makebox[#1\txtwidth]{\Large{#2}}
\fi
}
\begin{document}
\textbf{Test results:} \\
\hidefalse\hangman{test 1}: test with the default size and a space.\\
\hidetrue\hangman{test 1}: test with the default size and a space: needs to show the space.\\
\hidefalse\hangman[2]{test-2}: test with the modified size and a hyphen.\\
\hidetrue\hangman[2]{test-2}: test with the modified size and a hyphen: needs to show the hyphen.\\
Not begining the line: \hidefalse\hangman[2]{test 3}: needs to remove the extra space.\\
Not begining the line: \hidetrue\hangman[2]{test 3}: needs to remove the extra space.\\[5mm]
\end{document}
我尝试了两次修改 \ifhide 指令来满足第 4 个条件。两次都产生了错误:
第一次修改:
\resizebox{#1\txtlargeur}{!}{ \multido{\k=1+1}{\n}{ \def\chark{\StrChar{#2}{\k}} \IfStrEqCase{\chark}{{ }{ }{-}{-}}[\chark] } }
给出了错误(不要相信行号):
! 未定义控制序列。\multido {\k =1+1}{\n }{ \def \chark {\StrChar {test 1}{\k }} \IfStrEqCase {\c l.28 \hidetrue\hangman{test 1} : 使用默认 s 测试 $\backslash$hangman... 错误消息顶行末尾的控制序列从未被 \def 过。如果您拼错了(例如,
\hobx'), type
I')和正确的拼写(例如,`I\hbox')。否则继续,我会忘记未定义的内容。
第二次修改:
\resizebox{#1\txtlargeur}{!}{%
\newcounter{k} \setcounter{k}{0}
\makeatletter
\@whilenum\value{k}<\n \do{%
\def\chark{\StrChar{#2}{\value{k}}}
\IfStrEqCase{\chark}{{ }{ }{-}{-}}[\chark]%
\stepcounter{k}
}%
\makeatother
}
给出了错误:
l.40 \hidetrue\hangman{test 1}:使用默认 s 测试 $\backslash$hangman……这里应该有一个数字;我插入了“0”。
欢迎任何帮助。
答案1
这能满足您的要求吗?我没有使用条件,而是使用 *-variant 实现了显示。我认为,这里需要等宽字体。
\documentclass{article}
\usepackage{graphicx}
\ExplSyntaxOn
\NewDocumentCommand{\hangmanrule}{}
{
\makebox[0.5em]{\hspace{0.4pt}\hrulefill\hspace{0.4pt}}
}
\NewDocumentCommand{\hangman}{sO{1.25}m}
{% #1 = optional * shows the word
% #2 = optional scale
% #3 = word
\scalebox{#2}
{% scale the result
\ttfamily
\IfBooleanTF{#1}
{% just show the word
#3
}
{% letters must become rules
\mathteacher_hangman_hide:n { #3 }
}
}
}
\cs_new_protected:Nn \mathteacher_hangman_hide:n
{
\tl_set:Nn \l__mathteacher_hangman_tl { #1 }
\regex_replace_all:nnN { [^-\s] } { \c{hangmanrule} } \l__mathteacher_hangman_tl
\tl_use:N \l__mathteacher_hangman_tl
}
\ExplSyntaxOff
\begin{document}
\hangman*{test}
\hangman{test}
\medskip
\hangman*{test-1}
\hangman{test-1}
\medskip
\hangman*[2]{this is a longer-larger test}
\hangman[2]{this is a longer-larger test}
\end{document}
使用“显示/隐藏”的全局设置:
\documentclass{article}
\usepackage{graphicx}
\ExplSyntaxOn
\NewDocumentCommand{\hangmanrule}{}
{
\makebox[0.5em]{\hspace{0.4pt}\hrulefill\hspace{0.4pt}}
}
\bool_new:N \g_mathteacher_hangman_show_bool
\NewDocumentCommand{\hangmanshow}{}
{
\bool_gset_true:N \g_mathteacher_hangman_show_bool
}
\NewDocumentCommand{\hangmanhide}{}
{
\bool_gset_false:N \g_mathteacher_hangman_show_bool
}
\NewDocumentCommand{\hangman}{O{1.25}m}
{% #1 = optional scale
% #2 = word
\scalebox{#1}
{% scale the result
\ttfamily
\bool_if:NTF \g_mathteacher_hangman_show_bool
{% just show the word
#2
}
{% letters must become rules
\mathteacher_hangman_hide:n { #2 }
}
}
}
\cs_new_protected:Nn \mathteacher_hangman_hide:n
{
\tl_set:Nn \l__mathteacher_hangman_tl { #1 }
\regex_replace_all:nnN { [^-\s] } { \c{hangmanrule} } \l__mathteacher_hangman_tl
\tl_use:N \l__mathteacher_hangman_tl
}
\ExplSyntaxOff
\begin{document}
\section{Show}
\hangmanshow
\hangman{test}
\medskip
\hangman{test-1}
\medskip
\hangman[2]{this is a longer-larger test}
\section{Hide}
\hangmanhide
\hangman{test}
\medskip
\hangman{test-1}
\medskip
\hangman[2]{this is a longer-larger test}
\end{document}