我使用的是 Plain TeX(出于字体原因,实际上是 XeTeX,但我基本上像使用 Plain 一样使用它,这是我习惯的)。我正在为某人输入一首诗,我想创建一个类似于
it's magic
tragic
我想也许我可以用它\phantom
来实现这个目的,比如
\begingroup\obeylines
it's magic
\hphantom{it's} tragic
\endgroup%obeylines
我使用是\hphantom
因为我想要水平空间,但我不太清楚两者的区别。使用 和 的输出\hphantom
都是\phantom
一样的:
无论我把空间放在盒子里面还是外面似乎都无关紧要\phantom
。
\obeylines
我不太清楚为什么幻影被放在了它自己的线路上,但我想这和我无法理解的事情有关。提前感谢你的帮助,如果这可能是一个愚蠢的错误,我很抱歉。
答案1
如果您使用 LaTeX,您所显示的标记就会具有您想要的效果。
\documentclass{article}
\begin{document}
\begingroup\obeylines
it's magic
\hphantom{it's} tragic
\endgroup%obeylines
\end{document}
在普通的 TeX 中,\hphantom
不会以以下方式开始一个段落:
\begingroup\obeylines
it's magic
\leavevmode\hphantom{it's} tragic
\endgroup%obeylines
\bye
但我只会将纯 TeX 用于小型测试示例,而不是真实文档。
答案2
答案3
如果您愿意使用 LuaTeX(通常应该与 XeTeX 兼容),我们可以定义一个环境,自动将任何初始缩进与前一行对齐,而无需任何额外的标记:
%%%%%%%%%%%%%%%%%%
%%% Formatting %%%
%%%%%%%%%%%%%%%%%%
% Make LuaTeX load fonts like XeTeX
\input luaotfload.sty
\directlua{
config.luaotfload.default_features.global.tlig = true
config.luaotfload.default_features.global.trep = true
}
% Load the fonts
\font\seventeenrm="[lmroman17-regular]" at 17pt
\font\adventorbold="TeX Gyre Adventor/B" at 12pt
% Set the main font
\seventeenrm
\baselineskip=1.2em
\nopagenumbers
%%%%%%%%%%%%%%%%
%%% TeX Code %%%
%%%%%%%%%%%%%%%%
\newattribute\alignspacesattr
\def\beginalignspaces{%
\bgroup%
\alignspacesattr=1% Mark all nodes with this attribute
\catcode`\ =12% Make the space into a regular character
\obeylines% Process line-by-line
\toksapp\everypar{\setbox0=\lastbox}% Remove the indent from every line
}
\def\endalignspaces{%
\par% Make sure that the last line is processed
\egroup%
}
%%%%%%%%%%%%%%%%
%%% Lua Code %%%
%%%%%%%%%%%%%%%%
\directlua{
% Helper function to traverse through any marked nodes
local n_attr
local function get_next_attr(n)
local next = n.next
if next then
n_attr = select(2, node.find_attribute(next, "alignspacesattr"))
return n_attr
end
end
% Replaces a node with another node
local function replace_node(head, n1, n2)
local head, current = node.remove(head, n1)
head, n2 = node.insert_before(head, current, n2)
return head, n2
end
local prev_widths = {}
% Define the callback, which runs for every line
luatexbase.add_to_callback("pre_linebreak_filter", function (head)
% Remove any discretionaries
local head = head
if get_next_attr(head) then
head = node.flatten_discretionaries(head)
end
% Initialize the line-local variables
local this_widths = {}
local before_chars = true
n_attr = head
% Iterate over every character in a marked line
while get_next_attr(n_attr) do
local char = n_attr.char
% Replace space glyphs with some sort of glue
if char == string.byte(" ") then
local hskip = node.new("glue")
if before_chars then
% If we're at the start of the line, then make the space the
% same width as the character immediately above it.
hskip.width = prev_widths[rawlen(this_widths) + 1]
else
% If we're in the middle of the line, set it to the regular
% space width.
local params = font.getfont(n_attr.font).parameters
node.setglue(
hskip,
params.space, params.space_stretch, params.space_shrink,
0, 0
)
end
head, n_attr = replace_node(head, n_attr, hskip)
else
% If we're not at a space, then set that we're not at the start
% of the line.
before_chars = false
end
% Recurse through any ligatures
local chars = {}
local function check_components(n)
if n.components then
for m in node.traverse(n.components) do
check_components(m)
end
elseif char and
(n.id == node.id("glyph") or n.id == node.id("glue"))
then
chars[rawlen(chars) + 1] = n
end
end
check_components(n_attr)
% Save the widths of the characters on this line
for _, n in ipairs(chars) do
this_widths[rawlen(this_widths) + 1] = (n.width or 0)
end
end
prev_widths = this_widths
return head
end, "align_spaces")
}
%%%%%%%%%%%%
%%% Demo %%%
%%%%%%%%%%%%
\beginalignspaces
% Works with different character widths
abc def ghi jkl mno pqr
def ghi
hi jkl m
no pqr
r stu
f ghi jkl mno pqr stu
% And with em-dashes
M l M --- M
l M --- M
M --- M
--- M
M
% And with ligatures
waffles
les
% And with different fonts
ABCDEF G {\adventorbold H I} J K
{\adventorbold I} J
EF G {\adventorbold H I}
ABCDEF G {\adventorbold H }
abM l M --- ABC
---
\endalignspaces
\bye