19

I'd lik to rotate every letter/character of a paragraph 90 degrees counterclockwise, yet keeping the left-to-right flow intact.

Everything I have found so far only rotates one letter at a time and not multiple letters.

This is what I use now:

\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}
4
  • Interesting question! Out of curiosity: What's the application for this?
    – Jake
    Commented Nov 14, 2012 at 22:22
  • 1
    I am learning morsecode and have written a tool that generates soundfiles for me to "study". It also outputs the correct groups of five letters (one "word") in a row of twelve words of what it made into soundfiles. I copy down what I read with my ears, then compare my copy with the printout. I lay the copied down letters below the current row, then compare what I got right or wrong. Having the letters rotated on my printout would free me from rotating them visually ;)
    – Christian
    Commented Nov 14, 2012 at 22:32
  • Maybe this can help a step further: tex.stackexchange.com/a/28912/7417
    – Count Zero
    Commented Nov 14, 2012 at 22:38
  • Right direction, but changing the 180 to 90 or 270 yields funny output for me as the text is also written from right-to-left now and the characters are overlapping a bit. Also, I don't know how to remove the right-to-left part (deleting one of the rotaing rows doesn't do it).
    – Christian
    Commented Nov 14, 2012 at 22:45

3 Answers 3

13

This solution is based on soul. \srotate takes the text and rotates the tokens, centered at the math axis. Because of the rotation the side bearings are missing, thus the code adds .05ex around the letters, hyphens get a little more space.

\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}

Result
click to enlarge

Answer to the problem in comment

The letters have different total heights, e.g. Q has a larger depth than A. The example can be modified by using a box with a fixed width for the letter:

\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}

Result
click to enlarge

1
  • Perfect - I added what I use right now to my question. I wonder, though, why line 05 seems to be out of sync with the spacing of the ther lines (just a bit, starting at the second word)?
    – Christian
    Commented Nov 14, 2012 at 23:24
7

Here is a version adapted from egreg's solution at How to split text into characters:

enter image description here

Code:

\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
  • This looks promising, yet the spaces between words seem to disappear and the letters overlap.
    – Christian
    Commented Nov 14, 2012 at 22:55
  • Yeah, saw that problem when I added more text. Not sure I'll be able to figure that out as I think that the problem I am having handling that is in the expl3 portion of the code. But haven't given up yet!! Commented Nov 14, 2012 at 22:59
  • \tl_map_inline:nn disregards spaces. A slower routine is necessary for keeping them.
    – egreg
    Commented Nov 14, 2012 at 23:18
5

Inspired by Peter's answer, here's a set of LaTeX3 macros that also take care of spaces.

\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}

The idea is just the same, but the text is first split into words and a sequence of words is formed; we apply rotation to every letter, which is then put in a 1.6ex wide box (all vertically centered with respect to the same line with the help of \vcenter).

enter image description here

1
  • Thanks - another interesting and helpful way of doing it!
    – Christian
    Commented Nov 20, 2012 at 8:36

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .