自动分类环境的建议

自动分类环境的建议

微电子工程协会

背景

本网站有很好的例子 如何绘制分类层次树图但通常你必须只显示一个具体群体或单个物种在长分类中的位置。那么树就没有用了。一个解决方案是简单地以纯文本显示有序的分类单元:

Class Mammalia C. Linnaeus, 1758
Order Primates C. Linnaeus, 1758
Superfamily Hominoidea (Gray, 1825) 
Family Hominidae  Gray, 1825
Genus Homo C. Linnaeus, 1758
Homo sapiens  C. Linnaeus, 1758

这是正确的,但通常以分层缩进来显示,从而产生倾斜的边距(看起来好多了,而且在我看来更容易理解):

Class Mammalia Linnaeus, 1758
 Order Primates Linnaeus, 1758
  Superfamily Hominoidea (Gray, 1825) 
   Family Hominidae  Gray, 1825
    Genus Homo Linnaeus, 1758
     Species Homo sapiens Linnaeus, 1758

在 LaTeX 中手动获取上述内容很容易,但如果科学名称也与左边距平行缩进,效果会更好。使用表格环境可以手动完成此操作,因此您可以获得:

Class           Mammalia Linnaeus, 1758
 Order           Primates Linnaeus, 1758
  Superfamily     Hominoidea (Gray, 1825)
   Family          Hominidae  Gray, 1825
    Genus           Homo Linnaeus, 1758
     Especies        Homo sapiens Linnaeus, 1758

但需要大量输入,并且任何分类单元都Mammalia必须位于所有组级别(FamilyGenus等)的右侧。对于此示例,这在一列中可能没问题,但在较长的分类(20-25 行)或两列文档中,水平空间有限,那么最好从 Mamalia的末尾左侧开始Species

Class        Mammalia Linnaeus, 1758
  Order        Primates Linnaeus, 1758
    Superfamily  Hominoidea (Gray, 1825) 
      Family       Hominidae Gray, 1825
        Genus        Homo Linnaeus, 1758
          Species      Homo sapiens Linnaeus, 1758

并根据需要减少压痕长度:

Class        Mammalia Linnaeus, 1758
 Order        Primates Linnaeus, 1758
  Superfamily  Hominoidea (Gray, 1825) 
   Family       Hominidae Gray, 1825
    Genus        Homo Linnaeus, 1758
     Species      Homo sapiens Linnaeus, 1758

由于这无法在表格中(轻易地)完成,我认为在一个环境中可以(或多或少)“自动”地完成这一点。

期望目标

理想情况下,环境(或任何其他方法)应该无需在纯文本中输入任何(尽可能少)LaTeX 命令即可工作:

\begin{taxonomy}
Class Mammalia Linnaeus, 1758
Order Primates Linnaeus, 1758
Superfamily Hominoidea (Gray, 1825) 
Family Hominidae Gray, 1825
Genus Homo Linnaeus, 1758
Homo sapiens  Linnaeus, 1758
\end{taxonomy}

和:

  • 在不减小字体大小的情况下,尽量不要断行。也就是说,如果某行的文本占用的空间超过 1\linewidth默认间距,则必须将该间距减小到合理的值。

  • 如果整个环境占用的空间小于\linewidth,则必须将其居中(显然,不会丢失格式)。

但这是我迄今为止的幼稚尝试:

\documentclass[12pt]{article}
\usepackage{lipsum,xcolor}

\newcounter{line}
\def\doline#1{\addtocounter{line}{1}\hspace{\value{line}\parindent}#1}

\def\marker{\end{taxonomicon}}
{\obeylines
\gdef\getlines#1
  {\def\text{#1}%
  \ifx\text\marker \let\next\text
    \else \doline{#1}\let\next\getlines \fi
  \next}}
\newenvironment{taxonomicon}{\sffamily\hfill\begingroup\obeylines\getlines}%
  {\setcounter{line}{0}\endgroup}

\newcommand\taxon[2]{
\makebox[7em][l]{\color{gray}#1\dotfill}
#2
}

\begin{document}

\lipsum[1]

% poor man's version

\parindent=1.7em % adjust as needed

\begin{taxonomicon} 
Class Mammalia C. Linnaeus, 1758
Order Primates C. Linnaeus, 1758
Superfamily Hominoidea (Gray, 1825) 
Family Hominidae  Gray, 1825
Genus Homo C. Linnaeus, 1758
Homo sapiens  C. Linnaeus, 1758

\end{taxonomicon}

\lipsum[2]

\parindent=1.2em % adjust as needed

\begin{taxonomicon} 
\taxon{Class}{Mammalia Linnaeus, 1758}
\taxon{Order}{Primates Linnaeus, 1758}
\taxon{Superfamily}{Hominoidea (Gray, 1825)}
\taxon{Family}{Hominidae  Gray, 1825}
\taxon{Genus}{Homo Linnaeus, 1758}
\taxon{Species}{Homo sapiens} Linnaeus, 1758

\end{taxonomicon}

\lipsum[3]
\end{document}

注意:我只要求一种分类解决方案,该分类在每一行中总是下降 1 个级别(无论文本的实际含义如何),但是对于更复杂的分类(例如,有两个科和几个属)的建议会很棒。

答案1

您的规范非常复杂。这是一个不完整的解决方案,其中第二部分总是从最长的第一部分开始。

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentEnvironment{taxonomy}{O{1em}}
 {
  \begin{center}
  \taxon_get_line:
 }
 {
  \taxon_print:n { #1 }
  \end{center}
 }

\seq_new:N \l_taxon_item_seq
\seq_new:N \l_taxon_itemsA_seq
\seq_new:N \l_taxon_itemsB_seq
\dim_new:N \l_taxon_width_dim
\dim_new:N \l_taxon_indent_dim
\dim_new:N \l_taxon_default_indent_dim
\box_new:N \l_taxon_item_box

\cs_new_protected:Npn \taxon_get_line:
 {
  \peek_meaning_ignore_spaces:NF \end { \taxon_get_line:w }
 }

\cs_new_protected:Npn \taxon_get_line:w #1 \\
 {
  \seq_set_split:Nnx \l_taxon_items_seq { ~ } { \tl_trim_spaces:n { #1 } }
  \seq_pop_left:NN \l_taxon_items_seq \l_tmpa_tl
  \seq_put_right:NV \l_taxon_itemsA_seq \l_tmpa_tl
  \seq_put_right:Nx \l_taxon_itemsB_seq { \seq_use:Nn \l_taxon_items_seq { ~ } }
  \taxon_get_line:
 }

\cs_new_protected:Npn \taxon_print:n #1
 {
  \dim_zero:N \l_taxon_indent_dim
  \dim_set:Nn \l_taxon_default_indent_dim { #1 }
  \seq_map_inline:Nn \l_taxon_itemsA_seq
   {
    \hbox_set:Nn \l_taxon_item_box { \hspace{ \l_taxon_indent_dim } ##1 }
    \dim_compare:nT { \l_taxon_width_dim < \box_wd:N \l_taxon_item_box }
     {
      \dim_set:Nn \l_taxon_width_dim { \box_wd:N \l_taxon_item_box }
     }
    \dim_add:Nn \l_taxon_indent_dim { \l_taxon_default_indent_dim }
   }
  \dim_add:Nn \l_taxon_width_dim { \l_taxon_default_indent_dim }
  \dim_zero:N \l_taxon_indent_dim
  \leavevmode
  \vbox:n
   {
    \seq_mapthread_function:NNN \l_taxon_itemsA_seq \l_taxon_itemsB_seq \taxon_print_line:nn
   }
 }
\cs_new_protected:Npn \taxon_print_line:nn #1 #2
 {
  \hbox:n { \hspace{ \l_taxon_indent_dim } \makebox[\l_taxon_width_dim][l]{#1\dotfill}#2 }
  \dim_add:Nn \l_taxon_indent_dim { \l_taxon_default_indent_dim }
 }

\cs_generate_variant:Nn \seq_set_split:Nnn { Nnx }
\ExplSyntaxOff

\begin{document}

\begin{taxonomy}
Class Mammalia Linnaeus, 1758 \\
Order Primates Linnaeus, 1758 \\
Superfamily Hominoidea (Gray, 1825) \\
Family Hominidae Gray, 1825 \\
Genus Homo Linnaeus, 1758 \\
Species Homo sapiens  Linnaeus, 1758 \\
\end{taxonomy}

\begin{taxonomy}[.5em]
Class Mammalia Linnaeus, 1758 \\
Order Primates Linnaeus, 1758 \\
Superfamily Hominoidea (Gray, 1825) \\
Family Hominidae Gray, 1825 \\
Genus Homo Linnaeus, 1758 \\
Species Homo sapiens  Linnaeus, 1758 \\
\end{taxonomy}

\end{document}

在此处输入图片描述

添加“备份”更正

可以通过添加第二个可选参数来实现评论中的想法。

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentEnvironment{taxonomy}{O{1em}O{0pt}}
 {
  \begin{center}
  \taxon_get_line:
 }
 {
  \taxon_print:nn { #1 } { #2 }
  \end{center}
 }

\seq_new:N \l_taxon_item_seq
\seq_new:N \l_taxon_itemsA_seq
\seq_new:N \l_taxon_itemsB_seq
\dim_new:N \l_taxon_width_dim
\dim_new:N \l_taxon_indent_dim
\dim_new:N \l_taxon_default_indent_dim
\dim_new:N \l_taxon_corr_dim
\box_new:N \l_taxon_item_box

\cs_new_protected:Npn \taxon_get_line:
 {
  \peek_meaning_ignore_spaces:NF \end { \taxon_get_line:w }
 }

\cs_new_protected:Npn \taxon_get_line:w #1 \\
 {
  \seq_set_split:Nnx \l_taxon_items_seq { ~ } { \tl_trim_spaces:n { #1 } }
  \seq_pop_left:NN \l_taxon_items_seq \l_tmpa_tl
  \seq_put_right:NV \l_taxon_itemsA_seq \l_tmpa_tl
  \seq_put_right:Nx \l_taxon_itemsB_seq { \seq_use:Nn \l_taxon_items_seq { ~ } }
  \taxon_get_line:
 }

\cs_new_protected:Npn \taxon_print:nn #1 #2
 {
  \dim_zero:N \l_taxon_indent_dim
  \dim_set:Nn \l_taxon_default_indent_dim { #1 }
  \dim_set:Nn \l_taxon_corr_dim { #2 }
  \seq_map_inline:Nn \l_taxon_itemsA_seq
   {
    \hbox_set:Nn \l_taxon_item_box { \hspace{ \l_taxon_indent_dim } ##1 }
    \dim_compare:nT { \l_taxon_width_dim < \box_wd:N \l_taxon_item_box }
     {
      \dim_set:Nn \l_taxon_width_dim { \box_wd:N \l_taxon_item_box }
     }
    \dim_add:Nn \l_taxon_indent_dim { \l_taxon_default_indent_dim }
   }
  \dim_add:Nn \l_taxon_width_dim { \l_taxon_default_indent_dim }
  \dim_zero:N \l_taxon_indent_dim
  \leavevmode
  \vbox:n
   {
    \seq_mapthread_function:NNN \l_taxon_itemsA_seq \l_taxon_itemsB_seq \taxon_print_line:nn
   }
 }
\cs_new_protected:Npn \taxon_print_line:nn #1 #2
 {
  \hbox:n
   {
    \hspace{ \l_taxon_indent_dim }
    \makebox[\l_taxon_width_dim][l]{#1\dotfill\hspace{ -\l_taxon_corr_dim }}
    \hspace{ \l_taxon_corr_dim }
    #2
   }
  \dim_add:Nn \l_taxon_indent_dim { \l_taxon_default_indent_dim }
 }

\cs_generate_variant:Nn \seq_set_split:Nnn { Nnx }
\ExplSyntaxOff

\begin{document}

\begin{taxonomy}
Class Mammalia Linnaeus, 1758 \\
Order Primates Linnaeus, 1758 \\
Superfamily Hominoidea (Gray, 1825) \\
Family Hominidae Gray, 1825 \\
Genus Homo Linnaeus, 1758 \\
Species Homo sapiens  Linnaeus, 1758 \\
\end{taxonomy}

\begin{taxonomy}[2em][-6em]
Class Mammalia Linnaeus, 1758 \\
Order Primates Linnaeus, 1758 \\
Superfamily Hominoidea (Gray, 1825) \\
Family Hominidae Gray, 1825 \\
Genus Homo Linnaeus, 1758 \\
Species Homo sapiens  Linnaeus, 1758 \\
\end{taxonomy}

\end{document}

在此处输入图片描述

相关内容