Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I've been trying to achieve the following vertical sidebar effect in LaTeX for my resume, but turns out it's far more difficult than I thought (created easily in InDesign):

Sidebar

I've tried everything I could think of — sideways minipages, parboxes, tables, multirows, and on and on, but nothing's been able to replicate it. I've gotten close, but never managed to get the title flush along the top of the table (not to mention the centered horizontal rule). Any insight on implementing this?


For reference, here's my latest attempt at implementing this with a table and multirow (requires XeLaTeX):

\documentclass{article}
\usepackage{fontspec, multirow, rotating, tabularx, xunicode}
\def\Vhrulefill{\leavevmode\leaders\hrule height 0.7ex depth \dimexpr0.4pt-0.7ex\hfill\kern0pt}

\begin{document}
  \begin{tabularx}{\textwidth}{l X}
    & \textbf{Spoken Languages} \\
    & English, Hebrew (fluent in speaking, reading, and writing) \\
    & \\
    & \textbf{Programming Languages} \\
    & Objective-C, C, Ruby, Java, Python, HTML + CSS/SASS + JavaScript/CoffeeScript \\
    & \emph{Familiar with C++, Haskell, PHP} \\
    & \\
    & \textbf{Technologies} \\
    & OS X, iOS, Xcode, Unix/Linux Systems, LaTeX, Shell Scripting, Git, Vim, Jekyll \\
    & \emph{Familiar with Windows, Windows Server, MySQL} \\
    \multirow{-9}{*}{\begin{sideways}\Vhrulefill~skills\end{sideways}} &
\end{tabularx}
\end{document}

That produces the following output:

Sample


Update: Werner's answer is the one I think I'll go with since it fits my needs well; however, I've been trying to get it in a more general form so I can reuse it easily, and I've run into trouble.

I've created a new environment for this, but unfortunately, I can't get the label to align correctly along the top of the body text using the height of the text:

\documentclass{article}
\usepackage{graphicx, tabularx, xcolor}
\usepackage{environ}
\usepackage[margin=1in]{geometry}

\newlength{\sectionheight}
\newlength{\tablewidth}
\NewEnviron{rsection}[3]{%
  \setlength{\tablewidth}{#2}
  \addtolength{\tablewidth}{-1ex}
  \settoheight{\sectionheight}{\begin{tabularx}{\tablewidth}{l #3}\BODY\end{tabularx}}

  \begin{tabularx}{\tablewidth}{l #3}
    \BODY \\
    \raisebox{\normalbaselineskip}{\smash{\rotatebox{90}{%
      \color{black!33}\rule[.5ex]{\sectionheight}{.4pt}\llap{\colorbox{white}{\color{black!66}#1}}
    }}} &
  \end{tabularx}
}

\begin{document}
  \begin{rsection}{education}{0.5\textwidth}{X}
    & \textbf{Binghamton University, State University of New York} \\
    & B.S. — Computer Science · Expected 2016 \\
    & \\
    & Binghamton University Scholars Program \\
    & Binghamton President's Scholars Program
  \end{rsection}
  \begin{rsection}{skills}{0.5\textwidth}{X}
    & \textbf{Spoken Languages} \\
    & English, Hebrew (fluent in speaking, reading, and writing) \\
    & \\
    & \textbf{Programming Languages} \\
    & Objective-C, C, Ruby, Java, Python, HTML, CSS, SASS, JavaScript, CoffeeScript \\
    & \emph{Familiar with C++, Haskell, PHP} \\
    & \\
    & \textbf{Technologies} \\
    & OS X, iOS, Xcode, Unix/Linux Systems, LaTeX, Shell Scripting, Git, Vim, Jekyll \\
    & \emph{Familiar with Windows, Windows Server, MySQL}
  \end{rsection}
\end{document}

For some reason, \settoheight{\sectionheight}{\begin{tabularx}{\tablewidth}{l #3}\BODY\end{tabularx}} doesn't return the right height for the text, so the result looks like this:

Result

I'm expecting the label to look right, and for the tables to align next to each other. Any idea what's going wrong?

share|improve this question
    
It would be helpful if you can give us a minimal working example (MWE), showing us what you have done, for example with minipages. So it is easier and faster to help you. –  Kurt Nov 19 '12 at 3:05
    
@Kurt Added my latest attempt. Hope this helps... –  Itai Ferber Nov 19 '12 at 3:13
    
The document cannot be compiled using Latex. It requires Luatex or Xelatex. –  Vivi Nov 19 '12 at 3:34
    
@Vivi That's true — I use XeLaTeX. Is that an issue? –  Itai Ferber Nov 19 '12 at 3:40
    
I don't think it is an issue in terms of your question, but when other people try to compile your document they will not be able to unless they use Xelatex or Luatex. I am only saving them the trouble of having to find that out. Sorry, I am not able to help you with your question... –  Vivi Nov 19 '12 at 3:52
show 2 more comments

2 Answers

up vote 3 down vote accepted

Here is a very manual attempt at obtaining the result. Since the vertical rule + text spans 12 rows of the table (in my example), I draw a \rule of length 12\normalbaselineskip, and then rotate it into position:

enter image description here

\documentclass{article}
\usepackage{graphicx, tabularx, xcolor}% http://ctan.org/pkg/{graphicx,tabularx,xcolor}

\begin{document}
  \begin{tabularx}{\textwidth}{l X}
    & \textbf{Spoken Languages} \\
    & English, Hebrew (fluent in speaking, reading, and writing) \\
    & \\
    & \textbf{Programming Languages} \\
    & Objective-C, C, Ruby, Java, Python, HTML + CSS/SASS + JavaScript/CoffeeScript \\
    & \emph{Familiar with C++, Haskell, PHP} \\
    & \\
    & \textbf{Technologies} \\
    & OS X, iOS, Xcode, Unix/Linux Systems, LaTeX, Shell Scripting, Git, Vim, Jekyll \\
    \smash{\rotatebox{90}{%
      \color{black!20}\rule[.5ex]{12\normalbaselineskip}{.4pt}\llap{\colorbox{white}{\color{black!75}skills}}%
      }} & 
      \emph{Familiar with Windows, Windows Server, MySQL}
\end{tabularx}
\end{document}

graphicx provides \rotatebox{<degrees>}{<stuff>} while xcolor allows for changing the text/rule colours. I have foregone multirow since \smash removes the vertical height of its argument.


It is also possible to use zref's savepos module to identify the start/end of the rsection, and insert a rule accordingly:

enter image description here

\documentclass{article}
\usepackage{graphicx, tabularx, xcolor, environ}% http://ctan.org/pkg/{graphicx,tabularx,xcolor,environ}
\usepackage{zref-savepos}% http://ctan.org/pkg/zref
\usepackage[margin=1in]{geometry}% http://ctan.org/pkg/geometry

\makeatletter
% Taken from http://tex.stackexchange.com/a/69076/5764
% \zsaveposx/y is defined since 2011/12/05 v2.23 of zref-savepos
\@ifundefined{zsaveposy}{\let\zsaveposy\zsavepos}{}

\newlength{\tablewidth}
\newcounter{@rsection}
\NewEnviron{rsection}[3]{%
  % #1 = label
  % #2 = tabularx width
  % #3 = column specification
  \setlength{\tablewidth}{#2}%
  \stepcounter{@rsection}% Mark labels top/bottom based on rsection counter
  %
  \noindent\begin{tabularx}{\tablewidth}{l #3}
    \zsaveposy{rsection-top-\the@rsection}% Store top y-position
    \BODY \\[-\normalbaselineskip]% Place content
    \zsaveposy{rsection-bot-\the@rsection}% Store bottom y-position
    \zref@refused{rsection-top-\the@rsection}%
    \zref@refused{rsection-bot-\the@rsection}%
    \smash{\rotatebox{90}{%
      \color{black!33}%
        \rule[.5ex]{\dimexpr\normalbaselineskip+\zposy{rsection-top-\the@rsection}sp-\zposy{rsection-bot-\the@rsection}sp}{.4pt}%
        \llap{\colorbox{white}{\color{black!66}#1}}
    }} &
  \end{tabularx}%
}
\makeatother

\begin{document}
  \begin{rsection}{education}{0.5\textwidth}{X}
    & \textbf{Binghamton University, State University of New York} \\
    & B.S. — Computer Science · Expected 2016 \\
    & \\
    & Binghamton University Scholars Program \\
    & Binghamton President's Scholars Program
  \end{rsection}%
  \begin{rsection}{skills}{0.5\textwidth}{X}
    & \textbf{Spoken Languages} \\
    & English, Hebrew (fluent in speaking, reading, and writing) \\
    & \\
    & \textbf{Programming Languages} \\
    & Objective-C, C, Ruby, Java, Python, HTML, CSS, SASS, JavaScript, CoffeeScript \\
    & \emph{Familiar with C++, Haskell, PHP} \\
    & \\
    & \textbf{Technologies} \\
    & OS X, iOS, Xcode, Unix/Linux Systems, LaTeX, Shell Scripting, Git, Vim, Jekyll \\
    & \emph{Familiar with Windows, Windows Server, MySQL}
  \end{rsection}
\end{document}

In the above example, the labels rsection-bot-\the@rsection and rsection-top-\the@rsection store the y-position (in scaled points/sps) of the table bottom & top, respectively. An appropriate \dimexpr calculates the height of the table and inserts the rule (as before) in the first column.

share|improve this answer
    
I like this answer a lot; it's concise and fits my needs. I've been trying to generalize it though, and I've run into trouble. I've updated my question; any chance you could help? –  Itai Ferber Nov 19 '12 at 16:27
    
@ItaiFerber: I'll hopefully be able to tackle this later tonight (at work now). –  Werner Nov 19 '12 at 19:21
    
Thanks so much! –  Itai Ferber Nov 19 '12 at 19:41
    
Hate to be a bother, but just wondering if you could take a stab at it in your spare time. I'd definitely grant you the correct answer... :) –  Itai Ferber Nov 26 '12 at 6:58
    
@ItaiFerber: I've updated my answer with a zref-style answer, which should work with xelatex. Let me know if this is not sufficient. –  Werner Nov 28 '12 at 1:20
show 1 more comment

Here's an automated solution, allowing page breaks (in the case the table spans several pages); all you have to do is to enclose the table using the tikzborder environment, providing as mandatory argument the label:

\documentclass{article}
\usepackage{fontspec, tabularx,xunicode}
\usepackage{longtable}
\usepackage{atbegshi}
\usepackage{refcount}
\usepackage{tikz}
\usetikzlibrary{calc}
\usepackage{lipsum}

\newcounter{bordercntr}
\newcounter{borderpages}

\newcommand\tikzmark[1]{%
  \tikz[overlay,remember picture] \node (#1) {};}

\newenvironment{tikzborder}[1]
{%
  \gdef\bordertitle{#1}
  \stepcounter{bordercntr}%
  \tikzmark{start-border}\label{start-border\thebordercntr}%
  \ifnum\getpagerefnumber{start-border\thebordercntr}=\getpagerefnumber{end-border\thebordercntr} \else
    \begin{tikzpicture}[overlay, remember picture]
    \draw [ultra thick,gray]
      let \p1 = (start-border.south), \p2 = (end-border), \p3 = (current page.center) in%
         ( $ (\x3,\y1) + (-.55\textwidth,2pt) $ ) --  ( $ (\x3,\y3) + (-0.55\textwidth,-0.5\textheight-15pt) $ );
    \end{tikzpicture}%
  \begin{tikzpicture}[overlay, remember picture]
    \path let \p1 = (start-border.south), \p2 = (current page.center) in%
node[rotate=90,fill=white,anchor=east,font=\color{black!70}\sffamily] at ( $ (\x2,\y1) + (-.55\textwidth,2pt) $ ) {\bordertitle};
  \end{tikzpicture}
    \setcounter{borderpages} {\numexpr\getpagerefnumber{end-border\thebordercntr}-\getpagerefnumber{start-border\thebordercntr}}\theborderpages
    \ifnum\value{borderpages}>1
      \AtBeginShipoutNext{\tikzborderpage}%
    \fi
  \fi%
}
{\tikzmark{end-border}\label{end-border\thebordercntr}
  \ifnum\getpagerefnumber{start-border\thebordercntr}=\getpagerefnumber{end-border\thebordercntr}
    \begin{tikzpicture}[overlay, remember picture]
    \draw [ultra thick,gray]
      let \p1 = (start-border.south), \p2 = (end-border), \p3 = (current page.center) in
      ( $ (\x3,\y1) + (-.55\textwidth,2pt) $ ) --  ( $ (\x3,\y2) + (-.55\textwidth,10pt) $ );
    \end{tikzpicture}%
  \begin{tikzpicture}[overlay, remember picture]
    \path let \p1 = (start-border.south), \p2 = (current page.center) in%
node[rotate=90,fill=white,anchor=east,font=\color{black!70}\sffamily] at ( $ (\x2,\y1) + (-.55\textwidth,2pt) $ ) {\bordertitle};
  \end{tikzpicture}
  \else
    \begin{tikzpicture}[overlay, remember picture]
    \draw [ultra thick,gray]
      let \p1 = (start-border.north), \p2 = (end-border), \p3 = (current page.center) in
      ( $ (\x3,\y3) + (-.55\textwidth,.5\textheight-6pt) $ ) -- ( $ (\x3,\y2) + (-.55\textwidth,20pt) $ );
    \end{tikzpicture}%
  \fi%
}

\newcommand\tikzborderpage{%
  \begin{tikzpicture}[overlay, remember picture]
    \draw [ultra thick,gray]
      let \p1 = (current page.center) in
      ( $ (\x1,\y1) + (-.55\textwidth,0.5\textheight-15pt) $ ) -- ( $ (\x1,\y1) + (-.55\textwidth,-0.5\textheight) $ );
  \end{tikzpicture}
  \addtocounter{borderpages}{-1}%
  \ifnum\value{borderpages}>1
    \AtBeginShipoutNext{\tikzborderpage}%
  \fi%
}

\begin{document}


\begin{tikzborder}{skills}

\noindent\begin{tabularx}{\textwidth}{X}
     \textbf{Spoken Languages} \\
     English, Hebrew (fluent in speaking, reading, and writing) \\
     \\
     \textbf{Programming Languages} \\
     Objective-C, C, Ruby, Java, Python, HTML + CSS/SASS + JavaScript/CoffeeScript \\
     \emph{Familiar with C++, Haskell, PHP} \\
     \\
     \textbf{Technologies} \\
     OS X, iOS, Xcode, Unix/Linux Systems, LaTeX, Shell Scripting, Git, Vim, Jekyll \\
     \emph{Familiar with Windows, Windows Server, MySQL} \\
\end{tabularx}
\end{tikzborder}

\begin{tikzborder}{expertise}
\begin{longtable}{p{.7\textwidth}}
     \textbf{Spoken Languages} \\
     English, Hebrew (fluent in speaking, reading, and writing) \\
     \\
     \textbf{Programming Languages} \\
     Objective-C, C, Ruby, Java, Python, HTML + CSS/SASS + JavaScript/CoffeeScript \\
     \emph{Familiar with C++, Haskell, PHP} \\
     \\
     \textbf{Technologies} \\
     OS X, iOS, Xcode, Unix/Linux Systems, LaTeX, Shell Scripting, Git, Vim, Jekyll \\
     \emph{Familiar with Windows, Windows Server, MySQL} \\

     \textbf{Spoken Languages} \\
     English, Hebrew (fluent in speaking, reading, and writing) \\
     \\
     \textbf{Programming Languages} \\
     Objective-C, C, Ruby, Java, Python, HTML + CSS/SASS + JavaScript/CoffeeScript \\
     \emph{Familiar with C++, Haskell, PHP} \\
     \\
     \textbf{Technologies} \\
     OS X, iOS, Xcode, Unix/Linux Systems, LaTeX, Shell Scripting, Git, Vim, Jekyll \\
     \emph{Familiar with Windows, Windows Server, MySQL} \\

     \textbf{Spoken Languages} \\
     English, Hebrew (fluent in speaking, reading, and writing) \\
     \\
     \textbf{Programming Languages} \\
     Objective-C, C, Ruby, Java, Python, HTML + CSS/SASS + JavaScript/CoffeeScript \\
     \emph{Familiar with C++, Haskell, PHP} \\
     \\
     \textbf{Technologies} \\
     OS X, iOS, Xcode, Unix/Linux Systems, LaTeX, Shell Scripting, Git, Vim, Jekyll \\
     \emph{Familiar with Windows, Windows Server, MySQL} \\

     \textbf{Spoken Languages} \\
     English, Hebrew (fluent in speaking, reading, and writing) \\
     \\
     \textbf{Programming Languages} \\
     Objective-C, C, Ruby, Java, Python, HTML + CSS/SASS + JavaScript/CoffeeScript \\
     \emph{Familiar with C++, Haskell, PHP} \\
     \\
     \textbf{Technologies} \\
     OS X, iOS, Xcode, Unix/Linux Systems, LaTeX, Shell Scripting, Git, Vim, Jekyll \\
     \emph{Familiar with Windows, Windows Server, MySQL} \\

     \textbf{Spoken Languages} \\
     English, Hebrew (fluent in speaking, reading, and writing) \\
     \\
     \textbf{Programming Languages} \\
     Objective-C, C, Ruby, Java, Python, HTML + CSS/SASS + JavaScript/CoffeeScript \\
     \emph{Familiar with C++, Haskell, PHP} \\
     \\
     \textbf{Technologies} \\
     OS X, iOS, Xcode, Unix/Linux Systems, LaTeX, Shell Scripting, Git, Vim, Jekyll \\
     \emph{Familiar with Windows, Windows Server, MySQL} \\

     \textbf{Spoken Languages} \\
     English, Hebrew (fluent in speaking, reading, and writing) \\
     \\
     \textbf{Programming Languages} \\
     Objective-C, C, Ruby, Java, Python, HTML + CSS/SASS + JavaScript/CoffeeScript \\
     \emph{Familiar with C++, Haskell, PHP} \\
     \\
     \textbf{Technologies} \\
     OS X, iOS, Xcode, Unix/Linux Systems, LaTeX, Shell Scripting, Git, Vim, Jekyll \\
     \emph{Familiar with Windows, Windows Server, MySQL} \\

     \textbf{Spoken Languages} \\
     English, Hebrew (fluent in speaking, reading, and writing) \\
     \\
     \textbf{Programming Languages} \\
     Objective-C, C, Ruby, Java, Python, HTML + CSS/SASS + JavaScript/CoffeeScript \\
     \emph{Familiar with C++, Haskell, PHP} \\
     \\
     \textbf{Technologies} \\
     OS X, iOS, Xcode, Unix/Linux Systems, LaTeX, Shell Scripting, Git, Vim, Jekyll \\
     \emph{Familiar with Windows, Windows Server, MySQL} \\
\end{longtable}
\end{tikzborder}

\end{document}

enter image description here

share|improve this answer
    
I like this solution because it's automated, but unfortunately, it doesn't align along the text like I need it to. It's a bit overkill for my needs, but I appreciate it! –  Itai Ferber Nov 19 '12 at 16:19
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.