我真的很难理解这个庞大文档中的错误。我花了一些时间找出一个“最小示例”,以便能够准确地发布错误。请在尝试回答时不要更改结构,假设这个“玩具示例”可以轻松重新排列。非常感谢。这是示例。下面我将更详细地解释这些尝试。
% By Dr. Beco - 60 games
\documentclass[a4paper,12pt]{article}
\usepackage[utf8]{inputenc} % accented chars
\usepackage[english]{babel} % translations
\usepackage{graphicx} % includegraphics
\usepackage[ps]{skak} % chess
\usepackage{float} % figure[H]
\usepackage{xstring} % get tokens
%%%%%%%%%%%%%%%%%%%%% define \variable = value
\newcommand{\setvalue}[2]
{
\ifdefined #1
\renewcommand{#1}{#2}
\else
\newcommand{#1}{#2}
\fi
}
%%%%%%%%%%%%%%%%%%%%% fill all needed variables for a section
\newcommand{\setsec}[6]
{
\setvalue{\gnumber}{#1}
\setvalue{\gcolor}{#2}
\setvalue{\gdate}{#3}
\setvalue{\gresult}{#4}
\setvalue{\gopening}{#5}
\setvalue{\gfirstmoves}{#6}
\mysec{\gnumber}{\gcolor}{\gdate}{\gresult}{\gopening}{#6}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%% inicia seção
% parâmetros:
% #1 num. jogo
% #2 minha cor (W ou B)
% #3 Data
% #4 resultado (1:brancas, 0:pretas, 2:empate)
% #5 ECO code seguido do nome da abertura
% #6 Linha principal para mostrar a abertura
\newcommand{\mysec}[6]
{
\section*{Code #1#2, date: #3 result: #4 opening: #5}
\mygamesi{#1}{#2}{#5}{#6}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \mygamesi{Game Number}{Color}{Opening}{Moves}
\newcommand{\mygamesi}[4]
{
\newgame
\mainline{#4}
\begin{figure}[H]
\centering
\showboard
\caption{#1#2, #3}
\label{g1}
\end{figure}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% show some variation on board
% #1 game number \gnumber
% #2 my color \gcolor
% #3 #2 label key for \ref{}
% #4 #3 variation to show (board and caption)
% optional #1 : s=show full var in caption, h=hide, only last move in caption
\newcommand{\myvar}[3][h]
{
\storegame{mainline}
\hidemoves{#3}
\begin{figure}[H]
\centering
\showboard
\ifthenelse{\equal{#1}{s}}{\caption{opt S:position after variation \protect\movecomment{#3}}}{}
\ifthenelse{\equal{#1}{h}}{\caption{opt H:position after variation \protect\movecomment{\protect\StrBefore[2]{#3}{ }} ... \lastmove{}}}{} %<<<<<<<<<<<<<<<<<
\label{gv}
\end{figure}
\restoregame{mainline}
}
%%%%%%%%%%%%%%%%%%%%%%%%%% fim de seção
% #1 num. jogo \gnumber
% #2 minha cor (W ou B) \gcolor
\newcommand{\myend}
{
\begin{figure}[H]
% \includegraphics{\gnumber-graph.png}
[altern. text: evaluation graph]
\caption{\gnumber\gcolor, evaluation graph}
\label{ge}
\end{figure}
}
\tinyboard
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}
\setsec{1}{B}{2017.17.17}{0}{B00 Strange Defense}{1. e3 e5 2. d3 d4 3. Nc3 Bb4}
It was a serious game.
\mainline{4. a3 Bxc3+ 5. bxc3 dxe4 6. Qg4 Nf6 7. Qxg7
Rg8 8. Qh6 c5 9. Bg5 Ng4 }
after \variationcurrent{10. Qxh7 Qxg5 11. Qxe4 Nf6 12. Bb5+ Nbd7} you can see:
my var show:
\myvar[s]{v1}{10. Qxh7 Qxg5 11. Qxe4 Nf6 12. Bb5+ Nbd7}
my var hide:
\myvar[h]{v1}{10. Qxh7 Qxg5 11. Qxe4 Nf6 12. Bb5+ Nbd7}
White resigns
\myend
\end{document}
- 注意:我们使用 PDFLatex
- 有错误的行标记为
%<<<<<<<<<<<<<<<<<
我期望它能做什么
\myvar[s]
将在标题中显示所有棋步。效果很好。\myvar[h]
只会显示字符串的第一步、3 个点和最后一步。这是无法实现的。
问题是我无法给skak
命令的\movecomment{}
标题内添加变量。
我尝试过\def
和的所有组合\edef
,但我不太理解这些组合,所以我更喜欢一种LaTeX
方法。我尝试过\newcommand
和,以及在很多地方DeclareRobustCommand
添加和删除。\protect
这个想法很简单:给定一个带有走法的字符串,比如“1. e4 e5 2. d4 d5”,我想要“第一步”,也就是“1. e4”。skak
包中提供了一个lastmove
可以在 captions 中运行的函数,我甚至读过它的代码。但我无法理解它并进行调整。
我的简单解决方案是:
例如:
\StrBefore[2]{#1}{ }[\firstmove]
进而
\movecomment{\firstmove}
但谁说这有效?我已经尝试并阅读了有关此扩展和宏的资料一段时间了,但我无法解决。
谢谢任何帮助。
編輯:
还有一些不起作用的东西:
\newcommand{\setsec}[6]
{
\setvalue{\gnumber}{#1}
\setvalue{\gcolor}{#2}
\setvalue{\gdate}{#3}
\setvalue{\gresult}{#4}
\setvalue{\gopening}{#5}
\setvalue{\gfirstmoves}{#6}
\mysec{\gnumber}{\gcolor}{\gdate}{\gresult}{\gopening}{#6}
}
最后一行实际上应该是:
\mysec{\gnumber}{\gcolor}{\gdate}{\gresult}{\gopening}{\gfirstmoves}
可惜...
当前解决方案(解决方法)
内部命令
\myvar
:\ifthenelse{\equal{#1}{s}}{\caption{THEN: position after variation \protect\movecomment{#3}}}{\caption{ELSE: position after variation \protect\movecomment{#1} \ldots\ \lastmove{}}}
如果整行都作为标题:
\myvar[s]{v1}{10. Qc4+ Kb8 11. Qd3 Qf6 12. Rd1 Qxf2} % or \myvar{v1}{10. Qc4+ Kb8 11. Qd3 Qf6 12. Rd1 Qxf2}
如果只有第一个和最后一个动作在标题中:
\myvar[22. Qc4+]{v1}{10. Qc4+ Kb8 11. Qd3 Qf6 12. Rd1 Qxf2}
编辑:删除了包多列 - 毕竟不是一个最小示例。;)
答案1
这是该问题的更好的 MWE。
\documentclass[a4paper,12pt]{article}
\usepackage[ps]{skak} % chess
\usepackage{xstring} % get tokens
\begin{document}
Extracted String: \StrBefore[2]{10. Qxh7 Qxg5 11. Qxe4 Nf6 12. Bb5+ Nbd7}{ }
Move Comment: \movecomment{10. Qxh7 Qxg5 11. Qxe4 Nf6 12. Bb5+ Nbd7}
Reduced Move Comment: \movecomment{\StrBefore[2]{10. Qxh7 Qxg5 11. Qxe4 Nf6 12. Bb5+ Nbd7}{ }}
\end{document}
我认为这可能表明 存在根本问题\movecomment
。可能需要巧妙地使用\expandafter
。我试图解决它,但失败了。
一旦上述方法奏效,您就会想将其放入另一个宏中并使用位置参数。然后将其放入传递这些参数的另一个宏调用中。老实说,我看不出您所做的真的是最好的方法。相反,我看到了一种过度设计的方法,它不能在最低级别直接工作,需要尚未知晓的 TeX 级原始命令来强制它即使在最低级别也能工作,并且一旦将其封装在另一层带有位置参数的宏中(宏之上的宏之上的宏),可能会带来更多问题。
啊!
这是一个更简洁方法的起点。首先,我避免在宏中调用宏,也避免将参数从一个宏传递到另一个宏,然后再传递到另一个宏。我只需指定始终需要的内容和可以选择隐藏的内容,而不是费力地搜索字符串以删除空格后的部分。诚然,您说后一种方法是一种“变通方法”。然而,我诚实地选择这种“变通方法”而不是您每天尝试的方法,即使您拥有的方法可行。今天,您要跳过的空格的位置值为 [2]。明天,您可能会决定第三个示例的跳过值应为 [3]。然后,您必须重新硬编码 LaTeX 文档以仅在该点处理这种情况。在下面的方法中,您只需更改传递给宏的第二个和第三个参数的内容\myvar
。
\documentclass[a4paper,12pt]{article}
\usepackage{graphicx} % includegraphics
\usepackage[ps]{skak} % chess
\usepackage{float} % figure[H]
\setlength{\parindent}{0em}
\newcommand{\setvalue}[2]
{
\ifdefined #1
\renewcommand{#1}{#2}
\else
\newcommand{#1}{#2}
\fi
}
\newcommand{\setsec}[5]
{
\setvalue{\gnumber}{#1}
\setvalue{\gcolor}{#2}
\setvalue{\gdate}{#3}
\setvalue{\gresult}{#4}
\setvalue{\gopening}{#5}
\section*{Code \gnumber\gcolor, date: \gdate result: \gresult opening: \gopening}
}
\newcommand{\mygamesi}[1]
{
\setvalue{\gfirstmoves}{#1}
\newgame
\mainline{#1}
\begin{figure}[H]
\centering
\showboard
\caption{\gnumber{}\gcolor{}\gdate{}}
\label{g1}
\end{figure}
}
\newcommand{\myvar}[3][h]
{
\storegame{mainline}
\hidemoves{#2 #3}
\begin{figure}[H]
\centering
\showboard
\ifthenelse{\equal{#1}{s}}
{\caption{opt S:position after variation \protect\movecomment{#2\ #3}}}
{\caption{opt H:position after variation \protect\movecomment{#3}} ... \lastmove{}}
\label{gv}
\end{figure}
\restoregame{mainline}
}
\newcommand{\myend}
{
\begin{figure}[H]
% \includegraphics{\gnumber-graph.png}[altern. text: evaluation graph]
\caption{\gnumber\gcolor, evaluation graph}
\label{ge}
\end{figure}
}
\tinyboard
\begin{document}
\setsec{1}{B}{2017.17.17}{0}{B00 Strange Defense}
\mygamesi{1. e3 e5 2. d3 d4 3. Nc3 Bb4}
It was a serious game.
\mainline{4. a3 Bxc3+ 5. bxc3 dxe4 6. Qg4 Nf6 7. Qxg7
Rg8 8. Qh6 c5 9. Bg5 Ng4 }
after \variationcurrent{10. Qxh7 Qxg5 11. Qxe4 Nf6 12. Bb5+ Nbd7} you can see:
my var show:
\myvar[s]{10. Qxh7 Qxg5}{11. Qxe4 Nf6 12. Bb5+ Nbd7}
my var hide:
\myvar[h]{10. Qxh7 Qxg5}{11. Qxe4 Nf6 12. Bb5+ Nbd7}
White resigns
%
%\myend
\end{document}
我仍然很好奇,有人会发布我发布的 MWE 的解决方案。但我并不抱太大希望。