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 wanted to adapt Block quote with big quotation marks to languages like my natural language German, but also some other mainly Germanic and Slavic languages (c.f. Wikipedia: Non-English usage of quotation marks), where the opening quote is placed on the bottom.

Based on Andrew Stacey’s answer there and Werner Grundlingh’s idea for the quote signs in How do you create pull quotes? I came to the solution shown below.

My question is:
How can I improve this code? As it stands, all amounts have to be changed on a font change, and there is sometimes manual correction necessary, that must be found empiric; to see some strange effects, comment out the optional values for the question environment below (this is not related to the use of \blindtext; I had this also in real use cases and this was in fact the cause for introducing the correction value). Also the amount for shifting in above and below keys must be different. And at least the opening quote seems not to be placed exactly the same allways, cf. the first and second example.

Perhaps you also have an idea based on a different approach. For instance maybe there is a way with mdframed, since I use it anyway?

The name for the environment comes from the fact, that the original use is only for questions.

\documentclass{article}

\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}

\usepackage{kpfonts}% package with fonts of Kepler project
% loads also package "textcomp"

\usepackage[ngerman]{babel}% new German spelling

\usepackage[svgnames]{xcolor}
  \definecolor{framecolor}{named}{SteelBlue}
  \colorlet{framebgcolor}{PowderBlue!50!White}
  \definecolor{quotesignclr}{named}{LightSlateGrey}

\usepackage{changepage}% not needed with "memoir" and KOMA-Script classes or package "scrextend"

\usepackage{calc,etoolbox,environ,graphicx}

\usepackage[pangram]{blindtext}% for dummy text, needs "babel"

\usepackage{showframe}% just for showing the text margins

\usepackage{tikz}
  \usetikzlibrary{backgrounds,positioning}

% based on answer of Andrew Stacey in http://tex.stackexchange.com/a/28418/9237
% model for quotes: Werner Grundlingh in http://tex.stackexchange.com/a/45828/9237
\newlength{\bodywidth}
\newlength{\testwidth}
\newlength{\nodewidth}
\newcommand*{\openingquote}{\llap{\smash{\makebox[1em][r]{\quotedblbase\hspace*{0.1em}}}}}
\newcommand*{\closingquote}{\rlap{\smash{\makebox[1em][l]{\hspace*{0.1em}\textquotedblleft}}}}
%-----%
\NewEnviron{question}[1][0pt]%
{\begingroup
\settowidth{\bodywidth}{\itshape\BODY}
\setlength{\testwidth}{2.5em+0.6pt+\bodywidth}% 2.5em = 2*inner frame xsep;
                                              % 0.6pt = 2*line width+2*inner sep
\begin{adjustwidth}{3em}{3em}% with KOMA-Script use environment "addmargin" instead
\ifdimcomp{\testwidth}{<}{\linewidth}% "\ifdimcomp" provided by "etoolbox"
  %true:
  {\setlength{\nodewidth}{\bodywidth}\addtolength{\nodewidth}{-#1}}%
  %false:
  {\setlength{\nodewidth}{\linewidth}\addtolength{\nodewidth}{-2.5em-0.6pt-#1}}
\begin{tikzpicture}
    [background rectangle/.style={draw=framecolor,line width=0.2pt,fill=framebgcolor,rounded corners},
     show background rectangle,inner frame xsep=1.25em,inner frame ysep=0.5em]
% body text
  \node[text width=\nodewidth ,align=justify,inner sep=0.1pt] (TXT) {\itshape\BODY};
% opening quote
  \node[overlay,scale=2,text=quotesignclr,inner sep=0.1pt,above=0.25ex of TXT.south west]
       (OpQ) {\openingquote};
%closing quote
  \node[overlay,scale=2,text=quotesignclr,inner sep=0.1pt,below=2.75ex of TXT.north east]
       (ClQ) {\closingquote};
\end{tikzpicture}
\end{adjustwidth}}[\endgroup]

\begin{document}

% German quote signs --> German dummy text

\begin{question}
% text is extracted from package "blindtext"
Dies hier ist ein Blindtext zum Testen von Textausgaben.
Wer diesen Text liest, ist selbst schuld.
\end{question}

\begin{question}
\blindtext[1]
\end{question}

\begin{question}[-0.7em]
\blindtext[1]
\end{question}

\begin{question}[-5em]
\blindtext[1]
\end{question}

\begin{question}
\blindtext[1]
\end{question}

\begin{question}[10.6em]
\blindtext[1]
\end{question}

\end{document}
share|improve this question
add comment

1 Answer

up vote 9 down vote accepted

Here is a proposal, using some low level commands. The text is typeset in a \vtop and its depth is used to place the opening quotes, while the closing quotes will be level with the top line (with some lowering due to size).

Thanks to Jake, I've been able to solve a mystery that bugged me, about a spacing that seems necessary and is due to the inner sep of TikZ nodes.

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[ngerman]{babel}
\usepackage{kpfonts}
\usepackage[svgnames]{xcolor}
  \definecolor{framecolor}{named}{SteelBlue}
  \colorlet{framebgcolor}{PowderBlue!50!White}
  \definecolor{quotesignclr}{named}{LightSlateGrey}
\usepackage{changepage}
\usepackage{environ,graphicx}
\usepackage{tikz}
\usetikzlibrary{backgrounds}

\newcommand\sopeningquote{\scalebox{2}{\color{quotesignclr}\smash\quotedblbase}}
\newcommand\sclosingquote{\scalebox{2}{\color{quotesignclr}\smash\textquotedblleft}}

\makeatletter
\newsavebox\simplequestbox
\NewEnviron{simplequest}{%
  \normalfont
  \begin{adjustwidth}{3em}{3em}
  \settowidth{\dimen@}{\sopeningquote\kern.4em\sclosingquote}%
  \dimen@=\dimexpr\linewidth-\dimen@\relax
  \setbox\simplequestbox=\vtop{
    \@parboxrestore\itshape
    \hsize=\dimexpr\dimen@-\pgfkeysvalueof{/pgf/inner xsep}*2\relax % thanks, Jake
    \sbox\z@{\BODY}
    \ifdim\wd\z@>\hsize
      \noindent\BODY\par
    \else
      \box\z@
    \fi    
    \xdef\simplequestpd{\the\prevdepth}
  }
  \begin{tikzpicture}
    [background rectangle/.style={draw=framecolor,line width=0.2pt,
     fill=framebgcolor,rounded corners}, show background rectangle,
     inner frame xsep=-2pt,inner frame ysep=2pt]
    \node {\mbox{%
      \raisebox{\dimexpr-\dp\simplequestbox+\simplequestpd+.05ex}
        [0pt][0pt]{\sopeningquote}%
      \kern.2em
      \box\simplequestbox
      \kern.2em
      \raisebox{-1.4ex}[0pt][0pt]{\sclosingquote}}};
  \end{tikzpicture}
  \end{adjustwidth}
}
\makeatother
\begin{document}

\begin{simplequest}
Dies hier ist ein Blindtext zum Testen von Textausgaben.
Wer diesen Text liest, ist selbst schuld.
\end{simplequest}

\begin{simplequest}
Dies hier ist ein Blindtext
\end{simplequest}

\Large
\begin{simplequest}
Dies hier ist ein Blindtext zum Testen von Textausgaben.
Wer diesen Text liest, ist selbst schuld.
\end{simplequest}

\end{document}

In the picture the similar quotes are: top mine, bottom yours.

enter image description here


A problem may arise in case the text consists of more than one paragraph and the first one is not long enough to fill a line. Should this case present itself in the document, the code might be changed like this:

\makeatletter
\newsavebox\simplequestbox
\NewEnviron{simplequest}[1][]{%
  \normalfont
  \begin{adjustwidth}{3em}{3em}
  \settowidth{\dimen@}{\sopeningquote\kern.4em\sclosingquote}%
  \dimen@=\dimexpr\linewidth-\dimen@\relax
  \setbox\simplequestbox=\vtop{
    \@parboxrestore\itshape
    \hsize=\dimexpr\dimen@-\pgfkeysvalueof{/pgf/inner xsep}*2\relax % thanks, Jake
    \if\relax\detokenize{#1}\relax
      \sbox\z@{\BODY}
      \ifdim\wd\z@>\hsize
        \noindent\BODY\par
      \else
    \box\z@
      \fi
    \else
      \sbox\z@{#1}
      \hsize\wd\z@
      \BODY\par
    \fi
    \xdef\simplequestpd{\the\prevdepth}
  }
  \begin{tikzpicture}
    [background rectangle/.style={draw=framecolor,line width=0.2pt,
     fill=framebgcolor,rounded corners}, show background rectangle,
     inner frame xsep=-2pt,inner frame ysep=2pt]
    \node {\mbox{%
      \raisebox{\dimexpr-\dp\simplequestbox+\simplequestpd+.05ex}
        [0pt][0pt]{\sopeningquote}%
      \kern.2em
      \box\simplequestbox
      \kern.2em
      \raisebox{-1.4ex}[0pt][0pt]{\sclosingquote}}};
  \end{tikzpicture}
  \end{adjustwidth}
}
\makeatother

The environment now has an optional argument, the first short line; here's an example:

\begin{simplequest}[Dies hier ist ein Blindtext.]
Dies hier ist ein Blindtext.

Wer diesen Text liest, ist selbst schuld.
\end{simplequest}

enter image description here

One could try getting only the first paragraph, but this might be error prone.

share|improve this answer
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.