我正在尝试从 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
设置为km
和kg
。
例如,假设我们创建以下卡片:
\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
。
完整代码:
\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}
原始答案
这使用\fbox
和minipage
来创建盒中盒外观。我调整了一些百分比,使它们在每行上加起来为 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
,并且所有列均以此百分比指定。