定义一个命令(如目录),但针对与会者

定义一个命令(如目录),但针对与会者

我正在为一个俱乐部编写模板/课程,用于会议的官方协议。

因此,我们需要在协议开始时列出与会者的名单,并且在人员离开时,我们需要记录该人员离开(或加入或返回)的时间。

我想要定义 3 个命令\maketableofattendees, \joins[time]{Name}, \leaves[time]{Name}

参会者表应显示所有参会者的名单,包括他们第一次加入的时间和最后一次离开的时间。

还应该在协议中发生相应动作的位置打印连接和离开(例如发生连接或离开命令的地方)。

我该如何实现这个?

编辑:

输入示例:

\maketableofattendees{Attendees}
\joins[20:00]{Adam}
\joins[20:00]{Bob}

\section{First Topic}
Adam Speaks about a great topic and does a long speech.
First Poll: \attendeecount People Present. Yes: 2, No: 0

\joins[20:15]{Charlie}

\section{Second Topic}
Bob speaks about the second topic.
Second Poll: \attendeecount People Present. Yes: 1, No :2
\leaves[20:30]{Bob}

\section{Third Topic}
Adam speaks about the third topic.
Second Poll: \attendeecount People Present. Yes: 1, No :1

这将产生类似这样的结果:

Attendees:
Adam (From 20:00 to end)
Bob (From 20:00 to 20:30)
Charlie (From 20:15 to end)

#First Topic
Adam Speaks about a great topic and does a long speech.
First Poll: 2 People Present. Yes: 2, No: 0

== 20:15 Charlie enters the Meeting

# Second Topic
Bob speaks about the second topic.
Second Poll: 3 People Present. Yes: 1, No :2

== 20:30 Bob leaves the meeting

# Third Topic
Adam speaks about the third topic.
Second Poll: 2 People Present. Yes: 1, No :1

答案1

可以使用参考文献包。它在 CTAN 上不可用,因此需要手动安装到$TEXMFHOME/tex/latex/rdfref目录。

我会稍微修改一下你的 TeX 文件:

\documentclass{article}
\usepackage{attendees}
\begin{document}

\maketableofattendees{Attendees}
\maketableofpolls{Polls}


\joins[20:00]{Adam}
\joins[20:00]{Bob}

\topic{First Topic}
Adam Speaks about a great topic and does a long speech.

\poll{First Poll}{2}{0}
% First Poll: \attendeecount People Present. Yes: 2, No: 0

\joins[20:15]{Charlie}

\topic{Second Topic}
Bob speaks about the second topic.

\poll{Second Poll}{1}{2}%: \attendeecount People Present. Yes: 1, No :2
\leaves[20:30]{Bob}

\topic{Third Topic}
Adam speaks about the third topic.

\poll{Third Poll}{1}{1}%: \attendeecount People Present. Yes: 1, No :1

\end{document}

它使用attendees自定义包,其中包含文档中使用的命令的定义。我添加了一些新命令,即\maketableofpolls列出使用的投票和主题、\topic代替使用的命令\section以及\poll记录投票名称、投票并打印它们的命令。

这是attendees.sty包裹:

\ProvidesPackage{attendees}
\RequirePackage{rdfref-user,rdfref-query}


\newcommand\maketableofpolls[1]{%
  \section*{#1}%
  \Bind{?topic}{rdf:type}{at:topic}{%
    \noindent\textbf{\GetValProperty{?topic}{at:topicName}}\dotfill\GetValProperty{?topic}{doc:pageNo}\par
    \Bind{?poll}{at:pollTopic}{?topic}{%
      \noindent \quad\GetValProperty{?poll}{at:pollName}. Yes: \GetValProperty{?poll}{at:pollYes}, no: \GetValProperty{?poll}{at:pollNo}\dotfill\GetValProperty{?poll}{doc:pageNo}\par
    }
  } 
}

% \newcommand\at@printpoll

\newcommand\maketableofattendees[1]{%
  \section*{#1}%
  \Bind{?name}{rdf:type}{at:attendee}{%
    % \GetVal prints the variable name, \GetValProperty extracts property from the name
    % Set the default left time
    \def\at@left{end}%
    % use the real at:left if it has been set
    \IfProperty{\GetVal{?name}}{at:left}{\def\at@left{\GetValProperty{?name}{at:left}}}{}%
    \at@printname{\GetValProperty{?name}{at:name}}{\GetValProperty{?name}{at:joined}}{\at@left}%
  }%
}

\newcommand\at@printname[3]{\noindent\textbf{#1}~(From #2 to #3)\par}


\newcommand\topic[1]{%
  \section{#1}%
  \BlankNode%
  \AddProperty{rdf:type}{at:topic}%
  \AddPropertyEx{doc:pageNo}{\thepage}% save the page number
  \AddProperty{at:topicName}{#1}%
  \edef\CurrentTopic{\CurrentObject}% we want to reference the current topic in the poll
}
\newcommand\joins[2][]{%
  \WithObject{#2}{%
    \AddProperty{rdf:type}{at:attendee}%
    \AddProperty{at:name}{#2}%
    \AddProperty{at:joined}{#1}%
    \AddProperty{is:active}{yes}
  }%
}

\newcommand\leaves[2][]{%
  \WithObject{#2}{%
    \AddProperty{at:left}{#1}%
    \AddProperty{is:active}{} % remove the is:active property, so it doesn't pollute next \poll
  }%
}


\newcounter{poll@count}
\newcommand\poll[3]{%
  \setcounter{poll@count}{0}%
  \BlankNode%
  \AddProperty{rdf:type}{at:poll}%
  \AddPropertyEx{doc:pageNo}{\thepage}%
  \AddProperty{at:pollName}{#1}%%
  \AddPropertyEx{at:pollTopic}{\CurrentTopic}%
  \AddProperty{at:pollYes}{#2}%
  \AddProperty{at:pollNo}{#3}%
  % process all attendands%
  \Bind{?name}{rdf:type}{at:attendee}{%%
    % execute the code only on active attendands
    \IfProperty{\GetVal{?name}}{is:active}{\stepcounter{poll@count}}{}
  }%
  \par
  \medskip%
  \noindent\textbf{#1}: \arabic{poll@count} People Present. Yes: #2, No: #3\par
}%

\AtBeginDocument{%
  % reset attendands
  \Bind{?name}{rdf:type}{at:attendee}{\SetProperty{\GetVal{?name}}{is:active}{}}
}

\endinput

这里发生了很多事情。rdfref提供可以设置对象属性的命令。这些属性保存到辅助文件中,因此它们在下一次编译时从文档开头即可使用。这意味着每次对象更改时,文档都需要进行两次编译!

对象有两种类型:命名对象和匿名对象。在我们的示例中,命名对象是可以加入和离开会议的人。以下命令:

\newcommand\leaves[2][]{%
  \WithObject{#2}{%
    \AddProperty{at:left}{#1}%
    \SetProperty{#2}{is:active}{} % remove the is:active property, so it doesn't pollute next \poll
  }%
}

将设置人员离开的时间并使该人员处于非活动状态,因此不会在下一次轮询中计算。该\WithObject命令将人员姓名设置为当前对象标识符,并将属性保存到此对象。

使用了两个属性处理命令。第一个是\AddProperty,它设置当前对象的属性并将其保存到文件中aux,这意味着下次编译文档时将恢复此属性,并且从头开始可用。例如,它使我们能够制作参加者列表和民意调查列表。其他类型的属性只是临时的,例如在这种情况下,我们只需要在下一次民意调查计数中禁用此人。我们可以使用命令\SetProperty。它需要一个明确的对象标识符作为第一个参数。

相反,每个轮询都会创建匿名对象:

\newcommand\poll[3]{%
  \setcounter{poll@count}{0}%
  \BlankNode%
  \AddProperty{rdf:type}{at:poll}%
  \AddPropertyEx{doc:pageNo}{\thepage}%
  ...

创建\BlankNode一个匿名对象并且后续\AddProperty命令为其设置属性。\AddPropertyEx可用于保存宏的扩展值,例如我们例子中的页码。

可以使用以下命令查询属性\Bind

\newcommand\maketableofpolls[1]{%
  \section*{#1}%
  \Bind{?topic}{rdf:type}{at:topic}{%
    \noindent\textbf{\GetValProperty{?topic}{at:topicName}}\dotfill\GetValProperty{?topic}{doc:pageNo}\par
    \Bind{?poll}{at:pollTopic}{?topic}{%
      \noindent \quad\GetValProperty{?poll}{at:pollName}. Yes: \GetValProperty{?poll}{at:pollYes}, no: \GetValProperty{?poll}{at:pollNo}\dotfill\GetValProperty{?poll}{doc:pageNo}\par
    }
  } 
}

它需要四个参数。前三个是查询,最后一个是在匹配的属性上执行的代码。在本例中,我们首先查找所有主题。对于每个对象,我们设置rdf:type属性,at:topic用于主题、at:poll用于投票和at:attendee用于与会者。因此,我们需要搜索所有设置rdf:type为的对象at:topic

  \Bind{?topic}{rdf:type}{at:topic}{%

参数?topic是一个变量,它将在第四个参数中包含执行代码中的主题对象标识符。这里我们可以使用以下命令获取对象的各种参数\GetValProperty

    \noindent\textbf{\GetValProperty{?topic}{at:topicName}}\dotfill\GetValProperty{?topic}{doc:pageNo}\par

在这种情况下,使用主题名称和其起始的页码。

\Bind命令可以嵌套。要获取某个主题的所有民意调查,我们可以使用以下命令,该命令嵌套在上一个命令中\Bind

    \Bind{?poll}{at:pollTopic}{?topic}{%

这里使用了两个变量。?topic是从父绑定设置的,因此它包含当前主题对象。因此,?poll此命令中只搜索。

\Bindin 在命令中的另一种用法\poll是用于计算当前的参加人数:

 \Bind{?name}{rdf:type}{at:attendee}{%%
    % execute the code only on active attendands
    \IfProperty{\GetVal{?name}}{is:active}{\stepcounter{poll@count}}{}
  }%

\IfProperty命令测试对象是否具有属性。\GetVal从绑定变量中获取对象标识符。

由于所有属性都设置为辅助文件,因此它们具有与文档末尾相同的值。因此,有必要在文档开始时将所有与会者设置为非活动状态,并仅在命令中启用它们\join

\AtBeginDocument{%
  % reset attendands
  \Bind{?name}{rdf:type}{at:attendee}{\SetProperty{\GetVal{?name}}{is:active}{}}
}

直接\SetProperty将属性设置为对象。如果值为空,则删除该属性。

结果如下:

在此处输入图片描述

相关内容