键值版本

键值版本

我正在尝试从 RPG 角色表重新创建一个表格:

在此处输入图片描述

我并不特别在意颜色,黑白就很好,主要问题是尺寸。我要复制多份此表,我希望所有副本都是统一的。因此,即使每个数据值都是空白的,也只会生成一个与已填写版本具有相同测量值的空白表。

我希望每个框具有(大致)以下宽度(相对于总表格宽度):

  • 姓名:70%,班级:30%
  • 射程:21%,射速:37%,伤害:40%
  • 笔:21%,弹夹 18%,重装:18%,重量:14%,可用性:19%
  • 特殊:100%

用测量值代替表格数据的草图(未按比例绘制):

在此处输入图片描述

这些宽度是为了使表格在布局方面尽可能接近原始表格。我对 LaTeX 还比较陌生,而且除了基本数据表之外,对其他操作也非常陌生。我能想到的唯一方法是制作 100 列,然后使用。\multicolumn{% above}然而,即使使用这种冗长的方法,由于 LaTeX 喜欢将所有内容都做得尽可能小,最右边的列不会有其全宽,并且它会根据数据创建不同大小的表格。

我查看了相当多关于固定长度表列的问题,但所有问题似乎都是将其固定为小于其中的文本(导致多重),而不是希望保持大小相同并允许空白空间填补空白。

对于某些情况,目标是有一个宏,我可以为每个框输入数据,然后该宏会创建表格的副本,并填充输入的数据。我已经对宏进行了排序,问题只是表格的格式/布局。

这是我的宏代码:

\documentclass[11pt]{article}


\usepackage{fancyhdr}

\oddsidemargin 0.2cm
\topmargin -1.0cm
\textheight 24.0cm
\textwidth 15.25cm
\parindent=0pt
\parskip 1ex
\pagestyle{fancy}

\newcommand{\printweptable}{
\begin{tabular}{p{\linewidth}}
 Name: \name \hfill Cls: \class \\
 Rng: \range    \hfill RoF: \rof \hfill Rmg: \dmg\\
 Pen: \pen \hfill Clip: \clip \hfill Rld: \rld \hfill Wt: \wt \hfill Avl: \avl\\
 Special: \special
\end{tabular}
}

%Weapon info
\newcommand{\setwepstats}[9]{%
\def\name{#1}%
\def\class{#2}%
\def\range{#3}%
\def\rof{#4}%
\def\dmg{#5}%
\def\pen{#6}%
\def\clip{#7}%
\def\rld{#8}%
\def\wt{#9}
\wepstatsrelay
}%

\def\wepstatsrelay#1#2{
\def\avl{#1}%
\def\special{#2}}%

\begin{document}

\setwepstats{Name}{Class}{Range}{RoF}{Damage}{Pen}{Clip}{Reload}{Wt}{Availability}{Special}

\printweptable

\setwepstats{}{}{}{}{}{}{}{}{}{}{}

\printweptable

\end{document}

我想我应该使用 Werner 提供的代码,并废弃我原有的宏(他的宏看起来更简洁,更容易使用和重用)。

我现在已经合并了 Werner 和 cfr 提供的代码,并得到了以下工作代码:

\documentclass{article}

\usepackage{xkeyval}

\makeatletter
\define@cmdkey{rpg}[char@]{name}[]{}
\define@cmdkey{rpg}[char@]{class}[]{}
\define@cmdkey{rpg}[char@]{range}[]{}
\define@cmdkey{rpg}[char@]{rof}[]{}
\define@cmdkey{rpg}[char@]{damage}[]{}
\define@cmdkey{rpg}[char@]{pen}[]{}
\define@cmdkey{rpg}[char@]{clip}[]{}
\define@cmdkey{rpg}[char@]{reload}[]{}
\define@cmdkey{rpg}[char@]{weight}[]{}
\define@cmdkey{rpg}[char@]{availability}[]{}
\define@cmdkey{rpg}[char@]{special}[]{}
\define@cmdkey{rpg}[char@]{mods}[]{}
\define@cmdkey{rpg}[char@]{qualities}[]{}
\define@cmdkey{rpg}[char@]{width}[\linewidth]{}

\newcommand{\statlabel}{\textsc}

\usepackage{calc,xparse}
\newlength\mycardwidth
\setlength\mycardwidth{.75\textwidth}
\NewDocumentCommand \boxme { O{} }{%
  \fbox{%
    \parbox{\linewidth-2\fboxrule-2.5\fboxsep}{\strut #1}%
  }%
}
\NewDocumentCommand \pageme { O{} O{} }{%
  \begin{minipage}{#1\mycardwidth}
    \centering\boxme[#2]
  \end{minipage}%
}
\NewDocumentCommand \cardme { O{.75\textwidth} +m }{%
  \setlength\mycardwidth{#1-2\fboxrule-2\fboxsep}%
  \fbox{%
    \begin{minipage}{\mycardwidth}
      \centering
      #2%
    \end{minipage}%
  }%
}

\newcommand{\setcharacterstats}[1]{%
  \begingroup
  \setkeys{rpg}{name,class,range,rof,damage,pen,clip,reload,weight,availability,special,mods,qualities,width,#1}%
  \noindent
  \centering
  \cardme[\textwidth]{%
    \pageme[.69][\statlabel{Name}: \char@name]%
    \pageme[.31][\statlabel{Cls}: \char@class]

    \pageme[.22][\statlabel{Rng}: \hfill \char@range \hfill m]%
    \pageme[.38][\statlabel{RoF}: \char@rof]%
    \pageme[.4][\statlabel{Dmg}: \char@damage]

    \pageme[.22][\statlabel{Pen}: \char@pen]%
    \pageme[.19][\statlabel{Clip}: \char@clip]%
    \pageme[.19][\statlabel{Rld}: \char@reload]%
    \pageme[.18][\statlabel{Wt}: \hfill \char@weight \hfill kg]%
    \pageme[.22][\statlabel{Avl}: \char@availability]

    \pageme[][\statlabel{Special}: \char@special]%

    \pageme[][\statlabel{Mods}: \char@mods]%

    \pageme[][\statlabel{Qualities}: \char@qualities]%
  }
}
\makeatletter


%-----------------------------------
\begin{document}

\setcharacterstats{
  name = Long Las,
  class = Basic,
  range = 150,
  rof = S/-/-,
  damage = 1d10+3,
  pen = 1,
  clip = 40,
  reload = Full,
  weight = 4.5,
  availability = Scarce,
  special = Accurate Felling (4) Reliable
  }


\end{document}

但是,有了该代码,是否有办法将变量数据置于单元格剩余空间的中心?例如,如果我将名称设为 Carbine,则 : 和 C 之间的距离将等于 e 和单元格右侧之间的距离。(而不是将其置于整个单元格的中心)。

我尝试编辑宏中的变量以将其替换为\char@name\center{\char@name}但是这会将变量放在一个全新的行上(在单元格内),并仅根据单元格边将其居中。如果没有简单的方法可以做到这一点,我会坚持将其左对齐。

答案1

键值版本

这是我之前回答的一个版本,它提供了一个键值接口。我使用 LaTeX 3 代码来处理键,因为我发现这是最直观的使用方式,尽管语法乍一看有点奇怪。(也就是说,我从来没有理解如何正确使用xkeyval等,所以我不能用困难的、不奇怪的方式去做。)

此外,由于我的原始代码使用了xparse,我不需要添加任何包来使用此方法。geometry添加只是为了获得更宽的示例页面。

\cardme[<list of key-value pairs>]

\cardme现在接受一个可选参数,它是一个键值对的列表。

可用的键有:

avl=、卡片宽度=、剪辑=、cls=、dmg=、名称=、笔=、rld=、rng=、rof=、特殊=、wt=、

除了 之外card width,这些都采用文本,在本例中是键的值。在每种情况下,默认都是不排版任何内容作为值。 的默认值为card width,它需要一个维度.75\textwidth,与原始代码一样。

提供了两个附加宏。

\cardnames{<list of key-value pairs>}

可用于自定义每个键值对使用的标签。除了没有之外,键与以前一样card width。不同之处在于此宏不排版任何内容。它只是更改在每个框中创建标签时将使用的文本(如果\cardme稍后使用)。

相似地

\cardunits{<list of key-value pairs>}

可用于为每种类型的值分配单位。默认情况下,除 和 外,这些为空rng,分别wt设置为kmkg

例如,假设我们创建以下卡片:

\noindent
\cardme

这将是一张具有默认宽度和标签的空卡片。

\noindent
\cardme[%
  card width=\textwidth,
  name=This One,
  cls=Aristocracy,
  rng=450,
  rof=RoF,
  dmg=Extensive,
  pen=Pen,
  clip=Y,
  rld=N,
  wt=1,
  avl=Y,
  special=Extraordinary powers,
]

此卡片使用默认标签,但此时,卡片的每个框中都填写了一个值,并且宽度也增加了。

\cardnames{
  name=Enw,
  cls=Dth,
  rng=Pll,
  dmg=Dfd,
  clip=Cnf,
  rld=AilLl,
  wt=Pwys,
  avl=ArGl,
  special=Arbennig,
}

这不会排版任何内容。相反,它会更改一些标签,而其他标签保持不变。因此,当我们用

\noindent\cardme[card width=.85\textwidth]

我们将得到一张混合了默认和自定义标签且宽度为的空卡片.85\textwidth

3 张牌

完整代码:

\documentclass{article}
\usepackage{calc,xparse,geometry}
\ExplSyntaxOn
\dim_new:N \l_Archimedes_card_width_dim
\dim_set:Nn \l_Archimedes_card_width_dim { .75\textwidth }
\keys_define:nn { Archimedes / card }
{
  avl .tl_set:N = \l_Archimedes_avl_tl,
  card~width .dim_set:N = \l_Archimedes_card_width_dim,
  clip .tl_set:N = \l_Archimedes_clip_tl,
  cls .tl_set:N = \l_Archimedes_cls_tl,
  dmg .tl_set:N = \l_Archimedes_dmg_tl,
  name .tl_set:N = \l_Archimedes_name_tl,
  pen .tl_set:N = \l_Archimedes_pen_tl,
  rld .tl_set:N = \l_Archimedes_rld_tl,
  rng .tl_set:N = \l_Archimedes_rng_tl,
  rof .tl_set:N = \l_Archimedes_rof_tl,
  special .tl_set:N = \l_Archimedes_special_tl,
  wt .tl_set:N = \l_Archimedes_wt_tl,
  avl .initial:n = ,
  clip .initial:n = ,
  cls .initial:n = ,
  dmg .initial:n = ,
  name .initial:n = ,
  pen .initial:n = ,
  rld .initial:n = ,
  rng .initial:n = ,
  rof .initial:n = ,
  special .initial:n = ,
  wt .initial:n = ,
}
\keys_define:nn { Archimedes / card / names }
{
  avl .tl_set:N = \l_Archimedes_avlname_tl,
  clip .tl_set:N = \l_Archimedes_clipname_tl,
  cls .tl_set:N = \l_Archimedes_clsname_tl,
  dmg .tl_set:N = \l_Archimedes_dmgname_tl,
  name .tl_set:N = \l_Archimedes_namename_tl,
  pen .tl_set:N = \l_Archimedes_penname_tl,
  rld .tl_set:N = \l_Archimedes_rldname_tl,
  rng .tl_set:N = \l_Archimedes_rngname_tl,
  rof .tl_set:N = \l_Archimedes_rofname_tl,
  special .tl_set:N = \l_Archimedes_specialname_tl,
  wt .tl_set:N = \l_Archimedes_wtname_tl,
  avl .initial:n = Avl,
  clip .initial:n = Clip,
  cls .initial:n = Cls,
  dmg .initial:n = Dmg,
  name .initial:n = Name,
  pen .initial:n = Pen,
  rld .initial:n = Rld,
  rng .initial:n = Rng,
  rof .initial:n = RoF,
  special .initial:n = Special,
  wt .initial:n = Wt,
}
\keys_define:nn { Archimedes / card / units }
{
  avl .tl_set:N = \l_Archimedes_avlunit_tl,
  clip .tl_set:N = \l_Archimedes_clipunit_tl,
  cls .tl_set:N = \l_Archimedes_clsunit_tl,
  dmg .tl_set:N = \l_Archimedes_dmgunit_tl,
  name .tl_set:N = \l_Archimedes_nameunit_tl,
  pen .tl_set:N = \l_Archimedes_penunit_tl,
  rld .tl_set:N = \l_Archimedes_rldunit_tl,
  rng .tl_set:N = \l_Archimedes_rngunit_tl,
  rof .tl_set:N = \l_Archimedes_rofunit_tl,
  special .tl_set:N = \l_Archimedes_specialunit_tl,
  wt .tl_set:N = \l_Archimedes_wtunit_tl,
  avl .initial:n = ,
  clip .initial:n = ,
  cls .initial:n = ,
  dmg .initial:n = ,
  name .initial:n = ,
  pen .initial:n = ,
  rld .initial:n = ,
  rng .initial:n = km,
  rof .initial:n = ,
  special .initial:n = ,
  wt .initial:n = kg,
}
\cs_new_protected:Nn \Archimedes_pageme:nn
{
  \begin{minipage}{#1\l_Archimedes_card_width_dim}
    \centering
    \fbox{
      \parbox{\linewidth-2\fboxrule-2.5\fboxsep}
      {
        \strut
        \textsc{ \use:c { l_Archimedes_#2name_tl } } : ~ \skip_horizontal:n {\fill} \use:c { l_Archimedes_#2_tl } \skip_horizontal:n {\fill}  \hbox:n { \use:c { l_Archimedes_#2unit_tl } }
      }
    }
  \end{minipage}
}
\NewDocumentCommand \cardnames { m }{
  \keys_set:nn { Archimedes / card / names } { #1 }
}
\NewDocumentCommand \cardunits { m }{
  \keys_set:nn { Archimedes / card / units } { #1 }
}
\NewDocumentCommand \cardme { O {} }{%
  \group_begin:
  \keys_set:nn { Archimedes / card } { #1 }
  \dim_sub:Nn \l_Archimedes_card_width_dim { 2\fboxrule + 2\fboxsep }
  \fbox{
    \begin{minipage}{\l_Archimedes_card_width_dim}
      \centering
      \Archimedes_pageme:nn {.69 } { name }
      \Archimedes_pageme:nn {.31 } { cls }\par
      \Archimedes_pageme:nn { .22 } { rng }
      \Archimedes_pageme:nn { .38 } { rof }
      \Archimedes_pageme:nn { .4 } { dmg }\par
      \Archimedes_pageme:nn { .22 } { pen }
      \Archimedes_pageme:nn { .19 } { clip }
      \Archimedes_pageme:nn { .19 } { rld }
      \Archimedes_pageme:nn { .18 } { wt }
      \Archimedes_pageme:nn { .22 } { avl }\par
      \Archimedes_pageme:nn {  } { special }
    \end{minipage}
  }
  \group_end:
}
\ExplSyntaxOff
\begin{document}
\noindent
\cardme

\noindent
\cardme[%
  card width=\textwidth,
  name=This One,
  cls=Aristocracy,
  rng=450,
  rof=RoF,
  dmg=Extensive,
  pen=Pen,
  clip=Y,
  rld=N,
  wt=1,
  avl=Y,
  special=Extraordinary powers,
]

\cardnames{
  name=Enw,
  cls=Dth,
  rng=Pll,
  dmg=Dfd,
  clip=Cnf,
  rld=AilLl,
  wt=Pwys,
  avl=ArGl,
  special=Arbennig,
}

\noindent\cardme[card width=.85\textwidth]
\end{document}

原始答案

这使用\fboxminipage来创建盒中盒外观。我调整了一些百分比,使它们在每行上加起来为 100。

\cardme[<width>]{<content>}

设置主框。可选参数指定宽度。必需参数指定内容。默认宽度为文本块宽度的四分之三。

\pageme[<width>][<content>]

构造一个内部框。两个可选参数分别是:第一,宽度;第二,内容。默认是创建一个空框,其宽度为卡片的整个(内部)宽度。

然后

\cardme[.8\textwidth]{%
  \pageme[.69][Name]%
  \pageme[.31][Class]

  \pageme[.22][Range]%
  \pageme[.38][RoF]%
  \pageme[.4][Damage]

  \pageme[.22][Pen]%
  \pageme[.19][Clip]%
  \pageme[.19][Reload]%
  \pageme[.18][Weight]%
  \pageme[.22][Availability]

  \pageme[][Special]%
}

指定以下卡:

卡片

完整代码:

\documentclass{article}
\usepackage{calc,xparse}
\newlength\mycardwidth
\setlength\mycardwidth{.75\textwidth}
\NewDocumentCommand \boxme { O{} }{%
  \fbox{%
    \parbox{\linewidth-2\fboxrule-2.5\fboxsep}{\strut #1}%
  }%
}
\NewDocumentCommand \pageme { O{} O{} }{%
  \begin{minipage}{#1\mycardwidth}
    \centering\boxme[#2]
  \end{minipage}%
}
\NewDocumentCommand \cardme { O{.75\textwidth} +m }{%
  \setlength\mycardwidth{#1-2\fboxrule-2\fboxsep}%
  \fbox{%
    \begin{minipage}{\mycardwidth}
      \centering
      #2%
    \end{minipage}%
  }%
}
\begin{document}
\cardme[.8\textwidth]{%
  \pageme[.69][Name]%
  \pageme[.31][Class]

  \pageme[.22][Range]%
  \pageme[.38][RoF]%
  \pageme[.4][Damage]

  \pageme[.22][Pen]%
  \pageme[.19][Clip]%
  \pageme[.19][Reload]%
  \pageme[.18][Weight]%
  \pageme[.22][Availability]

  \pageme[][Special]%
}
\end{document}

答案2

这似乎需要一个键值接口:

在此处输入图片描述

\documentclass{article}

\usepackage{xkeyval}

\makeatletter
\define@cmdkey{rpg}[char@]{name}[]{}
\define@cmdkey{rpg}[char@]{class}[]{}
\define@cmdkey{rpg}[char@]{range}[]{}
\define@cmdkey{rpg}[char@]{rof}[]{}
\define@cmdkey{rpg}[char@]{damage}[]{}
\define@cmdkey{rpg}[char@]{pen}[]{}
\define@cmdkey{rpg}[char@]{clip}[]{}
\define@cmdkey{rpg}[char@]{reload}[]{}
\define@cmdkey{rpg}[char@]{weight}[]{}
\define@cmdkey{rpg}[char@]{availability}[]{}
\define@cmdkey{rpg}[char@]{special}[]{}
\define@cmdkey{rpg}[char@]{width}[\linewidth]{}

\newcommand{\setcharacterstats}[1]{%
  \begingroup
  \setkeys{rpg}{name,class,range,rof,damage,pen,clip,reload,weight,availability,special,width,#1}%
  \noindent
  \begin{tabular}{ @{} c @{} }
    \begin{tabular}{ | p{\dimexpr.69\char@width-2\tabcolsep} | p{\dimexpr.31\char@width-2\tabcolsep} | }
      \hline
      \statlabel{Name}: \char@name & \statlabel{Cls}: \char@class
    \end{tabular} \\
    \begin{tabular}{ | p{\dimexpr.23\char@width-2\tabcolsep} | p{\dimexpr.37\char@width-2\tabcolsep} | p{\dimexpr.4\char@width-2\tabcolsep} | }
      \hline
      \statlabel{Rng}: \char@range & \statlabel{RoF}: \char@rof & \statlabel{Dmg}: \char@damage
    \end{tabular} \\
    \begin{tabular}{ | p{\dimexpr.23\char@width-2\tabcolsep} | p{\dimexpr.20\char@width-2\tabcolsep} | p{\dimexpr.20\char@width-2\tabcolsep} |
                       p{\dimexpr.16\char@width-2\tabcolsep} | p{\dimexpr.21\char@width-2\tabcolsep} | }
      \hline
      \statlabel{Pen}: \char@pen & \statlabel{Clip}: \char@clip & \statlabel{Rld}: \char@reload & \statlabel{Wt}: \char@weight & \statlabel{Avl}: \char@availability
    \end{tabular} \\
    \begin{tabular}{ | p{\dimexpr\char@width-2\tabcolsep} | }
      \hline
      \statlabel{Special}: \char@special \\
      \hline
    \end{tabular}
  \end{tabular}\par
  \endgroup
}
\makeatletter

\newcommand{\statlabel}{\textsc}

\begin{document}

\setcharacterstats{
  name = The HuLK,
  class = Huge,
  range = Arm,
  rof = 5m,
  damage = 400,
  pen = 12,
  clip = 12.2,
  reload = 2s,
  weight = 7t,
  availability = 7,
  special = Green and very angry
  }

\end{document}

所有键都应不言自明,包括您可以调整width每个表的可能性。默认值为\linewidth,并且所有列均以此百分比指定。

相关内容