将长段(固定宽度)文本堆叠在一起的最佳方法是什么?我正在为密码学课程编写练习和解决方案,并希望能够在许多行中将明文置于密文之上。例如:
问题版本:
eiydimvexzzwkmf
ntfukuxzzfcjkfy
itizkcjwifkl
解决方案版本:
jackandjillwent
eiydimvexzzwkmf
upthehilltofetc
ntfukuxzzfcjkfy
apailofwater
itixzcjwifkl
到目前为止,我已经手动地逐行完成了这项工作,但我不想单独担心每一行。
答案1
以下可能是一个开始。它的代码来自长行文本的自动换行?(避免seqsplit
包裹) 和确定逐字字符的宽度(用于确定存储纯文本/密文的块的宽度)打字机字体(等宽字体):
\documentclass{article}
\usepackage{setspace,xcolor}% http://ctan.org/pkg/{setspace,xcolor}
\makeatletter
% \plaincyphertextweave[<num chars>]{<plain text>}{<cypher text>}
\newcommand{\plaincyphertextweave}[3][10]{%
\settowidth{\dimen0}{\ttfamily A}%
\settoheight{\dimen1}{\ttfamily\strut}%
\setlength{\dimen0}{\dimexpr#1\dimen0}%
\leavevmode\rlap{\parbox[t]{\the\dimen0}{\setstretch{2}\scan{#2}\ttfamily\strut\\[\dimexpr-1.7\baselineskip+\dimen1]\@tempa\strut}}% Plain text
\parbox[t]{\the\dimen0}{\setstretch{2}\scan{#3}\ttfamily\strut\\[\dimexpr-1.2\baselineskip+\dimen1]\color{black!50}\@tempa\strut}% Cypher text
}
% \stacktext[<num chars>]{<text>}
\newcommand{\stacktext}[2][10]{%
\settowidth{\dimen0}{\ttfamily A}%
\setlength{\dimen0}{\dimexpr#1\dimen0}%
\parbox[t]{\the\dimen0}{\scan{#2}\ttfamily\strut\@tempa\strut}%
}
%\def\scanfunction#1{#1}
\def\scan@letters#1#2{%
\g@addto@macro{\@tempa}{#1\hskip 0pt}%
\ifx#2\@empty\else
\expandafter\scan@letters
\fi
#2}
\def\scan#1{\let\@tempa\@empty\scan@letters #1\@empty}
\makeatother
\begin{document}
Default width (10 characters): \par
\stacktext{jackandjillwentupthehilltofetchapailofwater}
Forced width (15 characters): \par
\stacktext[15]{jackandjillwentupthehilltofetchapailofwater}
Plain/cypher text weave (20 characters): \par
\plaincyphertextweave[20]{jackandjillwentupthehilltofetchapailofwater}{retawfoliapahctefotllihehtputnewllijdnakcaj}
Some regular, readable text.
\end{document}
上面的例子提供了宽度为 的\stacktext[<num chars>]{<text>}
堆栈。具有类似的接口,但有一个额外的 ( ) 参数需要编织在 之间。编织是通过两个es 的叠加来实现的。<text>
<num chars>
\plaincyphertextweave[<num chars>]{<plain text>}{<cypher text>}
<cypher text>
<plain text>
\parbox
setspace
有助于拉伸文本以编织纯文本/密文组合。需要进行一些垂直调整,因为\baselineskip
稍后会进行。
指某东西的用途xcolor
提供突出显示不同纯文本/密文组件的方法。它仅用于说明目的。
警告:使用\parbox
es 会固定 op 处的定位/锚点[t]
。我不确定您的用例,所以这可能无关紧要。但是,如果[b]
需要 ottom-alignment,则需要进行一些更改。
答案2
以下示例使用包seqsplit
。对于问题文本设置为双\baselineskip
,
解决方案是,每个文本都\parbox
使用 double 命令进行设置\baselineskip
。然后将这些框设置在彼此的顶部,密码文本框移动一个\baselineskip
:
\documentclass{article}
\usepackage{seqsplit}
\newcommand*{\singlesplit}[2][\linewidth]{%
\par\noindent
\begingroup
\parbox[t]{#1}{%
\setlength{\baselineskip}{2\baselineskip}%
\seqsplit{#2}%
}%
\par
\endgroup
}
\newcommand*{\doublesplit}[3][\linewidth]{%
\par\noindent
\begingroup
\ttfamily
\parbox[t]{#1}{%
\ttfamily
\noindent
\raisebox{0pt}[\height][0pt]{%
\parbox[t]{#1}{%
\setlength{\baselineskip}{2\baselineskip}%
\seqsplit{#2}%
}%
}\\%
\parbox[t]{#1}{%
\setlength{\baselineskip}{2\baselineskip}%
\seqsplit{#3}%
}%
}%
\par
\endgroup
}
\begin{document}
\subsection*{Question version:}
\singlesplit[8em]{%
eiydimvexzzwkmf%
ntfukuxzzfcjkfy%
itizkcjwifkl%
}
\subsection*{Solution version:}
\doublesplit[8em]{%Result
jackandjillwent%
upthehilltofetc%
apailofwater%
}{
eiydimvexzzwkmf%
ntfukuxzzfcjkfy%
itizkcjwifkl%
}
\end{document}
评论:
\raisebox{0pt}[\height][0pt]{<stuff>}
效果是包含的框的深度stuff
为零。\parbox[t]
将参考点设置为第一行。因此,TeX 将纯文本框视为具有第一行尺寸的框。下一行是密码文本框。