定义分类的、可改变的变量以供整个文档使用

定义分类的、可改变的变量以供整个文档使用

总结

如何在 LaTeX 文档内的 JSON 文件(或某些类似类型的文件)中打印声明的分类和子分类值?


在我的文档中,我为变量分配了一堆值。例如:

多变的 价值
sheep
cow 哞哞
dog
cat

我想要做的是在整个文档中引用这些变量,并让它们自动扩展到价值列。如果我更新任何值并重新编译文档,更改将传播到整个文档。我知道我可以做这样的事情:

\newcommand{\sheep}{Baa}

但这是不可取的,因为它最终会污染我的文档,文档中会充斥着一堆杂乱无章的宏,而我必须跟踪这些宏。我的序言最终会变成这样:

\newcommand{\sheep}{Baa}
\newcommand{\cow}{Moo}
\newcommand{\dog}{Woof}
\newcommand{\cat}{Meow}
\newcommand{\chicken}{Bawk}
\newcommand{\snake}{Hiss}
\newcommand{\wolf}{Howl}

现在,假设我想把所有这些动物放入一个名为“动物”的类别中。例如,我会在宏中放置一个破折号(即\animals-sheep),但 TeX 不支持这样做。

我想知道是否有一些包或技术可以帮助我使用 JSON 文件(YML 或其他数据交换格式也可以接受)来执行如下操作:

文件: variables.json

{
     "animals": {
          "sheep": "Baa",
          "cow": "Moo",
          "canines": {
               "dog": "Woof",
               "wolf": "Howl",
               "legs": 4
          },
          "cat": "Meow",
          "birds": {
               "chicken": "bawk",
               "robin": "chirp"
          }
     },
     "letters": {
          "a": "alpha",
          "b": "bravo",
          "c": "charlie"
     }
}

然后在我的 LaTeX 文件中:

\documentclass{article}

\title{Animals and Letters}
\autor{Me}

\usepackage{jsonParser}

\jsonInclude{./variables.json}

\begin{document}
     \maketitle
     
     Hello there! Here's a demonstration of some animal sounds:
     
     A dog goes \jsonRef{animals.canines.dog} and has \jsonRef{animals.canines.legs} legs. \\
     % The line above should output "A dog goes Woof and has 4 legs."
     The word \jsonRef{letters.a} starts with the letter ``a"!
     % The line above should output "The word alpha starts with the letter “a”!"
\end{document}

animals.canines.dog如果我在./variables.json将中的值更新为后重新编译该文档"Bark",则输出应该是:

一只狗会叫,有 4 条腿。
单词 alpha 以字母“a”开头!

有人知道我该怎么做这样的事情吗?目前,我正在使用pdfLaTeX,但任何支持bibergls2bib和转义到 shell 的正常工作流(svg例如,对于包)的东西都可以。如果 LuaTeX 是这里的最佳选择(我预计可能是这种情况),请提供带有解释和注释的相应代码。

答案1

我向您展示了任务中比较简单的部分。如何使用由 TeX 基元构造的控制序列保存数据\csname以及\endcsname如何使用它们。您的 JSON 示例必须手动重写到\wdefs 集合中:

\def\wdef#1#2{\expandafter\def \csname word:#1\endcsname {#2}}
\def\jsonRef#1{\ifcsname word:#1\endcsname \csname word:#1\endcsname \else ???\fi}

\wdef {animals.sheep}         {baa}
\wdef {animals.cow}           {Moo}
\wdef {animals.canines.dog}   {Woof}
\wdef {animals.canines.wolf}  {Howl}
\wdef {animals.canines.legs}  {4}
\wdef {animals.cat}           {Meow}
\wdef {animals.birds.chicken} {bawk} 
\wdef {animals.birds.robin}   {chirp}
\wdef {letters.a}             {alpha}
\wdef {letters.b}             {bravo}
\wdef {letters.c}             {charlie}

A dog goes \jsonRef{animals.canines.dog} and has \jsonRef{animals.canines.legs} legs.

The word \jsonRef{letters.a} starts with the letter ``a"!

\wdef定义宏\word:animals.sheep\word:animals.cow\jsonRef宏使用它们。如果未定义宏,则打印???。

注意,所有宏都有共同的前缀word:。你原本的想法是不要使用任何内部前缀,但这是危险的。如果没有前缀,那么(例如)\wdef {hbox}{foo}重新定义 TeX 的内部控制序列\hbox,这可能会导致文档处理完全崩溃。

更复杂的任务是:如何将 JSON 文件示例转换为 s 集\wdef。这可以通过 TeX 宏来实现,但您也可以使用外部转换器。

答案2

LuaLaTeX 格式默认加载lualibs从 ConTeXt 移植过来的包含 JSON 解析器的包。

\documentclass{article}

\title{Animals and Letters}
\author{Me}

\newcommand\jsonInclude[1]{\directlua{
  userdata = userdata or {}
  userdata.json = utilities.json.load("\luaescapestring{#1}")
}}
\newcommand*\jsonRef[1]{\directlua{tex.sprint(userdata.json.#1)}} % pretty unsafe

\jsonInclude{./variables.json}

\begin{document}
     \maketitle
     
     Hello there! Here's a demonstration of some animal sounds:
     
     A dog goes \jsonRef{animals.canines.dog} and has \jsonRef{animals.canines.legs} legs. \\
     % The line above should output "A dog goes Woof and has 4 legs."
     The word \jsonRef{letters.a} starts with the letter ``a"!
     % The line above should output "The word alpha starts with the letter “a”!"
\end{document}

在此处输入图片描述

相关内容