ConTeXt 中的条件交叉引用(\in 和 \at)?

ConTeXt 中的条件交叉引用(\in 和 \at)?

我目前正在为我的学生编写一本全面的理论手册。为了更容易为不同群体的学生编写不同难度的文本,我还大量使用了模式:这些功能使我能够从针对一年级学生的 PDF 中排除针对二年级学生的章节。

为了便于阅读,我还使用了大量交叉引用(\in\at)。不幸的是,当我引用的部分在编译过程中被排除时,这会导致问题:显然,最终的 PDF 现在显示的不是引用,而是类似这样的内容“看章节??”

我想防止这种情况发生。理想情况下,我想设置一个新命令,仅当引用存在且被包含时才显示引用的全文。这可能吗?

为了更清楚地说明我的意思,这里有一个 MWE(通过使用 进行编译可以排除高级部分context --mode=firstyear ...):

\defineblock[advanced]

\startmodeset
  [firstyear]  {\hideblocks[advanced]}
  [secondyear] {\keepblocks[advanced]}
  [default]    {\keepblocks[advanced]}
\stopmodeset

\def\condin#1#2{%
  % the text specified by #1 should be hidden,
  % when the reference #2 does not exist.
}


\starttext

\chapter{Testing Conditional Cross References}


\beginadvanced

\section[sec:advanced]{Advanced Section}

\input{knuth}

\endadvanced


\section[sec:intermediate]{Intermediate Section}

\input{knuth}


\section[sec:beginner]{Beginner Section}

This section explains the topic in beginner's terms
and refers to another chapter for more advanced details:
Please see \in{section}[sec:advanced] for more details.

This whole sentence should be excluded from the PDF,
when the references sec:advanced does not exist.

\stoptext

任何帮助将非常感激。

答案1

ConTeXt 提供了一个命令\doifreferenceelse(的同义词\doifelsereference),其语法如下:

\doifreferenceelse{name}{yes branch}{no branch}

这与其他类似\doif...else宏。

答案2

为了以防万一,有人正在寻找类似问题的解决方案,我在这里发布我所使用的代码。

首先,感谢@Aditya,他让我知道了这个命令\doifreferencefoundelse:这是我需要的最后一个构建块。简而言之,我定义了一个新命令,\condref如下所示:

\startluacode
  userdata = userdata or {}

  function userdata.findreference(str)
    _, _, inreference = string.find(str, "\\in[^%[]*%[([^%]]+)%]")
    _, _, atreference = string.find(str, "\\at[^%[]*%[([^%]]+)%]")
    if inreference == nil then
      context(atreference)
    else
      context(inreference)
    end
  end
\stopluacode

\def\condref#1{%
  \doifreferencefoundelse{\ctxlua{userdata.findreference([[#1]])}}
    {#1}
    {}
}

此命令调用一些 Lua 代码来从参数 #1 中提取精确的交叉引用(由\in{...}[...]或指定\at{...}[...])。然后\doifreferencefoundelse检查交叉引用是否存在:如果存在,则包含参数 #1 的完整代码;但是,如果交叉引用缺失,则删除文本(即不包含任何内容)。(这是我第一次编写 Lua 代码,所以如果有人能帮助我提高代码效率,我会很高兴。例如,我不确定是否有或者可用的构造(如(in|at))?)

我现在可以使用如下命令:

She took down a jar from one of the shelves as she passed; it was labelled
‘ORANGE MARMALADE’ \condref{\footnote{For more information about Orange
Marmelade, please refer to \in{section}[sec:marmalade].}}, but to her
great disappointment it was empty: she did not like to drop the jar for
fear of killing somebody, so managed to put it into one of the cupboards
as she fell past it.

如果引用的部分sec:marmalade存在,则包含整个脚注;如果不存在(在我的情况下,这可能是由于该部分被编译模式排除而发生的),则脚注将被省略。

希望有所帮助。

相关内容