我想将段落中的每个字母/字符逆时针旋转 90 度,但保持从左到右的流动不变。
到目前为止我发现的所有内容都只是一次旋转一个字母,而不是多个字母。
这是我现在使用的:
\documentclass[a4paper,12pt,landscape]{article}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage{soul}
\usepackage{graphicx}
\usepackage{lipsum}
\usepackage[left=1cm,right=1cm,top=1cm,bottom=1cm,includeheadfoot]{geometry}
\makeatletter
\newlength\srotate@axis
\DeclareRobustCommand*{\srotate}{%
\SOUL@setup
\let\SOUL@everyhyphen\srotate@everyhyphen
\let\SOUL@everyexhyphen\srotate@everyexhyphen
\let\SOUL@everytoken\srotate@everytoken
\settoheight\srotate@axis{$\vcenter{}$}%
\SOUL@
}
\newcommand*{\srotate@everytoken}{%
\srotate@token{\the\SOUL@token}%
}
\newcommand*{\srotate@everyexhyphen}[1]{%
\srotate@token{\raisebox{-\srotate@axis}[.1ex][.1ex]{#1}}%
}
\newcommand*{\srotate@everyhyphen}{%
\discretionary{%
\srotate@everyexhyphen{-}%
}{}{}%
}
\newcommand*{\srotate@token}[1]{%
\kern.2ex
\raisebox{\srotate@axis}{\rotatebox[origin=B]{90}{#1}}%
\kern.2ex
}
\makeatother
\renewcommand{\familydefault}{\ttdefault}
\begin{document}
\noindent
01: \srotate{AST0S Q0LEA NTQOS 2SE2N EA0S9 9ST9Q E9S0Q ST0NV LASLN 2E22L 0ALOT 2OSTO +}
02: \srotate{0O0VV 9N9QO ETVAN V2VST N9OVL 2SOAT ET2S2 LATO0 EL0OA LO0V9 VVEE2 AETSA +}
03: \srotate{00AVS 0E2ON 2ASQE A9NTQ EQ220 92SA9 00OSQ AEVV0 AA9NT STV0L 2NN29 VN9SS +}
04: \srotate{VE2V0 VSASO EL9EO S2TNQ QOSTE N99A0 VQ9LV TV20E L9ESV QO2L2 E0Q2S TOE02 +}
05: \srotate{E2VSQ L0VEN 9A2VA QNQ0V EO00N T909Q STLNV 0LTNO NS9TT T2Q0Q NATAE ENOLE +}
\end{document}
答案1
该解决方案基于soul
.\srotate
获取文本并旋转标记,以数学轴为中心。由于旋转,侧边距丢失,因此代码.05ex
在字母周围添加,连字符获得更多空间。
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage{soul}
\usepackage{graphicx}
\usepackage{lipsum}
\makeatletter
\newlength\srotate@axis
\DeclareRobustCommand*{\srotate}{%
\SOUL@setup
\let\SOUL@everyhyphen\srotate@everyhyphen
\let\SOUL@everyexhyphen\srotate@everyexhyphen
\let\SOUL@everytoken\srotate@everytoken
\settoheight\srotate@axis{$\vcenter{}$}%
\SOUL@
}
\newcommand*{\srotate@everytoken}{%
\srotate@token{\the\SOUL@token}%
}
\newcommand*{\srotate@everyexhyphen}[1]{%
\srotate@token{\raisebox{-\srotate@axis}[.1ex][.1ex]{#1}}%
}
\newcommand*{\srotate@everyhyphen}{%
\discretionary{%
\srotate@everyexhyphen{-}%
}{}{}%
}
\newcommand*{\srotate@token}[1]{%
\kern.05ex
\raisebox{\srotate@axis}{\rotatebox[origin=B]{90}{#1}}%
\kern.05ex
}
\makeatother
\begin{document}
\noindent
\srotate{Hello--world. Nam dui ligula, fringilla a, euismod sodales,
sollicitudin vel, wisi. Morbi auctor lorem non justo. Nam lacus
libero, pretium at, lobortis vitae, ultricies et, tellus. Donec
aliquet, tortor sed accumsan bibendum, erat ligula aliquet magna,
vitae ornare odio metus a mi. Morbi ac orci et nisl hendrerit
mollis. Suspendisse ut massa. Cras nec ante. Pellentesque a nulla.
Cum sociis natoque penatibus et magnis dis parturient montes,
nascetur ridiculus mus. Aliquam tincidunt urna. Nulla ullamcorper
vestibulum turpis. Pellentesque cursus luctus mauris.}
\end{document}
回答评论中的问题
字母的总高度不同,例如,Q
深度大于A
。可以使用具有固定字母宽度的框来修改示例:
\documentclass[a4paper,12pt,landscape]{article}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage{soul}
\usepackage{graphicx}
\usepackage{lipsum}
\usepackage[left=1cm,right=1cm,top=1cm,bottom=1cm,includeheadfoot]{geometry}
\makeatletter
\newlength\srotate@axis
\newlength\srotate@width
\DeclareRobustCommand*{\srotate}{%
\SOUL@setup
\let\SOUL@everyhyphen\srotate@everyhyphen
\let\SOUL@everyexhyphen\srotate@everyexhyphen
\let\SOUL@everytoken\srotate@everytoken
\settoheight\srotate@axis{$\vcenter{}$}%
\settoheight\srotate@width{\raisebox{\depth}{XQ}}%
\SOUL@
}
\newcommand*{\srotate@everytoken}{%
\srotate@token{\the\SOUL@token}%
}
\newcommand*{\srotate@everyexhyphen}[1]{%
\srotate@token{\raisebox{-\srotate@axis}[.1ex][.1ex]{#1}}%
}
\newcommand*{\srotate@everyhyphen}{%
\discretionary{%
\srotate@everyexhyphen{-}%
}{}{}%
}
\newcommand*{\srotate@token}[1]{%
\kern.1ex
\hbox to \srotate@width{%
\hfil
\raisebox{\srotate@axis}{\rotatebox[origin=B]{90}{#1}}%
\hfil
}%
\kern.1ex
}
\makeatother
\renewcommand{\familydefault}{\ttdefault}
\begin{document}
01: \srotate{AST0S Q0LEA NTQOS 2SE2N EA0S9 9ST9Q E9S0Q ST0NV LASLN 2E22L 0ALOT 2OSTO +}
02: \srotate{0O0VV 9N9QO ETVAN V2VST N9OVL 2SOAT ET2S2 LATO0 EL0OA LO0V9 VVEE2 AETSA +}
03: \srotate{00AVS 0E2ON 2ASQE A9NTQ EQ220 92SA9 00OSQ AEVV0 AA9NT STV0L 2NN29 VN9SS +}
04: \srotate{VE2V0 VSASO EL9EO S2TNQ QOSTE N99A0 VQ9LV TV20E L9ESV QO2L2 E0Q2S TOE02 +}
05: \srotate{E2VSQ L0VEN 9A2VA QNQ0V EO00N T909Q STLNV 0LTNO NS9TT T2Q0Q NATAE ENOLE +}
\end{document}
答案2
这是改编自 egreg 的解决方案的版本如何将文本拆分为字符:
代码:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\stringprocess}{ m m }
{
\egreg_string_process:nn { #1 } { #2 }
}
\cs_new_protected:Npn \egreg_string_process:nn #1 #2
{
\tl_map_inline:nn { #2 } { #1 { ##1 } }
}
\ExplSyntaxOff
\newcommand{\rotatechar}[1]{\rotatebox{90}{#1}}
\begin{document}
\stringprocess{\rotatechar}{Roated}
\end{document}
答案3
受到 Peter 的回答的启发,这里有一组 LaTeX3 宏,它们也可以处理空格。
\documentclass{article}
\usepackage{graphicx}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\stringprocess}{ m m }
{
\egreg_wordlist_process:nn { #1 } { #2 }
}
\tl_new:N \l_egreg_wordlist_tl
\seq_new:N \l_egreg_words_seq
\cs_new_protected:Npn \egreg_wordlist_process:nn #1 #2
{
\tl_set:Nn \l_egreg_wordlist_tl {#2}
\seq_set_split:NnV \l_egreg_words_seq { ~ } \l_egreg_wordlist_tl
\seq_map_inline:Nn \l_egreg_words_seq { \egreg_string_process:nn { #1 } { ##1 } \hspace{1.6ex} }
\unskip
}
\cs_new_protected:Npn \egreg_string_process:nn #1 #2
{
\tl_map_inline:nn { #2 } { #1 { ##1 } }
}
\ExplSyntaxOff
\newcommand{\rotatechar}[1]{%
$\vcenter{\hbox to 1.6ex{\hfil\rotatebox{90}{#1}\hfil}}$}
\begin{document}
ABC\stringprocess{\rotatechar}{Rotated word}DEF
\end{document}
想法是一样的,但是首先将文本分成单词,然后形成一个单词序列;我们对每个字母进行旋转,然后将其放入 1.6ex 宽的框中(借助 ,所有字母都相对于同一行垂直居中\vcenter
)。